1 /****************************************************************************** 2 * 3 * Copyright (C) 2010-2013 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 nfc_ncif_rf_management_status (NFC_START_DEVT, *pp); 173 break; 174 175 case NCI_MSG_RF_DISCOVER_SELECT: 176 nfc_ncif_rf_management_status (NFC_SELECT_DEVT, *pp); 177 break; 178 179 case NCI_MSG_RF_T3T_POLLING: 180 break; 181 182 case NCI_MSG_RF_DISCOVER_MAP: 183 nfc_ncif_rf_management_status (NFC_MAP_DEVT, *pp); 184 break; 185 186 case NCI_MSG_RF_DEACTIVATE: 187 nfc_ncif_proc_deactivate (*pp, *p_old, FALSE); 188 break; 189 190 #if (NFC_NFCEE_INCLUDED == TRUE) 191 #if (NFC_RW_ONLY == FALSE) 192 193 case NCI_MSG_RF_SET_ROUTING: 194 nfc_ncif_event_status (NFC_SET_ROUTING_REVT, *pp); 195 break; 196 197 case NCI_MSG_RF_GET_ROUTING: 198 if (*pp != NFC_STATUS_OK) 199 nfc_ncif_event_status (NFC_GET_ROUTING_REVT, *pp); 200 break; 201 #endif 202 #endif 203 204 case NCI_MSG_RF_PARAMETER_UPDATE: 205 nfc_ncif_event_status (NFC_RF_COMM_PARAMS_UPDATE_REVT, *pp); 206 break; 207 208 default: 209 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code); 210 break; 211 } 212 } 213 214 /******************************************************************************* 215 ** 216 ** Function nci_proc_rf_management_ntf 217 ** 218 ** Description Process NCI notifications in the RF Management group 219 ** 220 ** Returns void 221 ** 222 *******************************************************************************/ 223 void nci_proc_rf_management_ntf (BT_HDR *p_msg) 224 { 225 UINT8 *p; 226 UINT8 *pp, len, op_code; 227 228 /* find the start of the NCI message and parse the NCI header */ 229 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 230 pp = p+1; 231 NCI_MSG_PRS_HDR1 (pp, op_code); 232 len = *pp++; 233 234 switch (op_code) 235 { 236 case NCI_MSG_RF_DISCOVER : 237 nfc_ncif_proc_discover_ntf (p, p_msg->len); 238 break; 239 240 case NCI_MSG_RF_DEACTIVATE: 241 nfc_ncif_proc_deactivate (NFC_STATUS_OK, *pp, TRUE); 242 break; 243 244 case NCI_MSG_RF_INTF_ACTIVATED: 245 nfc_ncif_proc_activate (pp, len); 246 break; 247 248 case NCI_MSG_RF_FIELD: 249 nfc_ncif_proc_rf_field_ntf (*pp); 250 break; 251 252 case NCI_MSG_RF_T3T_POLLING: 253 nfc_ncif_proc_t3t_polling_ntf (pp, len); 254 break; 255 256 #if (NFC_NFCEE_INCLUDED == TRUE) 257 #if (NFC_RW_ONLY == FALSE) 258 259 case NCI_MSG_RF_GET_ROUTING: 260 nfc_ncif_proc_get_routing (pp, len); 261 break; 262 263 case NCI_MSG_RF_EE_ACTION: 264 nfc_ncif_proc_ee_action (pp, len); 265 break; 266 267 case NCI_MSG_RF_EE_DISCOVERY_REQ: 268 nfc_ncif_proc_ee_discover_req (pp, len); 269 break; 270 #endif 271 #endif 272 273 default: 274 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code); 275 break; 276 } 277 } 278 279 #if (NFC_NFCEE_INCLUDED == TRUE) 280 #if (NFC_RW_ONLY == FALSE) 281 282 /******************************************************************************* 283 ** 284 ** Function nci_proc_ee_management_rsp 285 ** 286 ** Description Process NCI responses in the NFCEE Management group 287 ** 288 ** Returns void 289 ** 290 *******************************************************************************/ 291 void nci_proc_ee_management_rsp (BT_HDR *p_msg) 292 { 293 UINT8 *p; 294 UINT8 *pp, len, op_code; 295 tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback; 296 tNFC_NFCEE_DISCOVER_REVT nfcee_discover; 297 tNFC_NFCEE_INFO_REVT nfcee_info; 298 tNFC_NFCEE_MODE_SET_REVT mode_set; 299 tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info; 300 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT; 301 UINT8 *p_old = nfc_cb.last_cmd; 302 303 /* find the start of the NCI message and parse the NCI header */ 304 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 305 pp = p+1; 306 NCI_MSG_PRS_HDR1 (pp, op_code); 307 NFC_TRACE_DEBUG1 ("nci_proc_ee_management_rsp opcode:0x%x", op_code); 308 len = *pp++; 309 310 switch (op_code) 311 { 312 case NCI_MSG_NFCEE_DISCOVER: 313 p_evt = (tNFC_RESPONSE *) &nfcee_discover; 314 nfcee_discover.status = *pp++; 315 nfcee_discover.num_nfcee = *pp++; 316 317 if (nfcee_discover.status != NFC_STATUS_OK) 318 nfcee_discover.num_nfcee = 0; 319 320 event = NFC_NFCEE_DISCOVER_REVT; 321 break; 322 323 case NCI_MSG_NFCEE_MODE_SET: 324 p_evt = (tNFC_RESPONSE *) &mode_set; 325 mode_set.status = *pp; 326 mode_set.nfcee_id = 0; 327 event = NFC_NFCEE_MODE_SET_REVT; 328 mode_set.nfcee_id = *p_old++; 329 mode_set.mode = *p_old++; 330 break; 331 332 default: 333 p_cback = NULL; 334 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code); 335 break; 336 } 337 338 if (p_cback) 339 (*p_cback) (event, p_evt); 340 } 341 342 /******************************************************************************* 343 ** 344 ** Function nci_proc_ee_management_ntf 345 ** 346 ** Description Process NCI notifications in the NFCEE Management group 347 ** 348 ** Returns void 349 ** 350 *******************************************************************************/ 351 void nci_proc_ee_management_ntf (BT_HDR *p_msg) 352 { 353 UINT8 *p; 354 UINT8 *pp, len, op_code; 355 tNFC_RESPONSE_CBACK *p_cback = nfc_cb.p_resp_cback; 356 tNFC_NFCEE_INFO_REVT nfcee_info; 357 tNFC_RESPONSE *p_evt = (tNFC_RESPONSE *) &nfcee_info; 358 tNFC_RESPONSE_EVT event = NFC_NFCEE_INFO_REVT; 359 UINT8 xx; 360 UINT8 yy; 361 UINT8 ee_status; 362 tNFC_NFCEE_TLV *p_tlv; 363 364 /* find the start of the NCI message and parse the NCI header */ 365 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 366 pp = p+1; 367 NCI_MSG_PRS_HDR1 (pp, op_code); 368 NFC_TRACE_DEBUG1 ("nci_proc_ee_management_ntf opcode:0x%x", op_code); 369 len = *pp++; 370 371 if (op_code == NCI_MSG_NFCEE_DISCOVER) 372 { 373 nfcee_info.nfcee_id = *pp++; 374 ee_status = *pp++; 375 376 nfcee_info.ee_status = ee_status; 377 yy = *pp; 378 nfcee_info.num_interface = *pp++; 379 p = pp; 380 381 if (nfcee_info.num_interface > NFC_MAX_EE_INTERFACE) 382 nfcee_info.num_interface = NFC_MAX_EE_INTERFACE; 383 384 for (xx = 0; xx < nfcee_info.num_interface; xx++) 385 { 386 nfcee_info.ee_interface[xx] = *pp++; 387 } 388 389 pp = p + yy; 390 nfcee_info.num_tlvs = *pp++; 391 NFC_TRACE_DEBUG4 ("nfcee_id: 0x%x num_interface:0x%x/0x%x, num_tlvs:0x%x", 392 nfcee_info.nfcee_id, nfcee_info.num_interface, yy, nfcee_info.num_tlvs); 393 394 if (nfcee_info.num_tlvs > NFC_MAX_EE_TLVS) 395 nfcee_info.num_tlvs = NFC_MAX_EE_TLVS; 396 397 p_tlv = &nfcee_info.ee_tlv[0]; 398 399 for (xx = 0; xx < nfcee_info.num_tlvs; xx++, p_tlv++) 400 { 401 p_tlv->tag = *pp++; 402 p_tlv->len = yy = *pp++; 403 NFC_TRACE_DEBUG2 ("tag:0x%x, len:0x%x", p_tlv->tag, p_tlv->len); 404 if (p_tlv->len > NFC_MAX_EE_INFO) 405 p_tlv->len = NFC_MAX_EE_INFO; 406 p = pp; 407 STREAM_TO_ARRAY (p_tlv->info, pp, p_tlv->len); 408 pp = p += yy; 409 } 410 } 411 else 412 { 413 p_cback = NULL; 414 NFC_TRACE_ERROR1 ("unknown opcode:0x%x", op_code); 415 } 416 417 if (p_cback) 418 (*p_cback) (event, p_evt); 419 } 420 421 #endif 422 #endif 423 424 /******************************************************************************* 425 ** 426 ** Function nci_proc_prop_rsp 427 ** 428 ** Description Process NCI responses in the Proprietary group 429 ** 430 ** Returns void 431 ** 432 *******************************************************************************/ 433 void nci_proc_prop_rsp (BT_HDR *p_msg) 434 { 435 UINT8 *p; 436 UINT8 *p_evt; 437 UINT8 *pp, len, op_code; 438 tNFC_VS_CBACK *p_cback = (tNFC_VS_CBACK *)nfc_cb.p_vsc_cback; 439 440 /* find the start of the NCI message and parse the NCI header */ 441 p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset; 442 pp = p+1; 443 NCI_MSG_PRS_HDR1 (pp, op_code); 444 len = *pp++; 445 446 /*If there's a pending/stored command, restore the associated address of the callback function */ 447 if (p_cback) 448 (*p_cback) ((tNFC_VS_EVT) (NCI_RSP_BIT|op_code), p_msg->len, p_evt); 449 } 450 451 /******************************************************************************* 452 ** 453 ** Function nci_proc_prop_ntf 454 ** 455 ** Description Process NCI notifications in the Proprietary group 456 ** 457 ** Returns void 458 ** 459 *******************************************************************************/ 460 void nci_proc_prop_ntf (BT_HDR *p_msg) 461 { 462 UINT8 *p; 463 UINT8 *p_evt; 464 UINT8 *pp, len, op_code; 465 int i; 466 467 /* find the start of the NCI message and parse the NCI header */ 468 p = p_evt = (UINT8 *) (p_msg + 1) + p_msg->offset; 469 pp = p+1; 470 NCI_MSG_PRS_HDR1 (pp, op_code); 471 len = *pp++; 472 473 for (i = 0; i < NFC_NUM_VS_CBACKS; i++) 474 { 475 if (nfc_cb.p_vs_cb[i]) 476 { 477 (*nfc_cb.p_vs_cb[i]) ((tNFC_VS_EVT) (NCI_NTF_BIT|op_code), p_msg->len, p_evt); 478 } 479 } 480 } 481 482 #endif /* NFC_INCLUDED == TRUE*/ 483