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