// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Small test for gobi modem handles.  Avoids many dependencies.
// Code liberally cribbed from gobi-modem-reset.c

#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/limits.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>

#include "gobi/GobiConnectionMgmtAPI.h"

static void log(const char *format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  fputc('\n', stderr);
  fflush(stderr);
  vsyslog(LOG_INFO, format, args);
  va_end(args);
}

/* Returns true if the supplied devid string is valid. Valid devid strings are
 * of the form: [0-9]+ '-' [0-9]+ */
static bool isdevid(const char *devid) {
  const char *d = devid;

  /* Check the part before the dash... */
  if (!d || !isdigit(*d++))
    return false;

  while (*d && isdigit(*d))
    d++;

  /* ... the dash itself ... */
  if (*d++ != '-')
    return false;

  /* ... and the part after the dash. */
  if (!isdigit(*d++))
    return false;

  while (*d && isdigit(*d))
    d++;

  return *d == '\0';
}

static int reset(const char *dev) {
  char path[PATH_MAX];
  int fd = -1;
  int to_return = 1;

  if (snprintf(path, sizeof(path), "%s/authorized", dev) == sizeof(path)) {
    log("Could not build path");
    goto done;
  }

  fd = open(path, O_WRONLY | O_TRUNC | O_NOFOLLOW);
  if (fd < 0) {
    log("Could not open authorized file: %s", path);
    goto done;
  }

  log("deauthorizing: %s", path);
  if (write(fd, "0", 1) != 1) {
    log("write(0) failed: %d", errno);
    goto done;
  }

  log("sleeping for 1 second");
  sleep(1);

  log("reauthorizing: %s", path);
  if (write(fd, "1", 1) != 1) {
    log("write(1) failed: %d", errno);
    goto done;
  }
  to_return = 0;

done:
  if (fd >= 0) {
    close(fd);
  }
  return to_return;
}

static void usage(const char *progname) {
  fprintf(stderr, "Usage: %s <file | api> <usb-dev-id> <qcqmi-dev>\n",
          progname);
  fprintf(stderr, "\tExample: %s api 1-2 /dev/qcqmi0\n", progname);
  fprintf(stderr, "To determine the usb dev id, run \n");
  fprintf(stderr, "\tls -d /sys/bus/usb/drivers/{QCUSBNet2k,gobi}/*-*\n");
  fprintf(stderr, "and use the string before the :\n");
}

struct DEVICE_ELEMENT {
  char deviceNode[256];
  char deviceKey[16];
};

// Connect to first modem present.  Returns 0 on success.
int connect_modem() {
  const int MAX_MODEMS = 16;
  ULONG rc;

  DEVICE_ELEMENT devices[MAX_MODEMS];
  BYTE num_devices = MAX_MODEMS;

  rc = QCWWANEnumerateDevices(&num_devices,
                              reinterpret_cast<BYTE*>(devices));
  if (rc != 0) {
    log("Could not enumerate: %d", rc);
    return -1;
  }

  if (num_devices == 0) {
    log("No devices found");
    return -1;
  }

  rc = QCWWANConnect(devices[0].deviceNode, devices[0].deviceKey);
  if (rc !=0) {
    log("Could not QCWWANConnect to modem: %d", rc);
    return -1;
  }
  return 0;
}


int main(int argc, char *argv[]) {
  char usb_path[PATH_MAX];
  bool use_qcwwan = 1;

  openlog("gobi_handle_tester", LOG_PID, LOG_USER);
  if (argc != 4) {
    usage(argv[0]);
    return 1;
  }

  if (getuid() != 0) {
    fprintf(stderr, "This program must be run as root\n");
    return 1;
  }

  int argument = 1;
  const char *operation = argv[argument++];
  const char *usb_device_id = argv[argument++];
  const char *qmi_device_path = argv[argument++];

  if (!isdevid(usb_device_id)) {
    fprintf(stderr, "Could not parse device id %s\n", usb_device_id);
    usage(argv[0]);
    return 1;
  }

  if (strcmp(operation, "file") == 0) {
    // Just open /dev/qcqmi0 as a file
    use_qcwwan = 0;
  } else if (strcmp(operation, "api") == 0) {
    // Use QCWWANConnect to open a connection to the device
    use_qcwwan = 1;
  } else {
    fprintf(stderr, "Could not understand operation: %s\n", operation);
    usage(argv[0]);
    return 1;
  }

  snprintf(usb_path,
           sizeof(usb_path),
           "/sys/bus/usb/devices/%s", usb_device_id);

  log("operation: %s  use_qcwwan: %d", operation, use_qcwwan);
  log("USB path: %s", usb_path);
  log("device path: %s", qmi_device_path);

  int fd = -1;
  ULONG rc;

  if (use_qcwwan) {
    if (connect_modem() != 0) {
      log("Failure connecting to modem");
      return 4;
    }
  } else {
    fd = open(qmi_device_path, O_RDWR);
    if (fd < 0) {
      fprintf(stderr, "Could not open device %s\n", qmi_device_path);
      return 3;
    }
  }

  if (reset(usb_path) != 0)  {
    log("Reset failed.  Exiting");
    return 6;
  }

  log("sleeping while waiting for kernel handles to expire");

  for (int i = 0 ; i < 45; ++i) {
    sleep(1);
    fprintf(stderr, ".");
  }
  fputc('\n', stderr);

  log("closing");

  if (use_qcwwan) {
    rc = QCWWANDisconnect();
    if (rc != 0) {
      log("Failed on disconnect: %d", rc);
    }
  }

  if (fd >= 0) {
    rc = close(fd);
    if (rc != 0) {
      log("Failed on close: %d", rc);
    }
  }

  log("exiting");
  return 0;
}
