mesh/ps: add mesh network power save function

This commit is contained in:
qiyuexia 2020-03-28 20:56:02 +08:00
parent c9f29e0b59
commit 6d01dc4cfa
4 changed files with 89 additions and 4 deletions

View file

@ -460,6 +460,15 @@ static const esp_err_msg_t esp_err_msg_table[] = {
# endif
# ifdef ESP_ERR_MESH_VOTING
ERR_TBL_IT(ESP_ERR_MESH_VOTING), /* 16406 0x4016 */
# endif
# ifdef ESP_ERR_MESH_XMIT
ERR_TBL_IT(ESP_ERR_MESH_XMIT), /* 16407 0x4017 */
# endif
# 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 */
# endif
// components/esp_netif/include/esp_netif_types.h
# ifdef ESP_ERR_ESP_NETIF_BASE

View file

@ -125,6 +125,9 @@ extern "C" {
#define ESP_ERR_MESH_DISCARD_DUPLICATE (ESP_ERR_MESH_BASE + 20) /**< discard the packet due to the duplicate sequence number */
#define ESP_ERR_MESH_DISCARD (ESP_ERR_MESH_BASE + 21) /**< discard the packet */
#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 */
/**
* @brief Flags bitmap for esp_mesh_send() and esp_mesh_recv()
@ -151,6 +154,12 @@ extern "C" {
#define MESH_ASSOC_FLAG_ROOTS_FOUND (0x20) /**< root conflict is found */
#define MESH_ASSOC_FLAG_ROOT_FIXED (0x40) /**< fixed root */
/**
* @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 */
/*******************************************************
* Enumerations
*******************************************************/
@ -421,7 +430,6 @@ typedef union {
packets out. If not, devices had better to wait until this state changes to be
MESH_TODS_REACHABLE. */
mesh_event_vote_started_t vote_started; /**< vote started */
//mesh_event_root_got_ip_t got_ip; /**< root obtains IP address */
mesh_event_root_address_t root_addr; /**< root address */
mesh_event_root_switch_req_t switch_req; /**< root switch request */
mesh_event_root_conflict_t root_conflict; /**< other powerful root */
@ -591,6 +599,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.
*
* @return
* - ESP_OK
@ -1008,7 +1017,7 @@ bool esp_mesh_get_self_organized(void);
esp_err_t esp_mesh_waive_root(const mesh_vote_t *vote, int reason);
/**
* @brief Set vote percentage threshold for approval of being a root
* @brief Set vote percentage threshold for approval of being a root (default:0.9)
* - During the networking, only obtaining vote percentage reaches this threshold,
* the device could be a root.
*
@ -1484,6 +1493,49 @@ 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.
*
* @return true/false
*/
bool esp_mesh_is_network_active(void);
/**
* @brief Set device duty cycle and type
*
* @attention This API can be called at any time after mesh is initialized.
*
* @param[in] dev_duty device duty cycle
* @param[in] dev_duty_type device PS duty cycle type
*
* @return
* - ESP_OK
* - ESP_FAIL
*/
esp_err_t esp_mesh_set_active_duty_cycle(int dev_duty, int dev_duty_type);
/**
* @brief Get device duty cycle and type
*
* @param[out] dev_duty device duty cycle
* @param[out] dev_duty_type device PS duty cycle type
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_get_active_duty_cycle(int* dev_duty, int* dev_duty_type);
/**
* @brief Get the running active duty cycle
*
* @return the running active duty cycle
*/
int esp_mesh_get_running_active_duty_cycle(void);
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit ef66c9a7ee824b78d015782b6a886c053c4f9b51
Subproject commit d9f3c27adec317ebe418aee5ecec6bfc3e8a684f

View file

@ -19,6 +19,7 @@
/*******************************************************
* Macros
*******************************************************/
//#define MESH_ENABLE_POWER_SAVE
/*******************************************************
* Constants
@ -101,6 +102,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,
@ -380,13 +387,19 @@ void app_main(void)
ESP_ERROR_CHECK(esp_netif_init());
/* event initialization */
ESP_ERROR_CHECK(esp_event_loop_create_default());
/* crete network interfaces for mesh (only station instance saved for further manipulation, soft AP instance ignored */
/* create network interfaces for mesh (only station instance saved for further manipulation, soft AP instance ignored */
ESP_ERROR_CHECK(esp_netif_create_default_wifi_mesh_netifs(&netif_sta, NULL));
/* wifi initialization */
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
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());
@ -396,7 +409,14 @@ 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_ap_assoc_expire(60));
/* PS is enabled, it's better to increase the announce interval. */
ESP_ERROR_CHECK(esp_mesh_set_announce_interval(600, 3300));
#else
ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10));
#endif
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
/* mesh ID */
memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6);
@ -412,6 +432,10 @@ 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(),