1 /** @file
2  *  @brief Health Server Model APIs.
3  */
4 
5 /*
6  * Copyright (c) 2017 Intel Corporation
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 #ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_HEALTH_SRV_H_
11 #define ZEPHYR_INCLUDE_BLUETOOTH_MESH_HEALTH_SRV_H_
12 
13 /**
14  * @brief Health Server Model
15  * @defgroup bt_mesh_health_srv Health Server Model
16  * @ingroup bt_mesh
17  * @{
18  */
19 
20 #include <zephyr/bluetooth/mesh.h>
21 #include <zephyr/bluetooth/byteorder.h>
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 /** Callback function for the Health Server model */
28 struct bt_mesh_health_srv_cb {
29 	/** @brief Callback for fetching current faults.
30 	 *
31 	 *  Fault values may either be defined by the specification, or by a
32 	 *  vendor. Vendor specific faults should be interpreted in the context
33 	 *  of the accompanying Company ID. Specification defined faults may be
34 	 *  reported for any Company ID, and the same fault may be presented
35 	 *  for multiple Company IDs.
36 	 *
37 	 *  All faults shall be associated with at least one Company ID,
38 	 *  representing the device vendor or some other vendor whose vendor
39 	 *  specific fault values are used.
40 	 *
41 	 *  If there are multiple Company IDs that have active faults,
42 	 *  return only the faults associated with one of them at the time.
43 	 *  To report faults for multiple Company IDs, interleave which Company
44 	 *  ID is reported for each call.
45 	 *
46 	 *  @param model       Health Server model instance to get faults of.
47 	 *  @param test_id     Test ID response buffer.
48 	 *  @param company_id  Company ID response buffer.
49 	 *  @param faults      Array to fill with current faults.
50 	 *  @param fault_count The number of faults the fault array can fit.
51 	 *                     Should be updated to reflect the number of faults
52 	 *                     copied into the array.
53 	 *
54 	 *  @return 0 on success, or (negative) error code otherwise.
55 	 */
56 	int (*fault_get_cur)(struct bt_mesh_model *model, uint8_t *test_id,
57 			     uint16_t *company_id, uint8_t *faults,
58 			     uint8_t *fault_count);
59 
60 	/** @brief Callback for fetching all registered faults.
61 	 *
62 	 *  Registered faults are all past and current faults since the last
63 	 *  call to @c fault_clear. Only faults associated with the given
64 	 *  Company ID should be reported.
65 	 *
66 	 *  Fault values may either be defined by the specification, or by a
67 	 *  vendor. Vendor specific faults should be interpreted in the context
68 	 *  of the accompanying Company ID. Specification defined faults may be
69 	 *  reported for any Company ID, and the same fault may be presented
70 	 *  for multiple Company IDs.
71 	 *
72 	 *  @param model       Health Server model instance to get faults of.
73 	 *  @param company_id  Company ID to get faults for.
74 	 *  @param test_id     Test ID response buffer.
75 	 *  @param faults      Array to fill with registered faults.
76 	 *  @param fault_count The number of faults the fault array can fit.
77 	 *                     Should be updated to reflect the number of faults
78 	 *                     copied into the array.
79 	 *
80 	 *  @return 0 on success, or (negative) error code otherwise.
81 	 */
82 	int (*fault_get_reg)(struct bt_mesh_model *model, uint16_t company_id,
83 			     uint8_t *test_id, uint8_t *faults,
84 			     uint8_t *fault_count);
85 
86 	/** @brief Clear all registered faults associated with the given Company
87 	 * ID.
88 	 *
89 	 *  @param model      Health Server model instance to clear faults of.
90 	 *  @param company_id Company ID to clear faults for.
91 	 *
92 	 *  @return 0 on success, or (negative) error code otherwise.
93 	 */
94 	int (*fault_clear)(struct bt_mesh_model *model, uint16_t company_id);
95 
96 	/** @brief Run a self-test.
97 	 *
98 	 *  The Health server may support up to 256 self-tests for each Company
99 	 *  ID. The behavior for all test IDs are vendor specific, and should be
100 	 *  interpreted based on the accompanying Company ID. Test failures
101 	 *  should result in changes to the fault array.
102 	 *
103 	 *  @param model      Health Server model instance to run test for.
104 	 *  @param test_id    Test ID to run.
105 	 *  @param company_id Company ID to run test for.
106 	 *
107 	 *  @return 0 if the test execution was started successfully, or
108 	 * (negative) error code otherwise. Note that the fault array will not
109 	 * be reported back to the client if the test execution didn't start.
110 	 */
111 	int (*fault_test)(struct bt_mesh_model *model, uint8_t test_id,
112 			  uint16_t company_id);
113 
114 	/** @brief Start calling attention to the device.
115 	 *
116 	 *  The attention state is used to map an element address to a
117 	 *  physical device. When this callback is called, the device should
118 	 *  start some physical procedure meant to call attention to itself,
119 	 *  like blinking, buzzing, vibrating or moving. If there are multiple
120 	 *  Health server instances on the device, the attention state should
121 	 *  also help identify the specific element the server is in.
122 	 *
123 	 *  The attention calling behavior should continue until the @c attn_off
124 	 *  callback is called.
125 	 *
126 	 *  @param model Health Server model to start the attention state of.
127 	 */
128 	void (*attn_on)(struct bt_mesh_model *model);
129 
130 	/** @brief Stop the attention state.
131 	 *
132 	 *  Any physical activity started to call attention to the device should
133 	 *  be stopped.
134 	 *
135 	 *  @param model
136 	 */
137 	void (*attn_off)(struct bt_mesh_model *model);
138 };
139 
140 /**
141  *  A helper to define a health publication context
142  *
143  *  @param _name       Name given to the publication context variable.
144  *  @param _max_faults Maximum number of faults the element can have.
145  */
146 #define BT_MESH_HEALTH_PUB_DEFINE(_name, _max_faults) \
147 	BT_MESH_MODEL_PUB_DEFINE(_name, NULL, (1 + 3 + (_max_faults)))
148 
149 /** Mesh Health Server Model Context */
150 struct bt_mesh_health_srv {
151 	/** Composition data model entry pointer. */
152 	struct bt_mesh_model *model;
153 
154 	/** Optional callback struct */
155 	const struct bt_mesh_health_srv_cb *cb;
156 
157 	/** Attention Timer state */
158 	struct k_work_delayable attn_timer;
159 
160 #ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV
161 	/** Pointer to the array with Health Test Info Metadata */
162 	struct bt_mesh_models_metadata_entry *metadata;
163 #endif
164 };
165 
166 /**
167  *  Define a new health server model. Note that this API needs to be
168  *  repeated for each element that the application wants to have a
169  *  health server model on. Each instance also needs a unique
170  *  bt_mesh_health_srv and bt_mesh_model_pub context.
171  *
172  *  @param srv Pointer to a unique struct bt_mesh_health_srv.
173  *  @param pub Pointer to a unique struct bt_mesh_model_pub.
174  *
175  *  @return New mesh model instance.
176  */
177 #ifdef CONFIG_BT_MESH_LARGE_COMP_DATA_SRV
178 #define BT_MESH_MODEL_HEALTH_SRV(srv, pub)                                              \
179 	BT_MESH_MODEL_METADATA_CB(BT_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_op,   \
180 			 pub, srv, &bt_mesh_health_srv_cb, &(srv)->metadata)
181 #else
182 #define BT_MESH_MODEL_HEALTH_SRV(srv, pub)                                     \
183 	BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_HEALTH_SRV, bt_mesh_health_srv_op,   \
184 			 pub, srv, &bt_mesh_health_srv_cb)
185 #endif
186 
187 /**
188  *
189  *  Health Test Information Metadata ID.
190  */
191 #define BT_MESH_HEALTH_TEST_INFO_METADATA_ID 0x0001
192 
193 #define BT_MESH_HEALTH_TEST_INFO_METADATA(tests)                               \
194 	{                                                                      \
195 		.len = ARRAY_SIZE(tests),                                      \
196 		.id = BT_MESH_HEALTH_TEST_INFO_METADATA_ID,                    \
197 		.data = tests,                                                 \
198 	}
199 
200 /**
201  *
202  *  Define a Health Test Info Metadata array.
203  *
204  *  @param cid Company ID of the Health Test suite.
205  *  @param tests A comma separated list of tests.
206  *
207  *  @return A comma separated list of values that make Health Test Info Metadata
208  */
209 #define BT_MESH_HEALTH_TEST_INFO(cid, tests...)                                \
210 	BT_BYTES_LIST_LE16(cid), sizeof((uint8_t[]){ tests }), tests
211 
212 /** @brief Notify the stack that the fault array state of the given element has
213  *  changed.
214  *
215  *  This prompts the Health server on this element to publish the current fault
216  *  array if periodic publishing is disabled.
217  *
218  *  @param elem Element to update the fault state of.
219  *
220  *  @return 0 on success, or (negative) error code otherwise.
221  */
222 int bt_mesh_health_srv_fault_update(struct bt_mesh_elem *elem);
223 
224 /** @cond INTERNAL_HIDDEN */
225 extern const struct bt_mesh_model_op bt_mesh_health_srv_op[];
226 extern const struct bt_mesh_model_cb bt_mesh_health_srv_cb;
227 /** @endcond */
228 
229 #ifdef __cplusplus
230 }
231 #endif
232 
233 /**
234  * @}
235  */
236 
237 #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_HEALTH_SRV_H_ */
238