Merge branch 'feature/wac_support' into 'master'

homekit_switch: Modifications to support WAC

See merge request app-frameworks/esp-rainmaker!237
This commit is contained in:
Piyush Shah
2022-01-07 06:19:30 +00:00
8 changed files with 154 additions and 38 deletions

View File

@@ -155,7 +155,6 @@ before_script:
.build_homekit_switch: &build_homekit_switch
# Building homekit_switch app - Started
- cd $CI_PROJECT_DIR/examples/homekit_switch
- mkdir components
- cd components
- echo Cloning esp-homekit-sdk
- git clone --recursive --branch master --depth 1 https://github.com/espressif/esp-homekit-sdk.git

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "app_wifi_with_homekit.c"
INCLUDE_DIRS "."
REQUIRES wifi_provisioning qrcode esp_hap_core esp_hap_platform)

View File

@@ -0,0 +1,35 @@
menu "App Wi-Fi Provisioning"
config APP_WIFI_PROV_SHOW_QR
bool "Show provisioning QR code"
default y
help
Show the QR code for provisioning.
choice APP_WIFI_PROV_TRANSPORT
bool "Provisioning Transport method"
default APP_WIFI_PROV_TRANSPORT_BLE
help
Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one.
config APP_WIFI_PROV_TRANSPORT_SOFTAP
bool "Soft AP"
config APP_WIFI_PROV_TRANSPORT_BLE
bool "BLE"
select BT_ENABLED
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
endchoice
config APP_WIFI_PROV_TRANSPORT
int
default 1 if APP_WIFI_PROV_TRANSPORT_SOFTAP
default 2 if APP_WIFI_PROV_TRANSPORT_BLE
config APP_WIFI_USE_WAC_PROVISIONING
bool "Apple WAC Provisioning"
depends on HAP_MFI_ENABLE
default n
help
"Use Apple WAC Provisioning"
endmenu

View File

@@ -35,7 +35,11 @@
#include <qrcode.h>
#include <nvs.h>
#include <nvs_flash.h>
#include "app_wifi.h"
#include "app_wifi_with_homekit.h"
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
#include <hap_wac.h>
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
static const char *TAG = "app_wifi";
static const int WIFI_CONNECTED_EVENT = BIT0;
@@ -67,6 +71,28 @@ static void app_wifi_print_qr(const char *name, const char *pop, const char *tra
ESP_LOGI(TAG, "If QR code is not visible, copy paste the below URL in a browser.\n%s?data=%s", QRCODE_BASE_URL, payload);
}
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP
static void app_wac_softap_start(char *ssid)
{
}
#else
static void app_wac_softap_start(char *ssid)
{
hap_wifi_softap_start(ssid);
}
#endif /* ! CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
static void app_wac_softap_stop(void)
{
hap_wifi_softap_stop();
}
static void app_wac_sta_connect(wifi_config_t *wifi_cfg)
{
wifi_prov_mgr_configure_sta(wifi_cfg);
}
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
/* Event handler for catching system events */
static void event_handler(void* arg, esp_event_base_t event_base,
int32_t event_id, void* event_data)
@@ -96,6 +122,9 @@ static void event_handler(void* arg, esp_event_base_t event_base,
ESP_LOGI(TAG, "Provisioning successful");
break;
case WIFI_PROV_END:
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
hap_wac_stop();
#endif
/* De-initialize manager once provisioning is finished */
wifi_prov_mgr_deinit();
break;
@@ -104,14 +133,42 @@ static void event_handler(void* arg, esp_event_base_t event_base,
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
#ifdef ESP_NETIF_SUPPORTED
esp_netif_create_ip6_linklocal((esp_netif_t *)arg);
#else
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
#endif
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip));
/* Signal main application to continue execution */
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT);
} else if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) {
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
ESP_LOGI(TAG, "Connected with IPv6 Address:" IPV6STR, IPV62STR(event->ip6_info.ip));
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
ESP_LOGI(TAG, "Disconnected. Connecting to the AP again...");
esp_wifi_connect();
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
} else if (event_base == HAP_WAC_EVENT) {
switch (event_id) {
case HAP_WAC_EVENT_REQ_SOFTAP_START:
app_wac_softap_start((char *)event_data);
break;
case HAP_WAC_EVENT_REQ_SOFTAP_STOP:
app_wac_softap_stop();
break;
case HAP_WAC_EVENT_RECV_CRED:
app_wac_sta_connect((wifi_config_t *)event_data);
break;
case HAP_WAC_EVENT_STOPPED:
ESP_LOGI(TAG, "WAC Stopped");
break;
default:
break;
}
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
}
}
@@ -120,45 +177,55 @@ static void wifi_init_sta()
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
}
static void get_device_service_name(char *service_name, size_t max)
{
uint8_t eth_mac[6];
const char *ssid_prefix = "PROV_";
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
snprintf(service_name, max, "%s%02X%02X%02X",
ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]);
}
/* free the return value after use. */
static char *read_random_bytes_from_nvs()
/* Free random_bytes after use only if function returns ESP_OK */
static esp_err_t read_random_bytes_from_nvs(uint8_t **random_bytes, size_t *len)
{
nvs_handle handle;
esp_err_t err;
size_t required_size = 0;
void *value;
*len = 0;
if ((err = nvs_open_from_partition(CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE,
NVS_READONLY, &handle)) != ESP_OK) {
ESP_LOGD(TAG, "NVS open for %s %s %s failed with error %d", CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE, RANDOM_NVS_KEY, err);
return NULL;
return ESP_FAIL;
}
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, &required_size)) != ESP_OK) {
ESP_LOGD(TAG, "Failed to read key %s with error %d size %d", RANDOM_NVS_KEY, err, required_size);
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, len)) != ESP_OK) {
ESP_LOGD(TAG, "Error %d. Failed to read key %s.", err, RANDOM_NVS_KEY);
nvs_close(handle);
return NULL;
return ESP_ERR_NOT_FOUND;
}
value = calloc(required_size + 1, 1); /* + 1 for NULL termination */
if (value) {
nvs_get_blob(handle, RANDOM_NVS_KEY, value, &required_size);
*random_bytes = calloc(*len, 1);
if (*random_bytes) {
nvs_get_blob(handle, RANDOM_NVS_KEY, *random_bytes, len);
nvs_close(handle);
return ESP_OK;
}
nvs_close(handle);
return value;
return ESP_ERR_NO_MEM;
}
static esp_err_t get_device_service_name(char *service_name, size_t max)
{
uint8_t *nvs_random = NULL;
const char *ssid_prefix = "PROV_";
size_t nvs_random_size = 0;
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 3) {
uint8_t eth_mac[6];
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
snprintf(service_name, max, "%s%02x%02x%02x", ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]);
} else {
snprintf(service_name, max, "%s%02x%02x%02x", ssid_prefix, nvs_random[nvs_random_size - 3],
nvs_random[nvs_random_size - 2], nvs_random[nvs_random_size - 1]);
}
if (nvs_random) {
free(nvs_random);
}
return ESP_OK;
}
static esp_err_t get_device_pop(char *pop, size_t max, app_wifi_pop_type_t pop_type)
{
if (!pop || !max) {
@@ -175,14 +242,13 @@ static esp_err_t get_device_pop(char *pop, size_t max, app_wifi_pop_type_t pop_t
return err;
}
} else if (pop_type == POP_TYPE_RANDOM) {
char *nvs_pop = read_random_bytes_from_nvs();
if (!nvs_pop) {
uint8_t *nvs_random;
size_t nvs_random_size = 0;
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 4) {
return ESP_ERR_NOT_FOUND;
} else {
strncpy(pop, nvs_pop, max - 1);
pop[max - 1] = 0;
free(nvs_pop);
nvs_pop = NULL;
snprintf(pop, max, "%02x%02x%02x%02x", nvs_random[0], nvs_random[1], nvs_random[2], nvs_random[3]);
free(nvs_random);
return ESP_OK;
}
} else {
@@ -203,15 +269,21 @@ void app_wifi_with_homekit_init(void)
ESP_ERROR_CHECK(esp_event_loop_create_default());
wifi_event_group = xEventGroupCreate();
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
/* Initialize Wi-Fi including netif with default config */
#ifdef ESP_NETIF_SUPPORTED
esp_netif_create_default_wifi_sta();
esp_netif_t *wifi_netif = esp_netif_create_default_wifi_sta();
#endif
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
#ifdef ESP_NETIF_SUPPORTED
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, wifi_netif));
#else
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
#endif
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &event_handler, NULL));
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
}
@@ -326,6 +398,10 @@ esp_err_t app_wifi_with_homekit_start(app_wifi_pop_type_t pop_type)
app_wifi_print_qr(service_name, pop, PROV_TRANSPORT_SOFTAP);
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
ESP_LOGI(TAG, "Provisioning Started. Name : %s, POP : %s", service_name, pop);
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
esp_event_handler_register(HAP_WAC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL);
hap_wac_start();
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
} else {
ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA");

View File

@@ -0,0 +1,2 @@
COMPONENT_ADD_INCLUDEDIRS := .
COMPONENT_SRCDIRS := .

View File

@@ -1,2 +1,2 @@
idf_component_register(SRCS ./app_driver.c ./app_main.c ./app_homekit.c ./app_wifi_with_homekit.c
idf_component_register(SRCS ./app_driver.c ./app_main.c ./app_homekit.c
INCLUDE_DIRS ".")

View File

@@ -173,6 +173,7 @@ esp_err_t app_homekit_start(bool init_state)
app_homekit_show_qr();
}
#endif
hap_enable_mfi_auth(HAP_MFI_AUTH_HW);
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &app_homekit_event_handler, NULL);
esp_event_handler_register(HAP_EVENT, HAP_EVENT_CTRL_UNPAIRED, &app_homekit_event_handler, NULL);