• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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