• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 
20 /******************************************************************************
21  *
22  *  This file contains function of the NFC unit to receive/process NCI
23  *  commands.
24  *
25  ******************************************************************************/
26 #include <string.h>
27 #include "nfc_target.h"
28 #include "bt_types.h"
29 #include "gki.h"
30 
31 #if NFC_INCLUDED == TRUE
32 #include "nci_defs.h"
33 #include "nci_hmsgs.h"
34 #include "nfc_api.h"
35 #include "nfc_int.h"
36 
37 /*******************************************************************************
38 **
39 ** Function         nci_proc_core_rsp
40 **
41 ** Description      Process NCI responses in the CORE group
42 **
43 ** Returns          TRUE-caller of this function to free the GKI buffer p_msg
44 **
45 *******************************************************************************/
nci_proc_core_rsp(BT_HDR * p_msg)46 BOOLEAN nci_proc_core_rsp (BT_HDR *p_msg)
47 {
48     UINT8   *p;
49     UINT8   *pp, len, op_code;
50     BOOLEAN free = TRUE;
51     UINT8   *p_old = nfc_cb.last_cmd;
52 
53     /* find the start of the NCI message and parse the NCI header */
54     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
55     pp  = p+1;
56     NCI_MSG_PRS_HDR1 (pp, op_code);
57     NFC_TRACE_DEBUG1 ("nci_proc_core_rsp opcode:0x%x", op_code);
58     len = *pp++;
59 
60     /* process the message based on the opcode and message type */
61     switch (op_code)
62     {
63     case NCI_MSG_CORE_RESET:
64         nfc_ncif_proc_reset_rsp (pp, FALSE);
65         break;
66 
67     case NCI_MSG_CORE_INIT:
68         nfc_ncif_proc_init_rsp (p_msg);
69         free = FALSE;
70         break;
71 
72     case NCI_MSG_CORE_GET_CONFIG:
73         nfc_ncif_proc_get_config_rsp (p_msg);
74         break;
75 
76     case NCI_MSG_CORE_SET_CONFIG:
77         nfc_ncif_set_config_status (pp, len);
78         break;
79 
80     case NCI_MSG_CORE_CONN_CREATE:
81         nfc_ncif_proc_conn_create_rsp (p, p_msg->len, *p_old);
82         break;
83 
84     case NCI_MSG_CORE_CONN_CLOSE:
85         nfc_ncif_report_conn_close_evt (*p_old, *pp);
86         break;
87 
88     default:
89         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
90         break;
91     }
92 
93     return free;
94 }
95 
96 /*******************************************************************************
97 **
98 ** Function         nci_proc_core_ntf
99 **
100 ** Description      Process NCI notifications in the CORE group
101 **
102 ** Returns          void
103 **
104 *******************************************************************************/
nci_proc_core_ntf(BT_HDR * p_msg)105 void nci_proc_core_ntf (BT_HDR *p_msg)
106 {
107     UINT8   *p;
108     UINT8   *pp, len, op_code;
109     UINT8   conn_id;
110 
111     /* find the start of the NCI message and parse the NCI header */
112     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
113     pp  = p+1;
114     NCI_MSG_PRS_HDR1 (pp, op_code);
115     NFC_TRACE_DEBUG1 ("nci_proc_core_ntf opcode:0x%x", op_code);
116     len = *pp++;
117 
118     /* process the message based on the opcode and message type */
119     switch (op_code)
120     {
121     case NCI_MSG_CORE_RESET:
122         nfc_ncif_proc_reset_rsp (pp, TRUE);
123         break;
124 
125     case NCI_MSG_CORE_GEN_ERR_STATUS:
126         /* process the error ntf */
127         /* in case of timeout: notify the static connection callback */
128         nfc_ncif_event_status (NFC_GEN_ERROR_REVT, *pp);
129         nfc_ncif_error_status (NFC_RF_CONN_ID, *pp);
130         break;
131 
132     case NCI_MSG_CORE_INTF_ERR_STATUS:
133         conn_id = *(pp+1);
134         nfc_ncif_error_status (conn_id, *pp);
135         break;
136 
137     case NCI_MSG_CORE_CONN_CREDITS:
138         nfc_ncif_proc_credits(pp, len);
139         break;
140 
141     default:
142         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
143         break;
144     }
145 }
146 
147 
148 /*******************************************************************************
149 **
150 ** Function         nci_proc_rf_management_rsp
151 **
152 ** Description      Process NCI responses in the RF Management group
153 **
154 ** Returns          void
155 **
156 *******************************************************************************/
nci_proc_rf_management_rsp(BT_HDR * p_msg)157 void nci_proc_rf_management_rsp (BT_HDR *p_msg)
158 {
159     UINT8   *p;
160     UINT8   *pp, len, op_code;
161     UINT8   *p_old = nfc_cb.last_cmd;
162 
163     /* find the start of the NCI message and parse the NCI header */
164     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
165     pp  = p+1;
166     NCI_MSG_PRS_HDR1 (pp, op_code);
167     len = *pp++;
168 
169     switch (op_code)
170     {
171     case NCI_MSG_RF_DISCOVER:
172         nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP);
173         nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
174         break;
175 
176     case NCI_MSG_RF_DISCOVER_SELECT:
177         nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
178         break;
179 
180     case NCI_MSG_RF_T3T_POLLING:
181         break;
182 
183     case NCI_MSG_RF_DISCOVER_MAP:
184         nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
185         break;
186 
187     case NCI_MSG_RF_DEACTIVATE:
188         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_RSP))
189         {
190             return;
191         }
192         nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
193         break;
194 
195 #if (NFC_NFCEE_INCLUDED == TRUE)
196 #if (NFC_RW_ONLY == FALSE)
197 
198     case NCI_MSG_RF_SET_ROUTING:
199         nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
200         break;
201 
202     case NCI_MSG_RF_GET_ROUTING:
203         if (*pp != NFC_STATUS_OK)
204             nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
205         break;
206 #endif
207 #endif
208 
209     case NCI_MSG_RF_PARAMETER_UPDATE:
210         nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
211         break;
212 
213     default:
214         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
215         break;
216     }
217 }
218 
219 /*******************************************************************************
220 **
221 ** Function         nci_proc_rf_management_ntf
222 **
223 ** Description      Process NCI notifications in the RF Management group
224 **
225 ** Returns          void
226 **
227 *******************************************************************************/
nci_proc_rf_management_ntf(BT_HDR * p_msg)228 void nci_proc_rf_management_ntf (BT_HDR *p_msg)
229 {
230     UINT8   *p;
231     UINT8   *pp, len, op_code;
232 
233     /* find the start of the NCI message and parse the NCI header */
234     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
235     pp  = p+1;
236     NCI_MSG_PRS_HDR1 (pp, op_code);
237     len = *pp++;
238 
239     switch (op_code)
240     {
241     case NCI_MSG_RF_DISCOVER :
242         nfc_ncif_proc_discover_ntf (p, p_msg->len);
243         break;
244 
245     case NCI_MSG_RF_DEACTIVATE:
246         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
247         {
248             return;
249         }
250         nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
251         break;
252 
253     case NCI_MSG_RF_INTF_ACTIVATED:
254         if (FALSE == nfa_dm_p2p_prio_logic (op_code, pp, NFA_DM_P2P_PRIO_NTF))
255         {
256             return;
257         }
258         nfc_ncif_proc_activate (pp, len);
259         break;
260 
261     case NCI_MSG_RF_FIELD:
262         nfc_ncif_proc_rf_field_ntf (*pp);
263         break;
264 
265     case NCI_MSG_RF_T3T_POLLING:
266         nfc_ncif_proc_t3t_polling_ntf (pp, len);
267         break;
268 
269 #if (NFC_NFCEE_INCLUDED == TRUE)
270 #if (NFC_RW_ONLY == FALSE)
271 
272     case NCI_MSG_RF_GET_ROUTING:
273         nfc_ncif_proc_get_routing (pp, len);
274         break;
275 
276     case NCI_MSG_RF_EE_ACTION:
277         nfc_ncif_proc_ee_action (pp, len);
278         break;
279 
280     case NCI_MSG_RF_EE_DISCOVERY_REQ:
281         nfc_ncif_proc_ee_discover_req (pp, len);
282         break;
283 #endif
284 #endif
285 
286     default:
287         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
288         break;
289     }
290 }
291 
292 #if (NFC_NFCEE_INCLUDED == TRUE)
293 #if (NFC_RW_ONLY == FALSE)
294 
295 /*******************************************************************************
296 **
297 ** Function         nci_proc_ee_management_rsp
298 **
299 ** Description      Process NCI responses in the NFCEE Management group
300 **
301 ** Returns          void
302 **
303 *******************************************************************************/
nci_proc_ee_management_rsp(BT_HDR * p_msg)304 void nci_proc_ee_management_rsp (BT_HDR *p_msg)
305 {
306     UINT8   *p;
307     UINT8   *pp, len, op_code;
308     tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
309     tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
310     tNFC_NFCEE_INFO_REVT        nfcee_info;
311     tNFC_NFCEE_MODE_SET_REVT    mode_set;
312     tNFC_RESPONSE   *p_evt = (tNFC_RESPONSE *) &nfcee_info;
313     tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
314     UINT8   *p_old = nfc_cb.last_cmd;
315 
316     /* find the start of the NCI message and parse the NCI header */
317     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
318     pp  = p+1;
319     NCI_MSG_PRS_HDR1 (pp, op_code);
320     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
321     len = *pp++;
322 
323     switch (op_code)
324     {
325     case NCI_MSG_NFCEE_DISCOVER:
326         p_evt                       = (tNFC_RESPONSE *) &nfcee_discover;
327         nfcee_discover.status       = *pp++;
328         nfcee_discover.num_nfcee    = *pp++;
329 
330         if (nfcee_discover.status != NFC_STATUS_OK)
331             nfcee_discover.num_nfcee    = 0;
332 
333         event                       = NFC_NFCEE_DISCOVER_REVT;
334         break;
335 
336     case NCI_MSG_NFCEE_MODE_SET:
337         p_evt                   = (tNFC_RESPONSE *) &mode_set;
338         mode_set.status         = *pp;
339         mode_set.nfcee_id       = 0;
340         event                   = NFC_NFCEE_MODE_SET_REVT;
341         mode_set.nfcee_id       = *p_old++;
342         mode_set.mode           = *p_old++;
343         break;
344 
345     default:
346         p_cback = NULL;
347         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
348         break;
349     }
350 
351     if (p_cback)
352         (*p_cback) (event, p_evt);
353 }
354 
355 /*******************************************************************************
356 **
357 ** Function         nci_proc_ee_management_ntf
358 **
359 ** Description      Process NCI notifications in the NFCEE Management group
360 **
361 ** Returns          void
362 **
363 *******************************************************************************/
nci_proc_ee_management_ntf(BT_HDR * p_msg)364 void nci_proc_ee_management_ntf (BT_HDR *p_msg)
365 {
366     UINT8                 *p;
367     UINT8                 *pp, len, op_code;
368     tNFC_RESPONSE_CBACK   *p_cback = nfc_cb.p_resp_cback;
369     tNFC_NFCEE_INFO_REVT  nfcee_info;
370     tNFC_RESPONSE         *p_evt   = (tNFC_RESPONSE *) &nfcee_info;
371     tNFC_RESPONSE_EVT     event    = NFC_NFCEE_INFO_REVT;
372     UINT8                 xx;
373     UINT8                 yy;
374     UINT8                 ee_status;
375     tNFC_NFCEE_TLV        *p_tlv;
376 
377     /* find the start of the NCI message and parse the NCI header */
378     p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
379     pp  = p+1;
380     NCI_MSG_PRS_HDR1 (pp, op_code);
381     NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
382     len = *pp++;
383 
384     if (op_code == NCI_MSG_NFCEE_DISCOVER)
385     {
386         nfcee_info.nfcee_id    = *pp++;
387         ee_status                   = *pp++;
388 
389         nfcee_info.ee_status        = ee_status;
390         yy                          = *pp;
391         nfcee_info.num_interface    = *pp++;
392         p                           = pp;
393 
394         if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
395             nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
396 
397         for (xx = 0; xx < nfcee_info.num_interface; xx++)
398         {
399             nfcee_info.ee_interface[xx] = *pp++;
400         }
401 
402         pp                              = p + yy;
403         nfcee_info.num_tlvs             = *pp++;
404         NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
405             nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
406 
407         if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
408             nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
409 
410         p_tlv = &nfcee_info.ee_tlv[0];
411 
412         for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
413         {
414             p_tlv->tag  = *pp++;
415             p_tlv->len  = yy = *pp++;
416             NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
417             if (p_tlv->len > NFC_MAX_EE_INFO)
418                 p_tlv->len = NFC_MAX_EE_INFO;
419             p   = pp;
420             STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
421             pp  = p += yy;
422         }
423     }
424     else
425     {
426         p_cback = NULL;
427         NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
428     }
429 
430     if (p_cback)
431         (*p_cback) (event, p_evt);
432 }
433 
434 #endif
435 #endif
436 
437 /*******************************************************************************
438 **
439 ** Function         nci_proc_prop_rsp
440 **
441 ** Description      Process NCI responses in the Proprietary group
442 **
443 ** Returns          void
444 **
445 *******************************************************************************/
nci_proc_prop_rsp(BT_HDR * p_msg)446 void nci_proc_prop_rsp (BT_HDR *p_msg)
447 {
448     UINT8   *p;
449     UINT8   *p_evt;
450     UINT8   *pp, len, op_code;
451     tNFC_VS_CBACK   *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
452 
453     /* find the start of the NCI message and parse the NCI header */
454     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
455     pp  = p+1;
456     NCI_MSG_PRS_HDR1 (pp, op_code);
457     len = *pp++;
458 
459     /*If there's a pending/stored command, restore the associated address of the callback function */
460     if (p_cback)
461         (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
462 }
463 
464 /*******************************************************************************
465 **
466 ** Function         nci_proc_prop_ntf
467 **
468 ** Description      Process NCI notifications in the Proprietary group
469 **
470 ** Returns          void
471 **
472 *******************************************************************************/
nci_proc_prop_ntf(BT_HDR * p_msg)473 void nci_proc_prop_ntf (BT_HDR *p_msg)
474 {
475     UINT8   *p;
476     UINT8   *p_evt;
477     UINT8   *pp, len, op_code;
478     int i;
479 
480     /* find the start of the NCI message and parse the NCI header */
481     p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
482     pp  = p+1;
483     NCI_MSG_PRS_HDR1 (pp, op_code);
484     len = *pp++;
485 
486     for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
487     {
488         if (nfc_cb.p_vs_cb[i])
489         {
490             (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
491         }
492     }
493 }
494 
495 #endif /* NFC_INCLUDED == TRUE*/
496