10000 esp/espnow: mac/keys/msgs may also be bytearrays. · micropython/micropython@1356b48 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1356b48

Browse files
committed
esp/espnow: mac/keys/msgs may also be bytearrays.
- send()/add_peer()/mod_peer()/set_pmk() accept bytes, bytearrays or strings for mac addresses, keys and messages. (Uses mp_get_buffer_raise() to get backing data buffers from objs, so we can use any object which supports the buffer protocol. - Also make "initialised" flag a member of the espnow singleton instead of a global static.
1 parent 4144ba4 commit 1356b48

File tree

2 files changed

+74
-88
lines changed

2 files changed

+74
-88
lines changed

ports/esp32/esp_espnow.c

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static const size_t BUSY_WAIT_MS = 25; // milliseconds
7979
typedef struct _esp_espnow_obj_t {
8080
mp_obj_base_t base;
8181

82+
int initialised;
8283
buffer_t recv_buffer; // A buffer for received packets
8384
size_t recv_buffer_size;
8485
size_t sent_packets; // Count of sent packets
@@ -124,18 +125,13 @@ static int _buf_get_data_from_packet(const uint8_t *buf, size_t size,
124125
const uint8_t **peer_addr,
125126
const uint8_t **msg, size_t *msg_len);
126127
// These functions help cleanup boiler plate code for processing args.
127-
static const uint8_t *_get_str(mp_obj_t obj);
128-
static size_t _get_len(mp_obj_t obj);
129128
static bool _get_bool(mp_obj_t obj);
130-
static const uint8_t *_get_bytes(mp_obj_t obj);
131129
static const uint8_t *_get_bytes_len(mp_obj_t obj, size_t len);
132130
static const uint8_t *_get_peer(mp_obj_t obj);
133131

134132
// ### Initialisation and Config functions
135133
//
136134

137-
static int initialized = 0;
138-
139135
// Allocate and initialise the ESPNow module singleton
140136
// Returns the initialise singleton.
141137
STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args,
@@ -145,14 +141,17 @@ STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args,
145141
return espnow_singleton;
146142
}
147143
esp_espnow_obj_t *self = m_malloc0(sizeof(esp_espnow_obj_t));
144+
self->initialised = 0;
148145
self->base.type = &esp_espnow_type;
149146
self->recv_buffer_size = DEFAULT_RECV_BUFFER_SIZE;
150147
self->recv_timeout = DEFAULT_RECV_TIMEOUT;
151148

152149
// Allocate and initialise the "callee-owned" tuple for irecv().
153150
uint8_t msg_tmp[ESP_NOW_MAX_DATA_LEN], peer_tmp[ESP_NOW_ETH_ALEN];
154-
self->irecv_peer = MP_OBJ_TO_PTR(mp_obj_new_bytearray(ESP_NOW_ETH_ALEN, peer_tmp));
155-
self->irecv_msg = MP_OBJ_TO_PTR(mp_obj_new_bytearray(ESP_NOW_MAX_DATA_LEN, msg_tmp));
151+
self->irecv_peer = MP_OBJ_TO_PTR(
152+
mp_obj_new_bytearray(ESP_NOW_ETH_ALEN, peer_tmp));
153+
self->irecv_msg = MP_OBJ_TO_PTR(
154+
mp_obj_new_bytearray(ESP_NOW_MAX_DATA_LEN, msg_tmp));
156155
self->irecv_tuple = mp_obj_new_tuple(2, NULL);
157156
self->irecv_tuple->items[0] = MP_OBJ_FROM_PTR(self->irecv_peer);
158157
self->irecv_tuple->items[1] = MP_OBJ_FROM_PTR(self->irecv_msg);
@@ -175,14 +174,14 @@ recv_cb(const uint8_t *mac_addr, const uint8_t *data, int len);
175174
// allocate the recv data buffers.
176175
STATIC mp_obj_t espnow_init(mp_obj_t _) {
177176
esp_espnow_obj_t *self = espnow_singleton;
178-
if (initialized) {
177+
if (self->initialised) {
179178
return mp_const_none;
180179
}
181180
self->recv_buffer = buffer_init(self->recv_buffer_size);
182181
self->recv_buffer_size = buffer_size(self->recv_buffer);
183182
buffer_print("Recv buffer", self->recv_buffer);
184183

185-
initialized = 1;
184+
self->initialised = 1;
186185
esp_initialise_wifi();
187186
check_esp_err(esp_now_init());
188187
check_esp_err(esp_now_register_recv_cb(recv_cb));
@@ -197,14 +196,16 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_init_obj, espnow_init);
197196
// deallocate the recv data buffers.
198197
STATIC mp_obj_t espnow_deinit(mp_obj_t _) {
199198
esp_espnow_obj_t *self = espnow_singleton;
200-
if (initialized) {
201-
check_esp_err(esp_now_unregister_recv_cb());
202-
check_esp_err(esp_now_unregister_send_cb());
203-
check_esp_err(esp_now_deinit());
204-
initialized = 0;
205-
buffer_release(self->recv_buffer);
206-
self->peer_count = 0; // esp_now_deinit() removes all peers.
199+
if (!self->initialised) {
200+
return mp_const_none;
207201
}
202+
check_esp_err(esp_now_unregister_recv_cb());
203+
check_esp_err(esp_now_unregister_send_cb());
204+
check_esp_err(esp_now_deinit());
205+
self->initialised = 0;
206+
buffer_release(self->recv_buffer);
207+
self->peer_count = 0; // esp_now_deinit() removes all peers.
208+
208209
return mp_const_none;
209210
}
210211
STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_deinit_obj, espnow_deinit);
@@ -241,8 +242,8 @@ STATIC mp_obj_t espnow_config(
241242
uintptr_t name = (uintptr_t)args[ARG_get].u_obj;
242243
if (name == QS(MP_QSTR_rxbuf)) {
243244
return mp_obj_new_int(
244-
(initialized ? buffer_size(self->recv_buffer)
245-
: self->recv_buffer_size));
245+
(self->initialised ? buffer_size(self->recv_buffer)
246+
: self->recv_buffer_size));
246247
} else if (name == QS(MP_QSTR_timeout)) {
247248
return mp_obj_new_int(self->recv_timeout);
248249
} else {
@@ -335,7 +336,7 @@ STATIC void IRAM_ATTR recv_cb(
335336
// Timeout is set in args or by default.
336337
static int _wait_for_recv_packet(size_t n_args, const mp_obj_t *args) {
337338
esp_espnow_obj_t *self = espnow_singleton;
338-
if (!initialized) {
339+
if (!self->initialised) {
339340
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("not initialised"));
340341
}
341342
// Setup the timeout and wait for a packet to arrive
@@ -487,17 +488,22 @@ static int _do_espnow_send(
487488
// False if sync==True and message is not received by any recipients
488489
// Raises: EAGAIN if the internal espnow buffers are full.
489490
STATIC mp_obj_t espnow_send(size_t n_args, const mp_obj_t *args) {
490-
if (!initialized) {
491+
esp_espnow_obj_t *self = espnow_singleton;
492+
if (!self->initialised) {
491493
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("not initialised"));
492494
}
493495
// Check the various combinations of input arguments
494496
mp_obj_t peer = (n_args > 2) ? args[1] : mp_const_none;
495497
mp_obj_t msg = (n_args > 2) ? args[2] : (n_args == 2) ? args[1] : MP_OBJ_NULL;
496498
mp_obj_t sync = (n_args > 3) ? args[3] : mp_const_true;
497499

500+
// Get a pointer to the buffer of obj
501+
mp_buffer_info_t bufinfo;
502+
mp_get_buffer_raise(msg, &bufinfo, MP_BUFFER_READ);
503+
498504
int failed_responses =
499505
_do_espnow_send(
500-
_get_peer(peer), _get_str(msg), _get_len(msg), _get_bool(sync));
506+
_get_peer(peer), bufinfo.buf, bufinfo.len, _get_bool(sync));
501507
if (failed_responses < 0) {
502508
mp_raise_OSError(MP_EAGAIN);
503509
}
@@ -531,7 +537,7 @@ STATIC bool _update_peer_info(
531537
// Key can be <= 16 bytes - padded with '\0'.
532538
memcpy(peer->lmk,
533539
_get_bytes_len(obj, ESP_NOW_KEY_LEN),
534-
_get_len(obj));
540+
ESP_NOW_KEY_LEN);
535541
}
536542
}
537543
if (args[ARG_channel].u_int != -1) {
@@ -681,7 +687,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_peer_count_obj, espnow_peer_count);
681687
// Read an ESPNow packet into a stream buffer
682688
STATIC mp_uint_t espnow_stream_read(mp_obj_t self_in, void *buf_in,
683689
mp_uint_t size, int *errcode) {
684-
if (!initialized) {
690+
esp_espnow_obj_t *self = espnow_singleton;
691+
if (!self->initialised) {
685692
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("not initialised"));
686693
}
687694

@@ -770,7 +777,8 @@ STATIC mp_uint_t espnow_stream_ioctl(mp_obj_t self_in, mp_uint_t request,
770777

771778
// Iterating over ESPNow returns tuples of (peer_addr, message)...
772779
STATIC mp_obj_t espnow_iternext(mp_obj_t self_in) {
773-
if (!initialized) {
780+
esp_espnow_obj_t *self = espnow_singleton;
781+
if (!self->initialised) {
774782
return MP_OBJ_STOP_ITERATION;
775783
}
776784
return espnow_irecv(1, &self_in);
@@ -846,38 +854,20 @@ const mp_obj_module_t mp_module_esp_espnow = {
846854
};
847855

848856
// These functions help cleanup boiler plate code for processing args.
849-
static const uint8_t *_get_str(mp_obj_t obj) {
850-
size_t len;
851-
return (const uint8_t *)mp_obj_str_get_data(obj, &len);
852-
}
853-
854-
static size_t _get_len(mp_obj_t obj) {
855-
size_t len;
856-
(void)mp_obj_str_get_data(obj, &len);
857-
return len;
858-
}
859-
860857
static bool _get_bool(mp_obj_t obj) {
861858
if (obj == mp_const_true || obj == mp_const_false) {
862859
return obj == mp_const_true;
863860
}
864861
mp_raise_TypeError(MP_ERROR_TEXT("Expected True or False"));
865862
}
866863

867-
static const uint8_t *_get_bytes(mp_obj_t obj) {
868-
if (!mp_obj_is_type(obj, &mp_type_bytes)) {
869-
mp_raise_TypeError(MP_ERROR_TEXT("not bytes"));
870-
}
871-
size_t len;
872< 10000 /td>-
return (const uint8_t *)mp_obj_str_get_data(obj, &len);
873-
}
874-
875864
static const uint8_t *_get_bytes_len(mp_obj_t obj, size_t len) {
876-
const uint8_t *p = _get_bytes(obj);
877-
if (_get_len(obj) != len) {
865+
mp_buffer_info_t bufinfo;
866+
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
867+
if (bufinfo.len != len) {
878868
mp_raise_ValueError(MP_ERROR_TEXT("wrong length"));
879869
}
880-
return p;
870+
return (const uint8_t *)bufinfo.buf;
881871
}
882872

883873
// Check obj is a byte string and return ptr to mac address.

ports/esp8266/esp_espnow.c

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
#define ESP_NOW_KEY_LEN (16)
6060
#define ESP_NOW_ETH_ALEN (6)
6161
#define ESP_NOW_SEND_SUCCESS (0)
62-
// Will be unsued....
6362
#define ESP_ERR_ESPNOW_NO_MEM (-77777)
6463
#define ESP_OK (0)
6564
#define ESP_NOW_MAX_TOTAL_PEER_NUM (20)
@@ -100,8 +99,8 @@ static const size_t BUSY_WAIT_MS = 25; // milliseconds
10099
typedef struct _esp_espnow_obj_t {
101100
mp_obj_base_t base;
102101

102+
int initialised;
103103
buffer_t recv_buffer; // A buffer for received packets
104-
size_t recv_buffer_size;
105104
size_t sent_packets;
106105
volatile size_t recv_packets;
107106
size_t dropped_rx_pkts;
@@ -134,12 +133,12 @@ static void _buf_put_recv_data(buffer_t buf, const uint8_t *mac,
134133
static bool _buf_get_recv_data(buffer_t buf, uint8_t *mac, uint8_t *msg, int msg_len);
135134
// Peek at the next recv packet in the ring buffer to get the message length.
136135
static int _buf_peek_message_length(buffer_t buf);
136+
// Get a pointer to a str, bytes or bytearray object's data
137+
static uint8_t *_get_bytes_len(mp_obj_t obj, size_t size);
137138

138139
// ### Initialisation and Config functions
139140
//
140141

141-
static int initialized = 0;
142-
143142
STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args,
144143
size_t n_kw, const mp_obj_t *all_args) {
145144

@@ -148,7 +147,6 @@ STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args,
148147
}
149148
esp_espnow_obj_t *self = m_malloc0(sizeof(esp_espnow_obj_t));
150149
self->base.type = &esp_espnow_type;
151-
self->recv_buffer_size = DEFAULT_RECV_BUFFER_SIZE;
152150
self->recv_timeout = DEFAULT_RECV_TIMEOUT;
153151

154152
// Allocate and initialise the "callee-owned" tuple for irecv().
@@ -165,7 +163,7 @@ STATIC mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args,
165163
return self;
166164
}
167165

168-
void check_esp_err(int e) {
166+
static void check_esp_err(int e) {
169167
if (e != 0) {
170168
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
171169
MP_ERROR_TEXT("ESP-Now Unknown Error 0x%04x"), e));
@@ -183,15 +181,14 @@ recv_cb(uint8_t *mac_addr, uint8_t *data, uint8_t len);
183181
// allocate the recv data buffers.
184182
STATIC mp_obj_t espnow_init(size_t n_args, const mp_obj_t *args) {
185183
esp_espnow_obj_t *self = espnow_singleton;
186-
if (initialized) {
184+
if (self->initialised) {
187185
return mp_const_none;
188186
}
189-
if (n_args > 1) {
190-
self->recv_buffer_size = mp_obj_get_int(args[1]);
191-
}
192-
self->recv_buffer = buffer_init(self->recv_buffer_size);
187+
self->recv_buffer = buffer_init(
188+
(n_args > 1) ? mp_obj_get_int(args[1]) : DEFAULT_RECV_BUFFER_SIZE
189+
);
193190

194-
initialized = 1;
191+
self->initialise B41A d = 1;
195192
check_esp_err(esp_now_init());
196193
esp_now_set_self_role(ESP_NOW_ROLE_COMBO);
197194
esp_now_register_recv_cb(recv_cb);
@@ -206,22 +203,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_init_obj, 1, 2, espnow_init);
206203
// deallocate the recv data buffers.
207204
STATIC mp_obj_t espnow_deinit(mp_obj_t _) {
208205
esp_espnow_obj_t *self = espnow_singleton;
209-
if (initialized) {
210-
esp_now_unregister_recv_cb();
211-
esp_now_unregister_send_cb();
212-
esp_now_deinit();
213-
initialized = 0;
214-
buffer_release(self->recv_buffer);
206+
if (!self->initialised) {
207+
return mp_const_none;
215208
}
209+
esp_now_unregister_recv_cb();
210+
esp_now_unregister_send_cb();
211+
esp_now_deinit();
212+
self->initialised = 0;
213+
buffer_release(self->recv_buffer);
216214
return mp_const_none;
217215
}
218216
STATIC MP_DEFINE_CONST_FUN_OBJ_1(espnow_deinit_obj, espnow_deinit);
219217

220218
// set_pmk(primary_key)
221219
STATIC mp_obj_t espnow_set_pmk(mp_obj_t _, mp_obj_t key) {
222-
size_t len;
223220
check_esp_err(esp_now_set_kok(
224-
(uint8_t *)mp_obj_str_get_data(key, &len), ESP_NOW_KEY_LEN));
221+
_get_bytes_len(key, ESP_NOW_KEY_LEN), ESP_NOW_KEY_LEN));
225222
return mp_const_none;
226223
}
227224
STATIC MP_DEFINE_CONST_FUN_OBJ_2(espnow_set_pmk_obj, espnow_set_pmk);
@@ -315,14 +312,6 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_irecv_obj, 1, 2, espnow_irecv);
315312
// True if sync==True and message is received successfully by all recipients
316313
// False if sync==True and message is not received by any recipients
317314
// Raises: EAGAIN if the internal espnow buffers are full.
318-
static uint8_t *_get_bytes_len(mp_obj_t obj, size_t size) {
319-
size_t len;
320-
const uint8_t *p = (const uint8_t *)mp_obj_str_get_data(obj, &len);
321-
if (len != size) {
322-
mp_raise_ValueError(MP_ERROR_TEXT("wrong length"));
323-
}
324-
return (uint8_t *)p;
325-
}
326315

327316
static void wait_for_response(esp_espnow_obj_t *self) {
328317
int64_t start = mp_hal_ticks_ms();
@@ -342,17 +331,18 @@ STATIC mp_obj_t espnow_send(size_t n_args, const mp_obj_t *args) {
342331
wait_for_response(self);
343332
}
344333
int n = self->sent_successes;
345-
size_t msg_len;
346-
uint8_t *msg = (uint8_t *)mp_obj_str_get_data(args[2], &msg_len);
347-
uint8_t *mac = _get_bytes_len(args[1], ESP_NOW_ETH_ALEN);
348-
check_esp_err(esp_now_send(mac, msg, msg_len));
334+
mp_buffer_info_t bufinfo;
335+
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
336+
check_esp_err(esp_now_send(
337+
_get_bytes_len(args[1], ESP_NOW_ETH_ALEN),
338+
bufinfo.buf, bufinfo.len));
349339
self->sent_packets++;
350340
if (sync) {
351341
// Wait for message to be received by peer
352342
wait_for_response(self);
353343
}
354344

355-
return (self->sent_successes > n) ? mp_const_true : mp_const_false;
345+
return (!sync || self->sent_successes > n) ? mp_const_true : mp_const_false;
356346
}
357347
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow_send_obj, 3, 4, espnow_send);
358348

@@ -392,8 +382,6 @@ STATIC const mp_rom_map_elem_t esp_espnow_locals_dict_table[] = {
392382
};
393383
STATIC MP_DEFINE_CONST_DICT(esp_espnow_locals_dict, esp_espnow_locals_dict_table);
394384

395-
// XXX is it really worth having esp.espnow.ESPNow() or should this
396-
// singleton just be esp.ESPNow().
397385
STATIC const mp_rom_map_elem_t espnow_globals_dict_table[] = {
398386
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_espnow) },
399387
{ MP_ROM_QSTR(MP_QSTR_ESPNow), MP_ROM_PTR(&esp_espnow_type) },
@@ -429,8 +417,7 @@ _buf_put_recv_data(buffer_t buf, const uint8_t *mac,
429417
static bool
430418
_buf_get_recv_data(buffer_t buf, uint8_t *mac, uint8_t *msg, int msg_len) {
431419
uint8_t header[2]; // Copy out the header and ignore it
432-
return msg_len > 0 &&
433-
buffer_get(buf, header, sizeof(header)) &&
420+
return buffer_get(buf, header, sizeof(header)) &&
434421
buffer_get(buf, mac, ESP_NOW_ETH_ALEN) &&
435422
buffer_get(buf, msg, msg_len);
436423
}
@@ -441,11 +428,20 @@ static int
441428
_buf_peek_message_length(buffer_t buf) {
442429
// Check for the magic byte followed by the message length
443430
uint8_t header[2];
444-
return !buffer_peek(buf, header, sizeof(header))
445-
? BUF_EMPTY // No data to read
446-
: (header[0] != ESPNOW_MAGIC || header[1] > ESP_NOW_MAX_DATA_LEN)
447-
? BUF_ERROR // Packet header is wrong
448-
: header[1]; // Success: return length of message
431+
return buffer_peek(buf, header, sizeof(header))
432+
? (header[0] == ESPNOW_MAGIC && header[1] <= ESP_NOW_MAX_DATA_LEN)
433+
? header[1] // Success: return length of message
434+
: BUF_ERROR // Packet header is wrong
435+
: BUF_EMPTY; // No data to read
436+
}
437+
438+
static uint8_t *_get_bytes_len(mp_obj_t obj, size_t len) {
439+
mp_buffer_info_t bufinfo;
440+
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
441+
if (bufinfo.len != len) {
442+
mp_raise_ValueError(MP_ERROR_TEXT("wrong length"));
443+
}
444+
return (uint8_t *)bufinfo.buf;
449445
}
450446

451447
#endif // MICROPY_ESP8266_ESPNOW

0 commit comments

Comments
 (0)
0