Refactor MQTT commands

Refactor MQTT commands
This commit is contained in:
Theo Arends 2019-07-28 17:14:20 +02:00
parent a3e12dd3c8
commit 13a618634e
4 changed files with 369 additions and 329 deletions

View File

@ -452,23 +452,23 @@ char IndexSeparator()
}
}
void SetShortcut(char* str, uint8_t action)
void SetShortcutDefault(void)
{
if ('\0' != str[0]) { // There must be at least one character in the buffer
str[0] = '0' + action; // SC_CLEAR, SC_DEFAULT, SC_USER
str[1] = '\0';
if ('\0' != XdrvMailbox.data[0]) { // There must be at least one character in the buffer
XdrvMailbox.data[0] = '0' + SC_DEFAULT; // SC_CLEAR, SC_DEFAULT, SC_USER
XdrvMailbox.data[1] = '\0';
}
}
uint8_t Shortcut(const char* str)
uint8_t Shortcut()
{
uint8_t result = 10;
if ('\0' == str[1]) { // Only allow single character input for shortcut
if (('"' == str[0]) || ('0' == str[0])) {
if ('\0' == XdrvMailbox.data[1]) { // Only allow single character input for shortcut
if (('"' == XdrvMailbox.data[0]) || ('0' == XdrvMailbox.data[0])) {
result = SC_CLEAR;
} else {
result = atoi(str); // 1 = SC_DEFAULT, 2 = SC_USER
result = atoi(XdrvMailbox.data); // 1 = SC_DEFAULT, 2 = SC_USER
if (0 == result) {
result = 10;
}
@ -502,29 +502,6 @@ bool ParseIp(uint32_t* addr, const char* str)
return (3 == i);
}
void MakeValidMqtt(uint32_t option, char* str)
{
// option 0 = replace by underscore
// option 1 = delete character
uint32_t i = 0;
while (str[i] > 0) {
// if ((str[i] == '/') || (str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if ((str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if (option) {
uint32_t j = i;
while (str[j] > 0) {
str[j] = str[j +1];
j++;
}
i--;
} else {
str[i] = '_';
}
}
i++;
}
}
// Function to parse & check if version_str is newer than our currently installed version.
bool NewerVersion(char* version_str)
{

View File

@ -143,6 +143,7 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
backlog_delay = millis() + (100 * MIN_BACKLOG_DELAY);
char command[CMDSZ];
XdrvMailbox.command = command;
XdrvMailbox.index = index;
XdrvMailbox.data_len = data_len;
XdrvMailbox.payload = payload;
@ -150,9 +151,8 @@ void CommandHandler(char* topic, uint8_t* data, uint32_t data_len)
XdrvMailbox.usridx = user_index;
XdrvMailbox.topic = type;
XdrvMailbox.data = dataBuf;
XdrvMailbox.command = command;
int command_code = GetCommandCode(command, sizeof(command), type, kTasmotaCommands);
int command_code = GetCommandCode(XdrvMailbox.command, CMDSZ, type, kTasmotaCommands);
if (command_code >= 0) {
TasmotaCommand[command_code]();
} else {
@ -398,7 +398,7 @@ void CmndUpgrade(void)
void CmndOtaUrl(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ota_url))) {
strlcpy(Settings.ota_url, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? OTA_URL : XdrvMailbox.data, sizeof(Settings.ota_url));
strlcpy(Settings.ota_url, (SC_DEFAULT == Shortcut()) ? OTA_URL : XdrvMailbox.data, sizeof(Settings.ota_url));
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.ota_url);
}
@ -946,7 +946,7 @@ void CmndSyslog(void)
void CmndLoghost(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.syslog_host))) {
strlcpy(Settings.syslog_host, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? SYS_LOG_HOST : XdrvMailbox.data, sizeof(Settings.syslog_host));
strlcpy(Settings.syslog_host, (SC_DEFAULT == Shortcut()) ? SYS_LOG_HOST : XdrvMailbox.data, sizeof(Settings.syslog_host));
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.syslog_host);
}
@ -978,7 +978,7 @@ void CmndNtpServer(void)
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.ntp_server[0]))) {
strlcpy(Settings.ntp_server[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1==XdrvMailbox.index)?NTP_SERVER1:(2==XdrvMailbox.index)?NTP_SERVER2:NTP_SERVER3 : XdrvMailbox.data,
(SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1==XdrvMailbox.index)?NTP_SERVER1:(2==XdrvMailbox.index)?NTP_SERVER2:NTP_SERVER3 : XdrvMailbox.data,
sizeof(Settings.ntp_server[0]));
for (uint32_t i = 0; i < strlen(Settings.ntp_server[XdrvMailbox.index -1]); i++) {
if (Settings.ntp_server[XdrvMailbox.index -1][i] == ',') Settings.ntp_server[XdrvMailbox.index -1][i] = '.';
@ -1011,7 +1011,7 @@ void CmndSsid(void)
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.sta_ssid[0]))) {
strlcpy(Settings.sta_ssid[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1 == XdrvMailbox.index) ? STA_SSID1 : STA_SSID2 : XdrvMailbox.data,
(SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_SSID1 : STA_SSID2 : XdrvMailbox.data,
sizeof(Settings.sta_ssid[0]));
Settings.sta_active = XdrvMailbox.index -1;
restart_flag = 2;
@ -1023,9 +1023,9 @@ void CmndSsid(void)
void CmndPassword(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
if ((XdrvMailbox.data_len > 4 || SC_CLEAR == Shortcut(XdrvMailbox.data) || SC_DEFAULT == Shortcut(XdrvMailbox.data)) && (XdrvMailbox.data_len < sizeof(Settings.sta_pwd[0]))) {
if ((XdrvMailbox.data_len > 4 || SC_CLEAR == Shortcut() || SC_DEFAULT == Shortcut()) && (XdrvMailbox.data_len < sizeof(Settings.sta_pwd[0]))) {
strlcpy(Settings.sta_pwd[XdrvMailbox.index -1],
(SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data,
(SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? STA_PASS1 : STA_PASS2 : XdrvMailbox.data,
sizeof(Settings.sta_pwd[0]));
Settings.sta_active = XdrvMailbox.index -1;
restart_flag = 2;
@ -1039,7 +1039,7 @@ void CmndPassword(void)
void CmndHostname(void)
{
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.hostname))) {
strlcpy(Settings.hostname, (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WIFI_HOSTNAME : XdrvMailbox.data, sizeof(Settings.hostname));
strlcpy(Settings.hostname, (SC_DEFAULT == Shortcut()) ? WIFI_HOSTNAME : XdrvMailbox.data, sizeof(Settings.hostname));
if (strstr(Settings.hostname, "%") != nullptr) {
strlcpy(Settings.hostname, WIFI_HOSTNAME, sizeof(Settings.hostname));
}
@ -1076,7 +1076,7 @@ void CmndFriendlyname(void)
} else {
snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME "%d"), XdrvMailbox.index);
}
strlcpy(Settings.friendlyname[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? stemp1 : XdrvMailbox.data, sizeof(Settings.friendlyname[XdrvMailbox.index -1]));
strlcpy(Settings.friendlyname[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut()) ? stemp1 : XdrvMailbox.data, sizeof(Settings.friendlyname[XdrvMailbox.index -1]));
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, Settings.friendlyname[XdrvMailbox.index -1]);
}

View File

@ -2479,7 +2479,7 @@ bool WebCommand(void)
}
else if (CMND_WEBPASSWORD == command_code) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.web_password))) {
strlcpy(Settings.web_password, (SC_CLEAR == Shortcut(XdrvMailbox.data)) ? "" : (SC_DEFAULT == Shortcut(XdrvMailbox.data)) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
strlcpy(Settings.web_password, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? WEB_PASSWORD : XdrvMailbox.data, sizeof(Settings.web_password));
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.web_password);
} else {
Response_P(S_JSON_COMMAND_ASTERISK, command);

View File

@ -26,14 +26,26 @@
WiFiClient EspClient; // Wifi Client
#endif
enum MqttCommands {
CMND_MQTTHOST, CMND_MQTTPORT, CMND_MQTTRETRY, CMND_STATETEXT, CMND_MQTTFINGERPRINT, CMND_MQTTCLIENT,
CMND_MQTTUSER, CMND_MQTTPASSWORD, CMND_FULLTOPIC, CMND_PREFIX, CMND_GROUPTOPIC, CMND_TOPIC, CMND_PUBLISH,
CMND_BUTTONTOPIC, CMND_SWITCHTOPIC, CMND_BUTTONRETAIN, CMND_SWITCHRETAIN, CMND_POWERRETAIN, CMND_SENSORRETAIN };
const char kMqttCommands[] PROGMEM =
D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTFINGERPRINT "|" D_CMND_MQTTCLIENT "|"
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
D_CMND_MQTTFINGERPRINT "|"
#endif
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|"
#endif
D_CMND_MQTTHOST "|" D_CMND_MQTTPORT "|" D_CMND_MQTTRETRY "|" D_CMND_STATETEXT "|" D_CMND_MQTTCLIENT "|"
D_CMND_FULLTOPIC "|" D_CMND_PREFIX "|" D_CMND_GROUPTOPIC "|" D_CMND_TOPIC "|" D_CMND_PUBLISH "|"
D_CMND_BUTTONTOPIC "|" D_CMND_SWITCHTOPIC "|" D_CMND_BUTTONRETAIN "|" D_CMND_SWITCHRETAIN "|" D_CMND_POWERRETAIN "|" D_CMND_SENSORRETAIN ;
void (* const MqttCommand[])(void) PROGMEM = {
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
&CmndMqttFingerprint,
#endif
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
&CmndMqttUser, &CmndMqttPassword,
#endif
&CmndMqttHost, &CmndMqttPort, &CmndMqttRetry, &CmndStateText, &CmndMqttClient,
&CmndFullTopic, &CmndPrefix, &CmndGroupTopic, &CmndTopic, &CmndPublish,
&CmndButtonTopic, &CmndSwitchTopic, &CmndButtonRetain, &CmndSwitchRetain, &CmndPowerRetain, &CmndSensorRetain };
IPAddress mqtt_host_addr; // MQTT host IP address
uint32_t mqtt_host_hash = 0; // MQTT host name hash
@ -45,8 +57,6 @@ bool mqtt_connected = false; // MQTT virtual connection status
bool mqtt_allowed = false; // MQTT enabled and parameters valid
#ifdef USE_MQTT_TLS
// see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c
void to_hex(unsigned char * in, size_t insz, char * out, size_t outsz) {
unsigned char * pin = in;
@ -90,8 +100,73 @@ bool is_fingerprint_mono_value(uint8_t finger[20], uint8_t value) {
return true;
}
#ifdef USE_MQTT_AWS_IOT
void setLongMqttHost(const char *mqtt_host) {
if (strlen(mqtt_host) <= sizeof(Settings.mqtt_host)) {
strlcpy(Settings.mqtt_host, mqtt_host, sizeof(Settings.mqtt_host));
Settings.mqtt_user[0] = 0;
} else {
// need to split in mqtt_user first then mqtt_host
strlcpy(Settings.mqtt_user, mqtt_host, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_host, &mqtt_host[sizeof(Settings.mqtt_user)-1], sizeof(Settings.mqtt_host));
}
strlcpy(AWS_endpoint, mqtt_host, sizeof(AWS_endpoint));
}
#endif // USE_MQTT_AWS_IOT
#endif // USE_MQTT_TLS
void MakeValidMqtt(uint32_t option, char* str)
{
// option 0 = replace by underscore
// option 1 = delete character
uint32_t i = 0;
while (str[i] > 0) {
// if ((str[i] == '/') || (str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if ((str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
if (option) {
uint32_t j = i;
while (str[j] > 0) {
str[j] = str[j +1];
j++;
}
i--;
} else {
str[i] = '_';
}
}
i++;
}
}
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
void MqttDiscoverServer(void)
{
if (!mdns_begun) { return; }
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
if (n > 0) {
uint32_t i = 0; // If the hostname isn't set, use the first record found.
#ifdef MDNS_HOSTNAME
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
break; // Stop at matching record
}
}
#endif // MDNS_HOSTNAME
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(i).toString().c_str());
Settings.mqtt_port = MDNS.port(i);
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), Settings.mqtt_host, Settings.mqtt_port);
}
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
/*********************************************************************************************\
* MQTT driver specific code need to provide the following functions:
*
@ -114,8 +189,8 @@ PubSubClient MqttClient;
PubSubClient MqttClient(EspClient);
#endif
void MqttInit(void) {
void MqttInit(void)
{
#ifdef USE_MQTT_TLS
tlsClient = new BearSSL::WiFiClientSecure_light(1024,1024);
@ -139,7 +214,6 @@ void MqttInit(void) {
#endif // USE_MQTT_TLS
}
bool MqttIsConnected(void)
{
return MqttClient.connected();
@ -206,34 +280,6 @@ void MqttDataHandler(char* topic, uint8_t* data, unsigned int data_len)
/*********************************************************************************************/
#ifdef USE_DISCOVERY
#ifdef MQTT_HOST_DISCOVERY
void MqttDiscoverServer(void)
{
if (!mdns_begun) { return; }
int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
if (n > 0) {
uint32_t i = 0; // If the hostname isn't set, use the first record found.
#ifdef MDNS_HOSTNAME
for (i = n; i > 0; i--) { // Search from last to first and use first if not found
if (!strcmp(MDNS.hostname(i).c_str(), MDNS_HOSTNAME)) {
break; // Stop at matching record
}
}
#endif // MDNS_HOSTNAME
snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(i).toString().c_str());
Settings.mqtt_port = MDNS.port(i);
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), MDNS.hostname(i).c_str(), Settings.mqtt_host, Settings.mqtt_port);
}
}
#endif // MQTT_HOST_DISCOVERY
#endif // USE_DISCOVERY
void MqttRetryCounter(uint8_t value)
{
mqtt_retry_counter = value;
@ -311,7 +357,7 @@ void MqttPublish(const char* topic)
MqttPublish(topic, false);
}
void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, bool retained)
void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic, bool retained)
{
/* prefix 0 = cmnd using subtopic
* prefix 1 = stat using subtopic
@ -332,12 +378,12 @@ void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic, bool retaine
MqttPublish(stopic, retained);
}
void MqttPublishPrefixTopic_P(uint8_t prefix, const char* subtopic)
void MqttPublishPrefixTopic_P(uint32_t prefix, const char* subtopic)
{
MqttPublishPrefixTopic_P(prefix, subtopic, false);
}
void MqttPublishPowerState(uint8_t device)
void MqttPublishPowerState(uint32_t device)
{
char stopic[TOPSZ];
char scommand[33];
@ -380,7 +426,7 @@ void MqttPublishAllPowerState()
}
}
void MqttPublishPowerBlinkState(uint8_t device)
void MqttPublishPowerBlinkState(uint32_t device)
{
char scommand[33];
@ -518,7 +564,6 @@ void MqttReconnect(void)
#endif
if (2 == mqtt_initial_connection_state) { // Executed once just after power on and wifi is connected
mqtt_initial_connection_state = 1;
}
@ -617,126 +662,118 @@ void MqttCheck(void)
}
}
/*********************************************************************************************/
/*********************************************************************************************\
* Commands
\*********************************************************************************************/
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
void setLongMqttHost(const char *mqtt_host) {
if (strlen(mqtt_host) <= sizeof(Settings.mqtt_host)) {
strlcpy(Settings.mqtt_host, mqtt_host, sizeof(Settings.mqtt_host));
Settings.mqtt_user[0] = 0;
} else {
// need to split in mqtt_user first then mqtt_host
strlcpy(Settings.mqtt_user, mqtt_host, sizeof(Settings.mqtt_user));
strlcpy(Settings.mqtt_host, &mqtt_host[sizeof(Settings.mqtt_user)-1], sizeof(Settings.mqtt_host));
}
strlcpy(AWS_endpoint, mqtt_host, sizeof(AWS_endpoint));
}
#endif // USE_MQTT_AWS_IOT
bool MqttCommand(void)
{
char command [CMDSZ];
bool serviced = true;
char stemp1[TOPSZ];
char scommand[CMDSZ];
uint32_t index = XdrvMailbox.index;
uint32_t data_len = XdrvMailbox.data_len;
int32_t payload = XdrvMailbox.payload;
bool grpflg = XdrvMailbox.grpflg;
char *type = XdrvMailbox.topic;
char *dataBuf = XdrvMailbox.data;
int command_code = GetCommandCode(command, sizeof(command), type, kMqttCommands);
if (-1 == command_code) {
serviced = false; // Unknown command
}
else if (CMND_MQTTHOST == command_code) {
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
if ((data_len > 0) && (data_len <= sizeof(Settings.mqtt_host) + sizeof(Settings.mqtt_user) - 2)) {
setLongMqttHost((SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf);
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, AWS_endpoint);
#else
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_host))) {
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_HOST : dataBuf, sizeof(Settings.mqtt_host));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_host);
#endif
}
else if (CMND_MQTTPORT == command_code) {
if ((payload > 0) && (payload < 65536)) {
Settings.mqtt_port = (1 == payload) ? MQTT_PORT : payload;
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_port);
}
else if (CMND_MQTTRETRY == command_code) {
if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) {
Settings.mqtt_retry = payload;
mqtt_retry_counter = Settings.mqtt_retry;
}
Response_P(S_JSON_COMMAND_NVALUE, command, Settings.mqtt_retry);
}
else if ((CMND_STATETEXT == command_code) && (index > 0) && (index <= 4)) {
if ((data_len > 0) && (data_len < sizeof(Settings.state_text[0]))) {
for (uint32_t i = 0; i <= data_len; i++) {
if (dataBuf[i] == ' ') dataBuf[i] = '_';
}
strlcpy(Settings.state_text[index -1], dataBuf, sizeof(Settings.state_text[0]));
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, GetStateText(index -1));
}
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
else if ((CMND_MQTTFINGERPRINT == command_code) && (index > 0) && (index <= 2)) {
void CmndMqttFingerprint(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 2)) {
char fingerprint[60];
if ((data_len > 0) && (data_len < sizeof(fingerprint))) {
strlcpy(fingerprint, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? (1 == index) ? MQTT_FINGERPRINT1 : MQTT_FINGERPRINT2 : dataBuf, sizeof(fingerprint));
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(fingerprint))) {
strlcpy(fingerprint, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? (1 == XdrvMailbox.index) ? MQTT_FINGERPRINT1 : MQTT_FINGERPRINT2 : XdrvMailbox.data, sizeof(fingerprint));
char *p = fingerprint;
for (uint32_t i = 0; i < 20; i++) {
Settings.mqtt_fingerprint[index -1][i] = strtol(p, &p, 16);
Settings.mqtt_fingerprint[XdrvMailbox.index -1][i] = strtol(p, &p, 16);
}
restart_flag = 2;
}
fingerprint[0] = '\0';
for (uint32_t i = 0; i < sizeof(Settings.mqtt_fingerprint[index -1]); i++) {
snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[index -1][i]);
for (uint32_t i = 0; i < sizeof(Settings.mqtt_fingerprint[XdrvMailbox.index -1]); i++) {
snprintf_P(fingerprint, sizeof(fingerprint), PSTR("%s%s%02X"), fingerprint, (i) ? " " : "", Settings.mqtt_fingerprint[XdrvMailbox.index -1][i]);
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, fingerprint);
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, fingerprint);
}
#endif
else if (CMND_MQTTCLIENT == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_client))) {
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_CLIENT_ID : dataBuf, sizeof(Settings.mqtt_client));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_client);
}
#if !defined(USE_MQTT_TLS) || !defined(USE_MQTT_AWS_IOT) // user and password are disabled with AWS IoT
else if (CMND_MQTTUSER == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_user))) {
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_USER : dataBuf, sizeof(Settings.mqtt_user));
void CmndMqttUser(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_user))) {
strlcpy(Settings.mqtt_user, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_USER : XdrvMailbox.data, sizeof(Settings.mqtt_user));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_user);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_user);
}
else if (CMND_MQTTPASSWORD == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_pwd))) {
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut(dataBuf)) ? "" : (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_PASS : dataBuf, sizeof(Settings.mqtt_pwd));
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_pwd);
void CmndMqttPassword(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_pwd))) {
strlcpy(Settings.mqtt_pwd, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_PASS : XdrvMailbox.data, sizeof(Settings.mqtt_pwd));
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_pwd);
restart_flag = 2;
} else {
Response_P(S_JSON_COMMAND_ASTERISK, command);
Response_P(S_JSON_COMMAND_ASTERISK, XdrvMailbox.command);
}
}
#endif // USE_MQTT_AWS_IOT
else if (CMND_FULLTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_fulltopic))) {
MakeValidMqtt(1, dataBuf);
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1));
void CmndMqttHost(void)
{
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len <= sizeof(Settings.mqtt_host) + sizeof(Settings.mqtt_user) - 2)) {
setLongMqttHost((SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data);
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, AWS_endpoint);
#else
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_host))) {
strlcpy(Settings.mqtt_host, (SC_CLEAR == Shortcut()) ? "" : (SC_DEFAULT == Shortcut()) ? MQTT_HOST : XdrvMailbox.data, sizeof(Settings.mqtt_host));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_host);
#endif
}
void CmndMqttPort(void)
{
if ((XdrvMailbox.payload > 0) && (XdrvMailbox.payload < 65536)) {
Settings.mqtt_port = (1 == XdrvMailbox.payload) ? MQTT_PORT : XdrvMailbox.payload;
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, Settings.mqtt_port);
}
void CmndMqttRetry(void)
{
if ((XdrvMailbox.payload >= MQTT_RETRY_SECS) && (XdrvMailbox.payload < 32001)) {
Settings.mqtt_retry = XdrvMailbox.payload;
mqtt_retry_counter = Settings.mqtt_retry;
}
Response_P(S_JSON_COMMAND_NVALUE, XdrvMailbox.command, Settings.mqtt_retry);
}
void CmndStateText(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 4)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.state_text[0]))) {
for (uint32_t i = 0; i <= XdrvMailbox.data_len; i++) {
if (XdrvMailbox.data[i] == ' ') XdrvMailbox.data[i] = '_';
}
strlcpy(Settings.state_text[XdrvMailbox.index -1], XdrvMailbox.data, sizeof(Settings.state_text[0]));
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, GetStateText(XdrvMailbox.index -1));
}
}
void CmndMqttClient(void)
{
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_client))) {
strlcpy(Settings.mqtt_client, (SC_DEFAULT == Shortcut()) ? MQTT_CLIENT_ID : XdrvMailbox.data, sizeof(Settings.mqtt_client));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_client);
}
void CmndFullTopic(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_fulltopic))) {
MakeValidMqtt(1, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
char stemp1[TOPSZ];
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_FULLTOPIC : XdrvMailbox.data, sizeof(stemp1));
if (strcmp(stemp1, Settings.mqtt_fulltopic)) {
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
@ -744,21 +781,28 @@ bool MqttCommand(void)
restart_flag = 2;
}
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_fulltopic);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_fulltopic);
}
else if ((CMND_PREFIX == command_code) && (index > 0) && (index <= 3)) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_prefix[0]))) {
MakeValidMqtt(0, dataBuf);
strlcpy(Settings.mqtt_prefix[index -1], (SC_DEFAULT == Shortcut(dataBuf)) ? (1==index)?SUB_PREFIX:(2==index)?PUB_PREFIX:PUB_PREFIX2 : dataBuf, sizeof(Settings.mqtt_prefix[0]));
// if (Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] == '/') Settings.mqtt_prefix[index -1][strlen(Settings.mqtt_prefix[index -1])] = 0;
void CmndPrefix(void)
{
if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 3)) {
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_prefix[0]))) {
MakeValidMqtt(0, XdrvMailbox.data);
strlcpy(Settings.mqtt_prefix[XdrvMailbox.index -1], (SC_DEFAULT == Shortcut()) ? (1==XdrvMailbox.index)?SUB_PREFIX:(2==XdrvMailbox.index)?PUB_PREFIX:PUB_PREFIX2 : XdrvMailbox.data, sizeof(Settings.mqtt_prefix[0]));
// if (Settings.mqtt_prefix[XdrvMailbox.index -1][strlen(Settings.mqtt_prefix[XdrvMailbox.index -1])] == '/') Settings.mqtt_prefix[XdrvMailbox.index -1][strlen(Settings.mqtt_prefix[XdrvMailbox.index -1])] = 0;
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_INDEX_SVALUE, command, index, Settings.mqtt_prefix[index -1]);
Response_P(S_JSON_COMMAND_INDEX_SVALUE, XdrvMailbox.command, XdrvMailbox.index, Settings.mqtt_prefix[XdrvMailbox.index -1]);
}
else if (CMND_PUBLISH == command_code) {
if (data_len > 0) {
char *mqtt_part = strtok(dataBuf, " ");
}
void CmndPublish(void)
{
if (XdrvMailbox.data_len > 0) {
char *mqtt_part = strtok(XdrvMailbox.data, " ");
if (mqtt_part) {
char stemp1[TOPSZ];
strlcpy(stemp1, mqtt_part, sizeof(stemp1));
mqtt_part = strtok(nullptr, " ");
if (mqtt_part) {
@ -766,26 +810,31 @@ bool MqttCommand(void)
} else {
mqtt_data[0] = '\0';
}
MqttPublishDirect(stemp1, (index == 2));
MqttPublishDirect(stemp1, (XdrvMailbox.index == 2));
// Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_DONE);
mqtt_data[0] = '\0';
}
}
}
else if (CMND_GROUPTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.mqtt_grptopic))) {
MakeValidMqtt(0, dataBuf);
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_GRPTOPIC : dataBuf, sizeof(Settings.mqtt_grptopic));
void CmndGroupTopic(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_grptopic))) {
MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
strlcpy(Settings.mqtt_grptopic, (SC_DEFAULT == Shortcut()) ? MQTT_GRPTOPIC : XdrvMailbox.data, sizeof(Settings.mqtt_grptopic));
restart_flag = 2;
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_grptopic);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_grptopic);
}
else if (CMND_TOPIC == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.mqtt_topic))) {
MakeValidMqtt(0, dataBuf);
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
strlcpy(stemp1, (SC_DEFAULT == Shortcut(dataBuf)) ? MQTT_TOPIC : dataBuf, sizeof(stemp1));
void CmndTopic(void)
{
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.mqtt_topic))) {
MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
char stemp1[TOPSZ];
strlcpy(stemp1, (SC_DEFAULT == Shortcut()) ? MQTT_TOPIC : XdrvMailbox.data, sizeof(stemp1));
if (strcmp(stemp1, Settings.mqtt_topic)) {
Response_P((Settings.flag.mqtt_offline) ? S_OFFLINE : "");
MqttPublishPrefixTopic_P(TELE, PSTR(D_LWT), true); // Offline or remove previous retained topic
@ -793,83 +842,93 @@ bool MqttCommand(void)
restart_flag = 2;
}
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.mqtt_topic);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.mqtt_topic);
}
else if (CMND_BUTTONTOPIC == command_code) {
if (!grpflg && (data_len > 0) && (data_len < sizeof(Settings.button_topic))) {
MakeValidMqtt(0, dataBuf);
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
switch (Shortcut(dataBuf)) {
void CmndButtonTopic(void)
{
if (!XdrvMailbox.grpflg && (XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.button_topic))) {
MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
switch (Shortcut()) {
case SC_CLEAR: strlcpy(Settings.button_topic, "", sizeof(Settings.button_topic)); break;
case SC_DEFAULT: strlcpy(Settings.button_topic, mqtt_topic, sizeof(Settings.button_topic)); break;
case SC_USER: strlcpy(Settings.button_topic, MQTT_BUTTON_TOPIC, sizeof(Settings.button_topic)); break;
default: strlcpy(Settings.button_topic, dataBuf, sizeof(Settings.button_topic));
default: strlcpy(Settings.button_topic, XdrvMailbox.data, sizeof(Settings.button_topic));
}
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.button_topic);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.button_topic);
}
else if (CMND_SWITCHTOPIC == command_code) {
if ((data_len > 0) && (data_len < sizeof(Settings.switch_topic))) {
MakeValidMqtt(0, dataBuf);
if (!strcmp(dataBuf, mqtt_client)) SetShortcut(dataBuf, SC_DEFAULT);
switch (Shortcut(dataBuf)) {
void CmndSwitchTopic(void)
{
if ((XdrvMailbox.data_len > 0) && (XdrvMailbox.data_len < sizeof(Settings.switch_topic))) {
MakeValidMqtt(0, XdrvMailbox.data);
if (!strcmp(XdrvMailbox.data, mqtt_client)) { SetShortcutDefault(); }
switch (Shortcut()) {
case SC_CLEAR: strlcpy(Settings.switch_topic, "", sizeof(Settings.switch_topic)); break;
case SC_DEFAULT: strlcpy(Settings.switch_topic, mqtt_topic, sizeof(Settings.switch_topic)); break;
case SC_USER: strlcpy(Settings.switch_topic, MQTT_SWITCH_TOPIC, sizeof(Settings.switch_topic)); break;
default: strlcpy(Settings.switch_topic, dataBuf, sizeof(Settings.switch_topic));
default: strlcpy(Settings.switch_topic, XdrvMailbox.data, sizeof(Settings.switch_topic));
}
}
Response_P(S_JSON_COMMAND_SVALUE, command, Settings.switch_topic);
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, Settings.switch_topic);
}
else if (CMND_BUTTONRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) {
if (!payload) {
void CmndButtonRetain(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
for (uint32_t i = 1; i <= MAX_KEYS; i++) {
SendKey(0, i, 9); // Clear MQTT retain in broker
}
}
Settings.flag.mqtt_button_retain = payload;
Settings.flag.mqtt_button_retain = XdrvMailbox.payload;
}
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_button_retain));
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_button_retain));
}
else if (CMND_SWITCHRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) {
if (!payload) {
void CmndSwitchRetain(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
for (uint32_t i = 1; i <= MAX_SWITCHES; i++) {
SendKey(1, i, 9); // Clear MQTT retain in broker
}
}
Settings.flag.mqtt_switch_retain = payload;
Settings.flag.mqtt_switch_retain = XdrvMailbox.payload;
}
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_switch_retain));
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_switch_retain));
}
else if (CMND_POWERRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) {
if (!payload) {
void CmndPowerRetain(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
char stemp1[TOPSZ];
char scommand[CMDSZ];
for (uint32_t i = 1; i <= devices_present; i++) { // Clear MQTT retain in broker
GetTopic_P(stemp1, STAT, mqtt_topic, GetPowerDevice(scommand, i, sizeof(scommand), Settings.flag.device_index_enable));
mqtt_data[0] = '\0';
MqttPublish(stemp1, Settings.flag.mqtt_power_retain);
}
}
Settings.flag.mqtt_power_retain = payload;
Settings.flag.mqtt_power_retain = XdrvMailbox.payload;
}
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_power_retain));
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_power_retain));
}
else if (CMND_SENSORRETAIN == command_code) {
if ((payload >= 0) && (payload <= 1)) {
if (!payload) {
void CmndSensorRetain(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
if (!XdrvMailbox.payload) {
mqtt_data[0] = '\0';
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_ENERGY), Settings.flag.mqtt_sensor_retain);
}
Settings.flag.mqtt_sensor_retain = payload;
Settings.flag.mqtt_sensor_retain = XdrvMailbox.payload;
}
Response_P(S_JSON_COMMAND_SVALUE, command, GetStateText(Settings.flag.mqtt_sensor_retain));
}
else serviced = false; // Unknown command
return serviced;
Response_P(S_JSON_COMMAND_SVALUE, XdrvMailbox.command, GetStateText(Settings.flag.mqtt_sensor_retain));
}
/*********************************************************************************************\
@ -999,7 +1058,11 @@ bool Xdrv02(uint8_t function)
break;
#endif // USE_WEBSERVER
case FUNC_COMMAND:
result = MqttCommand();
int command_code = GetCommandCode(XdrvMailbox.command, CMDSZ, XdrvMailbox.topic, kMqttCommands);
if (command_code >= 0) {
MqttCommand[command_code]();
result = true;
}
break;
}
}