]> granicus.if.org Git - esp-idf/blob
4c95d45b28ee2f9745150a39f08bc71d7fe8146c
[esp-idf] /
1 // Copyright 2017-2019 Espressif Systems (Shanghai) PTE LTD
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "esp_bt_defs.h"
16
17 #include "provisioner_prov.h"
18 #include "esp_ble_mesh_defs.h"
19 #include "esp_ble_mesh_networking_api.h"
20 #include "esp_ble_mesh_provisioning_api.h"
21 #include "esp_ble_mesh_config_model_api.h"
22
23 #include "ble_mesh_adapter.h"
24 #include "ble_mesh_console_decl.h"
25
26 #if CONFIG_BLE_MESH_PROVISIONER
27
28 typedef struct {
29     struct arg_int *bearer;
30     struct arg_int *enable;
31     struct arg_end *end;
32 } ble_mesh_provisioner_bearer_t;
33 ble_mesh_provisioner_bearer_t provisioner_bearer;
34
35 typedef struct {
36     struct arg_str *add_del;
37     struct arg_str *device_addr;
38     struct arg_str *device_uuid;
39     struct arg_int *addr_type;
40     struct arg_int *bearer;
41     struct arg_int *oob_info;
42     struct arg_int *flag;
43     struct arg_end *end;
44 } ble_mesh_provisioner_addr_t;
45 ble_mesh_provisioner_addr_t provisioner_addr;
46
47 typedef struct {
48     struct arg_int *unicast_addr;
49     struct arg_end *end;
50 } ble_mesh_provisioner_get_node_t;
51 ble_mesh_provisioner_get_node_t provisioner_get_node;
52
53 typedef struct {
54     struct arg_int *oob_info;
55     struct arg_int *unicast_addr;
56     struct arg_int *element_num;
57     struct arg_int *net_idx;
58     struct arg_str *dev_key;
59     struct arg_str *uuid;
60     struct arg_end *end;
61 } ble_mesh_provisioner_add_node_t;
62 ble_mesh_provisioner_add_node_t provisioner_add_node;
63
64 typedef struct {
65     struct arg_int *appkey_index;
66     struct arg_int *element_address;
67     struct arg_int *network_index;
68     struct arg_int *mod_id;
69     struct arg_int *cid;
70     struct arg_end *end;
71 } ble_mesh_provisioner_bind_model_t;
72 ble_mesh_provisioner_bind_model_t provisioner_local_bind;
73
74 typedef struct {
75     struct arg_str *action_type;
76     struct arg_int *net_idx;
77     struct arg_int *app_idx;
78     struct arg_str *key;
79     struct arg_end *end;
80 } ble_mesh_provisioner_add_key_t;
81 ble_mesh_provisioner_add_key_t provisioner_add_key;
82
83 void ble_mesh_regist_provisioner_cmd(void);
84
85 void ble_mesh_prov_adv_cb(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type, const uint8_t adv_type,
86                           const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer);
87
88 void ble_mesh_register_mesh_provisioner(void)
89 {
90     ble_mesh_regist_provisioner_cmd();
91 }
92
93 void ble_mesh_prov_adv_cb(const esp_bd_addr_t addr, const esp_ble_addr_type_t addr_type, const uint8_t adv_type,
94                           const uint8_t *dev_uuid, uint16_t oob_info, esp_ble_mesh_prov_bearer_t bearer)
95 {
96     ESP_LOGD(TAG, "enter %s\n", __func__);
97     ESP_LOGI(TAG, "scan device address:");
98     esp_log_buffer_hex(TAG, addr, sizeof(esp_bd_addr_t));
99     ESP_LOGI(TAG, "scan device uuid:");
100     esp_log_buffer_hex(TAG, dev_uuid, 16);
101     ESP_LOGD(TAG, "exit %s\n", __func__);
102 }
103
104 int ble_mesh_provisioner_register(void)
105 {
106     ESP_LOGD(TAG, "enter %s \n", __func__);
107     // esp_ble_mesh_register_unprov_adv_pkt_callback(ble_mesh_prov_adv_cb);
108     ESP_LOGI(TAG, "Provisioner:Reg,OK");
109     ESP_LOGD(TAG, "exit %s \n", __func__);
110     return 0;
111 }
112
113 int ble_mesh_provision_address(int argc, char **argv)
114 {
115     esp_err_t err = ESP_OK;
116     esp_ble_mesh_unprov_dev_add_t device_addr = {0};
117     uint8_t  preset_addr_uuid[16] = {0x01, 0x02};
118     esp_ble_mesh_device_delete_t del_dev = {
119         .flag = BIT(0),
120     };
121
122     ESP_LOGD(TAG, "enter %s \n", __func__);
123
124     int nerrors = arg_parse(argc, argv, (void **) &provisioner_addr);
125     if (nerrors != 0) {
126         arg_print_errors(stderr, provisioner_addr.end, argv[0]);
127         return 1;
128     }
129     
130     if (provisioner_addr.device_addr->count != 0) {
131         if (provisioner_addr.device_uuid->count != 0) {
132             del_dev.flag = BIT(0) | BIT(1);
133             str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.uuid);
134             str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.uuid); 
135         } else {
136             del_dev.flag = BIT(0);
137             memcpy(device_addr.uuid, preset_addr_uuid, 16);
138             memcpy(del_dev.uuid, preset_addr_uuid, 16);
139         }
140         str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.addr);
141         str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.addr);
142         arg_int_to_value(provisioner_addr.addr_type, device_addr.addr_type, "address type");
143         arg_int_to_value(provisioner_addr.addr_type, del_dev.addr_type, "address type");
144     } else if (provisioner_addr.device_uuid->count != 0) {
145         del_dev.flag = BIT(1);
146         memcpy(device_addr.addr, preset_addr_uuid, 6);
147         memcpy(del_dev.addr, preset_addr_uuid, 6);
148         str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], device_addr.uuid);
149         str_2_mac((uint8_t *)provisioner_addr.device_addr->sval[0], del_dev.uuid); 
150     }
151
152     if (strcmp(provisioner_addr.add_del->sval[0], "add") == 0) {
153         arg_int_to_value(provisioner_addr.bearer, device_addr.bearer, "bearer");
154         arg_int_to_value(provisioner_addr.oob_info, device_addr.oob_info, "oob information");
155         err = esp_ble_mesh_provisioner_add_unprov_dev(&device_addr, provisioner_addr.flag->ival[0]);
156     } else if (strcmp(provisioner_addr.add_del->sval[0], "del") == 0) {
157         err = esp_ble_mesh_provisioner_delete_dev(&del_dev);
158     }
159
160     ESP_LOGD(TAG, "exit %s \n", __func__);
161     return err;
162 }
163
164 int ble_mesh_provisioner_bearer(int argc, char **argv)
165 {
166     esp_err_t err;
167
168     ESP_LOGD(TAG, "enter %s \n", __func__);
169
170     int nerrors = arg_parse(argc, argv, (void **) &provisioner_bearer);
171     if (nerrors != 0) {
172         arg_print_errors(stderr, provisioner_bearer.end, argv[0]);
173         return 1;
174     }
175
176     if (provisioner_bearer.enable->count != 0) {
177         if (provisioner_bearer.enable->ival[0]) {
178             err = esp_ble_mesh_provisioner_prov_enable(provisioner_bearer.bearer->ival[0]);
179         } else {
180             err = esp_ble_mesh_provisioner_prov_disable(provisioner_bearer.bearer->ival[0]);
181         }
182     } else {
183         return 1;
184     }
185
186     ESP_LOGD(TAG, "exit %s \n", __func__);
187     return err;
188 }
189
190 int ble_mesh_provisioner_get_node(int argc, char **argv)
191 {
192     uint16_t unicast_addr = 0;
193     uint16_t i = 0;
194     struct bt_mesh_node_t *node_info;
195
196     ESP_LOGD(TAG, "enter %s\n", __func__);
197     int nerrors = arg_parse(argc, argv, (void **) &provisioner_get_node);
198     if (nerrors != 0) {
199         arg_print_errors(stderr, provisioner_get_node.end, argv[0]);
200         return 1;
201     }
202
203     arg_int_to_value(provisioner_get_node.unicast_addr, unicast_addr, "unicast address");
204     node_info = bt_mesh_provisioner_get_node_info(unicast_addr);
205
206     if (node_info == NULL) {
207         return ESP_FAIL;
208     } else {
209         printf("OobInfo:0x%x,Address:0x%x,EleNum:0x%x,NetIdx:0x%x,DevKey:",
210                node_info->oob_info, node_info->unicast_addr, node_info->element_num, node_info->net_idx);
211         for (i = 0; i < 16; i++) {
212             printf("%02x", node_info->dev_key[i]);
213         }
214         printf(",DevUuid:");
215         for (i = 0; i < 16; i++) {
216             printf("%02x", node_info->dev_uuid[i]);
217         }
218         printf("\n");
219     }
220
221     ESP_LOGD(TAG, "exit %s\n", __func__);
222     return ESP_OK;
223 }
224
225 int ble_mesh_provisioner_add_node(int argc, char **argv)
226 {
227     struct bt_mesh_node_t node_info;
228     esp_err_t result;
229     ESP_LOGD(TAG, " enter %s\n", __func__);
230
231     int nerrors = arg_parse(argc, argv, (void **) &provisioner_add_node);
232     if (nerrors != 0) {
233         arg_print_errors(stderr, provisioner_add_node.end, argv[0]);
234         return 1;
235     }
236
237     arg_int_to_value(provisioner_add_node.oob_info, node_info.oob_info, "oob information");
238     arg_int_to_value(provisioner_add_node.unicast_addr, node_info.unicast_addr, "unicast address");
239     arg_int_to_value(provisioner_add_node.element_num, node_info.element_num, "element number");
240     arg_int_to_value(provisioner_add_node.net_idx, node_info.net_idx, "network index");
241     if (provisioner_add_node.dev_key->count != 0) {
242         get_value_string((char *)provisioner_add_node.dev_key->sval[0], (char *)node_info.dev_key);
243     }
244     if (provisioner_add_node.uuid->count != 0) {
245         get_value_string((char *)provisioner_add_node.uuid->sval[0], (char *)node_info.dev_uuid); 
246         get_value_string((char *)provisioner_add_node.uuid->sval[0], (char *)node_info.dev_uuid);
247     }
248
249     result = bt_mesh_provisioner_store_node_info(&node_info);
250     if (result == ESP_OK) {
251         ESP_LOGI(TAG, "Provisioner:AddNodeInfo,OK\n");
252     }
253
254     ESP_LOGD(TAG, "exit %s\n", __func__);
255     return result;
256 }
257
258 int ble_mesh_provisioner_add_key(int argc, char **argv)
259 {
260     esp_err_t err = ESP_OK;
261     uint8_t key[16] = {0};
262     esp_ble_mesh_prov_data_info_t info = {
263         .net_idx = 1,
264         .flag = NET_IDX_FLAG,
265     };
266     ESP_LOGD(TAG, " enter %s\n", __func__);
267
268     int nerrors = arg_parse(argc, argv, (void **) &provisioner_add_key);
269     if (nerrors != 0) {
270         arg_print_errors(stderr, provisioner_add_key.end, argv[0]);
271         return 1;
272     }
273
274     err = get_value_string((char *)provisioner_add_key.key->sval[0], (char *) key);
275     if (strcmp(provisioner_add_key.action_type->sval[0], "appkey") == 0) {
276         err = esp_ble_mesh_provisioner_add_local_app_key(key, provisioner_add_key.net_idx->ival[0], provisioner_add_key.app_idx->ival[0]);
277     } else if (strcmp(provisioner_add_key.action_type->sval[0], "netkey") == 0) {
278         // choose network key
279         info.net_idx = provisioner_add_key.net_idx->ival[0];
280         err = esp_ble_mesh_provisioner_add_local_net_key(key, provisioner_add_key.net_idx->ival[0]);
281         err = err | esp_ble_mesh_provisioner_set_prov_data_info(&info);
282     }
283
284     if (err != ESP_OK) {
285         ESP_LOGI(TAG, "Provisioner:KeyAction,Fail");
286     } else {
287         ESP_LOGI(TAG, "Provisioner:KeyAction,OK");
288     }
289
290     ESP_LOGD(TAG, "exit %s\n", __func__);
291     return err;
292 }
293
294 int ble_mesh_provision_bind_local_model(int argc, char **argv)
295 {
296     esp_err_t err;
297     uint16_t element_addr = 0;
298     uint16_t app_idx = 0;
299     uint16_t model_id = 0;
300     uint16_t company_id = 0xFFFF;
301
302     ESP_LOGD(TAG, " enter %s\n", __func__);
303
304     int nerrors = arg_parse(argc, argv, (void **) &provisioner_local_bind);
305     if (nerrors != 0) {
306         arg_print_errors(stderr, provisioner_local_bind.end, argv[0]);
307         return 1;
308     }
309
310     arg_int_to_value(provisioner_local_bind.element_address, element_addr, "element address");
311     arg_int_to_value(provisioner_local_bind.appkey_index, app_idx, "appkey index");
312     arg_int_to_value(provisioner_local_bind.mod_id, model_id, "model id");
313     arg_int_to_value(provisioner_local_bind.cid, company_id, "company id");
314     err = esp_ble_mesh_provisioner_bind_app_key_to_local_model(element_addr, app_idx, model_id, company_id);
315
316     if (err != ESP_OK) {
317         ESP_LOGE(TAG, "Provisioner:BindModel,Fail,%x\n", err);
318     } else {
319         ESP_LOGI(TAG, "Provisioner:BindModel,OK\n");
320     }
321     ESP_LOGD(TAG, "exit %s\n", __func__);
322     return err;
323 }
324
325 void ble_mesh_regist_provisioner_cmd(void)
326 {
327     const esp_console_cmd_t prov_register = {
328         .command = "bmpreg",
329         .help = "ble mesh provisioner: register callback",
330         .hint = NULL,
331         .func = &ble_mesh_provisioner_register,
332     };
333     ESP_ERROR_CHECK(esp_console_cmd_register(&prov_register));
334
335     provisioner_addr.add_del = arg_str1("z", NULL, "<add/delete>", "action type");
336     provisioner_addr.device_addr = arg_str0("d", NULL, "<address>", "device address");
337     provisioner_addr.device_uuid = arg_str0("u", NULL, "<uuid>", "device uuid");
338     provisioner_addr.addr_type = arg_int0("a", NULL, "<type>", "address type");
339     provisioner_addr.flag = arg_int0("f", NULL, "<flag>", "address flag");
340     provisioner_addr.flag->ival[0] = ADD_DEV_RM_AFTER_PROV_FLAG | ADD_DEV_FLUSHABLE_DEV_FLAG;
341     provisioner_addr.bearer = arg_int0("b", NULL, "<bearer>", "used bearer");
342     provisioner_addr.oob_info = arg_int0("o", NULL, "<oob info>", "oob information");
343     provisioner_addr.end = arg_end(1);
344
345     const esp_console_cmd_t provisioner_addr_cmd = {
346         .command = "bmpdev",
347         .help = "ble mesh provisioner: add/delete unprovisioned device",
348         .hint = NULL,
349         .func = &ble_mesh_provision_address,
350         .argtable = &provisioner_addr,
351     };
352     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_addr_cmd));
353
354     provisioner_bearer.bearer = arg_int0("b", NULL, "<bearer>", "bearer supported provisioner");
355     provisioner_bearer.enable = arg_int0("e", NULL, "<enable/disable>", "enable or disable bearer");
356     provisioner_bearer.end = arg_end(1);
357
358     const esp_console_cmd_t provisioner_bearer_cmd = {
359         .command = "bmpbearer",
360         .help = "ble mesh provisioner: enable/disable provisioner different bearer",
361         .hint = NULL,
362         .func = &ble_mesh_provisioner_bearer,
363         .argtable = &provisioner_bearer,
364     };
365     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_bearer_cmd));
366
367     provisioner_get_node.unicast_addr = arg_int1("u", NULL, "<address>", "get node by unicast address");
368     provisioner_get_node.end = arg_end(1);
369
370     const esp_console_cmd_t provisioner_get_node_cmd = {
371         .command = "bmpgetn",
372         .help = "ble mesh provisioner: get node",
373         .func = &ble_mesh_provisioner_get_node,
374         .argtable = &provisioner_get_node,
375     };
376     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_get_node_cmd));
377
378     provisioner_add_node.oob_info = arg_int0("o", NULL, "<oob info>", "oob information");
379     provisioner_add_node.unicast_addr = arg_int0("a", NULL, "<unicast address>", "unicast address");
380     provisioner_add_node.element_num = arg_int0("e", NULL, "<element num>", "element num");
381     provisioner_add_node.net_idx = arg_int0("n", NULL, "<net index>", "net index");
382     provisioner_add_node.dev_key = arg_str0("d", NULL, "<device key>", "device key");
383     provisioner_add_node.uuid = arg_str0("u", NULL, "<device uuid>", "device uuid");
384     provisioner_add_node.end = arg_end(1);
385
386     const esp_console_cmd_t provisioner_add_node_cmd = {
387         .command = "bmpaddn",
388         .help = "ble mesh provisioner: add node",
389         .func = &ble_mesh_provisioner_add_node,
390         .argtable = &provisioner_add_node,
391     };
392     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_add_node_cmd));
393
394     provisioner_local_bind.appkey_index = arg_int1("a", NULL, "<appkey index>", "appkey index");
395     provisioner_local_bind.element_address = arg_int1("e", NULL, "<element address>", "element address");
396     provisioner_local_bind.network_index = arg_int1("n", NULL, "<network index>", "network index");
397     provisioner_local_bind.mod_id = arg_int1("m", NULL, "<model id>", "model id");
398     provisioner_local_bind.cid = arg_int0("c", NULL, "<model id>", "company id");
399     provisioner_local_bind.end = arg_end(1);
400
401     const esp_console_cmd_t provisioner_local_bind_cmd = {
402         .command = "bmpbind",
403         .help = "ble mesh provisioner: bind local model",
404         .func = &ble_mesh_provision_bind_local_model,
405         .argtable = &provisioner_local_bind,
406     };
407     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_local_bind_cmd));
408
409     provisioner_add_key.action_type = arg_str1("z", NULL, "<action type>", "add appkey or network key");
410     provisioner_add_key.net_idx = arg_int1("n", NULL, "<net key index>", "network key index");
411     provisioner_add_key.key = arg_str1("k", NULL, "<key>", "appkey or network");
412     provisioner_add_key.app_idx = arg_int0("a", NULL, "<app key index>", "appkey index");
413     provisioner_add_key.end = arg_end(1);
414
415     const esp_console_cmd_t provisioner_add_key_cmd = {
416         .command = "bmpkey",
417         .help = "ble mesh provisioner: key",
418         .func = &ble_mesh_provisioner_add_key,
419         .argtable = &provisioner_add_key,
420     };
421     ESP_ERROR_CHECK(esp_console_cmd_register(&provisioner_add_key_cmd));
422 }
423 #endif
424