Shrink improv

This commit is contained in:
Theo Arends 2022-04-03 14:48:30 +02:00
parent db387c959e
commit 5672e0165a

View File

@ -55,10 +55,9 @@ enum ImprovSerialType {
static const uint8_t IMPROV_SERIAL_VERSION = 1;
struct IMPROV {
uint32_t last_read_byte;
uint8_t wifi_timeout;
uint8_t seriallog_level;
bool message;
uint8_t version;
} Improv;
/*********************************************************************************************/
@ -142,40 +141,7 @@ void ImprovSendSetting(uint32_t command) {
ImprovSendResponse((uint8_t*)data, len +3);
}
bool ImprovParseSerialByte(void) {
// 0 1 2 3 4 5 6 7 8 9 10 11 8 + le +1
// I M P R O V ve ty le co pl data ... \n
// 49 4D 50 52 4F 56 01 03 xx yy zz ........ 0A
if (6 == TasmotaGlobal.serial_in_byte_counter) {
return (IMPROV_SERIAL_VERSION == TasmotaGlobal.serial_in_byte);
}
if (TasmotaGlobal.serial_in_byte_counter <= 8) {
return true; // Wait for type and length
}
uint32_t data_len = TasmotaGlobal.serial_in_buffer[8];
if (TasmotaGlobal.serial_in_byte_counter <= 9 + data_len) { // Receive including '\n'
return true; // Wait for data
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("IMP: Rcvd '%*_H'"), TasmotaGlobal.serial_in_byte_counter, TasmotaGlobal.serial_in_buffer);
TasmotaGlobal.serial_in_byte_counter--; // Drop '\n'
uint8_t checksum = 0x00;
for (uint32_t i = 0; i < TasmotaGlobal.serial_in_byte_counter; i++) {
checksum += TasmotaGlobal.serial_in_buffer[i];
}
if (checksum != TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter]) {
ImprovSendError(IMPROV_ERROR_INVALID_RPC); // 0x01 - CRC error
return false;
}
uint32_t type = TasmotaGlobal.serial_in_buffer[7];
if (IMPROV_TYPE_RPC == type) { // 0x03
uint32_t data_length = TasmotaGlobal.serial_in_buffer[10];
if (data_length != data_len - 2) {
return false;
}
void ImprovReceived(void) {
uint32_t command = TasmotaGlobal.serial_in_buffer[9];
switch (command) {
case IMPROV_WIFI_SETTINGS: { // 0x01
@ -208,7 +174,7 @@ bool ImprovParseSerialByte(void) {
case IMPROV_GET_CURRENT_STATE: { // 0x02
ImprovSendState(RtcSettings.improv_state);
if (IMPROV_STATE_PROVISIONED == RtcSettings.improv_state) {
ImprovSendSetting(IMPROV_GET_CURRENT_STATE);
ImprovSendSetting(command);
}
break;
}
@ -216,7 +182,7 @@ bool ImprovParseSerialByte(void) {
char data[200];
uint32_t len = snprintf_P(data, sizeof(data), PSTR("01\nTasmota\n%s\n%s\n%s\n"),
TasmotaGlobal.version, GetDeviceHardware().c_str(), SettingsText(SET_DEVICENAME));
data[0] = IMPROV_GET_DEVICE_INFO;
data[0] = command;
ImprovSendResponse((uint8_t*)data, len);
break;
}
@ -238,9 +204,7 @@ bool ImprovParseSerialByte(void) {
for (uint32_t i = 0; i < n; i++) {
if (-1 == indices[i]) { continue; }
String cssid = WiFi.SSID(indices[i]);
// uint32_t cschn = WiFi.channel(indices[i]);
for (uint32_t j = i + 1; j < n; j++) {
// if ((cssid == WiFi.SSID(indices[j])) && (cschn == WiFi.channel(indices[j]))) {
if (cssid == WiFi.SSID(indices[j])) {
indices[j] = -1; // Set dup aps to index -1
}
@ -256,13 +220,13 @@ bool ImprovParseSerialByte(void) {
// Send each ssid separately to avoid overflowing the buffer
uint32_t len = snprintf_P(data, sizeof(data), PSTR("01\n%s\n%d\n%s\n"),
ssid_copy.c_str(), rssi, (encryption)?"NO":"YES");
data[0] = IMPROV_GET_WIFI_NETWORKS;
data[0] = command;
ImprovSendResponse((uint8_t*)data, len);
}
}
// Send empty response to signify the end of the list.
data[0] = IMPROV_GET_WIFI_NETWORKS;
data[0] = command;
ImprovSendResponse((uint8_t*)data, 3); // Empty string
break;
}
@ -274,9 +238,6 @@ bool ImprovParseSerialByte(void) {
default:
ImprovSendError(IMPROV_ERROR_UNKNOWN_RPC); // 0x02 - Unknown payload
}
}
return false;
}
/*********************************************************************************************/
@ -286,27 +247,45 @@ bool ImprovSerialInput(void) {
if (6 == TasmotaGlobal.serial_in_byte_counter) {
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = 0;
if (!strcmp_P(TasmotaGlobal.serial_in_buffer, PSTR("IMPROV"))) {
if (IMPROV_SERIAL_VERSION == TasmotaGlobal.serial_in_byte) {
Improv.seriallog_level = TasmotaGlobal.seriallog_level;
TasmotaGlobal.seriallog_level = 0; // Disable seriallogging interfering with IMPROV
Improv.last_read_byte = millis();
Improv.message = true;
Improv.version = IMPROV_SERIAL_VERSION;
}
}
if (Improv.message) {
uint32_t now = millis();
if (now - Improv.last_read_byte < 50) {
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter] = TasmotaGlobal.serial_in_byte;
if (ImprovParseSerialByte()) {
TasmotaGlobal.serial_in_byte_counter++;
TasmotaGlobal.serial_in_byte = 0;
Improv.last_read_byte = now;
return false;
}
if (IMPROV_SERIAL_VERSION == Improv.version) {
TasmotaGlobal.serial_in_buffer[TasmotaGlobal.serial_in_byte_counter++] = TasmotaGlobal.serial_in_byte;
// 0 1 2 3 4 5 6 7 8 9 10 11 8 + le +1
// I M P R O V ve ty le co pl data ... \n
// 49 4D 50 52 4F 56 01 03 xx yy zz ........ 0A
if (TasmotaGlobal.serial_in_byte_counter > 8) { // Wait for length
uint32_t data_len = TasmotaGlobal.serial_in_buffer[8];
if (TasmotaGlobal.serial_in_byte_counter > 10 + data_len) { // Receive including '\n'
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("IMP: Rcvd '%*_H'"), TasmotaGlobal.serial_in_byte_counter, TasmotaGlobal.serial_in_buffer);
uint32_t checksum_pos = TasmotaGlobal.serial_in_byte_counter -2;
uint8_t checksum = 0x00;
for (uint32_t i = 0; i < checksum_pos; i++) {
checksum += TasmotaGlobal.serial_in_buffer[i];
}
if (checksum != TasmotaGlobal.serial_in_buffer[checksum_pos]) {
ImprovSendError(IMPROV_ERROR_INVALID_RPC); // 0x01 - CRC error
}
else if (IMPROV_TYPE_RPC == TasmotaGlobal.serial_in_buffer[7]) {
uint32_t data_length = TasmotaGlobal.serial_in_buffer[10];
if (data_length == data_len - 2) {
ImprovReceived();
}
}
Improv.message = false;
Improv.version = 0; // Done
TasmotaGlobal.seriallog_level = Improv.seriallog_level; // Restore seriallogging
return true;
}
}
TasmotaGlobal.serial_in_byte = 0;
}
return false;
}