Skip to content

Commit d4eb2f4

Browse files
committed
Merge branch 'feature/wac_support' into 'master'
homekit_switch: Modifications to support WAC See merge request app-frameworks/esp-rainmaker!237
2 parents 297c0d5 + dc8ca40 commit d4eb2f4

File tree

8 files changed

+153
-37
lines changed

8 files changed

+153
-37
lines changed

.gitlab-ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,6 @@ before_script:
155155
.build_homekit_switch: &build_homekit_switch
156156
# Building homekit_switch app - Started
157157
- cd $CI_PROJECT_DIR/examples/homekit_switch
158-
- mkdir components
159158
- cd components
160159
- echo Cloning esp-homekit-sdk
161160
- git clone --recursive --branch master --depth 1 https://github.com/espressif/esp-homekit-sdk.git
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
idf_component_register(SRCS "app_wifi_with_homekit.c"
2+
INCLUDE_DIRS "."
3+
REQUIRES wifi_provisioning qrcode esp_hap_core esp_hap_platform)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
menu "App Wi-Fi Provisioning"
2+
3+
config APP_WIFI_PROV_SHOW_QR
4+
bool "Show provisioning QR code"
5+
default y
6+
help
7+
Show the QR code for provisioning.
8+
9+
choice APP_WIFI_PROV_TRANSPORT
10+
bool "Provisioning Transport method"
11+
default APP_WIFI_PROV_TRANSPORT_BLE
12+
help
13+
Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one.
14+
15+
config APP_WIFI_PROV_TRANSPORT_SOFTAP
16+
bool "Soft AP"
17+
config APP_WIFI_PROV_TRANSPORT_BLE
18+
bool "BLE"
19+
select BT_ENABLED
20+
depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
21+
endchoice
22+
23+
config APP_WIFI_PROV_TRANSPORT
24+
int
25+
default 1 if APP_WIFI_PROV_TRANSPORT_SOFTAP
26+
default 2 if APP_WIFI_PROV_TRANSPORT_BLE
27+
28+
config APP_WIFI_USE_WAC_PROVISIONING
29+
bool "Apple WAC Provisioning"
30+
depends on HAP_MFI_ENABLE
31+
default n
32+
help
33+
"Use Apple WAC Provisioning"
34+
35+
endmenu

examples/homekit_switch/main/app_wifi_with_homekit.c renamed to examples/homekit_switch/components/app_wifi/app_wifi_with_homekit.c

Lines changed: 111 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@
3535
#include <qrcode.h>
3636
#include <nvs.h>
3737
#include <nvs_flash.h>
38-
#include "app_wifi.h"
38+
#include "app_wifi_with_homekit.h"
39+
40+
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
41+
#include <hap_wac.h>
42+
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
3943

4044
static const char *TAG = "app_wifi";
4145
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
6771
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);
6872
}
6973

74+
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
75+
#ifdef CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP
76+
static void app_wac_softap_start(char *ssid)
77+
{
78+
}
79+
#else
80+
static void app_wac_softap_start(char *ssid)
81+
{
82+
hap_wifi_softap_start(ssid);
83+
}
84+
#endif /* ! CONFIG_APP_WIFI_PROV_TRANSPORT_SOFTAP */
85+
static void app_wac_softap_stop(void)
86+
{
87+
hap_wifi_softap_stop();
88+
}
89+
static void app_wac_sta_connect(wifi_config_t *wifi_cfg)
90+
{
91+
wifi_prov_mgr_configure_sta(wifi_cfg);
92+
}
93+
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
94+
95+
7096
/* Event handler for catching system events */
7197
static void event_handler(void* arg, esp_event_base_t event_base,
7298
int32_t event_id, void* event_data)
@@ -96,6 +122,9 @@ static void event_handler(void* arg, esp_event_base_t event_base,
96122
ESP_LOGI(TAG, "Provisioning successful");
97123
break;
98124
case WIFI_PROV_END:
125+
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
126+
hap_wac_stop();
127+
#endif
99128
/* De-initialize manager once provisioning is finished */
100129
wifi_prov_mgr_deinit();
101130
break;
@@ -104,14 +133,42 @@ static void event_handler(void* arg, esp_event_base_t event_base,
104133
}
105134
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
106135
esp_wifi_connect();
136+
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
137+
#ifdef ESP_NETIF_SUPPORTED
138+
esp_netif_create_ip6_linklocal((esp_netif_t *)arg);
139+
#else
140+
tcpip_adapter_create_ip6_linklocal(TCPIP_ADAPTER_IF_STA);
141+
#endif
107142
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
108143
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
109144
ESP_LOGI(TAG, "Connected with IP Address:" IPSTR, IP2STR(&event->ip_info.ip));
110145
/* Signal main application to continue execution */
111146
xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_EVENT);
147+
} else if (event_base == IP_EVENT && event_id == IP_EVENT_GOT_IP6) {
148+
ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data;
149+
ESP_LOGI(TAG, "Connected with IPv6 Address:" IPV6STR, IPV62STR(event->ip6_info.ip));
112150
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
113151
ESP_LOGI(TAG, "Disconnected. Connecting to the AP again...");
114152
esp_wifi_connect();
153+
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
154+
} else if (event_base == HAP_WAC_EVENT) {
155+
switch (event_id) {
156+
case HAP_WAC_EVENT_REQ_SOFTAP_START:
157+
app_wac_softap_start((char *)event_data);
158+
break;
159+
case HAP_WAC_EVENT_REQ_SOFTAP_STOP:
160+
app_wac_softap_stop();
161+
break;
162+
case HAP_WAC_EVENT_RECV_CRED:
163+
app_wac_sta_connect((wifi_config_t *)event_data);
164+
break;
165+
case HAP_WAC_EVENT_STOPPED:
166+
ESP_LOGI(TAG, "WAC Stopped");
167+
break;
168+
default:
169+
break;
170+
}
171+
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
115172
}
116173
}
117174

@@ -120,45 +177,55 @@ static void wifi_init_sta()
120177
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
121178
ESP_ERROR_CHECK(esp_wifi_start());
122179
}
123-
124-
static void get_device_service_name(char *service_name, size_t max)
125-
{
126-
uint8_t eth_mac[6];
127-
const char *ssid_prefix = "PROV_";
128-
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
129-
snprintf(service_name, max, "%s%02X%02X%02X",
130-
ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]);
131-
}
132-
133-
/* free the return value after use. */
134-
static char *read_random_bytes_from_nvs()
180+
/* Free random_bytes after use only if function returns ESP_OK */
181+
static esp_err_t read_random_bytes_from_nvs(uint8_t **random_bytes, size_t *len)
135182
{
136183
nvs_handle handle;
137184
esp_err_t err;
138-
size_t required_size = 0;
139-
void *value;
185+
*len = 0;
140186

141187
if ((err = nvs_open_from_partition(CONFIG_ESP_RMAKER_FACTORY_PARTITION_NAME, CREDENTIALS_NAMESPACE,
142188
NVS_READONLY, &handle)) != ESP_OK) {
143189
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);
144-
return NULL;
190+
return ESP_FAIL;
145191
}
146192

147-
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, &required_size)) != ESP_OK) {
148-
ESP_LOGD(TAG, "Failed to read key %s with error %d size %d", RANDOM_NVS_KEY, err, required_size);
193+
if ((err = nvs_get_blob(handle, RANDOM_NVS_KEY, NULL, len)) != ESP_OK) {
194+
ESP_LOGD(TAG, "Error %d. Failed to read key %s.", err, RANDOM_NVS_KEY);
149195
nvs_close(handle);
150-
return NULL;
196+
return ESP_ERR_NOT_FOUND;
151197
}
152198

153-
value = calloc(required_size + 1, 1); /* + 1 for NULL termination */
154-
if (value) {
155-
nvs_get_blob(handle, RANDOM_NVS_KEY, value, &required_size);
199+
*random_bytes = calloc(*len, 1);
200+
if (*random_bytes) {
201+
nvs_get_blob(handle, RANDOM_NVS_KEY, *random_bytes, len);
202+
nvs_close(handle);
203+
return ESP_OK;
156204
}
157-
158205
nvs_close(handle);
159-
return value;
206+
return ESP_ERR_NO_MEM;
207+
}
208+
209+
static esp_err_t get_device_service_name(char *service_name, size_t max)
210+
{
211+
uint8_t *nvs_random = NULL;
212+
const char *ssid_prefix = "PROV_";
213+
size_t nvs_random_size = 0;
214+
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 3) {
215+
uint8_t eth_mac[6];
216+
esp_wifi_get_mac(WIFI_IF_STA, eth_mac);
217+
snprintf(service_name, max, "%s%02x%02x%02x", ssid_prefix, eth_mac[3], eth_mac[4], eth_mac[5]);
218+
} else {
219+
snprintf(service_name, max, "%s%02x%02x%02x", ssid_prefix, nvs_random[nvs_random_size - 3],
220+
nvs_random[nvs_random_size - 2], nvs_random[nvs_random_size - 1]);
221+
}
222+
if (nvs_random) {
223+
free(nvs_random);
224+
}
225+
return ESP_OK;
160226
}
161227

228+
162229
static esp_err_t get_device_pop(char *pop, size_t max, app_wifi_pop_type_t pop_type)
163230
{
164231
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
175242
return err;
176243
}
177244
} else if (pop_type == POP_TYPE_RANDOM) {
178-
char *nvs_pop = read_random_bytes_from_nvs();
179-
if (!nvs_pop) {
245+
uint8_t *nvs_random;
246+
size_t nvs_random_size = 0;
247+
if ((read_random_bytes_from_nvs(&nvs_random, &nvs_random_size) != ESP_OK) || nvs_random_size < 4) {
180248
return ESP_ERR_NOT_FOUND;
181249
} else {
182-
strncpy(pop, nvs_pop, max - 1);
183-
pop[max - 1] = 0;
184-
free(nvs_pop);
185-
nvs_pop = NULL;
250+
snprintf(pop, max, "%02x%02x%02x%02x", nvs_random[0], nvs_random[1], nvs_random[2], nvs_random[3]);
251+
free(nvs_random);
186252
return ESP_OK;
187253
}
188254
} else {
@@ -203,15 +269,21 @@ void app_wifi_with_homekit_init(void)
203269
ESP_ERROR_CHECK(esp_event_loop_create_default());
204270
wifi_event_group = xEventGroupCreate();
205271

272+
/* Initialize Wi-Fi including netif with default config */
273+
#ifdef ESP_NETIF_SUPPORTED
274+
esp_netif_t *wifi_netif = esp_netif_create_default_wifi_sta();
275+
#endif
276+
206277
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
207-
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
278+
#ifdef ESP_NETIF_SUPPORTED
279+
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, wifi_netif));
280+
#else
208281
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
282+
#endif
283+
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_PROV_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
209284
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));
285+
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_GOT_IP6, &event_handler, NULL));
210286

211-
/* Initialize Wi-Fi including netif with default config */
212-
#ifdef ESP_NETIF_SUPPORTED
213-
esp_netif_create_default_wifi_sta();
214-
#endif
215287
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
216288
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
217289
}
@@ -326,6 +398,10 @@ esp_err_t app_wifi_with_homekit_start(app_wifi_pop_type_t pop_type)
326398
app_wifi_print_qr(service_name, pop, PROV_TRANSPORT_SOFTAP);
327399
#endif /* CONFIG_APP_WIFI_PROV_TRANSPORT_BLE */
328400
ESP_LOGI(TAG, "Provisioning Started. Name : %s, POP : %s", service_name, pop);
401+
#ifdef CONFIG_APP_WIFI_USE_WAC_PROVISIONING
402+
esp_event_handler_register(HAP_WAC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL);
403+
hap_wac_start();
404+
#endif /* CONFIG_APP_WIFI_USE_WAC_PROVISIONING */
329405
} else {
330406
ESP_LOGI(TAG, "Already provisioned, starting Wi-Fi STA");
331407

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
COMPONENT_ADD_INCLUDEDIRS := .
2+
COMPONENT_SRCDIRS := .
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
idf_component_register(SRCS ./app_driver.c ./app_main.c ./app_homekit.c ./app_wifi_with_homekit.c
1+
idf_component_register(SRCS ./app_driver.c ./app_main.c ./app_homekit.c
22
INCLUDE_DIRS ".")

examples/homekit_switch/main/app_homekit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ esp_err_t app_homekit_start(bool init_state)
173173
app_homekit_show_qr();
174174
}
175175
#endif
176+
hap_enable_mfi_auth(HAP_MFI_AUTH_HW);
176177
/* Register our event handler for Wi-Fi, IP and Provisioning related events */
177178
esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &app_homekit_event_handler, NULL);
178179
esp_event_handler_register(HAP_EVENT, HAP_EVENT_CTRL_UNPAIRED, &app_homekit_event_handler, NULL);

0 commit comments

Comments
 (0)