diff --git a/README.md b/README.md index ad35fbb6b6..dd82340149 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The latest binaries for embedded platforms: https://minisatip.org/forum/viewtopi Contact ------- -Please use https://minisatip.org/forum/ for any questions. +Please use https://minisatip.org/forum/ for any question or join slack: https://join.slack.com/t/minisatip/shared_invite/zt-rms717g0-SQR25SFs8RH9JlVZV4II7A In order to speed up the investigation of an issue, please provide the full log and a link to the application that is not working. @@ -31,11 +31,11 @@ https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=7UWQ7FXSABUH8&item Usage: ------- -minisatip version 1.0.4-da99a96, compiled in Feb 3 2021 16:35:57, with s2api version: 050B +minisatip version v1.1.6-76e53d1, compiled in Jun 4 2021 16:58:12, with s2api version: 050B ./minisatip [-[fgtzE]] [-a x:y:z] [-b X:Y] [-B X] [-H X:Y] [-d A:C-U ] [-D device_id] [-e X-Y,Z] [-i prio] [-[uj] A1:S1-F1[-PIN]] [-m mac] [-P port] [-l module1[,module2]] [-v module1[,module2]][-o oscam_host:dvbapi_port,offset] [-p public_host] [-r remote_rtp_host] [-R document_root] [-s [*][DELSYS:][FE_ID@][source_ip/]host[:port] [-u A1:S1-F1[-PIN]] [-L A1:low-high-switch] [-w http_server[:port]] - [-x http_port] [-X xml_path] [-y rtsp_port] + [-x http_port] [-X xml_path] [-y rtsp_port] [-I name_service] Help ------- @@ -46,7 +46,7 @@ Help * eg: -a 1:2:3 - it will report 1 dvb-s2 device, 2 dvb-t2 devices and 3 dvb-c devices -* -A --disable-ssdp disable SSDP announcement +* -G --disable-ssdp disable SSDP announcement * -b --buffer X:Y : set the app adapter buffer to X Bytes (default: 376000) and set the kernel DVB buffer to Y Bytes (default: 5775360) - both multiple of 188 * eg: -b 18800:18988 @@ -75,7 +75,7 @@ Help - note: * as adapter means apply to all adapters * -E Allows encrypted stream to be sent to the client even if the decrypting is unsuccessful - - note: when pids=all is emulated this pass NULLs too + - note: when pids=all is emulated this pass NULLs too * -Y --delsys ADAPTER1:DELIVERY_SYSTEM1[,ADAPTER2:DELIVERY_SYSTEM2[,..]] - specify the delivery system of the adapters (0 is the first adapter) * eg: --delsys 0:dvbt,1:dvbs @@ -95,6 +95,8 @@ Help * -H --threshold X:Y : set the write time threshold to X (UDP) / Y (TCP) milliseconds. * eg: -H 5:50 - set thresholds to 5ms (UDP) and 50ms (TCP) +* -I --name-app specificies an alternative Service Name + * -i --priority prio: set the DVR thread priority to prio * -k Emulate pids=all when the hardware does not support it, on enigma boxes is enabled by default diff --git a/readme_header b/readme_header index 5bb49aeb1e..d54e1aedf6 100755 --- a/readme_header +++ b/readme_header @@ -21,7 +21,7 @@ The latest binaries for embedded platforms: https://minisatip.org/forum/viewtopi Contact ------- -Please use https://minisatip.org/forum/ for any questions. +Please use https://minisatip.org/forum/ for any question or join slack: https://join.slack.com/t/minisatip/shared_invite/zt-rms717g0-SQR25SFs8RH9JlVZV4II7A In order to speed up the investigation of an issue, please provide the full log and a link to the application that is not working. diff --git a/src/dvbapi.c b/src/dvbapi.c index c8a8e4d6d9..5c6b783616 100644 --- a/src/dvbapi.c +++ b/src/dvbapi.c @@ -454,8 +454,7 @@ int dvbapi_send_pmt(SKey *k, int cmd_id) { copy16(buf, 23, 0x8701); // ca_device_descriptor (caX) buf[25] = demux; - memcpy(buf + 26, k->pi, k->pi_len); // CA description - len = 26 + k->pi_len; + len = 26 + pmt_add_ca_descriptor(pmt, buf + 26); // CA description // Pids associated with the PMT copy16(buf, 10, len - 12); @@ -756,15 +755,15 @@ int keys_del(int i) { } if (!ek) { buf[7] = 0xFF; - msg = "ALL"; + msg = "ALL"; TEST_WRITE(write(sock, buf, sizeof(buf)), sizeof(buf)); } else if (!ed) { buf[7] = k->demux_index; - msg = "DEMUX"; + msg = "DEMUX"; TEST_WRITE(write(sock, buf, sizeof(buf)), sizeof(buf)); } else { // only local socket mode where multiple channels are connected to // the same demux - msg = "PMT"; + msg = "PMT"; dvbapi_send_pmt(k, CMD_ID_NOT_SELECTED); } @@ -785,8 +784,8 @@ int keys_del(int i) { k->hops = k->caid = k->info_pid = k->prid = k->ecmtime = 0; dvbapi_last_close = getTick(); - LOG("Stopped key %d, active keys %d, sock %d, pmt pid %d, sid %04X, op %s", i, ek, - sock, pmt_pid, sid, msg); + LOG("Stopped key %d, active keys %d, sock %d, pmt pid %d, sid %04X, op %s", + i, ek, sock, pmt_pid, sid, msg); mutex_destroy(&k->mutex); @@ -813,8 +812,6 @@ int dvbapi_add_pmt(adapter *ad, SPMT *pmt) { LOG_AND_RETURN(1, "Could not add key for pmt %d", pmt->id); mutex_lock(&k->mutex); pmt->opaque = k; - k->pi_len = pmt->pi_len; - k->pi = pmt->pi; k->sid = pmt->sid; k->adapter = ad->id; k->pmt_pid = pid; diff --git a/src/dvbapi.h b/src/dvbapi.h index db4ac4a238..db4f9fa659 100644 --- a/src/dvbapi.h +++ b/src/dvbapi.h @@ -69,8 +69,7 @@ typedef struct struct_key { int ver; int ecms; int program_id; // pmt sid - unsigned char *pi, cardsystem[64], reader[64], from[64], protocol[64]; - int pi_len; + unsigned char cardsystem[64], reader[64], from[64], protocol[64]; int parity; int blen; int tsid, onid; diff --git a/src/pmt.c b/src/pmt.c index 8ba20cd09e..44e86d7291 100644 --- a/src/pmt.c +++ b/src/pmt.c @@ -105,31 +105,33 @@ static inline void mark_pid_null(uint8_t *b) { b[2] |= 0xFF; } -static inline void mark_pcr_only(uint8_t *b) { // Generate a clean packet with only the Adaptation field header and no payload +static inline void +mark_pcr_only(uint8_t *b) { // Generate a clean packet with only the Adaptation + // field header and no payload if ((b[3] & 0x10) == 0) // No payload { - mark_pid_null(b); - return; + mark_pid_null(b); + return; } // Convert the Payload Data in Adaptation Stuffing int i; int payload = get_adaptation_len(b); - for (i=0; i+payload < 188; i++) + for (i = 0; i + payload < 188; i++) b[payload + i] = 0xFF; b[4] += i; // Update the Adaptation field size // Clean the header b[1] &= 0x3F; // Remove TEI & PUSI - // b[1] &= 0x7F; // Remove TEI - // b[1] &= 0xBF; // Remove PUSI + // b[1] &= 0x7F; // Remove TEI + // b[1] &= 0xBF; // Remove PUSI b[3] &= 0x2F; // Set TSC not scrambled & Remove payload flag - //b[3] &= 0x3F // Set TSC not scrambled - //b[3] &= 0xEF // Remove payload flag + // b[3] &= 0x3F // Set TSC not scrambled + // b[3] &= 0xEF // Remove payload flag b[5] |= 0x80; // Set the Discontinuity indicator b[5] &= 0x9f; // Clear Random access indicator & ES priority indicator - //b[5] &= 0xBF; // Clear Random access indicator - //b[5] &= 0xDF; // Clear ES priority indicator + // b[5] &= 0xBF; // Clear Random access indicator + // b[5] &= 0xDF; // Clear ES priority indicator } int register_algo(SCW_op *o) { @@ -961,15 +963,15 @@ void mark_pids_null(adapter *ad) { if ((b[3] & 0x80) == 0x80) { if (opts.debug & (DEFAULT_LOG | LOG_DMX)) LOG("Marking PID %d packet %d pos %d as NULL", pid, i / 188, i); - if (ad->ca_mask && ad->drop_encrypted) - { - // Instead of remove ALL packets, when the packet has a PCR remove all payload and pass it + if (ad->ca_mask && ad->drop_encrypted) { + // Instead of remove ALL packets, when the packet has a PCR + // remove all payload and pass it if (get_has_pcr(b)) // It has PCR { mark_pcr_only(b); - // ad->flush = 1; // Not necessary as process_packets_for_stream() flush all packets. - } - else + // ad->flush = 1; // Not necessary as + // process_packets_for_stream() flush all packets. + } else mark_pid_null(b); } @@ -1521,16 +1523,11 @@ int process_pat(int filter, unsigned char *b, int len, void *opaque) { return 0; } -int pi_exist(int ecapid, int ecaid, unsigned char *es, int len) { - int es_len, caid, capid; +int pmt_caid_exist(SPMT *pmt, uint16_t caid, uint16_t capid) { int i; - for (i = 0; i < len; i += es_len) // reading program info - { - es_len = es[i + 1] + 2; - caid = es[i + 2] * 256 + es[i + 3]; - capid = (es[i + 4] & 0x1F) * 256 + es[i + 5]; - if (caid == ecaid && capid == ecapid) + for (i = 0; i < pmt->caids; i++) { + if (caid == pmt->caid[i] && capid == pmt->capid[i]) return 1; } return 0; @@ -1547,7 +1544,21 @@ int is_ac3_es(unsigned char *es, int len) { return isAC3; } -void find_pi(SPMT *pmt, unsigned char *es, int len) { +void pmt_add_caid(SPMT *pmt, uint16_t caid, uint16_t capid) { + if (!pmt_caid_exist(pmt, caid, capid)) { + LOG("PMT %d PI pos %d caid %04X => pid %04X (%d), index %d", pmt->id, + pmt->caids + 1, caid, capid, capid, pmt->caids); + if (pmt->caids < MAX_CAID - 1) { + pmt->caid[pmt->caids] = caid; + pmt->capid[pmt->caids++] = capid; + } else + LOG("Too many CAIDs for pmt %d, discarding %04X", pmt->id, caid); + } else + LOGM("%s: CAID %d CAPID %d already exists in PMT %d", __FUNCTION__, + caid, capid, pmt->id); +} + +void pmt_add_caids(SPMT *pmt, unsigned char *es, int len) { int es_len, caid, capid; int i; @@ -1559,22 +1570,7 @@ void find_pi(SPMT *pmt, unsigned char *es, int len) { continue; caid = es[i + 2] * 256 + es[i + 3]; capid = (es[i + 4] & 0x1F) * 256 + es[i + 5]; - if (!pi_exist(capid, caid, pmt->pi, pmt->pi_len)) { - if (pmt->pi_len + es_len > sizeof(pmt->pi) - 2) { - LOG("PI is too small %zd", sizeof(pmt->pi)); - return; - } - LOG("PMT %d PI pos %d caid %04X => pid %04X (%d), index %d", pmt->id, pmt->pi_len, - caid, capid, capid, pmt->caids); - memcpy(pmt->pi + pmt->pi_len, es + i, es_len); - pmt->pi_len += es_len; - if (pmt->caids < MAX_CAID - 1) { - pmt->caid[pmt->caids] = caid; - pmt->capid[pmt->caids++] = capid; - } else - LOG("Too many CAIDs for pmt %d, discarding %04X", pmt->id, - caid); - } + pmt_add_caid(pmt, caid, capid); } return; } @@ -1629,7 +1625,7 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { if (pmt->version == ver) { #ifndef DISABLE_TABLES - if (ad && pmt->pi_len && pmt->state && ad->ca_mask && + if (ad && pmt->caids && pmt->state && ad->ca_mask && pmt->master_pmt == pmt->id) send_pmt_to_cas(ad, pmt); #endif @@ -1649,11 +1645,9 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { return 0; } - memset(pmt->pi, 0, sizeof(pmt->pi)); memset(pmt->pmt, 0, sizeof(pmt->pmt)); memcpy(pmt->pmt, b, len); pmt->pmt_len = len; - pmt->pi_len = 0; if (!(p = find_pid(ad->id, pid))) return -1; @@ -1669,11 +1663,12 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { pmt->version = ver; mutex_lock(&pmt->mutex); - LOG("new PMT %d AD %d, pid: %04X (%d), len %d, pi_len %d, ver %d, pcr %d, sid " + LOG("new PMT %d AD %d, pid: %04X (%d), len %d, pi_len %d, ver %d, pcr %d, " + "sid " "%04X " "(%d) %s %s", - pmt->id, ad->id, pid, pid, pmt_len, pi_len, ver, pcr_pid, pmt->sid, pmt->sid, - pmt->name[0] ? "channel:" : "", pmt->name); + pmt->id, ad->id, pid, pid, pmt_len, pi_len, ver, pcr_pid, pmt->sid, + pmt->sid, pmt->name[0] ? "channel:" : "", pmt->name); pi = b + 12; pmt_b = pi + pi_len; @@ -1684,7 +1679,7 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { pmt->stream_pids = 0; if (pi_len > 0) - find_pi(pmt, pi, pi_len); + pmt_add_caids(pmt, pi, pi_len); es_len = 0; pmt->active_pids = 0; @@ -1710,9 +1705,9 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { LOG("PMT pid %d - stream pid %04X (%d), type %d%s, es_len %d, pos " "%d, " - "pi_len %d", + "caids %d", pid, spid, spid, stype, isAC3 ? " [AC3]" : "", es_len, i, - pmt->pi_len); + pmt->caids); if ((es_len + i + 5 > pmt_len) || (es_len < 0)) { LOGM("pmt processing complete, es_len + i %d, len %d, es_len %d", @@ -1729,7 +1724,7 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { if (pmt->first_active_pid < 0 && is_video) pmt->first_active_pid = spid; - find_pi(pmt, pmt_b + i + 5, es_len); + pmt_add_caids(pmt, pmt_b + i + 5, es_len); opmt = get_master_pmt_for_pid(ad->id, spid); if (opmt != -1 && opmt != pmt->master_pmt) { @@ -1749,14 +1744,14 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { } } // Add the PCR pid if it's independent - if (pcr_pid > 0 && pcr_pid < 8191) - { + if (pcr_pid > 0 && pcr_pid < 8191) { if (pmt->stream_pids < MAX_PMT_PIDS - 1) { pmt->stream_pid[pmt->stream_pids].type = 0; pmt->stream_pid[pmt->stream_pids++].pid = pcr_pid; LOG("added independent PCR pid %d for pmt %d", pcr_pid, pmt->id); } else - LOG("Too many pids for pmt %d, discarding prc_pid %d", pmt->id, pcr_pid); + LOG("Too many pids for pmt %d, discarding prc_pid %d", pmt->id, + pcr_pid); } if (pmt->first_active_pid < 0) @@ -1773,12 +1768,15 @@ int process_pmt(int filter, unsigned char *b, int len, void *opaque) { pmt->state = PMT_RUNNING; update_pids(ad->id); } - if (pmt->pi_len && pmt->master_pmt != pmt->id) { - find_pi(get_pmt(pmt->master_pmt), pmt->pi, pmt->pi_len); - } + SPMT *master = get_pmt(pmt->master_pmt); + if (pmt->caids && master && master != pmt) { + int i; + for (i = 0; i < pmt->caids; i++) + pmt_add_caid(master, pmt->caid[i], pmt->capid[i]); + } - if ((pmt->pi_len > 0) && enabled_channels) // PMT contains CA descriptor - // and there are active pids + if ((pmt->caids > 0) && enabled_channels) // PMT contains CA descriptor + // and there are active pids { #ifndef DISABLE_TABLES if (pmt->sid > 0 && pmt->master_pmt == pmt->id) @@ -1957,8 +1955,7 @@ void emulate_add_all_pids(adapter *ad) { updated = 1; } if (!ad->drop_encrypted) { - LOG("%s: adding (enforced) pid 8191 (NULL) too", - __FUNCTION__); + LOG("%s: adding (enforced) pid 8191 (NULL) too", __FUNCTION__); mark_pid_add(p_all->sid[i], ad->id, 8191); } } @@ -2069,21 +2066,36 @@ int pmt_tune(adapter *ad) { return 0; } +int pmt_add_ca_descriptor(SPMT *pmt, uint8_t *buf) { + int i, len = 0; + for (i = 0; i < pmt->caids; i++) { + buf[len] = 0x09; + buf[len + 1] = 0x04; + copy16(buf, len + 2, pmt->caid[i]); + copy16(buf, len + 4, pmt->capid[i]); + len += 6; + LOG("PMT %d added caid %04X, pid %04X, pos %d", pmt->id, pmt->caid[i], + pmt->capid[i], len); + } + return len; +} + int CAPMT_add_PMT(uint8_t *capmt, int len, SPMT *pmt, int cmd_id) { int i = 0, pos = 0; - for (i = 0; i < pmt->stream_pids && pos + 5 + pmt->pi_len < len; i++) { + for (i = 0; i < pmt->stream_pids; i++) { capmt[pos++] = pmt->stream_pid[i].type; copy16(capmt, pos, pmt->stream_pid[i].pid); pos += 2; - copy16(capmt, pos, pmt->pi_len + 1); + int pi_len_pos = pos, pi_len = 0; pos += 2; // append the stream descriptors - if (pmt->pi_len) { + if (pmt->caids) { capmt[pos++] = cmd_id; - memcpy(capmt + pos, pmt->pi, pmt->pi_len); - pos += pmt->pi_len; + pi_len = pmt_add_ca_descriptor(pmt, capmt + pos); + pos += pi_len; } + copy16(capmt, pi_len_pos, pi_len + 1); } return pos; } diff --git a/src/pmt.h b/src/pmt.h index f9253f097c..ce901a98f8 100644 --- a/src/pmt.h +++ b/src/pmt.h @@ -117,8 +117,6 @@ typedef struct struct_pmt { int id; unsigned char pmt[MAX_PI_LEN]; int pmt_len; - unsigned char pi[MAX_PI_LEN]; - int pi_len; int blen; int ca_mask, disabled_ca_mask; SPMT_batch *batch; @@ -223,5 +221,6 @@ void init_algo(); void update_cw(SPMT *pmt); int pmt_decrypt_stream(adapter *ad); int wait_pusi(adapter *ad, int len); +int pmt_add_ca_descriptor(SPMT *pmt, uint8_t *buf); #endif #endif