Home | History | Annotate | Download | only in objmng
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <svc_drm.h>
     18 #include <drm_inner.h>
     19 #include <parser_dm.h>
     20 #include <parser_dcf.h>
     21 #include <parser_rel.h>
     22 #include <drm_rights_manager.h>
     23 #include <drm_time.h>
     24 #include <drm_decoder.h>
     25 #include "log.h"
     26 
     27 /**
     28  * Current id.
     29  */
     30 static int32_t curID = 0;
     31 
     32 /**
     33  * The header pointer for the session list.
     34  */
     35 static T_DRM_Session_Node* sessionTable = NULL;
     36 
     37 /**
     38  * New a session.
     39  */
     40 static T_DRM_Session_Node* newSession(T_DRM_Input_Data data)
     41 {
     42     T_DRM_Session_Node* s = (T_DRM_Session_Node *)malloc(sizeof(T_DRM_Session_Node));
     43 
     44     if (NULL != s) {
     45         memset(s, 0, sizeof(T_DRM_Session_Node));
     46 
     47         s->sessionId = curID++;
     48         s->inputHandle = data.inputHandle;
     49         s->mimeType = data.mimeType;
     50         s->getInputDataLengthFunc = data.getInputDataLength;
     51         s->readInputDataFunc = data.readInputData;
     52         s->seekInputDataFunc = data.seekInputData;
     53     }
     54 
     55     return s;
     56 }
     57 
     58 /**
     59  * Free a session.
     60  */
     61 static void freeSession(T_DRM_Session_Node* s)
     62 {
     63     if (NULL == s)
     64         return;
     65 
     66     if (NULL != s->rawContent)
     67         free(s->rawContent);
     68 
     69     if (NULL != s->readBuf)
     70         free(s->readBuf);
     71 
     72     if (NULL != s->infoStruct)
     73         free(s->infoStruct);
     74 
     75     free(s);
     76 }
     77 
     78 /**
     79  * Add a session to list.
     80  */
     81 static int32_t addSession(T_DRM_Session_Node* s)
     82 {
     83     if (NULL == s)
     84         return -1;
     85 
     86     s->next = sessionTable;
     87     sessionTable = s;
     88 
     89     return s->sessionId;
     90 }
     91 
     92 /**
     93  * Get a session from the list.
     94  */
     95 static T_DRM_Session_Node* getSession(int32_t sessionId)
     96 {
     97     T_DRM_Session_Node* s;
     98 
     99     if (sessionId < 0 || NULL == sessionTable)
    100         return NULL;
    101 
    102     for (s = sessionTable; s != NULL; s = s->next) {
    103         if (sessionId == s->sessionId)
    104             return s;
    105     }
    106 
    107     return NULL;
    108 }
    109 
    110 /**
    111  * Remove a session from the list.
    112  */
    113 static void removeSession(int32_t sessionId)
    114 {
    115     T_DRM_Session_Node *curS, *preS;
    116 
    117     if (sessionId < 0 || NULL == sessionTable)
    118         return;
    119 
    120     if (sessionId == sessionTable->sessionId) {
    121         curS = sessionTable;
    122         sessionTable = curS->next;
    123         freeSession(curS);
    124         return;
    125     }
    126 
    127     for (preS = sessionTable; preS->next != NULL; preS = preS->next) {
    128         if (preS->next->sessionId == sessionId)
    129             curS = preS->next;
    130     }
    131 
    132     if (NULL == preS->next)
    133         return;
    134 
    135     preS->next = curS->next;
    136     freeSession(curS);
    137 }
    138 
    139 /**
    140  * Try to identify the mimetype according the input DRM data.
    141  */
    142 static int32_t getMimeType(const uint8_t *buf, int32_t bufLen)
    143 {
    144     const uint8_t *p;
    145 
    146     if (NULL == buf || bufLen <= 0)
    147         return TYPE_DRM_UNKNOWN;
    148 
    149     p = buf;
    150 
    151     /* check if it is DRM Content Format, only check the first field of Version, it must be "0x01" */
    152     if (0x01 == *p)
    153         return TYPE_DRM_CONTENT;
    154 
    155     /* check if it is DRM Message, only check the first two bytes, it must be the start flag of boundary: "--" */
    156     if (bufLen >= 2 && '-' == *p && '-' == *(p + 1))
    157         return TYPE_DRM_MESSAGE;
    158 
    159     /* check if it is DRM Rights XML format, only check the first several bytes, it must be: "<o-ex:rights" */
    160     if (bufLen >= 12 && 0 == strncmp("<o-ex:rights", (char *)p, 12))
    161         return TYPE_DRM_RIGHTS_XML;
    162 
    163     /* check if it is DRM Rights WBXML format, only check the first two bytes, it must be: 0x03, 0x0e */
    164     if (bufLen >= 2 && 0x03 == *p && 0x0e == *(p + 1))
    165         return TYPE_DRM_RIGHTS_WBXML;
    166 
    167     return TYPE_DRM_UNKNOWN;
    168 }
    169 
    170 static int32_t drm_skipCRLFinB64(const uint8_t* b64Data, int32_t len)
    171 {
    172     const uint8_t* p;
    173     int32_t skipLen = 0;
    174 
    175     if (NULL == b64Data || len <= 0)
    176         return -1;
    177 
    178     p = b64Data;
    179     while (p - b64Data < len) {
    180         if ('\r' == *p || '\n'== *p)
    181             skipLen++;
    182         p++;
    183     }
    184 
    185     return skipLen;
    186 }
    187 
    188 static int32_t drm_scanEndBoundary(const uint8_t* pBuf, int32_t len, uint8_t* const boundary)
    189 {
    190     const uint8_t* p;
    191     int32_t leftLen;
    192     int32_t boundaryLen;
    193 
    194     if (NULL == pBuf || len <=0 || NULL == boundary)
    195         return -1;
    196 
    197     p = pBuf;
    198     boundaryLen = strlen((char *)boundary) + 2; /* 2 means: '\r' and '\n' */
    199     leftLen = len - (p - pBuf);
    200     while (leftLen > 0) {
    201         if (NULL == (p = memchr(p, '\r', leftLen)))
    202             break;
    203 
    204         leftLen = len - (p - pBuf);
    205         if (leftLen < boundaryLen)
    206             return -2; /* here means may be the boundary has been split */
    207 
    208         if (('\n' == *(p + 1)) && (0 == memcmp(p + 2, boundary, strlen((char *)boundary))))
    209             return p - pBuf; /* find the boundary here */
    210 
    211         p++;
    212         leftLen--;
    213     }
    214 
    215     return len; /* no boundary found */
    216 }
    217 
    218 static int32_t drm_getLicenseInfo(T_DRM_Rights* pRights, T_DRM_Rights_Info* licenseInfo)
    219 {
    220     if (NULL != licenseInfo && NULL != pRights) {
    221         strcpy((char *)licenseInfo->roId, (char *)pRights->uid);
    222 
    223         if (1 == pRights->bIsDisplayable) {
    224             licenseInfo->displayRights.indicator = pRights->DisplayConstraint.Indicator;
    225             licenseInfo->displayRights.count =
    226                 pRights->DisplayConstraint.Count;
    227             licenseInfo->displayRights.startDate =
    228                 pRights->DisplayConstraint.StartTime.date;
    229             licenseInfo->displayRights.startTime =
    230                 pRights->DisplayConstraint.StartTime.time;
    231             licenseInfo->displayRights.endDate =
    232                 pRights->DisplayConstraint.EndTime.date;
    233             licenseInfo->displayRights.endTime =
    234                 pRights->DisplayConstraint.EndTime.time;
    235             licenseInfo->displayRights.intervalDate =
    236                 pRights->DisplayConstraint.Interval.date;
    237             licenseInfo->displayRights.intervalTime =
    238                 pRights->DisplayConstraint.Interval.time;
    239         }
    240         if (1 == pRights->bIsPlayable) {
    241             licenseInfo->playRights.indicator = pRights->PlayConstraint.Indicator;
    242             licenseInfo->playRights.count = pRights->PlayConstraint.Count;
    243             licenseInfo->playRights.startDate =
    244                 pRights->PlayConstraint.StartTime.date;
    245             licenseInfo->playRights.startTime =
    246                 pRights->PlayConstraint.StartTime.time;
    247             licenseInfo->playRights.endDate =
    248                 pRights->PlayConstraint.EndTime.date;
    249             licenseInfo->playRights.endTime =
    250                 pRights->PlayConstraint.EndTime.time;
    251             licenseInfo->playRights.intervalDate =
    252                 pRights->PlayConstraint.Interval.date;
    253             licenseInfo->playRights.intervalTime =
    254                 pRights->PlayConstraint.Interval.time;
    255         }
    256         if (1 == pRights->bIsExecuteable) {
    257             licenseInfo->executeRights.indicator = pRights->ExecuteConstraint.Indicator;
    258             licenseInfo->executeRights.count =
    259                 pRights->ExecuteConstraint.Count;
    260             licenseInfo->executeRights.startDate =
    261                 pRights->ExecuteConstraint.StartTime.date;
    262             licenseInfo->executeRights.startTime =
    263                 pRights->ExecuteConstraint.StartTime.time;
    264             licenseInfo->executeRights.endDate =
    265                 pRights->ExecuteConstraint.EndTime.date;
    266             licenseInfo->executeRights.endTime =
    267                 pRights->ExecuteConstraint.EndTime.time;
    268             licenseInfo->executeRights.intervalDate =
    269                 pRights->ExecuteConstraint.Interval.date;
    270             licenseInfo->executeRights.intervalTime =
    271                 pRights->ExecuteConstraint.Interval.time;
    272         }
    273         if (1 == pRights->bIsPrintable) {
    274             licenseInfo->printRights.indicator = pRights->PrintConstraint.Indicator;
    275             licenseInfo->printRights.count =
    276                 pRights->PrintConstraint.Count;
    277             licenseInfo->printRights.startDate =
    278                 pRights->PrintConstraint.StartTime.date;
    279             licenseInfo->printRights.startTime =
    280                 pRights->PrintConstraint.StartTime.time;
    281             licenseInfo->printRights.endDate =
    282                 pRights->PrintConstraint.EndTime.date;
    283             licenseInfo->printRights.endTime =
    284                 pRights->PrintConstraint.EndTime.time;
    285             licenseInfo->printRights.intervalDate =
    286                 pRights->PrintConstraint.Interval.date;
    287             licenseInfo->printRights.intervalTime =
    288                 pRights->PrintConstraint.Interval.time;
    289         }
    290         return TRUE;
    291     }
    292     return FALSE;
    293 }
    294 
    295 static int32_t drm_addRightsNodeToList(T_DRM_Rights_Info_Node **ppRightsHeader,
    296                                        T_DRM_Rights_Info_Node *pInputRightsNode)
    297 {
    298     T_DRM_Rights_Info_Node *pRightsNode;
    299 
    300     if (NULL == ppRightsHeader || NULL == pInputRightsNode)
    301         return FALSE;
    302 
    303     pRightsNode = (T_DRM_Rights_Info_Node *)malloc(sizeof(T_DRM_Rights_Info_Node));
    304     if (NULL == pRightsNode)
    305         return FALSE;
    306 
    307     memcpy(pRightsNode, pInputRightsNode, sizeof(T_DRM_Rights_Info_Node));
    308     pRightsNode->next = NULL;
    309 
    310     /* this means it is the first node */
    311     if (NULL == *ppRightsHeader)
    312         *ppRightsHeader = pRightsNode;
    313     else {
    314         T_DRM_Rights_Info_Node *pTmp;
    315 
    316         pTmp = *ppRightsHeader;
    317         while (NULL != pTmp->next)
    318             pTmp = pTmp->next;
    319 
    320         pTmp->next = pRightsNode;
    321     }
    322     return TRUE;
    323 }
    324 
    325 static int32_t drm_startConsumeRights(int32_t * bIsXXable,
    326                                       T_DRM_Rights_Constraint * XXConstraint,
    327                                       int32_t * writeFlag)
    328 {
    329     T_DB_TIME_SysTime curDateTime;
    330     T_DRM_DATETIME CurrentTime;
    331     uint8_t countFlag = 0;
    332 
    333     memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
    334 
    335     if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint || NULL == writeFlag)
    336         return DRM_FAILURE;
    337 
    338     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
    339         return DRM_SUCCESS;
    340 
    341     *bIsXXable = 0; /* Assume have invalid rights at first */
    342     *writeFlag = 0;
    343 
    344     if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT | DRM_INTERVAL_CONSTRAINT))) {
    345         DRM_time_getSysTime(&curDateTime);
    346 
    347         if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
    348                                 curDateTime.hour, curDateTime.min, curDateTime.sec))
    349             return DRM_FAILURE;
    350 
    351         YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
    352                       CurrentTime.date, curDateTime.hour, curDateTime.min,
    353                       curDateTime.sec, CurrentTime.time);
    354     }
    355 
    356     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
    357         *writeFlag = 1;
    358         /* If it has only one time for use, after use this function, we will delete this rights */
    359         if (XXConstraint->Count <= 0) {
    360             XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
    361             return DRM_RIGHTS_EXPIRED;
    362         }
    363 
    364         if (XXConstraint->Count-- <= 1) {
    365             XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
    366             countFlag = 1;
    367         }
    368     }
    369 
    370     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
    371         if (XXConstraint->StartTime.date > CurrentTime.date ||
    372             (XXConstraint->StartTime.date == CurrentTime.date &&
    373              XXConstraint->StartTime.time >= CurrentTime.time)) {
    374             *bIsXXable = 1;
    375             return DRM_RIGHTS_PENDING;
    376         }
    377     }
    378 
    379     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
    380         if (XXConstraint->EndTime.date < CurrentTime.date ||
    381             (XXConstraint->EndTime.date == CurrentTime.date &&
    382              XXConstraint->EndTime.time <= CurrentTime.time)) {
    383             *writeFlag = 1;
    384             XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
    385             return DRM_RIGHTS_EXPIRED;
    386         }
    387     }
    388 
    389     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
    390         int32_t year, mon, day, hour, min, sec, date, time;
    391         int32_t ret;
    392 
    393         XXConstraint->Indicator |= DRM_END_TIME_CONSTRAINT;
    394         XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT; /* Write off interval right */
    395         *writeFlag = 1;
    396 
    397         if (XXConstraint->Interval.date == 0
    398             && XXConstraint->Interval.time == 0) {
    399             return DRM_RIGHTS_EXPIRED;
    400         }
    401         date = CurrentTime.date + XXConstraint->Interval.date;
    402         time = CurrentTime.time + XXConstraint->Interval.time;
    403         INT_2_YMD_HMS(year, mon, day, date, hour, min, sec, time);
    404 
    405         if (sec > 59) {
    406             min += sec / 60;
    407             sec %= 60;
    408         }
    409         if (min > 59) {
    410             hour += min / 60;
    411             min %= 60;
    412         }
    413         if (hour > 23) {
    414             day += hour / 24;
    415             hour %= 24;
    416         }
    417         if (day > 31) {
    418             mon += day / 31;
    419             day %= 31;
    420         }
    421         if (mon > 12) {
    422             year += mon / 12;
    423             mon %= 12;
    424         }
    425         if (day > (ret = drm_monthDays(year, mon))) {
    426             day -= ret;
    427             mon++;
    428             if (mon > 12) {
    429                 mon -= 12;
    430                 year++;
    431             }
    432         }
    433         YMD_HMS_2_INT(year, mon, day, XXConstraint->EndTime.date, hour,
    434                       min, sec, XXConstraint->EndTime.time);
    435     }
    436 
    437     if (1 != countFlag)
    438         *bIsXXable = 1; /* Can go here ,so  right must be valid */
    439     return DRM_SUCCESS;
    440 }
    441 
    442 static int32_t drm_startCheckRights(int32_t * bIsXXable,
    443                                     T_DRM_Rights_Constraint * XXConstraint)
    444 {
    445     T_DB_TIME_SysTime curDateTime;
    446     T_DRM_DATETIME CurrentTime;
    447 
    448     memset(&CurrentTime, 0, sizeof(T_DRM_DATETIME));
    449 
    450     if (NULL == bIsXXable || 0 == *bIsXXable || NULL == XXConstraint)
    451         return DRM_FAILURE;
    452 
    453     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_NO_CONSTRAINT)) /* Have utter right? */
    454         return DRM_SUCCESS;
    455 
    456     *bIsXXable = 0; /* Assume have invalid rights at first */
    457 
    458     if (0 != (XXConstraint->Indicator & (DRM_START_TIME_CONSTRAINT | DRM_END_TIME_CONSTRAINT))) {
    459         DRM_time_getSysTime(&curDateTime);
    460 
    461         if (-1 == drm_checkDate(curDateTime.year, curDateTime.month, curDateTime.day,
    462                                 curDateTime.hour, curDateTime.min, curDateTime.sec))
    463             return DRM_FAILURE;
    464 
    465         YMD_HMS_2_INT(curDateTime.year, curDateTime.month, curDateTime.day,
    466                       CurrentTime.date, curDateTime.hour, curDateTime.min,
    467                       curDateTime.sec, CurrentTime.time);
    468     }
    469 
    470     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_COUNT_CONSTRAINT)) { /* Have count restrict? */
    471         if (XXConstraint->Count <= 0) {
    472             XXConstraint->Indicator &= ~DRM_COUNT_CONSTRAINT;
    473             return DRM_RIGHTS_EXPIRED;
    474         }
    475     }
    476 
    477     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_START_TIME_CONSTRAINT)) {
    478         if (XXConstraint->StartTime.date > CurrentTime.date ||
    479             (XXConstraint->StartTime.date == CurrentTime.date &&
    480              XXConstraint->StartTime.time >= CurrentTime.time)) {
    481             *bIsXXable = 1;
    482             return DRM_RIGHTS_PENDING;
    483         }
    484     }
    485 
    486     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) { /* Have end time restrict? */
    487         if (XXConstraint->EndTime.date < CurrentTime.date ||
    488             (XXConstraint->EndTime.date == CurrentTime.date &&
    489              XXConstraint->EndTime.time <= CurrentTime.time)) {
    490             XXConstraint->Indicator &= ~DRM_END_TIME_CONSTRAINT;
    491             return DRM_RIGHTS_EXPIRED;
    492         }
    493     }
    494 
    495     if (0 != (uint8_t)(XXConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) { /* Have interval time restrict? */
    496         if (XXConstraint->Interval.date == 0 && XXConstraint->Interval.time == 0) {
    497             XXConstraint->Indicator &= ~DRM_INTERVAL_CONSTRAINT;
    498             return DRM_RIGHTS_EXPIRED;
    499         }
    500     }
    501 
    502     *bIsXXable = 1;
    503     return DRM_SUCCESS;
    504 }
    505 
    506 int32_t drm_checkRoAndUpdate(int32_t id, int32_t permission)
    507 {
    508     int32_t writeFlag = 0;
    509     int32_t roAmount;
    510     int32_t validRoAmount = 0;
    511     int32_t flag = DRM_FAILURE;
    512     int32_t i, j;
    513     T_DRM_Rights *pRo;
    514     T_DRM_Rights *pCurRo;
    515     int32_t * pNumOfPriority;
    516     int32_t iNum;
    517     T_DRM_Rights_Constraint * pCurConstraint;
    518     T_DRM_Rights_Constraint * pCompareConstraint;
    519     int priority[8] = {1, 2, 4, 3, 8, 6, 7, 5};
    520 
    521     if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
    522         return DRM_FAILURE;
    523 
    524     validRoAmount = roAmount;
    525     if (roAmount < 1)
    526         return DRM_NO_RIGHTS;
    527 
    528     pRo = malloc(roAmount * sizeof(T_DRM_Rights));
    529     pCurRo = pRo;
    530     if (NULL == pRo)
    531         return DRM_FAILURE;
    532 
    533     if (FALSE == drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO)) {
    534         free(pRo);
    535         return DRM_FAILURE;
    536     }
    537 
    538     /** check the right priority */
    539     pNumOfPriority = malloc(sizeof(int32_t) * roAmount);
    540     for(i = 0; i < roAmount; i++) {
    541         iNum = roAmount - 1;
    542         for(j = 0; j < roAmount; j++) {
    543             if(i == j)
    544                 continue;
    545             switch(permission) {
    546             case DRM_PERMISSION_PLAY:
    547                 pCurConstraint = &pRo[i].PlayConstraint;
    548                 pCompareConstraint = &pRo[j].PlayConstraint;
    549                 break;
    550             case DRM_PERMISSION_DISPLAY:
    551                 pCurConstraint = &pRo[i].DisplayConstraint;
    552                 pCompareConstraint = &pRo[j].DisplayConstraint;
    553                 break;
    554             case DRM_PERMISSION_EXECUTE:
    555                 pCurConstraint = &pRo[i].ExecuteConstraint;
    556                 pCompareConstraint = &pRo[j].ExecuteConstraint;
    557                 break;
    558             case DRM_PERMISSION_PRINT:
    559                 pCurConstraint = &pRo[i].PrintConstraint;
    560                 pCompareConstraint = &pRo[j].PrintConstraint;
    561                 break;
    562             default:
    563                 free(pRo);
    564                 free(pNumOfPriority);
    565                 return DRM_FAILURE;
    566             }
    567 
    568             /**get priority by Indicator*/
    569             if(0 == (pCurConstraint->Indicator & DRM_NO_CONSTRAINT) &&
    570                 0 == (pCompareConstraint->Indicator & DRM_NO_CONSTRAINT)) {
    571                     int num1, num2;
    572                     num1 = (pCurConstraint->Indicator & 0x0e) >> 1;
    573                     num2 = (pCompareConstraint->Indicator & 0x0e) >> 1;
    574                     if(priority[num1] > priority[num2]) {
    575                         iNum--;
    576                         continue;
    577                     } else if(priority[pCurConstraint->Indicator] < priority[pCompareConstraint->Indicator])
    578                         continue;
    579             } else if(pCurConstraint->Indicator > pCompareConstraint->Indicator) {
    580                 iNum--;
    581                 continue;
    582             } else if(pCurConstraint->Indicator < pCompareConstraint->Indicator)
    583                 continue;
    584 
    585             if(0 != (pCurConstraint->Indicator & DRM_END_TIME_CONSTRAINT)) {
    586                 if(pCurConstraint->EndTime.date < pCompareConstraint->EndTime.date) {
    587                     iNum--;
    588                     continue;
    589                 } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
    590                     continue;
    591 
    592                 if(pCurConstraint->EndTime.time < pCompareConstraint->EndTime.time) {
    593                     iNum--;
    594                     continue;
    595                 } else if(pCurConstraint->EndTime.date > pCompareConstraint->EndTime.date)
    596                     continue;
    597             }
    598 
    599             if(0 != (pCurConstraint->Indicator & DRM_INTERVAL_CONSTRAINT)) {
    600                 if(pCurConstraint->Interval.date < pCompareConstraint->Interval.date) {
    601                     iNum--;
    602                     continue;
    603                 } else if(pCurConstraint->Interval.date > pCompareConstraint->Interval.date)
    604                     continue;
    605 
    606                 if(pCurConstraint->Interval.time < pCompareConstraint->Interval.time) {
    607                     iNum--;
    608                     continue;
    609                 } else if(pCurConstraint->Interval.time > pCompareConstraint->Interval.time)
    610                     continue;
    611             }
    612 
    613             if(0 != (pCurConstraint->Indicator & DRM_COUNT_CONSTRAINT)) {
    614                 if(pCurConstraint->Count < pCompareConstraint->Count) {
    615                     iNum--;
    616                     continue;
    617                 } else if(pCurConstraint->Count > pCompareConstraint->Count)
    618                     continue;
    619             }
    620 
    621             if(i < j)
    622                 iNum--;
    623         }
    624         pNumOfPriority[iNum] = i;
    625     }
    626 
    627     for (i = 0; i < validRoAmount; i++) {
    628         /** check the right priority */
    629         if (pNumOfPriority[i] >= validRoAmount)
    630             break;
    631 
    632         pCurRo = pRo + pNumOfPriority[i];
    633 
    634         switch (permission) {
    635         case DRM_PERMISSION_PLAY:
    636             flag =
    637                 drm_startConsumeRights(&pCurRo->bIsPlayable,
    638                                        &pCurRo->PlayConstraint, &writeFlag);
    639             break;
    640         case DRM_PERMISSION_DISPLAY:
    641             flag =
    642                 drm_startConsumeRights(&pCurRo->bIsDisplayable,
    643                                        &pCurRo->DisplayConstraint,
    644                                        &writeFlag);
    645             break;
    646         case DRM_PERMISSION_EXECUTE:
    647             flag =
    648                 drm_startConsumeRights(&pCurRo->bIsExecuteable,
    649                                        &pCurRo->ExecuteConstraint,
    650                                        &writeFlag);
    651             break;
    652         case DRM_PERMISSION_PRINT:
    653             flag =
    654                 drm_startConsumeRights(&pCurRo->bIsPrintable,
    655                                        &pCurRo->PrintConstraint, &writeFlag);
    656             break;
    657         default:
    658             free(pNumOfPriority);
    659             free(pRo);
    660             return DRM_FAILURE;
    661         }
    662 
    663         /* Here confirm the valid RO amount and set the writeFlag */
    664         if (0 == pCurRo->bIsPlayable && 0 == pCurRo->bIsDisplayable &&
    665             0 == pCurRo->bIsExecuteable && 0 == pCurRo->bIsPrintable) {
    666             int32_t iCurPri;
    667 
    668             /** refresh the right priority */
    669             iCurPri = pNumOfPriority[i];
    670             for(j = i; j < validRoAmount - 1; j++)
    671                 pNumOfPriority[j] = pNumOfPriority[j + 1];
    672 
    673             if(iCurPri != validRoAmount - 1) {
    674                 memcpy(pCurRo, pRo + validRoAmount - 1,
    675                     sizeof(T_DRM_Rights));
    676                 for(j = 0; j < validRoAmount -1; j++) {
    677                     if(validRoAmount - 1 == pNumOfPriority[j])
    678                         pNumOfPriority[j] = iCurPri;
    679                 }
    680             }
    681 
    682             /* Here means it is not the last one RO, so the invalid RO should be deleted */
    683             writeFlag = 1;
    684             validRoAmount--; /* If current right is invalid */
    685             i--;
    686         }
    687 
    688         /* If the flag is TRUE, this means: we have found a valid RO, so break, no need to check other RO */
    689         if (DRM_SUCCESS == flag)
    690             break;
    691     }
    692 
    693     if (1 == writeFlag) {
    694         /* Delete the *.info first */
    695         //drm_removeIdInfoFile(id);
    696 
    697         if (FALSE == drm_writeOrReadInfo(id, pRo, &validRoAmount, SAVE_ALL_RO))
    698             flag = DRM_FAILURE;
    699     }
    700 
    701     free(pNumOfPriority);
    702     free(pRo);
    703     return flag;
    704 }
    705 
    706 
    707 /* see svc_drm.h */
    708 int32_t SVC_drm_installRights(T_DRM_Input_Data data, T_DRM_Rights_Info* pRightsInfo)
    709 {
    710     uint8_t *buf;
    711     int32_t dataLen, bufLen;
    712     T_DRM_Rights rights;
    713 
    714     if (0 == data.inputHandle)
    715         return DRM_RIGHTS_DATA_INVALID;
    716 
    717     /* Get input rights data length */
    718     dataLen = data.getInputDataLength(data.inputHandle);
    719     if (dataLen <= 0)
    720         return DRM_RIGHTS_DATA_INVALID;
    721 
    722     /* Check if the length is larger than DRM max malloc length */
    723     if (dataLen > DRM_MAX_MALLOC_LEN)
    724         bufLen = DRM_MAX_MALLOC_LEN;
    725     else
    726         bufLen = dataLen;
    727 
    728     buf = (uint8_t *)malloc(bufLen);
    729     if (NULL == buf)
    730         return DRM_FAILURE;
    731 
    732     /* Read input data to buffer */
    733     if (0 >= data.readInputData(data.inputHandle, buf, bufLen)) {
    734         free(buf);
    735         return DRM_RIGHTS_DATA_INVALID;
    736     }
    737 
    738     /* if the input mime type is unknown, DRM engine will try to recognize it. */
    739     if (TYPE_DRM_UNKNOWN == data.mimeType)
    740         data.mimeType = getMimeType(buf, bufLen);
    741 
    742     switch(data.mimeType) {
    743     case TYPE_DRM_MESSAGE: /* in case of Combined Delivery, extract the rights part to install */
    744         {
    745             T_DRM_DM_Info dmInfo;
    746 
    747             memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
    748             if (FALSE == drm_parseDM(buf, bufLen, &dmInfo)) {
    749                 free(buf);
    750                 return DRM_RIGHTS_DATA_INVALID;
    751             }
    752 
    753             /* if it is not Combined Delivery, it can not use to "SVC_drm_installRights" */
    754             if (COMBINED_DELIVERY != dmInfo.deliveryType || dmInfo.rightsOffset <= 0 || dmInfo.rightsLen <= 0) {
    755                 free(buf);
    756                 return DRM_RIGHTS_DATA_INVALID;
    757             }
    758 
    759             memset(&rights, 0, sizeof(T_DRM_Rights));
    760             if (FALSE == drm_relParser(buf + dmInfo.rightsOffset, dmInfo.rightsLen, TYPE_DRM_RIGHTS_XML, &rights)) {
    761                 free(buf);
    762                 return DRM_RIGHTS_DATA_INVALID;
    763             }
    764         }
    765         break;
    766     case TYPE_DRM_RIGHTS_XML:
    767     case TYPE_DRM_RIGHTS_WBXML:
    768         memset(&rights, 0, sizeof(T_DRM_Rights));
    769         if (FALSE == drm_relParser(buf, bufLen, data.mimeType, &rights)) {
    770             free(buf);
    771             return DRM_RIGHTS_DATA_INVALID;
    772         }
    773         break;
    774     case TYPE_DRM_CONTENT: /* DCF should not using "SVC_drm_installRights", it should be used to open a session. */
    775     case TYPE_DRM_UNKNOWN:
    776     default:
    777         free(buf);
    778         return DRM_MEDIA_DATA_INVALID;
    779     }
    780 
    781     free(buf);
    782 
    783     /* append the rights information to DRM engine storage */
    784     if (FALSE == drm_appendRightsInfo(&rights))
    785         return DRM_FAILURE;
    786 
    787     memset(pRightsInfo, 0, sizeof(T_DRM_Rights_Info));
    788     drm_getLicenseInfo(&rights, pRightsInfo);
    789 
    790     return DRM_SUCCESS;
    791 }
    792 
    793 /* see svc_drm.h */
    794 int32_t SVC_drm_openSession(T_DRM_Input_Data data)
    795 {
    796     int32_t session;
    797     int32_t dataLen;
    798     T_DRM_Session_Node* s;
    799 
    800     if (0 == data.inputHandle)
    801         return DRM_MEDIA_DATA_INVALID;
    802 
    803     /* Get input data length */
    804     dataLen = data.getInputDataLength(data.inputHandle);
    805     if (dataLen <= 0)
    806         return DRM_MEDIA_DATA_INVALID;
    807 
    808     s = newSession(data);
    809     if (NULL == s)
    810         return DRM_FAILURE;
    811 
    812     /* Check if the length is larger than DRM max malloc length */
    813     if (dataLen > DRM_MAX_MALLOC_LEN)
    814         s->rawContentLen = DRM_MAX_MALLOC_LEN;
    815     else
    816         s->rawContentLen = dataLen;
    817 
    818     s->rawContent = (uint8_t *)malloc(s->rawContentLen);
    819     if (NULL == s->rawContent)
    820         return DRM_FAILURE;
    821 
    822     /* Read input data to buffer */
    823     if (0 >= data.readInputData(data.inputHandle, s->rawContent, s->rawContentLen)) {
    824         freeSession(s);
    825         return DRM_MEDIA_DATA_INVALID;
    826     }
    827 
    828     /* if the input mime type is unknown, DRM engine will try to recognize it. */
    829     if (TYPE_DRM_UNKNOWN == data.mimeType)
    830         data.mimeType = getMimeType(s->rawContent, s->rawContentLen);
    831 
    832     switch(data.mimeType) {
    833     case TYPE_DRM_MESSAGE:
    834         {
    835             T_DRM_DM_Info dmInfo;
    836 
    837             memset(&dmInfo, 0, sizeof(T_DRM_DM_Info));
    838             if (FALSE == drm_parseDM(s->rawContent, s->rawContentLen, &dmInfo)) {
    839                 freeSession(s);
    840                 return DRM_MEDIA_DATA_INVALID;
    841             }
    842 
    843             s->deliveryMethod = dmInfo.deliveryType;
    844 
    845             if (SEPARATE_DELIVERY_FL == s->deliveryMethod)
    846                 s->contentLength = DRM_UNKNOWN_DATA_LEN;
    847             else
    848                 s->contentLength = dmInfo.contentLen;
    849 
    850             s->transferEncoding = dmInfo.transferEncoding;
    851             s->contentOffset = dmInfo.contentOffset;
    852             s->bEndData = FALSE;
    853             strcpy((char *)s->contentType, (char *)dmInfo.contentType);
    854             strcpy((char *)s->contentID, (char *)dmInfo.contentID);
    855 
    856             if (SEPARATE_DELIVERY_FL == s->deliveryMethod) {
    857                 s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
    858                 if (NULL == s->infoStruct)
    859                     return DRM_FAILURE;
    860                 memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
    861 
    862                 ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dmInfo.contentLen;
    863                 strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dmInfo.rightsIssuer);
    864                 break;
    865             }
    866 
    867             if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
    868                 s->infoStruct = (T_DRM_DM_Base64_Node *)malloc(sizeof(T_DRM_DM_Base64_Node));
    869                 if (NULL == s->infoStruct)
    870                     return DRM_FAILURE;
    871                 memset(s->infoStruct, 0, sizeof(T_DRM_DM_Base64_Node));
    872 
    873                 strcpy((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
    874             } else {
    875                 s->infoStruct = (T_DRM_DM_Binary_Node *)malloc(sizeof(T_DRM_DM_Binary_Node));
    876                 if (NULL == s->infoStruct)
    877                     return DRM_FAILURE;
    878                 memset(s->infoStruct, 0, sizeof(T_DRM_DM_Binary_Node));
    879 
    880                 strcpy((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary, (char *)dmInfo.boundary);
    881             }
    882 
    883 
    884             if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding) {
    885                 if (s->contentLength > 0) {
    886                     int32_t encLen, decLen;
    887 
    888                     encLen = s->contentLength;
    889                     decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
    890 
    891                     decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
    892                     s->contentLength = decLen;
    893                 } else {
    894                     int32_t encLen = DRM_MAX_MALLOC_LEN - s->contentOffset, decLen;
    895                     int32_t skipLen, needBytes, i;
    896                     uint8_t *pStart;
    897                     int32_t res, bFoundBoundary = FALSE;
    898 
    899                     pStart = s->rawContent + s->contentOffset;
    900                     if (-1 == (skipLen = drm_skipCRLFinB64(pStart, encLen))) {
    901                         freeSession(s);
    902                         return DRM_FAILURE;
    903                     }
    904 
    905                     needBytes = DRM_B64_ENC_BLOCK - ((encLen - skipLen) % DRM_B64_ENC_BLOCK);
    906                     if (needBytes < DRM_B64_ENC_BLOCK) {
    907                         s->rawContent = (uint8_t *)realloc(s->rawContent, DRM_MAX_MALLOC_LEN + needBytes);
    908                         if (NULL == s->rawContent) {
    909                             freeSession(s);
    910                             return DRM_FAILURE;
    911                         }
    912 
    913                         i = 0;
    914                         while (i < needBytes) {
    915                             if (-1 != data.readInputData(data.inputHandle, s->rawContent + DRM_MAX_MALLOC_LEN + i, 1)) {
    916                                 if ('\r' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i) || '\n' == *(s->rawContent + DRM_MAX_MALLOC_LEN + i))
    917                                     continue;
    918                                 i++;
    919                             } else
    920                                 break;
    921                         }
    922                         encLen += i;
    923                     }
    924 
    925                     res = drm_scanEndBoundary(pStart, encLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
    926                     if (-1 == res) {
    927                         freeSession(s);
    928                         return DRM_FAILURE;
    929                     }
    930                     if (-2 == res) { /* may be there is a boundary */
    931                         int32_t boundaryLen, leftLen, readBytes;
    932                         char* pTmp = memrchr(pStart, '\r', encLen);
    933 
    934                         if (NULL == pTmp) {
    935                             freeSession(s);
    936                             return DRM_FAILURE; /* conflict */
    937                         }
    938                         boundaryLen = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
    939                         s->readBuf = (uint8_t *)malloc(boundaryLen);
    940                         if (NULL == s->readBuf) {
    941                             freeSession(s);
    942                             return DRM_FAILURE;
    943                         }
    944                         s->readBufOff = encLen - ((uint8_t *)pTmp - pStart);
    945                         s->readBufLen = boundaryLen - s->readBufOff;
    946                         memcpy(s->readBuf, pTmp, s->readBufOff);
    947                         readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
    948                         if (-1 == readBytes || readBytes < s->readBufLen) {
    949                             freeSession(s);
    950                             return DRM_MEDIA_DATA_INVALID;
    951                         }
    952 
    953                         if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary)) {
    954                             encLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
    955                             bFoundBoundary = TRUE;
    956                         }
    957                     } else {
    958                         if (res >= 0 && res < encLen) {
    959                             encLen = res;
    960                             bFoundBoundary = TRUE;
    961                         }
    962                     }
    963 
    964                     decLen = encLen / DRM_B64_ENC_BLOCK * DRM_B64_DEC_BLOCK;
    965                     decLen = drm_decodeBase64(s->rawContent, decLen, s->rawContent + s->contentOffset, &encLen);
    966                     ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen = decLen;
    967                     if (bFoundBoundary)
    968                         s->contentLength = decLen;
    969                 }
    970             } else {
    971                 /* binary data */
    972                 if (DRM_UNKNOWN_DATA_LEN == s->contentLength) {
    973                     /* try to check whether there is boundary may be split */
    974                     int32_t res, binContentLen;
    975                     uint8_t* pStart;
    976                     int32_t bFoundBoundary = FALSE;
    977 
    978                     pStart = s->rawContent + s->contentOffset;
    979                     binContentLen = s->rawContentLen - s->contentOffset;
    980                     res = drm_scanEndBoundary(pStart, binContentLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
    981 
    982                     if (-1 == res) {
    983                         freeSession(s);
    984                         return DRM_FAILURE;
    985                     }
    986 
    987                     if (-2 == res) { /* may be the boundary is split */
    988                         int32_t boundaryLen, leftLen, readBytes;
    989                         char* pTmp = memrchr(pStart, '\r', binContentLen);
    990 
    991                         if (NULL == pTmp) {
    992                             freeSession(s);
    993                             return DRM_FAILURE; /* conflict */
    994                         }
    995 
    996                         boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
    997                         s->readBuf = (uint8_t *)malloc(boundaryLen);
    998                         if (NULL == s->readBuf) {
    999                             freeSession(s);
   1000                             return DRM_FAILURE;
   1001                         }
   1002                         s->readBufOff = binContentLen - ((uint8_t *)pTmp - pStart);
   1003                         s->readBufLen = boundaryLen - s->readBufOff;
   1004                         memcpy(s->readBuf, pTmp, s->readBufOff);
   1005                         readBytes = data.readInputData(data.inputHandle, s->readBuf + s->readBufOff, s->readBufLen);
   1006                         if (-1 == readBytes || readBytes < s->readBufLen) {
   1007                             freeSession(s);
   1008                             return DRM_MEDIA_DATA_INVALID;
   1009                         }
   1010 
   1011                         if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
   1012                             binContentLen = (uint8_t *)pTmp - pStart; /* yes, it is the end boundary */
   1013                             bFoundBoundary = TRUE;
   1014                         }
   1015                     } else {
   1016                         if (res >= 0 && res < binContentLen) {
   1017                             binContentLen = res;
   1018                             bFoundBoundary = TRUE;
   1019                         }
   1020                     }
   1021 
   1022                     if (bFoundBoundary)
   1023                         s->contentLength = binContentLen;
   1024                 }
   1025             }
   1026         }
   1027         break;
   1028     case TYPE_DRM_CONTENT:
   1029         {
   1030             T_DRM_DCF_Info dcfInfo;
   1031             uint8_t* pEncData = NULL;
   1032 
   1033             memset(&dcfInfo, 0, sizeof(T_DRM_DCF_Info));
   1034             if (FALSE == drm_dcfParser(s->rawContent, s->rawContentLen, &dcfInfo, &pEncData)) {
   1035                 freeSession(s);
   1036                 return DRM_MEDIA_DATA_INVALID;
   1037             }
   1038 
   1039             s->infoStruct = (T_DRM_Dcf_Node *)malloc(sizeof(T_DRM_Dcf_Node));
   1040             if (NULL == s->infoStruct)
   1041                 return DRM_FAILURE;
   1042             memset(s->infoStruct, 0, sizeof(T_DRM_Dcf_Node));
   1043 
   1044             s->deliveryMethod = SEPARATE_DELIVERY;
   1045             s->contentLength = dcfInfo.DecryptedDataLen;
   1046             ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength = dcfInfo.EncryptedDataLen;
   1047             s->contentOffset = pEncData - s->rawContent;
   1048             strcpy((char *)s->contentType, (char *)dcfInfo.ContentType);
   1049             strcpy((char *)s->contentID, (char *)dcfInfo.ContentURI);
   1050             strcpy((char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer, (char *)dcfInfo.Rights_Issuer);
   1051         }
   1052         break;
   1053     case TYPE_DRM_RIGHTS_XML:   /* rights object should using "SVC_drm_installRights", it can not open a session */
   1054     case TYPE_DRM_RIGHTS_WBXML: /* rights object should using "SVC_drm_installRights", it can not open a session */
   1055     case TYPE_DRM_UNKNOWN:
   1056     default:
   1057         freeSession(s);
   1058         return DRM_MEDIA_DATA_INVALID;
   1059     }
   1060 
   1061     if ((SEPARATE_DELIVERY_FL == s->deliveryMethod || SEPARATE_DELIVERY == s->deliveryMethod) &&
   1062         s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN) {
   1063         uint8_t keyValue[DRM_KEY_LEN];
   1064         uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
   1065         int32_t seekPos, moreBytes;
   1066 
   1067         if (TRUE == drm_getKey(s->contentID, keyValue)) {
   1068             seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
   1069             memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
   1070 
   1071             if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
   1072                 s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
   1073                 s->contentLength -= moreBytes;
   1074             }
   1075         }
   1076     }
   1077 
   1078     session = addSession(s);
   1079     if (-1 == session)
   1080         return DRM_FAILURE;
   1081 
   1082     return session;
   1083 }
   1084 
   1085 /* see svc_drm.h */
   1086 int32_t SVC_drm_getDeliveryMethod(int32_t session)
   1087 {
   1088     T_DRM_Session_Node* s;
   1089 
   1090     if (session < 0)
   1091         return DRM_FAILURE;
   1092 
   1093     s = getSession(session);
   1094     if (NULL == s)
   1095         return DRM_SESSION_NOT_OPENED;
   1096 
   1097     return s->deliveryMethod;
   1098 }
   1099 
   1100 /* see svc_drm.h */
   1101 int32_t SVC_drm_getContentType(int32_t session, uint8_t* mediaType)
   1102 {
   1103     T_DRM_Session_Node* s;
   1104 
   1105     if (session < 0 || NULL == mediaType)
   1106         return DRM_FAILURE;
   1107 
   1108     s = getSession(session);
   1109     if (NULL == s)
   1110         return DRM_SESSION_NOT_OPENED;
   1111 
   1112     strcpy((char *)mediaType, (char *)s->contentType);
   1113 
   1114     return DRM_SUCCESS;
   1115 }
   1116 
   1117 /* see svc_drm.h */
   1118 int32_t SVC_drm_checkRights(int32_t session, int32_t permission)
   1119 {
   1120     T_DRM_Session_Node* s;
   1121     int32_t id;
   1122     T_DRM_Rights *pRo, *pCurRo;
   1123     int32_t roAmount;
   1124     int32_t i;
   1125     int32_t res = DRM_FAILURE;
   1126 
   1127     if (session < 0)
   1128         return DRM_FAILURE;
   1129 
   1130     s = getSession(session);
   1131     if (NULL == s)
   1132         return DRM_SESSION_NOT_OPENED;
   1133 
   1134     /* if it is Forward-Lock cases, check it and return directly */
   1135     if (FORWARD_LOCK == s->deliveryMethod) {
   1136         if (DRM_PERMISSION_PLAY == permission ||
   1137             DRM_PERMISSION_DISPLAY == permission ||
   1138             DRM_PERMISSION_EXECUTE == permission ||
   1139             DRM_PERMISSION_PRINT == permission)
   1140             return DRM_SUCCESS;
   1141 
   1142         return DRM_FAILURE;
   1143     }
   1144 
   1145     /* if try to forward, only DCF can be forwarded */
   1146     if (DRM_PERMISSION_FORWARD == permission) {
   1147         if (SEPARATE_DELIVERY == s->deliveryMethod)
   1148             return DRM_SUCCESS;
   1149 
   1150         return DRM_FAILURE;
   1151     }
   1152 
   1153     /* The following will check CD or SD other permissions */
   1154     if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
   1155         return DRM_FAILURE;
   1156 
   1157     drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
   1158     if (roAmount <= 0)
   1159         return DRM_FAILURE;
   1160 
   1161     pRo = malloc(roAmount * sizeof(T_DRM_Rights));
   1162     if (NULL == pRo)
   1163         return DRM_FAILURE;
   1164 
   1165     drm_writeOrReadInfo(id, pRo, &roAmount, GET_ALL_RO);
   1166 
   1167     pCurRo = pRo;
   1168     for (i = 0; i < roAmount; i++) {
   1169         switch (permission) {
   1170         case DRM_PERMISSION_PLAY:
   1171             res = drm_startCheckRights(&(pCurRo->bIsPlayable), &(pCurRo->PlayConstraint));
   1172             break;
   1173         case DRM_PERMISSION_DISPLAY:
   1174             res = drm_startCheckRights(&(pCurRo->bIsDisplayable), &(pCurRo->DisplayConstraint));
   1175             break;
   1176         case DRM_PERMISSION_EXECUTE:
   1177             res = drm_startCheckRights(&(pCurRo->bIsExecuteable), &(pCurRo->ExecuteConstraint));
   1178             break;
   1179         case DRM_PERMISSION_PRINT:
   1180             res = drm_startCheckRights(&(pCurRo->bIsPrintable), &(pCurRo->PrintConstraint));
   1181             break;
   1182         default:
   1183             free(pRo);
   1184             return DRM_FAILURE;
   1185         }
   1186 
   1187         if (DRM_SUCCESS == res) {
   1188             free(pRo);
   1189             return DRM_SUCCESS;
   1190         }
   1191         pCurRo++;
   1192     }
   1193 
   1194     free(pRo);
   1195     return res;
   1196 }
   1197 
   1198 /* see svc_drm.h */
   1199 int32_t SVC_drm_consumeRights(int32_t session, int32_t permission)
   1200 {
   1201     T_DRM_Session_Node* s;
   1202     int32_t id;
   1203 
   1204     if (session < 0)
   1205         return DRM_FAILURE;
   1206 
   1207     s = getSession(session);
   1208     if (NULL == s)
   1209         return DRM_SESSION_NOT_OPENED;
   1210 
   1211     if (DRM_PERMISSION_FORWARD == permission) {
   1212         if (SEPARATE_DELIVERY == s->deliveryMethod)
   1213             return DRM_SUCCESS;
   1214 
   1215         return DRM_FAILURE;
   1216     }
   1217 
   1218     if (FORWARD_LOCK == s->deliveryMethod) /* Forwardlock type have utter rights */
   1219         return DRM_SUCCESS;
   1220 
   1221     if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
   1222         return DRM_FAILURE;
   1223 
   1224     return drm_checkRoAndUpdate(id, permission);
   1225 }
   1226 
   1227 /* see svc_drm.h */
   1228 int32_t SVC_drm_getContentLength(int32_t session)
   1229 {
   1230     T_DRM_Session_Node* s;
   1231 
   1232     if (session < 0)
   1233         return DRM_FAILURE;
   1234 
   1235     s = getSession(session);
   1236     if (NULL == s)
   1237         return DRM_SESSION_NOT_OPENED;
   1238 
   1239     if (DRM_UNKNOWN_DATA_LEN == s->contentLength && s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength <= DRM_MAX_MALLOC_LEN &&
   1240         (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod)) {
   1241         uint8_t keyValue[DRM_KEY_LEN];
   1242         uint8_t lastDcfBuf[DRM_TWO_AES_BLOCK_LEN];
   1243         int32_t seekPos, moreBytes;
   1244 
   1245         if (TRUE == drm_getKey(s->contentID, keyValue)) {
   1246             seekPos = s->contentOffset + ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength - DRM_TWO_AES_BLOCK_LEN;
   1247             memcpy(lastDcfBuf, s->rawContent + seekPos, DRM_TWO_AES_BLOCK_LEN);
   1248 
   1249             if (TRUE == drm_updateDcfDataLen(lastDcfBuf, keyValue, &moreBytes)) {
   1250                 s->contentLength = ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength;
   1251                 s->contentLength -= moreBytes;
   1252             }
   1253         }
   1254     }
   1255 
   1256     return s->contentLength;
   1257 }
   1258 
   1259 static int32_t drm_readAesData(uint8_t* buf, T_DRM_Session_Node* s, int32_t aesStart, int32_t bufLen)
   1260 {
   1261     if (NULL == buf || NULL == s || aesStart < 0 || bufLen < 0)
   1262         return -1;
   1263 
   1264     if (aesStart - s->contentOffset + bufLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->encContentLength)
   1265         return -2;
   1266 
   1267     if (aesStart < DRM_MAX_MALLOC_LEN) {
   1268         if (aesStart + bufLen <= DRM_MAX_MALLOC_LEN) { /* read from buffer */
   1269             memcpy(buf, s->rawContent + aesStart, bufLen);
   1270             return bufLen;
   1271         } else { /* first read from buffer and then from InputStream */
   1272             int32_t point = DRM_MAX_MALLOC_LEN - aesStart;
   1273             int32_t res;
   1274 
   1275             if (((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf) {
   1276                 memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
   1277                 res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
   1278                 if (0 == res || -1 == res)
   1279                     return -1;
   1280 
   1281                 res += DRM_ONE_AES_BLOCK_LEN;
   1282             } else {
   1283                 memcpy(buf, s->rawContent + aesStart, point);
   1284                 res = s->readInputDataFunc(s->inputHandle, buf + point, bufLen - point);
   1285                 if (0 == res || -1 == res)
   1286                     return -1;
   1287 
   1288                 res += point;
   1289             }
   1290 
   1291             memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
   1292             ((T_DRM_Dcf_Node *)(s->infoStruct))->bAesBackupBuf = TRUE;
   1293 
   1294             return res;
   1295         }
   1296     } else { /* read from InputStream */
   1297         int32_t res;
   1298 
   1299         memcpy(buf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, DRM_ONE_AES_BLOCK_LEN);
   1300         res = s->readInputDataFunc(s->inputHandle, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
   1301 
   1302         if (0 == res || -1 == res)
   1303             return -1;
   1304 
   1305         memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesBackupBuf, buf + DRM_ONE_AES_BLOCK_LEN, DRM_ONE_AES_BLOCK_LEN);
   1306 
   1307         return DRM_ONE_AES_BLOCK_LEN + res;
   1308     }
   1309 }
   1310 
   1311 static int32_t drm_readContentFromBuf(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1312 {
   1313     int32_t readBytes;
   1314 
   1315     if (offset > s->contentLength)
   1316         return DRM_FAILURE;
   1317 
   1318     if (offset == s->contentLength)
   1319         return DRM_MEDIA_EOF;
   1320 
   1321     if (offset + mediaBufLen > s->contentLength)
   1322         readBytes = s->contentLength - offset;
   1323     else
   1324         readBytes = mediaBufLen;
   1325 
   1326     if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
   1327         memcpy(mediaBuf, s->rawContent + offset, readBytes);
   1328     else
   1329         memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
   1330 
   1331     return readBytes;
   1332 }
   1333 
   1334 static int32_t drm_readB64ContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1335 {
   1336     uint8_t encBuf[DRM_B64_ENC_BLOCK], decBuf[DRM_B64_DEC_BLOCK];
   1337     int32_t encLen, decLen;
   1338     int32_t i, j, piece, leftLen, firstBytes;
   1339     int32_t readBytes = 0;
   1340 
   1341     if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
   1342         readBytes = ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen - offset;
   1343         memcpy(mediaBuf, s->rawContent + offset, readBytes);
   1344     } else {
   1345         if (s->bEndData)
   1346             return DRM_MEDIA_EOF;
   1347 
   1348         firstBytes = offset % DRM_B64_DEC_BLOCK;
   1349         if (firstBytes > 0) {
   1350             if (DRM_B64_DEC_BLOCK - firstBytes >= mediaBufLen) {
   1351                 readBytes = mediaBufLen;
   1352                 memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
   1353                 return readBytes;
   1354             }
   1355 
   1356             readBytes = DRM_B64_DEC_BLOCK - firstBytes;
   1357             memcpy(mediaBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData + firstBytes, readBytes);
   1358         }
   1359     }
   1360 
   1361     leftLen = mediaBufLen - readBytes;
   1362     encLen = (leftLen - 1) / DRM_B64_DEC_BLOCK * DRM_B64_ENC_BLOCK + DRM_B64_ENC_BLOCK;
   1363     piece = encLen / DRM_B64_ENC_BLOCK;
   1364 
   1365     for (i = 0; i < piece; i++) {
   1366         j = 0;
   1367         while (j < DRM_B64_ENC_BLOCK) {
   1368             if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
   1369                 *(encBuf + j) = s->readBuf[s->readBufOff];
   1370                 s->readBufOff++;
   1371                 s->readBufLen--;
   1372             } else { /* read from InputStream */
   1373                 if (0 == s->readInputDataFunc(s->inputHandle, encBuf + j, 1))
   1374                     return DRM_MEDIA_DATA_INVALID;
   1375             }
   1376 
   1377             if ('\r' == *(encBuf + j) || '\n' == *(encBuf + j))
   1378                 continue; /* skip CRLF */
   1379 
   1380             if ('-' == *(encBuf + j)) {
   1381                 int32_t k, len;
   1382 
   1383                 /* invalid base64 data, it comes to end boundary */
   1384                 if (0 != j)
   1385                     return DRM_MEDIA_DATA_INVALID;
   1386 
   1387                 /* check whether it is really the boundary */
   1388                 len = strlen((char *)((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary);
   1389                 if (NULL == s->readBuf) {
   1390                     s->readBuf = (uint8_t *)malloc(len);
   1391                     if (NULL == s->readBuf)
   1392                         return DRM_FAILURE;
   1393                 }
   1394 
   1395                 s->readBuf[0] = '-';
   1396                 for (k = 0; k < len - 1; k++) {
   1397                     if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
   1398                         *(s->readBuf + k + 1) = s->readBuf[s->readBufOff];
   1399                         s->readBufOff++;
   1400                         s->readBufLen--;
   1401                     } else { /* read from InputStream */
   1402                         if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + 1, 1))
   1403                             return DRM_MEDIA_DATA_INVALID;
   1404                     }
   1405                 }
   1406                 if (0 == memcmp(s->readBuf, ((T_DRM_DM_Base64_Node *)(s->infoStruct))->boundary, len))
   1407                     s->bEndData = TRUE;
   1408                 else
   1409                     return DRM_MEDIA_DATA_INVALID;
   1410 
   1411                 break;
   1412             }
   1413             j++;
   1414         }
   1415 
   1416         if (TRUE == s->bEndData) { /* it means come to the end of base64 data */
   1417             if (0 == readBytes)
   1418                 return DRM_MEDIA_EOF;
   1419 
   1420             break;
   1421         }
   1422 
   1423         encLen = DRM_B64_ENC_BLOCK;
   1424         decLen = DRM_B64_DEC_BLOCK;
   1425         if (-1 == (decLen = drm_decodeBase64(decBuf, decLen, encBuf, &encLen)))
   1426             return DRM_MEDIA_DATA_INVALID;
   1427 
   1428         if (leftLen >= decLen) {
   1429             memcpy(mediaBuf + readBytes, decBuf, decLen);
   1430             readBytes += decLen;
   1431             leftLen -= decLen;
   1432         } else {
   1433             if (leftLen > 0) {
   1434                 memcpy(mediaBuf + readBytes, decBuf, leftLen);
   1435                 readBytes += leftLen;
   1436             }
   1437             break;
   1438         }
   1439     }
   1440     memcpy(((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeData, decBuf, DRM_B64_DEC_BLOCK);
   1441 
   1442     return readBytes;
   1443 }
   1444 
   1445 static int32_t drm_readBase64Content(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1446 {
   1447     int32_t readBytes;
   1448 
   1449     /* when the content length has been well-known */
   1450     if (s->contentLength >= 0)
   1451         readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
   1452     else /* else when the content length has not been well-known yet */
   1453         if (offset < ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen)
   1454             if (offset + mediaBufLen <= ((T_DRM_DM_Base64_Node *)(s->infoStruct))->b64DecodeDataLen) {
   1455                 readBytes = mediaBufLen;
   1456                 memcpy(mediaBuf, s->rawContent + offset, readBytes);
   1457             } else
   1458                 readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
   1459         else
   1460             readBytes = drm_readB64ContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
   1461 
   1462     return readBytes;
   1463 }
   1464 
   1465 static int32_t drm_readBinaryContentFromInputStream(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1466 {
   1467     int32_t res = 0, readBytes = 0;
   1468     int32_t leftLen;
   1469 
   1470     if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN) {
   1471         readBytes = DRM_MAX_MALLOC_LEN - s->contentOffset - offset;
   1472         memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
   1473     } else
   1474         if (s->bEndData)
   1475             return DRM_MEDIA_EOF;
   1476 
   1477     leftLen = mediaBufLen - readBytes;
   1478 
   1479     if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
   1480         if (leftLen <= s->readBufLen) {
   1481             memcpy(mediaBuf, s->readBuf + s->readBufOff, leftLen);
   1482             s->readBufOff += leftLen;
   1483             s->readBufLen -= leftLen;
   1484             readBytes += leftLen;
   1485             leftLen = 0;
   1486         } else {
   1487             memcpy(mediaBuf, s->readBuf + s->readBufOff, s->readBufLen);
   1488             s->readBufOff += s->readBufLen;
   1489             leftLen -= s->readBufLen;
   1490             readBytes += s->readBufLen;
   1491             s->readBufLen = 0;
   1492         }
   1493     }
   1494 
   1495     if (leftLen > 0) {
   1496         res = s->readInputDataFunc(s->inputHandle, mediaBuf + readBytes, mediaBufLen - readBytes);
   1497         if (-1 == res)
   1498             return DRM_MEDIA_DATA_INVALID;
   1499     }
   1500 
   1501     readBytes += res;
   1502     res = drm_scanEndBoundary(mediaBuf, readBytes, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary);
   1503     if (-1 == res)
   1504         return DRM_MEDIA_DATA_INVALID;
   1505     if (-2 == res) { /* may be the boundary is split */
   1506         int32_t boundaryLen, len, off, k;
   1507         char* pTmp = memrchr(mediaBuf, '\r', readBytes);
   1508 
   1509         if (NULL == pTmp)
   1510             return DRM_FAILURE; /* conflict */
   1511 
   1512         boundaryLen = strlen((char *)((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary) + 2; /* 2 means: '\r''\n' */
   1513         if (NULL == s->readBuf) {
   1514             s->readBuf = (uint8_t *)malloc(boundaryLen);
   1515             if (NULL == s->readBuf)
   1516                 return DRM_FAILURE;
   1517         }
   1518 
   1519         off = readBytes - ((uint8_t *)pTmp - mediaBuf);
   1520         len = boundaryLen - off;
   1521         memcpy(s->readBuf, pTmp, off);
   1522         for (k = 0; k < boundaryLen - off; k++) {
   1523             if (NULL != s->readBuf && s->readBufLen > 0) { /* read from backup buffer */
   1524                 *(s->readBuf + k + off) = s->readBuf[s->readBufOff];
   1525                 s->readBufOff++;
   1526                 s->readBufLen--;
   1527             } else { /* read from InputStream */
   1528                 if (-1 == s->readInputDataFunc(s->inputHandle, s->readBuf + k + off, 1))
   1529                     return DRM_MEDIA_DATA_INVALID;
   1530             }
   1531         }
   1532         s->readBufOff = off;
   1533         s->readBufLen = len;
   1534 
   1535         if (0 == drm_scanEndBoundary(s->readBuf, boundaryLen, ((T_DRM_DM_Binary_Node *)(s->infoStruct))->boundary)) {
   1536             readBytes = (uint8_t *)pTmp - mediaBuf; /* yes, it is the end boundary */
   1537             s->bEndData = TRUE;
   1538         }
   1539     } else {
   1540         if (res >= 0 && res < readBytes) {
   1541             readBytes = res;
   1542             s->bEndData = TRUE;
   1543         }
   1544     }
   1545 
   1546     if (s->bEndData) {
   1547         if (0 == readBytes)
   1548             return DRM_MEDIA_EOF;
   1549     }
   1550 
   1551     return readBytes;
   1552 }
   1553 
   1554 static int32_t drm_readBinaryContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1555 {
   1556     int32_t readBytes;
   1557 
   1558     if (s->contentLength >= 0)
   1559         readBytes = drm_readContentFromBuf(s, offset, mediaBuf, mediaBufLen);
   1560     else /* else when the content length has not been well-known yet */
   1561         if (s->contentOffset + offset < DRM_MAX_MALLOC_LEN)
   1562             if (s->contentOffset + offset + mediaBufLen <= DRM_MAX_MALLOC_LEN) {
   1563                 readBytes = mediaBufLen;
   1564                 memcpy(mediaBuf, s->rawContent + s->contentOffset + offset, readBytes);
   1565             } else
   1566                 readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
   1567         else
   1568             readBytes = drm_readBinaryContentFromInputStream(s, offset, mediaBuf, mediaBufLen);
   1569 
   1570     return readBytes;
   1571 }
   1572 
   1573 static int32_t drm_readAesContent(T_DRM_Session_Node* s, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1574 {
   1575     uint8_t keyValue[DRM_KEY_LEN];
   1576     uint8_t buf[DRM_TWO_AES_BLOCK_LEN];
   1577     int32_t readBytes = 0;
   1578     int32_t bufLen, piece, i, copyBytes, leftBytes;
   1579     int32_t aesStart, mediaStart, mediaBufOff;
   1580     AES_KEY key;
   1581 
   1582     if (FALSE == drm_getKey(s->contentID, keyValue))
   1583         return DRM_NO_RIGHTS;
   1584 
   1585     /* when the content length has been well-known */
   1586     if (s->contentLength > 0) {
   1587         if (offset > s->contentLength)
   1588             return DRM_FAILURE;
   1589 
   1590         if (offset == s->contentLength)
   1591             return DRM_MEDIA_EOF;
   1592 
   1593         if (offset + mediaBufLen > s->contentLength)
   1594             readBytes = s->contentLength - offset;
   1595         else
   1596             readBytes = mediaBufLen;
   1597 
   1598         aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
   1599         piece = (offset + readBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
   1600         mediaStart = offset % DRM_ONE_AES_BLOCK_LEN;
   1601 
   1602         AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
   1603         mediaBufOff = 0;
   1604         leftBytes = readBytes;
   1605 
   1606         for (i = 0; i < piece - 1; i++) {
   1607             memcpy(buf, s->rawContent + aesStart + i * DRM_ONE_AES_BLOCK_LEN, DRM_TWO_AES_BLOCK_LEN);
   1608             bufLen = DRM_TWO_AES_BLOCK_LEN;
   1609 
   1610             if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
   1611                 return DRM_MEDIA_DATA_INVALID;
   1612 
   1613             if (0 != i)
   1614                 mediaStart = 0;
   1615 
   1616             if (bufLen - mediaStart <= leftBytes)
   1617                 copyBytes = bufLen - mediaStart;
   1618             else
   1619                 copyBytes = leftBytes;
   1620 
   1621             memcpy(mediaBuf + mediaBufOff, buf + mediaStart, copyBytes);
   1622             leftBytes -= copyBytes;
   1623             mediaBufOff += copyBytes;
   1624         }
   1625     } else {
   1626         int32_t res;
   1627 
   1628         if (s->bEndData)
   1629             return DRM_MEDIA_EOF;
   1630 
   1631         if (((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen > ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff) {
   1632             if (mediaBufLen < ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff)
   1633                 copyBytes = mediaBufLen;
   1634             else
   1635                 copyBytes = ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen - ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff;
   1636 
   1637             memcpy(mediaBuf, ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData + ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff, copyBytes);
   1638             ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff += copyBytes;
   1639             readBytes += copyBytes;
   1640         }
   1641 
   1642         leftBytes = mediaBufLen - readBytes;
   1643         if (0 == leftBytes)
   1644             return readBytes;
   1645         if (leftBytes < 0)
   1646             return DRM_FAILURE;
   1647 
   1648         offset += readBytes;
   1649         aesStart = s->contentOffset + (offset / DRM_ONE_AES_BLOCK_LEN * DRM_ONE_AES_BLOCK_LEN);
   1650         piece = (offset + leftBytes - 1) / DRM_ONE_AES_BLOCK_LEN - offset / DRM_ONE_AES_BLOCK_LEN + 2;
   1651         mediaBufOff = readBytes;
   1652 
   1653         AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
   1654 
   1655         for (i = 0; i < piece - 1; i++) {
   1656             if (-1 == (res = drm_readAesData(buf, s, aesStart, DRM_TWO_AES_BLOCK_LEN)))
   1657                 return DRM_MEDIA_DATA_INVALID;
   1658 
   1659             if (-2 == res)
   1660                 break;
   1661 
   1662             bufLen = DRM_TWO_AES_BLOCK_LEN;
   1663             aesStart += DRM_ONE_AES_BLOCK_LEN;
   1664 
   1665             if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
   1666                 return DRM_MEDIA_DATA_INVALID;
   1667 
   1668             drm_discardPaddingByte(buf, &bufLen);
   1669 
   1670             if (bufLen <= leftBytes)
   1671                 copyBytes = bufLen;
   1672             else
   1673                 copyBytes = leftBytes;
   1674 
   1675             memcpy(mediaBuf + mediaBufOff, buf, copyBytes);
   1676             leftBytes -= copyBytes;
   1677             mediaBufOff += copyBytes;
   1678             readBytes += copyBytes;
   1679         }
   1680 
   1681         memcpy(((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecData, buf, DRM_ONE_AES_BLOCK_LEN);
   1682         ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataLen = bufLen;
   1683         ((T_DRM_Dcf_Node *)(s->infoStruct))->aesDecDataOff = copyBytes;
   1684 
   1685         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) {
   1686             s->bEndData = TRUE;
   1687             if (0 == readBytes)
   1688                 return DRM_MEDIA_EOF;
   1689         }
   1690     }
   1691 
   1692     return readBytes;
   1693 }
   1694 
   1695 /* see svc_drm.h */
   1696 int32_t SVC_drm_getContent(int32_t session, int32_t offset, uint8_t* mediaBuf, int32_t mediaBufLen)
   1697 {
   1698     T_DRM_Session_Node* s;
   1699     int32_t readBytes;
   1700 
   1701     if (session < 0 || offset < 0 || NULL == mediaBuf || mediaBufLen <= 0)
   1702         return DRM_FAILURE;
   1703 
   1704     s = getSession(session);
   1705     if (NULL == s)
   1706         return DRM_SESSION_NOT_OPENED;
   1707 
   1708     if (0 >= s->getInputDataLengthFunc(s->inputHandle))
   1709         return DRM_MEDIA_DATA_INVALID;
   1710 
   1711     switch(s->deliveryMethod) {
   1712     case FORWARD_LOCK:
   1713     case COMBINED_DELIVERY:
   1714         if (DRM_MESSAGE_CODING_BASE64 == s->transferEncoding)
   1715             readBytes = drm_readBase64Content(s, offset, mediaBuf, mediaBufLen);
   1716         else /* binary */
   1717             readBytes = drm_readBinaryContent(s, offset, mediaBuf, mediaBufLen);
   1718         break;
   1719     case SEPARATE_DELIVERY:
   1720     case SEPARATE_DELIVERY_FL:
   1721         readBytes = drm_readAesContent(s, offset, mediaBuf, mediaBufLen);
   1722         break;
   1723     default:
   1724         return DRM_FAILURE;
   1725     }
   1726 
   1727     return readBytes;
   1728 }
   1729 
   1730 /* see svc_drm.h */
   1731 int32_t SVC_drm_getRightsIssuer(int32_t session, uint8_t* rightsIssuer)
   1732 {
   1733     T_DRM_Session_Node* s;
   1734 
   1735     if (session < 0 || NULL == rightsIssuer)
   1736         return DRM_FAILURE;
   1737 
   1738     s = getSession(session);
   1739     if (NULL == s)
   1740         return DRM_SESSION_NOT_OPENED;
   1741 
   1742     if (SEPARATE_DELIVERY == s->deliveryMethod || SEPARATE_DELIVERY_FL == s->deliveryMethod) {
   1743         strcpy((char *)rightsIssuer, (char *)((T_DRM_Dcf_Node *)(s->infoStruct))->rightsIssuer);
   1744         return DRM_SUCCESS;
   1745     }
   1746 
   1747     return DRM_NOT_SD_METHOD;
   1748 }
   1749 
   1750 /* see svc_drm.h */
   1751 int32_t SVC_drm_getRightsInfo(int32_t session, T_DRM_Rights_Info* rights)
   1752 {
   1753     T_DRM_Session_Node* s;
   1754     T_DRM_Rights rightsInfo;
   1755     int32_t roAmount, id;
   1756 
   1757     if (session < 0 || NULL == rights)
   1758         return DRM_FAILURE;
   1759 
   1760     s = getSession(session);
   1761     if (NULL == s)
   1762         return DRM_SESSION_NOT_OPENED;
   1763 
   1764     if (FORWARD_LOCK == s->deliveryMethod) {
   1765         strcpy((char *)rights->roId, "ForwardLock");
   1766         rights->displayRights.indicator = DRM_NO_CONSTRAINT;
   1767         rights->playRights.indicator = DRM_NO_CONSTRAINT;
   1768         rights->executeRights.indicator = DRM_NO_CONSTRAINT;
   1769         rights->printRights.indicator = DRM_NO_CONSTRAINT;
   1770         return DRM_SUCCESS;
   1771     }
   1772 
   1773     if (FALSE == drm_readFromUidTxt(s->contentID, &id, GET_ID))
   1774         return DRM_NO_RIGHTS;
   1775 
   1776     if (FALSE == drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT))
   1777         return DRM_FAILURE;
   1778 
   1779     if (roAmount < 0)
   1780         return DRM_NO_RIGHTS;
   1781 
   1782     /* some rights has been installed, but now there is no valid rights */
   1783     if (0 == roAmount) {
   1784         strcpy((char *)rights->roId, s->contentID);
   1785         rights->displayRights.indicator = DRM_NO_PERMISSION;
   1786         rights->playRights.indicator = DRM_NO_PERMISSION;
   1787         rights->executeRights.indicator = DRM_NO_PERMISSION;
   1788         rights->printRights.indicator = DRM_NO_PERMISSION;
   1789         return DRM_SUCCESS;
   1790     }
   1791 
   1792     roAmount = 1;
   1793     memset(&rightsInfo, 0, sizeof(T_DRM_Rights));
   1794     if (FALSE == drm_writeOrReadInfo(id, &rightsInfo, &roAmount, GET_A_RO))
   1795         return DRM_FAILURE;
   1796 
   1797     memset(rights, 0, sizeof(T_DRM_Rights_Info));
   1798     drm_getLicenseInfo(&rightsInfo, rights);
   1799     return DRM_SUCCESS;
   1800 }
   1801 
   1802 /* see svc_drm.h */
   1803 int32_t SVC_drm_closeSession(int32_t session)
   1804 {
   1805     if (session < 0)
   1806         return DRM_FAILURE;
   1807 
   1808     if (NULL == getSession(session))
   1809         return DRM_SESSION_NOT_OPENED;
   1810 
   1811     removeSession(session);
   1812 
   1813     return DRM_SUCCESS;
   1814 }
   1815 
   1816 /* see svc_drm.h */
   1817 int32_t SVC_drm_updateRights(uint8_t* contentID, int32_t permission)
   1818 {
   1819     int32_t id;
   1820 
   1821     if (NULL == contentID)
   1822         return DRM_FAILURE;
   1823 
   1824     if (FALSE == drm_readFromUidTxt(contentID, &id, GET_ID))
   1825         return DRM_FAILURE;
   1826 
   1827     return drm_checkRoAndUpdate(id, permission);
   1828 }
   1829 
   1830 /* see svc_drm.h */
   1831 int32_t SVC_drm_viewAllRights(T_DRM_Rights_Info_Node **ppRightsInfo)
   1832 {
   1833     T_DRM_Rights_Info_Node rightsNode;
   1834     int32_t maxId, id, roAmount, j;
   1835     T_DRM_Rights rights;
   1836 
   1837     memset(&rights, 0, sizeof(T_DRM_Rights));
   1838 
   1839     if (NULL == ppRightsInfo)
   1840         return DRM_FAILURE;
   1841 
   1842     *ppRightsInfo = NULL;
   1843 
   1844     maxId = drm_getMaxIdFromUidTxt();
   1845     if (-1 == maxId)
   1846         return DRM_FAILURE;
   1847 
   1848     for (id = 1; id <= maxId; id++) {
   1849         drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
   1850         if (roAmount <= 0) /* this means there is not any rights */
   1851             continue;
   1852 
   1853         for (j = 1; j <= roAmount; j++) {
   1854             if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
   1855                 continue;
   1856 
   1857             memset(&rightsNode, 0, sizeof(T_DRM_Rights_Info_Node));
   1858 
   1859             drm_getLicenseInfo(&rights, &(rightsNode.roInfo));
   1860 
   1861             if (FALSE == drm_addRightsNodeToList(ppRightsInfo, &rightsNode))
   1862                 continue;
   1863         }
   1864     }
   1865     return DRM_SUCCESS;
   1866 }
   1867 
   1868 /* see svc_drm.h */
   1869 int32_t SVC_drm_freeRightsInfoList(T_DRM_Rights_Info_Node *pRightsHeader)
   1870 {
   1871     T_DRM_Rights_Info_Node *pNode, *pTmp;
   1872 
   1873     if (NULL == pRightsHeader)
   1874         return DRM_FAILURE;
   1875 
   1876     pNode = pRightsHeader;
   1877 
   1878     while (NULL != pNode) {
   1879         pTmp = pNode;
   1880         pNode = pNode->next;
   1881         free(pTmp);
   1882     }
   1883     return DRM_SUCCESS;
   1884 }
   1885 
   1886 /* see svc_drm.h */
   1887 int32_t SVC_drm_deleteRights(uint8_t* roId)
   1888 {
   1889     int32_t maxId, id, roAmount, j;
   1890     T_DRM_Rights rights;
   1891 
   1892     memset(&rights, 0, sizeof(T_DRM_Rights));
   1893 
   1894     if (NULL == roId)
   1895         return DRM_FAILURE;
   1896 
   1897     maxId = drm_getMaxIdFromUidTxt();
   1898     if (-1 == maxId)
   1899         return DRM_NO_RIGHTS;
   1900 
   1901     for (id = 1; id <= maxId; id++) {
   1902         drm_writeOrReadInfo(id, NULL, &roAmount, GET_ROAMOUNT);
   1903         if (roAmount <= 0) /* this means there is not any rights */
   1904             continue;
   1905 
   1906         for (j = 1; j <= roAmount; j++) {
   1907             if (FALSE == drm_writeOrReadInfo(id, &rights, &j, GET_A_RO))
   1908                 continue;
   1909 
   1910             /* here find the RO which will be deleted */
   1911             if (0 == strcmp((char *)rights.uid, (char *)roId)) {
   1912                 T_DRM_Rights *pAllRights;
   1913 
   1914                 pAllRights = (T_DRM_Rights *)malloc(roAmount * sizeof(T_DRM_Rights));
   1915                 if (NULL == pAllRights)
   1916                     return DRM_FAILURE;
   1917 
   1918                 drm_writeOrReadInfo(id, pAllRights, &roAmount, GET_ALL_RO);
   1919                 roAmount--;
   1920                 if (0 == roAmount) { /* this means it is the last one rights */
   1921                     drm_removeIdInfoFile(id); /* delete the id.info file first */
   1922                     drm_updateUidTxtWhenDelete(id); /* update uid.txt file */
   1923                     free(pAllRights);
   1924                     return DRM_SUCCESS;
   1925                 } else /* using the last one rights instead of the deleted one */
   1926                     memcpy(pAllRights + (j - 1), pAllRights + roAmount, sizeof(T_DRM_Rights));
   1927 
   1928                 /* delete the id.info file first */
   1929 //                drm_removeIdInfoFile(id);
   1930 
   1931                 if (FALSE == drm_writeOrReadInfo(id, pAllRights, &roAmount, SAVE_ALL_RO)) {
   1932                     free(pAllRights);
   1933                     return DRM_FAILURE;
   1934                 }
   1935 
   1936                 free(pAllRights);
   1937                 return DRM_SUCCESS;
   1938             }
   1939         }
   1940     }
   1941 
   1942     return DRM_FAILURE;
   1943 }
   1944