blob: 232d9f44a1c3b6943063caecca4d21659aa228a5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025#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) {
git-you.kim72.gmail.comfd202962012-07-30 17:06:41 +09001481 memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, leftLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 s->readBufOff += leftLen;
1483 s->readBufLen -= leftLen;
1484 readBytes += leftLen;
1485 leftLen = 0;
1486 } else {
git-you.kim72.gmail.comfd202962012-07-30 17:06:41 +09001487 memcpy(mediaBuf + readBytes, s->readBuf + s->readBufOff, s->readBufLen);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 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;
Chia-chi Yeh64e69e82009-08-06 02:28:24 +08001580 AES_KEY key;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581
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
Chia-chi Yeh64e69e82009-08-06 02:28:24 +08001602 AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 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
Chia-chi Yeh64e69e82009-08-06 02:28:24 +08001610 if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 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
Chia-chi Yeh64e69e82009-08-06 02:28:24 +08001653 AES_set_decrypt_key(keyValue, DRM_KEY_LEN * 8, &key);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654
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
Chia-chi Yeh64e69e82009-08-06 02:28:24 +08001665 if (drm_aesDecBuffer(buf, &bufLen, &key) < 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 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}