Update includes and BUILD
This commit is contained in:
@@ -26,13 +26,11 @@ cc_library(
|
||||
hdrs = ["ecm.h"],
|
||||
deps = [
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/strings",
|
||||
"//common:aes_cbc_util",
|
||||
"//common:status",
|
||||
"//common:string_util",
|
||||
"//media_cas_packager_sdk/public:wv_cas_types",
|
||||
"//protos/public:media_cas_cc_proto",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
)
|
||||
@@ -44,8 +42,6 @@ cc_test(
|
||||
deps = [
|
||||
":ecm",
|
||||
"//testing:gunit_main",
|
||||
"//common:status",
|
||||
"//media_cas_packager_sdk/public:wv_cas_types",
|
||||
"//protos/public:media_cas_encryption_cc_proto",
|
||||
],
|
||||
)
|
||||
@@ -57,7 +53,6 @@ cc_library(
|
||||
deps = [
|
||||
":ecm",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"//common:status",
|
||||
],
|
||||
)
|
||||
@@ -91,15 +86,12 @@ cc_library(
|
||||
":simulcrypt_util",
|
||||
":util",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/container:node_hash_map",
|
||||
"@abseil_repo//absl/memory",
|
||||
"@abseil_repo//absl/strings",
|
||||
"@abseil_repo//absl/strings:str_format",
|
||||
"//common:crypto_util",
|
||||
"//common:random_util",
|
||||
"//common:status",
|
||||
"//example:constants",
|
||||
"//media_cas_packager_sdk/public:wv_cas_ecm",
|
||||
"//media_cas_packager_sdk/public:wv_cas_key_fetcher",
|
||||
"//media_cas_packager_sdk/public:wv_cas_types",
|
||||
@@ -132,12 +124,13 @@ cc_library(
|
||||
],
|
||||
deps = [
|
||||
":simulcrypt_util",
|
||||
":ts_packet",
|
||||
":util",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/strings",
|
||||
"@abseil_repo//absl/strings:str_format",
|
||||
"//common:status",
|
||||
"//example:test_emmg_messages",
|
||||
"//protos/public:media_cas_cc_proto",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -182,10 +175,7 @@ cc_library(
|
||||
hdrs = [
|
||||
"mpeg2ts.h",
|
||||
],
|
||||
deps = [
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
],
|
||||
deps = ["//base"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
@@ -198,8 +188,6 @@ cc_library(
|
||||
deps = [
|
||||
":util",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"//common:status",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -215,7 +203,6 @@ cc_library(
|
||||
deps = [
|
||||
":mpeg2ts",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"@abseil_repo//absl/strings",
|
||||
"//common:status",
|
||||
"//common:string_util",
|
||||
@@ -227,7 +214,6 @@ cc_test(
|
||||
size = "small",
|
||||
srcs = ["ts_packet_test.cc"],
|
||||
deps = [
|
||||
":mpeg2ts",
|
||||
":ts_packet",
|
||||
"//base",
|
||||
"//testing:gunit_main",
|
||||
@@ -245,7 +231,6 @@ cc_library(
|
||||
":mpeg2ts",
|
||||
":ts_packet",
|
||||
"//base",
|
||||
"@abseil_repo//absl/base:core_headers",
|
||||
"//common:status",
|
||||
],
|
||||
)
|
||||
@@ -258,6 +243,8 @@ cc_test(
|
||||
],
|
||||
deps = [
|
||||
":util",
|
||||
"//base",
|
||||
"//testing:gunit_main",
|
||||
"//common:status",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -8,14 +8,13 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ecm.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <bitset>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "common/aes_cbc_util.h"
|
||||
#include "common/status.h"
|
||||
#include "common/string_util.h"
|
||||
#include "protos/public/media_cas_encryption.pb.h"
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdint>
|
||||
#include "common/status.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_types.h"
|
||||
#include "protos/public/media_cas.pb.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ecm_generator.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "absl/memory/memory.h"
|
||||
|
||||
@@ -8,14 +8,8 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ecm.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "common/status.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_types.h"
|
||||
#include "protos/public/media_cas_encryption.pb.h"
|
||||
|
||||
using ::testing::Return;
|
||||
|
||||
@@ -8,22 +8,13 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ecmg_client_handler.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "common/crypto_util.h"
|
||||
#include "common/random_util.h"
|
||||
#include "common/status.h"
|
||||
#include "example/constants.h"
|
||||
#include "media_cas_packager_sdk/internal/ecmg_constants.h"
|
||||
#include "media_cas_packager_sdk/internal/fixed_key_fetcher.h"
|
||||
#include "media_cas_packager_sdk/internal/mpeg2ts.h"
|
||||
@@ -32,7 +23,6 @@
|
||||
#include "media_cas_packager_sdk/internal/util.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_ecm.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_key_fetcher.h"
|
||||
#include "media_cas_packager_sdk/public/wv_cas_types.h"
|
||||
|
||||
// CA System ID for Widevine.
|
||||
static constexpr uint16_t kWidevineSystemId = 0x4AD4;
|
||||
@@ -96,7 +86,7 @@ Status ProcessPrivateParameters(const char* const request, uint16_t param_type,
|
||||
break;
|
||||
case AGE_RESTRICTION:
|
||||
if (param_length != AGE_RESTRICTION_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -106,7 +96,7 @@ Status ProcessPrivateParameters(const char* const request, uint16_t param_type,
|
||||
case ENTITLEMENT_ID_KEY_COMBINATION: {
|
||||
if (param_length !=
|
||||
kEntitlementKeyIdSizeBytes + kEntitlementKeyValueSizeBytes) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -185,7 +175,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
}
|
||||
case CP_DURATION:
|
||||
if (param_length != CP_DURATION_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -194,7 +184,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case CP_NUMBER:
|
||||
if (param_length != CP_NUMBER_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -208,7 +198,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case ECM_CHANNEL_ID:
|
||||
if (param_length != ECM_CHANNEL_ID_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -217,7 +207,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case ECM_ID:
|
||||
if (param_length != ECM_ID_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -226,7 +216,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case ECM_STREAM_ID:
|
||||
if (param_length != ECM_STREAM_ID_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -235,7 +225,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case NOMINAL_CP_DURATION:
|
||||
if (param_length != NOMINAL_CP_DURATION_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -244,7 +234,7 @@ Status HandleParameters(const char* const request, size_t request_length,
|
||||
break;
|
||||
case SUPER_CAS_ID:
|
||||
if (param_length != SUPER_CAS_ID_SIZE) {
|
||||
return Status(error::INVALID_ARGUMENT,
|
||||
return Status(error::FAILED_PRECONDITION,
|
||||
absl::StrCat("Invalid parameter length ", param_length,
|
||||
" for parameter type ", param_type));
|
||||
}
|
||||
@@ -357,10 +347,14 @@ uint16_t StatusToDvbErrorCode(const Status& status) {
|
||||
return 0;
|
||||
}
|
||||
switch (status.error_code()) {
|
||||
case error::FAILED_PRECONDITION:
|
||||
return INCONSISTENT_LENGTH_FOR_DVB_PARAMETER;
|
||||
case error::INVALID_ARGUMENT:
|
||||
return INVALID_VALUE_FOR_DVB_PARAMETER;
|
||||
case error::NOT_FOUND:
|
||||
return MISSING_MANDATORY_DVB_PARAMETER;
|
||||
case error::UNIMPLEMENTED:
|
||||
return UNKNOWN_PARAMETER_TYPE_VALUE;
|
||||
case error::INTERNAL:
|
||||
default:
|
||||
return UNKNOWN_ERROR;
|
||||
@@ -454,22 +448,8 @@ void EcmgClientHandler::HandleRequest(const char* const request, char* response,
|
||||
Status status = HandleParameters(request + offset, request_length, ¶ms);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
switch (status.error_code()) {
|
||||
case error::INVALID_ARGUMENT:
|
||||
// TODO(user): Should use INCONSISTENT_LENGTH_FOR_DVB_PARAMETER in most
|
||||
// cases.
|
||||
BuildChannelError(params.ecm_channel_id,
|
||||
INVALID_VALUE_FOR_DVB_PARAMETER,
|
||||
status.error_message(), response, response_length);
|
||||
break;
|
||||
case error::UNIMPLEMENTED:
|
||||
BuildChannelError(params.ecm_channel_id, UNKNOWN_PARAMETER_TYPE_VALUE,
|
||||
status.error_message(), response, response_length);
|
||||
break;
|
||||
default:
|
||||
BuildChannelError(params.ecm_channel_id, UNKNOWN_ERROR,
|
||||
status.error_message(), response, response_length);
|
||||
}
|
||||
BuildChannelError(params.ecm_channel_id, StatusToDvbErrorCode(status),
|
||||
status.error_message(), response, response_length);
|
||||
return;
|
||||
}
|
||||
switch (request_type) {
|
||||
@@ -535,7 +515,7 @@ void EcmgClientHandler::HandleChannelSetup(const EcmgParameters& params,
|
||||
channel_id_ = params.ecm_channel_id;
|
||||
channel_id_set_ = true;
|
||||
|
||||
Status status = UpdatePrivateParameters(params, false);
|
||||
Status status = UpdateChannelPrivateParameters(params);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
BuildChannelError(params.ecm_channel_id, StatusToDvbErrorCode(status),
|
||||
@@ -595,7 +575,7 @@ void EcmgClientHandler::HandleStreamSetup(const EcmgParameters& params,
|
||||
streams_info_[params.ecm_stream_id] = absl::make_unique<EcmgStreamInfo>();
|
||||
streams_info_[params.ecm_stream_id]->ecm_id = params.ecm_id;
|
||||
|
||||
Status status = UpdatePrivateParameters(params, true);
|
||||
Status status = UpdateStreamPrivateParameters(params);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
BuildStreamError(params.ecm_channel_id, params.ecm_stream_id,
|
||||
@@ -684,7 +664,7 @@ void EcmgClientHandler::HandleCwProvision(const EcmgParameters& params,
|
||||
}
|
||||
|
||||
// Update private parameters based on access_criteria if any.
|
||||
Status status = UpdatePrivateParameters(params, true);
|
||||
Status status = UpdateStreamPrivateParameters(params);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
BuildStreamError(params.ecm_channel_id, params.ecm_stream_id,
|
||||
@@ -721,47 +701,23 @@ void EcmgClientHandler::HandleCwProvision(const EcmgParameters& params,
|
||||
params.cp_number, ecm_datagram, response, response_length);
|
||||
}
|
||||
|
||||
Status EcmgClientHandler::UpdatePrivateParameters(const EcmgParameters& params,
|
||||
bool stream_specific) {
|
||||
EcmgStreamInfo* stream_info =
|
||||
stream_specific ? streams_info_[params.ecm_stream_id].get() : nullptr;
|
||||
|
||||
Status EcmgClientHandler::UpdateCommonPrivateParameters(
|
||||
const EcmgParameters& params) {
|
||||
if (params.age_restriction != 0xff) {
|
||||
if (params.age_restriction > kMaxAllowedAgeRestriction) {
|
||||
return {error::INVALID_ARGUMENT, "Age restriction too large."};
|
||||
}
|
||||
age_restriction_ = params.age_restriction;
|
||||
}
|
||||
|
||||
if (!params.crypto_mode.empty()) {
|
||||
if (!StringToCryptoMode(params.crypto_mode,
|
||||
stream_specific ? &stream_info->crypto_mode
|
||||
: &ecmg_config_->crypto_mode)) {
|
||||
return {error::INVALID_ARGUMENT,
|
||||
absl::StrCat("Unknown crypto mode: ", params.crypto_mode, ".")};
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.track_types.empty()) {
|
||||
track_types_.assign(params.track_types.begin(), params.track_types.end());
|
||||
}
|
||||
|
||||
if (!params.stream_track_type.empty()) {
|
||||
if (stream_specific) {
|
||||
stream_info->track_type = params.stream_track_type;
|
||||
} else {
|
||||
LOG(WARNING) << "Ignoring stream track type received in channel config.";
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.content_id.empty()) {
|
||||
content_id_ = params.content_id;
|
||||
}
|
||||
|
||||
if (!params.content_provider.empty()) {
|
||||
content_provider_ = params.content_provider;
|
||||
}
|
||||
|
||||
if (!params.content_ivs.empty()) {
|
||||
if (params.content_ivs.size() < ecmg_config_->number_of_content_keys) {
|
||||
return {error::INVALID_ARGUMENT,
|
||||
@@ -778,19 +734,54 @@ Status EcmgClientHandler::UpdatePrivateParameters(const EcmgParameters& params,
|
||||
return {error::INVALID_ARGUMENT, "Size of content ivs must match."};
|
||||
}
|
||||
}
|
||||
if (stream_specific) {
|
||||
stream_info->content_ivs.assign(params.content_ivs.begin(),
|
||||
params.content_ivs.end());
|
||||
} else {
|
||||
content_ivs_.assign(params.content_ivs.begin(), params.content_ivs.end());
|
||||
}
|
||||
}
|
||||
|
||||
if (!params.entitlement_comb.empty()) {
|
||||
entitlement_comb_.assign(params.entitlement_comb.begin(),
|
||||
params.entitlement_comb.end());
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
Status EcmgClientHandler::UpdateChannelPrivateParameters(
|
||||
const EcmgParameters& params) {
|
||||
Status status = UpdateCommonPrivateParameters(params);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
if (!params.crypto_mode.empty()) {
|
||||
if (!StringToCryptoMode(params.crypto_mode, &ecmg_config_->crypto_mode)) {
|
||||
return {error::INVALID_ARGUMENT,
|
||||
absl::StrCat("Unknown crypto mode: ", params.crypto_mode, ".")};
|
||||
}
|
||||
}
|
||||
if (!params.content_ivs.empty()) {
|
||||
content_ivs_.assign(params.content_ivs.begin(), params.content_ivs.end());
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
Status EcmgClientHandler::UpdateStreamPrivateParameters(
|
||||
const EcmgParameters& params) {
|
||||
DCHECK(streams_info_.contains(params.ecm_stream_id));
|
||||
EcmgStreamInfo* stream_info = streams_info_[params.ecm_stream_id].get();
|
||||
|
||||
Status status = UpdateCommonPrivateParameters(params);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
if (!params.crypto_mode.empty()) {
|
||||
if (!StringToCryptoMode(params.crypto_mode, &stream_info->crypto_mode)) {
|
||||
return {error::INVALID_ARGUMENT,
|
||||
absl::StrCat("Unknown crypto mode: ", params.crypto_mode, ".")};
|
||||
}
|
||||
}
|
||||
if (!params.stream_track_type.empty()) {
|
||||
stream_info->track_type = params.stream_track_type;
|
||||
}
|
||||
if (!params.content_ivs.empty()) {
|
||||
stream_info->content_ivs.assign(params.content_ivs.begin(),
|
||||
params.content_ivs.end());
|
||||
}
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,8 @@
|
||||
#define MEDIA_CAS_PACKAGER_SDK_INTERNAL_ECMG_CLIENT_HANDLER_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -116,12 +111,12 @@ class EcmgClientHandler {
|
||||
size_t* response_length);
|
||||
void HandleCwProvision(const EcmgParameters& params, char* response,
|
||||
size_t* response_length);
|
||||
// Update private paprameters using |params|. |stream_specific| indicates if
|
||||
// |params| is for a single stream or the whole channel. If |stream_specific|
|
||||
// is true, |params| will only affect values of this stream. If it is false,
|
||||
// |param| will affect all streams of the channel.
|
||||
Status UpdatePrivateParameters(const EcmgParameters& params,
|
||||
bool stream_specific);
|
||||
|
||||
// Update private parameters using |params|.
|
||||
Status UpdateChannelPrivateParameters(const EcmgParameters& params);
|
||||
Status UpdateStreamPrivateParameters(const EcmgParameters& params);
|
||||
Status UpdateCommonPrivateParameters(const EcmgParameters& params);
|
||||
|
||||
// Check if all required parameters have been set. If so, initialize |ecm_| by
|
||||
// fetching entitlement keys.
|
||||
Status CheckAndInitializeEcm(const EcmgParameters& params);
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ecmg_client_handler.h"
|
||||
|
||||
#include <string>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
@@ -455,6 +456,81 @@ TEST_F(EcmgClientHandlerTest, WrongParameterChannelId) {
|
||||
CheckStreamError(UNKNOWN_ECM_CHANNEL_ID_VALUE, response_, response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, WrongParameterCryptoMode) {
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
"someCryptoMode", {kTrackTypesHD, kTrackTypesSD},
|
||||
kContentId, kContentProvider, /*entitlements*/ {},
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckChannelError(INVALID_VALUE_FOR_DVB_PARAMETER, response_, response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, WrongParameterLengthSuperCasId) {
|
||||
// Setup a channel with an unexpected super cas id length (2 instead of 4).
|
||||
handler_->HandleRequest(kTestEcmgChannelSetupWrongParameterLength, response_,
|
||||
&response_len_);
|
||||
CheckChannelError(INCONSISTENT_LENGTH_FOR_DVB_PARAMETER, response_,
|
||||
response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, NoEntitlementsNoContentIdProvider) {
|
||||
BuildChannelSetupRequest(kChannelId, kSuperCasId, kAgeRestriction,
|
||||
kCryptoMode, {kTrackTypesHD, kTrackTypesSD},
|
||||
/*ContentId*/ "", /*ContentProvider*/ "",
|
||||
/*entitlements*/ {}, request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
|
||||
const std::vector<EcmgCpCwCombination> cp_cw_combination = {
|
||||
{kCpNumber, kContentKeyEven}, {kCpNumber + 1, kContentKeyOdd}};
|
||||
BuildCwProvisionRequest(kChannelId, kStreamId, kCpNumber, cp_cw_combination,
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckStreamError(MISSING_MANDATORY_DVB_PARAMETER, response_, response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, NotEnoughInjectedEntitlements) {
|
||||
BuildChannelSetupRequest(
|
||||
kChannelId, kSuperCasId, kAgeRestriction, kCryptoMode,
|
||||
{kTrackTypesHD, kTrackTypesSD},
|
||||
/*ContentId*/ "", /*ContentProvider*/ "",
|
||||
{absl::StrCat(kEntitlementKeyIdEven, kEntitlementKeyValueEven),
|
||||
absl::StrCat(kEntitlementKeyIdOdd, kEntitlementKeyValueOdd)},
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgChannelStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgChannelStatus, response_, response_len_));
|
||||
|
||||
BuildStreamSetupRequest(kChannelId, kStreamId, kEcmId, kNominalCpDuration,
|
||||
kTrackTypesSD, {kContentKeyEven, kContentKeyEven},
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
EXPECT_EQ(sizeof(kTestEcmgStreamStatus), response_len_);
|
||||
EXPECT_EQ(0, memcmp(kTestEcmgStreamStatus, response_, response_len_));
|
||||
|
||||
const std::vector<EcmgCpCwCombination> cp_cw_combination = {
|
||||
{kCpNumber, kContentKeyEven}, {kCpNumber + 1, kContentKeyOdd}};
|
||||
BuildCwProvisionRequest(kChannelId, kStreamId, kCpNumber, cp_cw_combination,
|
||||
request_, &request_len_);
|
||||
handler_->HandleRequest(request_, response_, &response_len_);
|
||||
CheckStreamError(MISSING_MANDATORY_DVB_PARAMETER, response_, response_len_);
|
||||
}
|
||||
|
||||
TEST_F(EcmgClientHandlerTest, WrongMessageLength) {
|
||||
// Setup a channel with a wrong message length specified (too large).
|
||||
handler_->HandleRequest(kTestEcmgChannelSetupWrongMessageLength, response_,
|
||||
&response_len_);
|
||||
CheckChannelError(UNKNOWN_PARAMETER_TYPE_VALUE, response_, response_len_);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace cas
|
||||
} // namespace widevine
|
||||
|
||||
@@ -10,18 +10,19 @@
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "example/test_emmg_messages.h"
|
||||
#include "media_cas_packager_sdk/internal/emmg_constants.h"
|
||||
#include "media_cas_packager_sdk/internal/mpeg2ts.h"
|
||||
#include "media_cas_packager_sdk/internal/simulcrypt_constants.h"
|
||||
#include "media_cas_packager_sdk/internal/simulcrypt_util.h"
|
||||
#include "media_cas_packager_sdk/internal/ts_packet.h"
|
||||
#include "media_cas_packager_sdk/internal/util.h"
|
||||
#include "protos/public/media_cas.pb.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
@@ -125,6 +126,36 @@ void Emmg::BuildStreamSetup() {
|
||||
Host16ToBigEndian(request_ + 3, &total_param_length);
|
||||
}
|
||||
|
||||
Status Emmg::GeneratePrivateData(const std::string& content_provider,
|
||||
const std::string& content_id, uint8_t* buffer) {
|
||||
DCHECK(buffer);
|
||||
// Generate payload.
|
||||
CaDescriptorPrivateData private_data;
|
||||
private_data.set_provider(content_provider);
|
||||
private_data.set_content_id(content_id);
|
||||
std::string private_data_str = private_data.SerializeAsString();
|
||||
std::string payload_filler(kMaxTsPayloadSize - private_data_str.size(), 0);
|
||||
|
||||
// Wrap the data with a TS header.
|
||||
TsPacket ecm_packet;
|
||||
ecm_packet.set_payload_unit_start_indicator(true);
|
||||
ecm_packet.set_pid(0);
|
||||
ecm_packet.set_payload(absl::StrCat(private_data_str, payload_filler));
|
||||
ecm_packet.set_adaptation_field_control(TsPacket::kPayloadOnly);
|
||||
ecm_packet.set_continuity_counter(continuity_counter_);
|
||||
continuity_counter_ = ++continuity_counter_ & 0xf;
|
||||
|
||||
// And write the packet.
|
||||
std::string ecm_ts_packet;
|
||||
Status status = ecm_packet.Write(&ecm_ts_packet);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << status.ToString();
|
||||
return status;
|
||||
}
|
||||
memcpy(buffer, ecm_ts_packet.data(), ecm_ts_packet.size());
|
||||
return OkStatus();
|
||||
}
|
||||
|
||||
void Emmg::BuildDataProvision() {
|
||||
bzero(request_, BUFFER_SIZE);
|
||||
request_length_ = 0;
|
||||
@@ -142,15 +173,11 @@ void Emmg::BuildDataProvision() {
|
||||
simulcrypt_util::AddUint16Param(EMMG_DATA_ID, emmg_config_->data_id, request_,
|
||||
&request_length_);
|
||||
|
||||
// Add a fake TS packet.
|
||||
uint16_t datagram_type = EMMG_DATAGRAM;
|
||||
Host16ToBigEndian(request_ + request_length_, &datagram_type);
|
||||
request_length_ += 2;
|
||||
uint16_t param_length = sizeof(kTestEmmgTsPacket); // Should be 188.
|
||||
Host16ToBigEndian(request_ + request_length_, ¶m_length);
|
||||
request_length_ += 2;
|
||||
memcpy(request_ + request_length_, kTestEmmgTsPacket, param_length);
|
||||
request_length_ += param_length;
|
||||
uint8_t datagram[kTsPacketSize];
|
||||
GeneratePrivateData(emmg_config_->content_provider, emmg_config_->content_id,
|
||||
datagram);
|
||||
simulcrypt_util::AddParam(EMMG_DATAGRAM, datagram, kTsPacketSize, request_,
|
||||
&request_length_);
|
||||
|
||||
uint16_t total_param_length = request_length_ - 5;
|
||||
Host16ToBigEndian(request_ + 3, &total_param_length);
|
||||
|
||||
@@ -10,13 +10,9 @@
|
||||
#define MEDIA_CAS_PACKAGER_SDK_INTERNAL_EMMG_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdint>
|
||||
#include "glog/logging.h"
|
||||
#include "common/status.h"
|
||||
|
||||
#define BUFFER_SIZE (1024)
|
||||
@@ -32,6 +28,8 @@ struct EmmgConfig {
|
||||
uint16_t data_stream_id;
|
||||
uint16_t data_id;
|
||||
uint8_t data_type;
|
||||
std::string content_provider;
|
||||
std::string content_id;
|
||||
};
|
||||
|
||||
// A class that sends EMMG/PDG message to the MUX server.
|
||||
@@ -62,6 +60,8 @@ class Emmg {
|
||||
void SendStreamCloseRequest();
|
||||
void SendChannelClose();
|
||||
|
||||
Status GeneratePrivateData(const std::string& content_provider,
|
||||
const std::string& content_id, uint8_t* buffer);
|
||||
void ReceiveResponseAndVerify(uint16_t expected_type);
|
||||
void Send(uint16_t message_type);
|
||||
|
||||
@@ -72,6 +72,8 @@ class Emmg {
|
||||
// |server_socket_fd| is a file descriptor we can use to communicate
|
||||
// with the MUX server.
|
||||
int server_socket_fd_;
|
||||
// |continuity_counter| is incremented each time private data is generated.
|
||||
int continuity_counter_ = 0;
|
||||
};
|
||||
|
||||
} // namespace cas
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/emmg.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "testing/gunit.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
@@ -38,6 +44,8 @@ class EmmgTest : public ::testing::Test {
|
||||
config_.data_stream_id = 0x0001;
|
||||
config_.data_id = 0x0001;
|
||||
config_.data_type = 0x01;
|
||||
config_.content_provider = "widevine_test";
|
||||
config_.content_id = "CasTsFake";
|
||||
emmg_ = absl::make_unique<TestableEmmg>(&config_);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/fixed_key_fetcher.h"
|
||||
|
||||
#include "common/status.h"
|
||||
#include "protos/public/media_cas_encryption.pb.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#ifndef MEDIA_CAS_PACKAGER_SDK_INTERNAL_FIXED_KEY_FETCHER_H_
|
||||
#define MEDIA_CAS_PACKAGER_SDK_INTERNAL_FIXED_KEY_FETCHER_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common/status.h"
|
||||
#include "media_cas_packager_sdk/internal/key_fetcher.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <cstdint>
|
||||
#include "base/macros.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/simulcrypt_util.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#include "glog/logging.h"
|
||||
|
||||
@@ -12,13 +12,8 @@
|
||||
#define MEDIA_CAS_PACKAGER_SDK_INTERNAL_SIMULCRYPT_UTIL_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <cstdint>
|
||||
#include "common/status.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "glog/logging.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "common/status.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
namespace widevine {
|
||||
|
||||
@@ -33,11 +33,9 @@
|
||||
#ifndef MEDIA_CAS_PACKAGER_SDK_INTERNAL_TS_PACKET_H_
|
||||
#define MEDIA_CAS_PACKAGER_SDK_INTERNAL_TS_PACKET_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <cstdint>
|
||||
#include "base/macros.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "common/status.h"
|
||||
#include "media_cas_packager_sdk/internal/mpeg2ts.h"
|
||||
|
||||
@@ -8,12 +8,9 @@
|
||||
|
||||
#include "media_cas_packager_sdk/internal/ts_packet.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "testing/gmock.h"
|
||||
#include "testing/gunit.h"
|
||||
#include "media_cas_packager_sdk/internal/mpeg2ts.h"
|
||||
|
||||
namespace widevine {
|
||||
namespace cas {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "media_cas_packager_sdk/internal/util.h"
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user