1 /**
2 ****************************************************************************************
3 *
4 * @file user_task.c
5 *
6 * @brief
7 *
8 * Copyright (C) RivieraWaves 2009-2016
9 *
10 *
11 ****************************************************************************************
12 */
13
14 /**
15 ****************************************************************************************
16 * @addtogroup HTPTTASK
17 * @{
18 ****************************************************************************************
19 */
20
21
22 /*
23 * INCLUDE FILES
24 ****************************************************************************************
25 */
26 #include "rwip_config.h"
27
28 #if (BLE_APP_USER)
29 #include "app.h"
30 #include "gap.h"
31 #include "gattc_task.h"
32 #include "attm.h"
33 #include "user.h"
34 #include "user_task.h"
35 #include "prf_utils.h"
36 #include "app_user.h"
37 #include "app_task.h"
38 #include "ke_mem.h"
39 #include "co_utils.h"
40 //#include "interface.h"
41 #include "ble_arch.h"
42 #include "ke_timer.h"
43
44 #ifdef N32WB452_BT_API
45 #include "n32wb452_data_fifo.h"
46 #include "n32wb452_ble_api.h"
47 #include "n32wb452_log_level.h"
48
49 extern uint8_t rx_fff5_chr[300];
50 extern uint16_t rx_fff5_len;
51 extern uint8_t rx_fff5_flag;
52 extern uint16_t rvc_total;
53
54 extern bt_event_callback_handler_t g_pcallback;
55
56 #endif
57
58 /*
59 * FUNCTION DEFINITIONS
60 ****************************************************************************************
61 */
62 //#include "Bkey_user.h"
63 /**
64 ****************************************************************************************
65 * @brief Handles reception of the @ref HTPT_ENABLE_REQ message.
66 * The handler enables the Health Thermometer Profile Thermometer Role.
67 * @param[in] msgid Id of the message received (probably unused).
68 * @param[in] param Pointer to the parameters of the message.
69 * @param[in] dest_id ID of the receiving task instance (probably unused).
70 * @param[in] src_id ID of the sending task instance.
71 * @return If the message was consumed or not.
72 ****************************************************************************************
73 */
user_enable_req_handler(ke_msg_id_t const msgid,struct user_enable_req const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)74 static int user_enable_req_handler(ke_msg_id_t const msgid,
75 struct user_enable_req const *param,
76 ke_task_id_t const dest_id,
77 ke_task_id_t const src_id)
78 {
79 uint8_t status = PRF_ERR_REQ_DISALLOWED;
80 // check state of the task
81 if (gapc_get_conhdl(param->conidx) != GAP_INVALID_CONHDL)
82 {
83 // restore Bond Data
84 struct user_env_tag *user_env = PRF_ENV_GET(USER, user);
85 user_env->ntf_ind_cfg[param->conidx] = param->ntf_ind_cfg;
86 status = GAP_ERR_NO_ERROR;
87
88 }
89
90 // send response
91 struct user_enable_rsp *rsp = KE_MSG_ALLOC(USER_ENABLE_RSP, src_id, dest_id, user_enable_rsp);
92 rsp->conidx = param->conidx;
93 rsp->status = status;
94 ke_msg_send(rsp);
95
96 return (KE_MSG_CONSUMED);
97 }
98
99 /**
100 ****************************************************************************************
101 * @brief Handles reception of the @ref HTPT_TEMP_SEND_REQ message.
102 * @param[in] msgid Id of the message received (probably unused).
103 * @param[in] param Pointer to the parameters of the message.
104 * @param[in] dest_id ID of the receiving task instance (probably unused).
105 * @param[in] src_id ID of the sending task instance.
106 * @return If the message was consumed or not.
107 ****************************************************************************************
108 */
user_data_notify_req_handler(ke_msg_id_t const msgid,struct user_notify_req const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)109 static int user_data_notify_req_handler(ke_msg_id_t const msgid,
110 struct user_notify_req const *param,
111 ke_task_id_t const dest_id,
112 ke_task_id_t const src_id)
113 {
114 // Status
115 int msg_status = KE_MSG_SAVED;
116 uint8_t state = ke_state_get(dest_id);
117
118 // check state of the task
119 if (state == USER_IDLE)
120 {
121 // Get the address of the environment
122 struct user_env_tag *user_env = PRF_ENV_GET(USER, user);
123
124 // for intermediate measurement, feature must be enabled
125 if (/*!(param->send_param_length) &&*/ (!USER_IS_FEATURE_SUPPORTED(user_env->features, USER_DATA_NOTIFY_CHAR_SUP)))
126 {
127 struct user_notify_rsp *rsp = KE_MSG_ALLOC(USER_NOTIFY_RSP, src_id, dest_id, user_notify_rsp);
128 rsp->status = PRF_ERR_FEATURE_NOT_SUPPORTED;
129 ke_msg_send(rsp);
130 }
131 else
132 {
133 // allocate operation to execute
134 user_env->operation = (struct user_op *) ke_malloc(sizeof(struct user_op) + param->send_param_length, KE_MEM_ATT_DB);
135
136 // Initialize operation parameters
137 user_env->operation->cursor = 0;
138 user_env->operation->dest_id = src_id;
139 user_env->operation->conidx = GAP_INVALID_CONIDX;
140
141 // Stable measurement indication or intermediate measurement notification
142
143 user_env->operation->op = user_env->ntf_ind_cfg[param->att_idx+1];// USER_DATA_NTF;
144 //蓝牙 notify handle
145 user_env->operation->handle = USER_HANDLE(param->att_idx);
146
147
148 //Pack the temperature measurement value
149
150 user_env->operation->length = param->send_param_length;
151 memcpy(&(user_env->operation->data[0]), param->send_param_payload, user_env->operation->length);
152 // put task in a busy state
153
154 ke_state_set(dest_id, USER_BUSY);
155
156 user_exe_operation();
157 }
158
159 msg_status = KE_MSG_CONSUMED;
160 }
161
162 return (msg_status);
163 }
164
165
166 /**
167 ****************************************************************************************
168 * @brief Handles reception of the attribute info request message.
169 *
170 * @param[in] msgid Id of the message received (probably unused).
171 * @param[in] param Pointer to the parameters of the message.
172 * @param[in] dest_id ID of the receiving task instance (probably unused).
173 * @param[in] src_id ID of the sending task instance.
174 * @return If the message was consumed or not.
175 ****************************************************************************************
176 */
user_gattc_att_info_req_ind_handler(ke_msg_id_t const msgid,struct gattc_att_info_req_ind * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)177 static int user_gattc_att_info_req_ind_handler(ke_msg_id_t const msgid,
178 struct gattc_att_info_req_ind *param,
179 ke_task_id_t const dest_id,
180 ke_task_id_t const src_id)
181 {
182
183 struct user_env_tag *user_env = PRF_ENV_GET(USER, user);
184
185 uint8_t att_idx = USER_IDX(param->handle);
186 struct gattc_att_info_cfm *cfm;
187
188 //Send write response
189 cfm = KE_MSG_ALLOC(GATTC_ATT_INFO_CFM, src_id, dest_id, gattc_att_info_cfm);
190 cfm->handle = param->handle;
191
192
193 ke_msg_send(cfm);
194
195 return (KE_MSG_CONSUMED);
196 }
197
198
199
200
201
202
203 /**
204 ****************************************************************************************
205 * @brief Handles reception of the @ref GL2C_CODE_ATT_WR_CMD_IND message.
206 * The handler compares the new values with current ones and notifies them if they changed.
207 * @param[in] msgid Id of the message received (probably unused).
208 * @param[in] param Pointer to the parameters of the message.
209 * @param[in] dest_id ID of the receiving task instance (probably unused).
210 * @param[in] src_id ID of the sending task instance.
211 * @return If the message was consumed or not.
212 ****************************************************************************************
213 */
user_gattc_write_req_ind_handler(ke_msg_id_t const msgid,struct gattc_write_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)214 static int user_gattc_write_req_ind_handler(ke_msg_id_t const msgid,
215 struct gattc_write_req_ind const *param,
216 ke_task_id_t const dest_id,
217 ke_task_id_t const src_id)
218 {
219 #ifdef N32WB452_BT_API
220 int32_t ret;
221 #endif
222
223
224 struct user_env_tag *user_env = PRF_ENV_GET(USER, user);
225 uint8_t status = ATT_ERR_NO_ERROR;
226 int msg_status = KE_MSG_CONSUMED;
227 uint8_t conidx = KE_IDX_GET(src_id);
228 // to check if confirmation message should be send
229 uint8_t att_idx = USER_IDX(param->handle);
230 // uint32_t i;
231 // ble_log(BLE_DEBUG,"%d\r\n",att_idx);
232 if (param->length > USER_DATA_LEN_MAX)
233 {
234 status = PRF_ERR_UNEXPECTED_LEN;
235 }
236 else
237 {
238 // printf("user_gattc_write_req_ind_handler, idx = %x\r\n", att_idx);
239 switch (att_idx)
240 {
241 case USER_IDX_WRITE_NOTIFY_VAL:
242 {
243 #ifdef N32WB452_BT_API
244
245 ble_log(BLE_DEBUG,"w[%x,%d].\r\n", param->value, param->length);
246 ret = fifo_write(param->value, param->length);
247 if (ret != E_OK) {
248 ble_log(BLE_DEBUG,"write err.\r\n");
249 }
250
251 if (g_pcallback) {
252 (*g_pcallback)(BT_EVENT_RCV_DATA, param->value, param->length, att_idx);
253 }
254 #else
255
256 // test for NK-bluetooth apk test
257 ble_log(BLE_DEBUG,"curlen=%d,totallen=%d,buf=0x%x[basebuf:%x].\r\n", app_env.rx_data.RxCurrentLen, app_env.rx_data.RxTotalLen, param->value, app_env.rx_data.RxBuf);
258 ble_log(BLE_DEBUG,"RECV[%02x]: ",param->length);
259 for(i=0; i<param->length; i++)
260 {
261 ble_log(BLE_DEBUG,"%02X, ",param->value[i]);
262 }
263 ble_log(BLE_DEBUG,"\r\n");
264 ble_log(BLE_DEBUG,"1 curlen=%d, TotalLen = %d.\r\n", app_env.rx_data.RxCurrentLen, app_env.rx_data.RxTotalLen);
265
266 if (app_env.rx_data.RxTotalLen == 0)
267 {
268 app_env.rx_data.RxCurrentLen = 0;
269 app_env.rx_data.RxTotalLen = param->value[0] + (param->value[1]<<8) + 2;
270 ble_log(BLE_DEBUG,"2RxTotalLen = %d.\r\n", app_env.rx_data.RxTotalLen);
271
272 ASSERT_ERR( app_env.rx_data.RxTotalLen < RX_DAT_BUF_SIZE );
273 }
274
275 memcpy(app_env.rx_data.RxBuf+app_env.rx_data.RxCurrentLen, param->value,param->length);
276 app_env.rx_data.RxCurrentLen += param->length;
277 if (app_env.rx_data.RxCurrentLen >= app_env.rx_data.RxTotalLen)
278 {
279 ble_log(BLE_DEBUG,"3data_notify[%d,%d].\r\n", app_env.rx_data.RxCurrentLen, app_env.rx_data.RxTotalLen);
280
281 app_user_data_notify(app_env.rx_data.RxTotalLen, app_env.rx_data.RxBuf, USER_IDX_WRITE_NOTIFY_VAL);
282 app_env.rx_data.RxTotalLen = 0;
283 app_env.rx_data.RxCurrentLen = 0;
284 }
285 #endif
286 }
287
288 break;
289 #ifdef BLE_OTA_WRITE_CHAR_EN
290 case USER_IDX_WRITE_NOTIFY2_CFG:
291 {
292 status = user_update_ntf_ind_cfg(conidx, USER_DATA_NTF, PRF_CLI_START_NTF, att_idx, co_read16p(param->value));
293 }
294 break;
295 #endif
296 case USER_IDX_WRITE_NOTIFY_CFG: //0xFFF5 NOTIFY ENABLE
297 {
298 status = user_update_ntf_ind_cfg(conidx, USER_DATA_NTF, PRF_CLI_START_NTF, att_idx, co_read16p(param->value));
299 }
300 break;
301
302 default:
303 {
304 status = ATT_ERR_REQUEST_NOT_SUPPORTED;
305 }
306 break;
307 }
308 }
309 //Send write response
310 struct gattc_write_cfm *cfm = KE_MSG_ALLOC(GATTC_WRITE_CFM, src_id, dest_id, gattc_write_cfm);
311 cfm->handle = param->handle;
312 cfm->status = status;
313 ke_msg_send(cfm);
314
315 return (msg_status);
316 }
317
318
319 /**
320 ****************************************************************************************
321 * @brief Handles reception of the @ref GATTC_READ_REQ_IND message.
322 * @param[in] msgid Id of the message received (probably unused).
323 * @param[in] param Pointer to the parameters of the message.
324 * @param[in] dest_id ID of the receiving task instance (probably unused).
325 * @param[in] src_id ID of the sending task instance.
326 * @return If the message was consumed or not.
327 ****************************************************************************************
328 */
user_gattc_read_req_ind_handler(ke_msg_id_t const msgid,struct gattc_read_req_ind const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)329 static int user_gattc_read_req_ind_handler(ke_msg_id_t const msgid, struct gattc_read_req_ind const *param,
330 ke_task_id_t const dest_id, ke_task_id_t const src_id)
331 {
332 struct user_env_tag *user_env = PRF_ENV_GET(USER, user);
333 uint8_t value_size = 0;
334 uint8_t status = ATT_ERR_NO_ERROR;
335 uint8_t value[USER_DATA_LEN_MAX];
336 // retrieve handle information
337 uint8_t att_idx = USER_IDX(param->handle);
338 switch (att_idx)
339 {
340 #ifdef BLE_OTA_WRITE_CHAR_EN
341 case USER_IDX_READ_NOTIFY_VAL:
342 {
343 #if 1 // lizhk add, fff7 read encryption status.
344 if (ke_state_get(TASK_APP)!= APPM_ENCRYPTED)
345 {
346 memcpy(value, (uint8_t *)"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 20);
347 value_size = 20;
348 }
349 else
350 {
351 memcpy(value, (uint8_t *)"\x17\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 20);
352 value_size = 20;
353 }
354 #endif
355 break;
356 }
357 #endif
358
359 case USER_IDX_WRITE_NOTIFY_CFG:
360 #if BLE_OTA_WRITE_CHAR_EN
361 case USER_IDX_WRITE_NOTIFY2_CFG:
362 {
363 *(uint16_t *)value = user_env->ntf_ind_cfg[att_idx];
364 value_size = 2;
365 }
366 break;
367 #endif
368
369 default:
370 {
371 status = ATT_ERR_REQUEST_NOT_SUPPORTED;
372 }
373 break;
374 }
375 // Send data to peer device
376 struct gattc_read_cfm *cfm = KE_MSG_ALLOC_DYN(GATTC_READ_CFM, src_id, dest_id, gattc_read_cfm, value_size);
377 cfm->length = value_size;
378 memcpy(cfm->value, value, value_size);
379 cfm->handle = param->handle;
380 cfm->status = status;
381 ke_msg_send(cfm);// Send value to peer device.
382 return (KE_MSG_CONSUMED);
383 }
384
385 /**
386 ****************************************************************************************
387 * @brief Handles @ref GATTC_CMP_EVT for GATTC_NOTIFY and GATT_INDICATE message meaning
388 * that Measurement notification/indication has been correctly sent to peer device
389 *
390 *
391 * @param[in] msgid Id of the message received.
392 * @param[in] param Pointer to the parameters of the message.
393 * @param[in] dest_id ID of the receiving task instance
394 * @param[in] src_id ID of the sending task instance.
395 * @return If the message was consumed or not.
396 ****************************************************************************************
397 */
user_gattc_cmp_evt_handler(ke_msg_id_t const msgid,struct gattc_cmp_evt const * param,ke_task_id_t const dest_id,ke_task_id_t const src_id)398 static int user_gattc_cmp_evt_handler(ke_msg_id_t const msgid, struct gattc_cmp_evt const *param,
399 ke_task_id_t const dest_id, ke_task_id_t const src_id)
400 {
401 // continue operation execution
402
403 user_exe_operation();
404
405 return (KE_MSG_CONSUMED);
406 }
407
408
409 /*
410 * GLOBAL VARIABLE DEFINITIONS
411 ****************************************************************************************
412 */
413
414
415
416 /// Default State handlers definition
417 const struct ke_msg_handler user_default_state[] =
418 {
419 {USER_ENABLE_REQ, (ke_msg_func_t) user_enable_req_handler},
420 {USER_NOTIFY_REQ, (ke_msg_func_t) user_data_notify_req_handler},
421
422 {GATTC_ATT_INFO_REQ_IND, (ke_msg_func_t) user_gattc_att_info_req_ind_handler},
423 {GATTC_WRITE_REQ_IND, (ke_msg_func_t) user_gattc_write_req_ind_handler},
424 {GATTC_READ_REQ_IND, (ke_msg_func_t) user_gattc_read_req_ind_handler},
425 {GATTC_CMP_EVT, (ke_msg_func_t) user_gattc_cmp_evt_handler},
426
427 };
428
429
430 ///Specifies the message handlers that are common to all states.
431 const struct ke_state_handler user_default_handler = KE_STATE_HANDLER(user_default_state);
432 //const struct ke_state_handler user1_default_handler = KE_STATE_HANDLER(user1_default_state);
433 //const struct ke_state_handler user2_default_handler = KE_STATE_HANDLER(user2_default_state);
434
435 #endif //BLE_HT_THERMOM
436
437 /// @} HTPTTASK
438
439