@@ -293,6 +293,45 @@ namespace Plugin {
293293 using State
294294 = Exchange::IContentProtection::INotification::Status::State;
295295
296+ private:
297+ enum { NoSuchSession = 21009 };
298+ enum { WatermarkRenderFailed = 20001 };
299+
300+ static Core::OptionalType<uint32_t > SecManagerStatus (
301+ uint16_t classification, uint16_t reason)
302+ {
303+ Core::OptionalType<uint32_t > result;
304+ // https://github.com/comcast-contentsecurity/spec
305+ static std::map<std::tuple<uint16_t , uint16_t >, uint32_t > map{
306+ { { 100 , 3 }, 21003 },
307+ { { 100 , 4 }, 21004 },
308+ { { 100 , 5 }, 21005 },
309+ { { 100 , 6 }, 21006 },
310+ { { 100 , 7 }, 21007 },
311+ { { 100 , 8 }, 21008 },
312+ { { 100 , 9 }, NoSuchSession },
313+ { { 100 , 12 }, 21012 },
314+ { { 100 , 14 }, 21014 },
315+ { { 100 , 15 }, 21015 },
316+ { { 200 , 1 }, 22001 },
317+ { { 200 , 3 }, 22003 },
318+ { { 200 , 4 }, 22004 },
319+ { { 200 , 8 }, 22008 },
320+ { { 200 , 11 }, 22011 },
321+ { { 200 , 12 }, 22012 },
322+ { { 200 , 13 }, 22013 },
323+ { { 200 , 16 }, 22016 },
324+ { { 300 , 1 }, 23001 },
325+ { { 300 , 3 }, 23003 },
326+ { { 300 , 12 }, 23012 }
327+ };
328+ auto it = map.find (std::make_tuple (classification, reason));
329+ if (it != map.end ()) {
330+ result = it->second ;
331+ }
332+ return result;
333+ }
334+
296335 private:
297336 class Implementation : public Exchange ::IContentProtection {
298337 public:
@@ -348,10 +387,8 @@ namespace Plugin {
348387 override
349388 {
350389 uint32_t result;
351- Core::JSON::String jsonString;
352- jsonString.FromString (initData);
353390 JsonObject out;
354- out.FromString (jsonString );
391+ out.FromString (initData );
355392 out[" clientId" ] = clientId;
356393 out[" keySystem" ] = Core::JSON::EnumType<KeySystem>(keySystem)
357394 .Data ();
@@ -361,12 +398,16 @@ namespace Plugin {
361398 OpenSessionTimeout, _T (" openPlaybackSession" ), out, in);
362399 if (result == Core::ERROR_NONE) {
363400 if (!in[" success" ].Boolean ()) {
364- result = Core::ERROR_GENERAL;
401+ auto context = in[" secManagerResultContext" ].Object ();
402+ auto status = SecManagerStatus (
403+ context[" class" ].Number (),
404+ context[" reason" ].Number ());
405+ result = status.IsSet ()
406+ ? status.Value ()
407+ : Core::ERROR_GENERAL;
365408 } else {
366409 sessionId = in[" sessionId" ].Number ();
367- string inStr;
368- in.ToString (inStr);
369- response = Core::ToQuotedString (' \" ' , inStr);
410+ in.ToString (response);
370411
371412 _parent._sessionStorage .Set (sessionId,
372413 { clientId, appId, keySystem });
@@ -380,7 +421,7 @@ namespace Plugin {
380421 {
381422 auto session = _parent._sessionStorage .Get (sessionId);
382423 if (!session.IsSet ()) {
383- return Core::ERROR_ILLEGAL_STATE; // No such session
424+ return NoSuchSession;
384425 }
385426
386427 uint32_t result;
@@ -406,14 +447,12 @@ namespace Plugin {
406447 {
407448 auto session = _parent._sessionStorage .Get (sessionId);
408449 if (!session.IsSet ()) {
409- return Core::ERROR_ILLEGAL_STATE; // No such session
450+ return NoSuchSession;
410451 }
411452
412453 uint32_t result;
413- Core::JSON::String jsonString;
414- jsonString.FromString (initData);
415454 JsonObject out;
416- out.FromString (jsonString );
455+ out.FromString (initData );
417456 out[" clientId" ] = session.Value ().ClientId ;
418457 out[" sessionId" ] = sessionId;
419458 out[" keySystem" ] = Core::JSON::EnumType<KeySystem>(
@@ -426,11 +465,15 @@ namespace Plugin {
426465 OpenSessionTimeout, _T (" updatePlaybackSession" ), out, in);
427466 if (result == Core::ERROR_NONE) {
428467 if (!in[" success" ].Boolean ()) {
429- result = Core::ERROR_GENERAL;
468+ auto context = in[" secManagerResultContext" ].Object ();
469+ auto status = SecManagerStatus (
470+ context[" class" ].Number (),
471+ context[" reason" ].Number ());
472+ result = status.IsSet ()
473+ ? status.Value ()
474+ : Core::ERROR_GENERAL;
430475 } else {
431- string inStr;
432- in.ToString (inStr);
433- response = Core::ToQuotedString (' \" ' , inStr);
476+ in.ToString (response);
434477 }
435478 }
436479 return result;
@@ -441,7 +484,7 @@ namespace Plugin {
441484 {
442485 auto session = _parent._sessionStorage .Get (sessionId);
443486 if (!session.IsSet ()) {
444- return Core::ERROR_ILLEGAL_STATE; // No such session
487+ return NoSuchSession;
445488 }
446489
447490 uint32_t result;
@@ -453,7 +496,13 @@ namespace Plugin {
453496 ClosePlaybackSessionParams, JsonObject>(
454497 Timeout, _T (" closePlaybackSession" ), out, in);
455498 if ((result == Core::ERROR_NONE) && !in[" success" ].Boolean ()) {
456- result = Core::ERROR_GENERAL;
499+ auto context = in[" secManagerResultContext" ].Object ();
500+ auto status = SecManagerStatus (
501+ context[" class" ].Number (),
502+ context[" reason" ].Number ());
503+ result = status.IsSet ()
504+ ? status.Value ()
505+ : Core::ERROR_GENERAL;
457506 }
458507 return result;
459508 }
@@ -742,7 +791,7 @@ namespace Plugin {
742791 WatermarkStatusChanged (
743792 watermark.Value ().SessionId ,
744793 session.Value ().AppId ,
745- { State::FAILED, 20001 });
794+ { State::FAILED, WatermarkRenderFailed });
746795 }
747796 })
748797 == Core::ERROR_NONE);
0 commit comments