You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
139 lines
6.4 KiB
139 lines
6.4 KiB
/*! \file ELClient.h |
|
\brief Definitions for ELClient |
|
*/ |
|
|
|
#ifndef _EL_CLIENT_H_ |
|
#define _EL_CLIENT_H_ |
|
|
|
#include <avr/pgmspace.h> |
|
#include <HardwareSerial.h> |
|
#include <Arduino.h> |
|
#include "ELClientResponse.h" |
|
#include "FP.h" |
|
|
|
#define ESP_TIMEOUT 5000 /**< Default timeout for TCP requests when waiting for a response */ |
|
#define MQTT_MAX_PACKET_SIZE 300 |
|
|
|
// Enumeration of commands supported by esp-link, this needs to match the definition in |
|
// esp-link! |
|
typedef enum { |
|
CMD_NULL = 0, /**< null, mainly to prevent 0 from doing something bad */ |
|
CMD_SYNC, /**< Synchronize, starts the protocol */ |
|
CMD_RESP_V, /**< Response with a value */ |
|
CMD_RESP_CB, /**< Response with a callback */ |
|
CMD_WIFI_STATUS, /**< Get the wifi status */ |
|
CMD_CB_ADD, /**< Add a custom callback */ |
|
CMD_CB_EVENTS, /**< ??? */ |
|
CMD_GET_TIME, /**< Get current time in seconds since the unix epoch */ |
|
//CMD_GET_INFO, |
|
|
|
CMD_MQTT_SETUP = 10, /**< Register callback functions */ |
|
CMD_MQTT_PUBLISH, /**< Publish MQTT topic */ |
|
CMD_MQTT_SUBSCRIBE, /**< Subscribe to MQTT topic */ |
|
CMD_MQTT_LWT, /**< Define MQTT last will */ |
|
|
|
CMD_REST_SETUP = 20, /**< Setup REST connection */ |
|
CMD_REST_REQUEST, /**< Make request to REST server */ |
|
CMD_REST_SETHEADER, /**< Define HTML header */ |
|
|
|
CMD_WEB_SETUP = 30, /**< web-server setup */ |
|
CMD_WEB_DATA, /**< used for publishing web-server data */ |
|
|
|
CMD_SOCKET_SETUP = 40, /**< Setup socket connection */ |
|
CMD_SOCKET_SEND, /**< Send socket packet */ |
|
} CmdName; /**< Enumeration of commands supported by esp-link, this needs to match the definition in esp-link! */ |
|
|
|
enum WIFI_STATUS { |
|
STATION_IDLE = 0, /**< Idle status */ |
|
STATION_CONNECTING, /**< Trying to connect */ |
|
STATION_WRONG_PASSWORD, /**< Connection error, wrong password */ |
|
STATION_NO_AP_FOUND, /**< Connection error, AP not found */ |
|
STATION_CONNECT_FAIL, /**< Connection error, connection failed */ |
|
STATION_GOT_IP /**< Connected, received IP */ |
|
}; /**< Enumeration of possible WiFi status */ |
|
|
|
typedef struct { |
|
uint8_t* buf; |
|
uint16_t bufSize; |
|
uint16_t dataLen; |
|
uint8_t isEsc; |
|
} ELClientProtocol; /**< Protocol structure */ |
|
|
|
// The ELClient class implements the basic protocol to communicate with esp-link using SLIP. |
|
// The SLIP protocol just provides framing, i.e., it delineates the start and end of packets. |
|
// The format of each packet is dictated by ELClient and consists of a 2-byte command, a 2-byte |
|
// count of arguments, a 4-byte callback addr, then the arguments, and finally 1 2-byte CRC. |
|
// |
|
// ELClient handles communication set-up and reset. It has to take a number of scenarios into |
|
// account, including simultaneous power-on reset of arduino and esp-link, spontaneous reset of |
|
// esp-link, and reset of arduino. Returning to a consistent state in all these cases is handled by |
|
// the Sync function and null commands. |
|
// |
|
// When ELClient starts it needs to send a Sync to esp-link. This clears all state and callbacks on |
|
// the esp-link side and then ELClient can install callbacks, etc. In order to catch the cases where |
|
// esp-link resets ELClient ensures that it sends periodic commands to esp-link and checks whether |
|
// esp-link responds with a "not synced" error, which indicates that it reset. If such an error |
|
// occurs ELClient starts with a fresh Sync. Unfortunately this has to be propagated up the |
|
// communication layers because the client may have to re-subscribe to MQTT messages or to certain |
|
// callbacks. |
|
class ELClient { |
|
public: |
|
// Create an esp-link client based on a stream and with a specified debug output stream. |
|
ELClient(Stream* serial, Stream* debug); |
|
// Create an esp-link client based on a stream with no debug output |
|
ELClient(Stream* serial); |
|
|
|
Stream* _debug; /**< Data stream for debug use */ |
|
|
|
//== Requests |
|
// Start a request. cmd is the command to execute, value is either the address of a function |
|
// to call with a response or a first argument to the command if there is no CB. |
|
// Argc is the number of additional arguments |
|
void Request(uint16_t cmd, uint32_t value, uint16_t argc); |
|
// Add a an argument consisting of a data block to a request |
|
void Request(const void* data, uint16_t len); |
|
// Add a an argument consisting of a data block in flash to a request |
|
void Request(const __FlashStringHelper* data, uint16_t len); |
|
// Finish a request |
|
void Request(void); |
|
|
|
//== Responses |
|
// Process the input stream, call this in loop() to dispatch call-back based responses. |
|
// Callbacks on FP are invoked with an ElClientResponse pointer as argument. |
|
// Returns the ELClientPacket if a non-callback response was received, typically this is |
|
// used to create an ELClientResponse. Returns NULL if no response needs to be processed. |
|
ELClientPacket *Process(void); |
|
// Busy wait for a response with a timeout in milliseconds, returns an ELClientPacket |
|
// if a response was recv'd and NULL otherwise. The ELClientPacket is typically used to |
|
// create an ELClientResponse. |
|
ELClientPacket *WaitReturn(uint32_t timeout=ESP_TIMEOUT); |
|
|
|
//== Commands built-into ELClient |
|
// Initialize and synchronize communication with esp-link with a timeout in milliseconds, |
|
// and remove all existing callbacks. Registers the wifiCb and returns true on success |
|
boolean Sync(uint32_t timeout=ESP_TIMEOUT); |
|
// Request the wifi status |
|
void GetWifiStatus(void); |
|
|
|
// Callback for wifi status changes. This callback must be attached before calling Sync |
|
FP<void, void*> wifiCb; /**< Pointer to callback function */ |
|
// Callback to indicate protocol reset, typically due to esp-link resetting. The callback |
|
// should call Sync and perform any other callback registration afresh. |
|
void (*resetCb)(); /**< Pointer to callback function */ |
|
|
|
//private: |
|
Stream* _serial; /**< Serial stream for communication with ESP */ |
|
boolean _debugEn; /**< Flag for debug - True = enabled, False = disabled */ |
|
uint16_t crc; /**< CRC checksum */ |
|
ELClientProtocol _proto; /**< Protocol structure */ |
|
uint8_t _protoBuf[MQTT_MAX_PACKET_SIZE]; /**< Protocol buffer */ |
|
|
|
void init(); |
|
void DBG(const char* info); |
|
ELClientPacket *protoCompletedCb(void); |
|
void write(uint8_t data); |
|
void write(void* data, uint16_t len); |
|
uint16_t crc16Add(unsigned char b, uint16_t acc); |
|
uint16_t crc16Data(const unsigned char *data, uint16_t len, uint16_t acc); |
|
}; |
|
#endif // _EL_CLIENT_H_
|
|
|