//..............................................................................
//
//  Device Monitor transport for SerialMonProcessor
//

import "iox_Monitor.jnc"
import "SerialMonProcessor_win.jnc"
import "SerialMonProcessor_lnx.jnc"

//..............................................................................

class SerialMonitor: iox.Monitor
{
protected:
	SerialMonSession* m_session;
	SerialMonProcessor* m_processor;

public:
	construct(SerialMonSession* session);

	bool errorcode capture(char const* deviceName);

protected:
	override processNotification(io.DeviceMonitorNotifyHdr const* notifyHdr)
	{
		m_processor.processNotification(notifyHdr);
	}

	override processError(std.Error const* error);
}

// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SerialMonitor.construct(SerialMonSession* session)
{
	basetype.construct(session.m_pluginHost);
	m_session = session;

	switch (sys.g_systemInfo.m_osKind)
	{
	case sys.OsKind.Windows:
		m_processor = new SerialMonProcessor_win(m_session.m_logWriter);
		break;

	case sys.OsKind.Linux:
		m_processor = new SerialMonProcessor_lnx(m_session.m_logWriter);
		break;

	default:
		std.setError("Unsupported OS");
		throw;
	}
}

bool errorcode SerialMonitor.capture(char const* deviceName)
{
	if (!(sys.g_systemInfo.m_osFlags & sys.OsFlags.Posix))
	{
		basetype.capture(deviceName);
	}
	else
	{
		static io.psx.DeviceMonitorIoctlDesc ioctlDescTable[] =
		{
			{ psx.TCSETA,   sizeof(psx.termio) },
			{ psx.TCSETAW,  sizeof(psx.termio) },
			{ psx.TCSETAF,  sizeof(psx.termio) },
			{ psx.TCSETS,   sizeof(psx.termios) },
			{ psx.TCSETSW,  sizeof(psx.termios) },
			{ psx.TCSETSF,  sizeof(psx.termios) },
			{ psx.TIOCMGET, sizeof(uint_t) },
			{ psx.TIOCMBIS, sizeof(uint_t) },
			{ psx.TIOCMBIC, sizeof(uint_t) },
		}

		basetype.capture(deviceName, null, ioctlDescTable, sizeof(ioctlDescTable) / sizeof(ioctlDescTable[0]));
	}

	m_processor.reset();
	return true;
}

void SerialMonitor.processError(std.Error const* error)
{
	m_session.m_logWriter.write(log.StdRecordCode.Error, error);
	m_session.close();
}

//..............................................................................
