Merge branch 'mesh/power_save_function' into 'master'

mesh/ps: add duty control and support only transmit/receive on active duty

See merge request espressif/esp-idf!8152
This commit is contained in:
Jiang Jiang Jian 2020-05-06 15:53:49 +08:00
commit 09d4767947
10 changed files with 267 additions and 59 deletions

View file

@ -470,8 +470,8 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# ifdef ESP_ERR_MESH_QUEUE_READ
ERR_TBL_IT(ESP_ERR_MESH_QUEUE_READ), /* 16408 0x4018 */
# endif
# ifdef ESP_ERR_MESH_INACTIVE
ERR_TBL_IT(ESP_ERR_MESH_INACTIVE), /* 16409 0x4019 */
# ifdef ESP_ERR_MESH_PS
ERR_TBL_IT(ESP_ERR_MESH_PS), /* 16409 0x4019 */
# endif
// components/esp_netif/include/esp_netif_types.h
# ifdef ESP_ERR_ESP_NETIF_BASE

View file

@ -127,7 +127,7 @@ extern "C" {
#define ESP_ERR_MESH_VOTING (ESP_ERR_MESH_BASE + 22) /**< vote in progress */
#define ESP_ERR_MESH_XMIT (ESP_ERR_MESH_BASE + 23) /**< XMIT */
#define ESP_ERR_MESH_QUEUE_READ (ESP_ERR_MESH_BASE + 24) /**< error in reading queue */
#define ESP_ERR_MESH_INACTIVE (ESP_ERR_MESH_BASE + 25) /**< mesh network is not active */
#define ESP_ERR_MESH_PS (ESP_ERR_MESH_BASE + 25) /**< mesh PS is not specified as enable or disable */
/**
* @brief Flags bitmap for esp_mesh_send() and esp_mesh_recv()
@ -158,7 +158,16 @@ extern "C" {
/**
* @brief Mesh PS (Power Save) duty cycle type
*/
#define MESH_PS_DEVICE_DUTY_REQUEST (0x01) /**< requests to join a network PS without specifying a duty cycle */
#define MESH_PS_DEVICE_DUTY_REQUEST (0x01) /**< requests to join a network PS without specifying a device duty cycle. After the
device joins the network, a network duty cycle will be provided by the network */
#define MESH_PS_DEVICE_DUTY_DEMAND (0x04) /**< requests to join a network PS and specifies a demanded device duty cycle */
#define MESH_PS_NETWORK_DUTY_MASTER (0x80) /**< indicates the device is the NWK-DUTY-MASTER (network duty cycle master) */
/**
* @brief Mesh PS (Power Save) duty cycle applied rule
*/
#define MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE (0) /** the specified network duty is applied to the entire network <*/
#define MESH_PS_NETWORK_DUTY_APPLIED_UPLINK (1) /** the specified network duty is applied to only the up-link path <*/
/*******************************************************
* Enumerations
@ -200,6 +209,8 @@ typedef enum {
after finding it. */
MESH_EVENT_ROUTER_SWITCH, /**< if users specify BSSID of the router in mesh configuration, when the root connects to another
router with the same SSID, this event will be posted and the new router information is attached. */
MESH_EVENT_PS_PARENT_DUTY, /**< parent duty */
MESH_EVENT_PS_CHILD_DUTY, /**< child duty */
MESH_EVENT_MAX,
} mesh_event_id_t;
@ -302,7 +313,8 @@ typedef struct {
*/
typedef struct {
wifi_event_sta_connected_t connected; /**< parent information, same as Wi-Fi event SYSTEM_EVENT_STA_CONNECTED does */
uint8_t self_layer; /**< layer */
uint16_t self_layer; /**< layer */
uint8_t duty; /**< parent duty */
} mesh_event_connected_t;
/**
@ -316,7 +328,7 @@ typedef struct {
* @brief Layer change information
*/
typedef struct {
uint8_t new_layer; /**< new layer */
uint16_t new_layer; /**< new layer */
} mesh_event_layer_change_t;
/**
@ -415,6 +427,14 @@ typedef struct {
*/
typedef wifi_event_sta_connected_t mesh_event_router_switch_t;
/**
* @brief PS duty information
*/
typedef struct {
uint8_t duty; /**< parent or child duty */
mesh_event_child_connected_t child_connected; /**< child info */
} mesh_event_ps_duty_t;
/**
* @brief Mesh event information
*/
@ -440,6 +460,7 @@ typedef union {
mesh_event_network_state_t network_state; /**< network state, such as whether current mesh network has a root. */
mesh_event_find_network_t find_network; /**< network found that can join */
mesh_event_router_switch_t router_switch; /**< new router information */
mesh_event_ps_duty_t ps_duty; /**< PS duty information */
} mesh_event_info_t;
/**
@ -601,7 +622,7 @@ esp_err_t esp_mesh_start(void);
* - Delete TX and RX queues.
* - Release resources.
* - Restore Wi-Fi softAP to default settings if Wi-Fi dual mode is enabled.
* - Set Wi-Fi power save type to WIFI_PS_NONE.
* - Set Wi-Fi Power Save type to WIFI_PS_NONE.
*
* @return
* - ESP_OK
@ -849,7 +870,9 @@ esp_err_t esp_mesh_set_type(mesh_type_t type);
mesh_type_t esp_mesh_get_type(void);
/**
* @brief Set network max layer value (max:25, default:25)
* @brief Set network max layer value
* - for tree topology, the max is 25.
* - for chain topology, the max is 1000.
* - Network max layer limits the max hop count.
*
* @attention This API shall be called before mesh is started.
@ -1477,7 +1500,7 @@ int64_t esp_mesh_get_tsf_time(void);
* @brief Set mesh topology. The default value is MESH_TOPO_TREE
* - MESH_TOPO_CHAIN supports up to 1000 layers
*
* @attention This API shall be called before mesh is started
* @attention This API shall be called before mesh is started.
*
* @param[in] topo MESH_TOPO_TREE or MESH_TOPO_CHAIN
*
@ -1496,23 +1519,57 @@ esp_err_t esp_mesh_set_topology(esp_mesh_topology_t topo);
esp_mesh_topology_t esp_mesh_get_topology(void);
/**
* @brief Check whether the mesh network is in active state
* - If the mesh network is not in active state, mesh devices will neither transmit nor receive frames.
* - If power save mode of the mesh network is enabled, devices should check whether the network is active before
* sending any packets. (i.e. before calling esp_mesh_send()).
* - Power save mode is enabled by setting the PS type to WIFI_PS_MIN_MODEM for all devices before mesh is started.
* @brief Enable mesh Power Save function
*
* @attention This API shall be called before mesh is started.
*
* @return
* - ESP_OK
* - ESP_ERR_WIFI_NOT_INIT
* - ESP_ERR_MESH_NOT_ALLOWED
*/
esp_err_t esp_mesh_enable_ps(void);
/**
* @brief Disable mesh Power Save function
*
* @attention This API shall be called before mesh is started.
*
* @return
* - ESP_OK
* - ESP_ERR_WIFI_NOT_INIT
* - ESP_ERR_MESH_NOT_ALLOWED
*/
esp_err_t esp_mesh_disable_ps(void);
/**
* @brief Check whether the mesh Power Save function is enabled
*
* @return true/false
*/
bool esp_mesh_is_network_active(void);
bool esp_mesh_is_ps_enabled(void);
/**
* @brief Set device duty cycle and type
* @brief Check whether the device is in active state
* - If the device is not in active state, it will neither transmit nor receive frames.
*
* @attention This API can be called at any time after mesh is initialized.
* @return true/false
*/
bool esp_mesh_is_device_active(void);
/**
* @brief Set the device duty cycle and type
* - The range of dev_duty values is 1 to 100. The default value is 12.
* - dev_duty = 100, the PS will be stopped.
* - dev_duty is better to not less than 5.
* - dev_duty_type could be MESH_PS_DEVICE_DUTY_REQUEST or MESH_PS_DEVICE_DUTY_DEMAND.
* - If dev_duty_type is set to MESH_PS_DEVICE_DUTY_REQUEST, the device will use a nwk_duty provided by the network.
* - If dev_duty_type is set to MESH_PS_DEVICE_DUTY_DEMAND, the device will use the specified dev_duty.
*
* @attention This API can be called at any time after mesh is started.
*
* @param[in] dev_duty device duty cycle
* @param[in] dev_duty_type device PS duty cycle type
* @param[in] dev_duty_type device PS duty cycle type, not accept MESH_PS_NETWORK_DUTY_MASTER
*
* @return
* - ESP_OK
@ -1531,8 +1588,63 @@ esp_err_t esp_mesh_set_active_duty_cycle(int dev_duty, int dev_duty_type);
*/
esp_err_t esp_mesh_get_active_duty_cycle(int* dev_duty, int* dev_duty_type);
/**
* @brief Set the network duty cycle, duration and rule
* - The range of nwk_duty values is 1 to 100. The default value is 12.
* - nwk_duty is the network duty cycle the entire network or the up-link path will use. A device that successfully
* sets the nwk_duty is known as a NWK-DUTY-MASTER.
* - duration_mins specifies how long the specified nwk_duty will be used. Once duration_mins expires, the root will take
* over as the NWK-DUTY-MASTER. If an existing NWK-DUTY-MASTER leaves the network, the root will take over as the
* NWK-DUTY-MASTER again.
* - duration_mins = (-1) represents nwk_duty will be used until a new NWK-DUTY-MASTER with a different nwk_duty appears.
* - Only the root can set duration_mins to (-1).
* - applied_rule could be MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE or MESH_PS_NETWORK_DUTY_APPLIED_UPLINK.
* - If applied_rule is set to MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE, the nwk_duty will be used by the entire network.
* - If applied_rule is set to MESH_PS_NETWORK_DUTY_APPLIED_UPLINK, the nwk_duty will only be used by the up-link path nodes.
* - The root does not accept MESH_PS_NETWORK_DUTY_APPLIED_UPLINK.
* - A nwk_duty with duration_mins(-1) set by the root is the default network duty cycle used by the entire network.
*
* @attention This API can be called at any time after mesh is started.
* - In self-organized network, if this API is called before mesh is started in all devices, (1)nwk_duty shall be set to the
* same value for all devices; (2)duration_mins shall be set to (-1); (3)applied_rule shall be set to
* MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE; after the voted root appears, the root will become the NWK-DUTY-MASTER and broadcast
* the nwk_duty and its identity of NWK-DUTY-MASTER.
* - If the root is specified (FIXED-ROOT), call this API in the root to provide a default nwk_duty for the entire network.
* - After joins the network, any device can call this API to change the nwk_duty, duration_mins or applied_rule.
*
* @param[in] nwk_duty network duty cycle
* @param[in] duration_mins duration (unit: minutes)
* @param[in] applied_rule MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE or MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
*
* @return
* - ESP_OK
* - ESP_FAIL
*/
esp_err_t esp_mesh_set_network_duty_cycle(int nwk_duty, int duration_mins, int applied_rule);
/**
* @brief Get the network duty cycle, duration, type and rule
*
* @param[out] nwk_duty current network duty cycle
* @param[out] duration_mins the duration of current nwk_duty
* @param[out] dev_duty_type if it includes MESH_PS_DEVICE_DUTY_MASTER, this device is the current NWK-DUTY-MASTER.
* @param[out] applied_rule MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE or MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_get_network_duty_cycle(int* nwk_duty, int* duration_mins, int* dev_duty_type, int* applied_rule);
/**
* @brief Get the running active duty cycle
* - The running active duty cycle of the root is 100.
* - If duty type is set to MESH_PS_DEVICE_DUTY_REQUEST, the running active duty cycle is nwk_duty provided by the network.
* - If duty type is set to MESH_PS_DEVICE_DUTY_DEMAND, the running active duty cycle is dev_duty specified by the users.
* - In a mesh network, devices are typically working with a certain duty-cycle (transmitting, receiving and sleep) to
* reduce the power consumption. The running active duty cycle decides the amount of awake time within a beacon interval.
* At each start of beacon interval, all devices wake up, broadcast beacons, and transmit packets if they do have pending
* packets for their parents or for their children. Note that Low-duty-cycle means devices may not be active in most of
* the time, the latency of data transmission might be greater.
*
* @return the running active duty cycle
*/

View file

@ -16,6 +16,7 @@
#define __ESP_MESH_INTERNAL_H__
#include "esp_err.h"
#include "esp_mesh.h"
#include "esp_wifi.h"
#include "esp_wifi_types.h"
#include "esp_private/wifi.h"
@ -96,6 +97,19 @@ typedef struct {
uint8_t toDS; /**< toDS state */
} __attribute__((packed)) mesh_assoc_t;
/**
* @brief Mesh PS duties
*/
typedef struct {
uint8_t device;
uint8_t parent;
struct {
bool used;
uint8_t duty;
uint8_t mac[6];
} child[ESP_WIFI_MAX_CONN_NUM];
} esp_mesh_ps_duties_t;
/*******************************************************
* Function Definitions
*******************************************************/
@ -263,6 +277,14 @@ esp_err_t esp_mesh_set_announce_interval(int short_ms, int long_ms);
*/
esp_err_t esp_mesh_get_announce_interval(int *short_ms, int *long_ms);
/**
* @brief Get the running duties of device, parent and children
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_ps_get_duties(esp_mesh_ps_duties_t* ps_duties);
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit 9f06eb78123f4684a622762e2d5f01112f1aa823
Subproject commit c9405220be44b7d6ef0caa957d7f051757c2a4f9

View file

@ -95,7 +95,6 @@ initial condition:
- - MSSC SSC[1-<node_num>] mesh -Q -o 3
- - P SSC[1-<node_num>] RE "MID,%%s"%%(<mesh_id>)
- P SSC[1-<node_num>] RE "MROUTER,%%s"%%(<router_ssid>)
- P SSC[1-<node_num>] RE "SWITCH_PARENT,%%s"%%(<duration_ms>)
- P SSC[1-<node_num>] C NO_SPECIFIC_SETTINGS
restore cmd set:
- ''

View file

@ -402,22 +402,23 @@ test cases:
cmd set:
- ''
- - SSC MNODE(0) meshsend -S -d <MNODE(0,0)_mac> -l 1460 -c 20 -b 20 -f 2 -t 0
- - P MNODE(0) C +MESHTXPKT,OK
- - P MNODE(0) C +MESHTXPKT,OK C +MESHSEND,OK
- P MNODE(0,0) C +MESHRXPKT,OK
- - SSC MNODE(0) meshsend -S -d <MNODE(0,0)_mac> -l 1460 -c 20 -b 20 -f 2 -t 1
- - P MNODE(0) C +MESHTXPKT,OK
- - P MNODE(0) C +MESHTXPKT,FAIL C +MESHSEND,OK
- - SSC MNODE(0) meshsend -S -d <MNODE(0,0)_mac> -l 1460 -c 20 -b 20 -f 2 -t 2
- - P MNODE(0) C +MESHTXPKT,OK
- - P MNODE(0) C +MESHTXPKT,OK C +MESHSEND,OK
- P MNODE(0,0) C +MESHRXPKT,OK
- - SSC MNODE(0,0) meshsend -S -d <MNODE(0)_mac> -l 1460 -c 20 -b 20 -f 2 -t 2
- - P MNODE(0,0) C +MESHTXPKT,FAIL
- - P MNODE(0,0) C +MESHTXPKT,FAIL C +MESHSEND,OK
- - SSC MNODE(0,0) meshsend -S -d <MNODE(0)_mac> -l 1460 -c 20 -b 20 -f 2 -t 0
- - P MNODE(0,0) C +MESHTXPKT,FAIL
- - P MNODE(0,0) C +MESHTXPKT,OK C +MESHSEND,OK
- P MNODE(0) C +MESHRXPKT,OK
expected result: |-
1. succeed
2. succeed
2. failed
3. succeed
4. succeed
4. failed
5. succeed
steps: |-
1. root send unicast to L2 with tos = P2P

View file

@ -1043,7 +1043,7 @@ test cases:
- - P SSC[1-<node_num>] C +MESHSET:MLAYER,OK
- - MSSC SSC[1-<node_num>] mesh -T
- - P SSC[1-<node_num>] C +MESH:START,OK
- - DELAY 60
- - DELAY <delay_time>
- - ''
- - VALUE <tree_node_num> <node_num>
- - R PC_COM L OK

View file

@ -19,6 +19,78 @@ menu "Example Configuration"
help
Mesh Network Topology.
config MESH_ENABLE_PS
bool "Enable mesh PS (power save) function"
default y
help
Enable/Disable Power Save function.
choice
bool "Mesh PS device duty cycle type"
depends on MESH_ENABLE_PS
default MESH_PS_DEV_DUTY_TYPE_REQUEST
help
Mesh PS device duty cycle type.
config MESH_PS_DEV_DUTY_TYPE_REQUEST
bool "MESH_PS_DEV_DUTY_TYPE_REQUEST"
config MESH_PS_DEV_DUTY_TYPE_DEMAND
bool "MESH_PS_DEV_DUTY_TYPE_DEMAND"
endchoice
config MESH_PS_DEV_DUTY_TYPE
int
depends on MESH_ENABLE_PS
default 1 if MESH_PS_DEV_DUTY_TYPE_REQUEST
default 4 if MESH_PS_DEV_DUTY_TYPE_DEMAND
help
Mesh PS device duty cycle type.
config MESH_PS_DEV_DUTY
int "Mesh PS device duty cycle"
depends on MESH_ENABLE_PS
range 1 100
default 12
help
Mesh PS device duty cycle.
config MESH_PS_NWK_DUTY
int "Mesh PS network duty cycle"
depends on MESH_ENABLE_PS
range 1 100
default 12
help
Mesh PS network duty cycle.
config MESH_PS_NWK_DUTY_DURATION
int "Mesh PS network duty cycle duration (unit: minutes)"
depends on MESH_ENABLE_PS
range -1 100
default -1
help
Mesh PS network duty cycle duration.
choice
bool "Mesh PS network duty cycle rule"
depends on MESH_ENABLE_PS
default MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
help
Mesh PS network duty cycle rule.
config MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
bool "MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE"
config MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
bool "MESH_PS_NETWORK_DUTY_APPLIED_UPLINK"
endchoice
config MESH_PS_NWK_DUTY_RULE
int
depends on MESH_ENABLE_PS
default 0 if MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE
default 1 if MESH_PS_NETWORK_DUTY_APPLIED_UPLINK
help
Mesh PS network duty cycle rule.
config MESH_MAX_LAYER
int "Mesh Max Layer"
range 1 25 if MESH_TOPO_TREE

View file

@ -45,9 +45,6 @@ esp_err_t mesh_light_init(void)
.timer_num = LEDC_TIMER_0,
.clk_cfg = LEDC_AUTO_CLK,
};
#ifdef CONFIG_IDF_TARGET_ESP32
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
#endif
ledc_timer_config(&ledc_timer);
ledc_channel_config_t ledc_channel = {

View file

@ -19,7 +19,6 @@
/*******************************************************
* Macros
*******************************************************/
//#define MESH_ENABLE_POWER_SAVE
/*******************************************************
* Constants
@ -102,18 +101,12 @@ void esp_mesh_p2p_tx_main(void *arg)
}
for (i = 0; i < route_table_size; i++) {
#ifdef MESH_ENABLE_POWER_SAVE
/* PS is enabled, it's better to check if the device is active now. */
while (!esp_mesh_is_network_active()) {
vTaskDelay(10 / portTICK_RATE_MS);
}
#endif
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(),
MAC2STR(route_table[i].addr), esp_get_minimum_free_heap_size(),
err, data.proto, data.tos);
} else if (!(send_count % 100)) {
ESP_LOGW(MESH_TAG,
@ -121,7 +114,7 @@ void esp_mesh_p2p_tx_main(void *arg)
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(),
MAC2STR(route_table[i].addr), esp_get_minimum_free_heap_size(),
err, data.proto, data.tos);
}
}
@ -165,7 +158,7 @@ void esp_mesh_p2p_rx_main(void *arg)
"[#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.size, esp_get_minimum_free_heap_size(), flag, err, data.proto,
data.tos);
}
}
@ -187,7 +180,7 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
mesh_addr_t id = {0,};
static uint8_t last_layer = 0;
static uint16_t last_layer = 0;
switch (event_id) {
case MESH_EVENT_STARTED: {
@ -244,10 +237,10 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
mesh_layer = connected->self_layer;
memcpy(&mesh_parent_addr.addr, connected->connected.bssid, 6);
ESP_LOGI(MESH_TAG,
"<MESH_EVENT_PARENT_CONNECTED>layer:%d-->%d, parent:"MACSTR"%s, ID:"MACSTR"",
"<MESH_EVENT_PARENT_CONNECTED>layer:%d-->%d, parent:"MACSTR"%s, ID:"MACSTR", duty:%d",
last_layer, mesh_layer, MAC2STR(mesh_parent_addr.addr),
esp_mesh_is_root() ? "<ROOT>" :
(mesh_layer == 2) ? "<layer2>" : "", MAC2STR(id.addr));
(mesh_layer == 2) ? "<layer2>" : "", MAC2STR(id.addr), connected->duty);
last_layer = mesh_layer;
mesh_connected_indicator(mesh_layer);
is_mesh_connected = true;
@ -365,6 +358,17 @@ void mesh_event_handler(void *arg, esp_event_base_t event_base,
router_switch->ssid, router_switch->channel, MAC2STR(router_switch->bssid));
}
break;
case MESH_EVENT_PS_PARENT_DUTY: {
mesh_event_ps_duty_t *ps_duty = (mesh_event_ps_duty_t *)event_data;
ESP_LOGI(MESH_TAG, "<MESH_EVENT_PS_PARENT_DUTY>duty:%d", ps_duty->duty);
}
break;
case MESH_EVENT_PS_CHILD_DUTY: {
mesh_event_ps_duty_t *ps_duty = (mesh_event_ps_duty_t *)event_data;
ESP_LOGI(MESH_TAG, "<MESH_EVENT_PS_CHILD_DUTY>cidx:%d, "MACSTR", duty:%d", ps_duty->child_connected.aid-1,
MAC2STR(ps_duty->child_connected.mac), ps_duty->duty);
}
break;
default:
ESP_LOGI(MESH_TAG, "unknown id:%d", event_id);
break;
@ -394,12 +398,6 @@ void app_main(void)
ESP_ERROR_CHECK(esp_wifi_init(&config));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH));
#ifdef MESH_ENABLE_POWER_SAVE
/* enable the mesh PS function by setting WIFI_PS_MIN_MODEM for all mesh devices before mesh is started */
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_MIN_MODEM));
#else
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
#endif
ESP_ERROR_CHECK(esp_wifi_start());
/* mesh initialization */
ESP_ERROR_CHECK(esp_mesh_init());
@ -409,12 +407,17 @@ void app_main(void)
/* set mesh max layer according to the topology */
ESP_ERROR_CHECK(esp_mesh_set_max_layer(CONFIG_MESH_MAX_LAYER));
ESP_ERROR_CHECK(esp_mesh_set_vote_percentage(1));
#ifdef MESH_ENABLE_POWER_SAVE
/* PS is enabled, it's better to increase the associate expired time. */
ESP_ERROR_CHECK(esp_mesh_set_xon_qsize(128));
#ifdef CONFIG_MESH_ENABLE_PS
/* Enable mesh PS function */
ESP_ERROR_CHECK(esp_mesh_enable_ps());
/* better to increase the associate expired time, if a small duty cycle is set. */
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(60));
/* PS is enabled, it's better to increase the announce interval. */
/* better to increase the announce interval to avoid too much management traffic, if a small duty cycle is set. */
ESP_ERROR_CHECK(esp_mesh_set_announce_interval(600, 3300));
#else
/* Disable mesh PS function */
ESP_ERROR_CHECK(esp_mesh_disable_ps());
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10));
#endif
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
@ -432,13 +435,15 @@ void app_main(void)
memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
strlen(CONFIG_MESH_AP_PASSWD));
ESP_ERROR_CHECK(esp_mesh_set_config(&cfg));
#ifdef MESH_ENABLE_POWER_SAVE
/* PS is enabled, set the device active duty cycle. (default:12) */
ESP_ERROR_CHECK(esp_mesh_set_active_duty_cycle(15, MESH_PS_DEVICE_DUTY_REQUEST));
#endif
/* mesh start */
ESP_ERROR_CHECK(esp_mesh_start());
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s<%d>%s\n", esp_get_free_heap_size(),
#ifdef CONFIG_MESH_ENABLE_PS
/* set the device active duty cycle. (default:12, MESH_PS_DEVICE_DUTY_REQUEST) */
ESP_ERROR_CHECK(esp_mesh_set_active_duty_cycle(CONFIG_MESH_PS_DEV_DUTY, CONFIG_MESH_PS_DEV_DUTY_TYPE));
/* set the network active duty cycle. (default:12, -1, MESH_PS_NETWORK_DUTY_APPLIED_ENTIRE) */
ESP_ERROR_CHECK(esp_mesh_set_network_duty_cycle(CONFIG_MESH_PS_NWK_DUTY, CONFIG_MESH_PS_NWK_DUTY_DURATION, CONFIG_MESH_PS_NWK_DUTY_RULE));
#endif
ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s<%d>%s, ps:%d\n", esp_get_minimum_free_heap_size(),
esp_mesh_is_root_fixed() ? "root fixed" : "root not fixed",
esp_mesh_get_topology(), esp_mesh_get_topology() ? "(chain)":"(tree)");
esp_mesh_get_topology(), esp_mesh_get_topology() ? "(chain)":"(tree)", esp_mesh_is_ps_enabled());
}