The sources are capmt (oscam's DVBAPI) ECM INFO and cwc (newcamd) client.
The latest DVBAPI network protocol should be used to get this info.
int descrambler_resolved ( struct service *t, th_descrambler_t *ignore );
void descrambler_keys ( th_descrambler_t *t, int type,
const uint8_t *even, const uint8_t *odd );
+void descrambler_notify ( th_descrambler_t *t,
+ uint16_t caid, uint32_t provid,
+ const char *cardsystem, uint16_t pid, uint32_t ecmtime,
+ uint16_t hops, const char *reader, const char *from,
+ const char *protocol );
int descrambler_descramble ( struct service *t,
struct elementary_stream *st,
const uint8_t *tsb, int len );
pthread_mutex_unlock(&capmt->capmt_mutex);
}
+static void
+capmt_process_notify(capmt_t *capmt, uint8_t adapter,
+ uint16_t sid, uint16_t caid, uint32_t provid,
+ const char *cardsystem, uint16_t pid, uint32_t ecmtime,
+ uint16_t hops, const char *reader, const char *from,
+ const char *protocol )
+{
+ mpegts_service_t *t;
+ capmt_service_t *ct;
+
+ pthread_mutex_lock(&capmt->capmt_mutex);
+ LIST_FOREACH(ct, &capmt->capmt_services, ct_link) {
+ t = (mpegts_service_t *)ct->td_service;
+
+ if (sid != t->s_dvb_service_id)
+ continue;
+ if (adapter != ct->ct_adapter)
+ continue;
+
+ descrambler_notify((th_descrambler_t *)ct, caid, provid,
+ cardsystem, pid, ecmtime, hops, reader, from,
+ protocol);
+ }
+ pthread_mutex_unlock(&capmt->capmt_mutex);
+}
+
static int
capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
{
char *protocol = capmt_peek_str(sb, &offset2);
uint8_t hops = sbuf_peek_u8(sb, offset2);
+ capmt_process_notify(capmt, adapter, sid, caid, provid,
+ cardsystem, pid, ecmtime, hops, reader,
+ from, protocol);
+
tvhlog(LOG_DEBUG, "capmt", "%s: ECM_INFO: adapter=%d sid=%d caid=%04X(%s) pid=%04X provid=%06X ecmtime=%d hops=%d reader=%s from=%s protocol=%s",
capmt_name(capmt), adapter, sid, caid, cardsystem, pid, provid, ecmtime, hops, reader, from, protocol);
int es_section;
int es_channel;
+ uint16_t es_caid;
+ uint16_t es_provid;
uint16_t es_seq;
char es_nok;
cwc_t *cwc = ct->cs_cwc;
ecm_pid_t *ep;
ecm_section_t *es2;
- char chaninfo[32];
+ char chaninfo[128];
int i;
int64_t delay = (getmonoclock() - es->es_time) / 1000LL; // in ms
descrambler_keys((th_descrambler_t *)ct, DESCRAMBLER_AES, msg + 3, msg + 3 + 16);
pthread_mutex_lock(&cwc->cwc_mutex);
}
+
+ snprintf(chaninfo, sizeof(chaninfo), "%s:%i", cwc->cwc_hostname, cwc->cwc_port);
+ descrambler_notify((th_descrambler_t *)ct,
+ es->es_caid, es->es_provid,
+ caid2name(es->es_caid),
+ es->es_channel, delay,
+ 1, "", chaninfo, "newcamd");
}
}
struct cs_card_data *pcard = NULL;
caid_t *c;
uint16_t caid;
- uint32_t providerid;
+ uint32_t provid;
if (data == NULL)
return;
found:
caid = c->caid;
- providerid = c->providerid;
+ provid = c->providerid;
switch(data[0]) {
case 0x80:
if (es->es_keystate == ES_FORBIDDEN || es->es_keystate == ES_IDLE)
break;
+ es->es_caid = caid;
+ es->es_provid = provid;
es->es_channel = channel;
es->es_pending = 1;
es->es_resolved = 0;
goto end;
}
- es->es_seq = cwc_send_msg(cwc, data, len, sid, 1, caid, providerid);
+ es->es_seq = cwc_send_msg(cwc, data, len, sid, 1, caid, provid);
tvhlog(LOG_DEBUG, "cwc",
"Sending ECM%s section=%d/%d, for service \"%s\" (seqno: %d)",
#include "input.h"
#include "input/mpegts/tsdemux.h"
#include "dvbcam.h"
+#include "streaming.h"
#define MAX_QUICK_ECM_ENTRIES 100
}
}
+void
+descrambler_notify( th_descrambler_t *td,
+ uint16_t caid, uint32_t provid,
+ const char *cardsystem, uint16_t pid, uint32_t ecmtime,
+ uint16_t hops, const char *reader, const char *from,
+ const char *protocol )
+{
+ mpegts_service_t *t = (mpegts_service_t *)td->td_service;
+ streaming_message_t *sm;
+ descramble_info_t *di;
+
+ tvhlog(LOG_DEBUG, "descrambler", "info - service='%s' caid=%04X(%s) "
+ "provid=%06X ecmtime=%d hops=%d "
+ "reader=%s from=%s protocol=%s",
+ t->s_dvb_svcname, caid, cardsystem, provid,
+ ecmtime, hops, reader, from, protocol);
+
+ sm = streaming_msg_create(SMT_DESCRAMBLE_INFO);
+ sm->sm_data = di = calloc(1, sizeof(*di));
+
+ di->pid = pid;
+ di->caid = caid;
+ di->provid = provid;
+ di->ecmtime = ecmtime;
+ di->hops = hops;
+ strncpy(di->cardsystem, cardsystem, sizeof(di->cardsystem)-1);
+ strncpy(di->reader, reader, sizeof(di->reader)-1);
+ strncpy(di->from, from, sizeof(di->protocol)-1);
+ strncpy(di->protocol, protocol, sizeof(di->protocol)-1);
+
+ pthread_mutex_lock(&t->s_stream_mutex);
+ streaming_pad_deliver(&t->s_streaming_pad, sm);
+ pthread_mutex_unlock(&t->s_stream_mutex);
+}
+
int
descrambler_resolved( service_t *t, th_descrambler_t *ignore )
{
case SMT_SKIP:
case SMT_SIGNAL_STATUS:
case SMT_TIMESHIFT_STATUS:
+ case SMT_DESCRAMBLE_INFO:
break;
case SMT_EXIT:
static void *htsp_server, *htsp_server_2;
-#define HTSP_PROTO_VERSION 23
+#define HTSP_PROTO_VERSION 24
#define HTSP_ASYNC_OFF 0x00
#define HTSP_ASYNC_ON 0x01
htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus);
}
+/**
+ *
+ */
+static void
+htsp_subscription_descramble_info(htsp_subscription_t *hs, descramble_info_t *di)
+{
+ /* don't bother old clients */
+ if (hs->hs_htsp->htsp_version < 24)
+ return;
+
+ htsmsg_t *m = htsmsg_create_map();
+ htsmsg_add_str(m, "method", "descrambleInfo");
+ htsmsg_add_u32(m, "pid", di->pid);
+ htsmsg_add_u32(m, "caid", di->caid);
+ htsmsg_add_u32(m, "provid", di->provid);
+ htsmsg_add_u32(m, "ecmtime", di->ecmtime);
+ htsmsg_add_u32(m, "hops", di->hops);
+ if (di->cardsystem[0])
+ htsmsg_add_str(m, "cardsystem", di->cardsystem);
+ if (di->reader[0])
+ htsmsg_add_str(m, "reader", di->reader);
+ if (di->from[0])
+ htsmsg_add_str(m, "from", di->from);
+ if (di->protocol[0])
+ htsmsg_add_str(m, "protocol", di->protocol);
+ htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus);
+}
+
/**
*
*/
htsp_subscription_signal_status(hs, sm->sm_data);
break;
+ case SMT_DESCRAMBLE_INFO:
+ htsp_subscription_descramble_info(hs, sm->sm_data);
+ break;
+
case SMT_NOSTART:
case SMT_NOSTART_WARN:
htsp_subscription_status(hs, streaming_code2txt(sm->sm_code),
case SMT_EXIT:
case SMT_SERVICE_STATUS:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
case SMT_NOSTART:
case SMT_NOSTART_WARN:
case SMT_MPEGTS:
case SMT_EXIT:
case SMT_SERVICE_STATUS:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
case SMT_NOSTART:
case SMT_NOSTART_WARN:
case SMT_MPEGTS:
case SMT_EXIT:
case SMT_SERVICE_STATUS:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
case SMT_NOSTART:
case SMT_NOSTART_WARN:
case SMT_MPEGTS:
case SMT_EXIT:
case SMT_SERVICE_STATUS:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
case SMT_NOSTART:
case SMT_NOSTART_WARN:
case SMT_MPEGTS:
case SMT_SPEED:
case SMT_SERVICE_STATUS:
case SMT_TIMESHIFT_STATUS:
+ case SMT_DESCRAMBLE_INFO:
break;
}
memcpy(dst->sm_data, src->sm_data, sizeof(signal_status_t));
break;
+ case SMT_DESCRAMBLE_INFO:
+ dst->sm_data = malloc(sizeof(descramble_info_t));
+ memcpy(dst->sm_data, src->sm_data, sizeof(descramble_info_t));
+ break;
+
case SMT_TIMESHIFT_STATUS:
dst->sm_data = malloc(sizeof(timeshift_status_t));
memcpy(dst->sm_data, src->sm_data, sizeof(timeshift_status_t));
case SMT_SKIP:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
#if ENABLE_TIMESHIFT
case SMT_TIMESHIFT_STATUS:
#endif
case SMT_NOSTART:
case SMT_NOSTART_WARN:
case SMT_SERVICE_STATUS:
+ case SMT_DESCRAMBLE_INFO:
return -1;
break;
case SMT_NOSTART_WARN:
case SMT_SERVICE_STATUS:
case SMT_TIMESHIFT_STATUS:
+ case SMT_DESCRAMBLE_INFO:
break;
/* Store */
int tc_block; /* total block count */
} signal_status_t;
+/**
+ * Descramble info
+ */
+typedef struct descramble_info {
+ uint16_t pid;
+ uint16_t caid;
+ uint32_t provid;
+ uint32_t ecmtime;
+ uint16_t hops;
+ char cardsystem[128];
+ char reader [128];
+ char from [128];
+ char protocol [128];
+} descramble_info_t;
+
/**
* Streaming skip
*/
*/
SMT_SIGNAL_STATUS,
+ /**
+ * Descrambler info message
+ *
+ * Notification about descrambler
+ */
+ SMT_DESCRAMBLE_INFO,
+
/**
* Streaming stop.
*
case SMT_SKIP:
case SMT_SPEED:
case SMT_SIGNAL_STATUS:
+ case SMT_DESCRAMBLE_INFO:
case SMT_TIMESHIFT_STATUS:
break;