mirror of https://github.com/arendst/Tasmota.git
parent
7d30ab5929
commit
433d69d4bc
|
@ -37,6 +37,7 @@ uint8_t client_next = 0;
|
||||||
uint8_t *tcp_buf = nullptr; // data transfer buffer
|
uint8_t *tcp_buf = nullptr; // data transfer buffer
|
||||||
bool ip_filter_enabled = false;
|
bool ip_filter_enabled = false;
|
||||||
IPAddress ip_filter;
|
IPAddress ip_filter;
|
||||||
|
bool tcp_serial = false;
|
||||||
|
|
||||||
#include <TasmotaSerial.h>
|
#include <TasmotaSerial.h>
|
||||||
TasmotaSerial *TCPSerial = nullptr;
|
TasmotaSerial *TCPSerial = nullptr;
|
||||||
|
@ -58,8 +59,6 @@ void TCPLoop(void)
|
||||||
bool busy; // did we transfer some data?
|
bool busy; // did we transfer some data?
|
||||||
int32_t buf_len;
|
int32_t buf_len;
|
||||||
|
|
||||||
if (!TCPSerial) return;
|
|
||||||
|
|
||||||
// check for a new client connection
|
// check for a new client connection
|
||||||
if ((server_tcp) && (server_tcp->hasClient())) {
|
if ((server_tcp) && (server_tcp->hasClient())) {
|
||||||
WiFiClient new_client = server_tcp->available();
|
WiFiClient new_client = server_tcp->available();
|
||||||
|
@ -138,14 +137,21 @@ void TCPLoop(void)
|
||||||
|
|
||||||
void TCPInit(void) {
|
void TCPInit(void) {
|
||||||
if (PinUsed(GPIO_TCP_RX) && PinUsed(GPIO_TCP_TX)) {
|
if (PinUsed(GPIO_TCP_RX) && PinUsed(GPIO_TCP_TX)) {
|
||||||
if (0 == (0x80 & Settings->tcp_config)) // !0x80 means unitialized
|
if (0 == (0x80 & Settings->tcp_config)) { // !0x80 means unitialized
|
||||||
Settings->tcp_config = 0x80 | ParseSerialConfig("8N1"); // default as 8N1 for backward compatibility
|
Settings->tcp_config = 0x80 | ParseSerialConfig("8N1"); // default as 8N1 for backward compatibility
|
||||||
|
}
|
||||||
tcp_buf = (uint8_t*) malloc(TCP_BRIDGE_BUF_SIZE);
|
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
|
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()) {
|
if (TCPSerial->hardwareSerial()) {
|
||||||
ClaimSerial();
|
ClaimSerial();
|
||||||
}
|
}
|
||||||
|
@ -167,9 +173,6 @@ void TCPInit(void) {
|
||||||
// Params: port,<IPv4 allow>
|
// Params: port,<IPv4 allow>
|
||||||
//
|
//
|
||||||
void CmndTCPStart(void) {
|
void CmndTCPStart(void) {
|
||||||
|
|
||||||
if (!TCPSerial) { return; }
|
|
||||||
|
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
if (ArgC() == 2) {
|
if (ArgC() == 2) {
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
@ -205,8 +208,6 @@ void CmndTCPStart(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTCPBaudrate(void) {
|
void CmndTCPBaudrate(void) {
|
||||||
if (!TCPSerial) { return; }
|
|
||||||
|
|
||||||
if ((XdrvMailbox.payload >= 1200) && (XdrvMailbox.payload <= 115200)) {
|
if ((XdrvMailbox.payload >= 1200) && (XdrvMailbox.payload <= 115200)) {
|
||||||
XdrvMailbox.payload /= 1200; // Make it a valid baudrate
|
XdrvMailbox.payload /= 1200; // Make it a valid baudrate
|
||||||
if (Settings->tcp_baudrate != XdrvMailbox.payload) {
|
if (Settings->tcp_baudrate != XdrvMailbox.payload) {
|
||||||
|
@ -220,8 +221,6 @@ void CmndTCPBaudrate(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CmndTCPConfig(void) {
|
void CmndTCPConfig(void) {
|
||||||
if (!TCPSerial) { return; }
|
|
||||||
|
|
||||||
if (XdrvMailbox.data_len > 0) {
|
if (XdrvMailbox.data_len > 0) {
|
||||||
uint8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
uint8_t serial_config = ParseSerialConfig(XdrvMailbox.data);
|
||||||
if ((serial_config >= 0) && (Settings->tcp_config != (0x80 | serial_config))) {
|
if ((serial_config >= 0) && (Settings->tcp_config != (0x80 | serial_config))) {
|
||||||
|
@ -241,8 +240,6 @@ void CmndTCPConfig(void) {
|
||||||
void CmndTCPConnect(void) {
|
void CmndTCPConnect(void) {
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
|
|
||||||
if (!TCPSerial) { return; }
|
|
||||||
|
|
||||||
if (ArgC() == 2) {
|
if (ArgC() == 2) {
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
WiFiClient new_client;
|
WiFiClient new_client;
|
||||||
|
@ -283,16 +280,17 @@ bool Xdrv41(uint32_t function)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
switch (function) {
|
if (FUNC_PRE_INIT == function) {
|
||||||
case FUNC_LOOP:
|
TCPInit();
|
||||||
TCPLoop();
|
} else if (tcp_serial) {
|
||||||
break;
|
switch (function) {
|
||||||
case FUNC_PRE_INIT:
|
case FUNC_LOOP:
|
||||||
TCPInit();
|
TCPLoop();
|
||||||
break;
|
break;
|
||||||
case FUNC_COMMAND:
|
case FUNC_COMMAND:
|
||||||
result = DecodeCommand(kTCPCommands, TCPCommand);
|
result = DecodeCommand(kTCPCommands, TCPCommand);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ struct ModbusBridgeTCP
|
||||||
};
|
};
|
||||||
|
|
||||||
ModbusBridgeTCP modbusBridgeTCP;
|
ModbusBridgeTCP modbusBridgeTCP;
|
||||||
#endif
|
#endif // USE_MODBUS_BRIDGE_TCP
|
||||||
|
|
||||||
#include <TasmotaModbus.h>
|
#include <TasmotaModbus.h>
|
||||||
TasmotaModbus *modbusBridgeModbus = nullptr;
|
TasmotaModbus *modbusBridgeModbus = nullptr;
|
||||||
|
@ -171,6 +171,7 @@ struct ModbusBridge
|
||||||
uint8_t count = 0; // Number of values to read / write
|
uint8_t count = 0; // Number of values to read / write
|
||||||
bool raw = false;
|
bool raw = false;
|
||||||
uint8_t *buffer = nullptr; // Buffer for storing read / write data
|
uint8_t *buffer = nullptr; // Buffer for storing read / write data
|
||||||
|
bool enabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
ModbusBridge modbusBridge;
|
ModbusBridge modbusBridge;
|
||||||
|
@ -193,28 +194,28 @@ void ModbusBridgeAllocError(const char* s)
|
||||||
//
|
//
|
||||||
// Applies serial configuration to modbus serial port
|
// Applies serial configuration to modbus serial port
|
||||||
//
|
//
|
||||||
bool ModbusBridgeBegin(void)
|
bool ModbusBridgeBegin(void) {
|
||||||
{
|
if ((Settings->modbus_sbaudrate < 1) || (Settings->modbus_sbaudrate > (115200 / 300))) {
|
||||||
if ((Settings->modbus_sbaudrate < 1) || (Settings->modbus_sbaudrate > (115200 / 300)))
|
|
||||||
Settings->modbus_sbaudrate = (uint8_t)((uint32_t)MBR_BAUDRATE / 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;
|
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
|
int result = modbusBridgeModbus->Begin(Settings->modbus_sbaudrate * 300, ConvertSerialConfig(Settings->modbus_sconfig)); // Reinitialize modbus port with new baud rate
|
||||||
if (result)
|
if (result) {
|
||||||
{
|
if (2 == result) {
|
||||||
if (2 == result)
|
|
||||||
{
|
|
||||||
ClaimSerial();
|
ClaimSerial();
|
||||||
}
|
}
|
||||||
AddLog(LOG_LEVEL_DEBUG, PSTR("MBS: MBR %s ser init at %d baud"), (2 == result ? "HW" : "SW"), Settings->modbus_sbaudrate * 300);
|
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) {
|
||||||
if (nullptr == modbusBridge.buffer)
|
modbusBridge.buffer = (uint8_t *)malloc(MBR_RECEIVE_BUFFER_SIZE);
|
||||||
{
|
}
|
||||||
ModbusBridgeAllocError(PSTR("BUFFER"));
|
if (nullptr == modbusBridge.buffer) {
|
||||||
result = false;
|
ModbusBridgeAllocError(PSTR("BUFFER"));
|
||||||
}
|
result = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -569,31 +570,29 @@ void ModbusBridgeHandle(void)
|
||||||
//
|
//
|
||||||
// Inits the tasmota modbus driver, sets serialport and if TCP enabled allocates a TCP buffer
|
// Inits the tasmota modbus driver, sets serialport and if TCP enabled allocates a TCP buffer
|
||||||
//
|
//
|
||||||
void ModbusBridgeInit(void)
|
void ModbusBridgeInit(void) {
|
||||||
{
|
if (PinUsed(GPIO_MBR_RX) && PinUsed(GPIO_MBR_TX)) {
|
||||||
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()) {
|
||||||
if (nullptr == modbusBridgeModbus) modbusBridgeModbus = new TasmotaModbus(Pin(GPIO_MBR_RX), Pin(GPIO_MBR_TX), Pin(GPIO_MBR_TX_ENA));
|
modbusBridge.enabled = true;
|
||||||
ModbusBridgeBegin();
|
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
// If TCP bridge is enabled allocate a TCP receive buffer
|
// 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) modbusBridgeTCP.tcp_buf = (uint8_t *)malloc(MODBUS_BRIDGE_TCP_BUF_SIZE);
|
||||||
if (nullptr == modbusBridgeTCP.tcp_buf)
|
if (nullptr == modbusBridgeTCP.tcp_buf) {
|
||||||
{
|
ModbusBridgeAllocError(PSTR("TCP"));
|
||||||
ModbusBridgeAllocError(PSTR("TCP"));
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
#ifdef MODBUS_BRIDGE_TCP_DEFAULT_PORT
|
#ifdef MODBUS_BRIDGE_TCP_DEFAULT_PORT
|
||||||
else
|
else {
|
||||||
{
|
AddLog(LOG_LEVEL_INFO, PSTR("MBS: MBRTCP Starting server on port %d"), MODBUS_BRIDGE_TCP_DEFAULT_PORT);
|
||||||
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 = new WiFiServer(MODBUS_BRIDGE_TCP_DEFAULT_PORT);
|
||||||
modbusBridgeTCP.server_tcp->begin(); // start TCP server
|
modbusBridgeTCP.server_tcp->begin(); // start TCP server
|
||||||
modbusBridgeTCP.server_tcp->setNoDelay(true);
|
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?
|
bool busy; // did we transfer some data?
|
||||||
int32_t buf_len;
|
int32_t buf_len;
|
||||||
|
|
||||||
if (!modbusBridgeModbus)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// check for a new client connection
|
// check for a new client connection
|
||||||
if ((modbusBridgeTCP.server_tcp) && (modbusBridgeTCP.server_tcp->hasClient()))
|
if ((modbusBridgeTCP.server_tcp) && (modbusBridgeTCP.server_tcp->hasClient()))
|
||||||
{
|
{
|
||||||
|
@ -1055,13 +1051,8 @@ void CmndModbusBridgeSetConfig(void)
|
||||||
//
|
//
|
||||||
void CmndModbusTCPStart(void)
|
void CmndModbusTCPStart(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!modbusBridgeModbus)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
|
|
||||||
if (ArgC() == 2)
|
if (ArgC() == 2)
|
||||||
{
|
{
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
@ -1109,11 +1100,6 @@ void CmndModbusTCPConnect(void)
|
||||||
{
|
{
|
||||||
int32_t tcp_port = XdrvMailbox.payload;
|
int32_t tcp_port = XdrvMailbox.payload;
|
||||||
|
|
||||||
if (!modbusBridgeModbus)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ArgC() == 2)
|
if (ArgC() == 2)
|
||||||
{
|
{
|
||||||
char sub_string[XdrvMailbox.data_len];
|
char sub_string[XdrvMailbox.data_len];
|
||||||
|
@ -1170,23 +1156,19 @@ bool Xdrv63(uint32_t function)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (FUNC_PRE_INIT == function)
|
if (FUNC_PRE_INIT == function) {
|
||||||
{
|
|
||||||
ModbusBridgeInit();
|
ModbusBridgeInit();
|
||||||
}
|
} else if (modbusBridge.enabled) {
|
||||||
else if (modbusBridgeModbus)
|
switch (function) {
|
||||||
{
|
case FUNC_LOOP:
|
||||||
switch (function)
|
ModbusBridgeHandle();
|
||||||
{
|
|
||||||
case FUNC_COMMAND:
|
|
||||||
result = DecodeCommand(kModbusBridgeCommands, ModbusBridgeCommand);
|
|
||||||
break;
|
|
||||||
case FUNC_LOOP:
|
|
||||||
ModbusBridgeHandle();
|
|
||||||
#ifdef USE_MODBUS_BRIDGE_TCP
|
#ifdef USE_MODBUS_BRIDGE_TCP
|
||||||
ModbusTCPHandle();
|
ModbusTCPHandle();
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case FUNC_COMMAND:
|
||||||
|
result = DecodeCommand(kModbusBridgeCommands, ModbusBridgeCommand);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
Loading…
Reference in New Issue