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 58 : MediaKeysServerInternal::MediaKeysServerInternal(
105 : const std::string &keySystem, const std::shared_ptr<IMainThreadFactory> &mainThreadFactory,
106 : std::shared_ptr<firebolt::rialto::wrappers::IOcdmSystemFactory> ocdmSystemFactory,
107 58 : std::shared_ptr<IMediaKeySessionFactory> mediaKeySessionFactory)
108 58 : : m_mediaKeySessionFactory(mediaKeySessionFactory), m_kKeySystem(keySystem)
109 : {
110 58 : RIALTO_SERVER_LOG_DEBUG("entry:");
111 :
112 58 : m_mainThread = mainThreadFactory->getMainThread();
113 58 : if (!m_mainThread)
114 : {
115 1 : throw std::runtime_error("Failed to get the main thread");
116 : }
117 57 : m_mainThreadClientId = m_mainThread->registerClient();
118 :
119 57 : if (!ocdmSystemFactory)
120 : {
121 1 : throw std::runtime_error("No ocdmSystemFactory");
122 : }
123 :
124 56 : bool result = false;
125 56 : auto task = [&]()
126 : {
127 56 : m_ocdmSystem = ocdmSystemFactory->createOcdmSystem(keySystem);
128 56 : if (!m_ocdmSystem)
129 : {
130 1 : RIALTO_SERVER_LOG_ERROR("Ocdm system could not be created");
131 : }
132 : else
133 : {
134 55 : result = true;
135 : }
136 56 : };
137 :
138 56 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
139 56 : if (!result)
140 : {
141 1 : throw std::runtime_error("MediaKeys construction failed");
142 : }
143 73 : }
144 :
145 165 : MediaKeysServerInternal::~MediaKeysServerInternal()
146 : {
147 55 : RIALTO_SERVER_LOG_DEBUG("entry:");
148 :
149 55 : auto task = [&]()
150 : {
151 55 : m_ocdmSystem.reset();
152 :
153 55 : m_mainThread->unregisterClient(m_mainThreadClientId);
154 110 : };
155 :
156 55 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
157 110 : }
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,
214 : int32_t &keySessionId)
215 : {
216 53 : RIALTO_SERVER_LOG_DEBUG("entry:");
217 :
218 : MediaKeyErrorStatus status;
219 53 : auto task = [&]() { status = createKeySessionInternal(sessionType, client, 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 : 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);
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 : const LimitedDurationLicense &ldlState)
247 : {
248 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
249 :
250 : MediaKeyErrorStatus status;
251 3 : auto task = [&]() { status = generateRequestInternal(keySessionId, initDataType, initData, ldlState); };
252 :
253 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
254 3 : return status;
255 : }
256 :
257 3 : MediaKeyErrorStatus MediaKeysServerInternal::generateRequestInternal(int32_t keySessionId, InitDataType initDataType,
258 : const std::vector<uint8_t> &initData,
259 : const LimitedDurationLicense &ldlState)
260 : {
261 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
262 3 : if (sessionIter == m_mediaKeySessions.end())
263 : {
264 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
265 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
266 : }
267 :
268 2 : MediaKeyErrorStatus status = sessionIter->second->generateRequest(initDataType, initData, ldlState);
269 2 : if (MediaKeyErrorStatus::OK != status)
270 : {
271 1 : RIALTO_SERVER_LOG_ERROR("Failed to generate request for the key session %d", keySessionId);
272 1 : return status;
273 : }
274 1 : return status;
275 : }
276 :
277 3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSession(int32_t keySessionId)
278 : {
279 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
280 :
281 : MediaKeyErrorStatus status;
282 3 : auto task = [&]() { status = loadSessionInternal(keySessionId); };
283 :
284 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
285 3 : return status;
286 : }
287 :
288 3 : MediaKeyErrorStatus MediaKeysServerInternal::loadSessionInternal(int32_t keySessionId)
289 : {
290 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
291 3 : if (sessionIter == m_mediaKeySessions.end())
292 : {
293 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
294 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
295 : }
296 :
297 2 : MediaKeyErrorStatus status = sessionIter->second->loadSession();
298 2 : if (MediaKeyErrorStatus::OK != status)
299 : {
300 1 : RIALTO_SERVER_LOG_ERROR("Failed to load the session %d", keySessionId);
301 1 : return status;
302 : }
303 1 : return status;
304 : }
305 :
306 3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSession(int32_t keySessionId, const std::vector<uint8_t> &responseData)
307 : {
308 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
309 :
310 : MediaKeyErrorStatus status;
311 3 : auto task = [&]() { status = updateSessionInternal(keySessionId, responseData); };
312 :
313 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
314 3 : return status;
315 : }
316 :
317 3 : MediaKeyErrorStatus MediaKeysServerInternal::updateSessionInternal(int32_t keySessionId,
318 : const std::vector<uint8_t> &responseData)
319 : {
320 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
321 3 : if (sessionIter == m_mediaKeySessions.end())
322 : {
323 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
324 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
325 : }
326 :
327 2 : MediaKeyErrorStatus status = sessionIter->second->updateSession(responseData);
328 2 : if (MediaKeyErrorStatus::OK != status)
329 : {
330 1 : RIALTO_SERVER_LOG_ERROR("Failed to update the session %d", keySessionId);
331 1 : return status;
332 : }
333 1 : return status;
334 : }
335 :
336 3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeader(int32_t keySessionId, const std::vector<uint8_t> &requestData)
337 : {
338 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
339 :
340 : MediaKeyErrorStatus status;
341 3 : auto task = [&]() { status = setDrmHeaderInternal(keySessionId, requestData); };
342 :
343 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
344 3 : return status;
345 : }
346 :
347 3 : MediaKeyErrorStatus MediaKeysServerInternal::setDrmHeaderInternal(int32_t keySessionId,
348 : const std::vector<uint8_t> &requestData)
349 : {
350 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
351 3 : if (sessionIter == m_mediaKeySessions.end())
352 : {
353 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
354 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
355 : }
356 :
357 2 : MediaKeyErrorStatus status = sessionIter->second->setDrmHeader(requestData);
358 2 : if (MediaKeyErrorStatus::OK != status)
359 : {
360 1 : RIALTO_SERVER_LOG_ERROR("Failed to set drm header");
361 1 : return status;
362 : }
363 :
364 1 : return status;
365 : }
366 :
367 3 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySession(int32_t keySessionId)
368 : {
369 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
370 :
371 : MediaKeyErrorStatus status;
372 3 : auto task = [&]() { status = closeKeySessionInternal(keySessionId); };
373 :
374 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
375 3 : return status;
376 : }
377 :
378 3 : MediaKeyErrorStatus MediaKeysServerInternal::closeKeySessionInternal(int32_t keySessionId)
379 : {
380 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
381 3 : if (sessionIter == m_mediaKeySessions.end())
382 : {
383 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
384 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
385 : }
386 :
387 2 : MediaKeyErrorStatus status = sessionIter->second->closeKeySession();
388 2 : if (MediaKeyErrorStatus::OK != status)
389 : {
390 1 : RIALTO_SERVER_LOG_ERROR("Failed to close the key session %d", keySessionId);
391 1 : return status;
392 : }
393 1 : return status;
394 : }
395 :
396 5 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySession(int32_t keySessionId)
397 : {
398 5 : RIALTO_SERVER_LOG_DEBUG("entry:");
399 :
400 : MediaKeyErrorStatus status;
401 5 : auto task = [&]() { status = removeKeySessionInternal(keySessionId); };
402 :
403 5 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
404 5 : return status;
405 : }
406 :
407 5 : MediaKeyErrorStatus MediaKeysServerInternal::removeKeySessionInternal(int32_t keySessionId)
408 : {
409 5 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
410 5 : if (sessionIter == m_mediaKeySessions.end())
411 : {
412 2 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
413 2 : return MediaKeyErrorStatus::BAD_SESSION_ID;
414 : }
415 :
416 3 : MediaKeyErrorStatus status = sessionIter->second->removeKeySession();
417 3 : if (MediaKeyErrorStatus::OK != status)
418 : {
419 1 : RIALTO_SERVER_LOG_ERROR("Failed to remove the key session %d", keySessionId);
420 1 : return status;
421 : }
422 2 : return status;
423 : }
424 :
425 2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteDrmStore()
426 : {
427 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
428 :
429 : MediaKeyErrorStatus status;
430 2 : auto task = [&]() { status = m_ocdmSystem->deleteSecureStore(); };
431 :
432 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
433 2 : return status;
434 : }
435 :
436 2 : MediaKeyErrorStatus MediaKeysServerInternal::deleteKeyStore()
437 : {
438 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
439 :
440 : MediaKeyErrorStatus status;
441 2 : auto task = [&]() { status = m_ocdmSystem->deleteKeyStore(); };
442 :
443 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
444 2 : return status;
445 : }
446 :
447 2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmStoreHash(std::vector<unsigned char> &drmStoreHash)
448 : {
449 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
450 2 : constexpr size_t kHashSize{256};
451 2 : drmStoreHash.resize(kHashSize);
452 : MediaKeyErrorStatus status;
453 2 : auto task = [&]() { status = m_ocdmSystem->getSecureStoreHash(&drmStoreHash[0], kHashSize); };
454 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
455 2 : return status;
456 : }
457 :
458 2 : MediaKeyErrorStatus MediaKeysServerInternal::getKeyStoreHash(std::vector<unsigned char> &keyStoreHash)
459 : {
460 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
461 2 : constexpr size_t kHashSize{256};
462 2 : keyStoreHash.resize(kHashSize);
463 : MediaKeyErrorStatus status;
464 2 : auto task = [&]() { status = m_ocdmSystem->getKeyStoreHash(&keyStoreHash[0], kHashSize); };
465 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
466 2 : return status;
467 : }
468 :
469 2 : MediaKeyErrorStatus MediaKeysServerInternal::getLdlSessionsLimit(uint32_t &ldlLimit)
470 : {
471 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
472 :
473 : MediaKeyErrorStatus status;
474 2 : auto task = [&]() { status = m_ocdmSystem->getLdlSessionsLimit(&ldlLimit); };
475 :
476 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
477 2 : return status;
478 : }
479 :
480 3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmError(int32_t keySessionId, uint32_t &errorCode)
481 : {
482 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
483 :
484 : MediaKeyErrorStatus status;
485 3 : auto task = [&]() { status = getLastDrmErrorInternal(keySessionId, errorCode); };
486 :
487 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
488 3 : return status;
489 : }
490 :
491 3 : MediaKeyErrorStatus MediaKeysServerInternal::getLastDrmErrorInternal(int32_t keySessionId, uint32_t &errorCode)
492 : {
493 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
494 3 : if (sessionIter == m_mediaKeySessions.end())
495 : {
496 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
497 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
498 : }
499 :
500 2 : MediaKeyErrorStatus status = sessionIter->second->getLastDrmError(errorCode);
501 2 : if (MediaKeyErrorStatus::OK != status)
502 : {
503 1 : RIALTO_SERVER_LOG_ERROR("Failed to get last drm error");
504 : }
505 :
506 2 : return status;
507 : }
508 :
509 2 : MediaKeyErrorStatus MediaKeysServerInternal::getDrmTime(uint64_t &drmTime)
510 : {
511 : MediaKeyErrorStatus status;
512 2 : auto task = [&]() { status = m_ocdmSystem->getDrmTime(&drmTime); };
513 :
514 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
515 2 : return status;
516 : }
517 :
518 3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionId(int32_t keySessionId, std::string &cdmKeySessionId)
519 : {
520 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
521 :
522 : MediaKeyErrorStatus status;
523 3 : auto task = [&]() { status = getCdmKeySessionIdInternal(keySessionId, cdmKeySessionId); };
524 :
525 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
526 3 : return status;
527 : }
528 :
529 2 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySession(int32_t keySessionId)
530 : {
531 2 : RIALTO_SERVER_LOG_DEBUG("entry:");
532 :
533 : MediaKeyErrorStatus status;
534 2 : auto task = [&]() { status = releaseKeySessionInternal(keySessionId); };
535 :
536 2 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
537 2 : return status;
538 : }
539 :
540 2 : MediaKeyErrorStatus MediaKeysServerInternal::releaseKeySessionInternal(int32_t keySessionId)
541 : {
542 2 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
543 2 : if (sessionIter == m_mediaKeySessions.end())
544 : {
545 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
546 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
547 : }
548 :
549 1 : m_mediaKeySessions.erase(sessionIter);
550 1 : return MediaKeyErrorStatus::OK;
551 : }
552 :
553 3 : MediaKeyErrorStatus MediaKeysServerInternal::getCdmKeySessionIdInternal(int32_t keySessionId, std::string &cdmKeySessionId)
554 : {
555 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
556 3 : if (sessionIter == m_mediaKeySessions.end())
557 : {
558 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
559 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
560 : }
561 :
562 2 : MediaKeyErrorStatus status = sessionIter->second->getCdmKeySessionId(cdmKeySessionId);
563 2 : if (MediaKeyErrorStatus::OK != status)
564 : {
565 1 : RIALTO_SERVER_LOG_ERROR("Failed to get cdm key session id");
566 1 : return status;
567 : }
568 :
569 1 : return status;
570 : }
571 :
572 3 : MediaKeyErrorStatus MediaKeysServerInternal::decrypt(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
573 : {
574 3 : RIALTO_SERVER_LOG_DEBUG("entry:");
575 :
576 : MediaKeyErrorStatus status;
577 3 : auto task = [&]() { status = decryptInternal(keySessionId, encrypted, caps); };
578 :
579 3 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
580 3 : return status;
581 : }
582 :
583 3 : MediaKeyErrorStatus MediaKeysServerInternal::decryptInternal(int32_t keySessionId, GstBuffer *encrypted, GstCaps *caps)
584 : {
585 3 : auto sessionIter = m_mediaKeySessions.find(keySessionId);
586 3 : if (sessionIter == m_mediaKeySessions.end())
587 : {
588 1 : RIALTO_SERVER_LOG_ERROR("Failed to find the session %d", keySessionId);
589 1 : return MediaKeyErrorStatus::BAD_SESSION_ID;
590 : }
591 :
592 2 : MediaKeyErrorStatus status = sessionIter->second->decrypt(encrypted, caps);
593 2 : if (MediaKeyErrorStatus::OK != status)
594 : {
595 1 : RIALTO_SERVER_LOG_ERROR("Failed to decrypt buffer.");
596 1 : return status;
597 : }
598 1 : RIALTO_SERVER_LOG_INFO("Successfully decrypted buffer.");
599 :
600 1 : return status;
601 : }
602 :
603 1 : void MediaKeysServerInternal::ping(std::unique_ptr<IHeartbeatHandler> &&heartbeatHandler)
604 : {
605 1 : RIALTO_SERVER_LOG_DEBUG("entry:");
606 1 : auto task = [&]() { heartbeatHandler.reset(); };
607 :
608 1 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
609 : }
610 :
611 4 : MediaKeyErrorStatus MediaKeysServerInternal::getMetricSystemData(std::vector<uint8_t> &buffer)
612 : {
613 4 : RIALTO_SERVER_LOG_DEBUG("entry:");
614 :
615 4 : uint32_t bufferLength{1024};
616 4 : const uint32_t kMaxBufferLength{65536};
617 : MediaKeyErrorStatus status;
618 4 : buffer.resize(bufferLength);
619 :
620 11 : for (int attempts = 0; bufferLength <= kMaxBufferLength; ++attempts)
621 : {
622 11 : auto task = [&]() { status = m_ocdmSystem->getMetricSystemData(bufferLength, buffer); };
623 11 : m_mainThread->enqueueTaskAndWait(m_mainThreadClientId, task);
624 :
625 11 : if (status != MediaKeyErrorStatus::BUFFER_TOO_SMALL)
626 : {
627 3 : break;
628 : }
629 :
630 8 : if (bufferLength >= kMaxBufferLength)
631 : {
632 1 : RIALTO_SERVER_LOG_ERROR("Buffer size %u exceeds the maximum allowed size %u", bufferLength, kMaxBufferLength);
633 1 : return MediaKeyErrorStatus::BUFFER_TOO_SMALL;
634 : }
635 :
636 7 : RIALTO_SERVER_LOG_WARN("Buffer is too small, resizing from %u to %u", bufferLength, bufferLength * 2);
637 7 : bufferLength *= 2;
638 7 : buffer.resize(bufferLength);
639 : }
640 :
641 3 : if (status == MediaKeyErrorStatus::OK)
642 : {
643 : // If the buffer remains larger than bufferLength (due to a previous resize),
644 : // the client may have values in the extra space. So this resize would ensure the buffer is trimmed to the correct size.
645 2 : buffer.resize(bufferLength);
646 2 : RIALTO_SERVER_LOG_DEBUG("Successfully retrieved metric system data, final buffer length: %u", bufferLength);
647 : }
648 : else
649 : {
650 1 : RIALTO_SERVER_LOG_ERROR("Failed to retrieve metric system data, status: %s, last buffer length tried: %u",
651 : firebolt::rialto::mediaKeyErrorStatusToString(status), bufferLength);
652 : }
653 3 : return status;
654 : }
655 :
656 : }; // namespace firebolt::rialto::server
|