1 /*
2  *			GPAC - Multimedia Framework C SDK
3  *
4  *			Authors: Jonathan Sillan
5  *			Copyright (c) Telecom ParisTech 2011-2020
6  *					All rights reserved
7  *
8  *  This file is part of GPAC / media tools sub-project
9  *
10  *  GPAC is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU Lesser General Public License as published by
12  *  the Free Software Foundation; either version 2, or (at your option)
13  *  any later version.
14  *
15  *  GPAC is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; see the file COPYING.  If not, write to
22  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 
26 
27 #include <gpac/dsmcc.h>
28 
29 #ifdef GPAC_ENABLE_DSMCC
30 
31 /* DSMCC */
32 
33 
34 /* static functions */
35 static GF_Err dsmcc_download_data_validation(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK* DownloadDataBlock,GF_M2TS_DSMCC_MODULE* dsmcc_module,u32 downloadId);
36 static GF_Err gf_m2ts_dsmcc_process_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR *CompatibilityDesc, char* data,GF_BitStream *bs,u32* data_shift);
37 static GF_Err gf_m2ts_dsmcc_process_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER *MessageHeader, char* data,GF_BitStream *bs,u32* data_shift,u32 mode);
38 static GF_Err gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD *dsmcc_overlord,GF_M2TS_DSMCC_SECTION *dsmcc, char  *data, GF_BitStream *bs,u32* data_shift);
39 static GF_Err gf_m2ts_dsmcc_section_delete(GF_M2TS_DSMCC_SECTION *dsmcc);
40 static GF_Err gf_m2ts_dsmcc_delete_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER *MessageHeader);
41 static GF_Err gf_m2ts_dsmcc_delete_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR *CompatibilityDesc);
42 
43 
44 static GF_Err dsmcc_module_delete(GF_M2TS_DSMCC_MODULE* dsmcc_module);
45 //static GF_Err dsmcc_module_state(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,u32 moduleId,u32 moduleVersion);
46 static GF_Err dsmcc_create_module_validation(GF_M2TS_DSMCC_INFO_MODULES* InfoModules, u32 downloadId, GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,u32 nb_module);
47 static GF_Err dsmcc_module_complete(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_MODULE* dsmcc_module,u32 moduleIndex);
48 static GF_Err dsmcc_get_biop_module_info(GF_M2TS_DSMCC_MODULE* dsmcc_module,char* data,u8 data_size);
49 static GF_M2TS_DSMCC_MODULE* dsmcc_create_module(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord, GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC* DownloadInfoIndication);
50 
51 /* BIOP */
52 static GF_Err dsmcc_process_biop_data(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_MODULE* dsmcc_module,char* data,u32 data_size);
53 static GF_M2TS_DSMCC_BIOP_HEADER* dsmcc_process_biop_header(GF_BitStream* bs);
54 static GF_Err dsmcc_process_biop_file(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_OVERLORD*dsmcc_overlord,u16 moduleId,u32 downloadId);
55 static GF_Err dsmcc_process_biop_directory(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_OVERLORD*dsmcc_overlord,Bool IsServiceGateway);
56 static GF_Err dsmcc_process_biop_stream_event(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway);
57 static GF_Err dsmcc_process_biop_stream_message(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway);
58 
59 /* Tools */
60 static void dsmcc_biop_get_context(GF_BitStream* bs,GF_M2TS_DSMCC_SERVICE_CONTEXT* Context,u32 serviceContextList_count);
61 static void dsmcc_biop_descriptor(GF_BitStream* bs,GF_List* list,u32 size);
62 static GF_Err dsmcc_biop_get_ior(GF_BitStream* bs,GF_M2TS_DSMCC_IOR* IOR);
63 static GF_M2TS_DSMCC_DIR* dsmcc_get_directory(GF_List* List, u32 objectKey_data);
64 static GF_M2TS_DSMCC_FILE* dsmcc_get_file(GF_List* ServiceGatewayList,u16 moduleId,u32 downloadId,u32 objectKey_data);
65 static GF_Err dsmcc_check_element_validation(GF_List* List,char* Parent_name,GF_M2TS_DSMCC_BIOP_NAME Name);
66 static char* dsmcc_get_file_namepath(GF_M2TS_DSMCC_DIR* Dir,char* name);
67 
68 /* Free */
69 static void dsmcc_free_biop_context(GF_M2TS_DSMCC_SERVICE_CONTEXT* Context,u32 serviceContextList_count);
70 static void dsmcc_free_biop_name(GF_M2TS_DSMCC_BIOP_NAME* Name, u32 nb_name);
71 static void dsmcc_free_biop_descriptor(GF_List* list);
72 static void dsmcc_free_biop_ior(GF_M2TS_DSMCC_IOR* IOR);
73 static void dsmcc_free_biop_header(GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header);
74 static void dsmcc_free_biop_directory(GF_M2TS_DSMCC_BIOP_DIRECTORY* BIOP_Directory);
75 static void dsmcc_free_biop_file(GF_M2TS_DSMCC_BIOP_FILE* BIOP_File);
76 static void dsmcc_free_biop_stream_event(GF_M2TS_DSMCC_BIOP_STREAM_EVENT* BIOP_StreamEvent);
77 static void dsmcc_free_biop_stream_message(GF_M2TS_DSMCC_BIOP_STREAM_MESSAGE* BIOP_StreamMessage);
78 
79 GF_EXPORT
gf_m2ts_init_dsmcc_overlord(u32 service_id)80 GF_M2TS_DSMCC_OVERLORD* gf_m2ts_init_dsmcc_overlord(u32 service_id) {
81 	GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord;
82 	GF_SAFEALLOC(dsmcc_overlord,GF_M2TS_DSMCC_OVERLORD);
83 	dsmcc_overlord->dsmcc_modules = gf_list_new();
84 	dsmcc_overlord->service_id = service_id;
85 	return dsmcc_overlord;
86 }
87 
88 GF_EXPORT
gf_m2ts_get_dmscc_overlord(GF_List * Dsmcc_controller,u32 service_id)89 GF_M2TS_DSMCC_OVERLORD* gf_m2ts_get_dmscc_overlord(GF_List* Dsmcc_controller,u32 service_id)
90 {
91 	u16 nb_dsmcc,i;
92 
93 	nb_dsmcc = gf_list_count(Dsmcc_controller);
94 
95 	if(!nb_dsmcc) {
96 		return NULL;
97 	} else {
98 		for(i =0; i<nb_dsmcc; i++) {
99 			GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord = (GF_M2TS_DSMCC_OVERLORD*)gf_list_get(Dsmcc_controller,i);
100 			if(dsmcc_overlord->service_id == service_id) {
101 				return dsmcc_overlord;
102 			}
103 		}
104 	}
105 	return NULL;
106 }
107 
on_dsmcc_section(GF_M2TS_Demuxer * ts,u32 evt_type,void * par)108 void on_dsmcc_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par)
109 {
110 	GF_M2TS_SL_PCK *pck = (GF_M2TS_SL_PCK *)par;
111 	char *data;
112 	u32 u32_data_size;
113 	u32 u32_table_id;
114 	GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord;
115 
116 	dsmcc_overlord = gf_m2ts_get_dmscc_overlord(ts->dsmcc_controler,pck->stream->service_id);
117 
118 	if (dsmcc_overlord && evt_type == GF_M2TS_EVT_DSMCC_FOUND) {
119 		GF_Err e;
120 		GF_M2TS_DSMCC_SECTION* dsmcc;
121 		data = pck->data;
122 		u32_data_size = pck->data_len;
123 		u32_table_id = data[0];
124 		GF_SAFEALLOC(dsmcc,GF_M2TS_DSMCC_SECTION);
125 
126 		e = gf_m2ts_process_dsmcc(dsmcc_overlord,dsmcc,data,u32_data_size,u32_table_id);
127 		if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_DSMCC_FOUND, pck);
128 		assert(e == GF_OK);
129 	}
130 }
131 
132 GF_EXPORT
gf_m2ts_process_dsmcc(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_SECTION * dsmcc,char * data,u32 data_size,u32 table_id)133 GF_Err gf_m2ts_process_dsmcc(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_SECTION *dsmcc, char  *data, u32 data_size, u32 table_id)
134 {
135 	GF_BitStream *bs;
136 	u32 data_shift,reserved_test;
137 
138 	data_shift = 0;
139 	//first_section = *first_section_received;
140 	bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ);
141 
142 	dsmcc->table_id = gf_bs_read_int(bs,8);
143 	dsmcc->section_syntax_indicator = gf_bs_read_int(bs,1);
144 	dsmcc->private_indicator = gf_bs_read_int(bs,1);
145 	reserved_test = gf_bs_read_int(bs,2);
146 	if (reserved_test != 3) {
147 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] test reserved flag is not at 3. Corrupted section, abording processing\n"));
148 		return GF_CORRUPTED_DATA;
149 	}
150 	dsmcc->dsmcc_section_length = gf_bs_read_int(bs,12);
151 	if (dsmcc->dsmcc_section_length > DSMCC_SECTION_LENGTH_MAX) {
152 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] section length should not exceed 4096. Wrong section, abording processing \n"));
153 		return GF_CORRUPTED_DATA;
154 	}
155 	dsmcc->table_id_extension = gf_bs_read_int(bs,16);
156 
157 	/*bit shifting */
158 	gf_bs_read_int(bs,2);
159 
160 	dsmcc->version_number = gf_bs_read_int(bs,5);
161 	if(dsmcc->version_number != 0 &&(dsmcc->table_id == GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA || dsmcc->table_id == GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE)) {
162 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Version number should be 0 for Encapsulated Data or UN Message, abording processing \n"));
163 		return GF_CORRUPTED_DATA;
164 	}
165 
166 	dsmcc->current_next_indicator = gf_bs_read_int(bs,1);
167 	if (!dsmcc->current_next_indicator) {
168 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] current next indicator should be at 1 \n"));
169 		return GF_CORRUPTED_DATA;
170 	}
171 	dsmcc->section_number = gf_bs_read_int(bs,8);
172 	/*if(dsmcc->section_number >0 && ((*first_section_received) == 0)){
173 	GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Wainting for the first section \n"));
174 	return GF_CORRUPTED_DATA;
175 	}
176 	*first_section_received = 1;*/
177 	dsmcc->last_section_number = gf_bs_read_int(bs,8);
178 
179 	switch (dsmcc->table_id) {
180 	case GF_M2TS_TABLE_ID_DSM_CC_ENCAPSULATED_DATA:
181 	{
182 		data_shift = (u32)(gf_bs_get_position(bs));
183 		break;
184 	}
185 	case GF_M2TS_TABLE_ID_DSM_CC_UN_MESSAGE:
186 	case GF_M2TS_TABLE_ID_DSM_CC_DOWNLOAD_DATA_MESSAGE:
187 	{
188 		data_shift = (u32)(gf_bs_get_position(bs));
189 		gf_m2ts_dsmcc_download_data(dsmcc_overlord,dsmcc,data,bs,&data_shift);
190 		break;
191 	}
192 	case GF_M2TS_TABLE_ID_DSM_CC_STREAM_DESCRIPTION:
193 	{
194 		data_shift = (u32)(gf_bs_get_position(bs));
195 		break;
196 	}
197 	default:
198 	{
199 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unknown DSMCC Section Type \n"));
200 		break;
201 	}
202 	}
203 
204 	if (dsmcc->section_syntax_indicator == 0) {
205 		dsmcc->checksum = gf_bs_read_int(bs,32);
206 	} else {
207 		dsmcc->CRC_32= gf_bs_read_int(bs,32);
208 	}
209 
210 	data_shift = (u32)(gf_bs_get_position(bs));
211 
212 	/*if(data_shift != dsmcc->dsmcc_section_length){.
213 	GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process AIT] AIT processed length error. Difference between byte shifting %d and data size %d \n",data_shift,data_size));
214 	return GF_CORRUPTED_DATA;
215 	}*/
216 
217 	//gf_m2ts_dsmcc_extract_info(ts,dsmcc);
218 	gf_m2ts_dsmcc_section_delete(dsmcc);
219 
220 	return GF_OK;
221 }
222 
gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_SECTION * dsmcc,char * data,GF_BitStream * bs,u32 * data_shift)223 static GF_Err gf_m2ts_dsmcc_download_data(GF_M2TS_DSMCC_OVERLORD *dsmcc_overlord,GF_M2TS_DSMCC_SECTION *dsmcc, char  *data, GF_BitStream *bs,u32* data_shift)
224 {
225 	GF_M2TS_DSMCC_DOWNLOAD_DATA_MESSAGE* DataMessage;
226 	GF_SAFEALLOC(DataMessage,GF_M2TS_DSMCC_DOWNLOAD_DATA_MESSAGE);
227 
228 	/* Header */
229 	gf_m2ts_dsmcc_process_message_header(&DataMessage->DownloadDataHeader,data,bs,data_shift,1);
230 	dsmcc->DSMCC_Extension = DataMessage;
231 
232 	switch (DataMessage->DownloadDataHeader.messageId)
233 	{
234 	case DOWNLOAD_INFO_REQUEST:
235 	{
236 		GF_M2TS_DSMCC_DOWNLOAD_INFO_REQUEST*  DownloadInfoRequest;
237 		GF_SAFEALLOC(DownloadInfoRequest,GF_M2TS_DSMCC_DOWNLOAD_INFO_REQUEST);
238 		DataMessage->dataMessagePayload = DownloadInfoRequest;
239 
240 		/* Payload */
241 		DownloadInfoRequest->bufferSize = gf_bs_read_int(bs,32);
242 		DownloadInfoRequest->maximumBlockSize = gf_bs_read_int(bs,16);
243 		gf_m2ts_dsmcc_process_compatibility_descriptor(&DownloadInfoRequest->CompatibilityDescr,data,bs,data_shift);
244 		DownloadInfoRequest->privateDataLength = gf_bs_read_int(bs,16);
245 		DownloadInfoRequest->privateDataByte = (char*)gf_calloc(DownloadInfoRequest->privateDataLength,sizeof(char));
246 		gf_bs_read_data(bs,DownloadInfoRequest->privateDataByte,(u32)(DownloadInfoRequest->privateDataLength));
247 		break;
248 	}
249 	case DOWNLOAD_INFO_REPONSE_INDICATION:
250 	{
251 		u32 i,nb_modules;
252 		GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC* DownloadInfoIndication;
253 		GF_SAFEALLOC(DownloadInfoIndication,GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC);
254 		DataMessage->dataMessagePayload = DownloadInfoIndication;
255 
256 		/* Payload */
257 		DownloadInfoIndication->downloadId = gf_bs_read_int(bs,32);
258 		DownloadInfoIndication->blockSize = gf_bs_read_int(bs,16);
259 		DownloadInfoIndication->windowSize = gf_bs_read_int(bs,8);
260 		DownloadInfoIndication->ackPeriod = gf_bs_read_int(bs,8);
261 		DownloadInfoIndication->tCDownloadWindow = gf_bs_read_int(bs,32);
262 		DownloadInfoIndication->tCDownloadScenario = gf_bs_read_int(bs,32);
263 
264 		/* Compatibility Descr */
265 		gf_m2ts_dsmcc_process_compatibility_descriptor(&DownloadInfoIndication->CompatibilityDescr,data,bs,data_shift);
266 		DownloadInfoIndication->numberOfModules = gf_bs_read_int(bs,16);
267 		/* Versioning of the DownloadInfoIndication is made by the field transactionId (here known as downloadId) */
268 		if(DataMessage->DownloadDataHeader.downloadId > dsmcc_overlord->transactionId) {
269 			dsmcc_overlord->transactionId = DataMessage->DownloadDataHeader.downloadId;
270 			nb_modules = gf_list_count(dsmcc_overlord->dsmcc_modules);
271 			for(i = 0; i<DownloadInfoIndication->numberOfModules; i++) {
272 				DownloadInfoIndication->Modules.moduleId = gf_bs_read_int(bs,16);
273 				DownloadInfoIndication->Modules.moduleSize = gf_bs_read_int(bs,32);
274 				DownloadInfoIndication->Modules.moduleVersion = gf_bs_read_int(bs,8);
275 				DownloadInfoIndication->Modules.moduleInfoLength = gf_bs_read_int(bs,8);
276 				DownloadInfoIndication->Modules.moduleInfoByte = (char*)gf_calloc(DownloadInfoIndication->Modules.moduleInfoLength,sizeof(char));
277 				gf_bs_read_data(bs,DownloadInfoIndication->Modules.moduleInfoByte,(u32)(DownloadInfoIndication->Modules.moduleInfoLength));
278 				if(!dsmcc_create_module_validation(&DownloadInfoIndication->Modules,DownloadInfoIndication->downloadId,dsmcc_overlord,nb_modules)) {
279 					/* Creation of the module */
280 					GF_M2TS_DSMCC_MODULE*dsmcc_module = dsmcc_create_module(dsmcc_overlord,DownloadInfoIndication);
281 					if(DownloadInfoIndication->Modules.moduleInfoLength) {
282 						GF_Err e;
283 						e = dsmcc_get_biop_module_info(dsmcc_module,DownloadInfoIndication->Modules.moduleInfoByte,DownloadInfoIndication->Modules.moduleInfoLength);
284 						if(e) {
285 							GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in BIOP Module Info for module %d, abording the processing \n",dsmcc_module->moduleId));
286 							gf_free(DownloadInfoIndication->Modules.moduleInfoByte);
287 							DownloadInfoIndication->Modules.moduleInfoByte = NULL;
288 							return GF_CORRUPTED_DATA;
289 						}
290 					}
291 				}
292 				gf_free(DownloadInfoIndication->Modules.moduleInfoByte);
293 				DownloadInfoIndication->Modules.moduleInfoByte = NULL;
294 			}
295 			DownloadInfoIndication->privateDataLength = gf_bs_read_int(bs,16);
296 			DownloadInfoIndication->privateDataByte = (char*)gf_calloc(DownloadInfoIndication->privateDataLength,sizeof(char));
297 			gf_bs_read_data(bs,DownloadInfoIndication->privateDataByte,(u32)(DownloadInfoIndication->privateDataLength));
298 		}
299 		break;
300 	}
301 	case DOWNLOAD_DATA_BLOCK:
302 	{
303 		u32 modules_count, i;
304 		GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK* DownloadDataBlock;
305 		GF_SAFEALLOC(DownloadDataBlock,GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK);
306 		DataMessage->dataMessagePayload = DownloadDataBlock;
307 		modules_count = gf_list_count(dsmcc_overlord->dsmcc_modules);
308 
309 		if(!modules_count) {
310 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Download Information Indicator has not been received yet, waiting before processing data block \n"));
311 			break;
312 		}
313 
314 
315 		DownloadDataBlock->moduleId = gf_bs_read_int(bs,16);
316 
317 		DownloadDataBlock->moduleVersion = gf_bs_read_int(bs,8);
318 		DownloadDataBlock->reserved = gf_bs_read_int(bs,8);
319 		if(DownloadDataBlock->reserved != 0xFF) {
320 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] DataHeader reserved slot does not have the correct value, abording the processing \n"));
321 			return GF_CORRUPTED_DATA;
322 		}
323 		DownloadDataBlock->blockNumber = gf_bs_read_int(bs,16);
324 
325 		for(i=0; i<modules_count; i++) {
326 			GF_M2TS_DSMCC_MODULE* dsmcc_module = gf_list_get(dsmcc_overlord->dsmcc_modules,i);
327 			/* Test if the data are compatible with the module configuration */
328 			if(!dsmcc_download_data_validation(dsmcc_overlord,DownloadDataBlock,dsmcc_module,DataMessage->DownloadDataHeader.downloadId)) {
329 
330 				DownloadDataBlock->dataBlocksize = (DataMessage->DownloadDataHeader.messageLength - 6);
331 				if(dsmcc_module->block_size < DownloadDataBlock->dataBlocksize) {
332 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error block_size should be >= to DownloadDataBlock->dataBlocksize , abording the processing \n"));
333 					return GF_CORRUPTED_DATA;
334 				}
335 				DownloadDataBlock->blockDataByte = (char*)gf_calloc(DownloadDataBlock->dataBlocksize,sizeof(char));
336 				*data_shift = (u32)(gf_bs_get_position(bs));
337 				gf_bs_read_data(bs,DownloadDataBlock->blockDataByte,DownloadDataBlock->dataBlocksize);
338 				memcpy(dsmcc_module->buffer+dsmcc_module->byte_sift,DownloadDataBlock->blockDataByte,DownloadDataBlock->dataBlocksize*sizeof(char));
339 				dsmcc_module->byte_sift += DownloadDataBlock->dataBlocksize;
340 				dsmcc_module->last_section_number = dsmcc->last_section_number;
341 				dsmcc_module->section_number++;
342 				if(dsmcc_module->section_number == (dsmcc_module->last_section_number+1)) {
343 					dsmcc_module_complete(dsmcc_overlord,dsmcc_module,i);
344 				}
345 				break;
346 			}
347 		}
348 
349 		break;
350 	}
351 	case DOWNLOAD_DATA_REQUEST:
352 	{
353 		GF_M2TS_DSMCC_DOWNLOAD_DATA_REQUEST_MESSAGE* DownloadDataRequest;
354 		GF_SAFEALLOC(DownloadDataRequest,GF_M2TS_DSMCC_DOWNLOAD_DATA_REQUEST_MESSAGE);
355 		DataMessage->dataMessagePayload = DownloadDataRequest;
356 		DownloadDataRequest->moduleId = gf_bs_read_int(bs,16);
357 		DownloadDataRequest->blockNumber = gf_bs_read_int(bs,16);
358 		DownloadDataRequest->downloadReason  = gf_bs_read_int(bs,8);
359 		break;
360 	}
361 	case DOWNLOAD_DATA_CANCEL:
362 
363 	{
364 		GF_M2TS_DSMCC_DOWNLOAD_CANCEL* DownloadCancel;
365 		GF_SAFEALLOC(DownloadCancel,GF_M2TS_DSMCC_DOWNLOAD_CANCEL);
366 		DataMessage->dataMessagePayload = DownloadCancel;
367 		DownloadCancel->downloadId = gf_bs_read_int(bs,32);
368 		DownloadCancel->moduleId = gf_bs_read_int(bs,16);
369 		DownloadCancel->blockNumber = gf_bs_read_int(bs,16);
370 		DownloadCancel->downloadCancelReason = gf_bs_read_int(bs,8);
371 		DownloadCancel->reserved = gf_bs_read_int(bs,8);
372 		DownloadCancel->privateDataLength = gf_bs_read_int(bs,16);
373 		if(DownloadCancel->privateDataLength) {
374 			DownloadCancel->privateDataByte = (char*)gf_calloc(DownloadCancel->privateDataLength,sizeof(char));
375 			gf_bs_read_data(bs,DownloadCancel->privateDataByte,(u32)(DownloadCancel->privateDataLength));
376 		}
377 		break;
378 
379 	}
380 	case DOWNLOAD_SERVER_INITIATE:
381 	{
382 		GF_Err e;
383 		GF_M2TS_DSMCC_DOWNLOAD_SERVER_INIT* DownloadServerInit;
384 		GF_SAFEALLOC(DownloadServerInit,GF_M2TS_DSMCC_DOWNLOAD_SERVER_INIT);
385 		DataMessage->dataMessagePayload = DownloadServerInit;
386 		gf_bs_read_data(bs,DownloadServerInit->serverId,20);
387 		gf_m2ts_dsmcc_process_compatibility_descriptor(&DownloadServerInit->CompatibilityDescr,data,bs,data_shift);
388 		DownloadServerInit->privateDataLength = gf_bs_read_int(bs,16);
389 		if(DownloadServerInit->privateDataLength) {
390 
391 			u32 i;
392 
393 			GF_M2TS_DSMCC_SERVICE_GATEWAY_INFO* ServiceGateWayInfo;
394 			GF_SAFEALLOC(ServiceGateWayInfo,GF_M2TS_DSMCC_SERVICE_GATEWAY_INFO);
395 
396 			/* IOR */
397 			e = dsmcc_biop_get_ior(bs,&ServiceGateWayInfo->IOR);
398 			if(e) {
399 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Corrupted IOR, abording the processing \n"));
400 				gf_free(ServiceGateWayInfo);
401 				return GF_CORRUPTED_DATA;
402 			}
403 			ServiceGateWayInfo->downloadTaps_count = gf_bs_read_int(bs,8);
404 			ServiceGateWayInfo->Taps = (GF_M2TS_DSMCC_BIOP_TAPS*)gf_calloc(ServiceGateWayInfo->downloadTaps_count,sizeof(GF_M2TS_DSMCC_BIOP_TAPS));
405 			for(i=0; i<ServiceGateWayInfo->downloadTaps_count; i++) {
406 				ServiceGateWayInfo->Taps[i].id = gf_bs_read_int(bs,16);
407 				ServiceGateWayInfo->Taps[i].use = gf_bs_read_int(bs,16);
408 				ServiceGateWayInfo->Taps[i].assocTag = gf_bs_read_int(bs,16);
409 				ServiceGateWayInfo->Taps[i].selector_length = gf_bs_read_int(bs,8);
410 				ServiceGateWayInfo->Taps[i].selector_type = gf_bs_read_int(bs,16);
411 				ServiceGateWayInfo->Taps[i].transactionId = gf_bs_read_int(bs,32);
412 				ServiceGateWayInfo->Taps[i].timeout = gf_bs_read_int(bs,32);
413 			}
414 			ServiceGateWayInfo->serviceContextList_count = gf_bs_read_int(bs,8);
415 			ServiceGateWayInfo->ServiceContext = (GF_M2TS_DSMCC_SERVICE_CONTEXT*)gf_calloc(ServiceGateWayInfo->serviceContextList_count,sizeof(GF_M2TS_DSMCC_SERVICE_CONTEXT));
416 			dsmcc_biop_get_context(bs,ServiceGateWayInfo->ServiceContext,ServiceGateWayInfo->serviceContextList_count);
417 			ServiceGateWayInfo->userInfoLength = gf_bs_read_int(bs,16);
418 			if(ServiceGateWayInfo->userInfoLength != 0) {
419 				ServiceGateWayInfo->userInfo_data = (char*)gf_calloc(ServiceGateWayInfo->userInfoLength,sizeof(char));
420 				gf_bs_read_data(bs,ServiceGateWayInfo->userInfo_data,(u32)(ServiceGateWayInfo->userInfoLength));
421 			}
422 
423 			if(!dsmcc_overlord->ServiceGateway && gf_list_count(ServiceGateWayInfo->IOR.taggedProfile)) {
424 				GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile = (GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE*)gf_list_get(ServiceGateWayInfo->IOR.taggedProfile,0);
425 				dsmcc_overlord->ServiceGateway = (GF_M2TS_DSMCC_SERVICE_GATEWAY*)gf_calloc(1,sizeof(GF_M2TS_DSMCC_SERVICE_GATEWAY));
426 				dsmcc_overlord->ServiceGateway->downloadId = taggedProfile->BIOPProfileBody->ObjectLocation.carouselId;
427 				dsmcc_overlord->ServiceGateway->moduleId = taggedProfile->BIOPProfileBody->ObjectLocation.moduleId;
428 				dsmcc_overlord->ServiceGateway->service_id = dsmcc_overlord->service_id;
429 				dsmcc_overlord->ServiceGateway->File = gf_list_new();
430 				dsmcc_overlord->ServiceGateway->Dir = gf_list_new();
431 			}
432 		}
433 
434 		break;
435 	}
436 
437 	default:
438 	{
439 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unknown dataMessagePayload Type \n"));
440 		break;
441 	}
442 	}
443 
444 	//dsmcc->DSMCC_Extension = DataMessage;
445 
446 	return GF_OK;
447 }
448 
449 
450 
451 
gf_m2ts_dsmcc_process_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER * MessageHeader,char * data,GF_BitStream * bs,u32 * data_shift,u32 mode)452 static GF_Err gf_m2ts_dsmcc_process_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER *MessageHeader, char* data,GF_BitStream *bs,u32* data_shift,u32 mode)
453 {
454 	u32 byte_shift;
455 
456 	byte_shift = *data_shift;
457 
458 	MessageHeader->protocolDiscriminator = gf_bs_read_int(bs,8);
459 	if (MessageHeader->protocolDiscriminator != 0x11) {
460 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] DataHeader Protocol Discriminator slot does not have the correct value, abording the processing \n"));
461 		return GF_CORRUPTED_DATA;
462 	}
463 	MessageHeader->dsmccType = gf_bs_read_int(bs,8);
464 	MessageHeader->messageId = gf_bs_read_int(bs,16);
465 	/* mode 0 for Message Header - 1 for Download Data header */
466 	if (mode == 0) {
467 		MessageHeader->transactionId = gf_bs_read_int(bs,32);
468 	} else if (mode == 1) {
469 		MessageHeader->downloadId = gf_bs_read_int(bs,32);
470 	}
471 	MessageHeader->reserved = gf_bs_read_int(bs,8);
472 	if (MessageHeader->reserved != 0xFF) {
473 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] DataHeader reserved slot does not have the correct value, abording the processing \n"));
474 		return GF_CORRUPTED_DATA;
475 	}
476 	MessageHeader->adaptationLength = gf_bs_read_int(bs,8);
477 	MessageHeader->header_length = ((u32)(gf_bs_get_position(bs)) - byte_shift);
478 	MessageHeader->messageLength = gf_bs_read_int(bs,16);
479 
480 	if (MessageHeader->adaptationLength > 0) {
481 		MessageHeader->DsmccAdaptationHeader = (GF_M2TS_DSMCC_ADAPTATION_HEADER*)gf_calloc(1, sizeof(GF_M2TS_DSMCC_ADAPTATION_HEADER));
482 		MessageHeader->DsmccAdaptationHeader->adaptationType = gf_bs_read_int(bs,8);
483 
484 		MessageHeader->DsmccAdaptationHeader->adaptationDataByte = (char*)gf_calloc(MessageHeader->adaptationLength-1,sizeof(char));
485 		gf_bs_read_data(bs,MessageHeader->DsmccAdaptationHeader->adaptationDataByte,(u32)(MessageHeader->adaptationLength));
486 
487 	}
488 
489 	*data_shift = (u32)(gf_bs_get_position(bs));
490 
491 	return GF_OK;
492 }
493 
gf_m2ts_dsmcc_process_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR * CompatibilityDesc,char * data,GF_BitStream * bs,u32 * data_shift)494 static GF_Err gf_m2ts_dsmcc_process_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR *CompatibilityDesc, char* data,GF_BitStream *bs,u32* data_shift)
495 {
496 	u32 i,j,byte_shift;
497 
498 	byte_shift = (u32)(gf_bs_get_position(bs));
499 
500 	CompatibilityDesc->compatibilityDescriptorLength = gf_bs_read_int(bs,16);
501 
502 	if(CompatibilityDesc->compatibilityDescriptorLength) {
503 		CompatibilityDesc->descriptorCount = gf_bs_read_int(bs,16);
504 		if(CompatibilityDesc->descriptorCount) {
505 			CompatibilityDesc->Descriptor = (GF_M2TS_DSMCC_DESCRIPTOR*)gf_calloc(CompatibilityDesc->descriptorCount,sizeof(GF_M2TS_DSMCC_DESCRIPTOR));
506 			for(i=0; i<CompatibilityDesc->descriptorCount; i++) {
507 				CompatibilityDesc->Descriptor[i].descriptorType = gf_bs_read_int(bs,8);
508 				CompatibilityDesc->Descriptor[i].descriptorLength = gf_bs_read_int(bs,8);
509 				CompatibilityDesc->Descriptor[i].specifierType = gf_bs_read_int(bs,8);
510 				CompatibilityDesc->Descriptor[i].specifierData = gf_bs_read_int(bs,21);
511 				CompatibilityDesc->Descriptor[i].model = gf_bs_read_int(bs,16);
512 				CompatibilityDesc->Descriptor[i].version = gf_bs_read_int(bs,16);
513 				CompatibilityDesc->Descriptor[i].subDescriptorCount = gf_bs_read_int(bs,8);
514 				if(CompatibilityDesc->Descriptor[i].subDescriptorCount) {
515 					CompatibilityDesc->Descriptor[i].SubDescriptor  = (GF_M2TS_DSMCC_SUBDESCRIPTOR*)gf_calloc(CompatibilityDesc->Descriptor[i].subDescriptorCount,sizeof(GF_M2TS_DSMCC_SUBDESCRIPTOR));
516 					for(j=0; j>CompatibilityDesc->Descriptor[i].subDescriptorCount; j++) {
517 						CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorType = gf_bs_read_int(bs,8);
518 						CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorLength = gf_bs_read_int(bs,8);
519 						if(CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorLength) {
520 							CompatibilityDesc->Descriptor[i].SubDescriptor[j].additionalInformation = (char*)gf_calloc(CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorLength,sizeof(char));
521 							gf_bs_read_data(bs,CompatibilityDesc->Descriptor[i].SubDescriptor[j].additionalInformation,(u32)(CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorLength));
522 						}
523 
524 					}
525 				}
526 			}
527 		}
528 	}
529 
530 	*data_shift = (u32)(gf_bs_get_position(bs));
531 	if(*data_shift != byte_shift+2+CompatibilityDesc->compatibilityDescriptorLength) {
532 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Descriptor length not respected, difference between %d and %d \n",(*data_shift - byte_shift),2+CompatibilityDesc->compatibilityDescriptorLength));
533 		return GF_CORRUPTED_DATA;
534 	}
535 
536 	return GF_OK;
537 }
538 
dsmcc_create_module_validation(GF_M2TS_DSMCC_INFO_MODULES * InfoModules,u32 downloadId,GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,u32 nb_module)539 static GF_Err dsmcc_create_module_validation(GF_M2TS_DSMCC_INFO_MODULES* InfoModules, u32 downloadId, GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,u32 nb_module) {
540 
541 	u32 i;
542 	for (i=0; i<nb_module; i++) {
543 		GF_M2TS_DSMCC_PROCESSED dsmcc_process = dsmcc_overlord->processed[i];
544 		if ((InfoModules->moduleId == dsmcc_process.moduleId) && (downloadId == dsmcc_process.downloadId)) {
545 			if (InfoModules->moduleVersion <= dsmcc_process.version_number) {
546 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Module already intialized \n"));
547 				return GF_CORRUPTED_DATA;
548 			} else {
549 				GF_M2TS_DSMCC_MODULE* dsmcc_module = (GF_M2TS_DSMCC_MODULE*)gf_list_get(dsmcc_overlord->dsmcc_modules,i);
550 				dsmcc_module_delete(dsmcc_module);
551 				gf_list_rem(dsmcc_overlord->dsmcc_modules,i);
552 				dsmcc_process.version_number = InfoModules->moduleVersion;
553 				dsmcc_process.done = 0;
554 				return GF_OK;
555 			}
556 		}
557 	}
558 	return  GF_OK;
559 }
560 
561 //static GF_Err dsmcc_module_state(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,u32 moduleId,u32 moduleVersion){
562 //
563 //	u32 i,nb_module;
564 //	nb_module = gf_list_count(dsmcc_overlord->dsmcc_modules);
565 //	/* This test comes from the fact that the moduleVersion only borrow the least 5 significant bits of the moduleVersion conveys in DownloadDataBlock */
566 //	/* If the moduleVersion is eq to 0x1F, it does not tell if it is clearly 0x1F or a superior value. So in this case it is better to process the data */
567 //	/* If the moduleVersion is eq to 0x0, it means that the data conveys a DownloadDataResponse, so it has to be processed */
568 //	if (moduleVersion != 0 || moduleVersion < 0x1F) {
569 //		for (i=0; i<nb_module; i++) {
570 //			GF_M2TS_DSMCC_PROCESSED dsmcc_process = dsmcc_overlord->processed[i];
571 //			if ((moduleId == dsmcc_process.moduleId) && (moduleVersion <= dsmcc_process.version_number)) {
572 //				if (dsmcc_process.done) {
573 //					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Module already processed \n"));
574 //					return GF_CORRUPTED_DATA;
575 //				} else {
576 //					return GF_OK;
577 //				}
578 //			}
579 //		}
580 //	}
581 //	return  GF_OK;
582 //}
583 
dsmcc_download_data_validation(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK * DownloadDataBlock,GF_M2TS_DSMCC_MODULE * dsmcc_module,u32 downloadId)584 static GF_Err dsmcc_download_data_validation(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK* DownloadDataBlock,GF_M2TS_DSMCC_MODULE* dsmcc_module,u32 downloadId)
585 {
586 	/* It checks if the module Id is eq to the SGW's module Id if Got_ServiceGateway is null (means that the SWG has not been processed yet
587 		If then Got_ServiceGateway = 1, all the module are processed */
588 	if(dsmcc_overlord->ServiceGateway) {
589 		if ((dsmcc_overlord->Got_ServiceGateway || dsmcc_module->moduleId == dsmcc_overlord->ServiceGateway->moduleId)&&
590 		        ((dsmcc_module->moduleId == DownloadDataBlock->moduleId) && (dsmcc_module->section_number == DownloadDataBlock->blockNumber) &&
591 		         (dsmcc_module->downloadId == downloadId) && (dsmcc_module->version_number == DownloadDataBlock->moduleVersion))) {
592 			return GF_OK;
593 		}
594 	}
595 
596 	return GF_CORRUPTED_DATA;
597 }
598 
dsmcc_module_complete(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_MODULE * dsmcc_module,u32 moduleIndex)599 static GF_Err dsmcc_module_complete(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_MODULE* dsmcc_module,u32 moduleIndex)
600 {
601 	u32 i,nb_module;
602 	GF_Err e;
603 	e = GF_OK;
604 	nb_module = gf_list_count(dsmcc_overlord->dsmcc_modules);
605 	for (i=0; i<nb_module; i++) {
606 		GF_M2TS_DSMCC_PROCESSED dsmcc_process = dsmcc_overlord->processed[i];
607 		if ((dsmcc_module->moduleId == dsmcc_process.moduleId) && dsmcc_module->version_number == dsmcc_process.version_number && dsmcc_module->downloadId == dsmcc_process.downloadId) {
608 			/*process buffer*/
609 			if(dsmcc_module->Gzip) {
610 				u32 uncomp_size;
611 				char* uncompressed_data;
612 
613 				gf_gz_decompress_payload(dsmcc_module->buffer,dsmcc_module->byte_sift,&uncompressed_data, &uncomp_size);
614 				//dsmcc_process_biop_data(dsmcc_overlord,dsmcc_module,uncompressed_data,dsmcc_module->original_size);
615 
616 				if(dsmcc_module->original_size == uncomp_size) {
617 					e = dsmcc_process_biop_data(dsmcc_overlord,dsmcc_module,uncompressed_data,dsmcc_module->original_size);
618 				} else {
619 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Buffer size is not equal to the module size. Flushing the data \n"));
620 					gf_free(dsmcc_module->buffer);
621 					dsmcc_module->buffer = NULL;
622 					dsmcc_module->buffer = (char*)gf_calloc(dsmcc_module->size,sizeof(char));
623 					dsmcc_module->section_number = 0;
624 					return GF_CORRUPTED_DATA;
625 				}
626 			} else {
627 				e = dsmcc_process_biop_data(dsmcc_overlord,dsmcc_module,dsmcc_module->buffer,dsmcc_module->size);
628 			}
629 			if(e) {
630 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error during the processing of the module data. Flushing the data \n"));
631 				gf_free(dsmcc_module->buffer);
632 				dsmcc_module->buffer = NULL;
633 				dsmcc_module->buffer = (char*)gf_calloc(dsmcc_module->size,sizeof(char));
634 				dsmcc_module->section_number = 0;
635 				return GF_CORRUPTED_DATA;
636 			} else {
637 				dsmcc_process.done = 1;
638 				dsmcc_module_delete(dsmcc_module);
639 				gf_list_rem(dsmcc_overlord->dsmcc_modules,moduleIndex);
640 			}
641 		}
642 	}
643 
644 	return  GF_OK;
645 }
646 
647 /* Delete structure of the DSMCC data processing */
648 
gf_m2ts_dsmcc_delete_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR * CompatibilityDesc)649 static GF_Err gf_m2ts_dsmcc_delete_compatibility_descriptor(GF_M2TS_DSMCC_COMPATIBILITY_DESCRIPTOR *CompatibilityDesc)
650 {
651 	u32 i,j;
652 	if (CompatibilityDesc->compatibilityDescriptorLength) {
653 		if (CompatibilityDesc->descriptorCount) {
654 			for (i=0; i<CompatibilityDesc->descriptorCount; i++) {
655 				if (CompatibilityDesc->Descriptor[i].subDescriptorCount) {
656 					for (j=0; j>CompatibilityDesc->Descriptor[i].subDescriptorCount; j++) {
657 						if (CompatibilityDesc->Descriptor[i].SubDescriptor[j].subDescriptorLength) {
658 							gf_free(CompatibilityDesc->Descriptor[i].SubDescriptor[j].additionalInformation);
659 						}
660 					}
661 					gf_free(CompatibilityDesc->Descriptor[i].SubDescriptor);
662 				}
663 			}
664 			gf_free(CompatibilityDesc->Descriptor);
665 		}
666 	}
667 	return GF_OK;
668 }
669 
gf_m2ts_dsmcc_delete_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER * MessageHeader)670 static GF_Err gf_m2ts_dsmcc_delete_message_header(GF_M2TS_DSMCC_MESSAGE_DATA_HEADER *MessageHeader)
671 {
672 	if (MessageHeader->adaptationLength > 0) {
673 		gf_free(MessageHeader->DsmccAdaptationHeader->adaptationDataByte);
674 		gf_free(MessageHeader->DsmccAdaptationHeader);
675 	}
676 	return GF_OK;
677 }
678 
gf_m2ts_dsmcc_section_delete(GF_M2TS_DSMCC_SECTION * dsmcc)679 static GF_Err gf_m2ts_dsmcc_section_delete(GF_M2TS_DSMCC_SECTION *dsmcc)
680 {
681 	GF_M2TS_DSMCC_DOWNLOAD_DATA_MESSAGE* DataMessage = (GF_M2TS_DSMCC_DOWNLOAD_DATA_MESSAGE*)dsmcc->DSMCC_Extension;
682 
683 	if(!DataMessage) {
684 		return GF_OK;
685 	}
686 
687 	switch (DataMessage->DownloadDataHeader.messageId)
688 	{
689 	case DOWNLOAD_INFO_REQUEST:
690 	{
691 		GF_M2TS_DSMCC_DOWNLOAD_INFO_REQUEST*  DownloadInfoRequest = (GF_M2TS_DSMCC_DOWNLOAD_INFO_REQUEST*)DataMessage->dataMessagePayload;
692 		if(DownloadInfoRequest->privateDataLength) {
693 			gf_free(DownloadInfoRequest->privateDataByte);
694 		}
695 		gf_free(DownloadInfoRequest);
696 		break;
697 	}
698 	case DOWNLOAD_INFO_REPONSE_INDICATION:
699 	{
700 		GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC* DownloadInfoIndication = (GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC*)DataMessage->dataMessagePayload;
701 
702 		/* Compatibility Descr */
703 		gf_m2ts_dsmcc_delete_compatibility_descriptor(&DownloadInfoIndication->CompatibilityDescr);
704 
705 		if (DownloadInfoIndication->privateDataLength) {
706 			gf_free(DownloadInfoIndication->privateDataByte);
707 		}
708 		gf_free(DownloadInfoIndication);
709 		break;
710 	}
711 	case DOWNLOAD_DATA_BLOCK:
712 	{
713 		GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK* DownloadDataBlock = (GF_M2TS_DSMCC_DOWNLOAD_DATA_BLOCK*)DataMessage->dataMessagePayload;
714 		if (DownloadDataBlock->dataBlocksize) {
715 			gf_free(DownloadDataBlock->blockDataByte);
716 		}
717 		gf_free(DownloadDataBlock);
718 		break;
719 	}
720 	case DOWNLOAD_DATA_REQUEST:
721 	{
722 		GF_M2TS_DSMCC_DOWNLOAD_DATA_REQUEST_MESSAGE* DownloadDataRequest = (GF_M2TS_DSMCC_DOWNLOAD_DATA_REQUEST_MESSAGE*)DataMessage->dataMessagePayload;
723 		gf_free(DownloadDataRequest);
724 		break;
725 	}
726 	case DOWNLOAD_DATA_CANCEL:
727 	{
728 		GF_M2TS_DSMCC_DOWNLOAD_CANCEL* DownloadCancel = (GF_M2TS_DSMCC_DOWNLOAD_CANCEL*)DataMessage->dataMessagePayload;
729 		if (DownloadCancel->privateDataLength) {
730 			gf_free(DownloadCancel->privateDataByte);
731 		}
732 		gf_free(DownloadCancel);
733 		break;
734 	}
735 	case DOWNLOAD_SERVER_INITIATE:
736 	{
737 		GF_M2TS_DSMCC_DOWNLOAD_SERVER_INIT* DownloadServerInit = (GF_M2TS_DSMCC_DOWNLOAD_SERVER_INIT*)DataMessage->dataMessagePayload;
738 		gf_m2ts_dsmcc_delete_compatibility_descriptor(&DownloadServerInit->CompatibilityDescr);
739 		if (DownloadServerInit->privateDataLength) {
740 			gf_free(DownloadServerInit->privateDataByte);
741 		}
742 		gf_free(DownloadServerInit);
743 		break;
744 	}
745 	default:
746 	{
747 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unknown dataMessagePayload Type \n"));
748 		break;
749 	}
750 	}
751 
752 	/* Header */
753 	gf_m2ts_dsmcc_delete_message_header(&DataMessage->DownloadDataHeader);
754 	gf_free(DataMessage);
755 	gf_free(dsmcc);
756 	return GF_OK;
757 }
758 
759 
dsmcc_module_delete(GF_M2TS_DSMCC_MODULE * dsmcc_module)760 static GF_Err dsmcc_module_delete(GF_M2TS_DSMCC_MODULE* dsmcc_module) {
761 
762 	gf_free(dsmcc_module->buffer);
763 	gf_free(dsmcc_module);
764 	return  GF_OK;
765 }
766 
767 /* BIOP MESSAGE */
768 
dsmcc_get_biop_module_info(GF_M2TS_DSMCC_MODULE * dsmcc_module,char * data,u8 data_size)769 static GF_Err dsmcc_get_biop_module_info(GF_M2TS_DSMCC_MODULE* dsmcc_module,char* data,u8 data_size) {
770 
771 	GF_M2TS_DSMCC_BIOP_MODULE_INFO* BIOP_ModuleInfo;
772 	GF_BitStream *bs;
773 	u8 i;
774 
775 
776 	bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ);
777 	GF_SAFEALLOC(BIOP_ModuleInfo,GF_M2TS_DSMCC_BIOP_MODULE_INFO);
778 	BIOP_ModuleInfo->descriptor = gf_list_new();
779 
780 	BIOP_ModuleInfo->moduleTimeOut = gf_bs_read_int(bs,32);
781 	BIOP_ModuleInfo->blockTimeOut = gf_bs_read_int(bs,32);
782 	BIOP_ModuleInfo->minBlockTime = gf_bs_read_int(bs,32);
783 	BIOP_ModuleInfo->taps_count = gf_bs_read_int(bs,8);
784 	if(!BIOP_ModuleInfo->taps_count) {
785 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Corrupted payload for BIOP Module Info \n"));
786 		gf_list_del(BIOP_ModuleInfo->descriptor);
787 		gf_free(BIOP_ModuleInfo);
788 		return GF_CORRUPTED_DATA;
789 	}
790 
791 	BIOP_ModuleInfo->Taps = (GF_M2TS_DSMCC_BIOP_TAPS*)gf_calloc(BIOP_ModuleInfo->taps_count,sizeof(GF_M2TS_DSMCC_BIOP_TAPS));
792 	for(i = 0; i < BIOP_ModuleInfo->taps_count; i++) {
793 		BIOP_ModuleInfo->Taps[i].id = gf_bs_read_int(bs,16);
794 		BIOP_ModuleInfo->Taps[i].use = gf_bs_read_int(bs,16);
795 		BIOP_ModuleInfo->Taps[i].assocTag = gf_bs_read_int(bs,16);
796 		BIOP_ModuleInfo->Taps[i].selector_length = gf_bs_read_int(bs,8);
797 		if(BIOP_ModuleInfo->Taps[i].selector_length) {
798 			BIOP_ModuleInfo->Taps[i].selector_data = (char*)gf_calloc(BIOP_ModuleInfo->Taps[i].selector_length,sizeof(char));
799 			gf_bs_read_data(bs,BIOP_ModuleInfo->Taps[i].selector_data,(u8)(BIOP_ModuleInfo->Taps[i].selector_length));
800 		}
801 		if(i == 0 && (BIOP_ModuleInfo->Taps[i].id != 0x00 || BIOP_ModuleInfo->Taps[i].use != 0x17 || BIOP_ModuleInfo->Taps[i].selector_length != 0x00)) {
802 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Corrupted payload for BIOP Module Info \n"));
803 			gf_free(BIOP_ModuleInfo->Taps);
804 			gf_list_del(BIOP_ModuleInfo->descriptor);
805 			gf_free(BIOP_ModuleInfo);
806 			return GF_CORRUPTED_DATA;
807 		}
808 	}
809 	BIOP_ModuleInfo->userInfoLength = gf_bs_read_int(bs,8);
810 	if(BIOP_ModuleInfo->userInfoLength) {
811 
812 		u32 nb_desc,j;
813 
814 		dsmcc_biop_descriptor(bs,BIOP_ModuleInfo->descriptor,(u32)(BIOP_ModuleInfo->userInfoLength));
815 
816 		nb_desc = gf_list_count(BIOP_ModuleInfo->descriptor);
817 		j = 0;
818 		while(j<nb_desc) {
819 			u8* descr_tag;
820 
821 			/* get the descriptor tag */
822 			descr_tag = (u8*)gf_list_get(BIOP_ModuleInfo->descriptor,j);
823 
824 			switch(*descr_tag) {
825 
826 			case CACHING_PRIORITY_DESCRIPTOR:
827 			{
828 				//GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR* CachingPriorityDescr = (GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR*)gf_list_get(BIOP_ModuleInfo->descriptor,j);
829 				break;
830 			}
831 			case COMPRESSED_MODULE_DESCRIPTOR:
832 			{
833 				u8 comp_meth;
834 				GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR* CompModuleDescr = (GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR*)gf_list_get(BIOP_ModuleInfo->descriptor,j);
835 				/*if CompModuleDescr->compression_method least significant nibble is eq to 0x08, the terminal shall support the Deflate compression algorithm (GZIP)*/
836 				comp_meth = (CompModuleDescr->compression_method &0x0F);
837 				if(comp_meth == 0x08) {
838 					dsmcc_module->Gzip = 1;
839 				}
840 				dsmcc_module->original_size = CompModuleDescr->original_size;
841 				break;
842 
843 			}
844 			default:
845 			{
846 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported descriptor Type \n"));
847 				break;
848 			}
849 			}
850 			j++;
851 		}
852 	}
853 
854 	dsmcc_free_biop_descriptor(BIOP_ModuleInfo->descriptor);
855 
856 	for(i = 0; i < BIOP_ModuleInfo->taps_count; i++) {
857 		if(BIOP_ModuleInfo->Taps[i].selector_length) {
858 			gf_free(BIOP_ModuleInfo->Taps[i].selector_data);
859 		}
860 	}
861 	gf_free(BIOP_ModuleInfo->Taps);
862 	gf_free(BIOP_ModuleInfo);
863 
864 	return GF_OK;
865 }
866 
dsmcc_process_biop_data(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_MODULE * dsmcc_module,char * data,u32 data_size)867 static GF_Err dsmcc_process_biop_data(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord,GF_M2TS_DSMCC_MODULE* dsmcc_module,char* data,u32 data_size) {
868 
869 	GF_BitStream *bs;
870 	GF_Err e;
871 	Bool Error;
872 	u32 byte_shift;
873 	GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway = dsmcc_overlord->ServiceGateway;
874 
875 	e = GF_OK;
876 	Error = 0;
877 
878 	bs = gf_bs_new(data,data_size,GF_BITSTREAM_READ);
879 
880 	byte_shift = (u32)(gf_bs_get_position(bs));
881 
882 	while(byte_shift < data_size) {
883 		GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header;
884 		BIOP_Header = dsmcc_process_biop_header(bs);
885 
886 		if(BIOP_Header) {
887 			if(!strcmp(BIOP_Header->objectKind_data,"fil")) {
888 				e = dsmcc_process_biop_file(bs,BIOP_Header,dsmcc_overlord,dsmcc_module->moduleId,dsmcc_module->downloadId);
889 			} else if(!strcmp(BIOP_Header->objectKind_data,"dir")) {
890 				e = dsmcc_process_biop_directory(bs,BIOP_Header,dsmcc_overlord,0);
891 			} else if(!strcmp(BIOP_Header->objectKind_data,"srg")) {
892 				e = dsmcc_process_biop_directory(bs,BIOP_Header,dsmcc_overlord,1);
893 				if(e == GF_OK) {
894 					dsmcc_overlord->Got_ServiceGateway = 1;
895 				}
896 			} else if(!strcmp(BIOP_Header->objectKind_data,"str")) {
897 				dsmcc_process_biop_stream_message(bs,BIOP_Header,ServiceGateway);
898 			} else if(!strcmp(BIOP_Header->objectKind_data,"ste")) {
899 				dsmcc_process_biop_stream_event(bs,BIOP_Header,ServiceGateway);
900 			} else {
901 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported BIOP Message, abording process \n"));
902 			}
903 		}
904 		byte_shift = (u32)(gf_bs_get_position(bs));
905 		if((e || !BIOP_Header) && (byte_shift < data_size)) {
906 			/* Error inside the data. Read next byte until a new "BIOP" is found or data_size is reached */
907 			gf_bs_read_int(bs,8);
908 			Error = 1;
909 		}
910 		if(BIOP_Header) {
911 			dsmcc_free_biop_header(BIOP_Header);
912 		}
913 
914 	}
915 
916 	if(Error) {
917 		return GF_CORRUPTED_DATA;
918 	}
919 
920 	return GF_OK;
921 }
922 
dsmcc_process_biop_header(GF_BitStream * bs)923 static GF_M2TS_DSMCC_BIOP_HEADER* dsmcc_process_biop_header(GF_BitStream* bs) {
924 
925 	GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header;
926 	GF_SAFEALLOC(BIOP_Header,GF_M2TS_DSMCC_BIOP_HEADER);
927 
928 	BIOP_Header->magic = gf_bs_read_int(bs,32);
929 	if(BIOP_Header->magic != 0x42494F50) {
930 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Wrong BIOP Header, abording process \n"));
931 		return NULL;
932 	}
933 	BIOP_Header->biop_version_major = gf_bs_read_int(bs,8);
934 	BIOP_Header->biop_version_minor = gf_bs_read_int(bs,8);
935 	BIOP_Header->byte_order = gf_bs_read_int(bs,8);
936 	BIOP_Header->message_type = gf_bs_read_int(bs,8);
937 	BIOP_Header->message_size = gf_bs_read_int(bs,32);
938 	BIOP_Header->objectKey_length = gf_bs_read_int(bs,8);
939 	if(BIOP_Header->objectKey_length) {
940 		BIOP_Header->objectKey_data = gf_bs_read_int(bs,BIOP_Header->objectKey_length*8);
941 	}
942 	BIOP_Header->objectKind_length = gf_bs_read_int(bs,32);
943 	if(BIOP_Header->objectKind_length) {
944 		BIOP_Header->objectKind_data = (char*)gf_calloc(BIOP_Header->objectKind_length,sizeof(char));
945 		gf_bs_read_data(bs,BIOP_Header->objectKind_data,(u32)(BIOP_Header->objectKind_length));
946 	}
947 	BIOP_Header->objectInfo_length = gf_bs_read_int(bs,16);
948 
949 	return BIOP_Header;
950 }
951 
dsmcc_process_biop_file(GF_BitStream * bs,GF_M2TS_DSMCC_BIOP_HEADER * BIOP_Header,GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,u16 moduleId,u32 downloadId)952 static GF_Err dsmcc_process_biop_file(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_OVERLORD*dsmcc_overlord,u16 moduleId,u32 downloadId) {
953 
954 	u32 nb_desc,descr_size;
955 	GF_M2TS_DSMCC_BIOP_FILE* BIOP_File;
956 	GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway;
957 	GF_M2TS_DSMCC_FILE* File;
958 
959 	GF_SAFEALLOC(BIOP_File,GF_M2TS_DSMCC_BIOP_FILE);
960 
961 	ServiceGateway = dsmcc_overlord->ServiceGateway;
962 
963 	BIOP_File->Header = BIOP_Header;
964 	BIOP_File->ContentSize = gf_bs_read_int(bs,64);
965 
966 	descr_size = BIOP_File->Header->objectInfo_length-8;
967 
968 	if(descr_size) {
969 		dsmcc_biop_descriptor(bs,BIOP_File->descriptor,descr_size);
970 	}
971 
972 	gf_bs_read_int(bs,(u32)(descr_size));
973 
974 	nb_desc = gf_list_count(BIOP_File->descriptor);
975 
976 	while(nb_desc) {
977 		u8* descr_tag;
978 
979 		/* get the descriptor tag */
980 		descr_tag = (u8*)gf_list_get(BIOP_File->descriptor,0);
981 
982 		switch(*descr_tag) {
983 		case CONTENT_TYPE_DESCRIPTOR:
984 		{
985 			//GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR* ContentTypeDescr = (GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR*)gf_list_get(BIOP_File->descriptor,0);
986 		}
987 		default:
988 		{
989 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported descriptor Type \n"));
990 			break;
991 		}
992 		}
993 		nb_desc--;
994 	}
995 
996 	BIOP_File->serviceContextList_count = gf_bs_read_int(bs,8);
997 	if(BIOP_File->serviceContextList_count) {
998 		BIOP_File->ServiceContext = (GF_M2TS_DSMCC_SERVICE_CONTEXT*)gf_calloc(BIOP_File->serviceContextList_count,sizeof(GF_M2TS_DSMCC_SERVICE_CONTEXT));
999 		dsmcc_biop_get_context(bs,BIOP_File->ServiceContext,BIOP_File->serviceContextList_count);
1000 	}
1001 	BIOP_File->messageBody_length = gf_bs_read_int(bs,32);
1002 	BIOP_File->content_length = gf_bs_read_int(bs,32);
1003 	if(BIOP_File->content_length) {
1004 		BIOP_File->content_byte = (char*)gf_calloc(BIOP_File->content_length,sizeof(char));
1005 		gf_bs_read_data(bs,BIOP_File->content_byte,(u32)(BIOP_File->content_length));
1006 
1007 	}
1008 	GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("module_Id %d \n",moduleId));
1009 	File = dsmcc_get_file(ServiceGateway->File,moduleId,downloadId,BIOP_File->Header->objectKey_data);
1010 	if(File) {
1011 		FILE* pFile;
1012 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("Fichier: %s module_Id %d place :%d \n",File->Path,moduleId,File->objectKey_data));
1013 		pFile = gf_fopen(File->Path,"wb");
1014 		if (pFile!=NULL) {
1015 			gf_fwrite(BIOP_File->content_byte, BIOP_File->content_length ,pFile);
1016 			gf_fclose(pFile);
1017 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[DSMCC] File created\n"));
1018 			if(!strcmp(File->name,"index.html")) {
1019 				dsmcc_overlord->get_index = 1;
1020 			}
1021 		}
1022 	} else {
1023 		GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[DSMCC] File could not be created\n"));
1024 	}
1025 
1026 	dsmcc_free_biop_file(BIOP_File);
1027 
1028 	return GF_OK;
1029 }
1030 
dsmcc_process_biop_directory(GF_BitStream * bs,GF_M2TS_DSMCC_BIOP_HEADER * BIOP_Header,GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,Bool IsServiceGateway)1031 static GF_Err dsmcc_process_biop_directory(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_OVERLORD*dsmcc_overlord,Bool IsServiceGateway) {
1032 
1033 	GF_M2TS_DSMCC_BIOP_DIRECTORY* BIOP_Directory;
1034 	GF_M2TS_DSMCC_DIR* Dir;
1035 	u32 i;
1036 	GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway;
1037 
1038 	GF_SAFEALLOC(BIOP_Directory,GF_M2TS_DSMCC_BIOP_DIRECTORY);
1039 
1040 	ServiceGateway = dsmcc_overlord->ServiceGateway;
1041 
1042 	/* Get the Header */
1043 	BIOP_Directory->Header = BIOP_Header;
1044 
1045 	if(BIOP_Directory->Header->objectInfo_length != 0x0) {
1046 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] ObjectInfo_length value is not correct \n"));
1047 		return GF_CORRUPTED_DATA;
1048 	}
1049 
1050 	if(IsServiceGateway) {
1051 		/* create a "dir" struct with no parent */
1052 		Dir = (GF_M2TS_DSMCC_DIR*)ServiceGateway;
1053 		ServiceGateway->objectKey_data = BIOP_Directory->Header->objectKey_data;
1054 		ServiceGateway->parent = NULL;
1055 		ServiceGateway->name = (char*)gf_strdup(dsmcc_overlord->root_dir);
1056 	} else {
1057 		/* get the dir related to the payload */
1058 		Dir = dsmcc_get_directory(ServiceGateway->Dir,BIOP_Directory->Header->objectKey_data);
1059 	}
1060 
1061 	BIOP_Directory->serviceContextList_count = gf_bs_read_int(bs,8);
1062 	if(BIOP_Directory->serviceContextList_count) {
1063 		BIOP_Directory->ServiceContext = (GF_M2TS_DSMCC_SERVICE_CONTEXT*)gf_calloc(BIOP_Directory->serviceContextList_count,sizeof(GF_M2TS_DSMCC_SERVICE_CONTEXT));
1064 		dsmcc_biop_get_context(bs,BIOP_Directory->ServiceContext,BIOP_Directory->serviceContextList_count);
1065 	}
1066 	BIOP_Directory->messageBody_length = gf_bs_read_int(bs,32);
1067 	BIOP_Directory->bindings_count = gf_bs_read_int(bs,16);
1068 	BIOP_Directory->Name = (GF_M2TS_DSMCC_BIOP_NAME*)gf_calloc(BIOP_Directory->bindings_count,sizeof(GF_M2TS_DSMCC_BIOP_NAME));
1069 
1070 	/* Get the linked files */
1071 	for(i = 0; i<BIOP_Directory->bindings_count; i++) {
1072 		u32 descr_length,nb_desc,j;
1073 		GF_Err e;
1074 
1075 		BIOP_Directory->Name[i].nameComponents_count = gf_bs_read_int(bs,8);
1076 		BIOP_Directory->Name[i].id_length = gf_bs_read_int(bs,8);
1077 		if(BIOP_Directory->Name[i].id_length) {
1078 			BIOP_Directory->Name[i].id_data = (char*)gf_calloc(BIOP_Directory->Name[i].id_length,sizeof(char));
1079 			gf_bs_read_data(bs,BIOP_Directory->Name[i].id_data,(u32)(BIOP_Directory->Name[i].id_length));
1080 		}
1081 		BIOP_Directory->Name[i].kind_length = gf_bs_read_int(bs,8);
1082 		if(BIOP_Directory->Name[i].kind_length > 0x04) {
1083 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] kind_length value is not valid\n"));
1084 			return GF_CORRUPTED_DATA;
1085 		}
1086 		if(BIOP_Directory->Name[i].kind_length) {
1087 			BIOP_Directory->Name[i].kind_data = (char*)gf_calloc(BIOP_Directory->Name[i].kind_length,sizeof(char));
1088 			gf_bs_read_data(bs,BIOP_Directory->Name[i].kind_data,(u32)(BIOP_Directory->Name[i].kind_length));
1089 		}
1090 
1091 		BIOP_Directory->Name[i].BindingType = gf_bs_read_int(bs,8);
1092 		/* IOR */
1093 		e = dsmcc_biop_get_ior(bs,&BIOP_Directory->Name[i].IOR);
1094 		if(e) {
1095 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in IOR processing\n"));
1096 			return GF_CORRUPTED_DATA;
1097 		}
1098 
1099 		BIOP_Directory->Name[i].objectInfo_length = gf_bs_read_int(bs,16);
1100 		if(!strcmp(BIOP_Directory->Name[i].kind_data,"fil")) {
1101 			BIOP_Directory->Name[i].ContentSize = gf_bs_read_int(bs,64);
1102 			descr_length = BIOP_Directory->Name[i].objectInfo_length - 8;
1103 		} else {
1104 			descr_length = BIOP_Directory->Name[i].objectInfo_length;
1105 		}
1106 
1107 		if(descr_length) {
1108 			BIOP_Directory->Name[i].descriptor = gf_list_new();
1109 			dsmcc_biop_descriptor(bs,BIOP_Directory->Name[i].descriptor,descr_length);
1110 		}
1111 
1112 		gf_bs_read_int(bs,(u32)(descr_length));
1113 
1114 		nb_desc = gf_list_count(BIOP_Directory->Name[i].descriptor);
1115 		j = 0;
1116 		while(j<nb_desc) {
1117 			u8* descr_tag;
1118 			/* get the descriptor tag */
1119 			descr_tag = (u8*)gf_list_get(BIOP_Directory->Name[i].descriptor ,0);
1120 
1121 			switch(*descr_tag) {
1122 			case CONTENT_TYPE_DESCRIPTOR:
1123 			{
1124 				//GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR* ContentTypeDescr = (GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR*)gf_list_get(BIOP_Directory->Name[i].descriptor ,j);
1125 			}
1126 			default:
1127 			{
1128 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported descriptor Type \n"));
1129 				break;
1130 			}
1131 			}
1132 			j++;
1133 		}
1134 
1135 		if(!strcmp(BIOP_Directory->Name[i].kind_data,"dir")) {
1136 			if(!dsmcc_check_element_validation(ServiceGateway->Dir,ServiceGateway->name,BIOP_Directory->Name[i])) {
1137 				GF_M2TS_DSMCC_DIR* Directory;
1138 				GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile = (GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE*)gf_list_get(BIOP_Directory->Name[i].IOR.taggedProfile,0);
1139 				GF_SAFEALLOC(Directory,GF_M2TS_DSMCC_DIR);
1140 				Directory->name = (char*)gf_strdup(BIOP_Directory->Name[i].id_data);
1141 				Directory->File = gf_list_new();
1142 				Directory->objectKey_data = taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_data;
1143 				Directory->downloadId = taggedProfile->BIOPProfileBody->ObjectLocation.carouselId;
1144 				Directory->moduleId = taggedProfile->BIOPProfileBody->ObjectLocation.moduleId;
1145 				Directory->parent = Dir;
1146 				Directory->Path = dsmcc_get_file_namepath(Dir,Directory->name);
1147 				e = gf_mkdir(Directory->Path);
1148 				if(e) {
1149 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error during the creation of the directory %s \n",Directory->Path));
1150 				}
1151 				gf_list_add(ServiceGateway->Dir,Directory);
1152 			}
1153 		} else if(!strcmp(BIOP_Directory->Name[i].kind_data,"fil")) {
1154 			if(!dsmcc_check_element_validation(ServiceGateway->File,ServiceGateway->name,BIOP_Directory->Name[i])) {
1155 				GF_M2TS_DSMCC_FILE* File;
1156 				GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile = (GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE*)gf_list_get(BIOP_Directory->Name[i].IOR.taggedProfile,0);
1157 				GF_SAFEALLOC(File,GF_M2TS_DSMCC_FILE);
1158 				File->name = (char*)gf_strdup(BIOP_Directory->Name[i].id_data);
1159 				File->objectKey_data = taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_data;
1160 				File->downloadId = taggedProfile->BIOPProfileBody->ObjectLocation.carouselId;
1161 				File->moduleId = taggedProfile->BIOPProfileBody->ObjectLocation.moduleId;
1162 				File->parent = Dir;
1163 				File->Path = dsmcc_get_file_namepath(Dir,File->name);
1164 				gf_list_add(ServiceGateway->File,File);
1165 			}
1166 		}
1167 	}
1168 	dsmcc_free_biop_directory(BIOP_Directory);
1169 
1170 	return GF_OK;
1171 }
1172 
dsmcc_process_biop_stream_event(GF_BitStream * bs,GF_M2TS_DSMCC_BIOP_HEADER * BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY * ServiceGateway)1173 static GF_Err dsmcc_process_biop_stream_event(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway) {
1174 
1175 	u32 i;
1176 	GF_M2TS_DSMCC_BIOP_STREAM_EVENT* BIOP_StreamEvent;
1177 	//GF_M2TS_DSMCC_FILE* File;
1178 
1179 	GF_SAFEALLOC(BIOP_StreamEvent,GF_M2TS_DSMCC_BIOP_STREAM_EVENT);
1180 
1181 	BIOP_StreamEvent->Header = BIOP_Header;
1182 	/* Get Info */
1183 	BIOP_StreamEvent->Info.aDescription_length = gf_bs_read_int(bs,8);
1184 	if(BIOP_StreamEvent->Info.aDescription_length) {
1185 		BIOP_StreamEvent->Info.aDescription_bytes = (char*)gf_calloc(BIOP_StreamEvent->Info.aDescription_length,sizeof(char));
1186 		gf_bs_read_data(bs,BIOP_StreamEvent->Info.aDescription_bytes,(u8)(BIOP_StreamEvent->Info.aDescription_length));
1187 	}
1188 	BIOP_StreamEvent->Info.duration_aSeconds = gf_bs_read_int(bs,32);
1189 	BIOP_StreamEvent->Info.duration_aMicroseconds = gf_bs_read_int(bs,32);
1190 	BIOP_StreamEvent->Info.audio = gf_bs_read_int(bs,8);
1191 	BIOP_StreamEvent->Info.video = gf_bs_read_int(bs,8);
1192 	BIOP_StreamEvent->Info.data = gf_bs_read_int(bs,8);
1193 
1194 	/* Event List */
1195 	BIOP_StreamEvent->eventNames_count = gf_bs_read_int(bs,16);
1196 	if(BIOP_StreamEvent->eventNames_count) {
1197 		BIOP_StreamEvent->EventList = (GF_M2TS_DSMCC_BIOP_EVENT_LIST*)gf_calloc(BIOP_StreamEvent->eventNames_count,sizeof(GF_M2TS_DSMCC_BIOP_EVENT_LIST));
1198 		for(i=0; i<BIOP_StreamEvent->eventNames_count; i++) {
1199 			BIOP_StreamEvent->EventList[i].eventName_length = gf_bs_read_int(bs,8);
1200 			BIOP_StreamEvent->EventList[i].eventName_length;
1201 			if(BIOP_StreamEvent->EventList[i].eventName_length) {
1202 				BIOP_StreamEvent->EventList[i].eventName_data_byte = (char*)gf_calloc(BIOP_StreamEvent->EventList[i].eventName_length,sizeof(char));
1203 				gf_bs_read_data(bs,BIOP_StreamEvent->EventList[i].eventName_data_byte,(u8)(BIOP_StreamEvent->EventList[i].eventName_length));
1204 			}
1205 		}
1206 	}
1207 
1208 	BIOP_StreamEvent->serviceContextList_count = gf_bs_read_int(bs,8);
1209 	if (BIOP_StreamEvent->serviceContextList_count) {
1210 		BIOP_StreamEvent->ServiceContext = (GF_M2TS_DSMCC_SERVICE_CONTEXT*)gf_calloc(BIOP_StreamEvent->serviceContextList_count,sizeof(GF_M2TS_DSMCC_SERVICE_CONTEXT));
1211 		dsmcc_biop_get_context(bs,BIOP_StreamEvent->ServiceContext,BIOP_StreamEvent->serviceContextList_count);
1212 	}
1213 
1214 	BIOP_StreamEvent->messageBody_length = gf_bs_read_int(bs,32);
1215 	BIOP_StreamEvent->taps_count = gf_bs_read_int(bs,8);
1216 	BIOP_StreamEvent->Taps = (GF_M2TS_DSMCC_BIOP_TAPS*)gf_calloc(BIOP_StreamEvent->taps_count,sizeof(GF_M2TS_DSMCC_BIOP_TAPS));
1217 	for (i=0; i<BIOP_StreamEvent->taps_count; i++) {
1218 		BIOP_StreamEvent->Taps[i].id = gf_bs_read_int(bs,16);
1219 		BIOP_StreamEvent->Taps[i].use = gf_bs_read_int(bs,16);
1220 		BIOP_StreamEvent->Taps[i].assocTag = gf_bs_read_int(bs,16);
1221 		BIOP_StreamEvent->Taps[i].selector_length = gf_bs_read_int(bs,8);
1222 		if(BIOP_StreamEvent->Taps[i].selector_length != 0x00) {
1223 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Stream Event : selector_length has a wrong value, abording the processing \n"));
1224 			return GF_CORRUPTED_DATA;
1225 		}
1226 	}
1227 	BIOP_StreamEvent->eventIds_count = gf_bs_read_int(bs,8);
1228 	if(BIOP_StreamEvent->eventIds_count != BIOP_StreamEvent->eventNames_count) {
1229 		GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Stream Event : eventIds_count has a wrong value, abording the processing \n"));
1230 		return GF_CORRUPTED_DATA;
1231 	} else if(BIOP_StreamEvent->eventIds_count) {
1232 		BIOP_StreamEvent->eventId = (u16*)gf_calloc(BIOP_StreamEvent->eventIds_count,sizeof(u16));
1233 		for(i =0; i<BIOP_StreamEvent->eventIds_count; i++) {
1234 			BIOP_StreamEvent->eventId[i] = gf_bs_read_int(bs,16);
1235 		}
1236 	}
1237 
1238 	dsmcc_free_biop_stream_event(BIOP_StreamEvent);
1239 
1240 	return GF_OK;
1241 }
1242 
dsmcc_process_biop_stream_message(GF_BitStream * bs,GF_M2TS_DSMCC_BIOP_HEADER * BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY * ServiceGateway)1243 static GF_Err dsmcc_process_biop_stream_message(GF_BitStream* bs,GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header,GF_M2TS_DSMCC_SERVICE_GATEWAY* ServiceGateway) {
1244 
1245 	u32 i;
1246 	GF_M2TS_DSMCC_BIOP_STREAM_MESSAGE* BIOP_StreamMessage;
1247 
1248 	GF_SAFEALLOC(BIOP_StreamMessage,GF_M2TS_DSMCC_BIOP_STREAM_MESSAGE);
1249 
1250 	BIOP_StreamMessage->Header = BIOP_Header;
1251 	/* Get Info */
1252 	BIOP_StreamMessage->Info.aDescription_length = gf_bs_read_int(bs,8);
1253 	if(BIOP_StreamMessage->Info.aDescription_length) {
1254 		BIOP_StreamMessage->Info.aDescription_bytes = (char*)gf_calloc(BIOP_StreamMessage->Info.aDescription_length,sizeof(char));
1255 		gf_bs_read_data(bs,BIOP_StreamMessage->Info.aDescription_bytes,(u8)(BIOP_StreamMessage->Info.aDescription_length));
1256 	}
1257 	BIOP_StreamMessage->Info.duration_aSeconds = gf_bs_read_int(bs,32);
1258 	BIOP_StreamMessage->Info.duration_aMicroseconds = gf_bs_read_int(bs,32);
1259 	BIOP_StreamMessage->Info.audio = gf_bs_read_int(bs,8);
1260 	BIOP_StreamMessage->Info.video = gf_bs_read_int(bs,8);
1261 	BIOP_StreamMessage->Info.data = gf_bs_read_int(bs,8);
1262 
1263 	BIOP_StreamMessage->serviceContextList_count = gf_bs_read_int(bs,8);
1264 	if(BIOP_StreamMessage->serviceContextList_count) {
1265 		BIOP_StreamMessage->ServiceContext = (GF_M2TS_DSMCC_SERVICE_CONTEXT*)gf_calloc(BIOP_StreamMessage->serviceContextList_count,sizeof(GF_M2TS_DSMCC_SERVICE_CONTEXT));
1266 		dsmcc_biop_get_context(bs,BIOP_StreamMessage->ServiceContext,BIOP_StreamMessage->serviceContextList_count);
1267 	}
1268 
1269 	BIOP_StreamMessage->messageBody_length = gf_bs_read_int(bs,32);
1270 	BIOP_StreamMessage->taps_count = gf_bs_read_int(bs,8);
1271 	BIOP_StreamMessage->Taps = (GF_M2TS_DSMCC_BIOP_TAPS*)gf_calloc(BIOP_StreamMessage->taps_count,sizeof(GF_M2TS_DSMCC_BIOP_TAPS));
1272 	for(i=0; i<BIOP_StreamMessage->taps_count; i++) {
1273 		BIOP_StreamMessage->Taps[i].id = gf_bs_read_int(bs,16);
1274 		BIOP_StreamMessage->Taps[i].use = gf_bs_read_int(bs,16);
1275 		BIOP_StreamMessage->Taps[i].assocTag = gf_bs_read_int(bs,16);
1276 		BIOP_StreamMessage->Taps[i].selector_length = gf_bs_read_int(bs,8);
1277 		if(BIOP_StreamMessage->Taps[i].selector_length != 0x00) {
1278 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Stream Event : selector_length has a wrong value, abording the processing \n"));
1279 			return GF_CORRUPTED_DATA;
1280 		}
1281 	}
1282 
1283 	dsmcc_free_biop_stream_message(BIOP_StreamMessage);
1284 
1285 	return GF_OK;
1286 }
1287 
1288 
1289 /* Tools */
1290 
dsmcc_create_module(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord,GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC * DownloadInfoIndication)1291 static GF_M2TS_DSMCC_MODULE* dsmcc_create_module(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord, GF_M2TS_DSMCC_DOWNLOAD_INFO_RESP_INDIC* DownloadInfoIndication)
1292 {
1293 	u32 module_index;
1294 	GF_M2TS_DSMCC_MODULE* dsmcc_module;
1295 	GF_SAFEALLOC(dsmcc_module,GF_M2TS_DSMCC_MODULE);
1296 	dsmcc_module->downloadId = DownloadInfoIndication->downloadId;
1297 	dsmcc_module->moduleId = DownloadInfoIndication->Modules.moduleId;
1298 	dsmcc_module->size = DownloadInfoIndication->Modules.moduleSize;
1299 	dsmcc_module->version_number = DownloadInfoIndication->Modules.moduleVersion;
1300 	dsmcc_module->block_size = DownloadInfoIndication->blockSize;
1301 	dsmcc_module->buffer = (char*)gf_calloc(dsmcc_module->size,sizeof(char));
1302 	module_index = gf_list_count(dsmcc_overlord->dsmcc_modules);
1303 	dsmcc_overlord->processed[module_index].moduleId = dsmcc_module->moduleId;
1304 	dsmcc_overlord->processed[module_index].downloadId = dsmcc_module->downloadId;
1305 	dsmcc_overlord->processed[module_index].version_number = dsmcc_module->version_number;
1306 	gf_list_add(dsmcc_overlord->dsmcc_modules,dsmcc_module);
1307 
1308 	return dsmcc_module;
1309 }
1310 
dsmcc_biop_descriptor(GF_BitStream * bs,GF_List * list,u32 size)1311 static void dsmcc_biop_descriptor(GF_BitStream* bs,GF_List* list,u32 size) {
1312 	u8 descr_tag;
1313 	u32 data_shift,start_pos;
1314 
1315 	start_pos = (u32)(gf_bs_get_position(bs));
1316 	data_shift = 0;
1317 
1318 	while(size > data_shift) {
1319 		descr_tag = gf_bs_read_int(bs,8);
1320 
1321 		switch(descr_tag) {
1322 
1323 		case CACHING_PRIORITY_DESCRIPTOR:
1324 		{
1325 			GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR* CachingPriorityDescr;
1326 			GF_SAFEALLOC(CachingPriorityDescr,GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR);
1327 			CachingPriorityDescr->descriptor_tag = descr_tag;
1328 			CachingPriorityDescr->descriptor_length = gf_bs_read_int(bs,8);
1329 			CachingPriorityDescr->priority_value = gf_bs_read_int(bs,8);
1330 			CachingPriorityDescr->transparency_level = gf_bs_read_int(bs,8);
1331 			gf_list_add(list,CachingPriorityDescr);
1332 			break;
1333 		}
1334 		case COMPRESSED_MODULE_DESCRIPTOR:
1335 		{
1336 			GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR* CompModuleDescr;
1337 			GF_SAFEALLOC(CompModuleDescr,GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR);
1338 			CompModuleDescr->descriptor_tag = descr_tag;
1339 			CompModuleDescr->descriptor_length = gf_bs_read_int(bs,8);
1340 			CompModuleDescr->compression_method = gf_bs_read_int(bs,8);
1341 			/* if CompModuleDescr->compression_method least significant nibble is eq to 0x08, the terminal shall support the Deflate compression algorithm (GZIP) */
1342 			CompModuleDescr->original_size = gf_bs_read_int(bs,32);
1343 			gf_list_add(list,CompModuleDescr);
1344 			break;
1345 
1346 		}
1347 		case CONTENT_TYPE_DESCRIPTOR:
1348 		{
1349 			GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR* ContentTypeDescr;
1350 			GF_SAFEALLOC(ContentTypeDescr,GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR);
1351 			ContentTypeDescr->descriptor_tag = descr_tag;
1352 			ContentTypeDescr->descriptor_length = gf_bs_read_int(bs,8);
1353 			ContentTypeDescr->content_type_data_byte = (char*)gf_calloc(ContentTypeDescr->descriptor_length,sizeof(char));
1354 			gf_bs_read_data(bs,ContentTypeDescr->content_type_data_byte,(u32)(ContentTypeDescr->descriptor_length));
1355 			gf_list_add(list,ContentTypeDescr);
1356 		}
1357 		default:
1358 		{
1359 			u32 dsize;
1360 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported Descriptor Type \n"));
1361 			/* byte shift - in descriptors length is on thr second byte*/
1362 			dsize = gf_bs_read_int(bs,8);
1363 			gf_bs_read_int(bs,8*dsize);
1364 			break;
1365 		}
1366 		}
1367 		data_shift = (u32)(gf_bs_get_position(bs)) - start_pos;
1368 	}
1369 }
1370 
dsmcc_biop_get_context(GF_BitStream * bs,GF_M2TS_DSMCC_SERVICE_CONTEXT * Context,u32 serviceContextList_count)1371 static void dsmcc_biop_get_context(GF_BitStream* bs,GF_M2TS_DSMCC_SERVICE_CONTEXT* Context,u32 serviceContextList_count)
1372 {
1373 	u32 i;
1374 
1375 	for(i=0; i<serviceContextList_count; i++) {
1376 		Context[i].context_id = gf_bs_read_int(bs,32);
1377 		Context[i].context_data_length = gf_bs_read_int(bs,16);
1378 		if(Context[i].context_data_length != 0) {
1379 			Context[i].context_data_byte = (char*)gf_calloc(Context[i].context_data_length ,sizeof(char));
1380 			gf_bs_read_data(bs,Context[i].context_data_byte,(u32)(Context[i].context_data_length ));
1381 		}
1382 	}
1383 }
1384 
dsmcc_biop_get_ior(GF_BitStream * bs,GF_M2TS_DSMCC_IOR * IOR)1385 static GF_Err dsmcc_biop_get_ior(GF_BitStream* bs,GF_M2TS_DSMCC_IOR* IOR)
1386 {
1387 	u32 i,j,left_lite_component;
1388 	/* IOR */
1389 	IOR->type_id_length = gf_bs_read_int(bs,32);
1390 	if(IOR->type_id_length > 0xA) {
1391 		//return GF_CORRUPTED_DATA;
1392 	}
1393 	IOR->type_id_byte = (char*)gf_calloc(IOR->type_id_length,sizeof(char));
1394 	gf_bs_read_data(bs,IOR->type_id_byte,(u32)(IOR->type_id_length));
1395 	IOR->taggedProfiles_count = gf_bs_read_int(bs,32);
1396 	IOR->taggedProfile = gf_list_new();
1397 	for(i = 0; i < IOR->taggedProfiles_count; i++) {
1398 		GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile;
1399 		GF_SAFEALLOC(taggedProfile,GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE);
1400 		gf_list_add(IOR->taggedProfile,taggedProfile);
1401 		taggedProfile->profileId_tag = gf_bs_read_int(bs,32);
1402 		taggedProfile->profile_data_length = gf_bs_read_int(bs,32);
1403 		taggedProfile->profile_data_byte_order = gf_bs_read_int(bs,8);
1404 		if(taggedProfile->profile_data_byte_order != 0x00) {
1405 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in IOR processing : profile data byte order has a wrong value, abording the processing \n"));
1406 			return GF_CORRUPTED_DATA;
1407 		}
1408 		taggedProfile->lite_component_count = gf_bs_read_int(bs,8);
1409 		left_lite_component = taggedProfile->lite_component_count;
1410 		switch(taggedProfile->profileId_tag) {
1411 		case TAG_BIOP:
1412 		{
1413 			/* Object Location */
1414 			GF_SAFEALLOC(taggedProfile->BIOPProfileBody,GF_M2TS_DSMCC_BIOP_PROFILE_BODY);
1415 			taggedProfile->BIOPProfileBody->ObjectLocation.componentId_tag = gf_bs_read_int(bs,32);
1416 			if(taggedProfile->BIOPProfileBody->ObjectLocation.componentId_tag != 0x49534F50) {
1417 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Profile Body : component tag has a wrong value, abording the processing \n"));
1418 				return GF_CORRUPTED_DATA;
1419 			}
1420 			taggedProfile->BIOPProfileBody->ObjectLocation.component_data_length = gf_bs_read_int(bs,8);
1421 			taggedProfile->BIOPProfileBody->ObjectLocation.carouselId = gf_bs_read_int(bs,32);
1422 			taggedProfile->BIOPProfileBody->ObjectLocation.moduleId = gf_bs_read_int(bs,16);
1423 			taggedProfile->BIOPProfileBody->ObjectLocation.version_major = gf_bs_read_int(bs,8);
1424 			if(taggedProfile->BIOPProfileBody->ObjectLocation.version_major != 0x01) {
1425 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Profile Body : version major has a wrong value, abording the processing \n"));
1426 				return GF_CORRUPTED_DATA;
1427 			}
1428 			taggedProfile->BIOPProfileBody->ObjectLocation.version_minor = gf_bs_read_int(bs,8);
1429 			if(taggedProfile->BIOPProfileBody->ObjectLocation.version_minor != 0x00) {
1430 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Profile Body : version minor has a wrong value, abording the processing \n"));
1431 				return GF_CORRUPTED_DATA;
1432 			}
1433 			taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_length = gf_bs_read_int(bs,8);
1434 			if(taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_length) {
1435 				taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_data = gf_bs_read_int(bs,taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_length*8);
1436 			}
1437 			/* ConnBinder */
1438 
1439 			taggedProfile->BIOPProfileBody->ConnBinder.componentId_tag = gf_bs_read_int(bs,32);
1440 			if(taggedProfile->BIOPProfileBody->ConnBinder.componentId_tag != 0x49534F40) {
1441 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in ConnBinder : componentId tag has a wrong value, abording the processing \n"));
1442 				return GF_CORRUPTED_DATA;
1443 			}
1444 			taggedProfile->BIOPProfileBody->ConnBinder.component_data_length = gf_bs_read_int(bs,8);
1445 			taggedProfile->BIOPProfileBody->ConnBinder.taps_count = gf_bs_read_int(bs,8);
1446 			taggedProfile->BIOPProfileBody->ConnBinder.Taps = (GF_M2TS_DSMCC_BIOP_TAPS*)gf_calloc(taggedProfile->BIOPProfileBody->ConnBinder.taps_count,sizeof(GF_M2TS_DSMCC_BIOP_TAPS));
1447 			for(j=0; j<taggedProfile->BIOPProfileBody->ConnBinder.taps_count; j++) {
1448 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].id = gf_bs_read_int(bs,16);
1449 				if(taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].id != 0x00) {
1450 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in ConnBinder : id has a wrong value, abording the processing \n"));
1451 					return GF_CORRUPTED_DATA;
1452 				}
1453 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].use = gf_bs_read_int(bs,16);
1454 				if(taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].use != 0x016) {
1455 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in ConnBinder : use has a wrong value, abording the processing \n"));
1456 					return GF_CORRUPTED_DATA;
1457 				}
1458 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].assocTag = gf_bs_read_int(bs,16);
1459 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].selector_length = gf_bs_read_int(bs,8);
1460 				if(taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].selector_length != 0x0A) {
1461 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in ConnBinder : selector_length has a wrong value, abording the processing \n"));
1462 					return GF_CORRUPTED_DATA;
1463 				}
1464 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].selector_type = gf_bs_read_int(bs,16);
1465 				if(taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].selector_type != 0x001) {
1466 					GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in ConnBinder : selector_type has a wrong value, abording the processing \n"));
1467 					return GF_CORRUPTED_DATA;
1468 				}
1469 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].transactionId = gf_bs_read_int(bs,32);
1470 				taggedProfile->BIOPProfileBody->ConnBinder.Taps[i].timeout = gf_bs_read_int(bs,32);
1471 			}
1472 			if(taggedProfile->BIOPProfileBody->ConnBinder.component_data_length-18 != 0) {
1473 				taggedProfile->BIOPProfileBody->ConnBinder.additional_tap_byte = (char*)gf_calloc(taggedProfile->BIOPProfileBody->ConnBinder.component_data_length-18,sizeof(char));
1474 				gf_bs_read_data(bs,taggedProfile->BIOPProfileBody->ConnBinder.additional_tap_byte,(u32)(taggedProfile->BIOPProfileBody->ConnBinder.component_data_length-18));
1475 			}
1476 			left_lite_component = left_lite_component - 2;
1477 			break;
1478 		}
1479 		case TAG_LITE_OPTIONS:
1480 		{
1481 			/* Service Location */
1482 			GF_SAFEALLOC(taggedProfile->ServiceLocation,GF_M2TS_DSMCC_BIOP_SERVICE_LOCATION);
1483 			taggedProfile->ServiceLocation->componentId_tag = gf_bs_read_int(bs,32);
1484 			if(taggedProfile->ServiceLocation->componentId_tag != 0x49534F46) {
1485 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Service Location : component tag has a wrong value, abording the processing \n"));
1486 				return GF_CORRUPTED_DATA;
1487 			}
1488 			taggedProfile->ServiceLocation->component_data_length = gf_bs_read_int(bs,8);
1489 			taggedProfile->ServiceLocation->serviceDomain_length = gf_bs_read_int(bs,8);
1490 			if(taggedProfile->ServiceLocation->serviceDomain_length != 0x14) {
1491 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Service Location : Service Domain Length tag has a wrong value, abording the processing \n"));
1492 				return GF_CORRUPTED_DATA;
1493 			}
1494 			taggedProfile->ServiceLocation->serviceDomain_data.AFI = gf_bs_read_int(bs,8);
1495 			taggedProfile->ServiceLocation->serviceDomain_data.type = gf_bs_read_int(bs,8);
1496 			taggedProfile->ServiceLocation->serviceDomain_data.carouselId = gf_bs_read_int(bs,32);
1497 			taggedProfile->ServiceLocation->serviceDomain_data.specifierType = gf_bs_read_int(bs,8);
1498 			taggedProfile->ServiceLocation->serviceDomain_data.specifierData = gf_bs_read_int(bs,24);
1499 			taggedProfile->ServiceLocation->serviceDomain_data.transport_stream_id = gf_bs_read_int(bs,16);
1500 			taggedProfile->ServiceLocation->serviceDomain_data.original_network_id = gf_bs_read_int(bs,16);
1501 			taggedProfile->ServiceLocation->serviceDomain_data.service_id = gf_bs_read_int(bs,16);
1502 			taggedProfile->ServiceLocation->serviceDomain_data.reserved = gf_bs_read_int(bs,32);
1503 			if(taggedProfile->ServiceLocation->serviceDomain_data.reserved != 0xFFFFFFFF) {
1504 				GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Error in Service Domain Data : reserved has a wrong value, abording the processing \n"));
1505 				return GF_CORRUPTED_DATA;
1506 			}
1507 			taggedProfile->ServiceLocation->nameComponents_count = gf_bs_read_int(bs,32);
1508 			taggedProfile->ServiceLocation->NameComponent = (GF_M2TS_DSMCC_BIOP_NAME_COMPONENT*)gf_calloc(taggedProfile->ServiceLocation->nameComponents_count,sizeof(GF_M2TS_DSMCC_BIOP_NAME_COMPONENT));
1509 			for(j = 0; j < taggedProfile->ServiceLocation->nameComponents_count; j++) {
1510 				taggedProfile->ServiceLocation->NameComponent[j].id_length = gf_bs_read_int(bs,32);
1511 				if(taggedProfile->ServiceLocation->NameComponent[j].id_length != 0) {
1512 					taggedProfile->ServiceLocation->NameComponent[j].id_data = (char*)gf_calloc(taggedProfile->ServiceLocation->NameComponent[j].id_length,sizeof(char));
1513 					gf_bs_read_data(bs,taggedProfile->ServiceLocation->NameComponent[i].id_data,(u32)(taggedProfile->ServiceLocation->NameComponent[j].id_length));
1514 				}
1515 				taggedProfile->ServiceLocation->NameComponent[j].kind_length = gf_bs_read_int(bs,32);
1516 				if(taggedProfile->ServiceLocation->NameComponent[j].kind_length != 0) {
1517 					taggedProfile->ServiceLocation->NameComponent[j].kind_data = (char*)gf_calloc(taggedProfile->ServiceLocation->NameComponent[j].kind_length,sizeof(char));
1518 					gf_bs_read_data(bs,taggedProfile->ServiceLocation->NameComponent[j].kind_data,(u32)(taggedProfile->ServiceLocation->NameComponent[j].kind_length));
1519 				}
1520 			}
1521 			taggedProfile->ServiceLocation->initialContext_length = gf_bs_read_int(bs,8);
1522 			if(taggedProfile->ServiceLocation->initialContext_length != 0) {
1523 				taggedProfile->ServiceLocation->InitialContext_data_byte = (char*)gf_calloc(taggedProfile->ServiceLocation->initialContext_length,sizeof(char));
1524 				gf_bs_read_data(bs,taggedProfile->ServiceLocation->InitialContext_data_byte,(u32)(taggedProfile->ServiceLocation->initialContext_length));
1525 			}
1526 			left_lite_component = left_lite_component - 1;
1527 			break;
1528 		}
1529 		default:
1530 		{
1531 			GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[Process DSMCC] Unsupported Service gateway profile tag \n"));
1532 			break;
1533 		}
1534 		}
1535 		taggedProfile->LiteComponent = (GF_M2TS_DSMCC_BIOP_LITE_COMPONENT*)gf_calloc(left_lite_component,sizeof(GF_M2TS_DSMCC_BIOP_LITE_COMPONENT));
1536 		for(j = 0; j<left_lite_component ; j++) {
1537 			taggedProfile->LiteComponent[j].componentId_tag = gf_bs_read_int(bs,32);
1538 			taggedProfile->LiteComponent[j].component_data_length = gf_bs_read_int(bs,8);
1539 			if(taggedProfile->LiteComponent[j].component_data_length != 0) {
1540 				taggedProfile->LiteComponent[j].component_data_byte = (char*)gf_calloc(taggedProfile->ServiceLocation->initialContext_length,sizeof(char));
1541 				gf_bs_read_data(bs,taggedProfile->LiteComponent[j].component_data_byte,(u32)(taggedProfile->LiteComponent[j].component_data_length));
1542 			}
1543 		}
1544 
1545 	}
1546 	return GF_OK;
1547 }
1548 
dsmcc_check_element_validation(GF_List * List,char * Parent_name,GF_M2TS_DSMCC_BIOP_NAME Name)1549 static GF_Err dsmcc_check_element_validation(GF_List* List,char* Parent_name,GF_M2TS_DSMCC_BIOP_NAME Name)
1550 {
1551 	u32 nb_elt,i;
1552 
1553 	GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile = (GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE*)gf_list_get(Name.IOR.taggedProfile,0);
1554 	nb_elt = gf_list_count(List);
1555 
1556 	for(i = 0; i < nb_elt; i++) {
1557 		GF_M2TS_DSMCC_FILE* File = (GF_M2TS_DSMCC_FILE*)gf_list_get(List,i);
1558 		if(!strcmp(File->name,Name.id_data) && !strcmp(File->parent,Parent_name) &&
1559 		        (File->objectKey_data == taggedProfile->BIOPProfileBody->ObjectLocation.objectKey_data) && File->moduleId == taggedProfile->BIOPProfileBody->ObjectLocation.moduleId) {
1560 			/* File or Dir already received */
1561 			return GF_BAD_PARAM;
1562 		}
1563 	}
1564 
1565 	return GF_OK;
1566 }
1567 
dsmcc_get_directory(GF_List * List,u32 objectKey_data)1568 static GF_M2TS_DSMCC_DIR* dsmcc_get_directory(GF_List* List, u32 objectKey_data) {
1569 	u32 nb_elt,i;
1570 
1571 	nb_elt = gf_list_count(List);
1572 
1573 	for(i = 0; i<nb_elt; i++) {
1574 		GF_M2TS_DSMCC_DIR* Dir = (GF_M2TS_DSMCC_DIR*)gf_list_get(List,i);
1575 		if(Dir->objectKey_data == objectKey_data) {
1576 			return Dir;
1577 		}
1578 		if(gf_list_count(Dir->Dir)) {
1579 			GF_M2TS_DSMCC_DIR* TmpDir;
1580 			TmpDir = dsmcc_get_directory(Dir->Dir,objectKey_data);
1581 			if(TmpDir) {
1582 				return TmpDir;
1583 			}
1584 		}
1585 	}
1586 	return NULL;
1587 }
1588 
dsmcc_get_file(GF_List * ServiceGateway_List,u16 moduleId,u32 downloadId,u32 objectKey_data)1589 static GF_M2TS_DSMCC_FILE* dsmcc_get_file(GF_List* ServiceGateway_List, u16 moduleId,u32 downloadId,u32 objectKey_data) {
1590 	u32 nb_elt,i;
1591 	nb_elt = gf_list_count(ServiceGateway_List);
1592 	for(i = 0; i<nb_elt; i++) {
1593 		GF_M2TS_DSMCC_FILE* File = (GF_M2TS_DSMCC_FILE*)gf_list_get(ServiceGateway_List,i);
1594 		if((File->objectKey_data == objectKey_data) && File->moduleId == moduleId && File->downloadId == downloadId) {
1595 			return File;
1596 		}
1597 	}
1598 	return NULL;
1599 }
1600 
dsmcc_get_file_namepath(GF_M2TS_DSMCC_DIR * Dir,char * name)1601 static char* dsmcc_get_file_namepath(GF_M2TS_DSMCC_DIR* Dir,char* name) {
1602 	char* Path;
1603 	GF_M2TS_DSMCC_DIR* directory = Dir;
1604 
1605 	Path = gf_calloc(512,sizeof(char));
1606 	sprintf(Path,"%s%c%s",directory->name,GF_PATH_SEPARATOR,name);
1607 	while(directory->parent != NULL) {
1608 		GF_M2TS_DSMCC_DIR* tempdir;
1609 		char* tempPath = gf_strdup(Path);
1610 		tempdir = (GF_M2TS_DSMCC_DIR*)directory->parent;
1611 		sprintf(Path,"%s%c%s",tempdir->name,GF_PATH_SEPARATOR,tempPath);
1612 		gf_free(tempPath);
1613 		directory = tempdir;
1614 	}
1615 	return Path;
1616 }
1617 
1618 
1619 /* Free struct */
1620 
dsmcc_delete_module(GF_M2TS_DSMCC_MODULE * module)1621 static void dsmcc_delete_module(GF_M2TS_DSMCC_MODULE* module)
1622 {
1623 	if(module->buffer) {
1624 		gf_free(module->buffer);
1625 	}
1626 
1627 	gf_free(module);
1628 }
1629 
dmscc_delete_file(GF_M2TS_DSMCC_FILE * File)1630 static void dmscc_delete_file(GF_M2TS_DSMCC_FILE* File) {
1631 
1632 	if(File->name) {
1633 		gf_free(File->name);
1634 	}
1635 	if(File->Path) {
1636 		gf_free(File->Path);
1637 	}
1638 }
1639 
dmscc_delete_dir(GF_M2TS_DSMCC_DIR * Dir)1640 static void dmscc_delete_dir(GF_M2TS_DSMCC_DIR* Dir) {
1641 
1642 	u32 nb_file, nb_dir,i;
1643 
1644 	if(Dir->name) {
1645 		gf_free(Dir->name);
1646 	}
1647 	if(Dir->Path) {
1648 		gf_free(Dir->Path);
1649 	}
1650 
1651 	nb_file = gf_list_count(Dir->File);
1652 	for(i=0; i<nb_file; i++) {
1653 		GF_M2TS_DSMCC_FILE* File = (GF_M2TS_DSMCC_FILE*)gf_list_get(Dir->File,i);
1654 		dmscc_delete_file(File);
1655 	}
1656 	gf_list_del(Dir->File);
1657 
1658 	nb_dir = gf_list_count(Dir->Dir);
1659 	for(i=0; i<nb_dir; i++) {
1660 		GF_M2TS_DSMCC_DIR* Sub_Dir = (GF_M2TS_DSMCC_DIR*)gf_list_get(Dir->Dir,i);
1661 		dmscc_delete_dir(Sub_Dir);
1662 	}
1663 	gf_list_del(Dir->Dir);
1664 	gf_free(Dir);
1665 }
1666 
dmscc_delete_servicegateway(GF_M2TS_DSMCC_SERVICE_GATEWAY * Servicegateway)1667 static void dmscc_delete_servicegateway(GF_M2TS_DSMCC_SERVICE_GATEWAY* Servicegateway) {
1668 
1669 	u32 nb_file, nb_dir,i;
1670 
1671 	if(Servicegateway->name) {
1672 		gf_free(Servicegateway->name);
1673 	}
1674 	nb_file = gf_list_count(Servicegateway->File);
1675 	for(i=0; i<nb_file; i++) {
1676 		GF_M2TS_DSMCC_FILE* File = (GF_M2TS_DSMCC_FILE*)gf_list_get(Servicegateway->File,i);
1677 		dmscc_delete_file(File);
1678 	}
1679 	gf_list_del(Servicegateway->File);
1680 
1681 	nb_dir = gf_list_count(Servicegateway->Dir);
1682 	for(i=0; i<nb_dir; i++) {
1683 		GF_M2TS_DSMCC_DIR* Dir = (GF_M2TS_DSMCC_DIR*)gf_list_get(Servicegateway->Dir,i);
1684 		dmscc_delete_dir(Dir);
1685 	}
1686 	gf_list_del(Servicegateway->Dir);
1687 	gf_free(Servicegateway);
1688 }
1689 
gf_m2ts_delete_dsmcc_overlord(GF_M2TS_DSMCC_OVERLORD * dsmcc_overlord)1690 void gf_m2ts_delete_dsmcc_overlord(GF_M2TS_DSMCC_OVERLORD* dsmcc_overlord)
1691 {
1692 	u16 nb_module,i;
1693 
1694 	nb_module = gf_list_count(dsmcc_overlord->dsmcc_modules);
1695 	for(i=0; i<nb_module; i++) {
1696 		GF_M2TS_DSMCC_MODULE* module = (GF_M2TS_DSMCC_MODULE*)gf_list_get(dsmcc_overlord->dsmcc_modules,i);
1697 		dsmcc_delete_module(module);
1698 	}
1699 	gf_list_del(dsmcc_overlord->dsmcc_modules);
1700 
1701 	nb_module = gf_list_count(dsmcc_overlord->Unprocessed_module);
1702 	for(i=0; i<nb_module; i++) {
1703 		GF_M2TS_DSMCC_MODULE* module = (GF_M2TS_DSMCC_MODULE*)gf_list_get(dsmcc_overlord->Unprocessed_module,i);
1704 		dsmcc_delete_module(module);
1705 	}
1706 	gf_list_del(dsmcc_overlord->dsmcc_modules);
1707 	dmscc_delete_servicegateway(dsmcc_overlord->ServiceGateway);
1708 
1709 	if(dsmcc_overlord->root_dir) {
1710 		gf_free(dsmcc_overlord->root_dir);
1711 	}
1712 
1713 	gf_free(dsmcc_overlord);
1714 }
1715 
dsmcc_free_biop_header(GF_M2TS_DSMCC_BIOP_HEADER * BIOP_Header)1716 static void dsmcc_free_biop_header(GF_M2TS_DSMCC_BIOP_HEADER* BIOP_Header) {
1717 
1718 	gf_free(BIOP_Header->objectKind_data);
1719 	gf_free(BIOP_Header);
1720 }
1721 
dsmcc_free_biop_directory(GF_M2TS_DSMCC_BIOP_DIRECTORY * BIOP_Directory)1722 static void dsmcc_free_biop_directory(GF_M2TS_DSMCC_BIOP_DIRECTORY* BIOP_Directory) {
1723 
1724 	gf_free(BIOP_Directory->objectInfo_data);
1725 	dsmcc_free_biop_context(BIOP_Directory->ServiceContext,BIOP_Directory->serviceContextList_count);
1726 	dsmcc_free_biop_name(BIOP_Directory->Name,BIOP_Directory->bindings_count);
1727 	gf_free(BIOP_Directory);
1728 }
1729 
dsmcc_free_biop_file(GF_M2TS_DSMCC_BIOP_FILE * BIOP_File)1730 static void dsmcc_free_biop_file(GF_M2TS_DSMCC_BIOP_FILE* BIOP_File) {
1731 
1732 	dsmcc_free_biop_descriptor(BIOP_File->descriptor);
1733 	dsmcc_free_biop_context(BIOP_File->ServiceContext,BIOP_File->serviceContextList_count);
1734 	if(BIOP_File->content_length) {
1735 		gf_free(BIOP_File->content_byte);
1736 	}
1737 	gf_free(BIOP_File);
1738 }
1739 
dsmcc_free_biop_stream_event(GF_M2TS_DSMCC_BIOP_STREAM_EVENT * BIOP_StreamEvent)1740 static void dsmcc_free_biop_stream_event(GF_M2TS_DSMCC_BIOP_STREAM_EVENT* BIOP_StreamEvent) {
1741 
1742 	u32 i;
1743 
1744 	if(BIOP_StreamEvent->Info.aDescription_length) {
1745 		gf_free(BIOP_StreamEvent->Info.aDescription_bytes);
1746 	}
1747 
1748 	if(BIOP_StreamEvent->objectInfo_byte) {
1749 		gf_free(BIOP_StreamEvent->objectInfo_byte);
1750 	}
1751 
1752 	if(BIOP_StreamEvent->eventNames_count) {
1753 		for(i=0; i<BIOP_StreamEvent->eventNames_count; i++) {
1754 			if(BIOP_StreamEvent->EventList[i].eventName_length) {
1755 				gf_free(BIOP_StreamEvent->EventList[i].eventName_data_byte);
1756 			}
1757 		}
1758 		gf_free(BIOP_StreamEvent->EventList);
1759 	}
1760 
1761 	if(BIOP_StreamEvent->taps_count) {
1762 		gf_free(BIOP_StreamEvent->Taps);
1763 	}
1764 
1765 	dsmcc_free_biop_context(BIOP_StreamEvent->ServiceContext,BIOP_StreamEvent->serviceContextList_count);
1766 
1767 	if(BIOP_StreamEvent->eventId) {
1768 		gf_free(BIOP_StreamEvent->eventId);
1769 	}
1770 }
1771 
dsmcc_free_biop_stream_message(GF_M2TS_DSMCC_BIOP_STREAM_MESSAGE * BIOP_StreamMessage)1772 static void dsmcc_free_biop_stream_message(GF_M2TS_DSMCC_BIOP_STREAM_MESSAGE* BIOP_StreamMessage) {
1773 
1774 	if(BIOP_StreamMessage->Info.aDescription_length) {
1775 		gf_free(BIOP_StreamMessage->Info.aDescription_bytes);
1776 	}
1777 
1778 	if(BIOP_StreamMessage->objectInfo_byte) {
1779 		gf_free(BIOP_StreamMessage->objectInfo_byte);
1780 	}
1781 
1782 	if(BIOP_StreamMessage->taps_count) {
1783 		gf_free(BIOP_StreamMessage->Taps);
1784 	}
1785 
1786 	dsmcc_free_biop_context(BIOP_StreamMessage->ServiceContext,BIOP_StreamMessage->serviceContextList_count);
1787 }
1788 
dsmcc_free_biop_ior(GF_M2TS_DSMCC_IOR * IOR)1789 static void dsmcc_free_biop_ior(GF_M2TS_DSMCC_IOR* IOR)
1790 {
1791 	u32 i,left_lite_component;
1792 
1793 	if(IOR->type_id_length) {
1794 		gf_free(IOR->type_id_byte);
1795 	}
1796 	for(i = 0; i < IOR->taggedProfiles_count; i++) {
1797 		GF_M2TS_DSMCC_BIOP_TAGGED_PROFILE* taggedProfile = gf_list_get(IOR->taggedProfile,0);
1798 		left_lite_component = taggedProfile->lite_component_count;
1799 
1800 		switch(taggedProfile->profileId_tag) {
1801 
1802 		case TAG_BIOP:
1803 		{
1804 			/* Object Location */
1805 			GF_SAFEALLOC(taggedProfile->BIOPProfileBody,GF_M2TS_DSMCC_BIOP_PROFILE_BODY);
1806 
1807 			gf_free(taggedProfile->BIOPProfileBody->ConnBinder.Taps);
1808 			if(taggedProfile->BIOPProfileBody->ConnBinder.component_data_length-18 != 0) {
1809 				gf_free(taggedProfile->BIOPProfileBody->ConnBinder.additional_tap_byte);
1810 			}
1811 			gf_free(taggedProfile->BIOPProfileBody);
1812 			left_lite_component = left_lite_component - 2;
1813 			break;
1814 		}
1815 		case TAG_LITE_OPTIONS:
1816 		{
1817 			/* Service Location */
1818 			u32 j;
1819 
1820 			for(j = 0; j < taggedProfile->ServiceLocation->nameComponents_count; j++) {
1821 
1822 				if(taggedProfile->ServiceLocation->NameComponent[j].id_length != 0) {
1823 					gf_free(taggedProfile->ServiceLocation->NameComponent[j].id_data);
1824 				}
1825 				if(taggedProfile->ServiceLocation->NameComponent[j].kind_length != 0) {
1826 					gf_free(taggedProfile->ServiceLocation->NameComponent[j].kind_data);
1827 				}
1828 			}
1829 			gf_free(taggedProfile->ServiceLocation->NameComponent);
1830 
1831 			if(taggedProfile->ServiceLocation->initialContext_length != 0) {
1832 				gf_free(taggedProfile->ServiceLocation->InitialContext_data_byte);
1833 			}
1834 			left_lite_component = left_lite_component - 1;
1835 			break;
1836 		}
1837 		}
1838 
1839 		for(i = 0; i<left_lite_component ; i++) {
1840 			if(taggedProfile->LiteComponent[i].component_data_length != 0) {
1841 				gf_free(taggedProfile->LiteComponent[i].component_data_byte);
1842 			}
1843 
1844 		}
1845 		gf_free(taggedProfile->LiteComponent);
1846 		gf_list_rem(IOR->taggedProfile,0);
1847 		gf_free(taggedProfile);
1848 	}
1849 	gf_list_del(IOR->taggedProfile);
1850 }
1851 
dsmcc_free_biop_descriptor(GF_List * list)1852 static void dsmcc_free_biop_descriptor(GF_List* list)
1853 {
1854 	while(gf_list_count(list)) {
1855 		u8* descr_tag;
1856 		descr_tag = (u8*)gf_list_get(list,0);
1857 
1858 		switch(*descr_tag) {
1859 
1860 		case CACHING_PRIORITY_DESCRIPTOR:
1861 		{
1862 			GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR* CachingPriorityDescr = (GF_M2TS_DSMCC_BIOP_CACHING_PRIORITY_DESCRIPTOR*)gf_list_get(list,0);
1863 			gf_list_rem(list,0);
1864 			gf_free(CachingPriorityDescr);
1865 			break;
1866 		}
1867 		case COMPRESSED_MODULE_DESCRIPTOR:
1868 		{
1869 			GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR* CompModuleDescr = (GF_M2TS_DSMCC_BIOP_COMPRESSED_MODULE_DESCRIPTOR*)gf_list_get(list,0);
1870 			gf_list_rem(list,0);
1871 			gf_free(CompModuleDescr);
1872 			break;
1873 
1874 		}
1875 		case CONTENT_TYPE_DESCRIPTOR:
1876 		{
1877 			GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR* ContentTypeDescr = (GF_M2TS_DSMCC_BIOP_CONTENT_TYPE_DESRIPTOR*)gf_list_get(list,0);
1878 			gf_list_rem(list,0);
1879 			if(ContentTypeDescr->descriptor_length) {
1880 				gf_free(ContentTypeDescr->content_type_data_byte);
1881 			}
1882 			gf_free(ContentTypeDescr);
1883 			break;
1884 		}
1885 		default:
1886 		{
1887 
1888 			break;
1889 		}
1890 		}
1891 
1892 	}
1893 	gf_list_del(list);
1894 }
1895 
1896 
dsmcc_free_biop_name(GF_M2TS_DSMCC_BIOP_NAME * Name,u32 nb_name)1897 static void dsmcc_free_biop_name(GF_M2TS_DSMCC_BIOP_NAME* Name, u32 nb_name) {
1898 	u32 i;
1899 
1900 	for(i =0; i<nb_name; i++) {
1901 
1902 		if(Name[i].id_length) {
1903 			gf_free(Name[i].id_data);
1904 		}
1905 		if(Name[i].kind_length) {
1906 			gf_free(Name[i].kind_data);
1907 		}
1908 		/* IOR */
1909 		dsmcc_free_biop_ior(&Name[i].IOR);
1910 		dsmcc_free_biop_descriptor(Name[i].descriptor);
1911 	}
1912 }
1913 
dsmcc_free_biop_context(GF_M2TS_DSMCC_SERVICE_CONTEXT * Context,u32 serviceContextList_count)1914 static void dsmcc_free_biop_context(GF_M2TS_DSMCC_SERVICE_CONTEXT* Context,u32 serviceContextList_count) {
1915 	u32 i;
1916 
1917 	for(i=0; i<serviceContextList_count; i++) {
1918 		if(Context[i].context_data_length != 0) {
1919 			gf_free(Context[i].context_data_byte);
1920 		}
1921 	}
1922 	gf_free(Context);
1923 }
1924 
1925 #endif //GPAC_ENABLE_DSMCC
1926