Update SimulCrypt ECMG on injecting entitlement keys
This commit is contained in:
@@ -29,7 +29,7 @@ constexpr char kTestEcmgChannelSetup[] = {
|
|||||||
constexpr char kTestEcmgChannelSetupWithPrivateParameters[] = {
|
constexpr char kTestEcmgChannelSetupWithPrivateParameters[] = {
|
||||||
'\x03', // protocol_version
|
'\x03', // protocol_version
|
||||||
'\x00', '\x01', // message_type - Channel_setup
|
'\x00', '\x01', // message_type - Channel_setup
|
||||||
'\x00', '\x8c', // message_length
|
'\x00', '\x1e', // message_length
|
||||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'\x00', '\x01', // parameter_value
|
'\x00', '\x01', // parameter_value
|
||||||
@@ -42,29 +42,7 @@ constexpr char kTestEcmgChannelSetupWithPrivateParameters[] = {
|
|||||||
'\x80', '\x01', // parameter_type - CRYPTO_MODE
|
'\x80', '\x01', // parameter_type - CRYPTO_MODE
|
||||||
'\x00', '\x07', // parameter_length
|
'\x00', '\x07', // parameter_length
|
||||||
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
||||||
'\x80', '\x02', // parameter_type - TRACK_TYPES
|
};
|
||||||
'\x00', '\x02', // parameter_length
|
|
||||||
'S', 'D', // parameter_value
|
|
||||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
|
||||||
'\x00', '\x30', // parameter_length
|
|
||||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
|
||||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
|
||||||
'\x00', '\x30', // parameter_length
|
|
||||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
|
||||||
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68'};
|
|
||||||
|
|
||||||
constexpr char kTestEcmgChannelTest[] = {
|
constexpr char kTestEcmgChannelTest[] = {
|
||||||
'\x03', // protocol_version
|
'\x03', // protocol_version
|
||||||
@@ -126,7 +104,7 @@ constexpr char kTestEcmgChannelStatus[] = {
|
|||||||
constexpr char kTestEcmgStreamSetupWithPrivateParameters[] = {
|
constexpr char kTestEcmgStreamSetupWithPrivateParameters[] = {
|
||||||
'\x03', // protocol_version
|
'\x03', // protocol_version
|
||||||
'\x01', '\x01', // message_type - Stream_setup
|
'\x01', '\x01', // message_type - Stream_setup
|
||||||
'\x00', '\x46', // message_length
|
'\x00', '\xae', // message_length
|
||||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'\x00', '\x01', // parameter_value
|
'\x00', '\x01', // parameter_value
|
||||||
@@ -139,17 +117,37 @@ constexpr char kTestEcmgStreamSetupWithPrivateParameters[] = {
|
|||||||
'\x00', '\x10', // parameter_type - nominal_CP_duration
|
'\x00', '\x10', // parameter_type - nominal_CP_duration
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'\x00', '\x64', // parameter_value
|
'\x00', '\x64', // parameter_value
|
||||||
'\x80', '\x03', // parameter_type - STREAM_TRACK_TYPE
|
'\x80', '\x02', // parameter_type - STREAM_TRACK_TYPE
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'S', 'D', // parameter_value
|
'S', 'D', // parameter_value
|
||||||
'\x80', '\x04', // parameter_type - CONTENT_IV
|
'\x80', '\x03', // parameter_type - CONTENT_IV
|
||||||
'\x00', '\x10', // parameter_length
|
'\x00', '\x10', // parameter_length
|
||||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
|
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', //
|
||||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f',
|
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', //
|
||||||
'\x80', '\x04', // parameter_type - CONTENT_IV
|
'\x80', '\x03', // parameter_type - CONTENT_IV
|
||||||
'\x00', '\x10', // parameter_length
|
'\x00', '\x10', // parameter_length
|
||||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
|
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f'};
|
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||||
|
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||||
|
'\x00', '\x30', // parameter_length
|
||||||
|
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
|
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||||
|
'\x00', '\x30', // parameter_length
|
||||||
|
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
// parameter_value (continued) - ENTITLEMENT_KEY (32 bytes)
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68'};
|
||||||
|
|
||||||
constexpr char kTestEcmgStreamSetup[] = {
|
constexpr char kTestEcmgStreamSetup[] = {
|
||||||
'\x03', // protocol_version
|
'\x03', // protocol_version
|
||||||
@@ -247,7 +245,7 @@ constexpr char kTestEcmgCwProvision[] = {
|
|||||||
constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
||||||
'\x03', // protocol_version
|
'\x03', // protocol_version
|
||||||
'\x02', '\x01', // message_type - CW_provision
|
'\x02', '\x01', // message_type - CW_provision
|
||||||
'\x00', '\xf4', // message_length
|
'\x00', '\xee', // message_length
|
||||||
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
'\x00', '\x0e', // parameter_type - ECM_channel_id
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'\x00', '\x01', // parameter_value
|
'\x00', '\x01', // parameter_value
|
||||||
@@ -271,28 +269,25 @@ constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
|||||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||||
'\x00', '\x0d', // parameter_type - access_criteria
|
'\x00', '\x0d', // parameter_type - access_criteria
|
||||||
'\x00', '\xac', // parameter_length
|
'\x00', '\xa6', // parameter_length
|
||||||
'\x80', '\x00', // access_criteria parameter_type - AGE_RESTRICTION
|
'\x80', '\x00', // access_criteria parameter_type - AGE_RESTRICTION
|
||||||
'\x00', '\x01', // parameter_length
|
'\x00', '\x01', // parameter_length
|
||||||
'\x00', // parameter_value
|
'\x00', // parameter_value
|
||||||
'\x80', '\x01', // access_criteria parameter_type - CRYPTO_MODE
|
'\x80', '\x01', // access_criteria parameter_type - CRYPTO_MODE
|
||||||
'\x00', '\x07', // parameter_length
|
'\x00', '\x07', // parameter_length
|
||||||
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
'A', 'e', 's', 'S', 'c', 't', 'e', // parameter_value
|
||||||
'\x80', '\x02', // access_criteria parameter_type - TRACK_TYPES
|
'\x80', '\x02', // access_criteria parameter_type - STREAM_TRACK_TYPE
|
||||||
'\x00', '\x02', // parameter_length
|
'\x00', '\x02', // parameter_length
|
||||||
'S', 'D', // parameter_value
|
'S', 'D', // parameter_value
|
||||||
'\x80', '\x03', // access_criteria parameter_type - STREAM_TRACK_TYPE
|
'\x80', '\x03', // access_criteria parameter_type - CONTENT_IV
|
||||||
'\x00', '\x02', // parameter_length
|
|
||||||
'S', 'D', // parameter_value
|
|
||||||
'\x80', '\x04', // access_criteria parameter_type - CONTENT_IV
|
|
||||||
'\x00', '\x10', // parameter_length
|
'\x00', '\x10', // parameter_length
|
||||||
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', //
|
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', //
|
||||||
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', //
|
'\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', //
|
||||||
'\x80', '\x04', // access_criteria parameter_type - CONTENT_IV
|
'\x80', '\x03', // access_criteria parameter_type - CONTENT_IV
|
||||||
'\x00', '\x10', // parameter_length
|
'\x00', '\x10', // parameter_length
|
||||||
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
'\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', //
|
||||||
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
'\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', //
|
||||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||||
'\x00', '\x30', // parameter_length
|
'\x00', '\x30', // parameter_length
|
||||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
@@ -302,7 +297,7 @@ constexpr char kTestEcmgCwProvisionWithAccessCriteria[] = {
|
|||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
'\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', //
|
||||||
'\x80', '\x05', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
'\x80', '\x04', // parameter_type - ENTITLEMENT_ID_KEY_COMBINATION
|
||||||
'\x00', '\x30', // parameter_length
|
'\x00', '\x30', // parameter_length
|
||||||
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
// parameter_value - ENTITLEMENT_ID (16 bytes)
|
||||||
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
'\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', //
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ Status ProcessPrivateParameters(const char* const request, uint16_t param_type,
|
|||||||
params->crypto_mode = std::string(request + *offset, param_length);
|
params->crypto_mode = std::string(request + *offset, param_length);
|
||||||
*offset += param_length;
|
*offset += param_length;
|
||||||
break;
|
break;
|
||||||
case TRACK_TYPES:
|
|
||||||
params->track_types.push_back(
|
|
||||||
std::string(request + *offset, param_length));
|
|
||||||
*offset += param_length;
|
|
||||||
break;
|
|
||||||
case STREAM_TRACK_TYPE:
|
case STREAM_TRACK_TYPE:
|
||||||
params->stream_track_type = std::string(request + *offset, param_length);
|
params->stream_track_type = std::string(request + *offset, param_length);
|
||||||
*offset += param_length;
|
*offset += param_length;
|
||||||
@@ -722,8 +717,7 @@ void EcmgClientHandler::HandleCwProvision(const EcmgParameters& params,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request entitlement keys if they do not exist yet.
|
if (streams_info_.at(params.ecm_stream_id)->ecm == nullptr) {
|
||||||
if (ecm_ == nullptr) {
|
|
||||||
status = CheckAndInitializeEcm(params);
|
status = CheckAndInitializeEcm(params);
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
LOG(ERROR) << status.ToString();
|
LOG(ERROR) << status.ToString();
|
||||||
@@ -758,9 +752,6 @@ Status EcmgClientHandler::UpdateCommonPrivateParameters(
|
|||||||
}
|
}
|
||||||
age_restriction_ = params.age_restriction;
|
age_restriction_ = params.age_restriction;
|
||||||
}
|
}
|
||||||
if (!params.track_types.empty()) {
|
|
||||||
track_types_.assign(params.track_types.begin(), params.track_types.end());
|
|
||||||
}
|
|
||||||
if (!params.content_ivs.empty()) {
|
if (!params.content_ivs.empty()) {
|
||||||
if (params.content_ivs.size() < ecmg_config_->number_of_content_keys) {
|
if (params.content_ivs.size() < ecmg_config_->number_of_content_keys) {
|
||||||
return {error::INVALID_ARGUMENT,
|
return {error::INVALID_ARGUMENT,
|
||||||
@@ -778,10 +769,6 @@ Status EcmgClientHandler::UpdateCommonPrivateParameters(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!params.entitlement_comb.empty()) {
|
|
||||||
entitlement_comb_.assign(params.entitlement_comb.begin(),
|
|
||||||
params.entitlement_comb.end());
|
|
||||||
}
|
|
||||||
return OkStatus();
|
return OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -825,26 +812,29 @@ Status EcmgClientHandler::UpdateStreamPrivateParameters(
|
|||||||
stream_info->content_ivs.assign(params.content_ivs.begin(),
|
stream_info->content_ivs.assign(params.content_ivs.begin(),
|
||||||
params.content_ivs.end());
|
params.content_ivs.end());
|
||||||
}
|
}
|
||||||
|
if (!params.entitlement_comb.empty()) {
|
||||||
|
stream_info->entitlement_comb.assign(params.entitlement_comb.begin(),
|
||||||
|
params.entitlement_comb.end());
|
||||||
|
}
|
||||||
return OkStatus();
|
return OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
Status EcmgClientHandler::CheckAndInitializeEcm(const EcmgParameters& params) {
|
Status EcmgClientHandler::CheckAndInitializeEcm(const EcmgParameters& params) {
|
||||||
DCHECK(ecm_ == nullptr);
|
DCHECK(streams_info_.contains(params.ecm_stream_id));
|
||||||
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
||||||
|
DCHECK(stream_info->ecm == nullptr);
|
||||||
|
|
||||||
if (stream_info->content_ivs.empty() && content_ivs_.empty()) {
|
if (stream_info->content_ivs.empty() && content_ivs_.empty()) {
|
||||||
return {error::NOT_FOUND, "Content iv not specified."};
|
return {error::NOT_FOUND, "Content iv not specified."};
|
||||||
}
|
}
|
||||||
if (track_types_.empty()) {
|
if (stream_info->entitlement_comb.empty()) {
|
||||||
return {error::NOT_FOUND, "Track type not specified."};
|
|
||||||
}
|
|
||||||
if (entitlement_comb_.empty()) {
|
|
||||||
return {error::NOT_FOUND, "Entitlement key id comb not specified."};
|
return {error::NOT_FOUND, "Entitlement key id comb not specified."};
|
||||||
}
|
}
|
||||||
if (entitlement_comb_.size() !=
|
if (stream_info->entitlement_comb.size() !=
|
||||||
track_types_.size() * ecmg_config_->number_of_content_keys) {
|
ecmg_config_->number_of_content_keys) {
|
||||||
return {error::NOT_FOUND,
|
return {error::NOT_FOUND,
|
||||||
"Number of injected entitlement keys must equal to number of "
|
"Number of injected entitlement keys must equal to number of "
|
||||||
"track types * number of content keys per ecm."};
|
"content keys per ecm."};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool key_rotation = ecmg_config_->number_of_content_keys > 1;
|
bool key_rotation = ecmg_config_->number_of_content_keys > 1;
|
||||||
@@ -862,25 +852,26 @@ Status EcmgClientHandler::CheckAndInitializeEcm(const EcmgParameters& params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<EntitlementKeyInfo> entitlements;
|
std::vector<EntitlementKeyInfo> entitlements;
|
||||||
entitlements.reserve(entitlement_comb_.size());
|
entitlements.reserve(stream_info->entitlement_comb.size());
|
||||||
for (size_t i = 0; i < entitlement_comb_.size(); i++) {
|
for (size_t i = 0; i < stream_info->entitlement_comb.size(); i++) {
|
||||||
entitlements.emplace_back();
|
entitlements.emplace_back();
|
||||||
EntitlementKeyInfo* entitlement = &entitlements.back();
|
EntitlementKeyInfo* entitlement = &entitlements.back();
|
||||||
entitlement->track_type = track_types_.at(key_rotation ? i / 2 : i);
|
entitlement->track_type = stream_info->track_type;
|
||||||
entitlement->is_even_key = key_rotation ? i % 2 == 0 : true;
|
entitlement->is_even_key = key_rotation ? i % 2 == 0 : true;
|
||||||
entitlement->key_id = entitlement_comb_[i].key_id;
|
entitlement->key_id = stream_info->entitlement_comb[i].key_id;
|
||||||
entitlement->key_value = entitlement_comb_[i].key_value;
|
entitlement->key_value = stream_info->entitlement_comb[i].key_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ecm_ = absl::make_unique<Ecm>();
|
stream_info->ecm = absl::make_unique<Ecm>();
|
||||||
return ecm_->Initialize(ecm_init_params, entitlements);
|
return stream_info->ecm->Initialize(ecm_init_params, entitlements);
|
||||||
}
|
}
|
||||||
|
|
||||||
Status EcmgClientHandler::BuildEcmDatagram(const EcmgParameters& params,
|
Status EcmgClientHandler::BuildEcmDatagram(const EcmgParameters& params,
|
||||||
uint8_t* ecm_datagram) const {
|
uint8_t* ecm_datagram) const {
|
||||||
DCHECK(ecm_datagram);
|
DCHECK(ecm_datagram);
|
||||||
DCHECK(ecm_);
|
DCHECK(streams_info_.contains(params.ecm_stream_id));
|
||||||
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
EcmgStreamInfo* stream_info = streams_info_.at(params.ecm_stream_id).get();
|
||||||
|
DCHECK(stream_info->ecm);
|
||||||
|
|
||||||
// Generate serialized ECM.
|
// Generate serialized ECM.
|
||||||
std::vector<EntitledKeyInfo> keys;
|
std::vector<EntitledKeyInfo> keys;
|
||||||
@@ -901,11 +892,11 @@ Status EcmgClientHandler::BuildEcmDatagram(const EcmgParameters& params,
|
|||||||
Status status;
|
Status status;
|
||||||
std::string serialized_ecm;
|
std::string serialized_ecm;
|
||||||
if (ecmg_config_->number_of_content_keys > 1) {
|
if (ecmg_config_->number_of_content_keys > 1) {
|
||||||
status = ecm_->GenerateEcm(&keys[0], &keys[1], stream_info->track_type,
|
status = stream_info->ecm->GenerateEcm(
|
||||||
&serialized_ecm);
|
&keys[0], &keys[1], stream_info->track_type, &serialized_ecm);
|
||||||
} else {
|
} else {
|
||||||
status = ecm_->GenerateSingleKeyEcm(&keys[0], stream_info->track_type,
|
status = stream_info->ecm->GenerateSingleKeyEcm(
|
||||||
&serialized_ecm);
|
&keys[0], stream_info->track_type, &serialized_ecm);
|
||||||
}
|
}
|
||||||
if (!status.ok()) {
|
if (!status.ok()) {
|
||||||
return status;
|
return status;
|
||||||
|
|||||||
@@ -62,9 +62,6 @@ struct EcmgParameters {
|
|||||||
// User defined paremeters below.
|
// User defined paremeters below.
|
||||||
uint8_t age_restriction = 0xff; // Assume 0xff (255) is an invalid value.
|
uint8_t age_restriction = 0xff; // Assume 0xff (255) is an invalid value.
|
||||||
std::string crypto_mode;
|
std::string crypto_mode;
|
||||||
// All track types that need to be supported in the channel.
|
|
||||||
// Used to request entitlement keys.
|
|
||||||
std::vector<std::string> track_types;
|
|
||||||
std::string stream_track_type;
|
std::string stream_track_type;
|
||||||
std::vector<std::string> content_ivs; // 8 or 16 bytes, one for each key.
|
std::vector<std::string> content_ivs; // 8 or 16 bytes, one for each key.
|
||||||
std::vector<EntitlementIdKeyComb> entitlement_comb;
|
std::vector<EntitlementIdKeyComb> entitlement_comb;
|
||||||
@@ -77,6 +74,8 @@ struct EcmgStreamInfo {
|
|||||||
CryptoMode crypto_mode = CryptoMode::kInvalid;
|
CryptoMode crypto_mode = CryptoMode::kInvalid;
|
||||||
// 8 or 16 bytes, one for each key. Will use |content_ivs_| if empty.
|
// 8 or 16 bytes, one for each key. Will use |content_ivs_| if empty.
|
||||||
std::vector<std::string> content_ivs;
|
std::vector<std::string> content_ivs;
|
||||||
|
std::vector<EntitlementIdKeyComb> entitlement_comb;
|
||||||
|
std::unique_ptr<Ecm> ecm;
|
||||||
};
|
};
|
||||||
|
|
||||||
// A class that handles one (and only one) ECMG client.
|
// A class that handles one (and only one) ECMG client.
|
||||||
@@ -133,10 +132,7 @@ class EcmgClientHandler {
|
|||||||
uint16_t channel_id_;
|
uint16_t channel_id_;
|
||||||
|
|
||||||
// Channel specific information.
|
// Channel specific information.
|
||||||
std::unique_ptr<Ecm> ecm_; // |ecm_| is shared within the channel.
|
|
||||||
uint8_t age_restriction_ = 0;
|
uint8_t age_restriction_ = 0;
|
||||||
std::vector<std::string> track_types_;
|
|
||||||
std::vector<EntitlementIdKeyComb> entitlement_comb_;
|
|
||||||
std::vector<std::string> content_ivs_;
|
std::vector<std::string> content_ivs_;
|
||||||
|
|
||||||
// Map from ECM_stream_id to EcmgStreamInfo.
|
// Map from ECM_stream_id to EcmgStreamInfo.
|
||||||
|
|||||||
@@ -92,10 +92,8 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
|||||||
|
|
||||||
void BuildChannelSetupRequest(uint16_t channel_id, uint32_t super_cas_id,
|
void BuildChannelSetupRequest(uint16_t channel_id, uint32_t super_cas_id,
|
||||||
uint8_t age_restriction,
|
uint8_t age_restriction,
|
||||||
const std::string& crypto_mode,
|
const std::string& crypto_mode, char* message,
|
||||||
const std::vector<std::string>& track_types,
|
size_t* message_length) {
|
||||||
const std::vector<std::string>& entitlements,
|
|
||||||
char* message, size_t* message_length) {
|
|
||||||
EXPECT_TRUE(message != nullptr);
|
EXPECT_TRUE(message != nullptr);
|
||||||
EXPECT_TRUE(message_length != nullptr);
|
EXPECT_TRUE(message_length != nullptr);
|
||||||
BuildMessageHeader(ECMG_SCS_PROTOCOL_VERSION, ECMG_CHANNEL_SETUP, message,
|
BuildMessageHeader(ECMG_SCS_PROTOCOL_VERSION, ECMG_CHANNEL_SETUP, message,
|
||||||
@@ -110,21 +108,6 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
|||||||
AddParam(CRYPTO_MODE, reinterpret_cast<const uint8_t*>(crypto_mode.c_str()),
|
AddParam(CRYPTO_MODE, reinterpret_cast<const uint8_t*>(crypto_mode.c_str()),
|
||||||
crypto_mode.size(), message, message_length);
|
crypto_mode.size(), message, message_length);
|
||||||
}
|
}
|
||||||
if (!track_types.empty()) {
|
|
||||||
for (const auto& track_type : track_types) {
|
|
||||||
AddParam(TRACK_TYPES,
|
|
||||||
reinterpret_cast<const uint8_t*>(track_type.c_str()),
|
|
||||||
track_type.size(), message, message_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!entitlements.empty()) {
|
|
||||||
for (const auto& entitlement : entitlements) {
|
|
||||||
AddParam(ENTITLEMENT_ID_KEY_COMBINATION,
|
|
||||||
reinterpret_cast<const uint8_t*>(entitlement.c_str()),
|
|
||||||
entitlement.size(), message, message_length);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t total_param_length = *message_length - 5;
|
uint16_t total_param_length = *message_length - 5;
|
||||||
Host16ToBigEndian(message + 3, &total_param_length);
|
Host16ToBigEndian(message + 3, &total_param_length);
|
||||||
}
|
}
|
||||||
@@ -132,6 +115,7 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
|||||||
void BuildStreamSetupRequest(uint16_t channel_id, uint16_t stream_id,
|
void BuildStreamSetupRequest(uint16_t channel_id, uint16_t stream_id,
|
||||||
uint16_t ecm_id, uint16_t nominal_CP_duration,
|
uint16_t ecm_id, uint16_t nominal_CP_duration,
|
||||||
const std::string& stream_track_type,
|
const std::string& stream_track_type,
|
||||||
|
const std::vector<std::string>& entitlements,
|
||||||
const std::vector<std::string>& content_ivs,
|
const std::vector<std::string>& content_ivs,
|
||||||
char* message, size_t* message_length) {
|
char* message, size_t* message_length) {
|
||||||
EXPECT_TRUE(message != nullptr);
|
EXPECT_TRUE(message != nullptr);
|
||||||
@@ -149,6 +133,13 @@ class EcmgClientHandlerTest : public ::testing::Test {
|
|||||||
reinterpret_cast<const uint8_t*>(stream_track_type.c_str()),
|
reinterpret_cast<const uint8_t*>(stream_track_type.c_str()),
|
||||||
stream_track_type.size(), message, message_length);
|
stream_track_type.size(), message, message_length);
|
||||||
}
|
}
|
||||||
|
if (!entitlements.empty()) {
|
||||||
|
for (const auto& entitlement : entitlements) {
|
||||||
|
AddParam(ENTITLEMENT_ID_KEY_COMBINATION,
|
||||||
|
reinterpret_cast<const uint8_t*>(entitlement.c_str()),
|
||||||
|
entitlement.size(), message, message_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!content_ivs.empty()) {
|
if (!content_ivs.empty()) {
|
||||||
for (auto& content_iv : content_ivs) {
|
for (auto& content_iv : content_ivs) {
|
||||||
AddParam(CONTENT_IV, reinterpret_cast<const uint8_t*>(content_iv.c_str()),
|
AddParam(CONTENT_IV, reinterpret_cast<const uint8_t*>(content_iv.c_str()),
|
||||||
@@ -293,25 +284,29 @@ TEST_F(EcmgClientHandlerTest, SuccessSequenceWithPrivateParameters) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, SuccessSequenceInjectedEntitlements) {
|
TEST_F(EcmgClientHandlerTest, SuccessSequenceInjectedEntitlements) {
|
||||||
BuildChannelSetupRequest(
|
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode,
|
kCryptoMode, request_, &request_len_);
|
||||||
{kTrackTypesHD, kTrackTypesSD},
|
|
||||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
|
||||||
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
|
||||||
request_, &request_len_);
|
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||||
|
|
||||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
BuildStreamSetupRequest(
|
||||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||||
request_, &request_len_);
|
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||||
|
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||||
|
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||||
|
|
||||||
|
BuildStreamSetupRequest(
|
||||||
|
kChannelId, kStreamId + 1, kEcmId, kNominalCpDuration, kTrackTypesHD,
|
||||||
|
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||||
|
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||||
|
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||||
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
|
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||||
|
|
||||||
const std::vector<EcmgCpCwCombination> cp_cw_combination = {
|
const std::vector<EcmgCpCwCombination> cp_cw_combination = {
|
||||||
{kCpNumber, kContentKeyEven}, {kCpNumber + 1, kContentKeyOdd}};
|
{kCpNumber, kContentKeyEven}, {kCpNumber + 1, kContentKeyOdd}};
|
||||||
BuildCwProvisionRequest(kChannelId, kStreamId, kCpNumber, cp_cw_combination,
|
BuildCwProvisionRequest(kChannelId, kStreamId, kCpNumber, cp_cw_combination,
|
||||||
@@ -319,8 +314,13 @@ TEST_F(EcmgClientHandlerTest, SuccessSequenceInjectedEntitlements) {
|
|||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgEcmResponse), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgEcmResponse), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgEcmResponse, response_, 27));
|
EXPECT_EQ(0, memcmp(kTestEcmgEcmResponse, response_, 27));
|
||||||
}
|
|
||||||
|
|
||||||
|
BuildCwProvisionRequest(kChannelId, kStreamId + 1, kCpNumber,
|
||||||
|
cp_cw_combination, request_, &request_len_);
|
||||||
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
|
EXPECT_EQ(sizeof(kTestEcmgEcmResponse), response_len_);
|
||||||
|
}
|
||||||
|
//
|
||||||
TEST_F(EcmgClientHandlerTest, SuccessChannelError) {
|
TEST_F(EcmgClientHandlerTest, SuccessChannelError) {
|
||||||
SetupValidChannel();
|
SetupValidChannel();
|
||||||
handler_->HandleRequest(kTestEcmgChannelError, response_, &response_len_);
|
handler_->HandleRequest(kTestEcmgChannelError, response_, &response_len_);
|
||||||
@@ -410,11 +410,7 @@ TEST_F(EcmgClientHandlerTest, WrongParameterInsufficientKey) {
|
|||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, WrongParameterSuperCasId) {
|
TEST_F(EcmgClientHandlerTest, WrongParameterSuperCasId) {
|
||||||
// Setup a channel with an unexpected super cas id (expecting kSuperCasId).
|
// Setup a channel with an unexpected super cas id (expecting kSuperCasId).
|
||||||
BuildChannelSetupRequest(
|
BuildChannelSetupRequest(kChannelId, 0, kAgeRestriction, kCryptoMode,
|
||||||
kChannelId, 0, kAgeRestriction, kCryptoMode,
|
|
||||||
{kTrackTypesHD, kTrackTypesSD},
|
|
||||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
|
||||||
request_, &request_len_);
|
request_, &request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
CheckChannelError(UNKNOWN_SUPER_CAS_ID_VALUE, response_, response_len_);
|
CheckChannelError(UNKNOWN_SUPER_CAS_ID_VALUE, response_, response_len_);
|
||||||
@@ -423,20 +419,18 @@ TEST_F(EcmgClientHandlerTest, WrongParameterSuperCasId) {
|
|||||||
TEST_F(EcmgClientHandlerTest, WrongParameterChannelId) {
|
TEST_F(EcmgClientHandlerTest, WrongParameterChannelId) {
|
||||||
SetupValidChannel();
|
SetupValidChannel();
|
||||||
// Setup a stream with an unexpected channel id (expecting kChannelId).
|
// Setup a stream with an unexpected channel id (expecting kChannelId).
|
||||||
BuildStreamSetupRequest(0, kStreamId, kEcmId, kNominalCpDuration,
|
BuildStreamSetupRequest(
|
||||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
0, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||||
request_, &request_len_);
|
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||||
|
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||||
|
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
CheckStreamError(UNKNOWN_ECM_CHANNEL_ID_VALUE, response_, response_len_);
|
CheckStreamError(UNKNOWN_ECM_CHANNEL_ID_VALUE, response_, response_len_);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, WrongParameterCryptoMode) {
|
TEST_F(EcmgClientHandlerTest, WrongParameterCryptoMode) {
|
||||||
BuildChannelSetupRequest(
|
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||||
kChannelId, kSuperCasId, kAgeRestriction, "someCryptoMode",
|
"someCryptoMode", request_, &request_len_);
|
||||||
{kTrackTypesHD, kTrackTypesSD},
|
|
||||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
|
||||||
request_, &request_len_);
|
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
CheckChannelError(INVALID_VALUE_FOR_DVB_PARAMETER, response_, response_len_);
|
CheckChannelError(INVALID_VALUE_FOR_DVB_PARAMETER, response_, response_len_);
|
||||||
}
|
}
|
||||||
@@ -451,15 +445,15 @@ TEST_F(EcmgClientHandlerTest, WrongParameterLengthSuperCasId) {
|
|||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, NoInjectedEntitlements) {
|
TEST_F(EcmgClientHandlerTest, NoInjectedEntitlements) {
|
||||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||||
kCryptoMode, {kTrackTypesSD},
|
kCryptoMode, request_, &request_len_);
|
||||||
/*entitlements*/ {}, request_, &request_len_);
|
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||||
|
|
||||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
BuildStreamSetupRequest(
|
||||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||||
request_, &request_len_);
|
/*entitlements*/ {}, {kContentKeyEven, kContentKeyEven}, request_,
|
||||||
|
&request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||||
@@ -473,19 +467,16 @@ TEST_F(EcmgClientHandlerTest, NoInjectedEntitlements) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
||||||
BuildChannelSetupRequest(
|
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode,
|
kCryptoMode, request_, &request_len_);
|
||||||
{kTrackTypesHD, kTrackTypesSD},
|
|
||||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
|
||||||
request_, &request_len_);
|
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||||
|
|
||||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
BuildStreamSetupRequest(
|
||||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||||
request_, &request_len_);
|
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
||||||
|
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||||
@@ -499,19 +490,18 @@ TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(EcmgClientHandlerTest, TooManyInjectedEntitlements) {
|
TEST_F(EcmgClientHandlerTest, TooManyInjectedEntitlements) {
|
||||||
BuildChannelSetupRequest(
|
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode, {kTrackTypesSD},
|
kCryptoMode, request_, &request_len_);
|
||||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
|
||||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
|
||||||
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
|
||||||
request_, &request_len_);
|
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||||
|
|
||||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
BuildStreamSetupRequest(
|
||||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
kChannelId, kStreamId, kEcmId, kNominalCpDuration, kTrackTypesSD,
|
||||||
request_, &request_len_);
|
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||||
|
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd),
|
||||||
|
absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven)},
|
||||||
|
{kContentKeyEven, kContentKeyEven}, request_, &request_len_);
|
||||||
handler_->HandleRequest(request_, response_, &response_len_);
|
handler_->HandleRequest(request_, response_, &response_len_);
|
||||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||||
|
|||||||
@@ -63,10 +63,9 @@
|
|||||||
// User defined ECMG parameter type values - 0x8000 to 0xFFFF.
|
// User defined ECMG parameter type values - 0x8000 to 0xFFFF.
|
||||||
#define AGE_RESTRICTION (0x8000)
|
#define AGE_RESTRICTION (0x8000)
|
||||||
#define CRYPTO_MODE (0x8001)
|
#define CRYPTO_MODE (0x8001)
|
||||||
#define TRACK_TYPES (0x8002)
|
#define STREAM_TRACK_TYPE (0x8002)
|
||||||
#define STREAM_TRACK_TYPE (0x8003)
|
#define CONTENT_IV (0x8003)
|
||||||
#define CONTENT_IV (0x8004)
|
#define ENTITLEMENT_ID_KEY_COMBINATION (0x8004)
|
||||||
#define ENTITLEMENT_ID_KEY_COMBINATION (0x8005)
|
|
||||||
|
|
||||||
// ECMG protocol error values.
|
// ECMG protocol error values.
|
||||||
#define INVALID_MESSAGE (0x0001)
|
#define INVALID_MESSAGE (0x0001)
|
||||||
|
|||||||
Reference in New Issue
Block a user