1 /******************************************************************************
2 *
3 * Copyright (C) 2012 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_nv_ci.h"
28 #include "nfc_hal_nv_co.h"
29
30 #include <string.h>
31 #include "nfc_hal_nv_co.h"
32
33 #ifndef NFC_HAL_HCI_NV_READ_TIMEOUT
34 #define NFC_HAL_HCI_NV_READ_TIMEOUT 1000
35 #endif
36
37 #ifndef NFC_HAL_HCI_NFCC_RSP_TIMEOUT
38 #define NFC_HAL_HCI_NFCC_RSP_TIMEOUT 3000
39 #endif
40
41 static void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block);
42 static void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size);
43 static void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status);
44 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data);
45
46 /*******************************************************************************
47 **
48 ** Function nfc_hal_hci_evt_hdlr
49 **
50 ** Description Processing event for NFA HCI
51 **
52 ** Returns None
53 **
54 *******************************************************************************/
nfc_hal_hci_evt_hdlr(tNFC_HAL_HCI_EVENT_DATA * p_evt_data)55 void nfc_hal_hci_evt_hdlr (tNFC_HAL_HCI_EVENT_DATA *p_evt_data)
56 {
57 switch (p_evt_data->hdr.event)
58 {
59 case NFC_HAL_HCI_RSP_NV_READ_EVT:
60 nfc_hal_hci_handle_nv_read (p_evt_data->nv_read.block, p_evt_data->nv_read.status, p_evt_data->nv_read.size);
61 break;
62
63 case NFC_HAL_HCI_RSP_NV_WRITE_EVT:
64 /* NV Ram write completed - nothing to do... */
65 break;
66
67 default:
68 break;
69 }
70 }
71
72 /*******************************************************************************
73 **
74 ** Function nfc_hal_hci_enable
75 **
76 ** Description Program nv data on to controller
77 **
78 ** Returns void
79 **
80 *******************************************************************************/
nfc_hal_hci_enable(void)81 void nfc_hal_hci_enable (void)
82 {
83
84 UINT8 *p_hci_netwk_cmd;
85
86 if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
87 {
88 p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
89 GKI_freebuf (p_hci_netwk_cmd);
90 nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
91 }
92
93 if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
94 {
95 p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
96 GKI_freebuf (p_hci_netwk_cmd);
97 nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
98 }
99
100 if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_NETWK_INFO_SIZE)) == NULL)
101 {
102 NCI_TRACE_ERROR0 ("nfc_hal_hci_enable: unable to allocate buffer for reading hci network info from nvram");
103 nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
104 }
105 else
106 {
107 nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
108 nfc_hal_cb.hci_cb.hci_netwk_config_block = 0;
109 memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
110 nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F3_NV_BLOCK);
111 nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
112 }
113 }
114
115 /*******************************************************************************
116 **
117 ** Function nfc_hal_hci_handle_hci_netwk_info
118 **
119 ** Description Handler function for HCI Network Notification
120 **
121 ** Returns None
122 **
123 *******************************************************************************/
nfc_hal_hci_handle_hci_netwk_info(UINT8 * p_data)124 void nfc_hal_hci_handle_hci_netwk_info (UINT8 *p_data)
125 {
126 UINT8 *p = p_data;
127 UINT16 data_len;
128 UINT8 target_handle;
129 UINT8 hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
130
131 NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_hci_netwk_info()");
132
133 /* skip NCI header byte0 (MT,GID), byte1 (OID) */
134 p += 2;
135
136 STREAM_TO_UINT8 (data_len, p);
137 target_handle = *(UINT8 *) p;
138
139 if (target_handle == NFC_HAL_HCI_DH_TARGET_HANDLE)
140 nfc_hal_nv_co_write (p, data_len,HC_DH_NV_BLOCK);
141
142 else if (target_handle == NFC_HAL_HCI_UICC0_TARGET_HANDLE)
143 {
144 if (p[12] & 0x80)
145 {
146 /* HCI Network notification received for UICC 0, Update nv data */
147 nfc_hal_nv_co_write (p, data_len,HC_F3_NV_BLOCK);
148 }
149 else
150 {
151 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
152 hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
153 memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
154 nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
155 }
156 }
157 else if (target_handle == NFC_HAL_HCI_UICC1_TARGET_HANDLE)
158 {
159 if (p[12] & 0x80)
160 {
161 /* HCI Network notification received for UICC 1, Update nv data */
162 nfc_hal_nv_co_write (p, data_len,HC_F4_NV_BLOCK);
163 }
164 else
165 {
166 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hci_netwk_info(): Type A Card Emulation invalid, Reset nv file: 0x%02x", p[15]);
167 hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
168 /* Reset Session ID */
169 memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
170 nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
171 }
172 }
173 }
174
175 /*******************************************************************************
176 **
177 ** Function nfc_hal_hci_handle_hcp_pkt
178 **
179 ** Description Handle HCP Packet
180 **
181 ** Returns None
182 **
183 *******************************************************************************/
nfc_hal_hci_handle_hcp_pkt(UINT8 * p_data)184 void nfc_hal_hci_handle_hcp_pkt (UINT8 *p_data)
185 {
186 UINT8 chaining_bit;
187 UINT8 pipe;
188 UINT8 type;
189 UINT8 inst;
190 UINT8 hci_netwk_cmd[1 + NFC_HAL_HCI_SESSION_ID_LEN];
191 UINT8 source_host;
192
193 chaining_bit = ((*p_data) >> 0x07) & 0x01;
194 pipe = (*p_data++) & 0x7F;
195
196 if ( (chaining_bit)
197 &&(pipe == NFC_HAL_HCI_ADMIN_PIPE) )
198 {
199 type = ((*p_data) >> 0x06) & 0x03;
200
201 if (type == NFC_HAL_HCI_COMMAND_TYPE)
202 {
203 inst = (*p_data++ & 0x3F);
204
205 if (inst == NFC_HAL_HCI_ADM_NOTIFY_ALL_PIPE_CLEARED)
206 {
207
208 STREAM_TO_UINT8 (source_host, p_data);
209
210 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Received Clear All pipe command for UICC: 0x%02x", source_host);
211 if (source_host == NFC_HAL_HCI_HOST_ID_UICC0)
212 {
213 hci_netwk_cmd[0] = NFC_HAL_HCI_UICC0_TARGET_HANDLE;
214 /* Reset Session ID */
215 memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
216 nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F3_NV_BLOCK);
217 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F3_NV_BLOCK);
218 }
219 else if (source_host == NFC_HAL_HCI_HOST_ID_UICC1)
220 {
221 hci_netwk_cmd[0] = NFC_HAL_HCI_UICC1_TARGET_HANDLE;
222 /* Reset Session ID */
223 memset (&hci_netwk_cmd[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
224 nfc_hal_nv_co_write (hci_netwk_cmd, 1, HC_F4_NV_BLOCK);
225 NCI_TRACE_DEBUG1 ("nfc_hal_hci_handle_hcp_pkt(): Sent command to reset nv file for block: 0x%02x", HC_F4_NV_BLOCK);
226 }
227 }
228 }
229 }
230 }
231
232 /*******************************************************************************
233 **
234 ** Function nfc_hal_hci_handle_nv_read
235 **
236 ** Description handler function for nv read complete event
237 **
238 ** Returns None
239 **
240 *******************************************************************************/
nfc_hal_hci_handle_nv_read(UINT8 block,tHAL_NFC_STATUS status,UINT16 size)241 void nfc_hal_hci_handle_nv_read (UINT8 block, tHAL_NFC_STATUS status, UINT16 size)
242 {
243 NFC_HDR *p_data = NULL;
244 UINT8 *p;
245 UINT8 *p_hci_netwk_info = NULL;
246
247 /* Stop timer as NVDATA Read Completed */
248 nfc_hal_main_stop_quick_timer (&nfc_hal_cb.hci_cb.hci_timer);
249
250 switch (block)
251 {
252 case HC_F3_NV_BLOCK:
253 case HC_F4_NV_BLOCK:
254 if ( (status != HAL_NFC_STATUS_OK)
255 ||(size > NFC_HAL_HCI_NETWK_INFO_SIZE) )
256 {
257 NCI_TRACE_DEBUG0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Set DEFAULT Configuration!");
258 memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
259 nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[0] = (block == HC_F3_NV_BLOCK) ? NFC_HAL_HCI_UICC0_TARGET_HANDLE : NFC_HAL_HCI_UICC1_TARGET_HANDLE;
260 memset (&nfc_hal_cb.hci_cb.p_hci_netwk_info_buf[1], 0xFF, NFC_HAL_HCI_SESSION_ID_LEN);
261 size = NFC_HAL_HCI_NETWK_INFO_SIZE;
262 }
263
264 p_hci_netwk_info = (UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE;
265 break;
266
267 case HC_DH_NV_BLOCK:
268 if ( (status == HAL_NFC_STATUS_OK)
269 &&(size <= NFC_HAL_HCI_DH_NETWK_INFO_SIZE) )
270 {
271 p_hci_netwk_info = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
272 }
273 else
274 {
275 NCI_TRACE_ERROR0 ("nfc_hal_hci_handle_nv_read: Invalid data from nv memory, Skip DH Configuration!");
276 }
277 break;
278
279 default:
280 return;
281 }
282
283 if (p_hci_netwk_info)
284 {
285 p = p_hci_netwk_info;
286 /* Send HCI Network ntf command using nv data */
287 NCI_MSG_BLD_HDR0 (p, NCI_MT_CMD, NCI_GID_PROP);
288 NCI_MSG_BLD_HDR1 (p, NCI_MSG_HCI_NETWK);
289 UINT8_TO_STREAM (p, (UINT8) size);
290
291 nfc_hal_dm_send_nci_cmd (p_hci_netwk_info, (UINT16) (NCI_MSG_HDR_SIZE + size), nfc_hal_hci_vsc_cback);
292
293 nfc_hal_cb.hci_cb.hci_netwk_config_block = block;
294 }
295 else
296 {
297 /* Set next HCI Network configuration */
298 nfc_hal_hci_set_next_hci_netwk_config (block);
299 }
300 }
301
302 /*******************************************************************************
303 **
304 ** Function nfc_hal_hci_init_complete
305 **
306 ** Description Notify VSC initialization is complete
307 **
308 ** Returns None
309 **
310 *******************************************************************************/
nfc_hal_hci_init_complete(tHAL_NFC_STATUS status)311 void nfc_hal_hci_init_complete (tHAL_NFC_STATUS status)
312 {
313 UINT8 *p_hci_netwk_cmd;
314
315 if (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf)
316 {
317 p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf - NCI_MSG_HDR_SIZE);
318 GKI_freebuf (p_hci_netwk_cmd);
319 nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = NULL;
320 }
321
322 if (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf)
323 {
324 p_hci_netwk_cmd = (UINT8 *) (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf - NCI_MSG_HDR_SIZE);
325 GKI_freebuf (p_hci_netwk_cmd);
326 nfc_hal_cb.hci_cb.p_hci_netwk_info_buf = NULL;
327 }
328
329 NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_IDLE);
330 nfc_hal_cb.p_stack_cback (HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
331 }
332
333 /*******************************************************************************
334 **
335 ** Function nfc_hal_hci_set_next_hci_netwk_config
336 **
337 ** Description set next hci network configuration
338 **
339 ** Returns None
340 **
341 *******************************************************************************/
nfc_hal_hci_set_next_hci_netwk_config(UINT8 block)342 void nfc_hal_hci_set_next_hci_netwk_config (UINT8 block)
343 {
344 UINT8 *p_hci_netwk_cmd;
345
346 switch (block)
347 {
348 case HC_F3_NV_BLOCK:
349 /* Send command to read nvram data for 0xF4 */
350 memset (nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, 0, NFC_HAL_HCI_NETWK_INFO_SIZE);
351 nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_info_buf, NFC_HAL_HCI_NETWK_INFO_SIZE, HC_F4_NV_BLOCK);
352 nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
353 break;
354
355 case HC_F4_NV_BLOCK:
356 if ((p_hci_netwk_cmd = (UINT8 *) GKI_getbuf (NCI_MSG_HDR_SIZE + NFC_HAL_HCI_DH_NETWK_INFO_SIZE)) == NULL)
357 {
358 NCI_TRACE_ERROR0 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer for reading hci network info from nvram");
359 nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
360 }
361 else
362 {
363 nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf = (UINT8 *) (p_hci_netwk_cmd + NCI_MSG_HDR_SIZE);
364 /* Send command to read nvram data for 0xF2 */
365 memset (nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, 0, NFC_HAL_HCI_DH_NETWK_INFO_SIZE);
366 nfc_hal_nv_co_read ((UINT8 *) nfc_hal_cb.hci_cb.p_hci_netwk_dh_info_buf, NFC_HAL_HCI_DH_NETWK_INFO_SIZE, HC_DH_NV_BLOCK);
367 nfc_hal_main_start_quick_timer (&nfc_hal_cb.hci_cb.hci_timer, NFC_HAL_HCI_VSC_TIMEOUT_EVT, NFC_HAL_HCI_NV_READ_TIMEOUT);
368 }
369 break;
370
371 case HC_DH_NV_BLOCK:
372 nfc_hal_hci_init_complete (HAL_NFC_STATUS_OK);
373 break;
374
375 default:
376 NCI_TRACE_ERROR1 ("nfc_hal_hci_set_next_hci_netwk_config: unable to allocate buffer to send VSC 0x%02x", block);
377 /* Brcm initialization failed */
378 nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
379 break;
380 }
381 }
382
383 /*******************************************************************************
384 **
385 ** Function nfc_hal_hci_vsc_cback
386 **
387 ** Description process VS callback event from stack
388 **
389 ** Returns none
390 **
391 *******************************************************************************/
nfc_hal_hci_vsc_cback(tNFC_HAL_NCI_EVT event,UINT16 data_len,UINT8 * p_data)392 static void nfc_hal_hci_vsc_cback (tNFC_HAL_NCI_EVT event, UINT16 data_len, UINT8 *p_data)
393 {
394 UINT8 *p_ret = NULL;
395 UINT8 status;
396
397 p_ret = p_data + NCI_MSG_HDR_SIZE;
398 status = *p_ret;
399
400 if (event != NFC_VS_HCI_NETWK_RSP)
401 return;
402
403 if (status != HAL_NFC_STATUS_OK)
404 nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
405
406 switch (nfc_hal_cb.hci_cb.hci_netwk_config_block)
407 {
408 case HC_F3_NV_BLOCK:
409 case HC_F4_NV_BLOCK:
410 case HC_DH_NV_BLOCK:
411 nfc_hal_hci_set_next_hci_netwk_config (nfc_hal_cb.hci_cb.hci_netwk_config_block);
412 break;
413
414 default:
415 /* Ignore the event */
416 break;
417 }
418 }
419
420 /*******************************************************************************
421 **
422 ** Function nfc_hal_nci_cmd_timeout_cback
423 **
424 ** Description callback function for timeout
425 **
426 ** Returns void
427 **
428 *******************************************************************************/
nfc_hal_hci_timeout_cback(void * p_tle)429 void nfc_hal_hci_timeout_cback (void *p_tle)
430 {
431 TIMER_LIST_ENT *p_tlent = (TIMER_LIST_ENT *)p_tle;
432
433 NCI_TRACE_DEBUG0 ("nfc_hal_hci_timeout_cback ()");
434
435 if (p_tlent->event == NFC_HAL_HCI_VSC_TIMEOUT_EVT)
436 {
437 NCI_TRACE_ERROR0 ("nfc_hal_hci_timeout_cback: Timeout - NFC HAL HCI BRCM Initialization Failed!");
438 nfc_hal_hci_init_complete (HAL_NFC_STATUS_FAILED);
439 }
440 }
441
442