aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/src
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/src')
-rw-r--r--firmware/src/main.c108
-rw-r--r--firmware/src/mqtt.c67
-rw-r--r--firmware/src/wifi.c1
-rw-r--r--firmware/src/wifi_scan.c59
4 files changed, 149 insertions, 86 deletions
diff --git a/firmware/src/main.c b/firmware/src/main.c
index 790959d..3f186f8 100644
--- a/firmware/src/main.c
+++ b/firmware/src/main.c
@@ -7,54 +7,120 @@
7#include "mqtt.h" 7#include "mqtt.h"
8#include "wifi.h" 8#include "wifi.h"
9 9
10#include <stdio.h>
10static const char *TAG = "app"; 11static const char *TAG = "app";
11 12
12/** 13/**
13 * @brief Initialize NVS flash storage, handling full or incompatible pages. 14 * @brief Initialize NVS (Non-Volatile Storage) flash storage, handling full or
15 * incompatible pages.
14 * 16 *
15 * @return esp_err_t ESP_OK on success, error code otherwise. 17 * This function checks the NVS flash storage to ensure that there is enough
18 * space and that the version of NVS is compatible. If the partition is full or
19 * incompatible, it will erase the NVS partition and attempt initialization
20 * again.
21 *
22 * @return esp_err_t
23 * - ESP_OK: Initialization successful.
24 * - Other error codes if initialization or erasure fails.
16 */ 25 */
17static esp_err_t nvs_flash_init_check(void) 26static esp_err_t nvs_flash_init_check(void)
18{ 27{
19 esp_err_t ret = nvs_flash_init(); 28 esp_err_t ret = nvs_flash_init();
29
20 if (ret == ESP_ERR_NVS_NO_FREE_PAGES || 30 if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
21 ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 31 ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
22 ESP_LOGW(TAG, 32 ESP_LOGW(TAG,
23 "NVS partition was full or incompatible, erasing..."); 33 "NVS partition is full or incompatible, erasing...");
24 ESP_ERROR_CHECK(nvs_flash_erase()); 34 ret = nvs_flash_erase();
35
36 if (ret != ESP_OK) {
37 ESP_LOGE(TAG, "Failed to erase NVS partition (%s)",
38 esp_err_to_name(ret));
39 return ret;
40 }
25 ret = nvs_flash_init(); 41 ret = nvs_flash_init();
26 } 42 }
43
27 if (ret != ESP_OK) 44 if (ret != ESP_OK)
28 ESP_LOGE(TAG, "Failed to initialize NVS (%s)", 45 ESP_LOGE(TAG, "Failed to initialize NVS (%s)",
29 esp_err_to_name(ret)); 46 esp_err_to_name(ret));
47
30 return ret; 48 return ret;
31} 49}
32 50
33/** 51/**
34 * @brief Application entry point. 52 * @brief General helper function to initialize a given component and log
53 * errors.
35 * 54 *
36 * Initializes NVS, network interface, event loop, 55 * This function takes an initialization function and a component name, attempts
37 * WiFi station, and MQTT client with proper error handling and logging. 56 * to initialize the component, and logs an error if initialization fails.
57 *
58 * @param init_func A function pointer to the initialization function of the
59 * component.
60 * @param component_name A string describing the name of the component being
61 * initialized.
62 *
63 * @return esp_err_t
64 * - ESP_OK: If initialization is successful.
65 * - Other error codes if initialization fails.
38 */ 66 */
39void app_main(void) 67static esp_err_t init_component(esp_err_t (*init_func)(void),
68 const char *component_name)
40{ 69{
41 esp_err_t ret = nvs_flash_init_check(); 70 esp_err_t ret = init_func();
42 if (ret != ESP_OK) {
43 ESP_LOGE(TAG, "NVS init failed, aborting app start");
44 return;
45 }
46 71
47 ret = esp_netif_init();
48 if (ret != ESP_OK) { 72 if (ret != ESP_OK) {
49 ESP_LOGE(TAG, "Failed to initialize network interface (%s)", 73 ESP_LOGE(TAG, "Failed to initialize %s (%s)", component_name,
50 esp_err_to_name(ret)); 74 esp_err_to_name(ret));
51 return; 75 return ret;
52 } 76 }
53 77
54 ret = esp_event_loop_create_default(); 78 return ESP_OK;
55 if (ret != ESP_OK) { 79}
56 ESP_LOGE(TAG, "Failed to create event loop (%s)", 80
57 esp_err_to_name(ret)); 81/**
82 * @brief Initializes all the essential components for the application.
83 *
84 * This function initializes the NVS storage, network interface, and event loop
85 * in sequence. If any of these components fail to initialize, the function
86 * returns an error, and the application will stop early.
87 *
88 * @return esp_err_t
89 * - ESP_OK: If all components are successfully initialized.
90 * - ESP_FAIL: If any component fails to initialize.
91 */
92esp_err_t init_app_components(void)
93{
94 if (init_component(nvs_flash_init_check, "NVS") != ESP_OK) {
95 ESP_LOGE(TAG, "NVS initialization failed, aborting app start.");
96 return ESP_FAIL;
97 }
98
99 if (init_component(esp_netif_init, "network interface") != ESP_OK)
100 return ESP_FAIL;
101
102 if (init_component(esp_event_loop_create_default, "event loop") !=
103 ESP_OK)
104 return ESP_FAIL;
105
106 return ESP_OK;
107}
108
109/**
110 * @brief Main entry point of the application.
111 *
112 * This function is responsible for initializing the core components of the
113 * application, including the NVS storage, network interface, and event loop. If
114 * any initialization step fails, the application will log the error and stop.
115 *
116 * After initialization, this function will configure the WiFi station and start
117 * the MQTT client.
118 */
119
120void app_main(void)
121{
122 if (init_app_components() != ESP_OK) {
123 ESP_LOGE(TAG, "App initialization failed, aborting.");
58 return; 124 return;
59 } 125 }
60 126
@@ -63,6 +129,4 @@ void app_main(void)
63 129
64 ESP_LOGI(TAG, "Starting MQTT client"); 130 ESP_LOGI(TAG, "Starting MQTT client");
65 mqtt_app_start(); 131 mqtt_app_start();
66
67 ESP_LOGI(TAG, "Application setup completed");
68} 132}
diff --git a/firmware/src/mqtt.c b/firmware/src/mqtt.c
index 90451bc..b171437 100644
--- a/firmware/src/mqtt.c
+++ b/firmware/src/mqtt.c
@@ -8,24 +8,12 @@
8#include <stdlib.h> 8#include <stdlib.h>
9#include <string.h> 9#include <string.h>
10 10
11#ifndef BUFFER_SIZE 11static const char *TAG = "mqtt";
12#define BUFFER_SIZE 64
13#endif
14
15#ifndef PUBLISH_INTERVAL_MS
16#define PUBLISH_INTERVAL_MS 1000
17#endif
18
19#ifndef PUBLISHER_TASK_STACK_SIZE
20#define PUBLISHER_TASK_STACK_SIZE 4096
21#endif
22
23#ifndef PUBLISHER_TASK_PRIORITY
24#define PUBLISHER_TASK_PRIORITY 5
25#endif
26
27static esp_mqtt_client_handle_t client; 12static esp_mqtt_client_handle_t client;
28 13
14/**
15 * @brief Obsługa zdarzeń MQTT
16 */
29static void mqtt_event_handler(void *handler_args, esp_event_base_t base, 17static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
30 int32_t event_id, void *event_data) 18 int32_t event_id, void *event_data)
31{ 19{
@@ -33,56 +21,63 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
33 21
34 switch (event->event_id) { 22 switch (event->event_id) {
35 case MQTT_EVENT_CONNECTED: 23 case MQTT_EVENT_CONNECTED:
36 printf("MQTT connected!\n"); 24 ESP_LOGI(TAG, "MQTT connected!");
37 esp_mqtt_client_subscribe(event->client, SUB_TOPIC, 1); 25 esp_mqtt_client_subscribe(event->client, SUB_TOPIC, 1);
38 break; 26 break;
39 27
40 case MQTT_EVENT_DATA: { 28 case MQTT_EVENT_DATA: {
41 char topic[event->topic_len + 1]; 29 char topic[event->topic_len + 1];
42 char data[event->data_len + 1]; 30 char data[event->data_len + 1];
31
43 memcpy(topic, event->topic, event->topic_len); 32 memcpy(topic, event->topic, event->topic_len);
44 topic[event->topic_len] = '\0'; 33 topic[event->topic_len] = '\0';
45 memcpy(data, event->data, event->data_len); 34 memcpy(data, event->data, event->data_len);
46 data[event->data_len] = '\0'; 35 data[event->data_len] = '\0';
47 36
48 printf("MQTT Msg received\nTopic: %s\nData: %s\n", topic, data); 37 ESP_LOGI(TAG, "MQTT Msg received | Topic: %s | Data: %s", topic,
38 data);
49 39
40 // Echo wiadomości do PUB_TOPIC tylko jeśli timestamp jest
41 // sensowny
50 char *endptr; 42 char *endptr;
51 long long sent = strtoll(data, &endptr, 10); 43 long long ts = strtoll(data, &endptr, 10);
52 if (endptr != data) { 44 if (endptr != data && *endptr == '\0' && ts > 0 && ts < 1e13) {
53 long long now = esp_timer_get_time() / 1000ULL; 45 esp_mqtt_client_publish(event->client, PUB_TOPIC, data,
54 long long rtt = now - sent; 46 0, 1, 0);
55 printf("RTT: %lld ms\n", rtt); 47 } else {
48 ESP_LOGW(TAG, "Nieprawidłowe dane, ignorowane: %s",
49 data);
56 } 50 }
51
57 break; 52 break;
58 } 53 }
59 54
60 default: 55 case MQTT_EVENT_DISCONNECTED:
56 ESP_LOGW(TAG, "MQTT disconnected");
61 break; 57 break;
62 }
63}
64 58
65static void publisher_task(void *pvParameters) 59 case MQTT_EVENT_ERROR:
66{ 60 ESP_LOGE(TAG, "MQTT error occurred");
67 while (1) { 61 break;
68 char buf[BUFFER_SIZE]; 62
69 snprintf(buf, BUFFER_SIZE, "%lld", 63 default:
70 (long long)(esp_timer_get_time() / 1000ULL)); 64 break;
71 esp_mqtt_client_publish(client, PUB_TOPIC, buf, 0, 1, 0);
72 vTaskDelay(pdMS_TO_TICKS(PUBLISH_INTERVAL_MS));
73 } 65 }
74} 66}
75 67
68/**
69 * @brief Uruchamia klienta MQTT
70 */
76void mqtt_app_start(void) 71void mqtt_app_start(void)
77{ 72{
78 esp_mqtt_client_config_t mqtt_cfg = { 73 esp_mqtt_client_config_t mqtt_cfg = {
79 .broker.address.uri = MQTT_URI, 74 .broker.address.uri = MQTT_URI,
80 }; 75 };
76
81 client = esp_mqtt_client_init(&mqtt_cfg); 77 client = esp_mqtt_client_init(&mqtt_cfg);
82 esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, 78 esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID,
83 mqtt_event_handler, NULL); 79 mqtt_event_handler, NULL);
84 esp_mqtt_client_start(client); 80 esp_mqtt_client_start(client);
85 81
86 xTaskCreate(publisher_task, "publisher_task", PUBLISHER_TASK_STACK_SIZE, 82 ESP_LOGI(TAG, "MQTT client started");
87 NULL, PUBLISHER_TASK_PRIORITY, NULL);
88} 83}
diff --git a/firmware/src/wifi.c b/firmware/src/wifi.c
index ea76f24..704b4a4 100644
--- a/firmware/src/wifi.c
+++ b/firmware/src/wifi.c
@@ -24,6 +24,7 @@
24 * 24 *
25 * The SSID and password are defined in the configuration headers. 25 * The SSID and password are defined in the configuration headers.
26 */ 26 */
27// cppcheck-suppress unusedFunction
27void wifi_init_sta(void) 28void wifi_init_sta(void)
28{ 29{
29 esp_netif_create_default_wifi_sta(); 30 esp_netif_create_default_wifi_sta();
diff --git a/firmware/src/wifi_scan.c b/firmware/src/wifi_scan.c
index e588cfc..02bb451 100644
--- a/firmware/src/wifi_scan.c
+++ b/firmware/src/wifi_scan.c
@@ -19,35 +19,36 @@
19 * 19 *
20 * @param pvParameter Task parameter (unused). 20 * @param pvParameter Task parameter (unused).
21 */ 21 */
22static void wifi_scan_task(void *pvParameter) { 22static void wifi_scan_task(void *pvParameter)
23 uint16_t ap_count = WIFI_SCAN_MAX_APS; 23{
24 static wifi_ap_record_t ap_info[WIFI_SCAN_MAX_APS]; 24 uint16_t ap_count = WIFI_SCAN_MAX_APS;
25 wifi_scan_config_t scan_config = { 25 static wifi_ap_record_t ap_info[WIFI_SCAN_MAX_APS];
26 .ssid = NULL, 26 wifi_scan_config_t scan_config = {
27 .bssid = NULL, 27 .ssid = NULL,
28 .channel = WIFI_SCAN_DEFAULT_CHANNEL, 28 .bssid = NULL,
29 .show_hidden = WIFI_SCAN_SHOW_HIDDEN, 29 .channel = WIFI_SCAN_DEFAULT_CHANNEL,
30 }; 30 .show_hidden = WIFI_SCAN_SHOW_HIDDEN,
31 };
31 32
32 ESP_LOGI("wifi_scan", "Starting Wi-Fi scan..."); 33 ESP_LOGI("wifi_scan", "Starting Wi-Fi scan...");
33 ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false)); 34 ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false));
34 35
35 while (true) { 36 while (true) {
36 uint16_t finished_ap_count = 0; 37 uint16_t finished_ap_count = 0;
37 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&finished_ap_count)); 38 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&finished_ap_count));
38 if (finished_ap_count > 0) 39 if (finished_ap_count > 0)
39 break; 40 break;
40 vTaskDelay(pdMS_TO_TICKS(WIFI_SCAN_POLL_INTERVAL_MS)); 41 vTaskDelay(pdMS_TO_TICKS(WIFI_SCAN_POLL_INTERVAL_MS));
41 } 42 }
42 43
43 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_info)); 44 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_info));
44 ESP_LOGI("wifi_scan", "Found %d access points:", ap_count); 45 ESP_LOGI("wifi_scan", "Found %d access points:", ap_count);
45 for (uint16_t ap_index = 0; ap_index < ap_count; ++ap_index) { 46 for (uint16_t ap_index = 0; ap_index < ap_count; ++ap_index) {
46 ESP_LOGI("wifi_scan", "%d: SSID: %s, RSSI: %d", ap_index + 1, 47 ESP_LOGI("wifi_scan", "%d: SSID: %s, RSSI: %d", ap_index + 1,
47 ap_info[ap_index].ssid, ap_info[ap_index].rssi); 48 ap_info[ap_index].ssid, ap_info[ap_index].rssi);
48 } 49 }
49 50
50 vTaskDelete(NULL); 51 vTaskDelete(NULL);
51} 52}
52 53
53/** 54/**
@@ -55,7 +56,9 @@ static void wifi_scan_task(void *pvParameter) {
55 * 56 *
56 * Creates a FreeRTOS task that runs the WiFi scan asynchronously. 57 * Creates a FreeRTOS task that runs the WiFi scan asynchronously.
57 */ 58 */
58void wifi_scan_start(void) { 59void wifi_scan_start(void)
59 xTaskCreate(wifi_scan_task, WIFI_SCAN_TASK_NAME, WIFI_SCAN_TASK_STACK_SIZE, 60{
60 NULL, WIFI_SCAN_TASK_PRIORITY, NULL); 61 xTaskCreate(wifi_scan_task, WIFI_SCAN_TASK_NAME,
62 WIFI_SCAN_TASK_STACK_SIZE, NULL, WIFI_SCAN_TASK_PRIORITY,
63 NULL);
61} 64}