Important Update:

- JSONparseCore:
  - Bug fix: Incorrectly terminated PrintString on null
- SelectableCore:
  - Add BaudRate, DataBits, Parity, StopBits, FlowCtrl, DataWait to THandle
  - Include Serial Port setup in SetPortHandle()
  - Read Serial Port config in LoadConfigData()
  - Rename SetSerialConfig() -> ConfigureSerialPort()
  - Configure Serial Port immediately after opening port
This commit is contained in:
Charl Wentzel
2017-11-29 11:30:05 +02:00
parent 89123fa4af
commit 92ce01a3b7
3 changed files with 64 additions and 43 deletions

View File

@@ -755,7 +755,7 @@ bool CJSONparse::PrintString( char * String, int Len )
write( OutputHandle, Mark, (BufPos-Mark) );
// Handle special chars
if (!*BufPos) {
if (BufPos-String >= Len) {
break;
}
else {

View File

@@ -72,11 +72,10 @@ bool CSelectableCore::LoadConfigData()
char Path[100];
char * Address;
char * Port;
char * Parity;
short ParityVal;
char * FlowCtrl;
short FlowCtrlVal;
char * ParityText;
char * FlowCtrlText;
short Parity;
short FlowCtrl;
// Call Previous load config
CFunctionCore::LoadConfigData();
@@ -101,30 +100,31 @@ bool CSelectableCore::LoadConfigData()
sprintf( Path, "Address/%s/Address", Name );
Address = (char*)DataTree->GetStr( NULL, Path, Address, true ); // Get address list value
}
SetPortHandle( Handle, Address ); // Assign values
Parity = (char*)DataTree->GetStr( TempMember, "Port/Parity", "none", true );
if (!strcasecmp( Parity, "none" ))
ParityVal = NO_PARITY;
else if (!strcasecmp( Parity, "odd" ))
ParityVal = ODD_PARITY;
else if (!strcasecmp( Parity, "even" ))
ParityVal = EVEN_PARITY;
else if (!strcasecmp( Parity, "mark" ))
ParityVal = MARK_PARITY;
ParityText = (char*)DataTree->GetStr( TempMember, "Port/Parity", "none", true );
if (!strcasecmp( ParityText, "none" ))
Parity = NO_PARITY;
else if (!strcasecmp( ParityText, "odd" ))
Parity = ODD_PARITY;
else if (!strcasecmp( ParityText, "even" ))
Parity = EVEN_PARITY;
else if (!strcasecmp( ParityText, "mark" ))
Parity = MARK_PARITY;
FlowCtrl = (char*)DataTree->GetStr( TempMember, "Port/FlowCtrl", "none", true );
if (!strcasecmp( FlowCtrl, "none" ))
FlowCtrlVal = NO_FLOWCTRL;
else if (!strcasecmp( FlowCtrl, "hardware" ))
FlowCtrlVal = HW_FLOWCTRL;
else if (!strcasecmp( FlowCtrl, "software" ))
FlowCtrlVal = SW_FLOWCTRL;
FlowCtrlText = (char*)DataTree->GetStr( TempMember, "Port/FlowCtrl", "none", true );
if (!strcasecmp( FlowCtrlText, "none" ))
FlowCtrl = NO_FLOWCTRL;
else if (!strcasecmp( FlowCtrlText, "hardware" ))
FlowCtrl = HW_FLOWCTRL;
else if (!strcasecmp( FlowCtrlText, "software" ))
FlowCtrl = SW_FLOWCTRL;
SetSerialConfig( Handle, DataTree->GetInt( TempMember, "Port/BaudRate", 19200, true ),
SetPortHandle( Handle, Address,
DataTree->GetInt( TempMember, "Port/BaudRate", 19200, true ),
DataTree->GetInt( TempMember, "Port/DataBits", 8, true ),
Parity,
DataTree->GetInt( TempMember, "Port/StopBits", 1, true ),
ParityVal, FlowCtrlVal,
FlowCtrl,
DataTree->GetInt( TempMember, "Port/DataWait", 0, true));
}
else if (!strcasecmp( Type, "TCPserver" ))
@@ -275,7 +275,8 @@ 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
if (!Handle || ((Handle->Type != ctNone) && (Handle->Type != ctPort)) || !FileName) {
@@ -294,6 +295,13 @@ bool CSelectableCore::SetPortHandle( THandle * Handle, const char * FileName )
Handle->Path = (char*)malloc( strlen(FileName)+1 );
strcpy( Handle->Path, FileName );
Handle->Baudrate = Baudrate;
Handle->DataBits = DataBits;
Handle->Parity = Parity;
Handle->StopBits = StopBits;
Handle->FlowCtrl = FlowCtrl;
Handle->DataWait = DataWait;
// Log event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Set as Port [%s]", Name, Handle->Name, FileName );
return true;
@@ -502,6 +510,9 @@ int CSelectableCore::OpenPort( THandle * Handle )
// Log Event
if (Log) Log->Message( LogLevel, dlMedium, "%s: Handle '%s' - Port opened [%s]", Name, Handle->Name, Handle->Path );
// Update port configuration
ConfigureSerialPort( Handle );
// Add to Select Lists
if (Selector) {
Selector->Add( Handle->FD, true, false, this );
@@ -1627,7 +1638,7 @@ bool CSelectableCore::Process()
//---------------------------------------------------------------------------
// Set serial port configuration parameters
bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait )
bool CSelectableCore::ConfigureSerialPort( THandle * Handle )
{
struct termios newtio;
int flags = 0;
@@ -1651,7 +1662,7 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
return false;
// Process the baud rate
switch (Baud)
switch (Handle->Baudrate)
{
case 921600: _baud = B921600; break;
case 576000: _baud = B576000; break;
@@ -1687,12 +1698,12 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
cfsetispeed( &newtio, (speed_t)_baud );
// Generate Mark/Space parity
if ((DataBits == 7) && ((Parity == MARK_PARITY) || (Parity == SPACE_PARITY)))
DataBits = 8;
if ((Handle->DataBits == 7) && ((Handle->Parity == MARK_PARITY) || (Handle->Parity == SPACE_PARITY)))
Handle->DataBits = 8;
// Process the data bits
newtio.c_cflag &= ~CSIZE;
switch (DataBits)
switch (Handle->DataBits)
{
case 5: newtio.c_cflag |= CS5; break;
case 6: newtio.c_cflag |= CS6; break;
@@ -1707,16 +1718,16 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
// Process Parity
newtio.c_cflag &= ~(PARENB | PARODD);
if (Parity == EVEN_PARITY)
if (Handle->Parity == EVEN_PARITY)
newtio.c_cflag |= PARENB;
else if (Parity == ODD_PARITY)
else if (Handle->Parity == ODD_PARITY)
newtio.c_cflag |= (PARENB | PARODD);
// Flow Control (for now)
newtio.c_cflag &= ~CRTSCTS;
// Process Stop Bits
if (StopBits == 2)
if (Handle->StopBits == 2)
newtio.c_cflag |= CSTOPB;
else
newtio.c_cflag &= ~CSTOPB;
@@ -1724,7 +1735,7 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
newtio.c_iflag = IGNBRK;
// Software Flow Control
if (FlowCtrl == SW_FLOWCTRL)
if (Handle->FlowCtrl == SW_FLOWCTRL)
newtio.c_iflag |= IXON | IXOFF;
else
newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
@@ -1734,7 +1745,7 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
newtio.c_oflag=0;
// Set wait parameters
newtio.c_cc[VTIME] = Wait; // Blocking: Allow at least a tenth of a second to wait for data
newtio.c_cc[VTIME] = Handle->DataWait; // Blocking: Allow at least a tenth of a second to wait for data
newtio.c_cc[VMIN] = 0; // Non-blocking: Don't set min bytes to receive
// Set Options (first time)
@@ -1752,7 +1763,7 @@ bool CSelectableCore::SetSerialConfig( THandle * Handle, int Baud, short DataBit
return false;
// Process Hardware Flow Control
if (FlowCtrl == HW_FLOWCTRL)
if (Handle->FlowCtrl == HW_FLOWCTRL)
newtio.c_cflag |= CRTSCTS;
else
newtio.c_cflag &= ~CRTSCTS;

View File

@@ -94,6 +94,13 @@ struct SHandle {
bool AddressFailed; // Indicate failure to connect to address
bool KeepAlive; // Socket keep alive
int Baudrate;
short DataBits;
short Parity;
short StopBits;
short FlowCtrl;
int DataWait;
// Buffers
CRollingBuffer * InBuffer;
CRollingBuffer * OutBuffer;
@@ -242,15 +249,16 @@ public:
return Handle;
}
// General port parameters
THandle * CreateHandle( const char * HandleName, bool CreateChannel );
bool SetCallback( THandle * Handle, EConnectState pState, FHandleCallback pCallback );
bool SetAutoManage( THandle * Handle, bool AutoManage, bool Persistent, int ReopenTime = 0 );
bool SetInBuffer( THandle * Handle, int InBufSize, int InTimeout, const char * InMarker, int InMarkerLen );
bool SetOutBuffer( THandle * Handle, int OutBufSize );
bool SetSerialConfig( THandle * Handle, int Baud, short DataBits, short StopBits, short Parity, short FlowCtrl, int Wait );
// File Interface
bool SetPortHandle( THandle * Handle, const char * FileName );
// Specific port parameters
bool SetPortHandle( THandle * Handle, const char * FileName,
int Baudrate, short DataBits, short Parity, short StopBits, short FlowCtrl, int DataWait );
bool SetForkPipeHandle( THandle * Handle, const char * ExecPath );
bool SetSocketHandle( THandle * Handle, EConnectType Type, const char * HostName, const char * PortName, bool KeepAlive );
bool ClearHandle( THandle * Handle );
@@ -273,6 +281,8 @@ public:
inline virtual bool Write( const char * HandleName ) { return (Write( GetHandle( HandleName ))); };
inline virtual bool Write( int FD ) { return (Write( GetHandle( FD ))); };
bool ConfigureSerialPort( THandle * Handle );
// Info
inline EConnectType GetType( const char * HandleName ) {
THandle * Handle = GetHandle( HandleName );