Important Update:

- SelectableCore:
  - Move Serial port config params to Port/SerialConfig
  - Only configure serial port if config setting provided in JSON file
  - Add SerialConfig param to THandle struct, set when serial config given
  - Rename method: ConfigureSerialPort() -> SetSerialPortConfig()
  - New method: GetSerialPortConfig() read serial port config into Handle
  - Split method SetPortHandle():
    - SetPortHandle() - only set port type and address
    - SetPortHandleSerial() - only set serial port parameters
This commit is contained in:
Charl Wentzel
2017-12-01 10:56:48 +02:00
parent 15e6d5a645
commit 3eaf0853fb
2 changed files with 154 additions and 57 deletions

View File

@@ -66,6 +66,7 @@ CSelectableCore::~CSelectableCore()
bool CSelectableCore::LoadConfigData() bool CSelectableCore::LoadConfigData()
{ {
TDataMember * TempMember; TDataMember * TempMember;
TDataMember * SerialConfig;
THandle * Handle; THandle * Handle;
char * Type; char * Type;
char * Name; char * Name;
@@ -100,32 +101,35 @@ bool CSelectableCore::LoadConfigData()
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 );
ParityText = (char*)DataTree->GetStr( TempMember, "Port/Parity", "none", true ); // Update configuration if specified
if (!strcasecmp( ParityText, "none" )) if ((SerialConfig = DataTree->GetMember( TempMember, "Port/SerialConfig", false )))
Parity = NO_PARITY; {
else if (!strcasecmp( ParityText, "odd" )) ParityText = (char*)DataTree->GetStr( SerialConfig, "Parity", "none", true );
Parity = ODD_PARITY; if (!strcasecmp( ParityText, "none" ))
else if (!strcasecmp( ParityText, "even" )) Parity = NO_PARITY;
Parity = EVEN_PARITY; else if (!strcasecmp( ParityText, "odd" ))
else if (!strcasecmp( ParityText, "mark" )) Parity = ODD_PARITY;
Parity = MARK_PARITY; else if (!strcasecmp( ParityText, "even" ))
Parity = EVEN_PARITY;
else if (!strcasecmp( ParityText, "mark" ))
Parity = MARK_PARITY;
FlowCtrlText = (char*)DataTree->GetStr( TempMember, "Port/FlowCtrl", "none", true ); FlowCtrlText = (char*)DataTree->GetStr( SerialConfig, "FlowCtrl", "none", true );
if (!strcasecmp( FlowCtrlText, "none" )) if (!strcasecmp( FlowCtrlText, "none" ))
FlowCtrl = NO_FLOWCTRL; FlowCtrl = NO_FLOWCTRL;
else if (!strcasecmp( FlowCtrlText, "hardware" )) else if (!strcasecmp( FlowCtrlText, "hardware" ))
FlowCtrl = HW_FLOWCTRL; FlowCtrl = HW_FLOWCTRL;
else if (!strcasecmp( FlowCtrlText, "software" )) else if (!strcasecmp( FlowCtrlText, "software" ))
FlowCtrl = SW_FLOWCTRL; FlowCtrl = SW_FLOWCTRL;
SetPortHandle( Handle, Address, Handle->SerialConfig = true;
DataTree->GetInt( TempMember, "Port/BaudRate", 19200, true ), SetPortHandleSerial( Handle, DataTree->GetInt( SerialConfig, "BaudRate", 19200, true ),
DataTree->GetInt( TempMember, "Port/DataBits", 8, true ), DataTree->GetInt( SerialConfig, "DataBits", 8, true ),
Parity, Parity, DataTree->GetInt( SerialConfig, "StopBits", 1, true ),
DataTree->GetInt( TempMember, "Port/StopBits", 1, true ), FlowCtrl, DataTree->GetInt( SerialConfig, "DataWait", 0, true ));
FlowCtrl, }
DataTree->GetInt( TempMember, "Port/DataWait", 0, true));
} }
else if (!strcasecmp( Type, "TCPserver" )) else if (!strcasecmp( Type, "TCPserver" ))
{ {
@@ -275,8 +279,7 @@ bool CSelectableCore::DestroyHandle( THandle * Handle )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName, bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait )
{ {
// Validate // Validate
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) { if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) {
@@ -295,6 +298,19 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName,
Handle->Path = (char*)malloc( strlen(FileName)+1 ); Handle->Path = (char*)malloc( strlen(FileName)+1 );
strcpy( Handle->Path, FileName ); 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::SetPortHandleSerial( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait )
{
// Validate
if (!Handle || (Handle->Type != ctPort)) {
return false;
}
Handle->Baudrate = Baudrate; Handle->Baudrate = Baudrate;
Handle->DataBits = DataBits; Handle->DataBits = DataBits;
Handle->Parity = Parity; Handle->Parity = Parity;
@@ -302,8 +318,6 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName,
Handle->FlowCtrl = FlowCtrl; Handle->FlowCtrl = FlowCtrl;
Handle->DataWait = DataWait; Handle->DataWait = DataWait;
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as Port [%s]", Name, Handle->Name, FileName );
return true; return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -511,7 +525,12 @@ int CSelectableCore::OpenPort( THandle * Handle )
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' - Port opened [%s]", Name, Handle->Name, Handle->Path );
// Update port configuration // Update port configuration
ConfigureSerialPort( Handle ); if (Handle->SerialConfig)
SetSerialPortConfig( Handle );
else
GetSerialPortConfig( 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,
Handle->Baudrate, Handle->DataBits, Handle->Parity, Handle->StopBits, Handle->FlowCtrl );
// Add to Select Lists // Add to Select Lists
if (Selector) { if (Selector) {
@@ -1630,11 +1649,11 @@ bool CSelectableCore::Process()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Set serial port configuration parameters // Set serial port configuration parameters
bool CSelectableCore::ConfigureSerialPort( THandle * Handle ) bool CSelectableCore::SetSerialPortConfig( THandle * Handle )
{ {
struct termios newtio; struct termios newtio;
int flags = 0; int flags = 0;
speed_t _baud = 0; speed_t baud = 0;
int mcs = 0; int mcs = 0;
// Get Handle // Get Handle
@@ -1656,38 +1675,38 @@ bool CSelectableCore::ConfigureSerialPort( THandle * Handle )
// Process the baud rate // Process the baud rate
switch (Handle->Baudrate) switch (Handle->Baudrate)
{ {
case 921600: _baud = B921600; break; case 921600: baud = B921600; break;
case 576000: _baud = B576000; break; case 576000: baud = B576000; break;
case 460800: _baud = B460800; break; case 460800: baud = B460800; break;
case 230400: _baud = B230400; break; case 230400: baud = B230400; break;
//case 128000: _baud = B128000; break; //case 128000: _baud = B128000; break;
case 115200: _baud = B115200; break; case 115200: baud = B115200; break;
//case 76800: _baud = B76800; break; //case 76800: _baud = B76800; break;
case 57600: _baud = B57600; break; case 57600: baud = B57600; break;
case 38400: _baud = B38400; break; case 38400: baud = B38400; break;
//case 28800: _baud = B28800; break; //case 28800: _baud = B28800; break;
case 19200: _baud = B19200; break; case 19200: baud = B19200; break;
//case 14400: _baud = B14400; break; //case 14400: _baud = B14400; break;
case 9600: _baud = B9600; break; case 9600: baud = B9600; break;
case 4800: _baud = B4800; break; case 4800: baud = B4800; break;
case 2400: _baud = B2400; break; case 2400: baud = B2400; break;
case 1800: _baud = B1800; break; case 1800: baud = B1800; break;
case 1200: _baud = B1200; break; case 1200: baud = B1200; break;
case 600: _baud = B600; break; case 600: baud = B600; break;
case 300: _baud = B300; break; case 300: baud = B300; break;
case 200: _baud = B200; break; case 200: baud = B200; break;
case 150: _baud = B150; break; case 150: baud = B150; break;
case 134: _baud = B134; break; case 134: baud = B134; break;
case 110: _baud = B110; break; case 110: baud = B110; break;
case 75: _baud = B75; break; case 75: baud = B75; break;
case 50: _baud = B50; break; case 50: baud = B50; break;
default: _baud = B9600; break; default: baud = B9600; break;
} }
// Set Baud rate // Set Baud rate
cfsetospeed( &newtio, (speed_t)_baud ); cfsetospeed( &newtio, (speed_t)baud );
cfsetispeed( &newtio, (speed_t)_baud ); cfsetispeed( &newtio, (speed_t)baud );
// 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)))
@@ -1775,6 +1794,82 @@ bool CSelectableCore::ConfigureSerialPort( THandle * Handle )
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Get serial port configuration parameters
bool CSelectableCore::GetSerialPortConfig( THandle * Handle )
{
int speed;
unsigned char bits;
struct termios getTermios;
// Validate handle
if (!Handle || (Handle->Type != ctPort)) {
return false;
}
// Get port setup
tcgetattr( Handle->FD, &getTermios );
// Get Baud Rate
speed = cfgetispeed( &getTermios );
switch (speed)
{
case B0 : Handle->Baudrate = 0; break;
case B50 : Handle->Baudrate = 50; break;
case B75 : Handle->Baudrate = 75; break;
case B110 : Handle->Baudrate = 110; break;
case B134 : Handle->Baudrate = 134; break;
case B150 : Handle->Baudrate = 150; break;
case B200 : Handle->Baudrate = 200; break;
case B300 : Handle->Baudrate = 300; break;
case B600 : Handle->Baudrate = 600; break;
case B1200 : Handle->Baudrate = 1200; break;
case B1800: Handle->Baudrate = 1800; break;
case B2400: Handle->Baudrate = 2400; break;
case B4800: Handle->Baudrate = 4800; break;
case B9600: Handle->Baudrate = 9600; break;
case B19200: Handle->Baudrate = 19200; break;
case B38400: Handle->Baudrate = 38400; break;
case B57600: Handle->Baudrate = 57600; break;
case B115200: Handle->Baudrate = 115200; break;
case B230400: Handle->Baudrate = 230400; break;
default: Handle->Baudrate = 999; break;
}
// Get Data Bits
bits = getTermios.c_cflag & CSIZE;
switch (bits)
{
case CS5: Handle->DataBits = 5; break;
case CS6: Handle->DataBits = 6; break;
case CS7: Handle->DataBits = 7; break;
case CS8: Handle->DataBits = 8; break;
default: Handle->DataBits = 255; break;
}
// Get Stop Bits
if (getTermios.c_cflag & CSTOPB)
Handle->StopBits = 2;
else
Handle->StopBits = 1;
// Get Parity
if (getTermios.c_iflag & (PARODD | PARENB))
Handle->Parity = ODD_PARITY;
else if (getTermios.c_iflag & PARENB)
Handle->Parity = EVEN_PARITY;
else
Handle->Parity = NO_PARITY;
// Get Flow Control
if (getTermios.c_cflag & CRTSCTS)
Handle->FlowCtrl = true;
else
Handle->FlowCtrl = false;
return true;
}
//---------------------------------------------------------------------------
bool CSelectableCore::BuildArgs( const char * ExecPath, int &Count, char * Args[] ) bool CSelectableCore::BuildArgs( const char * ExecPath, int &Count, char * Args[] )
{ {
bool ParamStarted = false; bool ParamStarted = false;

View File

@@ -94,6 +94,7 @@ struct SHandle {
bool AddressFailed; // Indicate failure to connect to address bool AddressFailed; // Indicate failure to connect to address
bool KeepAlive; // Socket keep alive bool KeepAlive; // Socket keep alive
bool SerialConfig;
int Baudrate; int Baudrate;
short DataBits; short DataBits;
short Parity; short Parity;
@@ -257,8 +258,8 @@ public:
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 SetPortHandle( THandle * Handle, const char * FileName );
int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait ); bool SetPortHandleSerial( THandle * Handle, int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
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 );
@@ -281,7 +282,8 @@ 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 ConfigureSerialPort( THandle * Handle ); bool SetSerialPortConfig( THandle * Handle );
bool GetSerialPortConfig( THandle * Handle );
// Info // Info
inline EConnectType GetType( const char * HandleName ) { inline EConnectType GetType( const char * HandleName ) {