nfc_ncif.c revision e29968cf3e053557a9c2efc5a7a42d0767c51d9d
1/*****************************************************************************
2**
3**  Name:          nfc_ncif.c
4**
5**  Description:   This file contains functions that interface with the NFC NCI
6**                 transport. On the receive side, it routes events to
7**                 the appropriate handler (callback). On the
8**                 transmit side, it manages the command transmission.
9**
10**
11**  Copyright (c) 1999-2012, Broadcom Corp., All Rights Reserved.
12**  Broadcom Bluetooth Core. Proprietary and confidential.
13**
14******************************************************************************/
15#include <string.h>
16#include "nfc_target.h"
17
18#if NFC_INCLUDED == TRUE
19#include "nfc_api.h"
20#include "nci_defs.h"
21#include "nci_int.h"
22#include "nci_hmsgs.h"
23#include "nfc_int.h"
24#include "rw_api.h"
25#include "rw_int.h"
26#include "hcidefs.h"
27
28#if (NFC_RW_ONLY == FALSE)
29static const UINT8 nfc_mpl_code_to_size[] =
30{64, 128, 192, 254};
31
32#endif /* NFC_RW_ONLY */
33
34
35#define NFC_PB_ATTRIB_REQ_FIXED_BYTES   1
36#define NFC_LB_ATTRIB_REQ_FIXED_BYTES   8
37
38
39
40
41
42/*******************************************************************************
43**
44** Function         nfc_wait_2_deactivate_timeout
45**
46** Description      Handle a command timeout
47**
48** Returns          void
49**
50*******************************************************************************/
51void nfc_wait_2_deactivate_timeout (void)
52{
53    NFC_TRACE_ERROR0("nfc_wait_2_deactivate_timeout");
54    nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
55    nci_snd_deactivate_cmd ((UINT8)((TIMER_PARAM_TYPE)nfc_cb.deactivate_timer.param));
56}
57
58
59/*******************************************************************************
60**
61** Function         nfc_ncif_send_data
62**
63** Description      This function is called to add the NCI data header
64**                  and send it to NCI task for sending it to transport
65**                  as credits are available.
66**
67** Returns          void
68**
69*******************************************************************************/
70UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data)
71{
72    UINT8   *pp;
73    UINT8   hdr0 = p_cb->conn_id;
74    UINT8   pbf  = 0;
75    UINT8   ulen = (UINT8)(p_data->len);
76
77    p_data->event           = BT_EVT_TO_NFC_NCI;
78    p_data->layer_specific  = p_cb->conn_id;
79    p_data->len            += NCI_DATA_HDR_SIZE;
80    p_data->offset         -= NCI_DATA_HDR_SIZE;
81    pp = (UINT8 *)(p_data + 1) + p_data->offset;
82    /* build NCI Data packet header */
83    NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
84
85    /* post the p_buf to NCI task */
86    GKI_send_msg (NCI_TASK, NCI_TASK_MBOX, p_data);
87
88    return (NCI_STATUS_OK);
89}
90
91/*******************************************************************************
92**
93** Function         nfc_ncif_send_vsc
94**
95** Description      Send NCI VS command to the NCI task
96**
97** Returns          void
98**
99*******************************************************************************/
100void nfc_ncif_send_vsc (BT_HDR *p_buf)
101{
102    /* post the p_buf to NCI task */
103    p_buf->event            = BT_EVT_TO_NFC_NCI;
104    p_buf->layer_specific   = NCI_MSGS_LS_NCI_VSC;
105    GKI_send_msg (NCI_TASK, NCI_TASK_MBOX, p_buf);
106}
107
108
109/*******************************************************************************
110**
111** Function         nfc_ncif_send_cmd
112**
113** Description      Send NCI command to the NCI task
114**
115** Returns          void
116**
117*******************************************************************************/
118void nfc_ncif_send_cmd (BT_HDR *p_buf)
119{
120    /* post the p_buf to NCI task */
121    p_buf->event            = BT_EVT_TO_NFC_NCI;
122    p_buf->layer_specific   = NCI_MSGS_LS_CONTROL;
123    GKI_send_msg (NCI_TASK, NCI_TASK_MBOX, p_buf);
124}
125
126
127/*******************************************************************************
128**
129** Function         nfc_ncif_process_event
130**
131** Description      This function is called to process the data/response/notification
132**                  from NFCC
133**
134** Returns          TRUE if need to free buffer
135**
136*******************************************************************************/
137BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg)
138{
139    UINT8   mt, pbf, gid, *p, *pp;
140    BOOLEAN free = TRUE;
141    UINT8   oid;
142
143    p = (UINT8 *)(p_msg + 1) + p_msg->offset;
144
145    pp = p;
146    NCI_MSG_PRS_HDR0(pp, mt, pbf, gid);
147
148    switch (mt)
149    {
150    case NCI_MT_DATA:
151        NFC_TRACE_DEBUG0( "NFC received data");
152        nfc_ncif_proc_data(p_msg);
153        free = FALSE;
154        break;
155
156    case NCI_MT_RSP:
157        NFC_TRACE_DEBUG1( "NFC received rsp gid:%d", gid);
158        oid = ((*pp) & NCI_OID_MASK);
159        switch (gid)
160        {
161        case NCI_GID_CORE:      /* 0000b NCI Core group */
162            free = nci_proc_core_rsp(p_msg);
163            break;
164        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
165            nci_proc_rf_management_rsp(p_msg);
166            break;
167#if (NFC_NFCEE_INCLUDED == TRUE)
168#if (NFC_RW_ONLY == FALSE)
169        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
170            nci_proc_ee_management_rsp(p_msg);
171            break;
172#endif
173#endif
174        case NCI_GID_PROP:      /* 1111b Proprietary */
175            if (nfc_cb.p_vs_evt_hdlr)
176                (*nfc_cb.p_vs_evt_hdlr)(NFC_INT_NCI_VS_RSP_EVT, p_msg);
177            else
178                nci_proc_prop_rsp (p_msg);
179            break;
180        default:
181            NFC_TRACE_ERROR1( "NFC: Unknown gid:%d", gid);
182            break;
183        }
184
185
186        break;
187
188    case NCI_MT_NTF:
189        NFC_TRACE_DEBUG1( "NFC received ntf gid:%d", gid);
190        switch (gid)
191        {
192        case NCI_GID_CORE:      /* 0000b NCI Core group */
193            nci_proc_core_ntf(p_msg);
194            break;
195        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
196            nci_proc_rf_management_ntf(p_msg);
197            break;
198#if (NFC_NFCEE_INCLUDED == TRUE)
199#if (NFC_RW_ONLY == FALSE)
200        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
201            nci_proc_ee_management_ntf(p_msg);
202            break;
203#endif
204#endif
205        case NCI_GID_PROP:      /* 1111b Proprietary */
206            if (nfc_cb.p_vs_evt_hdlr)
207                (*nfc_cb.p_vs_evt_hdlr)(NFC_INT_NCI_VS_NTF_EVT, p_msg);
208            else
209                nci_proc_prop_ntf (p_msg);
210            break;
211        default:
212            NFC_TRACE_ERROR1( "NFC: Unknown gid:%d", gid);
213            break;
214        }
215        break;
216
217    default:
218        NFC_TRACE_DEBUG2( "NFC received unknown mt:0x%x, gid:%d", mt, gid);
219    }
220
221    return (free);
222}
223
224/*******************************************************************************
225**
226** Function         nfc_ncif_rf_management_status
227**
228** Description      This function is called to report an event
229**
230** Returns          void
231**
232*******************************************************************************/
233void nfc_ncif_rf_management_status(tNFC_DISCOVER_EVT event, UINT8 status)
234{
235    tNFC_DISCOVER   evt_data;
236    if (nfc_cb.p_discv_cback)
237    {
238        evt_data.status = (tNFC_STATUS)status;
239        (*nfc_cb.p_discv_cback)(event, &evt_data);
240    }
241}
242
243/*******************************************************************************
244**
245** Function         nfc_ncif_set_config_status
246**
247** Description      This function is called to report NFC_SET_CONFIG_REVT
248**
249** Returns          void
250**
251*******************************************************************************/
252void nfc_ncif_set_config_status (UINT8 *p, UINT8 len)
253{
254    tNFC_RESPONSE   evt_data;
255    if (nfc_cb.p_resp_cback)
256    {
257        evt_data.set_config.status          = (tNFC_STATUS)*p++;
258        evt_data.set_config.num_param_id    = NFC_STATUS_OK;
259        if (evt_data.set_config.status != NFC_STATUS_OK)
260        {
261            evt_data.set_config.num_param_id    = *p++;
262            STREAM_TO_ARRAY(evt_data.set_config.param_ids, p, evt_data.set_config.num_param_id);
263        }
264
265        (*nfc_cb.p_resp_cback)(NFC_SET_CONFIG_REVT, &evt_data);
266    }
267}
268
269/*******************************************************************************
270**
271** Function         nfc_ncif_event_status
272**
273** Description      This function is called to report an event
274**
275** Returns          void
276**
277*******************************************************************************/
278void nfc_ncif_event_status(tNFC_RESPONSE_EVT event, UINT8 status)
279{
280    tNFC_RESPONSE   evt_data;
281    if (nfc_cb.p_resp_cback)
282    {
283        evt_data.status = (tNFC_STATUS)status;
284        (*nfc_cb.p_resp_cback)(event, &evt_data);
285    }
286}
287
288/*******************************************************************************
289**
290** Function         nfc_ncif_error_status
291**
292** Description      This function is called to report an error event to data cback
293**
294** Returns          void
295**
296*******************************************************************************/
297void nfc_ncif_error_status(UINT8 conn_id, UINT8 status)
298{
299    tNFC_CONN_CB * p_cb;
300    p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
301    if (p_cb && p_cb->p_cback)
302    {
303        (*p_cb->p_cback)(conn_id, NFC_ERROR_CEVT, (tNFC_CONN *) &status);
304    }
305}
306
307/*******************************************************************************
308**
309** Function         nfc_ncif_proc_rf_field_ntf
310**
311** Description      This function is called to process RF field notification
312**
313** Returns          void
314**
315*******************************************************************************/
316#if (NFC_RW_ONLY == FALSE)
317void nfc_ncif_proc_rf_field_ntf(UINT8 rf_status)
318{
319    tNFC_RESPONSE   evt_data;
320    if (nfc_cb.p_resp_cback)
321    {
322        evt_data.status            = (tNFC_STATUS)NFC_STATUS_OK;
323        evt_data.rf_field.rf_field = rf_status;
324        (*nfc_cb.p_resp_cback)(NFC_RF_FIELD_REVT, &evt_data);
325    }
326}
327#endif
328
329
330/*******************************************************************************
331**
332** Function         nfc_ncif_decode_rf_params
333**
334** Description      This function is called to process the detected technology
335**                  and mode and the associated parameters for DISCOVER_NTF and
336**                  ACTIVATE_NTF
337**
338** Returns          void
339**
340*******************************************************************************/
341UINT8 * nfc_ncif_decode_rf_params(tNFC_RF_TECH_PARAMS *p_param, UINT8 *p)
342{
343    tNFC_RF_PA_PARAMS   *p_pa;
344    UINT8               len, *p_start, u8;
345    tNFC_RF_PB_PARAMS   *p_pb;
346    tNFC_RF_LF_PARAMS   *p_lf;
347    tNFC_RF_PF_PARAMS   *p_pf;
348    tNFC_RF_PISO15693_PARAMS *p_i93;
349
350    len             = *p++;
351    p_start         = p;
352    switch (p_param->mode)
353    {
354    case NCI_DISCOVERY_TYPE_POLL_A:
355    case NCI_DISCOVERY_TYPE_POLL_A_ACTIVE:
356        p_pa        = &p_param->param.pa;
357        /*
358SENS_RES Response   2 bytes Defined in [DIGPROT] Available after Technology Detection
359NFCID1 length   1 byte  Length of NFCID1 Available after Collision Resolution
360NFCID1  4, 7, or 10 bytes   Defined in [DIGPROT]Available after Collision Resolution
361SEL_RES Response    1 byte  Defined in [DIGPROT]Available after Collision Resolution
362        */
363        STREAM_TO_ARRAY(p_pa->sens_res, p, 2);
364        p_pa->nfcid1_len     = *p++;
365        if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN)
366            p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN;
367        STREAM_TO_ARRAY(p_pa->nfcid1, p, p_pa->nfcid1_len);
368        u8                   = *p++;
369        if (u8)
370            p_pa->sel_rsp    = *p++;
371        break;
372
373    case NCI_DISCOVERY_TYPE_POLL_B:
374        /*
375SENSB_RES Response length (n)   1 byte  Length of SENSB_RES Response (Byte 2 - Byte 12 or 13)Available after Technology Detection
376SENSB_RES Response Byte 2 - Byte 12 or 13   11 or 12 bytes  Defined in [DIGPROT] Available after Technology Detection
377        */
378        p_pb                = &p_param->param.pb;
379        p_pb->sensb_res_len = *p++;
380        if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
381            p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
382        STREAM_TO_ARRAY(p_pb->sensb_res, p, p_pb->sensb_res_len);
383        memcpy(p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
384        break;
385
386    case NCI_DISCOVERY_TYPE_POLL_F:
387    case NCI_DISCOVERY_TYPE_POLL_F_ACTIVE:
388        /*
389Bit Rate    1 byte  1   212 kbps/2   424 kbps/0 and 3 to 255  RFU
390SENSF_RES Response length.(n) 1 byte  Length of SENSF_RES (Byte 2 - Byte 17 or 19).Available after Technology Detection
391SENSF_RES Response Byte 2 - Byte 17 or 19  n bytes Defined in [DIGPROT] Available after Technology Detection
392        */
393        p_pf                = &p_param->param.pf;
394        p_pf->bit_rate      = *p++;
395        p_pf->sensf_res_len = *p++;
396        if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
397            p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
398        STREAM_TO_ARRAY(p_pf->sensf_res, p, p_pf->sensf_res_len);
399        memcpy(p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
400        p_pf->mrti_check    = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
401        p_pf->mrti_update   = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
402        break;
403
404    case NCI_DISCOVERY_TYPE_LISTEN_F:
405    case NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
406        p_lf                = &p_param->param.lf;
407        u8                  = *p++;
408        if (u8)
409        {
410            STREAM_TO_ARRAY(p_lf->nfcid2, p, NCI_NFCID2_LEN);
411        }
412        break;
413
414    case NCI_DISCOVERY_TYPE_POLL_ISO15693:
415        p_i93               = &p_param->param.pi93;
416        p_i93->flag         = *p++;
417        p_i93->dsfid        = *p++;
418        STREAM_TO_ARRAY(p_i93->uid, p, NFC_ISO15693_UID_LEN);
419        break;
420
421    case NCI_DISCOVERY_TYPE_POLL_KOVIO:
422        p_param->param.pk.uid_len = *p++;
423        STREAM_TO_ARRAY(p_param->param.pk.uid, p, NFC_KOVIO_MAX_LEN);
424        break;
425    }
426
427    return (p_start + len);
428}
429
430/*******************************************************************************
431**
432** Function         nfc_ncif_proc_discover_ntf
433**
434** Description      This function is called to process discover notification
435**
436** Returns          void
437**
438*******************************************************************************/
439void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen)
440{
441    tNFC_DISCOVER   evt_data;
442
443    if (nfc_cb.p_discv_cback)
444    {
445        p                              += NCI_MSG_HDR_SIZE;
446        evt_data.status                 = NCI_STATUS_OK;
447        evt_data.result.rf_disc_id      = *p++;
448        evt_data.result.protocol        = *p++;
449
450        /* fill in tNFC_RESULT_DEVT */
451        evt_data.result.rf_tech_param.mode  = *p++;
452        p = nfc_ncif_decode_rf_params(&evt_data.result.rf_tech_param, p);
453
454        evt_data.result.more            = *p++;
455        (*nfc_cb.p_discv_cback)(NFC_RESULT_DEVT, &evt_data);
456    }
457}
458
459/*******************************************************************************
460**
461** Function         nfc_ncif_proc_activate
462**
463** Description      This function is called to process de-activate
464**                  response and notification
465**
466** Returns          void
467**
468*******************************************************************************/
469void nfc_ncif_proc_activate(UINT8 *p, UINT8 len)
470{
471    tNFC_DISCOVER   evt_data;
472    tNFC_INTF_PARAMS        *p_intf = &evt_data.activate.intf_param;
473    tNFC_INTF_PA_ISO_DEP    *p_pa_iso;
474    tNFC_INTF_LB_ISO_DEP    *p_lb_iso;
475    tNFC_INTF_PB_ISO_DEP    *p_pb_iso;
476#if (NFC_RW_ONLY == FALSE)
477    tNFC_INTF_PA_NFC_DEP    *p_pa_nfc;
478    int                     mpl_idx = 0;
479    UINT8                   gb_idx = 0, mpl;
480#endif
481    UINT8                   t0;
482    tNCI_DISCOVERY_TYPE     mode;
483    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
484    UINT8                   *pp, len_act;
485    tNFC_ACTIVATE_MSGS      *p_msgs;
486    UINT8                   buff_size, num_buff;
487
488    nfc_set_state (NFC_STATE_OPEN);
489
490    memset (p_intf, 0, sizeof(tNFC_INTF_PARAMS));
491    evt_data.activate.rf_disc_id    = *p++;
492    p_intf->type                    = *p++;
493    evt_data.activate.protocol      = *p++;
494
495    if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE)
496        evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP;
497
498    evt_data.activate.rf_tech_param.mode    = *p++;
499    buff_size                               = *p++;
500    num_buff                                = *p++;
501    /* fill in tNFC_activate_DEVT */
502    p = nfc_ncif_decode_rf_params(&evt_data.activate.rf_tech_param, p);
503
504    evt_data.activate.rf_tech_param.mode    = *p++;
505    evt_data.activate.tx_bitrate            = *p++;
506    evt_data.activate.rx_bitrate            = *p++;
507    mode         = evt_data.activate.rf_tech_param.mode;
508    len_act      = *p++;
509    NFC_TRACE_DEBUG3( "nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act, mode);
510    /* just in case the interface reports activation parameters not defined in the NCI spec */
511    p_intf->intf_param.frame.param_len      = len_act;
512    if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS)
513        p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS;
514    pp = p;
515    STREAM_TO_ARRAY(p_intf->intf_param.frame.param, pp, p_intf->intf_param.frame.param_len);
516    if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP)
517    {
518        /* Make max payload of NCI aligned to max payload of ISO-DEP for better performance */
519        if (buff_size > NCI_ISO_DEP_MAX_INFO)
520            buff_size = NCI_ISO_DEP_MAX_INFO;
521
522        switch (mode)
523        {
524        case NCI_DISCOVERY_TYPE_POLL_A:
525            p_pa_iso                  = &p_intf->intf_param.pa_iso;
526            p_pa_iso->ats_res_len     = *p++;
527
528            if (p_pa_iso->ats_res_len == 0)
529                break;
530
531            if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN)
532                p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN;
533            STREAM_TO_ARRAY(p_pa_iso->ats_res, p, p_pa_iso->ats_res_len);
534            pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
535            t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
536            pp++;       /* T0 */
537            if (t0 & NCI_ATS_TA_MASK)
538                pp++;   /* TA */
539            if (t0 & NCI_ATS_TB_MASK)
540            {
541                /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time Integer) */
542                p_pa_iso->fwi       = (((*pp) >> 4) & 0x0F);
543                p_pa_iso->sfgi      = ((*pp) & 0x0F);
544                pp++;   /* TB */
545            }
546            if (t0 & NCI_ATS_TC_MASK)
547            {
548                p_pa_iso->nad_used  = ((*pp) & 0x01);
549                pp++;   /* TC */
550            }
551            p_pa_iso->his_byte_len  = (UINT8)(p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
552            memcpy (p_pa_iso->his_byte,  pp, p_pa_iso->his_byte_len);
553            break;
554
555        case NCI_DISCOVERY_TYPE_LISTEN_A:
556            p_intf->intf_param.la_iso.rats = *p++;
557            break;
558
559        case NCI_DISCOVERY_TYPE_POLL_B:
560            /* ATTRIB RSP
561            Byte 1   Byte 2 ~ 2+n-1
562            MBLI/DID Higher layer - Response
563            */
564            p_pb_iso                     = &p_intf->intf_param.pb_iso;
565            p_pb_iso->attrib_res_len     = *p++;
566
567            if (p_pb_iso->attrib_res_len == 0)
568                break;
569
570            if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
571                p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
572            STREAM_TO_ARRAY(p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
573            p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
574            if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES)
575            {
576                p_pb_iso->hi_info_len    = p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
577                if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
578                    p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
579                memcpy (p_pb_iso->hi_info, &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES], p_pb_iso->hi_info_len);
580            }
581            break;
582
583        case NCI_DISCOVERY_TYPE_LISTEN_B:
584            /* ATTRIB CMD
585            Byte 2~5 Byte 6  Byte 7  Byte 8  Byte 9  Byte 10 ~ 10+k-1
586            NFCID0   Param 1 Param 2 Param 3 Param 4 Higher layer - INF
587            */
588            p_lb_iso                     = &p_intf->intf_param.lb_iso;
589            p_lb_iso->attrib_req_len     = *p++;
590
591            if (p_lb_iso->attrib_req_len == 0)
592                break;
593
594            if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
595                p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
596            STREAM_TO_ARRAY(p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
597            memcpy (p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
598            if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES)
599            {
600                p_lb_iso->hi_info_len    = p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
601                if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
602                    p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
603                memcpy (p_lb_iso->hi_info, &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES], p_lb_iso->hi_info_len);
604            }
605            break;
606        }
607
608    }
609#if (NFC_RW_ONLY == FALSE)
610    else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP)
611    {
612        /* Make max payload of NCI aligned to max payload of NFC-DEP for better performance */
613        if (buff_size > NCI_NFC_DEP_MAX_DATA)
614            buff_size = NCI_NFC_DEP_MAX_DATA;
615
616        p_pa_nfc                  = &p_intf->intf_param.pa_nfc;
617        p_pa_nfc->atr_res_len     = *p++;
618
619        if (p_pa_nfc->atr_res_len > 0)
620        {
621            if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
622                p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
623            STREAM_TO_ARRAY(p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
624            if ((mode == NCI_DISCOVERY_TYPE_POLL_A)
625              ||(mode == NCI_DISCOVERY_TYPE_POLL_F)
626              ||(mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE)
627              ||(mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE))
628            {
629                /* ATR_RES
630                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
631                NFCID3T   DIDT    BST     BRT     TO      PPT     [GT0 ... GTn] */
632                mpl_idx                 = 14;
633                gb_idx                  = NCI_P_GEN_BYTE_INDEX;
634                p_pa_nfc->waiting_time  = p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
635            }
636            else if ((mode == NCI_DISCOVERY_TYPE_LISTEN_A)
637                   ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F)
638                   ||(mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE)
639                   ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE))
640            {
641                /* ATR_REQ
642                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
643                NFCID3I   DIDI    BSI     BRI     PPI     [GI0 ... GIn] */
644                mpl_idx = 13;
645                gb_idx  = NCI_L_GEN_BYTE_INDEX;
646            }
647
648            mpl                         = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
649            p_pa_nfc->max_payload_size  = nfc_mpl_code_to_size[mpl];
650            if (p_pa_nfc->atr_res_len > gb_idx)
651            {
652                p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
653                if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
654                    p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
655                memcpy(p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx], p_pa_nfc->gen_bytes_len);
656            }
657        }
658    }
659#endif
660        p_cb->act_protocol = evt_data.activate.protocol;
661
662    /* update RF connection buffer size and credit on NCI task before calling callback function */
663    p_msgs = (tNFC_ACTIVATE_MSGS *) GKI_getbuf(sizeof (tNFC_ACTIVATE_MSGS));
664    if (p_msgs)
665    {
666        p_msgs->buff_size               = buff_size;
667        p_msgs->num_buff                = num_buff;
668        p_msgs->bt_hdr.event            = BT_EVT_TO_NFC_MSGS;
669        p_msgs->bt_hdr.layer_specific   = NFC_MSGS_RF_ACT_CREDITS;
670        GKI_send_msg (NCI_TASK, NCI_TASK_MBOX, p_msgs);
671    }
672
673    if (nfc_cb.p_discv_cback)
674    {
675        (*nfc_cb.p_discv_cback)(NFC_ACTIVATE_DEVT, &evt_data);
676    }
677}
678
679/*******************************************************************************
680**
681** Function         nfc_ncif_proc_deactivate
682**
683** Description      This function is called to process de-activate
684**                  response and notification
685**
686** Returns          void
687**
688*******************************************************************************/
689void nfc_ncif_proc_deactivate(UINT8 status, UINT8 deact_type, BOOLEAN is_ntf)
690{
691    tNFC_DISCOVER   evt_data;
692    tNFC_DEACTIVATE_DEVT    *p_deact;
693    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
694    void    *p_data;
695
696    nfc_set_state (NFC_STATE_IDLE);
697    p_deact             = &evt_data.deactivate;
698    p_deact->status     = status;
699    p_deact->type       = deact_type;
700    p_deact->is_ntf     = is_ntf;
701
702    while ( (p_data = GKI_dequeue(&p_cb->rx_q)) != NULL)
703    {
704        GKI_freebuf(p_data);
705    }
706
707    if (p_cb->p_cback)
708        (*p_cb->p_cback)(NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) p_deact);
709
710    if (nfc_cb.p_discv_cback)
711    {
712        (*nfc_cb.p_discv_cback)(NFC_DEACTIVATE_DEVT, &evt_data);
713    }
714}
715/*******************************************************************************
716**
717** Function         nfc_ncif_proc_ee_action
718**
719** Description      This function is called to process NFCEE ACTION NTF
720**
721** Returns          void
722**
723*******************************************************************************/
724#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
725void nfc_ncif_proc_ee_action(UINT8 *p, UINT16 plen)
726{
727    tNFC_EE_ACTION_REVT evt_data;
728    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
729    UINT8   data_len, ulen, tag, *p_data;
730    UINT8   max_len;
731
732    if (p_cback)
733    {
734        memset (&evt_data.act_data, 0, sizeof(tNFC_ACTION_DATA));
735        evt_data.status             = NFC_STATUS_OK;
736        evt_data.nfcee_id           = *p++;
737        evt_data.act_data.trigger   = *p++;
738        data_len                    = *p++;
739        if (plen >= 3)
740            plen -= 3;
741        if (data_len > plen)
742            data_len = (UINT8)plen;
743
744        switch (evt_data.act_data.trigger)
745        {
746        case NCI_EE_TRIG_7816_SELECT:
747            if (data_len > NFC_MAX_AID_LEN)
748                data_len = NFC_MAX_AID_LEN;
749            evt_data.act_data.param.aid.len_aid = data_len;
750            STREAM_TO_ARRAY(evt_data.act_data.param.aid.aid, p, data_len);
751            break;
752        case NCI_EE_TRIG_RF_PROTOCOL:
753            evt_data.act_data.param.protocol    = *p++;
754            break;
755        case NCI_EE_TRIG_RF_TECHNOLOGY:
756            evt_data.act_data.param.technology  = *p++;
757            break;
758        case NCI_EE_TRIG_APP_INIT:
759            while (data_len > NFC_TL_SIZE)
760            {
761                data_len    -= NFC_TL_SIZE;
762                tag         = *p++;
763                ulen        = *p++;
764                if (ulen > data_len)
765                    ulen = data_len;
766                p_data      = NULL;
767                max_len     = ulen;
768                switch(tag)
769                {
770                case NCI_EE_ACT_TAG_AID:    /* AID                 */
771                    if (max_len > NFC_MAX_AID_LEN)
772                        max_len = NFC_MAX_AID_LEN;
773                    evt_data.act_data.param.app_init.len_aid = max_len;
774                    p_data = evt_data.act_data.param.app_init.aid;
775                    break;
776                case NCI_EE_ACT_TAG_DATA:   /* hex data for app    */
777                    if (max_len > NFC_MAX_APP_DATA_LEN)
778                        max_len = NFC_MAX_APP_DATA_LEN;
779                    evt_data.act_data.param.app_init.len_data   = max_len;
780                    p_data                                      = evt_data.act_data.param.app_init.data;
781                    break;
782                }
783                if (p_data)
784                {
785                    STREAM_TO_ARRAY(p_data, p, max_len);
786                }
787                data_len -= ulen;
788            }
789            break;
790        }
791        (*p_cback) (NFC_EE_ACTION_REVT, (tNFC_RESPONSE *)&evt_data);
792    }
793}
794
795/*******************************************************************************
796**
797** Function         nfc_ncif_proc_ee_discover_req
798**
799** Description      This function is called to process NFCEE DISCOVER REQ NTF
800**
801** Returns          void
802**
803*******************************************************************************/
804void nfc_ncif_proc_ee_discover_req(UINT8 *p, UINT16 plen)
805{
806    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
807    tNFC_EE_DISCOVER_REQ_REVT   ee_disc_req;
808    tNFC_EE_DISCOVER_INFO       *p_info;
809    UINT8                       u8;
810
811    NFC_TRACE_DEBUG2( "nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
812    if (p_cback)
813    {
814        u8  = *p;
815        ee_disc_req.status      = NFC_STATUS_OK;
816        ee_disc_req.num_info    = *p++;
817        p_info                  = ee_disc_req.info;
818        if (plen)
819            plen--;
820        while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN))
821        {
822            p_info->op  = *p++;                  /* T */
823            if (*p != NFC_EE_DISCOVER_INFO_LEN)/* L */
824            {
825                NFC_TRACE_DEBUG1( "bad entry len:%d", *p );
826                return;
827            }
828            p++;
829            /* V */
830            p_info->nfcee_id    = *p++;
831            p_info->tech_n_mode = *p++;
832            p_info->protocol    = *p++;
833            u8--;
834            plen    -=NFC_EE_DISCOVER_ENTRY_LEN;
835            p_info++;
836        }
837        (*p_cback) (NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE *)&ee_disc_req);
838    }
839
840}
841
842/*******************************************************************************
843**
844** Function         nfc_ncif_proc_get_routing
845**
846** Description      This function is called to process get routing notification
847**
848** Returns          void
849**
850*******************************************************************************/
851void nfc_ncif_proc_get_routing(UINT8 *p, UINT8 len)
852{
853    tNFC_GET_ROUTING_REVT evt_data;
854    UINT8       more, num_entries, xx, yy, *pn, tl;
855    tNFC_STATUS status = NFC_STATUS_CONTINUE;
856
857    if (nfc_cb.p_resp_cback)
858    {
859        more        = *p++;
860        num_entries = *p++;
861        for (xx=0; xx<num_entries; xx++)
862        {
863            if ((more == FALSE) && (xx == (num_entries - 1)))
864                status = NFC_STATUS_OK;
865            evt_data.status         = (tNFC_STATUS)status;
866            evt_data.nfcee_id       = *p++;
867            evt_data.num_tlvs       = *p++;
868            evt_data.tlv_size       = 0;
869            pn                      = evt_data.param_tlvs;
870            for (yy=0; yy<evt_data.num_tlvs; yy++)
871            {
872                tl                  = *(p+1);
873                tl                 += NFC_TL_SIZE;
874                STREAM_TO_ARRAY(pn, p, tl);
875                evt_data.tlv_size  += tl;
876                pn                 += tl;
877            }
878            (*nfc_cb.p_resp_cback)(NFC_GET_ROUTING_REVT, (tNFC_RESPONSE *)&evt_data);
879        }
880    }
881}
882#endif
883
884/*******************************************************************************
885**
886** Function         nfc_ncif_proc_conn_create_rsp
887**
888** Description      This function is called to process connection create
889**                  response
890**
891** Returns          void
892**
893*******************************************************************************/
894void nfc_ncif_proc_conn_create_rsp (UINT8 *p, UINT16 plen, UINT8 dest_type)
895{
896    tNFC_CONN_CB * p_cb;
897    tNFC_STATUS    status;
898    tNFC_CONN_CBACK *p_cback;
899    tNFC_CONN   evt_data;
900    UINT8           conn_id;
901
902    /* find the pending connection control block */
903    p_cb                = nfc_find_conn_cb_by_conn_id(NFC_PEND_CONN_ID);
904    if (p_cb)
905    {
906        p                                  += NCI_MSG_HDR_SIZE;
907        status                              = *p++;
908        evt_data.conn_create.buff_size      = *p++;
909        evt_data.conn_create.num_buffs      = *p++;
910        conn_id                             = *p++;
911        evt_data.conn_create.status         = status;
912        evt_data.conn_create.dest_type      = dest_type;
913        evt_data.conn_create.id             = p_cb->id;
914        p_cback = p_cb->p_cback;
915        if (status == NCI_STATUS_OK)
916        {
917            nfc_set_conn_id(p_cb, conn_id);
918        }
919        else
920        {
921            nfc_free_conn_cb (p_cb);
922        }
923
924
925        if (p_cback)
926            (*p_cback)(conn_id, NFC_CONN_CREATE_CEVT, &evt_data);
927    }
928}
929
930/*******************************************************************************
931**
932** Function         nfc_ncif_report_conn_close_evt
933**
934** Description      This function is called to report connection close event
935**
936** Returns          void
937**
938*******************************************************************************/
939void nfc_ncif_report_conn_close_evt (UINT8 conn_id, tNFC_STATUS status)
940{
941    tNFC_CONN       evt_data;
942    tNFC_CONN_CBACK *p_cback;
943    tNFC_CONN_CB    *p_cb;
944
945    p_cb = nfc_find_conn_cb_by_conn_id(conn_id);
946    if (p_cb)
947    {
948        p_cback         = p_cb->p_cback;
949        nfc_free_conn_cb(p_cb);
950        evt_data.status = status;
951        if (p_cback)
952            (*p_cback)(conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
953    }
954}
955
956/*******************************************************************************
957**
958** Function         nfc_ncif_proc_reset_rsp
959**
960** Description      This function is called to process reset response/notification
961**
962** Returns          void
963**
964*******************************************************************************/
965void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf)
966{
967    UINT8 status = *p++;
968
969    if (is_ntf)
970    {
971        NFC_TRACE_ERROR1( "reset notification!!:0x%x ", status);
972        /* clean up, if the state is OPEN
973         * FW does not report reset ntf right now */
974        if (nfc_cb.nfc_state == NFC_STATE_OPEN)
975        {
976            /*if any conn_cb is connected, close it.
977              if any pending outgoing packets are dropped.*/
978            nfc_reset_all_conn_cbs();
979        }
980        status = NCI_STATUS_OK;
981    }
982
983    if (nfc_cb.nfc_state == NFC_STATE_RESTARTING)
984    {
985        nfc_reset_all_conn_cbs();
986    }
987
988    if (status == NCI_STATUS_OK)
989    {
990        if ((*p) != NCI_VERSION)
991        {
992            NFC_TRACE_ERROR2( "NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION, *p);
993            if ((*p) < NCI_VERSION_0_F)
994            {
995                NFC_TRACE_ERROR0( "NFCC version is too old");
996                nfc_enabled(NCI_STATUS_FAILED, NULL);
997                return;
998            }
999        }
1000
1001        nci_snd_core_init ();
1002    }
1003    else
1004    {
1005        NFC_TRACE_ERROR0 ("Failed to reset NFCC");
1006        nfc_enabled (status, NULL);
1007    }
1008}
1009
1010/*******************************************************************************
1011**
1012** Function         nfc_ncif_proc_init_rsp
1013**
1014** Description      This function is called to process init response
1015**
1016** Returns          void
1017**
1018*******************************************************************************/
1019void nfc_ncif_proc_init_rsp (BT_HDR *p_msg)
1020{
1021    UINT8 *p, status;
1022    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
1023
1024    p        = (UINT8 *)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
1025
1026    /* handle init params in nfc_enabled */
1027    status   = *p;
1028    if (status == NCI_STATUS_OK)
1029    {
1030        if (nfc_cb.p_vs_evt_hdlr)
1031            (*nfc_cb.p_vs_evt_hdlr)(NFC_INT_ENABLE_END_EVT, p_msg);
1032        p_cb->id            = NFC_RF_CONN_ID;
1033        p_cb->act_protocol  = NCI_PROTOCOL_UNKNOWN;
1034    }
1035
1036    nfc_enabled(status, p_msg);
1037    GKI_freebuf(p_msg);
1038}
1039
1040/*******************************************************************************
1041**
1042** Function         nfc_ncif_proc_get_config_rsp
1043**
1044** Description      This function is called to process get config response
1045**
1046** Returns          void
1047**
1048*******************************************************************************/
1049void nfc_ncif_proc_get_config_rsp (BT_HDR *p_evt)
1050{
1051    UINT8   *p;
1052    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
1053    tNFC_RESPONSE  evt_data;
1054
1055    p_evt->offset += NCI_MSG_HDR_SIZE;
1056    p_evt->len    -= NCI_MSG_HDR_SIZE;
1057    if (p_cback)
1058    {
1059        p                                = (UINT8 *)(p_evt + 1) + p_evt->offset;
1060        evt_data.get_config.status       = *p++;
1061        evt_data.get_config.tlv_size     = p_evt->len;
1062        evt_data.get_config.p_param_tlvs = p;
1063        (*p_cback)(NFC_GET_CONFIG_REVT, &evt_data);
1064    }
1065}
1066
1067/*******************************************************************************
1068**
1069** Function         nfc_ncif_proc_t3t_polling_ntf
1070**
1071** Description      Handle NCI_MSG_RF_T3T_POLLING NTF
1072**
1073** Returns          void
1074**
1075*******************************************************************************/
1076void nfc_ncif_proc_t3t_polling_ntf(UINT8 *p, UINT16 plen)
1077{
1078    UINT8 status;
1079    UINT8 num_responses;
1080
1081    /* Pass result to RW_T3T for processing */
1082    STREAM_TO_UINT8(status, p);
1083    STREAM_TO_UINT8(num_responses, p);
1084    plen-=NFC_TL_SIZE;
1085    rw_t3t_handle_nci_poll_ntf(status, num_responses, (UINT8)plen, p);
1086}
1087
1088/*******************************************************************************
1089**
1090** Function         nfc_data_event
1091**
1092** Description      Report Data event on the given connection control block
1093**
1094** Returns          void
1095**
1096*******************************************************************************/
1097void nfc_data_event(tNFC_CONN_CB * p_cb)
1098{
1099    BT_HDR      *p_evt;
1100    tNFC_DATA_CEVT data_cevt;
1101    UINT8       *p;
1102
1103    if (p_cb->p_cback)
1104    {
1105        while ( (p_evt = (BT_HDR *)GKI_dequeue(&p_cb->rx_q)) != NULL)
1106        {
1107            /* report data event */
1108            p_evt->offset   += NCI_MSG_HDR_SIZE;
1109            p_evt->len      -= NCI_MSG_HDR_SIZE;
1110            if (p_evt->layer_specific)
1111                data_cevt.status = NFC_STATUS_BAD_LENGTH;
1112            else
1113                data_cevt.status = NFC_STATUS_OK;
1114            data_cevt.p_data = p_evt;
1115            /* adjust payload, if needed */
1116            if (p_cb->conn_id == NFC_RF_CONN_ID)
1117            {
1118                /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status byte needs to be removed
1119                 */
1120                if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) && (p_cb->act_protocol <= NCI_PROTOCOL_T3T))
1121                {
1122                    p_evt->len--;
1123                    p                = (UINT8 *)(p_evt + 1);
1124                    data_cevt.status = *(p + p_evt->offset + p_evt->len);
1125                }
1126            }
1127            (*p_cb->p_cback)(p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN *)&data_cevt);
1128            p_evt = NULL;
1129        }
1130    }
1131}
1132
1133/*******************************************************************************
1134**
1135** Function         nfc_ncif_proc_data
1136**
1137** Description      Find the connection control block associated with the data
1138**                  packet and report the Data event.
1139**
1140** Returns          void
1141**
1142*******************************************************************************/
1143void nfc_ncif_proc_data(BT_HDR *p_msg)
1144{
1145    UINT8   *pp, cid, len;
1146    tNFC_CONN_CB * p_cb;
1147    UINT8   pbf;
1148
1149    pp   = (UINT8 *)(p_msg+1) + p_msg->offset;
1150    NFC_TRACE_DEBUG3( "nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
1151    NCI_DATA_PRS_HDR(pp, pbf, cid, len);
1152    p_cb = nfc_find_conn_cb_by_conn_id(cid);
1153    if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE))
1154    {
1155        NFC_TRACE_DEBUG1 ( "nfc_ncif_proc_data len:%d", len);
1156        if (len > 0)
1157        {
1158            GKI_enqueue (&p_cb->rx_q, p_msg);
1159            nfc_data_event (p_cb);
1160            return;
1161        }
1162        /* else an empty data packet*/
1163    }
1164    GKI_freebuf (p_msg);
1165}
1166
1167#endif /* NFC_INCLUDED == TRUE*/
1168