Important update:
- SelectableCore:
- Rename methods: SetSerialPortConfig() -> WriteSerialConfig(),
GetSerialPortConfig() -> ReadSerialConfig(),
InputHandle() -> OutputHandle(),
ProcessBuffer() -> ProcessInputBuffer()
SetPortHandle(config)() -> SetSerialHandle(Config)()
- Rename serial port identification: "Port" -> "SerialPort"
- Update logs accordingly
- Add LinePrinter Port
- Add to LoadConfig()
- Add SetLinePrinterHandle() & OpenLinePrinterPort() methods
- Add handling for open/read/write/close events
- Add CloseDelay for AutoManage (non-persistent) ports
- Rename handle timer: ReopenStart -> LastAction
- Reset timer on all open/read/write/close events
- Check for Close timeout in Process() and close port
- Remove CloseChildren parameter on Close() method
- Add QuickReopen parameter to Close() method
- SelectCore:
- Overwrite existing handle - not yet removed
- Handle In/Out baudrate on serial port separately
This commit is contained in:
@@ -93,17 +93,19 @@ void CSelect::Add( int FD, bool Read, bool Write, CSelectableCore * Function )
|
|||||||
while (*Handle && ((*Handle)->FD != FD)) {
|
while (*Handle && ((*Handle)->FD != FD)) {
|
||||||
Handle = &((*Handle)->Next);
|
Handle = &((*Handle)->Next);
|
||||||
}
|
}
|
||||||
|
if (*Handle) {
|
||||||
|
// Old handle not yet removed, remove from read/write lists
|
||||||
|
Remove( FD, true, true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
// Create if not exist
|
// Create if not exist
|
||||||
if (!*Handle) {
|
|
||||||
// Create
|
|
||||||
*Handle = (TSelectHandle*)malloc( sizeof(TSelectHandle) );
|
*Handle = (TSelectHandle*)malloc( sizeof(TSelectHandle) );
|
||||||
memset( *Handle, 0, sizeof(TSelectHandle) );
|
memset( *Handle, 0, sizeof(TSelectHandle) );
|
||||||
|
(*Handle)->FD = FD;
|
||||||
|
}
|
||||||
|
|
||||||
// Set Parameters
|
// Set Parameters
|
||||||
(*Handle)->FD = FD;
|
|
||||||
(*Handle)->Function = Function;
|
(*Handle)->Function = Function;
|
||||||
}
|
|
||||||
|
|
||||||
// Add Read select
|
// Add Read select
|
||||||
if (Read && !(*Handle)->Read) {
|
if (Read && !(*Handle)->Read) {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ CSelectableCore::~CSelectableCore()
|
|||||||
{
|
{
|
||||||
// Close handle if open
|
// Close handle if open
|
||||||
if ((FirstHandle->State == csOpen) || (FirstHandle->State == csWaitingtoOpen)) {
|
if ((FirstHandle->State == csOpen) || (FirstHandle->State == csWaitingtoOpen)) {
|
||||||
Close( FirstHandle, true );
|
Close( FirstHandle, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
NextHandle = FirstHandle->Next;
|
NextHandle = FirstHandle->Next;
|
||||||
@@ -94,14 +94,14 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Channel" ) );
|
Handle->Channel = GetChannel( DataTree->GetStr( TempMember, "Channel" ) );
|
||||||
|
|
||||||
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
Type = (char*)DataTree->GetStr( TempMember, "Type", "TCPclient", true );
|
||||||
if (!strcasecmp( Type, "Port" ))
|
if (!strcasecmp( Type, "Serial" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL ); // Get default value
|
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL ); // Get default value
|
||||||
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
||||||
sprintf( Path, "Address/%s/Address", Name );
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
||||||
}
|
}
|
||||||
SetPortHandle( Handle, Address );
|
SetSerialHandle( Handle, Address );
|
||||||
|
|
||||||
// Update configuration if specified
|
// Update configuration if specified
|
||||||
if ((SerialConfig = DataTree->GetMember( TempMember, "Port/SerialConfig", false )))
|
if ((SerialConfig = DataTree->GetMember( TempMember, "Port/SerialConfig", false )))
|
||||||
@@ -125,12 +125,21 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
FlowCtrl = SW_FLOWCTRL;
|
FlowCtrl = SW_FLOWCTRL;
|
||||||
|
|
||||||
Handle->SerialConfig = true;
|
Handle->SerialConfig = true;
|
||||||
SetPortHandleSerial( Handle, DataTree->GetInt( SerialConfig, "BaudRate", 19200, true ),
|
SetSerialHandleConfig( Handle, DataTree->GetInt( SerialConfig, "BaudRate", 19200, true ),
|
||||||
DataTree->GetInt( SerialConfig, "DataBits", 8, true ),
|
DataTree->GetInt( SerialConfig, "DataBits", 8, true ),
|
||||||
Parity, DataTree->GetInt( SerialConfig, "StopBits", 1, true ),
|
Parity, DataTree->GetInt( SerialConfig, "StopBits", 1, true ),
|
||||||
FlowCtrl, DataTree->GetInt( SerialConfig, "DataWait", 0, true ));
|
FlowCtrl, DataTree->GetInt( SerialConfig, "DataWait", 0, true ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcasecmp( Type, "LinePrinter" ))
|
||||||
|
{
|
||||||
|
Address = (char*)DataTree->GetStr( TempMember, "Port/Address", NULL ); // Get default value
|
||||||
|
if ((Name = (char*)DataTree->GetStr( TempMember, "Port/Name", NULL ))) {
|
||||||
|
sprintf( Path, "Address/%s/Address", Name );
|
||||||
|
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
|
||||||
|
}
|
||||||
|
SetLinePrinterHandle( Handle, Address );
|
||||||
|
}
|
||||||
else if (!strcasecmp( Type, "TCPserver" ))
|
else if (!strcasecmp( Type, "TCPserver" ))
|
||||||
{
|
{
|
||||||
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
Address = (char*)DataTree->GetStr( TempMember, "Socket/Address", NULL ); // Get default Address value
|
||||||
@@ -163,7 +172,8 @@ bool CSelectableCore::LoadConfigData()
|
|||||||
// Set Auto Mange
|
// Set Auto Mange
|
||||||
SetAutoManage( Handle, DataTree->GetBool( TempMember, "AutoManage/Enabled", true, true ),
|
SetAutoManage( Handle, DataTree->GetBool( TempMember, "AutoManage/Enabled", true, true ),
|
||||||
DataTree->GetBool( TempMember, "AutoManage/Persistent", false, true ),
|
DataTree->GetBool( TempMember, "AutoManage/Persistent", false, true ),
|
||||||
DataTree->GetInt( TempMember, "AutoManage/ReopenDelay", 2000, true ) );
|
DataTree->GetInt( TempMember, "AutoManage/ReopenDelay", 2000, true ),
|
||||||
|
DataTree->GetInt( TempMember, "AutoManage/CloseDelay", 2000, true ));
|
||||||
|
|
||||||
// Input buffer
|
// Input buffer
|
||||||
SetInBuffer( Handle, DataTree->GetInt( TempMember, "InputBuffer/Size", 0 ),
|
SetInBuffer( Handle, DataTree->GetInt( TempMember, "InputBuffer/Size", 0 ),
|
||||||
@@ -279,15 +289,15 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
|
bool CSelectableCore::SetSerialHandle( THandle * Handle, const char * FileName )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) {
|
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctSerial)) || !FileName) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Type
|
// Set Type
|
||||||
Handle->Type = ctPort;
|
Handle->Type = ctSerial;
|
||||||
|
|
||||||
// Clear File Name
|
// Clear File Name
|
||||||
if (Handle->Path) {
|
if (Handle->Path) {
|
||||||
@@ -304,14 +314,15 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::SetPortHandleSerial( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait )
|
bool CSelectableCore::SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Handle || (Handle->Type != ctPort)) {
|
if (!Handle || (Handle->Type != ctSerial)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle->Baudrate = Baudrate;
|
Handle->InBaudrate = Baudrate;
|
||||||
|
Handle->OutBaudrate = Baudrate;
|
||||||
Handle->DataBits = DataBits;
|
Handle->DataBits = DataBits;
|
||||||
Handle->Parity = Parity;
|
Handle->Parity = Parity;
|
||||||
Handle->StopBits = StopBits;
|
Handle->StopBits = StopBits;
|
||||||
@@ -322,6 +333,31 @@ bool CSelectableCore::SetPortHandleSerial( THandle * Handle, int Baudrate, short
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool CSelectableCore::SetLinePrinterHandle( THandle * Handle, const char * FileName )
|
||||||
|
{
|
||||||
|
// Validate
|
||||||
|
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctLinePrinter)) || !FileName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set Type
|
||||||
|
Handle->Type = ctLinePrinter;
|
||||||
|
|
||||||
|
// Clear File Name
|
||||||
|
if (Handle->Path) {
|
||||||
|
free( Handle->Path );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set name
|
||||||
|
Handle->Path = (char*)malloc( strlen(FileName)+1 );
|
||||||
|
strcpy( Handle->Path, FileName );
|
||||||
|
|
||||||
|
// Log event
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as Port [%s]", Name, Handle->Name, FileName );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath )
|
bool CSelectableCore::SetForkPipeHandle( THandle * Handle, const char * ExecPath )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
@@ -429,7 +465,7 @@ bool CSelectableCore::SetCallback( THandle * Handle, EConnectState pState, FHand
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenDelay )
|
bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenDelay, int CloseTimeout )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Handle) {
|
if (!Handle) {
|
||||||
@@ -440,6 +476,7 @@ bool CSelectableCore::SetAutoManage( THandle * Handle, bool AutoManage, bool Per
|
|||||||
Handle->AutoManage = AutoManage;
|
Handle->AutoManage = AutoManage;
|
||||||
Handle->Persistent = Persistent;
|
Handle->Persistent = Persistent;
|
||||||
Handle->ReopenDelay = ReopenDelay;
|
Handle->ReopenDelay = ReopenDelay;
|
||||||
|
Handle->CloseTimeout = CloseTimeout;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
@@ -495,7 +532,7 @@ bool CSelectableCore::SetOutBuffer( THandle * Handle, int OutBufSize )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::OpenPort( THandle * Handle )
|
int CSelectableCore::OpenSerialPort( THandle * Handle )
|
||||||
{
|
{
|
||||||
// Validate
|
// Validate
|
||||||
if (!Handle || (Handle->Type == ctNone)) {
|
if (!Handle || (Handle->Type == ctNone)) {
|
||||||
@@ -508,7 +545,7 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
|||||||
if (access( Handle->Path, F_OK ) != 0)
|
if (access( Handle->Path, F_OK ) != 0)
|
||||||
{
|
{
|
||||||
// Log event
|
// Log event
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port not found [%s]", Name, Handle->Name, Handle->Path );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Serial Port not found [%s]", Name, Handle->Name, Handle->Path );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,20 +554,20 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
|||||||
if (Handle->FD == -1)
|
if (Handle->FD == -1)
|
||||||
{
|
{
|
||||||
// Log event
|
// Log event
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not open Port [%s]", Name, Handle->Name, Handle->Path );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not open Serial Port [%s]", Name, Handle->Name, Handle->Path );
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log Event
|
// Log Event
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->Path );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Serial Port opened [%s]", Name, Handle->Name, Handle->Path );
|
||||||
|
|
||||||
// Update port configuration
|
// Update port configuration
|
||||||
if (Handle->SerialConfig)
|
if (Handle->SerialConfig)
|
||||||
SetSerialPortConfig( Handle );
|
WriteSerialConfig( Handle );
|
||||||
else
|
else
|
||||||
GetSerialPortConfig( Handle );
|
ReadSerialConfig( Handle );
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port config, B:%d, D:%d, P:%d, S:%d, F:%d", Name, Handle->Name,
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Serial Port config, IB:%d, OB:%d, D:%d, P:%d, S:%d, F:%d", Name, Handle->Name,
|
||||||
Handle->Baudrate, Handle->DataBits, Handle->Parity, Handle->StopBits, Handle->FlowCtrl );
|
Handle->InBaudrate, Handle->OutBaudrate, Handle->DataBits, Handle->Parity, Handle->StopBits, Handle->FlowCtrl );
|
||||||
|
|
||||||
// Add to Select Lists
|
// Add to Select Lists
|
||||||
if (Selector) {
|
if (Selector) {
|
||||||
@@ -541,7 +578,46 @@ int CSelectableCore::OpenPort( THandle * Handle )
|
|||||||
ChangeState( Handle, csOpen );
|
ChangeState( Handle, csOpen );
|
||||||
return Handle->FD;
|
return Handle->FD;
|
||||||
}
|
}
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int CSelectableCore::OpenLinePrinterPort( THandle * Handle )
|
||||||
|
{
|
||||||
|
// Validate
|
||||||
|
if (!Handle || (Handle->Type == ctNone)) {
|
||||||
|
return -1;
|
||||||
|
} else if (Handle->State == csOpen) {
|
||||||
|
return Handle->FD;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if port exits
|
||||||
|
if (access( Handle->Path, F_OK ) != 0)
|
||||||
|
{
|
||||||
|
// Log event
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Printer Port not found [%s]", Name, Handle->Name, Handle->Path );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open Port
|
||||||
|
Handle->FD = open( Handle->Path, O_RDWR );
|
||||||
|
if (Handle->FD == -1)
|
||||||
|
{
|
||||||
|
// Log event
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Could not open Printer Port [%s]", Name, Handle->Name, Handle->Path );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Log Event
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Printer Port opened [%s]", Name, Handle->Name, Handle->Path );
|
||||||
|
|
||||||
|
// Add to Select Lists
|
||||||
|
if (Selector) {
|
||||||
|
Selector->Add( Handle->FD, true, false, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set state
|
||||||
|
ChangeState( Handle, csOpen );
|
||||||
|
return Handle->FD;
|
||||||
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::OpenForkPipe( THandle * Handle )
|
int CSelectableCore::OpenForkPipe( THandle * Handle )
|
||||||
@@ -892,6 +968,9 @@ int CSelectableCore::OpenRemoteClientSocket( THandle * Handle )
|
|||||||
(*RemoteClient)->Parent = Handle;
|
(*RemoteClient)->Parent = Handle;
|
||||||
(*RemoteClient)->State = csWaitingtoOpen;
|
(*RemoteClient)->State = csWaitingtoOpen;
|
||||||
|
|
||||||
|
// Reset Timer
|
||||||
|
SetStartTime( &((*RemoteClient)->LastAction) );
|
||||||
|
|
||||||
// Log Event
|
// Log Event
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server accepted Remote TCP Client connection [%s]", Name, Handle->Name, ClientAddress );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - TCP Server accepted Remote TCP Client connection [%s]", Name, Handle->Name, ClientAddress );
|
||||||
|
|
||||||
@@ -1024,9 +1103,6 @@ int CSelectableCore::OpenClientSocket( THandle * Handle )
|
|||||||
ChangeState( Handle, csFailed );
|
ChangeState( Handle, csFailed );
|
||||||
Handle->AddressFailed = true;
|
Handle->AddressFailed = true;
|
||||||
|
|
||||||
// Start re-open timer
|
|
||||||
SetStartTime( &(Handle->ReopenStart) );
|
|
||||||
|
|
||||||
// Reset Handle
|
// Reset Handle
|
||||||
Handle->FD = -1;
|
Handle->FD = -1;
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1045,8 +1121,11 @@ int CSelectableCore::Open( THandle * Handle )
|
|||||||
|
|
||||||
// Open correctly
|
// Open correctly
|
||||||
switch (Handle->Type) {
|
switch (Handle->Type) {
|
||||||
case ctPort :
|
case ctSerial :
|
||||||
FD = OpenPort( Handle );
|
FD = OpenSerialPort( Handle );
|
||||||
|
break;
|
||||||
|
case ctLinePrinter :
|
||||||
|
FD = OpenLinePrinterPort( Handle );
|
||||||
break;
|
break;
|
||||||
case ctForkPipe :
|
case ctForkPipe :
|
||||||
FD = OpenForkPipe( Handle );
|
FD = OpenForkPipe( Handle );
|
||||||
@@ -1064,16 +1143,14 @@ int CSelectableCore::Open( THandle * Handle )
|
|||||||
FD = -1;
|
FD = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear timer
|
// Set timer (for re-open or auto-close)
|
||||||
if ((Handle->State == csOpen) || (Handle->State == csWaitingtoOpen)) {
|
SetStartTime( &Handle->LastAction );
|
||||||
ClearStartTime( &Handle->ReopenStart );
|
|
||||||
}
|
|
||||||
return FD;
|
return FD;
|
||||||
};
|
};
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Delete socket
|
// Delete socket
|
||||||
bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
bool CSelectableCore::Close( THandle * Handle, bool QuickReopen )
|
||||||
{
|
{
|
||||||
bool Fail;
|
bool Fail;
|
||||||
THandle * ChildHandle = NULL;
|
THandle * ChildHandle = NULL;
|
||||||
@@ -1084,7 +1161,7 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Close Children
|
// Close Children
|
||||||
if (CloseChildren && (Handle->Type == ctServer))
|
if (Handle->Type == ctServer)
|
||||||
{
|
{
|
||||||
ChildHandle = FirstHandle;
|
ChildHandle = FirstHandle;
|
||||||
while (ChildHandle)
|
while (ChildHandle)
|
||||||
@@ -1093,7 +1170,7 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
|||||||
{
|
{
|
||||||
// Close and remove handle
|
// Close and remove handle
|
||||||
NextHandle = ChildHandle->Next;
|
NextHandle = ChildHandle->Next;
|
||||||
Close( ChildHandle );
|
Close( ChildHandle, false );
|
||||||
ChildHandle = NextHandle;
|
ChildHandle = NextHandle;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1108,15 +1185,23 @@ bool CSelectableCore::Close( THandle * Handle, bool CloseChildren )
|
|||||||
Fail = (close( Handle->FD ))? true : false;
|
Fail = (close( Handle->FD ))? true : false;
|
||||||
ChangeState( Handle, ((Fail)? csFailed : csClosed) );
|
ChangeState( Handle, ((Fail)? csFailed : csClosed) );
|
||||||
|
|
||||||
// Start re-open timer
|
// Start timer (for re-open)
|
||||||
SetStartTime( &(Handle->ReopenStart) );
|
if (QuickReopen)
|
||||||
|
ClearStartTime( &(Handle->LastAction) );
|
||||||
|
else
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
|
|
||||||
// Show action
|
// Show action
|
||||||
switch (Handle->Type)
|
switch (Handle->Type)
|
||||||
{
|
{
|
||||||
case ctPort:
|
case ctSerial:
|
||||||
// Log Event
|
// Log Event
|
||||||
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Serial Port %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ctLinePrinter:
|
||||||
|
// Log Event
|
||||||
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Printer Port %s [%s]", Name, Handle->Name, ((Fail)? "failed" : "closed"), Handle->Path );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ctForkPipe:
|
case ctForkPipe:
|
||||||
@@ -1176,6 +1261,8 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
if (ClientFD == -1) {
|
if (ClientFD == -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Reset Timer
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
|
|
||||||
// Add to Select Lists
|
// Add to Select Lists
|
||||||
if (Selector) {
|
if (Selector) {
|
||||||
@@ -1193,17 +1280,24 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctClient) {
|
||||||
OpenClientSocket( Handle );
|
OpenClientSocket( Handle );
|
||||||
}
|
}
|
||||||
|
// Reset Timer (for auto-close)
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if anything to read
|
// Check if anything to read
|
||||||
ioctl( Handle->FD, FIONREAD, &BytesWaiting );
|
ioctl( Handle->FD, FIONREAD, &BytesWaiting );
|
||||||
|
|
||||||
// EOF from server
|
// Error or EOF from server
|
||||||
if (BytesWaiting < 1)
|
if (BytesWaiting < 1)
|
||||||
{
|
{
|
||||||
|
// Log if there is an error
|
||||||
|
if (Log && (BytesWaiting < 1))
|
||||||
|
Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Error: [%d] $s", Name, Handle->Name, errno, strerror(errno) );
|
||||||
|
|
||||||
// Close Handle
|
// Close Handle
|
||||||
Close( Handle );
|
Close( Handle, false );
|
||||||
|
|
||||||
// Destroy Client
|
// Destroy Client
|
||||||
if (Handle->Type == ctRemoteClient) {
|
if (Handle->Type == ctRemoteClient) {
|
||||||
@@ -1212,24 +1306,36 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Handle->Type == ctPort)
|
else if (Handle->Type == ctSerial)
|
||||||
{
|
{
|
||||||
// Check if anything to read
|
// Check if anything to read
|
||||||
ioctl( Handle->FD, FIONREAD, &BytesWaiting );
|
ioctl( Handle->FD, FIONREAD, &BytesWaiting );
|
||||||
|
|
||||||
// EOF from port
|
// Error on port
|
||||||
if (BytesWaiting < 1)
|
if (BytesWaiting < 0)
|
||||||
{
|
{
|
||||||
// Close Handle
|
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Error: [%d] $s", Name, Handle->Name, errno, strerror(errno) );
|
||||||
Close( Handle );
|
|
||||||
|
|
||||||
// Destroy Port
|
// Close Handle
|
||||||
if (Handle->Type == ctRemoteClient) {
|
Close( Handle, false );
|
||||||
RemoveHandle( Handle );
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (Handle->Type == ctLinePrinter)
|
||||||
|
{
|
||||||
|
// // Check if anything to read
|
||||||
|
// ioctl( Handle->FD, FIONREAD, &BytesWaiting ); <-- Not valid ioctl for lp port
|
||||||
|
//
|
||||||
|
// // Error on port
|
||||||
|
// if (BytesWaiting < 0)
|
||||||
|
// {
|
||||||
|
// if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Error: [%d] $s", Name, Handle->Name, errno, strerror(errno) );
|
||||||
|
//
|
||||||
|
// // Close Handle
|
||||||
|
// Close( Handle, false );
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
if (Handle->State != csOpen) {
|
if (Handle->State != csOpen) {
|
||||||
@@ -1240,7 +1346,7 @@ bool CSelectableCore::Read( THandle * Handle )
|
|||||||
if (Handle->InBuffer && (BytesRead = Handle->InBuffer->ReadFromFD( Handle->FD, BytesWaiting )))
|
if (Handle->InBuffer && (BytesRead = Handle->InBuffer->ReadFromFD( Handle->FD, BytesWaiting )))
|
||||||
{
|
{
|
||||||
// Process Buffer
|
// Process Buffer
|
||||||
ProcessBuffer( Handle, false );
|
ProcessInputBuffer( Handle, false );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
@@ -1269,13 +1375,10 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
// Must be opened manually
|
// Must be opened manually
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
|
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
||||||
{
|
{
|
||||||
// Complete opening process
|
// Attempt to re-open port
|
||||||
if (Open( Handle ) == -1) {
|
Open( Handle );
|
||||||
// Reset Timer
|
|
||||||
SetStartTime( &(Handle->ReopenStart) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1290,6 +1393,8 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
} else if (Handle->Type == ctClient) {
|
} else if (Handle->Type == ctClient) {
|
||||||
OpenClientSocket( Handle );
|
OpenClientSocket( Handle );
|
||||||
}
|
}
|
||||||
|
// Reset Timer (for auto-close)
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
|
|
||||||
// Remove from set for select write
|
// Remove from set for select write
|
||||||
if (Selector) {
|
if (Selector) {
|
||||||
@@ -1312,6 +1417,9 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
|
|
||||||
// Update Buffer
|
// Update Buffer
|
||||||
Handle->OutBuffer->Clear( BytesWritten );
|
Handle->OutBuffer->Clear( BytesWritten );
|
||||||
|
|
||||||
|
// Reset Timer
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Buffer emtpy
|
// Check if Buffer emtpy
|
||||||
@@ -1336,7 +1444,7 @@ bool CSelectableCore::Write( THandle * Handle )
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force )
|
bool CSelectableCore::ProcessInputBuffer( THandle * Handle, bool Force )
|
||||||
{
|
{
|
||||||
int Pos = 0;
|
int Pos = 0;
|
||||||
int Len = 0;
|
int Len = 0;
|
||||||
@@ -1481,7 +1589,7 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
|||||||
if (Handle->Channel && !strcasecmp( ChannelName, Handle->Channel->Name ))
|
if (Handle->Channel && !strcasecmp( ChannelName, Handle->Channel->Name ))
|
||||||
{
|
{
|
||||||
// Input to Handle
|
// Input to Handle
|
||||||
TempWritten = InputHandle( Handle, Data, Len );
|
TempWritten = OutputHandle( Handle, Data, Len );
|
||||||
BytesWritten = (TempWritten > BytesWritten)? TempWritten : BytesWritten;
|
BytesWritten = (TempWritten > BytesWritten)? TempWritten : BytesWritten;
|
||||||
HandleCount++;
|
HandleCount++;
|
||||||
}
|
}
|
||||||
@@ -1498,7 +1606,7 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len
|
|||||||
}
|
}
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
int CSelectableCore::OutputHandle( THandle * Handle, const char * Data, int Len )
|
||||||
{
|
{
|
||||||
THandle * ChildHandle = NULL;
|
THandle * ChildHandle = NULL;
|
||||||
int BytesWritten = 0;
|
int BytesWritten = 0;
|
||||||
@@ -1512,13 +1620,10 @@ int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
|||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Handle not Open (not auto-managed)", Name, Handle->Name );
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Handle not Open (not auto-managed)", Name, Handle->Name );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
|
else if (Timeout( Handle->LastAction, Handle->ReopenDelay ))
|
||||||
{
|
{
|
||||||
// Complete opening process
|
// Complete opening process
|
||||||
if (Open( Handle ) == -1) {
|
Open( Handle );
|
||||||
// Reset Timer
|
|
||||||
SetStartTime( &(Handle->ReopenStart) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if Handle is open
|
// Check if Handle is open
|
||||||
if (Handle->State == csWaitingtoOpen) {
|
if (Handle->State == csWaitingtoOpen) {
|
||||||
@@ -1533,7 +1638,7 @@ int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Retry (auto-managed) Handle re-open in %d ms", Name, Handle->Name,
|
if (Log) Log->Message( LogLevel, dlHigh, "%s: Handle '%s' - Input rejected, Retry (auto-managed) Handle re-open in %d ms", Name, Handle->Name,
|
||||||
TimeLeft( Handle->ReopenStart, Handle->ReopenDelay) );
|
TimeLeft( Handle->LastAction, Handle->ReopenDelay) );
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1565,11 +1670,14 @@ int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// Show event
|
||||||
|
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - OUT:", Name, ChildHandle->Name );
|
||||||
|
|
||||||
// Write directly to handle
|
// Write directly to handle
|
||||||
BytesWritten = WriteToFD( ChildHandle->FD, Data, Len, true );
|
BytesWritten = WriteToFD( ChildHandle->FD, Data, Len, true );
|
||||||
|
|
||||||
// Show event
|
// Reset Timer
|
||||||
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - OUT:", Name, ChildHandle->Name );
|
SetStartTime( &(Handle->LastAction) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Next
|
// Next
|
||||||
@@ -1598,7 +1706,11 @@ int CSelectableCore::InputHandle( THandle * Handle, const char * Data, int Len )
|
|||||||
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
if (Log) Log->Output( LogLevel, dlHigh, LogOutput, Data, Len, "%s: Handle '%s' - OUT:", Name, Handle->Name );
|
||||||
|
|
||||||
// Write directly to handle
|
// Write directly to handle
|
||||||
BytesWritten = WriteToFD( Handle->FD, Data, Len, true );
|
if ((BytesWritten = WriteToFD( Handle->FD, Data, Len, true )))
|
||||||
|
{
|
||||||
|
// Reset Timer
|
||||||
|
SetStartTime( &(Handle->LastAction) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1617,15 +1729,9 @@ bool CSelectableCore::Process()
|
|||||||
// Auto manage handles
|
// Auto manage handles
|
||||||
if ((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent)
|
if ((Handle->State != csOpen) && Handle->AutoManage && Handle->Persistent)
|
||||||
{
|
{
|
||||||
// Check duration since last PortIn
|
// Try to re-open port after delay
|
||||||
if (Timeout( Handle->ReopenStart, Handle->ReopenDelay ))
|
if (Timeout( Handle->LastAction, Handle->ReopenDelay )) {
|
||||||
{
|
Open( Handle );
|
||||||
// Complete opening process
|
|
||||||
if (Open( Handle ) == -1)
|
|
||||||
{
|
|
||||||
// Reset Timer
|
|
||||||
SetStartTime( &(Handle->ReopenStart) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1636,12 +1742,22 @@ bool CSelectableCore::Process()
|
|||||||
if (Timeout( Handle->InStart, Handle->InTimeout ))
|
if (Timeout( Handle->InStart, Handle->InTimeout ))
|
||||||
{
|
{
|
||||||
// Process Input
|
// Process Input
|
||||||
ProcessBuffer( Handle, true );
|
ProcessInputBuffer( Handle, true );
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
ClearStartTime( &(Handle->InStart) );
|
ClearStartTime( &(Handle->InStart) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for auto close (but not on servers)
|
||||||
|
if ((Handle->State == csOpen) && (Handle->Type != ctServer) && Handle->AutoManage && !Handle->Persistent)
|
||||||
|
{
|
||||||
|
// Close port after timeout
|
||||||
|
if (Timeout( Handle->LastAction, Handle->CloseTimeout )) {
|
||||||
|
Close( Handle, true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Handle = Handle->Next;
|
Handle = Handle->Next;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1649,15 +1765,16 @@ bool CSelectableCore::Process()
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Set serial port configuration parameters
|
// Set serial port configuration parameters
|
||||||
bool CSelectableCore::SetSerialPortConfig( THandle * Handle )
|
bool CSelectableCore::WriteSerialConfig( THandle * Handle )
|
||||||
{
|
{
|
||||||
struct termios newtio;
|
struct termios newtio;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
speed_t baud = 0;
|
speed_t inbaud = 0;
|
||||||
|
speed_t outbaud = 0;
|
||||||
int mcs = 0;
|
int mcs = 0;
|
||||||
|
|
||||||
// Get Handle
|
// Get Handle
|
||||||
if (!Handle || (Handle->Type != ctPort)) {
|
if (!Handle || (Handle->Type != ctSerial)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1673,40 +1790,70 @@ bool CSelectableCore::SetSerialPortConfig( THandle * Handle )
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Process the baud rate
|
// Process the baud rate
|
||||||
switch (Handle->Baudrate)
|
switch (Handle->InBaudrate)
|
||||||
{
|
{
|
||||||
case 921600: baud = B921600; break;
|
case 921600: inbaud = B921600; break;
|
||||||
case 576000: baud = B576000; break;
|
case 576000: inbaud = B576000; break;
|
||||||
case 460800: baud = B460800; break;
|
case 460800: inbaud = B460800; break;
|
||||||
case 230400: baud = B230400; break;
|
case 230400: inbaud = B230400; break;
|
||||||
//case 128000: _baud = B128000; break;
|
//case 128000: _inbaud = B128000; break;
|
||||||
case 115200: baud = B115200; break;
|
case 115200: inbaud = B115200; break;
|
||||||
//case 76800: _baud = B76800; break;
|
//case 76800: _inbaud = B76800; break;
|
||||||
case 57600: baud = B57600; break;
|
case 57600: inbaud = B57600; break;
|
||||||
case 38400: baud = B38400; break;
|
case 38400: inbaud = B38400; break;
|
||||||
//case 28800: _baud = B28800; break;
|
//case 28800: _inbaud = B28800; break;
|
||||||
case 19200: baud = B19200; break;
|
case 19200: inbaud = B19200; break;
|
||||||
//case 14400: _baud = B14400; break;
|
//case 14400: _inbaud = B14400; break;
|
||||||
case 9600: baud = B9600; break;
|
case 9600: inbaud = B9600; break;
|
||||||
case 4800: baud = B4800; break;
|
case 4800: inbaud = B4800; break;
|
||||||
case 2400: baud = B2400; break;
|
case 2400: inbaud = B2400; break;
|
||||||
case 1800: baud = B1800; break;
|
case 1800: inbaud = B1800; break;
|
||||||
case 1200: baud = B1200; break;
|
case 1200: inbaud = B1200; break;
|
||||||
case 600: baud = B600; break;
|
case 600: inbaud = B600; break;
|
||||||
case 300: baud = B300; break;
|
case 300: inbaud = B300; break;
|
||||||
case 200: baud = B200; break;
|
case 200: inbaud = B200; break;
|
||||||
case 150: baud = B150; break;
|
case 150: inbaud = B150; break;
|
||||||
case 134: baud = B134; break;
|
case 134: inbaud = B134; break;
|
||||||
case 110: baud = B110; break;
|
case 110: inbaud = B110; break;
|
||||||
case 75: baud = B75; break;
|
case 75: inbaud = B75; break;
|
||||||
case 50: baud = B50; break;
|
case 50: inbaud = B50; break;
|
||||||
|
|
||||||
default: baud = B9600; break;
|
default: inbaud = B9600; break;
|
||||||
|
}
|
||||||
|
switch (Handle->OutBaudrate)
|
||||||
|
{
|
||||||
|
case 921600: outbaud = B921600; break;
|
||||||
|
case 576000: outbaud = B576000; break;
|
||||||
|
case 460800: outbaud = B460800; break;
|
||||||
|
case 230400: outbaud = B230400; break;
|
||||||
|
//case 128000: _outbaud = B128000; break;
|
||||||
|
case 115200: outbaud = B115200; break;
|
||||||
|
//case 76800: _outbaud = B76800; break;
|
||||||
|
case 57600: outbaud = B57600; break;
|
||||||
|
case 38400: outbaud = B38400; break;
|
||||||
|
//case 28800: _outbaud = B28800; break;
|
||||||
|
case 19200: outbaud = B19200; break;
|
||||||
|
//case 14400: _outbaud = B14400; break;
|
||||||
|
case 9600: outbaud = B9600; break;
|
||||||
|
case 4800: outbaud = B4800; break;
|
||||||
|
case 2400: outbaud = B2400; break;
|
||||||
|
case 1800: outbaud = B1800; break;
|
||||||
|
case 1200: outbaud = B1200; break;
|
||||||
|
case 600: outbaud = B600; break;
|
||||||
|
case 300: outbaud = B300; break;
|
||||||
|
case 200: outbaud = B200; break;
|
||||||
|
case 150: outbaud = B150; break;
|
||||||
|
case 134: outbaud = B134; break;
|
||||||
|
case 110: outbaud = B110; break;
|
||||||
|
case 75: outbaud = B75; break;
|
||||||
|
case 50: outbaud = B50; break;
|
||||||
|
|
||||||
|
default: outbaud = B9600; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Baud rate
|
// Set Baud rate
|
||||||
cfsetospeed( &newtio, (speed_t)baud );
|
cfsetispeed( &newtio, (speed_t)inbaud );
|
||||||
cfsetispeed( &newtio, (speed_t)baud );
|
cfsetospeed( &newtio, (speed_t)outbaud );
|
||||||
|
|
||||||
// Generate Mark/Space parity
|
// Generate Mark/Space parity
|
||||||
if ((Handle->DataBits == 7) && ((Handle->Parity == MARK_PARITY) || (Handle->Parity == SPACE_PARITY)))
|
if ((Handle->DataBits == 7) && ((Handle->Parity == MARK_PARITY) || (Handle->Parity == SPACE_PARITY)))
|
||||||
@@ -1795,44 +1942,69 @@ bool CSelectableCore::SetSerialPortConfig( THandle * Handle )
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Get serial port configuration parameters
|
// Get serial port configuration parameters
|
||||||
bool CSelectableCore::GetSerialPortConfig( THandle * Handle )
|
bool CSelectableCore::ReadSerialConfig( THandle * Handle )
|
||||||
{
|
{
|
||||||
int speed;
|
int inspeed;
|
||||||
|
int outspeed;
|
||||||
unsigned char bits;
|
unsigned char bits;
|
||||||
struct termios getTermios;
|
struct termios getTermios;
|
||||||
|
|
||||||
// Validate handle
|
// Validate handle
|
||||||
if (!Handle || (Handle->Type != ctPort)) {
|
if (!Handle || (Handle->Type != ctSerial)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get port setup
|
// Get port setup
|
||||||
tcgetattr( Handle->FD, &getTermios );
|
tcgetattr( Handle->FD, &getTermios );
|
||||||
|
inspeed = cfgetispeed( &getTermios );
|
||||||
|
outspeed = cfgetospeed( &getTermios );
|
||||||
|
|
||||||
// Get Baud Rate
|
// Get Baud Rate
|
||||||
speed = cfgetispeed( &getTermios );
|
switch (inspeed)
|
||||||
switch (speed)
|
|
||||||
{
|
{
|
||||||
case B0 : Handle->Baudrate = 0; break;
|
case B0 : Handle->InBaudrate = 0; break;
|
||||||
case B50 : Handle->Baudrate = 50; break;
|
case B50 : Handle->InBaudrate = 50; break;
|
||||||
case B75 : Handle->Baudrate = 75; break;
|
case B75 : Handle->InBaudrate = 75; break;
|
||||||
case B110 : Handle->Baudrate = 110; break;
|
case B110 : Handle->InBaudrate = 110; break;
|
||||||
case B134 : Handle->Baudrate = 134; break;
|
case B134 : Handle->InBaudrate = 134; break;
|
||||||
case B150 : Handle->Baudrate = 150; break;
|
case B150 : Handle->InBaudrate = 150; break;
|
||||||
case B200 : Handle->Baudrate = 200; break;
|
case B200 : Handle->InBaudrate = 200; break;
|
||||||
case B300 : Handle->Baudrate = 300; break;
|
case B300 : Handle->InBaudrate = 300; break;
|
||||||
case B600 : Handle->Baudrate = 600; break;
|
case B600 : Handle->InBaudrate = 600; break;
|
||||||
case B1200 : Handle->Baudrate = 1200; break;
|
case B1200 : Handle->InBaudrate = 1200; break;
|
||||||
case B1800: Handle->Baudrate = 1800; break;
|
case B1800: Handle->InBaudrate = 1800; break;
|
||||||
case B2400: Handle->Baudrate = 2400; break;
|
case B2400: Handle->InBaudrate = 2400; break;
|
||||||
case B4800: Handle->Baudrate = 4800; break;
|
case B4800: Handle->InBaudrate = 4800; break;
|
||||||
case B9600: Handle->Baudrate = 9600; break;
|
case B9600: Handle->InBaudrate = 9600; break;
|
||||||
case B19200: Handle->Baudrate = 19200; break;
|
case B19200: Handle->InBaudrate = 19200; break;
|
||||||
case B38400: Handle->Baudrate = 38400; break;
|
case B38400: Handle->InBaudrate = 38400; break;
|
||||||
case B57600: Handle->Baudrate = 57600; break;
|
case B57600: Handle->InBaudrate = 57600; break;
|
||||||
case B115200: Handle->Baudrate = 115200; break;
|
case B115200: Handle->InBaudrate = 115200; break;
|
||||||
case B230400: Handle->Baudrate = 230400; break;
|
case B230400: Handle->InBaudrate = 230400; break;
|
||||||
default: Handle->Baudrate = 999; break;
|
default: Handle->InBaudrate = 0; break;
|
||||||
|
}
|
||||||
|
switch (outspeed)
|
||||||
|
{
|
||||||
|
case B0 : Handle->OutBaudrate = 0; break;
|
||||||
|
case B50 : Handle->OutBaudrate = 50; break;
|
||||||
|
case B75 : Handle->OutBaudrate = 75; break;
|
||||||
|
case B110 : Handle->OutBaudrate = 110; break;
|
||||||
|
case B134 : Handle->OutBaudrate = 134; break;
|
||||||
|
case B150 : Handle->OutBaudrate = 150; break;
|
||||||
|
case B200 : Handle->OutBaudrate = 200; break;
|
||||||
|
case B300 : Handle->OutBaudrate = 300; break;
|
||||||
|
case B600 : Handle->OutBaudrate = 600; break;
|
||||||
|
case B1200 : Handle->OutBaudrate = 1200; break;
|
||||||
|
case B1800: Handle->OutBaudrate = 1800; break;
|
||||||
|
case B2400: Handle->OutBaudrate = 2400; break;
|
||||||
|
case B4800: Handle->OutBaudrate = 4800; break;
|
||||||
|
case B9600: Handle->OutBaudrate = 9600; break;
|
||||||
|
case B19200: Handle->OutBaudrate = 19200; break;
|
||||||
|
case B38400: Handle->OutBaudrate = 38400; break;
|
||||||
|
case B57600: Handle->OutBaudrate = 57600; break;
|
||||||
|
case B115200: Handle->OutBaudrate = 115200; break;
|
||||||
|
case B230400: Handle->OutBaudrate = 230400; break;
|
||||||
|
default: Handle->OutBaudrate = 0 ; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Data Bits
|
// Get Data Bits
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// Types required for connections
|
// Types required for connections
|
||||||
typedef enum { ctNone = 0, ctPort = 1, ctForkPipe = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5 } EConnectType;
|
typedef enum { ctNone = 0, ctSerial = 1, ctLinePrinter = 2, ctServer = 3, ctRemoteClient = 4, ctClient = 5, ctForkPipe = 6 } EConnectType;
|
||||||
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
|
const char ConnectTypeName[][15] = { "None", "Port", "ForkPipe", "Server", "RemoteClient", "Client" };
|
||||||
|
|
||||||
typedef enum { csNone = 0, csWaitingtoOpen = 1, csOpen = 2, csDataWaiting = 3, csClosed = 4, csFailed = 5 } EConnectState;
|
typedef enum { csNone = 0, csWaitingtoOpen = 1, csOpen = 2, csDataWaiting = 3, csClosed = 4, csFailed = 5 } EConnectState;
|
||||||
@@ -78,6 +78,9 @@ struct SHandle {
|
|||||||
|
|
||||||
bool AutoManage;
|
bool AutoManage;
|
||||||
bool Persistent;
|
bool Persistent;
|
||||||
|
timeval LastAction;
|
||||||
|
long ReopenDelay; // millisecs
|
||||||
|
long CloseTimeout; // millisecs
|
||||||
|
|
||||||
// Callback functions
|
// Callback functions
|
||||||
FHandleCallback StateCallback[ 6 ];
|
FHandleCallback StateCallback[ 6 ];
|
||||||
@@ -95,7 +98,8 @@ struct SHandle {
|
|||||||
bool KeepAlive; // Socket keep alive
|
bool KeepAlive; // Socket keep alive
|
||||||
|
|
||||||
bool SerialConfig;
|
bool SerialConfig;
|
||||||
int Baudrate;
|
int InBaudrate;
|
||||||
|
int OutBaudrate;
|
||||||
short DataBits;
|
short DataBits;
|
||||||
short Parity;
|
short Parity;
|
||||||
short StopBits;
|
short StopBits;
|
||||||
@@ -114,10 +118,6 @@ struct SHandle {
|
|||||||
timeval InStart;
|
timeval InStart;
|
||||||
long InTimeout; // millisecs
|
long InTimeout; // millisecs
|
||||||
|
|
||||||
// Reopen Timer
|
|
||||||
timeval ReopenStart;
|
|
||||||
long ReopenDelay; // millisecs
|
|
||||||
|
|
||||||
// List / Tree
|
// List / Tree
|
||||||
TChannel * Channel;
|
TChannel * Channel;
|
||||||
THandle * Parent;
|
THandle * Parent;
|
||||||
@@ -199,23 +199,27 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Port Operations
|
// Port Operations
|
||||||
virtual int OpenPort( THandle * Handle );
|
int OpenSerialPort( THandle * Handle );
|
||||||
|
bool WriteSerialConfig( THandle * Handle );
|
||||||
|
bool ReadSerialConfig( THandle * Handle );
|
||||||
|
|
||||||
|
int OpenLinePrinterPort( THandle * Handle );
|
||||||
|
|
||||||
// ForkPipe Operations
|
// ForkPipe Operations
|
||||||
virtual int OpenForkPipe( THandle * Handle );
|
int OpenForkPipe( THandle * Handle );
|
||||||
|
|
||||||
// Socket Operations
|
// Socket Operations
|
||||||
bool ResolveAddress( THandle * Handle );
|
bool ResolveAddress( THandle * Handle );
|
||||||
virtual int OpenServerSocket( THandle * Handle );
|
int OpenServerSocket( THandle * Handle );
|
||||||
virtual int OpenRemoteClientSocket( THandle * Handle );
|
int OpenRemoteClientSocket( THandle * Handle );
|
||||||
virtual int OpenClientSocket( THandle * Handle );
|
int OpenClientSocket( THandle * Handle );
|
||||||
|
|
||||||
// Mutual Operations
|
// Mutual Operations
|
||||||
int ReadFromFD( int FD, char * Data, int MaxLen );
|
int ReadFromFD( int FD, char * Data, int MaxLen );
|
||||||
int WriteToFD( int FD, const char * Data, int Len, bool Force );
|
int WriteToFD( int FD, const char * Data, int Len, bool Force );
|
||||||
|
|
||||||
// Buffer operations
|
// Buffer operations
|
||||||
virtual bool ProcessBuffer( THandle * Handle, bool Force );
|
virtual bool ProcessInputBuffer( THandle * Handle, bool Force );
|
||||||
|
|
||||||
// Specific operations
|
// Specific operations
|
||||||
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
|
bool BuildArgs( const char * ExecPath, int &Count, char * Args[] );
|
||||||
@@ -253,28 +257,29 @@ public:
|
|||||||
// General port parameters
|
// General port parameters
|
||||||
THandle * CreateHandle( const char * HandleName, bool CreateChannel );
|
THandle * CreateHandle( const char * HandleName, bool CreateChannel );
|
||||||
bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback );
|
bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback );
|
||||||
bool SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenTime = 0 );
|
bool SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenDelay = 0, int CloseTimeout = 0 );
|
||||||
bool SetInBuffer( THandle * Handle, int InBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
|
bool SetInBuffer( THandle * Handle, int InBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
|
||||||
bool SetOutBuffer( THandle * Handle, int OutBufSize );
|
bool SetOutBuffer( THandle * Handle, int OutBufSize );
|
||||||
|
|
||||||
// Specific port parameters
|
// Specific port parameters
|
||||||
bool SetPortHandle( THandle * Handle, const char * FileName );
|
bool SetSerialHandle( THandle * Handle, const char * FileName );
|
||||||
bool SetPortHandleSerial( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
|
bool SetSerialHandleConfig( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
|
||||||
|
bool SetLinePrinterHandle( THandle * Handle, const char * FileName );
|
||||||
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
|
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
|
||||||
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive );
|
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive );
|
||||||
bool ClearHandle( THandle * Handle );
|
bool ClearHandle( THandle * Handle );
|
||||||
|
|
||||||
// FD Operations
|
// FD Operations
|
||||||
virtual int Open( THandle * Handle );
|
virtual int Open( THandle * Handle );
|
||||||
virtual bool Close( THandle * Handle, bool CloseChildren = false );
|
virtual bool Close( THandle * Handle, bool QuickReopen );
|
||||||
virtual bool Read( THandle * Handle );
|
virtual bool Read( THandle * Handle );
|
||||||
virtual bool Write( THandle * Handle );
|
virtual bool Write( THandle * Handle );
|
||||||
|
|
||||||
// FD operations
|
// FD operations
|
||||||
inline virtual int Open( const char * HandleName ) { return (Open( GetHandle( HandleName ))); };
|
inline virtual int Open( const char * HandleName ) { return (Open( GetHandle( HandleName ))); };
|
||||||
|
|
||||||
inline virtual bool Close( const char * HandleName, bool CloseChildren = false ) { return (Close( GetHandle( HandleName ), CloseChildren )); };
|
inline virtual bool Close( const char * HandleName, bool QuickReopen ) { return (Close( GetHandle( HandleName ), QuickReopen )); };
|
||||||
inline virtual bool Close( int FD, bool CloseChildren = false ) { return (Close( GetHandle( FD ), CloseChildren )); };
|
inline virtual bool Close( int FD, bool QuickReopen ) { return (Close( GetHandle( FD ), QuickReopen )); };
|
||||||
|
|
||||||
inline virtual bool Read( const char * HandleName ) { return (Read( GetHandle( HandleName ))); };
|
inline virtual bool Read( const char * HandleName ) { return (Read( GetHandle( HandleName ))); };
|
||||||
inline virtual bool Read( int FD ) { return (Read( GetHandle( FD ))); };
|
inline virtual bool Read( int FD ) { return (Read( GetHandle( FD ))); };
|
||||||
@@ -282,9 +287,6 @@ public:
|
|||||||
inline virtual bool Write( const char * HandleName ) { return (Write( GetHandle( HandleName ))); };
|
inline virtual bool Write( const char * HandleName ) { return (Write( GetHandle( HandleName ))); };
|
||||||
inline virtual bool Write( int FD ) { return (Write( GetHandle( FD ))); };
|
inline virtual bool Write( int FD ) { return (Write( GetHandle( FD ))); };
|
||||||
|
|
||||||
bool SetSerialPortConfig( THandle * Handle );
|
|
||||||
bool GetSerialPortConfig( THandle * Handle );
|
|
||||||
|
|
||||||
// Info
|
// Info
|
||||||
inline EConnectType GetType( const char * HandleName ) {
|
inline EConnectType GetType( const char * HandleName ) {
|
||||||
THandle * Handle = GetHandle( HandleName );
|
THandle * Handle = GetHandle( HandleName );
|
||||||
@@ -297,7 +299,7 @@ public:
|
|||||||
|
|
||||||
// Function Interface
|
// Function Interface
|
||||||
virtual int Input( const char * ChannelName, const char * Buffer, int BufLen = -1 );
|
virtual int Input( const char * ChannelName, const char * Buffer, int BufLen = -1 );
|
||||||
int InputHandle( THandle * Handle, const char * Data, int Len );
|
int OutputHandle( THandle * Handle, const char * Data, int Len );
|
||||||
virtual bool Process();
|
virtual bool Process();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ bool CWatchdogCore::LoadConfigData()
|
|||||||
// Call Previous load config
|
// Call Previous load config
|
||||||
CSelectableCore::LoadConfigData();
|
CSelectableCore::LoadConfigData();
|
||||||
|
|
||||||
// Set Auto Mange
|
// Set specific parameters
|
||||||
SetInterval( DataTree->GetInt( ConfigMember, "Parameters/PingInterval", 500, true ));
|
SetInterval( DataTree->GetInt( ConfigMember, "Parameters/PingInterval", 500, true ));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -83,7 +83,7 @@ bool CWatchdogCore::Process()
|
|||||||
if (Timeout( PingTimer, PingInterval ))
|
if (Timeout( PingTimer, PingInterval ))
|
||||||
{
|
{
|
||||||
// Send command
|
// Send command
|
||||||
InputHandle( Ping, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
OutputHandle( Ping, Protocol->GetCommandStr(), Protocol->GetCommandLen() );
|
||||||
|
|
||||||
// Reset timer
|
// Reset timer
|
||||||
SetStartTime( &PingTimer );
|
SetStartTime( &PingTimer );
|
||||||
|
|||||||
Reference in New Issue
Block a user