#include #include #include #include static const char* SETUP_SSID = "sensor-setup"; static const byte EEPROM_INITIALIZED_MARKER = 0xF1; //Just a magic number static const uint8_t SETUP_MODE_PIN = D7; static const uint8_t HAN_RX_PIN = 3; //RX for Serial. Seems to be GPIO3 on most boards ESP8266WebServer server(80); DNSServer dnsServer; static const byte DNS_PORT = 53; IPAddress apIP(192, 168, 4, 1); #define MAX_SSID_LENGTH (32) #define MAX_PASSWORD_LENGTH (64) char ssid_param[MAX_SSID_LENGTH+1]; char password_param[MAX_PASSWORD_LENGTH+1]; boolean in_setup_mode; static const int DATABUFFER_LENGTH = 256; uint8_t data_buffer[DATABUFFER_LENGTH]; volatile int databuffer_pos; volatile bool buffer_overflow; volatile unsigned long databuffer_receive_time; static unsigned long MINIMUM_TIME_BETWEEN_PACKETS = 1000L; static const uint8_t SLIP_END = 0xC0; static const uint8_t SLIP_ESC = 0xDB; static const uint8_t SLIP_ESC_END = 0xDC; static const uint8_t SLIP_ESC_ESC = 0xDD; static const unsigned CRC16_XMODEM_POLY = 0x1021; static const SerialConfig SERIAL_MODE = SERIAL_8N1; void read_persistent_string(char* s, int max_length, int& adr) { int i = 0; byte c; do { c = EEPROM.read(adr++); if (i(c); } } while (c!=0); s[i] = 0; } void read_persistent_params() { int adr = 0; if (EEPROM_INITIALIZED_MARKER != EEPROM.read(adr++)) { ssid_param[0] = 0; password_param[0] = 0; } else { read_persistent_string(ssid_param, MAX_SSID_LENGTH, adr); read_persistent_string(password_param, MAX_PASSWORD_LENGTH, adr); } } void write_persistent_string(const char* s, size_t max_length, int& adr) { for (int i=0; i"\ ""\ ""\ ""\ "Setup"\ ""\ ""\ ""\ "
"\ "SSID:
"\ "Password:
"\ ""\ "
"\ ""\ ""); server.send(200, F("text/html"), body); } } void serialEvent() { unsigned long now = millis(); if (nowMINIMUM_TIME_BETWEEN_PACKETS) { databuffer_pos = 0; buffer_overflow = false; databuffer_receive_time = now; } uint8_t b; while (Serial.available()) { b = Serial.read(); if (0==databuffer_pos && SLIP_END==b) //FRAME_END can be sent to force reset of buffer { continue; } if ((databuffer_pos+1) < DATABUFFER_LENGTH) //Room for one more byte? { //ESC ESC_END => END (0xDB 0xDC => 0xC0) //ESC ESC_ESC => ESC (0xDB 0xDD => 0xDB) if (databuffer_pos>0 && SLIP_ESC==data_buffer[databuffer_pos-1]) { if (SLIP_ESC_END==b) { data_buffer[databuffer_pos-1] = SLIP_END; continue; } else if (SLIP_ESC_ESC==b) { //data_buffer[databuffer_pos-1] = SLIP_ESC; //Already has this value continue; } } data_buffer[databuffer_pos++] = b; } else { buffer_overflow = true; } } } char* toHex(char* buffer, unsigned int value) { buffer[0]='0'; buffer[1]='x'; uint8_t length = value<256?2:4; for (uint8_t i=length; i>0; i--) { buffer[i+1] = ((value&0x000F)<=9?'0':'A'-10)+(value&0x000F); value = value >> 4; } buffer[length+2] = 0; return buffer; } void dumpHex(const uint8_t* data_buffer, int databuffer_pos, String& response, uint8_t start_pos, uint8_t length) { char tmp_buffer[7]; if(start_pos!=0) { response += "\n"; } response.concat(toHex(tmp_buffer, start_pos)); response += ":"; for (int i=0; idatabuffer_pos) ? 0 : data_buffer[start_pos+3]<<24 | data_buffer[start_pos+2]<<16 | data_buffer[start_pos+1]<<8 | data_buffer[start_pos]; } unsigned short hexToShort(const uint8_t* data_buffer, int databuffer_pos, uint8_t start_pos) { return ((start_pos+2)>databuffer_pos) ? 0 : data_buffer[start_pos+1]<<8 | data_buffer[start_pos]; } boolean validCrc16(const uint8_t* data_buffer, int databuffer_pos, uint8_t content_start_pos, uint8_t content_length, uint8_t crc_start_pos) { if ((content_start_pos+content_length)>databuffer_pos || (crc_start_pos+2)>databuffer_pos) { return false; } unsigned crc = 0; for (uint8_t i=0; i