e12
 
Loading...
Searching...
No Matches
e12_protocol.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2023 e12.io
3 * All rights reserved.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19#ifndef H_E12_SPEC
20#define H_E12_SPEC
21
22#include <stdint.h>
23
28#define E12_MAX_PKT_SIZE 128
29
34#define E12_MAX_DATA_PAYLOAD (E12_MAX_PKT_SIZE - sizeof(e12_onwire_head_t) - 8)
35
79
80enum class e12_release_t : uint8_t {
82 STABLE = 0,
84 CANARY,
86 DEV
87};
88
89enum class ctl_op_t : uint8_t {
91 READ = 0,
93 WRITE
94};
95
100enum class e12_err_t : int8_t {
101 ERR_NONE = 0,
102 ERR_RETRY_LATER = -1,
103};
104
110enum class e12_evt_status_t : uint8_t {
111 STATUS_DONE = 0,
115};
116
121enum class e12_node_op_status_t : uint8_t {
122 STATUS_NONE = 0,
127};
128
132enum class mcu_arch_t : uint8_t { ARCH_NONE = 0, ARCH_ATMEGA328, ARCH_SAMD21 };
133
137enum class mcu_flashing_protocol_t : uint8_t {
138 PROTOCOL_NONE = 0,
141};
142
143#define E12_MAX_LOG_BUFFERS 1
144#define MAX_S_LOG_DATA 16
145typedef struct __attribute__((packed, aligned(4))) e12_log_evt {
146 uint8_t type;
147 uint8_t status;
148 uint8_t src;
149 uint8_t src_index;
150 uint32_t ts;
151 uint32_t count;
152 union {
153 uint32_t state;
154 struct {
155 uint8_t s : 1;
156 uint8_t f : 1;
157 uint8_t i : 1;
158 uint8_t : 0;
159 uint8_t in_use : 1;
160 uint8_t : 0;
161 uint8_t resv1;
162 uint8_t resv2;
163 };
164 };
165 union {
166 char s_data[MAX_S_LOG_DATA];
167 struct {
168 float f_data;
169 int32_t i_data;
170 uint32_t resv3;
171 uint32_t resv4;
172 };
173 };
175
176typedef struct __attribute__((packed, aligned(4))) e12_wakeup_data {
177 uint32_t ms;
179
180typedef struct __attribute__((packed, aligned(4))) e12_debug_blink {
181 uint32_t on_ms;
182 uint32_t off_ms;
183 uint32_t count;
185
186typedef struct __attribute__((packed, aligned(4))) e12_node_properties {
187 union {
188 uint32_t flags;
189 struct {
190 uint8_t REBOOT : 1;
191 uint8_t FACTORY_RESET : 1;
192 uint8_t DISABLE_SLEEP : 1;
193 uint8_t REFRESH_CONFIG : 1;
194 uint8_t ACTIVATE_WIFI : 1;
195 uint8_t ACTIVATE_LTE : 1;
196 uint8_t ACTIVATE_LORA : 1;
197 uint8_t ACTIVATE_WIFI_CAPTIVE_PORTAL : 1;
198 uint8_t ENCRYPT : 1;
199 uint8_t TRANSMIT : 1;
200 uint8_t LOGMASK : 1;
201 };
202 };
203 union {
204 uint64_t data;
205 struct {
206 uint32_t data1;
207 uint32_t data2;
208 };
209 };
211
212#define MAX_SSID_LEN 32
213#define MAX_PWD_LEN 32
214typedef struct __attribute__((packed, aligned(4))) e12_auth_data {
215 struct {
216 uint8_t AUTH_WIFI : 1;
217 uint8_t AUTH_LTE_AP : 1;
218 };
219 union {
220 struct {
221 char ssid[MAX_SSID_LEN];
222 char pwd[MAX_PWD_LEN];
223 } wifi;
224 };
226
227typedef struct __attribute__((packed, aligned(4))) e12_node_state {
228 struct {
229 uint8_t AUTH_OK : 1;
230 uint8_t CONFIGURED : 1;
231 uint8_t CONNECTED : 1;
232 };
233 e12_node_op_status_t op_status;
234 uint16_t next_connection_in_sec;
235 union {
236 uint32_t data;
237 struct {
238 uint32_t node_wake_up_ms; // if e12_node is in sleep mode
239 };
240 };
242
243#define MAX_LOG_SIZE (sizeof(e12_log_evt_t))
244
245typedef struct __attribute__((packed, aligned(4))) e12_header {
246 uint8_t seq;
247 uint8_t len;
248 struct {
249 uint8_t RESP_EXPECTED : 1;
250 uint8_t IS_RESPONSE : 1;
251 uint8_t : 0;
252 };
253 e12_cmd_t cmd;
255
256#define E12_MAGIC_MARKER_LEN 2
257#define E12_MAGIC_MARKER_1 (0xEC)
258#define E12_MAGIC_MARKER_2 (0xEC ^ 0xCE)
259typedef union __attribute__((packed, aligned(4))) e12_onwire_head {
260 uint32_t head;
261 struct {
262 uint8_t magic[E12_MAGIC_MARKER_LEN];
263 uint8_t len;
264 uint8_t checksum;
265 };
267
268#define E12_MAX_CMD_DATA_PAYLOAD (E12_MAX_DATA_PAYLOAD - sizeof(e12_header_t))
269#define E12_MAX_FIRMWARE_VERSION_LEN 32
270
271typedef struct __attribute__((packed, aligned(4))) {
272 e12_header_t head;
273 union {
274 uint32_t data;
275 struct {
276 uint8_t type : 1;
277 uint8_t op : 1;
278 uint8_t response : 1;
279 uint8_t : 0;
280 uint8_t pin;
281 uint16_t value;
282 };
283 };
285
286// it is expected that the head.len is set to include the
287// size of e12_header_t + size of the specific msg payload
288// so typically e.g msg_err.head.len = sizeof(msg_err);
289typedef union __attribute__((packed, aligned(4))) e12_packet {
290 uint8_t buf[E12_MAX_DATA_PAYLOAD];
291 struct {
292 e12_header_t head;
293 char data[E12_MAX_CMD_DATA_PAYLOAD];
294 } msg;
295 struct {
296 e12_header_t head;
297 uint32_t err; // 0 = OK, 1 = ERR
298 } msg_err;
299 struct {
300 e12_header_t head;
301 uint32_t ms;
302 } msg_wakeup;
303 struct {
304 e12_header_t head;
305 uint32_t ms;
306 } msg_sleep;
307 struct {
308 e12_header_t head;
310 } msg_debug_blink;
311 struct {
312 e12_header_t head;
314 } msg_node_props;
315 struct {
316 e12_header_t head;
317 e12_auth_data_t data;
318 } msg_auth_credentials;
319 struct {
320 e12_header_t head;
321 uint32_t ms;
322 } msg_time;
323 struct {
324 e12_header_t head;
325 uint32_t release_type;
326 uint32_t size;
327 char version[E12_MAX_FIRMWARE_VERSION_LEN];
328 } msg_ota;
329 struct {
330 e12_header_t head;
331 uint32_t version;
332 mcu_arch_t arch;
334 bool flashing_enabled;
335 } msg_info;
336 struct {
337 e12_header_t head;
338 union {
339 uint32_t all;
340 struct {
341 uint16_t digital;
342 uint16_t analog;
343 };
344 } pins;
345 union {
346 uint32_t all;
347 struct {
348 uint16_t digital;
349 uint16_t analog;
350 };
351 } mask;
352 } msg_dev_profile;
353 e12_ctl_msg_t msg_ctl;
354 struct {
355 e12_header_t head;
356 } msg_vmcu_ota;
358
359typedef union __attribute__((packed, aligned(4))) e12_onwire {
360 uint8_t buf[E12_MAX_PKT_SIZE];
361 struct {
363 e12_packet_t data;
364 uint8_t resp_pending : 1;
365 uint8_t : 0;
366 uint8_t recv_len;
367 uint8_t resv;
368 uint8_t resv1;
369 uint32_t ts;
370 };
372
373typedef struct __attribute__((packed, aligned(4))) e12_data {
374 uint8_t IS_JSON : 1;
375 uint8_t STORE : 1;
376 uint8_t FETCH : 1;
377 uint8_t : 0;
378 uint32_t ts_ms;
379 uint8_t data[E12_MAX_CMD_DATA_PAYLOAD - 5];
381
382typedef struct __attribute__((packed, aligned(4))) e12_device {
383 e12_data_t state;
384 e12_data_t config;
385 e12_log_evt_t log;
387
388typedef struct __attribute__((packed, aligned(4))) {
389 ctl_op_t op;
390 uint8_t pin;
391 int16_t value;
393
403class e12 {
404 private:
405 uint32_t _vid;
406 uint32_t _pid;
407 uint32_t _version;
408 uint32_t _pin_mask;
409 uint32_t _pin_io_mask;
410 e12_node_state_t _status;
411 uint32_t _mcu_fwr_version;
412 mcu_arch_t _arch;
413 mcu_flashing_protocol_t _protocol;
414 bool _mcu_flashing_enabled;
415
416 e12_onwire_t _encode_buf;
417 e12_onwire_t _decode_buf;
418 e12_device_t* _dev_ptr;
419
420 protected:
421 uint32_t _timeout;
422 uint8_t _seq;
423
428 e12_onwire_t* get_encode_buffer() { return &_encode_buf; }
429
434 e12_onwire_t* get_decode_buffer() { return &_decode_buf; }
435
440 void flush_buffer(e12_onwire_t* buf);
441
447
456 uint32_t data);
457
466 bool on_ctl(ctl_op_t op, uint8_t pin, uint32_t val);
467
468 public:
474 e12(uint32_t vid, uint32_t pid);
475
479 ~e12();
480
481 // Packet handling
482
488
495
502 e12_packet_t* decode(e12_onwire_t* pkt, uint8_t data);
503
504 // Device management
505
510 void set_e12_device(e12_device_t* p) { _dev_ptr = p; }
511
517 void set_product_info(uint32_t vid, uint32_t pid) {
518 _vid = vid;
519 _pid = pid;
520 }
521
529 void set_fwr_details(uint32_t fwr_version, mcu_arch_t arch,
530 mcu_flashing_protocol_t protocol, bool enabled) {
531 _mcu_fwr_version = fwr_version;
532 _arch = arch;
533 _protocol = protocol;
534 _mcu_flashing_enabled = enabled;
535 }
536
542 uint32_t get_fwr_version() { return _mcu_fwr_version; }
543
544 uint32_t get_pin_mask();
545 uint32_t get_pin_io_mask();
546
552 int publish_info();
553
559 int publish_profile();
560
566 bool set_pin_in(uint8_t pin_number, bool is_analog = false);
567
573 bool set_pin_out(uint8_t pin_number, bool is_analog = false);
574
580
585 void set_timeout(uint32_t ms) { _timeout = ms; }
586
591 bool is_configured() { return _status.CONFIGURED; }
592
597 void set_configured(bool status) { _status.CONFIGURED = status; }
598
603 uint32_t get_version() { return _version; }
604
609 void set_version(uint32_t v) { _version = v; }
610
618 void set_pin_mask(uint32_t pin_mask, uint32_t io_mask) {
619 _pin_mask = pin_mask;
620 _pin_io_mask = io_mask;
621 }
622
623 // Communication
624
632 virtual e12_packet_t* get_request(e12_cmd_t cmd, bool response = true,
633 void* data = 0);
634
641
647 bool get_message(e12_packet_t* data);
648
656 static uint8_t get_checksum(const char* data, uint8_t len);
657
663 virtual int on_receive(e12_packet_t* p);
664
669 virtual int wakeup_e12_node() { return 0; }
670
671 // Utility
672
678 virtual int print_buffer(e12_onwire_t* buf) { return 0; }
679
687 virtual int on_ctl_read(uint8_t pin);
688
696 virtual bool on_ctl_write(uint8_t pin, uint32_t val);
697
698 // Pure virtual functions to be implemented by derived classes
699
700 virtual int begin(void* bus, uint8_t e12_addr = 0) = 0;
701 virtual uint32_t get_time_ms() = 0;
703 virtual int send(e12_packet_t* buf, bool retry = true) = 0;
704 virtual e12_packet_t* read() = 0;
705 virtual int sleep(uint32_t ms, void* data) = 0;
706 virtual int log(uint8_t type, uint8_t status, uint32_t ts, void* data) = 0;
707 virtual int on_wakeup() = 0;
709 virtual int on_config(const char* s, int len) = 0;
710 virtual int on_get_state(char* s, int len, void* ctx) = 0;
711 virtual int on_restore_state(const char* s, int len) = 0;
712};
713
714#endif
This class represents the base class for the e12 protocol.
Definition e12_protocol.h:403
virtual bool on_ctl_write(uint8_t pin, uint32_t val)
Validates a WRITE request (PIN <- IN only)
Definition e12_protocol.cpp:543
virtual int set_node_auth_credentials(e12_auth_data_t *auth)=0
virtual int on_wakeup()=0
uint32_t _timeout
Timeout value in milliseconds.
Definition e12_protocol.h:421
virtual int sleep(uint32_t ms, void *data)=0
void set_version(uint32_t v)
Sets the version of the e12 protocol.
Definition e12_protocol.h:609
bool is_configured()
Checks if the e12 endpoint is configured.
Definition e12_protocol.h:591
e12_packet_t * decode(e12_onwire_t *pkt, uint8_t data)
Decodes the given data into a packet.
Definition e12_protocol.cpp:450
uint32_t get_fwr_version()
Get the fwr version object.
Definition e12_protocol.h:542
virtual int on_config(const char *s, int len)=0
void set_node_properties(e12_node_properties_t *props)
Sets the properties of the e12 node.
Definition e12_protocol.cpp:143
void flush_buffer(e12_onwire_t *buf)
Flushes the given buffer.
Definition e12_protocol.cpp:298
virtual e12_log_evt_t * get_log_evt()=0
virtual e12_packet_t * get_response(e12_packet_t *p)
Gets a response packet for the given packet.
Definition e12_protocol.cpp:313
void set_product_info(uint32_t vid, uint32_t pid)
Sets the product information.
Definition e12_protocol.h:517
e12_onwire_t * get_encode_buffer()
Gets the buffer for encoding packets.
Definition e12_protocol.h:428
virtual int send(e12_packet_t *buf, bool retry=true)=0
bool get_message(e12_packet_t *data)
Gets a message from the e12 protocol.
Definition e12_protocol.cpp:282
void set_e12_device(e12_device_t *p)
Sets the e12 device.
Definition e12_protocol.h:510
virtual int log(uint8_t type, uint8_t status, uint32_t ts, void *data)=0
e12_node_op_status_t set_node_status(e12_node_op_status_t status, uint32_t data)
Sets the status of the e12 node.
Definition e12_protocol.cpp:513
static uint8_t get_checksum(const char *data, uint8_t len)
Get the checksum object.
Definition e12_protocol.cpp:267
virtual int begin(void *bus, uint8_t e12_addr=0)=0
void set_pin_mask(uint32_t pin_mask, uint32_t io_mask)
Sets the bit mask for pin and io. Recommended to be used by advanced user or else use set_pin_in and ...
Definition e12_protocol.h:618
e12_node_op_status_t get_node_status()
Gets the status of the e12 node.
Definition e12_protocol.cpp:504
int publish_info()
Publish info e.g fwr version, arch, protocol etc.
Definition e12_protocol.cpp:58
uint32_t get_pin_mask()
Get the pin io mask object. top 16bit for analog, lower 16bit for digital.
Definition e12_protocol.cpp:129
e12_onwire_t * get_decode_buffer()
Gets the buffer for decoding packets.
Definition e12_protocol.h:434
virtual uint32_t get_time_ms()=0
~e12()
Destructor for the e12 class.
Definition e12_protocol.cpp:51
virtual int on_get_state(char *s, int len, void *ctx)=0
void set_fwr_details(uint32_t fwr_version, mcu_arch_t arch, mcu_flashing_protocol_t protocol, bool enabled)
Set the vmcu firmware details object.
Definition e12_protocol.h:529
bool set_pin_out(uint8_t pin_number, bool is_analog=false)
Sets the pin as output and type (analog/digital)
Definition e12_protocol.cpp:108
virtual int wakeup_e12_node()
Wakes up the e12 node.
Definition e12_protocol.h:669
bool on_ctl(ctl_op_t op, uint8_t pin, uint32_t val)
function doing basic sanity and scheduling return cmds
Definition e12_protocol.cpp:410
e12_onwire_t * encode(e12_packet_t *data)
Encodes the given data into a packet.
Definition e12_protocol.cpp:73
e12_packet_t * e12_get_packet()
Gets a new packet for the e12 protocol.
Definition e12_protocol.cpp:493
uint32_t get_version()
Gets the version of the e12 protocol.
Definition e12_protocol.h:603
virtual e12_packet_t * get_request(e12_cmd_t cmd, bool response=true, void *data=0)
Gets a request packet for the given command.
Definition e12_protocol.cpp:159
void set_configured(bool status)
Set the configured status for e12 endpoint.
Definition e12_protocol.h:597
virtual int on_receive(e12_packet_t *p)
Handles the received packet.
Definition e12_protocol.cpp:375
virtual int on_ctl_read(uint8_t pin)
allows READ state of any valid pin
Definition e12_protocol.cpp:533
virtual int on_restore_state(const char *s, int len)=0
uint8_t _seq
Sequence number for packets.
Definition e12_protocol.h:422
bool set_pin_in(uint8_t pin_number, bool is_analog=false)
Sets the pin as input and type (analog/digital)
Definition e12_protocol.cpp:89
virtual int print_buffer(e12_onwire_t *buf)
Prints the contents of the buffer.
Definition e12_protocol.h:678
virtual e12_packet_t * read()=0
void set_timeout(uint32_t ms)
Sets the timeout value.
Definition e12_protocol.h:585
uint32_t get_pin_io_mask()
Get the pin io mask object. top 16bit for analog, lower 16bit for digital.
Definition e12_protocol.cpp:137
int publish_profile()
Publish profile info e.g pin configuration.
Definition e12_protocol.cpp:65
struct __attribute__((packed, aligned(4))) e12_log_evt
Definition e12_protocol.h:145
#define MAX_S_LOG_DATA
Definition e12_protocol.h:144
ctl_op_t
Definition e12_protocol.h:89
@ READ
READ operation.
@ WRITE
WRITE operation.
#define E12_MAX_PKT_SIZE
e12 on wire max packet size
Definition e12_protocol.h:28
#define E12_MAX_CMD_DATA_PAYLOAD
Definition e12_protocol.h:268
e12_release_t
Definition e12_protocol.h:80
@ STABLE
Stable release.
@ DEV
Development release.
@ CANARY
Canary release.
e12_auth_data_t
Definition e12_protocol.h:225
#define E12_MAX_DATA_PAYLOAD
e12 max payload size in bytes in a e12 packet
Definition e12_protocol.h:34
e12_cmd_t
e12 commands
Definition e12_protocol.h:40
@ CMD_INFO
used to send current VMCU firmware version
@ CMD_NODE_SLEEP
typically sent by e12 node intending to go to sleep
@ CMD_NODE_AWAKE
typically sent by e12 node when it powers on or wake up from sleep
@ CMD_PING
typical ping cmd. responded with a "pong" string
@ CMD_DEBUG_BLINK
initiate a debug blink of led on e12 node
@ CMD_VMCU_OTA
request initiation of VMCU OTA
@ CMD_STATE
used to either send or request vendor state from e12 node
@ CMD_TIME
request current time in ms from e12 node
@ CMD_LOG
used to log a vendor event to e12 node for store and forward
@ CMD_CONFIG
used to request vendor specific configuration
@ CMD_SET_NODE_PROPERTIES
@ CMD_PROFILE
used to send device profile info e.g pins (digital/analog), in/out etc
@ CMD_OTA
request initiation of OTA
@ CMD_AUTH
used to pass authentication credential for e.g WiFi or LTE etc
@ CMD_STATUS
asked to query the e12 node for various status information
@ CMD_SCHEDULE_WAKEUP
request e12 node to wake vendor mcu after certain ms
e12_debug_blink_t
Definition e12_protocol.h:184
e12_err_t
Used to indicate the error status of an operation.
Definition e12_protocol.h:100
e12_onwire_t
Definition e12_protocol.h:371
e12_evt_status_t
Used to indicate the status of an event. This information is typically carried in a log event.
Definition e12_protocol.h:110
#define MAX_PWD_LEN
Definition e12_protocol.h:213
e12_device_t
Definition e12_protocol.h:386
e12_node_properties_t
Definition e12_protocol.h:210
e12_node_op_status_t
Used to indicate the operation status of an e12 node e.g active, sleep, ota etc.
Definition e12_protocol.h:121
e12_data_t
Definition e12_protocol.h:380
#define E12_MAGIC_MARKER_LEN
Definition e12_protocol.h:256
#define MAX_SSID_LEN
Definition e12_protocol.h:212
mcu_arch_t
Supported MCU architecture.
Definition e12_protocol.h:132
e12_ctl_msg_t
Definition e12_protocol.h:284
mcu_flashing_protocol_t
Supported MCU flashing protocols architecture.
Definition e12_protocol.h:137
e12_node_state_t
Definition e12_protocol.h:241
e12_wakeup_data_t
Definition e12_protocol.h:178
e12_header_t
Definition e12_protocol.h:254
#define E12_MAX_FIRMWARE_VERSION_LEN
Definition e12_protocol.h:269
e12_onwire_head_t
Definition e12_protocol.h:266
e12_log_evt_t
Definition e12_protocol.h:174
e12_packet_t
Definition e12_protocol.h:357
ctl_log_t
Definition e12_protocol.h:392