60
60
#define TAG "network_driver"
61
61
#define PORT_REPLY_SIZE (TUPLE_SIZE(2) + REF_SIZE)
62
62
63
- static const char * const ap_atom = ATOM_STR ("\x2" , "ap" );
64
- static const char * const ap_channel_atom = ATOM_STR ("\xA" , "ap_channel" );
65
- static const char * const ap_sta_connected_atom = ATOM_STR ("\x10" , "ap_sta_connected" );
66
- static const char * const ap_sta_disconnected_atom = ATOM_STR ("\x13" , "ap_sta_disconnected" );
67
- static const char * const ap_sta_ip_assigned_atom = ATOM_STR ("\x12" , "ap_sta_ip_assigned" );
68
- static const char * const ap_started_atom = ATOM_STR ("\xA" , "ap_started" );
69
- static const char * const dhcp_hostname_atom = ATOM_STR ("\xD" , "dhcp_hostname" );
70
- static const char * const host_atom = ATOM_STR ("\x4" , "host" );
71
- static const char * const max_connections_atom = ATOM_STR ("\xF" , "max_connections" );
72
- static const char * const psk_atom = ATOM_STR ("\x3" , "psk" );
73
- static const char * const sntp_atom = ATOM_STR ("\x4" , "sntp" );
74
- static const char * const sntp_sync_atom = ATOM_STR ("\x9" , "sntp_sync" );
75
- static const char * const ssid_atom = ATOM_STR ("\x4" , "ssid" );
76
- static const char * const ssid_hidden_atom = ATOM_STR ("\xB" , "ssid_hidden" );
77
- static const char * const sta_atom = ATOM_STR ("\x3" , "sta" );
78
- static const char * const sta_connected_atom = ATOM_STR ("\xD" , "sta_connected" );
79
- static const char * const sta_beacon_timeout_atom = ATOM_STR ("\x12" , "sta_beacon_timeout" );
80
- static const char * const sta_disconnected_atom = ATOM_STR ("\x10" , "sta_disconnected" );
81
- static const char * const sta_got_ip_atom = ATOM_STR ("\xA" , "sta_got_ip" );
82
-
83
63
ESP_EVENT_DECLARE_BASE (sntp_event_base );
84
64
ESP_EVENT_DEFINE_BASE (sntp_event_base );
85
65
@@ -112,11 +92,6 @@ struct ClientData
112
92
uint64_t ref_ticks ;
113
93
};
114
94
115
- static inline term make_atom (GlobalContext * global , AtomString atom_str )
116
- {
117
- return globalcontext_make_atom (global , atom_str );
118
- }
119
-
120
95
static term tuple_from_addr (Heap * heap , uint32_t addr )
121
96
{
122
97
term terms [4 ];
@@ -151,20 +126,58 @@ static void send_got_ip(struct ClientData *data, esp_netif_ip_info_t *info)
151
126
term gw = tuple_from_addr (& heap , ntohl (info -> gw .addr ));
152
127
153
128
term ip_info = port_heap_create_tuple3 (& heap , ip , netmask , gw );
154
- term reply = port_heap_create_tuple2 (& heap , make_atom (data -> global , sta_got_ip_atom ), ip_info );
129
+ term reply = port_heap_create_tuple2 (& heap , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\xA" , "sta_got_ip" ) ), ip_info );
155
130
send_term (& heap , data , reply );
156
131
}
157
132
END_WITH_STACK_HEAP (heap , data -> global );
158
133
}
159
134
135
+ // Used to initialize atoms use in STA mode callbacks when sta mode is configured
136
+ // callbacks should get the existing atom term from from the atom string.
137
+ #define NUM_STA_ATOMS 4
138
+ bool init_sta_cb_atoms (GlobalContext * glb )
139
+ {
140
+ bool result = true;
141
+ AtomString sta_cb_atom [NUM_STA_ATOMS ] = { ATOM_STR ("\xD" , "sta_connected" ), ATOM_STR ("\x12" , "sta_beacon_timeout" ),
142
+ ATOM_STR ("\x10" , "sta_disconnected" ), ATOM_STR ("\xA" , "sta_got_ip" ) };
143
+
144
+ for (int atom = 0 ; atom < NUM_STA_ATOMS ; atom ++ ) {
145
+ int index = globalcontext_insert_atom (glb , sta_cb_atom [atom ]);
146
+ if (UNLIKELY (index < 0 )) {
147
+ result = false;
148
+ }
149
+ }
150
+
151
+ return result ;
152
+ }
153
+
154
+ // Used to initialize atoms use in AP mode callbacks when ap mode is configured
155
+ // callbacks should get the existing atom term from from the atom string.
156
+ #define NUM_AP_ATOMS 4
157
+ bool init_ap_cb_atoms (GlobalContext * glb )
158
+ {
159
+ bool result = true;
160
+ AtomString ap_cb_atoms [NUM_AP_ATOMS ] = { ATOM_STR ("\x10" , "ap_sta_connected" ), ATOM_STR ("\x13" , "ap_sta_disconnected" ),
161
+ ATOM_STR ("\x12" , "ap_sta_ip_assigned" ), ATOM_STR ("\xA" , "ap_started" ) };
162
+
163
+ for (int atom = 0 ; atom < NUM_AP_ATOMS ; atom ++ ) {
164
+ int index = globalcontext_insert_atom (glb , ap_cb_atoms [atom ]);
165
+ if (UNLIKELY (index < 0 )) {
166
+ result = false;
167
+ }
168
+ }
169
+
170
+ return result ;
171
+ }
172
+
160
173
static void send_sta_connected (struct ClientData * data )
161
174
{
162
175
TRACE ("Sending sta_connected back to AtomVM\n" );
163
176
164
177
// {Ref, sta_connected}
165
178
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE , heap );
166
179
{
167
- send_term (& heap , data , make_atom (data -> global , sta_connected_atom ));
180
+ send_term (& heap , data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\xD" , "sta_connected" ) ));
168
181
}
169
182
END_WITH_STACK_HEAP (heap , data -> global );
170
183
}
@@ -176,7 +189,7 @@ static void send_sta_beacon_timeout(struct ClientData *data)
176
189
// {Ref, sta_beacon_timeout}
177
190
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE , heap );
178
191
{
179
- send_term (& heap , data , make_atom (data -> global , sta_beacon_timeout_atom ));
192
+ send_term (& heap , data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x12" , "sta_beacon_timeout" ) ));
180
193
}
181
194
END_WITH_STACK_HEAP (heap , data -> global );
182
195
}
@@ -188,7 +201,7 @@ static void send_sta_disconnected(struct ClientData *data)
188
201
// {Ref, sta_disconnected}
189
202
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE , heap );
190
203
{
191
- send_term (& heap , data , make_atom (data -> global , sta_disconnected_atom ));
204
+ send_term (& heap , data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x10" , "sta_disconnected" ) ));
192
205
}
193
206
END_WITH_STACK_HEAP (heap , data -> global );
194
207
}
@@ -200,7 +213,7 @@ static void send_ap_started(struct ClientData *data)
200
213
// {Ref, ap_started}
201
214
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE , heap );
202
215
{
203
- send_term (& heap , data , make_atom (data -> global , ap_started_atom ));
216
+ send_term (& heap , data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\xA" , "ap_started" ) ));
204
217
}
205
218
END_WITH_STACK_HEAP (heap , data -> global );
206
219
}
@@ -220,13 +233,13 @@ static void send_atom_mac(struct ClientData *data, term atom, uint8_t *mac)
220
233
static void send_ap_sta_connected (struct ClientData * data , uint8_t * mac )
221
234
{
222
235
TRACE ("Sending ap_sta_connected back to AtomVM\n" );
223
- send_atom_mac (data , make_atom (data -> global , ap_sta_connected_atom ), mac );
236
+ send_atom_mac (data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x10" , "ap_sta_connected" ) ), mac );
224
237
}
225
238
226
239
static void send_ap_sta_disconnected (struct ClientData * data , uint8_t * mac )
227
240
{
228
241
TRACE ("Sending ap_sta_disconnected back to AtomVM\n" );
229
- send_atom_mac (data , make_atom (data -> global , ap_sta_disconnected_atom ), mac );
242
+ send_atom_mac (data , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x13" , "ap_sta_disconnected" ) ), mac );
230
243
}
231
244
232
245
static void send_ap_sta_ip_assigned (struct ClientData * data , esp_ip4_addr_t * ip )
@@ -236,7 +249,7 @@ static void send_ap_sta_ip_assigned(struct ClientData *data, esp_ip4_addr_t *ip)
236
249
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE + TUPLE_SIZE (2 ) + TUPLE_SIZE (4 ), heap );
237
250
{
238
251
term ip_term = tuple_from_addr (& heap , ntohl (ip -> addr ));
239
- term reply = port_heap_create_tuple2 (& heap , make_atom (data -> global , ap_sta_ip_assigned_atom ), ip_term );
252
+ term reply = port_heap_create_tuple2 (& heap , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x12" , "ap_sta_ip_assigned" ) ), ip_term );
240
253
send_term (& heap , data , reply );
241
254
}
242
255
END_WITH_STACK_HEAP (heap , data -> global );
@@ -250,7 +263,7 @@ static void send_sntp_sync(struct ClientData *data, struct timeval *tv)
250
263
BEGIN_WITH_STACK_HEAP (PORT_REPLY_SIZE + TUPLE_SIZE (2 ) * 2 + BOXED_INT64_SIZE * 2 , heap );
251
264
{
252
265
term tv_tuple = port_heap_create_tuple2 (& heap , term_make_maybe_boxed_int64 (tv -> tv_sec , & heap ), term_make_maybe_boxed_int64 (tv -> tv_usec , & heap ));
253
- term reply = port_heap_create_tuple2 (& heap , make_atom (data -> global , sntp_sync_atom ), tv_tuple );
266
+ term reply = port_heap_create_tuple2 (& heap , globalcontext_existing_term_from_atom_string (data -> global , ATOM_STR ( "\x9" , "sntp_sync" ) ), tv_tuple );
254
267
send_term (& heap , data , reply );
255
268
}
256
269
END_WITH_STACK_HEAP (heap , data -> global );
@@ -380,8 +393,8 @@ static wifi_config_t *get_sta_wifi_config(term sta_config, GlobalContext *global
380
393
TRACE ("No STA config\n" );
381
394
return NULL ;
382
395
}
383
- term ssid_term = interop_kv_get_value (sta_config , ssid_atom , global );
384
- term pass_term = interop_kv_get_value (sta_config , psk_atom , global );
396
+ term ssid_term = interop_kv_get_value (sta_config , ATOM_STR ( "\x4" , "ssid" ) , global );
397
+ term pass_term = interop_kv_get_value (sta_config , ATOM_STR ( "\x3" , "psk" ) , global );
385
398
386
399
//
387
400
// Check parameters
@@ -469,9 +482,9 @@ static wifi_config_t *get_ap_wifi_config(term ap_config, GlobalContext *global)
469
482
TRACE ("No AP config\n" );
470
483
return NULL ;
471
484
}
472
- term ssid_term = interop_kv_get_value (ap_config , ssid_atom , global );
473
- term pass_term = interop_kv_get_value (ap_config , psk_atom , global );
474
- term channel_term = interop_kv_get_value (ap_config , ap_channel_atom , global );
485
+ term ssid_term = interop_kv_get_value (ap_config , ATOM_STR ( "\x4" , "ssid" ) , global );
486
+ term pass_term = interop_kv_get_value (ap_config , ATOM_STR ( "\x3" , "psk" ) , global );
487
+ term channel_term = interop_kv_get_value (ap_config , ATOM_STR ( "\xA" , "ap_channel" ) , global );
475
488
476
489
//
477
490
// Check parameters
@@ -545,9 +558,9 @@ static wifi_config_t *get_ap_wifi_config(term ap_config, GlobalContext *global)
545
558
}
546
559
547
560
wifi_config -> ap .authmode = IS_NULL_PTR (psk ) ? WIFI_AUTH_OPEN : WIFI_AUTH_WPA_WPA2_PSK ;
548
- term ssid_hidden_term = interop_kv_get_value (ap_config , ssid_hidden_atom , global );
561
+ term ssid_hidden_term = interop_kv_get_value (ap_config , ATOM_STR ( "\xB" , "ssid_hidden" ) , global );
549
562
wifi_config -> ap .ssid_hidden = term_is_invalid_term (ssid_hidden_term ) ? 0 : ssid_hidden_term == TRUE_ATOM ;
550
- term max_connections_term = interop_kv_get_value (ap_config , max_connections_atom , global );
563
+ term max_connections_term = interop_kv_get_value (ap_config , ATOM_STR ( "\xF" , "max_connections" ) , global );
551
564
wifi_config -> ap .max_connection = term_is_invalid_term (max_connections_term ) ? 4 : term_to_int (max_connections_term );
552
565
553
566
ESP_LOGI (TAG , "AP ssid: %s" , wifi_config -> ap .ssid );
@@ -570,16 +583,21 @@ static void time_sync_notification_cb(struct timeval *tv)
570
583
571
584
static void maybe_set_sntp (term sntp_config , GlobalContext * global )
572
585
{
573
- if (!term_is_invalid_term (sntp_config ) && !term_is_invalid_term (interop_kv_get_value (sntp_config , host_atom , global ))) {
586
+ if (!term_is_invalid_term (sntp_config ) && !term_is_invalid_term (interop_kv_get_value (sntp_config , ATOM_STR ( "\x4" , "host" ) , global ))) {
574
587
int ok ;
575
- char * host = interop_term_to_string (interop_kv_get_value (sntp_config , host_atom , global ), & ok );
588
+ char * host = interop_term_to_string (interop_kv_get_value (sntp_config , ATOM_STR ( "\x4" , "host" ) , global ), & ok );
576
589
if (LIKELY (ok )) {
577
590
// do not free(sntp)
578
591
esp_sntp_setoperatingmode (SNTP_OPMODE_POLL );
579
592
esp_sntp_setservername (0 , host );
580
593
sntp_set_time_sync_notification_cb (time_sync_notification_cb );
581
594
esp_sntp_init ();
582
- ESP_LOGI (TAG , "SNTP initialized with host set to %s" , host );
595
+ int sntp_sync_index = globalcontext_insert_atom (global , ATOM_STR ("\x9" , "sntp_sync" ));
596
+ if (UNLIKELY (sntp_sync_index < 0 )) {
597
+ ESP_LOGE (TAG , "Failed to create 'sntp_sync' atom! sntp_sync callbacks will fail." );
598
+ } else {
599
+ ESP_LOGI (TAG , "SNTP initialized with host set to %s" , host );
600
+ }
583
601
} else {
584
602
ESP_LOGE (TAG , "Unable to locate sntp host in configuration" );
585
603
}
@@ -627,8 +645,8 @@ static void start_network(Context *ctx, term pid, term ref, term config)
627
645
//
628
646
// Get the STA and AP config, if set
629
647
//
630
- term sta_config = interop_kv_get_value_default (config , sta_atom , term_invalid_term (), ctx -> global );
631
- term ap_config = interop_kv_get_value_default (config , ap_atom , term_invalid_term (), ctx -> global );
648
+ term sta_config = interop_kv_get_value_default (config , ATOM_STR ( "\x3" , "sta" ) , term_invalid_term (), ctx -> global );
649
+ term ap_config = interop_kv_get_value_default (config , ATOM_STR ( "\x2" , "ap" ) , term_invalid_term (), ctx -> global );
632
650
if (UNLIKELY (term_is_invalid_term (sta_config ) && term_is_invalid_term (ap_config ))) {
633
651
ESP_LOGE (TAG , "Expected STA or AP configuration but got neither" );
634
652
term error = port_create_error_tuple (ctx , BADARG_ATOM );
@@ -725,10 +743,39 @@ static void start_network(Context *ctx, term pid, term ref, term config)
725
743
wifi_mode_t wifi_mode = WIFI_MODE_NULL ;
726
744
if (!IS_NULL_PTR (sta_wifi_config ) && !IS_NULL_PTR (ap_wifi_config )) {
727
745
wifi_mode = WIFI_MODE_APSTA ;
728
- } else if (!IS_NULL_PTR (sta_wifi_config )) {
729
- wifi_mode = WIFI_MODE_STA ;
730
- } else {
746
+ bool sta_atoms_ok = init_sta_cb_atoms (ctx -> global );
747
+ bool ap_atoms_ok = init_ap_cb_atoms (ctx -> global );
748
+ if (UNLIKELY (!sta_atoms_ok || !ap_atoms_ok )) {
749
+ ESP_LOGE (TAG , "Unable to insert callback atoms" );
750
+ free (ap_wifi_config );
751
+ free (sta_wifi_config );
752
+ port_ensure_available (ctx , TUPLE_SIZE (2 ));
753
+ term error = port_create_error_tuple (ctx , OUT_OF_MEMORY_ATOM );
754
+ port_send_reply (ctx , pid , ref , error );
755
+ return ;
756
+ }
757
+ } else if (!IS_NULL_PTR (ap_wifi_config )) {
731
758
wifi_mode = WIFI_MODE_AP ;
759
+ bool ap_atoms_ok = init_ap_cb_atoms (ctx -> global );
760
+ if (UNLIKELY (!ap_atoms_ok )) {
761
+ ESP_LOGE (TAG , "Unable to insert callback atoms" );
762
+ free (ap_wifi_config );
763
+ port_ensure_available (ctx , TUPLE_SIZE (2 ));
764
+ term error = port_create_error_tuple (ctx , OUT_OF_MEMORY_ATOM );
765
+ port_send_reply (ctx , pid , ref , error );
766
+ return ;
767
+ }
768
+ } else {
769
+ wifi_mode = WIFI_MODE_STA ;
770
+ bool sta_atoms_ok = init_sta_cb_atoms (ctx -> global );
771
+ if (UNLIKELY (!sta_atoms_ok )) {
772
+ ESP_LOGE (TAG , "Unable to insert callback atoms" );
773
+ free (sta_wifi_config );
774
+ port_ensure_available (ctx , TUPLE_SIZE (2 ));
775
+ term error = port_create_error_tuple (ctx , OUT_OF_MEMORY_ATOM );
776
+ port_send_reply (ctx , pid , ref , error );
777
+ return ;
778
+ }
732
779
}
733
780
if ((err = esp_wifi_set_mode (wifi_mode )) != ESP_OK ) {
734
781
ESP_LOGE (TAG , "Error setting wifi mode %d" , err );
@@ -789,16 +836,16 @@ static void start_network(Context *ctx, term pid, term ref, term config)
789
836
//
790
837
// Set up simple NTP, if configured
791
838
//
792
- maybe_set_sntp (interop_kv_get_value (config , sntp_atom , ctx -> global ), ctx -> global );
839
+ maybe_set_sntp (interop_kv_get_value (config , ATOM_STR ( "\x4" , "sntp" ) , ctx -> global ), ctx -> global );
793
840
794
841
//
795
842
// Set the DHCP hostname, if STA mode is enabled
796
843
//
797
844
if (!IS_NULL_PTR (sta_wifi_config )) {
798
- set_dhcp_hostname (sta_wifi_interface , "STA" , interop_kv_get_value (sta_config , dhcp_hostname_atom , ctx -> global ));
845
+ set_dhcp_hostname (sta_wifi_interface , "STA" , interop_kv_get_value (sta_config , ATOM_STR ( "\xD" , "dhcp_hostname" ) , ctx -> global ));
799
846
}
800
847
if (!IS_NULL_PTR (ap_wifi_config )) {
801
- set_dhcp_hostname (ap_wifi_interface , "AP" , interop_kv_get_value (ap_config , dhcp_hostname_atom , ctx -> global ));
848
+ set_dhcp_hostname (ap_wifi_interface , "AP" , interop_kv_get_value (ap_config , ATOM_STR ( "\xD" , "dhcp_hostname" ) , ctx -> global ));
802
849
}
803
850
804
851
//
@@ -861,9 +908,17 @@ static void get_sta_rssi(Context *ctx, term pid, term ref)
861
908
return ;
862
909
}
863
910
term rssi = term_from_int (sta_rssi );
911
+ int rssi_atom_index = globalcontext_insert_atom (ctx -> global , ATOM_STR ("\x4" , "rssi" ));
912
+ if (UNLIKELY (rssi_atom_index < 0 )) {
913
+ ESP_LOGE (TAG , "Failed to create 'rssi' atom!" );
914
+ port_ensure_available (ctx , tuple_reply_size );
915
+ term error = port_create_error_tuple (ctx , OUT_OF_MEMORY_ATOM );
916
+ port_send_reply (ctx , pid , ref , error );
917
+ return ;
918
+ }
864
919
// {Ref, {rssi, -25}}
865
920
port_ensure_available (ctx , tuple_reply_size );
866
- term reply = port_create_tuple2 (ctx , make_atom ( ctx -> global , ATOM_STR ( "\x4" , "rssi" ) ), rssi );
921
+ term reply = port_create_tuple2 (ctx , term_from_atom_index ( rssi_atom_index ), rssi );
867
922
port_send_reply (ctx , pid , ref , reply );
868
923
}
869
924
0 commit comments