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