Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2022 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include <stdexcept>
21 :
22 : #include "MediaKeysServerInternal.h"
23 : #include "RialtoServerLogging.h"
24 :
25 : namespace firebolt::rialto
26 : {
27 1 : const char *mediaKeyErrorStatusToString(const MediaKeyErrorStatus &status)
28 : {
29 1 : switch (status)
30 : {
31 0 : case firebolt::rialto::MediaKeyErrorStatus::OK:
32 0 : return "OK";
33 0 : case firebolt::rialto::MediaKeyErrorStatus::BAD_SESSION_ID:
34 0 : return "BAD_SESSION_ID";
35 1 : case firebolt::rialto::MediaKeyErrorStatus::INTERFACE_NOT_IMPLEMENTED:
36 1 : return "INTERFACE_NOT_IMPLEMENTED";
37 0 : case firebolt::rialto::MediaKeyErrorStatus::BUFFER_TOO_SMALL:
38 0 : return "BUFFER_TOO_SMALL";
39 0 : case firebolt::rialto::MediaKeyErrorStatus::NOT_SUPPORTED:
40 0 : return "NOT_SUPPORTED";
41 0 : default:
42 0 : return "FAIL";
43 : }
44 : }
45 :
46 1 : std::shared_ptr<IMediaKeysFactory> IMediaKeysFactory::createFactory()
47 : {
48 1 : return server::IMediaKeysServerInternalFactory::createFactory();
49 : }
50 : } // namespace firebolt::rialto
51 :
52 : namespace firebolt::rialto::server
53 : {
54 53 : int32_t generateSessionId()
55 : {
56 : static int32_t keySessionId{0};
57 53 : return keySessionId++;
58 : }
59 :
60 2 : std::shared_ptr<IMediaKeysServerInternalFactory> IMediaKeysServerInternalFactory::createFactory()
61 : {
62 2 : std::shared_ptr<IMediaKeysServerInternalFactory> factory;
63 :
64 : try
65 : {
66 2 : factory = std::make_shared<MediaKeysServerInternalFactory>();
67 : }
68 0 : catch (const std::exception &e)
69 : {
70 0 : RIALTO_SERVER_LOG_ERROR("Failed to create the media keys factory, reason: %s", e.what());
71 : }
72 :
73 2 : return factory;
74 : }
75 :
76 1 : std::unique_ptr<IMediaKeys> MediaKeysServerInternalFactory::createMediaKeys(const std::string &keySystem) const
77 : {
78 1 : RIALTO_SERVER_LOG_ERROR("This function can't be used by rialto server. Please use createMediaKeysServerInternal");
79 1 : return nullptr;
80 : }
81 :
82 : std::unique_ptr<IMediaKeysServerInternal>
83 1 : MediaKeysServerInternalFactory::createMediaKeysServerInternal(const std::string &keySystem) const
84 : {
85 1 : std::unique_ptr<IMediaKeysServerInternal> mediaKeys;
86 : try
87 : {
88 2 : mediaKeys = std::make_unique<server::MediaKeysServerInternal>(keySystem,
89 3 : server::IMainThreadFactory::createFactory(),
90 3 : wrappers::IOcdmSystemFactory::createFactory(),
91 3 : server::IMediaKeySessionFactory::createFactory());
92 : }
93 1 : catch (const std::exception &e)
94 : {
95 1 : RIALTO_SERVER_LOG_ERROR("Failed to create the media keys, reason: %s", e.what());
96 : }
97 :
98 1 : return mediaKeys;
99 : }
100 : }; // namespace firebolt::rialto::server
101 :
102 : namespace firebolt::rialto::server
103 : {
104 60 : MediaKeysServerInternal::MediaKeysServerInternal(
105 : const std::string &keySystem, const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
106 : std::shared_ptr<firebolt::rialto::wrappers::IOcdmSystemFactory> ocdmSystemFactory,
107 60 : std::shared_ptr<IMediaKeySessionFactory> mediaKeySessionFactory)
108 60 : : m_mediaKeySessionFactory(mediaKeySessionFactory), m_kKeySystem(keySystem)
109 : {
110 60 : RIALTO_SERVER_LOG_DEBUG("entry:");
111 :
112 60 : m_mainThread = mainThreadFactory->getMainThread();
113 60 : if (!m_mainThread)
114 : {
115 1 : throw std::runtime_error("Failed to get the main thread");
116 : }
117 59 : m_mainThreadClientId = m_mainThread->registerClient();
118 :
119 59 : if (!ocdmSystemFactory)
120 : {
121 1 : throw std::runtime_error("No ocdmSystemFactory");
122 : }
123 :
124 58 : bool result = false;
125 58 : auto task = [&]()
126 : {
127 58 : m_ocdmSystem = ocdmSystemFactory->createOcdmSystem(keySystem);
128 58 : if (!m_ocdmSystem)
129 : {
130 1 : RIALTO_SERVER_LOG_ERROR("Ocdm system could not be created");
131 : }
132 : else
133 : {
134 57 : result = true;
135 : }
136 58 : };
137 :
138 58 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
139 58 : if (!result)
140 : {
141 1 : throw std::runtime_error("MediaKeys construction failed");
142 : }
143 75 : }
144 :
145 171 : MediaKeysServerInternal::~MediaKeysServerInternal()
146 : {
147 57 : RIALTO_SERVER_LOG_DEBUG("entry:");
148 :
149 57 : auto task = [&]()
150 : {
151 57 : m_ocdmSystem.reset();
152 :
153 57 : m_mainThread->unregisterClient(m_mainThreadClientId);
154 114 : };
155 :
156 57 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
157 114 : }
158 :
159 3 : MediaKeyErrorStatus MediaKeysServerInternal::selectKeyId(int32_t keySessionId, const std::vector<uint8_t> &keyId)
160 : {
161 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
162 :
163 : MediaKeyErrorStatus status;
164 3 : auto task = [&]() { status = selectKeyIdInternal(keySessionId, keyId); };
165 :
166 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
167 3 : return status;
168 : }
169 :
170 3 : MediaKeyErrorStatus MediaKeysServerInternal::selectKeyIdInternal(int32_t keySessionId, const std::vector<uint8_t> &keyId)
171 : {
172 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
173 3 : if (sessionIter == m_mediaKeySessions.end())
174 : {
175 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
176 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
177 : }
178 :
179 2 : MediaKeyErrorStatus status = sessionIter->second->selectKeyId(keyId);
180 2 : if (MediaKeyErrorStatus::OK != status)
181 : {
182 1 : RIALTO_SERVER_LOG_ERROR("Failed to select key id");
183 1 : return status;
184 : }
185 :
186 1 : return status;
187 : }
188 :
189 3 : bool MediaKeysServerInternal::containsKey(int32_t keySessionId, const std::vector<uint8_t> &keyId)
190 : {
191 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
192 :
193 3 : bool result{false};
194 3 : auto task = [&]() { result = containsKeyInternal(keySessionId, keyId); };
195 :
196 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
197 3 : return result;
198 : }
199 :
200 3 : bool MediaKeysServerInternal::containsKeyInternal(int32_t keySessionId, const std::vector<uint8_t> &keyId)
201 : {
202 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
203 3 : if (sessionIter == m_mediaKeySessions.end())
204 : {
205 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
206 1 : return false;
207 : }
208 :
209 2 : return sessionIter->second->containsKey(keyId);
210 : }
211 :
212 53 : MediaKeyErrorStatus MediaKeysServerInternal::createKeySession(KeySessionType sessionType,
213 : std::weak_ptr<IMediaKeysClient> client, bool isLDL,
214 : int32_t &keySessionId)
215 : {
216 53 : RIALTO_SERVER_LOG_DEBUG("entry:");
217 :
218 : MediaKeyErrorStatus status;
219 53 : auto task = [&]() { status = createKeySessionInternal(sessionType, client, isLDL, keySessionId); };
220 :
221 53 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
222 53 : return status;
223 : }
224 :
225 53 : MediaKeyErrorStatus MediaKeysServerInternal::createKeySessionInternal(KeySessionType sessionType,
226 : std::weak_ptr<IMediaKeysClient> client,
227 : bool isLDL, int32_t &keySessionId)
228 : {
229 53 : int32_t keySessionIdTemp = generateSessionId();
230 : std::unique_ptr<IMediaKeySession> mediaKeySession =
231 106 : m_mediaKeySessionFactory->createMediaKeySession(m_kKeySystem, keySessionIdTemp, *m_ocdmSystem, sessionType,
232 106 : client, isLDL);
233 53 : if (!mediaKeySession)
234 : {
235 1 : RIALTO_SERVER_LOG_ERROR("Failed to create a new media key session");
236 1 : return MediaKeyErrorStatus::FAIL;
237 : }
238 52 : keySessionId = keySessionIdTemp;
239 52 : m_mediaKeySessions.emplace(std::make_pair(keySessionId, std::move(mediaKeySession)));
240 :
241 52 : return MediaKeyErrorStatus::OK;
242 53 : }
243 :
244 3 : MediaKeyErrorStatus MediaKeysServerInternal::generateRequest(int32_t keySessionId, InitDataType initDataType,
245 : const std::vector<uint8_t> &initData)
246 : {
247 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
248 :
249 : MediaKeyErrorStatus status;
250 3 : auto task = [&]() { status = generateRequestInternal(keySessionId, initDataType, initData); };
251 :
252 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
253 3 : return status;
254 : }
255 :
256 3 : MediaKeyErrorStatus MediaKeysServerInternal::generateRequestInternal(int32_t keySessionId, InitDataType initDataType,
257 : const std::vector<uint8_t> &initData)
258 : {
259 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
260 3 : if (sessionIter == m_mediaKeySessions.end())
261 : {
262 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
263 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
264 : }
265 :
266 2 : MediaKeyErrorStatus status = sessionIter->second->generateRequest(initDataType, initData);
267 2 : if (MediaKeyErrorStatus::OK != status)
268 : {
269 1 : RIALTO_SERVER_LOG_ERROR("Failed to generate request for the key session %d", keySessionId);
270 1 : return status;
271 : }
272 1 : return status;
273 : }
274 :
275 3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSession(int32_t keySessionId)
276 : {
277 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
278 :
279 : MediaKeyErrorStatus status;
280 3 : auto task = [&]() { status = loadSessionInternal(keySessionId); };
281 :
282 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
283 3 : return status;
284 : }
285 :
286 3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSessionInternal(int32_t keySessionId)
287 : {
288 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
289 3 : if (sessionIter == m_mediaKeySessions.end())
290 : {
291 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
292 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
293 : }
294 :
295 2 : MediaKeyErrorStatus status = sessionIter->second->loadSession();
296 2 : if (MediaKeyErrorStatus::OK != status)
297 : {
298 1 : RIALTO_SERVER_LOG_ERROR("Failed to load the session %d", keySessionId);
299 1 : return status;
300 : }
301 1 : return status;
302 : }
303 :
304 3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSession(int32_t keySessionId, const std::vector<uint8_t> &responseData)
305 : {
306 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
307 :
308 : MediaKeyErrorStatus status;
309 3 : auto task = [&]() { status = updateSessionInternal(keySessionId, responseData); };
310 :
311 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
312 3 : return status;
313 : }
314 :
315 3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSessionInternal(int32_t keySessionId,
316 : const std::vector<uint8_t> &responseData)
317 : {
318 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
319 3 : if (sessionIter == m_mediaKeySessions.end())
320 : {
321 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
322 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
323 : }
324 :
325 2 : MediaKeyErrorStatus status = sessionIter->second->updateSession(responseData);
326 2 : if (MediaKeyErrorStatus::OK != status)
327 : {
328 1 : RIALTO_SERVER_LOG_ERROR("Failed to update the session %d", keySessionId);
329 1 : return status;
330 : }
331 1 : return status;
332 : }
333 :
334 3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeader(int32_t keySessionId, const std::vector<uint8_t> &requestData)
335 : {
336 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
337 :
338 : MediaKeyErrorStatus status;
339 3 : auto task = [&]() { status = setDrmHeaderInternal(keySessionId, requestData); };
340 :
341 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
342 3 : return status;
343 : }
344 :
345 3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeaderInternal(int32_t keySessionId,
346 : const std::vector<uint8_t> &requestData)
347 : {
348 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
349 3 : if (sessionIter == m_mediaKeySessions.end())
350 : {
351 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
352 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
353 : }
354 :
355 2 : MediaKeyErrorStatus status = sessionIter->second->setDrmHeader(requestData);
356 2 : if (MediaKeyErrorStatus::OK != status)
357 : {
358 1 : RIALTO_SERVER_LOG_ERROR("Failed to set drm header");
359 1 : return status;
360 : }
361 :
362 1 : return status;
363 : }
364 :
365 3 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySession(int32_t keySessionId)
366 : {
367 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
368 :
369 : MediaKeyErrorStatus status;
370 3 : auto task = [&]() { status = closeKeySessionInternal(keySessionId); };
371 :
372 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
373 3 : return status;
374 : }
375 :
376 3 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySessionInternal(int32_t keySessionId)
377 : {
378 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
379 3 : if (sessionIter == m_mediaKeySessions.end())
380 : {
381 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
382 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
383 : }
384 :
385 2 : MediaKeyErrorStatus status = sessionIter->second->closeKeySession();
386 2 : if (MediaKeyErrorStatus::OK != status)
387 : {
388 1 : RIALTO_SERVER_LOG_ERROR("Failed to close the key session %d", keySessionId);
389 1 : return status;
390 : }
391 1 : return status;
392 : }
393 :
394 5 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySession(int32_t keySessionId)
395 : {
396 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
397 :
398 : MediaKeyErrorStatus status;
399 5 : auto task = [&]() { status = removeKeySessionInternal(keySessionId); };
400 :
401 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
402 5 : return status;
403 : }
404 :
405 5 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySessionInternal(int32_t keySessionId)
406 : {
407 5 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
408 5 : if (sessionIter == m_mediaKeySessions.end())
409 : {
410 2 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
411 2 : return MediaKeyErrorStatus::BAD_SESSION_ID;
412 : }
413 :
414 3 : MediaKeyErrorStatus status = sessionIter->second->removeKeySession();
415 3 : if (MediaKeyErrorStatus::OK != status)
416 : {
417 1 : RIALTO_SERVER_LOG_ERROR("Failed to remove the key session %d", keySessionId);
418 1 : return status;
419 : }
420 2 : return status;
421 : }
422 :
423 2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteDrmStore()
424 : {
425 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
426 :
427 : MediaKeyErrorStatus status;
428 2 : auto task = [&]() { status = m_ocdmSystem->deleteSecureStore(); };
429 :
430 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
431 2 : return status;
432 : }
433 :
434 2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteKeyStore()
435 : {
436 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
437 :
438 : MediaKeyErrorStatus status;
439 2 : auto task = [&]() { status = m_ocdmSystem->deleteKeyStore(); };
440 :
441 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
442 2 : return status;
443 : }
444 :
445 2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmStoreHash(std::vector<unsigned char> &drmStoreHash)
446 : {
447 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
448 2 : constexpr size_t kHashSize{256};
449 2 : drmStoreHash.resize(kHashSize);
450 : MediaKeyErrorStatus status;
451 2 : auto task = [&]() { status = m_ocdmSystem->getSecureStoreHash(&drmStoreHash[0], kHashSize); };
452 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
453 2 : return status;
454 : }
455 :
456 2 : MediaKeyErrorStatus MediaKeysServerInternal::getKeyStoreHash(std::vector<unsigned char> &keyStoreHash)
457 : {
458 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
459 2 : constexpr size_t kHashSize{256};
460 2 : keyStoreHash.resize(kHashSize);
461 : MediaKeyErrorStatus status;
462 2 : auto task = [&]() { status = m_ocdmSystem->getKeyStoreHash(&keyStoreHash[0], kHashSize); };
463 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
464 2 : return status;
465 : }
466 :
467 2 : MediaKeyErrorStatus MediaKeysServerInternal::getLdlSessionsLimit(uint32_t &ldlLimit)
468 : {
469 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
470 :
471 : MediaKeyErrorStatus status;
472 2 : auto task = [&]() { status = m_ocdmSystem->getLdlSessionsLimit(&ldlLimit); };
473 :
474 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
475 2 : return status;
476 : }
477 :
478 3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmError(int32_t keySessionId, uint32_t &errorCode)
479 : {
480 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
481 :
482 : MediaKeyErrorStatus status;
483 3 : auto task = [&]() { status = getLastDrmErrorInternal(keySessionId, errorCode); };
484 :
485 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
486 3 : return status;
487 : }
488 :
489 3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmErrorInternal(int32_t keySessionId, uint32_t &errorCode)
490 : {
491 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
492 3 : if (sessionIter == m_mediaKeySessions.end())
493 : {
494 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
495 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
496 : }
497 :
498 2 : MediaKeyErrorStatus status = sessionIter->second->getLastDrmError(errorCode);
499 2 : if (MediaKeyErrorStatus::OK != status)
500 : {
501 1 : RIALTO_SERVER_LOG_ERROR("Failed to get last drm error");
502 : }
503 :
504 2 : return status;
505 : }
506 :
507 2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmTime(uint64_t &drmTime)
508 : {
509 : MediaKeyErrorStatus status;
510 2 : auto task = [&]() { status = m_ocdmSystem->getDrmTime(&drmTime); };
511 :
512 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
513 2 : return status;
514 : }
515 :
516 3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId)
517 : {
518 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
519 :
520 : MediaKeyErrorStatus status;
521 3 : auto task = [&]() { status = getCdmKeySessionIdInternal(keySessionId, cdmKeySessionId); };
522 :
523 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
524 3 : return status;
525 : }
526 :
527 2 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySession(int32_t keySessionId)
528 : {
529 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
530 :
531 : MediaKeyErrorStatus status;
532 2 : auto task = [&]() { status = releaseKeySessionInternal(keySessionId); };
533 :
534 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
535 2 : return status;
536 : }
537 :
538 2 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySessionInternal(int32_t keySessionId)
539 : {
540 2 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
541 2 : if (sessionIter == m_mediaKeySessions.end())
542 : {
543 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
544 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
545 : }
546 :
547 1 : m_mediaKeySessions.erase(sessionIter);
548 1 : return MediaKeyErrorStatus::OK;
549 : }
550 :
551 3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionIdInternal(int32_t keySessionId, std::string &cdmKeySessionId)
552 : {
553 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
554 3 : if (sessionIter == m_mediaKeySessions.end())
555 : {
556 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
557 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
558 : }
559 :
560 2 : MediaKeyErrorStatus status = sessionIter->second->getCdmKeySessionId(cdmKeySessionId);
561 2 : if (MediaKeyErrorStatus::OK != status)
562 : {
563 1 : RIALTO_SERVER_LOG_ERROR("Failed to get cdm key session id");
564 1 : return status;
565 : }
566 :
567 1 : return status;
568 : }
569 :
570 3 : MediaKeyErrorStatus MediaKeysServerInternal::decrypt(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
571 : {
572 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
573 :
574 : MediaKeyErrorStatus status;
575 3 : auto task = [&]() { status = decryptInternal(keySessionId, encrypted, caps); };
576 :
577 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
578 3 : return status;
579 : }
580 :
581 3 : MediaKeyErrorStatus MediaKeysServerInternal::decryptInternal(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
582 : {
583 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
584 3 : if (sessionIter == m_mediaKeySessions.end())
585 : {
586 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
587 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
588 : }
589 :
590 2 : MediaKeyErrorStatus status = sessionIter->second->decrypt(encrypted, caps);
591 2 : if (MediaKeyErrorStatus::OK != status)
592 : {
593 1 : RIALTO_SERVER_LOG_ERROR("Failed to decrypt buffer.");
594 1 : return status;
595 : }
596 1 : RIALTO_SERVER_LOG_INFO("Successfully decrypted buffer.");
597 :
598 1 : return status;
599 : }
600 :
601 2 : bool MediaKeysServerInternal::isNetflixPlayreadyKeySystem() const
602 : {
603 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
604 2 : return m_kKeySystem.find("netflix") != std::string::npos;
605 : }
606 :
607 1 : void MediaKeysServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
608 : {
609 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
610 1 : auto task = [&]() { heartbeatHandler.reset(); };
611 :
612 1 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
613 : }
614 :
615 4 : MediaKeyErrorStatus MediaKeysServerInternal::getMetricSystemData(std::vector<uint8_t> &buffer)
616 : {
617 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
618 :
619 4 : uint32_t bufferLength{1024};
620 4 : const uint32_t kMaxBufferLength{65536};
621 : MediaKeyErrorStatus status;
622 4 : buffer.resize(bufferLength);
623 :
624 11 : for (int attempts = 0; bufferLength <= kMaxBufferLength; ++attempts)
625 : {
626 11 : auto task = [&]() { status = m_ocdmSystem->getMetricSystemData(bufferLength, buffer); };
627 11 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
628 :
629 11 : if (status != MediaKeyErrorStatus::BUFFER_TOO_SMALL)
630 : {
631 3 : break;
632 : }
633 :
634 8 : if (bufferLength >= kMaxBufferLength)
635 : {
636 1 : RIALTO_SERVER_LOG_ERROR("Buffer size %u exceeds the maximum allowed size %u", bufferLength, kMaxBufferLength);
637 1 : return MediaKeyErrorStatus::BUFFER_TOO_SMALL;
638 : }
639 :
640 7 : RIALTO_SERVER_LOG_WARN("Buffer is too small, resizing from %u to %u", bufferLength, bufferLength * 2);
641 7 : bufferLength *= 2;
642 7 : buffer.resize(bufferLength);
643 : }
644 :
645 3 : if (status == MediaKeyErrorStatus::OK)
646 : {
647 : // If the buffer remains larger than bufferLength (due to a previous resize),
648 : // the client may have values in the extra space. So this resize would ensure the buffer is trimmed to the correct size.
649 2 : buffer.resize(bufferLength);
650 2 : RIALTO_SERVER_LOG_DEBUG("Successfully retrieved metric system data, final buffer length: %u", bufferLength);
651 : }
652 : else
653 : {
654 1 : RIALTO_SERVER_LOG_ERROR("Failed to retrieve metric system data, status: %s, last buffer length tried: %u",
655 : firebolt::rialto::mediaKeyErrorStatusToString(status), bufferLength);
656 : }
657 3 : return status;
658 : }
659 :
660 : }; // namespace firebolt::rialto::server
|