xref: /btstack/src/mesh/mesh_node.h (revision 1b464e99afd70ddaf6b75be1ba7cc563a5f5dfd8)
1 /*
2  * Copyright (C) 2019 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #ifndef __MESH_NODE_H
39 #define __MESH_NODE_H
40 
41 #include <stdint.h>
42 
43 #include "btstack_linked_list.h"
44 #include "mesh/mesh_network.h"
45 
46 #if defined __cplusplus
47 extern "C" {
48 #endif
49 
50 #define MESH_APPKEY_INVALID                     0xffffu
51 
52 #define MAX_NR_MESH_APPKEYS_PER_MODEL           3u
53 #define MAX_NR_MESH_SUBSCRIPTION_PER_MODEL      3u
54 
55 #define MESH_HEARTBEAT_PUBLICATION_FEATURE_RELAY      1
56 #define MESH_HEARTBEAT_PUBLICATION_FEATURE_PROXY      2
57 #define MESH_HEARTBEAT_PUBLICATION_FEATURE_FRIEND     4
58 #define MESH_HEARTBEAT_PUBLICATION_FEATURE_LOW_POWER  8
59 
60 struct mesh_model;
61 struct mesh_element;
62 
63 // function to handle model operation message
64 typedef void (*mesh_operation_handler)(struct mesh_model * mesh_model, mesh_pdu_t * pdu);
65 
66 // function to publish the current state of a model
67 // @param mesh_model to publish
68 // @returns mesh_pdu with status message
69 typedef mesh_pdu_t * (*mesh_publish_state_t)(struct mesh_model * mesh_model);
70 
71 typedef enum {
72     MESH_NODE_IDENTITY_STATE_ADVERTISING_STOPPED = 0,
73     MESH_NODE_IDENTITY_STATE_ADVERTISING_RUNNING,
74     MESH_NODE_IDENTITY_STATE_ADVERTISING_NOT_SUPPORTED
75 } mesh_node_identity_state_t;
76 
77 typedef enum {
78     MESH_FRIEND_STATE_DISABLED = 0,
79     MESH_FRIEND_STATE_ENABLED,
80     MESH_FRIEND_STATE_NOT_SUPPORTED
81 } mesh_friend_state_t;
82 
83 typedef enum {
84     MESH_MODEL_PUBLICATION_STATE_IDLE,
85     MESH_MODEL_PUBLICATION_STATE_W4_PUBLICATION_MS,
86     MESH_MODEL_PUBLICATION_STATE_PUBLICATION_READY,
87     MESH_MODEL_PUBLICATION_STATE_W4_RETRANSMIT_MS,
88     MESH_MODEL_PUBLICATION_STATE_RETRANSMIT_READY,
89 } mesh_model_publication_state_t;
90 
91 typedef struct {
92     mesh_publish_state_t publish_state_fn;
93     mesh_model_publication_state_t state;
94     uint32_t next_publication_ms;
95     uint32_t next_retransmit_ms;
96     uint8_t  retransmit_count;
97 
98     uint16_t address;
99     uint16_t appkey_index;
100     uint8_t  friendship_credential_flag;
101     uint8_t  period;
102     uint8_t  period_divisor;  // divide period by 2 ^ period_divisor, default = 2^0 = 1, added for Health Server
103     uint8_t  ttl;
104     uint8_t  retransmit;
105 } mesh_publication_model_t;
106 
107 typedef struct {
108     uint16_t destination;
109     uint16_t count;      // Number of Heartbeat messages to be sent
110     uint16_t period_s;   // Period for sending Heartbeat messages in seconds
111     uint16_t features;   // Bit field indicating features that trigger Heartbeat messages when changed
112     uint16_t netkey_index;
113     uint8_t  ttl;        // TTL to be used when sending Heartbeat messages
114 } mesh_heartbeat_publication_state_t;
115 
116 typedef struct {
117     uint32_t opcode;
118     uint16_t minimum_length;
119     mesh_operation_handler handler;
120 } mesh_operation_t;
121 
122 typedef struct mesh_model {
123     // linked list item
124     btstack_linked_item_t item;
125 
126     // element
127     struct mesh_element * element;
128 
129     // internal model enumeration
130     uint16_t mid;
131 
132     // vendor_id << 16 | model id, use BLUETOOTH_COMPANY_ID_BLUETOOTH_SIG_INC for SIG models
133     uint32_t model_identifier;
134 
135     // model operations
136     const mesh_operation_t * operations;
137 
138     // publication model if supported
139     mesh_publication_model_t * publication_model;
140 
141     // data
142     void * model_data;
143 
144     // bound appkeys
145     uint16_t appkey_indices[MAX_NR_MESH_APPKEYS_PER_MODEL];
146 
147     // subscription list
148     uint16_t subscriptions[MAX_NR_MESH_SUBSCRIPTION_PER_MODEL];
149 
150     // packet handler for transition events in server, event callback handler in client
151     btstack_packet_handler_t model_packet_handler;
152 } mesh_model_t;
153 
154 typedef struct {
155     btstack_linked_list_iterator_t it;
156 } mesh_model_iterator_t;
157 
158 typedef struct mesh_element {
159     // linked list item
160     btstack_linked_item_t item;
161 
162     // element index
163     uint16_t element_index;
164 
165     // LOC
166     uint16_t loc;
167 
168     // models
169     btstack_linked_list_t models;
170     uint16_t models_count_sig;
171     uint16_t models_count_vendor;
172 
173 } mesh_element_t;
174 
175 typedef struct {
176     btstack_linked_list_iterator_t it;
177 } mesh_element_iterator_t;
178 
179 
180 void mesh_node_init(void);
181 
182 /**
183  * @brief Set unicast address of primary element
184  * @param unicast_address
185  */
186 void mesh_node_primary_element_address_set(uint16_t unicast_address);
187 
188 /**
189  * @brief Set location of primary element
190  * @note Returned by Configuration Server Composite Data
191  * @param location
192  */
193 void mesh_node_set_primary_element_location(uint16_t location);
194 
195 /**
196  * @brief Set location of element
197  * @param element
198  * @param location
199  */
200 void mesh_node_set_element_location(mesh_element_t * element, uint16_t location);
201 
202 /**
203  * @brief Get unicast address of primary element
204  */
205 uint16_t mesh_node_get_primary_element_address(void);
206 
207 /**
208  * @brief Get Primary Element of this node
209  */
210 mesh_element_t * mesh_node_get_primary_element(void);
211 
212 /**
213  * @brief Add secondary element
214  * @param element
215  */
216 void mesh_node_add_element(mesh_element_t * element);
217 
218 /**
219  * @brief Get number elements
220  * @returns number of elements on this node
221  */
222 uint16_t mesh_node_element_count(void);
223 
224 /**
225  * @brief Get element for given unicast address
226  * @param unicast_address
227  */
228 mesh_element_t * mesh_node_element_for_unicast_address(uint16_t unicast_address);
229 
230 /**
231  * @brief Get element by index
232  * @param element_index
233  */
234 mesh_element_t * mesh_node_element_for_index(uint16_t element_index);
235 
236 /**
237  * @brief Get element index for give model
238  * @param mesh_model
239  */
240 uint8_t mesh_access_get_element_index(mesh_model_t * mesh_model);
241 
242 /**
243  * @brief Get unicast address for give model
244  * @param mesh_model
245  */
246 uint16_t mesh_access_get_element_address(mesh_model_t * mesh_model);
247 
248 /**
249  * @brief Add model to element
250  * @param element
251  * @param mesh_model
252  */
253 void mesh_element_add_model(mesh_element_t * element, mesh_model_t * mesh_model);
254 
255 // Mesh Element Iterator
256 void mesh_element_iterator_init(mesh_element_iterator_t * iterator);
257 
258 int mesh_element_iterator_has_next(mesh_element_iterator_t * iterator);
259 
260 mesh_element_t * mesh_element_iterator_next(mesh_element_iterator_t * iterator);
261 
262 // Mesh Model Iterator
263 
264 void mesh_model_iterator_init(mesh_model_iterator_t * iterator, mesh_element_t * element);
265 
266 int mesh_model_iterator_has_next(mesh_model_iterator_t * iterator);
267 
268 mesh_model_t * mesh_model_iterator_next(mesh_model_iterator_t * iterator);
269 
270 // Mesh Model Utility
271 
272 mesh_model_t * mesh_model_get_by_identifier(mesh_element_t * element, uint32_t model_identifier);
273 
274 uint32_t mesh_model_get_model_identifier_bluetooth_sig(uint16_t model_id);
275 
276 int mesh_model_is_bluetooth_sig(uint32_t model_identifier);
277 
278 uint16_t mesh_model_get_model_id(uint32_t model_identifier);
279 
280 uint32_t mesh_model_get_model_identifier(uint16_t vendor_id, uint16_t model_id);
281 
282 uint16_t mesh_model_get_vendor_id(uint32_t model_identifier);
283 
284 mesh_model_t * mesh_node_get_configuration_server(void);
285 
286 mesh_model_t * mesh_node_get_health_server(void);
287 
288 mesh_model_t * mesh_access_model_for_address_and_model_identifier(uint16_t element_address, uint32_t model_identifier, uint8_t * status);
289 
290 void mesh_model_reset_appkeys(mesh_model_t * mesh_model);
291 
292 // Mesh Model Subscriptions
293 int mesh_model_contains_subscription(mesh_model_t * mesh_model, uint16_t address);
294 
295 /**
296  * @brief Set Device UUID
297  * @param device_uuid
298  */
299 void mesh_node_set_device_uuid(const uint8_t * device_uuid);
300 
301 /**
302  * @brief Get Device UUID
303  * @returns device_uuid if set, NULL otherwise
304  */
305 const uint8_t * mesh_node_get_device_uuid(void);
306 
307 /**
308  * @brief Set node info reported in Composition Data Page 0
309  * @param company_id (cid)
310  * @param product_id (pid)
311  * @param product_version_id (vid)
312  */
313 void mesh_node_set_info(uint16_t company_id, uint16_t product_id, uint16_t product_version_id);
314 
315 /**
316  * @brief Get node info: company_id
317  * @returns company_id
318  */
319 uint16_t mesh_node_get_company_id(void);
320 
321 /**
322  * @brief Get node info: product_id
323  * @returns product_id
324  */
325 uint16_t mesh_node_get_product_id(void);
326 
327 /**
328  * @brief Get node info: product_version_id
329  * @returns product_version_id
330  */
331 uint16_t mesh_node_get_product_version_id(void);
332 
333 
334 // Heartbeat (helper)
335 uint16_t mesh_heartbeat_pwr2(uint8_t value);
336 uint8_t mesh_heartbeat_count_log(uint16_t value);
337 uint8_t mesh_heartbeat_period_log(uint16_t value);
338 
339 #if defined __cplusplus
340 }
341 #endif
342 
343 #endif //__MESH_NODE_H
344