// 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 dumplicated 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., maxium 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 ( 1 ) {
    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
