Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

PlantUML Macro
formatSVG
titleCreate MKS - Cobalt/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Cobalt
participant Starboard
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Cobalt       ->  Starboard:     SbDrmGenerateSessionUpdateRequest(media_keys_handle,\n\t\tticket, init_data_type, iv)
Starboard    ->  ocdmProxy:     opencdm_construct_session(media_keys_handle, init_data_type, iv)

ocdmProxy    ->  rialtoClient:  createKeySession(media_keys_handle, sessionType=TEMPORARY, client, isLDL=false)
rialtoClient ->  rialtoServer:  createKeySession(media_keys_handle, type, isLDL)
rialtoServer ->  rialtoServer:  generate unique key_session_id and create local key session object
rialtoServer --> rialtoClient:  status, key_session_id
rialtoClient --> ocdmProxy:     status, key_session_id

ocdmProxy    ->  rialtoClient:  generateRequest(key_session_id, init_data_type, init_data)
rialtoClient ->  rialtoServer:  generateRequest(key_session_id, init_data_type, init_data)
activate rialtoServer

opt ocdm_session not yet created for this key session
rialtoServer ->  Ocdm:          opencdm_construct_session(media_key_system, Temporary, iv, CDMData=NULL)
Ocdm         --> rialtoServer:  status, ocdm_key_session
end

rialtoServer --> rialtoClient:  status
rialtoClient --> ocdmProxy:     status
ocdmProxy    --> Starboard:     status, session_handle
Starboard    --> Cobalt:        

opt media_keys.key_system == "com.netflix.playready" && no errors

note over rialtoServer, Ocdm: For Netflix no errors

Ocdm         -/  rialtoServer:  process_challenge_callback(ocdm_key_session, url, challenge) won't be received, Rialto must call\nopencdm_session_get_challenge_data() to get the challenge then call\nonLicenseRequest() with it
rialtoServer ->  Ocdm:          opencdm_session_get_challenge_data(ocdm_session, is_LDL)
Ocdm         --> rialtoServer:  challenge
rialtoServer -/  rialtoClient:
note left: Callback automatically occurs after opencdm_construct_session() for non-Netflix key system
rialtoServer -/  rialtoClient:  onLicenseRequest(key_session_id, challenge, url)
rialtoClient -/  ocdmProxy:     onLicenseRequest(key_session_id, challenge, url="")
deactivate rialtoServer
rialtoClientocdmProxy    -/  ocdmProxyStarboard:     onLicenseRequest(key_process_challenge_callback(session_idhandle, challengeurl, urlchallenge)

else media_keys.key_system != "com.netflix.playready" && no errors

OcdmStarboard    -/  Cobalt:         -/  rialtoServer:  process_challenge_callback(ocdm_key_session, url, challenge)
note left: Callback automatically occurs after opencdm_construct_session() for non-Netflix key system
rialtoServer -/  rialtoClient:  onLicenseRequest(key_session_SbDrmSessionUpdateRequestFunc(media_keys_handle, context,\n\t\tticket, kSbDrmStatusSuccess,\n\t\tkSbDrmSessionRequestTypeLicenseRequest,\n\t\tNULL, session_id, challenge, url)

rialtoClientelse -/If generateRequest() ocdmProxy:fails at any point  onLicenseRequest(key_session_id, challenge, url)
ensure error callback is made (not showing all cases to keep diagram simple)

opt Server error
rialtoServer --> rialtoClient:  status!=OK
end
rialtoClient --> ocdmProxy:     status!=OK
ocdmProxy    -/  Starboard:     process_challenge_callback(session_handle, url, challengeNULL)
Starboard    -/  Cobalt:        SbDrmSessionUpdateRequestFunc(media_keys_handle, context,ticket,\n\t\tticket, kSbDrmStatusSuccess,\n\t\tkSbDrmSessionRequestTypeLicenseRequest,\n\t\tNULL, session_id, challenge, urltUnknownError, RequestTypeLicenseRequest)

else If generateRequest() fails at any point ensure error callback is made (not showing all cases to keep diagram simple)

opt Server error
rialtoServer --> rialtoClient:  status!=OK
end
rialtoClient --> ocdmProxy:     status!=OK
ocdmProxy    -/  Starboard:     process_challenge_callback(session_handle, url, NULL)
Starboard    -/  Cobalt:        SbDrmSessionUpdateRequestFunc(ticket,\n\t\tUnknownError, RequestTypeLicenseRequest)

end

note across: Rialto API follows EME/libNova APIs which put IV in generateRequest which doesn't map directly to OCDM/Fusion so some complexity in here but as this model is proven retain it

@enduml

Create - Netflix/native Rialto

end

note across: Rialto API follows EME/libRialtoClient APIs which put IV in generateRequest which doesn't map directly to OCDM/Fusion so some complexity in here but as this model is proven retain it

@enduml

Create - Netflix/OCDM

PlantUML Macro
formatSVG
titleCreate MKS - Netflix/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Netflix       ->  DPI:     createDrmSession(media_keys, content_id, license_type, drm_header)
DPI    ->  ocdmProxy:     opencdm_construct_session(media_keys_handle, init_data_type, iv)
ocdmProxy    ->  ocdmProxy:  Create internal session object
ocdmProxy    ->  DPI:  session_handle

DPI -> ocdmProxy: opencdm_session_get_challenge_data(session, challenge_buffer, challenge_size, is_ldl)
ocdmProxy
PlantUML Macro
formatSVG
titleCreate MKS - Netflix/native Rialto
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
end box

Netflix      ->  DPIrialtoClient:  createKeySession(media_keys_handle, session_type=TEMPORARY, client, is_ldl)
rialtoClient ->  rialtoServer:   createDrmSessioncreateKeySession(media_keys, content_idhandle, license_type, drmis_headerldl)
DPIrialtoServer ->  rialtoServer:  generate     ->  DPI:           Create DPI unique key_session_id and create local key session object
DPIrialtoServer --> rialtoClient:  status,      ->  DPI:key_session_id
rialtoClient --> ocdmProxy:     status, key_session_id

ocdmProxy    ->  rialtoClient: Store contentgenerateRequest(key_session_id, licenseinit_data_type, &\ndrm_header in session object
DPI          --> Netflix:       session_handle
Netflix      ->  DPIinit_data)
rialtoClient ->  rialtoServer:  generateRequest(key_session_id, init_data_type, init_data)
activate rialtoServer

opt ocdm_session not yet created for this key session
rialtoServer ->  Ocdm:           getChallengeData(is_LDL)
DPI   opencdm_construct_session(media_key_system, Temporary, iv, CDMData=NULL)
Ocdm       ->  rialtoClient:  createKeySession(media_keys_handle, session_type=TEMPORARY, is_LDL)
rialtoClient   -->  rialtoServer:  createKeySession(media_keys_handlestatus, session_type, is_LDL)ocdm_key_session
end

note over rialtoServer, Ocdm: For As createKeySessionNetflix process_challenge_callback() inwon't Cobaltbe diagram above
rialtoServer --> rialtoClient:  status, key_session_id
rialtoClient --> DPI:           status, key_session_id

DPI    received, Rialto must call\nopencdm_session_get_challenge_data() to get the challenge then call\nonLicenseRequest() with it
rialtoServer ->  Ocdm:      ->  rialtoClient:  generateRequest(keyopencdm_session_id, initget_challenge_data(ocdm_type=DRMHEADERsession, init_data=drm_header)
rialtoClient ->  rialtoServer:  generateRequestis_LDL)
Ocdm         --> rialtoServer:  challenge
rialtoServer -/  rialtoClient:  onLicenseRequest(key_session_id, init_data_typechallenge, init_dataurl="")
notedeactivate over rialtoServer:As generateRequest() in Cobalt diagram above,\nsee note that opendm_session_get_challenge_data()

rialtoClient -/  ocdmProxy:     onLicenseRequest(key_session_id, challenge, url)

rialtoServer --> rialtoClient:  status
rialtoClient --> DPIocdmProxy:     status
ocdmProxy      status
note over DPI: getChallengeData() must block until onLicenseRequest() callback received
rialtoServer -/  rialtoClient:  onLicenseRequest(key_session_id, challenge, url)
rialtoClient -/  DPI:           onLicenseRequest(key_session_id, challenge, url)
DPI          --> Netflix:       status, challenge


@enduml

...

--> DPI:     status, challenge_buffer
DPI    --> Netflix:

@enduml


Create - Netflix/native Rialto

PlantUML Macro
formatSVG
titleUpdate Create MKS - CobaltNetflix/OCDMnative Rialto
@startuml

autonumber

box "Container" #LightGreen
participant CobaltNetflix
participant Starboard
participant ocdmProxyDPI
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

CobaltNetflix       ->  StarboardDPI:        SbDrmUpdateSession   createDrmSession(media_keys_handle, ticketcontent_id, keylicense_type, sessiondrm_idheader)
StarboardDPI          ->  ocdmProxyDPI:     opencdm_session_update(session_id, key)
ocdmProxy    -> Create ocdmProxy:DPI session object
DPI   Lookup MediaKeys object for session_id
ocdmProxy    ->  rialtoClientDPI:  updateKeySession(media_keys_handle, session_id, key)
rialtoClient ->  rialtoServer:  updateKeySession(media_keys_handle, session        Store content_id, key)

opt media_keys.key_system == "com.netflix.playready"
rialtoServer ->  Ocdm:license_type &\ndrm_header in session object
DPI          --> Netflix:       session_handle
Netflix     opencdm_session_store_license_data(session_id, license_data=key)
Ocdm   ->  DPI:       --> rialtoServer:  status, secure_stop_id
note left: Secure stop ID ignored as\nnot supported by Rialto
else
rialtoServergetChallengeData(is_LDL)
DPI          ->  OcdmrialtoClient:  createKeySession(media_keys_handle, session_type=TEMPORARY, is_LDL)
rialtoClient ->  rialtoServer:   opencdm_session_update(session_id, key)
Ocdm         --> rialtoServer:  status
end

createKeySession(media_keys_handle, session_type, is_LDL)
note over rialtoServer: As createKeySession() in Cobalt diagram above
rialtoServer --> rialtoClient:  status, key_session_id
rialtoClient --> ocdmProxyDPI:      status

opt update successful

ocdmProxy    --> Starboard:status, key_session_id

DPI      status=OK
Starboard    --> Cobalt rialtoClient:  generateRequest(key_session_id,      status=OK

loop For each key updated
Ocdm         -/init_data_type=DRMHEADER, init_data=drm_header)
rialtoClient ->  rialtoServer:  OnKeyUpdatedgenerateRequest(key_session_id, init_data_type, keyinit_iddata)
rialtoServernote -> over rialtoServer:As  Store updated key_id
end
OcdmgenerateRequest() in Cobalt diagram above,\nsee note that opendm_session_get_challenge_data()
rialtoServer --> rialtoClient:  status
rialtoClient --> DPI:           -/status
note over rialtoServer:  OnAllKeysUpdated(session_id)DPI: getChallengeData() must block until onLicenseRequest() callback received
rialtoServer -/  rialtoClient:  onKeyStatusesChangedonLicenseRequest(key_session_id, key_statuseschallenge, url)
rialtoClient -/  ocdmProxyDPI:     onKeyStatusesChanged(session_id, key_statuses)
loop For each key updated
ocdmProxy    -/  Starboard:     OnKeyUpdated(onLicenseRequest(key_session_id, challenge, key_idurl)
end
ocdmProxy DPI   -/  Starboard:     OnAllKeysUpdated(session_id)
Starboard    -/  Cobalt--> Netflix:       status, challenge


@enduml


Update - Cobalt/OCDM


PlantUML Macro
formatSVG
titleUpdate MKS - Cobalt/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Cobalt
participant Starboard
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

Cobalt       ->  Starboard SbDrmSessionUpdatedFunc(media_keys_handle, context, ticket, kSbDrmStatusSuccess, nullptr, session_id);
Starboard    -/  Cobalt:        SbDrmSessionKeyStatusesChangedFunc(media_keys_handle, context, session_id, key_ids, key_statuses);

else update failed

ocdmProxy    --> Starboard:     status=NOK
Starboard    -/  Cobalt:        SbDrmSessionUpdatedFuncSbDrmUpdateSession(media_keys_handle, context, ticket, kSbDrmStatusUnknownErrorkey, nullptr, session_id);
Starboard    -->  CobaltocdmProxy:     opencdm_session_update(session_id, key)
ocdmProxy   status=NOK

end

@enduml

Update - Netflix/native Rialto

PlantUML Macro
formatSVG
titleUpdate MKS - Netflix/native Rialto
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

Netflix      ->  DPI:           storeLicenseData(session_id, license_data)
DPI          ->  DPI ->  ocdmProxy:     Lookup MediaKeys object for session_id
ocdmProxy    ->  rialtoClient:  updateSession(media_keys_handle, session_id, key)
rialtoClient ->  rialtoServer:  updateSession(media_keys_handle, session_id, key)

opt media_keys.key_system == "com.netflix.playready"
rialtoServer ->  Ocdm:           Lookup MediaKeys object for opencdm_session_store_license_data(session_id
DPI, license_data=key)
Ocdm          -->  rialtoClientrialtoServer:  updateKeySession(media_keys_handlestatus, sessionsecure_stop_id, license_data)
rialtoClient ->  rialtoServer:  updateKeySession(media_keys_handle, 
note left: Secure stop ID ignored as\nnot supported by Rialto
else
rialtoServer ->  Ocdm:          opencdm_session_update(session_id, license_datakey)

noteOcdm   over rialtoServer, Ocdm: As shown for updateKeySession in previous diagram--> rialtoServer:  status
end

rialtoServer --> rialtoClient:  status
rialtoClient --> DPIocdmProxy:     status

opt update successful

ocdmProxy    status
DPI --> Starboard:     status=OK
Starboard    --> NetflixCobalt:        status=OK

note across: Key update messages will be generated as shown in previous diagram

@enduml

License Renewal - Cobalt/OCDM

PlantUML Macro
formatSVG
titleLicense Renewal - Cobalt/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Cobalt
participant Starboard
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

loop For each key updated
Ocdm         -/  rialtoServer:  OnKeyUpdated(session_id, key_id)
rialtoServer ->  rialtoServer:  Store updated key_id
end
Ocdm         -/  rialtoServer:   process_challenge_callbackOnAllKeysUpdated(session_id, user_data, license_renewal_message, url)
rialtoServer -/  rialtoClient:   onLicenseRenewalonKeyStatusesChanged(session_id, licensekey_renewal_messagestatuses)
rialtoClient -/  ocdmProxy:      onLicenseRenewalonKeyStatusesChanged(session_id, licensekey_renewal_messagestatuses)
loop For each key updated
ocdmProxy    -/  Starboard:      process_challenge_callbackOnKeyUpdated(session_id, user_data, license_renewal_message, url="")
Starboardkey_id)
end
ocdmProxy    -/  Starboard:      Extract request_type & request_content from license_renewal_message
note left: Use user_data to determine media_keys etcOnAllKeysUpdated(session_id)
Starboard    -/  Cobalt:        SbDrmSessionUpdatedFunc(media_keys_handle, context, ticket, kSbDrmStatusSuccess, nullptr, session_id);
Starboard    -/  Cobalt:         SbDrmSessionUpdateRequestFuncSbDrmSessionKeyStatusesChangedFunc(media_keys, request_status=kSbDrmStatusSuccess_handle, request_typecontext, session_id, requestkey_contentids, urlkey_statuses);

noteelse across: App then should fetch the updated license and call SbDrmUpdateSession() in the same way as for the initial license

@enduml

...

update failed

ocdmProxy    --> Starboard:     status=NOK
Starboard    -/  Cobalt:        SbDrmSessionUpdatedFunc(media_keys_handle, context, ticket, kSbDrmStatusUnknownError, nullptr, session_id);
Starboard    --> Cobalt:        status=NOK

end

@enduml


Update - Netflix/native Rialto


PlantUML Macro
formatSVG
titleLicense Renewal Update MKS - Netflix/native Rialto
@startuml

autonumber

box "Container" #LightGreen
participant ClientNetflix
participant DPI
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


OcdmNetflix      ->   -/ rialtoServerDPI:   process_challenge_callback(session_id, user_data, license_renewal_message, url)
rialtoServer -/ rialtoClient:   onLicenseRenewalstoreLicenseData(session_id, license_renewal_messagedata)
rialtoClientDPI          -/> Client DPI:           Lookup MediaKeys object for onLicenseRenewal(session_id, license_renewal_message)

note across: App then should fetch the updated license and call updateKeySession() in the same way as for the initial license

@enduml

Key Session Error - TODO

Not supported in avbus-poc or libNova - not required? If need, it follows a same pattern as License Renewal above and we would need to add onError() method in IMediaKeysClient interface.

Select Key ID - Netflix/native Rialto


DPI          ->  rialtoClient:  updateKeySession(media_keys_handle, session_id, license_data)
rialtoClient ->  rialtoServer:  updateKeySession(media_keys_handle, session_id, license_data)

note over rialtoServer, Ocdm: As shown for updateKeySession in previous diagram

rialtoServer --> rialtoClient:  status
rialtoClient --> DPI:           status
DPI          --> Netflix:       status

note across: Key update messages will be generated as shown in previous diagram

@enduml


License Renewal - Cobalt/OCDM

PlantUML Macro
formatSVG
titleLicense Renewal - Cobalt/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Cobalt
participant Starboard
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Ocdm         -/ rialtoServer:   process_challenge_callback(session_id, user_data, license_renewal_message, url)
rialtoServer -/ rialtoClient:   onLicenseRenewal(session_id, license_renewal_message)
rialtoClient -/ ocdmProxy:      onLicenseRenewal(session_id, license_renewal_message)
ocdmProxy    -/ Starboard:      process_challenge_callback(session_id, user_data, license_renewal_message, url="")
Starboard    -/ Starboard:      Extract request_type & request_content from license_renewal_message
note left: Use user_data to determine media_keys etc
Starboard    -/ Cobalt:         SbDrmSessionUpdateRequestFunc(media_keys, request_status=kSbDrmStatusSuccess, request_type, session_id, request_content, url)

note across: App then should fetch the updated license and call SbDrmUpdateSession() in the same way as for the initial license

@enduml


License Renewal - native Rialto

PlantUML Macro
formatSVG
titleLicense Renewal - native Rialto
@startuml

autonumber

box "Container" #LightGreen
participant Client
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Ocdm         -/ rialtoServer:   process_challenge_callback(session_id, user_data, license_renewal_message, url)
rialtoServer -/ rialtoClient:   onLicenseRenewal(session_id, license_renewal_message)
rialtoClient -/ Client:         onLicenseRenewal(session_id, license_renewal_message)

note across: App then should fetch the updated license and call updateKeySession() in the same way as for the initial license

@enduml



Key Session Error - TODO

Not supported in avbus-poc or libNova - not required? If need, it follows a same pattern as License Renewal above and we would need to add onError() method in IMediaKeysClient interface.


Select Key ID - Netflix/native Rialto


PlantUML Macro
formatSVG
titleSelect Key ID
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box


Netflix      ->  DPI:           initDecryptContextByKid(session_id, key_id)
DPI          ->  DPI:           Lookup MediaKeys object for session_id
DPI          ->  rialtoClient:  selectKeyId(media_keys_handle, session_id, key_id)
rialtoClient ->  rialtoClient:  Store session_id & key_id
note right
The key_id should be stored with the associated session_id in
a map/vector. This key_id will be retrieved later and stored in
the metadata when the client calls addSegment() call. When a
key session is destroyed the relevant entry in the map should
be removed. See Netflix to Rialto Client diagram.
end note
rialtoClient --> DPI:           status
DPI          --> Netflix:       status

@enduml 


Contains Key - Netflix/native Rialto


PlantUML Macro
formatSVG
titleContains Key
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Netflix      ->  DPI:           hasLicense(session_id, key_id)
DPI          ->  DPI:           Lookup MediaKeys object for session_id
DPI          ->  rialtoClient:  containsKey(media_keys_handle, session_id, key_id)
rialtoClient ->  rialtoServer:  containsKey(media_keys_handle, session_id, key_id)
rialtoServer ->  Ocdm:          opencdm_session_has_key_id(session, key_id)



Ocdm         --> rialtoServer:  result
rialtoServer --> rialtoClient:  result
rialtoClient --> 
PlantUML Macro
formatSVG
titleSelect Key ID
@startuml

autonumber

box "Container" #LightGreen
participant Netflix
participant DPI
participant rialtoClient
end box


Netflix      ->  DPI:           initDecryptContextByKid(session_id, key_id)result
DPI            -->  DPINetflix:       result


@enduml



Remove/OCDM

Note that Remove is not required by Cobalt so we do not yet need to implement this API.


PlantUML Macro
formatSVG
titleRemove MKS
@startuml

autonumber

box "Container" #LightGreen
participant  Lookup MediaKeys object for session_id
DPI   Client
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Client       ->  rialtoClientocdmProxy:  selectKeyId(media_keys_handle, session_id, key   opencdm_session_remove(session_id)
rialtoClientocdmProxy ->  rialtoClient: -> Store session_id & key_id
note right
The key_id should be stored with the associated ocdmProxy:     Lookup MediaKeys object for session_id in
aocdmProxy map/vector. This key_id will-> be retrievedrialtoClient: later and stored in
the metadata when the client calls addSegment() call. When a
key session is destroyed the relevant entry in the map should
be removed. See Netflix to Rialto Client diagram.
end note
rialtoClient removeKeySession(media_keys_handle, session_id)
rialtoClient ->  rialtoServer:  removeKeySession(media_keys_handle, session_id)
rialtoServer ->  Ocdm:          opencdm_session_remove(session_id)
Ocdm         --> DPIrialtoServer:  status
rialtoServer       --> rialtoClient:  status
DPI rialtoClient --> ocdmProxy:     status
ocdmProxy    --> NetflixClient:        status

@enduml 

...


Load/OCDM

Note that Load is not required by Cobalt so we do not yet need to implement this API.


PlantUML Macro
formatSVG
titleContains KeyLoad MKS
@startuml

autonumber

box "Container" #LightGreen
participant NetflixClient
participant DPIocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Netflix  Client       ->  ocdmProxy:     opencdm_session_load(session_id)
ocdmProxy    ->  DPI:   ocdmProxy:     Lookup MediaKeys object for session_id
ocdmProxy    ->  rialtoClient:  hasLicenseloadKeySession(sessionmedia_keys_idhandle, keysession_id)
DPIrialtoClient  ->   rialtoServer:  loadKeySession(media_keys_handle, session_id)
rialtoServer  ->   DPIOcdm:           Lookup MediaKeys object for opencdm_session_load(session_id)
DPIOcdm          --> rialtoServer: rialtoClient:  containsKey(media_keys_handle, session_id, key_id)status
rialtoServer --> rialtoClient:  status
rialtoClient --> ocdmProxy: rialtoServer:  containsKey(media_keys_handle, session_id, key_id)
rialtoServer ->  Ocdm status
ocdmProxy    --> Client:          opencdm_session_has_key_id(session, key_id)



Ocdm         --> rialtoServer:  result
rialtoServer --> rialtoClient:  result
rialtoClient --> DPIstatus

@enduml


Close - Cobalt/OCDM


PlantUML Macro
formatSVG
title"Destroy" MKS - Cobalt/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant Cobalt
participant Starboard
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Cobalt       ->  Starboard:     SbDrmCloseSession(media_keys_handle, session_id)
Starboard    -> result
DPI ocdmProxy:     opencdm_session_close(session_id)
ocdmProxy    --> Netflix ocdmProxy:     Lookup MediaKeys object for result


@enduml

Remove -  native Rialto

Note that Remove is not required by Cobalt so we do not yet need to implement this API.

PlantUML Macro
formatSVG
titleRemove MKS
@startuml

autonumber

box "Container" #LightGreen
participant Client
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Client       ->  ocdmProxy:     opencdm_session_remove(session_id)
ocdmProxy    ->  ocdmProxysession_id
ocdmProxy    ->  rialtoClient:  closeKeySession(media_keys_handle, session_id)
rialtoClient ->  rialtoServer:  closeKeySession(media_keys_handle, session_id)

opt No buffered media segments that need this session for decryption

opt media_keys.key_system == "com.netflix.playready"
rialtoServer ->  Ocdm:     Lookup  MediaKeys object for opencdm_session_cancel_challenge_data(session_id)
ocdmProxyOcdm    ->  rialtoClient:  removeKeySession(media_keys_handle, session_id)
rialtoClient -->  rialtoServer:  removeKeySession(media_keys_handle, session_id)  status
rialtoServer ->  Ocdm:          opencdm_session_removeclean_decrypt_context(session_id)
Ocdm         --> rialtoServer:  status
else !Netflix
rialtoServer --> rialtoClient Ocdm:  status
rialtoClient --> ocdmProxy:        status
ocdmProxy    --> Client:        status

@enduml

Load -  native Rialto

Note that Load is not required by Cobalt so we do not yet need to implement this API.

PlantUML Macro
formatSVG
titleLoad MKS
@startuml

autonumber

box "Container" #LightGreen
participant Client
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Client       ->  ocdmProxy:opencdm_session_close(session_id)
note right: TODO: Current code only calls for !Netflix\nbut maybe should we always call it?
Ocdm         --> rialtoServer:  status
end

rialtoServer ->  Ocdm:          opencdm_destruct_session_load(session_id)
ocdmProxyOcdm         --> rialtoServer:  status

else  ocdmProxy:     Lookup MediaKeys object for session_id
ocdmProxy    ->  rialtoClient:  loadKeySession(media_keys_handle, session_id)
rialtoClient ->  rialtoServer:  loadKeySession(media_keys_handle, session_id)
rialtoServer ->  Ocdm:          opencdm_session_load(session_id)
Ocdm     Media segments are buffered that need this media key sessions
note over rialtoServer, Ocdm
The above sequence must be deferred until no media segments
are buffered that reference this media key session otherwise
their decryption will fail. rialtoServer must track these
references, details not shown for brevity.
end note
end

rialtoServer --> rialtoClient:  status
rialtoClient --> ocdmProxy:     status
ocdmProxy    --> rialtoServerStarboard:     status
rialtoServerStarboard    -->/  rialtoClientCobalt:  status
rialtoClient --> ocdmProxy:      SbDrmSessionClosedFunc(media_keys_handle,  status
ocdmProxycontext, session_id)
Starboard    --> ClientCobalt:        status

@enduml


Close -

...

Netflix/

...

native Rialto

PlantUML Macro
formatSVG
title"Destroy" MKS - Cobalt/OCDMClose - Netflix/native Rialto
@startuml

autonumber

box "Container" #LightGreen
participant CobaltNetflix
participant StarboardDPI
participant ocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


Cobalt box

Netflix      ->  DPI:           ~IDrmSession()
DPI          ->  DPI:           Lookup MediaKeys object for session_id
DPI          ->  StarboardrialtoClient:  closeKeySession(media_keys_handle, session_id)
rialtoClient ->  SbDrmCloseSessionrialtoServer:  closeKeySession(media_keys_handle, session_id)
Starboard
note over rialtoServer, Ocdm: Same sequence as closeKeySession above

rialtoServer --> rialtoClient:  status
rialtoClient --> DPI:          -> status
DPI ocdmProxy:     opencdm_session_close(session_id)
ocdmProxy    -->  ocdmProxy:     Lookup MediaKeys object for session_id
ocdmProxy  Netflix:

@enduml

Set DRM Header

PlantUML Macro
formatSVG
titleSet DRM Header
@startuml

autonumber

box "Container" #LightGreen
participant Application
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

Application  ->  rialtoClient:  closeKeySession setDrmHeader(media_keys_handle, session_id, drmHeader)
rialtoClient ->  rialtoServer:  closeKeySession setDrmHeader(media_keys_handle, session_id)

opt media_keys.key_system == "com.netflix.playready"
, drmHeader)
rialtoServer ->  Ocdm:             opencdm   opencdm_session_cancelset_challengedrm_dataheader(session_idhandle, drmHeader)
Ocdm         --> rialtoServer:  status
rialtoServer --> rialtoClient:  status
rialtoClient --> rialtoServerApplication :  status
rialtoServer 
@enduml

Get Last DRM Error

PlantUML Macro
formatSVG
titleGet Last DRM Error
@startuml

autonumber

box "Container" #LightGreen
participant Application
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

Application  ->  rialtoClient:  getLastDrmError(media_keys_handle, ->  Ocdm:          opencdm_session_clean_decrypt_context(session_id)
Ocdm         --rialtoClient ->  rialtoServer:  status
else !Netflix getLastDrmError(media_keys_handle, session_id, drmHeader)
rialtoServer ->  Ocdm:             opencdm   opencdm_session_system_closeerror(session_idhandle)
note right: TODO: Current code only calls for !Netflix\nbut maybe should we always call it?
Ocdm         --> rialtoServer:  status
end

rialtoServer ->  Ocdm:          opencdm_destruct_session(session_id)
Ocdm         --> rialtoServer:  status

rialtoServer --> rialtoClient:  status
rialtoClient --> ocdmProxy:     status
ocdmProxy    --> Starboard:     status
Starboard    -/  Cobalt:        SbDrmSessionClosedFunc(media_keys_handle, context, session_id)
Starboard    --> Cobalt:        status

@enduml

...

Ocdm         --> rialtoServer:  status, errorCode
rialtoServer --> rialtoClient:  status, errorCode
rialtoClient --> Application :  status, errorCode

@enduml

Get CDM Key Session Id

PlantUML Macro
formatSVG
titleGet CDM Key Session Id
@startuml

autonumber

box "Container" #LightGreen
participant Application
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box

Application  ->  rialtoClient:  getCdmKeySessionId(media_keys_handle, session_id)
rialtoClient ->  rialtoServer:  getCdmKeySessionId(media_keys_handle, session_id)
rialtoServer ->  Ocdm:          opencdm_session_id(session_handle)
Ocdm         --> rialtoServer:  status, cdmSessionId
rialtoServer --> rialtoClient:  status, cdmSessionId
rialtoClient --> Application :  status, cdmSessionId

@enduml

Release/OCDM

PlantUML Macro
formatSVG
titleClose - Netflix/native RialtoRelease/OCDM
@startuml

autonumber

box "Container" #LightGreen
participant NetflixClient
participant DPIocdmProxy
participant rialtoClient
end box

box "Platform" #LightBlue
participant rialtoServer
participant Ocdm
end box


NetflixClient       ->  DPIocdmProxy:           ~IDrmSession()
DPI    opencdm_destruct_session(session_id)
ocdmProxy      ->  DPI:      ocdmProxy:      Lookup MediaKeys object for session_id
DPI       object for session_id
ocdmProxy    ->  rialtoClient:  closeKeySessionreleaseKeySession(media_keys_handle, session_id)
rialtoClient ->  rialtoServer:  closeKeySessionreleaseKeySession(media_keys_handle, session_id)

noterialtoServer over-> rialtoServer, Ocdm: Same      sequence as closeKeySession above
 opencdm_destruct_session(session_id)
Ocdm         --> rialtoServer:  status
rialtoServer --> rialtoClient:  status
rialtoClient --> DPIocdmProxy:     status
ocdmProxy      status
DPI--> Client:          --> Netflix:status

@enduml