nfc_ncif.c revision 1c9ec36d38f5c62c9ab6874141e3559777046438
1/******************************************************************************
2 *
3 *  Copyright (C) 1999-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 functions that interface with the NFC NCI transport.
23 *  On the receive side, it routes events to the appropriate handler
24 *  (callback). On the transmit side, it manages the command transmission.
25 *
26 ******************************************************************************/
27#include <string.h>
28#include "nfc_target.h"
29
30#if NFC_INCLUDED == TRUE
31#include "nfc_hal_api.h"
32#include "nfc_api.h"
33#include "nci_defs.h"
34#include "nci_hmsgs.h"
35#include "nfc_int.h"
36#include "rw_api.h"
37#include "rw_int.h"
38#include "hcidefs.h"
39#include "nfc_hal_api.h"
40
41#if (NFC_RW_ONLY == FALSE)
42static const UINT8 nfc_mpl_code_to_size[] =
43{64, 128, 192, 254};
44
45#endif /* NFC_RW_ONLY */
46
47
48#define NFC_PB_ATTRIB_REQ_FIXED_BYTES   1
49#define NFC_LB_ATTRIB_REQ_FIXED_BYTES   8
50
51
52/*******************************************************************************
53**
54** Function         nfc_ncif_update_window
55**
56** Description      Update tx cmd window to indicate that NFCC can received
57**
58** Returns          void
59**
60*********************************************************************************/
61void nfc_ncif_update_window (void)
62{
63    /* Sanity check - see if we were expecting a update_window */
64    if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW)
65    {
66        if (nfc_cb.nfc_state != NFC_STATE_W4_HAL_CLOSE)
67        {
68            NFC_TRACE_ERROR0("nfc_ncif_update_window: Unexpected call");
69        }
70        return;
71    }
72
73    /* Stop command-pending timer */
74    nfc_stop_timer (&nfc_cb.nci_wait_rsp_timer);
75
76    nfc_cb.p_vsc_cback = NULL;
77    nfc_cb.nci_cmd_window++;
78
79    /* Check if there were any commands waiting to be sent */
80    nfc_ncif_check_cmd_queue (NULL);
81}
82
83/*******************************************************************************
84**
85** Function         nfc_ncif_cmd_timeout
86**
87** Description      Handle a command timeout
88**
89** Returns          void
90**
91*******************************************************************************/
92void nfc_ncif_cmd_timeout (void)
93{
94    NFC_TRACE_ERROR0 ("nfc_ncif_cmd_timeout");
95
96    /* report an error */
97    nfc_ncif_event_status(NFC_GEN_ERROR_REVT, NFC_STATUS_HW_TIMEOUT);
98    nfc_ncif_event_status(NFC_NFCC_TIMEOUT_REVT, NFC_STATUS_HW_TIMEOUT);
99
100    /* if enabling NFC, notify upper layer of failure */
101    if (nfc_cb.nfc_state == NFC_STATE_CORE_INIT)
102    {
103        nfc_enabled (NFC_STATUS_FAILED, NULL);
104    }
105
106    /* XXX maco since this failure is unrecoverable, abort the process */
107    abort();
108}
109
110/*******************************************************************************
111**
112** Function         nfc_wait_2_deactivate_timeout
113**
114** Description      Handle a command timeout
115**
116** Returns          void
117**
118*******************************************************************************/
119void nfc_wait_2_deactivate_timeout (void)
120{
121    NFC_TRACE_ERROR0 ("nfc_wait_2_deactivate_timeout");
122    nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
123    nci_snd_deactivate_cmd ((UINT8) ((TIMER_PARAM_TYPE) nfc_cb.deactivate_timer.param));
124}
125
126
127/*******************************************************************************
128**
129** Function         nfc_ncif_send_data
130**
131** Description      This function is called to add the NCI data header
132**                  and send it to NCIT task for sending it to transport
133**                  as credits are available.
134**
135** Returns          void
136**
137*******************************************************************************/
138UINT8 nfc_ncif_send_data (tNFC_CONN_CB *p_cb, BT_HDR *p_data)
139{
140    UINT8 *pp;
141    UINT8 *ps;
142    UINT8   ulen = NCI_MAX_PAYLOAD_SIZE;
143    BT_HDR *p;
144    UINT8   pbf = 1;
145    UINT8   buffer_size = p_cb->buff_size;
146    UINT8   hdr0 = p_cb->conn_id;
147    BOOLEAN fragmented = FALSE;
148
149    NFC_TRACE_DEBUG3 ("nfc_ncif_send_data :%d, num_buff:%d qc:%d", p_cb->conn_id, p_cb->num_buff, p_cb->tx_q.count);
150    if (p_cb->id == NFC_RF_CONN_ID)
151    {
152        if (nfc_cb.nfc_state != NFC_STATE_OPEN)
153        {
154            if (nfc_cb.nfc_state == NFC_STATE_CLOSING)
155            {
156                if ((p_data == NULL) && /* called because credit from NFCC */
157                    (nfc_cb.flags  & NFC_FL_DEACTIVATING))
158                {
159                    if (p_cb->init_credits == p_cb->num_buff)
160                    {
161                        /* all the credits are back */
162                        nfc_cb.flags  &= ~NFC_FL_DEACTIVATING;
163                        NFC_TRACE_DEBUG2 ("deactivating NFC-DEP init_credits:%d, num_buff:%d", p_cb->init_credits, p_cb->num_buff);
164                        nfc_stop_timer(&nfc_cb.deactivate_timer);
165                        nci_snd_deactivate_cmd ((UINT8)((TIMER_PARAM_TYPE)nfc_cb.deactivate_timer.param));
166                    }
167                }
168            }
169            return NCI_STATUS_FAILED;
170        }
171    }
172
173    if (p_data)
174    {
175        /* always enqueue the data to the tx queue */
176        GKI_enqueue (&p_cb->tx_q, p_data);
177    }
178
179    /* try to send the first data packet in the tx queue  */
180    p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
181
182    /* post data fragment to NCIT task as credits are available */
183    while (p_data && (p_data->len >= 0) && (p_cb->num_buff > 0))
184    {
185        if (p_data->len <= buffer_size)
186        {
187            pbf         = 0;   /* last fragment */
188            ulen        = (UINT8)(p_data->len);
189            fragmented  = FALSE;
190        }
191        else
192        {
193            fragmented  = TRUE;
194            ulen        = buffer_size;
195        }
196
197        if (!fragmented)
198        {
199            /* if data packet is not fragmented, use the original buffer */
200            p         = p_data;
201            p_data    = (BT_HDR *)GKI_dequeue (&p_cb->tx_q);
202        }
203        else
204        {
205            /* the data packet is too big and need to be fragmented
206             * prepare a new GKI buffer
207             * (even the last fragment to avoid issues) */
208            if ((p = NCI_GET_CMD_BUF(ulen)) == NULL)
209                return (NCI_STATUS_BUFFER_FULL);
210            p->len    = ulen;
211            p->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
212            if (p->len)
213            {
214            pp        = (UINT8 *)(p + 1) + p->offset;
215            ps        = (UINT8 *)(p_data + 1) + p_data->offset;
216            memcpy (pp, ps, ulen);
217            }
218            /* adjust the BT_HDR on the old fragment */
219            p_data->len     -= ulen;
220            p_data->offset  += ulen;
221        }
222
223        p->event             = BT_EVT_TO_NFC_NCI;
224        p->layer_specific    = pbf;
225        p->len              += NCI_DATA_HDR_SIZE;
226        p->offset           -= NCI_DATA_HDR_SIZE;
227        pp = (UINT8 *)(p + 1) + p->offset;
228        /* build NCI Data packet header */
229        NCI_DATA_PBLD_HDR(pp, pbf, hdr0, ulen);
230
231        if (p_cb->num_buff != NFC_CONN_NO_FC)
232            p_cb->num_buff--;
233
234        /* send to HAL */
235        HAL_WRITE(p);
236
237        if (!fragmented)
238        {
239            /* check if there are more data to send */
240            p_data = (BT_HDR *)GKI_getfirst (&p_cb->tx_q);
241        }
242    }
243
244    return (NCI_STATUS_OK);
245}
246
247/*******************************************************************************
248**
249** Function         nfc_ncif_check_cmd_queue
250**
251** Description      Send NCI command to the transport
252**
253** Returns          void
254**
255*******************************************************************************/
256void nfc_ncif_check_cmd_queue (BT_HDR *p_buf)
257{
258    UINT8   *ps;
259    /* If there are commands waiting in the xmit queue, or if the controller cannot accept any more commands, */
260    /* then enqueue this command */
261    if (p_buf)
262    {
263        if ((nfc_cb.nci_cmd_xmit_q.count) || (nfc_cb.nci_cmd_window == 0))
264        {
265            GKI_enqueue (&nfc_cb.nci_cmd_xmit_q, p_buf);
266            p_buf = NULL;
267        }
268    }
269
270    /* If controller can accept another command, then send the next command */
271    if (nfc_cb.nci_cmd_window > 0)
272    {
273        /* If no command was provided, or if older commands were in the queue, then get cmd from the queue */
274        if (!p_buf)
275            p_buf = (BT_HDR *)GKI_dequeue (&nfc_cb.nci_cmd_xmit_q);
276
277        if (p_buf)
278        {
279            /* save the message header to double check the response */
280            ps   = (UINT8 *)(p_buf + 1) + p_buf->offset;
281            memcpy(nfc_cb.last_hdr, ps, NFC_SAVED_HDR_SIZE);
282            memcpy(nfc_cb.last_cmd, ps + NCI_MSG_HDR_SIZE, NFC_SAVED_CMD_SIZE);
283            if (p_buf->layer_specific == NFC_WAIT_RSP_VSC)
284            {
285                /* save the callback for NCI VSCs)  */
286                nfc_cb.p_vsc_cback = (void *)((tNFC_NCI_VS_MSG *)p_buf)->p_cback;
287            }
288
289            /* send to HAL */
290            HAL_WRITE(p_buf);
291
292            /* Indicate command is pending */
293            nfc_cb.nci_cmd_window--;
294
295            /* start NFC command-timeout timer */
296            nfc_start_timer (&nfc_cb.nci_wait_rsp_timer, (UINT16)(NFC_TTYPE_NCI_WAIT_RSP), nfc_cb.nci_wait_rsp_tout);
297        }
298    }
299
300    if (nfc_cb.nci_cmd_window == NCI_MAX_CMD_WINDOW)
301    {
302        /* the command queue must be empty now */
303        if (nfc_cb.flags & NFC_FL_CONTROL_REQUESTED)
304        {
305            /* HAL requested control or stack needs to handle pre-discover */
306            nfc_cb.flags &= ~NFC_FL_CONTROL_REQUESTED;
307            if (nfc_cb.flags & NFC_FL_DISCOVER_PENDING)
308            {
309                if (nfc_cb.p_hal->prediscover ())
310                {
311                    /* HAL has the command window now */
312                    nfc_cb.flags         |= NFC_FL_CONTROL_GRANTED;
313                    nfc_cb.nci_cmd_window = 0;
314                }
315                else
316                {
317                    /* HAL does not need to send command,
318                     * - restore the command window and issue the discovery command now */
319                    nfc_cb.flags         &= ~NFC_FL_DISCOVER_PENDING;
320                    ps                    = (UINT8 *)nfc_cb.p_disc_pending;
321                    nci_snd_discover_cmd (*ps, (tNFC_DISCOVER_PARAMS *)(ps + 1));
322                    GKI_freebuf (nfc_cb.p_disc_pending);
323                    nfc_cb.p_disc_pending = NULL;
324                }
325            }
326            else if (nfc_cb.flags & NFC_FL_HAL_REQUESTED)
327            {
328                /* grant the control to HAL */
329                nfc_cb.flags         &= ~NFC_FL_HAL_REQUESTED;
330                nfc_cb.flags         |= NFC_FL_CONTROL_GRANTED;
331                nfc_cb.nci_cmd_window = 0;
332                nfc_cb.p_hal->control_granted ();
333            }
334        }
335    }
336}
337
338
339/*******************************************************************************
340**
341** Function         nfc_ncif_send_cmd
342**
343** Description      Send NCI command to the NCIT task
344**
345** Returns          void
346**
347*******************************************************************************/
348void nfc_ncif_send_cmd (BT_HDR *p_buf)
349{
350    /* post the p_buf to NCIT task */
351    p_buf->event            = BT_EVT_TO_NFC_NCI;
352    p_buf->layer_specific   = 0;
353    nfc_ncif_check_cmd_queue (p_buf);
354}
355
356
357/*******************************************************************************
358**
359** Function         nfc_ncif_process_event
360**
361** Description      This function is called to process the data/response/notification
362**                  from NFCC
363**
364** Returns          TRUE if need to free buffer
365**
366*******************************************************************************/
367BOOLEAN nfc_ncif_process_event (BT_HDR *p_msg)
368{
369    UINT8   mt, pbf, gid, *p, *pp;
370    BOOLEAN free = TRUE;
371    UINT8   oid;
372    UINT8   *p_old, old_gid, old_oid, old_mt;
373
374    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
375
376    pp = p;
377    NCI_MSG_PRS_HDR0 (pp, mt, pbf, gid);
378
379    switch (mt)
380    {
381    case NCI_MT_DATA:
382        NFC_TRACE_DEBUG0 ("NFC received data");
383        nfc_ncif_proc_data (p_msg);
384        free = FALSE;
385        break;
386
387    case NCI_MT_RSP:
388        NFC_TRACE_DEBUG1 ("NFC received rsp gid:%d", gid);
389        oid = ((*pp) & NCI_OID_MASK);
390        p_old   = nfc_cb.last_hdr;
391        NCI_MSG_PRS_HDR0(p_old, old_mt, pbf, old_gid);
392        old_oid = ((*p_old) & NCI_OID_MASK);
393        /* make sure this is the RSP we are waiting for before updating the command window */
394        if ((old_gid != gid) || (old_oid != oid))
395        {
396            NFC_TRACE_ERROR2 ("nfc_ncif_process_event unexpected rsp: gid:0x%x, oid:0x%x", gid, oid);
397            return TRUE;
398        }
399
400        switch (gid)
401        {
402        case NCI_GID_CORE:      /* 0000b NCI Core group */
403            free = nci_proc_core_rsp (p_msg);
404            break;
405        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
406            nci_proc_rf_management_rsp (p_msg);
407            break;
408#if (NFC_NFCEE_INCLUDED == TRUE)
409#if (NFC_RW_ONLY == FALSE)
410        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
411            nci_proc_ee_management_rsp (p_msg);
412            break;
413#endif
414#endif
415        case NCI_GID_PROP:      /* 1111b Proprietary */
416                nci_proc_prop_rsp (p_msg);
417            break;
418        default:
419            NFC_TRACE_ERROR1 ("NFC: Unknown gid:%d", gid);
420            break;
421        }
422
423        nfc_ncif_update_window ();
424        break;
425
426    case NCI_MT_NTF:
427        NFC_TRACE_DEBUG1 ("NFC received ntf gid:%d", gid);
428        switch (gid)
429        {
430        case NCI_GID_CORE:      /* 0000b NCI Core group */
431            nci_proc_core_ntf (p_msg);
432            break;
433        case NCI_GID_RF_MANAGE:   /* 0001b NCI Discovery group */
434            nci_proc_rf_management_ntf (p_msg);
435            break;
436#if (NFC_NFCEE_INCLUDED == TRUE)
437#if (NFC_RW_ONLY == FALSE)
438        case NCI_GID_EE_MANAGE:  /* 0x02 0010b NFCEE Discovery group */
439            nci_proc_ee_management_ntf (p_msg);
440            break;
441#endif
442#endif
443        case NCI_GID_PROP:      /* 1111b Proprietary */
444                nci_proc_prop_ntf (p_msg);
445            break;
446        default:
447            NFC_TRACE_ERROR1 ("NFC: Unknown gid:%d", gid);
448            break;
449        }
450        break;
451
452    default:
453        NFC_TRACE_DEBUG2 ("NFC received unknown mt:0x%x, gid:%d", mt, gid);
454    }
455
456    return (free);
457}
458
459/*******************************************************************************
460**
461** Function         nfc_ncif_rf_management_status
462**
463** Description      This function is called to report an event
464**
465** Returns          void
466**
467*******************************************************************************/
468void nfc_ncif_rf_management_status (tNFC_DISCOVER_EVT event, UINT8 status)
469{
470    tNFC_DISCOVER   evt_data;
471    if (nfc_cb.p_discv_cback)
472    {
473        evt_data.status = (tNFC_STATUS) status;
474        (*nfc_cb.p_discv_cback) (event, &evt_data);
475    }
476}
477
478/*******************************************************************************
479**
480** Function         nfc_ncif_set_config_status
481**
482** Description      This function is called to report NFC_SET_CONFIG_REVT
483**
484** Returns          void
485**
486*******************************************************************************/
487void nfc_ncif_set_config_status (UINT8 *p, UINT8 len)
488{
489    tNFC_RESPONSE   evt_data;
490    if (nfc_cb.p_resp_cback)
491    {
492        evt_data.set_config.status          = (tNFC_STATUS) *p++;
493        evt_data.set_config.num_param_id    = NFC_STATUS_OK;
494        if (evt_data.set_config.status != NFC_STATUS_OK)
495        {
496            evt_data.set_config.num_param_id    = *p++;
497            STREAM_TO_ARRAY (evt_data.set_config.param_ids, p, evt_data.set_config.num_param_id);
498        }
499
500        (*nfc_cb.p_resp_cback) (NFC_SET_CONFIG_REVT, &evt_data);
501    }
502}
503
504/*******************************************************************************
505**
506** Function         nfc_ncif_event_status
507**
508** Description      This function is called to report an event
509**
510** Returns          void
511**
512*******************************************************************************/
513void nfc_ncif_event_status (tNFC_RESPONSE_EVT event, UINT8 status)
514{
515    tNFC_RESPONSE   evt_data;
516    if (nfc_cb.p_resp_cback)
517    {
518        evt_data.status = (tNFC_STATUS) status;
519        (*nfc_cb.p_resp_cback) (event, &evt_data);
520    }
521}
522
523/*******************************************************************************
524**
525** Function         nfc_ncif_error_status
526**
527** Description      This function is called to report an error event to data cback
528**
529** Returns          void
530**
531*******************************************************************************/
532void nfc_ncif_error_status (UINT8 conn_id, UINT8 status)
533{
534    tNFC_CONN_CB * p_cb;
535    p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
536    if (p_cb && p_cb->p_cback)
537    {
538        (*p_cb->p_cback) (conn_id, NFC_ERROR_CEVT, (tNFC_CONN *) &status);
539    }
540}
541
542/*******************************************************************************
543**
544** Function         nfc_ncif_proc_rf_field_ntf
545**
546** Description      This function is called to process RF field notification
547**
548** Returns          void
549**
550*******************************************************************************/
551#if (NFC_RW_ONLY == FALSE)
552void nfc_ncif_proc_rf_field_ntf (UINT8 rf_status)
553{
554    tNFC_RESPONSE   evt_data;
555    if (nfc_cb.p_resp_cback)
556    {
557        evt_data.status            = (tNFC_STATUS) NFC_STATUS_OK;
558        evt_data.rf_field.rf_field = rf_status;
559        (*nfc_cb.p_resp_cback) (NFC_RF_FIELD_REVT, &evt_data);
560    }
561}
562#endif
563
564/*******************************************************************************
565**
566** Function         nfc_ncif_proc_credits
567**
568** Description      This function is called to process data credits
569**
570** Returns          void
571**
572*******************************************************************************/
573void nfc_ncif_proc_credits(UINT8 *p, UINT16 plen)
574{
575    UINT8   num, xx;
576    tNFC_CONN_CB * p_cb;
577
578    num = *p++;
579    for (xx = 0; xx < num; xx++)
580    {
581        p_cb = nfc_find_conn_cb_by_conn_id(*p++);
582        if (p_cb && p_cb->num_buff != NFC_CONN_NO_FC)
583        {
584            p_cb->num_buff += (*p);
585#if (BT_USE_TRACES == TRUE)
586            if (p_cb->num_buff > p_cb->init_credits)
587            {
588                if (nfc_cb.nfc_state == NFC_STATE_OPEN)
589                {
590                    /* if this happens in activated state, it's very likely that our NFCC has issues */
591                    /* However, credit may be returned after deactivation */
592                    NFC_TRACE_ERROR2( "num_buff:0x%x, init_credits:0x%x", p_cb->num_buff, p_cb->init_credits);
593                }
594                p_cb->num_buff = p_cb->init_credits;
595            }
596#endif
597            /* check if there's nay data in tx q to be sent */
598            nfc_ncif_send_data (p_cb, NULL);
599        }
600        p++;
601    }
602}
603/*******************************************************************************
604**
605** Function         nfc_ncif_decode_rf_params
606**
607** Description      This function is called to process the detected technology
608**                  and mode and the associated parameters for DISCOVER_NTF and
609**                  ACTIVATE_NTF
610**
611** Returns          void
612**
613*******************************************************************************/
614UINT8 * nfc_ncif_decode_rf_params (tNFC_RF_TECH_PARAMS *p_param, UINT8 *p)
615{
616    tNFC_RF_PA_PARAMS   *p_pa;
617    UINT8               len, *p_start, u8;
618    tNFC_RF_PB_PARAMS   *p_pb;
619    tNFC_RF_LF_PARAMS   *p_lf;
620    tNFC_RF_PF_PARAMS   *p_pf;
621    tNFC_RF_PISO15693_PARAMS *p_i93;
622
623    len             = *p++;
624    p_start         = p;
625    memset ( &p_param->param, 0, sizeof (tNFC_RF_TECH_PARAMU));
626    switch (p_param->mode)
627    {
628    case NCI_DISCOVERY_TYPE_POLL_A:
629    case NCI_DISCOVERY_TYPE_POLL_A_ACTIVE:
630        p_pa        = &p_param->param.pa;
631        /*
632SENS_RES Response   2 bytes Defined in [DIGPROT] Available after Technology Detection
633NFCID1 length   1 byte  Length of NFCID1 Available after Collision Resolution
634NFCID1  4, 7, or 10 bytes   Defined in [DIGPROT]Available after Collision Resolution
635SEL_RES Response    1 byte  Defined in [DIGPROT]Available after Collision Resolution
636HRx Length  1 Octets    Length of HRx Parameters collected from the response to the T1T RID command.
637HRx 0 or 2 Octets   If present, the first byte SHALL contain HR0 and the second byte SHALL contain HR1 as defined in [DIGITAL].
638        */
639        STREAM_TO_ARRAY (p_pa->sens_res, p, 2);
640        p_pa->nfcid1_len     = *p++;
641        if (p_pa->nfcid1_len > NCI_NFCID1_MAX_LEN)
642            p_pa->nfcid1_len = NCI_NFCID1_MAX_LEN;
643        STREAM_TO_ARRAY (p_pa->nfcid1, p, p_pa->nfcid1_len);
644        u8                   = *p++;
645        if (u8)
646            p_pa->sel_rsp    = *p++;
647        if (len == (7 + p_pa->nfcid1_len + u8)) /* 2(sens_res) + 1(len) + p_pa->nfcid1_len + 1(len) + u8 + hr (1:len + 2) */
648        {
649            p_pa->hr_len     = *p++;
650            if (p_pa->hr_len == NCI_T1T_HR_LEN)
651            {
652                p_pa->hr[0]  = *p++;
653                p_pa->hr[1]  = *p;
654            }
655        }
656        break;
657
658    case NCI_DISCOVERY_TYPE_POLL_B:
659        /*
660SENSB_RES Response length (n)   1 byte  Length of SENSB_RES Response (Byte 2 - Byte 12 or 13)Available after Technology Detection
661SENSB_RES Response Byte 2 - Byte 12 or 13   11 or 12 bytes  Defined in [DIGPROT] Available after Technology Detection
662        */
663        p_pb                = &p_param->param.pb;
664        p_pb->sensb_res_len = *p++;
665        if (p_pb->sensb_res_len > NCI_MAX_SENSB_RES_LEN)
666            p_pb->sensb_res_len = NCI_MAX_SENSB_RES_LEN;
667        STREAM_TO_ARRAY (p_pb->sensb_res, p, p_pb->sensb_res_len);
668        memcpy (p_pb->nfcid0, p_pb->sensb_res, NFC_NFCID0_MAX_LEN);
669        break;
670
671    case NCI_DISCOVERY_TYPE_POLL_F:
672    case NCI_DISCOVERY_TYPE_POLL_F_ACTIVE:
673        /*
674Bit Rate    1 byte  1   212 kbps/2   424 kbps/0 and 3 to 255  RFU
675SENSF_RES Response length.(n) 1 byte  Length of SENSF_RES (Byte 2 - Byte 17 or 19).Available after Technology Detection
676SENSF_RES Response Byte 2 - Byte 17 or 19  n bytes Defined in [DIGPROT] Available after Technology Detection
677        */
678        p_pf                = &p_param->param.pf;
679        p_pf->bit_rate      = *p++;
680        p_pf->sensf_res_len = *p++;
681        if (p_pf->sensf_res_len > NCI_MAX_SENSF_RES_LEN)
682            p_pf->sensf_res_len = NCI_MAX_SENSF_RES_LEN;
683        STREAM_TO_ARRAY (p_pf->sensf_res, p, p_pf->sensf_res_len);
684        memcpy (p_pf->nfcid2, p_pf->sensf_res, NCI_NFCID2_LEN);
685        p_pf->mrti_check    = p_pf->sensf_res[NCI_MRTI_CHECK_INDEX];
686        p_pf->mrti_update   = p_pf->sensf_res[NCI_MRTI_UPDATE_INDEX];
687        break;
688
689    case NCI_DISCOVERY_TYPE_LISTEN_F:
690    case NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
691        p_lf                = &p_param->param.lf;
692        u8                  = *p++;
693        if (u8)
694        {
695            STREAM_TO_ARRAY (p_lf->nfcid2, p, NCI_NFCID2_LEN);
696        }
697        break;
698
699    case NCI_DISCOVERY_TYPE_POLL_ISO15693:
700        p_i93               = &p_param->param.pi93;
701        p_i93->flag         = *p++;
702        p_i93->dsfid        = *p++;
703        STREAM_TO_ARRAY (p_i93->uid, p, NFC_ISO15693_UID_LEN);
704        break;
705
706    case NCI_DISCOVERY_TYPE_POLL_KOVIO:
707        p_param->param.pk.uid_len = *p++;
708        if (p_param->param.pk.uid_len > NFC_KOVIO_MAX_LEN)
709        {
710            NFC_TRACE_ERROR2( "Kovio UID len:0x%x exceeds max(0x%x)", p_param->param.pk.uid_len, NFC_KOVIO_MAX_LEN);
711            p_param->param.pk.uid_len = NFC_KOVIO_MAX_LEN;
712        }
713        STREAM_TO_ARRAY (p_param->param.pk.uid, p, p_param->param.pk.uid_len);
714        break;
715    }
716
717    return (p_start + len);
718}
719
720/*******************************************************************************
721**
722** Function         nfc_ncif_proc_discover_ntf
723**
724** Description      This function is called to process discover notification
725**
726** Returns          void
727**
728*******************************************************************************/
729void nfc_ncif_proc_discover_ntf (UINT8 *p, UINT16 plen)
730{
731    tNFC_DISCOVER   evt_data;
732
733    if (nfc_cb.p_discv_cback)
734    {
735        p                              += NCI_MSG_HDR_SIZE;
736        evt_data.status                 = NCI_STATUS_OK;
737        evt_data.result.rf_disc_id      = *p++;
738        evt_data.result.protocol        = *p++;
739
740        /* fill in tNFC_RESULT_DEVT */
741        evt_data.result.rf_tech_param.mode  = *p++;
742        p = nfc_ncif_decode_rf_params (&evt_data.result.rf_tech_param, p);
743
744        evt_data.result.more            = *p++;
745        (*nfc_cb.p_discv_cback) (NFC_RESULT_DEVT, &evt_data);
746    }
747}
748
749/*******************************************************************************
750**
751** Function         nfc_ncif_proc_activate
752**
753** Description      This function is called to process de-activate
754**                  response and notification
755**
756** Returns          void
757**
758*******************************************************************************/
759void nfc_ncif_proc_activate (UINT8 *p, UINT8 len)
760{
761    tNFC_DISCOVER   evt_data;
762    tNFC_INTF_PARAMS        *p_intf = &evt_data.activate.intf_param;
763    tNFC_INTF_PA_ISO_DEP    *p_pa_iso;
764    tNFC_INTF_LB_ISO_DEP    *p_lb_iso;
765    tNFC_INTF_PB_ISO_DEP    *p_pb_iso;
766#if (NFC_RW_ONLY == FALSE)
767    tNFC_INTF_PA_NFC_DEP    *p_pa_nfc;
768    int                     mpl_idx = 0;
769    UINT8                   gb_idx = 0, mpl;
770#endif
771    UINT8                   t0;
772    tNCI_DISCOVERY_TYPE     mode;
773    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
774    UINT8                   *pp, len_act;
775    UINT8                   buff_size, num_buff;
776    tNFC_RF_PA_PARAMS       *p_pa;
777
778    nfc_set_state (NFC_STATE_OPEN);
779
780    memset (p_intf, 0, sizeof (tNFC_INTF_PARAMS));
781    evt_data.activate.rf_disc_id    = *p++;
782    p_intf->type                    = *p++;
783    evt_data.activate.protocol      = *p++;
784
785    if (evt_data.activate.protocol == NCI_PROTOCOL_18092_ACTIVE)
786        evt_data.activate.protocol = NCI_PROTOCOL_NFC_DEP;
787
788    evt_data.activate.rf_tech_param.mode    = *p++;
789    buff_size                               = *p++;
790    num_buff                                = *p++;
791    /* fill in tNFC_activate_DEVT */
792    p = nfc_ncif_decode_rf_params (&evt_data.activate.rf_tech_param, p);
793
794    evt_data.activate.data_mode             = *p++;
795    evt_data.activate.tx_bitrate            = *p++;
796    evt_data.activate.rx_bitrate            = *p++;
797    mode         = evt_data.activate.rf_tech_param.mode;
798    len_act      = *p++;
799    NFC_TRACE_DEBUG3 ("nfc_ncif_proc_activate:%d %d, mode:0x%02x", len, len_act, mode);
800    /* just in case the interface reports activation parameters not defined in the NCI spec */
801    p_intf->intf_param.frame.param_len      = len_act;
802    if (p_intf->intf_param.frame.param_len > NFC_MAX_RAW_PARAMS)
803        p_intf->intf_param.frame.param_len = NFC_MAX_RAW_PARAMS;
804    pp = p;
805    STREAM_TO_ARRAY (p_intf->intf_param.frame.param, pp, p_intf->intf_param.frame.param_len);
806    if (evt_data.activate.intf_param.type == NCI_INTERFACE_ISO_DEP)
807    {
808        /* Make max payload of NCI aligned to max payload of ISO-DEP for better performance */
809        if (buff_size > NCI_ISO_DEP_MAX_INFO)
810            buff_size = NCI_ISO_DEP_MAX_INFO;
811
812        switch (mode)
813        {
814        case NCI_DISCOVERY_TYPE_POLL_A:
815            p_pa_iso                  = &p_intf->intf_param.pa_iso;
816            p_pa_iso->ats_res_len     = *p++;
817
818            if (p_pa_iso->ats_res_len == 0)
819                break;
820
821            if (p_pa_iso->ats_res_len > NFC_MAX_ATS_LEN)
822                p_pa_iso->ats_res_len = NFC_MAX_ATS_LEN;
823            STREAM_TO_ARRAY (p_pa_iso->ats_res, p, p_pa_iso->ats_res_len);
824            pp = &p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
825            t0 = p_pa_iso->ats_res[NCI_ATS_T0_INDEX];
826            pp++;       /* T0 */
827            if (t0 & NCI_ATS_TA_MASK)
828                pp++;   /* TA */
829            if (t0 & NCI_ATS_TB_MASK)
830            {
831                /* FWI (Frame Waiting time Integer) & SPGI (Start-up Frame Guard time Integer) */
832                p_pa_iso->fwi       = (((*pp) >> 4) & 0x0F);
833                p_pa_iso->sfgi      = ((*pp) & 0x0F);
834                pp++;   /* TB */
835            }
836            if (t0 & NCI_ATS_TC_MASK)
837            {
838                p_pa_iso->nad_used  = ((*pp) & 0x01);
839                pp++;   /* TC */
840            }
841            p_pa_iso->his_byte_len  = (UINT8) (p_pa_iso->ats_res_len - (pp - p_pa_iso->ats_res));
842            memcpy (p_pa_iso->his_byte,  pp, p_pa_iso->his_byte_len);
843            break;
844
845        case NCI_DISCOVERY_TYPE_LISTEN_A:
846            p_intf->intf_param.la_iso.rats = *p++;
847            break;
848
849        case NCI_DISCOVERY_TYPE_POLL_B:
850            /* ATTRIB RSP
851            Byte 1   Byte 2 ~ 2+n-1
852            MBLI/DID Higher layer - Response
853            */
854            p_pb_iso                     = &p_intf->intf_param.pb_iso;
855            p_pb_iso->attrib_res_len     = *p++;
856
857            if (p_pb_iso->attrib_res_len == 0)
858                break;
859
860            if (p_pb_iso->attrib_res_len > NFC_MAX_ATTRIB_LEN)
861                p_pb_iso->attrib_res_len = NFC_MAX_ATTRIB_LEN;
862            STREAM_TO_ARRAY (p_pb_iso->attrib_res, p, p_pb_iso->attrib_res_len);
863            p_pb_iso->mbli = (p_pb_iso->attrib_res[0]) >> 4;
864            if (p_pb_iso->attrib_res_len > NFC_PB_ATTRIB_REQ_FIXED_BYTES)
865            {
866                p_pb_iso->hi_info_len    = p_pb_iso->attrib_res_len - NFC_PB_ATTRIB_REQ_FIXED_BYTES;
867                if (p_pb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
868                    p_pb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
869                memcpy (p_pb_iso->hi_info, &p_pb_iso->attrib_res[NFC_PB_ATTRIB_REQ_FIXED_BYTES], p_pb_iso->hi_info_len);
870            }
871            break;
872
873        case NCI_DISCOVERY_TYPE_LISTEN_B:
874            /* ATTRIB CMD
875            Byte 2~5 Byte 6  Byte 7  Byte 8  Byte 9  Byte 10 ~ 10+k-1
876            NFCID0   Param 1 Param 2 Param 3 Param 4 Higher layer - INF
877            */
878            p_lb_iso                     = &p_intf->intf_param.lb_iso;
879            p_lb_iso->attrib_req_len     = *p++;
880
881            if (p_lb_iso->attrib_req_len == 0)
882                break;
883
884            if (p_lb_iso->attrib_req_len > NFC_MAX_ATTRIB_LEN)
885                p_lb_iso->attrib_req_len = NFC_MAX_ATTRIB_LEN;
886            STREAM_TO_ARRAY (p_lb_iso->attrib_req, p, p_lb_iso->attrib_req_len);
887            memcpy (p_lb_iso->nfcid0, p_lb_iso->attrib_req, NFC_NFCID0_MAX_LEN);
888            if (p_lb_iso->attrib_req_len > NFC_LB_ATTRIB_REQ_FIXED_BYTES)
889            {
890                p_lb_iso->hi_info_len    = p_lb_iso->attrib_req_len - NFC_LB_ATTRIB_REQ_FIXED_BYTES;
891                if (p_lb_iso->hi_info_len > NFC_MAX_GEN_BYTES_LEN)
892                    p_lb_iso->hi_info_len = NFC_MAX_GEN_BYTES_LEN;
893                memcpy (p_lb_iso->hi_info, &p_lb_iso->attrib_req[NFC_LB_ATTRIB_REQ_FIXED_BYTES], p_lb_iso->hi_info_len);
894            }
895            break;
896        }
897
898    }
899#if (NFC_RW_ONLY == FALSE)
900    else if (evt_data.activate.intf_param.type == NCI_INTERFACE_NFC_DEP)
901    {
902        /* Make max payload of NCI aligned to max payload of NFC-DEP for better performance */
903        if (buff_size > NCI_NFC_DEP_MAX_DATA)
904            buff_size = NCI_NFC_DEP_MAX_DATA;
905
906        p_pa_nfc                  = &p_intf->intf_param.pa_nfc;
907        p_pa_nfc->atr_res_len     = *p++;
908
909        if (p_pa_nfc->atr_res_len > 0)
910        {
911            if (p_pa_nfc->atr_res_len > NFC_MAX_ATS_LEN)
912                p_pa_nfc->atr_res_len = NFC_MAX_ATS_LEN;
913            STREAM_TO_ARRAY (p_pa_nfc->atr_res, p, p_pa_nfc->atr_res_len);
914            if (  (mode == NCI_DISCOVERY_TYPE_POLL_A)
915                ||(mode == NCI_DISCOVERY_TYPE_POLL_F)
916                ||(mode == NCI_DISCOVERY_TYPE_POLL_A_ACTIVE)
917                ||(mode == NCI_DISCOVERY_TYPE_POLL_F_ACTIVE)  )
918            {
919                /* ATR_RES
920                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17 Byte 18~18+n
921                NFCID3T   DIDT    BST     BRT     TO      PPT     [GT0 ... GTn] */
922                mpl_idx                 = 14;
923                gb_idx                  = NCI_P_GEN_BYTE_INDEX;
924                p_pa_nfc->waiting_time  = p_pa_nfc->atr_res[NCI_L_NFC_DEP_TO_INDEX] & 0x0F;
925            }
926            else if (  (mode == NCI_DISCOVERY_TYPE_LISTEN_A)
927                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F)
928                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_A_ACTIVE)
929                     ||(mode == NCI_DISCOVERY_TYPE_LISTEN_F_ACTIVE)  )
930            {
931                /* ATR_REQ
932                Byte 3~12 Byte 13 Byte 14 Byte 15 Byte 16 Byte 17~17+n
933                NFCID3I   DIDI    BSI     BRI     PPI     [GI0 ... GIn] */
934                mpl_idx = 13;
935                gb_idx  = NCI_L_GEN_BYTE_INDEX;
936            }
937
938            mpl                         = ((p_pa_nfc->atr_res[mpl_idx]) >> 4) & 0x03;
939            p_pa_nfc->max_payload_size  = nfc_mpl_code_to_size[mpl];
940            if (p_pa_nfc->atr_res_len > gb_idx)
941            {
942                p_pa_nfc->gen_bytes_len = p_pa_nfc->atr_res_len - gb_idx;
943                if (p_pa_nfc->gen_bytes_len > NFC_MAX_GEN_BYTES_LEN)
944                    p_pa_nfc->gen_bytes_len = NFC_MAX_GEN_BYTES_LEN;
945                memcpy (p_pa_nfc->gen_bytes, &p_pa_nfc->atr_res[gb_idx], p_pa_nfc->gen_bytes_len);
946            }
947        }
948    }
949#endif
950    else if ((evt_data.activate.intf_param.type == NCI_INTERFACE_FRAME) && (evt_data.activate.protocol == NCI_PROTOCOL_T1T) )
951    {
952        p_pa = &evt_data.activate.rf_tech_param.param.pa;
953        if ((len_act == NCI_T1T_HR_LEN) && (p_pa->hr_len == 0))
954        {
955            p_pa->hr_len    = NCI_T1T_HR_LEN;
956            p_pa->hr[0]     = *p++;
957            p_pa->hr[1]     = *p++;
958        }
959    }
960
961    p_cb->act_protocol  = evt_data.activate.protocol;
962    p_cb->buff_size     = buff_size;
963    p_cb->num_buff      = num_buff;
964    p_cb->init_credits  = num_buff;
965
966    if (nfc_cb.p_discv_cback)
967    {
968        (*nfc_cb.p_discv_cback) (NFC_ACTIVATE_DEVT, &evt_data);
969    }
970}
971
972/*******************************************************************************
973**
974** Function         nfc_ncif_proc_deactivate
975**
976** Description      This function is called to process de-activate
977**                  response and notification
978**
979** Returns          void
980**
981*******************************************************************************/
982void nfc_ncif_proc_deactivate (UINT8 status, UINT8 deact_type, BOOLEAN is_ntf)
983{
984    tNFC_DISCOVER   evt_data;
985    tNFC_DEACTIVATE_DEVT    *p_deact;
986    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
987    void    *p_data;
988
989    nfc_set_state (NFC_STATE_IDLE);
990    p_deact             = &evt_data.deactivate;
991    p_deact->status     = status;
992    p_deact->type       = deact_type;
993    p_deact->is_ntf     = is_ntf;
994
995    while ((p_data = GKI_dequeue (&p_cb->rx_q)) != NULL)
996    {
997        GKI_freebuf (p_data);
998    }
999
1000    while ((p_data = GKI_dequeue (&p_cb->tx_q)) != NULL)
1001    {
1002        GKI_freebuf (p_data);
1003    }
1004
1005    if (p_cb->p_cback)
1006        (*p_cb->p_cback) (NFC_RF_CONN_ID, NFC_DEACTIVATE_CEVT, (tNFC_CONN *) p_deact);
1007
1008    if (nfc_cb.p_discv_cback)
1009    {
1010        (*nfc_cb.p_discv_cback) (NFC_DEACTIVATE_DEVT, &evt_data);
1011    }
1012}
1013/*******************************************************************************
1014**
1015** Function         nfc_ncif_proc_ee_action
1016**
1017** Description      This function is called to process NFCEE ACTION NTF
1018**
1019** Returns          void
1020**
1021*******************************************************************************/
1022#if ((NFC_NFCEE_INCLUDED == TRUE) && (NFC_RW_ONLY == FALSE))
1023void nfc_ncif_proc_ee_action (UINT8 *p, UINT16 plen)
1024{
1025    tNFC_EE_ACTION_REVT evt_data;
1026    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
1027    UINT8   data_len, ulen, tag, *p_data;
1028    UINT8   max_len;
1029
1030    if (p_cback)
1031    {
1032        memset (&evt_data.act_data, 0, sizeof (tNFC_ACTION_DATA));
1033        evt_data.status             = NFC_STATUS_OK;
1034        evt_data.nfcee_id           = *p++;
1035        evt_data.act_data.trigger   = *p++;
1036        data_len                    = *p++;
1037        if (plen >= 3)
1038            plen -= 3;
1039        if (data_len > plen)
1040            data_len = (UINT8) plen;
1041
1042        switch (evt_data.act_data.trigger)
1043        {
1044        case NCI_EE_TRIG_7816_SELECT:
1045            if (data_len > NFC_MAX_AID_LEN)
1046                data_len = NFC_MAX_AID_LEN;
1047            evt_data.act_data.param.aid.len_aid = data_len;
1048            STREAM_TO_ARRAY (evt_data.act_data.param.aid.aid, p, data_len);
1049            break;
1050        case NCI_EE_TRIG_RF_PROTOCOL:
1051            evt_data.act_data.param.protocol    = *p++;
1052            break;
1053        case NCI_EE_TRIG_RF_TECHNOLOGY:
1054            evt_data.act_data.param.technology  = *p++;
1055            break;
1056        case NCI_EE_TRIG_APP_INIT:
1057            while (data_len > NFC_TL_SIZE)
1058            {
1059                data_len    -= NFC_TL_SIZE;
1060                tag         = *p++;
1061                ulen        = *p++;
1062                if (ulen > data_len)
1063                    ulen = data_len;
1064                p_data      = NULL;
1065                max_len     = ulen;
1066                switch (tag)
1067                {
1068                case NCI_EE_ACT_TAG_AID:    /* AID                 */
1069                    if (max_len > NFC_MAX_AID_LEN)
1070                        max_len = NFC_MAX_AID_LEN;
1071                    evt_data.act_data.param.app_init.len_aid = max_len;
1072                    p_data = evt_data.act_data.param.app_init.aid;
1073                    break;
1074                case NCI_EE_ACT_TAG_DATA:   /* hex data for app    */
1075                    if (max_len > NFC_MAX_APP_DATA_LEN)
1076                        max_len = NFC_MAX_APP_DATA_LEN;
1077                    evt_data.act_data.param.app_init.len_data   = max_len;
1078                    p_data                                      = evt_data.act_data.param.app_init.data;
1079                    break;
1080                }
1081                if (p_data)
1082                {
1083                    STREAM_TO_ARRAY (p_data, p, max_len);
1084                }
1085                data_len -= ulen;
1086            }
1087            break;
1088        }
1089        (*p_cback) (NFC_EE_ACTION_REVT, (tNFC_RESPONSE *) &evt_data);
1090    }
1091}
1092
1093/*******************************************************************************
1094**
1095** Function         nfc_ncif_proc_ee_discover_req
1096**
1097** Description      This function is called to process NFCEE DISCOVER REQ NTF
1098**
1099** Returns          void
1100**
1101*******************************************************************************/
1102void nfc_ncif_proc_ee_discover_req (UINT8 *p, UINT16 plen)
1103{
1104    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
1105    tNFC_EE_DISCOVER_REQ_REVT   ee_disc_req;
1106    tNFC_EE_DISCOVER_INFO       *p_info;
1107    UINT8                       u8;
1108
1109    NFC_TRACE_DEBUG2 ("nfc_ncif_proc_ee_discover_req %d len:%d", *p, plen);
1110    if (p_cback)
1111    {
1112        u8  = *p;
1113        ee_disc_req.status      = NFC_STATUS_OK;
1114        ee_disc_req.num_info    = *p++;
1115        p_info                  = ee_disc_req.info;
1116        if (plen)
1117            plen--;
1118        while ((u8 > 0) && (plen >= NFC_EE_DISCOVER_ENTRY_LEN))
1119        {
1120            p_info->op  = *p++;                  /* T */
1121            if (*p != NFC_EE_DISCOVER_INFO_LEN)/* L */
1122            {
1123                NFC_TRACE_DEBUG1 ("bad entry len:%d", *p );
1124                return;
1125            }
1126            p++;
1127            /* V */
1128            p_info->nfcee_id    = *p++;
1129            p_info->tech_n_mode = *p++;
1130            p_info->protocol    = *p++;
1131            u8--;
1132            plen    -=NFC_EE_DISCOVER_ENTRY_LEN;
1133            p_info++;
1134        }
1135        (*p_cback) (NFC_EE_DISCOVER_REQ_REVT, (tNFC_RESPONSE *) &ee_disc_req);
1136    }
1137
1138}
1139
1140/*******************************************************************************
1141**
1142** Function         nfc_ncif_proc_get_routing
1143**
1144** Description      This function is called to process get routing notification
1145**
1146** Returns          void
1147**
1148*******************************************************************************/
1149void nfc_ncif_proc_get_routing (UINT8 *p, UINT8 len)
1150{
1151    tNFC_GET_ROUTING_REVT evt_data;
1152    UINT8       more, num_entries, xx, yy, *pn, tl;
1153    tNFC_STATUS status = NFC_STATUS_CONTINUE;
1154
1155    if (nfc_cb.p_resp_cback)
1156    {
1157        more        = *p++;
1158        num_entries = *p++;
1159        for (xx = 0; xx < num_entries; xx++)
1160        {
1161            if ((more == FALSE) && (xx == (num_entries - 1)))
1162                status = NFC_STATUS_OK;
1163            evt_data.status         = (tNFC_STATUS) status;
1164            evt_data.nfcee_id       = *p++;
1165            evt_data.num_tlvs       = *p++;
1166            evt_data.tlv_size       = 0;
1167            pn                      = evt_data.param_tlvs;
1168            for (yy = 0; yy < evt_data.num_tlvs; yy++)
1169            {
1170                tl                  = *(p+1);
1171                tl                 += NFC_TL_SIZE;
1172                STREAM_TO_ARRAY (pn, p, tl);
1173                evt_data.tlv_size  += tl;
1174                pn                 += tl;
1175            }
1176            (*nfc_cb.p_resp_cback) (NFC_GET_ROUTING_REVT, (tNFC_RESPONSE *) &evt_data);
1177        }
1178    }
1179}
1180#endif
1181
1182/*******************************************************************************
1183**
1184** Function         nfc_ncif_proc_conn_create_rsp
1185**
1186** Description      This function is called to process connection create
1187**                  response
1188**
1189** Returns          void
1190**
1191*******************************************************************************/
1192void nfc_ncif_proc_conn_create_rsp (UINT8 *p, UINT16 plen, UINT8 dest_type)
1193{
1194    tNFC_CONN_CB * p_cb;
1195    tNFC_STATUS    status;
1196    tNFC_CONN_CBACK *p_cback;
1197    tNFC_CONN   evt_data;
1198    UINT8           conn_id;
1199
1200    /* find the pending connection control block */
1201    p_cb                = nfc_find_conn_cb_by_conn_id (NFC_PEND_CONN_ID);
1202    if (p_cb)
1203    {
1204        p                                  += NCI_MSG_HDR_SIZE;
1205        status                              = *p++;
1206        p_cb->buff_size                     = *p++;
1207        p_cb->num_buff = p_cb->init_credits = *p++;
1208        conn_id                             = *p++;
1209        evt_data.conn_create.status         = status;
1210        evt_data.conn_create.dest_type      = dest_type;
1211        evt_data.conn_create.id             = p_cb->id;
1212        evt_data.conn_create.buff_size      = p_cb->buff_size;
1213        evt_data.conn_create.num_buffs      = p_cb->num_buff;
1214        p_cback = p_cb->p_cback;
1215        if (status == NCI_STATUS_OK)
1216        {
1217            nfc_set_conn_id (p_cb, conn_id);
1218        }
1219        else
1220        {
1221            nfc_free_conn_cb (p_cb);
1222        }
1223
1224
1225        if (p_cback)
1226            (*p_cback) (conn_id, NFC_CONN_CREATE_CEVT, &evt_data);
1227    }
1228}
1229
1230/*******************************************************************************
1231**
1232** Function         nfc_ncif_report_conn_close_evt
1233**
1234** Description      This function is called to report connection close event
1235**
1236** Returns          void
1237**
1238*******************************************************************************/
1239void nfc_ncif_report_conn_close_evt (UINT8 conn_id, tNFC_STATUS status)
1240{
1241    tNFC_CONN       evt_data;
1242    tNFC_CONN_CBACK *p_cback;
1243    tNFC_CONN_CB    *p_cb;
1244
1245    p_cb = nfc_find_conn_cb_by_conn_id (conn_id);
1246    if (p_cb)
1247    {
1248        p_cback         = p_cb->p_cback;
1249        nfc_free_conn_cb (p_cb);
1250        evt_data.status = status;
1251        if (p_cback)
1252            (*p_cback) (conn_id, NFC_CONN_CLOSE_CEVT, &evt_data);
1253    }
1254}
1255
1256/*******************************************************************************
1257**
1258** Function         nfc_ncif_proc_reset_rsp
1259**
1260** Description      This function is called to process reset response/notification
1261**
1262** Returns          void
1263**
1264*******************************************************************************/
1265void nfc_ncif_proc_reset_rsp (UINT8 *p, BOOLEAN is_ntf)
1266{
1267    UINT8 status = *p++;
1268
1269    if (is_ntf)
1270    {
1271        NFC_TRACE_ERROR1 ("reset notification!!:0x%x ", status);
1272        /* clean up, if the state is OPEN
1273         * FW does not report reset ntf right now */
1274        if (nfc_cb.nfc_state == NFC_STATE_OPEN)
1275        {
1276            /*if any conn_cb is connected, close it.
1277              if any pending outgoing packets are dropped.*/
1278            nfc_reset_all_conn_cbs ();
1279        }
1280        status = NCI_STATUS_OK;
1281    }
1282
1283    if (nfc_cb.flags & (NFC_FL_RESTARTING|NFC_FL_POWER_CYCLE_NFCC))
1284    {
1285        nfc_reset_all_conn_cbs ();
1286    }
1287
1288    if (status == NCI_STATUS_OK)
1289    {
1290        if ((*p) != NCI_VERSION)
1291        {
1292            NFC_TRACE_ERROR2 ("NCI version mismatch!!:0x%02x != 0x%02x ", NCI_VERSION, *p);
1293            if ((*p) < NCI_VERSION_0_F)
1294            {
1295                NFC_TRACE_ERROR0 ("NFCC version is too old");
1296                status = NCI_STATUS_FAILED;
1297            }
1298        }
1299    }
1300
1301    if (status == NCI_STATUS_OK)
1302    {
1303        nci_snd_core_init ();
1304    }
1305    else
1306    {
1307        NFC_TRACE_ERROR0 ("Failed to reset NFCC");
1308        nfc_enabled (status, NULL);
1309    }
1310}
1311
1312/*******************************************************************************
1313**
1314** Function         nfc_ncif_proc_init_rsp
1315**
1316** Description      This function is called to process init response
1317**
1318** Returns          void
1319**
1320*******************************************************************************/
1321void nfc_ncif_proc_init_rsp (BT_HDR *p_msg)
1322{
1323    UINT8 *p, status;
1324    tNFC_CONN_CB * p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID];
1325
1326    p = (UINT8 *) (p_msg + 1) + p_msg->offset;
1327
1328    /* handle init params in nfc_enabled */
1329    status   = *(p + NCI_MSG_HDR_SIZE);
1330    if (status == NCI_STATUS_OK)
1331    {
1332        p_cb->id            = NFC_RF_CONN_ID;
1333        p_cb->act_protocol  = NCI_PROTOCOL_UNKNOWN;
1334
1335        nfc_set_state (NFC_STATE_W4_POST_INIT_CPLT);
1336
1337        nfc_cb.p_nci_init_rsp = p_msg;
1338        nfc_cb.p_hal->core_initialized (p);
1339    }
1340    else
1341    {
1342        nfc_enabled (status, NULL);
1343        GKI_freebuf (p_msg);
1344    }
1345}
1346
1347/*******************************************************************************
1348**
1349** Function         nfc_ncif_proc_get_config_rsp
1350**
1351** Description      This function is called to process get config response
1352**
1353** Returns          void
1354**
1355*******************************************************************************/
1356void nfc_ncif_proc_get_config_rsp (BT_HDR *p_evt)
1357{
1358    UINT8   *p;
1359    tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback;
1360    tNFC_RESPONSE  evt_data;
1361
1362    p_evt->offset += NCI_MSG_HDR_SIZE;
1363    p_evt->len    -= NCI_MSG_HDR_SIZE;
1364    if (p_cback)
1365    {
1366        p                                = (UINT8 *) (p_evt + 1) + p_evt->offset;
1367        evt_data.get_config.status       = *p++;
1368        evt_data.get_config.tlv_size     = p_evt->len;
1369        evt_data.get_config.p_param_tlvs = p;
1370        (*p_cback) (NFC_GET_CONFIG_REVT, &evt_data);
1371    }
1372}
1373
1374/*******************************************************************************
1375**
1376** Function         nfc_ncif_proc_t3t_polling_ntf
1377**
1378** Description      Handle NCI_MSG_RF_T3T_POLLING NTF
1379**
1380** Returns          void
1381**
1382*******************************************************************************/
1383void nfc_ncif_proc_t3t_polling_ntf (UINT8 *p, UINT16 plen)
1384{
1385    UINT8 status;
1386    UINT8 num_responses;
1387
1388    /* Pass result to RW_T3T for processing */
1389    STREAM_TO_UINT8 (status, p);
1390    STREAM_TO_UINT8 (num_responses, p);
1391    plen-=NFC_TL_SIZE;
1392    rw_t3t_handle_nci_poll_ntf (status, num_responses, (UINT8) plen, p);
1393}
1394
1395/*******************************************************************************
1396**
1397** Function         nfc_data_event
1398**
1399** Description      Report Data event on the given connection control block
1400**
1401** Returns          void
1402**
1403*******************************************************************************/
1404void nfc_data_event (tNFC_CONN_CB * p_cb)
1405{
1406    BT_HDR      *p_evt;
1407    tNFC_DATA_CEVT data_cevt;
1408    UINT8       *p;
1409
1410    if (p_cb->p_cback)
1411    {
1412        while ((p_evt = (BT_HDR *)GKI_getfirst (&p_cb->rx_q)) != NULL)
1413        {
1414            if (p_evt->layer_specific & NFC_RAS_FRAGMENTED)
1415            {
1416                /* Not the last fragment */
1417                if (!(p_evt->layer_specific & NFC_RAS_TOO_BIG))
1418                {
1419                    /* buffer can hold more */
1420                    if (  (p_cb->conn_id != NFC_RF_CONN_ID)
1421                        ||(nfc_cb.reassembly)  )
1422                    {
1423                        /* If not rf connection or If rf connection and reassembly requested,
1424                         * try to Reassemble next packet */
1425                        break;
1426                    }
1427                }
1428            }
1429
1430            p_evt = (BT_HDR *) GKI_dequeue (&p_cb->rx_q);
1431            /* report data event */
1432            p_evt->offset   += NCI_MSG_HDR_SIZE;
1433            p_evt->len      -= NCI_MSG_HDR_SIZE;
1434
1435            if (p_evt->layer_specific)
1436                data_cevt.status = NFC_STATUS_CONTINUE;
1437            else
1438            {
1439                nfc_cb.reassembly = TRUE;
1440                data_cevt.status = NFC_STATUS_OK;
1441            }
1442
1443            data_cevt.p_data = p_evt;
1444            /* adjust payload, if needed */
1445            if (p_cb->conn_id == NFC_RF_CONN_ID)
1446            {
1447                /* if NCI_PROTOCOL_T1T/NCI_PROTOCOL_T2T/NCI_PROTOCOL_T3T, the status byte needs to be removed
1448                 */
1449                if ((p_cb->act_protocol >= NCI_PROTOCOL_T1T) && (p_cb->act_protocol <= NCI_PROTOCOL_T3T))
1450                {
1451                    p_evt->len--;
1452                    p                = (UINT8 *) (p_evt + 1);
1453                    data_cevt.status = *(p + p_evt->offset + p_evt->len);
1454                }
1455            }
1456            (*p_cb->p_cback) (p_cb->conn_id, NFC_DATA_CEVT, (tNFC_CONN *) &data_cevt);
1457            p_evt = NULL;
1458        }
1459    }
1460}
1461
1462/*******************************************************************************
1463**
1464** Function         nfc_ncif_proc_data
1465**
1466** Description      Find the connection control block associated with the data
1467**                  packet. Assemble the data packet, if needed.
1468**                  Report the Data event.
1469**
1470** Returns          void
1471**
1472*******************************************************************************/
1473void nfc_ncif_proc_data (BT_HDR *p_msg)
1474{
1475    UINT8   *pp, cid;
1476    tNFC_CONN_CB * p_cb;
1477    UINT8   pbf;
1478    BT_HDR  *p_last;
1479    UINT8   *ps, *pd;
1480    UINT16  size;
1481    BT_HDR  *p_max = NULL;
1482    UINT16  len;
1483
1484    pp   = (UINT8 *) (p_msg+1) + p_msg->offset;
1485    NFC_TRACE_DEBUG3 ("nfc_ncif_proc_data 0x%02x%02x%02x", pp[0], pp[1], pp[2]);
1486    NCI_DATA_PRS_HDR (pp, pbf, cid, len);
1487    p_cb = nfc_find_conn_cb_by_conn_id (cid);
1488    if (p_cb && (p_msg->len >= NCI_DATA_HDR_SIZE))
1489    {
1490        NFC_TRACE_DEBUG1 ("nfc_ncif_proc_data len:%d", len);
1491
1492        p_msg->layer_specific       = 0;
1493        if (pbf)
1494            p_msg->layer_specific   = NFC_RAS_FRAGMENTED;
1495        p_last = (BT_HDR *)GKI_getlast (&p_cb->rx_q);
1496        if (p_last && (p_last->layer_specific & NFC_RAS_FRAGMENTED))
1497        {
1498            /* last data buffer is not last fragment, append this new packet to the last */
1499            size = GKI_get_buf_size(p_last);
1500            if (size < (BT_HDR_SIZE + p_last->len + p_last->offset + len))
1501            {
1502                /* the current size of p_last is not big enough to hold the new fragment, p_msg */
1503                if (size != GKI_MAX_BUF_SIZE)
1504                {
1505                    /* try the biggest GKI pool */
1506                    p_max = (BT_HDR *)GKI_getpoolbuf (GKI_MAX_BUF_SIZE_POOL_ID);
1507                    if (p_max)
1508                    {
1509                        /* copy the content of last buffer to the new buffer */
1510                        memcpy(p_max, p_last, BT_HDR_SIZE);
1511                        pd  = (UINT8 *)(p_max + 1) + p_max->offset;
1512                        ps  = (UINT8 *)(p_last + 1) + p_last->offset;
1513                        memcpy(pd, ps, p_last->len);
1514
1515                        /* place the new buffer in the queue instead */
1516                        GKI_remove_from_queue (&p_cb->rx_q, p_last);
1517                        GKI_freebuf (p_last);
1518                        GKI_enqueue (&p_cb->rx_q, p_max);
1519                        p_last  = p_max;
1520                    }
1521                }
1522                if (p_max == NULL)
1523                {
1524                    /* Biggest GKI Pool not available (or)
1525                     * Biggest available GKI Pool is not big enough to hold the new fragment, p_msg */
1526                    p_last->layer_specific  |= NFC_RAS_TOO_BIG;
1527                }
1528            }
1529
1530            ps   = (UINT8 *)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
1531            len  = p_msg->len - NCI_MSG_HDR_SIZE;
1532
1533            if (!(p_last->layer_specific & NFC_RAS_TOO_BIG))
1534            {
1535                pd   = (UINT8 *)(p_last + 1) + p_last->offset + p_last->len;
1536                memcpy(pd, ps, len);
1537                p_last->len  += len;
1538                /* do not need to update pbf and len in NCI header.
1539                 * They are stripped off at NFC_DATA_CEVT and len may exceed 255 */
1540                NFC_TRACE_DEBUG1 ("nfc_ncif_proc_data len:%d", p_last->len);
1541                p_last->layer_specific  = p_msg->layer_specific;
1542                GKI_freebuf (p_msg);
1543#ifdef DISP_NCI
1544                if (!(p_last->layer_specific & NFC_RAS_FRAGMENTED))
1545                {
1546                    /* this packet was reassembled. display the complete packet */
1547                    DISP_NCI ((UINT8 *)(p_last + 1) + p_last->offset, p_last->len, TRUE);
1548                }
1549#endif
1550                nfc_data_event (p_cb);
1551            }
1552            else
1553            {
1554                /* Not enough memory to add new buffer
1555                 * Send data already in queue first with status Continue */
1556                nfc_data_event (p_cb);
1557                /* now enqueue the new buffer to the rx queue */
1558                GKI_enqueue (&p_cb->rx_q, p_msg);
1559            }
1560        }
1561        else
1562        {
1563            /* if this is the first fragment on RF link */
1564            if (  (p_msg->layer_specific & NFC_RAS_FRAGMENTED)
1565                &&(p_cb->conn_id == NFC_RF_CONN_ID)
1566                &&(p_cb->p_cback)  )
1567            {
1568                /* Indicate upper layer that local device started receiving data */
1569                (*p_cb->p_cback) (p_cb->conn_id, NFC_DATA_START_CEVT, NULL);
1570            }
1571            /* enqueue the new buffer to the rx queue */
1572            GKI_enqueue (&p_cb->rx_q, p_msg);
1573            nfc_data_event (p_cb);
1574        }
1575        return;
1576    }
1577    GKI_freebuf (p_msg);
1578}
1579
1580#endif /* NFC_INCLUDED == TRUE*/
1581