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 */
30static int32_t curID = 0;
31
32/**
33 * The header pointer for the session list.
34 */
35static T_DRM_Session_Node* sessionTable = NULL;
36
37/**
38 * New a session.
39 */
40static 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 */
61static 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 */
81static 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 */
95static 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 */
113static 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 */
142static 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
170static 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
188static 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
218static 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
295static 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
325static 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
442static 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
506int32_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 */
708int32_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 */
794int32_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 */
1086int32_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 */
1101int32_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 */
1118int32_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 */
1199int32_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 */
1228int32_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
1259static 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
1311static 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
1334static 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
1445static 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
1465static 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 + readBytes, s->readBuf + s->readBufOff, leftLen);
1482            s->readBufOff += leftLen;
1483            s->readBufLen -= leftLen;
1484            readBytes += leftLen;
1485            leftLen = 0;
1486        } else {
1487            memcpy(mediaBuf + readBytes, 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
1554static 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
1573static 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 */
1696int32_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 */
1731int32_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 */
1751int32_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 */
1803int32_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 */
1817int32_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 */
1831int32_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 */
1869int32_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 */
1887int32_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