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