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