#include "VirtualSerialPort.h"

extern "C" 
{
# include "vspCmd.h"
};


VirtualSerialPort::VirtualSerialPort(const char *systemName,
				     const char *appName,
				     const char *deviceName,
				     Word channelNo,
				     sio32Chan *sio32Channel,
				     Int16 cardNo,
				     Word cardAddr)
  : SerialDevice(systemName, appName, deviceName, channelNo)
{
  _sio32Chan = sio32Channel;
  _cardAddr = cardAddr;

  bzero((char *)&vspDmItems, sizeof(ibcVspDmItems));

  if (createIbcVspDmItems(&vspDmItems, _dmPrefix, _appName, cardNo) != OK)
  {
    setError("VspCard::VspCard() - createIbcVspDmItems() failed");
    return;
    
#if 0    
    throw IbcAppError(IbcAppError::DataMgr, _name,
		      "VspCard::VspCard() - createIbcVspDmItems() failed");
#endif
  }

  initIbcVspProvider(&vspDmItems);

  if (handleResetEvent() != OK)
  {
    setError("VspCard::VspCard() - handleResetEvent() failed");
    return;
    
#if 0
    throw IbcAppError(IbcAppError::DataMgr, _name,
		      "VspCard::VspCard() - handleResetEvent() failed");
#endif
  }
}


STATUS VirtualSerialPort::handleResetEvent()
{
  updateIbcVspDmItems(_sio32Chan, _cardAddr, _channelNo, &vspDmItems, 
		      _appName);

  return OK;
}


STATUS VirtualSerialPort::startMonitoring(DmMonitor *dmMonitor)
{
  dmMonitor->addMonitoredItem(vspDmItems.vspBaud);
  dmMonitor->addMonitoredItem(vspDmItems.vspData);
  dmMonitor->addMonitoredItem(vspDmItems.vspStop);
  dmMonitor->addMonitoredItem(vspDmItems.vspPar);
  dmMonitor->addMonitoredItem(vspDmItems.vspMsgOut);
  dmMonitor->addMonitoredItem(vspDmItems.vspHandshake);
  dmMonitor->addMonitoredItem(vspDmItems.vspProtocol);
  dmMonitor->addMonitoredItem(vspDmItems.vspBreak);

  return OK;
}


STATUS VirtualSerialPort::processDmChanges(DmGroup *dmGroup)
{
  MBool debug = FALSE;
  STATUS status;
  Int16   baud;
  Nat16   data, stop, par, numOfBytes;
  MBool handshake;
  Int16   proto;
  Nat16   mode;
  messageStruct msgOut;

  if (dmGroup->itemChanged(vspDmItems.vspBreak))
  {
    dprintf("VirtualSerialPort::processDmChanges() - vspBreak changed\n");

    dm_read(vspDmItems.vspBreak, (char *) &mode,
            sizeof(mode), (DM_Time *) NULL);

    if (IBC_VSP_SendBreak(_sio32Chan, _cardAddr, _channelNo, mode) == ERROR)
    {
      logMsg("VirtualSerialPort::processDmChanges() - "
	     "IBC_VSP_SendBreak() failed\n");
      status = ERROR;
    }
  }

  if  (dmGroup->itemChanged(vspDmItems.vspMsgOut))
  {
    dprintf("VirtualSerialPort::processDmChanges() - msgOut changed\n");

    dm_read(vspDmItems.vspMsgOut, (char *) &msgOut,
            sizeof(msgOut), (DM_Time *) NULL);

    if (IBC_VSP_Write(_sio32Chan, _cardAddr, _channelNo, msgOut.buffer,
		      msgOut.len) == ERROR)
    {
      logMsg("VirtualSerialPort::processDmChanges() - "
	     "IBC_VSP_Write() failed\n");
      status = ERROR;
    }
  }

  if (dmGroup->itemChanged(vspDmItems.vspBaud) ||
      dmGroup->itemChanged(vspDmItems.vspData) ||
      dmGroup->itemChanged(vspDmItems.vspStop) ||
      dmGroup->itemChanged(vspDmItems.vspPar) ||
      dmGroup->itemChanged(vspDmItems.vspHandshake) ||
      dmGroup->itemChanged(vspDmItems.vspProtocol))
  {                            
    dprintf("VirtualSerialPort::processDmChanges() - setup changed\n");

    /* Read VSP parameters from dmgr*/
    dm_read(vspDmItems.vspBaud, (char *) &baud,
	    sizeof(baud), (DM_Time *) NULL);

    dm_read(vspDmItems.vspData, (char *) &data,
	    sizeof(data), (DM_Time *) NULL);

    dm_read(vspDmItems.vspStop, (char *) &stop,
	    sizeof(stop), (DM_Time *) NULL);

    dm_read(vspDmItems.vspPar, (char *) &par,
	    sizeof(par), (DM_Time *) NULL);

    dm_read(vspDmItems.vspHandshake, (char *) &handshake,
	    sizeof(handshake), (DM_Time *) NULL);

    dm_read(vspDmItems.vspProtocol, (char *) &proto,
	    sizeof(proto), (DM_Time *) NULL);

    if (IBC_VSP_SetLineParm(_sio32Chan, _cardAddr, _channelNo, 
			    baud, data, stop, par, handshake, 
			    proto ) == ERROR)
    {
      logMsg("VirtualSerialPort::processDmChanges() - Error Setting up VSP\n");
      status = ERROR;
    }
  } 

  return status;
}



MBool VirtualSerialPort::handleSrq(Word requestCode, Byte *packet)
{
  return processIbcVspSRQ(requestCode, packet, _cardAddr, _channelNo, 
			  &vspDmItems);
}


STATUS VirtualSerialPort::handleResetSrq()
{
  return OK;
}


STATUS VirtualSerialPort::startSampling()
{
  return OK;
}


STATUS VirtualSerialPort::sampleMicro()
{
  return OK;
}
