1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-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 function of the NFC unit to receive/process NCI/VS
23  *  commands/responses.
24  *
25  ******************************************************************************/
26 #include <string.h>
27 #include "nfc_hal_int.h"
28 #include "nfc_hal_post_reset.h"
29 #include "userial.h"
30 #include "nci_defs.h"
31 
32 
33 /*****************************************************************************
34 ** Constants and types
35 *****************************************************************************/
36 
37 /*****************************************************************************
38 ** Local function prototypes
39 *****************************************************************************/
40 
41 /*******************************************************************************
42 **
43 ** Function         nfc_hal_nci_assemble_nci_msg
44 **
45 ** Description      This function is called to reassemble the received NCI
46 **                  response/notification packet, if required.
47 **                  (The data packets are posted to NFC task for reassembly)
48 **
49 ** Returns          void.
50 **
51 *******************************************************************************/
nfc_hal_nci_assemble_nci_msg(void)52 void nfc_hal_nci_assemble_nci_msg (void)
53 {
54     NFC_HDR *p_msg = nfc_hal_cb.ncit_cb.p_rcv_msg;
55     UINT8 u8;
56     UINT8 *p, *pp;
57     UINT8 hdr[2];
58     UINT8   *ps, *pd;
59     UINT16  size, needed;
60     BOOLEAN disp_again = FALSE;
61 
62     if ((p_msg == NULL) || (p_msg->len < NCI_MSG_HDR_SIZE))
63         return;
64 
65 #ifdef DISP_NCI
66     DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
67 #endif
68 
69     p       = (UINT8 *) (p_msg + 1) + p_msg->offset;
70     u8      = *p++;
71     /* remove the PBF bit for potential reassembly later */
72     hdr[0]  = u8 & ~NCI_PBF_MASK;
73     if ((u8 & NCI_MT_MASK) == NCI_MT_DATA)
74     {
75         /* clear the RFU in octet1 */
76         *(p) = 0;
77         /* data packet reassembly is performed in NFC task */
78         return;
79     }
80     else
81     {
82         *(p) &= NCI_OID_MASK;
83     }
84 
85     hdr[1]  = *p;
86     pp = hdr;
87     /* save octet0 and octet1 of an NCI header in layer_specific for the received packet */
88     STREAM_TO_UINT16 (p_msg->layer_specific, pp);
89 
90     if (nfc_hal_cb.ncit_cb.p_frag_msg)
91     {
92         if (nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific != p_msg->layer_specific)
93         {
94             /* check if these fragments are of the same NCI message */
95             HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() - different messages 0x%x, 0x%x!!", nfc_hal_cb.ncit_cb.p_frag_msg->layer_specific, p_msg->layer_specific);
96             nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_ERROR;
97         }
98         else if (nfc_hal_cb.ncit_cb.nci_ras == 0)
99         {
100             disp_again = TRUE;
101             /* if not previous reassembly error, append the new fragment */
102             p_msg->offset   += NCI_MSG_HDR_SIZE;
103             p_msg->len      -= NCI_MSG_HDR_SIZE;
104             size    = GKI_get_buf_size (nfc_hal_cb.ncit_cb.p_frag_msg);
105             needed  = (NFC_HDR_SIZE + nfc_hal_cb.ncit_cb.p_frag_msg->len + nfc_hal_cb.ncit_cb.p_frag_msg->offset + p_msg->len);
106             if (size >= needed)
107             {
108                 /* the buffer for reassembly is big enough to append the new fragment */
109                 ps   = (UINT8 *) (p_msg + 1) + p_msg->offset;
110                 pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + nfc_hal_cb.ncit_cb.p_frag_msg->len;
111                 memcpy (pd, ps, p_msg->len);
112                 nfc_hal_cb.ncit_cb.p_frag_msg->len  += p_msg->len;
113                 /* adjust the NCI packet length */
114                 pd   = (UINT8 *) (nfc_hal_cb.ncit_cb.p_frag_msg + 1) + nfc_hal_cb.ncit_cb.p_frag_msg->offset + 2;
115                 *pd  = (UINT8) (nfc_hal_cb.ncit_cb.p_frag_msg->len - NCI_MSG_HDR_SIZE);
116             }
117             else
118             {
119                 nfc_hal_cb.ncit_cb.nci_ras  |= NFC_HAL_NCI_RAS_TOO_BIG;
120                 HAL_TRACE_ERROR2 ("nfc_hal_nci_assemble_nci_msg() buffer overrun (%d + %d)!!", nfc_hal_cb.ncit_cb.p_frag_msg->len, p_msg->len);
121             }
122         }
123         /* we are done with this new fragment, free it */
124         GKI_freebuf (p_msg);
125     }
126     else
127     {
128         nfc_hal_cb.ncit_cb.p_frag_msg = p_msg;
129     }
130 
131 
132     if ((u8 & NCI_PBF_MASK) == NCI_PBF_NO_OR_LAST)
133     {
134         /* last fragment */
135         p_msg               = nfc_hal_cb.ncit_cb.p_frag_msg;
136         p                   = (UINT8 *) (p_msg + 1) + p_msg->offset;
137         *p                  = u8; /* this should make the PBF flag as Last Fragment */
138         nfc_hal_cb.ncit_cb.p_frag_msg  = NULL;
139 
140         p_msg->layer_specific = nfc_hal_cb.ncit_cb.nci_ras;
141         /* still report the data packet, if the incoming packet is too big */
142         if (nfc_hal_cb.ncit_cb.nci_ras & NFC_HAL_NCI_RAS_ERROR)
143         {
144             /* NFCC reported NCI fragments for different NCI messages and this is the last fragment - drop it */
145             HAL_TRACE_ERROR0 ("nfc_hal_nci_assemble_nci_msg() clearing NCI_RAS_ERROR");
146             GKI_freebuf (p_msg);
147             p_msg = NULL;
148         }
149 #ifdef DISP_NCI
150         if ((nfc_hal_cb.ncit_cb.nci_ras == 0) && (disp_again))
151         {
152             DISP_NCI ((UINT8 *) (p_msg + 1) + p_msg->offset, (UINT16) (p_msg->len), TRUE);
153         }
154 #endif
155         /* clear the error flags, so the next NCI packet is clean */
156         nfc_hal_cb.ncit_cb.nci_ras = 0;
157     }
158     else
159     {
160         /* still reassembling */
161         p_msg = NULL;
162     }
163 
164     nfc_hal_cb.ncit_cb.p_rcv_msg = p_msg;
165 }
166 
167 /*****************************************************************************
168 **
169 ** Function         nfc_hal_nci_receive_nci_msg
170 **
171 ** Description
172 **      Handle incoming data (NCI events) from the serial port.
173 **
174 **      If there is data waiting from the serial port, this funciton reads the
175 **      data and parses it. Once an entire NCI message has been read, it sends
176 **      the message the the NFC_TASK for processing
177 **
178 *****************************************************************************/
nfc_hal_nci_receive_nci_msg(tNFC_HAL_NCIT_CB * p_cb,UINT8 byte)179 static BOOLEAN nfc_hal_nci_receive_nci_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
180 {
181     UINT16      len;
182     BOOLEAN     msg_received = FALSE;
183 
184     switch (p_cb->rcv_state)
185     {
186     case NFC_HAL_RCV_NCI_MSG_ST:
187 
188         /* Initialize rx parameters */
189         p_cb->rcv_state = NFC_HAL_RCV_NCI_HDR_ST;
190         p_cb->rcv_len   = NCI_MSG_HDR_SIZE;
191 
192         /* Start of new message. Allocate a buffer for message */
193         if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
194         {
195             /* Initialize NFC_HDR */
196             p_cb->p_rcv_msg->len    = 0;
197             p_cb->p_rcv_msg->event  = 0;
198             p_cb->p_rcv_msg->offset = 0;
199 
200             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
201         }
202         else
203         {
204             HAL_TRACE_ERROR0 ("Unable to allocate buffer for incoming NCI message.");
205         }
206         p_cb->rcv_len--;
207         break;
208 
209     case NFC_HAL_RCV_NCI_HDR_ST:
210 
211         if (p_cb->p_rcv_msg)
212         {
213             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
214         }
215 
216         p_cb->rcv_len--;
217 
218         /* Check if we read in entire NFC message header yet */
219         if (p_cb->rcv_len == 0)
220         {
221             p_cb->rcv_len       = byte;
222 
223             /* If non-zero payload, then go to receive-data state */
224             if (byte > 0)
225             {
226                 p_cb->rcv_state = NFC_HAL_RCV_NCI_PAYLOAD_ST;
227             }
228             else
229             {
230                 msg_received    = TRUE;
231                 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
232             }
233         }
234         break;
235 
236     case NFC_HAL_RCV_NCI_PAYLOAD_ST:
237 
238         p_cb->rcv_len--;
239         if (p_cb->p_rcv_msg)
240         {
241             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
242 
243             if (p_cb->rcv_len > 0)
244             {
245                 /* Read in the rest of the message */
246                 len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
247                 p_cb->p_rcv_msg->len    += len;
248                 p_cb->rcv_len           -= len;
249             }
250         }
251 
252         /* Check if we read in entire message yet */
253         if (p_cb->rcv_len == 0)
254         {
255             msg_received    = TRUE;
256             p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;
257         }
258         break;
259     }
260 
261     return (msg_received);
262 }
263 
264 /*****************************************************************************
265 **
266 ** Function         nfc_hal_nci_receive_bt_msg
267 **
268 ** Description
269 **      Handle incoming BRCM specific data from the serial port.
270 **
271 **      If there is data waiting from the serial port, this funciton reads the
272 **      data and parses it. Once an entire message has been read, it returns
273 **      TRUE.
274 **
275 *****************************************************************************/
nfc_hal_nci_receive_bt_msg(tNFC_HAL_NCIT_CB * p_cb,UINT8 byte)276 static BOOLEAN nfc_hal_nci_receive_bt_msg (tNFC_HAL_NCIT_CB *p_cb, UINT8 byte)
277 {
278     UINT16  len;
279     BOOLEAN msg_received = FALSE;
280 
281     switch (p_cb->rcv_state)
282     {
283     case NFC_HAL_RCV_BT_MSG_ST:
284 
285         /* Initialize rx parameters */
286         p_cb->rcv_state = NFC_HAL_RCV_BT_HDR_ST;
287         p_cb->rcv_len   = HCIE_PREAMBLE_SIZE;
288 
289         if ((p_cb->p_rcv_msg = (NFC_HDR *) GKI_getpoolbuf (NFC_HAL_NCI_POOL_ID)) != NULL)
290         {
291             /* Initialize NFC_HDR */
292             p_cb->p_rcv_msg->len    = 0;
293             p_cb->p_rcv_msg->event  = 0;
294             p_cb->p_rcv_msg->offset = 0;
295 
296             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
297         }
298         else
299         {
300             HAL_TRACE_ERROR0 ("[nfc] Unable to allocate buffer for incoming NCI message.");
301         }
302         p_cb->rcv_len--;
303         break;
304 
305     case NFC_HAL_RCV_BT_HDR_ST:
306         if (p_cb->p_rcv_msg)
307         {
308             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
309         }
310         p_cb->rcv_len--;
311 
312         /* Check if we received entire preamble yet */
313         if (p_cb->rcv_len == 0)
314         {
315             /* Received entire preamble. Length is in the last byte(s) of the preamble */
316             p_cb->rcv_len = byte;
317 
318             /* Verify that buffer is big enough to fit message */
319             if ((p_cb->p_rcv_msg) &&
320                 ((sizeof (NFC_HDR) + HCIE_PREAMBLE_SIZE + byte) > GKI_get_buf_size (p_cb->p_rcv_msg))  )
321             {
322                 /* Message cannot fit into buffer */
323                 GKI_freebuf (p_cb->p_rcv_msg);
324                 p_cb->p_rcv_msg     = NULL;
325 
326                 HAL_TRACE_ERROR0 ("Invalid length for incoming BT HCI message.");
327             }
328 
329             /* Message length is valid */
330             if (byte)
331             {
332                 /* Read rest of message */
333                 p_cb->rcv_state = NFC_HAL_RCV_BT_PAYLOAD_ST;
334             }
335             else
336             {
337                 /* Message has no additional parameters. (Entire message has been received) */
338                 msg_received    = TRUE;
339                 p_cb->rcv_state = NFC_HAL_RCV_IDLE_ST;  /* Next, wait for packet type of next message */
340             }
341         }
342         break;
343 
344     case NFC_HAL_RCV_BT_PAYLOAD_ST:
345         p_cb->rcv_len--;
346         if (p_cb->p_rcv_msg)
347         {
348             *((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len++) = byte;
349 
350             if (p_cb->rcv_len > 0)
351             {
352                 /* Read in the rest of the message */
353                 len = USERIAL_Read (USERIAL_NFC_PORT, ((UINT8 *) (p_cb->p_rcv_msg + 1) + p_cb->p_rcv_msg->offset + p_cb->p_rcv_msg->len),  p_cb->rcv_len);
354                 p_cb->p_rcv_msg->len    += len;
355                 p_cb->rcv_len           -= len;
356             }
357         }
358 
359         /* Check if we read in entire message yet */
360         if (p_cb->rcv_len == 0)
361         {
362             msg_received        = TRUE;
363             p_cb->rcv_state     = NFC_HAL_RCV_IDLE_ST;      /* Next, wait for packet type of next message */
364         }
365         break;
366     }
367 
368     /* If we received entire message */
369 #if (NFC_HAL_TRACE_PROTOCOL == TRUE)
370     if (msg_received && p_cb->p_rcv_msg)
371     {
372         /* Display protocol trace message */
373         DispHciEvt (p_cb->p_rcv_msg);
374     }
375 #endif
376 
377     return (msg_received);
378 }
379 
380 /*******************************************************************************
381 **
382 ** Function         nfc_hal_nci_proc_rx_bt_msg
383 **
384 ** Description      Received BT message from NFCC
385 **
386 **                  Notify command complete if initializing NFCC
387 **                  Forward BT message to NFC task
388 **
389 ** Returns          void
390 **
391 *******************************************************************************/
nfc_hal_nci_proc_rx_bt_msg(void)392 static void nfc_hal_nci_proc_rx_bt_msg (void)
393 {
394     UINT8   *p;
395     NFC_HDR *p_msg;
396     UINT16  opcode, old_opcode;
397     tNFC_HAL_BTVSC_CPLT       vcs_cplt_params;
398     tNFC_HAL_BTVSC_CPLT_CBACK *p_cback = NULL;
399 
400     /* if complete BT message is received successfully */
401     if (nfc_hal_cb.ncit_cb.p_rcv_msg)
402     {
403         p_msg   = nfc_hal_cb.ncit_cb.p_rcv_msg;
404         HAL_TRACE_DEBUG1 ("nfc_hal_nci_proc_rx_bt_msg (): GOT an BT msgs init_sta:%d", nfc_hal_cb.dev_cb.initializing_state);
405         HAL_TRACE_DEBUG2 ("event: 0x%x, wait_rsp:0x%x", p_msg->event, nfc_hal_cb.ncit_cb.nci_wait_rsp);
406         /* increase the cmd window here */
407         if (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_PROP)
408         {
409             p = (UINT8 *) (p_msg + 1) + p_msg->offset;
410             if (*p == HCI_COMMAND_COMPLETE_EVT)
411             {
412                 p  += 3; /* code, len, cmd window */
413                 STREAM_TO_UINT16 (opcode, p);
414                 p   = nfc_hal_cb.ncit_cb.last_hdr;
415                 STREAM_TO_UINT16 (old_opcode, p);
416                 if (opcode == old_opcode)
417                 {
418                     nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
419                     p_cback = (tNFC_HAL_BTVSC_CPLT_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback;
420                     nfc_hal_cb.ncit_cb.p_vsc_cback  = NULL;
421                     nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
422                 }
423             }
424         }
425 
426         /* if initializing BRCM NFCC */
427         if ((nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE) ||
428             (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ||
429             (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE))
430         {
431             /* this is command complete event for baud rate update or download patch */
432             p = (UINT8 *) (p_msg + 1) + p_msg->offset;
433 
434             p += 1;    /* skip opcode */
435             STREAM_TO_UINT8  (vcs_cplt_params.param_len, p);
436 
437             p += 1;    /* skip num command packets */
438             STREAM_TO_UINT16 (vcs_cplt_params.opcode, p);
439 
440             vcs_cplt_params.param_len -= 3;
441             vcs_cplt_params.p_param_buf = p;
442 
443             if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
444             {
445                 NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
446                 nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
447             }
448             if (p_cback)
449             {
450                 nfc_hal_cb.ncit_cb.p_vsc_cback = NULL;
451                 (*p_cback) (&vcs_cplt_params);
452             }
453 
454             /* do not BT send message to NFC task */
455             GKI_freebuf (p_msg);
456         }
457         else
458         {
459             /* do not BT send message to NFC task */
460             GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
461         }
462         nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
463     }
464 }
465 
466 /*****************************************************************************
467 **
468 ** Function         nfc_hal_nci_receive_msg
469 **
470 ** Description
471 **      Handle incoming data (NCI events) from the serial port.
472 **
473 **      If there is data waiting from the serial port, this funciton reads the
474 **      data and parses it. Once an entire NCI message has been read, it sends
475 **      the message the the NFC_TASK for processing
476 **
477 *****************************************************************************/
nfc_hal_nci_receive_msg(UINT8 byte)478 BOOLEAN nfc_hal_nci_receive_msg (UINT8 byte)
479 {
480     tNFC_HAL_NCIT_CB *p_cb = &(nfc_hal_cb.ncit_cb);
481     BOOLEAN msg_received = FALSE;
482 
483     if (p_cb->rcv_state == NFC_HAL_RCV_IDLE_ST)
484     {
485         /* if this is NCI message */
486         if (byte == HCIT_TYPE_NFC)
487         {
488             p_cb->rcv_state = NFC_HAL_RCV_NCI_MSG_ST;
489         }
490         /* if this is BT message */
491         else if (byte == HCIT_TYPE_EVENT)
492         {
493             p_cb->rcv_state = NFC_HAL_RCV_BT_MSG_ST;
494         }
495         else
496         {
497             HAL_TRACE_ERROR1 ("Unknown packet type drop this byte 0x%x", byte);
498         }
499     }
500     else if (p_cb->rcv_state <= NFC_HAL_RCV_NCI_PAYLOAD_ST)
501     {
502         msg_received = nfc_hal_nci_receive_nci_msg (p_cb, byte);
503     }
504     else
505     {
506         if (nfc_hal_nci_receive_bt_msg (p_cb, byte))
507         {
508             /* received BT message */
509             nfc_hal_nci_proc_rx_bt_msg ();
510         }
511     }
512 
513     return (msg_received);
514 }
515 
516 /*******************************************************************************
517 **
518 ** Function         nfc_hal_nci_preproc_rx_nci_msg
519 **
520 ** Description      NFCC sends NCI message to DH while initializing NFCC
521 **                  processing low power mode
522 **
523 ** Returns          TRUE, if NFC task need to receive NCI message
524 **
525 *******************************************************************************/
nfc_hal_nci_preproc_rx_nci_msg(NFC_HDR * p_msg)526 BOOLEAN nfc_hal_nci_preproc_rx_nci_msg (NFC_HDR *p_msg)
527 {
528     UINT8 *p, *pp;
529     UINT8 mt, pbf, gid, op_code;
530     UINT8 payload_len;
531 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
532     UINT8  cid;
533     UINT16 data_len;
534 #endif
535 
536     HAL_TRACE_DEBUG0 ("nfc_hal_nci_preproc_rx_nci_msg()");
537 
538     /* if initializing BRCM NFCC */
539     if (nfc_hal_cb.dev_cb.initializing_state != NFC_HAL_INIT_STATE_IDLE)
540     {
541         nfc_hal_dm_proc_msg_during_init (p_msg);
542         /* do not send message to NFC task while initializing NFCC */
543         return (FALSE);
544     }
545     else
546     {
547         p = (UINT8 *) (p_msg + 1) + p_msg->offset;
548         pp = p;
549         NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
550         NCI_MSG_PRS_HDR1 (p, op_code);
551         payload_len = *p++;
552 
553 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
554         if (mt == NCI_MT_DATA)
555         {
556             if (nfc_hal_cb.hci_cb.hcp_conn_id)
557             {
558                 NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
559                 if (cid == nfc_hal_cb.hci_cb.hcp_conn_id)
560                 {
561                     nfc_hal_hci_handle_hcp_pkt_from_hc (pp);
562                 }
563 
564             }
565         }
566 
567         if (gid == NCI_GID_PROP) /* this is for hci netwk ntf */
568         {
569             if (mt == NCI_MT_NTF)
570             {
571                 if (op_code == NCI_MSG_HCI_NETWK)
572                 {
573                     nfc_hal_hci_handle_hci_netwk_info ((UINT8 *) (p_msg + 1) + p_msg->offset);
574                 }
575             }
576         }
577         else
578 #endif
579         if (gid == NCI_GID_RF_MANAGE)
580         {
581             if (mt == NCI_MT_NTF)
582             {
583                 if (op_code == NCI_MSG_RF_INTF_ACTIVATED)
584                 {
585                     if ((nfc_hal_cb.max_rf_credits) && (payload_len > 5))
586                     {
587                         /* API used wants to limit the RF data credits */
588                         p += 5; /* skip RF disc id, interface, protocol, tech&mode, payload size */
589                         if (*p > nfc_hal_cb.max_rf_credits)
590                         {
591                             HAL_TRACE_DEBUG2 ("RfDataCredits %d->%d", *p, nfc_hal_cb.max_rf_credits);
592                             *p = nfc_hal_cb.max_rf_credits;
593                         }
594                     }
595                 }
596             }
597         }
598 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
599         else if (gid == NCI_GID_CORE)
600         {
601             if (mt == NCI_MT_RSP)
602             {
603                 if (op_code == NCI_MSG_CORE_CONN_CREATE)
604                 {
605                     if (nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp)
606                     {
607                         p++; /* skip status byte */
608                         nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
609                         p++; /* skip buff size */
610                         p++; /* num of buffers */
611                         nfc_hal_cb.hci_cb.hcp_conn_id = *p;
612                     }
613                 }
614             }
615         }
616 #endif
617     }
618 
619     if (nfc_hal_cb.dev_cb.power_mode == NFC_HAL_POWER_MODE_FULL)
620     {
621         if (nfc_hal_cb.dev_cb.snooze_mode != NFC_HAL_LP_SNOOZE_MODE_NONE)
622         {
623             /* extend idle timer */
624             nfc_hal_dm_power_mode_execute (NFC_HAL_LP_RX_DATA_EVT);
625         }
626     }
627 
628     return (TRUE);
629 }
630 
631 /*******************************************************************************
632 **
633 ** Function         nfc_hal_nci_add_nfc_pkt_type
634 **
635 ** Description      Add packet type (HCIT_TYPE_NFC)
636 **
637 ** Returns          TRUE, if NFCC can receive NCI message
638 **
639 *******************************************************************************/
nfc_hal_nci_add_nfc_pkt_type(NFC_HDR * p_msg)640 void nfc_hal_nci_add_nfc_pkt_type (NFC_HDR *p_msg)
641 {
642     UINT8   *p;
643     UINT8   hcit;
644 
645     /* add packet type in front of NCI header */
646     if (p_msg->offset > 0)
647     {
648         p_msg->offset--;
649         p_msg->len++;
650 
651         p  = (UINT8 *) (p_msg + 1) + p_msg->offset;
652         *p = HCIT_TYPE_NFC;
653     }
654     else
655     {
656         HAL_TRACE_ERROR0 ("nfc_hal_nci_add_nfc_pkt_type () : No space for packet type");
657         hcit = HCIT_TYPE_NFC;
658         USERIAL_Write (USERIAL_NFC_PORT, &hcit, 1);
659     }
660 }
661 
662 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
663 /*******************************************************************************
664 **
665 ** Function         nci_brcm_check_cmd_create_hcp_connection
666 **
667 ** Description      Check if this is command to create HCP connection
668 **
669 ** Returns          None
670 **
671 *******************************************************************************/
nci_brcm_check_cmd_create_hcp_connection(NFC_HDR * p_msg)672 static void nci_brcm_check_cmd_create_hcp_connection (NFC_HDR *p_msg)
673 {
674     UINT8 *p;
675     UINT8 mt, pbf, gid, op_code;
676 
677     nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = FALSE;
678 
679     p = (UINT8 *) (p_msg + 1) + p_msg->offset;
680 
681     if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_IDLE)
682     {
683         NCI_MSG_PRS_HDR0 (p, mt, pbf, gid);
684         NCI_MSG_PRS_HDR1 (p, op_code);
685 
686         if (gid == NCI_GID_CORE)
687         {
688             if (mt == NCI_MT_CMD)
689             {
690                 if (op_code == NCI_MSG_CORE_CONN_CREATE)
691                 {
692                     if (  ((NCI_CORE_PARAM_SIZE_CON_CREATE + 4) == *p++)
693                         &&(NCI_DEST_TYPE_NFCEE == *p++)
694                         &&(1 == *p++)
695                         &&(NCI_CON_CREATE_TAG_NFCEE_VAL == *p++)
696                         &&(2 == *p++)  )
697                     {
698                         p++;
699                         if (NCI_NFCEE_INTERFACE_HCI_ACCESS == *p)
700                         {
701                             nfc_hal_cb.hci_cb.b_wait_hcp_conn_create_rsp = TRUE;
702                             return;
703                         }
704                     }
705 
706                 }
707             }
708         }
709     }
710 }
711 
712 #endif
713 
714 /*******************************************************************************
715 **
716 ** Function         nfc_hal_nci_send_cmd
717 **
718 ** Description      Send NCI command to the transport
719 **
720 ** Returns          void
721 **
722 *******************************************************************************/
nfc_hal_nci_send_cmd(NFC_HDR * p_buf)723 void nfc_hal_nci_send_cmd (NFC_HDR *p_buf)
724 {
725     BOOLEAN continue_to_process = TRUE;
726     UINT8   *ps, *pd;
727     UINT16  max_len;
728     UINT16  buf_len, offset;
729     UINT8   *p;
730     UINT8   hdr[NCI_MSG_HDR_SIZE];
731     UINT8   nci_ctrl_size = nfc_hal_cb.ncit_cb.nci_ctrl_size;
732     UINT8   delta = 0;
733 
734 #if (defined(NFC_HAL_HCI_INCLUDED) && (NFC_HAL_HCI_INCLUDED == TRUE))
735     if (  (nfc_hal_cb.hci_cb.hcp_conn_id == 0)
736         &&(nfc_hal_cb.nvm_cb.nvm_type != NCI_SPD_NVM_TYPE_NONE)  )
737         nci_brcm_check_cmd_create_hcp_connection ((NFC_HDR*) p_buf);
738 #endif
739 
740     /* check low power mode state */
741     continue_to_process = nfc_hal_dm_power_mode_execute (NFC_HAL_LP_TX_DATA_EVT);
742 
743     if (!continue_to_process)
744     {
745         /* save the command to be sent until NFCC is free. */
746         nfc_hal_cb.ncit_cb.p_pend_cmd   = p_buf;
747         return;
748     }
749 
750     max_len = nci_ctrl_size + NCI_MSG_HDR_SIZE;
751     buf_len = p_buf->len;
752     offset  = p_buf->offset;
753 #ifdef DISP_NCI
754     if (buf_len > max_len)
755     {
756         /* this command needs to be fragmented. display the complete packet first */
757         DISP_NCI ((UINT8 *) (p_buf + 1) + p_buf->offset, p_buf->len, FALSE);
758     }
759 #endif
760     ps      = (UINT8 *) (p_buf + 1) + p_buf->offset;
761     memcpy (hdr, ps, NCI_MSG_HDR_SIZE);
762     while (buf_len > max_len)
763     {
764         HAL_TRACE_DEBUG2 ("buf_len (%d) > max_len (%d)", buf_len, max_len);
765         /* the NCI command is bigger than the NFCC Max Control Packet Payload Length
766          * fragment the command */
767 
768         p_buf->len  = max_len;
769         ps   = (UINT8 *) (p_buf + 1) + p_buf->offset;
770         /* mark the control packet as fragmented */
771         *ps |= NCI_PBF_ST_CONT;
772         /* adjust the length of this fragment */
773         ps  += 2;
774         *ps  = nci_ctrl_size;
775 
776         /* add NCI packet type in front of message */
777         nfc_hal_nci_add_nfc_pkt_type (p_buf);
778 
779         /* send this fragment to transport */
780         p = (UINT8 *) (p_buf + 1) + p_buf->offset;
781 
782 #ifdef DISP_NCI
783         delta = p_buf->len - max_len;
784         DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
785 #endif
786         USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
787 
788         /* adjust the len and offset to reflect that part of the command is already sent */
789         buf_len -= nci_ctrl_size;
790         offset  += nci_ctrl_size;
791         HAL_TRACE_DEBUG2 ("p_buf->len: %d buf_len (%d)", p_buf->len, buf_len);
792         p_buf->len      = buf_len;
793         p_buf->offset   = offset;
794         pd   = (UINT8 *) (p_buf + 1) + p_buf->offset;
795         /* restore the NCI header */
796         memcpy (pd, hdr, NCI_MSG_HDR_SIZE);
797         pd  += 2;
798         *pd  = (UINT8) (p_buf->len - NCI_MSG_HDR_SIZE);
799     }
800 
801     HAL_TRACE_DEBUG1 ("p_buf->len: %d", p_buf->len);
802 
803     /* add NCI packet type in front of message */
804     nfc_hal_nci_add_nfc_pkt_type (p_buf);
805 
806     /* send this fragment to transport */
807     p = (UINT8 *) (p_buf + 1) + p_buf->offset;
808 
809 #ifdef DISP_NCI
810     delta = p_buf->len - buf_len;
811     DISP_NCI (p + delta, (UINT16) (p_buf->len - delta), FALSE);
812 #endif
813     USERIAL_Write (USERIAL_NFC_PORT, p, p_buf->len);
814 
815     GKI_freebuf (p_buf);
816 }
817 
818 /*******************************************************************************
819 **
820 ** Function         nfc_hal_nci_cmd_timeout_cback
821 **
822 ** Description      callback function for timeout
823 **
824 ** Returns          void
825 **
826 *******************************************************************************/
nfc_hal_nci_cmd_timeout_cback(void * p_tle)827 void nfc_hal_nci_cmd_timeout_cback (void *p_tle)
828 {
829     TIMER_LIST_ENT  *p_tlent = (TIMER_LIST_ENT *)p_tle;
830 
831     HAL_TRACE_DEBUG0 ("nfc_hal_nci_cmd_timeout_cback ()");
832 
833     nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE;
834 
835     if (p_tlent->event == NFC_HAL_TTYPE_NCI_WAIT_RSP)
836     {
837         if (nfc_hal_cb.dev_cb.initializing_state <= NFC_HAL_INIT_STATE_W4_PATCH_INFO)
838         {
839             NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
840             nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
841         }
842         else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_APP_COMPLETE)
843         {
844             if (nfc_hal_cb.prm.state != NFC_HAL_PRM_ST_IDLE)
845             {
846                 nfc_hal_prm_process_timeout (NULL);
847             }
848             else
849             {
850                 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
851                 nfc_hal_main_pre_init_done (HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
852             }
853         }
854         else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_POST_INIT_DONE)
855         {
856             NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
857             nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
858         }
859         else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_CONTROL_DONE)
860         {
861             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
862             nfc_hal_cb.p_stack_cback (HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
863         }
864         else if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE)
865         {
866             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
867             nfc_hal_cb.p_stack_cback (HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_ERR_CMD_TIMEOUT);
868         }
869     }
870 }
871 
872 
873 /*******************************************************************************
874 **
875 ** Function         HAL_NfcSetMaxRfDataCredits
876 **
877 ** Description      This function sets the maximum RF data credit for HAL.
878 **                  If 0, use the value reported from NFCC.
879 **
880 ** Returns          none
881 **
882 *******************************************************************************/
HAL_NfcSetMaxRfDataCredits(UINT8 max_credits)883 void HAL_NfcSetMaxRfDataCredits (UINT8 max_credits)
884 {
885     HAL_TRACE_DEBUG2 ("HAL_NfcSetMaxRfDataCredits %d->%d", nfc_hal_cb.max_rf_credits, max_credits);
886     nfc_hal_cb.max_rf_credits   = max_credits;
887 }
888