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