add mesh feature

This commit is contained in:
qiyueixa
2018-02-27 18:22:20 +08:00
parent c842725be0
commit 2984cdbbe3
30 changed files with 2522 additions and 3 deletions

View File

@@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := internal_transceiver
include $(IDF_PATH)/make/project.mk

View File

@@ -0,0 +1,23 @@
# Mesh Internal Transceiver Example
This example demonstrates how to use the mesh APIs to set up a mesh network, send and receive messages over the mesh network and etc.
Features Demonstrated
- mesh initialization
- mesh configuration
- mesh start
- mesh event handler
- root send and receive
- other nodes receive
Run `make menuconfig` to configure the mesh network channel, router SSID, router password and mesh softAP settings.
When the mesh network is established and if you happen to run this example on ESP-WROVER-KIT boards, the RGB light indicator will show you on which layer devices are.
The pink reprents root; the yellow reprents layer 2; the red reprents layer 3; the blue reprents layer 4; the green reprents layer 5; the white reprents layer greater than 5.
Root continuously sends an On / Off control message to all devices in its routing table. Devices including root itself receive this message and do the On / Off.

View File

@@ -0,0 +1,74 @@
menu "Example Configuration"
config MESH_CHANNEL
int "channel"
range 1 14
default 1
help
mesh network channel.
config MESH_ROUTER_SSID
string "Router SSID"
default "ROUTER_SSID"
help
Router SSID.
config MESH_ROUTER_PASSWD
string "Router password"
default "ROUTER_PASSWD"
help
Router password.
choice
bool "Mesh AP Authentication Mode"
default MAP_AUTH_MODE_OPEN
help
Authentication mode.
config WIFI_AUTH_OPEN
bool "WIFI_AUTH_OPEN"
config WIFI_AUTH_WPA_PSK
bool "WIFI_AUTH_WPA_PSK"
config WIFI_AUTH_WPA2_PSK
bool "WIFI_AUTH_WPA2_PSK"
config WIFI_AUTH_WPA_WPA2_PSK
bool "WIFI_AUTH_WPA_WPA2_PSK"
endchoice
config MESH_AP_AUTHMODE
int
default 0 if WIFI_AUTH_OPEN
default 2 if WIFI_AUTH_WPA_PSK
default 3 if WIFI_AUTH_WPA2_PSK
default 4 if WIFI_AUTH_WPA_WPA2_PSK
help
Mesh AP authentication mode.
config MESH_AP_PASSWD
string "Mesh AP Password"
default "MAP_PASSWD"
help
Mesh AP password.
config MESH_AP_CONNECTIONS
int "Mesh AP Connections"
range 1 10
default 6
help
The number of stations allowed to connect in.
config MESH_MAX_LAYER
int "Mesh Max Layer"
range 1 15
default 6
help
Max layer allowed in mesh network.
config MESH_ROUTE_TABLE_SIZE
int "Mesh Routing Table Size"
range 1 300
default 50
help
The number of devices over the network(max: 300).
endmenu

View File

@@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@@ -0,0 +1,57 @@
/* Mesh Internal Transceiver Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#ifndef __MESH_LIGHT_H__
#define __MESH_LIGHT_H__
#include "esp_err.h"
/*******************************************************
* Constants
*******************************************************/
#define MESH_LIGHT_RED (0xff)
#define MESH_LIGHT_GREEN (0xfe)
#define MESH_LIGHT_BLUE (0xfd)
#define MESH_LIGHT_YELLOW (0xfc)
#define MESH_LIGHT_PINK (0xfb)
#define MESH_LIGHT_INIT (0xfa)
#define MESH_LIGHT_WARNING (0xf9)
#define MESH_TOKEN_ID (0x0)
#define MESH_TOKEN_VALUE (0xbeef)
#define MESH_CONTROL_CMD (0x2)
/*******************************************************
* Type Definitions
*******************************************************/
/*******************************************************
* Structures
*******************************************************/
typedef struct {
uint8_t cmd;
bool on;
uint8_t token_id;
uint16_t token_value;
} mesh_light_ctl_t;
/*******************************************************
* Variables Declarations
*******************************************************/
/*******************************************************
* Function Definitions
*******************************************************/
esp_err_t mesh_light_init(void);
esp_err_t mesh_light_set(int color);
esp_err_t mesh_light_process(mesh_addr_t *from, uint8_t *buf, uint16_t len);
void mesh_connected_indicator(int layer);
void mesh_disconnected_indicator(void);
#endif /* __MESH_LIGHT_H__ */

View File

@@ -0,0 +1,174 @@
/* Mesh Internal Transceiver Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "esp_err.h"
#include "esp_mesh.h"
#include "mesh_light.h"
#include "driver/gpio.h"
#include "driver/ledc.h"
/*******************************************************
* Constants
*******************************************************/
/* RGB configuration on ESP-WROVER-KIT board */
#define LEDC_IO_0 (0)
#define LEDC_IO_1 (2)
#define LEDC_IO_2 (4)
#define LEDC_IO_3 (5)
/*******************************************************
* Variable Definitions
*******************************************************/
static bool bool_light_inited = false;
/*******************************************************
* Function Definitions
*******************************************************/
esp_err_t mesh_light_init(void)
{
if (bool_light_inited == true) {
return ESP_OK;
}
bool_light_inited = true;
ledc_timer_config_t ledc_timer = {
.bit_num = LEDC_TIMER_13_BIT, .freq_hz = 5000, .speed_mode =
LEDC_HIGH_SPEED_MODE, .timer_num = LEDC_TIMER_0
};
ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = { .channel = LEDC_CHANNEL_0, .duty =
100, .gpio_num = LEDC_IO_0, .intr_type = LEDC_INTR_FADE_END,
.speed_mode = LEDC_HIGH_SPEED_MODE, .timer_sel = LEDC_TIMER_0
};
ledc_channel_config(&ledc_channel);
ledc_channel.channel = LEDC_CHANNEL_1;
ledc_channel.gpio_num = LEDC_IO_1;
ledc_channel_config(&ledc_channel);
ledc_channel.channel = LEDC_CHANNEL_2;
ledc_channel.gpio_num = LEDC_IO_2;
ledc_channel_config(&ledc_channel);
ledc_channel.channel = LEDC_CHANNEL_3;
ledc_channel.gpio_num = LEDC_IO_3;
ledc_channel_config(&ledc_channel);
ledc_fade_func_install(0);
mesh_light_set(MESH_LIGHT_INIT);
return ESP_OK;
}
esp_err_t mesh_light_set(int color)
{
switch (color) {
case MESH_LIGHT_RED:
/* Red */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 0);
break;
case MESH_LIGHT_GREEN:
/* Green */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 0);
break;
case MESH_LIGHT_BLUE:
/* Blue */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 3000);
break;
case MESH_LIGHT_YELLOW:
/* Yellow */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 0);
break;
case MESH_LIGHT_PINK:
/* Pink */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 3000);
break;
case MESH_LIGHT_INIT:
/* can't say */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 3000);
break;
case MESH_LIGHT_WARNING:
/* warning */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 3000);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 3000);
break;
default:
/* off */
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1, 0);
ledc_set_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, 0);
}
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_1);
ledc_update_duty(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2);
return ESP_OK;
}
void mesh_connected_indicator(int layer)
{
switch (layer) {
case 1:
mesh_light_set(MESH_LIGHT_PINK);
break;
case 2:
mesh_light_set(MESH_LIGHT_YELLOW);
break;
case 3:
mesh_light_set(MESH_LIGHT_RED);
break;
case 4:
mesh_light_set(MESH_LIGHT_BLUE);
break;
case 5:
mesh_light_set(MESH_LIGHT_GREEN);
break;
case 6:
mesh_light_set(MESH_LIGHT_WARNING);
break;
default:
mesh_light_set(0);
}
}
void mesh_disconnected_indicator(void)
{
mesh_light_set(MESH_LIGHT_WARNING);
}
esp_err_t mesh_light_process(mesh_addr_t *from, uint8_t *buf, uint16_t len)
{
mesh_light_ctl_t *in = (mesh_light_ctl_t *) buf;
if (!from || !buf || len < sizeof(mesh_light_ctl_t)) {
return ESP_FAIL;
}
if (in->token_id != MESH_TOKEN_ID || in->token_value != MESH_TOKEN_VALUE) {
return ESP_FAIL;
}
if (in->cmd == MESH_CONTROL_CMD) {
if (in->on) {
mesh_connected_indicator(esp_mesh_get_layer());
} else {
mesh_light_set(0);
}
}
return ESP_OK;
}

View File

@@ -0,0 +1,400 @@
/* Mesh Internal Transceiver Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <string.h>
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event_loop.h"
#include "esp_log.h"
#include "esp_mesh.h"
#include "esp_mesh_internal.h"
#include "mesh_light.h"
#include "nvs_flash.h"
/*******************************************************
* Macros
*******************************************************/
//#define MESH_P2P_TOS_OFF
//#define MESH_ROOT_TO_GROUP
/*******************************************************
* Constants
*******************************************************/
#define RX_SIZE (1500)
#define TX_SIZE (1460)
/*******************************************************
* Variable Definitions
*******************************************************/
static const char *MESH_TAG = "mesh_main";
static const uint8_t MESH_ID[6] = { 0x77, 0x77, 0x77, 0x77, 0x77, 0x77 };
static uint8_t tx_buf[TX_SIZE] = { 0, };
static uint8_t rx_buf[RX_SIZE] = { 0, };
static bool is_running = true;
static bool is_mesh_connected = false;
static mesh_addr_t mesh_parent_addr;
static int mesh_layer = -1;
mesh_light_ctl_t light_on = {
.cmd = MESH_CONTROL_CMD,
.on = 1,
.token_id = MESH_TOKEN_ID,
.token_value = MESH_TOKEN_VALUE,
};
mesh_light_ctl_t light_off = {
.cmd = MESH_CONTROL_CMD,
.on = 0,
.token_id = MESH_TOKEN_ID,
.token_value = MESH_TOKEN_VALUE,
};
/*******************************************************
* Function Declarations
*******************************************************/
/*******************************************************
* Function Definitions
*******************************************************/
void mesh_send_to_group(const mesh_data_t *data, const mesh_addr_t *group, int seqno)
{
esp_err_t err = esp_mesh_send(group, data,
MESH_DATA_P2P | MESH_DATA_GROUP,
NULL, 0);
if (err) {
ESP_LOGE(MESH_TAG,
"[GROUP:%d][L:%d][rtableSize:%d]parent:"MACSTR" to "MACSTR", heap:%d[err:0x%x, proto:%d, tos:%d]",
seqno, mesh_layer, esp_mesh_get_routing_table_size(),
MAC2STR(mesh_parent_addr.addr), MAC2STR(group->addr),
esp_get_free_heap_size(), err, data->proto, data->tos)
} else {
ESP_LOGW(MESH_TAG,
"[GROUP:%d][L:%d][rtableSize:%d]parent:"MACSTR" to "MACSTR", heap:%d[err:0x%x, proto:%d, tos:%d]",
seqno, mesh_layer, esp_mesh_get_routing_table_size(),
MAC2STR(mesh_parent_addr.addr), MAC2STR(group->addr),
esp_get_free_heap_size(), err, data->proto, data->tos)
}
}
void esp_mesh_p2p_tx_main(void *arg)
{
int i;
esp_err_t err;
int send_count = 0;
mesh_addr_t route_table[CONFIG_MESH_ROUTE_TABLE_SIZE];
int route_table_size = 0;
mesh_data_t data;
data.data = tx_buf;
data.size = sizeof(tx_buf);
data.proto = MESH_PROTO_BIN;
#ifdef MESH_P2P_TOS_OFF
data.tos = MESH_TOS_DEF;
#endif /* MESH_P2P_TOS_OFF */
is_running = true;
while (is_running) {
/* normal nodes rather than root do nothing but print */
if (!esp_mesh_is_root()) {
ESP_LOGI(MESH_TAG, "[layer:%d]%s%s[rtableSize:%d]", mesh_layer,
is_mesh_connected ? "CONNECT" : "DISCONNECT",
esp_mesh_is_root() ? "<ROOT>" : "[NODE]",
esp_mesh_get_routing_table_size())
vTaskDelay(10 * 1000 / portTICK_RATE_MS);
continue;
}
esp_mesh_get_routing_table((mesh_addr_t *) &route_table,
CONFIG_MESH_ROUTE_TABLE_SIZE * 6, &route_table_size);
if (send_count && !(send_count % 100)) {
ESP_LOGI(MESH_TAG, "size:%d/%d,send_count:%d", route_table_size,
esp_mesh_get_routing_table_size(), send_count)
}
send_count++;
tx_buf[25] = (send_count >> 24) & 0xff;
tx_buf[24] = (send_count >> 16) & 0xff;
tx_buf[23] = (send_count >> 8) & 0xff;
tx_buf[22] = (send_count >> 0) & 0xff;
if (send_count % 2) {
memcpy(tx_buf, (uint8_t *)&light_on, sizeof(light_on));
} else {
memcpy(tx_buf, (uint8_t *)&light_off, sizeof(light_off));
}
#ifdef MESH_ROOT_TO_GROUP
mesh_send_to_group(&data, (mesh_addr_t *)MESH_GROUP_ID, send_count);
vTaskDelay(1 * 1000 / portTICK_RATE_MS);
continue;
#endif
for (i = 0; i < route_table_size; i++) {
err = esp_mesh_send(&route_table[i], &data, MESH_DATA_P2P, NULL, 0);
if (err) {
ESP_LOGE(MESH_TAG,
"[ROOT-2-UNICAST:%d][L:%d]parent:"MACSTR" to "MACSTR", heap:%d[err:0x%x, proto:%d, tos:%d]",
send_count, mesh_layer, MAC2STR(mesh_parent_addr.addr),
MAC2STR(route_table[i].addr), esp_get_free_heap_size(),
err, data.proto, data.tos)
} else if (!(send_count % 100)) {
ESP_LOGW(MESH_TAG,
"[ROOT-2-UNICAST:%d][L:%d][rtableSize:%d]parent:"MACSTR" to "MACSTR", heap:%d[err:0x%x, proto:%d, tos:%d]",
send_count, mesh_layer,
esp_mesh_get_routing_table_size(),
MAC2STR(mesh_parent_addr.addr),
MAC2STR(route_table[i].addr), esp_get_free_heap_size(),
err, data.proto, data.tos)
}
}
vTaskDelay(1 * 1000 / portTICK_RATE_MS);
}
vTaskDelete(NULL);
}
void esp_mesh_p2p_rx_main(void *arg)
{
int recv_count = 0;
esp_err_t err;
mesh_addr_t from;
int send_count = 0;
mesh_data_t data;
int flag = 0;
data.data = rx_buf;
data.size = RX_SIZE;
is_running = true;
while (is_running) {
data.size = RX_SIZE;
err = esp_mesh_recv(&from, &data, portMAX_DELAY, &flag, NULL, 0);
if (err != ESP_OK || !data.size) {
ESP_LOGE(MESH_TAG, "err:0x%x, size:%d", err, data.size)
continue;
}
/* extract send count */
if (data.size >= sizeof(send_count)) {
send_count = (data.data[25] << 24) | (data.data[24] << 16)
| (data.data[23] << 8) | data.data[22];
}
recv_count++;
/* process light control */
mesh_light_process(&from, data.data, data.size);
if (!(recv_count % 1)) {
ESP_LOGW(MESH_TAG,
"[#RX:%d/%d][L:%d] parent:"MACSTR", receive from "MACSTR", size:%d, heap:%d, flag:%d[err:0x%x, proto:%d, tos:%d]",
recv_count, send_count, mesh_layer,
MAC2STR(mesh_parent_addr.addr), MAC2STR(from.addr),
data.size, esp_get_free_heap_size(), flag, err, data.proto,
data.tos)
}
}
vTaskDelete(NULL);
}
esp_err_t esp_mesh_comm_p2p_start(void)
{
static bool is_comm_p2p_started = false;
if (!is_comm_p2p_started) {
is_comm_p2p_started = true;
xTaskCreate(esp_mesh_p2p_tx_main, "MPTX", 3072, NULL, 5, NULL);
xTaskCreate(esp_mesh_p2p_rx_main, "MPRX", 3072, NULL, 5, NULL);
}
return ESP_OK;
}
void esp_mesh_event_handler(mesh_event_t event)
{
#ifdef MESH_ROOT_TO_GROUP
mesh_addr_t group;
#endif
static uint8_t last_layer = 0;
static int disconnect_count = 0;
ESP_LOGD(MESH_TAG, "esp_event_handler:%d", event.id)
switch (event.id) {
case MESH_EVENT_STARTED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_STARTED>")
break;
case MESH_EVENT_STOPPED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_STOPPED>")
break;
case MESH_EVENT_CHILD_CONNECTED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_CHILD_CONNECTED>aid:%d, "MACSTR"",
event.info.child_connected.aid,
MAC2STR(event.info.child_connected.mac))
break;
case MESH_EVENT_CHILD_DISCONNECTED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_CHILD_DISCONNECTED>aid:%d, "MACSTR"",
event.info.child_disconnected.aid,
MAC2STR(event.info.child_disconnected.mac))
break;
case MESH_EVENT_ROUTING_TABLE_ADD:
ESP_LOGW(MESH_TAG, "<MESH_EVENT_ROUTING_TABLE_ADD>add %d, new:%d",
event.info.routing_table.rt_size_change,
event.info.routing_table.rt_size_new)
break;
case MESH_EVENT_ROUTING_TABLE_REMOVE:
ESP_LOGW(MESH_TAG, "<MESH_EVENT_ROUTING_TABLE_REMOVE>remove %d, new:%d",
event.info.routing_table.rt_size_change,
event.info.routing_table.rt_size_new)
break;
case MESH_EVENT_NO_PARNET_FOUND:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_NO_PARNET_FOUND>scan times:%d",
event.info.no_parent.scan_times)
/* TODO handler for the failure */
break;
case MESH_EVENT_PARENT_CONNECTED:
mesh_layer = event.info.connected.self_layer;
memcpy(&mesh_parent_addr.addr, event.info.connected.connected.bssid, 6);
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_PARENT_CONNECTED>layer:%d-->%d, parent:"MACSTR"%s, discnx:%d",
last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr),
esp_mesh_is_root() ? "<ROOT>" :
(mesh_layer == 2) ? "<layer2>" : "", disconnect_count)
disconnect_count = 0;
last_layer = mesh_layer;
mesh_connected_indicator(mesh_layer);
is_mesh_connected = true;
if (esp_mesh_is_root()) {
tcpip_adapter_dhcpc_start(TCPIP_ADAPTER_IF_STA);
}
#ifdef MESH_ROOT_TO_GROUP
if (mesh_layer == 3) {
ESP_ERROR_CHECK(
esp_mesh_set_group_id((mesh_addr_t * ) MESH_GROUP_ID, 1))
ESP_ERROR_CHECK(esp_mesh_get_group_list(&group, 1))
ESP_LOGI(MESH_TAG, "num:%d, group "MACSTR"\n",
esp_mesh_get_group_num(), MAC2STR(group.addr))
}
#endif
esp_mesh_comm_p2p_start();
break;
case MESH_EVENT_PARENT_DISCONNECTED:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_PARENT_DISCONNECTED>reason:%d, count:%d",
event.info.disconnected.reason, disconnect_count)
if (event.info.disconnected.reason == 201) {
disconnect_count++;
}
is_mesh_connected = false;
mesh_disconnected_indicator();
break;
case MESH_EVENT_LAYER_CHANGE:
mesh_layer = event.info.layer_change.new_layer;
ESP_LOGI(MESH_TAG, "<MESH_EVENT_LAYER_CHANGE>layer:%d-->%d%s",
last_layer, mesh_layer,
esp_mesh_is_root() ? "<ROOT>" :
(mesh_layer == 2) ? "<layer2>" : "")
last_layer = mesh_layer;
mesh_connected_indicator(mesh_layer);
break;
case MESH_EVENT_ROOT_ADDRESS:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_ADDRESS>rc_addr:"MACSTR"",
MAC2STR(event.info.root_addr.addr))
break;
case MESH_EVENT_ROOT_GOT_IP:
/* root starts to connect to server */
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_ROOT_GOT_IP>sta ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
IP2STR(&event.info.got_ip.ip_info.ip),
IP2STR(&event.info.got_ip.ip_info.netmask),
IP2STR(&event.info.got_ip.ip_info.gw))
break;
case MESH_EVENT_ROOT_LOST_IP:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_LOST_IP>")
break;
case MESH_EVENT_VOTE_STARTED:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_VOTE_STARTED>attempts:%d, reason:%d, rc_addr:"MACSTR"",
event.info.vote_started.attempts,
event.info.vote_started.reason,
MAC2STR(event.info.vote_started.rc_addr.addr))
break;
case MESH_EVENT_VOTE_STOPPED:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_VOTE_DONE>")
break;
case MESH_EVENT_ROOT_SWITCH_REQ:
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_ROOT_SWITCH_REQ>reason:%d, rc_addr:"MACSTR"",
event.info.switch_req.reason,
MAC2STR( event.info.switch_req.rc_addr.addr))
break;
case MESH_EVENT_ROOT_SWITCH_ACK:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_ROOT_SWITCH_ACK>")
break;
case MESH_EVENT_TODS_STATE:
ESP_LOGI(MESH_TAG, "<MESH_EVENT_TODS_REACHABLE>state:%d",
event.info.toDS_state)
;
break;
default:
ESP_LOGI(MESH_TAG, "unknown")
break;
}
}
void app_main(void)
{
ESP_ERROR_CHECK(mesh_light_init());
ESP_ERROR_CHECK(nvs_flash_init());
/* tcpip initialization */
tcpip_adapter_init();
/* for mesh
* stop DHCP server on softAP interface by default
* stop DHCP client on station interface by default
* */
ESP_ERROR_CHECK(tcpip_adapter_dhcps_stop(TCPIP_ADAPTER_IF_AP));
ESP_ERROR_CHECK(tcpip_adapter_dhcpc_stop(TCPIP_ADAPTER_IF_STA));
#if 0
/* static ip settings */
tcpip_adapter_ip_info_t sta_ip;
sta_ip.ip.addr = ipaddr_addr("192.168.1.102");
sta_ip.gw.addr = ipaddr_addr("192.168.1.1");
sta_ip.netmask.addr = ipaddr_addr("255.255.255.0");
tcpip_adapter_set_ip_info(WIFI_IF_STA, &sta_ip);
#endif
/* wifi initialization */
ESP_ERROR_CHECK(esp_event_loop_init(NULL, NULL));
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&config));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH));
ESP_ERROR_CHECK(esp_wifi_start());
/* mesh initialization */
ESP_ERROR_CHECK(esp_mesh_init());
ESP_ERROR_CHECK(esp_mesh_set_max_layer(CONFIG_MESH_MAX_LAYER));
ESP_ERROR_CHECK(esp_mesh_set_ap_authmode(CONFIG_MESH_AP_AUTHMODE));
ESP_ERROR_CHECK(esp_mesh_set_vote_percentage(1));
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10));
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
/* mesh ID */
memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6);
/* mesh event callback */
cfg.event_cb = &esp_mesh_event_handler;
/* router */
cfg.channel = CONFIG_MESH_CHANNEL;
cfg.router.ssid_len = strlen(CONFIG_MESH_ROUTER_SSID);
memcpy((uint8_t *) &cfg.router.ssid, CONFIG_MESH_ROUTER_SSID, cfg.router.ssid_len);
memcpy((uint8_t *) &cfg.router.password, CONFIG_MESH_ROUTER_PASSWD,
strlen(CONFIG_MESH_ROUTER_PASSWD));
/* mesh softAP */
cfg.mesh_ap.max_connection = CONFIG_MESH_AP_CONNECTIONS;
memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
strlen(CONFIG_MESH_AP_PASSWD));
ESP_ERROR_CHECK(esp_mesh_set_config(&cfg));
/* mesh start */
ESP_ERROR_CHECK(esp_mesh_start());
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d\n", esp_get_free_heap_size())
}