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 <dcf/DrmDcfContainer.h>
18
19DcfContainer::DcfContainer(const uint8_t* data,istream& inRawData,uint64_t conOff)
20                : FullBox(data),mConStream(inRawData)
21{
22    if(!data)
23    {
24        return;
25    }
26
27    const uint8_t* p = data;
28    const uint8_t* flag = this->getFlag();
29
30    if(flag[0] & USER_DATA_FLAG)
31    {
32        mHasUserData = true;
33    }
34    else
35    {
36        mHasUserData = false;
37    }
38
39    p += this->getLen();
40
41    FullBox fullBoxDiscrete(p);
42
43    p += fullBoxDiscrete.getLen();
44
45    mContentTypeLen = *p;
46    p++;
47
48    mContentType.assign((const char*)p,0,mContentTypeLen);
49    p += mContentTypeLen;
50
51    // parse common header
52    FullBox fullBoxComm(p);
53    p += fullBoxComm.getLen();
54
55    mEncryptionMethod = *p;
56    p++;
57
58    mPaddingScheme = *p;
59    p++;
60
61    mPlaintextLength = ntoh_int64(*((uint64_t *)p));
62    p += sizeof(mPlaintextLength);
63
64    mContentIDLength = ntohs(*(uint16_t *)p);
65    p += sizeof(mContentIDLength);
66
67    mRightsIssuerURLLength = ntohs(*(uint16_t *)p);
68    p += sizeof(mRightsIssuerURLLength);
69
70    mTextualHeadersLength = ntohs(*(uint16_t *)p);
71    p += sizeof(mTextualHeadersLength);
72
73    mContentID.assign((const char *)p,0,mContentIDLength);
74    p += mContentIDLength;
75
76    mRightsIssuerURL.assign((const char *)p,0,mRightsIssuerURLLength);
77    p += mRightsIssuerURLLength;
78
79    // parse textual header
80    if (mTextualHeadersLength > 0)
81    {
82        if(false == parseTextualHeaders(p,mTextualHeadersLength))
83        {
84            return;
85        }
86
87        p += mTextualHeadersLength;
88    }
89
90    ////////////// parser group id
91
92    ///parse content
93    p = data + this->getLen() + fullBoxDiscrete.getSize();
94    FullBox fullBoxContetn(p);
95    p += fullBoxContetn.getLen();
96    mDataLen = ntoh_int64(*((uint64_t *)p));
97    p += sizeof(mDataLen);
98
99    mDecOffset = conOff + (p - data);
100    p += mDataLen;
101
102    /////////////// parser user data
103}
104
105DcfContainer::~DcfContainer()
106{
107    uint32_t size = mTextualHeaders.size();
108
109    for(uint32_t i = 0; i < size; i++)
110    {
111        delete mTextualHeaders[i];
112    }
113
114    mTextualHeaders.clear();
115    mCustomHeader.clear();
116}
117
118
119string DcfContainer::getContentType(void) const
120{
121    return mContentType;
122}
123
124uint8_t DcfContainer::getEncryptionMethod(void) const
125{
126    return mEncryptionMethod;
127}
128
129uint8_t DcfContainer::getPaddingScheme(void) const
130{
131    return mPaddingScheme;
132}
133
134uint64_t DcfContainer::getPlaintextLength(void) const
135{
136    return mPlaintextLength;
137}
138
139uint16_t DcfContainer::getContentIDLength(void) const
140{
141    return mContentIDLength;
142}
143
144uint16_t DcfContainer::getRightsIssuerURLLength(void) const
145{
146    return mRightsIssuerURLLength;
147}
148
149uint16_t DcfContainer::getTextualHeadersLength(void) const
150{
151    return mTextualHeadersLength;
152}
153
154string DcfContainer::getContentID(void) const
155{
156    return mContentID;
157}
158
159string DcfContainer::getRightsIssuerURL(void) const
160{
161    return mRightsIssuerURL;
162}
163
164string DcfContainer::getPreviewMethod(void) const
165{
166    return mSlientMethod;
167}
168
169string DcfContainer::getContentLocation(void) const
170{
171    return mContentLocation;
172}
173
174string DcfContainer::getContentURL(void) const
175{
176    return mContentURL;
177}
178
179vector<string> DcfContainer::getCustomerHead(void) const
180{
181    return mCustomHeader;
182}
183
184istream& DcfContainer::getStream(void) const
185{
186    return mConStream;
187}
188
189DrmInStream DcfContainer::getPreviewElementData(void) const
190{
191     // get data based on mPreviewElementURI
192     //encryptedData = ;
193
194     DrmInStream inStream;
195     return inStream;
196}
197
198DrmInStream DcfContainer::getDecryptContent(uint8_t* decryptKey) const
199{
200    DrmInStream inStream(this,decryptKey);
201    return inStream;
202}
203
204bool DcfContainer::parseTextualHeaders(const uint8_t* data, uint32_t len)
205{
206    if(!data)
207    {
208        return false;
209    }
210
211    const uint8_t* p = data;
212
213    while (len > (uint32_t)(p - data))
214    {
215        uint32_t l = strlen((const char*)p);
216
217        string str((const char*)p, l);
218        TextualHeader* tmp = new TextualHeader(str);
219
220        if(!tmp)
221        {
222            return false;
223        }
224
225        mTextualHeaders.push_back(tmp);
226
227        p += l + 1;
228    }
229
230    uint32_t size = mTextualHeaders.size();
231    uint32_t silentpos = 0;
232    uint32_t previewpos = 0;
233
234    for( uint32_t i = 0; i < size; i++)
235    {
236        string tempStr = mTextualHeaders[i]->getName();
237
238        if(tempStr == "Silent")
239        {
240            silentpos = i;
241            mSlientMethod = mTextualHeaders[i]->getValue();
242            mSilentRightsURL = mTextualHeaders[i]->getParam();
243        }
244        else if(tempStr == "Preview")
245        {
246            previewpos = i;
247            mPreviewMethod = mTextualHeaders[i]->getValue();
248
249            if(mPreviewMethod == "instant")
250            {
251                mPreviewElementURI = mTextualHeaders[i]->getParam();
252            }
253            else
254            {
255                mPreviewRightsURL = mTextualHeaders[i]->getParam();
256            }
257        }
258        else if(tempStr == "ContentURL")
259        {
260            mContentURL = mTextualHeaders[i]->getValue();
261        }
262        else if(tempStr == "ContentVersion")
263        {
264            mContentVersion = mTextualHeaders[i]->getValue();
265        }
266        if(tempStr == "Content-Location")
267        {
268            mContentLocation = mTextualHeaders[i]->getValue();
269        }
270        else
271        {
272            string str = mTextualHeaders[i]->getName();
273            str += ":";
274            str += mTextualHeaders[i]->getValue();
275            mCustomHeader.push_back(str);
276        }
277    }
278
279    if(silentpos < previewpos)
280    {
281        mSilentFirst = true;
282    }
283    else
284    {
285        mSilentFirst = false;
286    }
287
288    return true;
289}
290
291
292
293
294
295