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  *  Functions for handling NFC HAL NCI Transport events
22  *
23  ******************************************************************************/
24 #include <string.h>
25 #include "nfc_hal_int.h"
26 #include "nfc_hal_post_reset.h"
27 #include "upio.h"
28 #include "userial.h"
29 
30 /****************************************************************************
31 ** Definitions
32 ****************************************************************************/
33 
34 /* Default NFC HAL NCI port configuration  */
35 NFC_HAL_TRANS_CFG_QUALIFIER tNFC_HAL_TRANS_CFG nfc_hal_trans_cfg = {
36     NFC_HAL_SHARED_TRANSPORT_ENABLED, /* bSharedTransport */
37     USERIAL_BAUD_115200,              /* Baud rate */
38     USERIAL_FC_HW                     /* Flow control */
39 };
40 
41 /* Control block for NFC HAL NCI transport */
42 tNFC_HAL_CB nfc_hal_cb;
43 
44 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
45 /****************************************************************************
46 ** Internal function prototypes
47 ****************************************************************************/
48 static void nfc_hal_main_userial_cback(tUSERIAL_PORT port, tUSERIAL_EVT evt,
49                                        tUSERIAL_EVT_DATA* p_data);
50 static void nfc_hal_main_handle_terminate(void);
51 static void nfc_hal_main_timeout_cback(void* p_tle);
52 
53 #if (NFC_HAL_DEBUG == TRUE)
54 const char* const nfc_hal_init_state_str[] = {
55     "IDLE",           /* Initialization is done                */
56     "W4_XTAL_SET",    /* Waiting for crystal setting rsp       */
57     "POST_XTAL_SET",  /* Waiting for reset ntf after xtal set  */
58     "W4_NFCC_ENABLE", /* Waiting for reset ntf atter REG_PU up */
59     "W4_BUILD_INFO",  /* Waiting for build info rsp            */
60     "W4_PATCH_INFO",  /* Waiting for patch info rsp            */
61     "W4_APP_COMPL",   /* Waiting for complete from application */
62     "W4_POST_INIT",   /* Waiting for complete of post init     */
63     "W4_CONTROL",     /* Waiting for control release           */
64     "W4_PREDISC",     /* Waiting for complete of prediscover   */
65     "CLOSING"         /* Shutting down                         */
66 };
67 #endif
68 
69 /*******************************************************************************
70 **
71 ** Function         nfc_hal_main_init
72 **
73 ** Description      This function initializes control block for NFC HAL
74 **
75 ** Returns          nothing
76 **
77 *******************************************************************************/
nfc_hal_main_init(void)78 void nfc_hal_main_init(void) {
79   /* Clear control block */
80   memset(&nfc_hal_cb, 0, sizeof(tNFC_HAL_CB));
81 
82   nfc_hal_cb.ncit_cb.nci_ctrl_size = NFC_HAL_NCI_INIT_CTRL_PAYLOAD_SIZE;
83   nfc_hal_cb.trace_level = NFC_HAL_INITIAL_TRACE_LEVEL;
84   nfc_hal_cb.timer.p_cback = nfc_hal_main_timeout_cback;
85 }
86 
87 /*******************************************************************************
88 **
89 ** Function         nfc_hal_main_open_transport
90 **
91 ** Description      Open transport and prepare for new incoming message;
92 **
93 ** Returns          nothing
94 **
95 *******************************************************************************/
nfc_hal_main_open_transport(void)96 static void nfc_hal_main_open_transport(void) {
97   tUSERIAL_OPEN_CFG open_cfg;
98 
99   /* Initialize control block */
100   nfc_hal_cb.ncit_cb.rcv_state =
101       NFC_HAL_RCV_IDLE_ST; /* to process packet type */
102 
103   if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
104     GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
105     nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
106   }
107 
108   /* open transport */
109   open_cfg.fmt =
110       (USERIAL_DATABITS_8 | USERIAL_PARITY_NONE | USERIAL_STOPBITS_1);
111   open_cfg.baud = nfc_hal_trans_cfg.userial_baud;
112   open_cfg.fc = nfc_hal_trans_cfg.userial_fc;
113   open_cfg.buf = USERIAL_BUF_BYTE;
114 
115   USERIAL_Open(USERIAL_NFC_PORT, &open_cfg, nfc_hal_main_userial_cback);
116 
117   {
118     /* Wait for NFCC to enable - Core reset notification */
119     NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_NFCC_ENABLE);
120 
121     /* NFCC Enable timeout */
122     nfc_hal_main_start_quick_timer(
123         &nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE,
124         ((p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout) *
125          QUICK_TIMER_TICKS_PER_SEC) /
126             1000);
127   }
128 }
129 
130 /*******************************************************************************
131 **
132 ** Function         nfc_hal_main_close
133 **
134 ** Description      Check and shutdown NFCC
135 **
136 ** Returns          None
137 **
138 *******************************************************************************/
nfc_hal_main_close(void)139 void nfc_hal_main_close(void) {
140   tHAL_NFC_CBACK* p_stack_cback_temp;
141 
142   if ((nfc_hal_cb.dev_cb.initializing_state !=
143        NFC_HAL_INIT_STATE_W4_NFCC_TURN_OFF) &&
144       (nfc_hal_cb.hal_flags & NFC_HAL_FLAGS_NEED_DISABLE_VSC)) {
145     nfc_hal_cb.dev_cb.initializing_state = NFC_HAL_INIT_STATE_W4_NFCC_TURN_OFF;
146     nfc_hal_dm_set_power_level_zero();
147   } else {
148     nfc_hal_main_handle_terminate();
149 
150     /* Close uart */
151     USERIAL_Close(USERIAL_NFC_PORT);
152 
153     if (nfc_hal_cb.p_stack_cback) {
154       p_stack_cback_temp = nfc_hal_cb.p_stack_cback;
155       nfc_hal_cb.p_stack_cback = NULL;
156       p_stack_cback_temp(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
157     }
158   }
159 }
160 
161 /*******************************************************************************
162 **
163 ** Function         nfa_hal_pre_discover_done_cback
164 **
165 ** Description      Pre-discovery CFG is sent.
166 **
167 ** Returns          nothing
168 **
169 *******************************************************************************/
nfa_hal_pre_discover_done_cback(tNFC_HAL_NCI_EVT event,uint16_t data_len,uint8_t * p_data)170 void nfa_hal_pre_discover_done_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len,
171                                      uint8_t* p_data) {
172   NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
173   nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
174   nfc_hal_cb.p_stack_cback(HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
175 }
176 
177 /*******************************************************************************
178 **
179 ** Function         nfa_hal_send_pre_discover_cfg
180 **
181 ** Description      sending Pre-discovery CFG
182 **
183 ** Returns          nothing
184 **
185 *******************************************************************************/
nfa_hal_send_pre_discover_cfg(void)186 void nfa_hal_send_pre_discover_cfg(void) {
187   if (nfc_hal_dm_set_config(
188           p_nfc_hal_pre_discover_cfg[0], &p_nfc_hal_pre_discover_cfg[1],
189           nfa_hal_pre_discover_done_cback) != HAL_NFC_STATUS_OK) {
190     nfa_hal_pre_discover_done_cback(0, 0, NULL);
191   }
192 }
193 
194 /*******************************************************************************
195 **
196 ** Function         nfc_hal_main_send_error
197 **
198 ** Description      send an Error event to NFC stack
199 **
200 ** Returns          nothing
201 **
202 *******************************************************************************/
nfc_hal_main_send_error(tHAL_NFC_STATUS status)203 void nfc_hal_main_send_error(tHAL_NFC_STATUS status) {
204   /* Notify stack */
205   nfc_hal_cb.p_stack_cback(HAL_NFC_ERROR_EVT, status);
206 }
207 
208 /*******************************************************************************
209 **
210 ** Function         nfc_hal_main_userial_cback
211 **
212 ** Description      USERIAL callback for NCI transport
213 **
214 ** Returns          nothing
215 **
216 *******************************************************************************/
nfc_hal_main_userial_cback(tUSERIAL_PORT port,tUSERIAL_EVT evt,tUSERIAL_EVT_DATA * p_data)217 static void nfc_hal_main_userial_cback(tUSERIAL_PORT port, tUSERIAL_EVT evt,
218                                        tUSERIAL_EVT_DATA* p_data) {
219   if (evt == USERIAL_RX_READY_EVT) {
220     /* Notify transport task of serial port event */
221     GKI_send_event(NFC_HAL_TASK, NFC_HAL_TASK_EVT_DATA_RDY);
222   } else if (evt == USERIAL_TX_DONE_EVT) {
223     /* Serial driver has finshed sending data from USERIAL_Write */
224     /* Currently, no action is needed for this event */
225   } else if (evt == USERIAL_ERR_EVT) {
226     HAL_TRACE_ERROR0(
227         "nfc_hal_main_userial_cback: USERIAL_ERR_EVT. Notifying NFC_TASK of "
228         "transport error");
229     if (nfc_hal_cb.ncit_cb.nci_wait_rsp != NFC_HAL_WAIT_RSP_NONE) {
230       nfc_hal_main_stop_quick_timer(&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
231       nfc_hal_nci_cmd_timeout_cback(
232           (void*)&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer);
233     } else {
234       nfc_hal_main_send_error(HAL_NFC_STATUS_ERR_TRANSPORT);
235     }
236   } else if (evt == USERIAL_WAKEUP_EVT) {
237     HAL_TRACE_DEBUG1("nfc_hal_main_userial_cback: USERIAL_WAKEUP_EVT: %d",
238                      p_data->sigs);
239   } else {
240     HAL_TRACE_DEBUG1("nfc_hal_main_userial_cback: unhandled userial evt: %i",
241                      evt);
242   }
243 }
244 
245 /*******************************************************************************
246 **
247 ** Function         nfc_hal_main_exit_op_done
248 **
249 ** Description      handle completion of HAL exit operation
250 **
251 ** Returns          nothing
252 **
253 *******************************************************************************/
nfc_hal_main_exit_op_done(tNFC_HAL_NCI_EVT event,uint16_t data_len,uint8_t * p_data)254 void nfc_hal_main_exit_op_done(tNFC_HAL_NCI_EVT event, uint16_t data_len,
255                                uint8_t* p_data) {
256   nfc_hal_main_close();
257 }
258 
259 /*******************************************************************************
260 **
261 ** Function         nfc_hal_main_pre_init_done
262 **
263 ** Description      notify complete of pre-initialization
264 **
265 ** Returns          nothing
266 **
267 *******************************************************************************/
nfc_hal_main_pre_init_done(tHAL_NFC_STATUS status)268 void nfc_hal_main_pre_init_done(tHAL_NFC_STATUS status) {
269   HAL_TRACE_DEBUG1("nfc_hal_main_pre_init_done () status = %d", status);
270 
271   if (status != HAL_NFC_STATUS_OK) {
272     nfc_hal_main_handle_terminate();
273 
274     /* Close uart */
275     USERIAL_Close(USERIAL_NFC_PORT);
276   }
277 
278   /* Notify NFC Task the status of initialization */
279   nfc_hal_cb.p_stack_cback(HAL_NFC_OPEN_CPLT_EVT, status);
280 }
281 
282 /*******************************************************************************
283 **
284 ** Function         nfc_hal_main_timeout_cback
285 **
286 ** Description      callback function for timeout
287 **
288 ** Returns          void
289 **
290 *******************************************************************************/
nfc_hal_main_timeout_cback(void * p_tle)291 static void nfc_hal_main_timeout_cback(void* p_tle) {
292   TIMER_LIST_ENT* p_tlent = (TIMER_LIST_ENT*)p_tle;
293 
294   HAL_TRACE_DEBUG0("nfc_hal_main_timeout_cback ()");
295 
296   switch (p_tlent->event) {
297     case NFC_HAL_TTYPE_POWER_CYCLE:
298       nfc_hal_main_open_transport();
299       break;
300 
301     case NFC_HAL_TTYPE_NFCC_ENABLE:
302       /* NFCC should have enabled now, notify transport openned */
303       nfc_hal_dm_pre_init_nfcc();
304       break;
305 
306     default:
307       HAL_TRACE_DEBUG1(
308           "nfc_hal_main_timeout_cback: unhandled timer event (0x%04x)",
309           p_tlent->event);
310       break;
311   }
312 }
313 
314 /*******************************************************************************
315 **
316 ** Function         nfc_hal_main_handle_terminate
317 **
318 ** Description      Handle NFI transport shutdown
319 **
320 ** Returns          nothing
321 **
322 *******************************************************************************/
nfc_hal_main_handle_terminate(void)323 static void nfc_hal_main_handle_terminate(void) {
324   NFC_HDR* p_msg;
325 
326   /* dequeue and free buffer */
327   if (nfc_hal_cb.ncit_cb.p_pend_cmd != NULL) {
328     GKI_freebuf(nfc_hal_cb.ncit_cb.p_pend_cmd);
329     nfc_hal_cb.ncit_cb.p_pend_cmd = NULL;
330   }
331 
332   /* Free unsent nfc rx buffer */
333   if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
334     GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
335     nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
336   }
337 
338   /* Free buffer for pending fragmented response/notification */
339   if (nfc_hal_cb.ncit_cb.p_frag_msg) {
340     GKI_freebuf(nfc_hal_cb.ncit_cb.p_frag_msg);
341     nfc_hal_cb.ncit_cb.p_frag_msg = NULL;
342   }
343 
344   /* Free buffers in the tx mbox */
345   while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_HAL_TASK_MBOX)) != NULL) {
346     GKI_freebuf(p_msg);
347   }
348 
349   /* notify closing transport */
350   nfc_hal_dm_shutting_down_nfcc();
351 }
352 
353 /*******************************************************************************
354 **
355 ** Function         nfc_hal_main_start_quick_timer
356 **
357 ** Description      Start a timer for the specified amount of time.
358 **                  NOTE: The timeout resolution depends on including modules.
359 **                  QUICK_TIMER_TICKS_PER_SEC should be used to convert from
360 **                  time to ticks.
361 **
362 **
363 ** Returns          void
364 **
365 *******************************************************************************/
nfc_hal_main_start_quick_timer(TIMER_LIST_ENT * p_tle,uint16_t type,uint32_t timeout)366 void nfc_hal_main_start_quick_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
367                                     uint32_t timeout) {
368   NFC_HDR* p_msg;
369 
370   /* if timer list is currently empty, start periodic GKI timer */
371   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
372     /* if timer starts on other than NCIT task (script wrapper) */
373     if (GKI_get_taskid() != NFC_HAL_TASK) {
374       /* post event to start timer in NCIT task */
375       p_msg = (NFC_HDR*)GKI_getbuf(NFC_HDR_SIZE);
376       if (p_msg != NULL) {
377         p_msg->event = NFC_HAL_EVT_TO_START_QUICK_TIMER;
378         GKI_send_msg(NFC_HAL_TASK, NFC_HAL_TASK_MBOX, p_msg);
379       }
380     } else {
381       GKI_start_timer(NFC_HAL_QUICK_TIMER_ID,
382                       ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)),
383                       true);
384     }
385   }
386 
387   GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
388 
389   p_tle->event = type;
390   p_tle->ticks = timeout; /* Save the number of ticks for the timer */
391 
392   GKI_add_to_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
393 }
394 
395 /*******************************************************************************
396 **
397 ** Function         nfc_hal_main_stop_quick_timer
398 **
399 ** Description      Stop a timer.
400 **
401 ** Returns          void
402 **
403 *******************************************************************************/
nfc_hal_main_stop_quick_timer(TIMER_LIST_ENT * p_tle)404 void nfc_hal_main_stop_quick_timer(TIMER_LIST_ENT* p_tle) {
405   GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
406 
407   /* if timer list is empty stop periodic GKI timer */
408   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
409     GKI_stop_timer(NFC_HAL_QUICK_TIMER_ID);
410   }
411 }
412 
413 /*******************************************************************************
414 **
415 ** Function         nfc_hal_main_process_quick_timer_evt
416 **
417 ** Description      Process quick timer event
418 **
419 ** Returns          void
420 **
421 *******************************************************************************/
nfc_hal_main_process_quick_timer_evt(void)422 static void nfc_hal_main_process_quick_timer_evt(void) {
423   TIMER_LIST_ENT* p_tle;
424 
425   GKI_update_timer_list(&nfc_hal_cb.quick_timer_queue, 1);
426 
427   while ((nfc_hal_cb.quick_timer_queue.p_first) &&
428          (!nfc_hal_cb.quick_timer_queue.p_first->ticks)) {
429     p_tle = nfc_hal_cb.quick_timer_queue.p_first;
430     GKI_remove_from_timer_list(&nfc_hal_cb.quick_timer_queue, p_tle);
431 
432     if (p_tle->p_cback) {
433       (*p_tle->p_cback)(p_tle);
434     }
435   }
436 
437   /* if timer list is empty stop periodic GKI timer */
438   if (nfc_hal_cb.quick_timer_queue.p_first == NULL) {
439     GKI_stop_timer(NFC_HAL_QUICK_TIMER_ID);
440   }
441 }
442 
443 /*******************************************************************************
444 **
445 ** Function         nfc_hal_send_nci_msg_to_nfc_task
446 **
447 ** Description      This function is called to send nci message to nfc task
448 **
449 ** Returns          void
450 **
451 *******************************************************************************/
nfc_hal_send_nci_msg_to_nfc_task(NFC_HDR * p_msg)452 void nfc_hal_send_nci_msg_to_nfc_task(NFC_HDR* p_msg) {
453 #ifdef NFC_HAL_SHARED_GKI
454   /* Using shared NFC/HAL GKI resources - send message buffer directly to
455    * NFC_TASK for processing */
456   p_msg->event = BT_EVT_TO_NFC_NCI;
457   GKI_send_msg(NFC_TASK, NFC_MBOX_ID, p_msg);
458 #else
459   /* Send NCI message to the stack */
460   nfc_hal_cb.p_data_cback(p_msg->len, (uint8_t*)((p_msg + 1) + p_msg->offset));
461   GKI_freebuf(p_msg);
462 #endif
463 }
464 
465 /*******************************************************************************
466 **
467 ** Function         nfc_hal_send_credit_ntf_for_cid
468 **
469 ** Description      This function is called to send credit ntf
470 **                  for the specified connection id to nfc task
471 **
472 ** Returns          void
473 **
474 *******************************************************************************/
nfc_hal_send_credit_ntf_for_cid(uint8_t cid)475 static void nfc_hal_send_credit_ntf_for_cid(uint8_t cid) {
476   NFC_HDR* p_msg;
477   uint8_t *p, *ps;
478 
479   /* Start of new message. Allocate a buffer for message */
480   p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID);
481   if (p_msg != NULL) {
482     /* Initialize NFC_HDR */
483     p_msg->len = NCI_DATA_HDR_SIZE + 0x03;
484     p_msg->event = 0;
485     p_msg->offset = 0;
486     p_msg->layer_specific = 0;
487 
488     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
489     ps = p;
490     NCI_MSG_BLD_HDR0(p, NCI_MT_NTF, NCI_GID_CORE);
491     NCI_MSG_BLD_HDR1(p, NCI_MSG_CORE_CONN_CREDITS);
492     UINT8_TO_STREAM(p, 0x03);
493 
494     /* Number of credit entries */
495     *p++ = 0x01;
496     /* Connection id of the credit ntf */
497     *p++ = cid;
498     /* Number of credits */
499     *p = 0x01;
500 #ifdef DISP_NCI
501     DISP_NCI(ps, (uint16_t)p_msg->len, true);
502 #endif
503     nfc_hal_send_nci_msg_to_nfc_task(p_msg);
504   } else {
505     HAL_TRACE_ERROR0(
506         "Unable to allocate buffer for Sending credit ntf to stack");
507   }
508 }
509 
510 /*******************************************************************************
511 **
512 ** Function         nfc_hal_main_send_message
513 **
514 ** Description      This function is calledto send an NCI message.
515 **
516 ** Returns          void
517 **
518 *******************************************************************************/
nfc_hal_main_send_message(NFC_HDR * p_msg)519 static void nfc_hal_main_send_message(NFC_HDR* p_msg) {
520 #if (NFC_HAL_HCI_INCLUDED == TRUE)
521   uint8_t cid, pbf;
522   uint16_t data_len;
523 #endif
524   uint8_t *ps, *pp;
525   uint16_t len = p_msg->len;
526 #ifdef DISP_NCI
527   uint8_t delta;
528 #endif
529 
530   HAL_TRACE_DEBUG1("nfc_hal_main_send_message() ls:0x%x",
531                    p_msg->layer_specific);
532   if ((p_msg->layer_specific == NFC_HAL_WAIT_RSP_CMD) ||
533       (p_msg->layer_specific == NFC_HAL_WAIT_RSP_VSC)) {
534     nfc_hal_nci_send_cmd(p_msg);
535   } else {
536     /* NFC task has fragmented the data packet to the appropriate size
537      * and data credit is available; just send it */
538 
539     /* add NCI packet type in front of message */
540     nfc_hal_nci_add_nfc_pkt_type(p_msg);
541 
542     /* send this packet to transport */
543     ps = (uint8_t*)(p_msg + 1) + p_msg->offset;
544     pp = ps + 1;
545 #ifdef DISP_NCI
546     delta = p_msg->len - len;
547     DISP_NCI(ps + delta, (uint16_t)(p_msg->len - delta), false);
548 #endif
549 
550 #if (NFC_HAL_HCI_INCLUDED == TRUE)
551     if (nfc_hal_cb.hci_cb.hcp_conn_id) {
552       NCI_DATA_PRS_HDR(pp, pbf, cid, data_len);
553       if (cid == nfc_hal_cb.hci_cb.hcp_conn_id) {
554         if (nfc_hal_hci_handle_hcp_pkt_to_hc(pp)) {
555           HAL_TRACE_DEBUG0(
556               "nfc_hal_main_send_message() - Drop rsp to Fake cmd, Fake credit "
557               "ntf");
558           GKI_freebuf(p_msg);
559           nfc_hal_send_credit_ntf_for_cid(cid);
560           return;
561         }
562       }
563     }
564 #endif
565 
566     /* check low power mode state */
567     if (nfc_hal_dm_power_mode_execute(NFC_HAL_LP_TX_DATA_EVT)) {
568       USERIAL_Write(USERIAL_NFC_PORT, ps, p_msg->len);
569     } else {
570       HAL_TRACE_ERROR0(
571           "nfc_hal_main_send_message(): drop data in low power mode");
572     }
573     GKI_freebuf(p_msg);
574   }
575 }
576 
577 /*******************************************************************************
578 **
579 ** Function         nfc_hal_main_task
580 **
581 ** Description      NFC HAL NCI transport event processing task
582 **
583 ** Returns          0
584 **
585 *******************************************************************************/
nfc_hal_main_task(uint32_t param)586 uint32_t nfc_hal_main_task(uint32_t param) {
587   uint16_t event;
588   uint8_t byte;
589   uint8_t num_interfaces;
590   uint8_t* p;
591   NFC_HDR* p_msg;
592   bool free_msg;
593 
594   HAL_TRACE_DEBUG0("NFC_HAL_TASK started");
595 
596   /* Main loop */
597   while (true) {
598     event = GKI_wait(0xFFFF, 0);
599 
600     /* Handle NFC_HAL_TASK_EVT_INITIALIZE (for initializing NCI transport) */
601     if (event & NFC_HAL_TASK_EVT_INITIALIZE) {
602       HAL_TRACE_DEBUG0(
603           "NFC_HAL_TASK got NFC_HAL_TASK_EVT_INITIALIZE signal. Opening NFC "
604           "transport...");
605 
606       nfc_hal_main_open_transport();
607     }
608 
609     /* Check for terminate event */
610     if (event & NFC_HAL_TASK_EVT_TERMINATE) {
611       HAL_TRACE_DEBUG0("NFC_HAL_TASK got NFC_HAL_TASK_EVT_TERMINATE");
612 
613       nfc_hal_main_close();
614 
615       continue;
616     }
617 
618     /* Check for power cycle event */
619     if (event & NFC_HAL_TASK_EVT_POWER_CYCLE) {
620       HAL_TRACE_DEBUG0("NFC_HAL_TASK got NFC_HAL_TASK_EVT_POWER_CYCLE");
621       nfc_hal_main_handle_terminate();
622 
623       /* Close uart */
624       USERIAL_Close(USERIAL_NFC_PORT);
625 
626       /* power cycle timeout */
627       nfc_hal_main_start_quick_timer(
628           &nfc_hal_cb.timer, NFC_HAL_TTYPE_POWER_CYCLE,
629           (NFC_HAL_POWER_CYCLE_DELAY * QUICK_TIMER_TICKS_PER_SEC) / 1000);
630       continue;
631     }
632 
633     /* NCI message ready to be sent to NFCC */
634     if (event & NFC_HAL_TASK_EVT_MBOX) {
635       while ((p_msg = (NFC_HDR*)GKI_read_mbox(NFC_HAL_TASK_MBOX)) != NULL) {
636         free_msg = true;
637         switch (p_msg->event & NFC_EVT_MASK) {
638           case NFC_HAL_EVT_TO_NFC_NCI:
639             nfc_hal_main_send_message(p_msg);
640             /* do not free buffer. NCI VS code may keep it for processing later
641              */
642             free_msg = false;
643             break;
644 
645           case NFC_HAL_EVT_POST_CORE_RESET:
646             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_POST_INIT_DONE);
647 
648             /* set NCI Control packet size from CORE_INIT_RSP */
649             p = (uint8_t*)(p_msg + 1) + p_msg->offset + NCI_MSG_HDR_SIZE;
650             p += 5;
651             STREAM_TO_UINT8(num_interfaces, p);
652             p += (num_interfaces + 3);
653             nfc_hal_cb.ncit_cb.nci_ctrl_size = *p;
654 
655             /* start post initialization */
656             nfc_hal_cb.dev_cb.next_dm_config = NFC_HAL_DM_CONFIG_LPTD;
657             nfc_hal_cb.dev_cb.next_startup_vsc = 1;
658 
659             nfc_hal_dm_config_nfcc();
660             break;
661 
662           case NFC_HAL_EVT_TO_START_QUICK_TIMER:
663             GKI_start_timer(
664                 NFC_HAL_QUICK_TIMER_ID,
665                 ((GKI_SECS_TO_TICKS(1) / QUICK_TIMER_TICKS_PER_SEC)), true);
666             break;
667 
668           case NFC_HAL_EVT_HCI:
669             nfc_hal_hci_evt_hdlr((tNFC_HAL_HCI_EVENT_DATA*)p_msg);
670             break;
671 
672           case NFC_HAL_EVT_PRE_DISCOVER:
673             NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_W4_PREDISCOVER_DONE);
674             nfa_hal_send_pre_discover_cfg();
675             break;
676 
677           case NFC_HAL_EVT_CONTROL_GRANTED:
678             nfc_hal_dm_send_pend_cmd();
679             break;
680 
681           default:
682             break;
683         }
684 
685         if (free_msg) GKI_freebuf(p_msg);
686       }
687     }
688 
689     /* Data waiting to be read from serial port */
690     if (event & NFC_HAL_TASK_EVT_DATA_RDY) {
691       while (true) {
692         /* Read one byte to see if there is anything waiting to be read */
693         if (USERIAL_Read(USERIAL_NFC_PORT, &byte, 1) == 0) {
694           break;
695         }
696 
697         if (nfc_hal_nci_receive_msg(byte)) {
698           /* complete of receiving NCI message */
699           nfc_hal_nci_assemble_nci_msg();
700           if (nfc_hal_cb.ncit_cb.p_rcv_msg) {
701             if (nfc_hal_nci_preproc_rx_nci_msg(nfc_hal_cb.ncit_cb.p_rcv_msg)) {
702               /* Send NCI message to the stack */
703               nfc_hal_send_nci_msg_to_nfc_task(nfc_hal_cb.ncit_cb.p_rcv_msg);
704             } else {
705               if (nfc_hal_cb.ncit_cb.p_rcv_msg)
706                 GKI_freebuf(nfc_hal_cb.ncit_cb.p_rcv_msg);
707             }
708             nfc_hal_cb.ncit_cb.p_rcv_msg = NULL;
709           }
710         }
711       } /* while (TRUE) */
712     }
713 
714     /* Process quick timer tick */
715     if (event & NFC_HAL_QUICK_TIMER_EVT_MASK) {
716       nfc_hal_main_process_quick_timer_evt();
717     }
718   }
719 
720   HAL_TRACE_DEBUG0("nfc_hal_main_task terminated");
721 
722   GKI_exit_task(GKI_get_taskid());
723   return 0;
724 }
725 
726 /*******************************************************************************
727 **
728 ** Function         HAL_NfcSetTraceLevel
729 **
730 ** Description      This function sets the trace level for HAL.  If called with
731 **                  a value of 0xFF, it simply returns the current trace level.
732 **
733 ** Returns          The new or current trace level
734 **
735 *******************************************************************************/
HAL_NfcSetTraceLevel(uint8_t new_level)736 uint8_t HAL_NfcSetTraceLevel(uint8_t new_level) {
737   if (new_level != 0xFF) nfc_hal_cb.trace_level = new_level;
738 
739   return (nfc_hal_cb.trace_level);
740 }
741