Fix serial resource checks

Fix serial resource checks (#20053)
This commit is contained in:
Theo Arends 2023-11-20 12:35:06 +01:00
parent 7d30ab5929
commit 433d69d4bc
2 changed files with 70 additions and 90 deletions

View File

@ -37,6 +37,7 @@ uint8_t client_next = 0;
uint8_t *tcp_buf = nullptr; // data transfer buffer
bool ip_filter_enabled = false;
IPAddress ip_filter;
bool tcp_serial = false;
#include <TasmotaSerial.h>
TasmotaSerial *TCPSerial = nullptr;
@ -58,8 +59,6 @@ void TCPLoop(void)
bool busy; // did we transfer some data?
int32_t buf_len;
if (!TCPSerial) return;
// check for a new client connection
if ((server_tcp) && (server_tcp->hasClient())) {
WiFiClient new_client = server_tcp->available();
@ -138,14 +137,21 @@ void TCPLoop(void)
void TCPInit(void) {
if (PinUsed(GPIO_TCP_RX) && PinUsed(GPIO_TCP_TX)) {
if (0 == (0x80 & Settings->tcp_config)) // !0x80 means unitialized
Settings->tcp_config = 0x80 | ParseSerialConfig("8N1"); // default as 8N1 for backward compatibility
if (0 == (0x80 & Settings->tcp_config)) { // !0x80 means unitialized
Settings->tcp_config = 0x80 | ParseSerialConfig("8N1"); // default as 8N1 for backward compatibility
}
tcp_buf = (uint8_t*) malloc(TCP_BRIDGE_BUF_SIZE);
if (!tcp_buf) { AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_TCP "could not allocate buffer")); return; }
if (!tcp_buf) {
AddLog(LOG_LEVEL_ERROR, PSTR(D_LOG_TCP "could not allocate buffer"));
return;
}
if (!Settings->tcp_baudrate) { Settings->tcp_baudrate = 115200 / 1200; }
if (!Settings->tcp_baudrate) {
Settings->tcp_baudrate = 115200 / 1200;
}
TCPSerial = new TasmotaSerial(Pin(GPIO_TCP_RX), Pin(GPIO_TCP_TX), TasmotaGlobal.seriallog_level ? 1 : 2, 0, TCP_BRIDGE_BUF_SIZE); // set a receive buffer of 256 bytes
if (TCPSerial->begin(Settings->tcp_baudrate * 1200, ConvertSerialConfig(0x7F & Settings->tcp_config))) {
tcp_serial = TCPSerial->begin(Settings->tcp_baudrate * 1200, ConvertSerialConfig(0x7F & Settings->tcp_config));
if (tcp_serial) {
if (TCPSerial->hardwareSerial()) {
ClaimSerial();
}
@ -167,9 +173,6 @@ void TCPInit(void) {
// Params: port,<IPv4 allow>
//
void CmndTCPStart(void) {
if (!TCPSerial) { return; }
int32_t tcp_port = XdrvMailbox.payload;
if (ArgC() == 2) {
char sub_string[XdrvMailbox.data_len];
@ -205,8 +208,6 @@ void CmndTCPStart(void) {
}
void CmndTCPBaudrate(void) {
if (!TCPSerial) { return; }
if ((XdrvMailbox.payload >= 1200) && (XdrvMailbox.payload <= 115200)) {
XdrvMailbox.payload /= 1200; // Make it a valid baudrate
if (Settings->tcp_baudrate != XdrvMailbox.payload) {
@ -220,8 +221,6 @@ void CmndTCPBaudrate(void) {
}
void CmndTCPConfig(void) {
if (!TCPSerial) { return; }
if (XdrvMailbox.data_len > 0) {
uint8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
if ((serial_config >= 0) && (Settings->tcp_config != (0x80 | serial_config))) {
@ -241,8 +240,6 @@ void CmndTCPConfig(void) {
void CmndTCPConnect(void) {
int32_t tcp_port = XdrvMailbox.payload;
if (!TCPSerial) { return; }
if (ArgC() == 2) {
char sub_string[XdrvMailbox.data_len];
WiFiClient new_client;
@ -283,16 +280,17 @@ bool Xdrv41(uint32_t function)
{
bool result = false;
switch (function) {
case FUNC_LOOP:
TCPLoop();
break;
case FUNC_PRE_INIT:
TCPInit();
break;
case FUNC_COMMAND:
result = DecodeCommand(kTCPCommands, TCPCommand);
break;
if (FUNC_PRE_INIT == function) {
TCPInit();
} else if (tcp_serial) {
switch (function) {
case FUNC_LOOP:
TCPLoop();
break;
case FUNC_COMMAND:
result = DecodeCommand(kTCPCommands, TCPCommand);
break;
}
}
return result;
}

View File

@ -102,7 +102,7 @@ struct ModbusBridgeTCP
};
ModbusBridgeTCP modbusBridgeTCP;
#endif
#endif // USE_MODBUS_BRIDGE_TCP
#include <TasmotaModbus.h>
TasmotaModbus *modbusBridgeModbus = nullptr;
@ -171,6 +171,7 @@ struct ModbusBridge
uint8_t count = 0; // Number of values to read / write
bool raw = false;
uint8_t *buffer = nullptr; // Buffer for storing read / write data
bool enabled = false;
};
ModbusBridge modbusBridge;
@ -193,28 +194,28 @@ void ModbusBridgeAllocError(const char* s)
//
// Applies serial configuration to modbus serial port
//
bool ModbusBridgeBegin(void)
{
if ((Settings->modbus_sbaudrate < 1) || (Settings->modbus_sbaudrate > (115200 / 300)))
bool ModbusBridgeBegin(void) {
if ((Settings->modbus_sbaudrate < 1) || (Settings->modbus_sbaudrate > (115200 / 300))) {
Settings->modbus_sbaudrate = (uint8_t)((uint32_t)MBR_BAUDRATE / 300);
if (Settings->modbus_sconfig > TS_SERIAL_8O2)
}
if (Settings->modbus_sconfig > TS_SERIAL_8O2) {
Settings->modbus_sconfig = TS_SERIAL_8N1;
}
int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
if (result)
{
if (2 == result)
{
if (result) {
if (2 == result) {
ClaimSerial();
}
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR %s ser init at %d baud"), (2 == result ? "HW" : "SW"), Settings->modbus_sbaudrate * 300);
if (nullptr == modbusBridge.buffer) modbusBridge.buffer = (uint8_t *)malloc(MBR_RECEIVE_BUFFER_SIZE);
if (nullptr == modbusBridge.buffer)
{
ModbusBridgeAllocError(PSTR("BUFFER"));
result = false;
}
if (nullptr == modbusBridge.buffer) {
modbusBridge.buffer = (uint8_t *)malloc(MBR_RECEIVE_BUFFER_SIZE);
}
if (nullptr == modbusBridge.buffer) {
ModbusBridgeAllocError(PSTR("BUFFER"));
result = false;
}
}
return result;
@ -569,31 +570,29 @@ void ModbusBridgeHandle(void)
//
// Inits the tasmota modbus driver, sets serialport and if TCP enabled allocates a TCP buffer
//
void ModbusBridgeInit(void)
{
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX))
{
if (nullptr == modbusBridgeModbus) modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX), Pin(GPIO_MBR_TX_ENA));
ModbusBridgeBegin();
void ModbusBridgeInit(void) {
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX)) {
modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX), Pin(GPIO_MBR_TX_ENA));
if (ModbusBridgeBegin()) {
modbusBridge.enabled = true;
#ifdef USE_MODBUS_BRIDGE_TCP
// If TCP bridge is enabled allocate a TCP receive buffer
if (nullptr == modbusBridgeTCP.tcp_buf) modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
if (nullptr == modbusBridgeTCP.tcp_buf)
{
ModbusBridgeAllocError(PSTR("TCP"));
return;
}
// If TCP bridge is enabled allocate a TCP receive buffer
if (nullptr == modbusBridgeTCP.tcp_buf) modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
if (nullptr == modbusBridgeTCP.tcp_buf) {
ModbusBridgeAllocError(PSTR("TCP"));
return;
}
#ifdef MODBUS_BRIDGE_TCP_DEFAULT_PORT
else
{
AddLog(LOG_LEVEL_INFO, PSTR("MBS: MBRTCP Starting server on port %d"), MODBUS_BRIDGE_TCP_DEFAULT_PORT);
else {
AddLog(LOG_LEVEL_INFO, PSTR("MBS: MBRTCP Starting server on port %d"), MODBUS_BRIDGE_TCP_DEFAULT_PORT);
modbusBridgeTCP.server_tcp = new WiFiServer(MODBUS_BRIDGE_TCP_DEFAULT_PORT);
modbusBridgeTCP.server_tcp->begin(); // start TCP server
modbusBridgeTCP.server_tcp->setNoDelay(true);
modbusBridgeTCP.server_tcp = new WiFiServer(MODBUS_BRIDGE_TCP_DEFAULT_PORT);
modbusBridgeTCP.server_tcp->begin(); // start TCP server
modbusBridgeTCP.server_tcp->setNoDelay(true);
}
#endif // MODBUS_BRIDGE_TCP_DEFAULT_PORT
#endif // USE_MODBUS_BRIDGE_TCP
}
#endif
#endif
}
}
@ -608,9 +607,6 @@ void ModbusTCPHandle(void)
bool busy; // did we transfer some data?
int32_t buf_len;
if (!modbusBridgeModbus)
return;
// check for a new client connection
if ((modbusBridgeTCP.server_tcp) && (modbusBridgeTCP.server_tcp->hasClient()))
{
@ -1055,13 +1051,8 @@ void CmndModbusBridgeSetConfig(void)
//
void CmndModbusTCPStart(void)
{
if (!modbusBridgeModbus)
{
return;
}
int32_t tcp_port = XdrvMailbox.payload;
if (ArgC() == 2)
{
char sub_string[XdrvMailbox.data_len];
@ -1109,11 +1100,6 @@ void CmndModbusTCPConnect(void)
{
int32_t tcp_port = XdrvMailbox.payload;
if (!modbusBridgeModbus)
{
return;
}
if (ArgC() == 2)
{
char sub_string[XdrvMailbox.data_len];
@ -1170,23 +1156,19 @@ bool Xdrv63(uint32_t function)
{
bool result = false;
if (FUNC_PRE_INIT == function)
{
if (FUNC_PRE_INIT == function) {
ModbusBridgeInit();
}
else if (modbusBridgeModbus)
{
switch (function)
{
case FUNC_COMMAND:
result = DecodeCommand(kModbusBridgeCommands, ModbusBridgeCommand);
break;
case FUNC_LOOP:
ModbusBridgeHandle();
} else if (modbusBridge.enabled) {
switch (function) {
case FUNC_LOOP:
ModbusBridgeHandle();
#ifdef USE_MODBUS_BRIDGE_TCP
ModbusTCPHandle();
ModbusTCPHandle();
#endif
break;
break;
case FUNC_COMMAND:
result = DecodeCommand(kModbusBridgeCommands, ModbusBridgeCommand);
break;
}
}
return result;