HDHomeRun PRIME tuning improvements

Add tune_cable_vchannel() that logs the tuner status 1 second after
tuning to the virtual channel.

Change-Id: I1fccf0dd909dcafebba5813512497c374238cb36
diff --git a/hdhomerun_plugin.c b/hdhomerun_plugin.c
index 6a7b1f8..98ea933 100644
--- a/hdhomerun_plugin.c
+++ b/hdhomerun_plugin.c
@@ -141,12 +141,18 @@
 
   if (hdhr->cc_tuner) {
     // HDHomeRun PRIME
-    if (strstr(channel, "vchan:") == NULL) {
-      char vchan[32];
-      snprintf(vchan, sizeof(vchan), "vchan:%d", atoi(channel));
-      ret = tune_channel(hdhr->hd, vchan, "", stream_tar);
-    } else
-      ret = tune_channel(hdhr->hd, channel, "", stream_tar);
+    int ch = -1;
+
+    // channel format: xx
+    // xx=Comcast virtual channel
+    if (sscanf(channel, "%d", &ch) == 1) {
+      ret = tune_cable_vchannel(hdhr->hd, ch, stream_tar);
+      goto out;
+    }
+
+    // other channel formats
+    ret = tune_channel(hdhr->hd, channel, "", stream_tar);
+
   } else {
     // HDHomeRun US
     char tune_str[32], map_str[32], prog_str[8];
diff --git a/hdhomerun_tuner.c b/hdhomerun_tuner.c
index 2bbf1d9..d220d64 100644
--- a/hdhomerun_tuner.c
+++ b/hdhomerun_tuner.c
@@ -247,6 +247,57 @@
   return ret;
 }
 
+int tune_cable_vchannel(void *device, unsigned int channel, char *stream_target)
+{
+  char channel_str[8];
+  char target_str[64];
+  struct hdhomerun_device_t *hd;
+  struct hdhomerun_tuner_status_t ts;
+  struct hdhomerun_tuner_vstatus_t tvs;
+  int ret;
+
+  hd = (struct hdhomerun_device_t *)device;
+
+  // Set tuner vchannel
+  snprintf(channel_str, sizeof(channel_str), "%u", channel);
+  ret = hdhomerun_device_set_tuner_vchannel(hd, channel_str);
+  if (ret <= 0) {
+    printf("hdhr:ERROR: set_tuner_vchannel %s\n", channel_str);
+    goto out;
+  }
+
+  sleep(1);
+
+  // Get tuner status
+  ret = hdhomerun_device_get_tuner_status(hd, NULL, &ts);
+  if (ret > 0) {
+    printf("hdhr:hdhomerun tuner status: ch=%s lock=%s ss=%u snq=%u seq=%u\n",
+           ts.channel, ts.lock_str, ts.signal_strength,
+           ts.signal_to_noise_quality, ts.symbol_error_quality);
+  } else {
+    printf("hdhr:ERROR: get_tuner_status\n");
+  }
+
+  // Get tuner vstatus
+  ret = hdhomerun_device_get_tuner_vstatus(hd, NULL, &tvs);
+  if (ret > 0) {
+    printf("hdhr:hdhomerun tuner vstatus: vch=%s name=%s auth=%s cci=%s "
+           "cgms=%s\n", tvs.vchannel, tvs.name, tvs.auth, tvs.cci, tvs.cgms);
+  } else {
+    printf("hdhr:ERROR: get_tuner_vstatus\n");
+  }
+
+  // Set tuner stream target
+  snprintf(target_str, sizeof(target_str), "%s ttl=2", stream_target);
+  ret = hdhomerun_device_set_tuner_target(hd, target_str);
+  if (ret <= 0) {
+    printf("hdhr:ERROR: set_tuner_target %s\n", target_str);
+  }
+
+out:
+  return ret;
+}
+
 // channel format: map:us-cable,auto:68
 int stop_channel(void *device)
 {
diff --git a/hdhomerun_tuner.h b/hdhomerun_tuner.h
index d788a59..4f1ed2e 100644
--- a/hdhomerun_tuner.h
+++ b/hdhomerun_tuner.h
@@ -37,6 +37,8 @@
 int tune_atsc_vchannel(void *device, unsigned int channel,
                        unsigned int vchannel_major, unsigned int vchannel_minor,
                        char *stream_target);
+int tune_cable_vchannel(void *device, unsigned int channel,
+                        char *stream_target);
 int stop_channel(void *device);
 int scan_vchannel(void *device, int vchannel, struct channel_entry_t *ce);
 int tuner_input_sharing(struct hdhr_tuner_t *ht1, struct hdhr_tuner_t *ht2);