📄 ms_cardea.c
字号:
* */#include <stdio.h>#include <sys/time.h>#if 0static struct timeval sample_time_last = { 0 };static RMuint32 sample_count = 0;static RMuint32 sample_bytes = 0;#endif#if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2) RMstatus decrypt_cardea_sample( void * cardea_url, RMuint16 stream_index, RMuint32 media_object_number, RMuint32 buf_phys, RMuint8 *buf, RMuint32 size)#elseRMstatus decrypt_cardea_sample( void * cardea_url, RMuint16 stream_index, RMuint32 media_object_number, RMuint8 *buf, RMuint32 size)#endif#if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2){ struct ms_url_context_s *url_ctx = (struct ms_url_context_s *) cardea_url; struct ms_upnp_extension_s *ms_context = (struct ms_upnp_extension_s *) url_ctx->server; RMstatus status; if (ms_context == NULL) { RMDBGLOG((ENABLE,"** Error ** NULL context\n")); return RM_ERROR; } if (url_ctx == NULL) { RMDBGLOG((ENABLE,"** Error ** NULL url context\n")); return RM_ERROR; } RMDBGLOG((ENABLE,"ms_context: 0x%08x\n", ms_context)); RMDBGLOG((ENABLE,"url context is at: 0x%08x, url hash: %d\n", url_ctx, url_ctx->url_hash)); if (stream_index == 0 || stream_index > 127){ RMDBGLOG((ENABLE,"** Error ** stream index value is invalid : %ld\n", stream_index)); return RM_ERROR; } /* Check the media object number is the same as the one registered with the sample ID */ if (url_ctx->ms_stream_decryption_context[stream_index].media_object_number != media_object_number){// RMDBGLOG((ENABLE,"** Errror ** media object number mismatch : %lu != %lu\n", fprintf(stderr,"** Errror ** media object number mismatch : %lu != %lu\n", media_object_number, url_ctx->ms_stream_decryption_context[stream_index].media_object_number); return RM_ERROR; }{#if 0 struct timeval sample_time; RMuint32 elapsed; gettimeofday( &sample_time, 0 ); if ( sample_time_last.tv_sec == 0 ) { sample_time_last = sample_time; } elapsed = sample_time.tv_usec - sample_time_last.tv_usec + 1000000 * (sample_time.tv_sec - sample_time_last.tv_sec); if ( elapsed >= 1000000 ) { fprintf( stderr, "Sample Rate = %ld %ld %ld\n", elapsed, (RMint32)sample_count * 1000 * 1000 / elapsed, (RMint32)sample_bytes * 976 / elapsed ); sample_time_last = sample_time; sample_count = 0; sample_bytes = 0; } sample_count++; sample_bytes += size;#endif} status = decrypt_cardea_sample_core( (wmdrmnet_context*)ms_context->drm_context, url_ctx->ms_stream_decryption_context[stream_index].sample_id, buf_phys, buf, size, url_ctx->ms_stream_decryption_context[stream_index].byte_count, url_ctx->url_hash); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"** Error ** CARDEA core decryption failed.\n")); return status; } /* Update the byte count */ url_ctx->ms_stream_decryption_context[stream_index].byte_count += size; return RM_OK;}#else{ struct ms_url_context_s *url_ctx = (struct ms_url_context_s *) cardea_url; struct ms_upnp_extension_s *ms_context = (struct ms_upnp_extension_s *) url_ctx->server; RMstatus status; if (ms_context == NULL){ RMDBGLOG((ENABLE,"** Error ** NULL context\n")); return RM_ERROR; } if (url_ctx == NULL) { RMDBGLOG((ENABLE,"** Error ** NULL url context\n")); return RM_ERROR; } RMDBGLOG((ENABLE,"ms_context: 0x%08x\n", ms_context)); RMDBGLOG((ENABLE,"url context is at: 0x%08x, url hash: %d\n", url_ctx, url_ctx->url_hash)); if (stream_index == 0 || stream_index > 127){ RMDBGLOG((ENABLE,"** Error ** stream index value is invalid : %ld\n", stream_index)); return RM_ERROR; } /* Check the media object number is the same as the one registered with the sample ID */ if (url_ctx->ms_stream_decryption_context[stream_index].media_object_number != media_object_number){ RMDBGLOG((ENABLE,"** Errror ** media object number mismatch : %lu != %lu\n", media_object_number, url_ctx->ms_stream_decryption_context[stream_index].media_object_number)); return RM_ERROR; } status = decrypt_cardea_sample_core( ms_context->drm_context, url_ctx->ms_stream_decryption_context[stream_index].sample_id, buf, size, url_ctx->ms_stream_decryption_context[stream_index].byte_count, url_ctx->url_hash); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"** Error ** CARDEA core decryption failed.\n")); return status; } /* Update the byte count */ url_ctx->ms_stream_decryption_context[stream_index].byte_count += size; return RM_OK;}#endif/** * Get the output protection level for a given cardea context * * @param cardea_context - the current cardea context * @param opl - pointer to the structure that should be * filled with the output protection level data * @return RM_OK on success */RMstatus get_cardea_opl( void * cardea_context, struct cardea_opl_s *opl){ struct ms_url_context_s *url_ctx = (struct ms_url_context_s *) cardea_context; struct ms_upnp_extension_s *ms_context = (struct ms_upnp_extension_s *) url_ctx->server; if (ms_context == NULL || ms_context->drm_context == NULL || opl == NULL) return RM_ERROR; /* Could be more than a simple cast, don't rely on it */ return get_cardea_opl_core((wmdrmnet_context*)ms_context->drm_context, url_ctx->url_hash, (struct cardea_opl_core_s *) opl);}/** * Get the session ID header for a given URL * * This function tries to get the session header associated with a URL. If no * MS DRM session header is required, or if a license has not been obtained, * this function will return NUL. * * @param url - url for which a session header is required * @return NULL if no session header is available */RMascii * get_ms_session_header(const RMascii *url){ RMuint32 i; struct ms_url_context_s *url_ctx; for (i=0;i<MAX_MS_DEVICE;i++){ if (ms_device[i] != NULL) { url_ctx = (struct ms_url_context_s *)find_url(ms_device[i], (RMascii *)url); if( (url_ctx != NULL) && (url_ctx->session_header != NULL) ) { RMDBGLOG((ENABLE, "Found session header: 0x%08x\n", url_ctx->session_header)); return url_ctx->session_header; } } } RMDBGLOG((ENABLE, "No session header found for url!!\n")); return NULL;}#if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2)/** * Get the output protection level for a given cardea context * * @param cardea_context - the current cardea context * @param opl - pointer to the structure that should be * filled with the output protection level data * @return RM_OK on success */RMstatus get_cardea_analog_opl( void * cardea_context, struct cardea_extended_analog_video_s *analog_opl, RMuint32 *analog_opl_size, RMuint32 *analog_opl_count ){ struct ms_url_context_s *url_ctx = (struct ms_url_context_s *) cardea_context; struct ms_upnp_extension_s *ms_context = (struct ms_upnp_extension_s *) url_ctx->server; if (ms_context == NULL || ms_context->drm_context == NULL || analog_opl == NULL || analog_opl_size == 0 || analog_opl_count == 0) return RM_ERROR; /* Could be more than a simple cast, don't rely on it */ return get_cardea_analog_opl_core( ms_context->drm_context, url_ctx->url_hash, (struct cardea_extended_analog_video_core_s *) analog_opl, analog_opl_size, analog_opl_count );}/** * Get the session ID header for a given URL * * This function tries to get the session header associated with a URL. If no * MS DRM session header is required, or if a license has not been obtained, * this function will return NUL. * * @param cardea_context - the current cardea context * @param cci_info - pointer to the structure that should be * filled with copy control information. * @return RM_OK on success*/RMstatus get_cardea_cci( void * cardea_context, struct rmcci *cci_info ){ RMuint32 n; RMstatus status; struct cardea_opl_s cardea_opl; RMuint32 analog_opl_size, analog_opl_count; RMuint8 analog_opl_buf[1024]; struct cardea_extended_analog_video_s *analog_opl = (struct cardea_extended_analog_video_s *)analog_opl_buf; if ( cardea_context == NULL ) { RMDBGLOG((ENABLE,"Error cardea context is NULL.\n")); goto exit_with_error; } RMMemset( cci_info, 0, sizeof(struct rmcci) ); cci_info->SPDIF_LBit = 1; /* OPL */ status = get_cardea_opl(cardea_context, &cardea_opl); if (RMFAILED(status)){ RMDBGLOG((ENABLE,"Cannot retrieve CARDEA output protection level.\n")); goto exit_with_error; } RMDBGLOG((ENABLE, "OPLs:\n" " Digital Video Uncompressed : %ld\n" " Digital Video Compressed : %ld\n" " Digital Audio Uncompressed : %ld\n" " Digital Audio Compressed : %ld\n" " Analog Video : %ld\n", cardea_opl.min_digital_uncompressed_video, cardea_opl.min_digital_compressed_video, cardea_opl.min_digital_uncompressed_audio, cardea_opl.min_digital_compressed_audio, cardea_opl.min_analog_video )); if ( cardea_opl.min_digital_uncompressed_video <= CARDEA_OPL_UNPROTECTED_UNCOMPRESSED_DIGITAL_VIDEO ) { ; } else if ( cardea_opl.min_digital_uncompressed_video <= CARDEA_OPL_PROTECTED_UNCOMPRESSED_DIGITAL_VIDEO ) { cci_info->HDCP_Enable = 1; } else { cci_info->DigitalVideo_disable = 1; } #if 0 if ( cardea_opl.min_digital_compressed_video <= CARDEA_OPL_UNPROTECTED_COMPRESSED_DIGITAL_VIDEO ) { ; } else if ( cardea_opl.min_digital_compressed_video <= CARDEA_OPL_PROTECTED_COMPRESSED_DIGITAL_VIDEO ) { cci_info->HDCP_Enable = 1; } else { cci_info->DigitalVideo_disable = 1; cci_info->HDCP_Enable = 0; } #endif if ( cardea_opl.min_digital_uncompressed_audio <= CARDEA_OPL_UNPROTECTED_UNCOMPRESSED_DIGITAL_AUDIO ) { ; } else if ( cardea_opl.min_digital_uncompressed_audio <= CARDEA_OPL_PROTECTED_1_UNCOMPRESSED_DIGITAL_AUDIO ) { cci_info->SPDIF_CpBit = 1; cci_info->SPDIF_LBit = 0; cci_info->HDCP_Enable = 1; } else if ( cardea_opl.min_digital_uncompressed_audio <= CARDEA_OPL_PROTECTED_2_UNCOMPRESSED_DIGITAL_AUDIO ) { cci_info->DigitalUncompressedAudio_disable = 1; } else { cci_info->DigitalUncompressedAudio_disable = 1; } if ( cardea_opl.min_digital_uncompressed_audio <= CARDEA_OPL_UNPROTECTED_COMPRESSED_DIGITAL_AUDIO ) { ; } else if ( cardea_opl.min_digital_compressed_audio <= CARDEA_OPL_PROTECTED_1_COMPRESSED_DIGITAL_AUDIO ) { cci_info->SPDIF_CpBit = 1; cci_info->SPDIF_LBit = 0; cci_info->HDCP_Enable = 1; } else if ( cardea_opl.min_digital_compressed_audio <= CARDEA_OPL_PROTECTED_2_COMPRESSED_DIGITAL_AUDIO ) { cci_info->DigitalCompressedAudio_disable = 1; } else { cci_info->DigitalCompressedAudio_disable = 1; } if ( cardea_opl.min_analog_video <= CARDEA_OPL_UNPROTECTED_ANALOG_VIDEO ) { ; } else if ( cardea_opl.min_analog_video <= CARDEA_OPL_PROTECTED_ANALOG_VIDEO ) { cci_info->Video_CGMSA = 3; } else { cci_info->AnalogVideo_disable = 1; } if ( cci_info->AnalogVideo_disable != 0 ) { goto skip_macrovision_processing; } analog_opl_size = sizeof(analog_opl_buf); status = get_cardea_analog_opl( cardea_context, analog_opl, &analog_opl_size, &analog_opl_count ); if ( RMFAILED(status) ) { RMDBGLOG((ENABLE,"Error getting CARDEA extended analog opl.\n")); goto exit_with_error; } n = 0; while( n < analog_opl_size ) {#if 0 RMDBGLOG((ENABLE, "%s:%d - Analog GUID = %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", __FILE__, __LINE__, analog_opl->guid[0], analog_opl->guid[1], analog_opl->guid[2], analog_opl->guid[3], analog_opl->guid[4], analog_opl->guid[5], analog_opl->guid[6], analog_opl->guid[7], analog_opl->guid[8], analog_opl->guid[9], analog_opl->guid[10], analog_opl->guid[11], analog_opl->guid[12], analog_opl->guid[13], analog_opl->guid[14], analog_opl->guid[15] ));#endif if ( RMMemcmp( analog_opl->guid, MacroVision_ACP_GUID1, sizeof(MacroVision_ACP_GUID1) ) == 0 ) { cci_info->Video_agc = (RMuint8)analog_opl->data[0] & 0x03; cci_info->Video_aps = cci_info->Video_agc;#if 0 switch( cci_info->Video_agc ) { case 0: break; case 1: case 3: cci_info->Video_CGMSA = 3; break; case 2: cci_info->Video_CGMSA = 3; break; };#endif } else if ( RMMemcmp( analog_opl->guid, ComponentOut_Constraint_GUID, sizeof(ComponentOut_Constraint_GUID) ) == 0 ) { cci_info->AnalogVideo_imageConstraint = 1; } n += analog_opl->size; analog_opl = (struct cardea_extended_analog_video_s *)((RMuint8 *)analog_opl + analog_opl->size); }skip_macrovision_processing: ; return RM_OK;exit_with_error: return RM_ERROR;}RMstatus load_cardea(RMuint8 *certificate, RMint32 size) { RMDBGLOG((ENABLE, "Running cardea_certificate_core\n")); return cardea_certificate_core(certificate, size);}#endifRMstatus destroy_cardea_license_data(void *cardea_context){ RMstatus dr; struct ms_url_context_s *ms_url = cardea_context; struct ms_upnp_extension_s *ms_context = ms_url->server; RMDBGLOG((ENABLE, "url_ctx 0x%08x\n", ms_url)); RMDBGLOG((ENABLE, "Wiping hash: %d\n", ms_url->url_hash)); dr = destroy_url_license( ms_context->drm_context, ms_url->url_hash); dr = destroy_url_context(cardea_context); cardea_context = NULL; RMDBGLOG((ENABLE, "ctx: 0x%08x\n", cardea_context)); return dr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -