- fix Building without Nagra not possible at Nagra_Merlin https://trac.streamboard...
[oscam.git] / module-streamrelay.c
blobcbea39c3e1956a1ab57b8a2b363a31167390ce5b
1 #define MODULE_LOG_PREFIX "relay"
3 #include "globals.h"
5 #ifdef MODULE_STREAMRELAY
7 #if !STATIC_LIBDVBCSA
8 #include <dlfcn.h>
9 #endif
10 #include "module-streamrelay.h"
11 #include "oscam-config.h"
12 #include "oscam-net.h"
13 #include "oscam-string.h"
14 #include "oscam-time.h"
15 #include "oscam-chk.h"
17 #define STREAM_UNDEFINED 0x00
18 #define STREAM_VIDEO 0x01
19 #define STREAM_AUDIO 0x02
20 #define STREAM_SUBTITLE 0x03
21 #define STREAM_TELETEXT 0x04
23 extern int32_t exit_oscam;
25 typedef struct
27 int32_t connfd;
28 int32_t connid;
29 } stream_client_conn_data;
31 char stream_source_host[256];
32 char *stream_source_auth = NULL;
33 uint32_t cluster_size = 50;
34 bool has_dvbcsa_ecm = 0, is_dvbcsa_static = 1;
36 static uint8_t stream_server_mutex_init = 0;
37 static pthread_mutex_t stream_server_mutex;
38 static int32_t glistenfd, gconncount = 0, gconnfd[STREAM_SERVER_MAX_CONNECTIONS];
40 static pthread_mutex_t fixed_key_srvid_mutex;
41 static uint16_t stream_cur_srvid[STREAM_SERVER_MAX_CONNECTIONS];
42 static stream_client_key_data key_data[STREAM_SERVER_MAX_CONNECTIONS];
44 #ifdef MODULE_RADEGAST
45 static int32_t gRadegastFd = 0;
47 static bool connect_to_radegast(void)
49 struct SOCKADDR cservaddr;
51 if (gRadegastFd == 0)
52 gRadegastFd = socket(DEFAULT_AF, SOCK_STREAM, 0);
54 if (gRadegastFd < 0)
56 gRadegastFd = 0;
57 return false;
60 int32_t flags = fcntl(gRadegastFd, F_GETFL);
61 fcntl(gRadegastFd, F_SETFL, flags | O_NONBLOCK);
63 bzero(&cservaddr, sizeof(cservaddr));
64 SIN_GET_FAMILY(cservaddr) = DEFAULT_AF;
65 SIN_GET_PORT(cservaddr) = htons(cfg.rad_port);
66 SIN_GET_ADDR(cservaddr) = cfg.rad_srvip;
68 if (connect(gRadegastFd, (struct sockaddr *)&cservaddr, sizeof(cservaddr)) == -1)
70 return false;
73 return true;
76 static void close_radegast_connection(void)
78 close(gRadegastFd);
79 gRadegastFd = 0;
82 static bool send_to_radegast(uint8_t* data, int len)
84 if (send(gRadegastFd, data, len, 0) < 0)
86 cs_log("send_to_radegast: Send failure");
87 return false;
89 return true;
92 static void radegast_client_ecm(stream_client_data *cdata)
94 uint16_t section_length = SCT_LEN(cdata->ecm_data);
95 uint8_t md5tmp[MD5_DIGEST_LENGTH];
96 MD5(cdata->ecm_data, section_length, md5tmp);
98 if (!memcmp(cdata->ecm_md5, md5tmp, MD5_DIGEST_LENGTH)) { return; }
99 memcpy(cdata->ecm_md5, md5tmp, MD5_DIGEST_LENGTH);
101 uint16_t packet_len;
102 static uint8_t header_len = 2;
103 static uint8_t payload_static_len = 12;
105 if (gRadegastFd <= 0)
106 { connect_to_radegast(); }
108 packet_len = header_len + payload_static_len + section_length;
109 uint8_t outgoing_data[packet_len];
110 outgoing_data[0] = 1;
111 outgoing_data[1] = payload_static_len + section_length;
112 outgoing_data[2] = 10; // caid
113 outgoing_data[3] = 2;
114 outgoing_data[4] = cdata->caid >> 8;
115 outgoing_data[5] = cdata->caid & 0xFF;
116 outgoing_data[6] = 9; // srvid
117 outgoing_data[7] = 4;
118 outgoing_data[8] = cdata->srvid & 0xFF;
119 outgoing_data[10] = cdata->srvid >> 8;
120 outgoing_data[12] = 3;
121 outgoing_data[13] = section_length;
123 memcpy(outgoing_data + header_len + payload_static_len, cdata->ecm_data, section_length);
125 if (!send_to_radegast(outgoing_data, packet_len))
127 close_radegast_connection();
128 if (connect_to_radegast())
130 send_to_radegast(outgoing_data, packet_len);
135 void ParseEcmData(stream_client_data *cdata)
137 uint8_t *data = cdata->ecm_data;
138 uint16_t section_length = SCT_LEN(data);
140 if (section_length < 11)
142 return;
145 radegast_client_ecm(cdata);
147 #endif // MODULE_RADEGAST
149 static void write_cw(ECM_REQUEST *er, int32_t connid)
151 #if DVBCSA_KEY_ECM
152 const uint8_t ecm = (caid_is_videoguard(er->caid) && (er->ecm[4] != 0 && (er->ecm[2] - er->ecm[4]) == 4)) ? 4 : 0;
153 #endif
154 if (memcmp(er->cw, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0)
156 if (has_dvbcsa_ecm)
158 dvbcsa_bs_key_set(er->cw, key_data[connid].key[EVEN]);
162 if (memcmp(er->cw + 8, "\x00\x00\x00\x00\x00\x00\x00\x00", 8) != 0)
164 if (has_dvbcsa_ecm)
166 dvbcsa_bs_key_set(er->cw + 8, key_data[connid].key[ODD]);
171 bool stream_write_cw(ECM_REQUEST *er)
173 int32_t i;
174 if (er->rc == E_FOUND)
176 bool cw_written = false;
177 //SAFE_MUTEX_LOCK(&fixed_key_srvid_mutex);
178 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
180 if (stream_cur_srvid[i] == er->srvid)
182 write_cw(er, i);
183 cw_written = true;
184 // don't return as there might be more connections for the same channel (e.g. recordings)
187 //SAFE_MUTEX_UNLOCK(&fixed_key_srvid_mutex);
188 return cw_written;
190 return true;
193 static void SearchTsPackets(const uint8_t *buf, const uint32_t bufLength, uint16_t *packetSize, uint16_t *startOffset)
195 uint32_t i;
197 for (i = 0; i < bufLength; i++)
199 if (buf[i] == 0x47)
201 // if three packets align, probably safe to assume correct size
202 if ((buf[i + 188] == 0x47) & (buf[i + 376] == 0x47))
204 (*packetSize) = 188;
205 (*startOffset) = i;
206 return;
208 else if ((buf[i + 204] == 0x47) & (buf[i + 408] == 0x47))
210 (*packetSize) = 204;
211 (*startOffset) = i;
212 return;
214 else if ((buf[i + 208] == 0x47) & (buf[i + 416] == 0x47))
216 (*packetSize) = 208;
217 (*startOffset) = i;
218 return;
223 (*packetSize) = 0;
224 (*startOffset) = 0;
227 typedef void (*ts_data_callback)(stream_client_data *cdata);
229 static void ParseTsData(const uint8_t table_id, const uint8_t table_mask, const uint8_t min_table_length, int8_t *flag,
230 uint8_t *data, const uint16_t data_length, uint16_t *data_pos, const int8_t payloadStart,
231 const uint8_t *buf, const int32_t len, ts_data_callback func, stream_client_data *cdata)
233 int32_t i;
234 uint16_t offset = 0;
235 bool found_start = 0;
237 if (len < 1)
239 return;
242 if (*flag == 0 && !payloadStart)
244 return;
247 if (*flag == 0)
249 *data_pos = 0;
250 offset = 1 + buf[0];
252 else if (payloadStart)
254 offset = 1;
257 if ((len - offset) < 1)
259 return;
262 const int32_t free_data_length = (data_length - *data_pos);
263 const int32_t copySize = (len - offset) > free_data_length ? free_data_length : (len - offset);
265 memcpy(data + *data_pos, buf + offset, copySize);
266 *data_pos += copySize;
268 for (i = 0; i < *data_pos; i++)
270 if ((data[i] & table_mask) == table_id)
272 if (i != 0)
274 if (*data_pos - i > i)
276 memmove(data, &data[i], *data_pos - i);
278 else
280 memcpy(data, &data[i], *data_pos - i);
283 *data_pos -= i;
285 found_start = 1;
286 break;
290 const uint16_t section_length = SCT_LEN(data);
292 if (!found_start || (section_length > data_length) || (section_length < min_table_length))
294 *flag = 0;
295 return;
298 if ((*data_pos < section_length) || (*data_pos < 3))
300 *flag = 2;
301 return;
304 func(cdata);
306 found_start = 0;
307 for (i = section_length; i < *data_pos; i++)
309 if ((data[i] & table_mask) == table_id)
311 if (*data_pos - i > i)
313 memmove(data, &data[i], *data_pos - i);
315 else
317 memcpy(data, &data[i], *data_pos - i);
320 *data_pos -= i;
321 found_start = 1;
322 break;
326 if (!found_start || (data_length < *data_pos + copySize + 1))
328 *data_pos = 0;
331 *flag = 1;
334 static void ParsePatData(stream_client_data *cdata)
336 int32_t i;
337 uint16_t srvid;
338 #ifdef __BISS__
339 cdata->STREAMpidcount = 0;
340 #endif
341 for (i = 8; i + 7 < SCT_LEN(cdata->pat_data); i += 4)
343 srvid = b2i(2, cdata->pat_data + i);
344 if (srvid == 0)
346 continue;
349 if (cdata->srvid == srvid)
351 cdata->pmt_pid = b2i(2, cdata->pat_data + i + 2) & 0x1FFF;
352 cs_log_dbg(D_READER, "Stream client %i found pmt pid: 0x%04X (%i)",
353 cdata->connid, cdata->pmt_pid, cdata->pmt_pid);
354 break;
359 static void ParseDescriptors(const uint8_t *buffer, const uint16_t info_length, uint8_t *type)
361 uint32_t i;
362 uint8_t j, descriptor_length = 0;
364 if (info_length < 1)
366 return;
369 for (i = 0; i + 1 < info_length; i += descriptor_length + 2)
371 descriptor_length = buffer[i + 1];
372 switch (buffer[i]) // descriptor tag
374 case 0x05: // Registration descriptor
376 // "HDMV" format identifier is removed
377 // Cam does not need to know about Blu-ray
378 const char format_identifiers_audio[10][5] =
380 "AC-3", "BSSD", "dmat", "DRA1", "DTS1",
381 "DTS2", "DTS3", "EAC3", "mlpa", "Opus",
383 for (j = 0; j < 10; j++)
385 if (memcmp(buffer + i + 2, format_identifiers_audio[j], 4) == 0)
387 *type = STREAM_AUDIO;
388 break;
391 break;
393 //case 0x09: // CA descriptor
395 // break;
397 case 0x46: // VBI teletext descriptor (DVB)
398 case 0x56: // teletext descriptor (DVB)
400 *type = STREAM_TELETEXT;
401 break;
403 case 0x59: // subtitling descriptor (DVB)
405 *type = STREAM_SUBTITLE;
406 break;
408 case 0x6A: // AC-3 descriptor (DVB)
409 case 0x7A: // enhanced AC-3 descriptor (DVB)
410 case 0x7B: // DTS descriptor (DVB)
411 case 0x7C: // AAC descriptor (DVB)
412 case 0x81: // AC-3 descriptor (ATSC)
413 case 0xCC: // Enhanced AC-3 descriptor (ATSC)
415 *type = STREAM_AUDIO;
416 break;
418 case 0x7F: // extension descriptor (DVB)
420 switch(buffer[i + 2]) // extension descriptor tag
422 case 0x0E: // DTS-HD descriptor (DVB)
423 case 0x0F: // DTS Neural descriptor (DVB)
424 case 0x15: // AC-4 descriptor (DVB)
425 *type = STREAM_AUDIO;
426 break;
428 case 0x20: // TTML subtitling descriptor (DVB)
429 *type = STREAM_SUBTITLE;
430 break;
432 default:
433 *type = STREAM_UNDEFINED;
434 break;
436 break;
438 default:
439 break;
444 static void stream_parse_pmt_ca_descriptor(const uint8_t *data, const int32_t data_pos, const int32_t offset, const uint16_t info_length, stream_client_data *cdata)
446 if (cdata->ecm_pid)
448 return;
451 // parse program descriptors (we are looking only for CA descriptor here)
452 int32_t i;
453 uint16_t caid;
454 uint8_t descriptor_tag, descriptor_length = 0;
456 for (i = offset; i + 1 < offset + info_length; i += descriptor_length + 2)
458 descriptor_tag = data[i + data_pos];
459 descriptor_length = data[i + 1 + data_pos];
460 if (descriptor_length < 1)
462 break;
465 if (i + 1 + descriptor_length >= offset + info_length)
467 break;
470 if (descriptor_tag == 0x09 && descriptor_length >= 4)
472 caid = b2i(2, data + i + 2 + data_pos);
473 if (chk_ctab_ex(caid, &cfg.stream_relay_ctab))
475 if (cdata->caid == NO_CAID_VALUE)
477 cdata->caid = caid;
480 if (cdata->caid != caid)
482 continue;
484 cdata->ecm_pid = b2i(2, data + i + 4 + data_pos) & 0x1FFF;
485 cs_log_dbg(D_READER, "Stream client %i found ecm pid: 0x%04X (%i)",
486 cdata->connid, cdata->ecm_pid, cdata->ecm_pid);
492 static void ParsePmtData(stream_client_data *cdata)
494 int32_t i;
495 uint16_t program_info_length = 0, es_info_length = 0, elementary_pid;
496 const uint16_t section_length = SCT_LEN(cdata->pmt_data);
497 uint8_t offset = 0;
499 cdata->ecm_pid = 0;
500 cdata->pcr_pid = b2i(2, cdata->pmt_data + 8) & 0x1FFF;
502 if (cdata->pcr_pid != 0x1FFF)
504 cs_log_dbg(D_READER, "Stream client %i found pcr pid: 0x%04X (%i)",
505 cdata->connid, cdata->pcr_pid, cdata->pcr_pid);
507 program_info_length = b2i(2, cdata->pmt_data + 10) & 0xFFF;
508 if (!program_info_length)
510 offset = 5;
511 program_info_length = (b2i(2, cdata->pmt_data + 10 + offset) & 0xFFF);
513 if (12 + offset + program_info_length >= section_length) { return; }
514 stream_parse_pmt_ca_descriptor(cdata->pmt_data, 0, 12 + offset, program_info_length, cdata);
516 offset = offset == 5 ? 0 : program_info_length;
517 for (i = 12 + offset; i + 4 < section_length; i += 5 + es_info_length)
519 elementary_pid = b2i(2, cdata->pmt_data + i + 1) & 0x1FFF;
520 es_info_length = b2i(2, cdata->pmt_data + i + 3) & 0xFFF;
521 switch (cdata->pmt_data[i]) // stream type
523 case 0x01:
524 case 0x02:
525 case 0x10:
526 case 0x1B:
527 case 0x20:
528 case 0x24:
529 case 0x25:
530 case 0x42:
531 case 0xD1:
532 case 0xEA:
534 cs_log_dbg(D_READER, "Stream client %i found video pid: 0x%04X (%i)",
535 cdata->connid, elementary_pid, elementary_pid);
536 stream_parse_pmt_ca_descriptor(cdata->pmt_data, i, 5, es_info_length, cdata);
537 break;
539 case 0x03:
540 case 0x04:
541 case 0x0F:
542 case 0x11:
543 case 0x1C:
544 case 0x2D:
545 case 0x2E:
546 case 0x81:
548 cs_log_dbg(D_READER, "Stream client %i found audio pid: 0x%04X (%i)",
549 cdata->connid, elementary_pid, elementary_pid);
550 break;
552 case 0x06:
553 //case 0x81: // some ATSC AC-3 streams do not contain the AC-3 descriptor!
554 case 0x87:
556 uint8_t type = STREAM_UNDEFINED;
557 ParseDescriptors(cdata->pmt_data + i + 5, es_info_length, &type);
558 if (type == STREAM_AUDIO)
560 cs_log_dbg(D_READER, "Stream client %i found audio pid: 0x%04X (%i)",
561 cdata->connid, elementary_pid, elementary_pid);
563 else if (type == STREAM_TELETEXT)
565 cs_log_dbg(D_READER, "Stream client %i found teletext pid: 0x%04X (%i)",
566 cdata->connid, elementary_pid, elementary_pid);
568 break;
571 #ifdef __BISS__
572 cdata->STREAMpids[cdata->STREAMpidcount] = elementary_pid;
573 cdata->STREAMpidcount++;
574 #endif
578 static void ParseTsPackets(stream_client_data *data, uint8_t *stream_buf, uint32_t bufLength, uint16_t packetSize)
580 uint8_t payloadStart;
581 uint16_t pid, offset;
582 uint32_t i, tsHeader;
584 for (i = 0; i < bufLength; i += packetSize)
586 tsHeader = b2i(4, stream_buf + i);
587 pid = (tsHeader & 0x1FFF00) >> 8;
588 payloadStart = (tsHeader & 0x400000) >> 22;
590 if (tsHeader & 0x20)
592 offset = 4 + stream_buf[i + 4] + 1;
594 else
596 offset = 4;
599 if (packetSize - offset < 1)
601 continue;
604 if (pid == 0x0000 && data->have_pat_data != 1) // Search the PAT for the PMT pid
606 ParseTsData(0x00, 0xFF, 16, &data->have_pat_data, data->pat_data, sizeof(data->pat_data),
607 &data->pat_data_pos, payloadStart, stream_buf + i + offset, packetSize - offset, ParsePatData, data);
608 continue;
611 if (pid == data->pmt_pid && data->have_pmt_data != 1) // Search the PMT for PCR, ECM, Video and Audio pids
613 ParseTsData(0x02, 0xFF, 21, &data->have_pmt_data, data->pmt_data, sizeof(data->pmt_data),
614 &data->pmt_data_pos, payloadStart, stream_buf + i + offset, packetSize - offset, ParsePmtData, data);
615 continue;
618 // We have bot PAT and PMT data - No need to search the rest of the packets
619 if (data->have_pat_data == 1 && data->have_pmt_data == 1)
621 break;
626 static void decrypt(struct dvbcsa_bs_batch_s *tsbbatch, uint16_t fill[2], const uint8_t oddeven, const int32_t connid)
628 if (fill[oddeven] > 0)
630 #if 0
631 uint16_t i;
632 for(i = fill[oddeven]; i <= cluster_size; i++)
634 tsbbatch[i].data = NULL;
635 tsbbatch[i].len = 0;
637 #else
638 tsbbatch[fill[oddeven]].data = NULL;
639 #endif
640 //cs_log_dbg(D_READER, "dvbcsa (%s), batch=%d", oddeven == ODD ? "odd" : "even", fill[oddeven]);
642 fill[oddeven] = 0;
644 dvbcsa_bs_decrypt(key_data[connid].key[oddeven], tsbbatch, 184);
647 #define decrypt(a) decrypt(tsbbatch, fill, a, data->connid)
649 static void DescrambleTsPackets(stream_client_data *data, uint8_t *stream_buf, uint32_t bufLength, uint16_t packetSize, struct dvbcsa_bs_batch_s *tsbbatch)
651 uint32_t i, tsHeader;
652 uint16_t offset, fill[2] = {0,0};
653 uint8_t oddeven = 0;
654 #ifdef MODULE_RADEGAST
655 uint16_t pid;
656 uint8_t payloadStart;
657 #endif
659 for (i = 0; i < bufLength; i += packetSize)
661 tsHeader = b2i(4, stream_buf + i);
662 #ifdef MODULE_RADEGAST
663 pid = (tsHeader & 0x1FFF00) >> 8;
664 payloadStart = (tsHeader & 0x400000) >> 22;
665 #endif
666 offset = (tsHeader & 0x20) ? 4 + stream_buf[i + 4] + 1 : 4;
667 if (packetSize - offset < 1)
669 continue;
671 #ifdef MODULE_RADEGAST
672 #ifdef __BISS__
673 if(data->ecm_pid == 0x1FFF && caid_is_biss_fixed(data->caid))
675 uint32_t j, n;
676 uint16_t ecm_len = 7;
677 data->ecm_data[0] = 0x80; // to pass the cache check it must be 0x80 or 0x81
678 data->ecm_data[1] = 0x00;
679 data->ecm_data[2] = 0x04;
680 i2b_buf(2, data->srvid, data->ecm_data + 3);
681 i2b_buf(2, data->pmt_pid, data->ecm_data + 5);
682 for(j = 0, n = 7; j < data->STREAMpidcount; j++, n += 2)
684 i2b_buf(2, data->STREAMpids[j], data->ecm_data + n);
685 data->ecm_data[2] += 2;
686 ecm_len += 2;
688 data->ens &= 0x0FFFFFFF; // clear top 4 bits (in case of DVB-T/C or garbage), prepare for flagging
689 data->ens |= 0xA0000000; // flag to emu: this is the namespace, not a pid
690 i2b_buf(2, data->tsid, data->ecm_data + ecm_len); // place tsid after the last stream pid
691 i2b_buf(2, data->onid, data->ecm_data + ecm_len + 2); // place onid right after tsid
692 i2b_buf(4, data->ens, data->ecm_data + ecm_len + 4); // place namespace at the end of the ecm
693 data->ecm_data[2] += 8;
694 ParseEcmData(data);
695 } else
696 #endif // __BISS__
697 if (data->ecm_pid && pid == data->ecm_pid) // Process the ECM data
699 // set to null pid
700 stream_buf[i + 1] |= 0x1F;
701 stream_buf[i + 2] = 0xFF;
702 ParseTsData(0x80, 0xFE, 3, &data->have_ecm_data, data->ecm_data, sizeof(data->ecm_data),
703 &data->ecm_data_pos, payloadStart, stream_buf + i + offset, packetSize - offset, ParseEcmData, data);
704 continue;
706 #endif // MODULE_RADEGAST
707 if ((tsHeader & 0xC0) == 0)
709 continue;
712 stream_buf[i + 3] &= 0x3f; // consider it decrypted now
713 oddeven = (tsHeader & 0xC0) == 0xC0 ? ODD: EVEN;
714 decrypt(oddeven == ODD ? EVEN : ODD);
715 tsbbatch[fill[oddeven]].data = &stream_buf[i + offset];
716 tsbbatch[fill[oddeven]].len = packetSize - offset;
717 fill[oddeven]++;
719 if (fill[oddeven] > cluster_size - 1)
721 decrypt(oddeven);
725 decrypt(oddeven);
728 static int32_t connect_to_stream(char *http_buf, int32_t http_buf_len, char *stream_path)
730 struct SOCKADDR cservaddr;
731 IN_ADDR_T in_addr;
733 int32_t streamfd = socket(DEFAULT_AF, SOCK_STREAM, 0);
734 if (streamfd == -1) { return -1; }
736 struct timeval tv;
737 tv.tv_sec = 2;
738 tv.tv_usec = 0;
739 if (setsockopt(streamfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv))
741 cs_log("ERROR: setsockopt() failed for SO_RCVTIMEO");
742 return -1;
745 bzero(&cservaddr, sizeof(cservaddr));
746 SIN_GET_FAMILY(cservaddr) = DEFAULT_AF;
747 SIN_GET_PORT(cservaddr) = htons(cfg.stream_source_port);
748 cs_resolve(stream_source_host, &in_addr, NULL, NULL);
749 SIN_GET_ADDR(cservaddr) = in_addr;
751 if (connect(streamfd, (struct sockaddr *)&cservaddr, sizeof(cservaddr)) == -1)
753 cs_log("WARNING: Connect to stream source port %d failed", cfg.stream_source_port);
754 return -1;
757 if (stream_source_auth)
759 snprintf(http_buf, http_buf_len, "GET %s HTTP/1.1\nHost: %s:%u\n"
760 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0\n"
761 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
762 "Accept-Language: en-US\n"
763 "Authorization: Basic %s\n"
764 "Connection: keep-alive\n\n", stream_path, stream_source_host, cfg.stream_source_port, stream_source_auth);
766 else
768 snprintf(http_buf, http_buf_len, "GET %s HTTP/1.1\nHost: %s:%u\n"
769 "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0\n"
770 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\n"
771 "Accept-Language: en-US\n"
772 "Connection: keep-alive\n\n", stream_path, stream_source_host, cfg.stream_source_port);
775 if (send(streamfd, http_buf, cs_strlen(http_buf), 0) == -1) { return -1; }
776 return streamfd;
779 static void stream_client_disconnect(stream_client_conn_data *conndata)
781 int32_t i;
783 SAFE_MUTEX_LOCK(&fixed_key_srvid_mutex);
784 stream_cur_srvid[conndata->connid] = NO_SRVID_VALUE;
785 SAFE_MUTEX_UNLOCK(&fixed_key_srvid_mutex);
787 SAFE_MUTEX_LOCK(&stream_server_mutex);
788 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
790 if (gconnfd[i] == conndata->connfd)
792 gconnfd[i] = -1;
793 gconncount--;
796 SAFE_MUTEX_UNLOCK(&stream_server_mutex);
798 shutdown(conndata->connfd, 2);
799 close(conndata->connfd);
801 cs_log("Stream client %i disconnected",conndata->connid);
803 NULLFREE(conndata);
806 static void *stream_client_handler(void *arg)
808 stream_client_conn_data *conndata = (stream_client_conn_data *)arg;
809 stream_client_data *data;
811 char *http_buf, stream_path[255], stream_path_copy[255];
812 char *saveptr, *token, http_version[4];
814 int8_t streamConnectErrorCount = 0, streamDataErrorCount = 0;
815 int32_t bytesRead = 0, http_status_code = 0;
816 int32_t i, clientStatus, streamStatus, streamfd;
818 uint8_t *stream_buf;
819 uint16_t packetCount = 0, packetSize = 0, startOffset = 0;
820 uint32_t remainingDataPos, remainingDataLength, tmp_pids[4];
821 uint8_t descrambling = 0;
823 const int32_t cur_dvb_buffer_size = DVB_BUFFER_SIZE_CSA;
824 const int32_t cur_dvb_buffer_wait = DVB_BUFFER_WAIT_CSA;
826 struct dvbcsa_bs_batch_s *tsbbatch;
828 cs_log("Stream client %i connected", conndata->connid);
830 if (!cs_malloc(&http_buf, 1024))
832 stream_client_disconnect(conndata);
833 return NULL;
836 if (!cs_malloc(&stream_buf, DVB_BUFFER_SIZE))
838 NULLFREE(http_buf);
839 stream_client_disconnect(conndata);
840 return NULL;
843 if (!cs_malloc(&data, sizeof(stream_client_data)))
845 NULLFREE(http_buf);
846 NULLFREE(stream_buf);
847 stream_client_disconnect(conndata);
848 return NULL;
851 clientStatus = recv(conndata->connfd, http_buf, 1024, 0);
852 if (clientStatus < 1)
854 NULLFREE(http_buf);
855 NULLFREE(stream_buf);
856 NULLFREE(data);
857 stream_client_disconnect(conndata);
858 return NULL;
861 http_buf[1023] = '\0';
862 if (sscanf(http_buf, "GET %254s ", stream_path) < 1)
864 NULLFREE(http_buf);
865 NULLFREE(stream_buf);
866 NULLFREE(data);
867 stream_client_disconnect(conndata);
868 return NULL;
871 cs_strncpy(stream_path_copy, stream_path, sizeof(stream_path));
873 token = strtok_r(stream_path_copy, ":", &saveptr); // token 0
874 for (i = 1; token != NULL && i < 7; i++) // tokens 1 to 6
876 token = strtok_r(NULL, ":", &saveptr);
877 if (token == NULL)
879 break;
882 if (i >= 3) // We olny need token 3 (srvid), 4 (tsid), 5 (onid) and 6 (ens)
884 if (sscanf(token, "%x", &tmp_pids[i - 3]) != 1)
886 tmp_pids[i - 3] = 0;
891 data->srvid = tmp_pids[0] & 0xFFFF;
892 data->tsid = tmp_pids[1] & 0xFFFF;
893 data->onid = tmp_pids[2] & 0xFFFF;
894 data->ens = tmp_pids[3];
896 if (data->srvid == 0) // We didn't get a srvid - Exit
898 NULLFREE(http_buf);
899 NULLFREE(stream_buf);
900 NULLFREE(data);
901 stream_client_disconnect(conndata);
902 return NULL;
905 key_data[conndata->connid].key[ODD] = dvbcsa_bs_key_alloc();
906 key_data[conndata->connid].key[EVEN] = dvbcsa_bs_key_alloc();
908 if (!cs_malloc(&tsbbatch, (cluster_size + 1) * sizeof(struct dvbcsa_bs_batch_s)))
910 NULLFREE(http_buf);
911 NULLFREE(stream_buf);
912 NULLFREE(data);
913 stream_client_disconnect(conndata);
914 return NULL;
917 SAFE_MUTEX_LOCK(&fixed_key_srvid_mutex);
918 stream_cur_srvid[conndata->connid] = data->srvid;
919 SAFE_MUTEX_UNLOCK(&fixed_key_srvid_mutex);
921 cs_log("Stream client %i request %s", conndata->connid, stream_path);
923 cs_log_dbg(D_READER, "Stream client %i received srvid: %04X tsid: %04X onid: %04X ens: %08X",
924 conndata->connid, data->srvid, data->tsid, data->onid, data->ens);
926 snprintf(http_buf, 1024, "HTTP/1.0 200 OK\nConnection: Close\nContent-Type: video/mpeg\nServer: stream_enigma2\n\n");
927 clientStatus = send(conndata->connfd, http_buf, cs_strlen(http_buf), 0);
929 data->connid = conndata->connid;
930 data->caid = NO_CAID_VALUE;
931 data->have_pat_data = 0;
932 data->have_pmt_data = 0;
933 data->have_cat_data = 0;
934 data->have_ecm_data = 0;
935 data->have_emm_data = 0;
937 while (!exit_oscam && clientStatus != -1 && streamConnectErrorCount < 3
938 && streamDataErrorCount < 15)
940 streamfd = connect_to_stream(http_buf, 1024, stream_path);
941 if (streamfd == -1)
943 cs_log("WARNING: stream client %i cannot connect to stream source", conndata->connid);
944 streamConnectErrorCount++;
945 cs_sleepms(500);
946 continue;
948 streamStatus = 0;
949 bytesRead = 0;
950 while (!exit_oscam && clientStatus != -1 && streamStatus != -1
951 #if 0
952 && streamConnectErrorCount < 3 && streamDataErrorCount < 15)
953 #else
954 && (streamConnectErrorCount < 3 || streamDataErrorCount < 15))
955 #endif
957 streamStatus = recv(streamfd, stream_buf + bytesRead, cur_dvb_buffer_size - bytesRead, MSG_WAITALL);
958 if (streamStatus == 0) // socket closed
960 cs_log("WARNING: stream client %i - stream source closed connection", conndata->connid);
961 streamConnectErrorCount++;
962 cs_sleepms(100);
963 break;
965 if (streamStatus < 0) // error
967 if ((errno == EWOULDBLOCK) | (errno == EAGAIN))
969 cs_log("WARNING: stream client %i no data from stream source", conndata->connid);
970 streamDataErrorCount++; // 2 sec timeout * 15 = 30 seconds no data -> close
971 cs_sleepms(100);
972 continue;
974 cs_log("WARNING: stream client %i error receiving data from stream source", conndata->connid);
975 streamConnectErrorCount++;
976 cs_sleepms(100);
977 break;
979 if (streamStatus < cur_dvb_buffer_size - bytesRead) // probably just received header but no stream
981 if (!bytesRead && streamStatus > 13 &&
982 sscanf((const char*)stream_buf, "HTTP/%3s %d ", http_version , &http_status_code) == 2 &&
983 http_status_code != 200)
985 cs_log("ERROR: stream client %i got %d response from stream source", conndata->connid, http_status_code);
986 streamConnectErrorCount++;
987 cs_sleepms(100);
988 break;
990 else
992 cs_log_dbg(0, "WARNING: stream client %i non-full buffer from stream source", conndata->connid);
993 streamDataErrorCount++;
994 cs_sleepms(100);
997 else
999 streamDataErrorCount = 0;
1002 streamConnectErrorCount = 0;
1003 bytesRead += streamStatus;
1005 if (bytesRead >= cur_dvb_buffer_wait)
1007 startOffset = 0;
1009 // only search if not starting on ts packet or unknown packet size
1010 if (stream_buf[0] != 0x47 || packetSize == 0)
1012 SearchTsPackets(stream_buf, bytesRead, &packetSize, &startOffset);
1015 if (packetSize == 0)
1017 bytesRead = 0;
1019 else
1021 packetCount = ((bytesRead - startOffset) / packetSize);
1023 // We have both PAT and PMT data - We can start descrambling
1024 if (data->have_pat_data == 1 && data->have_pmt_data == 1)
1026 if (chk_ctab_ex(data->caid, &cfg.stream_relay_ctab) && (data->caid != 0xA101 || data->caid == NO_CAID_VALUE))
1028 DescrambleTsPackets(data, stream_buf + startOffset, packetCount * packetSize, packetSize, tsbbatch);
1029 if (!descrambling && cfg.stream_relay_buffer_time) {
1030 cs_sleepms(cfg.stream_relay_buffer_time);
1031 descrambling = 1;
1034 else
1036 cs_log_dbg(D_READER, "Stream client %i caid %04X not enabled in stream relay config",
1037 conndata->connid, data->caid);
1040 else // Search PAT and PMT packets for service information
1042 ParseTsPackets(data, stream_buf + startOffset, packetCount * packetSize, packetSize);
1045 clientStatus = send(conndata->connfd, stream_buf + startOffset, packetCount * packetSize, 0);
1047 remainingDataPos = startOffset + (packetCount * packetSize);
1048 remainingDataLength = bytesRead - remainingDataPos;
1050 if (remainingDataPos < remainingDataLength)
1052 memmove(stream_buf, stream_buf + remainingDataPos, remainingDataLength);
1054 else
1056 memcpy(stream_buf, stream_buf + remainingDataPos, remainingDataLength);
1059 bytesRead = remainingDataLength;
1064 close(streamfd);
1067 NULLFREE(http_buf);
1068 NULLFREE(stream_buf);
1070 dvbcsa_bs_key_free(key_data[conndata->connid].key[ODD]);
1071 dvbcsa_bs_key_free(key_data[conndata->connid].key[EVEN]);
1072 NULLFREE(tsbbatch);
1074 NULLFREE(data);
1076 stream_client_disconnect(conndata);
1077 return NULL;
1080 void *stream_server(void *UNUSED(a))
1082 #ifdef IPV6SUPPORT
1083 struct sockaddr_in6 servaddr, cliaddr;
1084 #else
1085 struct sockaddr_in servaddr, cliaddr;
1086 #endif
1087 socklen_t clilen;
1088 int32_t connfd, reuse = 1, i;
1089 int8_t connaccepted;
1090 stream_client_conn_data *conndata;
1092 cluster_size = dvbcsa_bs_batch_size();
1093 has_dvbcsa_ecm = (DVBCSA_HEADER_ECM);
1095 #if !DVBCSA_KEY_ECM
1096 #pragma message "WARNING: Streamrelay is compiled without dvbcsa ecm headers! ECM processing via Streamrelay will not work!"
1097 #endif
1098 #if !STATIC_LIBDVBCSA
1099 has_dvbcsa_ecm = (dlsym(RTLD_DEFAULT, "dvbcsa_bs_key_set_ecm"));
1100 is_dvbcsa_static = 0;
1101 #endif
1103 cs_log("%s: (%s) %s dvbcsa parallel mode = %d (relay buffer time: %d ms)%s%s",
1104 (!DVBCSA_HEADER_ECM || !has_dvbcsa_ecm) ? "WARNING" : "INFO",
1105 (!has_dvbcsa_ecm) ? "wrong" : "ecm",
1106 (!is_dvbcsa_static) ? "dynamic" : "static",
1107 cluster_size,
1108 cfg.stream_relay_buffer_time,
1109 (!DVBCSA_HEADER_ECM || !has_dvbcsa_ecm) ? "! ECM processing via Streamrelay does not work!" : "",
1110 (!DVBCSA_HEADER_ECM) ? " Missing dvbcsa ecm headers during build!" : "");
1112 if (!stream_server_mutex_init)
1114 SAFE_MUTEX_INIT(&stream_server_mutex, NULL);
1115 stream_server_mutex_init = 1;
1118 SAFE_MUTEX_LOCK(&fixed_key_srvid_mutex);
1119 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
1121 stream_cur_srvid[i] = NO_SRVID_VALUE;
1123 SAFE_MUTEX_UNLOCK(&fixed_key_srvid_mutex);
1125 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
1127 gconnfd[i] = -1;
1129 #ifdef IPV6SUPPORT
1130 glistenfd = socket(AF_INET6, SOCK_STREAM, 0);
1131 if (glistenfd == -1)
1133 cs_log("ERROR: cannot create stream server socket");
1134 return NULL;
1137 bzero(&servaddr,sizeof(servaddr));
1138 servaddr.sin6_family = AF_INET6;
1139 servaddr.sin6_addr = in6addr_any;
1140 servaddr.sin6_port = htons(cfg.stream_relay_port);
1141 #else
1142 glistenfd = socket(AF_INET, SOCK_STREAM, 0);
1143 if (glistenfd == -1)
1145 cs_log("ERROR: cannot create stream server socket");
1146 return NULL;
1149 bzero(&servaddr,sizeof(servaddr));
1150 servaddr.sin_family = AF_INET;
1151 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
1152 servaddr.sin_port = htons(cfg.stream_relay_port);
1153 #endif
1154 setsockopt(glistenfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
1156 if (bind(glistenfd,(struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
1158 cs_log("ERROR: cannot bind to stream server socket");
1159 close(glistenfd);
1160 return NULL;
1163 if (listen(glistenfd, 3) == -1)
1165 cs_log("ERROR: cannot listen to stream server socket");
1166 close(glistenfd);
1167 return NULL;
1170 while (!exit_oscam)
1172 clilen = sizeof(cliaddr);
1173 connfd = accept(glistenfd,(struct sockaddr *)&cliaddr, &clilen);
1175 if (connfd == -1)
1177 cs_log("ERROR: accept() failed");
1178 break;
1181 connaccepted = 0;
1183 #ifdef MODULE_RADEGAST
1184 if(cfg.stream_client_source_host)
1186 #ifdef IPV6SUPPORT
1187 // Read ip of client who wants to play the stream
1188 unsigned char *ip = (unsigned char *)&cliaddr.sin6_addr;
1189 cs_log("Stream Client ip is: %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x, will fetch stream there\n", ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]);
1191 // Store ip of client in stream_source_host variable
1192 snprintf(stream_source_host, sizeof(stream_source_host), "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", ip[0], ip[1], ip[2], ip[3], ip[4], ip[5], ip[6], ip[7], ip[8], ip[9], ip[10], ip[11], ip[12], ip[13], ip[14], ip[15]);
1193 #else
1194 // Read ip of client who wants to play the stream
1195 unsigned char *ip = (unsigned char *)&cliaddr.sin_addr.s_addr;
1196 cs_log("Stream Client ip is: %d.%d.%d.%d, will fetch stream there\n", ip[0], ip[1], ip[2], ip[3]);
1198 // Store ip of client in stream_source_host variable
1199 snprintf(stream_source_host, sizeof(stream_source_host), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
1200 #endif
1202 #endif
1204 if (cs_malloc(&conndata, sizeof(stream_client_conn_data)))
1206 SAFE_MUTEX_LOCK(&stream_server_mutex);
1207 if (gconncount < STREAM_SERVER_MAX_CONNECTIONS)
1209 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
1211 if (gconnfd[i] == -1)
1213 gconnfd[i] = connfd;
1214 gconncount++;
1215 connaccepted = 1;
1217 conndata->connfd = connfd;
1218 conndata->connid = i;
1220 break;
1224 SAFE_MUTEX_UNLOCK(&stream_server_mutex);
1227 if (connaccepted)
1229 int on = 1;
1230 if (setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0)
1232 cs_log("ERROR: stream client %i setsockopt() failed for TCP_NODELAY", conndata->connid);
1235 start_thread("stream client", stream_client_handler, (void*)conndata, NULL, 1, 0);
1237 else
1239 shutdown(connfd, 2);
1240 close(connfd);
1241 cs_log("ERROR: stream server client dropped because of too many connections (%i)", STREAM_SERVER_MAX_CONNECTIONS);
1244 cs_sleepms(20);
1247 close(glistenfd);
1249 return NULL;
1252 void init_stream_server(void)
1254 char authtmp[128];
1256 if (cfg.stream_relay_enabled)
1259 cs_strncpy(stream_source_host, cfg.stream_source_host, sizeof(stream_source_host));
1261 if (cfg.stream_source_auth_user && cfg.stream_source_auth_password)
1263 snprintf(authtmp, sizeof(authtmp), "%s:%s", cfg.stream_source_auth_user, cfg.stream_source_auth_password);
1264 b64encode(authtmp, cs_strlen(authtmp), &stream_source_auth);
1267 start_thread("stream_server", stream_server, NULL, NULL, 1, 1);
1268 cs_log("Stream Relay server initialized");
1272 void stop_stream_server(void)
1274 int32_t i;
1276 SAFE_MUTEX_LOCK(&stream_server_mutex);
1277 for (i = 0; i < STREAM_SERVER_MAX_CONNECTIONS; i++)
1279 if (gconnfd[i] != -1)
1281 shutdown(gconnfd[i], 2);
1282 close(gconnfd[i]);
1283 gconnfd[i] = -1;
1287 gconncount = 0;
1288 SAFE_MUTEX_UNLOCK(&stream_server_mutex);
1290 #ifdef MODULE_RADEGAST
1291 close_radegast_connection();
1292 #endif
1294 shutdown(glistenfd, 2);
1295 close(glistenfd);
1298 #endif // MODULE_STREAMRELAY