src/input/mpegts/dvb_psi.c \
src/input/mpegts/fastscan.c \
src/input/mpegts/mpegts_mux_sched.c \
- src/input/mpegts/mpegts_network_scan.c
+ src/input/mpegts/mpegts_network_scan.c \
+ src/input/mpegts/mpegts_tsdebug.c \
+ src/descrambler/tsdebugcw.c
SRCS-$(CONFIG_MPEGTS) += $(SRCS-MPEGTS)
I18N-C += $(SRCS-MPEGTS)
SRCS-${CONFIG_DDCI} += $(SRCS-DDCI)
I18N-C += $(SRCS-DDCI)
-# TSDEBUGCW
-SRCS-TSDEBUG = \
- src/input/mpegts/mpegts_tsdebug.c \
- src/descrambler/tsdebugcw.c
-SRCS-${CONFIG_TSDEBUG} += $(SRCS-TSDEBUG)
-I18N-C += $(SRCS-TSDEBUG)
-
# crypto algorithms
SRCS-${CONFIG_SSL} += src/descrambler/algo/libaesdec.c
SRCS-${CONFIG_SSL} += src/descrambler/algo/libaes128dec.c
"kqueue:no"
"dbus_1:auto"
"android:no"
- "tsdebug:no"
"gtimer_check:no"
"slow_memoryinfo:no"
"libsystemd_daemon:no"
fi
fi
-#
-# TSDebug
-#
-if enabled_or_auto tsdebug; then
- enable mpegts_dvb
-fi
-
#
# systemd
#
if (j >= DESCRAMBLER_MAX_KEYS) {
tvherror(LS_DESCRAMBLER, "too many keys");
- goto fin;
+ goto end;
}
if (pid == 0)
if (tvhcsa_set_type(&tk->key_csa, type) < 0) {
if (tk->key_type_overwritten)
- goto fin;
+ goto end;
if (type == DESCRAMBLER_CSA_CBC && tk->key_csa.csa_type == DESCRAMBLER_DES_NCB) {
tvhwarn(LS_DESCRAMBLER,
"Keep key%s type %s (requested %s) for service \"%s\", check your caclient",
tvhcsa_destroy(&tk->key_csa);
tvhcsa_init(&tk->key_csa);
if (tvhcsa_set_type(&tk->key_csa, type) < 0)
- goto fin;
+ goto end;
tk->key_valid = 0;
}
td->td_ecm_idle(td);
pthread_mutex_lock(&t->s_stream_mutex);
}
- goto fin;
+ goto end;
}
if (even && memcmp(empty, even, tk->key_csa.csa_keylen)) {
dr->dr_key_const ? " (const)" : "");
}
-fin:
-#if ENABLE_TSDEBUG
- if (j) {
- tsdebug_packet_t *tp = malloc(sizeof(*tp));
- uint16_t keylen = tk->key_csa.csa_keylen;
- mpegts_service_t *ms = (mpegts_service_t *)t;
- uint16_t sid = ms->s_dvb_service_id;
- uint32_t pos = 0, crc;
- mpegts_mux_t *mm = ms->s_dvb_mux;
- mpegts_mux_instance_t *mmi = mm ? mm->mm_active : NULL;
- mpegts_input_t *mi = mmi ? mmi->mmi_input : NULL;
- if (mi == NULL || (mm->mm_tsdebug_fd < 0 && mm->mm_tsdebug_fd2 < 0)) {
- free(tp);
- goto end;
- }
- pthread_mutex_unlock(&t->s_stream_mutex);
- memset(tp->pkt, 0xff, sizeof(tp->pkt));
- tp->pkt[pos++] = 0x47; /* sync byte */
- tp->pkt[pos++] = 0x1f; /* PID MSB */
- tp->pkt[pos++] = 0xff; /* PID LSB */
- tp->pkt[pos++] = 0x00; /* CC */
- memcpy(tp->pkt + pos, "TVHeadendDescramblerKeys", 24);
- pos += 24;
- tp->pkt[pos++] = type & 0xff;
- tp->pkt[pos++] = keylen & 0xff;
- tp->pkt[pos++] = (sid >> 8) & 0xff;
- tp->pkt[pos++] = sid & 0xff;
- tp->pkt[pos++] = (pid >> 8) & 0xff;
- tp->pkt[pos++] = pid & 0xff;
- memcpy(tp->pkt + pos, even ?: empty, keylen);
- memcpy(tp->pkt + pos + keylen, odd ?: empty, keylen);
- pos += 2 * keylen;
- crc = tvh_crc32(tp->pkt, pos, 0x859aa5ba);
- tp->pkt[pos++] = (crc >> 24) & 0xff;
- tp->pkt[pos++] = (crc >> 16) & 0xff;
- tp->pkt[pos++] = (crc >> 8) & 0xff;
- tp->pkt[pos++] = crc & 0xff;
- pthread_mutex_lock(&mm->mm_tsdebug_lock);
- tp->pos = mm->mm_tsdebug_pos;
- TAILQ_INSERT_HEAD(&mm->mm_tsdebug_packets, tp, link);
- pthread_mutex_unlock(&mm->mm_tsdebug_lock);
- return;
- }
-#endif
end:
pthread_mutex_unlock(&t->s_stream_mutex);
}
MM_AC3_PMT_N05,
};
-typedef struct tsdebug_packet {
- TAILQ_ENTRY(tsdebug_packet) link;
- uint8_t pkt[188];
- off_t pos;
-} tsdebug_packet_t;
-
/* Multiplex */
struct mpegts_mux
{
int mm_pmt_ac3;
int mm_eit_tsid_nocheck;
uint16_t mm_sid_filter;
-
- /*
- * TSDEBUG
- */
-#if ENABLE_TSDEBUG
- pthread_mutex_t mm_tsdebug_lock;
- int mm_tsdebug_fd;
- int mm_tsdebug_fd2;
- off_t mm_tsdebug_pos;
- TAILQ_HEAD(, tsdebug_packet) mm_tsdebug_packets;
-#endif
};
#define PREFCAPID_OFF 0
void mpegts_input_open_cat_monitor ( mpegts_mux_t *mm, mpegts_service_t *s );
-#if ENABLE_TSDEBUG
-
-void tsdebug_started_mux(mpegts_input_t *mi, mpegts_mux_t *mm);
-void tsdebug_stopped_mux(mpegts_input_t *mi, mpegts_mux_t *mm);
-void tsdebug_check_tspkt(mpegts_mux_t *mm, uint8_t *pkt, int len);
-
-static inline void
-tsdebug_write(mpegts_mux_t *mm, uint8_t *buf, size_t len)
-{
- if (mm && mm->mm_tsdebug_fd2 >= 0)
- if (write(mm->mm_tsdebug_fd2, buf, len) != len)
- tvherror(LS_TSDEBUG, "unable to write input data (%i)", errno);
-}
-
-static inline ssize_t
-sbuf_tsdebug_read(mpegts_mux_t *mm, sbuf_t *sb, int fd)
-{
- ssize_t r = sbuf_read(sb, fd);
- tsdebug_write(mm, sb->sb_data + sb->sb_ptr - r, r);
- return r;
-}
-
-#else
-
-static inline void tsdebug_started_mux(mpegts_input_t *mi, mpegts_mux_t *mm) { return; }
-static inline void tsdebug_stopped_mux(mpegts_input_t *mi, mpegts_mux_t *mm) { return; }
-static inline void tsdebug_write(mpegts_mux_t *mm, uint8_t *buf, size_t len) { return; }
-static inline ssize_t sbuf_tsdebug_read(mpegts_mux_t *mm, sbuf_t *sb, int fd) { return sbuf_read(sb, fd); }
+void tsdebug_encode_keys
+ ( uint8_t *dst, uint16_t sid, uint16_t pid,
+ uint8_t keytype, uint8_t keylen, uint8_t *even, uint8_t *odd );
-#endif
+void tsdebug_check_tspkt( mpegts_mux_t *mm, uint8_t *pkt, int len );
void mpegts_table_dispatch(const uint8_t *sec, size_t r, void *mt);
static inline void mpegts_table_grab(mpegts_table_t *mt)
*
* vim:sts=2:ts=2:sw=2:et
*****************************************************************************/
-
} else {
sbuf_append(&im->mm_iptv_buffer, buf, len);
}
- tsdebug_write((mpegts_mux_t *)im, buf, len);
hp->off += len;
if (hp->hls_url && hp->off == 0 && len >= 2*188) {
seq = nseq;
/* Move data */
- tsdebug_write((mpegts_mux_t *)im, rtp + hlen, len);
sbuf_append(&im->mm_iptv_buffer, rtp + hlen, len);
res += len;
}
lfe->lfe_nodata = 0;
/* Read */
- if ((n = sbuf_tsdebug_read(mmi->mmi_mux, &sb, dvr)) < 0) {
+ if ((n = sbuf_read(&sb, dvr)) < 0) {
if (ERRNO_AGAIN(errno))
continue;
if (errno == EOVERFLOW) {
{
mpegts_mux_t *mm = mmi->mmi_mux;
- tsdebug_started_mux(mi, mm);
-
/* Deliver first TS packets as fast as possible */
atomic_set_s64(&mi->mi_last_dispatch, 0);
}
notify_reload("input_status");
mpegts_input_dbus_notify(mi, 0);
-
- tsdebug_stopped_mux(mi, mm);
}
static int
int table_wakeup = 0;
mpegts_mux_t *mm = mpkt->mp_mux;
mpegts_mux_instance_t *mmi;
-#if ENABLE_TSDEBUG
- off_t tsdebug_pos;
-#endif
if (mm == NULL || (mmi = mm->mm_active) == NULL)
return 0;
assert(mm == mmi->mmi_mux);
-#if ENABLE_TSDEBUG
- tsdebug_pos = mm->mm_tsdebug_pos;
-#endif
-
/* Process */
assert((len % 188) == 0);
while (len > 0) {
/* Ignore NULL packets */
if (pid == 0x1FFF) {
-#if ENABLE_TSDEBUG
- tsdebug_check_tspkt(mm, tsb, llen);
-#endif
+ if (tsb[4] == 'T' && tsb[5] == 'V')
+ tsdebug_check_tspkt(mm, tsb, llen);
goto done;
}
done:
tsb += llen;
len -= llen;
-#if ENABLE_TSDEBUG
- mm->mm_tsdebug_pos += llen;
-#endif
}
/* Raw stream */
streaming_pad_deliver(&mmi->mmi_streaming_pad, streaming_msg_clone(&sm));
pktbuf_ref_dec(pb);
}
-#if ENABLE_TSDEBUG
- if (mm->mm_tsdebug_fd >= 0 || mm->mm_tsdebug_fd2 >= 0) {
- tsdebug_packet_t *tp, *tp_next;
- off_t pos = 0;
- size_t used = tsb - mpkt->mp_data;
- pthread_mutex_lock(&mm->mm_tsdebug_lock);
- for (tp = TAILQ_FIRST(&mm->mm_tsdebug_packets); tp; tp = tp_next) {
- tp_next = TAILQ_NEXT(tp, link);
- assert((tp->pos % 188) == 0);
- assert(tp->pos >= tsdebug_pos && tp->pos < tsdebug_pos + used);
- if (mm->mm_tsdebug_fd >= 0) {
- tvh_write(mm->mm_tsdebug_fd, mpkt->mp_data + pos, tp->pos - tsdebug_pos - pos);
- tvh_write(mm->mm_tsdebug_fd, tp->pkt, 188);
- }
- pos = tp->pos - tsdebug_pos;
- TAILQ_REMOVE(&mm->mm_tsdebug_packets, tp, link);
- free(tp);
- }
- if (pos < used && mm->mm_tsdebug_fd >= 0)
- tvh_write(mm->mm_tsdebug_fd, mpkt->mp_data + pos, used - pos);
- pthread_mutex_unlock(&mm->mm_tsdebug_lock);
- }
-#endif
if (mpkt->mp_cc_restart) {
LIST_FOREACH(s, &mm->mm_transports, s_active_link)
mm->mm_last_pid = -1;
mm->mm_created = gclk();
-#if ENABLE_TSDEBUG
- pthread_mutex_init(&mm->mm_tsdebug_lock, NULL);
- mm->mm_tsdebug_fd = mm->mm_tsdebug_fd2 = -1;
-#endif
-
/* Configuration */
if (conf)
idnode_load(&mm->mm_id, conf);
/*
* Tvheadend - MPEGTS debug output
- * Copyright (C) 2015,2016,2017 Jaroslav Kysela
+ * Copyright (C) 2015,2016,2017,2018 Jaroslav Kysela
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
#include "input.h"
-#include <fcntl.h>
-#include <sys/stat.h>
-
void
-tsdebug_started_mux
- ( mpegts_input_t *mi, mpegts_mux_t *mm )
+tsdebug_encode_keys
+ ( uint8_t *dst, uint16_t sid, uint16_t pid,
+ uint8_t keytype, uint8_t keylen, uint8_t *even, uint8_t *odd )
{
- extern char *tvheadend_tsdebug;
- static const char *tmpdir = "/tmp/tvheadend.tsdebug/";
- char path[PATH_MAX];
- struct stat st;
- if (!tvheadend_tsdebug && !stat(tmpdir, &st) && (st.st_mode & S_IFDIR) != 0)
- tvheadend_tsdebug = (char *)tmpdir;
- if (tvheadend_tsdebug && !strcmp(tvheadend_tsdebug, tmpdir) && stat(tmpdir, &st))
- tvheadend_tsdebug = NULL;
- if (tvheadend_tsdebug) {
- snprintf(path, sizeof(path), "%s/%s-%li-%p-mux.ts", tvheadend_tsdebug,
- mm->mm_nicename, (long)mono2sec(mclk()), mi);
- mm->mm_tsdebug_fd = tvh_open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
- if (mm->mm_tsdebug_fd < 0)
- tvherror(LS_TSDEBUG, "unable to create file '%s' (%i)", path, errno);
- snprintf(path, sizeof(path), "%s/%s-%li-%p-input.ts", tvheadend_tsdebug,
- mm->mm_nicename, (long)mono2sec(mclk()), mi);
- mm->mm_tsdebug_fd2 = tvh_open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
- if (mm->mm_tsdebug_fd2 < 0)
- tvherror(LS_TSDEBUG, "unable to create file '%s' (%i)", path, errno);
- } else {
- mm->mm_tsdebug_fd = -1;
- mm->mm_tsdebug_fd2 = -1;
- }
-}
+ uint32_t pos = 0, crc;
-void
-tsdebug_stopped_mux
- ( mpegts_input_t *mi, mpegts_mux_t *mm )
-{
- tsdebug_packet_t *tp;
- if (mm->mm_tsdebug_fd >= 0)
- close(mm->mm_tsdebug_fd);
- if (mm->mm_tsdebug_fd2 >= 0)
- close(mm->mm_tsdebug_fd2);
- mm->mm_tsdebug_fd = -1;
- mm->mm_tsdebug_fd2 = -1;
- mm->mm_tsdebug_pos = 0;
- while ((tp = TAILQ_FIRST(&mm->mm_tsdebug_packets)) != NULL) {
- TAILQ_REMOVE(&mm->mm_tsdebug_packets, tp, link);
- free(tp);
- }
+ memset(dst, 0xff, 188);
+ dst[pos++] = 0x47; /* sync byte */
+ dst[pos++] = 0x1f; /* PID MSB */
+ dst[pos++] = 0xff; /* PID LSB */
+ dst[pos++] = 0x00; /* CC */
+ memcpy(dst + pos, "TVHeadendDescramblerKeys", 24);
+ dst += 24;
+ dst[pos++] = keytype;
+ dst[pos++] = keylen;
+ dst[pos++] = (sid >> 8) & 0xff;
+ dst[pos++] = sid & 0xff;
+ dst[pos++] = (pid >> 8) & 0xff;
+ dst[pos++] = pid & 0xff;
+ memcpy(dst + pos, even, keylen);
+ memcpy(dst + pos + keylen, odd, keylen);
+ pos += 2 * keylen;
+ crc = tvh_crc32(dst, pos, 0x859aa5ba);
+ dst[pos++] = (crc >> 24) & 0xff;
+ dst[pos++] = (crc >> 16) & 0xff;
+ dst[pos++] = (crc >> 8) & 0xff;
+ dst[pos++] = crc & 0xff;
}
void
if (crc != tvh_crc32(pkt, pos, 0x859aa5ba))
return;
LIST_FOREACH(t, &mm->mm_services, s_dvb_mux_link)
- if (t->s_dvb_service_id == sid) break;
+ if (t->s_components.set_service_id == sid) break;
if (!t)
return;
pos = 4 + 24 + 4;
}
} else {
wrdata:
- tsdebug_write((mpegts_mux_t *)lfe->sf_curmux, p + pos, len);
sbuf_append(&lfe->sf_sbuf, p + pos, len);
}
next:
if (nfds < 1) continue;
if (ev[0].ptr != hfe) break;
- if((r = sbuf_tsdebug_read(mmi->mmi_mux, &sb, sockfd)) < 0) {
+ if((r = sbuf_read(&sb, sockfd)) < 0) {
/* whoopsy */
if(ERRNO_AGAIN(errno))
continue;