1
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
40
41
42
43
47
48
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
78
79
80
81
82
83
86
87
88
92
93
94
95
96
97
105
106
107
108
111
112
113
117
118
119
120
121
122
123
124
125
126
130
131
132
138
139
140
141
142
143
144
145
149
150
151
154
155
156
157
158
159
160
164
165
169
170
171
172
173
174
177
178
179
180
182
189
190
191
192
196
197
202
203
204
205
206
207
208
212
213
217
218
219
220
221
225
226
227
228
233
234
235
236
237
238
239
240
241
242
275
276
277
297
298
299
321
322
323
324
325
326
327
328
329
330
/* ... */
#include <string.h>
#include <esp_log.h>
#include <esp_err.h>
#ifdef CONFIG_BT_CONTROLLER_ENABLED
#include "esp_bt.h"
#endif
#include <protocomm.h>
#include <protocomm_ble.h>
#include "wifi_provisioning/scheme_ble.h"
#include "wifi_provisioning_priv.h"
static const char *TAG = "wifi_prov_scheme_ble";
extern const wifi_prov_scheme_t wifi_prov_scheme_ble;
static uint8_t *custom_service_uuid;
static uint8_t *custom_ble_addr;
static uint8_t custom_keep_ble_on;
static uint8_t *custom_manufacturer_data;
static size_t custom_manufacturer_data_len;
esp_err_t wifi_prov_mgr_keep_ble_on(uint8_t is_on_after_ble_stop)
{
if (!is_on_after_ble_stop) {
return ESP_ERR_INVALID_ARG;
}{...}
custom_keep_ble_on = is_on_after_ble_stop;
return ESP_OK;
}{ ... }
static esp_err_t prov_start(protocomm_t *pc, void *config)
{
if (!pc) {
ESP_LOGE(TAG, "Protocomm handle cannot be null");
return ESP_ERR_INVALID_ARG;
}{...}
if (!config) {
ESP_LOGE(TAG, "Cannot start with null configuration");
return ESP_ERR_INVALID_ARG;
}{...}
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
ble_config->keep_ble_on = custom_keep_ble_on;
#if defined(CONFIG_WIFI_PROV_BLE_BONDING)
ble_config->ble_bonding = 1;
#endif
#if defined(CONFIG_WIFI_PROV_BLE_SEC_CONN) || defined(CONFIG_BT_BLUEDROID_ENABLED)
ble_config->ble_sm_sc = 1;
#endif
#if defined(CONFIG_WIFI_PROV_BLE_FORCE_ENCRYPTION)
ble_config->ble_link_encryption = 1;
#endif
#if defined(CONFIG_WIFI_PROV_BLE_NOTIFY)
ble_config->ble_notify = 1;
#endif
if (protocomm_ble_start(pc, ble_config) != ESP_OK) {
ESP_LOGE(TAG, "Failed to start protocomm BLE service");
return ESP_FAIL;
}{...}
return ESP_OK;
}{ ... }
esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *addr)
{
if (!addr) {
return ESP_ERR_INVALID_ARG;
}{...}
custom_ble_addr = (uint8_t *) malloc(BLE_ADDR_LEN);
if (custom_ble_addr == NULL) {
ESP_LOGE(TAG, "Error allocating memory for random address");
return ESP_ERR_NO_MEM;
}{...}
memcpy(custom_ble_addr, addr, BLE_ADDR_LEN);
return ESP_OK;
}{ ... }
esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128)
{
if (!uuid128) {
return ESP_ERR_INVALID_ARG;
}{...}
custom_service_uuid = uuid128;
return ESP_OK;
}{ ... }
esp_err_t wifi_prov_scheme_ble_set_mfg_data(uint8_t *mfg_data, ssize_t mfg_data_len)
{
if (!mfg_data || !mfg_data_len) {
return ESP_ERR_INVALID_ARG;
}{...}
custom_manufacturer_data = (uint8_t *) malloc(mfg_data_len);
if (custom_manufacturer_data == NULL) {
ESP_LOGE(TAG, "Error allocating memory for mfg_data");
return ESP_ERR_NO_MEM;
}{...}
custom_manufacturer_data_len = mfg_data_len;
memcpy(custom_manufacturer_data, mfg_data, mfg_data_len);
return ESP_OK;
}{ ... }
static void *new_config(void)
{
protocomm_ble_config_t *ble_config = calloc(1, sizeof(protocomm_ble_config_t));
if (!ble_config) {
ESP_LOGE(TAG, "Error allocating memory for new configuration");
return NULL;
}{...}
const uint8_t service_uuid[16] = {
/* ... */
0x07, 0xed, 0x9b, 0x2d, 0x0f, 0x06, 0x7c, 0x87,
0x9b, 0x43, 0x43, 0x6b, 0x4d, 0x24, 0x75, 0x17,
}{...};
memcpy(ble_config->service_uuid, service_uuid, sizeof(ble_config->service_uuid));
return ble_config;
}{ ... }
static void delete_config(void *config)
{
if (!config) {
ESP_LOGE(TAG, "Cannot delete null configuration");
return;
}{...}
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
for (unsigned int i = 0; i < ble_config->nu_lookup_count; i++) {
free((void *)ble_config->nu_lookup[i].name);
}{...}
free(ble_config->nu_lookup);
free(ble_config);
}{ ... }
static esp_err_t set_config_service(void *config, const char *service_name, const char *service_key)
{
if (!config) {
ESP_LOGE(TAG, "Cannot set null configuration");
return ESP_ERR_INVALID_ARG;
}{...}
if (!service_name) {
ESP_LOGE(TAG, "Service name cannot be NULL");
return ESP_ERR_INVALID_ARG;
}{...}
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
strlcpy(ble_config->device_name, service_name, sizeof(ble_config->device_name));
if (custom_service_uuid) {
memcpy(ble_config->service_uuid, custom_service_uuid, sizeof(ble_config->service_uuid));
}{...}
if (custom_manufacturer_data) {
size_t mfg_data_len = custom_manufacturer_data_len;
/* ... */
if (mfg_data_len > (MAX_BLE_MANUFACTURER_DATA_LEN - sizeof(ble_config->device_name) - 2)) {
ESP_LOGE(TAG, "Manufacturer data length is more than the max allowed size; expect truncated mfg_data ");
/* ... */
mfg_data_len = MAX_BLE_MANUFACTURER_DATA_LEN - sizeof(ble_config->device_name) - 2;
}{...}
ble_config->manufacturer_data = custom_manufacturer_data;
ble_config->manufacturer_data_len = mfg_data_len;
}{...} else {
ble_config->manufacturer_data = NULL;
ble_config->manufacturer_data_len = 0;
}{...}
if (custom_ble_addr){
ble_config->ble_addr = custom_ble_addr;
}{...} else {
ble_config->ble_addr = NULL;
}{...}
return ESP_OK;
}{ ... }
static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, uint16_t uuid)
{
if (!config) {
ESP_LOGE(TAG, "Cannot set null configuration");
return ESP_ERR_INVALID_ARG;
}{...}
if (!endpoint_name) {
ESP_LOGE(TAG, "EP name cannot be null");
return ESP_ERR_INVALID_ARG;
}{...}
protocomm_ble_config_t *ble_config = (protocomm_ble_config_t *) config;
char *copy_ep_name = strdup(endpoint_name);
if (!copy_ep_name) {
ESP_LOGE(TAG, "Error allocating memory for EP name");
return ESP_ERR_NO_MEM;
}{...}
protocomm_ble_name_uuid_t *lookup_table = (
realloc(ble_config->nu_lookup, (ble_config->nu_lookup_count + 1) * sizeof(protocomm_ble_name_uuid_t)));
if (!lookup_table) {
ESP_LOGE(TAG, "Error allocating memory for EP-UUID lookup table");
free(copy_ep_name);
return ESP_ERR_NO_MEM;
}{...}
lookup_table[ble_config->nu_lookup_count].name = copy_ep_name;
lookup_table[ble_config->nu_lookup_count].uuid = uuid;
ble_config->nu_lookup = lookup_table;
ble_config->nu_lookup_count += 1;
return ESP_OK;
}{ ... }
void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data)
{
switch (event) {
case WIFI_PROV_INIT: {
#ifdef CONFIG_BT_CONTROLLER_ENABLED
esp_err_t err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
if (err != ESP_OK) {
ESP_LOGE(TAG, "bt_mem_release of classic BT failed %d", err);
}{...} else {
ESP_LOGI(TAG, "BT memory released");
}{...}
/* ... */#endif
break;
}{...}
... case WIFI_PROV_DEINIT: {
#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
#ifdef CONFIG_BT_CONTROLLER_ENABLED
esp_err_t err = esp_bt_mem_release(ESP_BT_MODE_BTDM);
if (err != ESP_OK) {
ESP_LOGE(TAG, "bt_mem_release of BTDM failed %d", err);
}{...} else {
ESP_LOGI(TAG, "BTDM memory released");
}{...}
/* ... */#endif/* ... */
#endif
break;
}{...}
... default:
break;...
}{...}
}{ ... }
void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data)
{
switch (event) {
case WIFI_PROV_INIT: {
#ifdef CONFIG_BT_CONTROLLER_ENABLED
esp_err_t err;
err = esp_bt_mem_release(ESP_BT_MODE_CLASSIC_BT);
if (err != ESP_OK) {
ESP_LOGE(TAG, "bt_mem_release of classic BT failed %d", err);
}{...} else {
ESP_LOGI(TAG, "BT memory released");
}{...}
/* ... */#endif
break;
}{...}
... default:
break;...
}{...}
}{ ... }
void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data)
{
switch (event) {
case WIFI_PROV_DEINIT: {
#ifndef CONFIG_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV
#ifdef CONFIG_BT_CONTROLLER_ENABLED
esp_err_t err;
err = esp_bt_mem_release(ESP_BT_MODE_BLE);
if (err != ESP_OK) {
ESP_LOGE(TAG, "bt_mem_release of BLE failed %d", err);
}{...} else {
ESP_LOGI(TAG, "BLE memory released");
}{...}
/* ... */#endif/* ... */
#endif
break;
}{...}
... default:
break;...
}{...}
}{ ... }
const wifi_prov_scheme_t wifi_prov_scheme_ble = {
.prov_start = prov_start,
.prov_stop = protocomm_ble_stop,
.new_config = new_config,
.delete_config = delete_config,
.set_config_service = set_config_service,
.set_config_endpoint = set_config_endpoint,
.wifi_mode = WIFI_MODE_STA
}{...};