nci_hrcv.c revision e9df6ba5a8fcccf306a80b1670b423be8fe7746a
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*******************************************************************************/
45BOOLEAN 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*******************************************************************************/
104void 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*******************************************************************************/
156void 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*******************************************************************************/
222void 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*******************************************************************************/
290void 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*******************************************************************************/
350void 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*******************************************************************************/
432void 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*******************************************************************************/
459void 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