source: trunk/module-dvbapi.c@ 4149

Last change on this file since 4149 was 4141, checked in by dingo35, 13 years ago

all: simplify debug system, add D_DVBAPI = -d128, eliminate cs_ptyp which complicates stuff unnecc

File size: 61.1 KB
Line 
1#include "globals.h"
2
3#ifdef HAVE_DVBAPI
4
5#include "module-dvbapi.h"
6
7#ifdef AZBOX
8#include "openxcas/openxcas_api.h"
9#include "openxcas/openxcas_message.h"
10
11int openxcas_provid, openxcas_seq, openxcas_filter_idx, openxcas_stream_id, openxcas_cipher_idx, openxcas_busy;
12unsigned char openxcas_cw[16];
13unsigned short openxcas_sid, openxcas_caid, openxcas_ecm_pid, openxcas_video_pid, openxcas_audio_pid, openxcas_data_pid;
14
15void azbox_openxcas_ecm_callback(int stream_id, unsigned int sequence, int cipher_index, unsigned int caid, unsigned char *ecm_data, int l, unsigned short pid);
16void azbox_openxcas_ex_callback(int stream_id, unsigned int seq, int idx, unsigned int pid, unsigned char *ecm_data, int l);
17void azbox_send_dcw(struct s_client *client, ECM_REQUEST *er);
18void * azbox_main(void * cli);
19#endif
20
21#ifdef COOL
22int coolapi_set_filter (int fd, int num, int pid, byte * flt, byte * mask);
23int coolapi_remove_filter (int fd, int num);
24int coolapi_open_device (int demux_index, int demux_id);
25int coolapi_close_device(int fd);
26int coolapi_write_cw(int mask, unsigned short *STREAMpids, int count, ca_descr_t * ca_descr);
27int coolapi_set_pid (int demux_id, int num, int index, int pid);
28void coolapi_close_all();
29void dvbapi_write_cw(int demux_id, uchar *cw, int index);
30#endif
31const char *boxdesc[] = { "none", "dreambox", "duckbox", "ufs910", "dbox2", "ipbox", "ipbox-pmt", "dm7000", "qboxhd", "coolstream" };
32
33const struct box_devices devices[BOX_COUNT] = {
34 /* QboxHD (dvb-api-3)*/ { "/tmp/virtual_adapter/", "ca%d", "demux%d", "/tmp/camd.socket" },
35 /* dreambox (dvb-api-3)*/ { "/dev/dvb/adapter%d/", "ca%d", "demux%d", "/tmp/camd.socket" },
36 /* dreambox (dvb-api-1)*/ { "/dev/dvb/card%d/", "ca%d", "demux%d", "/tmp/camd.socket" },
37 /* sh4 (stapi)*/ { "/dev/stapi/", "stpti4_ioctl", "stpti4_ioctl", "/tmp/camd.socket" },
38 /* coolstream)*/ { "/dev/cnxt/", "null", "null", "/tmp/camd.socket" }
39};
40
41int selected_box=-1;
42int selected_api=-1;
43int disable_pmt_files=0;
44int dir_fd=-1, pausecam=0;
45DEMUXTYPE demux[MAX_DEMUX];
46int ca_fd[8];
47
48struct s_dvbapi_priority *dvbapi_priority=NULL;
49struct s_client *dvbapi_client=NULL;
50
51int dvbapi_set_filter(int demux_id, int api, unsigned short pid, uchar *filt, uchar *mask, int timeout, int pidindex, int count, int type) {
52#ifdef AZBOX
53 openxcas_caid = demux[demux_id].ECMpids[pidindex].CAID;
54 openxcas_ecm_pid = pid;
55
56 return 1;
57#endif
58 int ret=-1,n=-1,i;
59
60 for (i=0; i<MAX_FILTER && demux[demux_id].demux_fd[i].fd>0; i++);
61
62 if (i>=MAX_FILTER) {
63 cs_log("no free filter");
64 return -1;
65 }
66 n=i;
67
68 demux[demux_id].demux_fd[n].pidindex = pidindex;
69 demux[demux_id].demux_fd[n].pid = pid;
70 demux[demux_id].demux_fd[n].type = type;
71 demux[demux_id].demux_fd[n].count = count;
72
73 switch(api) {
74 case DVBAPI_3:
75 demux[demux_id].demux_fd[n].fd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
76 struct dmx_sct_filter_params sFP2;
77
78 memset(&sFP2,0,sizeof(sFP2));
79
80 sFP2.pid = pid;
81 sFP2.timeout = timeout;
82 sFP2.flags = DMX_IMMEDIATE_START;
83 memcpy(sFP2.filter.filter,filt,16);
84 memcpy(sFP2.filter.mask,mask,16);
85 ret=ioctl(demux[demux_id].demux_fd[n].fd, DMX_SET_FILTER, &sFP2);
86
87 break;
88 case DVBAPI_1:
89 demux[demux_id].demux_fd[n].fd = dvbapi_open_device(0, demux[demux_id].demux_index, demux[demux_id].adapter_index);
90 struct dmxSctFilterParams sFP1;
91
92 memset(&sFP1,0,sizeof(sFP1));
93
94 sFP1.pid = pid;
95 sFP1.timeout = timeout;
96 sFP1.flags = DMX_IMMEDIATE_START;
97 memcpy(sFP1.filter.filter,filt,16);
98 memcpy(sFP1.filter.mask,mask,16);
99 ret=ioctl(demux[demux_id].demux_fd[n].fd, DMX_SET_FILTER1, &sFP1);
100
101 break;
102#ifdef WITH_STAPI
103 case STAPI:
104 demux[demux_id].demux_fd[n].fd = 1;
105 ret=stapi_set_filter(demux_id, pid, filt, mask, n, demux[demux_id].pmt_file);
106
107 break;
108#endif
109#ifdef COOL
110 case COOLAPI:
111 demux[demux_id].demux_fd[n].fd = coolapi_open_device(demux[demux_id].demux_index, demux_id);
112 if(demux[demux_id].demux_fd[n].fd > 0)
113 ret = coolapi_set_filter(demux[demux_id].demux_fd[n].fd, n, pid, filt, mask);
114 break;
115#endif
116 default:
117 break;
118 }
119
120 if (ret < 0)
121 cs_debug_mask(D_DVBAPI, "could not start demux filter (Errno: %d)", errno);
122
123 return ret;
124}
125
126int dvbapi_check_array(unsigned short *array, int len, unsigned short match) {
127 int i;
128 for (i=0; i<len; i++) {
129 if (array[i]==match) {
130 return i;
131 }
132 }
133 return -1;
134}
135
136int dvbapi_detect_api() {
137#ifdef COOL
138 selected_api=COOLAPI;
139 selected_box = 4;
140 disable_pmt_files = 1;
141 cs_debug_mask(D_DVBAPI, "Detected coolstream Api");
142 return 1;
143#else
144 int num_apis=2, i,devnum=-1, dmx_fd=0, ret=-1;
145 uchar filter[32];
146 char device_path[128], device_path2[128];
147
148 for (i=0;i<BOX_COUNT;i++) {
149 sprintf(device_path2, devices[i].demux_device, 0);
150 sprintf(device_path, devices[i].path, 0);
151
152 sprintf(device_path, "%s%s", device_path, device_path2);
153
154 if ((dmx_fd = open(device_path, O_RDWR)) > 0) {
155 devnum=i;
156 break;
157 }
158 }
159
160 if (dmx_fd < 0) return 0;
161 close(dmx_fd);
162 selected_box = devnum;
163
164#ifdef WITH_STAPI
165 if (devnum==3) {
166 if (stapi_open()==FALSE) {
167 cs_log("stapi: setting up stapi failed.");
168 return 0;
169 }
170
171 selected_api=STAPI;
172 selected_box=3;
173 close(dmx_fd);
174 return 1;
175 }
176#endif
177 memset(filter,0,32);
178
179 filter[0]=0x01;
180 filter[16]=0xFF;
181
182 for (i=0;i<num_apis;i++) {
183 ret = dvbapi_set_filter(0, i, 0x0001, filter, filter+16, 1, 0, 0, TYPE_ECM);
184
185 if (ret >= 0) {
186 selected_api=i;
187 dvbapi_stop_filter(0, TYPE_ECM);
188 break;
189 }
190 }
191
192 if (ret < 0) return 0;
193
194 cs_debug_mask(D_DVBAPI, "Detected %s Api: %d", device_path, selected_api);
195#endif
196
197 return 1;
198}
199
200int dvbapi_read_device(int dmx_fd, unsigned char *buf, int length)
201{
202 int len, rc;
203 struct pollfd pfd[1];
204
205 pfd[0].fd = dmx_fd;
206 pfd[0].events = (POLLIN | POLLPRI);
207
208 rc = poll(pfd, 1, 7000);
209 if (rc<1) {
210 cs_log("read on %d timed out", dmx_fd);
211 return -1;
212 }
213
214 len = read(dmx_fd, buf, length);
215
216 if (len==-1)
217 cs_log("read error %d on fd %d", errno, dmx_fd);
218
219 return len;
220}
221
222int dvbapi_open_device(int type, int num, int adapter) {
223 int dmx_fd;
224 int ca_offset=0;
225 char device_path[128], device_path2[128];
226
227 if (type==0) {
228 sprintf(device_path2, devices[selected_box].demux_device, num);
229 sprintf(device_path, devices[selected_box].path, adapter);
230
231 sprintf(device_path, "%s%s", device_path, device_path2);
232 } else {
233 if (cfg->dvbapi_boxtype==BOXTYPE_DUCKBOX || cfg->dvbapi_boxtype==BOXTYPE_DBOX2 || cfg->dvbapi_boxtype==BOXTYPE_UFS910)
234 ca_offset=1;
235
236 if (cfg->dvbapi_boxtype==BOXTYPE_QBOXHD)
237 num=0;
238
239 sprintf(device_path2, devices[selected_box].ca_device, num+ca_offset);
240 sprintf(device_path, devices[selected_box].path, adapter);
241
242 sprintf(device_path, "%s%s", device_path, device_path2);
243 }
244
245 if ((dmx_fd = open(device_path, O_RDWR)) < 0) {
246 cs_debug_mask(D_DVBAPI, "error opening device %s (Errno: %d)", device_path, errno);
247 return -1;
248 }
249
250 cs_debug_mask(D_DVBAPI, "DEVICE open (%s) fd %d", device_path, dmx_fd);
251 return dmx_fd;
252}
253
254int dvbapi_stop_filter(int demux_index, int type) {
255 int g;
256
257 for (g=0;g<MAX_FILTER;g++) {
258 if (demux[demux_index].demux_fd[g].type==type) {
259 dvbapi_stop_filternum(demux_index, g);
260 }
261 }
262
263 return 1;
264}
265
266int dvbapi_stop_filternum(int demux_index, int num)
267{
268 int ret=-1;
269 if (demux[demux_index].demux_fd[num].fd>0) {
270#ifdef COOL
271 ret=coolapi_remove_filter(demux[demux_index].demux_fd[num].fd, num);
272 coolapi_close_device(demux[demux_index].demux_fd[num].fd);
273#else
274#ifdef WITH_STAPI
275 ret=stapi_remove_filter(demux_index, num, demux[demux_index].pmt_file);
276#else
277 ret=ioctl(demux[demux_index].demux_fd[num].fd,DMX_STOP);
278 close(demux[demux_index].demux_fd[num].fd);
279#endif
280#endif
281 demux[demux_index].demux_fd[num].fd=0;
282 }
283 return ret;
284}
285
286void dvbapi_start_filter(int demux_id, int pidindex, unsigned short pid, uchar table, uchar mask, int timeout, int type)
287{
288 uchar filter[32];
289
290 cs_debug_mask(D_DVBAPI, "set filter pid: %04x", pid);
291
292 memset(filter,0,32);
293
294 filter[0]=table;
295 filter[16]=mask;
296
297 dvbapi_set_filter(demux_id, selected_api, pid, filter, filter+16, timeout, pidindex, 0, type);
298}
299
300int dvbapi_find_emmpid(int demux_id, uint8 type) {
301 int k;
302 for (k=0; k<demux[demux_id].EMMpidcount; k++) {
303 if (demux[demux_id].EMMpids[k].CAID == demux[demux_id].ECMpids[demux[demux_id].pidindex].CAID
304 && (demux[demux_id].EMMpids[k].PROVID == demux[demux_id].ECMpids[demux[demux_id].pidindex].PROVID || !demux[demux_id].ECMpids[demux[demux_id].pidindex].PROVID || !demux[demux_id].EMMpids[k].PROVID)
305 && demux[demux_id].EMMpids[k].type & type)
306 return k;
307 }
308 return -1;
309}
310
311void dvbapi_start_emm_filter(int demux_index) {
312 int j;
313 char *typtext[]={"UNKNOWN", "UNIQUE", "SHARED", "GLOBAL"};
314
315 if (demux[demux_index].pidindex==-1) return;
316
317 if (demux[demux_index].EMMpidcount == 0 || !demux[demux_index].rdr || !hexserialset(demux[demux_index].rdr))
318 return;
319
320 if (demux[demux_index].emm_filter==1 && !memcmp(demux[demux_index].rdr->hexserial, demux[demux_index].hexserial, 8))
321 return;
322
323 if (memcmp(demux[demux_index].rdr->hexserial, demux[demux_index].hexserial, 8))
324 dvbapi_stop_filter(demux_index, TYPE_EMM);
325
326 if (demux[demux_index].rdr->card_system==0)
327 demux[demux_index].rdr->card_system=get_cardsystem(demux[demux_index].ECMpids[demux[demux_index].pidindex].CAID);
328
329 uchar dmx_filter[256];
330 memset(dmx_filter, 0, sizeof(dmx_filter));
331
332 get_emm_filter(demux[demux_index].rdr, dmx_filter);
333
334 int filter_count=dmx_filter[1];
335
336 cs_debug_mask(D_DVBAPI, "start %d emm filter for %s", filter_count, demux[demux_index].rdr->label);
337
338 for (j=1;j<=filter_count && j < 8;j++) {
339 int startpos=2+(34*(j-1));
340
341 if (dmx_filter[startpos+1] != 0x00)
342 continue;
343
344 uchar filter[32];
345 memcpy(filter, dmx_filter+startpos+2, 32);
346 int emmtype=dmx_filter[startpos];
347 int count=dmx_filter[startpos+1];
348 int l=-1;
349
350 switch(emmtype) {
351 case GLOBAL: l=dvbapi_find_emmpid(demux_index, T_GLOBAL); break;
352 case SHARED: l=dvbapi_find_emmpid(demux_index, T_SHARED); break;
353 case UNIQUE: l=dvbapi_find_emmpid(demux_index, T_UNIQUE); break;
354 }
355
356 if (l>-1) {
357 cs_debug_mask(D_DVBAPI, "starting emm filter %s, pid: 0x%04X", typtext[emmtype], demux[demux_index].EMMpids[l].PID);
358 cs_ddump_mask(D_DVBAPI, filter, 32, "demux filter:");
359 dvbapi_set_filter(demux_index, selected_api, demux[demux_index].EMMpids[l].PID, filter, filter+16, 0, demux[demux_index].pidindex, count, TYPE_EMM);
360 } else {
361 cs_debug_mask(D_DVBAPI, "no emm pid found");
362 }
363 }
364
365 memcpy(demux[demux_index].hexserial, demux[demux_index].rdr->hexserial, 8);
366 demux[demux_index].emm_filter=1;
367}
368
369void dvbapi_add_ecmpid(int demux_id, ushort caid, ushort ecmpid, ulong provid) {
370 int n,added=0;
371
372 if (demux[demux_id].ECMpidcount>=ECM_PIDS)
373 return;
374
375 int stream = demux[demux_id].STREAMpidcount-1;
376 for (n=0;n<demux[demux_id].ECMpidcount;n++) {
377 if (stream>-1 && demux[demux_id].ECMpids[n].CAID == caid && demux[demux_id].ECMpids[n].ECM_PID == ecmpid) {
378 if (demux[demux_id].ECMpids[n].slen == 0) {
379 //we already got this caid/ecmpid as global, no need to add the single stream
380 cs_debug_mask(D_DVBAPI, "[SKIP STREAM %d] CAID: %04X\tECM_PID: %04X\tPROVID: %06X", n, caid, ecmpid, provid);
381 continue;
382 }
383 added=1;
384 demux[demux_id].ECMpids[n].stream[demux[demux_id].ECMpids[n].slen++]=stream;
385 cs_debug_mask(D_DVBAPI, "[ADD STREAM %d] CAID: %04X\tECM_PID: %04X\tPROVID: %06X", n, caid, ecmpid, provid);
386 }
387 }
388
389 if (added==1)
390 return;
391
392 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].ECM_PID = ecmpid;
393 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].CAID = caid;
394 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].PROVID = provid;
395 if (stream>-1)
396 demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].stream[demux[demux_id].ECMpids[demux[demux_id].ECMpidcount].slen++]=stream;
397
398 cs_log("[ADD PID %d] CAID: %04X\tECM_PID: %04X\tPROVID: %06X", demux[demux_id].ECMpidcount, caid, ecmpid, provid);
399 demux[demux_id].ECMpidcount++;
400}
401
402void dvbapi_add_emmpid(int demux_id, ushort caid, ushort emmpid, ulong provid, uint8 type) {
403 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PID = emmpid;
404 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].CAID = caid;
405 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount].PROVID = provid;
406 demux[demux_id].EMMpids[demux[demux_id].EMMpidcount++].type = type;
407 cs_debug_mask(D_DVBAPI, "[ADD EMMPID] CAID: %04X\tEMM_PID: %04X\tPROVID: %06X - (type %d)", caid, emmpid, provid, type);
408}
409
410void dvbapi_parse_cat(int demux_id, uchar *buf, int len) {
411 unsigned short i, k;
412
413 cs_ddump_mask(D_DVBAPI, buf, len, "cat:");
414
415 for (i = 8; i < (((buf[1] & 0x0F) << 8) | buf[2]) - 1; i += buf[i + 1] + 2) {
416 if (buf[i] != 0x09) continue;
417 unsigned short caid=(((buf[i + 2] & 0x1F) << 8) | buf[i + 3]);
418 unsigned short emm_pid=(((buf[i + 4] & 0x1F) << 8) | buf[i + 5]);
419 ulong emm_provider = 0;
420
421 switch (caid >> 8) {
422 case 0x01:
423 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, T_UNIQUE);
424 cs_debug_mask(D_DVBAPI, "[cat] CAID: %04x\tEMM_PID: %04x", caid, emm_pid);
425 for (k = i+7; k < i+buf[i+1]+2; k += 4) {
426 emm_provider = (buf[k+2] << 8| buf[k+3]);
427 emm_pid = (buf[k] & 0x0F) << 8 | buf[k+1];
428 cs_debug_mask(D_DVBAPI, "[cat] CAID: %04X\tEMM_PID: %04X\tPROVID: %06X", caid, emm_pid, emm_provider);
429 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, T_SHARED);
430 }
431 break;
432 case 0x05:
433 for (k = i+6; k < i+buf[i+1]+2; k += buf[k+1]+2) {
434 if (buf[k]==0x14) {
435 emm_provider = buf[k+2] << 16 | (buf[k+3] << 8| (buf[k+4] & 0xF0));
436 cs_debug_mask(D_DVBAPI, "[cat] CAID: %04x\tEMM_PID: %04x\tPROVID: %06X", caid, emm_pid, emm_provider);
437 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, T_UNIQUE|T_SHARED|T_GLOBAL);
438 }
439 }
440 break;
441 case 0x18:
442 emm_provider = (buf[i+1] == 0x07) ? (buf[i+6] << 16 | (buf[i+7] << 8| (buf[i+8]))) : 0;
443 cs_debug_mask(D_DVBAPI, "[cat] CAID: %04x\tEMM_PID: %04x\tPROVID: %06X", caid, emm_pid, emm_provider);
444 dvbapi_add_emmpid(demux_id, caid, emm_pid, emm_provider, T_UNIQUE|T_SHARED|T_GLOBAL);
445 break;
446 default:
447 cs_debug_mask(D_DVBAPI, "[cat] CAID: %04x\tEMM_PID: %04x", caid, emm_pid);
448 dvbapi_add_emmpid(demux_id, caid, emm_pid, 0, T_UNIQUE|T_SHARED|T_GLOBAL);
449 break;
450 }
451 }
452 return;
453}
454
455int dvbapi_get_descindex() {
456 int i,j,idx=1,fail=1;
457 while (fail) {
458 fail=0;
459 for (i=0;i<MAX_DEMUX;i++) {
460 for (j=0;j<demux[i].ECMpidcount;j++) {
461 if (demux[i].ECMpids[j].index==idx) {
462 idx++;
463 fail=1;
464 break;
465 }
466 }
467 }
468 }
469 return idx;
470}
471
472void dvbapi_set_pid(int demux_id, int num, int index) {
473 int i;
474
475 if (demux[demux_id].pidindex == -1) return;
476
477 switch(selected_api) {
478#ifdef WITH_STAPI
479 case STAPI:
480 stapi_set_pid(demux_id, num, index, demux[demux_id].STREAMpids[num], demux[demux_id].pmt_file);
481 break;
482#endif
483 default:
484 for (i=0;i<8;i++) {
485 if (demux[demux_id].ca_mask & (1 << i)) {
486 if (ca_fd[i]<=0)
487 ca_fd[i]=dvbapi_open_device(1, i, demux[demux_id].adapter_index);
488 if (ca_fd[i]>0) {
489 ca_pid_t ca_pid2;
490 memset(&ca_pid2,0,sizeof(ca_pid2));
491 ca_pid2.pid = demux[demux_id].STREAMpids[num];
492 ca_pid2.index = index;
493 if (ioctl(ca_fd[i], CA_SET_PID, &ca_pid2)==-1)
494 cs_debug_mask(D_DVBAPI, "Error CA_SET_PID pid=0x%04x index=%d errno=%d", ca_pid2.pid, ca_pid2.index, errno);
495 else
496 cs_debug_mask(D_DVBAPI, "CA_SET_PID pid=0x%04x index=%d", ca_pid2.pid, ca_pid2.index);
497 }
498 }
499 }
500 break;
501 }
502 return;
503}
504
505void dvbapi_stop_descrambling(int demux_id) {
506 int i;
507
508 if (demux[demux_id].program_number==0) return;
509
510 cs_debug_mask(D_DVBAPI, "stop descrambling (demux_id: %d)", demux_id);
511
512 dvbapi_stop_filter(demux_id, TYPE_ECM);
513 dvbapi_stop_filter(demux_id, TYPE_EMM);
514
515 for (i=0;i<demux[demux_id].STREAMpidcount;i++) {
516 dvbapi_set_pid(demux_id, i, -1);
517 }
518
519 memset(&demux[demux_id], 0 ,sizeof(DEMUXTYPE));
520 demux[demux_id].pidindex=-1;
521
522 unlink(ECMINFO_FILE);
523
524 return;
525}
526
527void dvbapi_start_descrambling(int demux_id) {
528 int j,k;
529 int streamcount=0;
530
531 demux[demux_id].pidindex = demux[demux_id].curindex;
532
533 for (j=0; j<demux[demux_id].ECMpidcount; j++) {
534 if (demux[demux_id].curindex == j || (demux[demux_id].ECMpids[demux[demux_id].curindex].CAID == demux[demux_id].ECMpids[j].CAID
535 && demux[demux_id].ECMpids[demux[demux_id].curindex].PROVID == demux[demux_id].ECMpids[j].PROVID
536 && demux[demux_id].ECMpids[j].PROVID > 0)) {
537
538 if (demux[demux_id].curindex != j) {
539 if (demux[demux_id].ECMpids[j].status < 0 || demux[demux_id].ECMpids[demux[demux_id].curindex].slen == 0)
540 continue;
541
542 dvbapi_start_filter(demux_id, j, demux[demux_id].ECMpids[j].ECM_PID, 0x80, 0xF0, 3000, TYPE_ECM);
543 }
544
545 if (!demux[demux_id].ECMpids[j].index)
546 demux[demux_id].ECMpids[j].index=dvbapi_get_descindex();
547
548 demux[demux_id].ECMpids[j].checked=1;
549 demux[demux_id].ECMpids[j].irdeto_curchid=demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_curchid;
550
551 if (demux[demux_id].ECMpids[j].slen>0) {
552 for (k=0; k<demux[demux_id].ECMpids[j].slen; k++)
553 dvbapi_set_pid(demux_id, demux[demux_id].ECMpids[j].stream[k], demux[demux_id].ECMpids[j].index-1);
554 } else {
555 for (k=0;k<demux[demux_id].STREAMpidcount;k++)
556 dvbapi_set_pid(demux_id, k, demux[demux_id].ECMpids[j].index-1);
557 }
558 streamcount++;
559 }
560 }
561
562 cs_log("Start descrambling PID #%d (CAID: %04X) %d", demux[demux_id].curindex, demux[demux_id].ECMpids[demux[demux_id].curindex].CAID, streamcount);
563
564 if (cfg->dvbapi_au>0)
565 dvbapi_start_filter(demux_id, demux[demux_id].pidindex, 0x001, 0x01, 0xFF, 0, TYPE_EMM); //CAT
566}
567
568#ifdef READER_VIACCESS
569extern int viaccess_reassemble_emm(uchar *buffer, uint *len);
570#endif
571#ifdef READER_CRYPTOWORKS
572extern int cryptoworks_reassemble_emm(uchar *buffer, uint *len);
573#endif
574
575void dvbapi_process_emm (int demux_index, int filter_num, unsigned char *buffer, unsigned int len) {
576 EMM_PACKET epg;
577
578 if (demux[demux_index].pidindex==-1) return;
579
580 ulong provider = demux[demux_index].ECMpids[demux[demux_index].pidindex].PROVID;
581 ushort caid = demux[demux_index].ECMpids[demux[demux_index].pidindex].CAID;
582
583 switch (caid >> 8) {
584 case 0x05:
585#ifdef READER_VIACCESS
586 if (!viaccess_reassemble_emm(buffer, &len))
587#endif
588 return;
589 break;
590 case 0x0d:
591#ifdef READER_CRYPTOWORKS
592 if (!cryptoworks_reassemble_emm(buffer, &len))
593#endif
594 return;
595 break;
596 }
597
598
599 cs_ddump_mask(D_DVBAPI, buffer, len, "emm from fd %d:", demux[demux_index].demux_fd[filter_num].fd);
600
601 struct s_dvbapi_priority *mapentry = dvbapi_check_prio_match(demux_index, demux[demux_index].pidindex, 'm');
602 if (mapentry) {
603 cs_debug_mask(D_DVBAPI, "Mapping EMM from %04X:%06X to %04X:%06X", caid, provider, mapentry->mapcaid, mapentry->mapprovid);
604 caid = mapentry->mapcaid;
605 provider = mapentry->mapprovid;
606 }
607
608 memset(&epg, 0, sizeof(epg));
609
610 memcpy(epg.caid, i2b(2, caid), 2);
611 memcpy(epg.provid, i2b(4, provider), 4);
612
613 epg.l=len;
614 memcpy(epg.emm, buffer, epg.l);
615
616 if(cfg->dvbapi_au==2 && demux[demux_index].rdr) {
617 dvbapi_client->autoau=0;
618 dvbapi_client->aureader=demux[demux_index].rdr;
619 }
620
621 do_emm(dvbapi_client, &epg);
622}
623
624void dvbapi_read_priority() {
625 FILE *fp;
626 char token[128], str1[128];
627 char type;
628 int i, ret, count=0;
629
630 const char *cs_prio="oscam.dvbapi";
631
632 snprintf(token, 127, "%s%s", cs_confdir, cs_prio);
633 fp=fopen(token, "r");
634
635 if (!fp) {
636 cs_log("can't open priority file %s", token);
637 return;
638 }
639
640 if (dvbapi_priority) {
641 cs_log("reread priority file %s", cs_prio);
642 struct s_dvbapi_priority *o, *p;
643 for (p = dvbapi_priority; p != NULL; p = o) {
644 o = p->next;
645 free(p);
646 }
647 dvbapi_priority = NULL;
648 }
649
650 while (fgets(token, sizeof(token), fp)) {
651 if (token[0]=='#' || token[0]=='/') continue;
652 if (strlen(token)>100) continue;
653
654 memset(str1, 0, 128);
655
656 for (i=0;i<(int)strlen(token);i++) {
657 if ((token[i]==':' || token[i]==' ') && token[i+1]==':') {
658 memmove(token+i+2, token+i+1, strlen(token)-i+1);
659 token[i+1]='0';
660 }
661 if (token[i]=='#' || token[i]=='/') {
662 token[i]='\0';
663 break;
664 }
665 }
666
667 type = 0;
668#ifdef WITH_STAPI
669 uint disablefilter=0;
670 ret = sscanf(trim(token), "%c: %63s %63s %d", &type, str1, str1+64, &disablefilter);
671#else
672 ret = sscanf(trim(token), "%c: %63s %63s", &type, str1, str1+64);
673#endif
674 type = tolower(type);
675
676 if (ret<1 || (type != 'p' && type != 'i' && type != 'm' && type != 'd' && type != 's'))
677 continue;
678
679 struct s_dvbapi_priority *entry = malloc(sizeof(struct s_dvbapi_priority));
680 memset(entry, 0, sizeof(struct s_dvbapi_priority));
681
682 entry->type=type;
683 entry->next=NULL;
684
685 count++;
686
687#ifdef WITH_STAPI
688 if (type=='s') {
689 strncpy(entry->devname, str1, 29);
690 strncpy(entry->pmtfile, str1+64, 29);
691
692 entry->disablefilter=disablefilter;
693
694 cs_debug_mask(D_DVBAPI, "stapi prio: ret=%d | %c: %s %s | disable %d", ret, type, entry->devname, entry->pmtfile, disablefilter);
695
696 if (!dvbapi_priority) {
697 dvbapi_priority=entry;
698 } else {
699 struct s_dvbapi_priority *p;
700 for (p = dvbapi_priority; p->next != NULL; p = p->next);
701 p->next = entry;
702 }
703 continue;
704 }
705#endif
706
707 char c_srvid[34];
708 c_srvid[0]='\0';
709 uint caid=0, provid=0, srvid=0, ecmpid=0, chid=0;
710 sscanf(str1, "%4x:%6x:%33[^:s]:%4x:%4x", &caid, &provid, c_srvid, &ecmpid, &chid);
711
712 entry->caid=caid;
713 entry->provid=provid;
714 entry->ecmpid=ecmpid;
715 entry->chid=chid;
716
717 uint delay=0, force=0, mapcaid=0, mapprovid=0;
718 switch (type) {
719 case 'd':
720 sscanf(str1+64, "%4d", &delay);
721 entry->delay=delay;
722 break;
723 case 'p':
724 sscanf(str1+64, "%1d", &force);
725 entry->force=force;
726 break;
727 case 'm':
728 sscanf(str1+64, "%4x:%6x", &mapcaid, &mapprovid);
729 entry->mapcaid=mapcaid;
730 entry->mapprovid=mapprovid;
731 break;
732 }
733
734 if (c_srvid[0]=='=') {
735 struct s_srvid *this;
736
737 for (this = cfg->srvid; this; this = this->next) {
738 if (strcmp(this->prov, c_srvid+1)==0) {
739 struct s_dvbapi_priority *entry2 = malloc(sizeof(struct s_dvbapi_priority));
740 memcpy(entry2, entry, sizeof(struct s_dvbapi_priority));
741
742 entry2->srvid=this->srvid;
743
744 cs_debug_mask(D_DVBAPI, "prio srvid: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X | prio %d | delay %d",
745 ret, entry2->type, entry2->caid, entry2->provid, entry2->srvid, entry2->ecmpid, entry2->chid, entry2->mapcaid, entry2->mapprovid, entry2->force, entry2->delay);
746
747 if (!dvbapi_priority) {
748 dvbapi_priority=entry2;
749 } else {
750 struct s_dvbapi_priority *p;
751 for (p = dvbapi_priority; p->next != NULL; p = p->next);
752 p->next = entry2;
753 }
754 }
755 }
756 free(entry);
757 continue;
758 } else {
759 sscanf(c_srvid, "%4x", &srvid);
760 entry->srvid=srvid;
761 }
762
763 cs_debug_mask(D_DVBAPI, "prio: ret=%d | %c: %04X %06X %04X %04X %04X -> map %04X %06X | prio %d | delay %d",
764 ret, entry->type, entry->caid, entry->provid, entry->srvid, entry->ecmpid, entry->chid, entry->mapcaid, entry->mapprovid, entry->force, entry->delay);
765
766 if (!dvbapi_priority) {
767 dvbapi_priority=entry;
768 } else {
769 struct s_dvbapi_priority *p;
770 for (p = dvbapi_priority; p->next != NULL; p = p->next);
771 p->next = entry;
772 }
773 }
774
775 cs_log("%d entries read from %s", count, cs_prio);
776
777 fclose(fp);
778 return;
779}
780
781struct s_dvbapi_priority *dvbapi_check_prio_match(int demux_id, int pidindex, char type) {
782 struct s_dvbapi_priority *p;
783 int i;
784
785 for (p=dvbapi_priority, i=0; p != NULL; p=p->next, i++) {
786 if (p->type != type) continue;
787
788 if (p->caid && p->caid != demux[demux_id].ECMpids[pidindex].CAID) continue;
789 if (p->provid && p->provid != demux[demux_id].ECMpids[pidindex].PROVID) continue;
790 if (p->ecmpid && p->ecmpid != demux[demux_id].ECMpids[pidindex].ECM_PID) continue;
791 if (p->srvid && p->srvid != demux[demux_id].program_number) continue;
792 if (p->chid && p->chid != demux[demux_id].ECMpids[pidindex].irdeto_chid) continue;
793
794 return p;
795 }
796 return NULL;
797
798}
799
800void dvbapi_resort_ecmpids(int demux_index) {
801 int n,i;
802
803 for (n=0; n<demux[demux_index].ECMpidcount; n++)
804 demux[demux_index].ECMpids[n].status=0;
805
806 demux[demux_index].max_status=0;
807 int new_status=1;
808
809 if (dvbapi_priority) {
810 struct s_dvbapi_priority *p;
811 for (p=dvbapi_priority, i=0; p != NULL; p=p->next, i++) {
812 for (n=0; n<demux[demux_index].ECMpidcount; n++) {
813 if (demux[demux_index].ECMpids[n].status != 0) continue;
814
815 if (p->caid && p->caid != demux[demux_index].ECMpids[n].CAID) continue;
816 if (p->provid && p->provid != demux[demux_index].ECMpids[n].PROVID) continue;
817 if (p->ecmpid && p->ecmpid != demux[demux_index].ECMpids[n].ECM_PID) continue;
818 if (p->srvid && p->srvid != demux[demux_index].program_number) continue;
819
820 if (p->type=='p') {
821 demux[demux_index].ECMpids[n].status = new_status++;
822 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, demux[demux_index].ECMpids[n].status);
823 } else if (p->type=='i') {
824 demux[demux_index].ECMpids[n].status = -1;
825 cs_debug_mask(D_DVBAPI, "[IGNORE PID %d] %04X:%06X (file)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID);
826 }
827 }
828 }
829 }
830
831 for (n=0; n<demux[demux_index].ECMpidcount; n++) {
832 int nr;
833 SIDTAB *sidtab;
834 ECM_REQUEST er;
835 er.caid = demux[demux_index].ECMpids[n].CAID;
836 er.prid = demux[demux_index].ECMpids[n].PROVID;
837 er.srvid = demux[demux_index].program_number;
838
839 for (nr=0, sidtab=cfg->sidtab; sidtab; sidtab=sidtab->next, nr++) {
840 if (sidtab->num_caid | sidtab->num_provid | sidtab->num_srvid) {
841 if ((cfg->dvbapi_sidtabno&((SIDTABBITS)1<<nr)) && (chk_srvid_match(&er, sidtab))) {
842 demux[demux_index].ECMpids[n].status = -1; //ignore
843 cs_debug_mask(D_DVBAPI, "[IGNORE PID %d] %04X:%06X (service %s) pos %d", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, sidtab->label, nr);
844 }
845 if ((cfg->dvbapi_sidtabok&((SIDTABBITS)1<<nr)) && (chk_srvid_match(&er, sidtab))) {
846 demux[demux_index].ECMpids[n].status = new_status++; //priority
847 cs_debug_mask(D_DVBAPI, "[PRIORITIZE PID %d] %04X:%06X (service: %s position: %d)", n, demux[demux_index].ECMpids[n].CAID, demux[demux_index].ECMpids[n].PROVID, sidtab->label, demux[demux_index].ECMpids[n].status);
848 }
849 }
850 }
851 }
852
853 demux[demux_index].max_status = new_status;
854 return;
855}
856
857
858void dvbapi_parse_descriptor(int demux_id, unsigned int info_length, unsigned char *buffer) {
859 //int ca_pmt_cmd_id = buffer[i + 5];
860 unsigned int descriptor_length=0;
861 unsigned int j,u;
862
863 if (info_length<1)
864 return;
865
866 if (buffer[0]==0x01) {
867 buffer=buffer+1;
868 info_length--;
869 }
870
871 for (j = 0; j < info_length; j += descriptor_length + 2) {
872 descriptor_length = buffer[j+1];
873 int descriptor_ca_system_id = (buffer[j+2] << 8) | buffer[j+3];
874 int descriptor_ca_pid = ((buffer[j+4] & 0x1F) << 8) | buffer[j+5];
875 int descriptor_ca_provider = 0;
876
877 if (demux[demux_id].ECMpidcount>=ECM_PIDS)
878 break;
879
880 cs_debug_mask(D_DVBAPI, "[pmt] type: %02x\tlength: %d", buffer[j], descriptor_length);
881
882 if (buffer[j] != 0x09) continue;
883
884 if (descriptor_ca_system_id >> 8 == 0x01) {
885 for (u=2; u<descriptor_length; u+=15) {
886 descriptor_ca_pid = ((buffer[j+2+u] & 0x1F) << 8) | buffer[j+2+u+1];
887 descriptor_ca_provider = (buffer[j+2+u+2] << 8) | buffer[j+2+u+3];
888 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider);
889 }
890 } else {
891 if (descriptor_ca_system_id >> 8 == 0x05 && descriptor_length == 0x0F && buffer[j+12] == 0x14)
892 descriptor_ca_provider = buffer[j+14] << 16 | (buffer[j+15] << 8| (buffer[j+16] & 0xF0));
893
894 if (descriptor_ca_system_id >> 8 == 0x18 && descriptor_length == 0x07)
895 descriptor_ca_provider = buffer[j+6] << 16 | (buffer[j+7] << 8| (buffer[j+8]));
896
897 if (descriptor_ca_system_id >> 8 == 0x4A && descriptor_length == 0x05)
898 descriptor_ca_provider = buffer[j+6];
899
900 dvbapi_add_ecmpid(demux_id, descriptor_ca_system_id, descriptor_ca_pid, descriptor_ca_provider);
901 }
902 }
903}
904
905void dvbapi_try_next_caid(int demux_id) {
906 int num=-1, n, j;
907
908 if (demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_curchid+1 < demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_numchids) {
909 demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_curchid++;
910 demux[demux_id].ECMpids[demux[demux_id].curindex].table=0;
911 cs_log("trying irdeto chid index: %d", demux[demux_id].ECMpids[demux[demux_id].curindex].irdeto_curchid);
912 return;
913 }
914
915 if (demux[demux_id].tries > 2) {
916 cs_log("can't decode channel");
917 dvbapi_stop_filter(demux_id, TYPE_ECM);
918 return;
919 }
920
921 //values for first run (status > 0)
922 int start=1;
923 int end=demux[demux_id].max_status;
924
925 while (num==-1) {
926 for (j = start; j <= end && num == -1; j++) {
927 for (n=0; n<demux[demux_id].ECMpidcount; n++) {
928 if (demux[demux_id].ECMpids[n].checked == 0 && demux[demux_id].ECMpids[n].status == j) {
929 num=n;
930 break;
931 }
932 }
933 }
934 if (start==0 || num>-1) break;
935 //values for second run (status==0)
936 start=0;
937 end=0;
938 }
939
940 if (num == -1) {
941 demux[demux_id].tries++;
942 cs_log("try pids again #%d", demux[demux_id].tries);
943 for (n=0; n<demux[demux_id].ECMpidcount; n++) {
944 demux[demux_id].ECMpids[n].checked=0;
945 demux[demux_id].ECMpids[n].irdeto_curchid=0;
946 demux[demux_id].ECMpids[n].table=0;
947 }
948 dvbapi_try_next_caid(demux_id);
949 return;
950 }
951
952 dvbapi_stop_filter(demux_id, TYPE_ECM);
953
954 cs_debug_mask(D_DVBAPI, "[TRY PID %d] CAID: %04X PROVID: %06X CA_PID: %04X", num, demux[demux_id].ECMpids[num].CAID, demux[demux_id].ECMpids[num].PROVID, demux[demux_id].ECMpids[num].ECM_PID);
955#ifdef AZBOX
956 openxcas_provid = demux[demux_id].ECMpids[num].PROVID;
957 openxcas_caid = demux[demux_id].ECMpids[num].CAID;
958 openxcas_ecm_pid = demux[demux_id].ECMpids[num].ECM_PID;
959#endif
960 demux[demux_id].curindex=num;
961
962 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, 0x80, 0xF0, 3000, TYPE_ECM); //ECM
963 demux[demux_id].ECMpids[num].checked=1;
964}
965
966int dvbapi_parse_capmt(unsigned char *buffer, unsigned int length, int connfd, char *pmtfile) {
967 unsigned int i;
968 int demux_id=-1;
969 unsigned short ca_mask=0x01, demux_index=0x00, adapter_index=0x00;
970
971 int ca_pmt_list_management = buffer[0];
972 unsigned int program_number = (buffer[1] << 8) | buffer[2];
973 unsigned int program_info_length = ((buffer[4] & 0x0F) << 8) | buffer[5];
974
975 if (buffer[17]==0x82 && buffer[18]==0x02) {
976 //enigma2
977 ca_mask = buffer[19];
978 demux_index = buffer[20];
979 }
980
981 cs_ddump_mask(D_DVBAPI, buffer, length, "capmt:");
982
983 for (i = 0; i < MAX_DEMUX; i++) {
984 if (connfd>0 && demux[i].socket_fd == connfd) {
985 //PMT Update
986#ifdef COOL
987 demux_id = i;
988 unsigned char lastcw[16];
989 int n;
990 for(n = 0; n < 2; n++) {
991 memcpy(&lastcw[n*8], demux[demux_id].lastcw[n], 8);
992 memset(demux[demux_id].lastcw[n], 0, 8);
993 }
994 demux[demux_id].ca_mask=ca_mask;
995 dvbapi_write_cw(demux_id, lastcw, 0);//FIXME
996 demux[demux_id].curindex = demux[demux_id].pidindex;
997 demux[demux_id].STREAMpidcount=0;
998 demux[demux_id].ECMpidcount=0;
999 demux[demux_id].EMMpidcount=0;
1000 ca_pmt_list_management = 0x01;
1001#else
1002 if (ca_pmt_list_management == 0x05) {
1003 demux_id = i;
1004 demux[demux_id].curindex = demux[demux_id].pidindex;
1005 demux[demux_id].STREAMpidcount=0;
1006 demux[demux_id].ECMpidcount=0;
1007 demux[demux_id].EMMpidcount=0;
1008 }
1009 if (ca_pmt_list_management == 0x03 || ca_pmt_list_management == 0x01)
1010 dvbapi_stop_descrambling(i);
1011 if (ca_pmt_list_management == 0x02)
1012 demux_id=i;
1013#endif
1014 }
1015 }
1016
1017 if (demux_id==-1)
1018 for (demux_id=0; demux_id<MAX_DEMUX && demux[demux_id].program_number>0; demux_id++);
1019
1020 if (demux_id>=MAX_DEMUX) {
1021 cs_log("error no free id (MAX_DEMUX)");
1022 return -1;
1023 }
1024
1025 if (cfg->dvbapi_boxtype == BOXTYPE_IPBOX_PMT) {
1026 ca_mask = demux_id + 1;
1027 demux_index = demux_id;
1028 }
1029
1030 if (cfg->dvbapi_boxtype == BOXTYPE_QBOXHD && buffer[17]==0x82 && buffer[18]==0x03) {
1031 //ca_mask = buffer[19]; // with STONE 1.0.4 always 0x01
1032 demux_index = buffer[20]; // with STONE 1.0.4 always 0x00
1033 adapter_index = buffer[21]; // with STONE 1.0.4 adapter index can be 0,1,2
1034 ca_mask = (1 << adapter_index); // use adapter_index as ca_mask (used as index for ca_fd[] array)
1035 }
1036
1037 demux[demux_id].program_number=((buffer[1] << 8) | buffer[2]);
1038 demux[demux_id].demux_index=demux_index;
1039 demux[demux_id].adapter_index=adapter_index;
1040 demux[demux_id].ca_mask=ca_mask;
1041 demux[demux_id].socket_fd=connfd;
1042 demux[demux_id].rdr=NULL;
1043 demux[demux_id].pidindex=-1;
1044
1045 cs_debug_mask(D_DVBAPI, "id: %d\tdemux_index: %d\tca_mask: %02x\tprogram_info_length: %d\tca_pmt_list_management %02x",
1046 demux_id, demux[demux_id].demux_index, demux[demux_id].ca_mask, program_info_length, ca_pmt_list_management);
1047
1048 if (pmtfile)
1049 strcpy(demux[demux_id].pmt_file, pmtfile);
1050
1051 if (program_info_length > 1 && program_info_length < length)
1052 dvbapi_parse_descriptor(demux_id, program_info_length-1, buffer+7);
1053
1054 unsigned int es_info_length=0;
1055 for (i = program_info_length + 6; i < length; i += es_info_length + 5) {
1056 int stream_type = buffer[i];
1057 unsigned short elementary_pid = ((buffer[i + 1] & 0x1F) << 8) | buffer[i + 2];
1058 es_info_length = ((buffer[i + 3] & 0x0F) << 8) | buffer[i + 4];
1059
1060 cs_debug_mask(D_DVBAPI, "[pmt] stream_type: %02x\tpid: %04x\tlength: %d", stream_type, elementary_pid, es_info_length);
1061
1062 if (demux[demux_id].STREAMpidcount >= ECM_PIDS)
1063 break;
1064
1065 demux[demux_id].STREAMpids[demux[demux_id].STREAMpidcount++]=elementary_pid;
1066
1067 if (es_info_length != 0 && es_info_length < length) {
1068 dvbapi_parse_descriptor(demux_id, es_info_length, buffer+i+5);
1069 }
1070 }
1071 cs_debug_mask(D_DVBAPI, "Found %d ECMpids and %d STREAMpids in PMT", demux[demux_id].ECMpidcount, demux[demux_id].STREAMpidcount);
1072
1073 char *name = get_servicename(demux[demux_id].program_number, demux[demux_id].ECMpidcount>0 ? demux[demux_id].ECMpids[0].CAID : 0);
1074 cs_log("new program number: %04X (%s)", program_number, name);
1075
1076#ifdef AZBOX
1077 openxcas_sid = program_number;
1078#endif
1079
1080 if (ca_pmt_list_management == 0x05) {
1081 dvbapi_start_descrambling(demux_id);
1082 } else if (demux[demux_id].ECMpidcount>0 && ca_pmt_list_management != 0x01) {
1083 dvbapi_resort_ecmpids(demux_id);
1084 dvbapi_try_next_caid(demux_id);
1085 } else {
1086 // set channel srvid+caid
1087 dvbapi_client->last_srvid = demux[demux_id].program_number;
1088 dvbapi_client->last_caid = 0;
1089 // reset idle-Time
1090 dvbapi_client->last=time((time_t)0);
1091 }
1092
1093 return demux_id;
1094}
1095
1096
1097void dvbapi_handlesockmsg (unsigned char *buffer, unsigned int len, int connfd) {
1098 unsigned int val=0, size=0, i, k;
1099
1100 //cs_dump(buffer, len, "handlesockmsg:");
1101 for (k = 0; k < len; k += 3 + size + val) {
1102 if (buffer[0+k] != 0x9F || buffer[1+k] != 0x80) {
1103 cs_log("unknown socket command: %02x", buffer[0+k]);
1104 return;
1105 }
1106
1107 if (k>0) {
1108 cs_log("Unsupported capmt. Please report");
1109 cs_dump(buffer, len, "capmt:");
1110 }
1111
1112 if (buffer[3+k] & 0x80) {
1113 val = 0;
1114 size = buffer[3+k] & 0x7F;
1115 for (i = 0; i < size; i++)
1116 val = (val << 8) | buffer[i + 1 + 3 + k];
1117 size++;
1118 } else {
1119 val = buffer[3+k] & 0x7F;
1120 size = 1;
1121 }
1122 switch(buffer[2+k]) {
1123 case 0x32:
1124 dvbapi_parse_capmt(buffer + size + 3 + k, val, connfd, NULL);
1125 break;
1126 case 0x3f:
1127 //9F 80 3f 04 83 02 00 <demux index>
1128 cs_ddump_mask(D_DVBAPI, buffer, len, "capmt 3f:");
1129 // ipbox fix
1130 if (cfg->dvbapi_boxtype==BOXTYPE_IPBOX) {
1131 int demux_index=buffer[7+k];
1132 for (i = 0; i < MAX_DEMUX; i++) {
1133 if (demux[i].demux_index == demux_index) {
1134 dvbapi_stop_descrambling(i);
1135 break;
1136 }
1137 }
1138 // check do we have any demux running on this fd
1139 short execlose = 1;
1140 for (i = 0; i < MAX_DEMUX; i++) {
1141 if (demux[i].socket_fd == connfd) {
1142 execlose = 0;
1143 break;
1144 }
1145 }
1146 if (execlose) close(connfd);
1147 } else {
1148 close(connfd);
1149 }
1150 break;
1151 default:
1152 cs_log("handlesockmsg() unknown command");
1153 cs_dump(buffer, len, "unknown command:");
1154 break;
1155 }
1156 }
1157}
1158
1159int dvbapi_init_listenfd() {
1160 int clilen,listenfd;
1161 struct sockaddr_un servaddr;
1162
1163 memset(&servaddr, 0, sizeof(struct sockaddr_un));
1164 servaddr.sun_family = AF_UNIX;
1165 strcpy(servaddr.sun_path, devices[selected_box].cam_socket_path);
1166 clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
1167
1168 if ((unlink(devices[selected_box].cam_socket_path) < 0) && (errno != ENOENT))
1169 return 0;
1170 if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
1171 return 0;
1172 if (bind(listenfd, (struct sockaddr *) &servaddr, clilen) < 0)
1173 return 0;
1174 if (listen(listenfd, 5) < 0)
1175 return 0;
1176 // change the access right on the camd.socket
1177 // this will allow oscam to run as root if needed
1178 // and still allow non root client to connect to the socket
1179
1180 chmod(devices[selected_box].cam_socket_path, S_IRWXU | S_IRWXG | S_IRWXO);
1181
1182 return listenfd;
1183}
1184
1185void dvbapi_chk_caidtab(char *caidasc, char type) {
1186 char *ptr1, *ptr3;
1187 int i;
1188
1189 for (i=0, ptr1=strtok(caidasc, ","); (ptr1); ptr1=strtok(NULL, ",")) {
1190 unsigned long caid, prov;
1191 if( (ptr3=strchr(trim(ptr1), ':')) )
1192 *ptr3++='\0';
1193 else
1194 ptr3="";
1195
1196 if (((caid=a2i(ptr1, 2))|(prov=a2i(ptr3, 3)))) {
1197 struct s_dvbapi_priority *entry = malloc(sizeof(struct s_dvbapi_priority));
1198 memset(entry, 0, sizeof(struct s_dvbapi_priority));
1199 entry->caid=caid;
1200
1201 if (type=='d') {
1202 char tmp1[5];
1203 sprintf(tmp1, "%04X", (uint)prov);
1204 int cw_delay = strtol(tmp1, '\0', 10);
1205 entry->delay=cw_delay;
1206 } else
1207 entry->provid=prov;
1208
1209 entry->type=type;
1210
1211 entry->next=NULL;
1212
1213 if (!dvbapi_priority) {
1214 dvbapi_priority=entry;
1215 } else {
1216 struct s_dvbapi_priority *p;
1217 for (p = dvbapi_priority; p->next != NULL; p = p->next);
1218 p->next = entry;
1219 }
1220
1221 }
1222 }
1223}
1224
1225pthread_mutex_t event_handler_lock;
1226
1227void event_handler(int signal) {
1228 struct stat pmt_info;
1229 char dest[1024];
1230 DIR *dirp;
1231 struct dirent *dp;
1232 int i, pmt_fd;
1233 uchar mbuf[1024];
1234
1235 if (dvbapi_client != cur_client()) return;
1236
1237 signal=signal; //avoid compiler warnings
1238 pthread_mutex_lock(&event_handler_lock);
1239
1240 int standby_fd = open(STANDBY_FILE, O_RDONLY);
1241 pausecam = (standby_fd > 0) ? 1 : 0;
1242 if (standby_fd) close(standby_fd);
1243
1244 if (cfg->dvbapi_boxtype==BOXTYPE_IPBOX || cfg->dvbapi_pmtmode == 1) {
1245 pthread_mutex_unlock(&event_handler_lock);
1246 return;
1247 }
1248
1249 for (i=0;i<MAX_DEMUX;i++) {
1250 if (demux[i].pmt_file[0] != 0) {
1251 sprintf(dest, "%s%s", TMPDIR, demux[i].pmt_file);
1252 pmt_fd = open(dest, O_RDONLY);
1253 if(pmt_fd>0) {
1254 if (fstat(pmt_fd, &pmt_info) != 0) {
1255 close(pmt_fd);
1256 continue;
1257 }
1258
1259 if (pmt_info.st_mtime != demux[i].pmt_time) {
1260 cs_log("stoping demux for pmt file %s", dest);
1261 dvbapi_stop_descrambling(i);
1262 }
1263
1264 close(pmt_fd);
1265 continue;
1266 } else {
1267 cs_log("stoping demux for pmt file %s", dest);
1268 dvbapi_stop_descrambling(i);
1269 }
1270 }
1271 }
1272
1273 if (disable_pmt_files) {
1274 pthread_mutex_unlock(&event_handler_lock);
1275 return;
1276 }
1277
1278 dirp = opendir(TMPDIR);
1279 if (!dirp) {
1280 cs_log("opendir errno %d", errno);
1281 pthread_mutex_unlock(&event_handler_lock);
1282 return;
1283 }
1284
1285 while ((dp = readdir(dirp))) {
1286 if (strlen(dp->d_name) < 7)
1287 continue;
1288 if (strncmp(dp->d_name, "pmt", 3)!=0 || strncmp(dp->d_name+strlen(dp->d_name)-4, ".tmp", 4)!=0)
1289 continue;
1290
1291 sprintf(dest, "%s%s", TMPDIR, dp->d_name);
1292 pmt_fd = open(dest, O_RDONLY);
1293 if (pmt_fd < 0)
1294 continue;
1295
1296 if (fstat(pmt_fd, &pmt_info) != 0)
1297 { close(pmt_fd); continue; }
1298
1299 int found=0;
1300 for (i=0;i<MAX_DEMUX;i++) {
1301 if (strcmp(demux[i].pmt_file, dp->d_name)==0) {
1302 if (pmt_info.st_mtime == demux[i].pmt_time) {
1303 found=1;
1304 continue;
1305 }
1306 dvbapi_stop_descrambling(i);
1307 }
1308 }
1309 if (found)
1310 { close(pmt_fd); continue; }
1311
1312 cs_log("found pmt file %s", dest);
1313 cs_sleepms(100);
1314
1315 unsigned int len = read(pmt_fd,mbuf,sizeof(mbuf));
1316 close(pmt_fd);
1317
1318 if (len < 1) {
1319 cs_log("pmt file %s have invalid len!", dest);
1320 continue;
1321 }
1322
1323 int pmt_id;
1324#ifdef QBOXHD
1325 uint j1,j2;
1326 // QboxHD pmt.tmp is the full capmt written as a string of hex values
1327 // pmt.tmp must be longer than 3 bytes (6 hex chars) and even length
1328 if ((len<6) || ((len%2) != 0) || ((len/2)>sizeof(dest))) {
1329 cs_log("error parsing QboxHD pmt.tmp, incorrect length");
1330 continue;
1331 }
1332
1333 for(j2=0,j1=0;j2<len;j2+=2,j1++) {
1334 if (sscanf((char*)mbuf+j2, "%02X", dest+j1) != 1) {
1335 cs_log("error parsing QboxHD pmt.tmp, data not valid in position %d",j2);
1336 pthread_mutex_unlock(&event_handler_lock);
1337 return;
1338 }
1339 }
1340
1341 cs_ddump_mask(D_DVBAPI, dest,len/2,"QboxHD pmt.tmp:");
1342
1343 pmt_id = dvbapi_parse_capmt(dest+4, (len/2)-4, -1, dp->d_name);
1344#else
1345 if (len>sizeof(dest)) {
1346 cs_log("event_handler() dest buffer is to small for pmt data!");
1347 continue;
1348 }
1349 cs_ddump_mask(D_DVBAPI, mbuf,len,"pmt:");
1350
1351 memcpy(dest, "\x03\xFF\xFF\x00\x00\x13\x00", 7);
1352
1353 dest[1] = mbuf[3];
1354 dest[2] = mbuf[4];
1355 dest[5] = mbuf[11]+1;
1356
1357 memcpy(dest + 7, mbuf + 12, len - 12 - 4);
1358
1359 pmt_id = dvbapi_parse_capmt((uchar*)dest, 7 + len - 12 - 4, -1, dp->d_name);
1360#endif
1361 if (pmt_id>=0) {
1362 strcpy(demux[pmt_id].pmt_file, dp->d_name);
1363 demux[pmt_id].pmt_time = pmt_info.st_mtime;
1364 }
1365
1366 if (cfg->dvbapi_pmtmode == 3) {
1367 disable_pmt_files=1;
1368 break;
1369 }
1370 }
1371 closedir(dirp);
1372 pthread_mutex_unlock(&event_handler_lock);
1373}
1374
1375void *dvbapi_event_thread(void *cli) {
1376 struct s_client * client = (struct s_client *) cli;
1377 pthread_setspecific(getclient, client);
1378
1379 while(1) {
1380 cs_sleepms(750);
1381 event_handler(0);
1382 }
1383
1384 return NULL;
1385}
1386
1387void dvbapi_process_input(int demux_id, int filter_num, uchar *buffer, int len) {
1388 struct s_ecmpids *curpid = &demux[demux_id].ECMpids[demux[demux_id].demux_fd[filter_num].pidindex];
1389
1390#ifdef COOL
1391 cs_debug_mask(D_DVBAPI, "dvbapi_process_input: demux %d filter %d len %d buffer %x curtable %x curindex %d\n", demux_id, filter_num, len, buffer[0], curpid->table, demux[demux_id].curindex);
1392#endif
1393 if (demux[demux_id].demux_fd[filter_num].type==TYPE_ECM) {
1394 if (len != (((buffer[1] & 0xf) << 8) | buffer[2]) + 3) //invaild CAT length
1395 return;
1396
1397 if (buffer[0] != 0x80 && buffer[0] != 0x81)
1398 return;
1399
1400 unsigned short caid = curpid->CAID;
1401 unsigned long provid = curpid->PROVID;
1402
1403 if ((caid >> 8) == 0x06) {
1404 //80 70 39 53 04 05 00 88
1405 if (buffer[5]>10) return;
1406 if (curpid->irdeto_numchids != buffer[5]+1) {
1407 cs_log("Found %d IRDETO ECM CHIDs", buffer[5]+1);
1408 curpid->irdeto_numchids = buffer[5]+1;
1409 curpid->irdeto_curchid = 0;
1410 }
1411
1412 if (demux[demux_id].pidindex==-1) {
1413 curpid->irdeto_chid = buffer[7];
1414 struct s_dvbapi_priority *chidentry = dvbapi_check_prio_match(demux_id, demux[demux_id].demux_fd[filter_num].pidindex, 'i');
1415 if (chidentry) {
1416 cs_debug_mask(D_DVBAPI, "ignoring %04X:%06X:%02X", curpid->CAID, curpid->PROVID, curpid->irdeto_chid);
1417 dvbapi_try_next_caid(demux_id);
1418 return;
1419 }
1420 }
1421
1422 if (buffer[4] != curpid->irdeto_curchid) {
1423 //wait for the correct chid
1424 return;
1425 }
1426 }
1427
1428 if (curpid->table == buffer[0])
1429 return;
1430
1431 curpid->table = buffer[0];
1432#ifdef COOL
1433 int num = demux[demux_id].curindex;//FIXME or pidindex ?
1434 dvbapi_stop_filternum(demux_id, filter_num);
1435 dvbapi_start_filter(demux_id, num, demux[demux_id].ECMpids[num].ECM_PID, buffer[0] ^ 1, 0xFF, 3000, TYPE_ECM);
1436#endif
1437
1438 struct s_dvbapi_priority *mapentry = dvbapi_check_prio_match(demux_id, demux[demux_id].demux_fd[filter_num].pidindex, 'm');
1439
1440 if (!provid)
1441 provid = chk_provid(buffer, caid);
1442
1443 if (provid != curpid->PROVID)
1444 curpid->PROVID = provid;
1445
1446 if (cfg->dvbapi_au>0)
1447 dvbapi_start_emm_filter(demux_id);
1448
1449 ECM_REQUEST *er;
1450 if (!(er=get_ecmtask()))
1451 return;
1452
1453 er->srvid = demux[demux_id].program_number;
1454 er->caid = caid;
1455 er->pid = curpid->ECM_PID;
1456 er->prid = provid;
1457
1458 if (mapentry) {
1459 cs_debug_mask(D_DVBAPI, "Mapping ECM from %04X:%06X to %04X:%06X", er->caid, er->prid, mapentry->mapcaid, mapentry->mapprovid);
1460 er->caid = mapentry->mapcaid;
1461 er->prid = mapentry->mapprovid;
1462 }
1463
1464 er->l=len;
1465 memcpy(er->ecm, buffer, er->l);
1466
1467 cs_debug_mask(D_DVBAPI, "request cw for caid %04X provid %06X srvid %04X pid %04X chid %02X", er->caid, er->prid, er->srvid, er->pid, (caid >> 8) == 0x06 ? buffer[7] : 0);
1468 get_cw(dvbapi_client, er);
1469 }
1470
1471 if (demux[demux_id].demux_fd[filter_num].type==TYPE_EMM) {
1472 if (buffer[0]==0x01) { //CAT
1473 cs_debug_mask(D_DVBAPI, "receiving cat");
1474 dvbapi_parse_cat(demux_id, buffer, len);
1475
1476 dvbapi_stop_filternum(demux_id, filter_num);
1477 return;
1478 }
1479 dvbapi_process_emm(demux_id, filter_num, buffer, len);
1480 }
1481
1482 if (demux[demux_id].demux_fd[filter_num].count==1) {
1483 //stop filter
1484 dvbapi_stop_filternum(demux_id, filter_num);
1485 }
1486 if (demux[demux_id].demux_fd[filter_num].count>1) {
1487 demux[demux_id].demux_fd[filter_num].count--;
1488 }
1489}
1490
1491void * dvbapi_main_local(void *cli) {
1492 struct s_client * client = (struct s_client *) cli;
1493 client->thread=pthread_self();
1494 pthread_setspecific(getclient, cli);
1495
1496 dvbapi_client=cli;
1497
1498 int maxpfdsize=(MAX_DEMUX*MAX_FILTER)+MAX_DEMUX+2;
1499 struct pollfd pfd2[maxpfdsize];
1500 int i,rc,pfdcount,g,connfd,clilen,j;
1501 int ids[maxpfdsize], fdn[maxpfdsize], type[maxpfdsize];
1502 struct timeb tp;
1503 struct sockaddr_un servaddr;
1504 ssize_t len=0;
1505 uchar mbuf[1024];
1506
1507 struct s_auth *account=0;
1508 int ok=0;
1509 if (!account) {
1510 client->usr[0]=0;
1511 for (ok=0, account=cfg->account; (account) && (!ok); account=account->next)
1512 if( (ok=!strcmp(cfg->dvbapi_usr, account->usr)) )
1513 break;
1514 }
1515
1516 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
1517
1518 memset(demux, 0, sizeof(struct demux_s) * MAX_DEMUX);
1519 memset(ca_fd, 0, sizeof(ca_fd));
1520
1521 dvbapi_read_priority();
1522 dvbapi_detect_api();
1523
1524 if (selected_box == -1 || selected_api==-1) {
1525 cs_log("could not detect api version");
1526 return NULL;
1527 }
1528
1529 if (cfg->dvbapi_pmtmode == 1)
1530 disable_pmt_files=1;
1531
1532 int listenfd = -1;
1533 if (cfg->dvbapi_boxtype != BOXTYPE_IPBOX_PMT && cfg->dvbapi_pmtmode != 2) {
1534 listenfd = dvbapi_init_listenfd();
1535 if (listenfd < 1) {
1536 cs_log("could not init camd.socket.");
1537 return NULL;
1538 }
1539 }
1540
1541 if (cfg->dvbapi_pmtmode != 4) {
1542 struct sigaction signal_action;
1543 signal_action.sa_handler = event_handler;
1544 sigemptyset(&signal_action.sa_mask);
1545 signal_action.sa_flags = SA_RESTART;
1546 sigaction(SIGRTMIN + 1, &signal_action, NULL);
1547
1548 pthread_mutexattr_t attr;
1549 pthread_mutexattr_init(&attr);
1550 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1551 pthread_mutex_init(&event_handler_lock, &attr);
1552
1553 dir_fd = open(TMPDIR, O_RDONLY);
1554 if (dir_fd >= 0) {
1555 fcntl(dir_fd, F_SETSIG, SIGRTMIN + 1);
1556 fcntl(dir_fd, F_NOTIFY, DN_MODIFY | DN_CREATE | DN_DELETE | DN_MULTISHOT);
1557 event_handler(SIGRTMIN + 1);
1558 }
1559 } else {
1560 pthread_t event_thread;
1561 pthread_create(&event_thread, NULL, dvbapi_event_thread, (void*) dvbapi_client);
1562 pthread_detach(event_thread);
1563 }
1564
1565 cs_ftime(&tp);
1566 tp.time+=500;
1567
1568 pfd2[0].fd = client->fd_m2c_c;
1569 pfd2[0].events = (POLLIN | POLLPRI);
1570 type[0]=0;
1571
1572 pfd2[1].fd = listenfd;
1573 pfd2[1].events = (POLLIN | POLLPRI);
1574 type[1]=1;
1575
1576 while (1) {
1577 pfdcount = (listenfd > -1) ? 2 : 1;
1578
1579 chk_pending(tp);
1580
1581 if (pausecam==1) {
1582 cs_sleepms(500);
1583 continue;
1584 }
1585
1586 for (i=0;i<MAX_DEMUX;i++) {
1587 for (g=0;g<MAX_FILTER;g++) {
1588 if (demux[i].demux_fd[g].fd>0 && selected_api != STAPI && selected_api != COOLAPI) {
1589 pfd2[pfdcount].fd = demux[i].demux_fd[g].fd;
1590 pfd2[pfdcount].events = (POLLIN | POLLPRI);
1591 ids[pfdcount]=i;
1592 fdn[pfdcount]=g;
1593 type[pfdcount++]=0;
1594 }
1595 }
1596
1597 if (demux[i].socket_fd>0) {
1598 rc=0;
1599 if (cfg->dvbapi_boxtype==BOXTYPE_IPBOX) {
1600 for (j = 0; j < pfdcount; j++) {
1601 if (pfd2[j].fd == demux[i].socket_fd) {
1602 rc=1;
1603 break;
1604 }
1605 }
1606 if (rc==1) continue;
1607 }
1608
1609 pfd2[pfdcount].fd=demux[i].socket_fd;
1610 pfd2[pfdcount].events = (POLLIN | POLLPRI | POLLHUP);
1611 ids[pfdcount]=i;
1612 type[pfdcount++]=1;
1613 }
1614 }
1615
1616 rc = poll(pfd2, pfdcount, 500);
1617 if (rc<1) continue;
1618
1619 for (i = 0; i < pfdcount; i++) {
1620 if (pfd2[i].revents > 3)
1621 cs_debug_mask(D_DVBAPI, "event %d on fd %d", pfd2[i].revents, pfd2[i].fd);
1622
1623 if (pfd2[i].revents & (POLLHUP | POLLNVAL)) {
1624 if (type[i]==1) {
1625 for (j=0;j<MAX_DEMUX;j++) {
1626 if (demux[j].socket_fd==pfd2[i].fd) {
1627 dvbapi_stop_descrambling(j);
1628 }
1629 }
1630 close(pfd2[i].fd);
1631 continue;
1632 }
1633 if (pfd2[i].fd==client->fd_m2c_c) {
1634 cs_exit(0);
1635 }
1636 }
1637 if (pfd2[i].revents & (POLLIN | POLLPRI)) {
1638 if (pfd2[i].fd==client->fd_m2c_c) {
1639 process_client_pipe(client, NULL, 0);
1640 continue;
1641 }
1642
1643 if (type[i]==1) {
1644 if (pfd2[i].fd==listenfd) {
1645 connfd = accept(listenfd, (struct sockaddr *)&servaddr, (socklen_t *)&clilen);
1646 cs_debug_mask(D_DVBAPI, "new socket connection fd: %d", connfd);
1647
1648 disable_pmt_files=1;
1649
1650 if (connfd <= 0) {
1651 cs_log("accept() returns error %d, fd event %d", errno, pfd2[i].revents);
1652 continue;
1653 }
1654 } else {
1655 cs_debug_mask(D_DVBAPI, "PMT Update on socket %d.", pfd2[i].fd);
1656 connfd = pfd2[i].fd;
1657 }
1658
1659 len = read(connfd, mbuf, sizeof(mbuf));
1660
1661 if (len < 3) {
1662 cs_debug_mask(D_DVBAPI, "camd.socket: too short message received");
1663 continue;
1664 }
1665
1666 dvbapi_handlesockmsg(mbuf, len, connfd);
1667 } else { // type==0
1668 int demux_index=ids[i];
1669 int n=fdn[i];
1670
1671 if ((len=dvbapi_read_device(pfd2[i].fd, mbuf, sizeof(mbuf))) <= 0) {
1672 if (demux[demux_index].pidindex==-1) {
1673 dvbapi_try_next_caid(demux_index);
1674 }
1675 continue;
1676 }
1677
1678 if (pfd2[i].fd==(int)demux[demux_index].demux_fd[n].fd) {
1679 dvbapi_process_input(demux_index,n,mbuf,len);
1680 }
1681 }
1682 }
1683 }
1684 }
1685 return NULL;
1686}
1687
1688void dvbapi_write_cw(int demux_id, uchar *cw, int index) {
1689 int n;
1690 unsigned char nullcw[8];
1691 memset(nullcw, 0, 8);
1692 ca_descr_t ca_descr;
1693 memset(&ca_descr,0,sizeof(ca_descr));
1694
1695 for (n=0;n<2;n++) {
1696 if (memcmp(cw+(n*8),demux[demux_id].lastcw[n],8)!=0 && memcmp(cw+(n*8),nullcw,8)!=0) {
1697 ca_descr.index = index;
1698 ca_descr.parity = n;
1699 memcpy(demux[demux_id].lastcw[n],cw+(n*8),8);
1700 memcpy(ca_descr.cw,cw+(n*8),8);
1701#ifdef COOL
1702 cs_debug_mask(D_DVBAPI, "write cw%d index: %d (ca_mask %d)", n, ca_descr.index, demux[demux_id].ca_mask);
1703 coolapi_write_cw(demux[demux_id].ca_mask, demux[demux_id].STREAMpids, demux[demux_id].STREAMpidcount, &ca_descr);
1704#else
1705 int i;
1706 for (i=0;i<8;i++) {
1707 if (demux[demux_id].ca_mask & (1 << i)) {
1708 cs_debug_mask(D_DVBAPI, "write cw%d index: %d (ca%d)", n, ca_descr.index, i);
1709 if (ca_fd[i]<=0) {
1710 ca_fd[i]=dvbapi_open_device(1, i, demux[demux_id].adapter_index);
1711 if (ca_fd[i]<=0)
1712 return;
1713 }
1714
1715 if (ioctl(ca_fd[i], CA_SET_DESCR, &ca_descr) < 0)
1716 cs_debug_mask(D_DVBAPI, "Error CA_SET_DESCR");
1717 }
1718 }
1719#endif
1720 }
1721 }
1722}
1723
1724void dvbapi_send_dcw(struct s_client *client, ECM_REQUEST *er)
1725{
1726#ifdef AZBOX
1727 azbox_send_dcw(client, er);
1728 return;
1729#endif
1730 int i;
1731
1732 for (i=0;i<MAX_DEMUX;i++) {
1733 if (demux[i].program_number==er->srvid) {
1734 demux[i].rdr=er->selected_reader;
1735
1736 if (er->rc<=3 && demux[i].pidindex==-1 && er->caid!=0) {
1737 dvbapi_start_descrambling(i);
1738 }
1739
1740 if (er->rc>3 && demux[i].pidindex==-1) {
1741 struct s_dvbapi_priority *forceentry=dvbapi_check_prio_match(i, demux[i].curindex, 'p');
1742 if (forceentry) {
1743 //not found -> maybe card need emm
1744 if (forceentry->force>0)
1745 dvbapi_start_descrambling(i);
1746 else {
1747 dvbapi_try_next_caid(i);
1748 return;
1749 }
1750 } else {
1751 dvbapi_try_next_caid(i);
1752 return;
1753 }
1754 }
1755
1756 if (er->rc>3) {
1757 cs_debug_mask(D_DVBAPI, "cw not found");
1758 return;
1759 }
1760
1761 struct s_dvbapi_priority *delayentry=dvbapi_check_prio_match(i, demux[i].pidindex, 'd');
1762 if (delayentry) {
1763 if (delayentry->delay<1000) {
1764 cs_debug_mask(D_DVBAPI, "wait %d ms", delayentry->delay);
1765 cs_sleepms(delayentry->delay);
1766 }
1767 }
1768
1769 int j=0;
1770 for (j=0; j<demux[i].ECMpidcount; j++)
1771 if (demux[i].ECMpids[j].CAID == er->caid && demux[i].ECMpids[j].ECM_PID == er->pid)
1772 break;
1773 if (j==demux[i].ECMpidcount) continue;
1774
1775#ifdef WITH_STAPI
1776 stapi_write_cw(i, er->cw, demux[i].STREAMpids, demux[i].STREAMpidcount, demux[i].pmt_file);
1777#else
1778 dvbapi_write_cw(i, er->cw, demux[i].ECMpids[j].index-1);
1779#endif
1780 // reset idle-Time
1781 client->last=time((time_t)0);
1782
1783 FILE *ecmtxt;
1784 ecmtxt = fopen(ECMINFO_FILE, "w");
1785 if(ecmtxt != NULL) {
1786 fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\nprov: 0x%06X\n", er->caid, er->pid, (uint) er->prid);
1787 fprintf(ecmtxt, "reader: %s\n", er->selected_reader->label);
1788 if (er->selected_reader->typ & R_IS_CASCADING)
1789 fprintf(ecmtxt, "from: %s\n", er->selected_reader->device);
1790 else
1791 fprintf(ecmtxt, "from: local\n");
1792 fprintf(ecmtxt, "protocol: %s\n", er->selected_reader->ph.desc);
1793 fprintf(ecmtxt, "hops: %d\n", er->selected_reader->cc_currenthops);
1794 fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime/1000);
1795 fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1,demux[i].lastcw[0],8));
1796 fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1,demux[i].lastcw[1],8));
1797 fclose(ecmtxt);
1798 ecmtxt = NULL;
1799 }
1800 }
1801 }
1802}
1803
1804static void * dvbapi_handler(int ctyp) {
1805 //cs_log("dvbapi loaded fd=%d", idx);
1806 if (cfg->dvbapi_enabled == 1) {
1807 struct s_client * cl = cs_fork(0);
1808 cl->typ='c';
1809 cl->ctyp=ctyp;
1810#ifdef AZBOX
1811 pthread_create(&cl->thread, NULL, azbox_main, (void*) cl);
1812#else
1813 pthread_create(&cl->thread, NULL, dvbapi_main_local, (void*) cl);
1814#endif
1815 pthread_detach(cl->thread);
1816 }
1817
1818 return NULL;
1819}
1820
1821
1822#ifdef AZBOX
1823void azbox_openxcas_ecm_callback(int stream_id, unsigned int seq, int cipher_index, unsigned int caid, unsigned char *ecm_data, int l, unsigned short pid) {
1824 cs_debug_mask(D_DVBAPI, "openxcas: ecm callback received");
1825
1826 openxcas_stream_id = stream_id;
1827 //openxcas_seq = seq;
1828 //openxcas_caid = caid;
1829 openxcas_ecm_pid = pid;
1830 openxcas_busy = 1;
1831
1832 ECM_REQUEST *er;
1833 if (!(er=get_ecmtask()))
1834 return;
1835
1836 er->srvid = openxcas_sid;
1837 er->caid = openxcas_caid;
1838 er->pid = openxcas_ecm_pid;
1839 er->prid = openxcas_provid;
1840
1841 er->l=l;
1842 memcpy(er->ecm, ecm_data, er->l);
1843
1844 cs_debug_mask(D_DVBAPI, "request cw for caid %04X provid %06X srvid %04X pid %04X", er->caid, er->prid, er->srvid, er->pid);
1845 get_cw(dvbapi_client, er);
1846
1847 //openxcas_stop_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
1848 //openxcas_remove_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
1849
1850 openxcas_cipher_idx = cipher_index;
1851
1852 struct timeb tp;
1853 cs_ftime(&tp);
1854 tp.time+=500;
1855
1856 struct pollfd pfd;
1857 pfd.fd = dvbapi_client->fd_m2c_c;
1858 pfd.events = POLLIN | POLLPRI;
1859/*
1860 while(1) {
1861 chk_pending(tp);
1862
1863 if (poll(&pfd, 1, 10) < 0)
1864 continue;
1865
1866 if (pfd.revents & (POLLHUP | POLLNVAL)) {
1867 cs_debug_mask(D_DVBAPI, "openxcas: ecm/cw error");
1868 break;
1869 }
1870
1871 if (pfd.revents & (POLLIN | POLLPRI)) {
1872 chk_dcw(cur_client()->fd_m2c_c);
1873 break;
1874 }
1875 }*/
1876}
1877
1878
1879void azbox_openxcas_ex_callback(int stream_id, unsigned int seq, int idx, unsigned int pid, unsigned char *ecm_data, int l) {
1880 cs_debug_mask(D_DVBAPI, "openxcas: ex callback received");
1881
1882 openxcas_stream_id = stream_id;
1883 openxcas_ecm_pid = pid;
1884 openxcas_cipher_idx = idx; // is this really cipher_idx?
1885
1886 ECM_REQUEST *er;
1887 if (!(er=get_ecmtask()))
1888 return;
1889
1890 er->srvid = openxcas_sid;
1891 er->caid = openxcas_caid;
1892 er->pid = openxcas_ecm_pid;
1893 er->prid = openxcas_provid;
1894
1895 er->l=l;
1896 memcpy(er->ecm, ecm_data, er->l);
1897
1898 cs_debug_mask(D_DVBAPI, "request cw for caid %04X provid %06X srvid %04X pid %04X", er->caid, er->prid, er->srvid, er->pid);
1899 get_cw(dvbapi_client, er);
1900
1901 if (openxcas_stop_filter_ex(stream_id, seq, openxcas_filter_idx) < 0)
1902 cs_log("openxcas: unable to stop ex filter");
1903 else
1904 cs_debug_mask(D_DVBAPI, "openxcas: ex filter stopped");
1905
1906 struct timeb tp;
1907 cs_ftime(&tp);
1908 tp.time+=500;
1909
1910 chk_pending(tp);
1911 process_client_pipe(dvbapi_client, NULL, 0);
1912
1913 unsigned char mask[12];
1914 unsigned char comp[12];
1915 memset(&mask, 0x00, sizeof(mask));
1916 memset(&comp, 0x00, sizeof(comp));
1917
1918 mask[0] = 0xff;
1919 comp[0] = ecm_data[0] ^ 1;
1920
1921 if ((openxcas_filter_idx = openxcas_start_filter_ex(stream_id, seq, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ex_callback)) < 0)
1922 cs_log("openxcas: unable to start ex filter");
1923 else
1924 cs_debug_mask(D_DVBAPI, "openxcas: ex filter started, pid = %x", openxcas_ecm_pid);
1925}
1926
1927void * azbox_main(void *cli) {
1928 struct s_client * client = (struct s_client *) cli;
1929 client->thread=pthread_self();
1930 pthread_setspecific(getclient, cli);
1931 dvbapi_client=cli;
1932
1933 struct timeb tp;
1934 cs_ftime(&tp);
1935 tp.time+=500;
1936
1937 struct s_auth *account=0;
1938 int ok=0;
1939 if (!account) {
1940 client->usr[0]=0;
1941 for (ok=0, account=cfg->account; (account) && (!ok); account=account->next)
1942 if( (ok=!strcmp(cfg->dvbapi_usr, account->usr)) )
1943 break;
1944 }
1945
1946 cs_auth_client(client, ok ? account : (struct s_auth *)(-1), "dvbapi");
1947
1948 dvbapi_read_priority();
1949
1950 openxcas_msg_t msg;
1951 int ret;
1952 while ((ret = openxcas_get_message(&msg, 0)) >= 0) {
1953 cs_sleepms(10);
1954
1955 process_client_pipe(dvbapi_client, NULL, 0);
1956 chk_pending(tp);
1957
1958 if (ret) {
1959 openxcas_stream_id = msg.stream_id;
1960 openxcas_seq = msg.sequence;
1961
1962 switch(msg.cmd) {
1963 case OPENXCAS_SELECT_CHANNEL:
1964 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_SELECT_CHANNEL");
1965
1966 // parse channel info
1967 struct stOpenXCASChannel chan;
1968 memcpy(&chan, msg.buf, msg.buf_len);
1969
1970 cs_log("openxcas: channel change: sid = %x, vpid = %x. apid = %x", chan.service_id, chan.v_pid, chan.a_pid);
1971
1972 openxcas_video_pid = chan.v_pid;
1973 openxcas_audio_pid = chan.a_pid;
1974 openxcas_data_pid = chan.d_pid;
1975 break;
1976 case OPENXCAS_START_PMT_ECM:
1977 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_START_PMT_ECM");
1978
1979 // parse pmt
1980 uchar *dest = malloc(msg.buf_len + 7 - 12 - 4);
1981
1982 memcpy(dest, "\x00\xFF\xFF\x00\x00\x13\x00", 7);
1983
1984 dest[1] = msg.buf[3];
1985 dest[2] = msg.buf[4];
1986 dest[5] = msg.buf[11]+1;
1987
1988 memcpy(dest + 7, msg.buf + 12, msg.buf_len - 12 - 4);
1989
1990 dvbapi_parse_capmt(dest, 7 + msg.buf_len - 12 - 4, -1, NULL);
1991 free(dest);
1992
1993 unsigned char mask[12];
1994 unsigned char comp[12];
1995 memset(&mask, 0x00, sizeof(mask));
1996 memset(&comp, 0x00, sizeof(comp));
1997
1998 mask[0] = 0xfe;
1999 comp[0] = 0x80;
2000
2001 if ((ret = openxcas_add_filter(msg.stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback)) < 0)
2002 cs_log("openxcas: unable to add ecm filter");
2003 else
2004 cs_debug_mask(D_DVBAPI, "openxcas: ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);
2005
2006 if (openxcas_start_filter(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM) < 0)
2007 cs_log("openxcas: unable to start ecm filter");
2008 else
2009 cs_debug_mask(D_DVBAPI, "openxcas: ecm filter started");
2010
2011 if (!openxcas_create_cipher_ex(msg.stream_id, openxcas_seq, 0, openxcas_ecm_pid, openxcas_video_pid, 0xffff, openxcas_audio_pid, 0xffff, 0xffff, 0xffff))
2012 cs_log("openxcas: failed to create cipher ex");
2013 else
2014 cs_debug_mask(D_DVBAPI, "openxcas: cipher created");
2015 break;
2016 case OPENXCAS_STOP_PMT_ECM:
2017 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_STOP_PMT_ECM");
2018 openxcas_stop_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
2019 openxcas_remove_filter(msg.stream_id, OPENXCAS_FILTER_ECM);
2020 openxcas_stop_filter_ex(msg.stream_id, msg.sequence, openxcas_filter_idx);
2021 openxcas_destory_cipher_ex(msg.stream_id, msg.sequence);
2022 memset(&demux, 0, sizeof(demux));
2023 break;
2024 case OPENXCAS_ECM_CALLBACK:
2025 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_ECM_CALLBACK");
2026 struct stOpenXCAS_Data data;
2027 memcpy(&data, msg.buf, msg.buf_len);
2028 if (!openxcas_busy)
2029 openxcas_filter_callback(msg.stream_id, msg.sequence, OPENXCAS_FILTER_ECM, &data);
2030 break;
2031 case OPENXCAS_PID_FILTER_CALLBACK:
2032 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_PID_FILTER_CALLBACK");
2033 openxcas_filter_callback_ex(msg.stream_id, msg.sequence, (struct stOpenXCAS_Data *)msg.buf);
2034 break;
2035 case OPENXCAS_QUIT:
2036 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_QUIT");
2037 openxcas_close();
2038 cs_log("openxcas: exited");
2039 return NULL;
2040 break;
2041 case OPENXCAS_UKNOWN_MSG:
2042 default:
2043 cs_debug_mask(D_DVBAPI, "openxcas: msg: OPENXCAS_UKNOWN_MSG (%d)", msg.cmd);
2044 //cs_ddump_mask(D_DVBAPI, &msg, sizeof(msg), "msg dump:");
2045 break;
2046 }
2047 }
2048 }
2049 cs_log("openxcas: invalid message");
2050 return NULL;
2051}
2052
2053void azbox_send_dcw(struct s_client *client, ECM_REQUEST *er) {
2054 cs_debug_mask(D_DVBAPI, "openxcas: send_dcw");
2055
2056 openxcas_busy = 0;
2057
2058 int i;
2059 for (i=0; i < MAX_DEMUX; i++) {
2060 if (er->rc > 3) {
2061 cs_debug_mask(D_DVBAPI, "cw not found");
2062
2063 if (demux[i].pidindex==-1)
2064 dvbapi_try_next_caid(i);
2065
2066 openxcas_stop_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
2067 openxcas_remove_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
2068
2069 unsigned char mask[12];
2070 unsigned char comp[12];
2071 memset(&mask, 0x00, sizeof(mask));
2072 memset(&comp, 0x00, sizeof(comp));
2073
2074 mask[0] = 0xfe;
2075 comp[0] = 0x80;
2076
2077 if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0) {
2078 cs_log("openxcas: unable to add ecm filter (0)");
2079 if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, openxcas_caid, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0)
2080 cs_log("openxcas: unable to add ecm filter (%04x)", openxcas_caid);
2081 else
2082 cs_debug_mask(D_DVBAPI, "openxcas: ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, openxcas_caid);
2083 } else
2084 cs_debug_mask(D_DVBAPI, "openxcas: ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);
2085
2086 if (openxcas_start_filter(openxcas_stream_id, openxcas_seq, OPENXCAS_FILTER_ECM) < 0)
2087 cs_log("openxcas: unable to start ecm filter");
2088 else
2089 cs_debug_mask(D_DVBAPI, "openxcas: ecm filter started");
2090
2091 return;
2092 }
2093 }
2094
2095 unsigned char nullcw[8];
2096 memset(nullcw, 0, 8);
2097
2098 int n;
2099 for (n=0;n<2;n++) {
2100 if (memcmp(er->cw + (n * 8), demux[0].lastcw[n], 8) && memcmp(er->cw + (n * 8), nullcw, 8)) {
2101 memcpy(demux[0].lastcw[n], er->cw + (n * 8), 8);
2102 memcpy(openxcas_cw + (n * 8), er->cw + (n * 8), 8);
2103 }
2104 }
2105
2106 if (openxcas_set_key(openxcas_stream_id, openxcas_seq, 0, openxcas_cipher_idx, openxcas_cw, openxcas_cw + 8) != 1)
2107 cs_log("openxcas: set cw failed");
2108 else
2109 cs_ddump_mask(D_DVBAPI, openxcas_cw, 16, "openxcas: write cws to descrambler");
2110}
2111#endif
2112/*
2113 * protocol structure
2114 */
2115
2116void module_dvbapi(struct s_module *ph)
2117{
2118 strcpy(ph->desc, "dvbapi");
2119 ph->type=MOD_CONN_SERIAL;
2120 ph->multi=1;
2121 ph->watchdog=0;
2122 ph->s_handler=dvbapi_handler;
2123 ph->send_dcw=dvbapi_send_dcw;
2124}
2125#endif // HAVE_DVBAPI
Note: See TracBrowser for help on using the repository browser.