Mercurial > pt1.oyama
comparison arib25v023/arib25/src/arib_std_b25.c @ 3:6801fe7e04ff
updated to ariv25v023
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Tue, 17 Feb 2009 01:40:56 +0900 |
parents | arib25v021/arib25/src/arib_std_b25.c@67e8eca28a80 |
children |
comparison
equal
deleted
inserted
replaced
2:8ac7c59fefc9 | 3:6801fe7e04ff |
---|---|
1 #include <stdlib.h> | |
2 #include <string.h> | |
3 | |
4 #include "arib_std_b25.h" | |
5 #include "arib_std_b25_error_code.h" | |
6 #include "multi2.h" | |
7 #include "ts_common_types.h" | |
8 #include "ts_section_parser.h" | |
9 | |
10 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
11 inner structures | |
12 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
13 typedef struct { | |
14 int32_t pid; | |
15 int32_t type; | |
16 void *prev; | |
17 void *next; | |
18 } TS_STREAM_ELEM; | |
19 | |
20 typedef struct { | |
21 TS_STREAM_ELEM *head; | |
22 TS_STREAM_ELEM *tail; | |
23 int32_t count; | |
24 } TS_STREAM_LIST; | |
25 | |
26 typedef struct { | |
27 | |
28 uint8_t *pool; | |
29 uint8_t *head; | |
30 uint8_t *tail; | |
31 int32_t max; | |
32 | |
33 } TS_WORK_BUFFER; | |
34 | |
35 typedef struct { | |
36 | |
37 int32_t phase; | |
38 | |
39 int32_t program_number; | |
40 | |
41 int32_t pmt_pid; | |
42 TS_SECTION_PARSER *pmt; | |
43 | |
44 int32_t pcr_pid; | |
45 | |
46 TS_STREAM_LIST streams; | |
47 TS_STREAM_LIST old_strm; | |
48 | |
49 } TS_PROGRAM; | |
50 | |
51 typedef struct { | |
52 | |
53 int32_t ref; | |
54 int32_t phase; | |
55 | |
56 int32_t locked; | |
57 | |
58 int32_t ecm_pid; | |
59 TS_SECTION_PARSER *ecm; | |
60 | |
61 MULTI2 *m2; | |
62 | |
63 int32_t unpurchased; | |
64 int32_t last_error; | |
65 | |
66 void *prev; | |
67 void *next; | |
68 | |
69 } DECRYPTOR_ELEM; | |
70 | |
71 typedef struct { | |
72 DECRYPTOR_ELEM *head; | |
73 DECRYPTOR_ELEM *tail; | |
74 int32_t count; | |
75 } DECRYPTOR_LIST; | |
76 | |
77 typedef struct { | |
78 uint32_t ref; | |
79 uint32_t type; | |
80 int64_t normal_packet; | |
81 int64_t undecrypted; | |
82 void *target; | |
83 } PID_MAP; | |
84 | |
85 typedef struct { | |
86 | |
87 int32_t multi2_round; | |
88 int32_t strip; | |
89 int32_t emm_proc_on; | |
90 | |
91 int32_t unit_size; | |
92 | |
93 int32_t sbuf_offset; | |
94 | |
95 TS_SECTION_PARSER *pat; | |
96 TS_SECTION_PARSER *cat; | |
97 | |
98 TS_STREAM_LIST strm_pool; | |
99 | |
100 int32_t p_count; | |
101 TS_PROGRAM *program; | |
102 | |
103 DECRYPTOR_LIST decrypt; | |
104 | |
105 PID_MAP map[0x2000]; | |
106 | |
107 B_CAS_CARD *bcas; | |
108 B_CAS_ID casid; | |
109 int32_t ca_system_id; | |
110 | |
111 int32_t emm_pid; | |
112 TS_SECTION_PARSER *emm; | |
113 | |
114 TS_WORK_BUFFER sbuf; | |
115 TS_WORK_BUFFER dbuf; | |
116 | |
117 } ARIB_STD_B25_PRIVATE_DATA; | |
118 | |
119 typedef struct { | |
120 int64_t card_id; | |
121 int32_t associated_information_length; | |
122 int32_t protocol_number; | |
123 int32_t broadcaster_group_id; | |
124 int32_t update_number; | |
125 int32_t expiration_date; | |
126 } EMM_FIXED_PART; | |
127 | |
128 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
129 constant values | |
130 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
131 enum TS_STREAM_TYPE { | |
132 TS_STREAM_TYPE_11172_2_VIDEO = 0x01, | |
133 TS_STREAM_TYPE_13818_2_VIDEO = 0x02, | |
134 TS_STREAM_TYPE_11172_3_AUDIO = 0x03, | |
135 TS_STREAM_TYPE_13818_3_AUDIO = 0x04, | |
136 TS_STREAM_TYPE_13818_1_PRIVATE_SECTIONS = 0x05, | |
137 TS_STREAM_TYPE_13818_1_PES_PRIVATE_DATA = 0x06, | |
138 TS_STREAM_TYPE_13522_MHEG = 0x07, | |
139 TS_STREAM_TYPE_13818_1_DSM_CC = 0x08, | |
140 TS_STREAM_TYPE_H_222_1 = 0x09, | |
141 TS_STREAM_TYPE_13818_6_TYPE_A = 0x0a, | |
142 TS_STREAM_TYPE_13818_6_TYPE_B = 0x0b, | |
143 TS_STREAM_TYPE_13818_6_TYPE_C = 0x0c, | |
144 TS_STREAM_TYPE_13818_6_TYPE_D = 0x0d, | |
145 TS_STREAM_TYPE_13818_1_AUX = 0x0e, | |
146 TS_STREAM_TYPE_13818_7_AUDIO_ADTS = 0x0f, | |
147 TS_STREAM_TYPE_14496_2_VISUAL = 0x10, | |
148 TS_STREAM_TYPE_14496_3_AUDIO_LATM = 0x11, | |
149 TS_STREAM_TYPE_14496_1_PES_SL_PACKET = 0x12, | |
150 TS_STREAM_TYPE_14496_1_SECTIONS_SL_PACKET = 0x13, | |
151 TS_STREAM_TYPE_13818_6_SYNC_DWLOAD_PROTCOL = 0x14, | |
152 }; | |
153 | |
154 enum TS_SECTION_ID { | |
155 TS_SECTION_ID_PROGRAM_ASSOCIATION = 0x00, | |
156 TS_SECTION_ID_CONDITIONAL_ACCESS = 0x01, | |
157 TS_SECTION_ID_PROGRAM_MAP = 0x02, | |
158 TS_SECTION_ID_DESCRIPTION = 0x03, | |
159 TS_SECTION_ID_14496_SCENE_DESCRIPTION = 0x04, | |
160 TS_SECTION_ID_14496_OBJECT_DESCRIPTION = 0x05, | |
161 | |
162 /* ARIB STD-B10 stuff */ | |
163 TS_SECTION_ID_DSM_CC_HEAD = 0x3a, | |
164 TS_SECTION_ID_DSM_CC_TAIL = 0x3f, | |
165 TS_SECTION_ID_NIT_ACTUAL = 0x40, | |
166 TS_SECTION_ID_NIT_OTHER = 0x41, | |
167 TS_SECTION_ID_SDT_ACTUAL = 0x42, | |
168 TS_SECTION_ID_SDT_OTHER = 0x46, | |
169 TS_SECTION_ID_BAT = 0x4a, | |
170 TS_SECTION_ID_EIT_ACTUAL_CURRENT = 0x4e, | |
171 TS_SECTION_ID_EIT_OTHER_CURRENT = 0x4f, | |
172 TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_HEAD = 0x50, | |
173 TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_TAIL = 0x5f, | |
174 TS_SECTION_ID_EIT_OTHER_SCHEDULE_HEAD = 0x60, | |
175 TS_SECTION_ID_EIT_OTHER_SCHEDULE_TAIL = 0x6f, | |
176 TS_SECTION_ID_TDT = 0x70, | |
177 TS_SECTION_ID_RST = 0x71, | |
178 TS_SECTION_ID_ST = 0x72, | |
179 TS_SECTION_ID_TOT = 0x73, | |
180 TS_SECTION_ID_AIT = 0x74, | |
181 TS_SECTION_ID_DIT = 0x7e, | |
182 TS_SECTION_ID_SIT = 0x7f, | |
183 TS_SECTION_ID_ECM_S = 0x82, | |
184 TS_SECTION_ID_ECM = 0x83, | |
185 TS_SECTION_ID_EMM_S = 0x84, | |
186 TS_SECTION_ID_EMM_MESSAGE = 0x85, | |
187 TS_SECTION_ID_DCT = 0xc0, | |
188 TS_SECTION_ID_DLT = 0xc1, | |
189 TS_SECTION_ID_PCAT = 0xc2, | |
190 TS_SECTION_ID_SDTT = 0xc3, | |
191 TS_SECTION_ID_BIT = 0xc4, | |
192 TS_SECTION_ID_NBIT_BODY = 0xc5, | |
193 TS_SECTION_ID_NBIT_REFERENCE = 0xc6, | |
194 TS_SECTION_ID_LDT = 0xc7, | |
195 TS_SECTION_ID_CDT = 0xc8, | |
196 TS_SECTION_ID_LIT = 0xd0, | |
197 TS_SECTION_ID_ERT = 0xd1, | |
198 TS_SECTION_ID_ITT = 0xd2, | |
199 }; | |
200 | |
201 enum TS_DESCRIPTOR_TAG { | |
202 TS_DESCRIPTOR_TAG_VIDEO_STREAM = 0x02, | |
203 TS_DESCRIPTOR_TAG_AUDIO_STREAM = 0x03, | |
204 TS_DESCRIPTOR_TAG_HIERARCHY = 0x04, | |
205 TS_DESCRIPTOR_TAG_REGISTRATION = 0x05, | |
206 TS_DESCRIPTOR_TAG_DATA_STREAM_ALIGNMENT = 0x06, | |
207 TS_DESCRIPTOR_TAG_TARGET_BACKGROUND_GRID = 0x07, | |
208 TS_DESCRIPTOR_TAG_VIDEO_WINDOW = 0x08, | |
209 TS_DESCRIPTOR_TAG_CA = 0x09, | |
210 TS_DESCRIPTOR_TAG_ISO_639_LANGUAGE = 0x0a, | |
211 TS_DESCRIPTOR_TAG_SYSTEM_CLOCK = 0x0b, | |
212 TS_DESCRIPTOR_TAG_MULTIPLEX_BUF_UTILIZ = 0x0c, | |
213 TS_DESCRIPTOR_TAG_COPYRIGHT = 0x0d, | |
214 TS_DESCRIPTOR_TAG_MAXIMUM_BITRATE = 0x0e, | |
215 TS_DESCRIPTOR_TAG_PRIVATE_DATA_INDICATOR = 0x0f, | |
216 TS_DESCRIPTOR_TAG_SMOOTHING_BUFFER = 0x10, | |
217 TS_DESCRIPTOR_TAG_STD = 0x11, | |
218 TS_DESCRIPTOR_TAG_IBP = 0x12, | |
219 TS_DESCRIPTOR_TAG_MPEG4_VIDEO = 0x1b, | |
220 TS_DESCRIPTOR_TAG_MPEG4_AUDIO = 0x1c, | |
221 TS_DESCRIPTOR_TAG_IOD = 0x1d, | |
222 TS_DESCRIPTOR_TAG_SL = 0x1e, | |
223 TS_DESCRIPTOR_TAG_FMC = 0x1f, | |
224 TS_DESCRIPTOR_TAG_EXTERNAL_ES_ID = 0x20, | |
225 TS_DESCRIPTOR_TAG_MUXCODE = 0x21, | |
226 TS_DESCRIPTOR_TAG_FMX_BUFFER_SIZE = 0x22, | |
227 TS_DESCRIPTOR_TAG_MULTIPLEX_BUFFER = 0x23, | |
228 TS_DESCRIPTOR_TAG_AVC_VIDEO = 0x28, | |
229 TS_DESCRIPTOR_TAG_AVC_TIMING_HRD = 0x2a, | |
230 | |
231 /* ARIB STD-B10 stuff */ | |
232 TS_DESCRIPTOR_TAG_NETWORK_NAME = 0x40, | |
233 TS_DESCRIPTOR_TAG_SERVICE_LIST = 0x41, | |
234 TS_DESCRIPTOR_TAG_STUFFING = 0x42, | |
235 TS_DESCRIPTOR_TAG_SATELLITE_DELIVERY_SYS = 0x43, | |
236 TS_DESCRIPTOR_TAG_CABLE_DISTRIBUTION = 0x44, | |
237 TS_DESCRIPTOR_TAG_BOUNQUET_NAME = 0x47, | |
238 TS_DESCRIPTOR_TAG_SERVICE = 0x48, | |
239 TS_DESCRIPTOR_TAG_COUNTRY_AVAILABILITY = 0x49, | |
240 TS_DESCRIPTOR_TAG_LINKAGE = 0x4a, | |
241 TS_DESCRIPTOR_TAG_NVOD_REFERENCE = 0x4b, | |
242 TS_DESCRIPTOR_TAG_TIME_SHIFTED_SERVICE = 0x4c, | |
243 TS_DESCRIPTOR_TAG_SHORT_EVENT = 0x4d, | |
244 TS_DESCRIPTOR_TAG_EXTENDED_EVENT = 0x4e, | |
245 TS_DESCRIPTOR_TAG_TIME_SHIFTED_EVENT = 0x4f, | |
246 TS_DESCRIPTOR_TAG_COMPONENT = 0x50, | |
247 TS_DESCRIPTOR_TAG_MOSAIC = 0x51, | |
248 TS_DESCRIPTOR_TAG_STREAM_IDENTIFIER = 0x52, | |
249 TS_DESCRIPTOR_TAG_CA_IDENTIFIER = 0x53, | |
250 TS_DESCRIPTOR_TAG_CONTENT = 0x54, | |
251 TS_DESCRIPTOR_TAG_PARENTAL_RATING = 0x55, | |
252 TS_DESCRIPTOR_TAG_LOCAL_TIME_OFFSET = 0x58, | |
253 TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_STREAM = 0x63, | |
254 TS_DESCRIPTOR_TAG_HIERARCHICAL_TRANSMISSION = 0xc0, | |
255 TS_DESCRIPTOR_TAG_DIGITAL_COPY_CONTROL = 0xc1, | |
256 TS_DESCRIPTOR_TAG_NETWORK_IDENTIFICATION = 0xc2, | |
257 TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_TIME = 0xc3, | |
258 TS_DESCRIPTOR_TAG_AUDIO_COMPONENT = 0xc4, | |
259 TS_DESCRIPTOR_TAG_HYPERLINK = 0xc5, | |
260 TS_DESCRIPTOR_TAG_TARGET_REGION = 0xc6, | |
261 TS_DESCRIPTOR_TAG_DATA_COTENT = 0xc7, | |
262 TS_DESCRIPTOR_TAG_VIDEO_DECODE_CONTROL = 0xc8, | |
263 TS_DESCRIPTOR_TAG_DOWNLOAD_CONTENT = 0xc9, | |
264 TS_DESCRIPTOR_TAG_CA_EMM_TS = 0xca, | |
265 TS_DESCRIPTOR_TAG_CA_CONTRACT_INFORMATION = 0xcb, | |
266 TS_DESCRIPTOR_TAG_CA_SERVICE = 0xcc, | |
267 TS_DESCRIPTOR_TAG_TS_INFORMATION = 0xcd, | |
268 TS_DESCRIPTOR_TAG_EXTENDED_BROADCASTER = 0xce, | |
269 TS_DESCRIPTOR_TAG_LOGO_TRANSMISSION = 0xcf, | |
270 TS_DESCRIPTOR_TAG_BASIC_LOCAL_EVENT = 0xd0, | |
271 TS_DESCRIPTOR_TAG_REFERENCE = 0xd1, | |
272 TS_DESCRIPTOR_TAG_NODE_RELATION = 0xd2, | |
273 TS_DESCRIPTOR_TAG_SHORT_NODE_INFORMATION = 0xd3, | |
274 TS_DESCRIPTOR_TAG_STC_REFERENCE = 0xd4, | |
275 TS_DESCRIPTOR_TAG_SERIES = 0xd5, | |
276 TS_DESCRIPTOR_TAG_EVENT_GROUP = 0xd6, | |
277 TS_DESCRIPTOR_TAG_SI_PARAMETER = 0xd7, | |
278 TS_DESCRIPTOR_TAG_BROADCASTER_NAME = 0xd8, | |
279 TS_DESCRIPTOR_TAG_COMPONENT_GROUP = 0xd9, | |
280 TS_DESCRIPTOR_TAG_SI_PRIME_TS = 0xda, | |
281 TS_DESCRIPTOR_TAG_BOARD_INFORMATION = 0xdb, | |
282 TS_DESCRIPTOR_TAG_LDT_LINKAGE = 0xdc, | |
283 TS_DESCRIPTOR_TAG_CONNECTED_TRANSMISSION = 0xdd, | |
284 TS_DESCRIPTOR_TAG_CONTENT_AVAILABILITY = 0xde, | |
285 TS_DESCRIPTOR_TAG_VALUE_EXTENSION = 0xdf, | |
286 TS_DESCRIPTOR_TAG_SERVICE_GROUP = 0xe0, | |
287 TS_DESCRIPTOR_TAG_CARUSEL_COMPOSITE = 0xf7, | |
288 TS_DESCRIPTOR_TAG_CONDITIONAL_PLAYBACK = 0xf8, | |
289 TS_DESCRIPTOR_TAG_CABLE_TS_DIVISSION = 0xf9, | |
290 TS_DESCRIPTOR_TAG_TERRESTRIAL_DELIVERY_SYS = 0xfa, | |
291 TS_DESCRIPTOR_TAG_PARTIAL_RECEPTION = 0xfb, | |
292 TS_DESCRIPTOR_TAG_EMERGENCY_INFOMATION = 0xfc, | |
293 TS_DESCRIPTOR_TAG_DATA_COMPONENT = 0xfd, | |
294 TS_DESCRIPTOR_TAG_SYSTEM_MANAGEMENT = 0xfe, | |
295 }; | |
296 | |
297 enum PID_MAP_TYPE { | |
298 PID_MAP_TYPE_UNKNOWN = 0x0000, | |
299 PID_MAP_TYPE_PAT = 0x0100, | |
300 PID_MAP_TYPE_PMT = 0x0200, | |
301 PID_MAP_TYPE_NIT = 0x0300, | |
302 PID_MAP_TYPE_PCR = 0x0400, | |
303 PID_MAP_TYPE_ECM = 0x0500, | |
304 PID_MAP_TYPE_EMM = 0x0600, | |
305 PID_MAP_TYPE_EIT = 0x0700, | |
306 PID_MAP_TYPE_CAT = 0x0800, | |
307 PID_MAP_TYPE_OTHER = 0xff00, | |
308 }; | |
309 | |
310 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
311 function prottypes (interface method) | |
312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
313 static void release_arib_std_b25(void *std_b25); | |
314 static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round); | |
315 static int set_strip_arib_std_b25(void *std_b25, int32_t strip); | |
316 static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on); | |
317 static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas); | |
318 static int reset_arib_std_b25(void *std_b25); | |
319 static int flush_arib_std_b25(void *std_b25); | |
320 static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf); | |
321 static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf); | |
322 static int get_program_count_arib_std_b25(void *std_b25); | |
323 static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx); | |
324 | |
325 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
326 global function implementation | |
327 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
328 ARIB_STD_B25 *create_arib_std_b25() | |
329 { | |
330 int n; | |
331 | |
332 ARIB_STD_B25 *r; | |
333 ARIB_STD_B25_PRIVATE_DATA *prv; | |
334 | |
335 n = sizeof(ARIB_STD_B25_PRIVATE_DATA); | |
336 n += sizeof(ARIB_STD_B25); | |
337 | |
338 prv = (ARIB_STD_B25_PRIVATE_DATA *)calloc(1, n); | |
339 if(prv == NULL){ | |
340 return NULL; | |
341 } | |
342 | |
343 prv->multi2_round = 4; | |
344 | |
345 r = (ARIB_STD_B25 *)(prv+1); | |
346 r->private_data = prv; | |
347 | |
348 r->release = release_arib_std_b25; | |
349 r->set_multi2_round = set_multi2_round_arib_std_b25; | |
350 r->set_strip = set_strip_arib_std_b25; | |
351 r->set_emm_proc = set_emm_proc_arib_std_b25; | |
352 r->set_b_cas_card = set_b_cas_card_arib_std_b25; | |
353 r->reset = reset_arib_std_b25; | |
354 r->flush = flush_arib_std_b25; | |
355 r->put = put_arib_std_b25; | |
356 r->get = get_arib_std_b25; | |
357 r->get_program_count = get_program_count_arib_std_b25; | |
358 r->get_program_info = get_program_info_arib_std_b25; | |
359 | |
360 return r; | |
361 } | |
362 | |
363 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
364 function prottypes (private method) | |
365 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
366 static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25); | |
367 static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv); | |
368 static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv); | |
369 static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv); | |
370 static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv); | |
371 static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv); | |
372 static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv); | |
373 static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm); | |
374 static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail, int32_t ca_system_id); | |
375 static int32_t add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid); | |
376 static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv); | |
377 static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv); | |
378 static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round); | |
379 static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv); | |
380 | |
381 static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv); | |
382 static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv); | |
383 | |
384 static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm); | |
385 | |
386 static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid); | |
387 | |
388 static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid); | |
389 static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec); | |
390 static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid); | |
391 static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec); | |
392 static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv); | |
393 | |
394 static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list); | |
395 static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid); | |
396 static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type); | |
397 static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem); | |
398 static void clear_stream_list(TS_STREAM_LIST *list); | |
399 | |
400 static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size); | |
401 static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size); | |
402 static void reset_work_buffer(TS_WORK_BUFFER *buf); | |
403 static void release_work_buffer(TS_WORK_BUFFER *buf); | |
404 | |
405 static void extract_ts_header(TS_HEADER *dst, uint8_t *src); | |
406 static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src); | |
407 | |
408 static uint8_t *resync(uint8_t *head, uint8_t *tail, int32_t unit); | |
409 static uint8_t *resync_force(uint8_t *head, uint8_t *tail, int32_t unit); | |
410 | |
411 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
412 interface method implementation | |
413 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
414 static void release_arib_std_b25(void *std_b25) | |
415 { | |
416 ARIB_STD_B25_PRIVATE_DATA *prv; | |
417 | |
418 prv = private_data(std_b25); | |
419 if(prv == NULL){ | |
420 return; | |
421 } | |
422 | |
423 teardown(prv); | |
424 free(prv); | |
425 } | |
426 | |
427 static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round) | |
428 { | |
429 ARIB_STD_B25_PRIVATE_DATA *prv; | |
430 | |
431 prv = private_data(std_b25); | |
432 if(prv == NULL){ | |
433 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
434 } | |
435 | |
436 prv->multi2_round = round; | |
437 | |
438 return 0; | |
439 } | |
440 | |
441 static int set_strip_arib_std_b25(void *std_b25, int32_t strip) | |
442 { | |
443 ARIB_STD_B25_PRIVATE_DATA *prv; | |
444 | |
445 prv = private_data(std_b25); | |
446 if(prv == NULL){ | |
447 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
448 } | |
449 | |
450 prv->strip = strip; | |
451 | |
452 return 0; | |
453 } | |
454 | |
455 static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on) | |
456 { | |
457 ARIB_STD_B25_PRIVATE_DATA *prv; | |
458 | |
459 prv = private_data(std_b25); | |
460 if(prv == NULL){ | |
461 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
462 } | |
463 | |
464 prv->emm_proc_on = on; | |
465 | |
466 return 0; | |
467 } | |
468 | |
469 static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas) | |
470 { | |
471 int n; | |
472 B_CAS_INIT_STATUS is; | |
473 ARIB_STD_B25_PRIVATE_DATA *prv; | |
474 | |
475 prv = private_data(std_b25); | |
476 if(prv == NULL){ | |
477 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
478 } | |
479 | |
480 prv->bcas = bcas; | |
481 if(prv->bcas != NULL){ | |
482 n = prv->bcas->get_init_status(bcas, &is); | |
483 if(n < 0){ | |
484 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS; | |
485 } | |
486 prv->ca_system_id = is.ca_system_id; | |
487 n = prv->bcas->get_id(prv->bcas, &(prv->casid)); | |
488 if(n < 0){ | |
489 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS; | |
490 } | |
491 } | |
492 | |
493 return 0; | |
494 } | |
495 | |
496 static int reset_arib_std_b25(void *std_b25) | |
497 { | |
498 ARIB_STD_B25_PRIVATE_DATA *prv; | |
499 | |
500 prv = private_data(std_b25); | |
501 if(prv == NULL){ | |
502 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
503 } | |
504 | |
505 teardown(prv); | |
506 | |
507 return 0; | |
508 } | |
509 | |
510 static int flush_arib_std_b25(void *std_b25) | |
511 { | |
512 int r; | |
513 int m,n; | |
514 | |
515 int32_t crypt; | |
516 int32_t unit; | |
517 int32_t pid; | |
518 | |
519 uint8_t *p; | |
520 uint8_t *curr; | |
521 uint8_t *tail; | |
522 | |
523 TS_HEADER hdr; | |
524 DECRYPTOR_ELEM *dec; | |
525 TS_PROGRAM *pgrm; | |
526 | |
527 ARIB_STD_B25_PRIVATE_DATA *prv; | |
528 | |
529 prv = private_data(std_b25); | |
530 if(prv == NULL){ | |
531 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
532 } | |
533 | |
534 if(prv->unit_size < 188){ | |
535 r = select_unit_size(prv); | |
536 if(r < 0){ | |
537 return r; | |
538 } | |
539 } | |
540 | |
541 r = proc_arib_std_b25(prv); | |
542 if(r < 0){ | |
543 return r; | |
544 } | |
545 | |
546 unit = prv->unit_size; | |
547 curr = prv->sbuf.head; | |
548 tail = prv->sbuf.tail; | |
549 | |
550 m = prv->dbuf.tail - prv->dbuf.head; | |
551 n = tail - curr; | |
552 if(!reserve_work_buffer(&(prv->dbuf), m+n)){ | |
553 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
554 } | |
555 | |
556 r = 0; | |
557 | |
558 while( (curr+188) <= tail ){ | |
559 | |
560 if(curr[0] != 0x47){ | |
561 p = resync_force(curr, tail, unit); | |
562 if(p == NULL){ | |
563 goto LAST; | |
564 } | |
565 curr = p; | |
566 } | |
567 | |
568 extract_ts_header(&hdr, curr); | |
569 crypt = hdr.transport_scrambling_control; | |
570 pid = hdr.pid; | |
571 | |
572 if( (pid == 0x1fff) && (prv->strip) ){ | |
573 goto NEXT; | |
574 } | |
575 | |
576 p = curr+4; | |
577 if(hdr.adaptation_field_control & 0x02){ | |
578 p += (p[0]+1); | |
579 } | |
580 n = 188 - (p-curr); | |
581 if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){ | |
582 /* broken packet */ | |
583 curr += 1; | |
584 continue; | |
585 } | |
586 | |
587 if( (crypt != 0) && | |
588 (hdr.adaptation_field_control & 0x01) ){ | |
589 | |
590 if(prv->map[pid].type == PID_MAP_TYPE_OTHER){ | |
591 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
592 }else{ | |
593 dec = NULL; | |
594 } | |
595 | |
596 if( (dec != NULL) && (dec->m2 != NULL) ){ | |
597 m = dec->m2->decrypt(dec->m2, crypt, p, n); | |
598 if(m < 0){ | |
599 r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE; | |
600 goto LAST; | |
601 } | |
602 curr[3] &= 0x3f; | |
603 prv->map[pid].normal_packet += 1; | |
604 }else{ | |
605 prv->map[pid].undecrypted += 1; | |
606 } | |
607 }else{ | |
608 prv->map[pid].normal_packet += 1; | |
609 } | |
610 | |
611 if(!append_work_buffer(&(prv->dbuf), curr, 188)){ | |
612 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
613 goto LAST; | |
614 } | |
615 | |
616 if(prv->map[pid].type == PID_MAP_TYPE_ECM){ | |
617 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
618 if( (dec == NULL) || (dec->ecm == NULL) ){ | |
619 /* this code will never execute */ | |
620 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
621 goto LAST; | |
622 } | |
623 m = dec->ecm->put(dec->ecm, &hdr, p, n); | |
624 if(m < 0){ | |
625 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
626 goto LAST; | |
627 } | |
628 m = dec->ecm->get_count(dec->ecm); | |
629 if(m < 0){ | |
630 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
631 goto LAST; | |
632 } | |
633 if(m == 0){ | |
634 goto NEXT; | |
635 } | |
636 r = proc_ecm(dec, prv->bcas, prv->multi2_round); | |
637 if(r < 0){ | |
638 goto LAST; | |
639 } | |
640 }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){ | |
641 pgrm = (TS_PROGRAM *)(prv->map[pid].target); | |
642 if( (pgrm == NULL) || (pgrm->pmt == NULL) ){ | |
643 /* this code will never execute */ | |
644 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
645 goto LAST; | |
646 } | |
647 m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n); | |
648 if(m < 0){ | |
649 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
650 goto LAST; | |
651 } | |
652 m = pgrm->pmt->get_count(pgrm->pmt); | |
653 if(m < 0){ | |
654 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
655 goto LAST; | |
656 } | |
657 if(m == 0){ | |
658 goto NEXT; | |
659 } | |
660 r = proc_pmt(prv, pgrm); | |
661 if(r < 0){ | |
662 goto LAST; | |
663 } | |
664 }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){ | |
665 if( prv->emm_proc_on == 0){ | |
666 goto NEXT; | |
667 } | |
668 if( prv->emm == NULL ){ | |
669 prv->emm = create_ts_section_parser(); | |
670 if(prv->emm == NULL){ | |
671 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
672 goto LAST; | |
673 } | |
674 } | |
675 m = prv->emm->put(prv->emm, &hdr, p, n); | |
676 if(m < 0){ | |
677 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
678 goto LAST; | |
679 } | |
680 m = prv->emm->get_count(prv->emm); | |
681 if(m < 0){ | |
682 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
683 goto LAST; | |
684 } | |
685 if(m == 0){ | |
686 goto NEXT; | |
687 } | |
688 r = proc_emm(prv); | |
689 if(r < 0){ | |
690 goto LAST; | |
691 } | |
692 }else if(pid == 0x0001){ | |
693 if( prv->cat == NULL ){ | |
694 prv->cat = create_ts_section_parser(); | |
695 if(prv->cat == NULL){ | |
696 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
697 goto LAST; | |
698 } | |
699 } | |
700 m = prv->cat->put(prv->cat, &hdr, p, n); | |
701 if(m < 0){ | |
702 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
703 goto LAST; | |
704 } | |
705 m = prv->cat->get_count(prv->cat); | |
706 if(m < 0){ | |
707 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
708 goto LAST; | |
709 } | |
710 if(m == 0){ | |
711 goto NEXT; | |
712 } | |
713 r = proc_cat(prv); | |
714 if(r < 0){ | |
715 goto LAST; | |
716 } | |
717 }else if(pid == 0x0000){ | |
718 if( prv->pat == NULL ){ | |
719 prv->pat = create_ts_section_parser(); | |
720 if(prv->pat == NULL){ | |
721 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
722 goto LAST; | |
723 } | |
724 } | |
725 m = prv->pat->put(prv->pat, &hdr, p, n); | |
726 if(m < 0){ | |
727 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
728 goto LAST; | |
729 } | |
730 m = prv->pat->get_count(prv->pat); | |
731 if(m < 0){ | |
732 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
733 goto LAST; | |
734 } | |
735 if(m == 0){ | |
736 goto NEXT; | |
737 } | |
738 r = proc_pat(prv); | |
739 if(r < 0){ | |
740 goto LAST; | |
741 } | |
742 } | |
743 | |
744 NEXT: | |
745 curr += unit; | |
746 } | |
747 | |
748 LAST: | |
749 | |
750 m = curr - prv->sbuf.head; | |
751 n = tail - curr; | |
752 if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){ | |
753 p = prv->sbuf.pool; | |
754 memcpy(p, curr, n); | |
755 prv->sbuf.head = p; | |
756 prv->sbuf.tail = p+n; | |
757 }else{ | |
758 prv->sbuf.head = curr; | |
759 } | |
760 | |
761 return r; | |
762 } | |
763 | |
764 static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf) | |
765 { | |
766 int32_t n; | |
767 | |
768 ARIB_STD_B25_PRIVATE_DATA *prv; | |
769 | |
770 prv = private_data(std_b25); | |
771 if( (prv == NULL) || (buf == NULL) ){ | |
772 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
773 } | |
774 | |
775 if(!append_work_buffer(&(prv->sbuf), buf->data, buf->size)){ | |
776 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
777 } | |
778 | |
779 if(prv->unit_size < 188){ | |
780 n = select_unit_size(prv); | |
781 if(n < 0){ | |
782 return n; | |
783 } | |
784 if(prv->unit_size < 188){ | |
785 /* need more data */ | |
786 return 0; | |
787 } | |
788 } | |
789 | |
790 if(prv->p_count < 1){ | |
791 n = find_pat(prv); | |
792 if(n < 0){ | |
793 return n; | |
794 } | |
795 if(prv->p_count < 1){ | |
796 if(prv->sbuf_offset < (16*1024*1024)){ | |
797 /* need more data */ | |
798 return 0; | |
799 }else{ | |
800 /* exceed sbuf limit */ | |
801 return ARIB_STD_B25_ERROR_NO_PAT_IN_HEAD_16M; | |
802 } | |
803 } | |
804 prv->sbuf_offset = 0; | |
805 } | |
806 | |
807 if(!check_pmt_complete(prv)){ | |
808 n = find_pmt(prv); | |
809 if(n < 0){ | |
810 return n; | |
811 } | |
812 if(!check_pmt_complete(prv)){ | |
813 if(prv->sbuf_offset < (32*1024*1024)){ | |
814 /* need more data */ | |
815 return 0; | |
816 }else{ | |
817 /* exceed sbuf limit */ | |
818 return ARIB_STD_B25_ERROR_NO_PMT_IN_HEAD_32M; | |
819 } | |
820 } | |
821 prv->sbuf_offset = 0; | |
822 } | |
823 | |
824 if(!check_ecm_complete(prv)){ | |
825 n = find_ecm(prv); | |
826 if(n < 0){ | |
827 return n; | |
828 } | |
829 if(!check_ecm_complete(prv)){ | |
830 if(prv->sbuf_offset < (32*1024*1024)){ | |
831 /* need more data */ | |
832 return 0; | |
833 }else{ | |
834 /* exceed sbuf limit */ | |
835 return ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M; | |
836 } | |
837 } | |
838 prv->sbuf_offset = 0; | |
839 } | |
840 | |
841 return proc_arib_std_b25(prv); | |
842 } | |
843 | |
844 static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf) | |
845 { | |
846 ARIB_STD_B25_PRIVATE_DATA *prv; | |
847 prv = private_data(std_b25); | |
848 if( (prv == NULL) || (buf == NULL) ){ | |
849 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
850 } | |
851 | |
852 buf->data = prv->dbuf.head; | |
853 buf->size = prv->dbuf.tail - prv->dbuf.head; | |
854 | |
855 reset_work_buffer(&(prv->dbuf)); | |
856 | |
857 return 0; | |
858 } | |
859 | |
860 static int get_program_count_arib_std_b25(void *std_b25) | |
861 { | |
862 ARIB_STD_B25_PRIVATE_DATA *prv; | |
863 | |
864 prv = private_data(std_b25); | |
865 if(prv == NULL){ | |
866 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
867 } | |
868 | |
869 return prv->p_count; | |
870 } | |
871 | |
872 static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx) | |
873 { | |
874 ARIB_STD_B25_PRIVATE_DATA *prv; | |
875 | |
876 TS_PROGRAM *pgrm; | |
877 | |
878 TS_STREAM_ELEM *strm; | |
879 DECRYPTOR_ELEM *dec; | |
880 | |
881 int32_t pid; | |
882 | |
883 prv = private_data(std_b25); | |
884 if( (prv == NULL) || (info == NULL) || (idx < 0) || (idx >= prv->p_count) ){ | |
885 return ARIB_STD_B25_ERROR_INVALID_PARAM; | |
886 } | |
887 | |
888 pgrm = prv->program + idx; | |
889 | |
890 memset(info, 0, sizeof(ARIB_STD_B25_PROGRAM_INFO)); | |
891 | |
892 info->program_number = pgrm->program_number; | |
893 | |
894 pid = pgrm->pmt_pid; | |
895 info->total_packet_count += prv->map[pid].normal_packet; | |
896 info->total_packet_count += prv->map[pid].undecrypted; | |
897 info->undecrypted_packet_count += prv->map[pid].undecrypted; | |
898 | |
899 pid = pgrm->pcr_pid; | |
900 if( (pid != 0) && (pid != 0x1fff) ){ | |
901 info->total_packet_count += prv->map[pid].normal_packet; | |
902 info->total_packet_count += prv->map[pid].undecrypted; | |
903 info->undecrypted_packet_count += prv->map[pid].undecrypted; | |
904 } | |
905 | |
906 strm = pgrm->streams.head; | |
907 while(strm != NULL){ | |
908 pid = strm->pid; | |
909 if(prv->map[pid].type == PID_MAP_TYPE_ECM){ | |
910 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
911 info->ecm_unpurchased_count += dec->unpurchased; | |
912 info->last_ecm_error_code = dec->last_error; | |
913 } | |
914 info->total_packet_count += prv->map[pid].normal_packet; | |
915 info->total_packet_count += prv->map[pid].undecrypted; | |
916 info->undecrypted_packet_count += prv->map[pid].undecrypted; | |
917 strm = (TS_STREAM_ELEM *)(strm->next); | |
918 } | |
919 | |
920 return 0; | |
921 } | |
922 | |
923 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | |
924 private method implementation | |
925 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ | |
926 static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25) | |
927 { | |
928 ARIB_STD_B25 *p; | |
929 ARIB_STD_B25_PRIVATE_DATA *r; | |
930 | |
931 p = (ARIB_STD_B25 *)std_b25; | |
932 if(p == NULL){ | |
933 return NULL; | |
934 } | |
935 | |
936 r = (ARIB_STD_B25_PRIVATE_DATA *)p->private_data; | |
937 if( ((void *)(r+1)) != ((void *)p) ){ | |
938 return NULL; | |
939 } | |
940 | |
941 return r; | |
942 } | |
943 | |
944 static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv) | |
945 { | |
946 int i; | |
947 | |
948 prv->unit_size = 0; | |
949 prv->sbuf_offset = 0; | |
950 | |
951 if(prv->pat != NULL){ | |
952 prv->pat->release(prv->pat); | |
953 prv->pat = NULL; | |
954 } | |
955 if(prv->cat != NULL){ | |
956 prv->cat->release(prv->cat); | |
957 prv->cat = NULL; | |
958 } | |
959 | |
960 if(prv->program != NULL){ | |
961 for(i=0;i<prv->p_count;i++){ | |
962 release_program(prv, prv->program+i); | |
963 } | |
964 free(prv->program); | |
965 prv->program = NULL; | |
966 } | |
967 prv->p_count = 0; | |
968 | |
969 clear_stream_list(&(prv->strm_pool)); | |
970 | |
971 while(prv->decrypt.head != NULL){ | |
972 remove_decryptor(prv, prv->decrypt.head); | |
973 } | |
974 | |
975 memset(prv->map, 0, sizeof(prv->map)); | |
976 | |
977 prv->emm_pid = 0; | |
978 if(prv->emm != NULL){ | |
979 prv->emm->release(prv->emm); | |
980 prv->emm = NULL; | |
981 } | |
982 | |
983 release_work_buffer(&(prv->sbuf)); | |
984 release_work_buffer(&(prv->dbuf)); | |
985 } | |
986 | |
987 static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv) | |
988 { | |
989 int i; | |
990 int m,n,w; | |
991 int count[320-188]; | |
992 | |
993 unsigned char *head; | |
994 unsigned char *buf; | |
995 unsigned char *tail; | |
996 | |
997 head = prv->sbuf.head; | |
998 tail = prv->sbuf.tail; | |
999 | |
1000 buf = head; | |
1001 memset(count, 0, sizeof(count)); | |
1002 | |
1003 // 1st step, count up 0x47 interval | |
1004 while( (buf+188) < tail ){ | |
1005 if(buf[0] != 0x47){ | |
1006 buf += 1; | |
1007 continue; | |
1008 } | |
1009 m = 320; | |
1010 if( buf+m > tail ){ | |
1011 m = tail-buf; | |
1012 } | |
1013 for(i=188;i<m;i++){ | |
1014 if(buf[i] == 0x47){ | |
1015 count[i-188] += 1; | |
1016 } | |
1017 } | |
1018 buf += 1; | |
1019 } | |
1020 | |
1021 // 2nd step, select maximum appeared interval | |
1022 m = 0; | |
1023 n = 0; | |
1024 for(i=188;i<320;i++){ | |
1025 if(m < count[i-188]){ | |
1026 m = count[i-188]; | |
1027 n = i; | |
1028 } | |
1029 } | |
1030 | |
1031 // 3rd step, verify unit_size | |
1032 w = m*n; | |
1033 if( (m < 8) || ((w+3*n) < (tail-head)) ){ | |
1034 return ARIB_STD_B25_ERROR_NON_TS_INPUT_STREAM; | |
1035 } | |
1036 | |
1037 prv->unit_size = n; | |
1038 | |
1039 return 0; | |
1040 } | |
1041 | |
1042 static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1043 { | |
1044 int r; | |
1045 int n,size; | |
1046 | |
1047 int32_t unit; | |
1048 | |
1049 uint8_t *p; | |
1050 uint8_t *curr; | |
1051 uint8_t *tail; | |
1052 | |
1053 TS_HEADER hdr; | |
1054 | |
1055 r = 0; | |
1056 unit = prv->unit_size; | |
1057 curr = prv->sbuf.head + prv->sbuf_offset; | |
1058 tail = prv->sbuf.tail; | |
1059 | |
1060 while( (curr+unit) < tail ){ | |
1061 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ | |
1062 p = resync(curr, tail, unit); | |
1063 if(p == NULL){ | |
1064 goto LAST; | |
1065 } | |
1066 curr = p; | |
1067 } | |
1068 extract_ts_header(&hdr, curr); | |
1069 if(hdr.pid == 0x0000){ | |
1070 | |
1071 p = curr+4; | |
1072 if(hdr.adaptation_field_control & 0x02){ | |
1073 p += (p[0]+1); | |
1074 } | |
1075 size = 188 - (p-curr); | |
1076 if(size < 1){ | |
1077 goto NEXT; | |
1078 } | |
1079 | |
1080 if(prv->pat == NULL){ | |
1081 prv->pat = create_ts_section_parser(); | |
1082 if(prv->pat == NULL){ | |
1083 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1084 } | |
1085 } | |
1086 | |
1087 n = prv->pat->put(prv->pat, &hdr, p, size); | |
1088 if(n < 0){ | |
1089 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1090 curr += unit; | |
1091 goto LAST; | |
1092 } | |
1093 n = prv->pat->get_count(prv->pat); | |
1094 if(n < 0){ | |
1095 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1096 curr += unit; | |
1097 goto LAST; | |
1098 } | |
1099 if(n > 0){ | |
1100 curr += unit; | |
1101 goto LAST; | |
1102 } | |
1103 } | |
1104 NEXT: | |
1105 curr += unit; | |
1106 } | |
1107 | |
1108 LAST: | |
1109 prv->sbuf_offset = curr - prv->sbuf.head; | |
1110 | |
1111 if( (prv->pat != NULL) && (prv->pat->get_count(prv->pat) > 0) ){ | |
1112 r = proc_pat(prv); | |
1113 } | |
1114 | |
1115 return r; | |
1116 } | |
1117 | |
1118 static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1119 { | |
1120 int r; | |
1121 int i,n; | |
1122 int len; | |
1123 int count; | |
1124 | |
1125 int32_t program_number; | |
1126 int32_t pid; | |
1127 | |
1128 uint8_t *head; | |
1129 uint8_t *tail; | |
1130 | |
1131 TS_PROGRAM *work; | |
1132 TS_SECTION sect; | |
1133 | |
1134 r = 0; | |
1135 memset(§, 0, sizeof(sect)); | |
1136 | |
1137 n = prv->pat->get(prv->pat, §); | |
1138 if(n < 0){ | |
1139 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1140 goto LAST; | |
1141 } | |
1142 | |
1143 if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_ASSOCIATION){ | |
1144 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; | |
1145 goto LAST; | |
1146 } | |
1147 | |
1148 len = (sect.tail - sect.data) - 4; | |
1149 | |
1150 count = len / 4; | |
1151 work = (TS_PROGRAM *)calloc(count, sizeof(TS_PROGRAM)); | |
1152 if(work == NULL){ | |
1153 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1154 goto LAST; | |
1155 } | |
1156 | |
1157 if(prv->program != NULL){ | |
1158 for(i=0;i<prv->p_count;i++){ | |
1159 release_program(prv, prv->program+i); | |
1160 } | |
1161 free(prv->program); | |
1162 prv->program = NULL; | |
1163 } | |
1164 prv->p_count = 0; | |
1165 memset(&(prv->map), 0, sizeof(prv->map)); | |
1166 | |
1167 head = sect.data; | |
1168 tail = sect.tail-4; | |
1169 | |
1170 i = 0; | |
1171 while( (head+4) <= tail ){ | |
1172 program_number = ((head[0] << 8) | head[1]); | |
1173 pid = ((head[2] << 8) | head[3]) & 0x1fff; | |
1174 if(program_number != 0){ | |
1175 work[i].program_number = program_number; | |
1176 work[i].pmt_pid = pid; | |
1177 work[i].pmt = create_ts_section_parser(); | |
1178 if(work[i].pmt == NULL){ | |
1179 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1180 break; | |
1181 } | |
1182 prv->map[pid].type = PID_MAP_TYPE_PMT; | |
1183 prv->map[pid].target = work+i; | |
1184 i += 1; | |
1185 } | |
1186 head += 4; | |
1187 } | |
1188 | |
1189 prv->program = work; | |
1190 prv->p_count = i; | |
1191 | |
1192 prv->map[0x0000].ref = 1; | |
1193 prv->map[0x0000].type = PID_MAP_TYPE_PAT; | |
1194 prv->map[0x0000].target = NULL; | |
1195 | |
1196 LAST: | |
1197 if(sect.raw != NULL){ | |
1198 n = prv->pat->ret(prv->pat, §); | |
1199 if( (n < 0) && (r == 0) ){ | |
1200 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1201 } | |
1202 } | |
1203 | |
1204 return r; | |
1205 } | |
1206 | |
1207 static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1208 { | |
1209 int i,n; | |
1210 int num[3]; | |
1211 | |
1212 memset(num, 0, sizeof(num)); | |
1213 | |
1214 for(i=0;i<prv->p_count;i++){ | |
1215 n = prv->program[i].phase; | |
1216 if(n < 0){ | |
1217 n = 0; | |
1218 }else if(n > 2){ | |
1219 n = 2; | |
1220 } | |
1221 num[n] += 1; | |
1222 } | |
1223 | |
1224 if(num[2] > 0){ | |
1225 return 1; | |
1226 } | |
1227 | |
1228 if(num[0] > 0){ | |
1229 return 0; | |
1230 } | |
1231 | |
1232 return 1; | |
1233 } | |
1234 | |
1235 static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1236 { | |
1237 int r; | |
1238 int n,size; | |
1239 | |
1240 int32_t unit; | |
1241 | |
1242 uint8_t *p; | |
1243 uint8_t *curr; | |
1244 uint8_t *tail; | |
1245 | |
1246 TS_HEADER hdr; | |
1247 TS_PROGRAM *pgrm; | |
1248 | |
1249 r = 0; | |
1250 unit = prv->unit_size; | |
1251 curr = prv->sbuf.head + prv->sbuf_offset; | |
1252 tail = prv->sbuf.tail; | |
1253 | |
1254 while( (curr+unit) < tail ){ | |
1255 | |
1256 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ | |
1257 p = resync(curr, tail, unit); | |
1258 if(p == NULL){ | |
1259 goto LAST; | |
1260 } | |
1261 curr = p; | |
1262 } | |
1263 | |
1264 extract_ts_header(&hdr, curr); | |
1265 | |
1266 if(prv->map[hdr.pid].type != PID_MAP_TYPE_PMT){ | |
1267 goto NEXT; | |
1268 } | |
1269 pgrm = (TS_PROGRAM *)(prv->map[hdr.pid].target); | |
1270 if(pgrm == NULL){ | |
1271 goto NEXT; | |
1272 } | |
1273 | |
1274 if(pgrm->phase == 0){ | |
1275 | |
1276 p = curr + 4; | |
1277 if(hdr.adaptation_field_control & 0x02){ | |
1278 p += (p[0]+1); | |
1279 } | |
1280 size = 188 - (p-curr); | |
1281 if(size < 1){ | |
1282 goto NEXT; | |
1283 } | |
1284 | |
1285 if(pgrm->pmt == NULL){ | |
1286 /* this code will never execute */ | |
1287 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1288 curr += unit; | |
1289 goto LAST; | |
1290 } | |
1291 | |
1292 n = pgrm->pmt->put(pgrm->pmt, &hdr, p, size); | |
1293 if(n < 0){ | |
1294 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1295 curr += unit; | |
1296 goto LAST; | |
1297 } | |
1298 n = pgrm->pmt->get_count(pgrm->pmt); | |
1299 if(n < 0){ | |
1300 r =ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1301 curr += unit; | |
1302 goto LAST; | |
1303 } | |
1304 if(n == 0){ | |
1305 goto NEXT; | |
1306 } | |
1307 r = proc_pmt(prv, pgrm); | |
1308 if(r < 0){ | |
1309 curr += unit; | |
1310 goto LAST; | |
1311 } | |
1312 if(r > 0){ | |
1313 /* broken or unexpected section data */ | |
1314 goto NEXT; | |
1315 } | |
1316 pgrm->phase = 1; | |
1317 if(check_pmt_complete(prv)){ | |
1318 curr += unit; | |
1319 goto LAST; | |
1320 } | |
1321 }else{ | |
1322 pgrm->phase = 2; | |
1323 curr += unit; | |
1324 goto LAST; | |
1325 } | |
1326 | |
1327 NEXT: | |
1328 curr += unit; | |
1329 } | |
1330 | |
1331 LAST: | |
1332 prv->sbuf_offset = curr - prv->sbuf.head; | |
1333 | |
1334 return r; | |
1335 } | |
1336 | |
1337 static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm) | |
1338 { | |
1339 int r; | |
1340 | |
1341 int n; | |
1342 int length; | |
1343 | |
1344 uint8_t *head; | |
1345 uint8_t *tail; | |
1346 | |
1347 int32_t ecm_pid; | |
1348 int32_t pid; | |
1349 int32_t type; | |
1350 | |
1351 TS_SECTION sect; | |
1352 | |
1353 DECRYPTOR_ELEM *dec[2]; | |
1354 DECRYPTOR_ELEM *dw; | |
1355 | |
1356 TS_STREAM_ELEM *strm; | |
1357 | |
1358 r = 0; | |
1359 dec[0] = NULL; | |
1360 memset(§, 0, sizeof(sect)); | |
1361 | |
1362 n = pgrm->pmt->get(pgrm->pmt, §); | |
1363 if(n < 0){ | |
1364 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1365 goto LAST; | |
1366 } | |
1367 if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_MAP){ | |
1368 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; | |
1369 goto LAST; | |
1370 } | |
1371 | |
1372 head = sect.data; | |
1373 tail = sect.tail-4; | |
1374 | |
1375 pgrm->pcr_pid = ((head[0] << 8) | head[1]) & 0x1fff; | |
1376 length = ((head[2] << 8) | head[3]) & 0x0fff; | |
1377 head += 4; | |
1378 if(head+length > tail){ | |
1379 r = ARIB_STD_B25_WARN_BROKEN_TS_SECTION; | |
1380 goto LAST; | |
1381 } | |
1382 | |
1383 /* find major ecm_pid and regist decryptor */ | |
1384 ecm_pid = find_ca_descriptor_pid(head, head+length, prv->ca_system_id); | |
1385 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ | |
1386 dec[0] = set_decryptor(prv, ecm_pid); | |
1387 if(dec[0] == NULL){ | |
1388 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1389 goto LAST; | |
1390 } | |
1391 dec[0]->ref += 1; | |
1392 } | |
1393 head += length; | |
1394 | |
1395 /* unref old stream entries */ | |
1396 while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){ | |
1397 unref_stream(prv, strm->pid); | |
1398 memset(strm, 0, sizeof(TS_STREAM_ELEM)); | |
1399 put_stream_list_tail(&(prv->strm_pool), strm); | |
1400 } | |
1401 | |
1402 /* save current streams */ | |
1403 memcpy(&(pgrm->old_strm), &(pgrm->streams), sizeof(TS_STREAM_LIST)); | |
1404 memset(&(pgrm->streams), 0, sizeof(TS_STREAM_LIST)); | |
1405 | |
1406 /* add current stream entries */ | |
1407 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ | |
1408 if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){ | |
1409 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1410 goto LAST; | |
1411 } | |
1412 } | |
1413 | |
1414 while( head+4 < tail ){ | |
1415 | |
1416 type = head[0]; | |
1417 pid = ((head[1] << 8) | head[2]) & 0x1fff; | |
1418 length = ((head[3] << 8) | head[4]) & 0x0fff; | |
1419 head += 5; | |
1420 ecm_pid = find_ca_descriptor_pid(head, head+length, prv->ca_system_id); | |
1421 head += length; | |
1422 | |
1423 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){ | |
1424 dec[1] = set_decryptor(prv, ecm_pid); | |
1425 if(dec[1] == NULL){ | |
1426 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1427 goto LAST; | |
1428 } | |
1429 if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){ | |
1430 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1431 goto LAST; | |
1432 } | |
1433 }else{ | |
1434 dec[1] = NULL; | |
1435 } | |
1436 | |
1437 strm = get_stream_list_head(&(prv->strm_pool)); | |
1438 if( strm == NULL ){ | |
1439 strm = create_stream_elem(pid, type); | |
1440 if(strm == NULL){ | |
1441 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1442 goto LAST; | |
1443 } | |
1444 }else{ | |
1445 strm->pid = pid; | |
1446 strm->type = type; | |
1447 } | |
1448 | |
1449 prv->map[pid].type = PID_MAP_TYPE_OTHER; | |
1450 prv->map[pid].ref += 1; | |
1451 | |
1452 dw = select_active_decryptor(dec[0], dec[1], ecm_pid); | |
1453 bind_stream_decryptor(prv, pid, dw); | |
1454 | |
1455 put_stream_list_tail(&(pgrm->streams), strm); | |
1456 } | |
1457 | |
1458 LAST: | |
1459 if( dec[0] != NULL ){ | |
1460 dec[0]->ref -= 1; | |
1461 if( dec[0]->ref < 1 ){ | |
1462 remove_decryptor(prv, dec[0]); | |
1463 dec[0] = NULL; | |
1464 } | |
1465 } | |
1466 | |
1467 if(sect.raw != NULL){ | |
1468 n = pgrm->pmt->ret(pgrm->pmt, §); | |
1469 if( (n < 0) && (r == 0) ){ | |
1470 return ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1471 } | |
1472 } | |
1473 | |
1474 return 0; | |
1475 } | |
1476 | |
1477 static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail, int32_t ca_system_id) | |
1478 { | |
1479 uint32_t ca_pid; | |
1480 uint32_t ca_sys_id; | |
1481 | |
1482 uint32_t tag; | |
1483 uint32_t len; | |
1484 | |
1485 while(head+1 < tail){ | |
1486 tag = head[0]; | |
1487 len = head[1]; | |
1488 head += 2; | |
1489 if( (tag == 0x09) && /* CA_descriptor */ | |
1490 (len >= 4) && | |
1491 (head+len <= tail) ){ | |
1492 ca_sys_id = ((head[0] << 8) | head[1]); | |
1493 ca_pid = ((head[2] << 8) | head[3]) & 0x1fff; | |
1494 if(ca_sys_id == ca_system_id){ | |
1495 return ca_pid; | |
1496 } | |
1497 } | |
1498 head += len; | |
1499 } | |
1500 | |
1501 return 0; | |
1502 } | |
1503 | |
1504 static int add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid) | |
1505 { | |
1506 TS_STREAM_ELEM *strm; | |
1507 | |
1508 strm = find_stream_list_elem(list, ecm_pid); | |
1509 if(strm != NULL){ | |
1510 // ECM is already registered | |
1511 return 1; | |
1512 } | |
1513 | |
1514 strm = get_stream_list_head(&(prv->strm_pool)); | |
1515 if(strm == NULL){ | |
1516 strm = create_stream_elem(ecm_pid, PID_MAP_TYPE_ECM); | |
1517 if(strm == NULL){ | |
1518 return 0; | |
1519 } | |
1520 }else{ | |
1521 strm->pid = ecm_pid; | |
1522 strm->type = PID_MAP_TYPE_ECM; | |
1523 } | |
1524 | |
1525 put_stream_list_tail(list, strm); | |
1526 prv->map[ecm_pid].ref += 1; | |
1527 | |
1528 return 1; | |
1529 } | |
1530 | |
1531 static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1532 { | |
1533 int n,num[3]; | |
1534 DECRYPTOR_ELEM *e; | |
1535 | |
1536 memset(num, 0, sizeof(num)); | |
1537 | |
1538 e = prv->decrypt.head; | |
1539 while( e != NULL ){ | |
1540 n = e->phase; | |
1541 if(n < 0){ | |
1542 n = 0; | |
1543 }else if(n > 2){ | |
1544 n = 2; | |
1545 } | |
1546 num[n] += 1; | |
1547 e = (DECRYPTOR_ELEM *)(e->next); | |
1548 } | |
1549 | |
1550 if(num[2] > 0){ | |
1551 return 1; | |
1552 } | |
1553 | |
1554 if(num[0] > 0){ | |
1555 return 0; | |
1556 } | |
1557 | |
1558 return 1; | |
1559 } | |
1560 | |
1561 static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1562 { | |
1563 int r; | |
1564 int n,size; | |
1565 | |
1566 int32_t unit; | |
1567 | |
1568 uint8_t *p; | |
1569 uint8_t *curr; | |
1570 uint8_t *tail; | |
1571 | |
1572 TS_HEADER hdr; | |
1573 DECRYPTOR_ELEM *dec; | |
1574 | |
1575 r = 0; | |
1576 unit = prv->unit_size; | |
1577 curr = prv->sbuf.head + prv->sbuf_offset; | |
1578 tail = prv->sbuf.tail; | |
1579 | |
1580 while( (curr+unit) < tail ){ | |
1581 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ | |
1582 p = resync(curr, tail, unit); | |
1583 if(p == NULL){ | |
1584 goto LAST; | |
1585 } | |
1586 curr = p; | |
1587 } | |
1588 extract_ts_header(&hdr, curr); | |
1589 if(prv->map[hdr.pid].type != PID_MAP_TYPE_ECM){ | |
1590 goto NEXT; | |
1591 } | |
1592 dec = (DECRYPTOR_ELEM *)(prv->map[hdr.pid].target); | |
1593 if(dec == NULL){ | |
1594 goto NEXT; | |
1595 } | |
1596 | |
1597 if(dec->phase == 0){ | |
1598 | |
1599 p = curr + 4; | |
1600 if(hdr.adaptation_field_control & 0x02){ | |
1601 p += (p[0]+1); | |
1602 } | |
1603 size = 188 - (p-curr); | |
1604 if(size < 1){ | |
1605 goto NEXT; | |
1606 } | |
1607 | |
1608 if(dec->ecm == NULL){ | |
1609 /* this code will never execute */ | |
1610 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1611 curr += unit; | |
1612 goto LAST; | |
1613 } | |
1614 | |
1615 n = dec->ecm->put(dec->ecm, &hdr, p, size); | |
1616 if(n < 0){ | |
1617 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1618 curr += unit; | |
1619 goto LAST; | |
1620 } | |
1621 n = dec->ecm->get_count(dec->ecm); | |
1622 if(n < 0){ | |
1623 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1624 curr += unit; | |
1625 goto LAST; | |
1626 } | |
1627 if(n == 0){ | |
1628 goto NEXT; | |
1629 } | |
1630 | |
1631 r = proc_ecm(dec, prv->bcas, prv->multi2_round); | |
1632 if(r < 0){ | |
1633 curr += unit; | |
1634 goto LAST; | |
1635 } | |
1636 if( (r > 0) && (r != ARIB_STD_B25_WARN_UNPURCHASED_ECM) ){ | |
1637 /* broken or unexpected section data */ | |
1638 goto NEXT; | |
1639 } | |
1640 | |
1641 dec->phase = 1; | |
1642 if(check_ecm_complete(prv)){ | |
1643 curr += unit; | |
1644 goto LAST; | |
1645 } | |
1646 | |
1647 }else{ | |
1648 dec->phase = 2; | |
1649 curr += unit; | |
1650 goto LAST; | |
1651 } | |
1652 | |
1653 NEXT: | |
1654 curr += unit; | |
1655 } | |
1656 | |
1657 LAST: | |
1658 prv->sbuf_offset = curr - prv->sbuf.head; | |
1659 | |
1660 return r; | |
1661 } | |
1662 | |
1663 static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round) | |
1664 { | |
1665 int r,n; | |
1666 int length; | |
1667 | |
1668 uint8_t *p; | |
1669 | |
1670 B_CAS_INIT_STATUS is; | |
1671 B_CAS_ECM_RESULT res; | |
1672 | |
1673 TS_SECTION sect; | |
1674 | |
1675 r = 0; | |
1676 memset(§, 0, sizeof(sect)); | |
1677 | |
1678 if(bcas == NULL){ | |
1679 r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD; | |
1680 goto LAST; | |
1681 } | |
1682 | |
1683 n = dec->ecm->get(dec->ecm, §); | |
1684 if(n < 0){ | |
1685 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1686 goto LAST; | |
1687 } | |
1688 if(sect.hdr.table_id != TS_SECTION_ID_ECM_S){ | |
1689 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; | |
1690 goto LAST; | |
1691 } | |
1692 | |
1693 if(dec->locked){ | |
1694 /* previous ECM has returned unpurchased | |
1695 skip this pid for B-CAS card load reduction */ | |
1696 dec->unpurchased += 1; | |
1697 r = ARIB_STD_B25_WARN_UNPURCHASED_ECM; | |
1698 goto LAST; | |
1699 } | |
1700 | |
1701 length = (sect.tail - sect.data) - 4; | |
1702 p = sect.data; | |
1703 | |
1704 r = bcas->proc_ecm(bcas, &res, p, length); | |
1705 if(r < 0){ | |
1706 if(dec->m2 != NULL){ | |
1707 dec->m2->clear_scramble_key(dec->m2); | |
1708 } | |
1709 r = ARIB_STD_B25_ERROR_ECM_PROC_FAILURE; | |
1710 goto LAST; | |
1711 } | |
1712 | |
1713 if( (res.return_code != 0x0800) && | |
1714 (res.return_code != 0x0400) && | |
1715 (res.return_code != 0x0200) ){ | |
1716 /* return_code is not equal "purchased" */ | |
1717 if(dec->m2 != NULL){ | |
1718 dec->m2->release(dec->m2); | |
1719 dec->m2 = NULL; | |
1720 } | |
1721 dec->unpurchased += 1; | |
1722 dec->last_error = res.return_code; | |
1723 dec->locked += 1; | |
1724 r = ARIB_STD_B25_WARN_UNPURCHASED_ECM; | |
1725 goto LAST; | |
1726 } | |
1727 | |
1728 if(dec->m2 == NULL){ | |
1729 dec->m2 = create_multi2(); | |
1730 if(dec->m2 == NULL){ | |
1731 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1732 } | |
1733 r = bcas->get_init_status(bcas, &is); | |
1734 if(r < 0){ | |
1735 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS; | |
1736 } | |
1737 dec->m2->set_system_key(dec->m2, is.system_key); | |
1738 dec->m2->set_init_cbc(dec->m2, is.init_cbc); | |
1739 dec->m2->set_round(dec->m2, multi2_round); | |
1740 } | |
1741 | |
1742 dec->m2->set_scramble_key(dec->m2, res.scramble_key); | |
1743 | |
1744 LAST: | |
1745 if(sect.raw != NULL){ | |
1746 n = dec->ecm->ret(dec->ecm, §); | |
1747 if( (n < 0) && (r == 0) ){ | |
1748 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1749 } | |
1750 } | |
1751 | |
1752 return r; | |
1753 } | |
1754 | |
1755 static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1756 { | |
1757 int r; | |
1758 int m,n; | |
1759 | |
1760 int32_t crypt; | |
1761 int32_t unit; | |
1762 int32_t pid; | |
1763 | |
1764 uint8_t *p; | |
1765 uint8_t *curr; | |
1766 uint8_t *tail; | |
1767 | |
1768 TS_HEADER hdr; | |
1769 DECRYPTOR_ELEM *dec; | |
1770 TS_PROGRAM *pgrm; | |
1771 | |
1772 unit = prv->unit_size; | |
1773 curr = prv->sbuf.head; | |
1774 tail = prv->sbuf.tail; | |
1775 | |
1776 m = prv->dbuf.tail - prv->dbuf.head; | |
1777 n = tail - curr; | |
1778 if(!reserve_work_buffer(&(prv->dbuf), m+n)){ | |
1779 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1780 } | |
1781 | |
1782 r = 0; | |
1783 | |
1784 while( (curr+unit) < tail ){ | |
1785 | |
1786 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){ | |
1787 p = resync(curr, tail, unit); | |
1788 if(p == NULL){ | |
1789 goto LAST; | |
1790 } | |
1791 curr = p; | |
1792 } | |
1793 | |
1794 extract_ts_header(&hdr, curr); | |
1795 crypt = hdr.transport_scrambling_control; | |
1796 pid = hdr.pid; | |
1797 | |
1798 if( (pid == 0x1fff) && (prv->strip) ){ | |
1799 /* strip null(padding) stream */ | |
1800 goto NEXT; | |
1801 } | |
1802 | |
1803 p = curr+4; | |
1804 if(hdr.adaptation_field_control & 0x02){ | |
1805 p += (p[0]+1); | |
1806 } | |
1807 n = 188 - (p-curr); | |
1808 if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){ | |
1809 /* broken packet */ | |
1810 curr += 1; | |
1811 continue; | |
1812 } | |
1813 | |
1814 if( (crypt != 0) && | |
1815 (hdr.adaptation_field_control & 0x01) ){ | |
1816 | |
1817 if(prv->map[pid].type == PID_MAP_TYPE_OTHER){ | |
1818 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
1819 }else if( (prv->map[pid].type == 0) && | |
1820 (prv->decrypt.count == 1) ){ | |
1821 dec = prv->decrypt.head; | |
1822 }else{ | |
1823 dec = NULL; | |
1824 } | |
1825 | |
1826 if( (dec != NULL) && (dec->m2 != NULL) ){ | |
1827 m = dec->m2->decrypt(dec->m2, crypt, p, n); | |
1828 if(m < 0){ | |
1829 r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE; | |
1830 goto LAST; | |
1831 } | |
1832 curr[3] &= 0x3f; | |
1833 prv->map[pid].normal_packet += 1; | |
1834 }else{ | |
1835 prv->map[pid].undecrypted += 1; | |
1836 } | |
1837 }else{ | |
1838 prv->map[pid].normal_packet += 1; | |
1839 } | |
1840 | |
1841 if(!append_work_buffer(&(prv->dbuf), curr, 188)){ | |
1842 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1843 goto LAST; | |
1844 } | |
1845 | |
1846 if(prv->map[pid].type == PID_MAP_TYPE_ECM){ | |
1847 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
1848 if( (dec == NULL) || (dec->ecm == NULL) ){ | |
1849 /* this code will never execute */ | |
1850 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1851 goto LAST; | |
1852 } | |
1853 m = dec->ecm->put(dec->ecm, &hdr, p, n); | |
1854 if(m < 0){ | |
1855 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1856 goto LAST; | |
1857 } | |
1858 m = dec->ecm->get_count(dec->ecm); | |
1859 if(m < 0){ | |
1860 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE; | |
1861 goto LAST; | |
1862 } | |
1863 if(m == 0){ | |
1864 goto NEXT; | |
1865 } | |
1866 r = proc_ecm(dec, prv->bcas, prv->multi2_round); | |
1867 if(r < 0){ | |
1868 goto LAST; | |
1869 } | |
1870 }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){ | |
1871 pgrm = (TS_PROGRAM *)(prv->map[pid].target); | |
1872 if( (pgrm == NULL) || (pgrm->pmt == NULL) ){ | |
1873 /* this code will never execute */ | |
1874 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1875 goto LAST; | |
1876 } | |
1877 m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n); | |
1878 if(m < 0){ | |
1879 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1880 goto LAST; | |
1881 } | |
1882 m = pgrm->pmt->get_count(pgrm->pmt); | |
1883 if(m < 0){ | |
1884 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE; | |
1885 goto LAST; | |
1886 } | |
1887 if(m == 0){ | |
1888 goto NEXT; | |
1889 } | |
1890 r = proc_pmt(prv, pgrm); | |
1891 if(r < 0){ | |
1892 goto LAST; | |
1893 } | |
1894 }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){ | |
1895 if( prv->emm_proc_on == 0){ | |
1896 goto NEXT; | |
1897 } | |
1898 if( prv->emm == NULL ){ | |
1899 prv->emm = create_ts_section_parser(); | |
1900 if(prv->emm == NULL){ | |
1901 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
1902 goto LAST; | |
1903 } | |
1904 } | |
1905 m = prv->emm->put(prv->emm, &hdr, p, n); | |
1906 if(m < 0){ | |
1907 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
1908 goto LAST; | |
1909 } | |
1910 m = prv->emm->get_count(prv->emm); | |
1911 if(m < 0){ | |
1912 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
1913 goto LAST; | |
1914 } | |
1915 if(m == 0){ | |
1916 goto NEXT; | |
1917 } | |
1918 r = proc_emm(prv); | |
1919 if(r < 0){ | |
1920 goto LAST; | |
1921 } | |
1922 }else if(pid == 0x0001){ | |
1923 if( prv->cat == NULL ){ | |
1924 prv->cat = create_ts_section_parser(); | |
1925 if(prv->cat == NULL){ | |
1926 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1927 goto LAST; | |
1928 } | |
1929 } | |
1930 m = prv->cat->put(prv->cat, &hdr, p, n); | |
1931 if(m < 0){ | |
1932 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
1933 goto LAST; | |
1934 } | |
1935 m = prv->cat->get_count(prv->cat); | |
1936 if(m < 0){ | |
1937 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
1938 goto LAST; | |
1939 } | |
1940 if(m == 0){ | |
1941 goto NEXT; | |
1942 } | |
1943 r = proc_cat(prv); | |
1944 if(r < 0){ | |
1945 goto LAST; | |
1946 } | |
1947 }else if(pid == 0x0000){ | |
1948 if( prv->pat == NULL ){ | |
1949 prv->pat = create_ts_section_parser(); | |
1950 if(prv->pat == NULL){ | |
1951 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY; | |
1952 goto LAST; | |
1953 } | |
1954 } | |
1955 m = prv->pat->put(prv->pat, &hdr, p, n); | |
1956 if(m < 0){ | |
1957 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1958 goto LAST; | |
1959 } | |
1960 m = prv->pat->get_count(prv->pat); | |
1961 if(m < 0){ | |
1962 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE; | |
1963 goto LAST; | |
1964 } | |
1965 if(m == 0){ | |
1966 goto NEXT; | |
1967 } | |
1968 r = proc_pat(prv); | |
1969 goto LAST; | |
1970 } | |
1971 | |
1972 NEXT: | |
1973 curr += unit; | |
1974 } | |
1975 | |
1976 LAST: | |
1977 m = curr - prv->sbuf.head; | |
1978 n = tail - curr; | |
1979 if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){ | |
1980 p = prv->sbuf.pool; | |
1981 memcpy(p, curr, n); | |
1982 prv->sbuf.head = p; | |
1983 prv->sbuf.tail = p+n; | |
1984 }else{ | |
1985 prv->sbuf.head = curr; | |
1986 } | |
1987 | |
1988 return r; | |
1989 } | |
1990 | |
1991 static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv) | |
1992 { | |
1993 int r; | |
1994 int n; | |
1995 int emm_pid; | |
1996 | |
1997 TS_SECTION sect; | |
1998 | |
1999 r = 0; | |
2000 memset(§, 0, sizeof(sect)); | |
2001 | |
2002 n = prv->cat->get(prv->cat, §); | |
2003 if(n < 0){ | |
2004 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
2005 goto LAST; | |
2006 } | |
2007 | |
2008 if(sect.hdr.table_id != TS_SECTION_ID_CONDITIONAL_ACCESS){ | |
2009 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; | |
2010 goto LAST; | |
2011 } | |
2012 | |
2013 emm_pid = find_ca_descriptor_pid(sect.data, sect.tail-4, prv->ca_system_id); | |
2014 if( (emm_pid != 0x0000) && (emm_pid != 0x1fff) ){ | |
2015 if( (prv->map[emm_pid].target != NULL) && | |
2016 (prv->map[emm_pid].type == PID_MAP_TYPE_OTHER) ){ | |
2017 DECRYPTOR_ELEM *dec; | |
2018 dec = (DECRYPTOR_ELEM *)(prv->map[emm_pid].target); | |
2019 dec->ref -= 1; | |
2020 if(dec->ref < 1){ | |
2021 remove_decryptor(prv, dec); | |
2022 } | |
2023 } | |
2024 prv->emm_pid = emm_pid; | |
2025 prv->map[emm_pid].ref = 1; | |
2026 prv->map[emm_pid].type = PID_MAP_TYPE_EMM; | |
2027 prv->map[emm_pid].target = NULL; | |
2028 } | |
2029 | |
2030 prv->map[0x0001].ref = 1; | |
2031 prv->map[0x0001].type = PID_MAP_TYPE_CAT; | |
2032 prv->map[0x0001].target = NULL; | |
2033 | |
2034 LAST: | |
2035 | |
2036 if(sect.raw != NULL){ | |
2037 n = prv->cat->ret(prv->cat, §); | |
2038 if( (n < 0) && (r == 0) ){ | |
2039 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
2040 } | |
2041 } | |
2042 | |
2043 return r; | |
2044 } | |
2045 | |
2046 static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv) | |
2047 { | |
2048 int r; | |
2049 int i,j,n; | |
2050 | |
2051 int len; | |
2052 | |
2053 uint8_t *head; | |
2054 uint8_t *tail; | |
2055 | |
2056 TS_SECTION sect; | |
2057 EMM_FIXED_PART emm_hdr; | |
2058 | |
2059 r = 0; | |
2060 memset(§, 0, sizeof(sect)); | |
2061 | |
2062 if(prv->bcas == NULL){ | |
2063 r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD; | |
2064 goto LAST; | |
2065 } | |
2066 | |
2067 while( (n = prv->emm->get_count(prv->emm)) > 0 ){ | |
2068 | |
2069 n = prv->emm->get(prv->emm, §); | |
2070 if(n < 0){ | |
2071 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE; | |
2072 goto LAST; | |
2073 } | |
2074 | |
2075 if(sect.hdr.table_id == TS_SECTION_ID_EMM_MESSAGE){ | |
2076 /* EMM_MESSAGE is not supported */ | |
2077 goto NEXT; | |
2078 }else if(sect.hdr.table_id != TS_SECTION_ID_EMM_S){ | |
2079 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH; | |
2080 goto LAST; | |
2081 } | |
2082 | |
2083 head = sect.data; | |
2084 tail = sect.tail - 4; | |
2085 | |
2086 i = 0; | |
2087 while( (head+13) <= tail ){ | |
2088 | |
2089 extract_emm_fixed_part(&emm_hdr, head); | |
2090 len = emm_hdr.associated_information_length+7; | |
2091 if( (head+len) > tail ){ | |
2092 /* broken EMM element */ | |
2093 goto NEXT; | |
2094 } | |
2095 | |
2096 for(j=0;j<prv->casid.count;j++){ | |
2097 if(prv->casid.data[j] == emm_hdr.card_id){ | |
2098 n = prv->bcas->proc_emm(prv->bcas, head, len); | |
2099 if(n < 0){ | |
2100 r = ARIB_STD_B25_ERROR_EMM_PROC_FAILURE; | |
2101 goto LAST; | |
2102 } | |
2103 unlock_all_decryptor(prv); | |
2104 } | |
2105 } | |
2106 | |
2107 head += len; | |
2108 } | |
2109 | |
2110 NEXT: | |
2111 if(sect.raw != NULL){ | |
2112 n = prv->emm->ret(prv->emm, §); | |
2113 if( (n < 0) && (r == 0) ){ | |
2114 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
2115 goto LAST; | |
2116 } | |
2117 memset(§, 0, sizeof(sect)); | |
2118 } | |
2119 } | |
2120 | |
2121 LAST: | |
2122 if(sect.raw != NULL){ | |
2123 n = prv->emm->ret(prv->emm, §); | |
2124 if( (n < 0) && (r == 0) ){ | |
2125 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE; | |
2126 } | |
2127 } | |
2128 | |
2129 return r; | |
2130 } | |
2131 | |
2132 static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm) | |
2133 { | |
2134 int32_t pid; | |
2135 TS_STREAM_ELEM *strm; | |
2136 | |
2137 pid = pgrm->pmt_pid; | |
2138 | |
2139 if(pgrm->pmt != NULL){ | |
2140 pgrm->pmt->release(pgrm->pmt); | |
2141 pgrm->pmt = NULL; | |
2142 } | |
2143 | |
2144 while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){ | |
2145 unref_stream(prv, strm->pid); | |
2146 memset(strm, 0, sizeof(TS_STREAM_ELEM)); | |
2147 put_stream_list_tail(&(prv->strm_pool), strm); | |
2148 } | |
2149 | |
2150 while( (strm = get_stream_list_head(&(pgrm->streams))) != NULL ){ | |
2151 unref_stream(prv, strm->pid); | |
2152 memset(strm, 0, sizeof(TS_STREAM_ELEM)); | |
2153 put_stream_list_tail(&(prv->strm_pool), strm); | |
2154 } | |
2155 | |
2156 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; | |
2157 prv->map[pid].ref = 0; | |
2158 prv->map[pid].target = NULL; | |
2159 } | |
2160 | |
2161 static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid) | |
2162 { | |
2163 DECRYPTOR_ELEM *dec; | |
2164 | |
2165 prv->map[pid].ref -= 1; | |
2166 if( prv->map[pid].ref < 1 ){ | |
2167 if( (prv->map[pid].target != NULL) && | |
2168 (prv->map[pid].type == PID_MAP_TYPE_OTHER) ){ | |
2169 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
2170 dec->ref -= 1; | |
2171 if(dec->ref < 1){ | |
2172 remove_decryptor(prv, dec); | |
2173 } | |
2174 } | |
2175 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; | |
2176 prv->map[pid].ref = 0; | |
2177 prv->map[pid].target = NULL; | |
2178 } | |
2179 } | |
2180 | |
2181 static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid) | |
2182 { | |
2183 DECRYPTOR_ELEM *r; | |
2184 | |
2185 r = NULL; | |
2186 if(prv->map[pid].type == PID_MAP_TYPE_ECM){ | |
2187 r = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
2188 if(r != NULL){ | |
2189 return r; | |
2190 } | |
2191 } | |
2192 r = (DECRYPTOR_ELEM *)calloc(1, sizeof(DECRYPTOR_ELEM)); | |
2193 if(r == NULL){ | |
2194 return NULL; | |
2195 } | |
2196 r->ecm_pid = pid; | |
2197 r->ecm = create_ts_section_parser(); | |
2198 if(r->ecm == NULL){ | |
2199 free(r); | |
2200 return NULL; | |
2201 } | |
2202 | |
2203 if(prv->decrypt.tail != NULL){ | |
2204 r->prev = prv->decrypt.tail; | |
2205 r->next = NULL; | |
2206 prv->decrypt.tail->next = r; | |
2207 prv->decrypt.tail = r; | |
2208 prv->decrypt.count += 1; | |
2209 }else{ | |
2210 r->prev = NULL; | |
2211 r->next = NULL; | |
2212 prv->decrypt.head = r; | |
2213 prv->decrypt.tail = r; | |
2214 prv->decrypt.count = 1; | |
2215 } | |
2216 | |
2217 if( (prv->map[pid].type == PID_MAP_TYPE_OTHER) && | |
2218 (prv->map[pid].target != NULL) ){ | |
2219 DECRYPTOR_ELEM *dec; | |
2220 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
2221 dec->ref -= 1; | |
2222 if(dec->ref < 1){ | |
2223 remove_decryptor(prv, dec); | |
2224 } | |
2225 } | |
2226 | |
2227 prv->map[pid].type = PID_MAP_TYPE_ECM; | |
2228 prv->map[pid].target = r; | |
2229 | |
2230 return r; | |
2231 } | |
2232 | |
2233 static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec) | |
2234 { | |
2235 int32_t pid; | |
2236 | |
2237 DECRYPTOR_ELEM *prev; | |
2238 DECRYPTOR_ELEM *next; | |
2239 | |
2240 pid = dec->ecm_pid; | |
2241 if( (prv->map[pid].type == PID_MAP_TYPE_ECM) && | |
2242 (prv->map[pid].target == ((void *)dec)) ){ | |
2243 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN; | |
2244 prv->map[pid].target = NULL; | |
2245 } | |
2246 | |
2247 prev = (DECRYPTOR_ELEM *)(dec->prev); | |
2248 next = (DECRYPTOR_ELEM *)(dec->next); | |
2249 if(prev != NULL){ | |
2250 prev->next = next; | |
2251 }else{ | |
2252 prv->decrypt.head = next; | |
2253 } | |
2254 if(next != NULL){ | |
2255 next->prev = prev; | |
2256 }else{ | |
2257 prv->decrypt.tail = prev; | |
2258 } | |
2259 prv->decrypt.count -= 1; | |
2260 | |
2261 if(dec->ecm != NULL){ | |
2262 dec->ecm->release(dec->ecm); | |
2263 dec->ecm = NULL; | |
2264 } | |
2265 | |
2266 if(dec->m2 != NULL){ | |
2267 dec->m2->release(dec->m2); | |
2268 dec->m2 = NULL; | |
2269 } | |
2270 | |
2271 free(dec); | |
2272 } | |
2273 | |
2274 static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid) | |
2275 { | |
2276 if( b != NULL ){ | |
2277 return b; | |
2278 } | |
2279 if( pid == 0x1fff ){ | |
2280 return NULL; | |
2281 } | |
2282 return a; | |
2283 } | |
2284 | |
2285 static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec) | |
2286 { | |
2287 DECRYPTOR_ELEM *old; | |
2288 | |
2289 old = (DECRYPTOR_ELEM *)(prv->map[pid].target); | |
2290 if(old == dec){ | |
2291 /* already binded - do nothing */ | |
2292 return; | |
2293 } | |
2294 | |
2295 if(old != NULL){ | |
2296 old->ref -= 1; | |
2297 if(old->ref == 0){ | |
2298 remove_decryptor(prv, old); | |
2299 } | |
2300 prv->map[pid].target = NULL; | |
2301 } | |
2302 | |
2303 if(dec != NULL){ | |
2304 prv->map[pid].target = dec; | |
2305 dec->ref += 1; | |
2306 } | |
2307 } | |
2308 | |
2309 static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv) | |
2310 { | |
2311 DECRYPTOR_ELEM *e; | |
2312 | |
2313 e = prv->decrypt.head; | |
2314 while(e != NULL){ | |
2315 e->locked = 0; | |
2316 e = (DECRYPTOR_ELEM *)(e->next); | |
2317 } | |
2318 } | |
2319 | |
2320 static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list) | |
2321 { | |
2322 TS_STREAM_ELEM *r; | |
2323 | |
2324 r = list->head; | |
2325 if(r == NULL){ | |
2326 return NULL; | |
2327 } | |
2328 | |
2329 list->head = (TS_STREAM_ELEM *)(r->next); | |
2330 if(list->head == NULL){ | |
2331 list->tail = NULL; | |
2332 list->count = 0; | |
2333 }else{ | |
2334 list->head->prev = NULL; | |
2335 list->count -= 1; | |
2336 } | |
2337 | |
2338 r->prev = NULL; | |
2339 r->next = NULL; | |
2340 | |
2341 return r; | |
2342 } | |
2343 | |
2344 static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid) | |
2345 { | |
2346 TS_STREAM_ELEM *r; | |
2347 | |
2348 r = list->head; | |
2349 while(r != NULL){ | |
2350 if(r->pid == pid){ | |
2351 break; | |
2352 } | |
2353 r = (TS_STREAM_ELEM *)(r->next); | |
2354 } | |
2355 | |
2356 return r; | |
2357 } | |
2358 | |
2359 static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type) | |
2360 { | |
2361 TS_STREAM_ELEM *r; | |
2362 | |
2363 r = (TS_STREAM_ELEM *)calloc(1, sizeof(TS_STREAM_ELEM)); | |
2364 if(r == NULL){ | |
2365 return NULL; | |
2366 } | |
2367 | |
2368 r->pid = pid; | |
2369 r->type = type; | |
2370 | |
2371 return r; | |
2372 } | |
2373 | |
2374 static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem) | |
2375 { | |
2376 if(list->tail != NULL){ | |
2377 elem->prev = list->tail; | |
2378 elem->next = NULL; | |
2379 list->tail->next = elem; | |
2380 list->tail = elem; | |
2381 list->count += 1; | |
2382 }else{ | |
2383 elem->prev = NULL; | |
2384 elem->next = NULL; | |
2385 list->head = elem; | |
2386 list->tail = elem; | |
2387 list->count = 1; | |
2388 } | |
2389 } | |
2390 | |
2391 static void clear_stream_list(TS_STREAM_LIST *list) | |
2392 { | |
2393 TS_STREAM_ELEM *p,*n; | |
2394 | |
2395 p = list->head; | |
2396 while(p != NULL){ | |
2397 n = (TS_STREAM_ELEM *)(p->next); | |
2398 free(p); | |
2399 p = n; | |
2400 } | |
2401 | |
2402 list->head = NULL; | |
2403 list->tail = NULL; | |
2404 list->count = 0; | |
2405 } | |
2406 | |
2407 static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size) | |
2408 { | |
2409 int m,n; | |
2410 uint8_t *p; | |
2411 | |
2412 if(buf->max >= size){ | |
2413 return 1; | |
2414 } | |
2415 | |
2416 if(buf->max < 512){ | |
2417 n = 512; | |
2418 }else{ | |
2419 n = buf->max * 2; | |
2420 } | |
2421 | |
2422 while(n < size){ | |
2423 n += n; | |
2424 } | |
2425 | |
2426 p = (uint8_t *)malloc(n); | |
2427 if(p == NULL){ | |
2428 return 0; | |
2429 } | |
2430 | |
2431 m = 0; | |
2432 if(buf->pool != NULL){ | |
2433 m = buf->tail - buf->head; | |
2434 if(m > 0){ | |
2435 memcpy(p, buf->head, m); | |
2436 } | |
2437 free(buf->pool); | |
2438 buf->pool = NULL; | |
2439 } | |
2440 | |
2441 buf->pool = p; | |
2442 buf->head = p; | |
2443 buf->tail = p+m; | |
2444 buf->max = n; | |
2445 | |
2446 return 1; | |
2447 } | |
2448 | |
2449 static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size) | |
2450 { | |
2451 int m; | |
2452 | |
2453 if(size < 1){ | |
2454 /* ignore - do nothing */ | |
2455 return 1; | |
2456 } | |
2457 | |
2458 m = buf->tail - buf->pool; | |
2459 | |
2460 if( (m+size) > buf->max ){ | |
2461 if(!reserve_work_buffer(buf, m+size)){ | |
2462 return 0; | |
2463 } | |
2464 } | |
2465 | |
2466 memcpy(buf->tail, data, size); | |
2467 buf->tail += size; | |
2468 | |
2469 return 1; | |
2470 } | |
2471 | |
2472 static void reset_work_buffer(TS_WORK_BUFFER *buf) | |
2473 { | |
2474 buf->head = buf->pool; | |
2475 buf->tail = buf->pool; | |
2476 } | |
2477 | |
2478 static void release_work_buffer(TS_WORK_BUFFER *buf) | |
2479 { | |
2480 if(buf->pool != NULL){ | |
2481 free(buf->pool); | |
2482 } | |
2483 buf->pool = NULL; | |
2484 buf->head = NULL; | |
2485 buf->tail = NULL; | |
2486 buf->max = 0; | |
2487 } | |
2488 | |
2489 static void extract_ts_header(TS_HEADER *dst, uint8_t *src) | |
2490 { | |
2491 dst->sync = src[0]; | |
2492 dst->transport_error_indicator = (src[1] >> 7) & 0x01; | |
2493 dst->payload_unit_start_indicator = (src[1] >> 6) & 0x01; | |
2494 dst->transport_priority = (src[1] >> 5) & 0x01; | |
2495 dst->pid = ((src[1] & 0x1f) << 8) | src[2]; | |
2496 dst->transport_scrambling_control = (src[3] >> 6) & 0x03; | |
2497 dst->adaptation_field_control = (src[3] >> 4) & 0x03; | |
2498 dst->continuity_counter = src[3] & 0x0f; | |
2499 } | |
2500 | |
2501 static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src) | |
2502 { | |
2503 int i; | |
2504 | |
2505 dst->card_id = 0; | |
2506 for(i=0;i<6;i++){ | |
2507 dst->card_id = (dst->card_id << 8) | src[i]; | |
2508 } | |
2509 | |
2510 dst->associated_information_length = src[ 6]; | |
2511 dst->protocol_number = src[ 7]; | |
2512 dst->broadcaster_group_id = src[ 8]; | |
2513 dst->update_number = (src[ 9]<<8)|src[10]; | |
2514 dst->expiration_date = (src[11]<<8)|src[12]; | |
2515 } | |
2516 | |
2517 static uint8_t *resync(uint8_t *head, uint8_t *tail, int32_t unit_size) | |
2518 { | |
2519 int i; | |
2520 unsigned char *buf; | |
2521 | |
2522 buf = head; | |
2523 tail -= unit_size * 8; | |
2524 while( buf <= tail ){ | |
2525 if(buf[0] == 0x47){ | |
2526 for(i=1;i<8;i++){ | |
2527 if(buf[unit_size*i] != 0x47){ | |
2528 break; | |
2529 } | |
2530 } | |
2531 if(i == 8){ | |
2532 return buf; | |
2533 } | |
2534 } | |
2535 buf += 1; | |
2536 } | |
2537 | |
2538 return NULL; | |
2539 } | |
2540 | |
2541 static uint8_t *resync_force(uint8_t *head, uint8_t *tail, int32_t unit_size) | |
2542 { | |
2543 int i,n; | |
2544 unsigned char *buf; | |
2545 | |
2546 buf = head; | |
2547 while( buf <= (tail-188) ){ | |
2548 if(buf[0] == 0x47){ | |
2549 n = (tail - buf) / unit_size; | |
2550 if(n == 0){ | |
2551 return buf; | |
2552 } | |
2553 for(i=1;i<n;i++){ | |
2554 if(buf[unit_size*i] != 0x47){ | |
2555 break; | |
2556 } | |
2557 } | |
2558 if(i == n){ | |
2559 return buf; | |
2560 } | |
2561 } | |
2562 buf += 1; | |
2563 } | |
2564 | |
2565 return NULL; | |
2566 } |