1 /******************************************************************************
2  *
3  *  Copyright (C) 2012-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  *  Vendor-specific handler for HCI events
22  *
23  ******************************************************************************/
24 #include "gki.h"
25 #include "nfc_hal_api.h"
26 #include "nfc_hal_int.h"
27 #include "nfc_hal_target.h"
28 
29 #if (NFC_HAL_HCI_INCLUDED == TRUE)
30 
31 #include "nfc_hal_nv_ci.h"
32 #include "nfc_hal_nv_co.h"
33 
34 #include <string.h>
35 
36 #ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
37 #define NFC_HAL_HCI_NV_READ_TIMEOUT 1000
38 #endif
39 
40 #ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
41 #define NFC_HAL_HCI_NFCC_RSP_TIMEOUT 3000
42 #endif
43 
44 #define NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET 0x0C
45 #define NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET 0x32
46 #define NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET 0x7F
47 #define NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET 0xB4
48 
49 #define NFC_HAL_HCI_PIPE_VALID_MASK 0x80
50 
51 #define NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL 0xFF
52 #define NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL 0xFE
53 
54 /* Version string for BCM20791B3 */
55 const uint8_t NFC_HAL_DM_BCM20791B3_STR[] = "20791B3";
56 #define NFC_HAL_DM_BCM20791B3_STR_LEN (sizeof(NFC_HAL_DM_BCM20791B3_STR) - 1)
57 
58 /* Version string for BCM20791B4 */
59 const uint8_t NFC_HAL_DM_BCM20791B4_STR[] = "20791B4";
60 #define NFC_HAL_DM_BCM20791B4_STR_LEN (sizeof(NFC_HAL_DM_BCM20791B4_STR) - 1)
61 
62 /* Version string for BCM43341B0 */
63 const uint8_t NFC_HAL_DM_BCM43341B0_STR[] = "43341B0";
64 #define NFC_HAL_DM_BCM43341B0_STR_LEN (sizeof(NFC_HAL_DM_BCM43341B0_STR) - 1)
65 
66 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
67 /****************************************************************************
68 ** Internal function prototypes
69 ****************************************************************************/
70 static void nfc_hal_hci_set_next_hci_netwk_config(uint8_t block);
71 static void nfc_hal_hci_remove_dyn_pipe_to_uicc1(void);
72 static void nfc_hal_hci_handle_nv_read(uint8_t block, tHAL_NFC_STATUS status,
73                                        uint16_t size);
74 static void nfc_hal_hci_init_complete(tHAL_NFC_STATUS status);
75 static void nfc_hal_hci_vsc_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len,
76                                   uint8_t* p_data);
77 
78 /*******************************************************************************
79 **
80 ** Function         nfc_hal_hci_evt_hdlr
81 **
82 ** Description      Processing event for NFA HCI
83 **
84 ** Returns          None
85 **
86 *******************************************************************************/
nfc_hal_hci_evt_hdlr(tNFC_HAL_HCI_EVENT_DATA * p_evt_data)87 void nfc_hal_hci_evt_hdlr(tNFC_HAL_HCI_EVENT_DATA* p_evt_data) {
88   HAL_TRACE_DEBUG0("nfc_hal_hci_evt_hdlr ()");
89 
90   switch (p_evt_data->hdr.event) {
91     case NFC_HAL_HCI_RSP_NV_READ_EVT:
92       if ((nfc_hal_cb.hci_cb.p_hci_netwk_info_buf &&
93            (p_evt_data->nv_read.block == HC_F3_NV_BLOCK ||
94             p_evt_data->nv_read.block == HC_F4_NV_BLOCK ||
95             p_evt_data->nv_read.block == HC_F5_NV_BLOCK)) ||
96           (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf &&
97            p_evt_data->nv_read.block == HC_F2_NV_BLOCK)) {
98         nfc_hal_hci_handle_nv_read(p_evt_data->nv_read.block,
99                                    p_evt_data->nv_read.status,
100                                    p_evt_data->nv_read.size);
101       } else {
102         /* Invalid block or no buffer, Ignore */
103         HAL_TRACE_ERROR1(
104             "nfc_hal_hci_evt_hdlr: No buffer for handling read NV block: "
105             "0x%02x",
106             p_evt_data->nv_read.block);
107       }
108       break;
109 
110     case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
111       /* NV Ram write completed - nothing to do... */
112       break;
113 
114     default:
115       break;
116   }
117 }
118 
119 /*******************************************************************************
120 **
121 ** Function         nfc_hal_hci_enable
122 **
123 ** Description      Program nv data on to controller
124 **
125 ** Returns          void
126 **
127 *******************************************************************************/
nfc_hal_hci_enable(void)128 void nfc_hal_hci_enable(void) {
129   uint8_t* p_hci_netwk_cmd;
130 
131   HAL_TRACE_DEBUG0("nfc_hal_hci_enable ()");
132 
133   if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE) {
134     HAL_TRACE_DEBUG1(
135         "nfc_hal_hci_enable (): No HCI NETWK CMD to send for NVM Type: 0x%02x",
136         nfc_hal_cb.nvm_cb.nvm_type);
137     nfc_hal_hci_init_complete(HAL_NFC_STATUS_OK);
138     return;
139   }
140 
141   if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf) {
142     p_hci_netwk_cmd = (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf -
143                                  NCI_MSG_HDR_SIZE);
144     GKI_freebuf(p_hci_netwk_cmd);
145     nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
146   }
147 
148   if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf) {
149     p_hci_netwk_cmd =
150         (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
151     GKI_freebuf(p_hci_netwk_cmd);
152     nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
153   }
154 
155   if ((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST) ||
156       ((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) &&
157        ((!nfc_hal_cb.hci_cb.hci_fw_workaround) ||
158         (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM))) ||
159       (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST)) {
160     p_hci_netwk_cmd =
161         (uint8_t*)GKI_getbuf(NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE);
162     if (p_hci_netwk_cmd == NULL) {
163       HAL_TRACE_ERROR0(
164           "nfc_hal_hci_enable: unable to allocate buffer for reading hci "
165           "network info from nvram");
166       nfc_hal_hci_init_complete(HAL_NFC_STATUS_FAILED);
167     } else {
168       nfc_hal_cb.hci_cb.p_hci_netwk_info_buf =
169           (uint8_t*)(p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
170       nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
171       if (p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC0_HOST) {
172         memset(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0,
173                NFC_HAL_HCI_NETWK_INFO_SIZE);
174         nfc_hal_nv_co_read((uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_info_buf,
175                            NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
176         nfc_hal_main_start_quick_timer(&nfc_hal_cb.hci_cb.hci_timer,
177                                        NFC_HAL_HCI_VSC_TIMEOUT_EVT,
178                                        NFC_HAL_HCI_NV_READ_TIMEOUT);
179       } else {
180         HAL_TRACE_DEBUG1(
181             "nfc_hal_hci_enable (): Skip send F3 HCI NETWK CMD for UICC Mask: "
182             "0x%02x",
183             p_nfc_hal_cfg->nfc_hal_hci_uicc_support);
184         nfc_hal_hci_set_next_hci_netwk_config(HC_F3_NV_BLOCK);
185       }
186     }
187   } else {
188     HAL_TRACE_DEBUG2(
189         "nfc_hal_hci_enable (): No HCI NETWK CMD to send for UICC Mask: 0x%02x "
190         "& NVM Type: 0x%02x",
191         p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
192     nfc_hal_hci_set_next_hci_netwk_config(HC_F2_NV_BLOCK);
193   }
194 }
195 
196 /*******************************************************************************
197 **
198 ** Function         nfc_hal_hci_handle_build_info
199 **
200 ** Description      handle build info evt
201 **
202 ** Returns          void
203 **
204 *******************************************************************************/
nfc_hal_hci_handle_build_info(uint8_t chipverlen,uint8_t * p_chipverstr)205 void nfc_hal_hci_handle_build_info(uint8_t chipverlen, uint8_t* p_chipverstr) {
206   HAL_TRACE_DEBUG0("nfc_hal_hci_handle_build_info ()");
207 
208   if ((chipverlen == NFC_HAL_DM_BCM20791B3_STR_LEN) &&
209       (memcmp(NFC_HAL_DM_BCM20791B3_STR, p_chipverstr,
210               NFC_HAL_DM_BCM20791B3_STR_LEN) == 0)) {
211     /* BCM2079B3 FW - eSE restarted for patch download */
212     nfc_hal_cb.hci_cb.hci_fw_workaround = true;
213     nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = true;
214   } else if (((chipverlen == NFC_HAL_DM_BCM20791B4_STR_LEN) &&
215               (memcmp(NFC_HAL_DM_BCM20791B4_STR, p_chipverstr,
216                       NFC_HAL_DM_BCM20791B4_STR_LEN) == 0)) ||
217              ((chipverlen == NFC_HAL_DM_BCM43341B0_STR_LEN) &&
218               (memcmp(NFC_HAL_DM_BCM43341B0_STR, p_chipverstr,
219                       NFC_HAL_DM_BCM43341B0_STR_LEN) == 0))) {
220     /* BCM43341B0/BCM2079B4 FW - eSE restarted for patch download */
221     nfc_hal_cb.hci_cb.hci_fw_workaround = true;
222     nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = false;
223   } else {
224     /* BCM2079B5 FW - eSE not be restarted for patch download from UICC */
225     nfc_hal_cb.hci_cb.hci_fw_workaround = false;
226     nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd = false;
227   }
228 }
229 
230 /*******************************************************************************
231 **
232 ** Function         nfc_hal_hci_handle_hci_netwk_info
233 **
234 ** Description      Handler function for HCI Network Notification
235 **
236 ** Returns          None
237 **
238 *******************************************************************************/
nfc_hal_hci_handle_hci_netwk_info(uint8_t * p_data)239 void nfc_hal_hci_handle_hci_netwk_info(uint8_t* p_data) {
240   uint8_t* p = p_data;
241   uint16_t data_len;
242   uint8_t target_handle = 0;
243   uint8_t hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
244   uint8_t block = 0;
245 
246   HAL_TRACE_DEBUG0("nfc_hal_hci_handle_hci_netwk_info ()");
247 
248   /* skip NCI header byte0 (MT,GID), byte1 (OID) */
249   p += 2;
250 
251   STREAM_TO_UINT8(data_len, p);
252   target_handle = *(uint8_t*)p;
253 
254   if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE) {
255     /* Correct the session id assigned by DH */
256     *(p + 1) = nfc_hal_cb.hci_cb.dh_session_id[0];
257     nfc_hal_nv_co_write(p, data_len, HC_F2_NV_BLOCK);
258     return;
259   }
260 
261   if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE) {
262     block = HC_F3_NV_BLOCK;
263   } else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE) {
264     block = HC_F4_NV_BLOCK;
265   } else if (target_handle == NFC_HAL_HCI_UICC2_TARGET_HANDLE) {
266     block = HC_F5_NV_BLOCK;
267   } else {
268     HAL_TRACE_DEBUG1(
269         "nfc_hal_hci_handle_hci_netwk_info(): Invalid Target handle: 0x%02x",
270         target_handle);
271     return;
272   }
273 
274   if ((!nfc_hal_cb.hci_cb.hci_fw_validate_netwk_cmd) ||
275       (p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET] &
276        NFC_HAL_HCI_PIPE_VALID_MASK) ||
277       (p[NFC_HAL_HCI_NETWK_CMD_TYPE_B_CE_PIPE_INFO_OFFSET] &
278        NFC_HAL_HCI_PIPE_VALID_MASK) ||
279       (p[NFC_HAL_HCI_NETWK_CMD_TYPE_BP_CE_PIPE_INFO_OFFSET] &
280        NFC_HAL_HCI_PIPE_VALID_MASK) ||
281       (p[NFC_HAL_HCI_NETWK_CMD_TYPE_F_CE_PIPE_INFO_OFFSET] &
282        NFC_HAL_HCI_PIPE_VALID_MASK)) {
283     /* HCI Network notification received for UICC0/UICC1/UICC2, Update nv data
284      */
285     nfc_hal_nv_co_write(p, data_len, block);
286   } else {
287     HAL_TRACE_DEBUG1(
288         "nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, "
289         "Reset nv file: 0x%02x",
290         p[NFC_HAL_HCI_NETWK_CMD_TYPE_A_CE_PIPE_INFO_OFFSET]);
291     hci_netwk_cmd[0] = target_handle;
292     memset(&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
293     nfc_hal_nv_co_write(hci_netwk_cmd, 1, block);
294   }
295 }
296 
297 /*******************************************************************************
298 **
299 ** Function         nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh
300 **
301 ** Description      Fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
302 **
303 ** Returns          None
304 **
305 *******************************************************************************/
nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh(void)306 void nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh(void) {
307   NFC_HDR* p_msg;
308   uint8_t *p, *ps;
309 
310   HAL_TRACE_DEBUG1(
311       "nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh (): Fake "
312       "ADM_NOTIFY_ALL_PIPE_CLEARED (0x%02x) from HAL",
313       NFC_HAL_HCI_HOST_ID_UICC1);
314 
315   /* Start of new message. Allocate a buffer for message */
316   p_msg = (NFC_HDR*)GKI_getpoolbuf(NFC_HAL_NCI_POOL_ID);
317   if (p_msg != NULL) {
318     /* Initialize NFC_HDR */
319     p_msg->len = NCI_DATA_HDR_SIZE + 0x03;
320     p_msg->event = 0;
321     p_msg->offset = 0;
322     p_msg->layer_specific = 0;
323 
324     p = (uint8_t*)(p_msg + 1) + p_msg->offset;
325     ps = p;
326     NCI_DATA_BLD_HDR(p, nfc_hal_cb.hci_cb.hcp_conn_id, 0x03);
327     /* HCP header with ADMIN pipe id and chaining bit set */
328     *p++ = ((1 << 0x07) | (NFC_HAL_HCI_ADMIN_PIPE & 0x7F));
329     /* HCP Message header with Command type instruction and
330      * ADM_NOTIFY_ALL_PIPE_CLEARED command */
331     *p++ = ((NFC_HAL_HCI_COMMAND_TYPE << 6) |
332             (NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED & 0x3F));
333     /* HCP Data with UICC1 host id */
334     *p = NFC_HAL_HCI_HOST_ID_UICC1;
335 
336 #ifdef DISP_NCI
337     DISP_NCI(ps, (uint16_t)p_msg->len, true);
338 #endif
339     nfc_hal_send_nci_msg_to_nfc_task(p_msg);
340 
341   } else {
342     HAL_TRACE_ERROR0(
343         "Unable to allocate buffer for faking ADM_NOTIFY_ALL_PIPE_CLEARED cmd "
344         "from HAL to stack");
345   }
346 }
347 
348 /*******************************************************************************
349 **
350 ** Function         nfc_hal_hci_handle_hcp_pkt_to_hc
351 **
352 ** Description      Handle HCP Packet from NFC task to Host Controller
353 **
354 ** Returns          FALSE to send the packet to host controller
355 **                  TRUE to drop the packet and fake credit ntf for hcp
356 *connection
357 **
358 *******************************************************************************/
nfc_hal_hci_handle_hcp_pkt_to_hc(uint8_t * p_data)359 bool nfc_hal_hci_handle_hcp_pkt_to_hc(uint8_t* p_data) {
360   uint8_t chaining_bit;
361   uint8_t pipe;
362   uint8_t type;
363   uint8_t inst;
364   uint8_t index;
365 
366   HAL_TRACE_DEBUG0("nfc_hal_hci_handle_hcp_pkt_to_hc ()");
367 
368   chaining_bit = ((*p_data) >> 0x07) & 0x01;
369   pipe = (*p_data++) & 0x7F;
370 
371   if ((chaining_bit) && (pipe == NFC_HAL_HCI_ADMIN_PIPE)) {
372     type = ((*p_data) >> 0x06) & 0x03;
373 
374     if (type == NFC_HAL_HCI_COMMAND_TYPE) {
375       inst = (*p_data++ & 0x3F);
376       if (inst == NFC_HAL_HCI_ANY_GET_PARAMETER) {
377         index = *(p_data++);
378         if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX) {
379           /* Set flag to modify session id[0] on response
380            * from host controller to set session id cmd
381            */
382           nfc_hal_cb.hci_cb.update_session_id = true;
383         }
384       } else if (inst == NFC_HAL_HCI_ANY_SET_PARAMETER) {
385         index = *(p_data++);
386         if (index == NFC_HAL_HCI_WHITELIST_INDEX) {
387           if ((nfc_hal_cb.hci_cb.hci_fw_workaround) &&
388               (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)) {
389             /* Set flag to fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to nfc task
390              * after
391              * response from host controller to set whitelist cmd
392              */
393             nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = true;
394           }
395         } else if (index == NFC_HAL_HCI_SESSION_IDENTITY_INDEX) {
396           nfc_hal_cb.hci_cb.dh_session_id[0] = *p_data;
397           if (p_nfc_hal_cfg->nfc_hal_first_boot)
398             *p_data = NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
399           else
400             *p_data = NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
401         }
402       }
403     } else if (type == NFC_HAL_HCI_RESPONSE_TYPE) {
404       if ((nfc_hal_cb.hci_cb.hci_fw_workaround) &&
405           (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC) &&
406           (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1)) {
407         /* Got response to the fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd sent by HAL
408          * to nfc task */
409         nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1 = false;
410         /* return TRUE to drop this hcp without forwarding to host controller */
411         return true;
412       }
413     }
414   }
415 
416   return false;
417 }
418 
419 /*******************************************************************************
420 **
421 ** Function         nfc_hal_hci_handle_hcp_pkt_from_hc
422 **
423 ** Description      Handle HCP Packet from Host controller to Terminal Host
424 **
425 ** Returns          None
426 **
427 *******************************************************************************/
nfc_hal_hci_handle_hcp_pkt_from_hc(uint8_t * p_data)428 void nfc_hal_hci_handle_hcp_pkt_from_hc(uint8_t* p_data) {
429   uint8_t chaining_bit;
430   uint8_t pipe;
431   uint8_t type;
432   uint8_t inst;
433   uint8_t hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
434   uint8_t source_host;
435   uint8_t block = 0;
436 
437   HAL_TRACE_DEBUG0("nfc_hal_hci_handle_hcp_pkt_from_hc ()");
438 
439   chaining_bit = ((*p_data) >> 0x07) & 0x01;
440   pipe = (*p_data++) & 0x7F;
441 
442   if ((chaining_bit) && (pipe == NFC_HAL_HCI_ADMIN_PIPE)) {
443     type = ((*p_data) >> 0x06) & 0x03;
444 
445     if (type == NFC_HAL_HCI_COMMAND_TYPE) {
446       if (!nfc_hal_cb.hci_cb.hci_fw_workaround) return;
447 
448       inst = (*p_data++ & 0x3F);
449 
450       if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED) {
451         STREAM_TO_UINT8(source_host, p_data);
452 
453         HAL_TRACE_DEBUG1(
454             "nfc_hal_hci_handle_hcp_pkt_from_hc (): Received "
455             "ADM_NOTIFY_ALL_PIPE_CLEARED command for UICC: 0x%02x",
456             source_host);
457         if (source_host == NFC_HAL_HCI_HOST_ID_UICC0) {
458           block = HC_F3_NV_BLOCK;
459           hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
460         } else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1) {
461           block = HC_F4_NV_BLOCK;
462           hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
463         } else if (source_host == NFC_HAL_HCI_HOST_ID_UICC2) {
464           block = HC_F5_NV_BLOCK;
465           hci_netwk_cmd[0] = NFC_HAL_HCI_UICC2_TARGET_HANDLE;
466         }
467 
468         if (source_host >= NFC_HAL_HCI_HOST_ID_UICC0) {
469           /* Reset Session ID */
470           memset(&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
471           nfc_hal_nv_co_write(hci_netwk_cmd, 1, block);
472           HAL_TRACE_DEBUG1(
473               "nfc_hal_hci_handle_hcp_pkt_from_hc (): Sent command to reset nv "
474               "file for block: 0x%02x",
475               block);
476         }
477       }
478     } else if (type == NFC_HAL_HCI_RESPONSE_TYPE) {
479       if (nfc_hal_cb.hci_cb.update_session_id) {
480         nfc_hal_cb.hci_cb.update_session_id = false;
481         inst = (*p_data++ & 0x3F);
482         if (inst == NFC_HAL_HCI_ANY_OK) {
483           /* Correct the session id assigned by DH */
484           *p_data = nfc_hal_cb.hci_cb.dh_session_id[0];
485         }
486       } else if (nfc_hal_cb.hci_cb.clear_all_pipes_to_uicc1) {
487         /* NVM Type is UICC and got response from host controller
488          * to Set whitelist command. Now fake ADM_NOTIFY_ALL_PIPE_CLEARED cmd to
489          * NFC Task and then forward the whitelist cmd response
490          */
491         nfc_hal_hci_fake_adm_notify_all_pipe_cleared_to_dh();
492       }
493     }
494   }
495 }
496 
497 /*******************************************************************************
498 **
499 ** Function         nfc_hal_hci_handle_nv_read
500 **
501 ** Description      handler function for nv read complete event
502 **
503 ** Returns          None
504 **
505 *******************************************************************************/
nfc_hal_hci_handle_nv_read(uint8_t block,tHAL_NFC_STATUS status,uint16_t size)506 void nfc_hal_hci_handle_nv_read(uint8_t block, tHAL_NFC_STATUS status,
507                                 uint16_t size) {
508   uint8_t* p;
509   uint8_t* p_hci_netwk_info = NULL;
510 
511   HAL_TRACE_DEBUG3(
512       "nfc_hal_hci_handle_nv_read (): Block: [0x%02x], Status: [0x%02x], Size: "
513       "[0x%04x]",
514       block, status, size);
515 
516   /* Stop timer as NVDATA Read Completed */
517   nfc_hal_main_stop_quick_timer(&nfc_hal_cb.hci_cb.hci_timer);
518 
519   switch (block) {
520     case HC_F3_NV_BLOCK:
521     case HC_F4_NV_BLOCK:
522     case HC_F5_NV_BLOCK:
523       if ((status != HAL_NFC_STATUS_OK) ||
524           (size > NFC_HAL_HCI_NETWK_INFO_SIZE) ||
525           (size < NFC_HAL_HCI_MIN_NETWK_INFO_SIZE) ||
526           ((nfc_hal_cb.hci_cb.hci_fw_workaround) && (block == HC_F4_NV_BLOCK) &&
527            (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC))) {
528         HAL_TRACE_DEBUG1(
529             "nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set "
530             "DEFAULT Configuration for block:0x%02x",
531             block);
532         memset(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0,
533                NFC_HAL_HCI_NETWK_INFO_SIZE);
534         if (block == HC_F3_NV_BLOCK)
535           nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] =
536               NFC_HAL_HCI_UICC0_TARGET_HANDLE;
537         else if (block == HC_F4_NV_BLOCK)
538           nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] =
539               NFC_HAL_HCI_UICC1_TARGET_HANDLE;
540         else
541           nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] =
542               NFC_HAL_HCI_UICC2_TARGET_HANDLE;
543 
544         memset(&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF,
545                NFC_HAL_HCI_SESSION_ID_LEN);
546         size = NFC_HAL_HCI_NETWK_INFO_SIZE;
547       }
548 
549       p_hci_netwk_info =
550           (uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
551       break;
552 
553     case HC_F2_NV_BLOCK:
554       nfc_hal_cb.hci_cb.dh_session_id[0] =
555           nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1];
556       if (p_nfc_hal_cfg->nfc_hal_first_boot)
557         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] =
558             NFC_HAL_HCI_FIRST_BOOT_SESSION_ID_0_VAL;
559       else
560         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[1] =
561             NFC_HAL_HCI_NEXT_BOOT_SESSION_ID_0_VAL;
562 
563       if ((status != HAL_NFC_STATUS_OK) ||
564           (size > NFC_HAL_HCI_DH_NETWK_INFO_SIZE) ||
565           (size < NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE)) {
566         HAL_TRACE_DEBUG1(
567             "nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set "
568             "DEFAULT Configuration for block:0x%02x",
569             block);
570         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[0] =
571             NFC_HAL_HCI_DH_TARGET_HANDLE;
572         nfc_hal_cb.hci_cb.dh_session_id[0] = 0xFF;
573         memset(&nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf[2], 0xFF,
574                (NFC_HAL_HCI_SESSION_ID_LEN - 1));
575         memset((nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf +
576                 NFC_HAL_HCI_SESSION_ID_LEN + 1),
577                0, (NFC_HAL_HCI_DH_NETWK_INFO_SIZE - NFC_HAL_HCI_SESSION_ID_LEN -
578                    1));
579         size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
580         p_hci_netwk_info = (uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf -
581                            NCI_MSG_HDR_SIZE;
582       } else {
583         if ((nfc_hal_cb.hci_cb.hci_fw_workaround) &&
584             (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_UICC)) {
585           /* if NVM Type is UICC, then UICC1 will find session id mismatch when
586            * activated for patch download,
587            * and will remove pipes connected to DH even before DH is enabled, So
588            * DH will update NFCC
589            * control block by removing all dynamic pipes connected to UICC1 */
590 
591           nfc_hal_hci_remove_dyn_pipe_to_uicc1();
592           size = NFC_HAL_HCI_DH_NETWK_INFO_SIZE;
593         }
594         p_hci_netwk_info =
595             (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf -
596                        NCI_MSG_HDR_SIZE);
597       }
598       break;
599 
600     default:
601       return;
602   }
603 
604   p = p_hci_netwk_info;
605   /* Send HCI Network ntf command using nv data */
606   NCI_MSG_BLD_HDR0(p, NCI_MT_CMD, NCI_GID_PROP);
607   NCI_MSG_BLD_HDR1(p, NCI_MSG_HCI_NETWK);
608   UINT8_TO_STREAM(p, (uint8_t)size);
609 
610   nfc_hal_dm_send_nci_cmd(p_hci_netwk_info, (uint16_t)(NCI_MSG_HDR_SIZE + size),
611                           nfc_hal_hci_vsc_cback);
612 
613   nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
614 }
615 
616 /*******************************************************************************
617 **
618 ** Function         nfc_hal_hci_remove_dyn_pipe_to_uicc1
619 **
620 ** Description      Prepare hci network command read from nv file removing
621 **                  all pipes connected to UICC1
622 **
623 ** Returns          None
624 **
625 *******************************************************************************/
nfc_hal_hci_remove_dyn_pipe_to_uicc1(void)626 void nfc_hal_hci_remove_dyn_pipe_to_uicc1(void) {
627   uint8_t *p, *np;
628   uint8_t num_dyn_pipes = 0, new_num_dyn_pipes = 0;
629   uint8_t xx;
630   uint8_t source_host, dest_host, pipe_id;
631 
632   HAL_TRACE_DEBUG0("nfc_hal_hci_remove_dyn_pipe_to_uicc1 ()");
633 
634   p = (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf +
635                  NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
636   np = p;
637   num_dyn_pipes = *(p - 1);
638 
639   for (xx = 0; xx < num_dyn_pipes; xx++, p += NFC_HAL_HCI_PIPE_INFO_SIZE) {
640     source_host = *(uint8_t*)(p);
641     dest_host = *(uint8_t*)(p + 1);
642     pipe_id = *(uint8_t*)(p + 4);
643 
644     if ((source_host != NFC_HAL_HCI_HOST_ID_UICC1) &&
645         (dest_host != NFC_HAL_HCI_HOST_ID_UICC1)) {
646       memcpy(np, p, NFC_HAL_HCI_PIPE_INFO_SIZE);
647       np += NFC_HAL_HCI_PIPE_INFO_SIZE;
648       new_num_dyn_pipes++;
649     }
650   }
651 
652   memset((uint8_t*)(np), 0,
653          NFC_HAL_HCI_PIPE_INFO_SIZE * (20 - new_num_dyn_pipes));
654 
655   /* Update number of pipes after removing pipes connected to UICC1 */
656   p = (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf +
657                  NFC_HAL_HCI_MIN_DH_NETWK_INFO_SIZE);
658   *(p - 1) = new_num_dyn_pipes;
659 }
660 
661 /*******************************************************************************
662 **
663 ** Function         nfc_hal_hci_init_complete
664 **
665 ** Description      Notify VSC initialization is complete
666 **
667 ** Returns          None
668 **
669 *******************************************************************************/
nfc_hal_hci_init_complete(tHAL_NFC_STATUS status)670 void nfc_hal_hci_init_complete(tHAL_NFC_STATUS status) {
671   uint8_t* p_hci_netwk_cmd;
672 
673   HAL_TRACE_DEBUG1("nfc_hal_hci_init_complete (): Status: [0x%02x]", status);
674 
675   if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf) {
676     p_hci_netwk_cmd = (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf -
677                                  NCI_MSG_HDR_SIZE);
678     GKI_freebuf(p_hci_netwk_cmd);
679     nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
680   }
681 
682   if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf) {
683     p_hci_netwk_cmd =
684         (uint8_t*)(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
685     GKI_freebuf(p_hci_netwk_cmd);
686     nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
687   }
688 
689   NFC_HAL_SET_INIT_STATE(NFC_HAL_INIT_STATE_IDLE);
690 
691   nfc_hal_cb.p_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, status);
692 }
693 
694 /*******************************************************************************
695 **
696 ** Function         nfc_hal_hci_set_next_hci_netwk_config
697 **
698 ** Description      set next hci network configuration
699 **
700 ** Returns          None
701 **
702 *******************************************************************************/
nfc_hal_hci_set_next_hci_netwk_config(uint8_t block)703 void nfc_hal_hci_set_next_hci_netwk_config(uint8_t block) {
704   uint8_t* p_hci_netwk_cmd;
705 
706   HAL_TRACE_DEBUG1("nfc_hal_hci_set_next_hci_netwk_config (): Block: [0x%02x]",
707                    block);
708 
709   switch (block) {
710     case HC_F3_NV_BLOCK:
711       if ((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC1_HOST) &&
712           (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf) &&
713           ((!nfc_hal_cb.hci_cb.hci_fw_workaround) ||
714            (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_EEPROM))) {
715         /* Send command to read nvram data for 0xF4 */
716         memset(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0,
717                NFC_HAL_HCI_NETWK_INFO_SIZE);
718         nfc_hal_nv_co_read((uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_info_buf,
719                            NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
720         nfc_hal_main_start_quick_timer(&nfc_hal_cb.hci_cb.hci_timer,
721                                        NFC_HAL_HCI_VSC_TIMEOUT_EVT,
722                                        NFC_HAL_HCI_NV_READ_TIMEOUT);
723         break;
724       }
725       HAL_TRACE_DEBUG2(
726           "nfc_hal_hci_set_next_hci_netwk_config (): Skip send F4 HCI NETWK "
727           "CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x",
728           p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
729 
730     case HC_F4_NV_BLOCK:
731       if ((p_nfc_hal_cfg->nfc_hal_hci_uicc_support & HAL_NFC_HCI_UICC2_HOST) &&
732           (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)) {
733         /* Send command to read nvram data for 0xF5 */
734         memset(nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0,
735                NFC_HAL_HCI_NETWK_INFO_SIZE);
736         nfc_hal_nv_co_read((uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_info_buf,
737                            NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F5_NV_BLOCK);
738         nfc_hal_main_start_quick_timer(&nfc_hal_cb.hci_cb.hci_timer,
739                                        NFC_HAL_HCI_VSC_TIMEOUT_EVT,
740                                        NFC_HAL_HCI_NV_READ_TIMEOUT);
741         break;
742       }
743       HAL_TRACE_DEBUG2(
744           "nfc_hal_hci_set_next_hci_netwk_config (): Skip send F5 HCI NETWK "
745           "CMD for UICC Mask: 0x%02x & NVM Type: 0x%02x",
746           p_nfc_hal_cfg->nfc_hal_hci_uicc_support, nfc_hal_cb.nvm_cb.nvm_type);
747 
748     case HC_F5_NV_BLOCK:
749       p_hci_netwk_cmd = (uint8_t*)GKI_getbuf(NCI_MSG_HDR_SIZE +
750                                              NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
751       if (p_hci_netwk_cmd == NULL) {
752         HAL_TRACE_ERROR0(
753             "nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer "
754             "for reading hci network info from nvram");
755         nfc_hal_hci_init_complete(HAL_NFC_STATUS_FAILED);
756       } else {
757         nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf =
758             (uint8_t*)(p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
759         /* Send command to read nvram data for 0xF2 */
760         memset(nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0,
761                NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
762         nfc_hal_nv_co_read((uint8_t*)nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf,
763                            NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_F2_NV_BLOCK);
764         nfc_hal_main_start_quick_timer(&nfc_hal_cb.hci_cb.hci_timer,
765                                        NFC_HAL_HCI_VSC_TIMEOUT_EVT,
766                                        NFC_HAL_HCI_NV_READ_TIMEOUT);
767       }
768       break;
769 
770     case HC_F2_NV_BLOCK:
771       nfc_hal_hci_init_complete(HAL_NFC_STATUS_OK);
772       break;
773 
774     default:
775       HAL_TRACE_ERROR1(
776           "nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to "
777           "send VSC 0x%02x",
778           block);
779       /* Brcm initialization failed */
780       nfc_hal_hci_init_complete(HAL_NFC_STATUS_FAILED);
781       break;
782   }
783 }
784 
785 /*******************************************************************************
786 **
787 ** Function         nfc_hal_hci_vsc_cback
788 **
789 ** Description      process VS callback event from stack
790 **
791 ** Returns          none
792 **
793 *******************************************************************************/
nfc_hal_hci_vsc_cback(tNFC_HAL_NCI_EVT event,uint16_t data_len,uint8_t * p_data)794 static void nfc_hal_hci_vsc_cback(tNFC_HAL_NCI_EVT event, uint16_t data_len,
795                                   uint8_t* p_data) {
796   uint8_t* p_ret = NULL;
797   uint8_t status;
798 
799   p_ret = p_data + NCI_MSG_HDR_SIZE;
800   status = *p_ret;
801 
802   HAL_TRACE_DEBUG3(
803       "nfc_hal_hci_vsc_cback (): Event: [0x%02x], Data length: [0x%04x], "
804       "Status: [0x%02x]",
805       event, data_len, status);
806 
807   if (event != NFC_VS_HCI_NETWK_RSP) return;
808 
809   if (status != HAL_NFC_STATUS_OK) {
810     nfc_hal_hci_init_complete(HAL_NFC_STATUS_FAILED);
811     return;
812   }
813 
814   switch (nfc_hal_cb.hci_cb.hci_netwk_config_block) {
815     case HC_F3_NV_BLOCK:
816     case HC_F4_NV_BLOCK:
817     case HC_F5_NV_BLOCK:
818     case HC_F2_NV_BLOCK:
819       nfc_hal_hci_set_next_hci_netwk_config(
820           nfc_hal_cb.hci_cb.hci_netwk_config_block);
821       break;
822 
823     default:
824       /* Ignore the event */
825       break;
826   }
827 }
828 
829 /*******************************************************************************
830 **
831 ** Function         nfc_hal_nci_cmd_timeout_cback
832 **
833 ** Description      callback function for timeout
834 **
835 ** Returns          void
836 **
837 *******************************************************************************/
nfc_hal_hci_timeout_cback(void * p_tle)838 void nfc_hal_hci_timeout_cback(void* p_tle) {
839   TIMER_LIST_ENT* p_tlent = (TIMER_LIST_ENT*)p_tle;
840 
841   HAL_TRACE_DEBUG0("nfc_hal_hci_timeout_cback ()");
842 
843   if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT) {
844     HAL_TRACE_ERROR0(
845         "nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization "
846         "Failed!");
847     nfc_hal_hci_init_complete(HAL_NFC_STATUS_FAILED);
848   }
849 }
850 
851 #endif
852