14
14
15
15
#include <stdlib.h>
16
16
#include <esp_log.h>
17
+ #include <nvs.h>
17
18
#include <esp_event.h>
18
19
#include <esp_local_ctrl.h>
19
20
#include <wifi_provisioning/manager.h>
20
21
#include <esp_rmaker_internal.h>
22
+ #include <esp_rmaker_standard_services.h>
21
23
#include <esp_https_server.h>
22
24
#include <mdns.h>
23
25
26
+ #include <esp_idf_version.h>
27
+ #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (4 , 2 , 0 )
28
+ // Features supported in 4.2
29
+
30
+ #define ESP_RMAKER_LOCAL_CTRL_SECURITY_TYPE CONFIG_ESP_RMAKER_LOCAL_CTRL_SECURITY
31
+
32
+ #else
33
+
34
+ #if CONFIG_ESP_RMAKER_LOCAL_CTRL_SECURITY != 0
35
+ #warning "Local control security type is not supported in idf versions below 4.2. Using sec0 by default."
36
+ #endif
37
+ #define ESP_RMAKER_LOCAL_CTRL_SECURITY_TYPE 0
38
+
39
+ #endif /* !IDF4.2 */
40
+
24
41
static const char * TAG = "esp_rmaker_local" ;
25
42
26
43
/* Random Port number that will be used by the local control http instance
27
44
* for internal control communication.
28
45
*/
29
46
#define ESP_RMAKER_LOCAL_CTRL_HTTP_CTRL_PORT 12312
47
+ #define ESP_RMAKER_NVS_PART_NAME "nvs"
48
+ #define ESP_RMAKER_NVS_LOCAL_CTRL_NAMESPACE "local_ctrl"
49
+ #define ESP_RMAKER_NVS_LOCAL_CTRL_POP "pop"
50
+ #define ESP_RMAKER_POP_LEN 9
30
51
31
52
/* Custom allowed property types */
32
53
enum property_types {
@@ -123,19 +144,106 @@ static esp_err_t set_property_values(size_t props_count,
123
144
return ret ;
124
145
}
125
146
147
+ static char * __esp_rmaker_local_ctrl_get_nvs (const char * key )
148
+ {
149
+ char * val = NULL ;
150
+ nvs_handle handle ;
151
+ esp_err_t err = nvs_open_from_partition (ESP_RMAKER_NVS_PART_NAME , ESP_RMAKER_NVS_LOCAL_CTRL_NAMESPACE , NVS_READONLY , & handle );
152
+ if (err != ESP_OK ) {
153
+ return NULL ;
154
+ }
155
+ size_t len = 0 ;
156
+ if ((err = nvs_get_blob (handle , key , NULL , & len )) == ESP_OK ) {
157
+ val = calloc (1 , len + 1 ); /* +1 for NULL termination */
158
+ if (val ) {
159
+ nvs_get_blob (handle , key , val , & len );
160
+ }
161
+ }
162
+ nvs_close (handle );
163
+ return val ;
164
+
165
+ }
166
+
167
+ static esp_err_t __esp_rmaker_local_ctrl_set_nvs (const char * key , const char * val )
168
+ {
169
+ nvs_handle handle ;
170
+ esp_err_t err = nvs_open_from_partition (ESP_RMAKER_NVS_PART_NAME , ESP_RMAKER_NVS_LOCAL_CTRL_NAMESPACE , NVS_READWRITE , & handle );
171
+ if (err != ESP_OK ) {
172
+ return err ;
173
+ }
174
+ err = nvs_set_blob (handle , key , val , strlen (val ));
175
+ nvs_commit (handle );
176
+ nvs_close (handle );
177
+ return err ;
178
+ }
179
+
180
+ static char * esp_rmaker_local_ctrl_get_pop ()
181
+ {
182
+ char * pop = __esp_rmaker_local_ctrl_get_nvs (ESP_RMAKER_NVS_LOCAL_CTRL_POP );
183
+ if (pop ) {
184
+ return pop ;
185
+ }
186
+
187
+ ESP_LOGI (TAG , "Couldn't find POP in NVS. Generating a new one." );
188
+ pop = (char * )calloc (1 , ESP_RMAKER_POP_LEN );
189
+ if (!pop ) {
190
+ ESP_LOGE (TAG , "Couldn't allocate POP" );
191
+ return NULL ;
192
+ }
193
+ uint8_t random_bytes [ESP_RMAKER_POP_LEN ] = {0 };
194
+ esp_fill_random (& random_bytes , sizeof (random_bytes ));
195
+ snprintf (pop , ESP_RMAKER_POP_LEN , "%02x%02x%02x%02x" , random_bytes [0 ], random_bytes [1 ], random_bytes [2 ], random_bytes [3 ]);
196
+
197
+ __esp_rmaker_local_ctrl_set_nvs (ESP_RMAKER_NVS_LOCAL_CTRL_POP , pop );
198
+ return pop ;
199
+ }
200
+
201
+ static int esp_rmaker_local_ctrl_get_security_type ()
202
+ {
203
+ return ESP_RMAKER_LOCAL_CTRL_SECURITY_TYPE ;
204
+ }
205
+
206
+ static esp_err_t esp_rmaker_local_ctrl_service_enable (void )
207
+ {
208
+ char * pop_str = esp_rmaker_local_ctrl_get_pop ();
209
+ if (!pop_str ) {
210
+ ESP_LOGE (TAG , "Get POP failed" );
211
+ return ESP_FAIL ;
212
+ }
213
+ int sec_ver = esp_rmaker_local_ctrl_get_security_type ();
214
+
215
+ esp_rmaker_device_t * local_ctrl_service = esp_rmaker_create_local_control_service ("Local Control" , pop_str , sec_ver , NULL );
216
+ if (!local_ctrl_service ) {
217
+ ESP_LOGE (TAG , "Failed to create Schedule Service" );
218
+ free (pop_str );
219
+ return ESP_FAIL ;
220
+ }
221
+ free (pop_str );
222
+
223
+ esp_err_t err = esp_rmaker_node_add_device (esp_rmaker_get_node (), local_ctrl_service );
224
+ if (err != ESP_OK ) {
225
+ ESP_LOGE (TAG , "Failed to add service Service" );
226
+ return err ;
227
+ }
228
+
229
+ ESP_LOGD (TAG , "Local Control Service Enabled" );
230
+ return err ;
231
+ }
232
+
126
233
static esp_err_t __esp_rmaker_start_local_ctrl_service (const char * serv_name )
127
234
{
128
235
if (!serv_name ) {
129
236
ESP_LOGE (TAG , "Service name cannot be empty." );
130
237
return ESP_ERR_INVALID_ARG ;
131
238
}
132
- ESP_LOGI (TAG , "Starting ESP Local control with HTTP Transport." );
239
+
240
+ ESP_LOGI (TAG , "Starting ESP Local control with HTTP Transport and security version: %d" , esp_rmaker_local_ctrl_get_security_type ());
133
241
/* Set the configuration */
134
242
static httpd_ssl_config_t https_conf = HTTPD_SSL_CONFIG_DEFAULT ();
135
243
https_conf .transport_mode = HTTPD_SSL_TRANSPORT_INSECURE ;
136
244
https_conf .port_insecure = CONFIG_ESP_RMAKER_LOCAL_CTRL_HTTP_PORT ;
137
245
https_conf .httpd .ctrl_port = ESP_RMAKER_LOCAL_CTRL_HTTP_CTRL_PORT ;
138
-
246
+
139
247
mdns_init ();
140
248
mdns_hostname_set (serv_name );
141
249
@@ -155,8 +263,40 @@ static esp_err_t __esp_rmaker_start_local_ctrl_service(const char *serv_name)
155
263
.max_properties = 10
156
264
};
157
265
266
+ /* If sec1, add security type details to the config */
267
+ protocomm_security_pop_t * pop = NULL ;
268
+ #if ESP_RMAKER_LOCAL_CTRL_SECURITY_TYPE == 1
269
+ char * pop_str = esp_rmaker_local_ctrl_get_pop ();
270
+ /* Note: pop_str shouldn't be freed. If it gets freed, the pointer which is internally copied in esp_local_ctrl_start() will become invalid which would cause corruption. */
271
+
272
+ int sec_ver = esp_rmaker_local_ctrl_get_security_type ();
273
+
274
+ if (sec_ver != 0 && pop_str ) {
275
+ pop = (protocomm_security_pop_t * )calloc (1 , sizeof (protocomm_security_pop_t ));
276
+ if (!pop ) {
277
+ ESP_LOGE (TAG , "Failed to allocate pop" );
278
+ free (pop_str );
279
+ return ESP_ERR_NO_MEM ;
280
+ }
281
+ pop -> data = (uint8_t * )pop_str ;
282
+ pop -> len = strlen (pop_str );
283
+ }
284
+
285
+ config .proto_sec .version = sec_ver ;
286
+ config .proto_sec .custom_handle = NULL ;
287
+ config .proto_sec .pop = pop ;
288
+ #endif
289
+
158
290
/* Start esp_local_ctrl service */
159
291
ESP_ERROR_CHECK (esp_local_ctrl_start (& config ));
292
+
293
+ /* Add node_id in mdns */
294
+ mdns_service_txt_item_set ("_esp_local_ctrl" , "_tcp" , "node_id" , esp_rmaker_get_node_id ());
295
+
296
+ if (pop ) {
297
+ free (pop );
298
+ }
299
+
160
300
ESP_LOGI (TAG , "esp_local_ctrl service started with name : %s" , serv_name );
161
301
162
302
/* Create the Node Config property */
@@ -230,6 +370,10 @@ esp_err_t esp_rmaker_init_local_ctrl_service(void)
230
370
231
371
esp_err_t esp_rmaker_start_local_ctrl_service (const char * serv_name )
232
372
{
373
+ if (ESP_RMAKER_LOCAL_CTRL_SECURITY_TYPE == 1 ) {
374
+ esp_rmaker_local_ctrl_service_enable ();
375
+ }
376
+
233
377
if (!wait_for_wifi_prov ) {
234
378
return __esp_rmaker_start_local_ctrl_service (serv_name );
235
379
}
0 commit comments