// 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;
}

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_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 channel map %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 SER to hit 100% (max 3 secs)
  usleep(500000);
  for (i = 0; i < 10; i++) {
    ret = hdhomerun_device_get_tuner_status(hd, NULL, &ts);
    if (ret > 0 && ts.symbol_error_quality >= 100) {
      break;
    }
    usleep(250000);
  }

  // Get MPEG2-TS stream info
  ret = hdhomerun_device_get_tuner_streaminfo(hd, &streaminfo);
  if (ret <= 0) {
    printf("hdhr:ERROR: get tuner streaminfo\n");
    goto out;
  }
  printf("hdhr:hdhomerun streaminfo:\n%s", streaminfo);

  // Translate virtual channel (major.minor) to program number
  ret = vchan_to_prog_num(streaminfo, vchannel_major, vchannel_minor, &program);
  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
