1
1
/*
2
- * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
2
+ * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
3
3
*
4
4
* SPDX-License-Identifier: Apache-2.0
5
5
*/
6
6
7
+ #include <freertos/FreeRTOS.h>
8
+ #include <freertos/timers.h>
9
+ #include <freertos/semphr.h>
10
+
7
11
#include <string.h>
8
12
#include <esp_log.h>
9
13
#include <esp_wifi.h>
10
14
#include <esp_core_dump.h>
11
- #include <freertos/FreeRTOS.h>
12
- #include <freertos/timers.h>
15
+
13
16
#include <nvs.h>
14
17
#include <esp_crc.h>
15
- #include <freertos/semphr.h>
16
18
#include <esp_diag_data_store.h>
17
19
#include <esp_diagnostics.h>
18
20
#include <esp_diagnostics_metrics.h>
29
31
#include "esp_insights_encoder.h"
30
32
#include "esp_insights_cbor_decoder.h"
31
33
34
+ #ifdef CONFIG_ESP_INSIGHTS_CMD_RESP_ENABLED
35
+ #define INSIGHTS_CMD_RESP 1
36
+ #endif
37
+
32
38
#include <esp_idf_version.h>
33
39
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL (5 , 0 , 0 )
34
40
#include <esp_mac.h>
65
71
#define KEY_LOG_WR_FAIL "log_wr_fail"
66
72
67
73
#define DIAG_DATA_STORE_CRC_KEY "rtc_buf_sha"
68
- #define INSIGHTS_NVS_NAMESPACE "storage"
74
+ #define INSIGHTS_NVS_NAMESPACE "storage"
69
75
70
76
ESP_EVENT_DEFINE_BASE (INSIGHTS_EVENT );
71
77
78
+ #ifdef CONFIG_ESP_INSIGHTS_ENABLED
79
+
80
+ static const char * TAG = "esp_insights" ; /* tag for ESP_LOGx */
81
+
72
82
typedef struct esp_insights_entry {
73
83
esp_rmaker_work_fn_t work_fn ;
74
84
TimerHandle_t timer ;
@@ -87,6 +97,10 @@ typedef struct {
87
97
char app_sha256 [APP_ELF_SHA256_LEN ];
88
98
bool data_sent ;
89
99
#if SEND_INSIGHTS_META
100
+ #if INSIGHTS_CMD_RESP
101
+ bool conf_meta_msg_pending ;
102
+ uint32_t conf_meta_msg_id ;
103
+ #endif
90
104
bool meta_msg_pending ;
91
105
uint32_t meta_msg_id ;
92
106
uint32_t meta_crc ;
@@ -96,13 +110,13 @@ typedef struct {
96
110
TimerHandle_t data_send_timer ; /* timer to reset data_send_inprogress flag on timeout */
97
111
char * node_id ;
98
112
int boot_msg_id ; /* To track whether first message is sent or not, -1:failed, 0:success, >0:inprogress */
113
+ #if INSIGHTS_CMD_RESP
114
+ int conf_msg_id ;
115
+ #endif
99
116
bool init_done ; /* insights init done */
100
117
bool enabled ; /* insights enable is done */
101
118
} esp_insights_data_t ;
102
119
103
- #ifdef CONFIG_ESP_INSIGHTS_ENABLED
104
-
105
- static const char * TAG = "esp_insights" ;
106
120
static esp_insights_data_t s_insights_data ;
107
121
static esp_insights_entry_t * s_periodic_insights_entry ;
108
122
@@ -128,6 +142,14 @@ static bool is_insights_active(void)
128
142
return wifi_connected && s_insights_data .enabled ;
129
143
}
130
144
145
+ /* Returns true if wifi is connected, false otherwise */
146
+ static bool is_wifi_connected (void )
147
+ {
148
+ wifi_ap_record_t ap_info ;
149
+ bool wifi_connected = esp_wifi_sta_get_ap_info (& ap_info ) == ESP_OK ;
150
+ return wifi_connected ;
151
+ }
152
+
131
153
/* This executes in the context of timer task.
132
154
*
133
155
* There is a dynamic logic to decide the next instance when the insights
@@ -174,16 +196,17 @@ static esp_err_t esp_insights_unregister_periodic_handler(void)
174
196
{
175
197
if (s_periodic_insights_entry ) {
176
198
if (s_periodic_insights_entry -> timer ) {
199
+ ESP_LOGI (TAG , "Stopping the periodic timer" );
200
+ if (xTimerIsTimerActive (s_periodic_insights_entry -> timer ) == pdTRUE ) {
201
+ xTimerStop (s_periodic_insights_entry -> timer , portMAX_DELAY );
202
+ }
177
203
ESP_LOGI (TAG , "Deleting the periodic timer" );
178
- if (xTimerDelete (s_periodic_insights_entry -> timer , 10 ) != pdPASS ) {
179
- ESP_LOGE (TAG , "Failed to delete the periodic timer" );
180
- }
204
+ xTimerDelete (s_periodic_insights_entry -> timer , portMAX_DELAY );
205
+ s_periodic_insights_entry -> timer = NULL ;
181
206
}
182
207
183
- if (s_periodic_insights_entry ) {
184
- free (s_periodic_insights_entry );
185
- s_periodic_insights_entry = NULL ;
186
- }
208
+ free (s_periodic_insights_entry );
209
+ s_periodic_insights_entry = NULL ;
187
210
}
188
211
189
212
return ESP_OK ;
@@ -238,6 +261,11 @@ static void data_send_timeout_cb(TimerHandle_t handle)
238
261
if (s_insights_data .boot_msg_id > 0 ) {
239
262
s_insights_data .boot_msg_id = -1 ;
240
263
}
264
+ #if INSIGHTS_CMD_RESP
265
+ if (s_insights_data .conf_msg_id > 0 ) {
266
+ s_insights_data .conf_msg_id = -1 ;
267
+ }
268
+ #endif
241
269
xSemaphoreGive (s_insights_data .data_lock );
242
270
}
243
271
@@ -275,6 +303,11 @@ static void insights_event_handler(void* arg, esp_event_base_t event_base,
275
303
#endif // CONFIG_ESP_INSIGHTS_COREDUMP_ENABLE
276
304
s_insights_data .boot_msg_id = 0 ;
277
305
}
306
+ #if INSIGHTS_CMD_RESP
307
+ else if (s_insights_data .conf_msg_id > 0 && s_insights_data .conf_msg_id == data -> msg_id ) {
308
+ s_insights_data .conf_msg_id = 0 ;
309
+ }
310
+ #endif
278
311
xSemaphoreGive (s_insights_data .data_lock );
279
312
}
280
313
break ;
@@ -287,6 +320,11 @@ static void insights_event_handler(void* arg, esp_event_base_t event_base,
287
320
if (s_insights_data .boot_msg_id > 0 && data -> msg_id == s_insights_data .boot_msg_id ) {
288
321
s_insights_data .boot_msg_id = -1 ;
289
322
}
323
+ #if INSIGHTS_CMD_RESP
324
+ else if (s_insights_data .conf_msg_id > 0 && data -> msg_id == s_insights_data .conf_msg_id ) {
325
+ s_insights_data .conf_msg_id = -1 ;
326
+ }
327
+ #endif
290
328
xSemaphoreGive (s_insights_data .data_lock );
291
329
break ;
292
330
default :
@@ -348,10 +386,19 @@ static void send_boottime_data(void)
348
386
}
349
387
}
350
388
389
+ #if INSIGHTS_CMD_RESP
390
+ static void send_insights_conf_meta (void );
391
+ static void send_insights_config (void )
392
+ {
393
+ send_insights_conf_meta ();
394
+ }
395
+ #endif
396
+
351
397
#if SEND_INSIGHTS_META
352
398
/* Returns true if ESP Insights metadata CRC is changed */
353
399
static bool insights_meta_changed (void )
354
400
{
401
+ return true;
355
402
uint32_t nvs_crc ;
356
403
uint32_t meta_crc = esp_diag_meta_crc_get ();
357
404
esp_err_t err = esp_insights_meta_nvs_crc_get (& nvs_crc );
@@ -396,6 +443,35 @@ static void send_insights_meta(void)
396
443
}
397
444
#endif /* SEND_INSIGHTS_META */
398
445
446
+ #if INSIGHTS_CMD_RESP
447
+ static void send_insights_conf_meta (void )
448
+ {
449
+ uint16_t len = 0 ;
450
+
451
+ memset (s_insights_data .scratch_buf , 0 , INSIGHTS_DATA_MAX_SIZE );
452
+ len = esp_insights_encode_conf_meta (s_insights_data .scratch_buf , INSIGHTS_DATA_MAX_SIZE , s_insights_data .app_sha256 );
453
+ if (len == 0 ) {
454
+ #if INSIGHTS_DEBUG_ENABLED
455
+ ESP_LOGI (TAG , "No conf metadata to send" );
456
+ #endif
457
+ return ;
458
+ }
459
+ #if INSIGHTS_DEBUG_ENABLED
460
+ ESP_LOGI (TAG , "Insights conf meta data length %d" , len );
461
+ insights_dbg_dump (s_insights_data .scratch_buf , len );
462
+ #endif
463
+ int msg_id = esp_insights_transport_data_send (s_insights_data .scratch_buf , len );
464
+ if (msg_id > 0 ) {
465
+ xSemaphoreTake (s_insights_data .data_lock , portMAX_DELAY );
466
+ s_insights_data .conf_meta_msg_pending = true;
467
+ s_insights_data .conf_meta_msg_id = msg_id ;
468
+ xSemaphoreGive (s_insights_data .data_lock );
469
+ } else if (msg_id == 0 ) { /* sent successfully */
470
+ s_insights_data .conf_meta_msg_pending = false;
471
+ }
472
+ }
473
+ #endif
474
+
399
475
/* Consider 100 bytes are published and received on cloud but RMAKER_MQTT_EVENT_PUBLISHED
400
476
* event is not received for 100 bytes. In a mean time 50 bytes are added to the buffer.
401
477
* When the next time timer expires then old 100 bytes plus new 50 bytes will be published
@@ -477,6 +553,13 @@ static void send_insights_data(void)
477
553
xSemaphoreGive (s_insights_data .data_lock );
478
554
}
479
555
556
+ #if INSIGHTS_CMD_RESP
557
+ static void __insights_report_config_update (void * priv_data )
558
+ {
559
+ send_insights_config ();
560
+ }
561
+ #endif
562
+
480
563
static void insights_periodic_handler (void * priv_data )
481
564
{
482
565
xSemaphoreTake (s_insights_data .data_lock , portMAX_DELAY );
@@ -495,24 +578,58 @@ static void insights_periodic_handler(void *priv_data)
495
578
#if SEND_INSIGHTS_META
496
579
if (insights_meta_changed ()) {
497
580
send_insights_meta ();
581
+ #if INSIGHTS_CMD_RESP
582
+ send_insights_conf_meta ();
583
+ #endif
498
584
}
499
585
#endif /* SEND_INSIGHTS_META */
586
+
587
+ #if INSIGHTS_CMD_RESP
588
+ xSemaphoreTake (s_insights_data .data_lock , portMAX_DELAY );
589
+ if (s_insights_data .conf_msg_id == -1 ) {
590
+ xSemaphoreGive (s_insights_data .data_lock );
591
+ send_insights_config ();
592
+ } else {
593
+ xSemaphoreGive (s_insights_data .data_lock );
594
+ }
595
+ #endif
596
+ xSemaphoreTake (s_insights_data .data_lock , portMAX_DELAY );
500
597
if (s_insights_data .boot_msg_id == -1 ) {
598
+ xSemaphoreGive (s_insights_data .data_lock );
501
599
send_boottime_data ();
600
+ } else {
601
+ xSemaphoreGive (s_insights_data .data_lock );
502
602
}
503
603
send_insights_data ();
504
604
}
505
605
506
606
esp_err_t esp_insights_send_data (void )
507
607
{
508
- if (is_insights_active () == true) {
608
+ if (is_wifi_connected () == true) {
509
609
ESP_LOGI (TAG , "Sending data to cloud" );
510
610
return esp_rmaker_work_queue_add_task (insights_periodic_handler , NULL );
511
611
}
512
612
ESP_LOGW (TAG , "Wi-Fi not in connected state" );
513
613
return ESP_FAIL ;
514
614
}
515
615
616
+ #if INSIGHTS_CMD_RESP
617
+ void esp_insights_report_config_update (void )
618
+ {
619
+ s_insights_data .conf_msg_id = -1 ;
620
+ if (is_wifi_connected () == true) {
621
+ /* if wifi is connected, immediately send the report */
622
+ /* if not, this will be reported from periodic handler */
623
+ esp_rmaker_work_queue_add_task (__insights_report_config_update , NULL );
624
+ }
625
+ }
626
+ #else
627
+ void esp_insights_report_config_update (void )
628
+ {
629
+ ESP_LOGI (TAG , "Not reporting config when cmd_resp is not enabled" );
630
+ }
631
+ #endif
632
+
516
633
static void data_store_event_handler (void * arg , esp_event_base_t event_base ,
517
634
int32_t event_id , void * event_data )
518
635
{
@@ -633,7 +750,7 @@ static void variables_init(void)
633
750
ESP_LOGW (TAG , "Failed to initialize network variables" );
634
751
}
635
752
#endif /* CONFIG_DIAG_ENABLE_NETWORK_VARIABLES */
636
- esp_diag_variable_register ("diag" , KEY_LOG_WR_FAIL , "Log write fail count" , "Diagnostics.Log" , ESP_DIAG_DATA_TYPE_UINT );
753
+ esp_diag_variable_register (TAG_DIAG , KEY_LOG_WR_FAIL , "Log write fail count" , "Diagnostics.Log" , ESP_DIAG_DATA_TYPE_UINT );
637
754
return ;
638
755
}
639
756
ESP_LOGE (TAG , "Failed to initialize param-values." );
@@ -855,6 +972,9 @@ esp_err_t esp_insights_enable(esp_insights_config_t *config)
855
972
#endif /* CONFIG_DIAG_ENABLE_VARIABLES */
856
973
857
974
s_insights_data .boot_msg_id = -1 ;
975
+ #if INSIGHTS_CMD_RESP
976
+ s_insights_data .conf_msg_id = -1 ;
977
+ #endif
858
978
s_insights_data .data_send_timer = xTimerCreate ("data_send_timer" , CLOUD_REPORTING_TIMEOUT_TICKS ,
859
979
pdFALSE , NULL , data_send_timeout_cb );
860
980
if (!s_insights_data .data_send_timer ) {
0 commit comments