#include "WhoiUam.h"
#include "Syslog.h"
#include "LayeredControlIF.h"

#define ReadTimeout 10000

WhoiUam::WhoiUam(const char *name, SerialDevice *device, 
		 StringMsgHandler *handler, char acousticTokenDelimiter)
  : StreamSerialDriver(name, device, 
		       100,
		       "\n", ReadTimeout, 2)
{
  _device->setLineFormat(9600, 8, 1, "NONE");
  _handler = handler;
  _inputMessage = new StringMessage(UAM_MaxMessageBytes, 
				    acousticTokenDelimiter);
}


WhoiUam::~WhoiUam()
{
  delete _inputMessage;
}


DeviceIF::Status WhoiUam::initialize()
{
  return DeviceIF::Ok;
}


DeviceIF::Status WhoiUam::processRecord(unsigned char *record, 
					int nRecordBytes)
{
  Boolean debug = True;
  dprintf("WhoiUam::processRecord(): \"%s\"", record);

  if (!strncmp((char *)record, UAM_DiagnosticMnem, 
		    strlen(UAM_DiagnosticMnem)) ||
      !strncmp((char *)record, UAM_TimeoutMnem, 
	       strlen(UAM_TimeoutMnem))) {

    // Just a diagnostic message. Print it out and return
    Syslog::write("WhoiUam::processRecord() - modem diagnostic msg:\n%s",
		  record);

    return DeviceIF::Ok;
  }


  Boolean error = False;

  _inputMessage->setBuffer((char *)record);

  try {
    _handler->process(_inputMessage, &_outputMessages);
  }
  catch (Exception e) {
    Syslog::write("WhoiUam::processRecord() - caught exception: %s", e.msg);
    return DeviceIF::Error;
  }

  // Transmit output messages
  for (int i = 0; i < _outputMessages.size(); i++) {

    StringMessage *telemetry;
    _outputMessages.get(i, &telemetry);

    // Encode and write telemetry packet
    try {

      // Pad out-going message with blanks
      telemetry->pad(' ');

      dprintf("WhoiUam::processRecord(): writing %s", telemetry->buffer());

      if (_device->write(telemetry->buffer(), 
			 strlen(telemetry->buffer())) == -1) {

	Syslog::write("WhoiUam::processRecord() - write() failed");
	error = True;
      }
    }
    catch (Exception e) {
	Syslog::write("WhoiUam::processRecord() - write() failed; %s",
		      e.msg);
	error = True;
    }
    catch (...) {
	Syslog::write("WhoiUam::processRecord() - write() failed,"
		      "caught exception!");
	error = True;
    }
  }

  if (error)
    return DeviceIF::Error;
  else
    return DeviceIF::Ok;
}


void WhoiUam::handleReadTimeout()
{
  Syslog::write("WhoiUam::handleReadTimeout()");
}

