1 /*
2 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
3 */
4
5 #include <stdlib.h>
6 #include <bt_errno.h>
7 #include "mesh_model/mesh_model.h"
8
9 #ifdef CONFIG_BT_MESH_PROVISIONER
10 #include "provisioner_main.h"
11 #endif
12
13 extern u8_t bt_mesh_default_ttl_get(void);
14
15 #define TAG "BT_MESH_MODEL"
16 #define RECV_MSG_TID_QUEUE_SIZE 20
17 #define MESH_TRNSATION_CYCLE 100
18 #define CID_NVAL 0XFFFF
19 #define TIMEOUT 400
20 typedef struct _mesh_model {
21 uint8_t init_flag;
22 const struct bt_mesh_comp *mesh_comp;
23 model_event_cb user_model_event_cb;
24 S_ELEM_STATE *element_states;
25 } mesh_model;
26
27 mesh_model g_mesh_model;
28
29
30 typedef struct {
31 u8_t tid;
32 u16_t addr;
33 bt_u32_t time;
34 } _TID_QUEUE_S;
35
36
37
38 u16_t TRANS_TIMES[] = {1, 10, 100, 6000};
39
40 _TID_QUEUE_S tid_queue[RECV_MSG_TID_QUEUE_SIZE];
41
_mesh_timer_stop(S_MESH_STATE * p_state)42 static void _mesh_timer_stop(S_MESH_STATE *p_state)
43 {
44 k_timer_stop(&p_state->delay_timer);
45 k_timer_stop(&p_state->trans_timer);
46 }
47
_mesh_delay_timer_cb(void * p_timer,void * args)48 static void _mesh_delay_timer_cb(void *p_timer, void *args)
49 {
50 S_ELEM_STATE *p_elem = (S_ELEM_STATE *)args;
51
52 _mesh_timer_stop(&p_elem->state);
53 //model_event(GEN_EVT_SDK_DELAY_END, (void *)p_elem);
54 }
55
_mesh_trans_timer_cycle(void * p_timer,void * args)56 static void _mesh_trans_timer_cycle(void *p_timer, void *args)
57 {
58 S_ELEM_STATE *p_elem = (S_ELEM_STATE *)args;
59 bt_u32_t cur_time = k_uptime_get();
60
61 _mesh_timer_stop(&p_elem->state);
62
63 //LOGD(TAG, ">>>>>%d %d", (bt_u32_t)cur_time, (bt_u32_t)p_elem->state.trans_end_time);
64 if (cur_time >= p_elem->state.trans_end_time) {
65 //model_event(GEN_EVT_SDK_TRANS_END, (void *)p_elem);
66 } else {
67 //model_event(GEN_EVT_SDK_TRANS_CYCLE, (void *)p_elem);
68 k_timer_start(&p_elem->state.trans_timer, MESH_TRNSATION_CYCLE);
69 }
70 }
71
72
elem_state_init(struct bt_mesh_elem * elem)73 uint8_t elem_state_init(struct bt_mesh_elem *elem)
74 {
75 S_ELEM_STATE *elemState = (S_ELEM_STATE *)elem->models[2].user_data;
76
77 if (!elemState) {
78 return 0;
79 }
80
81 if (!elemState->state.timerInitFlag) {
82 k_timer_init(&elemState->state.delay_timer, _mesh_delay_timer_cb, elemState);
83 k_timer_init(&elemState->state.trans_timer, _mesh_trans_timer_cycle, elemState);
84 }
85
86 elemState->state.timerInitFlag = true;
87 return 0;
88 }
89
90
get_transition_time(u8_t byte)91 bt_u32_t get_transition_time(u8_t byte)
92 {
93 if ((byte & 0x3F) == 0x3F) {
94 //MODEL_E("%s ERROR, invalid 0x%02X!!!\n", __func__, byte);
95 return 0xFFFFFFFF;
96 }
97
98 return (byte & 0x3F) * TRANS_TIMES[byte >> 6] * 100;
99 }
100
_get_transition_byte(bt_u32_t time)101 static u8_t _get_transition_byte(bt_u32_t time)
102 {
103 //LOGD(TAG, "time(%d)", time);
104
105 time /= 100;
106
107 if (time > TRANS_TIMES[3] * 62) {
108 return 0;
109 } else if (time > TRANS_TIMES[2] * 62) {
110 return (time / TRANS_TIMES[3]) | 0xC0;
111 } else if (time > TRANS_TIMES[1] * 62) {
112 return (time / TRANS_TIMES[2]) | 0x80;
113 } else if (time > TRANS_TIMES[0] * 62) {
114 return (time / TRANS_TIMES[1]) | 0x40;
115 } else {
116 return (time / TRANS_TIMES[0]);
117 }
118 }
119
120
get_remain_byte(S_MESH_STATE * p_state,bool is_ack)121 u8_t get_remain_byte(S_MESH_STATE *p_state, bool is_ack)
122 {
123 u8_t remain_byte = p_state->trans;
124 bt_u32_t cur_time = k_uptime_get();
125
126 if (!is_ack && p_state->trans_start_time < cur_time) {
127 cur_time -= p_state->trans_start_time;
128 bt_u32_t l_trans = get_transition_time(p_state->trans);
129
130 if (l_trans == 0xFFFFFFFF) {
131 remain_byte = 0x3F;
132 } else if (l_trans > cur_time) {
133 remain_byte = _get_transition_byte(l_trans - cur_time);
134 } else {
135 remain_byte = 0;
136 }
137
138 }
139
140 //LOGD(TAG, "remain_byte(0x%02x)", remain_byte);
141
142 return remain_byte;
143 }
144
mesh_check_tid(u16_t src_addr,u8_t tid)145 E_MESH_ERROR_TYPE mesh_check_tid(u16_t src_addr, u8_t tid)
146 {
147 static u8_t cur_index = 0;
148 u8_t i = cur_index;
149 u8_t ri = 0;
150 bt_u32_t cur_time = k_uptime_get();
151 bt_u32_t end_time = 0;
152
153 while (i < cur_index + RECV_MSG_TID_QUEUE_SIZE) {
154 ri = i % RECV_MSG_TID_QUEUE_SIZE;
155
156 if (tid_queue[ri].tid == tid && tid_queue[ri].addr == src_addr) {
157 end_time = tid_queue[ri].time + 6000;
158
159 if (cur_time < end_time) {
160 break;
161 }
162 }
163
164 i++;
165 }
166
167 if (i < cur_index + RECV_MSG_TID_QUEUE_SIZE) {
168 return MESH_TID_REPEAT;
169 } else {
170 tid_queue[cur_index].tid = tid;
171 tid_queue[cur_index].addr = src_addr;
172 tid_queue[cur_index].time = cur_time;
173 cur_index++;
174 cur_index %= RECV_MSG_TID_QUEUE_SIZE;
175 return MESH_SUCCESS;
176 }
177 }
178
179
model_message_process(uint8_t event,void * p_arg)180 void model_message_process(uint8_t event, void *p_arg)
181 {
182 switch (event) {
183 default:
184 break;
185 }
186
187 return;
188 }
189
190
model_event(mesh_model_event_en event,void * p_arg)191 void model_event(mesh_model_event_en event, void *p_arg)
192 {
193
194 if (g_mesh_model.user_model_event_cb) {
195 g_mesh_model.user_model_event_cb(event, p_arg);
196 }
197
198 }
199
200
mesh_model_bind_map_get(const struct bt_mesh_comp * mesh_comp)201 static int mesh_model_bind_map_get(const struct bt_mesh_comp *mesh_comp)
202 {
203 if (!mesh_comp) {
204 return -1;
205 }
206
207 return 0;
208 }
209
mesh_model_set_user_data(const struct bt_mesh_comp * comp,S_ELEM_STATE * state)210 static int mesh_model_set_user_data(const struct bt_mesh_comp *comp, S_ELEM_STATE *state)
211 {
212 uint8_t ele_num;
213 uint8_t model_num;
214
215 for (ele_num = 0 ; ele_num < comp->elem_count; ele_num++) {
216 for (model_num = 0; model_num < comp->elem[ele_num].model_count; model_num++) {
217 if (comp->elem[ele_num].models[model_num].id != BT_MESH_MODEL_ID_CFG_SRV && \
218 comp->elem[ele_num].models[model_num].id != BT_MESH_MODEL_ID_CFG_CLI && \
219 comp->elem[ele_num].models[model_num].id != BT_MESH_MODEL_ID_HEALTH_SRV && \
220 comp->elem[ele_num].models[model_num].id != BT_MESH_MODEL_ID_HEALTH_CLI) {
221 comp->elem[ele_num].models[model_num].user_data = &state[ele_num];
222 }
223 }
224 }
225
226 return 0;
227 }
228
229
ble_mesh_model_init(const struct bt_mesh_comp * comp)230 int ble_mesh_model_init(const struct bt_mesh_comp *comp)
231 {
232 if (!comp) {
233 return -1;
234 }
235
236 int16_t ret;
237 ret = mesh_model_bind_map_get(comp);
238
239 if (ret) {
240 return -1;
241 }
242
243 if (g_mesh_model.element_states) {
244 free(g_mesh_model.element_states);
245 g_mesh_model.element_states = NULL;
246 }
247
248 g_mesh_model.element_states = (S_ELEM_STATE *)malloc(sizeof(S_ELEM_STATE) * comp->elem_count);
249
250 if (!g_mesh_model.element_states) {
251 return -1;
252 }
253
254 memset(g_mesh_model.element_states, 0, sizeof(S_ELEM_STATE) * comp->elem_count);
255
256 ret = mesh_model_set_user_data(comp, g_mesh_model.element_states);
257
258 if (ret) {
259 return -1;
260 }
261
262 g_mesh_model.mesh_comp = comp;
263 g_mesh_model.init_flag = 1;
264
265 return 0;
266 }
267
268
ble_mesh_model_get_comp_data()269 const struct bt_mesh_comp *ble_mesh_model_get_comp_data()
270 {
271 return g_mesh_model.mesh_comp;
272 }
273
ble_mesh_model_set_cb(model_event_cb event_cb)274 int ble_mesh_model_set_cb(model_event_cb event_cb)
275 {
276 if (!g_mesh_model.init_flag || !event_cb) {
277 return -1;
278 }
279
280 g_mesh_model.user_model_event_cb = event_cb;
281 return 0;
282 }
283
ble_mesh_model_find(uint16_t elem_idx,uint16_t mod_idx,uint16_t CID)284 struct bt_mesh_model *ble_mesh_model_find(uint16_t elem_idx, uint16_t mod_idx, uint16_t CID)
285 {
286 if (!g_mesh_model.init_flag) {
287 return NULL;
288 }
289
290 if (elem_idx > g_mesh_model.mesh_comp->elem_count) {
291 return NULL;
292 }
293
294 if (CID_NVAL != CID) {
295 extern struct bt_mesh_model *bt_mesh_model_find_vnd(struct bt_mesh_elem * elem, u16_t company, u16_t id);
296 return (struct bt_mesh_model *)bt_mesh_model_find_vnd(&g_mesh_model.mesh_comp->elem[elem_idx], CID, mod_idx);
297 } else {
298 extern struct bt_mesh_model *bt_mesh_model_find(struct bt_mesh_elem * elem, u16_t id);
299 return (struct bt_mesh_model *)bt_mesh_model_find(&g_mesh_model.mesh_comp->elem[elem_idx], mod_idx);
300 }
301
302 }
303
304
ble_mesh_model_status_get(uint16_t netkey_idx,uint16_t appkey_idx,uint16_t unicast_addr,struct bt_mesh_model * model,uint32_t op_code)305 int ble_mesh_model_status_get(uint16_t netkey_idx, uint16_t appkey_idx, uint16_t unicast_addr,struct bt_mesh_model *model,uint32_t op_code)
306 {
307 int err;
308 struct bt_mesh_msg_ctx ctx = {0};
309
310 if (0x0000 == unicast_addr) {
311 return -EADDRNOTAVAIL;
312 }
313
314 if (!model) {
315 return -EINVAL;
316 }
317
318 struct net_buf_simple *msg = NET_BUF_SIMPLE(2 + 0 + 6);
319
320 bt_mesh_model_msg_init(msg, op_code);
321
322 ctx.addr = unicast_addr;
323
324 ctx.net_idx = netkey_idx;
325
326 ctx.app_idx = appkey_idx;
327 ctx.send_ttl = bt_mesh_default_ttl_get();
328
329 err = bt_mesh_model_send(model, &ctx, msg, NULL, NULL);
330
331 if (err) {
332 LOGE(TAG, "mesh model get status send fail %d", err);
333 return err;
334 }
335
336 return 0;
337 }
338
339