// Copyright 2011 Google Inc. All Rights Reserved.
// Author: qianzhang@google.com (Qian Zhang)

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <inttypes.h>
#include "utility.h"
#include "channel_buffer.h"
#include "libhdhomerun/hdhomerun.h"
#include "hdhomerun_tuner.h"
#include "hdhomerun_dev.h"
#include "sagelog.h"

#define PARSE_TIMEOUT 2
#define CHANNE_SCAN_SRC "227.0.0.1"
#define CHANNEL_SCAN_PORT 6069

static volatile sig_atomic_t sigabort_flag = FALSE;
static volatile sig_atomic_t siginfo_flag = FALSE;

static const char *map_tbl[] = {"us-bcast", "us-cable", "us-hrc",   "us-irc",
                                "au-bcast", "tw-bcast", "eu-bcast", 0x0};

static void sigabort_handler(int arg)
{
  sigabort_flag = TRUE;
}

static void siginfo_handler(int arg)
{
  siginfo_flag = TRUE;
}

static void register_signal_handlers(sig_t sigpipe_handler,
                                     sig_t sigint_handler,
                                     sig_t siginfo_handler)
{
#if defined(SIGPIPE)
  signal(SIGPIPE, sigpipe_handler);
#endif
#if defined(SIGINT)
  signal(SIGINT, sigint_handler);
#endif
#if defined(SIGINFO)
  signal(SIGINFO, siginfo_handler);
#endif
}

// channel format: map:us-cable,auto:68
void *open_hdhr(char *name)
{
  struct hdhomerun_device_t *hd;
  hd = hdhomerun_device_create_from_str(name, NULL);
  return hd;
}

void close_hdhr(void *device)
{
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  if (hd) {
    hdhomerun_device_stream_stop(hd);
    hdhomerun_device_destroy(hd);
  }
}

int tune_channel(void *device, char *channel, char *program,
                 char *stream_target)
{
  char channel_str[32] = "auto:";
  char vchannel_str[16];
  char channel_map[32];
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  int ret;

  if (hd == NULL) {
    printf("hdhomerun invalid handle\n");
    return -1;
  }

  if (!get_string_by_name(channel, "vchan", vchannel_str, sizeof(vchannel_str),
                          NULL)) {
    vchannel_str[0] = 0x0;

    if (!get_string_by_name(channel, "auto", channel_str + 5,
                            sizeof(channel_str) - 5, NULL)) {
      printf("hdhomerun %p invalid channel %s\n", device, channel);
      return -1;
    }
    if (!get_string_by_name(channel, "map", channel_map, sizeof(channel_map),
                            NULL)) {
      printf("hdhomerun %p invalid channel map %s\n", device, channel);
      strncpy(channel_map, "us-cable", sizeof(channel_map));
    }
    if (program[0] == 0x0) {
      printf("hdhomerun %p invalid channel program %s\n", device, program);
      return -1;
    }
    ret = hdhomerun_device_set_tuner_channelmap(hd, channel_map);
    if (ret < 0)
      printf("hdhomerun failed to set tuner channel map %s\n", channel_map);

    ret = hdhomerun_device_set_tuner_channel(hd, channel_str);
    if (ret < 0)
      printf("hdhomerun tuning failed:%s ret:%d\n", channel_str, ret);

    ret = hdhomerun_device_set_tuner_program(hd, program);
    if (ret <= 0)
      printf("hdhomerun failed set program:%s ret:%d\n", program, ret);
  } else {
    ret = hdhomerun_device_set_tuner_vchannel(hd, vchannel_str);
    if (ret < 0)
      printf("hdhomerun tuning failed: vchannel:%s ret:%d\n", vchannel_str,
             ret);
  }

  char target[64];
  snprintf(target, sizeof(target), "%s ttl=2", stream_target);
  ret = hdhomerun_device_set_tuner_target(hd, target);
  if (ret < 0) {
    printf("hdhomerun failed set target %s  ret:%d\n", target, ret);
  }

  return ret;
}

static int vchan_to_prog_num(char *streaminfo, unsigned int vchan_major,
                             unsigned int vchan_minor, unsigned int *prog_num)
{
  char *line;
  char *next_line;
  unsigned int program_number;
  unsigned int virtual_major, virtual_minor;

  next_line = streaminfo;

  while (1) {
    line = next_line;
    next_line = strchr(line, '\n');
    if (!next_line) {
      break;
    }
    *next_line++ = 0;

    if (sscanf(line, "%u: %u.%u", &program_number, &virtual_major,
               &virtual_minor) != 3) {
      if (sscanf(line, "%u: %u", &program_number, &virtual_major) != 2) {
        continue;
      }
      virtual_minor = 0;
    }

    if (vchan_major == virtual_major && vchan_minor == virtual_minor) {
      *prog_num = program_number;
      return 1;
    }
  }

  return 0;
}

int tune_atsc_vchannel(void *device, unsigned int channel,
                       unsigned int vchannel_major, unsigned int vchannel_minor,
                       char *stream_target)
{
  char channel_map[16];
  char channel_str[16];
  char program_str[16];
  char target_str[64];
  struct hdhomerun_device_t *hd;
  struct hdhomerun_tuner_status_t ts;
  char *streaminfo;
  unsigned int program;
  int i, ret;

  hd = (struct hdhomerun_device_t *)device;

  // Set tuner channel map to US broadcast
  snprintf(channel_map, sizeof(channel_map), "us-bcast");
  ret = hdhomerun_device_set_tuner_channelmap(hd, channel_map);
  if (ret < 0) {
    printf("hdhr:ERROR: set_tuner_channelmap %s\n", channel_map);
    goto out;
  }

  // Tune to physical channel
  snprintf(channel_str, sizeof(channel_str), "auto:%u", channel);
  ret = hdhomerun_device_set_tuner_channel(hd, channel_str);
  if (ret <= 0) {
    printf("hdhr:ERROR: set_tuner_channel %s\n", channel_str);
    goto out;
  }

  // Wait for symbol error quality to hit 100% (max 3 secs)
  for (i = 0; i < 5; i++) {
    usleep(i == 0 ? 1000000 : 500000);
    ret = hdhomerun_device_get_tuner_status(hd, NULL, &ts);
    if (ret > 0 && ts.symbol_error_quality >= 100) {
      break;
    }
  }

  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);

  // Translate virtual channel to program number (max 2 secs)
  for (i = 0; i < 5; i++) {
    usleep(i == 0 ? 0 : 500000);
    ret = hdhomerun_device_get_tuner_streaminfo(hd, &streaminfo);
    if (ret > 0) {
      printf("hdhr:hdhomerun tuner streaminfo:\n%s", streaminfo);
      ret = vchan_to_prog_num(streaminfo, vchannel_major, vchannel_minor,
                              &program);
      if (ret > 0) {
        break;
      }
    }
  }

  if (ret <= 0) {
    printf("hdhr:ERROR: vchannel %d.%d not found in streaminfo\n",
           vchannel_major, vchannel_minor);
    goto out;
  }

  printf("hdhr:hdhomerun vchannel %u.%u -> program %u\n", vchannel_major,
         vchannel_minor, program);

  // Set tuner program
  snprintf(program_str, sizeof(program_str), "%u", program);
  ret = hdhomerun_device_set_tuner_program(hd, program_str);
  if (ret <= 0) {
    printf("hdhr:ERROR: set_tuner_program %s\n", program_str);
    goto out;
  }

  // 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)
{
  int ret;
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  if (hd == NULL) {
    printf("hdhomerun invalid handle\n");
    return -1;
  }

  ret = hdhomerun_device_set_tuner_channel(hd, "none");
  if (ret < 0) {
    printf("hdhomerun failed set channel none to stop streaming  ret:%d\n",
           ret);
  }

  ret = hdhomerun_device_set_tuner_vchannel(hd, "none");
  if (ret < 0) {
    printf("hdhomerun failed set vchannel none to stop streaming  ret:%d\n",
           ret);
  }

  ret = hdhomerun_device_set_tuner_target(hd, "none");
  if (ret < 0) {
    printf("hdhomerun failed set target none to stop streaming  ret:%d\n", ret);
  }

  return ret;
}

char *get_unit_name(struct hdhr_tuner_t *ht, char *name, int size)
{
  char *p = strchr(ht->name, '-');
  if (p != NULL) {
    int len = p - ht->name;
    strncpy(name, ht->name, len);
    name[len] = 0x0;
    return name;
  }
  name[0] = 0x0;
  return name;
}

static char *ip4_address(int ip4, char *buf, int size)
{
  snprintf(buf, size, "%u.%u.%u.%u", (unsigned int)(ip4 >> 24) & 0xFF,
           (unsigned int)(ip4 >> 16) & 0xFF, (unsigned int)(ip4 >> 8) & 0xFF,
           (unsigned int)(ip4 >> 0) & 0xFF);
  return buf;
}

int discover_device(struct hdhr_tuner_t *ht, int max_ht_num)
{
  int i, k, num = 0;
  struct hdhomerun_discover_device_t *device_info =
      malloc(max_ht_num * sizeof(struct hdhomerun_discover_device_t));
  int ret = hdhomerun_discover_find_devices_custom(
      0, HDHOMERUN_DEVICE_TYPE_TUNER, -1, device_info, 16);
  if (ret <= 0) {
    free(device_info);
    return 0;
  }
  // printf( "found %d hdhomerun device\n", ret );
  for (i = 0; i < ret; i++) {
    // printf( "ip:%x type:%x id:%x num:%d\n", device_info[i].ip_addr,
    // device_info[i].device_type, device_info[i].device_id,
    //    device_info[i].tuner_count );
    for (k = 0; k < device_info[i].tuner_count && num < max_ht_num; k++) {
      snprintf(ht[num].name, sizeof(ht[num].name), "%X-%d",
               device_info[i].device_id, k);
      ip4_address(device_info[i].ip_addr, ht[num].ip, sizeof(ht[num].ip));
      ht[num].type = device_info[i].device_type;
      ht[num].cc_tuner = 0;
      ht[num].model[0] = 0;
      num++;
    }
  }
  free(device_info);
  return num;
}

static char *get_tune_string(char *result, char *tune_str, int tune_str_len)
{
  int i = 0;
  int ch;
  while (map_tbl[i][0]) {
    if (get_int_val_by_name(result, map_tbl[i], &ch, NULL) > 0) {
      snprintf(tune_str, tune_str_len, "map:%s|auto:%d", map_tbl[i], ch);
      return tune_str;
    }
    i++;
  }
  return "";
}

static int get_tune_channel(char *result)
{
  int i = 0;
  int ch;
  while (map_tbl[i][0]) {
    if (get_int_val_by_name(result, map_tbl[i], &ch, NULL) > 0) {
      return ch;
    }
    i++;
  }
  return 0;
}

int scan_all(void *device, struct channel_entry_t *ce, int ce_num)
{
  int found_channel = 0;
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  if (hd == NULL) {
    printf("hdhomerun invalid handle\n");
    return -1;
  }

  char *ret_error;
  if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
    fprintf(stderr, "failed to lock tuner\n");
    if (ret_error) {
      fprintf(stderr, "%s\n", ret_error);
    }
    return -1;
  }

  hdhomerun_device_set_tuner_target(hd, "none");

  char *channelmap;
  if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
    fprintf(stderr, "failed to query channelmap from device\n");
    return -1;
  }

  const char *channelmap_scan_group =
      hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
  if (!channelmap_scan_group) {
    fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
    return -1;
  }

  if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
    fprintf(stderr, "failed to initialize channel scan\n");
    return -1;
  }

  register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

  int ret = 0;
  while (!sigabort_flag && found_channel < ce_num) {
    struct hdhomerun_channelscan_result_t result;
    char tune_str[32];
    char channel_name[32];
    int channel_num;
    ret = hdhomerun_device_channelscan_advance(hd, &result);
    if (ret <= 0) {
      break;
    }

    ret = hdhomerun_device_channelscan_detect(hd, &result);
    if (ret < 0) {
      break;
    }
    if (ret == 0) {
      continue;
    }
    if (0)
      printf("LOCK: %s %s (ss=%u snq=%u seq=%u)\n",
             get_tune_string(result.channel_str, tune_str, sizeof(tune_str)),
             result.status.lock_str, result.status.signal_strength,
             result.status.signal_to_noise_quality,
             result.status.symbol_error_quality);

    channel_num = get_tune_channel(result.channel_str);
    int i;
    for (i = 0; i < result.program_count; i++) {
      struct hdhomerun_channelscan_program_t *program = &result.programs[i];
      if (strstr(program->program_str, "encrypted") == NULL) {
        int program_id = atoi(program->program_str);

        if (!get_string_by_token(program->program_str, 2, channel_name,
                                 sizeof(channel_name), NULL)) {
          if (!get_string_by_token(program->program_str, 1, channel_name,
                                   sizeof(channel_name), NULL))
            snprintf(channel_name, sizeof(channel_name), "%d.%d", channel_num,
                     i);
          else {
            if (!strcmp(channel_name, "0"))
              snprintf(channel_name, sizeof(channel_name), "%d.%d", channel_num,
                       i);
          }
        }
        snprintf(
            ce->dev_tuning, sizeof(ce->dev_tuning), "%s prog:%d",
            get_tune_string(result.channel_str, tune_str, sizeof(tune_str)),
            program_id);
        strncpy(ce->ch_name, channel_name, sizeof(ce->ch_name));
        strncpy(ce->dev_name, device, sizeof(ce->dev_name));
        ce->ch = found_channel;
        ce->frq = result.frequency;
        ce->av_inf[0] = 0x0;
        ce++;
        if (++found_channel >= ce_num)
          break;

        printf("o");
      }
    }

    printf(".");
    fflush(stdout);
  }

  hdhomerun_device_tuner_lockkey_release(hd);

  if (ret < 0) {
    fprintf(stderr,
            "communication error sending request to hdhomerun device\n");
  }
  return found_channel;
}

struct vchan_tbl_t *create_vchan_tbl(struct hdhr_tuner_t *ht)
{
  struct vchan_tbl_t *vt = malloc(sizeof(struct vchan_tbl_t));
  vt->ht = *ht;
  vt->channel_size = 500;
  vt->channel_num = 0;
  vt->vchan = malloc(sizeof(struct vchan_t) * vt->channel_size);
  memset(vt->vchan, 0x0, sizeof(struct vchan_t) * vt->channel_size);
  return vt;
}

void release_vchan_tbl(struct vchan_tbl_t *vt)
{
  if (vt->vchan)
    free(vt->vchan);
  free(vt);
}

int grow_vhcan_tbl(struct vchan_tbl_t *vt)
{
  int new_channel_size = vt->channel_size + 100;
  struct vchan_t *new_vchan_list =
      malloc(sizeof(struct vchan_t) * new_channel_size);
  if (new_vchan_list == NULL)
    return 0;
  memcpy(new_vchan_list, vt->vchan, vt->channel_size * sizeof(struct vchan_t));
  free(vt->vchan);
  vt->vchan = new_vchan_list;
  vt->channel_size = new_channel_size;
  return 1;
}

int tuner_input_sharing(struct hdhr_tuner_t *ht1, struct hdhr_tuner_t *ht2)
{
  if (ht1->cc_tuner == 1 && !strcmp(ht1->ip, ht2->ip))
    return 1;
  return 0;
}

#ifdef TEST_APP
static int scan_channel(void *device, int index, struct channel_entry_t *ce,
                        int ce_channel_num, int ce_num)
{
  int found_channel = 0;
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  if (hd == NULL) {
    printf("hdhomerun invalid handle\n");
    return -1;
  }

  char *ret_error;
  if (hdhomerun_device_tuner_lockkey_request(hd, &ret_error) <= 0) {
    fprintf(stderr, "failed to lock tuner\n");
    if (ret_error) {
      fprintf(stderr, "%s\n", ret_error);
    }
    return -1;
  }

  hdhomerun_device_set_tuner_target(hd, "none");

  char *channelmap;
  if (hdhomerun_device_get_tuner_channelmap(hd, &channelmap) <= 0) {
    fprintf(stderr, "failed to query channelmap from device\n");
    return -1;
  }

  const char *channelmap_scan_group =
      hdhomerun_channelmap_get_channelmap_scan_group(channelmap);
  if (!channelmap_scan_group) {
    fprintf(stderr, "unknown channelmap '%s'\n", channelmap);
    return -1;
  }

  if (hdhomerun_device_channelscan_init(hd, channelmap_scan_group) <= 0) {
    fprintf(stderr, "failed to initialize channel scan\n");
    return -1;
  }

  register_signal_handlers(sigabort_handler, sigabort_handler, siginfo_handler);

  int ret = 0, i;
  do {
    struct hdhomerun_channelscan_result_t result;
    char tune_str[32];
    char channel_name[32];
    int channel_num;
    ret = hdhomerun_device_channelscan_at(hd, index, &result);
    // ret = hdhomerun_device_channelscan_advance( hd, &result );
    if (ret <= 0) {
      break;
    }
    // skip duplicated channel
    for (i = 0; i < ce_channel_num; i++) {
      if (ce->frq == result.frequency)
        break;
    }
    if (ce->frq == result.frequency)
      break;
    ret = hdhomerun_device_channelscan_detect(hd, &result);
    if (ret < 0) {
      break;
    }
    if (ret == 0) {
      continue;
    }

    if (0)
      printf("LOCK: %s %s (ss=%u snq=%u seq=%u)\n",
             get_tune_string(result.channel_str, tune_str, sizeof(tune_str)),
             result.status.lock_str, result.status.signal_strength,
             result.status.signal_to_noise_quality,
             result.status.symbol_error_quality);

    channel_num = get_tune_channel(result.channel_str);
    for (i = 0; i < result.program_count; i++) {
      struct hdhomerun_channelscan_program_t *program = &result.programs[i];
      if (strstr(program->program_str, "encrypted") == NULL) {
        int program_id = atoi(program->program_str);

        if (!get_string_by_token(program->program_str, 2, channel_name,
                                 sizeof(channel_name), NULL)) {
          if (!get_string_by_token(program->program_str, 1, channel_name,
                                   sizeof(channel_name), NULL))
            snprintf(channel_name, sizeof(channel_name), "%d.%d", channel_num,
                     i);
          else {
            if (!strcmp(channel_name, "0"))
              snprintf(channel_name, sizeof(channel_name), "%d.%d", channel_num,
                       i);
          }
        }
        struct channel_entry_t *ce_p = &ce[ce_channel_num];
        snprintf(
            ce->dev_tuning, sizeof(ce->dev_tuning), "%s prog:%d",
            get_tune_string(result.channel_str, tune_str, sizeof(tune_str)),
            program_id);
        strncpy(ce_p->ch_name, channel_name, sizeof(ce_p->ch_name));
        strncpy(ce_p->dev_name, device, sizeof(ce_p->dev_name));
        ce_p->ch = found_channel + ce_channel_num;
        ce_p->frq = result.frequency;
        ce_p->av_inf[0] = 0x0;
        char stream_tar[32];
        snprintf(stream_tar, sizeof(stream_tar), "udp://%s:%u", CHANNE_SCAN_SRC,
                 CHANNEL_SCAN_PORT);
        ret = tune_channel(hd, ce_p->dev_tuning, "", stream_tar);
        if (ret > 0)
          ret = parse_avinf(CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT, ce_p->av_inf,
                            sizeof(ce_p->av_inf), PARSE_TIMEOUT);
        if (ret > 0)
          ret = strstr(ce_p->av_inf, "ENCRYPTED") == NULL &&
                strstr(ce_p->av_inf, "NO-DATA") == NULL;
        if (ret)
          if (++ce_channel_num > ce_num)
            break;
      }
    }
  } while (0);

  hdhomerun_device_tuner_lockkey_release(hd);

  if (ret < 0) {
    fprintf(stderr,
            "communication error sending request to hdhomerun device\n");
  }
  return found_channel;
}

int scan_vchannel(void *device, int vchannel, struct channel_entry_t *ce)
{
  int ret;
  struct hdhomerun_device_t *hd = (struct hdhomerun_device_t *)device;
  if (hd == NULL) {
    sage_log((_LOG_ERROR, 3, "hdhomerun invalid handle."));
    return -1;
  }

  ce->state = 1;
  ce->ch = vchannel;
  ce->frq = 0;
  ce->av_inf[0] = 0x0;
  char stream_tar[32];
  snprintf(ce->ch_name, sizeof(ce->ch_name), "%d", vchannel);
  snprintf(ce->dev_tuning, sizeof(ce->dev_tuning), "vchan:%d", vchannel);
  snprintf(stream_tar, sizeof(stream_tar), "udp://%s:%u", CHANNE_SCAN_SRC,
           CHANNEL_SCAN_PORT);
  ret = tune_channel(device, ce->dev_tuning, "", stream_tar);
  if (ret > 0)
    ret = parse_avinf(CHANNE_SCAN_SRC, CHANNEL_SCAN_PORT, ce->av_inf,
                      sizeof(ce->av_inf), PARSE_TIMEOUT);
  if (ret > 0)
    ret = strstr(ce->av_inf, "ENCRYPTED") == NULL &&
          strstr(ce->av_inf, "NO-DATA") == NULL;
  if (ret <= 0) {
    ce->state = 0;
    return 0;
  }

  return 1;
}

static int _make_channel_entry_buffer(struct channel_entry_t *ce, char *buf,
                                      int size)
{
  int pos = 0;
  pos += snprintf(buf + pos, size - pos, "ch:%03d ", ce->ch);
  if (ce->ch_name[0])
    pos += snprintf(buf + pos, size - pos, "name:%s ", ce->ch_name);
  if (ce->src_ip[0] && ce->src_port)
    pos += snprintf(buf + pos, size - pos, "ip:%s port:%d ", ce->src_ip,
                    ce->src_port);
  if (ce->epg_id[0])
    pos += snprintf(buf + pos, size - pos, "epg:%s ", ce->epg_id);
  if (ce->dev_name[0])
    pos += snprintf(buf + pos, size - pos, "dev:%s ", ce->dev_name);
  if (ce->dev_tuning[0])
    pos += snprintf(buf + pos, size - pos, "tune:%s ", ce->dev_tuning);
  if (ce->av_inf[0])
    pos += snprintf(buf + pos, size - pos, "av:\"%s\" ", ce->av_inf);
  pos += snprintf(buf + pos, size - pos, "\n");
  return pos;
}

static int _save_channel_entry(char *file_name, struct channel_entry_t *ce,
                               int num)
{
  int i;
  char buf[2048];
  FILE *fp;
  fp = fopen(file_name, "w");
  if (fp == NULL) {
    // printf( "Can't open file %s to save channel table, errno:%d\n",
    // file_name, errno );
    return -1;
  }
  fputs("#Google sagetv channel table ver 1.0., maximum 2048 bytes per line\n",
        fp);
  fprintf(fp, "total_channel:%d\n", num);
  for (i = 0; i < num; i++) {
    _make_channel_entry_buffer(ce, buf, sizeof(buf));
    fputs(buf, fp);
    ce++;
  }
  fclose(fp);
  return 1;
}

int main(int argc, char *argv[])
{
  int i, ret = 0;
  int tuner_count = 0;
  struct hdhr_tuner_t ht[16];

  ret = discover_device(ht, 16);
  printf("found tuners:%d\n", ret);
  if (ret > 0) {
    for (i = 0; i < ret; i++) {
      // if a unit shares a source input in a device, copy data.
      if (i > 0 && tuner_input_sharing(&ht[i - 1], &ht[i])) {
        ht[i].cc_tuner = ht[i - 1].cc_tuner;
        strncpy(ht[i].model, ht[i - 1].model, sizeof(ht[i].model));
      } else
        get_dev_model(&ht[i]);

      printf("%d tuner:%s ip:%s type:%d cc:%d model:%s\n", i, ht[i].name,
             ht[i].ip, ht[i].type, ht[i].cc_tuner, ht[i].model);
    }
    tuner_count = ret;
  }

  // test channel scan
  if (0) {
    time_t t0 = time(NULL);
    struct channel_entry_t ce[400];
    int channel_num = 0;
    // channel_num = scan_all( "101007FD-0", ce, 400 );
    for (i = 60; i <= 70; i++) {
      ret = scan_channel("101007FD-1", i, ce, channel_num, 400);
      if (ret < 0 || sigabort_flag)
        break;
      printf("find channe:%d\n", ret);
      channel_num += ret;
    }
    printf("time:%ld\n", time(NULL) - t0);
    _save_channel_entry("channel-scan.txt", ce, channel_num);
  }

  // test vchannel scan
  if (0) {
    struct hdhr_tuner_t *cc_ht = NULL;
    for (i = 0; i < tuner_count; i++) {
      if (ht[i].cc_tuner) {
        cc_ht = &ht[i];
        break;
      }
    }

    if (cc_ht != NULL) {
      time_t t0 = time(NULL);
      struct vchan_tbl_t *vt = create_vchan_tbl(cc_ht);
      ret = get_vchannel_list(vt);
      if (ret > 0) {
        int n;
        int channel_num = 0;
        struct channel_list_t *cl = create_channel_list(ret);
        for (n = 1; n < vt->channel_num && channel_num < 500; n++) {
          printf("TRACE %d %s\n", n, vt->vchan[n].guide_name);
          ret = scan_vchannel(vt, n, cl);
          if (ret > 0) {
            struct channel_entry_t *ce_p = &cl->ce[channel_num];
            snprintf(ce_p->dev_name, sizeof(ce_p->dev_name), "HDHR.%s", device,
                     sizeof(ce_p->dev_name));
            channel_num++;
          }
          printf("TRACE channel %d, %d\n", channel_num, n);
        }
        _save_channel_entry("channel-scan.txt", cl);
      }
      release_vchan_tbl(vt);
      printf("time:%ld\n", time(NULL) - t0);
    }
  }

  // test tune
  if (1) {
    // printf( "tuning %s \n", device[i] );
    char *dev_name = "1311A273-0";  //"101007FD-1";
    // ret = tune_channel( dev_name, "map:us-cable|auto:68", "343",
    // "udp://226.0.0.1:4096" );
    ret = tune_channel(dev_name, "vchan:600", "", "udp://226.0.0.1:4096");
    printf("hit enter to stop\n");
    getchar();
    ret = stop_channel(dev_name);
  }

  return ret;
}

#endif
