Browse Source

add missing file

pull/1027/head
lumapu 2 years ago
parent
commit
62c9cb7529
  1. 173
      src/utils/improv.h

173
src/utils/improv.h

@ -0,0 +1,173 @@
//-----------------------------------------------------------------------------
// 2023 Ahoy, https://github.com/lumpapu/ahoy
// Creative Commons - http://creativecommons.org/licenses/by-nc-sa/4.0/deed
//-----------------------------------------------------------------------------
#ifndef __IMPROV_H__
#define __IMPROV_H__
#include <cstring>
#include <functional>
#include "dbg.h"
// https://www.improv-wifi.com/serial/
// https://github.com/jnthas/improv-wifi-demo/blob/main/src/esp32-wifiimprov/esp32-wifiimprov.ino
// configure ESP through Serial interface
class Improv {
public:
void setup(const char *devName, const char *version) {
mDevName = devName;
mVersion = version;
}
void tickSerial(void) {
if(Serial.available() == 0)
return;
uint8_t buf[80];
uint8_t len = Serial.readBytes(buf, 80);
dumpBuf(buf, len);
if(!checkPaket(&buf[0], 13, [this](uint8_t type, uint8_t buf[], uint8_t len) {
parsePayload(type, buf, len);
})) {
DBGPRINT(F("checkHeader failed"));
}
}
private:
enum State : uint8_t {
STATE_STOPPED = 0x00,
STATE_AWAITING_AUTHORIZATION = 0x01,
STATE_AUTHORIZED = 0x02,
STATE_PROVISIONING = 0x03,
STATE_PROVISIONED = 0x04,
};
enum Command : uint8_t {
UNKNOWN = 0x00,
WIFI_SETTINGS = 0x01,
IDENTIFY = 0x02,
GET_CURRENT_STATE = 0x02,
GET_DEVICE_INFO = 0x03,
GET_WIFI_NETWORKS = 0x04,
BAD_CHECKSUM = 0xFF,
};
enum ImprovSerialType : uint8_t {
TYPE_CURRENT_STATE = 0x01,
TYPE_ERROR_STATE = 0x02,
TYPE_RPC = 0x03,
TYPE_RPC_RESPONSE = 0x04
};
void dumpBuf(uint8_t buf[], uint8_t len) {
for(uint8_t i = 0; i < len; i++) {
DHEX(buf[i]);
DBGPRINT(" ");
}
DBGPRINTLN("");
}
inline uint8_t buildChecksum(uint8_t buf[], uint8_t len) {
uint8_t calc = 0;
for(uint8_t i = 0; i < (len - 1); i++) {
calc += buf[i];
}
return calc;
}
inline bool checkChecksum(uint8_t buf[], uint8_t len) {
return ((buildChecksum(buf, len)) == buf[len]);
}
bool checkPaket(uint8_t buf[], uint8_t len, std::function<void(uint8_t type, uint8_t b[], uint8_t l)> cb) {
if(len < 11)
return false;
if(0 != strncmp((char*)buf, "IMPROV", 6))
return false;
// verison check (only version 1 is supported!)
if(0x01 != buf[6])
return false;
if(!checkChecksum(buf, (6+3 + buf[9])))
return false;
cb(buf[7], &buf[9], buf[8]);
return true;
}
uint8_t char2Improv(const char *str, uint8_t buf[]) {
uint8_t len = strlen(str);
buf[0] = len;
for(uint8_t i = 1; i <= len; i++) {
buf[i] = (uint8_t)str[i-1];
}
return len + 1;
}
void sendDevInfo(void) {
uint8_t buf[100];
buf[7] = TYPE_RPC_RESPONSE;
buf[9] = GET_DEVICE_INFO; // repsonse to cmd
uint8_t p = 11;
// firmware name
p += char2Improv("AhoyDTU", &buf[p]);
// firmware version
p += char2Improv(mVersion, &buf[p]);
// chip variant
#if defined(ESP32)
p += char2Improv("ESP32", &buf[p]);
#else
p += char2Improv("ESP8266", &buf[p]);
#endif
// device name
p += char2Improv(mDevName, &buf[p]);
buf[10] = p - 11; // sub length
buf[8] = p - 9; // paket length
sendPaket(buf, p);
}
void setState(uint8_t state) {
uint8_t buf[20];
buf[7] = TYPE_CURRENT_STATE;
buf[8] = 0x01;
buf[9] = state;
sendPaket(buf, 10);
}
void sendPaket(uint8_t buf[], uint8_t len) {
buf[0] = 'I';
buf[1] = 'M';
buf[2] = 'P';
buf[3] = 'R';
buf[4] = 'O';
buf[5] = 'V';
buf[6] = 1; // protocol version
buf[len] = buildChecksum(buf, (len+1));
len++;
dumpBuf(buf, len);
Serial.write(buf, len);
}
void parsePayload(uint8_t type, uint8_t buf[], uint8_t len) {
DBGPRINTLN(F("parsePayload"));
if(TYPE_RPC == type) {
if(GET_CURRENT_STATE == buf[0])
setState(0x00);
else if(GET_DEVICE_INFO == buf[0])
sendDevInfo();
}
}
const char *mDevName, *mVersion;
};
#endif /*__IMPROV_H__*/
Loading…
Cancel
Save