/*!
  \file
  \brief handler SCIP 1.0 protocol

  \author Satofumi Kamimura

  $Id: scip_handler_10.c 1989 2012-05-18 00:32:36Z satofumi $
*/

#include "scip_handler_10.h"
#include "urg_errno.h"
#include "serial_errno.h"
#include <string.h>


enum {
  ScipTimeout = 1000,           /*!< [msec] */
  EachTimeout = 100,		/*!< [msec] */
};


int scip_send(serial_t *serial, const char *send_command)
{
  int n = (int)strlen(send_command);
  return serial_send(serial, send_command, n);
}


int scip_recv(serial_t *serial, const char *command_first,
              int* return_code, int expected_ret[], int timeout)
{
  char recv_ch = '\0';
  int ret_code = 0;
  int n;
  int i;

  /* Receive the response */
  char buffer[ScipLineWidth];

  /* Skip the first response */
  n = serial_getLine(serial, buffer, ScipLineWidth, timeout);
  if (n < 0) {
    return UrgSerialRecvFail;
  }

  /* ignore 0x00 response after connection */
  if (! ((n == 1) && (buffer[0] == 0x00))) {
    if (strncmp(buffer, command_first, 2)) {
      /* Treat as an error,if there is mismatch with sent characters */
      return UrgMismatchResponse;
    }
  }

  /* Read and pass the response characters. */
  n = serial_getLine(serial, buffer, ScipLineWidth, timeout);

  /* restore last character, and use next proccessing */
  n = serial_recv(serial, &recv_ch, 1, timeout);
  if ((n == 1) && (! serial_isLF(recv_ch))) {
    serial_ungetc(serial, recv_ch);
  }

  /* Returns 0, if received response characters are as expected */
  ret_code = strtol(buffer, NULL, 16);
  if (return_code != NULL) {
    *return_code = ret_code;
  }
  for (i = 0; expected_ret[i] != -1; ++i) {
    if (ret_code == expected_ret[i]) {
      return 0;
    }
  }
  return ret_code;
}


int scip_v(serial_t *serial, char *lines[], int lines_max)
{
  int send_n;
  int ret = 0;
  int expected_reply[] = { 0x0, -1 };
  int n;
  int i;

  /* Initialize by an empty message */
  for (i = 0; i < lines_max; ++i) {
    *lines[i] = '\0';
  }

  /* Send VV command */
  send_n = scip_send(serial, "V\n");
  if (send_n != 2) {
    return SerialSendFail;
  }

  /* Receive response */
  ret = scip_recv(serial, "V", NULL, expected_reply, ScipTimeout);
  if (ret < 0) {
    return ret;
  }

  /* Receive version information */
  for (i = 0; i < lines_max; ++i) {
    n = serial_getLine(serial, lines[i], ScipLineWidth, ScipTimeout);
    if (n <= 0) {
      return ret;
    }
  }

  serial_skip(serial, ScipTimeout, EachTimeout);
  return ret;
}


int scip_s(serial_t *serial, long baudrate)
{
  int expected_reply[] = { 0x0, 0x3, 0x4, -1 };
  int send_n;
  int ret;

  /* !!! Should be treated as an error if baud rate is not with in range of
         defined range */

  /* Send SS command */
  char buffer[] = "SSxxxxxx\n";
  snprintf(buffer, 10, "SS%06ld\n", baudrate);
  send_n = scip_send(serial, buffer);
  if (send_n != 9) {
    return SerialSendFail;
  }

  /* Receive response */
  ret = scip_recv(serial, "SS", NULL, expected_reply, ScipTimeout);
  if (ret < 0) {
    return ret;
  }

  return 0;
}
