📄 dtcp_callbacks.c
字号:
/* * * Copyright (c) Sigma Designs, Inc. 2005. All rights reserved. * *//** @file dtcp_callbacks.c @brief DTCP callbacks suitable for use as HTTP hooks @author Glen Adams @date 2005-04-29*/#include <string.h>#include "dtcp_api.h"#include "dtcp_callbacks.h"#include "dtcp_session.h"typedef struct { void *openfn; void *closefn; void *reopenfn; void *seekfn; void *prereadfn; void *postreadfn;} httpDtcpOps_s;static httpDtcpOps_s p_httpDtcpOps = { (void *) dtcp_open_callback, (void *) dtcp_close_callback, (void *) dtcp_reopen_callback, (void *) NULL, (void *) dtcp_pre_read_callback, (void *) dtcp_post_read_callback };void *httpDtcpOps = &p_httpDtcpOps;struct dtcp_cookie *dtcp_parse_url(RMascii *url){ RMint32 port = 0; RMascii *q; RMint32 i; struct dtcp_cookie *cookie; if (url == NULL) return NULL; /* Search for a content protection flag appended to the end of the url */ if (strstr(url, "CONTENTPROTECTIONTYPE=DTCP1") == NULL) { if (strstr(url, "contentprotectiontype=dtcp1") == NULL) { return NULL; } } /* Search for the DTCP port */ if ((q = strstr(url, "DTCP1PORT=")) == NULL) { if ((q = strstr(url, "dtcp1port=")) == NULL) { return NULL; } } /* Convert the DTCP port string into an integer */ q += 10; while ((*q >= '0') && (*q <= '9')) { port = (port * 10) + (*q - '0'); q++; } /* Search for the DTCP host */ if ((q = strstr(url, "DTCP1HOST=")) == NULL) { if ((q = strstr(url, "dtcp1host=")) == NULL) { return NULL; } } /* Allocate a cookie structure */ if ((cookie = RMCalloc(1, sizeof(*cookie))) == NULL) return NULL; /* Copy the DTCP host to the cookie */ q += 10; for (i = 0; ((*q == '.') || ((*q >= '0') && (*q <= '9'))); q++) if (i < DTCPHOSTLENGTH) cookie->dtcp_host[i++] = *q; /* NULL terminate DTCP host and initialize the cookie */ cookie->dtcp_host[i] = 0; cookie->dtcp_port = port; cookie->dtcp_ake_handle = NULL; cookie->dtcp_stream_handle = NULL; cookie->dtcp_emi = 0; cookie->dtcp_emi_updated = FALSE; cookie->dtcp_inband_flag = 0; cookie->dtcp_inband_context = NULL; cookie->dtcp_inband_callback = NULL; cookie->dtcp_inband_state = 0; cookie->BufferPoolDecryptionFlag = 0; cookie->dtcp_xrpc_base_addr1 = 0; cookie->dtcp_xrpc_base_addr2 = 0; cookie->dtcp_map_addr = NULL; cookie->dtcp_RUAMalloc1Completed = FALSE; cookie->dtcp_RUAMalloc2Completed = FALSE; cookie->dtcp_RUALockCompleted = FALSE; cookie->dtcp_RUAMapCompleted = FALSE; cookie->dtcp_DMA_ptr = NULL; return cookie;}RMint32 dtcp_open_callback(struct dtcp_cookie *cookie){ /* Check the cookie */ if ((cookie == NULL) || (cookie->dtcp_ake_handle == NULL)) return(-1); /* Open a DTCP stream */ if (dtcp_interface_open_stream(&cookie->dtcp_stream_handle, cookie->dtcp_ake_handle) < 0) { RMDBGLOG((ENABLE,"dtcp_interface_open_stream failed\n")); cookie->dtcp_stream_handle = NULL; return(-1); } return (0);}RMint32 dtcp_close_callback(struct dtcp_cookie *cookie){ /* Check the cookie */ if (cookie == NULL) return(-1); /* Close a DTCP stream */ if (cookie->dtcp_stream_handle != NULL) { if (dtcp_interface_close_stream(cookie->dtcp_stream_handle) < 0) RMDBGLOG((ENABLE,"dtcp_interface_close_stream failed\n")); cookie->dtcp_stream_handle = NULL; } return (0);}RMint32 dtcp_reopen_callback(struct dtcp_cookie *cookie){ RMint32 result; /* Check the cookie */ if (cookie == NULL) return(-1); if ((result = dtcp_close_callback(cookie)) < 0) return result; if ((result = dtcp_open_callback(cookie)) < 0) return result; return (0);}RMint32 dtcp_pre_read_callback(struct dtcp_cookie *cookie, RMuint8 *buffer, RMint32 length){ /* Check the cookie */ if ((cookie == NULL) || (cookie->dtcp_stream_handle == NULL)) return(-1); /* Truncate read size if necessary to prevent reading beyond a PCP */ return(dtcp_interface_read_size(cookie->dtcp_stream_handle, length));}RMint32 dtcp_post_read_callback(struct dtcp_cookie *cookie, RMuint8 *buffer, RMint32 length, RMint32 *more_data){ RMint32 dtcp_result = 0; RMuint8 *dtcp_buffer = NULL; RMint32 dtcp_count = 0; RMuint8 *dtcp_key = NULL; RMuint8 *dtcp_iv = NULL; RMstatus err; /* Check the cookie */ if ((cookie == NULL) || (cookie->dtcp_stream_handle == NULL)) return(-1); /* Reset more data flag to FALSE */ *more_data = 0; /* Submit the buffer for DTCP processing */ dtcp_result = dtcp_interface_decrypt(cookie->dtcp_stream_handle, buffer, length, &dtcp_buffer, &dtcp_count, &cookie->dtcp_emi, cookie->dtcp_inband_flag, &dtcp_key, &dtcp_iv, cookie->BufferPoolDecryptionFlag); if (dtcp_result < 0) { RMDBGLOG((ENABLE,"dtcp_interface_decrypt failed\n")); return(dtcp_result); } if ((dtcp_count > length) || (dtcp_count + AES_BLOCK_SIZE <= length)) { RMDBGLOG((ENABLE,"dtcp_interface_decrypt returned illegal count\n")); return(-1); } /* If a key rotation has occurred, ... */ if ((length == DTCP_HEADER_SIZE + AES_BLOCK_SIZE) && (dtcp_count == AES_BLOCK_SIZE)) { RMuint8 dtcp_tmp_buffer[AES_BLOCK_SIZE]; /* Shift the 16 byte AES block to the beginning of the buffer */ memcpy(dtcp_tmp_buffer, dtcp_buffer, AES_BLOCK_SIZE); memcpy(buffer, dtcp_tmp_buffer, AES_BLOCK_SIZE); /* Set more data flag to TRUE */ *more_data = 1; /* If using inband commands, invoke the inband callback */ if ((cookie->dtcp_inband_flag != 0) && (cookie->dtcp_inband_context != NULL) && (cookie->dtcp_inband_callback != NULL) && (dtcp_key != NULL) && (dtcp_iv != NULL)) cookie->dtcp_inband_callback(cookie, dtcp_key, dtcp_iv); } if (cookie->BufferPoolDecryptionFlag && cookie->dtcp_emi) { err = buffer_pool_decryption (cookie->dtcp_DMA_ptr, buffer, dtcp_count); if (err == RM_ERROR) { RMDBGLOG((ENABLE,"buffer_pool_decryption returned error: %s \n", RMstatusToString(err))); } } /* Return actual data read */ return (dtcp_count);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -