Skip to content

Commit

Permalink
Merge branch 'feature/mconfig-provision' into 'master'
Browse files Browse the repository at this point in the history
Feature/mconfig provision

See merge request application/esp-mdf!459
  • Loading branch information
zhanzhaocheng committed Nov 19, 2020
2 parents e0acefd + 7ded5df commit 1c76187
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 0 deletions.
14 changes: 14 additions & 0 deletions components/mconfig/Kconfig
Expand Up @@ -47,5 +47,19 @@ menu "MDF Mconfig"
help
Different length versions are incompatible. Increasing the length
will affect the network configuration time.

config MCONFIG_DIRECT_CONNECT_ROUTER
bool "Connect to router directly"
default n
help
If it set, the device will try to connect to router when provisioning,
otherwise the device will try to connect to mesh network with specific mesh_id

config MCONFIG_VERIFY_ROUTER
bool "Verify router password"
default y
help
If it is set, the mesh_password will generate by ap_password and mesh_password which
are passed from app.

endmenu
190 changes: 190 additions & 0 deletions components/mconfig/mconfig_blufi.c
Expand Up @@ -23,10 +23,12 @@
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_wifi.h"
#include "esp_mesh.h"

#include "mbedtls/aes.h"
#include "mbedtls/dhm.h"
#include "mbedtls/md5.h"
#include "mbedtls/sha256.h"
#include "esp32/rom/crc.h"

#include "mdf_common.h"
Expand Down Expand Up @@ -163,6 +165,27 @@ static void mconfig_blufi_rsa_decrypt_task(void *arg)
vTaskDelete(NULL);
}

static void combine_ap_mesh_password(uint8_t dst[64], const uint8_t *ap_password, const uint8_t *mesh_password)
{
uint8_t ap_sha256[32] = { 0 };
uint8_t mesh_sha256[32] = { 0 };

mbedtls_sha256_ret(ap_password, strlen((const char *)ap_password), ap_sha256, 0);
mbedtls_sha256_ret(mesh_password, strlen((const char *)mesh_password), mesh_sha256, 0);

for (int i = 0; i < 32; i++) {
mesh_sha256[i] ^= ap_sha256[i];
char tmp = ((mesh_sha256[i] & 0xf0) >> 4) + '0';
dst[2 * i] = tmp > '9' ? tmp + 'A' - '9' : tmp;
tmp = (mesh_sha256[i] & 0x0f) + '0';
dst[2 * i + 1] = tmp > '9' ? tmp + 'A' - '9' : tmp;
}

dst[63] = '\0';

MDF_LOGD("combine password: %s", dst);
}

extern void btc_blufi_report_error(esp_blufi_error_state_t state);

/**< BLUFI negotiate data function for negotiate share key */
Expand Down Expand Up @@ -316,6 +339,7 @@ static void mconfig_blufi_security_deinit(void)
mbedtls_aes_free(&g_blufi_aes);
}

#ifdef CONFIG_MCONFIG_DIRECT_CONNECT_ROUTER
/**< Set Blufi application specified event callback function */
static void blufi_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
Expand Down Expand Up @@ -405,6 +429,117 @@ static void blufi_wifi_event_handler(void *arg, esp_event_base_t event_base, int
break;
}
}
#else

static void mconfig_stop_mesh_cb(xTimerHandle timer)
{
esp_mesh_stop();
xTimerDelete(timer, 0);
}

static void blufi_mesh_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
mdf_err_t ret = MDF_OK;
static int s_disconnected_unknown_count = 0;
static int s_disconnected_handshake_count = 0;

switch (event_id) {
case MESH_EVENT_STOPPED:
mconfig_chain_slave_channel_switch_enable();
break;

case MESH_EVENT_PARENT_CONNECTED:
/**< Send MDF_EVENT_MCONFIG_BLUFI_STA_CONNECTED event to the event handler */
mdf_event_loop_send(MDF_EVENT_MCONFIG_BLUFI_STA_CONNECTED, NULL);

MDF_LOGI("BLUFI is success, Wi-Fi sta is connect");
s_disconnected_unknown_count = 0;
s_disconnected_handshake_count = 0;

esp_blufi_send_wifi_conn_report(WIFI_MODE_STA, ESP_BLUFI_STA_CONN_SUCCESS, 0, NULL);
wifi_event_sta_connected_t *event = (wifi_event_sta_connected_t *)event_data;
g_recv_config->config.channel = event->channel;

ret = mconfig_ble_connect_timer_create();
MDF_ERROR_BREAK(ret != MDF_OK, "<%s> mconfig_ble_connect_timercb", mdf_err_to_name(ret));

break;

case MESH_EVENT_PARENT_DISCONNECTED: {
esp_blufi_sta_conn_state_t sta_conn_state = ESP_BLUFI_STA_CONN_SUCCESS;
mesh_event_disconnected_t *disconnected = (mesh_event_disconnected_t *)event_data;

MDF_LOGW("disconnected reason: %d", disconnected->reason);

switch (disconnected->reason) {
case WIFI_REASON_ASSOC_TOOMANY:
MDF_LOGW("WIFI_REASON_ASSOC_TOOMANY Disassociated because AP is unable to handle all currently associated STAs");
MDF_LOGW("The number of connected devices on the router exceeds the limit");

sta_conn_state = BLUFI_STA_TOOMANY_ERR;

break;

case WIFI_REASON_MIC_FAILURE: /**< disconnected reason code 14 */
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: /**< disconnected reason code 15 */
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: /**< disconnected reason code 16 */
case WIFI_REASON_IE_IN_4WAY_DIFFERS: /**< disconnected reason code 17 */
case WIFI_REASON_HANDSHAKE_TIMEOUT: /**< disconnected reason code 204 */
MDF_LOGW("Wi-Fi 4-way handshake failed, count: %d", s_disconnected_handshake_count);

if (++s_disconnected_handshake_count >= 3) {
MDF_LOGW("Router password error");
sta_conn_state = BLUFI_STA_PASSWORD_ERR;
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_self_organized", mdf_err_to_name(ret));
}

break;

default:
if (++s_disconnected_unknown_count > 10) {
MDF_LOGW("Router password error");
sta_conn_state = BLUFI_STA_PASSWORD_ERR;
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_self_organized", mdf_err_to_name(ret));
}

break;
}

if (sta_conn_state != ESP_BLUFI_STA_CONN_SUCCESS) {
uint32_t disconnected_reason = disconnected->reason;

esp_blufi_send_error_info(sta_conn_state);

/**< Send MDF_EVENT_MCONFIG_BLUFI_STA_DISCONNECTED event to the event handler */
mdf_event_loop_send(MDF_EVENT_MCONFIG_BLUFI_STA_DISCONNECTED, (void *)disconnected_reason);

ret = esp_ble_gap_disconnect(g_spp_remote_bda);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_ble_gap_disconnect", mdf_err_to_name(ret));

xTimerHandle timer = xTimerCreate("stop_mesh", 1, pdFALSE, NULL, mconfig_stop_mesh_cb);
assert(xTimerStart(timer, 0) == pdPASS);
}

break;
}

case MESH_EVENT_NO_PARENT_FOUND: {
esp_blufi_sta_conn_state_t sta_conn_state = BLUFI_STA_AP_FOUND_ERR;
esp_blufi_send_error_info(sta_conn_state);

ret = esp_ble_gap_disconnect(g_spp_remote_bda);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_ble_gap_disconnect", mdf_err_to_name(ret));

xTimerHandle timer = xTimerCreate("stop_mesh", 1, pdFALSE, NULL, mconfig_stop_mesh_cb);
assert(xTimerStart(timer, 0) == pdPASS);
}
break;

default:
break;
}
}
#endif

static mdf_err_t mconfig_blufi_adv_start()
{
Expand Down Expand Up @@ -844,6 +979,7 @@ static void mconfig_blufi_event_callback(esp_blufi_cb_event_t event, esp_blufi_c
/**< Disable slave to switch wifi channel */
mconfig_chain_slave_channel_switch_disable();

#ifdef CONFIG_MCONFIG_DIRECT_CONNECT_ROUTER
/**< Wi-Fi try to connect AP */
wifi_config_t sta_config = {0};

Expand All @@ -858,7 +994,56 @@ static void mconfig_blufi_event_callback(esp_blufi_cb_event_t event, esp_blufi_c

ret = esp_wifi_connect();
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> Connect the ESP32 WiFi station to the AP", mdf_err_to_name(ret));
#else
/* mesh try to connect mesh network */
ret = esp_mesh_init();
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_init", mdf_err_to_name(ret));

esp_event_handler_register(MESH_EVENT, ESP_EVENT_ANY_ID, &blufi_mesh_event_handler, NULL);

ret = esp_mesh_set_topology(CONFIG_MWIFI_TOPOLOGY);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_topology", mdf_err_to_name(ret));

ret = esp_mesh_set_max_layer(CONFIG_MWIFI_MAX_LAYER);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_max_layer", mdf_err_to_name(ret));

ret = esp_mesh_set_vote_percentage(1);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_vote_percentage", mdf_err_to_name(ret));

mesh_cfg_t cfg = MESH_INIT_CONFIG_DEFAULT();

cfg.channel = g_recv_config->config.channel;
cfg.router.ssid_len = strlen(g_recv_config->config.router_ssid);
memcpy(cfg.router.ssid, g_recv_config->config.router_ssid, cfg.router.ssid_len);
memcpy(cfg.router.password, g_recv_config->config.router_password, strlen(g_recv_config->config.router_password));

memcpy(cfg.mesh_id.addr, g_recv_config->config.mesh_id, 6);
#if CONFIG_MCONFIG_VERIFY_ROUTER
combine_ap_mesh_password(cfg.mesh_ap.password, (const uint8_t *)g_recv_config->config.router_password, (const uint8_t *)g_recv_config->config.mesh_password);
memcpy(g_recv_config->config.mesh_password, cfg.mesh_ap.password, 64);
#else
memcpy(cfg.mesh_ap.password, g_recv_config->config.mesh_password, strlen(g_recv_config->config.mesh_password));
#endif

if (strlen((const char *)cfg.mesh_ap.password) > 0) {
ret = esp_mesh_set_ap_authmode(WIFI_AUTH_WPA_WPA2_PSK);
} else {
ret = esp_mesh_set_ap_authmode(WIFI_AUTH_OPEN);
}

MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_ap_authmode", mdf_err_to_name(ret));

cfg.mesh_ap.max_connection = CONFIG_MWIFI_MAX_CONNECTION;

ret = esp_mesh_set_config(&cfg);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_config", mdf_err_to_name(ret));

ret = esp_mesh_set_self_organized(true, false);
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_set_self_organized", mdf_err_to_name(ret));

ret = esp_mesh_start();
MDF_ERROR_BREAK(ret != ESP_OK, "<%s> esp_mesh_start", mdf_err_to_name(ret));
#endif
/**< Send MDF_EVENT_MCONFIG_BLUFI_STA_CONNECTED event to the event handler */
ret = mdf_event_loop_send(MDF_EVENT_MCONFIG_BLUFI_STA_CONNECTED, NULL);
MDF_ERROR_BREAK(ret < 0, "<%s> Send the event to the event handler", mdf_err_to_name(ret));
Expand Down Expand Up @@ -951,8 +1136,13 @@ mdf_err_t mconfig_blufi_deinit()

mconfig_ble_connect_timer_delete();

#ifdef CONFIG_MCONFIG_DIRECT_CONNECT_ROUTER
esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &blufi_wifi_event_handler);
esp_wifi_disconnect();
#else
esp_event_handler_unregister(MESH_EVENT, ESP_EVENT_ANY_ID, &blufi_mesh_event_handler);
esp_mesh_stop();
#endif
MDF_FREE(g_recv_config);

ret = esp_blufi_profile_deinit();
Expand Down
8 changes: 8 additions & 0 deletions components/mconfig/mconfig_chain.c
Expand Up @@ -310,6 +310,14 @@ static bool scan_mesh_device(uint8_t *bssid, int8_t *rssi)

channel = channel % 13 + 1;

if (channel >= 11 && second == WIFI_SECOND_CHAN_ABOVE) {
second = WIFI_SECOND_CHAN_BELOW;
}

if (channel <= 3 && second == WIFI_SECOND_CHAN_BELOW) {
second = WIFI_SECOND_CHAN_ABOVE;
}

if (esp_wifi_set_channel(channel, second) != ESP_OK) {
MDF_LOGW("esp_wifi_set_channel, channel: %d, second: %d", channel, second);
}
Expand Down

0 comments on commit 1c76187

Please sign in to comment.