19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <parser_dm.h> 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <parser_dcf.h> 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <svc_drm.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "log.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DRM_SKIP_SPACE_TAB(p) while( (*(p) == ' ') || (*(p) == '\t') ) \ 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p++ 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttypedef enum _DM_PARSE_STATUS { 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DM_PARSE_START, 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DM_PARSING_RIGHTS, 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DM_PARSING_CONTENT, 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DM_PARSE_END 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} DM_PARSE_STATUS; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int drm_strnicmp(const uint8_t* s1, const uint8_t* s2, int32_t n) 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n < 0 || NULL == s1 || NULL == s2) 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n == 0) 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (n-- != 0 && tolower(*s1) == tolower(*s2)) 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n == 0 || *s1 == '\0' || *s2 == '\0') 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s1++; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s2++; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return tolower(*s1) - tolower(*s2); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst uint8_t * drm_strnstr(const uint8_t * str, const uint8_t * strSearch, int32_t len) 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t i, stringLen; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == str || NULL == strSearch || len <= 0) 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stringLen = strlen((char *)strSearch); 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < len - stringLen + 1; i++) { 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (str[i] == *strSearch && 0 == memcmp(str + i, strSearch, stringLen)) 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return str + i; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* See parser_dm.h */ 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t drm_parseDM(const uint8_t *buffer, int32_t bufferLen, T_DRM_DM_Info *pDmInfo) 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t *pStart = NULL, *pEnd = NULL; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const uint8_t *pBufferEnd; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t contentLen, leftLen; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DM_PARSE_STATUS status = DM_PARSE_START; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t boundaryLen; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == buffer || bufferLen <= 0 || NULL == pDmInfo) 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Find the end of the input buffer */ 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pBufferEnd = buffer + bufferLen; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = bufferLen; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Find out the boundary */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart = drm_strnstr(buffer, (uint8_t *)"--", bufferLen); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pStart) 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; /* No boundary error */ 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = pStart; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Record the boundary */ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* if can not find the CRLF, return FALSE */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pEnd) 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy((char *)pDmInfo->boundary, (char *)pStart, pEnd - pStart); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boundaryLen = strlen((char *)pDmInfo->boundary) + 2; /* 2 means: '\r' and '\n' */ 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd += 2; /* skip the '\r' and '\n' */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart = pEnd; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = pBufferEnd - pStart; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->transferEncoding = DRM_MESSAGE_CODING_7BIT; /* According RFC2045 chapter 6.1, the default value should be 7bit.*/ 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char *)pDmInfo->contentType, "text/plain"); /* According RFC2045 chapter 5.2, the default value should be "text/plain". */ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Deal the header information */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((('\r' != *pStart) || ('\n' != *(pStart + 1))) && pStart < pBufferEnd) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pEnd) 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 != pDmInfo->deliveryType) { /* This means the delivery type has been confirmed */ 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strncmp((char *)pStart, HEADERS_TRANSFER_CODING, HEADERS_TRANSFER_CODING_LEN)) { 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart += HEADERS_TRANSFER_CODING_LEN; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRM_SKIP_SPACE_TAB(pStart); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_7BIT, pEnd - pStart)) 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->transferEncoding = DRM_MESSAGE_CODING_7BIT; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_8BIT, pEnd - pStart)) 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->transferEncoding = DRM_MESSAGE_CODING_8BIT; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_BINARY, pEnd - pStart)) 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->transferEncoding = DRM_MESSAGE_CODING_BINARY; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (0 == strncmp((char *)pStart, TRANSFER_CODING_TYPE_BASE64, pEnd - pStart)) 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->transferEncoding = DRM_MESSAGE_CODING_BASE64; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; /* Unknown transferCoding error */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_TYPE, HEADERS_CONTENT_TYPE_LEN)) { 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart += HEADERS_CONTENT_TYPE_LEN; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRM_SKIP_SPACE_TAB(pStart); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pEnd - pStart > 0) { 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy((char *)pDmInfo->contentType, (char *)pStart, pEnd - pStart); 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentType[pEnd - pStart] = '\0'; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_ID, HEADERS_CONTENT_ID_LEN)) { 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t tmpBuf[MAX_CONTENT_ID] = {0}; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t *pTmp; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart += HEADERS_CONTENT_ID_LEN; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRM_SKIP_SPACE_TAB(pStart); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* error: more than one content id */ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if(drm_strnstr(pStart, (uint8_t*)HEADERS_CONTENT_ID, pBufferEnd - pStart)){ 1415baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("drm_dmParser: error: more than one content id\r\n"); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSING_CONTENT; /* can go here means that the rights object has been parsed. */ 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Change the format from <...> to cid:... */ 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != (pTmp = (uint8_t *)memchr((char *)pStart, '<', pEnd - pStart))) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy((char *)tmpBuf, (char *)(pTmp + 1), pEnd - pTmp - 1); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL != (pTmp = (uint8_t *)memchr((char *)tmpBuf, '>', pEnd - pTmp - 1))) { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *pTmp = '\0'; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(pDmInfo->contentID, 0, MAX_CONTENT_ID); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf((char *)pDmInfo->contentID, "%s%s", "cid:", (int8_t *)tmpBuf); 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { /* First confirm delivery type, Forward_Lock, Combined Delivery or Separate Delivery */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == drm_strnicmp(pStart, (uint8_t *)HEADERS_CONTENT_TYPE, HEADERS_CONTENT_TYPE_LEN)) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart += HEADERS_CONTENT_TYPE_LEN; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project DRM_SKIP_SPACE_TAB(pStart); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pEnd - pStart > 0) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strncpy((char *)pDmInfo->contentType, (char *)pStart, pEnd - pStart); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentType[pEnd - pStart] = '\0'; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (0 == strcmp((char *)pDmInfo->contentType, DRM_MIME_TYPE_RIGHTS_XML)) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->deliveryType = COMBINED_DELIVERY; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSING_RIGHTS; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (0 == strcmp((char *)pDmInfo->contentType, DRM_MIME_TYPE_CONTENT)) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->deliveryType = SEPARATE_DELIVERY_FL; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSING_CONTENT; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else if (0 == pDmInfo->deliveryType) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->deliveryType = FORWARD_LOCK; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSING_CONTENT; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd += 2; /* skip the '\r' and '\n' */ 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart = pEnd; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = pBufferEnd - pStart; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart += 2; /* skip the second CRLF: "\r\n" */ 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = pStart; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Deal the content part, including rel or real content */ 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (leftLen > 0) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == (pEnd = memchr(pEnd, '\r', leftLen))) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = pBufferEnd; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; /* no boundary found */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = pBufferEnd - pEnd; 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (leftLen < boundaryLen) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = pBufferEnd; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; /* here means may be the boundary has been split */ 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (('\n' == *(pEnd + 1)) && (0 == memcmp(pEnd + 2, pDmInfo->boundary, strlen((char *)pDmInfo->boundary)))) 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; /* find the boundary here */ 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd++; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen--; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pEnd >= pBufferEnd) 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentLen = DRM_UNKNOWN_DATA_LEN; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentLen = pEnd - pStart; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch(pDmInfo->deliveryType) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case FORWARD_LOCK: 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentLen = contentLen; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentOffset = pStart - buffer; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSE_END; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case COMBINED_DELIVERY: 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DM_PARSING_RIGHTS == status) { 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->rightsLen = contentLen; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->rightsOffset = pStart - buffer; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentLen = contentLen; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentOffset = pStart - buffer; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSE_END; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case SEPARATE_DELIVERY_FL: 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project T_DRM_DCF_Info dcfInfo; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint8_t* pEncData = NULL; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(&dcfInfo, 0, sizeof(T_DRM_DCF_Info)); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DRM_UNKNOWN_DATA_LEN == contentLen) 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project contentLen = pEnd - pStart; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (FALSE == drm_dcfParser(pStart, contentLen, &dcfInfo, &pEncData)) 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentLen = dcfInfo.EncryptedDataLen; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pDmInfo->contentOffset = pEncData - buffer; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char *)pDmInfo->contentType, (char *)dcfInfo.ContentType); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char *)pDmInfo->contentID, (char *)dcfInfo.ContentURI); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char *)pDmInfo->rightsIssuer, (char *)dcfInfo.Rights_Issuer); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status = DM_PARSE_END; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project default: 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DM_PARSING_RIGHTS == status) { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* Here means the rights object data has been completed, boundary must exist */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = pBufferEnd - pEnd; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart = drm_strnstr(pEnd, pDmInfo->boundary, leftLen); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pStart) 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project leftLen = pBufferEnd - pStart; 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd = drm_strnstr(pStart, (uint8_t *)DRM_NEW_LINE_CRLF, leftLen); 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (NULL == pEnd) 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return FALSE; /* only rights object, no media object, error */ 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pEnd += 2; /* skip the "\r\n" */ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pStart = pEnd; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (DM_PARSE_END != status); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return TRUE; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 272