]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Physical network support for CableCARD (HDHomeRun Prime)
authorRobert Cameron <rob@rpcameron.net>
Sat, 12 May 2018 22:08:07 +0000 (15:08 -0700)
committerperexg <perex@perex.cz>
Thu, 7 Jun 2018 16:17:44 +0000 (18:17 +0200)
src/input/mpegts/mpegts_network_dvb.c
src/input/mpegts/tvhdhomerun/tvhdhomerun.c
src/input/mpegts/tvhdhomerun/tvhdhomerun.h
src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c

index e673d86b667fc087453577363b301362778dd992..525f39fe23ff3f16c63985142b73b60fa991cb21 100644 (file)
@@ -850,6 +850,8 @@ dvb_network_create_service
   /* Set service values from mux if CableCARD */
   if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_CABLECARD) {
     mpegts_network_t *ln = mm->mm_network;
+    if (!s->s_dvb_provider && lm->mm_provider_network_name)
+      s->s_dvb_provider = strdup(lm->mm_provider_network_name);
     if (!s->s_dvb_provider && ln->mn_provider_network_name)
       s->s_dvb_provider = strdup(ln->mn_provider_network_name);
     if (!s->s_dvb_channel_num)
index 228229c4bfd1a3c09001b2c780ccbb21e80c53ba..edce2150353aa03e262f3ecbfe9b9c9bdf4966a7 100644 (file)
@@ -117,6 +117,7 @@ tvhdhomerun_device_class_override_enum( void * p, const char *lang )
   htsmsg_add_str(m, NULL, "DVB-C");
   htsmsg_add_str(m, NULL, "ATSC-T");
   htsmsg_add_str(m, NULL, "ATSC-C");
+  htsmsg_add_str(m, NULL, "CableCARD");
   return m;
 }
 
@@ -318,13 +319,16 @@ static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo)
         override_type = "ATSC-T";
       type = dvb_str2type(override_type);
       if ( ! ( type == DVB_TYPE_C || type == DVB_TYPE_T ||
-               type == DVB_TYPE_ATSC_T || type == DVB_TYPE_ATSC_C ) ) {
+               type == DVB_TYPE_ATSC_T || type == DVB_TYPE_ATSC_C ||
+               type == DVB_TYPE_CABLECARD ) ) {
         type = DVB_TYPE_C;
       }
     }
   } else {
     if (strstr(hd->hd_info.deviceModel, "_atsc"))
       type = DVB_TYPE_ATSC_T;
+    if (strstr(hd->hd_info.deviceModel, "_cablecard"))
+      type = DVB_TYPE_CABLECARD;
   }
 
   hd->hd_override_type = strdup(dvb_type2str(type));
@@ -455,6 +459,7 @@ void tvhdhomerun_init ( void )
   idclass_register(&tvhdhomerun_frontend_dvbc_class);
   idclass_register(&tvhdhomerun_frontend_atsc_t_class);
   idclass_register(&tvhdhomerun_frontend_atsc_c_class);
+  idclass_register(&tvhdhomerun_frontend_cablecard_class);
   TAILQ_INIT(&tvhdhomerun_discoveries);
   pthread_mutex_init(&tvhdhomerun_discovery_lock, NULL);
   tvh_cond_init(&tvhdhomerun_discovery_cond);
index bbec1bcfc991808615f5d5a31e8ca5a2707fd5b8..80cd130e2faaf5a1c65988be58aa11cc9b7ebb4b 100644 (file)
@@ -25,6 +25,7 @@ extern const idclass_t tvhdhomerun_frontend_dvbt_class;
 extern const idclass_t tvhdhomerun_frontend_dvbc_class;
 extern const idclass_t tvhdhomerun_frontend_atsc_t_class;
 extern const idclass_t tvhdhomerun_frontend_atsc_c_class;
+extern const idclass_t tvhdhomerun_frontend_cablecard_class;
 
 void tvhdhomerun_init( void );
 void tvhdhomerun_done( void );
index e9e4ba3f6b0b6f4f1b6eeee85480df85c150c285..362eb327d22983ad12218e5839b895be72acdb0c 100644 (file)
@@ -257,6 +257,19 @@ tvhdhomerun_frontend_monitor_cb( void *aux )
       tvhdebug(LS_TVHDHOMERUN, "locked");
       hfe->hf_locked = 1;
 
+      /* Get CableCARD variables */
+      dvb_mux_t *lm = (dvb_mux_t *)mm;
+      struct hdhomerun_tuner_vstatus_t tuner_vstatus;
+      char *tuner_vstatus_str;
+      pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex);
+      res = hdhomerun_device_get_tuner_vstatus(hfe->hf_hdhomerun_tuner,
+        &tuner_vstatus_str, &tuner_vstatus);
+      pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex);
+      if (res < 1)
+        tvhwarn(LS_TVHDHOMERUN, "tuner_vstatus (%d)", res);
+      lm->lm_tuning.dmc_fe_vchan.name = strdup(tuner_vstatus.name);
+      sscanf(strstr(tuner_status.channel, ":"), ":%u", &lm->lm_tuning.dmc_fe_freq);
+
       /* start input thread */
       tvh_pipe(O_NONBLOCK, &hfe->hf_input_thread_pipe);
       pthread_mutex_lock(&hfe->hf_input_thread_mutex);
@@ -312,6 +325,9 @@ static void tvhdhomerun_device_open_pid(tvhdhomerun_frontend_t *hfe, int pid) {
   char buf[1024];
   int res;
 
+  if (hfe->hf_type == DVB_TYPE_CABLECARD)
+    return;
+
   /* a full mux subscription should specificly set the filter */
   if (pid == MPEGTS_FULLMUX_PID) {
     tvhdebug(LS_TVHDHOMERUN, "setting PID filter full mux");
@@ -417,6 +433,14 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins
             break;
       }
       break;
+    case DVB_TYPE_CABLECARD:
+      if (!dmc->dmc_fe_vchan.minor)
+        snprintf(channel_buf, sizeof(channel_buf), "%u", dmc->dmc_fe_vchan.num);
+      else
+        snprintf(channel_buf, sizeof(channel_buf), "%u.%u",
+          dmc->dmc_fe_vchan.num,
+          dmc->dmc_fe_vchan.minor);
+      break;
     default:
       snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq);
       break;
@@ -431,7 +455,10 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins
     tvherror(LS_TVHDHOMERUN, "failed to acquire lockkey: %s", perror);
     return SM_CODE_TUNING_FAILED;
   }
-  res = hdhomerun_device_set_tuner_channel(hfe->hf_hdhomerun_tuner, channel_buf);
+  if (hfe->hf_type == DVB_TYPE_CABLECARD)
+    res = hdhomerun_device_set_tuner_vchannel(hfe->hf_hdhomerun_tuner, channel_buf);
+  else
+    res = hdhomerun_device_set_tuner_channel(hfe->hf_hdhomerun_tuner, channel_buf);
   pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex);
   if(res < 1) {
     tvherror(LS_TVHDHOMERUN, "failed to tune to %s", channel_buf);
@@ -463,11 +490,13 @@ tvhdhomerun_frontend_start_mux
   res = tvhdhomerun_frontend_tune(hfe, mmi);
 
   /* reset the pfilters */
-  pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex);
-  r = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, "0x0000");
-  pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex);
-  if(r < 1)
-    tvherror(LS_TVHDHOMERUN, "failed to reset pfilter: %d", r);
+  if (hfe->hf_type != DVB_TYPE_CABLECARD) {
+    pthread_mutex_lock(&hfe->hf_hdhomerun_device_mutex);
+    r = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, "0x0000");
+    pthread_mutex_unlock(&hfe->hf_hdhomerun_device_mutex);
+    if(r < 1)
+      tvherror(LS_TVHDHOMERUN, "failed to reset pfilter: %d", r);
+  }
 
   return res;
 }
@@ -620,6 +649,16 @@ const idclass_t tvhdhomerun_frontend_atsc_c_class =
   }
 };
 
+const idclass_t tvhdhomerun_frontend_cablecard_class =
+{
+  .ic_super = &tvhdhomerun_frontend_class,
+  .ic_class = "tvhdhomerun_frontend_cablecard",
+  .ic_caption = N_("HDHomeRun CableCARD frontend"),
+  .ic_properties = (const property_t[]){
+    {}
+  }
+};
+
 static mpegts_network_t *
 tvhdhomerun_frontend_wizard_network ( tvhdhomerun_frontend_t *hfe )
 {
@@ -708,6 +747,8 @@ tvhdhomerun_frontend_create(tvhdhomerun_device_t *hd, struct hdhomerun_discover_
     idc = &tvhdhomerun_frontend_atsc_t_class;
   else if (type == DVB_TYPE_ATSC_C)
     idc = &tvhdhomerun_frontend_atsc_c_class;
+  else if (type == DVB_TYPE_CABLECARD)
+    idc = &tvhdhomerun_frontend_cablecard_class;
   else {
     tvherror(LS_TVHDHOMERUN, "unknown FE type %d", type);
     return NULL;