nci_hrcv.c revision 5c65c3a0f42e174e47fecd4e569606003217ff4e
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2013 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*******************************************************************************/
46BOOLEAN 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*******************************************************************************/
105void 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*******************************************************************************/
157void 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        nfc_ncif_rf_management_status (NFC_START_DEVT, *pp);
173        break;
174
175    case NCI_MSG_RF_DISCOVER_SELECT:
176        nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp);
177        break;
178
179    case NCI_MSG_RF_T3T_POLLING:
180        break;
181
182    case NCI_MSG_RF_DISCOVER_MAP:
183        nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp);
184        break;
185
186    case NCI_MSG_RF_DEACTIVATE:
187        nfc_ncif_proc_deactivate (*pp, *p_old, FALSE);
188        break;
189
190#if (NFC_NFCEE_INCLUDED == TRUE)
191#if (NFC_RW_ONLY == FALSE)
192
193    case NCI_MSG_RF_SET_ROUTING:
194        nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp);
195        break;
196
197    case NCI_MSG_RF_GET_ROUTING:
198        if (*pp != NFC_STATUS_OK)
199            nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp);
200        break;
201#endif
202#endif
203
204    case NCI_MSG_RF_PARAMETER_UPDATE:
205        nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp);
206        break;
207
208    default:
209        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
210        break;
211    }
212}
213
214/*******************************************************************************
215**
216** Function         nci_proc_rf_management_ntf
217**
218** Description      Process NCI notifications in the RF Management group
219**
220** Returns          void
221**
222*******************************************************************************/
223void nci_proc_rf_management_ntf (BT_HDR *p_msg)
224{
225    UINT8   *p;
226    UINT8   *pp, len, op_code;
227
228    /* find the start of the NCI message and parse the NCI header */
229    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
230    pp  = p+1;
231    NCI_MSG_PRS_HDR1 (pp, op_code);
232    len = *pp++;
233
234    switch (op_code)
235    {
236    case NCI_MSG_RF_DISCOVER :
237        nfc_ncif_proc_discover_ntf (p, p_msg->len);
238        break;
239
240    case NCI_MSG_RF_DEACTIVATE:
241        nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE);
242        break;
243
244    case NCI_MSG_RF_INTF_ACTIVATED:
245        nfc_ncif_proc_activate (pp, len);
246        break;
247
248    case NCI_MSG_RF_FIELD:
249        nfc_ncif_proc_rf_field_ntf (*pp);
250        break;
251
252    case NCI_MSG_RF_T3T_POLLING:
253        nfc_ncif_proc_t3t_polling_ntf (pp, len);
254        break;
255
256#if (NFC_NFCEE_INCLUDED == TRUE)
257#if (NFC_RW_ONLY == FALSE)
258
259    case NCI_MSG_RF_GET_ROUTING:
260        nfc_ncif_proc_get_routing (pp, len);
261        break;
262
263    case NCI_MSG_RF_EE_ACTION:
264        nfc_ncif_proc_ee_action (pp, len);
265        break;
266
267    case NCI_MSG_RF_EE_DISCOVERY_REQ:
268        nfc_ncif_proc_ee_discover_req (pp, len);
269        break;
270#endif
271#endif
272
273    default:
274        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
275        break;
276    }
277}
278
279#if (NFC_NFCEE_INCLUDED == TRUE)
280#if (NFC_RW_ONLY == FALSE)
281
282/*******************************************************************************
283**
284** Function         nci_proc_ee_management_rsp
285**
286** Description      Process NCI responses in the NFCEE Management group
287**
288** Returns          void
289**
290*******************************************************************************/
291void nci_proc_ee_management_rsp (BT_HDR *p_msg)
292{
293    UINT8   *p;
294    UINT8   *pp, len, op_code;
295    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
296    tNFC_NFCEE_DISCOVER_REVT    nfcee_discover;
297    tNFC_NFCEE_INFO_REVT        nfcee_info;
298    tNFC_NFCEE_MODE_SET_REVT    mode_set;
299    tNFC_RESPONSE   *p_evt = (tNFC_RESPONSE *) &nfcee_info;
300    tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT;
301    UINT8   *p_old = nfc_cb.last_cmd;
302
303    /* find the start of the NCI message and parse the NCI header */
304    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
305    pp  = p+1;
306    NCI_MSG_PRS_HDR1 (pp, op_code);
307    NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code);
308    len = *pp++;
309
310    switch (op_code)
311    {
312    case NCI_MSG_NFCEE_DISCOVER:
313        p_evt                       = (tNFC_RESPONSE *) &nfcee_discover;
314        nfcee_discover.status       = *pp++;
315        nfcee_discover.num_nfcee    = *pp++;
316
317        if (nfcee_discover.status != NFC_STATUS_OK)
318            nfcee_discover.num_nfcee    = 0;
319
320        event                       = NFC_NFCEE_DISCOVER_REVT;
321        break;
322
323    case NCI_MSG_NFCEE_MODE_SET:
324        p_evt                   = (tNFC_RESPONSE *) &mode_set;
325        mode_set.status         = *pp;
326        mode_set.nfcee_id       = 0;
327        event                   = NFC_NFCEE_MODE_SET_REVT;
328        mode_set.nfcee_id       = *p_old++;
329        mode_set.mode           = *p_old++;
330        break;
331
332    default:
333        p_cback = NULL;
334        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
335        break;
336    }
337
338    if (p_cback)
339        (*p_cback) (event, p_evt);
340}
341
342/*******************************************************************************
343**
344** Function         nci_proc_ee_management_ntf
345**
346** Description      Process NCI notifications in the NFCEE Management group
347**
348** Returns          void
349**
350*******************************************************************************/
351void nci_proc_ee_management_ntf (BT_HDR *p_msg)
352{
353    UINT8                 *p;
354    UINT8                 *pp, len, op_code;
355    tNFC_RESPONSE_CBACK   *p_cback = nfc_cb.p_resp_cback;
356    tNFC_NFCEE_INFO_REVT  nfcee_info;
357    tNFC_RESPONSE         *p_evt   = (tNFC_RESPONSE *) &nfcee_info;
358    tNFC_RESPONSE_EVT     event    = NFC_NFCEE_INFO_REVT;
359    UINT8                 xx;
360    UINT8                 yy;
361    UINT8                 ee_status;
362    tNFC_NFCEE_TLV        *p_tlv;
363
364    /* find the start of the NCI message and parse the NCI header */
365    p   = (UINT8 *) (p_msg + 1) + p_msg->offset;
366    pp  = p+1;
367    NCI_MSG_PRS_HDR1 (pp, op_code);
368    NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code);
369    len = *pp++;
370
371    if (op_code == NCI_MSG_NFCEE_DISCOVER)
372    {
373        nfcee_info.nfcee_id    = *pp++;
374        ee_status                   = *pp++;
375
376        nfcee_info.ee_status        = ee_status;
377        yy                          = *pp;
378        nfcee_info.num_interface    = *pp++;
379        p                           = pp;
380
381        if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE)
382            nfcee_info.num_interface = NFC_MAX_EE_INTERFACE;
383
384        for (xx = 0; xx < nfcee_info.num_interface; xx++)
385        {
386            nfcee_info.ee_interface[xx] = *pp++;
387        }
388
389        pp                              = p + yy;
390        nfcee_info.num_tlvs             = *pp++;
391        NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x",
392            nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs);
393
394        if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS)
395            nfcee_info.num_tlvs = NFC_MAX_EE_TLVS;
396
397        p_tlv = &nfcee_info.ee_tlv[0];
398
399        for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++)
400        {
401            p_tlv->tag  = *pp++;
402            p_tlv->len  = yy = *pp++;
403            NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len);
404            if (p_tlv->len > NFC_MAX_EE_INFO)
405                p_tlv->len = NFC_MAX_EE_INFO;
406            p   = pp;
407            STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len);
408            pp  = p += yy;
409        }
410    }
411    else
412    {
413        p_cback = NULL;
414        NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code);
415    }
416
417    if (p_cback)
418        (*p_cback) (event, p_evt);
419}
420
421#endif
422#endif
423
424/*******************************************************************************
425**
426** Function         nci_proc_prop_rsp
427**
428** Description      Process NCI responses in the Proprietary group
429**
430** Returns          void
431**
432*******************************************************************************/
433void nci_proc_prop_rsp (BT_HDR *p_msg)
434{
435    UINT8   *p;
436    UINT8   *p_evt;
437    UINT8   *pp, len, op_code;
438    tNFC_VS_CBACK   *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback;
439
440    /* find the start of the NCI message and parse the NCI header */
441    p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
442    pp  = p+1;
443    NCI_MSG_PRS_HDR1 (pp, op_code);
444    len = *pp++;
445
446    /*If there's a pending/stored command, restore the associated address of the callback function */
447    if (p_cback)
448        (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt);
449}
450
451/*******************************************************************************
452**
453** Function         nci_proc_prop_ntf
454**
455** Description      Process NCI notifications in the Proprietary group
456**
457** Returns          void
458**
459*******************************************************************************/
460void nci_proc_prop_ntf (BT_HDR *p_msg)
461{
462    UINT8   *p;
463    UINT8   *p_evt;
464    UINT8   *pp, len, op_code;
465    int i;
466
467    /* find the start of the NCI message and parse the NCI header */
468    p   = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset;
469    pp  = p+1;
470    NCI_MSG_PRS_HDR1 (pp, op_code);
471    len = *pp++;
472
473    for (i = 0; i < NFC_NUM_VS_CBACKS; i++)
474    {
475        if (nfc_cb.p_vs_cb[i])
476        {
477            (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt);
478        }
479    }
480}
481
482#endif /* NFC_INCLUDED == TRUE*/
483