1 | #ifndef CAM_H |
---|
2 | #define CAM_H |
---|
3 | |
---|
4 | void debugcaservice() |
---|
5 | { |
---|
6 | int i = 0; |
---|
7 | |
---|
8 | for(i = 0; i < MAXCASERVICE; i++) |
---|
9 | { |
---|
10 | if(caservice[i].service != NULL) |
---|
11 | { |
---|
12 | printf("number: %d\n", i); |
---|
13 | printf("service: %p\n", caservice[i].service); |
---|
14 | if(caservice[i].channel != NULL) |
---|
15 | printf("channel: %s\n", caservice[i].channel->name); |
---|
16 | printf("camsockfd: %d\n", caservice[i].camsockfd); |
---|
17 | printf("caslot: %p\n", caservice[i].caslot); |
---|
18 | printf("count: %d\n", caservice[i].count); |
---|
19 | } |
---|
20 | } |
---|
21 | } |
---|
22 | |
---|
23 | int getcaservicebyslot(struct caslot* caslot, int flag) |
---|
24 | { |
---|
25 | int i = 0; |
---|
26 | |
---|
27 | for(i = 0; i < MAXCASERVICE; i++) |
---|
28 | { |
---|
29 | if(caslot == caservice[i].caslot) |
---|
30 | { |
---|
31 | if(flag == 1) |
---|
32 | { |
---|
33 | if(caservice[i].service != NULL && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER)) |
---|
34 | return i; |
---|
35 | } |
---|
36 | else |
---|
37 | return i; |
---|
38 | } |
---|
39 | } |
---|
40 | return -1; |
---|
41 | } |
---|
42 | |
---|
43 | //flag 0 = from zap |
---|
44 | //flag 1 = from watchthread |
---|
45 | //flag 2 = from cathread / caservicedel |
---|
46 | //flag 3 = from recordthread |
---|
47 | int caserviceadd(struct service* snode, int flag) |
---|
48 | { |
---|
49 | int i = 0, first = -1; |
---|
50 | |
---|
51 | if(snode == NULL) return -1; |
---|
52 | |
---|
53 | for(i = 0; i < MAXCASERVICE; i++) |
---|
54 | { |
---|
55 | if(caservice[i].service != NULL && caservice[i].channel == snode->channel) |
---|
56 | { |
---|
57 | if((flag == 0 || flag == 3)) |
---|
58 | { |
---|
59 | caservice[i].service = snode; |
---|
60 | caservice[i].count++; |
---|
61 | return -1; |
---|
62 | } |
---|
63 | return i; |
---|
64 | } |
---|
65 | if(caservice[i].service == NULL && first == -1) |
---|
66 | first = i; |
---|
67 | } |
---|
68 | |
---|
69 | if(first != -1) |
---|
70 | { |
---|
71 | caservice[first].service = snode; |
---|
72 | caservice[first].channel = snode->channel; |
---|
73 | caservice[first].count = 1; |
---|
74 | caservice[first].camsockfd = -1; |
---|
75 | if(caservice[first].caslot != NULL && caservice[first].camanager > -1 && caservice[first].caslot->casession[caservice[first].camanager].inuse > 0) caservice[first].caslot->casession[caservice[first].camanager].inuse = 1; |
---|
76 | caservice[first].caslot = NULL; |
---|
77 | caservice[first].camanager = -1; |
---|
78 | free(caservice[first].capmt); caservice[first].capmt = NULL; |
---|
79 | caservice[first].capmtlen = 0; |
---|
80 | caservice[first].cmdpos = 0; |
---|
81 | return first; |
---|
82 | } |
---|
83 | |
---|
84 | return -1; |
---|
85 | } |
---|
86 | |
---|
87 | void caservicedel(struct service* snode, struct caslot* caslot) |
---|
88 | { |
---|
89 | int i = 0; |
---|
90 | |
---|
91 | for(i = 0; i < MAXCASERVICE; i++) |
---|
92 | { |
---|
93 | if(snode != NULL && caservice[i].service != NULL && caservice[i].channel == snode->channel) |
---|
94 | { |
---|
95 | caservice[i].count--; |
---|
96 | if(caservice[i].count < 1) |
---|
97 | { |
---|
98 | if(caservice[i].camsockfd > -1) |
---|
99 | sockclose(&caservice[i].camsockfd); |
---|
100 | if(caservice[i].caslot != NULL) |
---|
101 | { |
---|
102 | //sendcapmt(caservice[i].service, i + 1, 2); |
---|
103 | if(caservice[i].caslot != NULL && caservice[i].camanager > -1 && caservice[i].caslot->casession[caservice[i].camanager].inuse > 0) caservice[i].caslot->casession[caservice[i].camanager].inuse = 1; |
---|
104 | caservice[i].caslot = NULL; |
---|
105 | caservice[i].camanager = -1; |
---|
106 | } |
---|
107 | free(caservice[i].capmt); caservice[i].capmt = NULL; |
---|
108 | caservice[i].count = 0; |
---|
109 | caservice[i].capmtlen = 0; |
---|
110 | caservice[i].cmdpos = 0; |
---|
111 | caservice[i].service = NULL; |
---|
112 | caservice[i].channel = NULL; |
---|
113 | } |
---|
114 | else |
---|
115 | caservice[i].service = getservicebyservice(snode, 1); |
---|
116 | } |
---|
117 | //remove cam from slot |
---|
118 | if(caservice[i].service != NULL && caservice[i].caslot == caslot) |
---|
119 | { |
---|
120 | if(caservice[i].caslot != NULL && caservice[i].camanager > -1 && caservice[i].caslot->casession[caservice[i].camanager].inuse > 0) caservice[i].caslot->casession[caservice[i].camanager].inuse = 1; |
---|
121 | caservice[i].caslot = NULL; |
---|
122 | caservice[i].camanager = -1; |
---|
123 | } |
---|
124 | } |
---|
125 | } |
---|
126 | |
---|
127 | void freecaservice() |
---|
128 | { |
---|
129 | int i = 0; |
---|
130 | |
---|
131 | for(i = 0; i < MAXCASERVICE; i++) |
---|
132 | { |
---|
133 | free(caservice[i].capmt); |
---|
134 | caservice[i].capmt = NULL; |
---|
135 | |
---|
136 | caservice[i].caslot = NULL; |
---|
137 | caservice[i].camanager = -1; |
---|
138 | caservice[i].capmtlen = 0; |
---|
139 | caservice[i].cmdpos = 0; |
---|
140 | caservice[i].service = NULL; |
---|
141 | caservice[i].channel = NULL; |
---|
142 | |
---|
143 | if(caservice[i].camsockfd > -1) |
---|
144 | sockclose(&caservice[i].camsockfd); |
---|
145 | } |
---|
146 | } |
---|
147 | |
---|
148 | void dvbwritepmt(struct service* node, unsigned char* pmtbuf) |
---|
149 | { |
---|
150 | int length; |
---|
151 | FILE *fd; |
---|
152 | char* filename = NULL, *tmpnr = NULL; |
---|
153 | |
---|
154 | if(node == NULL || pmtbuf == NULL) |
---|
155 | { |
---|
156 | debug(1000, "NULL detect"); |
---|
157 | return; |
---|
158 | } |
---|
159 | |
---|
160 | if(node->fedev == NULL || (node->fedev != NULL && node->fedev->devnr == 0)) |
---|
161 | { |
---|
162 | filename = ostrcat(filename, "/tmp/pmt.tmp", 0, 0); |
---|
163 | } |
---|
164 | else |
---|
165 | { |
---|
166 | tmpnr = oitoa(node->fedev->devnr); |
---|
167 | filename = ostrcat(filename, "/tmp/pmt", 1, 0); |
---|
168 | filename = ostrcat(filename, tmpnr, 1, 1); |
---|
169 | filename = ostrcat(filename, ".tmp", 1, 0); |
---|
170 | } |
---|
171 | |
---|
172 | unlink(filename); |
---|
173 | length =((pmtbuf[1] & 0xf) << 8) + ((pmtbuf[2] + 3) & 0xff); |
---|
174 | if(filename != NULL) |
---|
175 | { |
---|
176 | fd=fopen(filename, "wbt"); |
---|
177 | if(fd != NULL) |
---|
178 | { |
---|
179 | if((int) fwrite(pmtbuf, sizeof(unsigned char), length, fd) != length) |
---|
180 | unlink(filename); |
---|
181 | else |
---|
182 | debug(200, "write %s", filename); |
---|
183 | fclose(fd); |
---|
184 | } |
---|
185 | } |
---|
186 | free(filename); |
---|
187 | } |
---|
188 | |
---|
189 | void sendcapmttosock(struct service* node, unsigned char* buf, int pos, int caservicenr) |
---|
190 | { |
---|
191 | int ret = 0, i = 0; |
---|
192 | |
---|
193 | if(caservice[caservicenr].camsockfd < 0 || socksend(&caservice[caservicenr].camsockfd, buf, pos, -1) != 0) |
---|
194 | { |
---|
195 | ret = sockopen(&caservice[caservicenr].camsockfd, "/tmp/camd.socket", 0, -1); |
---|
196 | if(ret == 0) |
---|
197 | ret = socksend(&caservice[caservicenr].camsockfd, buf, pos, -1); |
---|
198 | } |
---|
199 | |
---|
200 | if(ret == 0 && debug_level == 620) |
---|
201 | { |
---|
202 | printf("CA-PMT: "); |
---|
203 | for(i = 0; i < pos; i++) |
---|
204 | printf("%02x ", buf[i] & 0xff); |
---|
205 | printf("\n"); |
---|
206 | } |
---|
207 | } |
---|
208 | |
---|
209 | //flag 0: cam capmt |
---|
210 | //flag 1: emu capmt |
---|
211 | //flag 2: clear capmt |
---|
212 | int createcapmt(struct dvbdev* dvbnode, struct service* node, unsigned char* buf, int* lenbytes, int flag) |
---|
213 | { |
---|
214 | if(buf == NULL || node == NULL || node->channel == NULL) return -1; |
---|
215 | if(node->fedev == NULL || node->channel->pmt == NULL) return -1; |
---|
216 | if(node->channel->cadesc == NULL || node->channel->esinfo == NULL) return -1; |
---|
217 | |
---|
218 | int pos = 10, i = 0; |
---|
219 | struct cadesc* cadescnode = node->channel->cadesc; |
---|
220 | struct esinfo* esinfonode = node->channel->esinfo; |
---|
221 | |
---|
222 | memset(buf, 0, MINMALLOC); |
---|
223 | |
---|
224 | buf[0] = 0x9F; // ca_pmt_tag |
---|
225 | buf[1] = 0x80; // ca_pmt_tag |
---|
226 | buf[2] = 0x32; // ca_pmt_tag |
---|
227 | |
---|
228 | buf[pos++] = 0x03; //ca_pmt_lst_management: 0=more, 1=first, 2=last, 3=only, 4=add, 5=update |
---|
229 | buf[pos++] = node->channel->pmt->programnumber >> 8; |
---|
230 | buf[pos++] = node->channel->pmt->programnumber & 0xff; |
---|
231 | |
---|
232 | buf[pos++] = (node->channel->pmt->versionnumber << 1) | node->channel->pmt->currentnextindicator; |
---|
233 | |
---|
234 | buf[pos++] = 0x00; //len from here (programinfo len) |
---|
235 | buf[pos++] = 0x00; //len from here (programinfo len) |
---|
236 | buf[pos++] = 0x01; //ca_pmt_cmd_id: ok_descrambling=1 |
---|
237 | |
---|
238 | if(flag == 1) |
---|
239 | { |
---|
240 | buf[pos++] = 0x81; //id (fix) |
---|
241 | buf[pos++] = 0x08; //len |
---|
242 | buf[pos++] = 0x00; //namespace >> 24 |
---|
243 | buf[pos++] = 0x00; //(namespace >> 16) & 0xff |
---|
244 | buf[pos++] = 0x00; //(namespace >> 8) & 0xff |
---|
245 | buf[pos++] = 0x00; //namespace & 0xff |
---|
246 | buf[pos++] = 0x00; //transportstreamid >> 8 |
---|
247 | buf[pos++] = 0x00; //transportstreamid & 0xff |
---|
248 | buf[pos++] = 0x00; //original network id >> 8 |
---|
249 | buf[pos++] = 0x00; //original network id & 0xff |
---|
250 | |
---|
251 | buf[pos++] = 0x82; //id (fix) |
---|
252 | buf[pos++] = 0x02; //len |
---|
253 | |
---|
254 | /* |
---|
255 | while(tmpnode != NULL) |
---|
256 | { |
---|
257 | if(tmpnode->fedev != NULL) |
---|
258 | { |
---|
259 | //(demuxmask |= (1 << dmxdev->devnr) |
---|
260 | buf[pos] |= (1 << tmpnode->fedev->devnr); |
---|
261 | } |
---|
262 | tmpnode = tmpnode->next; |
---|
263 | } |
---|
264 | pos++; |
---|
265 | */ |
---|
266 | buf[pos++] |= (1 << node->fedev->devnr); //cadev_nr |
---|
267 | buf[pos++] = node->fedev->devnr; //demux_dev_nr |
---|
268 | |
---|
269 | buf[pos++] = 0x84; //id (fix) |
---|
270 | buf[pos++] = 0x02; //len |
---|
271 | buf[pos++] = node->channel->pmtpid >> 8; //pmtpid >> 8 |
---|
272 | buf[pos++] = node->channel->pmtpid & 0xff; //pmtpid & 0xff |
---|
273 | } |
---|
274 | |
---|
275 | while(cadescnode != NULL && flag < 2) |
---|
276 | { |
---|
277 | //remove caids, cam can't |
---|
278 | if(flag == 0 && status.casendallcaids == 0) |
---|
279 | { |
---|
280 | char* tmpnr = NULL; |
---|
281 | |
---|
282 | if(dvbnode != NULL) |
---|
283 | { |
---|
284 | tmpnr = oitoa(cadescnode->systemid); |
---|
285 | if(ostrstr(dvbnode->caslot->caids, tmpnr) == NULL) |
---|
286 | { |
---|
287 | free(tmpnr); tmpnr = NULL; |
---|
288 | cadescnode = cadescnode->next; |
---|
289 | continue; |
---|
290 | } |
---|
291 | free(tmpnr); tmpnr = NULL; |
---|
292 | } |
---|
293 | } |
---|
294 | |
---|
295 | if(cadescnode->len > 0 && cadescnode->pid == 0) |
---|
296 | { |
---|
297 | int cadesclen = 0; |
---|
298 | |
---|
299 | buf[pos++] = 0x09; //ca desc tag |
---|
300 | if(flag == 0 && status.caskipprivat == 1) //workaround for to long capmt |
---|
301 | { |
---|
302 | buf[pos++] = 4; |
---|
303 | cadesclen = cadesclen; |
---|
304 | } |
---|
305 | else |
---|
306 | { |
---|
307 | cadesclen = cadescnode->len; |
---|
308 | buf[pos++] = cadesclen; |
---|
309 | } |
---|
310 | buf[pos++] = cadescnode->systemid >> 8; |
---|
311 | buf[pos++] = cadescnode->systemid & 0xff; |
---|
312 | buf[pos++] = (cadescnode->reserved << 5) | (cadescnode->capid >> 8); |
---|
313 | buf[pos++] = cadescnode->capid & 0xff; |
---|
314 | |
---|
315 | if(cadesclen > 4) |
---|
316 | { |
---|
317 | memcpy(&buf[pos], cadescnode->privat, cadesclen - 4); |
---|
318 | pos += cadesclen - 4; |
---|
319 | } |
---|
320 | } |
---|
321 | cadescnode = cadescnode->next; |
---|
322 | } |
---|
323 | |
---|
324 | int tmppos = pos; |
---|
325 | |
---|
326 | while(esinfonode != NULL) |
---|
327 | { |
---|
328 | buf[pos++] = esinfonode->streamtype; |
---|
329 | buf[pos++] = esinfonode->pid >> 8; |
---|
330 | buf[pos++] = esinfonode->pid & 0xff; |
---|
331 | |
---|
332 | int eslenpos = pos; |
---|
333 | int eslen = 0; |
---|
334 | pos += 2; |
---|
335 | |
---|
336 | cadescnode = node->channel->cadesc; |
---|
337 | while(cadescnode != NULL && flag < 2) |
---|
338 | { |
---|
339 | if(cadescnode->len > 0 && cadescnode->pid == esinfonode->pid) |
---|
340 | { |
---|
341 | //remove caids, cam can't |
---|
342 | if(flag == 0 && status.casendallcaids == 0) |
---|
343 | { |
---|
344 | char* tmpnr = NULL; |
---|
345 | |
---|
346 | if(dvbnode != NULL) |
---|
347 | { |
---|
348 | tmpnr = oitoa(cadescnode->systemid); |
---|
349 | if(ostrstr(dvbnode->caslot->caids, tmpnr) == NULL) |
---|
350 | { |
---|
351 | free(tmpnr); tmpnr = NULL; |
---|
352 | cadescnode = cadescnode->next; |
---|
353 | continue; |
---|
354 | } |
---|
355 | free(tmpnr); tmpnr = NULL; |
---|
356 | } |
---|
357 | } |
---|
358 | |
---|
359 | if(eslen == 0) |
---|
360 | { |
---|
361 | eslen = 1; |
---|
362 | buf[pos++] = 0x01; //ca_pmt_cmd_id: ok_descrambling=1 |
---|
363 | } |
---|
364 | eslen = eslen + cadescnode->len + 2; |
---|
365 | buf[pos++] = 0x09; //ca desc tag |
---|
366 | buf[pos++] = cadescnode->len; |
---|
367 | buf[pos++] = cadescnode->systemid >> 8; |
---|
368 | buf[pos++] = cadescnode->systemid & 0xff; |
---|
369 | buf[pos++] = (cadescnode->reserved << 5) | (cadescnode->capid >> 8); |
---|
370 | buf[pos++] = cadescnode->capid & 0xff; |
---|
371 | if(cadescnode->len > 4) |
---|
372 | { |
---|
373 | memcpy(&buf[pos], cadescnode->privat, cadescnode->len - 4); |
---|
374 | pos += cadescnode->len - 4; |
---|
375 | } |
---|
376 | } |
---|
377 | cadescnode = cadescnode->next; |
---|
378 | } |
---|
379 | |
---|
380 | buf[eslenpos + 1] = eslen & 0xff; |
---|
381 | buf[eslenpos] = (eslen >> 8) & 0x0f; |
---|
382 | |
---|
383 | esinfonode = esinfonode->next; |
---|
384 | } |
---|
385 | |
---|
386 | *lenbytes = writelengthfield(&buf[3], pos - 10); |
---|
387 | for(i = 0; i < pos + 10; i++) |
---|
388 | { |
---|
389 | buf[(*lenbytes) + 3 + i] = buf[10 + i]; |
---|
390 | } |
---|
391 | pos = pos - 10 + (*lenbytes) + 3; |
---|
392 | tmppos = tmppos - 10 + (*lenbytes) + 3; |
---|
393 | |
---|
394 | //programinfo len |
---|
395 | buf[8 + (*lenbytes)] = (tmppos - 9 - (*lenbytes)) & 0xff; |
---|
396 | buf[7 + (*lenbytes)] = ((tmppos - 9 - (*lenbytes)) >> 8) & 0x0f; |
---|
397 | |
---|
398 | return pos; |
---|
399 | } |
---|
400 | |
---|
401 | //flag 0 = from zap |
---|
402 | //flag 1 = from watchthread |
---|
403 | //flag 2 = from cathread / caservicedel |
---|
404 | //flag 3 = from recordthread |
---|
405 | void sendcapmt(struct service* node, int clear, int flag) |
---|
406 | { |
---|
407 | int len = 0, i = 0, caservicenr = 0, lenbytes = 0; |
---|
408 | unsigned char* buf = NULL; |
---|
409 | struct dvbdev* dvbnode = dvbdev; |
---|
410 | |
---|
411 | //check if service should decrypt |
---|
412 | if(node == NULL) |
---|
413 | { |
---|
414 | debug(620, "service empty"); |
---|
415 | return; |
---|
416 | } |
---|
417 | if(node->channel == NULL) |
---|
418 | { |
---|
419 | debug(620, "channel empty"); |
---|
420 | return; |
---|
421 | } |
---|
422 | if(node->fedev == NULL) |
---|
423 | { |
---|
424 | debug(620, "no frontend"); |
---|
425 | return; |
---|
426 | } |
---|
427 | |
---|
428 | if(node->channel->crypt == 0) |
---|
429 | { |
---|
430 | debug(620, "channel not crypt"); |
---|
431 | |
---|
432 | //check if we can change input sources |
---|
433 | int doswitch = 1; |
---|
434 | for(i = 0; i < MAXCASERVICE; i++) |
---|
435 | { |
---|
436 | if(caservice[i].caslot != NULL && caservice[i].service != NULL && caservice[i].service->fedev != NULL) |
---|
437 | { |
---|
438 | if(caservice[i].service->fedev->devnr == node->fedev->devnr && (caservice[i].service->type == RECORDDIRECT || caservice[i].service->type == RECORDTIMER)) |
---|
439 | { |
---|
440 | debug(620, "can't change input sources"); |
---|
441 | doswitch = 0; |
---|
442 | } |
---|
443 | } |
---|
444 | } |
---|
445 | |
---|
446 | if(doswitch == 1) |
---|
447 | { |
---|
448 | debug(200, "reset routing tuner %d", node->fedev->devnr); |
---|
449 | switch(node->fedev->devnr) |
---|
450 | { |
---|
451 | case 0: setcisource(node->fedev->devnr, "A"); break; |
---|
452 | case 1: setcisource(node->fedev->devnr, "B"); break; |
---|
453 | case 2: setcisource(node->fedev->devnr, "C"); break; |
---|
454 | case 3: setcisource(node->fedev->devnr, "D"); break; |
---|
455 | } |
---|
456 | } |
---|
457 | |
---|
458 | return; |
---|
459 | } |
---|
460 | |
---|
461 | if(node->channel->pmt == NULL) |
---|
462 | { |
---|
463 | debug(620, "pmt empty"); |
---|
464 | return; |
---|
465 | } |
---|
466 | if(node->channel->cadesc == NULL) |
---|
467 | { |
---|
468 | debug(620, "cadesc empty"); |
---|
469 | return; |
---|
470 | } |
---|
471 | if(node->channel->esinfo == NULL) |
---|
472 | { |
---|
473 | debug(620, "esinfo empty"); |
---|
474 | return; |
---|
475 | } |
---|
476 | if(node->fedev->type == FRONTENDDEVDUMMY) |
---|
477 | { |
---|
478 | debug(620, "dummy frontend not crypt"); |
---|
479 | return; |
---|
480 | } |
---|
481 | if(flag != 3 && node->type != CHANNEL && node->type != RECORDDIRECT && node->type != RECORDTIMER && node->type != RECORDTIMESHIFT && node->type != RECORDSTREAM) |
---|
482 | { |
---|
483 | debug(620, "service type should not decrypt"); |
---|
484 | return; |
---|
485 | } |
---|
486 | |
---|
487 | buf = malloc(MINMALLOC); |
---|
488 | if(buf == NULL) |
---|
489 | { |
---|
490 | err("no mem"); |
---|
491 | return; |
---|
492 | } |
---|
493 | |
---|
494 | if(clear == 0) |
---|
495 | { |
---|
496 | caservicenr = caserviceadd(node, flag); |
---|
497 | if(caservicenr < 0) |
---|
498 | { |
---|
499 | debug(620, "service is decrypt"); |
---|
500 | free(buf); |
---|
501 | return; |
---|
502 | } |
---|
503 | |
---|
504 | int foundcam = 0; |
---|
505 | |
---|
506 | while(dvbnode != NULL) |
---|
507 | { |
---|
508 | if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL) |
---|
509 | { |
---|
510 | if(caservice[caservicenr].caslot == NULL) |
---|
511 | { |
---|
512 | lenbytes = 0; |
---|
513 | len = createcapmt(dvbnode, node, buf, &lenbytes, 0); |
---|
514 | if(len > -1) |
---|
515 | { |
---|
516 | if(sendcapmttocam(dvbnode, node, buf, len, caservicenr, lenbytes + 9, clear) == 0) |
---|
517 | { |
---|
518 | foundcam = 1; |
---|
519 | break; |
---|
520 | } |
---|
521 | } |
---|
522 | } |
---|
523 | } |
---|
524 | dvbnode = dvbnode->next; |
---|
525 | } |
---|
526 | |
---|
527 | if(caservice[caservicenr].camsockfd < 0 && foundcam == 0) |
---|
528 | { |
---|
529 | lenbytes = 0; |
---|
530 | len = createcapmt(NULL, node, buf, &lenbytes, 1); |
---|
531 | if(len > -1) |
---|
532 | sendcapmttosock(node, buf, len, caservicenr); |
---|
533 | } |
---|
534 | } |
---|
535 | |
---|
536 | if(clear > 0) |
---|
537 | { |
---|
538 | while(dvbnode != NULL) |
---|
539 | { |
---|
540 | if(dvbnode->type == CIDEV && dvbnode->fd > -1 && dvbnode->caslot != NULL && dvbnode->caslot->status == 2 && dvbnode->caslot->caids != NULL) |
---|
541 | { |
---|
542 | if(caservice[clear - 1].caslot == dvbnode->caslot) |
---|
543 | { |
---|
544 | lenbytes = 0; |
---|
545 | len = createcapmt(dvbnode, node, buf, &lenbytes, 2); |
---|
546 | if(len > -1) |
---|
547 | sendcapmttocam(dvbnode, node, buf, len, caservicenr, lenbytes + 9, clear); |
---|
548 | break; |
---|
549 | } |
---|
550 | } |
---|
551 | dvbnode = dvbnode->next; |
---|
552 | } |
---|
553 | } |
---|
554 | |
---|
555 | free(buf); |
---|
556 | } |
---|
557 | |
---|
558 | void checkcam() |
---|
559 | { |
---|
560 | int i = 0; |
---|
561 | if(status.pmtmode == 1) return; |
---|
562 | |
---|
563 | //struct can change from another thread |
---|
564 | m_lock(&status.servicemutex, 2); |
---|
565 | for(i = 0; i < MAXCASERVICE; i++) |
---|
566 | { |
---|
567 | if(caservice[i].service != NULL) |
---|
568 | { |
---|
569 | sockcheck(&caservice[i].camsockfd); |
---|
570 | if((caservice[i].camsockfd < 0 && caservice[i].camanager == -1) || caservice[i].caslot == NULL) |
---|
571 | sendcapmt(caservice[i].service, 0, 1); |
---|
572 | } |
---|
573 | } |
---|
574 | m_unlock(&status.servicemutex, 2); |
---|
575 | } |
---|
576 | |
---|
577 | struct pmt* addpmt(struct channel* chnode, int programnumber, int versionnumber, int currentnextindicator) |
---|
578 | { |
---|
579 | struct pmt *newnode = NULL; |
---|
580 | |
---|
581 | if(chnode == NULL) |
---|
582 | { |
---|
583 | err("NULL detect"); |
---|
584 | return NULL; |
---|
585 | } |
---|
586 | |
---|
587 | newnode = (struct pmt*)malloc(sizeof(struct pmt)); |
---|
588 | if(newnode == NULL) |
---|
589 | { |
---|
590 | err("no memory"); |
---|
591 | return NULL; |
---|
592 | } |
---|
593 | |
---|
594 | memset(newnode, 0, sizeof(struct pmt)); |
---|
595 | |
---|
596 | newnode->programnumber = programnumber; |
---|
597 | newnode->versionnumber = versionnumber; |
---|
598 | newnode->currentnextindicator = currentnextindicator; |
---|
599 | |
---|
600 | chnode->pmt = newnode; |
---|
601 | |
---|
602 | return newnode; |
---|
603 | } |
---|
604 | |
---|
605 | struct cadesc* addcadesc(struct channel* chnode, int pid, unsigned char* buf, struct cadesc* last) |
---|
606 | { |
---|
607 | struct cadesc *newnode = NULL, *prev = NULL, *node = NULL; |
---|
608 | |
---|
609 | if(chnode == NULL || buf == NULL) |
---|
610 | { |
---|
611 | err("NULL detect"); |
---|
612 | return NULL; |
---|
613 | } |
---|
614 | |
---|
615 | node = chnode->cadesc; |
---|
616 | |
---|
617 | newnode = (struct cadesc*)malloc(sizeof(struct cadesc)); |
---|
618 | if(newnode == NULL) |
---|
619 | { |
---|
620 | err("no memory"); |
---|
621 | return NULL; |
---|
622 | } |
---|
623 | |
---|
624 | memset(newnode, 0, sizeof(struct cadesc)); |
---|
625 | |
---|
626 | newnode->pid = pid; |
---|
627 | newnode->len = buf[1]; |
---|
628 | newnode->systemid = (buf[2] << 8) | buf[3]; |
---|
629 | newnode->reserved = buf[4] >> 5; |
---|
630 | newnode->capid = ((buf[4] & 0x1F) << 8) | buf[5]; |
---|
631 | |
---|
632 | if(newnode->len > 4) |
---|
633 | { |
---|
634 | newnode->privat = malloc(newnode->len - 4); |
---|
635 | if(newnode->privat == NULL) |
---|
636 | { |
---|
637 | err("no mem"); |
---|
638 | } |
---|
639 | else |
---|
640 | memcpy(newnode->privat, &buf[6], newnode->len - 4); |
---|
641 | } |
---|
642 | |
---|
643 | if(last == NULL) |
---|
644 | { |
---|
645 | while(node != NULL) |
---|
646 | { |
---|
647 | prev = node; |
---|
648 | node = node->next; |
---|
649 | } |
---|
650 | } |
---|
651 | else |
---|
652 | { |
---|
653 | prev = last; |
---|
654 | node = last->next; |
---|
655 | } |
---|
656 | |
---|
657 | if(prev == NULL) |
---|
658 | chnode->cadesc = newnode; |
---|
659 | else |
---|
660 | prev->next = newnode; |
---|
661 | |
---|
662 | newnode->next = node; |
---|
663 | |
---|
664 | return newnode; |
---|
665 | } |
---|
666 | |
---|
667 | struct esinfo* addesinfo(struct channel* chnode, int streamtype, int pid, struct esinfo* last) |
---|
668 | { |
---|
669 | struct esinfo *newnode = NULL, *prev = NULL, *node = NULL; |
---|
670 | |
---|
671 | if(chnode == NULL) |
---|
672 | { |
---|
673 | err("NULL detect"); |
---|
674 | return NULL; |
---|
675 | } |
---|
676 | |
---|
677 | node = chnode->esinfo; |
---|
678 | |
---|
679 | newnode = (struct esinfo*)malloc(sizeof(struct esinfo)); |
---|
680 | if(newnode == NULL) |
---|
681 | { |
---|
682 | err("no memory"); |
---|
683 | return NULL; |
---|
684 | } |
---|
685 | |
---|
686 | memset(newnode, 0, sizeof(struct esinfo)); |
---|
687 | |
---|
688 | newnode->streamtype = streamtype; |
---|
689 | newnode->pid = pid; |
---|
690 | |
---|
691 | if(last == NULL) |
---|
692 | { |
---|
693 | while(node != NULL) |
---|
694 | { |
---|
695 | prev = node; |
---|
696 | node = node->next; |
---|
697 | } |
---|
698 | } |
---|
699 | else |
---|
700 | { |
---|
701 | prev = last; |
---|
702 | node = last->next; |
---|
703 | } |
---|
704 | |
---|
705 | if(prev == NULL) |
---|
706 | chnode->esinfo = newnode; |
---|
707 | else |
---|
708 | prev->next = newnode; |
---|
709 | |
---|
710 | newnode->next = node; |
---|
711 | |
---|
712 | return newnode; |
---|
713 | } |
---|
714 | |
---|
715 | void freepmt(struct channel* chnode) |
---|
716 | { |
---|
717 | if(chnode == NULL || chnode->pmt == NULL) return; |
---|
718 | |
---|
719 | free(chnode->pmt); |
---|
720 | chnode->pmt = NULL; |
---|
721 | } |
---|
722 | |
---|
723 | void freecadesc(struct channel* chnode) |
---|
724 | { |
---|
725 | struct cadesc *node = NULL, *prev = NULL; |
---|
726 | |
---|
727 | if(chnode == NULL) return; |
---|
728 | |
---|
729 | node = chnode->cadesc; |
---|
730 | prev = chnode->cadesc; |
---|
731 | |
---|
732 | while(node != NULL) |
---|
733 | { |
---|
734 | prev = node; |
---|
735 | node = node->next; |
---|
736 | chnode->cadesc = node; |
---|
737 | |
---|
738 | free(prev->privat); |
---|
739 | prev->privat = NULL; |
---|
740 | |
---|
741 | free(prev); |
---|
742 | prev = NULL; |
---|
743 | |
---|
744 | } |
---|
745 | } |
---|
746 | |
---|
747 | void freeesinfo(struct channel* chnode) |
---|
748 | { |
---|
749 | struct esinfo *node = NULL, *prev = NULL; |
---|
750 | |
---|
751 | if(chnode == NULL) return; |
---|
752 | |
---|
753 | node = chnode->esinfo; |
---|
754 | prev = chnode->esinfo; |
---|
755 | |
---|
756 | while(node != NULL) |
---|
757 | { |
---|
758 | prev = node; |
---|
759 | node = node->next; |
---|
760 | chnode->esinfo = node; |
---|
761 | |
---|
762 | free(prev); |
---|
763 | prev = NULL; |
---|
764 | |
---|
765 | } |
---|
766 | } |
---|
767 | |
---|
768 | #endif |
---|