⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ms_cardea.c

📁 1. 8623L平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2005. All rights reserved. * */#define ALLOW_OS_CODE 1#include "rmdef/rmdef.h"#include "rmcore/include/rmcore.h"#include "rmcci/include/output_cci.h"#include "../include/ms_cardea_types.h"#include "wmdrmndcoreapi.h"#include "../include/ms_cardea.h"#include "../../rmlibwmdrmndupnp/include/ms_upnp.h"#if 0#define CARDEADBG ENABLE#else#define CARDEADBG DISABLE#endif#if 0#define PACKETDBG ENABLE#else#define PACKETDBG DISABLE#endif/* For testing create a fake device for any url in init_carde *//* #define TEST_FAKE_DEVICE */#ifdef TEST_FAKE_DEVICEextern wmdrmnet_context * init_wmdrmnet_context_fake(RMuint8 *content_key);/* Harcoded key for test purpose*/static RMuint8 content_key[] = { /* 16 bytes */	0x58, 0xfa, 0x13, 0x0e, 0xef, 0x29, 0x19, 0xfe,	0x26, 0x7f, 0xb6, 0xe1, 0xc8, 0x9d, 0x21, 0x66 };#endif/** All the knwon ms_device, keep track of them, also used by ms_cardea.h, so not static */struct ms_upnp_extension_s *ms_device[MAX_MS_DEVICE]; #if (EM86XX_CHIP==EM86XX_CHIPID_TANGO2)//// Note: The macrovision guid in the M$ docs is {C3FD11C6-F8B7-4d20-B008-1DB17D61F2DA}//       The macrovision guid in the license is {C611FDC3-B7F8-204d-B008-1DB17D61F2DA}//		 It appears that the guid a mixture of varying width fields with differing endiannessstatic RMuint8 MacroVision_ACP_GUID1[] = { 0xc6,0x11,0xfd,0xc3, 0xb7,0xf8, 0x20,0x4d, 0xb0,0x08, 0x1d,0xb1,0x7d,0x61,0xf2,0xda };// Component Output constraint {811C5110-46C8-4C6E-8163-c0482A15D47E}static RMuint8 ComponentOut_Constraint_GUID[] = { 0x10,0x51,0x1c,0x81, 0xc8,0x46, 0x6e,0x4c, 0x81,0x63, 0xc0,0x48,0x2a,0x15,0xd4,0x7e };#endif// http://cr.yp.to/cdb/cdb.txtstatic RMuint32 cdb_hash(RMuint8 *string, RMint32 length){	RMuint32 h = 5381;	for (; length >= 0;length--)		h = ((h<<5) + h) ^ string[length];	h = h % 256;	RMDBGLOG((ENABLE, "hashed to id: 0x%08x vs 0x%08x\n", h,  h ^ 0x0000000));	return h;}/** * Initialize CARDEA for a given URL * * This function tries to get the CARDEA session associated with the URL. If no * session is opened for this URL, returns NULL. * * @param url - url for which a session header is required * @return NULL if no session header is available */RMint32 init_cardea(const RMascii *url){	RMuint32 i;	RMstatus status;	for (i=0;i<MAX_MS_DEVICE;i++){		RMDBGLOG((ENABLE,"Inspecting device: %d\n", i));		if (ms_device[i] != NULL ) {			RMDBGLOG((ENABLE,"Inspecting device: %d\n", i));			/* Initialize CARDEA core */			status = init_cardea_core((wmdrmnet_context*)ms_device[i]->drm_context);			if (RMFAILED(status)) {				RMDBGLOG((ENABLE,"Cannot initialize CARDEA core\n"));				return -1;			}			return 0;		}	}	RMDBGLOG((ENABLE,"Cannot initialize CARDEA core\n"));	return -1;}void * init_cardea_url(struct ms_upnp_extension_s *ms_upnp, RMascii *url, RMascii *session_header){	RMint32 i;	struct ms_url_context_s *new_ctx = NULL;	if ( url == NULL ) {		RMDBGLOG((ENABLE, "passed URL is NULL!\n"));		return NULL;	}	RMDBGLOG((ENABLE, "Inserting url in device: 0x%08x\n", ms_upnp));	for (i=0; (i <= MAX_URL_CTX) && (ms_upnp->urls[i] != NULL); i++) {}		RMDBGLOG((ENABLE, "Searched through %d structs\n", i));	if ((i == MAX_URL_CTX)) {			i=0;			// we searched through the whole list, but there is a 			// allocated context at slot 0, which means we have no 			// free slots			if (ms_upnp->urls[0] != NULL) {				RMDBGLOG((ENABLE, "All slots appear to be full.. sorry!\n", i));				return NULL;			}	}	RMDBGLOG((ENABLE, "Inserting new URL ctx at position: %d\n", i));	new_ctx = (struct ms_url_context_s *)RMMalloc(sizeof(struct ms_url_context_s));	ms_upnp->urls[i] = new_ctx;	new_ctx->url = RMMallocAndDuplicateAscii(url);	new_ctx->url_hash = cdb_hash((RMuint8*)url, RMasciiLength(url));	new_ctx->license_present = FALSE;	new_ctx->server = ms_upnp;	new_ctx->server->use_count++;//	printf("new_ctx->server->use_count = %d\n",new_ctx->server->use_count);	if ( session_header == NULL ) {		RMDBGLOG((ENABLE, "pass NULL session header\n"));		new_ctx->session_header = NULL;	}	else		new_ctx->session_header = RMMallocAndDuplicateAscii(session_header);	/* Clear MS stream context */	RMMemset(new_ctx->ms_stream_decryption_context, 0, sizeof(new_ctx->ms_stream_decryption_context));	RMDBGLOG((ENABLE, "New url ctx at 0x%08x\n",  ms_upnp->urls[i]));	return new_ctx;}RMstatus destroy_url_context(void *ctx){	struct ms_url_context_s *url_ctx = (struct ms_url_context_s *)ctx;	RMuint32 i = 0;	if( url_ctx == NULL ) {		RMDBGLOG((ENABLE, "passed a null pointer... not erasing\n"));		return RM_ERROR;	}	if(url_ctx->server != NULL)	{		//printf("destroy_url_context  url_ctx->server=%x\n",url_ctx->server);	}	for (i=0; (i < MAX_URL_CTX) && (url_ctx->server->urls[i] != url_ctx);i++) {}	if ( i == MAX_URL_CTX ) {		RMDBGLOG((ENABLE, "Unable to find URL in this server, corrupted pointer ?\n"));		return RM_ERROR;	}	RMDBGLOG((ENABLE, "Destroying url ctx at: 0x%08x\n", ctx));	if ( url_ctx->session_header != NULL ) {			RMFree(url_ctx->session_header);			url_ctx->session_header = NULL;	}	if ( url_ctx->url != NULL ) {			RMFree(url_ctx->url);			url_ctx->url = NULL;	}		url_ctx->server->use_count--;	if(url_ctx->server->use_count == 0)	{				RMDBGLOG((ENABLE,"calling release_cardea from destroy_url_context \n"));		release_cardea(url_ctx);	}	url_ctx->server->urls[i] = NULL;	url_ctx->server = NULL;		RMFree(url_ctx);		return RM_OK;}/**  * Release CARDEA session  *  * Releases a session previously allocated via init_cardea()  *  * @param cardea_context - value returned by init_cardea()  * @return RM_OK on success  *         RM_ERROR otherwise  */RMstatus release_cardea(void *cardea_context) {	int			i,j;	RMstatus	status = RM_OK;	struct ms_url_context_s *url_ctx = ( struct ms_url_context_s *) cardea_context;	struct ms_upnp_extension_s *ms_context;	RMbool	found = FALSE; 	for (i=0;i<MAX_MS_DEVICE;i++){			for ( j=0; j < MAX_URL_CTX; j++)		{			if((ms_device[i] != NULL ) &&  (ms_device[i]->urls[j] == cardea_context))			{				found = TRUE;				break;			}					}		if(found == TRUE)			break;				}	if( !found ) {		RMDBGLOG((ENABLE, "Unable to find url context 0x%08x, not destroying...\n", cardea_context));				return RM_ERROR;	} 		ms_context = url_ctx->server;	for (i=0;i<MAX_MS_DEVICE;i++){		if ( ms_device[i] == ms_context ) {			if ( ms_device[i]->use_count == 0 ) {				destroy_ms_device( ms_context );			}			status = RM_OK;			break;		}		}		return status;}/** * Terminate CARDEA * * This function handles the termination of all cardea services *  * @return RM_OK on success */RMstatus term_cardea(){	/* Terminate CARDEA core */	return term_cardea_core();}static void *find_url(struct ms_upnp_extension_s *ms_upnp, RMascii *url){	RMint32 i;	struct ms_url_context_s *current_url;		if ( url == NULL ) {			RMDBGLOG((ENABLE, "Attempting to pass NULL for search!\n"));			return NULL;	} 	for (i=0; (i < MAX_URL_CTX) /*&& (ms_upnp->urls[i] != NULL)*/;i++) { 			if(ms_upnp->urls[i] != NULL) 			{ 					current_url = ms_upnp->urls[i]; 				 				RMDBGLOG((ENABLE, "Searching for url: 0x%08x\n", current_url->url)); 				if ( (current_url->url != NULL) && 				(RMCompareAscii(current_url->url, url)) ) { 					RMDBGLOG((ENABLE, "found url context... 0x%08x\n", current_url)); 						return current_url; 				} 			}	}	RMDBGLOG((ENABLE, "Did not find any matching urls!!!\n"));	return NULL;}void * find_cardea_url(RMascii *url){	RMint32 i;	void *ctx;		if ( url == NULL ) {			RMDBGLOG((ENABLE, "Attempting to pass NULL for search!\n"));			return NULL;	}	for (i=0;i<MAX_MS_DEVICE;i++){		if ( ms_device[i] != NULL ) {			if( (ctx = find_url(ms_device[i], url)) != NULL ) {				RMDBGLOG((ENABLE, "Found matching device for url: 0x%08x\n", ms_device[i]));				return ctx;			}		}	}	return NULL;}void * find_cardea_device(RMascii *url){	RMint32 i;	void *ctx;	for (i=0;i<MAX_MS_DEVICE;i++){		if ( ms_device[i] != NULL ) {			if( (ctx = find_url(ms_device[i], url)) != NULL ) {				RMDBGLOG((ENABLE, "Found matching device for url: 0x%08x\n", ms_device[i]));				return ms_device[i];			}		}	}	return NULL;}RMbool should_decrypt(void *cardea_ctx){	struct ms_url_context_s *url_ctx = (struct ms_url_context_s *)cardea_ctx;	if (url_ctx == NULL) {		RMDBGLOG((ENABLE, "passed NULL pointer... \n"));		return FALSE;	}	RMDBGLOG((ENABLE, "current ctx: 0x%08x\n", url_ctx ));	RMDBGLOG((ENABLE, "URL has license ? %s\n", url_ctx->license_present ? "Yes" : "No"));	return url_ctx->license_present;}/** * Update the sample ID for a particuler stream and media object * * @param cardea_context - the context to update * @param stream_index - current stream index * @param media_object_number - current media object number * @param sample_id - pointer to the sample ID data * @param sample_id_size - size of the sample id (should be 8) */void update_cardea_sample_id(		void * cardea_playback_url,		RMuint16 stream_index, 		RMuint32 media_object_number, 		RMuint8 *sample_id, 		RMuint32 sample_id_size){	struct ms_url_context_s *url_ctx = (struct ms_url_context_s *) cardea_playback_url;	struct ms_upnp_extension_s *ms_context = (struct ms_upnp_extension_s *) url_ctx->server;	if (ms_context == NULL){		RMDBGLOG((ENABLE,"** Error ** NULL context\n"));		return;	}		if ( url_ctx == NULL ) {		RMDBGLOG((ENABLE,"** Error ** NULL url context\n"));		return;	}		RMDBGLOG((ENABLE,"url_ctx: 0x%08x , key id: %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;	}	if (sample_id_size != 8)		RMDBGLOG((ENABLE,"** Warning ** sample Id size is not 8 (%ld)\n", sample_id_size));	if (url_ctx->ms_stream_decryption_context[stream_index].media_object_number != media_object_number){		url_ctx->ms_stream_decryption_context[stream_index].media_object_number = media_object_number;		RMMemset(url_ctx->ms_stream_decryption_context[stream_index].sample_id, 0, 8);		RMMemcpy(url_ctx->ms_stream_decryption_context[stream_index].sample_id, sample_id, sample_id_size);		/* Reset the byte count since we change media object */		url_ctx->ms_stream_decryption_context[stream_index].byte_count = 0;			RMDBGLOG((CARDEADBG,"ST:%02d,MON:%04lu,SID:0x%08lx%08lx\n", stream_index, media_object_number,					RMbeBufToUint32(url_ctx->ms_stream_decryption_context[stream_index].sample_id),					RMbeBufToUint32(url_ctx->ms_stream_decryption_context[stream_index].sample_id+4)));						}	/* If we are here, it means the url associated with the CARDEA context	 * has been or is currently being retrieved, so the license is not	 * valid anymore, reset the URL and session header fields */	//if (url_ctx->url != NULL){	//	RMFree(url_ctx->url);	//	url_ctx->url = NULL;	//}	if (url_ctx->session_header != NULL){		RMFree(url_ctx->session_header);		url_ctx->session_header = NULL;	}}/** * Decrypt cardea encrypted data (in place) * * @param cardea_context - the current cardea context * @param stream_index - current stream index * @param media_object_number - current media object number * @param buf - pointer to the data to decrypt * @param size - size of the data to decrypt * @return RM_OK on success

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -