initial commit
[arib_std_b25.git] / src / arib_std_b25.c
blob12bdf9fad0f6deac75025b36be15c4b0053a3a32
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
5 #include "arib_std_b25.h"
6 #include "arib_std_b25_error_code.h"
7 #include "multi2.h"
8 #include "ts_common_types.h"
9 #include "ts_section_parser.h"
11 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
12 inner structures
13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
14 typedef struct {
15 int32_t pid;
16 int32_t type;
17 void *prev;
18 void *next;
19 } TS_STREAM_ELEM;
21 typedef struct {
22 TS_STREAM_ELEM *head;
23 TS_STREAM_ELEM *tail;
24 int32_t count;
25 } TS_STREAM_LIST;
27 typedef struct {
29 uint8_t *pool;
30 uint8_t *head;
31 uint8_t *tail;
32 int32_t max;
34 } TS_WORK_BUFFER;
36 typedef struct {
38 int32_t phase;
40 int32_t program_number;
42 int32_t pmt_pid;
43 TS_SECTION_PARSER *pmt;
45 int32_t pcr_pid;
47 TS_STREAM_LIST streams;
48 TS_STREAM_LIST old_strm;
50 } TS_PROGRAM;
52 typedef struct {
54 int32_t ref;
55 int32_t phase;
57 int32_t locked;
59 int32_t ecm_pid;
60 TS_SECTION_PARSER *ecm;
62 MULTI2 *m2;
64 int32_t unpurchased;
65 int32_t last_error;
67 void *prev;
68 void *next;
70 } DECRYPTOR_ELEM;
72 typedef struct {
73 DECRYPTOR_ELEM *head;
74 DECRYPTOR_ELEM *tail;
75 int32_t count;
76 } DECRYPTOR_LIST;
78 typedef struct {
79 uint32_t ref;
80 uint32_t type;
81 int64_t normal_packet;
82 int64_t undecrypted;
83 void *target;
84 } PID_MAP;
86 typedef struct {
88 int32_t multi2_round;
89 int32_t strip;
90 int32_t emm_proc_on;
92 int32_t unit_size;
94 int32_t sbuf_offset;
96 TS_SECTION_PARSER *pat;
97 TS_SECTION_PARSER *cat;
99 TS_STREAM_LIST strm_pool;
101 int32_t p_count;
102 TS_PROGRAM *program;
104 DECRYPTOR_LIST decrypt;
106 PID_MAP map[0x2000];
108 B_CAS_CARD *bcas;
109 B_CAS_ID casid;
110 int32_t ca_system_id;
112 int32_t emm_pid;
113 TS_SECTION_PARSER *emm;
115 TS_WORK_BUFFER sbuf;
116 TS_WORK_BUFFER dbuf;
118 } ARIB_STD_B25_PRIVATE_DATA;
120 typedef struct {
121 int64_t card_id;
122 int32_t associated_information_length;
123 int32_t protocol_number;
124 int32_t broadcaster_group_id;
125 int32_t update_number;
126 int32_t expiration_date;
127 } EMM_FIXED_PART;
129 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
130 constant values
131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
132 enum TS_STREAM_TYPE {
133 TS_STREAM_TYPE_11172_2_VIDEO = 0x01,
134 TS_STREAM_TYPE_13818_2_VIDEO = 0x02,
135 TS_STREAM_TYPE_11172_3_AUDIO = 0x03,
136 TS_STREAM_TYPE_13818_3_AUDIO = 0x04,
137 TS_STREAM_TYPE_13818_1_PRIVATE_SECTIONS = 0x05,
138 TS_STREAM_TYPE_13818_1_PES_PRIVATE_DATA = 0x06,
139 TS_STREAM_TYPE_13522_MHEG = 0x07,
140 TS_STREAM_TYPE_13818_1_DSM_CC = 0x08,
141 TS_STREAM_TYPE_H_222_1 = 0x09,
142 TS_STREAM_TYPE_13818_6_TYPE_A = 0x0a,
143 TS_STREAM_TYPE_13818_6_TYPE_B = 0x0b,
144 TS_STREAM_TYPE_13818_6_TYPE_C = 0x0c,
145 TS_STREAM_TYPE_13818_6_TYPE_D = 0x0d,
146 TS_STREAM_TYPE_13818_1_AUX = 0x0e,
147 TS_STREAM_TYPE_13818_7_AUDIO_ADTS = 0x0f,
148 TS_STREAM_TYPE_14496_2_VISUAL = 0x10,
149 TS_STREAM_TYPE_14496_3_AUDIO_LATM = 0x11,
150 TS_STREAM_TYPE_14496_1_PES_SL_PACKET = 0x12,
151 TS_STREAM_TYPE_14496_1_SECTIONS_SL_PACKET = 0x13,
152 TS_STREAM_TYPE_13818_6_SYNC_DWLOAD_PROTCOL = 0x14,
155 enum TS_SECTION_ID {
156 TS_SECTION_ID_PROGRAM_ASSOCIATION = 0x00,
157 TS_SECTION_ID_CONDITIONAL_ACCESS = 0x01,
158 TS_SECTION_ID_PROGRAM_MAP = 0x02,
159 TS_SECTION_ID_DESCRIPTION = 0x03,
160 TS_SECTION_ID_14496_SCENE_DESCRIPTION = 0x04,
161 TS_SECTION_ID_14496_OBJECT_DESCRIPTION = 0x05,
163 /* ARIB STD-B10 stuff */
164 TS_SECTION_ID_DSM_CC_HEAD = 0x3a,
165 TS_SECTION_ID_DSM_CC_TAIL = 0x3f,
166 TS_SECTION_ID_NIT_ACTUAL = 0x40,
167 TS_SECTION_ID_NIT_OTHER = 0x41,
168 TS_SECTION_ID_SDT_ACTUAL = 0x42,
169 TS_SECTION_ID_SDT_OTHER = 0x46,
170 TS_SECTION_ID_BAT = 0x4a,
171 TS_SECTION_ID_EIT_ACTUAL_CURRENT = 0x4e,
172 TS_SECTION_ID_EIT_OTHER_CURRENT = 0x4f,
173 TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_HEAD = 0x50,
174 TS_SECTION_ID_EIT_ACTUAL_SCHEDULE_TAIL = 0x5f,
175 TS_SECTION_ID_EIT_OTHER_SCHEDULE_HEAD = 0x60,
176 TS_SECTION_ID_EIT_OTHER_SCHEDULE_TAIL = 0x6f,
177 TS_SECTION_ID_TDT = 0x70,
178 TS_SECTION_ID_RST = 0x71,
179 TS_SECTION_ID_ST = 0x72,
180 TS_SECTION_ID_TOT = 0x73,
181 TS_SECTION_ID_AIT = 0x74,
182 TS_SECTION_ID_DIT = 0x7e,
183 TS_SECTION_ID_SIT = 0x7f,
184 TS_SECTION_ID_ECM_S = 0x82,
185 TS_SECTION_ID_ECM = 0x83,
186 TS_SECTION_ID_EMM_S = 0x84,
187 TS_SECTION_ID_EMM_MESSAGE = 0x85,
188 TS_SECTION_ID_DCT = 0xc0,
189 TS_SECTION_ID_DLT = 0xc1,
190 TS_SECTION_ID_PCAT = 0xc2,
191 TS_SECTION_ID_SDTT = 0xc3,
192 TS_SECTION_ID_BIT = 0xc4,
193 TS_SECTION_ID_NBIT_BODY = 0xc5,
194 TS_SECTION_ID_NBIT_REFERENCE = 0xc6,
195 TS_SECTION_ID_LDT = 0xc7,
196 TS_SECTION_ID_CDT = 0xc8,
197 TS_SECTION_ID_LIT = 0xd0,
198 TS_SECTION_ID_ERT = 0xd1,
199 TS_SECTION_ID_ITT = 0xd2,
202 enum TS_DESCRIPTOR_TAG {
203 TS_DESCRIPTOR_TAG_VIDEO_STREAM = 0x02,
204 TS_DESCRIPTOR_TAG_AUDIO_STREAM = 0x03,
205 TS_DESCRIPTOR_TAG_HIERARCHY = 0x04,
206 TS_DESCRIPTOR_TAG_REGISTRATION = 0x05,
207 TS_DESCRIPTOR_TAG_DATA_STREAM_ALIGNMENT = 0x06,
208 TS_DESCRIPTOR_TAG_TARGET_BACKGROUND_GRID = 0x07,
209 TS_DESCRIPTOR_TAG_VIDEO_WINDOW = 0x08,
210 TS_DESCRIPTOR_TAG_CA = 0x09,
211 TS_DESCRIPTOR_TAG_ISO_639_LANGUAGE = 0x0a,
212 TS_DESCRIPTOR_TAG_SYSTEM_CLOCK = 0x0b,
213 TS_DESCRIPTOR_TAG_MULTIPLEX_BUF_UTILIZ = 0x0c,
214 TS_DESCRIPTOR_TAG_COPYRIGHT = 0x0d,
215 TS_DESCRIPTOR_TAG_MAXIMUM_BITRATE = 0x0e,
216 TS_DESCRIPTOR_TAG_PRIVATE_DATA_INDICATOR = 0x0f,
217 TS_DESCRIPTOR_TAG_SMOOTHING_BUFFER = 0x10,
218 TS_DESCRIPTOR_TAG_STD = 0x11,
219 TS_DESCRIPTOR_TAG_IBP = 0x12,
220 TS_DESCRIPTOR_TAG_MPEG4_VIDEO = 0x1b,
221 TS_DESCRIPTOR_TAG_MPEG4_AUDIO = 0x1c,
222 TS_DESCRIPTOR_TAG_IOD = 0x1d,
223 TS_DESCRIPTOR_TAG_SL = 0x1e,
224 TS_DESCRIPTOR_TAG_FMC = 0x1f,
225 TS_DESCRIPTOR_TAG_EXTERNAL_ES_ID = 0x20,
226 TS_DESCRIPTOR_TAG_MUXCODE = 0x21,
227 TS_DESCRIPTOR_TAG_FMX_BUFFER_SIZE = 0x22,
228 TS_DESCRIPTOR_TAG_MULTIPLEX_BUFFER = 0x23,
229 TS_DESCRIPTOR_TAG_AVC_VIDEO = 0x28,
230 TS_DESCRIPTOR_TAG_AVC_TIMING_HRD = 0x2a,
232 /* ARIB STD-B10 stuff */
233 TS_DESCRIPTOR_TAG_NETWORK_NAME = 0x40,
234 TS_DESCRIPTOR_TAG_SERVICE_LIST = 0x41,
235 TS_DESCRIPTOR_TAG_STUFFING = 0x42,
236 TS_DESCRIPTOR_TAG_SATELLITE_DELIVERY_SYS = 0x43,
237 TS_DESCRIPTOR_TAG_CABLE_DISTRIBUTION = 0x44,
238 TS_DESCRIPTOR_TAG_BOUNQUET_NAME = 0x47,
239 TS_DESCRIPTOR_TAG_SERVICE = 0x48,
240 TS_DESCRIPTOR_TAG_COUNTRY_AVAILABILITY = 0x49,
241 TS_DESCRIPTOR_TAG_LINKAGE = 0x4a,
242 TS_DESCRIPTOR_TAG_NVOD_REFERENCE = 0x4b,
243 TS_DESCRIPTOR_TAG_TIME_SHIFTED_SERVICE = 0x4c,
244 TS_DESCRIPTOR_TAG_SHORT_EVENT = 0x4d,
245 TS_DESCRIPTOR_TAG_EXTENDED_EVENT = 0x4e,
246 TS_DESCRIPTOR_TAG_TIME_SHIFTED_EVENT = 0x4f,
247 TS_DESCRIPTOR_TAG_COMPONENT = 0x50,
248 TS_DESCRIPTOR_TAG_MOSAIC = 0x51,
249 TS_DESCRIPTOR_TAG_STREAM_IDENTIFIER = 0x52,
250 TS_DESCRIPTOR_TAG_CA_IDENTIFIER = 0x53,
251 TS_DESCRIPTOR_TAG_CONTENT = 0x54,
252 TS_DESCRIPTOR_TAG_PARENTAL_RATING = 0x55,
253 TS_DESCRIPTOR_TAG_LOCAL_TIME_OFFSET = 0x58,
254 TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_STREAM = 0x63,
255 TS_DESCRIPTOR_TAG_HIERARCHICAL_TRANSMISSION = 0xc0,
256 TS_DESCRIPTOR_TAG_DIGITAL_COPY_CONTROL = 0xc1,
257 TS_DESCRIPTOR_TAG_NETWORK_IDENTIFICATION = 0xc2,
258 TS_DESCRIPTOR_TAG_PARTIAL_TRANSPORT_TIME = 0xc3,
259 TS_DESCRIPTOR_TAG_AUDIO_COMPONENT = 0xc4,
260 TS_DESCRIPTOR_TAG_HYPERLINK = 0xc5,
261 TS_DESCRIPTOR_TAG_TARGET_REGION = 0xc6,
262 TS_DESCRIPTOR_TAG_DATA_COTENT = 0xc7,
263 TS_DESCRIPTOR_TAG_VIDEO_DECODE_CONTROL = 0xc8,
264 TS_DESCRIPTOR_TAG_DOWNLOAD_CONTENT = 0xc9,
265 TS_DESCRIPTOR_TAG_CA_EMM_TS = 0xca,
266 TS_DESCRIPTOR_TAG_CA_CONTRACT_INFORMATION = 0xcb,
267 TS_DESCRIPTOR_TAG_CA_SERVICE = 0xcc,
268 TS_DESCRIPTOR_TAG_TS_INFORMATION = 0xcd,
269 TS_DESCRIPTOR_TAG_EXTENDED_BROADCASTER = 0xce,
270 TS_DESCRIPTOR_TAG_LOGO_TRANSMISSION = 0xcf,
271 TS_DESCRIPTOR_TAG_BASIC_LOCAL_EVENT = 0xd0,
272 TS_DESCRIPTOR_TAG_REFERENCE = 0xd1,
273 TS_DESCRIPTOR_TAG_NODE_RELATION = 0xd2,
274 TS_DESCRIPTOR_TAG_SHORT_NODE_INFORMATION = 0xd3,
275 TS_DESCRIPTOR_TAG_STC_REFERENCE = 0xd4,
276 TS_DESCRIPTOR_TAG_SERIES = 0xd5,
277 TS_DESCRIPTOR_TAG_EVENT_GROUP = 0xd6,
278 TS_DESCRIPTOR_TAG_SI_PARAMETER = 0xd7,
279 TS_DESCRIPTOR_TAG_BROADCASTER_NAME = 0xd8,
280 TS_DESCRIPTOR_TAG_COMPONENT_GROUP = 0xd9,
281 TS_DESCRIPTOR_TAG_SI_PRIME_TS = 0xda,
282 TS_DESCRIPTOR_TAG_BOARD_INFORMATION = 0xdb,
283 TS_DESCRIPTOR_TAG_LDT_LINKAGE = 0xdc,
284 TS_DESCRIPTOR_TAG_CONNECTED_TRANSMISSION = 0xdd,
285 TS_DESCRIPTOR_TAG_CONTENT_AVAILABILITY = 0xde,
286 TS_DESCRIPTOR_TAG_VALUE_EXTENSION = 0xdf,
287 TS_DESCRIPTOR_TAG_SERVICE_GROUP = 0xe0,
288 TS_DESCRIPTOR_TAG_CARUSEL_COMPOSITE = 0xf7,
289 TS_DESCRIPTOR_TAG_CONDITIONAL_PLAYBACK = 0xf8,
290 TS_DESCRIPTOR_TAG_CABLE_TS_DIVISSION = 0xf9,
291 TS_DESCRIPTOR_TAG_TERRESTRIAL_DELIVERY_SYS = 0xfa,
292 TS_DESCRIPTOR_TAG_PARTIAL_RECEPTION = 0xfb,
293 TS_DESCRIPTOR_TAG_EMERGENCY_INFOMATION = 0xfc,
294 TS_DESCRIPTOR_TAG_DATA_COMPONENT = 0xfd,
295 TS_DESCRIPTOR_TAG_SYSTEM_MANAGEMENT = 0xfe,
298 enum PID_MAP_TYPE {
299 PID_MAP_TYPE_UNKNOWN = 0x0000,
300 PID_MAP_TYPE_PAT = 0x0100,
301 PID_MAP_TYPE_PMT = 0x0200,
302 PID_MAP_TYPE_NIT = 0x0300,
303 PID_MAP_TYPE_PCR = 0x0400,
304 PID_MAP_TYPE_ECM = 0x0500,
305 PID_MAP_TYPE_EMM = 0x0600,
306 PID_MAP_TYPE_EIT = 0x0700,
307 PID_MAP_TYPE_CAT = 0x0800,
308 PID_MAP_TYPE_OTHER = 0xff00,
311 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
312 function prottypes (interface method)
313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
314 static void release_arib_std_b25(void *std_b25);
315 static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round);
316 static int set_strip_arib_std_b25(void *std_b25, int32_t strip);
317 static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on);
318 static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas);
319 static int reset_arib_std_b25(void *std_b25);
320 static int flush_arib_std_b25(void *std_b25);
321 static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf);
322 static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf);
323 static int get_program_count_arib_std_b25(void *std_b25);
324 static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx);
326 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
327 global function implementation
328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
329 ARIB_STD_B25 *create_arib_std_b25()
331 int n;
333 ARIB_STD_B25 *r;
334 ARIB_STD_B25_PRIVATE_DATA *prv;
336 n = sizeof(ARIB_STD_B25_PRIVATE_DATA);
337 n += sizeof(ARIB_STD_B25);
339 prv = (ARIB_STD_B25_PRIVATE_DATA *)calloc(1, n);
340 if(prv == NULL){
341 return NULL;
344 prv->multi2_round = 4;
346 r = (ARIB_STD_B25 *)(prv+1);
347 r->private_data = prv;
349 r->release = release_arib_std_b25;
350 r->set_multi2_round = set_multi2_round_arib_std_b25;
351 r->set_strip = set_strip_arib_std_b25;
352 r->set_emm_proc = set_emm_proc_arib_std_b25;
353 r->set_b_cas_card = set_b_cas_card_arib_std_b25;
354 r->reset = reset_arib_std_b25;
355 r->flush = flush_arib_std_b25;
356 r->put = put_arib_std_b25;
357 r->get = get_arib_std_b25;
358 r->get_program_count = get_program_count_arib_std_b25;
359 r->get_program_info = get_program_info_arib_std_b25;
361 return r;
364 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
365 function prottypes (private method)
366 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
367 static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25);
368 static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv);
369 static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv);
370 static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv);
371 static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv);
372 static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv);
373 static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv);
374 static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm);
375 static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail, int32_t ca_system_id);
376 static int32_t add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid);
377 static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv);
378 static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv);
379 static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round);
380 static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv);
382 static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv);
383 static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv);
385 static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm);
387 static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid);
389 static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid);
390 static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec);
391 static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid);
392 static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec);
393 static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv);
395 static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list);
396 static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid);
397 static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type);
398 static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem);
399 static void clear_stream_list(TS_STREAM_LIST *list);
401 static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size);
402 static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size);
403 static void reset_work_buffer(TS_WORK_BUFFER *buf);
404 static void release_work_buffer(TS_WORK_BUFFER *buf);
406 static void extract_ts_header(TS_HEADER *dst, uint8_t *src);
407 static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src);
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);
412 /* static uint32_t crc32(uint8_t *head, uint8_t *tail); */
414 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
415 interface method implementation
416 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
417 static void release_arib_std_b25(void *std_b25)
419 ARIB_STD_B25_PRIVATE_DATA *prv;
421 prv = private_data(std_b25);
422 if(prv == NULL){
423 return;
426 teardown(prv);
427 free(prv);
430 static int set_multi2_round_arib_std_b25(void *std_b25, int32_t round)
432 ARIB_STD_B25_PRIVATE_DATA *prv;
434 prv = private_data(std_b25);
435 if(prv == NULL){
436 return ARIB_STD_B25_ERROR_INVALID_PARAM;
439 prv->multi2_round = round;
441 return 0;
444 static int set_strip_arib_std_b25(void *std_b25, int32_t strip)
446 ARIB_STD_B25_PRIVATE_DATA *prv;
448 prv = private_data(std_b25);
449 if(prv == NULL){
450 return ARIB_STD_B25_ERROR_INVALID_PARAM;
453 prv->strip = strip;
455 return 0;
458 static int set_emm_proc_arib_std_b25(void *std_b25, int32_t on)
460 ARIB_STD_B25_PRIVATE_DATA *prv;
462 prv = private_data(std_b25);
463 if(prv == NULL){
464 return ARIB_STD_B25_ERROR_INVALID_PARAM;
467 prv->emm_proc_on = on;
469 return 0;
472 static int set_b_cas_card_arib_std_b25(void *std_b25, B_CAS_CARD *bcas)
474 int n;
475 B_CAS_INIT_STATUS is;
476 ARIB_STD_B25_PRIVATE_DATA *prv;
478 prv = private_data(std_b25);
479 if(prv == NULL){
480 return ARIB_STD_B25_ERROR_INVALID_PARAM;
483 prv->bcas = bcas;
484 if(prv->bcas != NULL){
485 n = prv->bcas->get_init_status(bcas, &is);
486 if(n < 0){
487 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS;
489 prv->ca_system_id = is.ca_system_id;
490 n = prv->bcas->get_id(prv->bcas, &(prv->casid));
491 if(n < 0){
492 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS;
496 return 0;
499 static int reset_arib_std_b25(void *std_b25)
501 ARIB_STD_B25_PRIVATE_DATA *prv;
503 prv = private_data(std_b25);
504 if(prv == NULL){
505 return ARIB_STD_B25_ERROR_INVALID_PARAM;
508 teardown(prv);
510 return 0;
513 static int flush_arib_std_b25(void *std_b25)
515 int r;
516 int m,n;
518 int32_t crypt;
519 int32_t unit;
520 int32_t pid;
522 uint8_t *p;
523 uint8_t *curr;
524 uint8_t *tail;
526 TS_HEADER hdr;
527 DECRYPTOR_ELEM *dec;
528 TS_PROGRAM *pgrm;
530 ARIB_STD_B25_PRIVATE_DATA *prv;
532 prv = private_data(std_b25);
533 if(prv == NULL){
534 return ARIB_STD_B25_ERROR_INVALID_PARAM;
537 if(prv->unit_size < 188){
538 r = select_unit_size(prv);
539 if(r < 0){
540 return r;
544 r = proc_arib_std_b25(prv);
545 if(r < 0){
546 return r;
549 unit = prv->unit_size;
550 curr = prv->sbuf.head;
551 tail = prv->sbuf.tail;
553 m = prv->dbuf.tail - prv->dbuf.head;
554 n = tail - curr;
555 if(!reserve_work_buffer(&(prv->dbuf), m+n)){
556 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
559 r = 0;
561 while( (curr+188) <= tail ){
563 if(curr[0] != 0x47){
564 p = resync_force(curr, tail, unit);
565 if(p == NULL){
566 goto LAST;
568 curr = p;
571 extract_ts_header(&hdr, curr);
572 crypt = hdr.transport_scrambling_control;
573 pid = hdr.pid;
575 if(hdr.transport_error_indicator != 0){
576 /* bit error - append output buffer without parsing */
577 if(!append_work_buffer(&(prv->dbuf), curr, 188)){
578 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
579 goto LAST;
581 goto NEXT;
584 if( (pid == 0x1fff) && (prv->strip) ){
585 goto NEXT;
588 p = curr+4;
589 if(hdr.adaptation_field_control & 0x02){
590 p += (p[0]+1);
592 n = 188 - (p-curr);
593 if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){
594 /* broken packet */
595 curr += 1;
596 continue;
599 if( (crypt != 0) &&
600 (hdr.adaptation_field_control & 0x01) ){
602 if(prv->map[pid].type == PID_MAP_TYPE_OTHER){
603 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
604 }else if( (prv->map[pid].type == 0) &&
605 (prv->decrypt.count == 1) ){
606 dec = prv->decrypt.head;
607 }else{
608 dec = NULL;
611 if( (dec != NULL) && (dec->m2 != NULL) ){
612 m = dec->m2->decrypt(dec->m2, crypt, p, n);
613 if(m < 0){
614 r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE;
615 goto LAST;
617 curr[3] &= 0x3f;
618 prv->map[pid].normal_packet += 1;
619 }else{
620 prv->map[pid].undecrypted += 1;
622 }else{
623 prv->map[pid].normal_packet += 1;
626 if(!append_work_buffer(&(prv->dbuf), curr, 188)){
627 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
628 goto LAST;
631 if(prv->map[pid].type == PID_MAP_TYPE_ECM){
632 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
633 if( (dec == NULL) || (dec->ecm == NULL) ){
634 /* this code will never execute */
635 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
636 goto LAST;
638 m = dec->ecm->put(dec->ecm, &hdr, p, n);
639 if(m < 0){
640 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
641 goto LAST;
643 m = dec->ecm->get_count(dec->ecm);
644 if(m < 0){
645 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
646 goto LAST;
648 if(m == 0){
649 goto NEXT;
651 r = proc_ecm(dec, prv->bcas, prv->multi2_round);
652 if(r < 0){
653 goto LAST;
655 }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){
656 pgrm = (TS_PROGRAM *)(prv->map[pid].target);
657 if( (pgrm == NULL) || (pgrm->pmt == NULL) ){
658 /* this code will never execute */
659 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
660 goto LAST;
662 m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n);
663 if(m < 0){
664 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
665 goto LAST;
667 m = pgrm->pmt->get_count(pgrm->pmt);
668 if(m < 0){
669 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
670 goto LAST;
672 if(m == 0){
673 goto NEXT;
675 r = proc_pmt(prv, pgrm);
676 if(r < 0){
677 goto LAST;
679 }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){
680 if( prv->emm_proc_on == 0){
681 goto NEXT;
683 if( prv->emm == NULL ){
684 prv->emm = create_ts_section_parser();
685 if(prv->emm == NULL){
686 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
687 goto LAST;
690 m = prv->emm->put(prv->emm, &hdr, p, n);
691 if(m < 0){
692 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
693 goto LAST;
695 m = prv->emm->get_count(prv->emm);
696 if(m < 0){
697 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
698 goto LAST;
700 if(m == 0){
701 goto NEXT;
703 r = proc_emm(prv);
704 if(r < 0){
705 goto LAST;
707 }else if(pid == 0x0001){
708 if( prv->cat == NULL ){
709 prv->cat = create_ts_section_parser();
710 if(prv->cat == NULL){
711 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
712 goto LAST;
715 m = prv->cat->put(prv->cat, &hdr, p, n);
716 if(m < 0){
717 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
718 goto LAST;
720 m = prv->cat->get_count(prv->cat);
721 if(m < 0){
722 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
723 goto LAST;
725 if(m == 0){
726 goto NEXT;
728 r = proc_cat(prv);
729 if(r < 0){
730 goto LAST;
732 }else if(pid == 0x0000){
733 if( prv->pat == NULL ){
734 prv->pat = create_ts_section_parser();
735 if(prv->pat == NULL){
736 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
737 goto LAST;
740 m = prv->pat->put(prv->pat, &hdr, p, n);
741 if(m < 0){
742 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
743 goto LAST;
745 m = prv->pat->get_count(prv->pat);
746 if(m < 0){
747 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
748 goto LAST;
750 if(m == 0){
751 goto NEXT;
753 r = proc_pat(prv);
754 if(r < 0){
755 goto LAST;
759 NEXT:
760 curr += unit;
763 LAST:
765 m = curr - prv->sbuf.head;
766 n = tail - curr;
767 if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){
768 p = prv->sbuf.pool;
769 memcpy(p, curr, n);
770 prv->sbuf.head = p;
771 prv->sbuf.tail = p+n;
772 }else{
773 prv->sbuf.head = curr;
776 return r;
779 static int put_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf)
781 int32_t n;
783 ARIB_STD_B25_PRIVATE_DATA *prv;
785 prv = private_data(std_b25);
786 if( (prv == NULL) || (buf == NULL) ){
787 return ARIB_STD_B25_ERROR_INVALID_PARAM;
790 if(!append_work_buffer(&(prv->sbuf), buf->data, buf->size)){
791 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
794 if(prv->unit_size < 188){
795 n = select_unit_size(prv);
796 if(n < 0){
797 return n;
799 if(prv->unit_size < 188){
800 /* need more data */
801 return 0;
805 if(prv->p_count < 1){
806 n = find_pat(prv);
807 if(n < 0){
808 return n;
810 if(prv->p_count < 1){
811 if(prv->sbuf_offset < (16*1024*1024)){
812 /* need more data */
813 return 0;
814 }else{
815 /* exceed sbuf limit */
816 return ARIB_STD_B25_ERROR_NO_PAT_IN_HEAD_16M;
819 prv->sbuf_offset = 0;
822 if(!check_pmt_complete(prv)){
823 n = find_pmt(prv);
824 if(n < 0){
825 return n;
827 if(!check_pmt_complete(prv)){
828 if(prv->sbuf_offset < (32*1024*1024)){
829 /* need more data */
830 return 0;
831 }else{
832 /* exceed sbuf limit */
833 return ARIB_STD_B25_ERROR_NO_PMT_IN_HEAD_32M;
836 prv->sbuf_offset = 0;
839 if(!check_ecm_complete(prv)){
840 n = find_ecm(prv);
841 if(n < 0){
842 return n;
844 if(!check_ecm_complete(prv)){
845 if(prv->sbuf_offset < (32*1024*1024)){
846 /* need more data */
847 return 0;
848 }else{
849 /* exceed sbuf limit */
850 return ARIB_STD_B25_ERROR_NO_ECM_IN_HEAD_32M;
853 prv->sbuf_offset = 0;
856 return proc_arib_std_b25(prv);
859 static int get_arib_std_b25(void *std_b25, ARIB_STD_B25_BUFFER *buf)
861 ARIB_STD_B25_PRIVATE_DATA *prv;
862 prv = private_data(std_b25);
863 if( (prv == NULL) || (buf == NULL) ){
864 return ARIB_STD_B25_ERROR_INVALID_PARAM;
867 buf->data = prv->dbuf.head;
868 buf->size = prv->dbuf.tail - prv->dbuf.head;
870 reset_work_buffer(&(prv->dbuf));
872 return 0;
875 static int get_program_count_arib_std_b25(void *std_b25)
877 ARIB_STD_B25_PRIVATE_DATA *prv;
879 prv = private_data(std_b25);
880 if(prv == NULL){
881 return ARIB_STD_B25_ERROR_INVALID_PARAM;
884 return prv->p_count;
887 static int get_program_info_arib_std_b25(void *std_b25, ARIB_STD_B25_PROGRAM_INFO *info, int idx)
889 ARIB_STD_B25_PRIVATE_DATA *prv;
891 TS_PROGRAM *pgrm;
893 TS_STREAM_ELEM *strm;
894 DECRYPTOR_ELEM *dec;
896 int32_t pid;
898 prv = private_data(std_b25);
899 if( (prv == NULL) || (info == NULL) || (idx < 0) || (idx >= prv->p_count) ){
900 return ARIB_STD_B25_ERROR_INVALID_PARAM;
903 pgrm = prv->program + idx;
905 memset(info, 0, sizeof(ARIB_STD_B25_PROGRAM_INFO));
907 info->program_number = pgrm->program_number;
909 pid = pgrm->pmt_pid;
910 info->total_packet_count += prv->map[pid].normal_packet;
911 info->total_packet_count += prv->map[pid].undecrypted;
912 info->undecrypted_packet_count += prv->map[pid].undecrypted;
914 pid = pgrm->pcr_pid;
915 if( (pid != 0) && (pid != 0x1fff) ){
916 info->total_packet_count += prv->map[pid].normal_packet;
917 info->total_packet_count += prv->map[pid].undecrypted;
918 info->undecrypted_packet_count += prv->map[pid].undecrypted;
921 strm = pgrm->streams.head;
922 while(strm != NULL){
923 pid = strm->pid;
924 if(prv->map[pid].type == PID_MAP_TYPE_ECM){
925 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
926 info->ecm_unpurchased_count += dec->unpurchased;
927 info->last_ecm_error_code = dec->last_error;
929 info->total_packet_count += prv->map[pid].normal_packet;
930 info->total_packet_count += prv->map[pid].undecrypted;
931 info->undecrypted_packet_count += prv->map[pid].undecrypted;
932 strm = (TS_STREAM_ELEM *)(strm->next);
935 return 0;
938 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
939 private method implementation
940 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
941 static ARIB_STD_B25_PRIVATE_DATA *private_data(void *std_b25)
943 ARIB_STD_B25 *p;
944 ARIB_STD_B25_PRIVATE_DATA *r;
946 p = (ARIB_STD_B25 *)std_b25;
947 if(p == NULL){
948 return NULL;
951 r = (ARIB_STD_B25_PRIVATE_DATA *)p->private_data;
952 if( ((void *)(r+1)) != ((void *)p) ){
953 return NULL;
956 return r;
959 static void teardown(ARIB_STD_B25_PRIVATE_DATA *prv)
961 int i;
963 prv->unit_size = 0;
964 prv->sbuf_offset = 0;
966 if(prv->pat != NULL){
967 prv->pat->release(prv->pat);
968 prv->pat = NULL;
970 if(prv->cat != NULL){
971 prv->cat->release(prv->cat);
972 prv->cat = NULL;
975 if(prv->program != NULL){
976 for(i=0;i<prv->p_count;i++){
977 release_program(prv, prv->program+i);
979 free(prv->program);
980 prv->program = NULL;
982 prv->p_count = 0;
984 clear_stream_list(&(prv->strm_pool));
986 while(prv->decrypt.head != NULL){
987 remove_decryptor(prv, prv->decrypt.head);
990 memset(prv->map, 0, sizeof(prv->map));
992 prv->emm_pid = 0;
993 if(prv->emm != NULL){
994 prv->emm->release(prv->emm);
995 prv->emm = NULL;
998 release_work_buffer(&(prv->sbuf));
999 release_work_buffer(&(prv->dbuf));
1002 static int select_unit_size(ARIB_STD_B25_PRIVATE_DATA *prv)
1004 int i;
1005 int m,n,w;
1006 int count[320-188];
1008 unsigned char *head;
1009 unsigned char *buf;
1010 unsigned char *tail;
1012 head = prv->sbuf.head;
1013 tail = prv->sbuf.tail;
1015 buf = head;
1016 memset(count, 0, sizeof(count));
1018 // 1st step, count up 0x47 interval
1019 while( (buf+188) < tail ){
1020 if(buf[0] != 0x47){
1021 buf += 1;
1022 continue;
1024 m = 320;
1025 if( buf+m > tail ){
1026 m = tail-buf;
1028 for(i=188;i<m;i++){
1029 if(buf[i] == 0x47){
1030 count[i-188] += 1;
1033 buf += 1;
1036 // 2nd step, select maximum appeared interval
1037 m = 0;
1038 n = 0;
1039 for(i=188;i<320;i++){
1040 if(m < count[i-188]){
1041 m = count[i-188];
1042 n = i;
1046 // 3rd step, verify unit_size
1047 w = m*n;
1048 if( (m < 8) || ((w+3*n) < (tail-head)) ){
1049 return ARIB_STD_B25_ERROR_NON_TS_INPUT_STREAM;
1052 prv->unit_size = n;
1054 return 0;
1057 static int find_pat(ARIB_STD_B25_PRIVATE_DATA *prv)
1059 int r;
1060 int n,size;
1062 int32_t unit;
1064 uint8_t *p;
1065 uint8_t *curr;
1066 uint8_t *tail;
1068 TS_HEADER hdr;
1070 r = 0;
1071 unit = prv->unit_size;
1072 curr = prv->sbuf.head + prv->sbuf_offset;
1073 tail = prv->sbuf.tail;
1075 while( (curr+unit) < tail ){
1076 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){
1077 p = resync(curr, tail, unit);
1078 if(p == NULL){
1079 goto LAST;
1081 curr = p;
1083 extract_ts_header(&hdr, curr);
1084 if(hdr.pid == 0x0000){
1086 p = curr+4;
1087 if(hdr.adaptation_field_control & 0x02){
1088 p += (p[0]+1);
1090 size = 188 - (p-curr);
1091 if(size < 1){
1092 goto NEXT;
1095 if(prv->pat == NULL){
1096 prv->pat = create_ts_section_parser();
1097 if(prv->pat == NULL){
1098 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1102 n = prv->pat->put(prv->pat, &hdr, p, size);
1103 if(n < 0){
1104 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
1105 curr += unit;
1106 goto LAST;
1108 n = prv->pat->get_count(prv->pat);
1109 if(n < 0){
1110 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
1111 curr += unit;
1112 goto LAST;
1114 if(n > 0){
1115 curr += unit;
1116 goto LAST;
1119 NEXT:
1120 curr += unit;
1123 LAST:
1124 prv->sbuf_offset = curr - prv->sbuf.head;
1126 if( (prv->pat != NULL) && (prv->pat->get_count(prv->pat) > 0) ){
1127 r = proc_pat(prv);
1130 return r;
1133 static int proc_pat(ARIB_STD_B25_PRIVATE_DATA *prv)
1135 int r;
1136 int i,n;
1137 int len;
1138 int count;
1140 int32_t program_number;
1141 int32_t pid;
1143 uint8_t *head;
1144 uint8_t *tail;
1146 TS_PROGRAM *work;
1147 TS_SECTION sect;
1149 r = 0;
1150 memset(&sect, 0, sizeof(sect));
1152 n = prv->pat->get(prv->pat, &sect);
1153 if(n < 0){
1154 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
1155 goto LAST;
1158 if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_ASSOCIATION){
1159 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH;
1160 goto LAST;
1163 len = (sect.tail - sect.data) - 4;
1165 count = len / 4;
1166 work = (TS_PROGRAM *)calloc(count, sizeof(TS_PROGRAM));
1167 if(work == NULL){
1168 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1169 goto LAST;
1172 if(prv->program != NULL){
1173 for(i=0;i<prv->p_count;i++){
1174 release_program(prv, prv->program+i);
1176 free(prv->program);
1177 prv->program = NULL;
1179 prv->p_count = 0;
1180 memset(&(prv->map), 0, sizeof(prv->map));
1182 head = sect.data;
1183 tail = sect.tail-4;
1185 i = 0;
1186 while( (head+4) <= tail ){
1187 program_number = ((head[0] << 8) | head[1]);
1188 pid = ((head[2] << 8) | head[3]) & 0x1fff;
1189 if(program_number != 0){
1190 work[i].program_number = program_number;
1191 work[i].pmt_pid = pid;
1192 work[i].pmt = create_ts_section_parser();
1193 if(work[i].pmt == NULL){
1194 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1195 break;
1197 prv->map[pid].type = PID_MAP_TYPE_PMT;
1198 prv->map[pid].target = work+i;
1199 i += 1;
1201 head += 4;
1204 prv->program = work;
1205 prv->p_count = i;
1207 prv->map[0x0000].ref = 1;
1208 prv->map[0x0000].type = PID_MAP_TYPE_PAT;
1209 prv->map[0x0000].target = NULL;
1211 LAST:
1212 if(sect.raw != NULL){
1213 n = prv->pat->ret(prv->pat, &sect);
1214 if( (n < 0) && (r == 0) ){
1215 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
1219 return r;
1222 static int check_pmt_complete(ARIB_STD_B25_PRIVATE_DATA *prv)
1224 int i,n;
1225 int num[3];
1227 memset(num, 0, sizeof(num));
1229 for(i=0;i<prv->p_count;i++){
1230 n = prv->program[i].phase;
1231 if(n < 0){
1232 n = 0;
1233 }else if(n > 2){
1234 n = 2;
1236 num[n] += 1;
1239 if(num[2] > 0){
1240 return 1;
1243 if(num[0] > 0){
1244 return 0;
1247 return 1;
1250 static int find_pmt(ARIB_STD_B25_PRIVATE_DATA *prv)
1252 int r;
1253 int n,size;
1255 int32_t unit;
1257 uint8_t *p;
1258 uint8_t *curr;
1259 uint8_t *tail;
1261 TS_HEADER hdr;
1262 TS_PROGRAM *pgrm;
1264 r = 0;
1265 unit = prv->unit_size;
1266 curr = prv->sbuf.head + prv->sbuf_offset;
1267 tail = prv->sbuf.tail;
1269 while( (curr+unit) < tail ){
1271 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){
1272 p = resync(curr, tail, unit);
1273 if(p == NULL){
1274 goto LAST;
1276 curr = p;
1279 extract_ts_header(&hdr, curr);
1281 if(prv->map[hdr.pid].type != PID_MAP_TYPE_PMT){
1282 goto NEXT;
1284 pgrm = (TS_PROGRAM *)(prv->map[hdr.pid].target);
1285 if(pgrm == NULL){
1286 goto NEXT;
1289 if(pgrm->phase == 0){
1291 p = curr + 4;
1292 if(hdr.adaptation_field_control & 0x02){
1293 p += (p[0]+1);
1295 size = 188 - (p-curr);
1296 if(size < 1){
1297 goto NEXT;
1300 if(pgrm->pmt == NULL){
1301 /* this code will never execute */
1302 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1303 curr += unit;
1304 goto LAST;
1307 n = pgrm->pmt->put(pgrm->pmt, &hdr, p, size);
1308 if(n < 0){
1309 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1310 curr += unit;
1311 goto LAST;
1313 n = pgrm->pmt->get_count(pgrm->pmt);
1314 if(n < 0){
1315 r =ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1316 curr += unit;
1317 goto LAST;
1319 if(n == 0){
1320 goto NEXT;
1322 r = proc_pmt(prv, pgrm);
1323 if(r < 0){
1324 curr += unit;
1325 goto LAST;
1327 if(r > 0){
1328 /* broken or unexpected section data */
1329 goto NEXT;
1331 pgrm->phase = 1;
1332 if(check_pmt_complete(prv)){
1333 curr += unit;
1334 goto LAST;
1336 }else{
1337 pgrm->phase = 2;
1338 curr += unit;
1339 goto LAST;
1342 NEXT:
1343 curr += unit;
1346 LAST:
1347 prv->sbuf_offset = curr - prv->sbuf.head;
1349 return r;
1352 static int proc_pmt(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm)
1354 int r;
1356 int n;
1357 int length;
1359 uint8_t *head;
1360 uint8_t *tail;
1362 int32_t ecm_pid;
1363 int32_t pid;
1364 int32_t type;
1366 TS_SECTION sect;
1368 DECRYPTOR_ELEM *dec[2];
1369 DECRYPTOR_ELEM *dw;
1371 TS_STREAM_ELEM *strm;
1373 r = 0;
1374 dec[0] = NULL;
1375 memset(&sect, 0, sizeof(sect));
1377 n = pgrm->pmt->get(pgrm->pmt, &sect);
1378 if(n < 0){
1379 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1380 goto LAST;
1382 if(sect.hdr.table_id != TS_SECTION_ID_PROGRAM_MAP){
1383 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH;
1384 goto LAST;
1387 head = sect.data;
1388 tail = sect.tail-4;
1390 pgrm->pcr_pid = ((head[0] << 8) | head[1]) & 0x1fff;
1391 length = ((head[2] << 8) | head[3]) & 0x0fff;
1392 head += 4;
1393 if(head+length > tail){
1394 r = ARIB_STD_B25_WARN_BROKEN_TS_SECTION;
1395 goto LAST;
1398 /* find major ecm_pid and regist decryptor */
1399 ecm_pid = find_ca_descriptor_pid(head, head+length, prv->ca_system_id);
1400 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){
1401 dec[0] = set_decryptor(prv, ecm_pid);
1402 if(dec[0] == NULL){
1403 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1404 goto LAST;
1406 dec[0]->ref += 1;
1407 } else {
1408 if (prv->decrypt.count == 1) {
1409 dec[0] = prv->decrypt.head;
1410 dec[0]->ref += 1;
1413 head += length;
1416 /* unref old stream entries */
1417 while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){
1418 unref_stream(prv, strm->pid);
1419 memset(strm, 0, sizeof(TS_STREAM_ELEM));
1420 put_stream_list_tail(&(prv->strm_pool), strm);
1423 /* save current streams */
1424 memcpy(&(pgrm->old_strm), &(pgrm->streams), sizeof(TS_STREAM_LIST));
1425 memset(&(pgrm->streams), 0, sizeof(TS_STREAM_LIST));
1427 /* add current stream entries */
1428 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){
1429 if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){
1430 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1431 goto LAST;
1435 while( head+4 < tail ){
1437 type = head[0];
1438 pid = ((head[1] << 8) | head[2]) & 0x1fff;
1439 length = ((head[3] << 8) | head[4]) & 0x0fff;
1440 head += 5;
1441 ecm_pid = find_ca_descriptor_pid(head, head+length, prv->ca_system_id);
1442 head += length;
1444 if( (ecm_pid != 0) && (ecm_pid != 0x1fff) ){
1445 dec[1] = set_decryptor(prv, ecm_pid);
1446 if(dec[1] == NULL){
1447 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1448 goto LAST;
1450 if(!add_ecm_stream(prv, &(pgrm->streams), ecm_pid)){
1451 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1452 goto LAST;
1454 }else{
1455 dec[1] = NULL;
1458 strm = get_stream_list_head(&(prv->strm_pool));
1459 if( strm == NULL ){
1460 strm = create_stream_elem(pid, type);
1461 if(strm == NULL){
1462 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1463 goto LAST;
1465 }else{
1466 strm->pid = pid;
1467 strm->type = type;
1470 prv->map[pid].type = PID_MAP_TYPE_OTHER;
1471 prv->map[pid].ref += 1;
1473 dw = select_active_decryptor(dec[0], dec[1], ecm_pid);
1474 bind_stream_decryptor(prv, pid, dw);
1476 put_stream_list_tail(&(pgrm->streams), strm);
1479 LAST:
1480 if( dec[0] != NULL ){
1481 dec[0]->ref -= 1;
1482 if( dec[0]->ref < 1 ){
1483 remove_decryptor(prv, dec[0]);
1484 dec[0] = NULL;
1488 if(sect.raw != NULL){
1489 n = pgrm->pmt->ret(pgrm->pmt, &sect);
1490 if( (n < 0) && (r == 0) ){
1491 return ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1495 return r;
1498 static int32_t find_ca_descriptor_pid(uint8_t *head, uint8_t *tail, int32_t ca_system_id)
1500 uint32_t ca_pid;
1501 uint32_t ca_sys_id;
1503 uint32_t tag;
1504 uint32_t len;
1506 while(head+1 < tail){
1507 tag = head[0];
1508 len = head[1];
1509 head += 2;
1510 if( (tag == 0x09) && /* CA_descriptor */
1511 (len >= 4) &&
1512 (head+len <= tail) ){
1513 ca_sys_id = ((head[0] << 8) | head[1]);
1514 ca_pid = ((head[2] << 8) | head[3]) & 0x1fff;
1515 if(ca_sys_id == ca_system_id){
1516 return ca_pid;
1519 head += len;
1522 return 0;
1525 static int add_ecm_stream(ARIB_STD_B25_PRIVATE_DATA *prv, TS_STREAM_LIST *list, int32_t ecm_pid)
1527 TS_STREAM_ELEM *strm;
1529 strm = find_stream_list_elem(list, ecm_pid);
1530 if(strm != NULL){
1531 // ECM is already registered
1532 return 1;
1535 strm = get_stream_list_head(&(prv->strm_pool));
1536 if(strm == NULL){
1537 strm = create_stream_elem(ecm_pid, PID_MAP_TYPE_ECM);
1538 if(strm == NULL){
1539 return 0;
1541 }else{
1542 strm->pid = ecm_pid;
1543 strm->type = PID_MAP_TYPE_ECM;
1546 put_stream_list_tail(list, strm);
1547 prv->map[ecm_pid].ref += 1;
1549 return 1;
1552 static int check_ecm_complete(ARIB_STD_B25_PRIVATE_DATA *prv)
1554 int n,num[3];
1555 DECRYPTOR_ELEM *e;
1557 memset(num, 0, sizeof(num));
1559 e = prv->decrypt.head;
1560 while( e != NULL ){
1561 n = e->phase;
1562 if(n < 0){
1563 n = 0;
1564 }else if(n > 2){
1565 n = 2;
1567 num[n] += 1;
1568 e = (DECRYPTOR_ELEM *)(e->next);
1571 if(num[2] > 0){
1572 return 1;
1575 if(num[0] > 0){
1576 return 0;
1579 return 1;
1582 static int find_ecm(ARIB_STD_B25_PRIVATE_DATA *prv)
1584 int r;
1585 int n,size;
1587 int32_t unit;
1589 uint8_t *p;
1590 uint8_t *curr;
1591 uint8_t *tail;
1593 TS_HEADER hdr;
1594 DECRYPTOR_ELEM *dec;
1596 r = 0;
1597 unit = prv->unit_size;
1598 curr = prv->sbuf.head + prv->sbuf_offset;
1599 tail = prv->sbuf.tail;
1601 while( (curr+unit) < tail ){
1602 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){
1603 p = resync(curr, tail, unit);
1604 if(p == NULL){
1605 goto LAST;
1607 curr = p;
1609 extract_ts_header(&hdr, curr);
1610 if(prv->map[hdr.pid].type != PID_MAP_TYPE_ECM){
1611 goto NEXT;
1613 dec = (DECRYPTOR_ELEM *)(prv->map[hdr.pid].target);
1614 if(dec == NULL){
1615 goto NEXT;
1618 if(dec->phase == 0){
1620 p = curr + 4;
1621 if(hdr.adaptation_field_control & 0x02){
1622 p += (p[0]+1);
1624 size = 188 - (p-curr);
1625 if(size < 1){
1626 goto NEXT;
1629 if(dec->ecm == NULL){
1630 /* this code will never execute */
1631 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1632 curr += unit;
1633 goto LAST;
1636 n = dec->ecm->put(dec->ecm, &hdr, p, size);
1637 if(n < 0){
1638 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1639 curr += unit;
1640 goto LAST;
1642 n = dec->ecm->get_count(dec->ecm);
1643 if(n < 0){
1644 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1645 curr += unit;
1646 goto LAST;
1648 if(n == 0){
1649 goto NEXT;
1652 r = proc_ecm(dec, prv->bcas, prv->multi2_round);
1653 if(r < 0){
1654 curr += unit;
1655 goto LAST;
1657 if( (r > 0) && (r != ARIB_STD_B25_WARN_UNPURCHASED_ECM) ){
1658 /* broken or unexpected section data */
1659 goto NEXT;
1662 dec->phase = 1;
1663 if(check_ecm_complete(prv)){
1664 curr += unit;
1665 goto LAST;
1668 }else{
1669 dec->phase = 2;
1670 curr += unit;
1671 goto LAST;
1674 NEXT:
1675 curr += unit;
1678 LAST:
1679 prv->sbuf_offset = curr - prv->sbuf.head;
1681 return r;
1684 static int proc_ecm(DECRYPTOR_ELEM *dec, B_CAS_CARD *bcas, int32_t multi2_round)
1686 int r,n;
1687 int length;
1689 uint8_t *p;
1691 B_CAS_INIT_STATUS is;
1692 B_CAS_ECM_RESULT res;
1694 TS_SECTION sect;
1696 r = 0;
1697 memset(&sect, 0, sizeof(sect));
1699 if(bcas == NULL){
1700 r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD;
1701 goto LAST;
1704 n = dec->ecm->get(dec->ecm, &sect);
1705 if(n < 0){
1706 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1707 goto LAST;
1709 if(sect.hdr.table_id != TS_SECTION_ID_ECM_S){
1710 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH;
1711 goto LAST;
1714 if(dec->locked){
1715 /* previous ECM has returned unpurchased
1716 skip this pid for B-CAS card load reduction */
1717 dec->unpurchased += 1;
1718 r = ARIB_STD_B25_WARN_UNPURCHASED_ECM;
1719 goto LAST;
1722 length = (sect.tail - sect.data) - 4;
1723 p = sect.data;
1725 r = bcas->proc_ecm(bcas, &res, p, length);
1726 if(r < 0){
1727 if(dec->m2 != NULL){
1728 dec->m2->clear_scramble_key(dec->m2);
1730 r = ARIB_STD_B25_ERROR_ECM_PROC_FAILURE;
1731 goto LAST;
1734 if( (res.return_code != 0x0800) &&
1735 (res.return_code != 0x0400) &&
1736 (res.return_code != 0x0200) ){
1737 /* return_code is not equal "purchased" */
1738 if(dec->m2 != NULL){
1739 dec->m2->release(dec->m2);
1740 dec->m2 = NULL;
1742 dec->unpurchased += 1;
1743 dec->last_error = res.return_code;
1744 dec->locked += 1;
1745 r = ARIB_STD_B25_WARN_UNPURCHASED_ECM;
1746 goto LAST;
1749 if(dec->m2 == NULL){
1750 dec->m2 = create_multi2();
1751 if(dec->m2 == NULL){
1752 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1754 r = bcas->get_init_status(bcas, &is);
1755 if(r < 0){
1756 return ARIB_STD_B25_ERROR_INVALID_B_CAS_STATUS;
1758 dec->m2->set_system_key(dec->m2, is.system_key);
1759 dec->m2->set_init_cbc(dec->m2, is.init_cbc);
1760 dec->m2->set_round(dec->m2, multi2_round);
1763 dec->m2->set_scramble_key(dec->m2, res.scramble_key);
1765 if (0) {
1766 int i;
1767 fprintf(stdout, "----\n");
1768 fprintf(stdout, "odd: ");
1769 for(i=0;i<8;i++){
1770 fprintf(stdout, " %02x", res.scramble_key[i]);
1772 fprintf(stdout, "\n");
1773 fprintf(stdout, "even:");
1774 for(i=8;i<16;i++){
1775 fprintf(stdout, " %02x", res.scramble_key[i]);
1777 fprintf(stdout, "\n");
1778 fflush(stdout);
1781 LAST:
1782 if(sect.raw != NULL){
1783 n = dec->ecm->ret(dec->ecm, &sect);
1784 if( (n < 0) && (r == 0) ){
1785 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1789 return r;
1792 static void dump_pts(uint8_t *src, int32_t crypt)
1794 int32_t pts_dts_flag;
1795 int64_t pts,dts;
1797 src += 4; // TS ヘッダ部
1798 src += 4; // start_code_prefix + stream_id 部
1799 src += 2; // packet_length 部
1801 pts_dts_flag = (src[1] >> 6) & 3;
1803 src += 3;
1804 if(pts_dts_flag & 2){
1805 // PTS
1806 pts = (src[0] >> 1) & 0x07;
1807 pts <<= 15;
1808 pts += ((src[1] << 8) + src[2]) >> 1;
1809 pts <<= 15;
1810 pts += ((src[3] << 8) + src[4]) >> 1;
1811 src += 5;
1813 if(pts_dts_flag & 1){
1814 // DTS
1815 dts = (src[0] >> 1) & 0x07;
1816 dts <<= 15;
1817 dts += ((src[1] << 8) + src[2]) >> 1;
1818 dts <<= 15;
1819 dts += ((src[3] << 8) + src[4]) >> 1;
1822 if(pts_dts_flag == 2){
1823 fprintf(stdout, " key=%d, pts=%"PRId64"\n", crypt, pts/90);
1824 fflush(stdout);
1828 static int proc_arib_std_b25(ARIB_STD_B25_PRIVATE_DATA *prv)
1830 int r;
1831 int m,n;
1833 int32_t crypt;
1834 int32_t unit;
1835 int32_t pid;
1837 uint8_t *p;
1838 uint8_t *curr;
1839 uint8_t *tail;
1841 TS_HEADER hdr;
1842 DECRYPTOR_ELEM *dec;
1843 TS_PROGRAM *pgrm;
1845 unit = prv->unit_size;
1846 curr = prv->sbuf.head;
1847 tail = prv->sbuf.tail;
1849 m = prv->dbuf.tail - prv->dbuf.head;
1850 n = tail - curr;
1851 if(!reserve_work_buffer(&(prv->dbuf), m+n)){
1852 return ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1855 r = 0;
1857 while( (curr+unit) < tail ){
1859 if( (curr[0] != 0x47) || (curr[unit] != 0x47) ){
1860 p = resync(curr, tail, unit);
1861 if(p == NULL){
1862 goto LAST;
1864 curr = p;
1867 extract_ts_header(&hdr, curr);
1868 crypt = hdr.transport_scrambling_control;
1869 pid = hdr.pid;
1871 if(hdr.transport_error_indicator != 0){
1872 /* bit error - append output buffer without parsing */
1873 if(!append_work_buffer(&(prv->dbuf), curr, 188)){
1874 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1875 goto LAST;
1877 goto NEXT;
1880 if( (pid == 0x1fff) && (prv->strip) ){
1881 /* strip null(padding) stream */
1882 goto NEXT;
1885 p = curr+4;
1886 if(hdr.adaptation_field_control & 0x02){
1887 p += (p[0]+1);
1889 n = 188 - (p-curr);
1890 if( (n < 1) && ((n < 0) || (hdr.adaptation_field_control & 0x01)) ){
1891 /* broken packet */
1892 curr += 1;
1893 continue;
1896 if( (crypt != 0) &&
1897 (hdr.adaptation_field_control & 0x01) ){
1899 if(prv->map[pid].type == PID_MAP_TYPE_OTHER){
1900 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
1901 }else if( (prv->map[pid].type == 0) &&
1902 (prv->decrypt.count == 1) ){
1903 dec = prv->decrypt.head;
1904 }else{
1905 dec = NULL;
1908 if( (dec != NULL) && (dec->m2 != NULL) ){
1909 m = dec->m2->decrypt(dec->m2, crypt, p, n);
1910 if(m < 0){
1911 r = ARIB_STD_B25_ERROR_DECRYPT_FAILURE;
1912 goto LAST;
1914 curr[3] &= 0x3f;
1915 prv->map[pid].normal_packet += 1;
1916 }else{
1917 prv->map[pid].undecrypted += 1;
1919 }else{
1920 prv->map[pid].normal_packet += 1;
1922 #if 0
1923 if( (hdr.payload_unit_start_indicator != 0) && (pid == 0x111) ){
1924 dump_pts(curr, crypt);
1926 #endif
1927 if(!append_work_buffer(&(prv->dbuf), curr, 188)){
1928 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
1929 goto LAST;
1932 if(prv->map[pid].type == PID_MAP_TYPE_ECM){
1933 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
1934 if( (dec == NULL) || (dec->ecm == NULL) ){
1935 /* this code will never execute */
1936 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1937 goto LAST;
1939 m = dec->ecm->put(dec->ecm, &hdr, p, n);
1940 if(m < 0){
1941 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1942 goto LAST;
1944 m = dec->ecm->get_count(dec->ecm);
1945 if(m < 0){
1946 r = ARIB_STD_B25_ERROR_ECM_PARSE_FAILURE;
1947 goto LAST;
1949 if(m == 0){
1950 goto NEXT;
1952 r = proc_ecm(dec, prv->bcas, prv->multi2_round);
1953 if(r < 0){
1954 goto LAST;
1956 }else if(prv->map[pid].type == PID_MAP_TYPE_PMT){
1957 pgrm = (TS_PROGRAM *)(prv->map[pid].target);
1958 if( (pgrm == NULL) || (pgrm->pmt == NULL) ){
1959 /* this code will never execute */
1960 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1961 goto LAST;
1963 m = pgrm->pmt->put(pgrm->pmt, &hdr, p, n);
1964 if(m < 0){
1965 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1966 goto LAST;
1968 m = pgrm->pmt->get_count(pgrm->pmt);
1969 if(m < 0){
1970 r = ARIB_STD_B25_ERROR_PMT_PARSE_FAILURE;
1971 goto LAST;
1973 if(m == 0){
1974 goto NEXT;
1976 r = proc_pmt(prv, pgrm);
1977 if(r < 0){
1978 goto LAST;
1980 }else if(prv->map[pid].type == PID_MAP_TYPE_EMM){
1981 if( prv->emm_proc_on == 0){
1982 goto NEXT;
1984 if( prv->emm == NULL ){
1985 prv->emm = create_ts_section_parser();
1986 if(prv->emm == NULL){
1987 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
1988 goto LAST;
1991 m = prv->emm->put(prv->emm, &hdr, p, n);
1992 if(m < 0){
1993 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
1994 goto LAST;
1996 m = prv->emm->get_count(prv->emm);
1997 if(m < 0){
1998 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
1999 goto LAST;
2001 if(m == 0){
2002 goto NEXT;
2004 r = proc_emm(prv);
2005 if(r < 0){
2006 goto LAST;
2008 }else if(pid == 0x0001){
2009 if( prv->cat == NULL ){
2010 prv->cat = create_ts_section_parser();
2011 if(prv->cat == NULL){
2012 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
2013 goto LAST;
2016 m = prv->cat->put(prv->cat, &hdr, p, n);
2017 if(m < 0){
2018 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
2019 goto LAST;
2021 m = prv->cat->get_count(prv->cat);
2022 if(m < 0){
2023 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
2024 goto LAST;
2026 if(m == 0){
2027 goto NEXT;
2029 r = proc_cat(prv);
2030 if(r < 0){
2031 goto LAST;
2033 }else if(pid == 0x0000){
2034 if( prv->pat == NULL ){
2035 prv->pat = create_ts_section_parser();
2036 if(prv->pat == NULL){
2037 r = ARIB_STD_B25_ERROR_NO_ENOUGH_MEMORY;
2038 goto LAST;
2041 m = prv->pat->put(prv->pat, &hdr, p, n);
2042 if(m < 0){
2043 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
2044 goto LAST;
2046 m = prv->pat->get_count(prv->pat);
2047 if(m < 0){
2048 r = ARIB_STD_B25_ERROR_PAT_PARSE_FAILURE;
2049 goto LAST;
2051 if(m == 0){
2052 goto NEXT;
2054 r = proc_pat(prv);
2055 goto LAST;
2058 NEXT:
2059 curr += unit;
2062 LAST:
2063 m = curr - prv->sbuf.head;
2064 n = tail - curr;
2065 if( (n < 1024) || (m > (prv->sbuf.max/2) ) ){
2066 p = prv->sbuf.pool;
2067 memcpy(p, curr, n);
2068 prv->sbuf.head = p;
2069 prv->sbuf.tail = p+n;
2070 }else{
2071 prv->sbuf.head = curr;
2074 return r;
2077 static int proc_cat(ARIB_STD_B25_PRIVATE_DATA *prv)
2079 int r;
2080 int n;
2081 int emm_pid;
2083 TS_SECTION sect;
2085 r = 0;
2086 memset(&sect, 0, sizeof(sect));
2088 n = prv->cat->get(prv->cat, &sect);
2089 if(n < 0){
2090 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
2091 goto LAST;
2094 if(sect.hdr.table_id != TS_SECTION_ID_CONDITIONAL_ACCESS){
2095 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH;
2096 goto LAST;
2099 emm_pid = find_ca_descriptor_pid(sect.data, sect.tail-4, prv->ca_system_id);
2100 if( (emm_pid != 0x0000) && (emm_pid != 0x1fff) ){
2101 if( (prv->map[emm_pid].target != NULL) &&
2102 (prv->map[emm_pid].type == PID_MAP_TYPE_OTHER) ){
2103 DECRYPTOR_ELEM *dec;
2104 dec = (DECRYPTOR_ELEM *)(prv->map[emm_pid].target);
2105 dec->ref -= 1;
2106 if(dec->ref < 1){
2107 remove_decryptor(prv, dec);
2110 prv->emm_pid = emm_pid;
2111 prv->map[emm_pid].ref = 1;
2112 prv->map[emm_pid].type = PID_MAP_TYPE_EMM;
2113 prv->map[emm_pid].target = NULL;
2116 prv->map[0x0001].ref = 1;
2117 prv->map[0x0001].type = PID_MAP_TYPE_CAT;
2118 prv->map[0x0001].target = NULL;
2120 LAST:
2122 if(sect.raw != NULL){
2123 n = prv->cat->ret(prv->cat, &sect);
2124 if( (n < 0) && (r == 0) ){
2125 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
2129 return r;
2132 static int proc_emm(ARIB_STD_B25_PRIVATE_DATA *prv)
2134 int r;
2135 int j,n;
2137 int len;
2139 uint8_t *head;
2140 uint8_t *tail;
2142 TS_SECTION sect;
2143 EMM_FIXED_PART emm_hdr;
2145 r = 0;
2146 memset(&sect, 0, sizeof(sect));
2148 if(prv->bcas == NULL){
2149 r = ARIB_STD_B25_ERROR_EMPTY_B_CAS_CARD;
2150 goto LAST;
2153 while( (n = prv->emm->get_count(prv->emm)) > 0 ){
2155 n = prv->emm->get(prv->emm, &sect);
2156 if(n < 0){
2157 r = ARIB_STD_B25_ERROR_CAT_PARSE_FAILURE;
2158 goto LAST;
2161 if(sect.hdr.table_id == TS_SECTION_ID_EMM_MESSAGE){
2162 /* EMM_MESSAGE is not supported */
2163 goto NEXT;
2164 }else if(sect.hdr.table_id != TS_SECTION_ID_EMM_S){
2165 r = ARIB_STD_B25_WARN_TS_SECTION_ID_MISSMATCH;
2166 goto LAST;
2169 head = sect.data;
2170 tail = sect.tail - 4;
2172 while( (head+13) <= tail ){
2174 extract_emm_fixed_part(&emm_hdr, head);
2175 len = emm_hdr.associated_information_length+7;
2176 if( (head+len) > tail ){
2177 /* broken EMM element */
2178 goto NEXT;
2181 for(j=0;j<prv->casid.count;j++){
2182 if(prv->casid.data[j] == emm_hdr.card_id){
2183 n = prv->bcas->proc_emm(prv->bcas, head, len);
2184 if(n < 0){
2185 r = ARIB_STD_B25_ERROR_EMM_PROC_FAILURE;
2186 goto LAST;
2188 unlock_all_decryptor(prv);
2192 head += len;
2195 NEXT:
2196 if(sect.raw != NULL){
2197 n = prv->emm->ret(prv->emm, &sect);
2198 if( (n < 0) && (r == 0) ){
2199 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
2200 goto LAST;
2202 memset(&sect, 0, sizeof(sect));
2206 LAST:
2207 if(sect.raw != NULL){
2208 n = prv->emm->ret(prv->emm, &sect);
2209 if( (n < 0) && (r == 0) ){
2210 r = ARIB_STD_B25_ERROR_EMM_PARSE_FAILURE;
2214 return r;
2217 static void release_program(ARIB_STD_B25_PRIVATE_DATA *prv, TS_PROGRAM *pgrm)
2219 int32_t pid;
2220 TS_STREAM_ELEM *strm;
2222 pid = pgrm->pmt_pid;
2224 if(pgrm->pmt != NULL){
2225 pgrm->pmt->release(pgrm->pmt);
2226 pgrm->pmt = NULL;
2229 while( (strm = get_stream_list_head(&(pgrm->old_strm))) != NULL ){
2230 unref_stream(prv, strm->pid);
2231 memset(strm, 0, sizeof(TS_STREAM_ELEM));
2232 put_stream_list_tail(&(prv->strm_pool), strm);
2235 while( (strm = get_stream_list_head(&(pgrm->streams))) != NULL ){
2236 unref_stream(prv, strm->pid);
2237 memset(strm, 0, sizeof(TS_STREAM_ELEM));
2238 put_stream_list_tail(&(prv->strm_pool), strm);
2241 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN;
2242 prv->map[pid].ref = 0;
2243 prv->map[pid].target = NULL;
2246 static void unref_stream(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid)
2248 DECRYPTOR_ELEM *dec;
2250 prv->map[pid].ref -= 1;
2251 if( prv->map[pid].ref < 1 ){
2252 if( (prv->map[pid].target != NULL) &&
2253 (prv->map[pid].type == PID_MAP_TYPE_OTHER) ){
2254 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
2255 dec->ref -= 1;
2256 if(dec->ref < 1){
2257 remove_decryptor(prv, dec);
2260 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN;
2261 prv->map[pid].ref = 0;
2262 prv->map[pid].target = NULL;
2266 static DECRYPTOR_ELEM *set_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid)
2268 DECRYPTOR_ELEM *r;
2270 r = NULL;
2271 if(prv->map[pid].type == PID_MAP_TYPE_ECM){
2272 r = (DECRYPTOR_ELEM *)(prv->map[pid].target);
2273 if(r != NULL){
2274 return r;
2277 r = (DECRYPTOR_ELEM *)calloc(1, sizeof(DECRYPTOR_ELEM));
2278 if(r == NULL){
2279 return NULL;
2281 r->ecm_pid = pid;
2282 r->ecm = create_ts_section_parser();
2283 if(r->ecm == NULL){
2284 free(r);
2285 return NULL;
2288 if(prv->decrypt.tail != NULL){
2289 r->prev = prv->decrypt.tail;
2290 r->next = NULL;
2291 prv->decrypt.tail->next = r;
2292 prv->decrypt.tail = r;
2293 prv->decrypt.count += 1;
2294 }else{
2295 r->prev = NULL;
2296 r->next = NULL;
2297 prv->decrypt.head = r;
2298 prv->decrypt.tail = r;
2299 prv->decrypt.count = 1;
2302 if( (prv->map[pid].type == PID_MAP_TYPE_OTHER) &&
2303 (prv->map[pid].target != NULL) ){
2304 DECRYPTOR_ELEM *dec;
2305 dec = (DECRYPTOR_ELEM *)(prv->map[pid].target);
2306 dec->ref -= 1;
2307 if(dec->ref < 1){
2308 remove_decryptor(prv, dec);
2312 prv->map[pid].type = PID_MAP_TYPE_ECM;
2313 prv->map[pid].target = r;
2315 return r;
2318 static void remove_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, DECRYPTOR_ELEM *dec)
2320 int32_t pid;
2322 DECRYPTOR_ELEM *prev;
2323 DECRYPTOR_ELEM *next;
2325 pid = dec->ecm_pid;
2326 if( (prv->map[pid].type == PID_MAP_TYPE_ECM) &&
2327 (prv->map[pid].target == ((void *)dec)) ){
2328 prv->map[pid].type = PID_MAP_TYPE_UNKNOWN;
2329 prv->map[pid].target = NULL;
2332 prev = (DECRYPTOR_ELEM *)(dec->prev);
2333 next = (DECRYPTOR_ELEM *)(dec->next);
2334 if(prev != NULL){
2335 prev->next = next;
2336 }else{
2337 prv->decrypt.head = next;
2339 if(next != NULL){
2340 next->prev = prev;
2341 }else{
2342 prv->decrypt.tail = prev;
2344 prv->decrypt.count -= 1;
2346 if(dec->ecm != NULL){
2347 dec->ecm->release(dec->ecm);
2348 dec->ecm = NULL;
2351 if(dec->m2 != NULL){
2352 dec->m2->release(dec->m2);
2353 dec->m2 = NULL;
2356 free(dec);
2359 static DECRYPTOR_ELEM *select_active_decryptor(DECRYPTOR_ELEM *a, DECRYPTOR_ELEM *b, int32_t pid)
2361 if( b != NULL ){
2362 return b;
2364 if( pid == 0x1fff ){
2365 return NULL;
2367 return a;
2370 static void bind_stream_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv, int32_t pid, DECRYPTOR_ELEM *dec)
2372 DECRYPTOR_ELEM *old;
2374 old = (DECRYPTOR_ELEM *)(prv->map[pid].target);
2375 if(old == dec){
2376 /* already binded - do nothing */
2377 return;
2380 if(old != NULL){
2381 old->ref -= 1;
2382 if(old->ref == 0){
2383 remove_decryptor(prv, old);
2385 prv->map[pid].target = NULL;
2388 if(dec != NULL){
2389 prv->map[pid].target = dec;
2390 dec->ref += 1;
2394 static void unlock_all_decryptor(ARIB_STD_B25_PRIVATE_DATA *prv)
2396 DECRYPTOR_ELEM *e;
2398 e = prv->decrypt.head;
2399 while(e != NULL){
2400 e->locked = 0;
2401 e = (DECRYPTOR_ELEM *)(e->next);
2405 static TS_STREAM_ELEM *get_stream_list_head(TS_STREAM_LIST *list)
2407 TS_STREAM_ELEM *r;
2409 r = list->head;
2410 if(r == NULL){
2411 return NULL;
2414 list->head = (TS_STREAM_ELEM *)(r->next);
2415 if(list->head == NULL){
2416 list->tail = NULL;
2417 list->count = 0;
2418 }else{
2419 list->head->prev = NULL;
2420 list->count -= 1;
2423 r->prev = NULL;
2424 r->next = NULL;
2426 return r;
2429 static TS_STREAM_ELEM *find_stream_list_elem(TS_STREAM_LIST *list, int32_t pid)
2431 TS_STREAM_ELEM *r;
2433 r = list->head;
2434 while(r != NULL){
2435 if(r->pid == pid){
2436 break;
2438 r = (TS_STREAM_ELEM *)(r->next);
2441 return r;
2444 static TS_STREAM_ELEM *create_stream_elem(int32_t pid, int32_t type)
2446 TS_STREAM_ELEM *r;
2448 r = (TS_STREAM_ELEM *)calloc(1, sizeof(TS_STREAM_ELEM));
2449 if(r == NULL){
2450 return NULL;
2453 r->pid = pid;
2454 r->type = type;
2456 return r;
2459 static void put_stream_list_tail(TS_STREAM_LIST *list, TS_STREAM_ELEM *elem)
2461 if(list->tail != NULL){
2462 elem->prev = list->tail;
2463 elem->next = NULL;
2464 list->tail->next = elem;
2465 list->tail = elem;
2466 list->count += 1;
2467 }else{
2468 elem->prev = NULL;
2469 elem->next = NULL;
2470 list->head = elem;
2471 list->tail = elem;
2472 list->count = 1;
2476 static void clear_stream_list(TS_STREAM_LIST *list)
2478 TS_STREAM_ELEM *p,*n;
2480 p = list->head;
2481 while(p != NULL){
2482 n = (TS_STREAM_ELEM *)(p->next);
2483 free(p);
2484 p = n;
2487 list->head = NULL;
2488 list->tail = NULL;
2489 list->count = 0;
2492 static int reserve_work_buffer(TS_WORK_BUFFER *buf, int32_t size)
2494 int m,n;
2495 uint8_t *p;
2497 if(buf->max >= size){
2498 return 1;
2501 if(buf->max < 512){
2502 n = 512;
2503 }else{
2504 n = buf->max * 2;
2507 while(n < size){
2508 n += n;
2511 p = (uint8_t *)malloc(n);
2512 if(p == NULL){
2513 return 0;
2516 m = 0;
2517 if(buf->pool != NULL){
2518 m = buf->tail - buf->head;
2519 if(m > 0){
2520 memcpy(p, buf->head, m);
2522 free(buf->pool);
2523 buf->pool = NULL;
2526 buf->pool = p;
2527 buf->head = p;
2528 buf->tail = p+m;
2529 buf->max = n;
2531 return 1;
2534 static int append_work_buffer(TS_WORK_BUFFER *buf, uint8_t *data, int32_t size)
2536 int m;
2538 if(size < 1){
2539 /* ignore - do nothing */
2540 return 1;
2543 m = buf->tail - buf->pool;
2545 if( (m+size) > buf->max ){
2546 if(!reserve_work_buffer(buf, m+size)){
2547 return 0;
2551 memcpy(buf->tail, data, size);
2552 buf->tail += size;
2554 return 1;
2557 static void reset_work_buffer(TS_WORK_BUFFER *buf)
2559 buf->head = buf->pool;
2560 buf->tail = buf->pool;
2563 static void release_work_buffer(TS_WORK_BUFFER *buf)
2565 if(buf->pool != NULL){
2566 free(buf->pool);
2568 buf->pool = NULL;
2569 buf->head = NULL;
2570 buf->tail = NULL;
2571 buf->max = 0;
2574 static void extract_ts_header(TS_HEADER *dst, uint8_t *src)
2576 dst->sync = src[0];
2577 dst->transport_error_indicator = (src[1] >> 7) & 0x01;
2578 dst->payload_unit_start_indicator = (src[1] >> 6) & 0x01;
2579 dst->transport_priority = (src[1] >> 5) & 0x01;
2580 dst->pid = ((src[1] & 0x1f) << 8) | src[2];
2581 dst->transport_scrambling_control = (src[3] >> 6) & 0x03;
2582 dst->adaptation_field_control = (src[3] >> 4) & 0x03;
2583 dst->continuity_counter = src[3] & 0x0f;
2586 static void extract_emm_fixed_part(EMM_FIXED_PART *dst, uint8_t *src)
2588 int i;
2590 dst->card_id = 0;
2591 for(i=0;i<6;i++){
2592 dst->card_id = (dst->card_id << 8) | src[i];
2595 dst->associated_information_length = src[ 6];
2596 dst->protocol_number = src[ 7];
2597 dst->broadcaster_group_id = src[ 8];
2598 dst->update_number = (src[ 9]<<8)|src[10];
2599 dst->expiration_date = (src[11]<<8)|src[12];
2602 static uint8_t *resync(uint8_t *head, uint8_t *tail, int32_t unit_size)
2604 int i;
2605 unsigned char *buf;
2607 buf = head;
2608 tail -= unit_size * 8;
2609 while( buf <= tail ){
2610 if(buf[0] == 0x47){
2611 for(i=1;i<8;i++){
2612 if(buf[unit_size*i] != 0x47){
2613 break;
2616 if(i == 8){
2617 return buf;
2620 buf += 1;
2623 return NULL;
2626 static uint8_t *resync_force(uint8_t *head, uint8_t *tail, int32_t unit_size)
2628 int i,n;
2629 unsigned char *buf;
2631 buf = head;
2632 while( buf <= (tail-188) ){
2633 if(buf[0] == 0x47){
2634 n = (tail - buf) / unit_size;
2635 if(n == 0){
2636 return buf;
2638 for(i=1;i<n;i++){
2639 if(buf[unit_size*i] != 0x47){
2640 break;
2643 if(i == n){
2644 return buf;
2647 buf += 1;
2650 return NULL;