1 #include "esp_wifi.h"
2 #include "esp_ota_ops.h"
3 #include "mqtt_client.h"
4 #include "freertos/FreeRTOS.h"
5
6 static const char *TAG = "node";
7 static esp_mqtt_client_handle_t mqtt;
8
9 // Телеметрия: снимаем кадр и отдаём в очередь
10 static void sensor_task(void *arg)
11 {
12 frame_t frame;
13 while (1) {
14 if (sensor_read(&frame) == ESP_OK) {
15 xQueueSend(tx_queue, &frame, 0);
16 }
17 vTaskDelay(pdMS_TO_TICKS(200));
18 }
19 }
20
21 static void link_task(void *arg)
22 {
23 frame_t frame;
24 char topic[64];
25 snprintf(topic, sizeof(topic), "dev/%s/telemetry", node_id);
26
27 while (1) {
28 if (xQueueReceive(tx_queue, &frame, portMAX_DELAY)) {
29 int msg = esp_mqtt_client_publish(mqtt, topic,
30 (const char *)&frame,
31 sizeof(frame), 1, 0);
32 if (msg < 0) {
33 ESP_LOGW(TAG, "publish failed, requeue");
34 xQueueSendToFront(tx_queue, &frame, 0);
35 vTaskDelay(pdMS_TO_TICKS(500));
36 }
37 }
38 }
39 }
40
41 // OTA: качаем образ, проверяем подпись, откатываемся при сбое
42 static void ota_task(void *arg)
43 {
44 esp_https_ota_config_t cfg = {
45 .http_config = &https_cfg,
46 .partial_http_download = true,
47 };
48
49 esp_err_t err = esp_https_ota(&cfg);
50 if (err == ESP_OK) {
51 ESP_LOGI(TAG, "image ok, reboot to new slot");
52 esp_ota_mark_app_valid_cancel_rollback();
53 esp_restart();
54 } else {
55 ESP_LOGE(TAG, "ota failed: %s", esp_err_to_name(err));
56 esp_ota_mark_app_invalid_rollback_and_reboot();
57 }
58 }
59
60 void app_main(void)
61 {
62 ESP_ERROR_CHECK(nvs_flash_init());
63 ESP_ERROR_CHECK(esp_netif_init());
64 ESP_ERROR_CHECK(esp_event_loop_create_default());
65
66 wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PASS);
67 mqtt = mqtt_start(CONFIG_BROKER_URI);
68 tx_queue = xQueueCreate(32, sizeof(frame_t));
69
70 xTaskCreate(sensor_task, "sensor", 4096, NULL, 5, NULL);
71 xTaskCreate(link_task, "link", 8192, NULL, 5, NULL);
72 xTaskCreate(ota_task, "ota", 8192, NULL, 4, NULL);
73 }
74 #include "esp_wifi.h"
75 #include "esp_ota_ops.h"
76 #include "mqtt_client.h"
77 #include "freertos/FreeRTOS.h"
78
79 static const char *TAG = "node";
80 static esp_mqtt_client_handle_t mqtt;
81
82 // Телеметрия: снимаем кадр и отдаём в очередь
83 static void sensor_task(void *arg)
84 {
85 frame_t frame;
86 while (1) {
87 if (sensor_read(&frame) == ESP_OK) {
88 xQueueSend(tx_queue, &frame, 0);
89 }
90 vTaskDelay(pdMS_TO_TICKS(200));
91 }
92 }
93
94 static void link_task(void *arg)
95 {
96 frame_t frame;
97 char topic[64];
98 snprintf(topic, sizeof(topic), "dev/%s/telemetry", node_id);
99
100 while (1) {
101 if (xQueueReceive(tx_queue, &frame, portMAX_DELAY)) {
102 int msg = esp_mqtt_client_publish(mqtt, topic,
103 (const char *)&frame,
104 sizeof(frame), 1, 0);
105 if (msg < 0) {
106 ESP_LOGW(TAG, "publish failed, requeue");
107 xQueueSendToFront(tx_queue, &frame, 0);
108 vTaskDelay(pdMS_TO_TICKS(500));
109 }
110 }
111 }
112 }
113
114 // OTA: качаем образ, проверяем подпись, откатываемся при сбое
115 static void ota_task(void *arg)
116 {
117 esp_https_ota_config_t cfg = {
118 .http_config = &https_cfg,
119 .partial_http_download = true,
120 };
121
122 esp_err_t err = esp_https_ota(&cfg);
123 if (err == ESP_OK) {
124 ESP_LOGI(TAG, "image ok, reboot to new slot");
125 esp_ota_mark_app_valid_cancel_rollback();
126 esp_restart();
127 } else {
128 ESP_LOGE(TAG, "ota failed: %s", esp_err_to_name(err));
129 esp_ota_mark_app_invalid_rollback_and_reboot();
130 }
131 }
132
133 void app_main(void)
134 {
135 ESP_ERROR_CHECK(nvs_flash_init());
136 ESP_ERROR_CHECK(esp_netif_init());
137 ESP_ERROR_CHECK(esp_event_loop_create_default());
138
139 wifi_connect(CONFIG_WIFI_SSID, CONFIG_WIFI_PASS);
140 mqtt = mqtt_start(CONFIG_BROKER_URI);
141 tx_queue = xQueueCreate(32, sizeof(frame_t));
142
143 xTaskCreate(sensor_task, "sensor", 4096, NULL, 5, NULL);
144 xTaskCreate(link_task, "link", 8192, NULL, 5, NULL);
145 xTaskCreate(ota_task, "ota", 8192, NULL, 4, NULL);
146 }