Skip to content

Commit

Permalink
Fix pmt processing for DDCI
Browse files Browse the repository at this point in the history
  • Loading branch information
catalinii committed Aug 17, 2018
1 parent d31b29f commit 21961e3
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 57 deletions.
58 changes: 26 additions & 32 deletions src/ddci.c
Expand Up @@ -152,7 +152,7 @@ inline static int get_mapping_table(int ad, int pid, int *ddci_adapter, int *rew
int idx = get_index_hash(&mapping_table[0].ad_pid, mapping_table_pids, sizeof(ddci_mapping_table_t), key, key);
if (idx == -1)
return -1;
if(ddci_adapter)
if (ddci_adapter)
*ddci_adapter = mapping_table[idx].ddci_adapter;
if (rewrite)
*rewrite = mapping_table[idx].rewrite;
Expand Down Expand Up @@ -394,19 +394,19 @@ int ddci_create_pat(ddci_device_t *d, uint8_t *b)
b[9] = b[10] = 0;
// PID 16
b[11] = 0x00;
b[12] = 0x10;
b[12] = 0x10;
len = 13;
for (i = 0; i < MAX_CHANNELS_ON_CI; i++)
if ((pmt = get_pmt(d->pmt[i])))
{
int dpid = get_mapping_table(pmt->adapter, pmt->pid, &ddci, NULL);
if(dpid == -1)
if (dpid == -1)
{
LOG("adapter %d pid %d not found in the mapping table", pmt->adapter, pmt->pid);
continue;
}
if(ddci != d->id)

if (ddci != d->id)
{
LOG("adapter %d pid %d not mapped to the right DDCI adapter %d != expected %d", pmt->adapter, pmt->pid, ddci, d->id);
continue;
Expand Down Expand Up @@ -441,12 +441,12 @@ void ddci_replace_pi(int adapter, unsigned char *es, int len)
continue;
capid = (es[i + 4] & 0x1F) * 256 + es[i + 5];
dpid = get_mapping_table(adapter, capid, &ddci, NULL);
if(dpid < 0)
if (dpid < 0)
dpid = capid;

es[i+4] &= 0xE0; //~0x1F
es[i+4] |= (dpid >> 8);
es[i+5] = dpid & 0xFF;
es[i + 4] &= 0xE0; //~0x1F
es[i + 4] |= (dpid >> 8);
es[i + 5] = dpid & 0xFF;
LOGM("%s: CA pid %d -> pid %d", __FUNCTION__, capid, dpid)
}
return;
Expand All @@ -460,12 +460,10 @@ int ddci_create_pmt(ddci_device_t *d, SPMT *pmt, uint8_t *clean)
uint8_t *b, *pi, *pmt_b;
clean[0] = 0;
b = clean + 1;
memcpy(b, pmt->pmt, len);
memcpy(b, pmt->pmt, len);
pi_len = ((b[10] & 0xF) << 8) + b[11];
pmt_len = pmt->pmt_len - 4;

LOGM("%s: PMT %d AD %d, pid: %04X (%d), pmt_len %d, pi_len %d, sid %04X (%d) %s %s",
__FUNCTION__, pmt->id, pmt->adapter, pid, pid, pmt_len, pi_len, pmt->sid, pmt->sid, pmt->name[0] ? "channel:" : "", pmt->name);
pi = b + 12;
pmt_b = pi + pi_len;

Expand All @@ -475,23 +473,26 @@ int ddci_create_pmt(ddci_device_t *d, SPMT *pmt, uint8_t *clean)
if (pi_len > 0)
ddci_replace_pi(pmt->adapter, pi, pi_len);

LOGM("%s: PMT %d AD %d, pid: %04X (%d), pmt_len %d, pi_len %d, total_len %d, sid %04X (%d) %s %s",
__FUNCTION__, pmt->id, pmt->adapter, pid, pid, pmt_len, pi_len, pmt_len - pi_len - 13, pmt->sid, pmt->sid, pmt->name[0] ? "channel:" : "", pmt->name);

es_len = 0;
pmt->active_pids = 0;
pmt->active = 1;
for (i = 0; i < pmt_len - pi_len - 12; i += (es_len) + 5) // reading streams
for (i = 0; i < pmt_len - pi_len - 13; i += (es_len) + 5) // reading streams
{
es_len = (pmt_b[i + 3] & 0xF) * 256 + pmt_b[i + 4];
spid = (pmt_b[i + 1] & 0x1F) * 256 + pmt_b[i + 2];
dpid = get_mapping_table(pmt->adapter, spid, &ddci, NULL);
if(dpid < 0)
dpid = pid;
if (dpid < 0)
dpid = spid;

pmt_b[i+1] &= 0xE0; //~0x1F
pmt_b[i+1] |= (dpid >> 8);
pmt_b[i+2] = dpid & 0xFF;
pmt_b[i + 1] &= 0xE0; //~0x1F
pmt_b[i + 1] |= (dpid >> 8);
pmt_b[i + 2] = dpid & 0xFF;

LOGM("%s: PMT pid %d - stream pid %04X (%d) es_len %d, pos %d",
__FUNCTION__, pid, spid, spid, es_len, i);
LOGM("DDCI: PMT pid %d - stream pid %04X -> %04X es_len %d, pos %d",
pid, spid, dpid, es_len, i);
if ((es_len + i + 5 > pmt_len) || (es_len < 0))
{
LOGM("pmt processing complete, es_len + i %d, len %d, es_len %d", es_len + i, pmt_len, es_len);
Expand All @@ -502,8 +503,8 @@ int ddci_create_pmt(ddci_device_t *d, SPMT *pmt, uint8_t *clean)
}

uint32_t crc = crc_32(b, pmt_len);
copy32(b,pmt_len, crc);
return pmt->pmt_len;
copy32(b, pmt_len, crc);
return pmt_len + 4 + 1;
}

int ddci_add_psi(ddci_device_t *d, uint8_t *dst, int len)
Expand All @@ -527,10 +528,10 @@ int ddci_add_psi(ddci_device_t *d, uint8_t *dst, int len)
{
psi_len = ddci_create_pmt(d, pmt, psi);
int dpid = get_mapping_table(pmt->adapter, pmt->pid, NULL, NULL);
if(dpid != -1)
if (dpid != -1)
pos += buffer_to_ts(dst + pos, len - pos, psi, psi_len, &d->pmt_cc[i], dpid);
else
LOG("%s: could not find PMT adapter %d and pid %d to mapping table", __FUNCTION__, pmt->adapter, pmt->pid);
else
LOG("%s: could not find PMT adapter %d and pid %d to mapping table", __FUNCTION__, pmt->adapter, pmt->pid);
}
d->last_pmt = ctime;
}
Expand Down Expand Up @@ -762,13 +763,6 @@ int push_ts_to_ddci_buffer(ddci_device_t *d, unsigned char *b, int rlen)
int ddci_read_sec_data(sockets *s)
{
unsigned char *b = s->buf;
int i, len = s->rlen;
for (i = 0; i < len; i += 188)
{
int pid = (b[i + 1] & 0x1F) * 256 + b[i + 2];
char cc = b[i + 3] & 0xF;
LOG("pid %d (%X) CC=%X %s pos: %d packet %d : %02X %02X %02X %02X", pid, pid, cc, (b[i + 3] & 0x80) ? "encrypted" : "", i, i / 188, b[i], b[i + 1], b[i + 2], b[i + 3]);
}

read_dmx(s);
if (s->rlen != 0)
Expand Down
2 changes: 1 addition & 1 deletion src/ddci.h
Expand Up @@ -8,7 +8,7 @@
#define PIDS_FOR_ADAPTER 128
#define MAX_CA_PIDS 20

#define DDCI_BUFFER (10000 * 188)
#define DDCI_BUFFER (100000 * 188)
typedef struct ddci_device
{
SMutex mutex;
Expand Down
27 changes: 14 additions & 13 deletions src/utils.c
Expand Up @@ -445,9 +445,9 @@ void set_signal_handler(char *argv0)
LOG("Could not set signal SIGINT");
}

if (sigaction(SIGTERM, &sig_action, NULL) != 0)
if (sigaction(SIGTERM, &sig_action, NULL) != 0)
{
LOG("Could not set signal SIGTERM");
LOG("Could not set signal SIGTERM");
}
if (signal(SIGHUP, SIG_IGN) != 0)
{
Expand Down Expand Up @@ -617,11 +617,11 @@ mymalloc(int a, char *f, int l)

void *myrealloc(void *p, int a, char *f, int l)
{
void *x = realloc(p, a);
if (!p)
memset(x, 0, a);
LOGM("%s:%d allocation_wrapper realloc allocated %d bytes from %p -> %p", f, l, a, p, x);
return x;
void *x = realloc(p, a);
if (!p)
memset(x, 0, a);
LOGM("%s:%d allocation_wrapper realloc allocated %d bytes from %p -> %p", f, l, a, p, x);
return x;
}

void myfree(void *x, char *f, int l)
Expand Down Expand Up @@ -1552,7 +1552,7 @@ void _hexdump(char *desc, void *addr, int len)
int i, pos = 0, bl = (len * 6 < 100) ? 100 : len * 6;
char buff[17];
char buf[bl];
char *pc = (char *)addr;
unsigned char *pc = (unsigned char *)addr;

if (len == 0)
{
Expand Down Expand Up @@ -1809,7 +1809,7 @@ int buffer_to_ts(uint8_t *dest, int dstsize, uint8_t *src, int srclen, char *cc,
while ((srclen > 0) && (len < dstsize))
{
if (dstsize - len < 188)
LOG_AND_RETURN(-1, "Not enough space to copy pid %d, len %d from %d, srclen %d", pid, len, dstsize,srclen)
LOG_AND_RETURN(-1, "Not enough space to copy pid %d, len %d from %d, srclen %d", pid, len, dstsize, srclen)
b = dest + len;
*cc = ((*cc) + 1) % 16;
b[0] = 0x47;
Expand All @@ -1826,21 +1826,22 @@ int buffer_to_ts(uint8_t *dest, int dstsize, uint8_t *src, int srclen, char *cc,
memset(b + left + 4, -1, 184 - left);
if (opts.debug & DEFAULT_LOG)
{
LOG("pid %d, left -> %d, len, cc %d", pid, left, *cc);
LOG("pid %d, left -> %d, len %d, cc %d", pid, left, len, *cc);
hexdump("packet -> ", b, 188);
}
len += 188;
}
return len;
}


void write_buf_to_file(char *file, uint8_t *buf, int len)
{
int x = open(file, O_RDWR);
if(x >= 0)
if (x >= 0)
{
write(x, buf, len);
close(x);
} else LOG("Could not write %d bytes to %s: %d", file, errno);
}
else
LOG("Could not write %d bytes to %s: %d", file, errno);
}
81 changes: 70 additions & 11 deletions tests/test_ddci.c
Expand Up @@ -235,7 +235,7 @@ int test_create_pat()
f.flags = FILTER_CRC;
f.id = 0;
f.adapter = 0;
d.pmt[0] = 1; // set to pmt 1
d.pmt[0] = 1; // set to pmt 1
pmts[1] = &pmt; // enable pmt 1
npmts = 2;
pmt.enabled = 1;
Expand All @@ -244,18 +244,78 @@ int test_create_pat()
psi_len = ddci_create_pat(&d, psi);
cc = 1;
buffer_to_ts(packet, 188, psi, psi_len, &cc, 0);
write_buf_to_file("/jail/tmp/x.ts", packet, 188);
int len = assemble_packet(&f, packet);
if(!len)
if (!len)
return 1;
int new_sid = packet[17] * 256 + packet[18];
int new_pid = packet[19] * 256 + packet[20];
int new_pid = packet[19] * 256 + packet[20];
new_pid &= 0x1FFF;
if(new_pid != dpid)
LOG_AND_RETURN(1, "PAT pid %d != mapping table pid %d", new_pid, dpid);
if(new_sid != pmt.sid)
LOG_AND_RETURN(1, "PAT sid %d != pmt sid %d", new_sid, pmt.sid);
return 0;
if (new_pid != dpid)
LOG_AND_RETURN(1, "PAT pid %d != mapping table pid %d", new_pid, dpid);
if (new_sid != pmt.sid)
LOG_AND_RETURN(1, "PAT sid %d != pmt sid %d", new_sid, pmt.sid);
return 0;
}

int test_create_pmt()
{
ddci_device_t d;
uint8_t psi[188];
uint8_t packet[188];

unsigned char pmt_sample[] = "\x02\xb0\x49\x00\x32\xeb\x00\x00\xe3\xff\xf0\x18\x09\x04\x09\xc4"
"\xfb\x9c\x09\x04\x09\x8c\xfa\x9c\x09\x04\x09\xaf\xff\x9c\x09\x04"
"\x09\x8d\xfc\x9c\x1b\xe3\xff\xf0\x03\x52\x01\x02\x03\xe4\x00\xf0"
"\x09\x0a\x04\x64\x65\x75\x01\x52\x01\x03\x03\xe4\x01\xf0\x09\x0a"
"\x04\x65\x6e\x67\x01\x52\x01\x06\xdc\x54\xdb\x72";

SPMT pmt;
char cc;
int psi_len;
SFilter f;
memset(&d, 0, sizeof(d));
memset(&pmt, 0, sizeof(pmt));
d.id = 0;
d.enabled = 1;
d.wo = DDCI_BUFFER - 188;
d.ro = 188;
memset(d.pid_mapping, -1, sizeof(d.pid_mapping));
memset(ddci_devices, 0, sizeof(ddci_devices));
ddci_devices[0] = &d;
int pid = 1023;
int capid = 7068;
// d.pid_mapping[pid] = 22; // forcing mapping to a different pid
// d.pid_mapping[capid] = 23; // forcing mapping to a different pid
int dpid = add_pid_mapping_table(0, pid, 0, 0);
int dcapid = add_pid_mapping_table(0, capid, 0, 0);
f.flags = FILTER_CRC;
f.id = 0;
f.adapter = 0;
d.pmt[0] = 1; // set to pmt 1
pmts[1] = &pmt; // enable pmt 1
npmts = 2;
pmt.enabled = 1;
pmt.sid = 0x66;
pmt.pid = pid;
strcpy(pmt.name, "TEST CHANNEL HD");
memcpy(pmt.pmt, pmt_sample, sizeof(pmt_sample));
pmt.pmt_len = sizeof(pmt_sample);
psi_len = ddci_create_pmt(&d, &pmt, psi);
cc = 1;
hexdump("PACK ", psi, psi_len);
buffer_to_ts(packet, 188, psi, psi_len, &cc, 0x63);
int len = assemble_packet(&f, packet);
if (!len)
return 1;
int new_pid = packet[42] * 256 + packet[43];
int new_capid = packet[21] * 256 + packet[22];
new_pid &= 0x1FFF;
new_capid &= 0x1FFF;
if (new_pid != dpid)
LOG_AND_RETURN(1, "PMT stream pid %04X != mapping table pid %04X", new_pid, dpid);
if (new_capid != dcapid)
LOG_AND_RETURN(1, "PMT PSI pid %04X != mapping table pid %04X", new_capid, dcapid);
return 0;
}

int main()
Expand All @@ -267,9 +327,8 @@ int main()
TEST_FUNC(test_push_ts_to_ddci(), "testing test_push_ts_to_ddci");
TEST_FUNC(test_copy_ts_from_ddci(), "testing test_copy_ts_from_ddci");
TEST_FUNC(test_ddci_process_ts(), "testing ddci_process_ts");
opts.debug = 0xFFFF;
opts.log = 0xFFFF;
TEST_FUNC(test_create_pat(), "testing create_pat");
TEST_FUNC(test_create_pmt(), "testing create_pat");
fflush(stdout);
return 0;
}

0 comments on commit 21961e3

Please sign in to comment.