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 <svc_drm.h>
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <drm_inner.h>
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <parser_dm.h>
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <parser_dcf.h>
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <parser_rel.h>
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <drm_rights_manager.h>
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <drm_time.h>
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <drm_decoder.h>
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "log.h"
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Current id.
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t curID = 0;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The header pointer for the session list.
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic T_DRM_Session_Node* sessionTable = NULL;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * New a session.
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic T_DRM_Session_Node* newSession(T_DRM_Input_Data data)
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s = (T_DRM_Session_Node *)malloc(sizeof(T_DRM_Session_Node));
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != s) {
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(s, 0, sizeof(T_DRM_Session_Node));
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->sessionId = curID++;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->inputHandle = data.inputHandle;
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->mimeType = data.mimeType;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->getInputDataLengthFunc = data.getInputDataLength;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->readInputDataFunc = data.readInputData;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->seekInputDataFunc = data.seekInputData;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return s;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Free a session.
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void freeSession(T_DRM_Session_Node* s)
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != s->rawContent)
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(s->rawContent);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != s->readBuf)
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(s->readBuf);
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != s->infoStruct)
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(s->infoStruct);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(s);
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Add a session to list.
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t addSession(T_DRM_Session_Node* s)
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s->next = sessionTable;
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sessionTable = s;
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return s->sessionId;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Get a session from the list.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic T_DRM_Session_Node* getSession(int32_t sessionId)
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sessionId < 0 || NULL == sessionTable)
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return NULL;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (s = sessionTable; s != NULL; s = s->next) {
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sessionId == s->sessionId)
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return s;
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return NULL;
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Remove a session from the list.
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void removeSession(int32_t sessionId)
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node *curS, *preS;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sessionId < 0 || NULL == sessionTable)
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sessionId == sessionTable->sessionId) {
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        curS = sessionTable;
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        sessionTable = curS->next;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        freeSession(curS);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (preS = sessionTable; preS->next != NULL; preS = preS->next) {
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (preS->next->sessionId == sessionId)
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            curS = preS->next;
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == preS->next)
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    preS->next = curS->next;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    freeSession(curS);
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Try to identify the mimetype according the input DRM data.
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t getMimeType(const uint8_t *buf, int32_t bufLen)
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const uint8_t *p;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == buf || bufLen <= 0)
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TYPE_DRM_UNKNOWN;
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    p = buf;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* check if it is DRM Content Format, only check the first field of Version, it must be "0x01" */
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0x01 == *p)
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TYPE_DRM_CONTENT;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* check if it is DRM Message, only check the first two bytes, it must be the start flag of boundary: "--" */
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bufLen >= 2 && '-' == *p && '-' == *(p + 1))
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TYPE_DRM_MESSAGE;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* check if it is DRM Rights XML format, only check the first several bytes, it must be: "<o-ex:rights" */
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bufLen >= 12 && 0 == strncmp("<o-ex:rights", (char *)p, 12))
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TYPE_DRM_RIGHTS_XML;
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* check if it is DRM Rights WBXML format, only check the first two bytes, it must be: 0x03, 0x0e */
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (bufLen >= 2 && 0x03 == *p && 0x0e == *(p + 1))
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TYPE_DRM_RIGHTS_WBXML;
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return TYPE_DRM_UNKNOWN;
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_skipCRLFinB64(const uint8_t* b64Data, int32_t len)
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const uint8_t* p;
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t skipLen = 0;
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == b64Data || len <= 0)
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    p = b64Data;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (p - b64Data < len) {
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if ('\r' == *p || '\n'== *p)
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            skipLen++;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p++;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return skipLen;
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_scanEndBoundary(const uint8_t* pBuf, int32_t len, uint8_t* const boundary)
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    const uint8_t* p;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t leftLen;
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t boundaryLen;
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == pBuf || len <=0 || NULL == boundary)
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    p = pBuf;
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    boundaryLen = strlen((char *)boundary) + 2; /* 2 means: '\r' and '\n' */
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    leftLen = len - (p - pBuf);
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (leftLen > 0) {
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL == (p = memchr(p, '\r', leftLen)))
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        leftLen = len - (p - pBuf);
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (leftLen < boundaryLen)
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -2; /* here means may be the boundary has been split */
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (('\n' == *(p + 1)) && (0 == memcmp(p + 2, boundary, strlen((char *)boundary))))
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return p - pBuf; /* find the boundary here */
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p++;
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        leftLen--;
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return len; /* no boundary found */
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_getLicenseInfo(T_DRM_Rights* pRights, T_DRM_Rights_Info* licenseInfo)
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != licenseInfo && NULL != pRights) {
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy((char *)licenseInfo->roId, (char *)pRights->uid);
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (1 == pRights->bIsDisplayable) {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.indicator = pRights->DisplayConstraint.Indicator;
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.count =
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.Count;
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.startDate =
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.StartTime.date;
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.startTime =
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.StartTime.time;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.endDate =
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.EndTime.date;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.endTime =
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.EndTime.time;
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.intervalDate =
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.Interval.date;
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->displayRights.intervalTime =
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->DisplayConstraint.Interval.time;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (1 == pRights->bIsPlayable) {
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.indicator = pRights->PlayConstraint.Indicator;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.count = pRights->PlayConstraint.Count;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.startDate =
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.StartTime.date;
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.startTime =
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.StartTime.time;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.endDate =
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.EndTime.date;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.endTime =
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.EndTime.time;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.intervalDate =
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.Interval.date;
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->playRights.intervalTime =
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PlayConstraint.Interval.time;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (1 == pRights->bIsExecuteable) {
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.indicator = pRights->ExecuteConstraint.Indicator;
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.count =
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.Count;
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.startDate =
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.StartTime.date;
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.startTime =
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.StartTime.time;
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.endDate =
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.EndTime.date;
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.endTime =
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.EndTime.time;
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.intervalDate =
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.Interval.date;
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->executeRights.intervalTime =
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->ExecuteConstraint.Interval.time;
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (1 == pRights->bIsPrintable) {
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.indicator = pRights->PrintConstraint.Indicator;
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.count =
2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.Count;
2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.startDate =
2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.StartTime.date;
2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.startTime =
2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.StartTime.time;
2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.endDate =
2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.EndTime.date;
2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.endTime =
2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.EndTime.time;
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.intervalDate =
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.Interval.date;
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            licenseInfo->printRights.intervalTime =
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pRights->PrintConstraint.Interval.time;
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return TRUE;
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return FALSE;
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_addRightsNodeToList(T_DRM_Rights_Info_Node **ppRightsHeader,
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       T_DRM_Rights_Info_Node *pInputRightsNode)
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights_Info_Node *pRightsNode;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == ppRightsHeader || NULL == pInputRightsNode)
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return FALSE;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pRightsNode = (T_DRM_Rights_Info_Node *)malloc(sizeof(T_DRM_Rights_Info_Node));
3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == pRightsNode)
3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return FALSE;
3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(pRightsNode, pInputRightsNode, sizeof(T_DRM_Rights_Info_Node));
3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pRightsNode->next = NULL;
3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* this means it is the first node */
3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == *ppRightsHeader)
3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *ppRightsHeader = pRightsNode;
3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else {
3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        T_DRM_Rights_Info_Node *pTmp;
3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pTmp = *ppRightsHeader;
3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (NULL != pTmp->next)
3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            pTmp = pTmp->next;
3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pTmp->next = pRightsNode;
3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return TRUE;
3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_startConsumeRights(int32_t * bIsXXable,
3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      T_DRM_Rights_Constraint * XXConstraint,
3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                      int32_t * writeFlag)
3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DB_TIME_SysTime curDateTime;
3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_DATETIME CurrentTime;
3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t countFlag = 0;
3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint || NULL == writeFlag)
3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *bIsXXable = 0; /* Assume have invalid rights at first */
3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *writeFlag = 0;
3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT | DRM_INTERVAL_CONSTRAINT))) {
3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DRM_time_getSysTime(&curDateTime);
3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                curDateTime.hour, curDateTime.min, curDateTime.sec))
3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      CurrentTime.date, curDateTime.hour, curDateTime.min,
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      curDateTime.sec, CurrentTime.time);
3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *writeFlag = 1;
3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* If it has only one time for use, after use this function, we will delete this rights */
3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->Count <= 0) {
3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->Count-- <= 1) {
3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            countFlag = 1;
3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->StartTime.date > CurrentTime.date ||
3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (XXConstraint->StartTime.date == CurrentTime.date &&
3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             XXConstraint->StartTime.time >= CurrentTime.time)) {
3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *bIsXXable = 1;
3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_PENDING;
3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->EndTime.date < CurrentTime.date ||
3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (XXConstraint->EndTime.date == CurrentTime.date &&
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             XXConstraint->EndTime.time <= CurrentTime.time)) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *writeFlag = 1;
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t year, mon, day, hour, min, sec, date, time;
3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t ret;
3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        XXConstraint->Indicator |= DRM_END_TIME_CONSTRAINT;
3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT; /* Write off interval right */
3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *writeFlag = 1;
3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->Interval.date == 0
3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && XXConstraint->Interval.time == 0) {
3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        date = CurrentTime.date + XXConstraint->Interval.date;
4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        time = CurrentTime.time + XXConstraint->Interval.time;
4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        INT_2_YMD_HMS(year, mon, day, date, hour, min, sec, time);
4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (sec > 59) {
4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            min += sec / 60;
4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sec %= 60;
4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (min > 59) {
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hour += min / 60;
4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            min %= 60;
4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (hour > 23) {
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            day += hour / 24;
4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            hour %= 24;
4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (day > 31) {
4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mon += day / 31;
4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            day %= 31;
4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (mon > 12) {
4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            year += mon / 12;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mon %= 12;
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (day > (ret = drm_monthDays(year, mon))) {
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            day -= ret;
4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mon++;
4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mon > 12) {
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mon -= 12;
4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                year++;
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        YMD_HMS_2_INT(year, mon, day, XXConstraint->EndTime.date, hour,
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      min, sec, XXConstraint->EndTime.time);
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (1 != countFlag)
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *bIsXXable = 1; /* Can go here ,so  right must be valid */
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_startCheckRights(int32_t * bIsXXable,
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    T_DRM_Rights_Constraint * XXConstraint)
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DB_TIME_SysTime curDateTime;
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_DATETIME CurrentTime;
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint)
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *bIsXXable = 0; /* Assume have invalid rights at first */
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT))) {
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        DRM_time_getSysTime(&curDateTime);
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                curDateTime.hour, curDateTime.min, curDateTime.sec))
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      CurrentTime.date, curDateTime.hour, curDateTime.min,
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                      curDateTime.sec, CurrentTime.time);
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->Count <= 0) {
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->StartTime.date > CurrentTime.date ||
4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (XXConstraint->StartTime.date == CurrentTime.date &&
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             XXConstraint->StartTime.time >= CurrentTime.time)) {
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            *bIsXXable = 1;
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_PENDING;
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->EndTime.date < CurrentTime.date ||
4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (XXConstraint->EndTime.date == CurrentTime.date &&
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project             XXConstraint->EndTime.time <= CurrentTime.time)) {
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (XXConstraint->Interval.date == 0 && XXConstraint->Interval.time == 0) {
4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_EXPIRED;
4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *bIsXXable = 1;
5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t drm_checkRoAndUpdate(int32_t id, int32_t permission)
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t writeFlag = 0;
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t roAmount;
5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t validRoAmount = 0;
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t flag = DRM_FAILURE;
5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t i, j;
5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights *pRo;
5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights *pCurRo;
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t * pNumOfPriority;
5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t iNum;
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights_Constraint * pCurConstraint;
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights_Constraint * pCompareConstraint;
5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int priority[8] = {1, 2, 4, 3, 8, 6, 7, 5};
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    validRoAmount = roAmount;
5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (roAmount < 1)
5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_NO_RIGHTS;
5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pRo = malloc(roAmount * sizeof(T_DRM_Rights));
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pCurRo = pRo;
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == pRo)
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO)) {
5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(pRo);
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /** check the right priority */
5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pNumOfPriority = malloc(sizeof(int32_t) * roAmount);
5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for(i = 0; i < roAmount; i++) {
5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        iNum = roAmount - 1;
5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for(j = 0; j < roAmount; j++) {
5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(i == j)
5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch(permission) {
5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DRM_PERMISSION_PLAY:
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCurConstraint = &pRo[i].PlayConstraint;
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCompareConstraint = &pRo[j].PlayConstraint;
5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DRM_PERMISSION_DISPLAY:
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCurConstraint = &pRo[i].DisplayConstraint;
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCompareConstraint = &pRo[j].DisplayConstraint;
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DRM_PERMISSION_EXECUTE:
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCurConstraint = &pRo[i].ExecuteConstraint;
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCompareConstraint = &pRo[j].ExecuteConstraint;
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case DRM_PERMISSION_PRINT:
5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCurConstraint = &pRo[i].PrintConstraint;
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pCompareConstraint = &pRo[j].PrintConstraint;
5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            default:
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(pRo);
5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(pNumOfPriority);
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_FAILURE;
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /**get priority by Indicator*/
5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(0 == (pCurConstraint->Indicator & DRM_NO_CONSTRAINT) &&
5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                0 == (pCompareConstraint->Indicator & DRM_NO_CONSTRAINT)) {
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int num1, num2;
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    num1 = (pCurConstraint->Indicator & 0x0e) >> 1;
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    num2 = (pCompareConstraint->Indicator & 0x0e) >> 1;
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if(priority[num1] > priority[num2]) {
5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        iNum--;
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else if(priority[pCurConstraint->Indicator] < priority[pCompareConstraint->Indicator])
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        continue;
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if(pCurConstraint->Indicator > pCompareConstraint->Indicator) {
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                iNum--;
5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else if(pCurConstraint->Indicator < pCompareConstraint->Indicator)
5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(0 != (pCurConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) {
5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if(pCurConstraint->EndTime.date < pCompareConstraint->EndTime.date) {
5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iNum--;
5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if(pCurConstraint->EndTime.time < pCompareConstraint->EndTime.time) {
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iNum--;
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(0 != (pCurConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) {
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if(pCurConstraint->Interval.date < pCompareConstraint->Interval.date) {
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iNum--;
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if(pCurConstraint->Interval.date > pCompareConstraint->Interval.date)
6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if(pCurConstraint->Interval.time < pCompareConstraint->Interval.time) {
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iNum--;
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if(pCurConstraint->Interval.time > pCompareConstraint->Interval.time)
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(0 != (pCurConstraint->Indicator & DRM_COUNT_CONSTRAINT)) {
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if(pCurConstraint->Count < pCompareConstraint->Count) {
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    iNum--;
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else if(pCurConstraint->Count > pCompareConstraint->Count)
6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    continue;
6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(i < j)
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                iNum--;
6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pNumOfPriority[iNum] = i;
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i = 0; i < validRoAmount; i++) {
6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /** check the right priority */
6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (pNumOfPriority[i] >= validRoAmount)
6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pCurRo = pRo + pNumOfPriority[i];
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (permission) {
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_PLAY:
6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flag =
6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                drm_startConsumeRights(&pCurRo->bIsPlayable,
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &pCurRo->PlayConstraint, &writeFlag);
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_DISPLAY:
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flag =
6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                drm_startConsumeRights(&pCurRo->bIsDisplayable,
6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &pCurRo->DisplayConstraint,
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &writeFlag);
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_EXECUTE:
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flag =
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                drm_startConsumeRights(&pCurRo->bIsExecuteable,
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &pCurRo->ExecuteConstraint,
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &writeFlag);
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_PRINT:
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flag =
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                drm_startConsumeRights(&pCurRo->bIsPrintable,
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                       &pCurRo->PrintConstraint, &writeFlag);
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(pNumOfPriority);
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(pRo);
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* Here confirm the valid RO amount and set the writeFlag */
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == pCurRo->bIsPlayable && 0 == pCurRo->bIsDisplayable &&
6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            0 == pCurRo->bIsExecuteable && 0 == pCurRo->bIsPrintable) {
6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t iCurPri;
6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /** refresh the right priority */
6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            iCurPri = pNumOfPriority[i];
6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for(j = i; j < validRoAmount - 1; j++)
6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pNumOfPriority[j] = pNumOfPriority[j + 1];
6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if(iCurPri != validRoAmount - 1) {
6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(pCurRo, pRo + validRoAmount - 1,
6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    sizeof(T_DRM_Rights));
6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for(j = 0; j < validRoAmount -1; j++) {
6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if(validRoAmount - 1 == pNumOfPriority[j])
6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        pNumOfPriority[j] = iCurPri;
6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* Here means it is not the last one RO, so the invalid RO should be deleted */
6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            writeFlag = 1;
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            validRoAmount--; /* If current right is invalid */
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            i--;
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* If the flag is TRUE, this means: we have found a valid RO, so break, no need to check other RO */
6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DRM_SUCCESS == flag)
6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (1 == writeFlag) {
6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /* Delete the *.info first */
6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //drm_removeIdInfoFile(id);
6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (FALSE == drm_writeOrReadInfo(id, pRo, &validRoAmount, SAVE_ALL_RO))
6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            flag = DRM_FAILURE;
6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(pNumOfPriority);
7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(pRo);
7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return flag;
7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_installRights(T_DRM_Input_Data data, T_DRM_Rights_Info* pRightsInfo)
7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t *buf;
7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t dataLen, bufLen;
7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights rights;
7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 == data.inputHandle)
7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_RIGHTS_DATA_INVALID;
7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Get input rights data length */
7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dataLen = data.getInputDataLength(data.inputHandle);
7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dataLen <= 0)
7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_RIGHTS_DATA_INVALID;
7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Check if the length is larger than DRM max malloc length */
7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dataLen > DRM_MAX_MALLOC_LEN)
7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bufLen = DRM_MAX_MALLOC_LEN;
7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        bufLen = dataLen;
7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    buf = (uint8_t *)malloc(bufLen);
7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == buf)
7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Read input data to buffer */
7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 >= data.readInputData(data.inputHandle, buf, bufLen)) {
7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(buf);
7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_RIGHTS_DATA_INVALID;
7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* if the input mime type is unknown, DRM engine will try to recognize it. */
7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (TYPE_DRM_UNKNOWN == data.mimeType)
7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.mimeType = getMimeType(buf, bufLen);
7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch(data.mimeType) {
7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_MESSAGE: /* in case of Combined Delivery, extract the rights part to install */
7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            T_DRM_DM_Info dmInfo;
7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_parseDM(buf, bufLen, &dmInfo)) {
7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(buf);
7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_RIGHTS_DATA_INVALID;
7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* if it is not Combined Delivery, it can not use to "SVC_drm_installRights" */
7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (COMBINED_DELIVERY != dmInfo.deliveryType || dmInfo.rightsOffset <= 0 || dmInfo.rightsLen <= 0) {
7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(buf);
7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_RIGHTS_DATA_INVALID;
7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(&rights, 0, sizeof(T_DRM_Rights));
7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_relParser(buf + dmInfo.rightsOffset, dmInfo.rightsLen, TYPE_DRM_RIGHTS_XML, &rights)) {
7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(buf);
7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_RIGHTS_DATA_INVALID;
7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_RIGHTS_XML:
7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_RIGHTS_WBXML:
7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memset(&rights, 0, sizeof(T_DRM_Rights));
7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (FALSE == drm_relParser(buf, bufLen, data.mimeType, &rights)) {
7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(buf);
7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_RIGHTS_DATA_INVALID;
7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_CONTENT: /* DCF should not using "SVC_drm_installRights", it should be used to open a session. */
7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_UNKNOWN:
7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    default:
7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(buf);
7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(buf);
7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* append the rights information to DRM engine storage */
7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_appendRightsInfo(&rights))
7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(pRightsInfo, 0, sizeof(T_DRM_Rights_Info));
7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    drm_getLicenseInfo(&rights, pRightsInfo);
7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_openSession(T_DRM_Input_Data data)
7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t session;
7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t dataLen;
7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 == data.inputHandle)
8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Get input data length */
8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    dataLen = data.getInputDataLength(data.inputHandle);
8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dataLen <= 0)
8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = newSession(data);
8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Check if the length is larger than DRM max malloc length */
8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (dataLen > DRM_MAX_MALLOC_LEN)
8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->rawContentLen = DRM_MAX_MALLOC_LEN;
8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->rawContentLen = dataLen;
8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s->rawContent = (uint8_t *)malloc(s->rawContentLen);
8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s->rawContent)
8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* Read input data to buffer */
8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 >= data.readInputData(data.inputHandle, s->rawContent, s->rawContentLen)) {
8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        freeSession(s);
8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* if the input mime type is unknown, DRM engine will try to recognize it. */
8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (TYPE_DRM_UNKNOWN == data.mimeType)
8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.mimeType = getMimeType(s->rawContent, s->rawContentLen);
8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch(data.mimeType) {
8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_MESSAGE:
8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            T_DRM_DM_Info dmInfo;
8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_parseDM(s->rawContent, s->rawContentLen, &dmInfo)) {
8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                freeSession(s);
8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_DATA_INVALID;
8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->deliveryMethod = dmInfo.deliveryType;
8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SEPARATE_DELIVERY_FL == s->deliveryMethod)
8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength = DRM_UNKNOWN_DATA_LEN;
8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else
8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength = dmInfo.contentLen;
8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->transferEncoding = dmInfo.transferEncoding;
8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->contentOffset = dmInfo.contentOffset;
8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->bEndData = FALSE;
8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcpy((char *)s->contentType, (char *)dmInfo.contentType);
8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcpy((char *)s->contentID, (char *)dmInfo.contentID);
8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (SEPARATE_DELIVERY_FL == s->deliveryMethod) {
8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (NULL == s->infoStruct)
8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_FAILURE;
8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dmInfo.contentLen;
8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dmInfo.rightsIssuer);
8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->infoStruct = (T_DRM_DM_Base64_Node *)malloc(sizeof(T_DRM_DM_Base64_Node));
8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (NULL == s->infoStruct)
8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_FAILURE;
8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(s->infoStruct, 0, sizeof(T_DRM_DM_Base64_Node));
8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                strcpy((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->infoStruct = (T_DRM_DM_Binary_Node *)malloc(sizeof(T_DRM_DM_Binary_Node));
8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (NULL == s->infoStruct)
8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_FAILURE;
8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memset(s->infoStruct, 0, sizeof(T_DRM_DM_Binary_Node));
8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                strcpy((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (s->contentLength > 0) {
8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t encLen, decLen;
8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    encLen = s->contentLength;
8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    s->contentLength = decLen;
8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t encLen = DRM_MAX_MALLOC_LEN - s->contentOffset, decLen;
8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t skipLen, needBytes, i;
8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint8_t *pStart;
8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t res, bFoundBoundary = FALSE;
8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pStart = s->rawContent + s->contentOffset;
9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (-1 == (skipLen = drm_skipCRLFinB64(pStart, encLen))) {
9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        freeSession(s);
9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return DRM_FAILURE;
9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    needBytes = DRM_B64_ENC_BLOCK - ((encLen - skipLen) % DRM_B64_ENC_BLOCK);
9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (needBytes < DRM_B64_ENC_BLOCK) {
9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->rawContent = (uint8_t *)realloc(s->rawContent, DRM_MAX_MALLOC_LEN + needBytes);
9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (NULL == s->rawContent) {
9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_FAILURE;
9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        i = 0;
9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        while (i < needBytes) {
9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (-1 != data.readInputData(data.inputHandle, s->rawContent + DRM_MAX_MALLOC_LEN + i, 1)) {
9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if ('\r' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i) || '\n' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i))
9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    continue;
9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                i++;
9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            } else
9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                break;
9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        encLen += i;
9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    res = drm_scanEndBoundary(pStart, encLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (-1 == res) {
9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        freeSession(s);
9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return DRM_FAILURE;
9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (-2 == res) { /* may be there is a boundary */
9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t boundaryLen, leftLen, readBytes;
9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        char* pTmp = memrchr(pStart, '\r', encLen);
9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (NULL == pTmp) {
9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_FAILURE; /* conflict */
9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        boundaryLen = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBuf = (uint8_t *)malloc(boundaryLen);
9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (NULL == s->readBuf) {
9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_FAILURE;
9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufOff = encLen - ((uint8_t *)pTmp - pStart);
9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufLen = boundaryLen - s->readBufOff;
9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        memcpy(s->readBuf, pTmp, s->readBufOff);
9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (-1 == readBytes || readBytes < s->readBufLen) {
9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_MEDIA_DATA_INVALID;
9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary)) {
9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            encLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            bFoundBoundary = TRUE;
9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (res >= 0 && res < encLen) {
9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            encLen = res;
9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            bFoundBoundary = TRUE;
9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen = decLen;
9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (bFoundBoundary)
9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->contentLength = decLen;
9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* binary data */
9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (DRM_UNKNOWN_DATA_LEN == s->contentLength) {
9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    /* try to check whether there is boundary may be split */
9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t res, binContentLen;
9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    uint8_t* pStart;
9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    int32_t bFoundBoundary = FALSE;
9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    pStart = s->rawContent + s->contentOffset;
9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    binContentLen = s->rawContentLen - s->contentOffset;
9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    res = drm_scanEndBoundary(pStart, binContentLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (-1 == res) {
9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        freeSession(s);
9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return DRM_FAILURE;
9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (-2 == res) { /* may be the boundary is split */
9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        int32_t boundaryLen, leftLen, readBytes;
9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        char* pTmp = memrchr(pStart, '\r', binContentLen);
9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (NULL == pTmp) {
9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_FAILURE; /* conflict */
9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBuf = (uint8_t *)malloc(boundaryLen);
9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (NULL == s->readBuf) {
9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_FAILURE;
10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufOff = binContentLen - ((uint8_t *)pTmp - pStart);
10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufLen = boundaryLen - s->readBufOff;
10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        memcpy(s->readBuf, pTmp, s->readBufOff);
10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (-1 == readBytes || readBytes < s->readBufLen) {
10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            freeSession(s);
10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_MEDIA_DATA_INVALID;
10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            binContentLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            bFoundBoundary = TRUE;
10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else {
10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (res >= 0 && res < binContentLen) {
10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            binContentLen = res;
10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            bFoundBoundary = TRUE;
10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (bFoundBoundary)
10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->contentLength = binContentLen;
10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_CONTENT:
10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        {
10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            T_DRM_DCF_Info dcfInfo;
10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            uint8_t* pEncData = NULL;
10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(&dcfInfo, 0, sizeof(T_DRM_DCF_Info));
10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_dcfParser(s->rawContent, s->rawContentLen, &dcfInfo, &pEncData)) {
10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                freeSession(s);
10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_DATA_INVALID;
10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (NULL == s->infoStruct)
10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_FAILURE;
10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->deliveryMethod = SEPARATE_DELIVERY;
10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->contentLength = dcfInfo.DecryptedDataLen;
10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dcfInfo.EncryptedDataLen;
10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->contentOffset = pEncData - s->rawContent;
10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcpy((char *)s->contentType, (char *)dcfInfo.ContentType);
10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcpy((char *)s->contentID, (char *)dcfInfo.ContentURI);
10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dcfInfo.Rights_Issuer);
10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_RIGHTS_XML:   /* rights object should using "SVC_drm_installRights", it can not open a session */
10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_RIGHTS_WBXML: /* rights object should using "SVC_drm_installRights", it can not open a session */
10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case TYPE_DRM_UNKNOWN:
10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    default:
10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        freeSession(s);
10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if ((SEPARATE_DELIVERY_FL == s->deliveryMethod || SEPARATE_DELIVERY == s->deliveryMethod) &&
10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN) {
10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint8_t keyValue[DRM_KEY_LEN];
10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t seekPos, moreBytes;
10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (TRUE == drm_getKey(s->contentID, keyValue)) {
10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength -= moreBytes;
10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    session = addSession(s);
10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (-1 == session)
10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return session;
10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getDeliveryMethod(int32_t session)
10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0)
10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return s->deliveryMethod;
10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getContentType(int32_t session, uint8_t* mediaType)
11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0 || NULL == mediaType)
11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    strcpy((char *)mediaType, (char *)s->contentType);
11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_checkRights(int32_t session, int32_t permission)
11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t id;
11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights *pRo, *pCurRo;
11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t roAmount;
11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t i;
11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t res = DRM_FAILURE;
11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0)
11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* if it is Forward-Lock cases, check it and return directly */
11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FORWARD_LOCK == s->deliveryMethod) {
11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DRM_PERMISSION_PLAY == permission ||
11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DRM_PERMISSION_DISPLAY == permission ||
11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DRM_PERMISSION_EXECUTE == permission ||
11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            DRM_PERMISSION_PRINT == permission)
11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_SUCCESS;
11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* if try to forward, only DCF can be forwarded */
11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (DRM_PERMISSION_FORWARD == permission) {
11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (SEPARATE_DELIVERY == s->deliveryMethod)
11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_SUCCESS;
11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* The following will check CD or SD other permissions */
11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (roAmount <= 0)
11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pRo = malloc(roAmount * sizeof(T_DRM_Rights));
11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == pRo)
11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO);
11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pCurRo = pRo;
11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i = 0; i < roAmount; i++) {
11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (permission) {
11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_PLAY:
11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = drm_startCheckRights(&(pCurRo->bIsPlayable), &(pCurRo->PlayConstraint));
11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_DISPLAY:
11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = drm_startCheckRights(&(pCurRo->bIsDisplayable), &(pCurRo->DisplayConstraint));
11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_EXECUTE:
11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = drm_startCheckRights(&(pCurRo->bIsExecuteable), &(pCurRo->ExecuteConstraint));
11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case DRM_PERMISSION_PRINT:
11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            res = drm_startCheckRights(&(pCurRo->bIsPrintable), &(pCurRo->PrintConstraint));
11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(pRo);
11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DRM_SUCCESS == res) {
11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            free(pRo);
11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_SUCCESS;
11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pCurRo++;
11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    free(pRo);
11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return res;
11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_consumeRights(int32_t session, int32_t permission)
12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t id;
12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0)
12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (DRM_PERMISSION_FORWARD == permission) {
12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (SEPARATE_DELIVERY == s->deliveryMethod)
12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_SUCCESS;
12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FORWARD_LOCK == s->deliveryMethod) /* Forwardlock type have utter rights */
12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return drm_checkRoAndUpdate(id, permission);
12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getContentLength(int32_t session)
12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0)
12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (DRM_UNKNOWN_DATA_LEN == s->contentLength && s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN &&
12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod)) {
12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint8_t keyValue[DRM_KEY_LEN];
12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t seekPos, moreBytes;
12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (TRUE == drm_getKey(s->contentID, keyValue)) {
12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->contentLength -= moreBytes;
12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return s->contentLength;
12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readAesData(uint8_t* buf, T_DRM_Session_Node* s, int32_t aesStart, int32_t bufLen)
12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == buf || NULL == s || aesStart < 0 || bufLen < 0)
12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -1;
12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (aesStart - s->contentOffset + bufLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength)
12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return -2;
12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (aesStart < DRM_MAX_MALLOC_LEN) {
12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (aesStart + bufLen <= DRM_MAX_MALLOC_LEN) { /* read from buffer */
12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(buf, s->rawContent + aesStart, bufLen);
12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return bufLen;
12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else { /* first read from buffer and then from InputStream */
12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t point = DRM_MAX_MALLOC_LEN - aesStart;
12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            int32_t res;
12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf) {
12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == res || -1 == res)
12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return -1;
12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res += DRM_ONE_AES_BLOCK_LEN;
12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(buf, s->rawContent + aesStart, point);
12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res = s->readInputDataFunc(s->inputHandle, buf + point, bufLen - point);
12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == res || -1 == res)
12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return -1;
12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                res += point;
12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf = TRUE;
12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return res;
12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else { /* read from InputStream */
12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t res;
12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == res || -1 == res)
13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return -1;
13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_ONE_AES_BLOCK_LEN + res;
13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readContentFromBuf(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes;
13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (offset > s->contentLength)
13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (offset == s->contentLength)
13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_EOF;
13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (offset + mediaBufLen > s->contentLength)
13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = s->contentLength - offset;
13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = mediaBufLen;
13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(mediaBuf, s->rawContent + offset, readBytes);
13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readB64ContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t encBuf[DRM_B64_ENC_BLOCK], decBuf[DRM_B64_DEC_BLOCK];
13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t encLen, decLen;
13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t i, j, piece, leftLen, firstBytes;
13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes = 0;
13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen - offset;
13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(mediaBuf, s->rawContent + offset, readBytes);
13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (s->bEndData)
13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_EOF;
13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        firstBytes = offset % DRM_B64_DEC_BLOCK;
13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (firstBytes > 0) {
13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (DRM_B64_DEC_BLOCK - firstBytes >= mediaBufLen) {
13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes = mediaBufLen;
13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return readBytes;
13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = DRM_B64_DEC_BLOCK - firstBytes;
13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    leftLen = mediaBufLen - readBytes;
13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    encLen = (leftLen - 1) / DRM_B64_DEC_BLOCK * DRM_B64_ENC_BLOCK + DRM_B64_ENC_BLOCK;
13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    piece = encLen / DRM_B64_ENC_BLOCK;
13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (i = 0; i < piece; i++) {
13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        j = 0;
13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        while (j < DRM_B64_ENC_BLOCK) {
13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *(encBuf + j) = s->readBuf[s->readBufOff];
13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->readBufOff++;
13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->readBufLen--;
13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else { /* read from InputStream */
13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == s->readInputDataFunc(s->inputHandle, encBuf + j, 1))
13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_MEDIA_DATA_INVALID;
13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ('\r' == *(encBuf + j) || '\n' == *(encBuf + j))
13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue; /* skip CRLF */
13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if ('-' == *(encBuf + j)) {
13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int32_t k, len;
13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* invalid base64 data, it comes to end boundary */
13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 != j)
13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_MEDIA_DATA_INVALID;
13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* check whether it is really the boundary */
13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                len = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (NULL == s->readBuf) {
13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    s->readBuf = (uint8_t *)malloc(len);
13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (NULL == s->readBuf)
13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        return DRM_FAILURE;
13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->readBuf[0] = '-';
13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                for (k = 0; k < len - 1; k++) {
13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        *(s->readBuf + k + 1) = s->readBuf[s->readBufOff];
13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufOff++;
14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        s->readBufLen--;
14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    } else { /* read from InputStream */
14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + 1, 1))
14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            return DRM_MEDIA_DATA_INVALID;
14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == memcmp(s->readBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, len))
14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    s->bEndData = TRUE;
14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                else
14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_MEDIA_DATA_INVALID;
14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            j++;
14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (TRUE == s->bEndData) { /* it means come to the end of base64 data */
14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (0 == readBytes)
14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_EOF;
14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        encLen = DRM_B64_ENC_BLOCK;
14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        decLen = DRM_B64_DEC_BLOCK;
14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (-1 == (decLen = drm_decodeBase64(decBuf, decLen, encBuf, &encLen)))
14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_DATA_INVALID;
14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (leftLen >= decLen) {
14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf + readBytes, decBuf, decLen);
14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes += decLen;
14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftLen -= decLen;
14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (leftLen > 0) {
14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(mediaBuf + readBytes, decBuf, leftLen);
14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes += leftLen;
14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memcpy(((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData, decBuf, DRM_B64_DEC_BLOCK);
14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readBase64Content(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes;
14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* when the content length has been well-known */
14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (s->contentLength >= 0)
14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else /* else when the content length has not been well-known yet */
14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen)
14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (offset + mediaBufLen <= ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes = mediaBufLen;
14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(mediaBuf, s->rawContent + offset, readBytes);
14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else
14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readBinaryContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t res = 0, readBytes = 0;
14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t leftLen;
14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN) {
14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = DRM_MAX_MALLOC_LEN - s->contentOffset - offset;
14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else
14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (s->bEndData)
14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_EOF;
14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    leftLen = mediaBufLen - readBytes;
14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (leftLen <= s->readBufLen) {
14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf, s->readBuf + s->readBufOff, leftLen);
14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->readBufOff += leftLen;
14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->readBufLen -= leftLen;
14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes += leftLen;
14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftLen = 0;
14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf, s->readBuf + s->readBufOff, s->readBufLen);
14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->readBufOff += s->readBufLen;
14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftLen -= s->readBufLen;
14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes += s->readBufLen;
14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->readBufLen = 0;
14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (leftLen > 0) {
14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        res = s->readInputDataFunc(s->inputHandle, mediaBuf + readBytes, mediaBufLen - readBytes);
14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (-1 == res)
14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_DATA_INVALID;
14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    readBytes += res;
15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    res = drm_scanEndBoundary(mediaBuf, readBytes, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (-1 == res)
15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (-2 == res) { /* may be the boundary is split */
15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t boundaryLen, len, off, k;
15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char* pTmp = memrchr(mediaBuf, '\r', readBytes);
15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL == pTmp)
15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE; /* conflict */
15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (NULL == s->readBuf) {
15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->readBuf = (uint8_t *)malloc(boundaryLen);
15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (NULL == s->readBuf)
15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_FAILURE;
15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        off = readBytes - ((uint8_t *)pTmp - mediaBuf);
15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        len = boundaryLen - off;
15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(s->readBuf, pTmp, off);
15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (k = 0; k < boundaryLen - off; k++) {
15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                *(s->readBuf + k + off) = s->readBuf[s->readBufOff];
15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->readBufOff++;
15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                s->readBufLen--;
15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else { /* read from InputStream */
15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + off, 1))
15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_MEDIA_DATA_INVALID;
15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->readBufOff = off;
15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        s->readBufLen = len;
15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = (uint8_t *)pTmp - mediaBuf; /* yes, it is the end boundary */
15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->bEndData = TRUE;
15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (res >= 0 && res < readBytes) {
15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = res;
15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->bEndData = TRUE;
15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (s->bEndData) {
15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == readBytes)
15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_EOF;
15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readBinaryContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes;
15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (s->contentLength >= 0)
15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else /* else when the content length has not been well-known yet */
15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN)
15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (s->contentOffset + offset + mediaBufLen <= DRM_MAX_MALLOC_LEN) {
15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes = mediaBufLen;
15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else
15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int32_t drm_readAesContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t keyValue[DRM_KEY_LEN];
15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    uint8_t buf[DRM_TWO_AES_BLOCK_LEN];
15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes = 0;
15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t bufLen, piece, i, copyBytes, leftBytes;
15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t aesStart, mediaStart, mediaBufOff;
158064e69e8ab8f63c0bba14d1e17c0e9595487fc0dcChia-chi Yeh    AES_KEY key;
15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_getKey(s->contentID, keyValue))
15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_NO_RIGHTS;
15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* when the content length has been well-known */
15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (s->contentLength > 0) {
15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset > s->contentLength)
15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset == s->contentLength)
15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_EOF;
15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (offset + mediaBufLen > s->contentLength)
15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = s->contentLength - offset;
15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else
15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = mediaBufLen;
15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        piece = (offset + readBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
16009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mediaStart = offset % DRM_ONE_AES_BLOCK_LEN;
16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
160264e69e8ab8f63c0bba14d1e17c0e9595487fc0dcChia-chi Yeh        AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mediaBufOff = 0;
16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        leftBytes = readBytes;
16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < piece - 1; i++) {
16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(buf, s->rawContent + aesStart + i * DRM_ONE_AES_BLOCK_LEN, DRM_TWO_AES_BLOCK_LEN);
16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bufLen = DRM_TWO_AES_BLOCK_LEN;
16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
161064e69e8ab8f63c0bba14d1e17c0e9595487fc0dcChia-chi Yeh            if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_DATA_INVALID;
16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (0 != i)
16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                mediaStart = 0;
16159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (bufLen - mediaStart <= leftBytes)
16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = bufLen - mediaStart;
16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else
16199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = leftBytes;
16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf + mediaBufOff, buf + mediaStart, copyBytes);
16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftBytes -= copyBytes;
16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaBufOff += copyBytes;
16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int32_t res;
16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (s->bEndData)
16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_MEDIA_EOF;
16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff) {
16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (mediaBufLen < ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff)
16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = mediaBufLen;
16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else
16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff;
16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData + ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff, copyBytes);
16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff += copyBytes;
16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes += copyBytes;
16409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        leftBytes = mediaBufLen - readBytes;
16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (0 == leftBytes)
16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return readBytes;
16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (leftBytes < 0)
16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return DRM_FAILURE;
16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        offset += readBytes;
16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        piece = (offset + leftBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mediaBufOff = readBytes;
16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
165364e69e8ab8f63c0bba14d1e17c0e9595487fc0dcChia-chi Yeh        AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (i = 0; i < piece - 1; i++) {
16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (-1 == (res = drm_readAesData(buf, s, aesStart, DRM_TWO_AES_BLOCK_LEN)))
16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_DATA_INVALID;
16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (-2 == res)
16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                break;
16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            bufLen = DRM_TWO_AES_BLOCK_LEN;
16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            aesStart += DRM_ONE_AES_BLOCK_LEN;
16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
166564e69e8ab8f63c0bba14d1e17c0e9595487fc0dcChia-chi Yeh            if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_DATA_INVALID;
16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drm_discardPaddingByte(buf, &bufLen);
16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (bufLen <= leftBytes)
16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = bufLen;
16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            else
16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                copyBytes = leftBytes;
16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memcpy(mediaBuf + mediaBufOff, buf, copyBytes);
16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            leftBytes -= copyBytes;
16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            mediaBufOff += copyBytes;
16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes += copyBytes;
16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData, buf, DRM_ONE_AES_BLOCK_LEN);
16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen = bufLen;
16839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff = copyBytes;
16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (aesStart - s->contentOffset > ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN && ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff == ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen) {
16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            s->bEndData = TRUE;
16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (0 == readBytes)
16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_MEDIA_EOF;
16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getContent(int32_t session, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t readBytes;
17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0 || offset < 0 || NULL == mediaBuf || mediaBufLen <= 0)
17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 >= s->getInputDataLengthFunc(s->inputHandle))
17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_MEDIA_DATA_INVALID;
17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    switch(s->deliveryMethod) {
17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case FORWARD_LOCK:
17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case COMBINED_DELIVERY:
17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = drm_readBase64Content(s, offset, mediaBuf, mediaBufLen);
17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else /* binary */
17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            readBytes = drm_readBinaryContent(s, offset, mediaBuf, mediaBufLen);
17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case SEPARATE_DELIVERY:
17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    case SEPARATE_DELIVERY_FL:
17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        readBytes = drm_readAesContent(s, offset, mediaBuf, mediaBufLen);
17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        break;
17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    default:
17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return readBytes;
17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getRightsIssuer(int32_t session, uint8_t* rightsIssuer)
17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0 || NULL == rightsIssuer)
17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod) {
17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy((char *)rightsIssuer, (char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer);
17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
17459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_NOT_SD_METHOD;
17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_getRightsInfo(int32_t session, T_DRM_Rights_Info* rights)
17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Session_Node* s;
17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights rightsInfo;
17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t roAmount, id;
17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0 || NULL == rights)
17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    s = getSession(session);
17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == s)
17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FORWARD_LOCK == s->deliveryMethod) {
17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy((char *)rights->roId, "ForwardLock");
17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->displayRights.indicator = DRM_NO_CONSTRAINT;
17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->playRights.indicator = DRM_NO_CONSTRAINT;
17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->executeRights.indicator = DRM_NO_CONSTRAINT;
17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->printRights.indicator = DRM_NO_CONSTRAINT;
17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_NO_RIGHTS;
17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (roAmount < 0)
17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_NO_RIGHTS;
17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /* some rights has been installed, but now there is no valid rights */
17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (0 == roAmount) {
17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        strcpy((char *)rights->roId, s->contentID);
17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->displayRights.indicator = DRM_NO_PERMISSION;
17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->playRights.indicator = DRM_NO_PERMISSION;
17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->executeRights.indicator = DRM_NO_PERMISSION;
17889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        rights->printRights.indicator = DRM_NO_PERMISSION;
17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SUCCESS;
17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    roAmount = 1;
17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&rightsInfo, 0, sizeof(T_DRM_Rights));
17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_writeOrReadInfo(id, &rightsInfo, &roAmount, GET_A_RO))
17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(rights, 0, sizeof(T_DRM_Rights_Info));
17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    drm_getLicenseInfo(&rightsInfo, rights);
17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_closeSession(int32_t session)
18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (session < 0)
18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == getSession(session))
18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_SESSION_NOT_OPENED;
18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    removeSession(session);
18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_updateRights(uint8_t* contentID, int32_t permission)
18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t id;
18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == contentID)
18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (FALSE == drm_readFromUidTxt(contentID, &id, GET_ID))
18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return drm_checkRoAndUpdate(id, permission);
18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_viewAllRights(T_DRM_Rights_Info_Node **ppRightsInfo)
18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights_Info_Node rightsNode;
18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t maxId, id, roAmount, j;
18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights rights;
18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&rights, 0, sizeof(T_DRM_Rights));
18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == ppRightsInfo)
18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *ppRightsInfo = NULL;
18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    maxId = drm_getMaxIdFromUidTxt();
18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (-1 == maxId)
18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (id = 1; id <= maxId; id++) {
18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (roAmount <= 0) /* this means there is not any rights */
18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (j = 1; j <= roAmount; j++) {
18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            memset(&rightsNode, 0, sizeof(T_DRM_Rights_Info_Node));
18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            drm_getLicenseInfo(&rights, &(rightsNode.roInfo));
18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_addRightsNodeToList(ppRightsInfo, &rightsNode))
18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_freeRightsInfoList(T_DRM_Rights_Info_Node *pRightsHeader)
18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights_Info_Node *pNode, *pTmp;
18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == pRightsHeader)
18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    pNode = pRightsHeader;
18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (NULL != pNode) {
18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pTmp = pNode;
18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        pNode = pNode->next;
18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        free(pTmp);
18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_SUCCESS;
18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* see svc_drm.h */
18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t SVC_drm_deleteRights(uint8_t* roId)
18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int32_t maxId, id, roAmount, j;
18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    T_DRM_Rights rights;
18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    memset(&rights, 0, sizeof(T_DRM_Rights));
18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (NULL == roId)
18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_FAILURE;
18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    maxId = drm_getMaxIdFromUidTxt();
18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (-1 == maxId)
18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return DRM_NO_RIGHTS;
19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (id = 1; id <= maxId; id++) {
19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (roAmount <= 0) /* this means there is not any rights */
19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            continue;
19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        for (j = 1; j <= roAmount; j++) {
19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                continue;
19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            /* here find the RO which will be deleted */
19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (0 == strcmp((char *)rights.uid, (char *)roId)) {
19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                T_DRM_Rights *pAllRights;
19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                pAllRights = (T_DRM_Rights *)malloc(roAmount * sizeof(T_DRM_Rights));
19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (NULL == pAllRights)
19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_FAILURE;
19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                drm_writeOrReadInfo(id, pAllRights, &roAmount, GET_ALL_RO);
19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                roAmount--;
19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (0 == roAmount) { /* this means it is the last one rights */
19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    drm_removeIdInfoFile(id); /* delete the id.info file first */
19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    drm_updateUidTxtWhenDelete(id); /* update uid.txt file */
19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    free(pAllRights);
19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_SUCCESS;
19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else /* using the last one rights instead of the deleted one */
19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    memcpy(pAllRights + (j - 1), pAllRights + roAmount, sizeof(T_DRM_Rights));
19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                /* delete the id.info file first */
19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                drm_removeIdInfoFile(id);
19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (FALSE == drm_writeOrReadInfo(id, pAllRights, &roAmount, SAVE_ALL_RO)) {
19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    free(pAllRights);
19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    return DRM_FAILURE;
19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                free(pAllRights);
19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return DRM_SUCCESS;
19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return DRM_FAILURE;
19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1944