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 * This file contains function of the NFC unit to receive/process NCI 22 * commands. 23 * 24 ******************************************************************************/ 25 #include <string.h> 26 27 #include <android-base/stringprintf.h> 28 #include <base/logging.h> 29 30 #include "nfc_target.h" 31 32 #include "bt_types.h" 33 #include "gki.h" 34 #include "nci_defs.h" 35 #include "nci_hmsgs.h" 36 #include "nfc_api.h" 37 #include "nfc_int.h" 38 39 using android::base::StringPrintf; 40 41 extern bool nfc_debug_enabled; 42 43 /******************************************************************************* 44 ** 45 ** Function nci_proc_core_rsp 46 ** 47 ** Description Process NCI responses in the CORE group 48 ** 49 ** Returns TRUE-caller of this function to free the GKI buffer p_msg 50 ** 51 *******************************************************************************/ 52 bool nci_proc_core_rsp(NFC_HDR* p_msg) { 53 uint8_t* p; 54 uint8_t *pp, len, op_code; 55 bool free = true; 56 uint8_t* p_old = nfc_cb.last_cmd; 57 58 /* find the start of the NCI message and parse the NCI header */ 59 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 60 pp = p + 1; 61 NCI_MSG_PRS_HDR1(pp, op_code); 62 DLOG_IF(INFO, nfc_debug_enabled) 63 << StringPrintf("nci_proc_core_rsp opcode:0x%x", op_code); 64 len = *pp++; 65 66 /* process the message based on the opcode and message type */ 67 switch (op_code) { 68 case NCI_MSG_CORE_RESET: 69 nfc_ncif_proc_reset_rsp(pp, false); 70 break; 71 72 case NCI_MSG_CORE_INIT: 73 nfc_ncif_proc_init_rsp(p_msg); 74 free = false; 75 break; 76 77 case NCI_MSG_CORE_GET_CONFIG: 78 nfc_ncif_proc_get_config_rsp(p_msg); 79 break; 80 81 case NCI_MSG_CORE_SET_CONFIG: 82 nfc_ncif_set_config_status(pp, len); 83 break; 84 85 case NCI_MSG_CORE_CONN_CREATE: 86 nfc_ncif_proc_conn_create_rsp(p, p_msg->len, *p_old); 87 break; 88 89 case NCI_MSG_CORE_CONN_CLOSE: 90 nfc_ncif_report_conn_close_evt(*p_old, *pp); 91 break; 92 case NCI_MSG_CORE_SET_POWER_SUB_STATE: 93 nfc_ncif_event_status(NFC_SET_POWER_SUB_STATE_REVT, *pp); 94 break; 95 default: 96 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 97 break; 98 } 99 100 return free; 101 } 102 103 /******************************************************************************* 104 ** 105 ** Function nci_proc_core_ntf 106 ** 107 ** Description Process NCI notifications in the CORE group 108 ** 109 ** Returns void 110 ** 111 *******************************************************************************/ 112 void nci_proc_core_ntf(NFC_HDR* p_msg) { 113 uint8_t* p; 114 uint8_t *pp, len, op_code; 115 uint8_t conn_id; 116 117 /* find the start of the NCI message and parse the NCI header */ 118 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 119 pp = p + 1; 120 NCI_MSG_PRS_HDR1(pp, op_code); 121 DLOG_IF(INFO, nfc_debug_enabled) 122 << StringPrintf("nci_proc_core_ntf opcode:0x%x", op_code); 123 len = *pp++; 124 125 /* process the message based on the opcode and message type */ 126 switch (op_code) { 127 case NCI_MSG_CORE_RESET: 128 nfc_ncif_proc_reset_rsp(pp, true); 129 break; 130 131 case NCI_MSG_CORE_GEN_ERR_STATUS: 132 /* process the error ntf */ 133 /* in case of timeout: notify the static connection callback */ 134 nfc_ncif_event_status(NFC_GEN_ERROR_REVT, *pp); 135 nfc_ncif_error_status(NFC_RF_CONN_ID, *pp); 136 break; 137 138 case NCI_MSG_CORE_INTF_ERR_STATUS: 139 conn_id = *(pp + 1); 140 nfc_ncif_error_status(conn_id, *pp); 141 break; 142 143 case NCI_MSG_CORE_CONN_CREDITS: 144 nfc_ncif_proc_credits(pp, len); 145 break; 146 147 default: 148 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 149 break; 150 } 151 } 152 153 /******************************************************************************* 154 ** 155 ** Function nci_proc_rf_management_rsp 156 ** 157 ** Description Process NCI responses in the RF Management group 158 ** 159 ** Returns void 160 ** 161 *******************************************************************************/ 162 void nci_proc_rf_management_rsp(NFC_HDR* p_msg) { 163 uint8_t* p; 164 uint8_t *pp, len, op_code; 165 uint8_t* p_old = nfc_cb.last_cmd; 166 167 /* find the start of the NCI message and parse the NCI header */ 168 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 169 pp = p + 1; 170 NCI_MSG_PRS_HDR1(pp, op_code); 171 len = *pp++; 172 173 switch (op_code) { 174 case NCI_MSG_RF_DISCOVER: 175 nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP); 176 nfc_ncif_rf_management_status(NFC_START_DEVT, *pp); 177 break; 178 179 case NCI_MSG_RF_DISCOVER_SELECT: 180 nfc_ncif_rf_management_status(NFC_SELECT_DEVT, *pp); 181 break; 182 183 case NCI_MSG_RF_T3T_POLLING: 184 break; 185 186 case NCI_MSG_RF_DISCOVER_MAP: 187 nfc_ncif_rf_management_status(NFC_MAP_DEVT, *pp); 188 break; 189 190 case NCI_MSG_RF_DEACTIVATE: 191 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_RSP) == false) { 192 return; 193 } 194 nfc_ncif_proc_deactivate(*pp, *p_old, false); 195 break; 196 197 #if (NFC_NFCEE_INCLUDED == TRUE) 198 #if (NFC_RW_ONLY == FALSE) 199 200 case NCI_MSG_RF_SET_ROUTING: 201 nfc_ncif_event_status(NFC_SET_ROUTING_REVT, *pp); 202 break; 203 204 case NCI_MSG_RF_GET_ROUTING: 205 if (*pp != NFC_STATUS_OK) 206 nfc_ncif_event_status(NFC_GET_ROUTING_REVT, *pp); 207 break; 208 #endif 209 #endif 210 211 case NCI_MSG_RF_PARAMETER_UPDATE: 212 nfc_ncif_event_status(NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp); 213 break; 214 215 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE: 216 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, false); 217 break; 218 default: 219 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 220 break; 221 } 222 } 223 224 /******************************************************************************* 225 ** 226 ** Function nci_proc_rf_management_ntf 227 ** 228 ** Description Process NCI notifications in the RF Management group 229 ** 230 ** Returns void 231 ** 232 *******************************************************************************/ 233 void nci_proc_rf_management_ntf(NFC_HDR* p_msg) { 234 uint8_t* p; 235 uint8_t *pp, len, op_code; 236 237 /* find the start of the NCI message and parse the NCI header */ 238 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 239 pp = p + 1; 240 NCI_MSG_PRS_HDR1(pp, op_code); 241 len = *pp++; 242 243 switch (op_code) { 244 case NCI_MSG_RF_DISCOVER: 245 nfc_ncif_proc_discover_ntf(p, p_msg->len); 246 break; 247 248 case NCI_MSG_RF_DEACTIVATE: 249 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) { 250 return; 251 } 252 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) { 253 nfc_cb.deact_reason = *(pp + 1); 254 } 255 nfc_ncif_proc_deactivate(NFC_STATUS_OK, *pp, true); 256 break; 257 258 case NCI_MSG_RF_INTF_ACTIVATED: 259 if (nfa_dm_p2p_prio_logic(op_code, pp, NFA_DM_P2P_PRIO_NTF) == false) { 260 return; 261 } 262 nfc_ncif_proc_activate(pp, len); 263 break; 264 265 case NCI_MSG_RF_FIELD: 266 nfc_ncif_proc_rf_field_ntf(*pp); 267 break; 268 269 case NCI_MSG_RF_T3T_POLLING: 270 nfc_ncif_proc_t3t_polling_ntf(pp, len); 271 break; 272 273 #if (NFC_NFCEE_INCLUDED == TRUE) 274 #if (NFC_RW_ONLY == FALSE) 275 276 case NCI_MSG_RF_GET_ROUTING: 277 nfc_ncif_proc_get_routing(pp, len); 278 break; 279 280 case NCI_MSG_RF_EE_ACTION: 281 nfc_ncif_proc_ee_action(pp, len); 282 break; 283 284 case NCI_MSG_RF_EE_DISCOVERY_REQ: 285 nfc_ncif_proc_ee_discover_req(pp, len); 286 break; 287 #endif 288 #endif 289 case NCI_MSG_RF_ISO_DEP_NAK_PRESENCE: 290 nfc_ncif_proc_isodep_nak_presence_check_status(*pp, true); 291 break; 292 default: 293 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 294 break; 295 } 296 } 297 298 #if (NFC_NFCEE_INCLUDED == TRUE) 299 #if (NFC_RW_ONLY == FALSE) 300 301 /******************************************************************************* 302 ** 303 ** Function nci_proc_ee_management_rsp 304 ** 305 ** Description Process NCI responses in the NFCEE Management group 306 ** 307 ** Returns void 308 ** 309 *******************************************************************************/ 310 void nci_proc_ee_management_rsp(NFC_HDR* p_msg) { 311 uint8_t* p; 312 uint8_t *pp, len, op_code; 313 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback; 314 tNFC_RESPONSE nfc_response; 315 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT; 316 uint8_t* p_old = nfc_cb.last_cmd; 317 318 /* find the start of the NCI message and parse the NCI header */ 319 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 320 pp = p + 1; 321 NCI_MSG_PRS_HDR1(pp, op_code); 322 DLOG_IF(INFO, nfc_debug_enabled) 323 << StringPrintf("nci_proc_ee_management_rsp opcode:0x%x", op_code); 324 len = *pp++; 325 326 switch (op_code) { 327 case NCI_MSG_NFCEE_DISCOVER: 328 nfc_response.nfcee_discover.status = *pp++; 329 nfc_response.nfcee_discover.num_nfcee = *pp++; 330 331 if (nfc_response.nfcee_discover.status != NFC_STATUS_OK) 332 nfc_response.nfcee_discover.num_nfcee = 0; 333 334 event = NFC_NFCEE_DISCOVER_REVT; 335 break; 336 337 case NCI_MSG_NFCEE_MODE_SET: 338 nfc_response.mode_set.status = *pp; 339 nfc_response.mode_set.nfcee_id = *p_old++; 340 nfc_response.mode_set.mode = *p_old++; 341 if (nfc_cb.nci_version != NCI_VERSION_2_0 || *pp != NCI_STATUS_OK) { 342 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF; 343 event = NFC_NFCEE_MODE_SET_REVT; 344 } else { 345 /* else response reports OK status on notification */ 346 return; 347 } 348 break; 349 350 case NCI_MSG_NFCEE_POWER_LINK_CTRL: 351 nfc_response.pl_control.status = *pp; 352 nfc_response.pl_control.nfcee_id = *p_old++; 353 nfc_response.pl_control.pl_control = *p_old++; 354 event = NFC_NFCEE_PL_CONTROL_REVT; 355 break; 356 default: 357 p_cback = NULL; 358 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 359 break; 360 } 361 362 if (p_cback) (*p_cback)(event, &nfc_response); 363 } 364 365 /******************************************************************************* 366 ** 367 ** Function nci_proc_ee_management_ntf 368 ** 369 ** Description Process NCI notifications in the NFCEE Management group 370 ** 371 ** Returns void 372 ** 373 *******************************************************************************/ 374 void nci_proc_ee_management_ntf(NFC_HDR* p_msg) { 375 uint8_t* p; 376 uint8_t *pp, len, op_code; 377 tNFC_RESPONSE_CBACK* p_cback = nfc_cb.p_resp_cback; 378 tNFC_RESPONSE nfc_response; 379 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT; 380 uint8_t* p_old = nfc_cb.last_cmd; 381 uint8_t xx; 382 uint8_t yy; 383 tNFC_NFCEE_TLV* p_tlv; 384 /* find the start of the NCI message and parse the NCI header */ 385 p = (uint8_t*)(p_msg + 1) + p_msg->offset; 386 pp = p + 1; 387 NCI_MSG_PRS_HDR1(pp, op_code); 388 DLOG_IF(INFO, nfc_debug_enabled) 389 << StringPrintf("nci_proc_ee_management_ntf opcode:0x%x", op_code); 390 len = *pp++; 391 392 if (op_code == NCI_MSG_NFCEE_DISCOVER) { 393 nfc_response.nfcee_info.nfcee_id = *pp++; 394 395 nfc_response.nfcee_info.ee_status = *pp++; 396 yy = *pp; 397 nfc_response.nfcee_info.num_interface = *pp++; 398 p = pp; 399 400 if (nfc_response.nfcee_info.num_interface > NFC_MAX_EE_INTERFACE) 401 nfc_response.nfcee_info.num_interface = NFC_MAX_EE_INTERFACE; 402 403 for (xx = 0; xx < nfc_response.nfcee_info.num_interface; xx++) { 404 nfc_response.nfcee_info.ee_interface[xx] = *pp++; 405 } 406 407 pp = p + yy; 408 nfc_response.nfcee_info.num_tlvs = *pp++; 409 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 410 "nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x", 411 nfc_response.nfcee_info.nfcee_id, nfc_response.nfcee_info.num_interface, 412 yy, nfc_response.nfcee_info.num_tlvs); 413 414 if (nfc_response.nfcee_info.num_tlvs > NFC_MAX_EE_TLVS) 415 nfc_response.nfcee_info.num_tlvs = NFC_MAX_EE_TLVS; 416 417 p_tlv = &nfc_response.nfcee_info.ee_tlv[0]; 418 419 for (xx = 0; xx < nfc_response.nfcee_info.num_tlvs; xx++, p_tlv++) { 420 p_tlv->tag = *pp++; 421 p_tlv->len = yy = *pp++; 422 DLOG_IF(INFO, nfc_debug_enabled) 423 << StringPrintf("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len); 424 if (p_tlv->len > NFC_MAX_EE_INFO) p_tlv->len = NFC_MAX_EE_INFO; 425 p = pp; 426 STREAM_TO_ARRAY(p_tlv->info, pp, p_tlv->len); 427 pp = p += yy; 428 } 429 } else if (op_code == NCI_MSG_NFCEE_MODE_SET) { 430 nfc_response.mode_set.status = *pp; 431 nfc_response.mode_set.nfcee_id = *p_old++; 432 nfc_response.mode_set.mode = *p_old++; 433 event = NFC_NFCEE_MODE_SET_REVT; 434 nfc_cb.flags &= ~NFC_FL_WAIT_MODE_SET_NTF; 435 nfc_stop_timer(&nfc_cb.nci_mode_set_ntf_timer); 436 } else if (op_code == NCI_MSG_NFCEE_STATUS) { 437 event = NFC_NFCEE_STATUS_REVT; 438 nfc_response.nfcee_status.status = NCI_STATUS_OK; 439 nfc_response.nfcee_status.nfcee_id = *pp++; 440 nfc_response.nfcee_status.nfcee_status = *pp; 441 } else { 442 p_cback = NULL; 443 LOG(ERROR) << StringPrintf("unknown opcode:0x%x", op_code); 444 } 445 446 if (p_cback) (*p_cback)(event, &nfc_response); 447 } 448 449 #endif 450 #endif 451 452 /******************************************************************************* 453 ** 454 ** Function nci_proc_prop_rsp 455 ** 456 ** Description Process NCI responses in the Proprietary group 457 ** 458 ** Returns void 459 ** 460 *******************************************************************************/ 461 void nci_proc_prop_rsp(NFC_HDR* p_msg) { 462 uint8_t* p; 463 uint8_t* p_evt; 464 uint8_t *pp, len, op_code; 465 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback; 466 467 /* find the start of the NCI message and parse the NCI header */ 468 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset; 469 pp = p + 1; 470 NCI_MSG_PRS_HDR1(pp, op_code); 471 len = *pp++; 472 473 /*If there's a pending/stored command, restore the associated address of the 474 * callback function */ 475 if (p_cback) 476 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt); 477 } 478 479 /******************************************************************************* 480 ** 481 ** Function nci_proc_prop_raw_vs_rsp 482 ** 483 ** Description Process RAW VS responses 484 ** 485 ** Returns void 486 ** 487 *******************************************************************************/ 488 void nci_proc_prop_raw_vs_rsp(NFC_HDR* p_msg) { 489 uint8_t op_code; 490 tNFC_VS_CBACK* p_cback = (tNFC_VS_CBACK*)nfc_cb.p_vsc_cback; 491 492 /* find the start of the NCI message and parse the NCI header */ 493 uint8_t* p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset; 494 uint8_t* p = p_evt + 1; 495 NCI_MSG_PRS_HDR1(p, op_code); 496 497 /* If there's a pending/stored command, restore the associated address of the 498 * callback function */ 499 if (p_cback) { 500 (*p_cback)((tNFC_VS_EVT)(NCI_RSP_BIT | op_code), p_msg->len, p_evt); 501 nfc_cb.p_vsc_cback = NULL; 502 } 503 nfc_cb.rawVsCbflag = false; 504 nfc_ncif_update_window(); 505 } 506 507 /******************************************************************************* 508 ** 509 ** Function nci_proc_prop_ntf 510 ** 511 ** Description Process NCI notifications in the Proprietary group 512 ** 513 ** Returns void 514 ** 515 *******************************************************************************/ 516 void nci_proc_prop_ntf(NFC_HDR* p_msg) { 517 uint8_t* p; 518 uint8_t* p_evt; 519 uint8_t *pp, len, op_code; 520 int i; 521 522 /* find the start of the NCI message and parse the NCI header */ 523 p = p_evt = (uint8_t*)(p_msg + 1) + p_msg->offset; 524 pp = p + 1; 525 NCI_MSG_PRS_HDR1(pp, op_code); 526 len = *pp++; 527 528 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) { 529 if (nfc_cb.p_vs_cb[i]) { 530 (*nfc_cb.p_vs_cb[i])((tNFC_VS_EVT)(NCI_NTF_BIT | op_code), p_msg->len, 531 p_evt); 532 } 533 } 534 } 535