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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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