]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
capmt: add OSCam new pc-nodmx mode (through unix socket)
authorJaroslav Kysela <perex@perex.cz>
Thu, 12 Nov 2015 08:32:55 +0000 (09:32 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 12 Nov 2015 08:32:55 +0000 (09:32 +0100)
src/descrambler/capmt.c

index 5b503469bfac5dcb6507ee4f67330e4c6386680c..af6be2a172dda168d988fc01b766d2fc6a320ec0 100644 (file)
@@ -123,7 +123,8 @@ typedef enum {
     CAPMT_OSCAM_MULTILIST,
     CAPMT_OSCAM_TCP,
     CAPMT_OSCAM_UNIX_SOCKET,
-    CAPMT_OSCAM_NET_PROTO
+    CAPMT_OSCAM_NET_PROTO,
+    CAPMT_OSCAM_UNIX_SOCKET_NP /* NET_PROTO through socket */
 } capmt_oscam_mode_t;
 
 /**
@@ -310,6 +311,14 @@ capmt_oscam_new(capmt_t *capmt)
          oscam != CAPMT_OSCAM_OLD;
 }
 
+static inline int
+capmt_oscam_netproto(capmt_t *capmt)
+{
+  int oscam = capmt->capmt_oscam;
+  return oscam == CAPMT_OSCAM_NET_PROTO ||
+         oscam == CAPMT_OSCAM_UNIX_SOCKET_NP;
+}
+
 static void
 capmt_poll_add(capmt_t *capmt, int fd, uint32_t u32)
 {
@@ -514,7 +523,7 @@ capmt_connect(capmt_t *capmt, int i)
     tvhlog(LOG_DEBUG, "capmt", "%s: Created socket %d", capmt_name(capmt), fd);
     capmt->capmt_sock[i] = fd;
     capmt->capmt_sock_reconnect[i]++;
-    if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO)
+    if (capmt_oscam_netproto(capmt))
       capmt_send_client_info(capmt);
     capmt_poll_add(capmt, fd, i + 1);
   }
@@ -955,7 +964,7 @@ capmt_stop_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset)
   capmt_dmx_t *filter;
   capmt_filters_t *cf;
 
-  if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO)
+  if (capmt_oscam_netproto(capmt))
     pid          = sbuf_peek_s16  (sb, offset + 6);
   else
     pid          = sbuf_peek_s16be(sb, offset + 6);
@@ -990,7 +999,7 @@ static void
 capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force)
 {
   /* flush out the greeting */
-  if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO)
+  if (capmt_oscam_netproto(capmt))
     capmt_flush_queue(capmt, 0);
 
   pthread_mutex_lock(&capmt->capmt_mutex);
@@ -1111,7 +1120,7 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
   if (sb->sb_ptr - offset < 4)
     return 0;
   cmd = sbuf_peek_u32(sb, offset);
-  if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO) {
+  if (capmt_oscam_netproto(capmt))  {
     adapter_byte = 1; //we need to take into account the adapter index byte which is now after the cmd
   } else {
     if (!sb->sb_bswap && !sb->sb_err) {
@@ -1134,7 +1143,7 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset)
     return 4 + 32;
   else if (oscam_new && cmd == DMX_SET_FILTER)
     //when using network protocol the dmx_sct_filter_params fields are added seperately to avoid padding problems, so we substract 2 bytes:
-    return 4 + 2 + 60 + adapter_byte + (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO ? -2 : 0);
+    return 4 + 2 + 60 + adapter_byte + (capmt_oscam_netproto(capmt) ? -2 : 0);
   else if (oscam_new && cmd == DMX_STOP)
     return 4 + 4 + adapter_byte;
   else if (oscam_new && cmd == DVBAPI_SERVER_INFO)
@@ -1179,7 +1188,7 @@ capmt_analyze_cmd(capmt_t *capmt, int adapter, sbuf_t *sb, int offset)
 
   cmd = sbuf_peek_u32(sb, offset);
 
-  if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO && cmd != DVBAPI_SERVER_INFO) {
+  if (capmt_oscam_netproto(capmt) && cmd != DVBAPI_SERVER_INFO) {
     adapter = sbuf_peek_u8(sb, 4);
     offset = 1;
   }
@@ -1311,7 +1320,8 @@ show_connection(capmt_t *capmt, const char *what)
            capmt->capmt_oscam,
            capmt->capmt_sockfile, capmt->capmt_port,
            what);
-  } else if (capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET) {
+  } else if (capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET ||
+             capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET_NP) {
     tvhlog(LOG_INFO, "capmt",
            "%s: mode %i sockfile %s got connection from client (%s)",
            capmt_name(capmt),
@@ -1496,7 +1506,7 @@ handle_single(capmt_t *capmt)
       adapter = -1;
       offset = 0;
       while (buffer.sb_ptr > 0) {
-        if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO) {
+        if (capmt_oscam_netproto(capmt)) {
           buffer.sb_bswap = 1;
         } else {
           adapter = buffer.sb_data[0];
@@ -1677,7 +1687,8 @@ capmt_thread(void *aux)
 #else
      if (capmt->capmt_oscam == CAPMT_OSCAM_TCP ||
          capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO ||
-         capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET) {
+         capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET ||
+         capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET_NP) {
        handle_single(capmt);
      } else {
        tvhlog(LOG_ERR, "capmt", "%s: Only modes 3 and 4 are supported for non-linuxdvb devices", capmt_name(capmt));
@@ -1990,7 +2001,7 @@ capmt_enumerate_services(capmt_t *capmt, int force)
     tvhlog(LOG_DEBUG, "capmt", "%s: %s: no subscribed services, closing socket, fd=%d", capmt_name(capmt), __FUNCTION__, capmt->capmt_sock[0]);
     if (capmt->capmt_sock[0] >= 0)
       caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_READY);
-    if (capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO) {
+    if (capmt_oscam_netproto(capmt)) {
       capmt_send_stop_descrambling(capmt);
       capmt_pid_flush(capmt);
     }
@@ -2050,9 +2061,10 @@ capmt_service_start(caclient_t *cac, service_t *s)
 
   if (tuner < 0 && capmt->capmt_oscam != CAPMT_OSCAM_TCP &&
                    capmt->capmt_oscam != CAPMT_OSCAM_NET_PROTO &&
-                   capmt->capmt_oscam != CAPMT_OSCAM_UNIX_SOCKET) {
+                   capmt->capmt_oscam != CAPMT_OSCAM_UNIX_SOCKET &&
+                   capmt->capmt_oscam != CAPMT_OSCAM_UNIX_SOCKET_NP) {
     tvhlog(LOG_WARNING, "capmt",
-           "%s: Virtual adapters are supported only in modes 3 and 4 (service \"%s\")",
+           "%s: Virtual adapters are supported only in modes 3, 4, 5 and 6 (service \"%s\")",
            capmt_name(capmt), t->s_dvb_svcname);
     goto fin;
   }
@@ -2120,7 +2132,8 @@ capmt_service_start(caclient_t *cac, service_t *s)
   }
 
   td = (th_descrambler_t *)ct;
-  if (capmt->capmt_oscam == CAPMT_OSCAM_TCP || capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO) {
+  if (capmt->capmt_oscam == CAPMT_OSCAM_TCP ||
+      capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO) {
     snprintf(buf, sizeof(buf), "capmt-%s-%i",
                                capmt->capmt_sockfile,
                                capmt->capmt_port);
@@ -2158,7 +2171,8 @@ capmt_free(caclient_t *cac)
   tvhlog(LOG_INFO, "capmt", "%s: mode %i %s %s port %i destroyed",
          capmt_name(capmt),
          capmt->capmt_oscam,
-         capmt->capmt_oscam == CAPMT_OSCAM_TCP || capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO ? "IP address" : "sockfile",
+         capmt->capmt_oscam == CAPMT_OSCAM_TCP ||
+           capmt->capmt_oscam == CAPMT_OSCAM_NET_PROTO ? "IP address" : "sockfile",
          capmt->capmt_sockfile, capmt->capmt_port);
   capmt_flush_queue(capmt, 1);
   free(capmt->capmt_sockfile);
@@ -2209,6 +2223,7 @@ static htsmsg_t *
 caclient_capmt_class_oscam_mode_list ( void *o, const char *lang )
 {
   static const struct strtab tab[] = {
+    { N_("OSCam new pc-nodmx (rev >= 10389)"), CAPMT_OSCAM_UNIX_SOCKET_NP },
     { N_("OSCam net protocol (rev >= 10389)"), CAPMT_OSCAM_NET_PROTO },
     { N_("OSCam pc-nodmx (rev >= 9756)"),      CAPMT_OSCAM_UNIX_SOCKET },
     { N_("OSCam TCP (rev >= 9574)"),           CAPMT_OSCAM_TCP },