1 /*
2  * SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef _PROVISIONER_PROV_H_
8 #define _PROVISIONER_PROV_H_
9 
10 #include "mesh_main.h"
11 #include "mesh_bearer_adapt.h"
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 #ifndef CONFIG_BLE_MESH_PBA_SAME_TIME
18 #define CONFIG_BLE_MESH_PBA_SAME_TIME   0
19 #endif
20 
21 #ifndef CONFIG_BLE_MESH_PBG_SAME_TIME
22 #define CONFIG_BLE_MESH_PBG_SAME_TIME   0
23 #endif
24 
25 #define RM_AFTER_PROV  BIT(0)
26 #define START_PROV_NOW BIT(1)
27 #define FLUSHABLE_DEV  BIT(2)
28 
29 struct bt_mesh_unprov_dev_add {
30     uint8_t  addr[6];
31     uint8_t  addr_type;
32     uint8_t  uuid[16];
33     uint16_t oob_info;
34     uint8_t  bearer;
35 };
36 
37 struct bt_mesh_device_delete {
38     uint8_t addr[6];
39     uint8_t addr_type;
40     uint8_t uuid[16];
41 };
42 
43 #define NET_IDX_FLAG  BIT(0)
44 #define FLAGS_FLAG    BIT(1)
45 #define IV_INDEX_FLAG BIT(2)
46 
47 struct bt_mesh_prov_data_info {
48     union {
49         uint16_t net_idx;
50         uint8_t  flags;
51         uint32_t iv_index;
52     };
53     uint8_t flag;
54 };
55 
56 /* The following APIs are for primary provisioner internal use */
57 
58 /**
59  * @brief This function decrements the current PB-GATT count.
60  *
61  * @return None
62  */
63 void bt_mesh_provisioner_pbg_count_dec(void);
64 
65 /**
66  * @brief This function clears the part of the link info of the proper device.
67  *
68  * @param[in] addr: Remote device address
69  *
70  * @return None
71  */
72 void bt_mesh_provisioner_clear_link_info(const uint8_t addr[6]);
73 
74 /**
75  * @brief This function handles the received PB-ADV PDUs.
76  *
77  * @param[in] buf: Pointer to the buffer containing generic provisioning PDUs
78  *
79  * @return Zero - success, otherwise - fail
80  */
81 void bt_mesh_provisioner_pb_adv_recv(struct net_buf_simple *buf);
82 
83 /**
84  * @brief This function sends provisioning invite to start
85  *        provisioning this unprovisioned device.
86  *
87  * @param[in] addr: Remote device address
88  * @param[in] conn: Pointer to the bt_conn structure
89  *
90  * @return Zero - success, otherwise - fail
91  */
92 int bt_mesh_provisioner_set_prov_conn(const uint8_t addr[6], struct bt_mesh_conn *conn);
93 
94 /**
95  * @brief This function sends provisioning invite to start
96  *        provisioning this unprovisioned device.
97  *
98  * @param[in] conn: Pointer to the bt_conn structure
99  * @param[in] addr: Address of the connected device
100  *
101  * @return Zero - success, otherwise - fail
102  */
103 int bt_mesh_provisioner_pb_gatt_open(struct bt_mesh_conn *conn, uint8_t *addr);
104 
105 /**
106  * @brief This function resets the used information when
107  *        related connection is terminated.
108  *
109  * @param[in] conn:   Pointer to the bt_conn structure
110  * @param[in] reason: Connection terminated reason
111  *
112  * @return Zero - success, otherwise - fail
113  */
114 int bt_mesh_provisioner_pb_gatt_close(struct bt_mesh_conn *conn, uint8_t reason);
115 
116 /**
117  * @brief This function handles the received PB-GATT provision
118  *        PDUs.
119  *
120  * @param[in] conn: Pointer to the bt_conn structure
121  * @param[in] buf:  Pointer to the buffer containing provision PDUs
122  *
123  * @return Zero - success, otherwise - fail
124  */
125 int bt_mesh_provisioner_pb_gatt_recv(struct bt_mesh_conn *conn, struct net_buf_simple *buf);
126 
127 /**
128  * @brief This function initializes provisioner's PB-GATT and PB-ADV
129  *        related information.
130  *
131  * @param[in] prov_info: Pointer to the application-initialized provisioner info.
132  *
133  * @return Zero - success, otherwise - fail
134  */
135 int bt_mesh_provisioner_prov_init(const struct bt_mesh_prov *prov_info);
136 
137 int bt_mesh_provisioner_prov_reset(bool erase);
138 
139 /**
140  * @brief This function de-initializes provisioner's PB-GATT and PB-ADV
141  *        related information.
142  *
143  * @param[in] erase: Indicate if erasing provisioning information from flash.
144  *
145  * @return Zero - success, otherwise - fail
146  */
147 int bt_mesh_provisioner_prov_deinit(bool erase);
148 
149 /**
150  * @brief This function parses the received unprovisioned device
151  *        beacon advertising packets, and if checked, starts to provision this device
152  *        using PB-ADV bearer.
153  *
154  * @param[in] buf:  Pointer to the buffer containing unprovisioned device beacon
155  * @param[in] rssi: RSSI of the received unprovisioned device beacon
156  *
157  * @return None
158  */
159 void bt_mesh_provisioner_unprov_beacon_recv(struct net_buf_simple *buf, int8_t rssi);
160 
161 void bt_mesh_provisioner_prov_adv_recv(struct net_buf_simple *buf,
162                                        const bt_mesh_addr_t *addr, int8_t rssi);
163 
164 /**
165  * @brief This function gets the bt_mesh_prov pointer.
166  *
167  * @return bt_mesh_prov pointer(prov)
168  */
169 const struct bt_mesh_prov *bt_mesh_provisioner_get_prov_info(void);
170 
171 void bt_mesh_provisioner_restore_prov_info(uint16_t primary_addr, uint16_t alloc_addr);
172 
173 /* The following APIs are for primary provisioner application use */
174 
175 /** @brief Add unprovisioned device info to unprov_dev queue
176  *
177  *  @param[in] add_dev: Pointer to the structure containing the device information
178  *  @param[in] flags:   Flags indicate several operations of the device information
179  *                       - Remove device information from queue after it is provisioned (BIT0)
180  *                       - Start provisioning as soon as device is added to queue (BIT1)
181  *                       - Device can be flushed when device queue is full (BIT2)
182  *
183  *  @return Zero on success or (negative) error code otherwise.
184  *
185  *  @note  1. Currently address type only supports public address and static random address.
186  *         2. If device UUID and/or device address and address type already exist in the
187  *            device queue, but the bearer differs from the existing one, add operation
188  *            will also be successful and it will update the provision bearer supported by
189  *            the device.
190  */
191 int bt_mesh_provisioner_add_unprov_dev(struct bt_mesh_unprov_dev_add *add_dev, uint8_t flags);
192 
193 /** @brief Provision an unprovisioned device with fixed unicast address.
194  *
195  *  @param[in] uuid:         Device UUID of the unprovisioned device
196  *  @param[in] addr:         Device address of the unprovisioned device
197  *  @param[in] addr_type:    Device address type of the unprovisioned device
198  *  @param[in] bearer:       Provisioning bearer going to be used
199  *  @param[in] oob_info:     OOB info of the unprovisioned device
200  *  @param[in] unicast_addr: Unicast address going to be allocated for the unprovisioned device
201  *
202  *  @return Zero on success or (negative) error code otherwise.
203  *
204  *  @note  1. Currently address type only supports public address and static random address.
205  *         2. Bearer must be equal to BLE_MESH_PROV_ADV or BLE_MESH_PROV_GATT
206  */
207 int bt_mesh_provisioner_prov_device_with_addr(const uint8_t uuid[16], const uint8_t addr[6],
208                                               uint8_t addr_type, bt_mesh_prov_bearer_t bearer,
209                                               uint16_t oob_info, uint16_t unicast_addr);
210 
211 /** @brief Delete device from queue, reset current provisioning link and reset the node
212  *
213  *  @param[in] del_dev: Pointer to the structure containing the device information
214  *
215  *  @return Zero on success or (negative) error code otherwise.
216  */
217 int bt_mesh_provisioner_delete_device(struct bt_mesh_device_delete *del_dev);
218 
219 /**
220  * @brief This function sets a part of the device UUID for comparison before
221  *        starting to provision the device.
222  *
223  * @param[in] offset: offset of the device UUID to be compared
224  * @param[in] length: length of the device UUID to be compared
225  * @param[in] match:  value to be compared
226  * @param[in] prov_flag: flags indicate if uuid_match advertising packets are received, after that
227  *                       the device will be provisioned at once or reported to the application layer
228  *
229  * @return Zero - success, otherwise - fail
230  */
231 int bt_mesh_provisioner_set_dev_uuid_match(uint8_t offset, uint8_t length,
232                                            const uint8_t *match, bool prov_flag);
233 
234 /** @brief Callback for provisioner receiving advertising packet from unprovisioned devices which are
235  *  not in the unprovisioned device queue.
236  *
237  *  Report on the unprovisioned device beacon and mesh provisioning service advertising data to application layer
238  *
239  *  @param addr      Unprovisioned device address pointer
240  *  @param addr_type Unprovisioned device address type
241  *  @param dev_uuid  Unprovisioned device device UUID pointer
242  *  @param bearer    Advertising packet received from PB-GATT or PB-ADV bearer
243  *  @param adv_type  Adv packet type, currently this is not used and we can use bearer to device
244  *                   the adv_type(ADV_IND or ADV_NONCONN_IND). This parameter will be used, when
245  *                   scan response data will be supported.
246  *  @param rssi      RSSI of the received advertising packet
247  *
248  */
249 typedef void (*unprov_adv_pkt_cb_t)(const uint8_t addr[6], const uint8_t addr_type,
250                                     const uint8_t adv_type, const uint8_t dev_uuid[16],
251                                     uint16_t oob_info, bt_mesh_prov_bearer_t bearer, int8_t rssi);
252 
253 /**
254  * @brief This function registers the callback which notifies the application
255  *        layer of the received mesh provisioning or unprovisioned device
256  *        beacon advertizing packets (from devices not in the unprov device queue).
257  *
258  * @param[in] cb: Callback of the notifying adv pkts function
259  *
260  * @return Zero - success, otherwise - fail
261  */
262 int bt_mesh_provisioner_adv_pkt_cb_register(unprov_adv_pkt_cb_t cb);
263 
264 /**
265  * @brief This function changes net_idx or flags or iv_index used in provisioning data.
266  *
267  * @param[in] info: Pointer of structure containing net_idx or flags or iv_index
268  *
269  * @return Zero - success, otherwise - fail
270  */
271 int bt_mesh_provisioner_set_prov_data_info(struct bt_mesh_prov_data_info *info);
272 
273 /**
274  * @brief This function initializes the provisioning information needed by Provisioner,
275  *        including NetKey Index, flags, IV Index, etc.
276  *
277  * @return Zero - success, otherwise - fail
278  */
279 int bt_mesh_provisioner_init_prov_info(void);
280 
281 /**
282  * @brief This function sets the provisioning bearer type used by Provisioner.
283  *
284  * @param[in] bearers: Provisioning bearer type
285  * @param[in] clear:   Indicate if the corresponding bearer type will be cleared
286  *
287  * @return None
288  */
289 void bt_mesh_provisioner_set_prov_bearer(bt_mesh_prov_bearer_t bearers, bool clear);
290 
291 /**
292  * @brief This function gets the provisioning bearer type used by Provisioner.
293  *
294  * @return Currently supported provisioning bearer type
295  */
296 bt_mesh_prov_bearer_t bt_mesh_provisioner_get_prov_bearer(void);
297 
298 /**
299  * @brief This function sets the Static OOB value used by Provisioner.
300  *
301  * @param[in] value:  Static OOB value
302  * @param[in] length: Static OOB value length
303  *
304  * @return Zero - success, otherwise - fail
305  */
306 int bt_mesh_provisioner_set_static_oob_value(const uint8_t *value, uint8_t length);
307 
308 /**
309  * @brief This function gets the unicast address of primary element of Provisioner.
310  *
311  * @return Unicast address of primary element of Provisioner.
312  */
313 uint16_t bt_mesh_provisioner_get_primary_elem_addr(void);
314 
315 /**
316  * @brief This function sets the unicast address of primary element of Provisioner.
317  *
318  * @param[in] addr: unicast address of primary element
319  *
320  * @return Zero - success, otherwise - fail
321  */
322 int bt_mesh_provisioner_set_primary_elem_addr(uint16_t addr);
323 
324 /**
325  * @brief This function is used to update next allocated address by Provisioner.
326  *
327  * @note  This function is used for mesh internal test.
328  *
329  * @param[in] unicast_addr: unicast address of the node
330  * @param[in] element_num:  element count of the node
331  *
332  * @return Zero - success, otherwise - fail
333  */
334 int bt_mesh_test_provisioner_update_alloc_addr(uint16_t unicast_addr, uint16_t element_num);
335 
336 /**
337  * @brief This function is called to input number/string out-put by unprovisioned device.
338  *
339  * @param[in] idx       The provisioning link index
340  * @param[in] val       Pointer of the input number/string
341  * @param[in] num_flag  Flag indicates if it is a number or string
342  *
343  * @return Zero - success, otherwise - fail
344  */
345 int bt_mesh_provisioner_set_oob_input_data(const uint8_t idx, const uint8_t *val, bool num_flag);
346 
347 /**
348  * @brief This function is called to output number/string which will be input by unprovisioned device.
349  *
350  * @param[in] idx       The provisioning link index
351  * @param[in] num       Pointer of the output number/string
352  * @param[in] size      Size of the output number/string
353  * @param[in] num_flag  Flag indicates if it is a number or string
354  *
355  * @return Zero - success, otherwise - fail
356  */
357 int bt_mesh_provisioner_set_oob_output_data(const uint8_t idx, const uint8_t *num,
358                                             uint8_t size, bool num_flag);
359 
360 /**
361  * @brief This function is called to read unprovisioned device's oob public key.
362  *
363  * @param[in] idx        The provisioning link index
364  * @param[in] pub_key_x  Unprovisioned device's Public Key X
365  * @param[in] pub_key_y  Unprovisioned device's Public Key Y
366  *
367  * @return Zero - success, otherwise - fail
368  */
369 int bt_mesh_provisioner_read_oob_pub_key(const uint8_t idx, const uint8_t pub_key_x[32],
370                                          const uint8_t pub_key_y[32]);
371 
372 /* The following APIs are for fast provisioning */
373 
374 /**
375  * @brief This function is called to set fast_prov_flag.
376  *
377  * @param[in] enable: Enable or disable fast provisioning
378  *
379  * @return None
380  */
381 void bt_mesh_provisioner_fast_prov_enable(bool enable);
382 
383 /**
384  * @brief This function is called to set netkey index used for fast provisioning.
385  *
386  * @param[in] net_idx: Netkey index
387  *
388  * @return None
389  */
390 void bt_mesh_provisioner_set_fast_prov_net_idx(uint16_t net_idx);
391 
392 /**
393  * @brief This function is called to get netkey index used for fast provisioning.
394  *
395  * @return net_idx of fast provisioning
396  */
397 uint16_t bt_mesh_provisioner_get_fast_prov_net_idx(void);
398 
399 /**
400  * @brief This function is called to set unicast address range used for fast provisioning.
401  *
402  * @param[in] min: Minimum unicast address
403  * @param[in] max: Maximum unicast address
404  *
405  * @return status for set unicast address range message
406  */
407 uint8_t bt_mesh_set_fast_prov_unicast_addr_range(uint16_t min, uint16_t max);
408 
409 /**
410  * @brief This function is called to set flags & iv_index used for fast provisioning.
411  *
412  * @param[in] flags:    Key refresh flag and iv update flag
413  * @param[in] iv_index: IV index
414  *
415  * @return None
416  */
417 void bt_mesh_set_fast_prov_flags_iv_index(uint8_t flags, uint32_t iv_index);
418 
419 #ifdef __cplusplus
420 }
421 #endif
422 
423 #endif /* _PROVISIONER_PROV_H_ */
424