diff --git a/JSONparseCore.cpp b/JSONparseCore.cpp index 358b8b4..94cbfbb 100644 --- a/JSONparseCore.cpp +++ b/JSONparseCore.cpp @@ -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 { diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 8aa4f2a..2dcb328 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -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,31 +100,32 @@ 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 ), - DataTree->GetInt( TempMember, "Port/DataBits", 8, true ), - DataTree->GetInt( TempMember, "Port/StopBits", 1, true ), - ParityVal, FlowCtrlVal, - DataTree->GetInt( TempMember, "Port/DataWait", 0, 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 ), + 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; diff --git a/SelectableCore.h b/SelectableCore.h index fab8e1a..cda5c6a 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -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 );