aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/main.c68
-rw-r--r--src/mqtt.c85
-rw-r--r--src/wifi.c49
-rw-r--r--src/wifi_scan.c61
5 files changed, 269 insertions, 0 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..483bc0c
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,6 @@
1# This file was automatically generated for projects
2# without default 'CMakeLists.txt' file.
3
4FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
5
6idf_component_register(SRCS ${app_sources})
diff --git a/src/main.c b/src/main.c
new file mode 100644
index 0000000..790959d
--- /dev/null
+++ b/src/main.c
@@ -0,0 +1,68 @@
1#include "esp_event.h"
2#include "esp_log.h"
3#include "esp_system.h"
4#include "esp_timer.h"
5#include "nvs_flash.h"
6
7#include "mqtt.h"
8#include "wifi.h"
9
10static const char *TAG = "app";
11
12/**
13 * @brief Initialize NVS flash storage, handling full or incompatible pages.
14 *
15 * @return esp_err_t ESP_OK on success, error code otherwise.
16 */
17static esp_err_t nvs_flash_init_check(void)
18{
19 esp_err_t ret = nvs_flash_init();
20 if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
21 ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
22 ESP_LOGW(TAG,
23 "NVS partition was full or incompatible, erasing...");
24 ESP_ERROR_CHECK(nvs_flash_erase());
25 ret = nvs_flash_init();
26 }
27 if (ret != ESP_OK)
28 ESP_LOGE(TAG, "Failed to initialize NVS (%s)",
29 esp_err_to_name(ret));
30 return ret;
31}
32
33/**
34 * @brief Application entry point.
35 *
36 * Initializes NVS, network interface, event loop,
37 * WiFi station, and MQTT client with proper error handling and logging.
38 */
39void app_main(void)
40{
41 esp_err_t ret = nvs_flash_init_check();
42 if (ret != ESP_OK) {
43 ESP_LOGE(TAG, "NVS init failed, aborting app start");
44 return;
45 }
46
47 ret = esp_netif_init();
48 if (ret != ESP_OK) {
49 ESP_LOGE(TAG, "Failed to initialize network interface (%s)",
50 esp_err_to_name(ret));
51 return;
52 }
53
54 ret = esp_event_loop_create_default();
55 if (ret != ESP_OK) {
56 ESP_LOGE(TAG, "Failed to create event loop (%s)",
57 esp_err_to_name(ret));
58 return;
59 }
60
61 ESP_LOGI(TAG, "Initializing WiFi in station mode");
62 wifi_init_sta();
63
64 ESP_LOGI(TAG, "Starting MQTT client");
65 mqtt_app_start();
66
67 ESP_LOGI(TAG, "Application setup completed");
68}
diff --git a/src/mqtt.c b/src/mqtt.c
new file mode 100644
index 0000000..716feec
--- /dev/null
+++ b/src/mqtt.c
@@ -0,0 +1,85 @@
1#include "mqtt.h"
2#include "config.h"
3#include "esp_log.h"
4#include "esp_timer.h"
5#include "freertos/FreeRTOS.h"
6#include "freertos/task.h"
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11#ifndef BUFFER_SIZE
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;
28
29static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
30 int32_t event_id, void *event_data) {
31 esp_mqtt_event_handle_t event = event_data;
32
33 switch (event->event_id) {
34 case MQTT_EVENT_CONNECTED:
35 printf("MQTT connected!\n");
36 esp_mqtt_client_subscribe(event->client, SUB_TOPIC, 1);
37 break;
38
39 case MQTT_EVENT_DATA: {
40 char topic[event->topic_len + 1];
41 char data[event->data_len + 1];
42 memcpy(topic, event->topic, event->topic_len);
43 topic[event->topic_len] = '\0';
44 memcpy(data, event->data, event->data_len);
45 data[event->data_len] = '\0';
46
47 printf("MQTT Msg received\nTopic: %s\nData: %s\n", topic, data);
48
49 char *endptr;
50 long long sent = strtoll(data, &endptr, 10);
51 if (endptr != data) {
52 long long now = esp_timer_get_time() / 1000ULL;
53 long long rtt = now - sent;
54 printf("RTT: %lld ms\n", rtt);
55 }
56 break;
57 }
58
59 default:
60 break;
61 }
62}
63
64static void publisher_task(void *pvParameters) {
65 while (1) {
66 char buf[BUFFER_SIZE];
67 snprintf(buf, BUFFER_SIZE, "%lld",
68 (long long)(esp_timer_get_time() / 1000ULL));
69 esp_mqtt_client_publish(client, PUB_TOPIC, buf, 0, 1, 0);
70 vTaskDelay(pdMS_TO_TICKS(PUBLISH_INTERVAL_MS));
71 }
72}
73
74void mqtt_app_start(void) {
75 esp_mqtt_client_config_t mqtt_cfg = {
76 .broker.address.uri = MQTT_URI,
77 };
78 client = esp_mqtt_client_init(&mqtt_cfg);
79 esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler,
80 NULL);
81 esp_mqtt_client_start(client);
82
83 xTaskCreate(publisher_task, "publisher_task", PUBLISHER_TASK_STACK_SIZE, NULL,
84 PUBLISHER_TASK_PRIORITY, NULL);
85}
diff --git a/src/wifi.c b/src/wifi.c
new file mode 100644
index 0000000..8d6b29d
--- /dev/null
+++ b/src/wifi.c
@@ -0,0 +1,49 @@
1#include "wifi.h"
2#include "config.h"
3#include "esp_event.h"
4#include "esp_netif.h"
5#include "esp_wifi.h"
6#include "freertos/FreeRTOS.h"
7#include "freertos/task.h"
8#include <string.h>
9
10#define WIFI_SCAN_DELAY_MS 3000
11
12/**
13 * @brief Initialize WiFi in station mode.
14 *
15 * This function performs the following steps:
16 * - Creates the default WiFi station network interface.
17 * - Initializes the WiFi driver with default configuration.
18 * - Sets WiFi mode to station.
19 * - Starts WiFi.
20 * - Starts scanning for available WiFi networks.
21 * - Waits for a predefined delay to allow scanning to complete.
22 * - Configures the WiFi station with SSID and password.
23 * - Connects to the configured WiFi network.
24 *
25 * The SSID and password are defined in the configuration headers.
26 */
27void wifi_init_sta(void) {
28 esp_netif_create_default_wifi_sta();
29
30 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
31 if (esp_wifi_init(&cfg) != ESP_OK) {
32 return;
33 }
34
35 esp_wifi_set_mode(WIFI_MODE_STA);
36 esp_wifi_start();
37
38 wifi_scan_start();
39 vTaskDelay(pdMS_TO_TICKS(WIFI_SCAN_DELAY_MS));
40
41 wifi_config_t wifi_config = {0};
42 strncpy((char *)wifi_config.sta.ssid, WIFI_SSID,
43 sizeof(wifi_config.sta.ssid) - 1);
44 strncpy((char *)wifi_config.sta.password, WIFI_PASS,
45 sizeof(wifi_config.sta.password) - 1);
46
47 esp_wifi_set_config(WIFI_IF_STA, &wifi_config);
48 esp_wifi_connect();
49}
diff --git a/src/wifi_scan.c b/src/wifi_scan.c
new file mode 100644
index 0000000..e588cfc
--- /dev/null
+++ b/src/wifi_scan.c
@@ -0,0 +1,61 @@
1#include "esp_log.h"
2#include "esp_wifi.h"
3#include "freertos/FreeRTOS.h"
4#include "freertos/task.h"
5
6#define WIFI_SCAN_TASK_STACK_SIZE 4096
7#define WIFI_SCAN_TASK_PRIORITY 5
8#define WIFI_SCAN_MAX_APS 20
9#define WIFI_SCAN_POLL_INTERVAL_MS 500
10#define WIFI_SCAN_DEFAULT_CHANNEL 0
11#define WIFI_SCAN_SHOW_HIDDEN true
12#define WIFI_SCAN_TASK_NAME "wifi_scan_task"
13
14/**
15 * @brief Task to perform WiFi scanning asynchronously.
16 *
17 * Starts a WiFi scan, polls for scan completion,
18 * retrieves and logs the found access points, then deletes itself.
19 *
20 * @param pvParameter Task parameter (unused).
21 */
22static void wifi_scan_task(void *pvParameter) {
23 uint16_t ap_count = WIFI_SCAN_MAX_APS;
24 static wifi_ap_record_t ap_info[WIFI_SCAN_MAX_APS];
25 wifi_scan_config_t scan_config = {
26 .ssid = NULL,
27 .bssid = NULL,
28 .channel = WIFI_SCAN_DEFAULT_CHANNEL,
29 .show_hidden = WIFI_SCAN_SHOW_HIDDEN,
30 };
31
32 ESP_LOGI("wifi_scan", "Starting Wi-Fi scan...");
33 ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, false));
34
35 while (true) {
36 uint16_t finished_ap_count = 0;
37 ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&finished_ap_count));
38 if (finished_ap_count > 0)
39 break;
40 vTaskDelay(pdMS_TO_TICKS(WIFI_SCAN_POLL_INTERVAL_MS));
41 }
42
43 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 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 ap_info[ap_index].ssid, ap_info[ap_index].rssi);
48 }
49
50 vTaskDelete(NULL);
51}
52
53/**
54 * @brief Starts the WiFi scan task.
55 *
56 * Creates a FreeRTOS task that runs the WiFi scan asynchronously.
57 */
58void wifi_scan_start(void) {
59 xTaskCreate(wifi_scan_task, WIFI_SCAN_TASK_NAME, WIFI_SCAN_TASK_STACK_SIZE,
60 NULL, WIFI_SCAN_TASK_PRIORITY, NULL);
61}