Merge branch 'mesh/power_save_function_with_local_duty' into 'master'

mesh/ps: add mesh network power save function

See merge request espressif/esp-idf!8203
This commit is contained in:
Jiang Jiang Jian
2020-04-02 19:43:12 +08:00
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 # endif
# ifdef ESP_ERR_MESH_VOTING # ifdef ESP_ERR_MESH_VOTING
ERR_TBL_IT(ESP_ERR_MESH_VOTING), /* 16406 0x4016 */ 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 # endif
// components/esp_netif/include/esp_netif_types.h // components/esp_netif/include/esp_netif_types.h
# ifdef ESP_ERR_ESP_NETIF_BASE # 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_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_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_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() * @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_ROOTS_FOUND (0x20) /**< root conflict is found */
#define MESH_ASSOC_FLAG_ROOT_FIXED (0x40) /**< fixed root */ #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 * Enumerations
*******************************************************/ *******************************************************/
@@ -421,7 +430,6 @@ typedef union {
packets out. If not, devices had better to wait until this state changes to be packets out. If not, devices had better to wait until this state changes to be
MESH_TODS_REACHABLE. */ MESH_TODS_REACHABLE. */
mesh_event_vote_started_t vote_started; /**< vote started */ 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_address_t root_addr; /**< root address */
mesh_event_root_switch_req_t switch_req; /**< root switch request */ mesh_event_root_switch_req_t switch_req; /**< root switch request */
mesh_event_root_conflict_t root_conflict; /**< other powerful root */ 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. * - Delete TX and RX queues.
* - Release resources. * - Release resources.
* - Restore Wi-Fi softAP to default settings if Wi-Fi dual mode is enabled. * - 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 * @return
* - ESP_OK * - 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); 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, * - During the networking, only obtaining vote percentage reaches this threshold,
* the device could be a root. * 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); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@@ -19,6 +19,7 @@
/******************************************************* /*******************************************************
* Macros * Macros
*******************************************************/ *******************************************************/
//#define MESH_ENABLE_POWER_SAVE
/******************************************************* /*******************************************************
* Constants * Constants
@@ -101,6 +102,12 @@ void esp_mesh_p2p_tx_main(void *arg)
} }
for (i = 0; i < route_table_size; i++) { 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); err = esp_mesh_send(&route_table[i], &data, MESH_DATA_P2P, NULL, 0);
if (err) { if (err) {
ESP_LOGE(MESH_TAG, ESP_LOGE(MESH_TAG,
@@ -380,13 +387,19 @@ void app_main(void)
ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_netif_init());
/* event initialization */ /* event initialization */
ESP_ERROR_CHECK(esp_event_loop_create_default()); 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)); ESP_ERROR_CHECK(esp_netif_create_default_wifi_mesh_netifs(&netif_sta, NULL));
/* wifi initialization */ /* wifi initialization */
wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&config)); 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_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL));
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); 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()); ESP_ERROR_CHECK(esp_wifi_start());
/* mesh initialization */ /* mesh initialization */
ESP_ERROR_CHECK(esp_mesh_init()); ESP_ERROR_CHECK(esp_mesh_init());
@@ -396,7 +409,14 @@ void app_main(void)
/* set mesh max layer according to the topology */ /* 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_max_layer(CONFIG_MESH_MAX_LAYER));
ESP_ERROR_CHECK(esp_mesh_set_vote_percentage(1)); 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)); ESP_ERROR_CHECK(esp_mesh_set_ap_assoc_expire(10));
#endif
mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT(); mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();
/* mesh ID */ /* mesh ID */
memcpy((uint8_t *) &cfg.mesh_id, MESH_ID, 6); 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, memcpy((uint8_t *) &cfg.mesh_ap.password, CONFIG_MESH_AP_PASSWD,
strlen(CONFIG_MESH_AP_PASSWD)); strlen(CONFIG_MESH_AP_PASSWD));
ESP_ERROR_CHECK(esp_mesh_set_config(&cfg)); 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 */ /* mesh start */
ESP_ERROR_CHECK(esp_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(), ESP_LOGI(MESH_TAG, "mesh starts successfully, heap:%d, %s<%d>%s\n", esp_get_free_heap_size(),