1 /* MeshLink-tiny Example */
4 #include "freertos/FreeRTOS.h"
5 #include "freertos/task.h"
6 #include "freertos/event_groups.h"
7 #include "esp_system.h"
11 #include "esp_console.h"
12 #include "esp_vfs_dev.h"
13 #include "driver/uart.h"
14 #include "linenoise/linenoise.h"
15 #include "argtable3/argtable3.h"
16 #include "nvs_flash.h"
21 #include "meshlink-tiny.h"
23 /* The examples use WiFi configuration that you can set via project configuration menu
25 If you'd rather not, just change the below entries to strings with
26 the config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid"
28 #define EXAMPLE_ESP_WIFI_SSID CONFIG_ESP_WIFI_SSID
29 #define EXAMPLE_ESP_WIFI_PASS CONFIG_ESP_WIFI_PASSWORD
30 #define EXAMPLE_ESP_MAXIMUM_RETRY CONFIG_ESP_MAXIMUM_RETRY
32 /* FreeRTOS event group to signal when we are connected*/
33 static EventGroupHandle_t s_wifi_event_group;
35 /* The event group allows multiple bits for each event, but we only care about two events:
36 * - we are connected to the AP with an IP
37 * - we failed to connect after the maximum amount of retries */
38 #define WIFI_CONNECTED_BIT BIT0
39 #define WIFI_FAIL_BIT BIT1
41 static const char *TAG = "wifi station";
43 static int s_retry_num = 0;
45 static void event_handler(void *arg, esp_event_base_t event_base,
46 int32_t event_id, void *event_data) {
47 if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
49 } else if(event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
50 if(s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
53 ESP_LOGI(TAG, "retry to connect to the AP");
55 xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
58 ESP_LOGI(TAG, "connect to the AP fail");
59 } else if(event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
60 ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data;
61 ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
63 xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
67 void wifi_init_sta(void) {
68 s_wifi_event_group = xEventGroupCreate();
70 ESP_ERROR_CHECK(esp_netif_init());
72 ESP_ERROR_CHECK(esp_event_loop_create_default());
73 esp_netif_create_default_wifi_sta();
75 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
76 ESP_ERROR_CHECK(esp_wifi_init(&cfg));
78 esp_event_handler_instance_t instance_any_id;
79 esp_event_handler_instance_t instance_got_ip;
80 ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
85 ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
91 wifi_config_t wifi_config = {
93 .ssid = EXAMPLE_ESP_WIFI_SSID,
94 .password = EXAMPLE_ESP_WIFI_PASS,
95 /* Setting a password implies station will connect to all security modes including WEP/WPA.
96 * However these modes are deprecated and not advisable to be used. Incase your Access point
97 * doesn't support WPA2, these mode can be enabled by commenting below line */
98 .threshold.authmode = WIFI_AUTH_WPA2_PSK,
106 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
107 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
108 ESP_ERROR_CHECK(esp_wifi_start());
110 ESP_LOGI(TAG, "wifi_init_sta finished.");
112 /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
113 * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
114 EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
115 WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
120 /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
122 if(bits & WIFI_CONNECTED_BIT) {
123 ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
124 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
125 } else if(bits & WIFI_FAIL_BIT) {
126 ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
127 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
129 ESP_LOGE(TAG, "UNEXPECTED EVENT");
132 /* The event will not be processed after unregister */
133 ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
134 ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
135 vEventGroupDelete(s_wifi_event_group);
138 static void mlt_log(meshlink_handle_t *mesh, meshlink_log_level_t leve, const char *text) {
139 ESP_LOGI(TAG, "Log: %s", text);
142 meshlink_handle_t *mesh = NULL;
144 static void receive(meshlink_handle_t *mesh, meshlink_node_t *from, const void *data, size_t len) {
145 char *str = (char *)data;
147 ESP_LOGI(TAG, "%s says: %s", from->name, str);
150 static int join_func(int argc, char **argv) {
155 if(!meshlink_join(mesh, argv[1])) {
156 ESP_LOGE(TAG, "Join failed");
160 ESP_LOGI(TAG, "Join completed");
162 meshlink_set_receive_cb(mesh, receive);
164 if(!meshlink_start(mesh)) {
165 ESP_LOGE(TAG, "Could not start mesh!");
172 static int say_func(int argc, char **argv) {
177 meshlink_node_t *peer = meshlink_get_node(mesh, argv[1]);
180 ESP_LOGE(TAG, "Peer not found");
184 if(!meshlink_send(mesh, peer, argv[2], strlen(argv[2]))) {
185 ESP_LOGE(TAG, "Send failed");
192 static int quit_func(int argc, char **argv) {
193 meshlink_close(mesh);
195 ESP_LOGI(TAG, "Closed mesh");
199 static void mlt_main(void) {
200 meshlink_set_log_cb(NULL, MESHLINK_DEBUG, mlt_log);
202 ESP_LOGI(TAG, "Starting MeshLink-tiny instance...");
203 mesh = meshlink_open_ephemeral("esp32", "chat", DEV_CLASS_PORTABLE);
206 ESP_LOGE(TAG, "Open failed!");
211 fsync(fileno(stdout));
212 setvbuf(stdin, NULL, _IONBF, 0);
214 esp_vfs_dev_uart_port_set_rx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CR);
215 esp_vfs_dev_uart_port_set_tx_line_endings(CONFIG_ESP_CONSOLE_UART_NUM, ESP_LINE_ENDINGS_CRLF);
217 const uart_config_t uart_config = {
218 .baud_rate = CONFIG_ESP_CONSOLE_UART_BAUDRATE,
219 .data_bits = UART_DATA_8_BITS,
220 .parity = UART_PARITY_DISABLE,
221 .stop_bits = UART_STOP_BITS_1,
222 #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
223 .source_clk = UART_SCLK_REF_TICK,
225 .source_clk = UART_SCLK_XTAL,
228 /* Install UART driver for interrupt-driven reads and writes */
229 ESP_ERROR_CHECK(uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM,
230 256, 0, 0, NULL, 0));
231 ESP_ERROR_CHECK(uart_param_config(CONFIG_ESP_CONSOLE_UART_NUM, &uart_config));
233 /* Tell VFS to use UART driver */
234 esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM);
236 esp_console_config_t console_config = {
237 .max_cmdline_args = 8,
238 .max_cmdline_length = 256,
241 ESP_ERROR_CHECK(esp_console_init(&console_config));
243 linenoiseSetMultiLine(1);
244 linenoiseHistorySetMaxLen(1);
245 linenoiseAllowEmpty(false);
247 esp_console_cmd_t join_cmd = {
249 .help = "Join a mesh",
253 esp_console_cmd_t say_cmd = {
255 .help = "Say something",
259 esp_console_cmd_t quit_cmd = {
265 esp_console_cmd_register(&join_cmd);
266 esp_console_cmd_register(&say_cmd);
267 esp_console_cmd_register(&quit_cmd);
268 esp_console_register_help_command();
271 char *line = linenoise("> ");
277 linenoiseHistoryAdd(line);
279 esp_console_run(line, &ret);
283 ESP_LOGI(TAG, "App quit");
284 esp_console_deinit();
287 void app_main(void) {
289 esp_err_t ret = nvs_flash_init();
291 if(ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
292 ESP_ERROR_CHECK(nvs_flash_erase());
293 ret = nvs_flash_init();
296 ESP_ERROR_CHECK(ret);
298 ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");