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