1/****************************************************************************** 2 * 3 * Copyright (C) 2010-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 * This is the utilities implementation file for the NFA Connection 22 * Handover. 23 * 24 ******************************************************************************/ 25 26#include "string.h" 27#include "nfa_sys.h" 28#include "llcp_api.h" 29#include "llcp_defs.h" 30#include "nfa_p2p_int.h" 31#include "nfa_cho_api.h" 32#include "nfa_cho_int.h" 33#include "trace_api.h" 34#include "nfa_mem_co.h" 35 36/***************************************************************************** 37** Constants 38*****************************************************************************/ 39/* Handover server name on LLCP */ 40static char *p_cho_service_name = "urn:nfc:sn:handover"; 41 42/* Handover Request Record Type */ 43static UINT8 hr_rec_type[HR_REC_TYPE_LEN] = { 0x48, 0x72 }; /* "Hr" */ 44 45/* Handover Select Record Type */ 46static UINT8 hs_rec_type[HS_REC_TYPE_LEN] = { 0x48, 0x73 }; /* "Hs" */ 47 48/* Handover Carrier recrod Type */ 49/* static UINT8 hc_rec_type[HC_REC_TYPE_LEN] = { 0x48, 0x63 }; "Hc" */ 50 51/* Collision Resolution Record Type */ 52static UINT8 cr_rec_type[CR_REC_TYPE_LEN] = { 0x63, 0x72 }; /* "cr" */ 53 54/* Alternative Carrier Record Type */ 55static UINT8 ac_rec_type[AC_REC_TYPE_LEN] = { 0x61, 0x63 }; /* "ac" */ 56 57/* Error Record Type */ 58static UINT8 err_rec_type[ERR_REC_TYPE_LEN] = { 0x65, 0x72, 0x72 }; /* "err" */ 59 60/* Bluetooth OOB Data Type */ 61static UINT8 *p_bt_oob_rec_type = (UINT8 *) "application/vnd.bluetooth.ep.oob"; 62 63/* WiFi Data Type */ 64static UINT8 *p_wifi_rec_type = (UINT8 *) "application/vnd.wfa.wsc"; 65 66/***************************************************************************** 67** Global Variables 68*****************************************************************************/ 69 70/***************************************************************************** 71** Static Functions 72*****************************************************************************/ 73static void nfa_cho_ndef_cback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data); 74 75/******************************************************************************* 76** 77** Function nfa_cho_ndef_cback 78** 79** Description callback function from NDEF handler 80** Post NDEF handler callback event to NFA Connection Handover module 81** 82** Returns None 83** 84*******************************************************************************/ 85static void nfa_cho_ndef_cback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *p_data) 86{ 87 tNFA_CHO_NDEF_TYPE_HDLR_EVT *p_msg; 88 tNFA_CHO_MSG_TYPE msg_type; 89 90 CHO_TRACE_DEBUG1 ("nfa_cho_ndef_cback () event=%d", event); 91 92 if ((p_msg = (tNFA_CHO_NDEF_TYPE_HDLR_EVT *) GKI_getbuf (sizeof (tNFA_CHO_NDEF_TYPE_HDLR_EVT))) != NULL) 93 { 94 p_msg->hdr.event = NFA_CHO_NDEF_TYPE_HANDLER_EVT; 95 96 /* copy NDEF handler callback event and data */ 97 p_msg->event = event; 98 memcpy (&(p_msg->data), p_data, sizeof (tNFA_NDEF_EVT_DATA)); 99 100 /* if it has NDEF message */ 101 if (event == NFA_NDEF_DATA_EVT) 102 { 103 if (p_data->ndef_data.ndef_type_handle == nfa_cho_cb.bt_ndef_type_handle ) 104 { 105 msg_type = nfa_cho_get_msg_type (p_data->ndef_data.len, 106 p_data->ndef_data.p_data); 107 if (msg_type != NFA_CHO_MSG_BT_OOB) 108 { 109 /* This is not simplified BT OOB Message. It contains BT OOB Message. */ 110 GKI_freebuf (p_msg); 111 return; 112 } 113 } 114 else if (p_data->ndef_data.ndef_type_handle == nfa_cho_cb.wifi_ndef_type_handle ) 115 { 116 msg_type = nfa_cho_get_msg_type (p_data->ndef_data.len, 117 p_data->ndef_data.p_data); 118 if (msg_type != NFA_CHO_MSG_WIFI) 119 { 120 /* This is not simplified WiFi Message. It contains WiFi Message. */ 121 GKI_freebuf (p_msg); 122 return; 123 } 124 } 125 126 /* 127 ** NDEF message could be bigger than max GKI buffer 128 ** so allocate memory from platform. 129 */ 130 p_msg->data.ndef_data.p_data = (UINT8 *) nfa_mem_co_alloc (p_msg->data.ndef_data.len); 131 132 if (p_msg->data.ndef_data.p_data) 133 { 134 memcpy (p_msg->data.ndef_data.p_data, 135 p_data->ndef_data.p_data, 136 p_msg->data.ndef_data.len); 137 } 138 else 139 { 140 CHO_TRACE_ERROR1 ("Failed nfa_mem_co_alloc () for %d bytes", p_msg->data.ndef_data.len); 141 GKI_freebuf (p_msg); 142 return; 143 } 144 } 145 146 nfa_sys_sendmsg (p_msg); 147 } 148} 149 150/******************************************************************************* 151** 152** Function nfa_cho_proc_ndef_type_handler_evt 153** 154** Description Process events (registration and NDEF data) from NFA NDEF 155** Type Handler 156** 157** Returns tNFA_STATUS 158** 159*******************************************************************************/ 160void nfa_cho_proc_ndef_type_handler_evt (tNFA_CHO_INT_EVENT_DATA *p_evt_data) 161{ 162 tNFA_CHO_MSG_TYPE msg_type; 163 164 if (p_evt_data->ndef_type_hdlr.event == NFA_NDEF_REGISTER_EVT) 165 { 166 if (p_evt_data->ndef_type_hdlr.data.ndef_reg.status == NFA_STATUS_OK) 167 { 168 /* store handle for deregistration */ 169 if (nfa_cho_cb.hs_ndef_type_handle == NFA_HANDLE_INVALID) 170 { 171 nfa_cho_cb.hs_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle; 172 } 173 else if (nfa_cho_cb.bt_ndef_type_handle == NFA_HANDLE_INVALID) 174 { 175 nfa_cho_cb.bt_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle; 176 } 177 else if (nfa_cho_cb.wifi_ndef_type_handle == NFA_HANDLE_INVALID) 178 { 179 nfa_cho_cb.wifi_ndef_type_handle = p_evt_data->ndef_type_hdlr.data.ndef_reg.ndef_type_handle; 180 } 181 } 182 } 183 else if (p_evt_data->ndef_type_hdlr.event == NFA_NDEF_DATA_EVT) 184 { 185 /* if negotiated handover is on going, then ignore static handover */ 186 if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED) 187 { 188#if (BT_TRACE_PROTOCOL == TRUE) 189 DispNDEFMsg (p_evt_data->ndef_type_hdlr.data.ndef_data.p_data, 190 p_evt_data->ndef_type_hdlr.data.ndef_data.len, TRUE); 191#endif 192 msg_type = nfa_cho_get_msg_type (p_evt_data->ndef_type_hdlr.data.ndef_data.len, 193 p_evt_data->ndef_type_hdlr.data.ndef_data.p_data); 194 195 if (msg_type == NFA_CHO_MSG_HS) 196 { 197 nfa_cho_proc_hs (p_evt_data->ndef_type_hdlr.data.ndef_data.len, 198 p_evt_data->ndef_type_hdlr.data.ndef_data.p_data); 199 } 200 else if ( (msg_type == NFA_CHO_MSG_BT_OOB) 201 ||(msg_type == NFA_CHO_MSG_WIFI) ) 202 { 203 /* simplified BT OOB/Wifi Message */ 204 nfa_cho_proc_simplified_format (p_evt_data->ndef_type_hdlr.data.ndef_data.len, 205 p_evt_data->ndef_type_hdlr.data.ndef_data.p_data); 206 } 207 else 208 { 209 CHO_TRACE_ERROR0 ("Unexpected CHO Message Type"); 210 } 211 } 212 213 nfa_mem_co_free (p_evt_data->ndef_type_hdlr.data.ndef_data.p_data); 214 } 215} 216 217/******************************************************************************* 218** 219** Function nfa_cho_proc_api_reg 220** 221** Description Process registeration request from application 222** Register Handover server on LLCP for negotiated handover 223** Register handover select records on NDEF handler for static handover 224** 225** Returns tNFA_STATUS 226** 227*******************************************************************************/ 228tNFA_STATUS nfa_cho_proc_api_reg (tNFA_CHO_INT_EVENT_DATA *p_evt_data) 229{ 230 CHO_TRACE_DEBUG1 ("nfa_cho_proc_api_reg (): enable_server=%d", 231 p_evt_data->api_reg.enable_server); 232 233 if (p_evt_data->api_reg.enable_server == TRUE) 234 { 235 /* Register Handover server on LLCP for negotiated handover */ 236 nfa_cho_cb.server_sap = LLCP_RegisterServer (LLCP_INVALID_SAP, 237 LLCP_LINK_TYPE_DATA_LINK_CONNECTION, 238 p_cho_service_name, 239 nfa_cho_sm_llcp_cback); 240 if (nfa_cho_cb.server_sap == LLCP_INVALID_SAP) 241 { 242 CHO_TRACE_ERROR0 ("Cannot register CHO server"); 243 return NFA_STATUS_FAILED; 244 } 245 else 246 { 247 nfa_p2p_enable_listening (NFA_ID_CHO, FALSE); 248 } 249 } 250 else 251 { 252 /* 253 ** Register Handover client on LLCP for negotiated handover 254 ** LLCP will notify link status through callback 255 */ 256 nfa_cho_cb.client_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION, 257 nfa_cho_sm_llcp_cback); 258 259 if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP) 260 { 261 CHO_TRACE_ERROR0 ("Cannot register CHO client"); 262 return NFA_STATUS_FAILED; 263 } 264 265 /* set flag not to deregister client when disconnected */ 266 nfa_cho_cb.flags |= NFA_CHO_FLAGS_CLIENT_ONLY; 267 } 268 269 /* Register handover select record on NDEF handler for static handover */ 270 if (nfa_cho_cb.hs_ndef_type_handle == NFA_HANDLE_INVALID) 271 { 272 NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN, 273 nfa_cho_ndef_cback); 274 } 275 if (nfa_cho_cb.bt_ndef_type_handle == NFA_HANDLE_INVALID) 276 { 277 NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_RFC2046_MEDIA, 278 p_bt_oob_rec_type, (UINT8) strlen ((char *) p_bt_oob_rec_type), 279 nfa_cho_ndef_cback); 280 } 281 if (nfa_cho_cb.wifi_ndef_type_handle == NFA_HANDLE_INVALID) 282 { 283 NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_RFC2046_MEDIA, 284 p_wifi_rec_type, (UINT8) strlen ((char *) p_wifi_rec_type), 285 nfa_cho_ndef_cback); 286 } 287 288 nfa_cho_cb.p_cback = p_evt_data->api_reg.p_cback; 289 290 return NFA_STATUS_OK; 291} 292 293/******************************************************************************* 294** 295** Function nfa_cho_proc_api_dereg 296** 297** Description Process deregisteration request from application 298** Disconnect LLCP connection if any 299** Deregister callback from NDEF handler and NFA P2P 300** 301** Returns None 302** 303*******************************************************************************/ 304void nfa_cho_proc_api_dereg (void) 305{ 306 CHO_TRACE_DEBUG0 ("nfa_cho_proc_api_dereg ()"); 307 308 /* Deregister outgoing connection, data link will be disconnected if any */ 309 if (nfa_cho_cb.client_sap != LLCP_INVALID_SAP) 310 { 311 LLCP_Deregister (nfa_cho_cb.client_sap); 312 nfa_cho_cb.client_sap = LLCP_INVALID_SAP; 313 } 314 315 /* Close Connection Handover server in LLCP, data link will be disconnected if any */ 316 if (nfa_cho_cb.server_sap != LLCP_INVALID_SAP) 317 { 318 LLCP_Deregister (nfa_cho_cb.server_sap); 319 nfa_cho_cb.server_sap = LLCP_INVALID_SAP; 320 } 321 322 /* Deregister type handler if any */ 323 if (nfa_cho_cb.hs_ndef_type_handle != NFA_HANDLE_INVALID) 324 { 325 NFA_DeregisterNDefTypeHandler (nfa_cho_cb.hs_ndef_type_handle); 326 nfa_cho_cb.hs_ndef_type_handle = NFA_HANDLE_INVALID; 327 } 328 329 if (nfa_cho_cb.bt_ndef_type_handle != NFA_HANDLE_INVALID) 330 { 331 NFA_DeregisterNDefTypeHandler (nfa_cho_cb.bt_ndef_type_handle); 332 nfa_cho_cb.bt_ndef_type_handle = NFA_HANDLE_INVALID; 333 } 334 335 if (nfa_cho_cb.wifi_ndef_type_handle != NFA_HANDLE_INVALID) 336 { 337 NFA_DeregisterNDefTypeHandler (nfa_cho_cb.wifi_ndef_type_handle); 338 nfa_cho_cb.wifi_ndef_type_handle = NFA_HANDLE_INVALID; 339 } 340 341 nfa_sys_stop_timer (&nfa_cho_cb.timer); 342 nfa_cho_cb.p_cback = NULL; 343 nfa_cho_cb.flags = 0; 344 345 nfa_p2p_disable_listening (NFA_ID_CHO, FALSE); 346} 347 348/******************************************************************************* 349** 350** Function nfa_cho_create_connection 351** 352** Description Create data link connection with handover server in remote 353** 354** 355** Returns None 356** 357*******************************************************************************/ 358tNFA_STATUS nfa_cho_create_connection (void) 359{ 360 tLLCP_CONNECTION_PARAMS conn_params; 361 tNFA_STATUS status = NFA_STATUS_FAILED; 362 363 CHO_TRACE_DEBUG0 ("nfa_cho_create_connection ()"); 364 365 if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP) 366 { 367 nfa_cho_cb.client_sap = LLCP_RegisterClient (LLCP_LINK_TYPE_DATA_LINK_CONNECTION, 368 nfa_cho_sm_llcp_cback); 369 } 370 371 if (nfa_cho_cb.client_sap == LLCP_INVALID_SAP) 372 { 373 CHO_TRACE_ERROR0 ("Cannot register CHO client"); 374 } 375 else 376 { 377 /* create data link connection with server name */ 378 conn_params.miu = (UINT16) (nfa_cho_cb.local_link_miu >= NFA_CHO_MIU ? NFA_CHO_MIU : nfa_cho_cb.local_link_miu); 379 conn_params.rw = NFA_CHO_RW; 380 BCM_STRNCPY_S (conn_params.sn, sizeof (conn_params.sn), 381 p_cho_service_name, LLCP_MAX_SN_LEN); 382 conn_params.sn[LLCP_MAX_SN_LEN] = 0; 383 384 if (LLCP_ConnectReq (nfa_cho_cb.client_sap, LLCP_SAP_SDP, &conn_params) == LLCP_STATUS_SUCCESS) 385 status = NFA_STATUS_OK; 386 } 387 388 return status; 389} 390 391/******************************************************************************* 392** 393** Function nfa_cho_process_disconnection 394** 395** Description Clean up buffers and notify disconnection to application 396** 397** 398** Returns None 399** 400*******************************************************************************/ 401void nfa_cho_process_disconnection (tNFA_CHO_DISC_REASON disc_reason) 402{ 403 tNFA_CHO_EVT_DATA evt_data; 404 405 nfa_sys_stop_timer (&nfa_cho_cb.timer); 406 407 /* free buffer for Tx/Rx NDEF message */ 408 if (nfa_cho_cb.p_tx_ndef_msg) 409 { 410 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 411 nfa_cho_cb.p_tx_ndef_msg = NULL; 412 } 413 if (nfa_cho_cb.p_rx_ndef_msg) 414 { 415 GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg); 416 nfa_cho_cb.p_rx_ndef_msg = NULL; 417 } 418 419 /* if no server is registered on LLCP, do not deregister client to get link statue from LLCP */ 420 if (!(nfa_cho_cb.flags & NFA_CHO_FLAGS_CLIENT_ONLY)) 421 { 422 if (nfa_cho_cb.client_sap != LLCP_INVALID_SAP) 423 { 424 LLCP_Deregister (nfa_cho_cb.client_sap); 425 nfa_cho_cb.client_sap = LLCP_INVALID_SAP; 426 } 427 } 428 429 nfa_cho_cb.flags &= ~NFA_CHO_FLAGS_CONN_COLLISION; 430 431 evt_data.disconnected.reason = disc_reason; 432 nfa_cho_cb.p_cback (NFA_CHO_DISCONNECTED_EVT, &evt_data); 433} 434 435/******************************************************************************* 436** 437** Function nfa_cho_notify_tx_fail_evt 438** 439** Description Notify application of NFA_CHO_TX_FAIL_EVT 440** 441** 442** Returns None 443** 444*******************************************************************************/ 445void nfa_cho_notify_tx_fail_evt (tNFA_STATUS status) 446{ 447 tNFA_CHO_EVT_DATA evt_data; 448 449 CHO_TRACE_DEBUG0 ("nfa_cho_notify_tx_fail_evt ()"); 450 451 evt_data.status = status; 452 453 if (nfa_cho_cb.p_cback) 454 nfa_cho_cb.p_cback (NFA_CHO_TX_FAIL_EVT, &evt_data); 455} 456 457/******************************************************************************* 458** 459** Function nfa_cho_reassemble_ho_msg 460** 461** Description Reassemble received data for handover message 462** 463** 464** Returns tNFA_CHO_RX_NDEF_STATUS 465** 466*******************************************************************************/ 467tNFA_CHO_RX_NDEF_STATUS nfa_cho_reassemble_ho_msg (UINT8 local_sap, UINT8 remote_sap) 468{ 469 tNFA_CHO_RX_NDEF_STATUS rx_status; 470 471 nfa_sys_stop_timer (&nfa_cho_cb.timer); 472 473 /* 474 ** allocate memory for NDEF message for the first segment 475 ** validate NDEF message to check if received complete message 476 */ 477 rx_status = nfa_cho_read_ndef_msg (local_sap, remote_sap); 478 479 /* if Temporary Memory Constraint */ 480 if (rx_status == NFA_CHO_RX_NDEF_TEMP_MEM) 481 { 482 CHO_TRACE_ERROR0 ("Failed due to Temporary Memory Constraint"); 483 484 /* if we are expecting Hr then send Hs Error record */ 485 if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR) 486 { 487 /* ask retry later, handover request will disconnect */ 488 nfa_cho_send_hs_error (NFA_CHO_ERROR_TEMP_MEM, NFA_CHO_TIMEOUT_FOR_RETRY); 489 } 490 else 491 { 492 /* we cannot send error record, so disconnect */ 493 nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INTERNAL_ERROR; 494 LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE); 495 } 496 } 497 /* Permanent Memory Constraint */ 498 else if (rx_status == NFA_CHO_RX_NDEF_PERM_MEM) 499 { 500 CHO_TRACE_ERROR0 ("Failed due to Permanent Memory Constraint"); 501 502 /* if we are expecting Hr then send Hs Error record */ 503 if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR) 504 { 505 /* 506 ** notify our buffer size and ask retry with modified message later 507 ** handover request will disconnect 508 */ 509 nfa_cho_send_hs_error (NFA_CHO_ERROR_PERM_MEM, nfa_cho_cb.rx_ndef_buf_size); 510 } 511 else 512 { 513 /* we cannot send error record, so disconnect */ 514 nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INTERNAL_ERROR; 515 LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE); 516 } 517 } 518 /* Invalid NDEF message */ 519 else if (rx_status == NFA_CHO_RX_NDEF_INVALID) 520 { 521 CHO_TRACE_ERROR0 ("Failed due to invalid NDEF message"); 522 523 if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR) 524 { 525 /* let Handover Requester got timeout */ 526 } 527 else 528 { 529 /* we cannot send error record, so disconnect */ 530 nfa_cho_cb.disc_reason = NFA_CHO_DISC_REASON_INVALID_MSG; 531 LLCP_DisconnectReq (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, FALSE); 532 } 533 } 534 /* need more segment */ 535 else if (rx_status == NFA_CHO_RX_NDEF_INCOMPLTE) 536 { 537 /* wait for next segment */ 538 if (nfa_cho_cb.substate == NFA_CHO_SUBSTATE_W4_REMOTE_HR) 539 { 540 nfa_sys_start_timer (&nfa_cho_cb.timer, 0, NFA_CHO_TIMEOUT_SEGMENTED_HR); 541 } 542 /* don't update running timer if we are waiting Hs */ 543 } 544 else /* NFA_CHO_RX_NDEF_COMPLETE */ 545 { 546 /* Received complete NDEF message */ 547 } 548 549 return rx_status; 550} 551 552/******************************************************************************* 553** 554** Function nfa_cho_send_handover_msg 555** 556** Description Send segmented or whole Handover Message on LLCP 557** if congested then wait for uncongested event from LLCP 558** 559** Returns tNFA_STATUS 560** 561*******************************************************************************/ 562tNFA_STATUS nfa_cho_send_handover_msg (void) 563{ 564 tNFA_STATUS status = NFA_STATUS_FAILED; 565 tLLCP_STATUS llcp_status; 566 UINT16 tx_size; 567 BT_HDR *p_msg; 568 UINT8 *p_src, *p_dst; 569 570 CHO_TRACE_DEBUG2 ("nfa_cho_send_handover_msg () size=%d, sent=%d", 571 nfa_cho_cb.tx_ndef_cur_size, nfa_cho_cb.tx_ndef_sent_size); 572 573 /* while data link connection is not congested */ 574 while ((!nfa_cho_cb.congested) && (nfa_cho_cb.tx_ndef_sent_size < nfa_cho_cb.tx_ndef_cur_size)) 575 { 576 /* select segment size as min (MIU of remote, remaining NDEF size) */ 577 if (nfa_cho_cb.tx_ndef_cur_size - nfa_cho_cb.tx_ndef_sent_size > nfa_cho_cb.remote_miu) 578 { 579 tx_size = nfa_cho_cb.remote_miu; 580 } 581 else 582 { 583 tx_size = (UINT16) (nfa_cho_cb.tx_ndef_cur_size - nfa_cho_cb.tx_ndef_sent_size); 584 } 585 586 /* transmit a segment on LLCP */ 587 if ((p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID)) != NULL) 588 { 589 p_msg->len = (UINT16) tx_size; 590 p_msg->offset = LLCP_MIN_OFFSET; 591 592 p_dst = (UINT8*) (p_msg + 1) + p_msg->offset; 593 p_src = nfa_cho_cb.p_tx_ndef_msg + nfa_cho_cb.tx_ndef_sent_size; 594 595 memcpy (p_dst, p_src, tx_size); 596 597 llcp_status = LLCP_SendData (nfa_cho_cb.local_sap, nfa_cho_cb.remote_sap, p_msg); 598 599 nfa_cho_cb.tx_ndef_sent_size += tx_size; 600 } 601 else 602 { 603 llcp_status = LLCP_STATUS_FAIL; 604 } 605 606 if (llcp_status == LLCP_STATUS_SUCCESS) 607 { 608 status = NFA_STATUS_OK; 609 } 610 else if (llcp_status == LLCP_STATUS_CONGESTED) 611 { 612 status = NFA_STATUS_CONGESTED; 613 CHO_TRACE_DEBUG0 ("Data link connection is congested"); 614 /* wait for uncongested event */ 615 nfa_cho_cb.congested = TRUE; 616 break; 617 } 618 else 619 { 620 status = NFA_STATUS_FAILED; 621 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 622 nfa_cho_cb.p_tx_ndef_msg = NULL; 623 break; 624 } 625 } 626 627 /* 628 ** free buffer when receiving response or disconnected because we may need to send 629 ** Hr message again due to collision 630 */ 631 632 return status; 633} 634 635/******************************************************************************* 636** 637** Function nfa_cho_read_ndef_msg 638** 639** Description allocate memory for NDEF message for the first segment 640** validate NDEF message to check if received complete message 641** 642** Returns None 643** 644*******************************************************************************/ 645tNFA_CHO_RX_NDEF_STATUS nfa_cho_read_ndef_msg (UINT8 local_sap, UINT8 remote_sap) 646{ 647 tNDEF_STATUS ndef_status; 648 tNFA_CHO_RX_NDEF_STATUS rx_status; 649 BOOLEAN more; 650 UINT32 length; 651 652 CHO_TRACE_DEBUG2 ("nfa_cho_read_ndef_msg () local_sap=0x%x, remote_sap=0x%x", 653 local_sap, remote_sap); 654 655 /* if this is the first segment */ 656 if (!nfa_cho_cb.p_rx_ndef_msg) 657 { 658 nfa_cho_cb.p_rx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 659 660 if (!nfa_cho_cb.p_rx_ndef_msg) 661 { 662 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 663 return NFA_CHO_RX_NDEF_TEMP_MEM; 664 } 665 666 nfa_cho_cb.rx_ndef_buf_size = LLCP_POOL_BUF_SIZE; 667 nfa_cho_cb.rx_ndef_cur_size = 0; 668 } 669 670 more = TRUE; 671 while (more) 672 { 673 more = LLCP_ReadDataLinkData (local_sap, 674 remote_sap, 675 (UINT16)(nfa_cho_cb.rx_ndef_buf_size - nfa_cho_cb.rx_ndef_cur_size), 676 &length, 677 nfa_cho_cb.p_rx_ndef_msg + nfa_cho_cb.rx_ndef_cur_size); 678 679 nfa_cho_cb.rx_ndef_cur_size += length; 680 681 /* if it doesn't fit into allocated memory */ 682 if ((nfa_cho_cb.rx_ndef_cur_size >= nfa_cho_cb.rx_ndef_buf_size) 683 &&(more)) 684 { 685 CHO_TRACE_ERROR0 ("Failed to store too much data"); 686 687 LLCP_FlushDataLinkRxData (local_sap, remote_sap); 688 689 GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg); 690 nfa_cho_cb.p_rx_ndef_msg = NULL; 691 692 return NFA_CHO_RX_NDEF_PERM_MEM; 693 } 694 } 695 696 /* check NDEF message */ 697 ndef_status = NDEF_MsgValidate (nfa_cho_cb.p_rx_ndef_msg, nfa_cho_cb.rx_ndef_cur_size, FALSE); 698 699 switch (ndef_status) 700 { 701 case NDEF_OK: 702 rx_status = NFA_CHO_RX_NDEF_COMPLETE; 703 break; 704 705 case NDEF_MSG_TOO_SHORT: 706 case NDEF_MSG_NO_MSG_END: 707 case NDEF_MSG_LENGTH_MISMATCH: 708 rx_status = NFA_CHO_RX_NDEF_INCOMPLTE; 709 break; 710 711 default: 712 rx_status = NFA_CHO_RX_NDEF_INVALID; 713 break; 714 } 715 716 if (rx_status == NFA_CHO_RX_NDEF_COMPLETE) 717 { 718#if (BT_TRACE_PROTOCOL == TRUE) 719 DispCHO (nfa_cho_cb.p_rx_ndef_msg, nfa_cho_cb.rx_ndef_cur_size, TRUE); 720#endif 721 } 722 else if (rx_status == NFA_CHO_RX_NDEF_INCOMPLTE) 723 { 724 CHO_TRACE_DEBUG0 ("Need more data to complete NDEF message"); 725 } 726 else /* if (rx_status == NFA_CHO_RX_NDEF_INVALID) */ 727 { 728 CHO_TRACE_ERROR1 ("Failed to validate NDEF message error=0x%x", ndef_status); 729 GKI_freebuf (nfa_cho_cb.p_rx_ndef_msg); 730 nfa_cho_cb.p_rx_ndef_msg = NULL; 731 } 732 733 return rx_status; 734} 735 736/******************************************************************************* 737** 738** Function nfa_cho_add_cr_record 739** 740** Description Adding Collision Resolution record 741** 742** 743** Returns NDEF_OK if success 744** 745*******************************************************************************/ 746tNDEF_STATUS nfa_cho_add_cr_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size) 747{ 748 tNDEF_STATUS status; 749 UINT32 temp32; 750 751 CHO_TRACE_DEBUG1 ("nfa_cho_add_cr_record () cur_size = %d", *p_cur_size); 752 753 /* Get random number from timer */ 754 temp32 = GKI_get_tick_count (); 755 nfa_cho_cb.tx_random_number = (UINT16) ((temp32 >> 16) ^ (temp32)); 756 757#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 758 if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_RANDOM) 759 { 760 nfa_cho_cb.tx_random_number = nfa_cho_cb.test_random_number; 761 } 762#endif 763 764 CHO_TRACE_DEBUG1 ("tx_random_number = 0x%04x", nfa_cho_cb.tx_random_number); 765 766 /* Add Well-Known Type:Collistion Resolution Record */ 767 status = NDEF_MsgAddWktCr (p_msg, max_size, p_cur_size, 768 nfa_cho_cb.tx_random_number); 769 770 return status; 771} 772 773/******************************************************************************* 774** 775** Function nfa_cho_add_ac_record 776** 777** Description Adding Alternative Carrier record 778** 779** 780** Returns NDEF_OK if success 781** 782*******************************************************************************/ 783tNDEF_STATUS nfa_cho_add_ac_record (UINT8 *p_msg, UINT32 max_size, UINT32 *p_cur_size, 784 UINT8 num_ac_info, tNFA_CHO_AC_INFO *p_ac_info, 785 UINT8 *p_ndef, UINT32 max_ndef_size, UINT32 *p_cur_ndef_size) 786{ 787 tNDEF_STATUS status = NDEF_OK; 788 UINT8 xx, yy; 789 UINT8 *p_rec, *p_id, id_len; 790 char carrier_data_ref_str[NFA_CHO_MAX_REF_NAME_LEN]; 791 char *aux_data_ref[NFA_CHO_MAX_AUX_DATA_COUNT]; 792 char aux_data_ref_str[NFA_CHO_MAX_AUX_DATA_COUNT][NFA_CHO_MAX_REF_NAME_LEN]; 793 794 CHO_TRACE_DEBUG1 ("nfa_cho_add_ac_record (): num_ac_info = %d", num_ac_info); 795 796 /* initialize auxilary data reference */ 797 for (xx = 0; xx < NFA_CHO_MAX_AUX_DATA_COUNT; xx++) 798 { 799 aux_data_ref[xx] = aux_data_ref_str[xx]; 800 } 801 802 p_rec = p_ndef; 803 804 /* Alternative Carrier Records */ 805 for (xx = 0; (xx < num_ac_info) && (status == NDEF_OK); xx++) 806 { 807 if (!p_rec) 808 { 809 status = NDEF_REC_NOT_FOUND; 810 break; 811 } 812 813 p_id = NDEF_RecGetId (p_rec, &id_len); 814 815 if ((p_id) && (id_len > 0) && (id_len <= NFA_CHO_MAX_REF_NAME_LEN)) 816 { 817 memcpy (carrier_data_ref_str, p_id, id_len); 818 carrier_data_ref_str[id_len] = 0x00; 819 } 820 else 821 { 822 CHO_TRACE_ERROR1 ("nfa_cho_add_ac_record ():id_len=%d", id_len); 823 status = NDEF_REC_NOT_FOUND; 824 break; 825 } 826 827 p_rec = NDEF_MsgGetNextRec (p_rec); 828 829 /* auxilary data reference */ 830 for (yy = 0; yy < p_ac_info[xx].num_aux_data; yy++) 831 { 832 if (!p_rec) 833 { 834 status = NDEF_REC_NOT_FOUND; 835 break; 836 } 837 838 p_id = NDEF_RecGetId (p_rec, &id_len); 839 840 if ((p_id) && (id_len > 0) && (id_len <= NFA_CHO_MAX_REF_NAME_LEN)) 841 { 842 memcpy (aux_data_ref_str[yy], p_id, id_len); 843 aux_data_ref_str[yy][id_len] = 0x00; 844 } 845 else 846 { 847 CHO_TRACE_ERROR1 ("nfa_cho_add_ac_record ():id_len=%d", id_len); 848 status = NDEF_REC_NOT_FOUND; 849 break; 850 } 851 852 p_rec = NDEF_MsgGetNextRec (p_rec); 853 } 854 855 if (status == NDEF_OK) 856 { 857 /* Add Well-Known Type:Alternative Carrier Record */ 858 status = NDEF_MsgAddWktAc (p_msg, max_size, p_cur_size, 859 p_ac_info[xx].cps, carrier_data_ref_str, 860 p_ac_info[xx].num_aux_data, aux_data_ref); 861 } 862 863 if (status != NDEF_OK) 864 { 865 break; 866 } 867 } 868 869 return status; 870} 871 872/******************************************************************************* 873** 874** Function nfa_cho_send_hr 875** 876** Description Sending Handover Request Message 877** It may send one from AC list to select a specific AC. 878** 879** Returns NFA_STATUS_OK if success 880** 881*******************************************************************************/ 882tNFA_STATUS nfa_cho_send_hr (tNFA_CHO_API_SEND_HR *p_api_send_hr) 883{ 884 tNDEF_STATUS status; 885 UINT8 *p_msg_cr_ac; 886 UINT32 cur_size_cr_ac, max_size; 887 UINT8 version; 888 889 CHO_TRACE_DEBUG0 ("nfa_cho_send_hr ()"); 890 891 /* Collistion Resolution Record and Alternative Carrier Records */ 892 893 p_msg_cr_ac = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 894 if (!p_msg_cr_ac) 895 { 896 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 897 return NFA_STATUS_NO_BUFFERS; 898 } 899 900 max_size = LLCP_POOL_BUF_SIZE; 901 NDEF_MsgInit (p_msg_cr_ac, max_size, &cur_size_cr_ac); 902 903 /* Collistion Resolution Record */ 904 if (NDEF_OK != nfa_cho_add_cr_record (p_msg_cr_ac, max_size, &cur_size_cr_ac)) 905 { 906 CHO_TRACE_ERROR0 ("Failed to add cr record"); 907 GKI_freebuf (p_msg_cr_ac); 908 return NFA_STATUS_FAILED; 909 } 910 911 /* Alternative Carrier Records */ 912 if (NDEF_OK != nfa_cho_add_ac_record (p_msg_cr_ac, max_size, &cur_size_cr_ac, 913 p_api_send_hr->num_ac_info, p_api_send_hr->p_ac_info, 914 p_api_send_hr->p_ndef, p_api_send_hr->max_ndef_size, 915 &(p_api_send_hr->cur_ndef_size))) 916 { 917 CHO_TRACE_ERROR0 ("Failed to add ac record"); 918 GKI_freebuf (p_msg_cr_ac); 919 return NFA_STATUS_FAILED; 920 } 921 922 /* Handover Request Message */ 923 924 nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 925 if (!nfa_cho_cb.p_tx_ndef_msg) 926 { 927 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 928 GKI_freebuf (p_msg_cr_ac); 929 return NFA_STATUS_FAILED; 930 } 931 932 max_size = LLCP_POOL_BUF_SIZE; 933 934 /* Handover Request Record */ 935 version = NFA_CHO_VERSION; 936 937#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 938 if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION) 939 { 940 version = nfa_cho_cb.test_version; 941 } 942#endif 943 944 status = NDEF_MsgCreateWktHr (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 945 version); 946 if (status != NDEF_OK) 947 { 948 CHO_TRACE_ERROR0 ("Failed to create Hr"); 949 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 950 nfa_cho_cb.p_tx_ndef_msg = NULL; 951 GKI_freebuf (p_msg_cr_ac); 952 return NFA_STATUS_FAILED; 953 } 954 955 /* Append Collistion Resolution Record and Alternative Carrier Records */ 956 status = NDEF_MsgAppendPayload (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 957 nfa_cho_cb.p_tx_ndef_msg, p_msg_cr_ac, cur_size_cr_ac); 958 959 GKI_freebuf (p_msg_cr_ac); 960 961 if (status != NDEF_OK) 962 { 963 CHO_TRACE_ERROR0 ("Failed to add cr/ac record"); 964 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 965 nfa_cho_cb.p_tx_ndef_msg = NULL; 966 return NFA_STATUS_FAILED; 967 } 968 969 970 /* Append Alternative Carrier Reference Data or Handover Carrier Record */ 971 status = NDEF_MsgAppendRec (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 972 p_api_send_hr->p_ndef, p_api_send_hr->cur_ndef_size); 973 974 if (status != NDEF_OK) 975 { 976 CHO_TRACE_ERROR0 ("Failed to add ac reference data or Hc record"); 977 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 978 nfa_cho_cb.p_tx_ndef_msg = NULL; 979 return NFA_STATUS_FAILED; 980 } 981 982#if (BT_TRACE_PROTOCOL == TRUE) 983 DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE); 984#endif 985 986 /* Send it to peer */ 987 nfa_cho_cb.tx_ndef_sent_size = 0; 988 989 status = nfa_cho_send_handover_msg (); 990 991 if (status == NFA_STATUS_CONGESTED) 992 { 993 status = NFA_STATUS_OK; 994 } 995 996 return status; 997} 998 999/******************************************************************************* 1000** 1001** Function nfa_cho_send_hs 1002** 1003** Description Send Handover Select Message 1004** 1005** 1006** Returns NFA_STATUS_OK if success 1007** 1008*******************************************************************************/ 1009tNFA_STATUS nfa_cho_send_hs (tNFA_CHO_API_SEND_HS *p_api_select) 1010{ 1011 tNDEF_STATUS status; 1012 UINT8 *p_msg_ac; 1013 UINT32 cur_size_ac = 0, max_size; 1014 UINT8 version; 1015 1016 CHO_TRACE_DEBUG1 ("nfa_cho_send_hs () num_ac_info=%d", p_api_select->num_ac_info); 1017 1018 if (p_api_select->num_ac_info > 0) 1019 { 1020 /* Alternative Carrier Records */ 1021 1022 p_msg_ac = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 1023 1024 if (!p_msg_ac) 1025 { 1026 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 1027 return NFA_STATUS_FAILED; 1028 } 1029 1030 max_size = LLCP_POOL_BUF_SIZE; 1031 NDEF_MsgInit (p_msg_ac, max_size, &cur_size_ac); 1032 1033 if (NDEF_OK != nfa_cho_add_ac_record (p_msg_ac, max_size, &cur_size_ac, 1034 p_api_select->num_ac_info, p_api_select->p_ac_info, 1035 p_api_select->p_ndef, p_api_select->max_ndef_size, 1036 &(p_api_select->cur_ndef_size))) 1037 { 1038 CHO_TRACE_ERROR0 ("Failed to add ac record"); 1039 GKI_freebuf (p_msg_ac); 1040 return NFA_STATUS_FAILED; 1041 } 1042 } 1043 else 1044 { 1045 p_msg_ac = NULL; 1046 } 1047 1048 /* Handover Select Message */ 1049 nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 1050 1051 if (!nfa_cho_cb.p_tx_ndef_msg) 1052 { 1053 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 1054 1055 if (p_msg_ac) 1056 GKI_freebuf (p_msg_ac); 1057 1058 return NFA_STATUS_FAILED; 1059 } 1060 max_size = LLCP_POOL_BUF_SIZE; 1061 1062 /* Handover Select Record */ 1063 version = NFA_CHO_VERSION; 1064 1065#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 1066 if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION) 1067 { 1068 version = nfa_cho_cb.test_version; 1069 } 1070#endif 1071 status = NDEF_MsgCreateWktHs (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 1072 version); 1073 1074 if (status != NDEF_OK) 1075 { 1076 CHO_TRACE_ERROR0 ("Failed to create Hs"); 1077 1078 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 1079 nfa_cho_cb.p_tx_ndef_msg = NULL; 1080 1081 if (p_msg_ac) 1082 GKI_freebuf (p_msg_ac); 1083 1084 return NFA_STATUS_FAILED; 1085 } 1086 1087 if (p_api_select->num_ac_info > 0) 1088 { 1089 /* Append Alternative Carrier Records */ 1090 status = NDEF_MsgAppendPayload (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 1091 nfa_cho_cb.p_tx_ndef_msg, p_msg_ac, cur_size_ac); 1092 1093 if (p_msg_ac) 1094 GKI_freebuf (p_msg_ac); 1095 1096 if (status != NDEF_OK) 1097 { 1098 CHO_TRACE_ERROR0 ("Failed to add cr record"); 1099 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 1100 nfa_cho_cb.p_tx_ndef_msg = NULL; 1101 return NFA_STATUS_FAILED; 1102 } 1103 1104 /* Append Alternative Carrier Reference Data */ 1105 status = NDEF_MsgAppendRec (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 1106 p_api_select->p_ndef, p_api_select->cur_ndef_size); 1107 1108 if (status != NDEF_OK) 1109 { 1110 CHO_TRACE_ERROR0 ("Failed to add ac reference data record"); 1111 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 1112 nfa_cho_cb.p_tx_ndef_msg = NULL; 1113 return NFA_STATUS_FAILED; 1114 } 1115 } 1116 1117#if (BT_TRACE_PROTOCOL == TRUE) 1118 DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE); 1119#endif 1120 1121 /* Send it to peer */ 1122 nfa_cho_cb.tx_ndef_sent_size = 0; 1123 1124 status = nfa_cho_send_handover_msg (); 1125 1126 if (status == NFA_STATUS_CONGESTED) 1127 { 1128 status = NFA_STATUS_OK; 1129 } 1130 return status; 1131} 1132 1133/******************************************************************************* 1134** 1135** Function nfa_cho_send_hs_error 1136** 1137** Description Sending Handover Select Message with error record 1138** 1139** 1140** Returns NFA_STATUS_OK if success 1141** 1142*******************************************************************************/ 1143tNFA_STATUS nfa_cho_send_hs_error (UINT8 error_reason, UINT32 error_data) 1144{ 1145 tNDEF_STATUS status; 1146 UINT8 version; 1147 UINT32 max_size; 1148 1149 CHO_TRACE_DEBUG2 ("nfa_cho_send_hs_error () error_reason=0x%x, error_data=0x%x", 1150 error_reason, error_data); 1151 1152 /* Handover Select Message */ 1153 nfa_cho_cb.p_tx_ndef_msg = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 1154 1155 if (!nfa_cho_cb.p_tx_ndef_msg) 1156 { 1157 CHO_TRACE_ERROR0 ("Failed to allocate buffer"); 1158 return NFA_STATUS_FAILED; 1159 } 1160 1161 max_size = LLCP_POOL_BUF_SIZE; 1162 1163 /* Handover Select Record with Version */ 1164 version = NFA_CHO_VERSION; 1165 1166#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 1167 if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_VERSION) 1168 { 1169 version = nfa_cho_cb.test_version; 1170 } 1171#endif 1172 status = NDEF_MsgCreateWktHs (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 1173 version); 1174 1175 if (status != NDEF_OK) 1176 { 1177 CHO_TRACE_ERROR0 ("Failed to create Hs"); 1178 1179 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 1180 nfa_cho_cb.p_tx_ndef_msg = NULL; 1181 1182 return NFA_STATUS_FAILED; 1183 } 1184 1185 /* Add Error Records */ 1186 status = NDEF_MsgAddWktErr (nfa_cho_cb.p_tx_ndef_msg, max_size, &nfa_cho_cb.tx_ndef_cur_size, 1187 error_reason, error_data); 1188 1189 if (status != NDEF_OK) 1190 { 1191 CHO_TRACE_ERROR0 ("Failed to add err record"); 1192 1193 GKI_freebuf (nfa_cho_cb.p_tx_ndef_msg); 1194 nfa_cho_cb.p_tx_ndef_msg = NULL; 1195 1196 return NFA_STATUS_FAILED; 1197 } 1198 1199#if (BT_TRACE_PROTOCOL == TRUE) 1200 DispCHO (nfa_cho_cb.p_tx_ndef_msg, nfa_cho_cb.tx_ndef_cur_size, FALSE); 1201#endif 1202 1203 /* Send it to peer */ 1204 nfa_cho_cb.tx_ndef_sent_size = 0; 1205 1206 status = nfa_cho_send_handover_msg (); 1207 1208 if (status == NFA_STATUS_CONGESTED) 1209 { 1210 status = NFA_STATUS_OK; 1211 } 1212 return status; 1213} 1214 1215/******************************************************************************* 1216** 1217** Function nfa_cho_get_random_number 1218** 1219** Description Return random number in Handover Request message 1220** 1221** 1222** Returns random number in "cr" record 1223** 1224*******************************************************************************/ 1225UINT16 nfa_cho_get_random_number (UINT8 *p_ndef_msg) 1226{ 1227 UINT16 random_number; 1228 UINT8 *p_cr_record, *p_cr_payload; 1229 UINT32 cr_payload_len; 1230 1231 CHO_TRACE_DEBUG0 ("nfa_cho_get_random_number ()"); 1232 1233 /* find Collision Resolution record */ 1234 p_cr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN); 1235 1236 if (!p_cr_record) 1237 { 1238 CHO_TRACE_ERROR0 ("Failed to find cr record"); 1239 return 0; 1240 } 1241 1242 /* get start of payload in Collision Resolution record */ 1243 p_cr_payload = NDEF_RecGetPayload (p_cr_record, &cr_payload_len); 1244 1245 if ((!p_cr_payload) || (cr_payload_len != 2)) 1246 { 1247 CHO_TRACE_ERROR0 ("Failed to get cr payload (random number)"); 1248 return 0; 1249 } 1250 1251 /* get random number from payload */ 1252 BE_STREAM_TO_UINT16 (random_number, p_cr_payload); 1253 1254 return random_number; 1255} 1256 1257/******************************************************************************* 1258** 1259** Function nfa_cho_parse_ac_records 1260** 1261** Description Parsing NDEF message to retrieve Alternative Carrier records 1262** and store into tNFA_CHO_AC_REC 1263** 1264** Returns tNFA_STATUS 1265** 1266*******************************************************************************/ 1267tNFA_STATUS nfa_cho_parse_ac_records (UINT8 *p_ndef_msg, UINT8 *p_num_ac_rec, tNFA_CHO_AC_REC *p_ac_rec) 1268{ 1269 UINT8 *p_ac_record, *p_ac_payload; 1270 UINT32 ac_payload_len; 1271 1272 UINT8 xx, yy; 1273 1274 CHO_TRACE_DEBUG0 ("nfa_cho_parse_ac_records ()"); 1275 1276 /* get Alternative Carrier record */ 1277 p_ac_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN); 1278 1279 xx = 0; 1280 1281 while ((p_ac_record) && (xx < NFA_CHO_MAX_AC_INFO)) 1282 { 1283 /* get payload */ 1284 p_ac_payload = NDEF_RecGetPayload (p_ac_record, &ac_payload_len); 1285 1286 if ((!p_ac_payload) || (ac_payload_len < 3)) 1287 { 1288 CHO_TRACE_ERROR0 ("Failed to get ac payload"); 1289 return NFA_STATUS_FAILED; 1290 } 1291 1292 /* Carrier Power State */ 1293 BE_STREAM_TO_UINT8 (p_ac_rec->cps, p_ac_payload); 1294 1295 /* Carrier Data Reference Length and Characters */ 1296 BE_STREAM_TO_UINT8 (p_ac_rec->carrier_data_ref.ref_len, p_ac_payload); 1297 1298 ac_payload_len -= 2; 1299 1300 /* remaining must have carrier data ref and Auxiliary Data Reference Count at least */ 1301 if (ac_payload_len > p_ac_rec->carrier_data_ref.ref_len) 1302 { 1303 if (p_ac_rec->carrier_data_ref.ref_len > NFA_CHO_MAX_REF_NAME_LEN) 1304 { 1305 CHO_TRACE_ERROR1 ("Too many bytes for carrier_data_ref, ref_len = %d", 1306 p_ac_rec->carrier_data_ref.ref_len); 1307 return NFA_STATUS_FAILED; 1308 } 1309 1310 BE_STREAM_TO_ARRAY (p_ac_payload, 1311 p_ac_rec->carrier_data_ref.ref_name, 1312 p_ac_rec->carrier_data_ref.ref_len); 1313 ac_payload_len -= p_ac_rec->carrier_data_ref.ref_len; 1314 } 1315 else 1316 { 1317 CHO_TRACE_ERROR0 ("Failed to parse carrier_data_ref.ref_len"); 1318 return NFA_STATUS_FAILED; 1319 } 1320 1321 /* Auxiliary Data Reference Count */ 1322 BE_STREAM_TO_UINT8 (p_ac_rec->aux_data_ref_count, p_ac_payload); 1323 ac_payload_len--; 1324 1325 /* Auxiliary Data Reference Length and Characters */ 1326 for (yy = 0; (yy < p_ac_rec->aux_data_ref_count) && (yy < NFA_CHO_MAX_AUX_DATA_COUNT); yy++) 1327 { 1328 if (ac_payload_len > 0) 1329 { 1330 BE_STREAM_TO_UINT8 (p_ac_rec->aux_data_ref[yy].ref_len, p_ac_payload); 1331 ac_payload_len--; 1332 1333 if (ac_payload_len >= p_ac_rec->aux_data_ref[yy].ref_len) 1334 { 1335 if (p_ac_rec->aux_data_ref[yy].ref_len > NFA_CHO_MAX_REF_NAME_LEN) 1336 { 1337 CHO_TRACE_ERROR2 ("Too many bytes for aux_data_ref[%d], ref_len=%d", 1338 yy, p_ac_rec->aux_data_ref[yy].ref_len); 1339 return NFA_STATUS_FAILED; 1340 } 1341 1342 BE_STREAM_TO_ARRAY (p_ac_payload, 1343 p_ac_rec->aux_data_ref[yy].ref_name, 1344 p_ac_rec->aux_data_ref[yy].ref_len); 1345 ac_payload_len -= p_ac_rec->aux_data_ref[yy].ref_len; 1346 } 1347 else 1348 { 1349 CHO_TRACE_ERROR1 ("Failed to parse ref_name for aux_data_ref[%d]", yy); 1350 return NFA_STATUS_FAILED; 1351 } 1352 } 1353 else 1354 { 1355 CHO_TRACE_ERROR1 ("Failed to parse ref_len for aux_data_ref[%d]", yy); 1356 return NFA_STATUS_FAILED; 1357 } 1358 } 1359 1360 if (ac_payload_len != 0) 1361 { 1362 CHO_TRACE_WARNING1 ("Found extra data in AC record[%d]", xx); 1363 } 1364 1365 xx++; 1366 p_ac_rec++; 1367 1368 /* get next Alternative Carrier record */ 1369 p_ac_record = NDEF_MsgGetNextRecByType (p_ac_record, NDEF_TNF_WKT, ac_rec_type, AC_REC_TYPE_LEN); 1370 } 1371 1372 *p_num_ac_rec = xx; 1373 1374 return NFA_STATUS_OK; 1375} 1376 1377/******************************************************************************* 1378** 1379** Function nfa_cho_parse_hr_record 1380** 1381** Description Parsing Handover Request message to retrieve version, random number, 1382** Alternative Carrier records and store into tNFA_CHO_AC_REC 1383** 1384** 1385** Returns tNFA_STATUS 1386** 1387*******************************************************************************/ 1388tNFA_STATUS nfa_cho_parse_hr_record (UINT8 *p_ndef_msg, 1389 UINT8 *p_version, 1390 UINT16 *p_random_number, 1391 UINT8 *p_num_ac_rec, 1392 tNFA_CHO_AC_REC *p_ac_rec) 1393{ 1394 UINT8 *p_hr_record, *p_hr_payload; 1395 UINT32 hr_payload_len; 1396 1397 CHO_TRACE_DEBUG0 ("nfa_cho_parse_hr_record ()"); 1398 1399 /* get Handover Request record */ 1400 p_hr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN); 1401 1402 if (!p_hr_record) 1403 { 1404 CHO_TRACE_ERROR0 ("Failed to find Hr record"); 1405 return NFA_STATUS_FAILED; 1406 } 1407 1408 p_hr_payload = NDEF_RecGetPayload (p_hr_record, &hr_payload_len); 1409 1410 if ((!p_hr_payload) || (hr_payload_len < 7)) 1411 { 1412 CHO_TRACE_ERROR0 ("Failed to get Hr payload (version, cr/ac record)"); 1413 return NFA_STATUS_FAILED; 1414 } 1415 1416 /* Version */ 1417 STREAM_TO_UINT8 ((*p_version), p_hr_payload); 1418 hr_payload_len--; 1419 1420 /* NDEF message for Collision Resolution record and Alternative Carrier records */ 1421 1422 if (NDEF_OK != NDEF_MsgValidate (p_hr_payload, hr_payload_len, FALSE)) 1423 { 1424 CHO_TRACE_ERROR0 ("Failed to validate NDEF message for cr/ac records"); 1425 return NFA_STATUS_FAILED; 1426 } 1427 1428 /* Collision Resolution record */ 1429 if (p_random_number) 1430 { 1431 *p_random_number = nfa_cho_get_random_number (p_hr_payload); 1432 } 1433 1434 /* Alternative Carrier records */ 1435 if (p_ac_rec) 1436 { 1437 return (nfa_cho_parse_ac_records (p_hr_payload, p_num_ac_rec, p_ac_rec)); 1438 } 1439 1440 return NFA_STATUS_OK; 1441} 1442 1443/******************************************************************************* 1444** 1445** Function nfa_cho_parse_carrier_config 1446** 1447** Description Parse Alternative Carrier Configuration and Aux Data 1448** 1449** 1450** Returns tNFA_STATUS 1451** 1452*******************************************************************************/ 1453tNFA_STATUS nfa_cho_parse_carrier_config (UINT8 *p_ndef_msg, UINT8 num_ac_rec, tNFA_CHO_AC_REC *p_ac_rec) 1454{ 1455 UINT8 *p_record; 1456 UINT8 xx, yy; 1457 1458 CHO_TRACE_DEBUG1 ("nfa_cho_parse_carrier_config () num_ac_rec = %d", num_ac_rec); 1459 1460 /* Parse Alternative Carrier Configuration and Aux Data */ 1461 for (xx = 0; xx < num_ac_rec; xx++) 1462 { 1463 p_record = NDEF_MsgGetFirstRecById (p_ndef_msg, 1464 p_ac_rec->carrier_data_ref.ref_name, 1465 p_ac_rec->carrier_data_ref.ref_len); 1466 1467 if (!p_record) 1468 { 1469 CHO_TRACE_ERROR2 ("Failed to find Payload ID: len=%d, [0x%x ...]", 1470 p_ac_rec->carrier_data_ref.ref_len, 1471 p_ac_rec->carrier_data_ref.ref_name[0]); 1472 return NFA_STATUS_FAILED; 1473 } 1474 1475 for (yy = 0; yy < p_ac_rec->aux_data_ref_count; yy++) 1476 { 1477 /* Get aux data record by Payload ID */ 1478 p_record = NDEF_MsgGetFirstRecById (p_ndef_msg, 1479 p_ac_rec->aux_data_ref[yy].ref_name, 1480 p_ac_rec->aux_data_ref[yy].ref_len); 1481 1482 if (!p_record) 1483 { 1484 CHO_TRACE_ERROR2 ("Failed to find Payload ID for Aux: len=%d, [0x%x ...]", 1485 p_ac_rec->aux_data_ref[yy].ref_len, 1486 p_ac_rec->aux_data_ref[yy].ref_name[0]); 1487 return NFA_STATUS_FAILED; 1488 } 1489 } 1490 1491 p_ac_rec++; 1492 } 1493 1494 return NFA_STATUS_OK; 1495} 1496 1497/******************************************************************************* 1498** 1499** Function nfa_cho_proc_hr 1500** 1501** Description Parse Handover Request Message 1502** In case of parsing error, let peer got timeout (1 sec). 1503** 1504** 1505** Returns None 1506** 1507*******************************************************************************/ 1508void nfa_cho_proc_hr (UINT32 length, UINT8 *p_ndef_msg) 1509{ 1510 tNFA_CHO_EVT_DATA evt_data; 1511 tNFA_CHO_API_SEND_HS select; 1512 UINT8 version; 1513 UINT16 random_number; 1514 1515 CHO_TRACE_DEBUG1 ("nfa_cho_proc_hr () length=%d", length); 1516 1517 /* Parse Handover Request record */ 1518 if (NDEF_OK != nfa_cho_parse_hr_record (p_ndef_msg, &version, &random_number, 1519 &evt_data.request.num_ac_rec, 1520 &evt_data.request.ac_rec[0])) 1521 { 1522 CHO_TRACE_ERROR0 ("Failed to parse hr record"); 1523 return; 1524 } 1525 1526 if (version != NFA_CHO_VERSION) 1527 { 1528 CHO_TRACE_DEBUG1 ("Version (0x%02x) not matched", version); 1529 /* For the future, */ 1530 /* if we have higher major then support peer's version */ 1531 /* if we have lower major then send empty handover select message */ 1532 if (NFA_CHO_GET_MAJOR_VERSION (version) > NFA_CHO_GET_MAJOR_VERSION (NFA_CHO_VERSION)) 1533 { 1534 select.num_ac_info = 0; 1535 nfa_cho_send_hs (&select); 1536 return; 1537 } 1538 } 1539 1540 if (NFA_STATUS_OK != nfa_cho_parse_carrier_config (p_ndef_msg, 1541 evt_data.request.num_ac_rec, 1542 &evt_data.request.ac_rec[0])) 1543 { 1544 CHO_TRACE_ERROR0 ("Failed to parse carrier configuration"); 1545 1546 evt_data.request.status = NFA_STATUS_FAILED; 1547 evt_data.request.num_ac_rec = 0; 1548 evt_data.request.p_ref_ndef = NULL; 1549 evt_data.request.ref_ndef_len = 0; 1550 1551 nfa_cho_cb.p_cback (NFA_CHO_REQUEST_EVT, &evt_data); 1552 return; 1553 } 1554 1555 if (evt_data.request.num_ac_rec) 1556 { 1557 /* passing alternative carrier references */ 1558 evt_data.request.p_ref_ndef = NDEF_MsgGetNextRec (p_ndef_msg); 1559 *evt_data.request.p_ref_ndef |= NDEF_MB_MASK; 1560 evt_data.request.ref_ndef_len = (UINT32)(length - (evt_data.request.p_ref_ndef - p_ndef_msg)); 1561 } 1562 else 1563 { 1564 evt_data.request.p_ref_ndef = NULL; 1565 evt_data.request.ref_ndef_len = 0; 1566 } 1567 1568 evt_data.request.status = NFA_STATUS_OK; 1569 1570 nfa_cho_cb.p_cback (NFA_CHO_REQUEST_EVT, &evt_data); 1571} 1572 1573/******************************************************************************* 1574** 1575** Function nfa_cho_get_error 1576** 1577** Description Search Error record and parse it 1578** 1579** 1580** Returns tNFA_STATUS 1581** 1582*******************************************************************************/ 1583tNFA_STATUS nfa_cho_get_error (UINT8 *p_ndef_msg, UINT8 *p_error_reason, UINT32 *p_error_data) 1584{ 1585 UINT8 *p_err_record, *p_err_payload, u8; 1586 UINT32 err_payload_len; 1587 1588 CHO_TRACE_DEBUG0 ("nfa_cho_get_error ()"); 1589 1590 p_err_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, err_rec_type, ERR_REC_TYPE_LEN); 1591 1592 if (!p_err_record) 1593 { 1594 CHO_TRACE_DEBUG0 ("Found no err record"); 1595 return NFA_STATUS_FAILED; 1596 } 1597 1598 p_err_payload = NDEF_RecGetPayload (p_err_record, &err_payload_len); 1599 1600 if (!p_err_payload) 1601 { 1602 CHO_TRACE_ERROR0 ("Failed to get err payload"); 1603 return NFA_STATUS_SYNTAX_ERROR; 1604 } 1605 1606 BE_STREAM_TO_UINT8 (*p_error_reason, p_err_payload); 1607 1608 if ( (err_payload_len == 2) 1609 &&( (*p_error_reason == NFA_CHO_ERROR_TEMP_MEM) 1610 ||(*p_error_reason == NFA_CHO_ERROR_CARRIER) ) ) 1611 { 1612 BE_STREAM_TO_UINT8 (u8, p_err_payload); 1613 *p_error_data = (UINT32)u8; 1614 } 1615 else if ( (err_payload_len == 5) 1616 &&(*p_error_reason == NFA_CHO_ERROR_PERM_MEM) ) 1617 { 1618 BE_STREAM_TO_UINT32 (*p_error_data, p_err_payload); 1619 } 1620 else 1621 { 1622 CHO_TRACE_ERROR2 ("Unknown error reason = %d, err_payload_len = %d", 1623 *p_error_reason, err_payload_len); 1624 return NFA_STATUS_SYNTAX_ERROR; 1625 } 1626 1627 CHO_TRACE_DEBUG2 ("error_reason=0x%x, error_data=0x%x", *p_error_reason, *p_error_data); 1628 1629 return NFA_STATUS_OK; 1630} 1631 1632/******************************************************************************* 1633** 1634** Function nfa_cho_parse_hs_record 1635** 1636** Description Parse Handover Select record 1637** 1638** 1639** Returns tNFA_STATUS 1640** 1641*******************************************************************************/ 1642tNFA_STATUS nfa_cho_parse_hs_record (UINT8 *p_ndef_msg, 1643 UINT8 *p_version, 1644 UINT8 *p_num_ac_rec, 1645 tNFA_CHO_AC_REC *p_ac_rec, 1646 UINT8 *p_error_reason, 1647 UINT32 *p_error_data) 1648{ 1649 tNFA_STATUS status; 1650 UINT8 *p_hs_record, *p_hs_payload; 1651 UINT32 hs_payload_len; 1652 1653 CHO_TRACE_DEBUG0 ("nfa_cho_parse_hs_record ()"); 1654 1655 /* get Handover Select record */ 1656 p_hs_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN); 1657 1658 if (!p_hs_record) 1659 { 1660 CHO_TRACE_ERROR0 ("Failed to find Hs record"); 1661 return NFA_STATUS_FAILED; 1662 } 1663 1664 p_hs_payload = NDEF_RecGetPayload (p_hs_record, &hs_payload_len); 1665 1666 if ((!p_hs_payload) || (hs_payload_len < 1)) /* at least version */ 1667 { 1668 CHO_TRACE_ERROR0 ("Failed to get Hs payload (version, ac record)"); 1669 return NFA_STATUS_FAILED; 1670 } 1671 1672 STREAM_TO_UINT8 ((*p_version), p_hs_payload); 1673 hs_payload_len--; 1674 1675 /* Check if error record is sent */ 1676 status = nfa_cho_get_error (p_ndef_msg, p_error_reason, p_error_data); 1677 1678 if (status == NFA_STATUS_SYNTAX_ERROR) 1679 { 1680 return NFA_STATUS_FAILED; 1681 } 1682 else if (status == NFA_STATUS_OK) 1683 { 1684 return NFA_STATUS_OK; 1685 } 1686 1687 if (hs_payload_len >= 3 ) 1688 { 1689 /* NDEF message for Alternative Carrier records */ 1690 if (NDEF_OK != NDEF_MsgValidate (p_hs_payload, hs_payload_len, FALSE)) 1691 { 1692 CHO_TRACE_ERROR0 ("Failed to validate NDEF message for ac records"); 1693 return NFA_STATUS_FAILED; 1694 } 1695 1696 /* Alternative Carrier records */ 1697 if (p_ac_rec) 1698 { 1699 if (NFA_STATUS_OK != nfa_cho_parse_ac_records (p_hs_payload, p_num_ac_rec, p_ac_rec)) 1700 { 1701 return NFA_STATUS_FAILED; 1702 } 1703 1704 CHO_TRACE_DEBUG1 ("Found %d ac record", *p_num_ac_rec); 1705 } 1706 } 1707 else 1708 { 1709 CHO_TRACE_DEBUG0 ("Empty Handover Select Message"); 1710 *p_num_ac_rec = 0; 1711 } 1712 1713 return NFA_STATUS_OK; 1714} 1715 1716/******************************************************************************* 1717** 1718** Function nfa_cho_proc_hs 1719** 1720** Description Parse Handover Select Message 1721** 1722** 1723** Returns FALSE if we need to select one from inactive ACs 1724** 1725*******************************************************************************/ 1726void nfa_cho_proc_hs (UINT32 length, UINT8 *p_ndef_msg) 1727{ 1728 tNFA_CHO_EVT_DATA evt_data; 1729 UINT8 version, error_reason = 0; 1730 UINT32 error_data; 1731 1732 CHO_TRACE_DEBUG0 ("nfa_cho_proc_hs ()"); 1733 1734 evt_data.select.status = NFA_STATUS_OK; 1735 1736 /* Parse Handover Select record */ 1737 if (NFA_STATUS_OK != nfa_cho_parse_hs_record (p_ndef_msg, &version, 1738 &evt_data.select.num_ac_rec, 1739 &evt_data.select.ac_rec[0], 1740 &error_reason, &error_data)) 1741 { 1742 CHO_TRACE_ERROR0 ("Failed to parse hs record"); 1743 1744 evt_data.select.status = NFA_STATUS_FAILED; 1745 } 1746 1747 if ( (evt_data.select.status == NFA_STATUS_OK) 1748 &&(error_reason != 0) ) 1749 { 1750 /* We got error records */ 1751 evt_data.sel_err.error_reason = error_reason; 1752 evt_data.sel_err.error_data = error_data; 1753 1754 nfa_cho_cb.p_cback (NFA_CHO_SEL_ERR_EVT, &evt_data); 1755 return; 1756 } 1757 1758 if ( (evt_data.select.status == NFA_STATUS_OK) 1759 &&(version != NFA_CHO_VERSION) ) 1760 { 1761 CHO_TRACE_ERROR1 ("Version (0x%02x) not matched", version); 1762 1763 evt_data.select.status = NFA_STATUS_FAILED; 1764 } 1765 1766 /* parse Alternative Carrier information */ 1767 1768 if ( (evt_data.select.status == NFA_STATUS_OK) 1769 &&(NFA_STATUS_OK != nfa_cho_parse_carrier_config (p_ndef_msg, 1770 evt_data.select.num_ac_rec, 1771 &evt_data.select.ac_rec[0])) ) 1772 { 1773 CHO_TRACE_ERROR0 ("Failed to parse carrier configuration"); 1774 1775 evt_data.select.status = NFA_STATUS_FAILED; 1776 } 1777 1778 if (evt_data.select.status == NFA_STATUS_OK) 1779 { 1780 if (evt_data.select.num_ac_rec) 1781 { 1782 /* passing alternative carrier references */ 1783 evt_data.select.p_ref_ndef = NDEF_MsgGetNextRec (p_ndef_msg); 1784 *evt_data.select.p_ref_ndef |= NDEF_MB_MASK; 1785 evt_data.select.ref_ndef_len = (UINT32)(length - (evt_data.select.p_ref_ndef - p_ndef_msg)); 1786 } 1787 else 1788 { 1789 evt_data.select.p_ref_ndef = NULL; 1790 evt_data.select.ref_ndef_len = 0; 1791 } 1792 } 1793 else 1794 { 1795 evt_data.select.num_ac_rec = 0; 1796 evt_data.select.p_ref_ndef = NULL; 1797 evt_data.select.ref_ndef_len = 0; 1798 } 1799 1800 nfa_cho_cb.p_cback (NFA_CHO_SELECT_EVT, &evt_data); 1801} 1802 1803/******************************************************************************* 1804** 1805** Function nfa_cho_proc_simplified_format 1806** 1807** Description Parse simplified BT OOB/Wifi Message 1808** 1809** 1810** Returns void 1811** 1812*******************************************************************************/ 1813void nfa_cho_proc_simplified_format (UINT32 length, UINT8 *p_ndef_msg) 1814{ 1815 tNFA_CHO_EVT_DATA evt_data; 1816 1817 CHO_TRACE_DEBUG0 ("nfa_cho_proc_simplified_format ()"); 1818 1819 evt_data.select.status = NFA_STATUS_OK; 1820 1821 evt_data.select.num_ac_rec = 1; 1822 1823 evt_data.select.ac_rec[0].cps = NFA_CHO_CPS_UNKNOWN; 1824 evt_data.select.ac_rec[0].carrier_data_ref.ref_len = 0; 1825 evt_data.select.ac_rec[0].aux_data_ref_count = 0; 1826 1827 evt_data.select.p_ref_ndef = p_ndef_msg; 1828 evt_data.select.ref_ndef_len = length; 1829 1830 nfa_cho_cb.p_cback (NFA_CHO_SELECT_EVT, &evt_data); 1831} 1832 1833/******************************************************************************* 1834** 1835** Function nfa_cho_get_msg_type 1836** 1837** Description Get handover message type to check collision 1838** 1839** 1840** Returns NFA_CHO_MSG_HR if it has Handover Request record 1841** NFA_CHO_MSG_HS if it has Handover Select record 1842** NFA_CHO_MSG_BT_OOB if it has simplified BT OOB record 1843** NFA_CHO_MSG_WIFI if it has simplified WiFi record 1844** NFA_CHO_MSG_UNKNOWN, otherwise 1845** 1846*******************************************************************************/ 1847tNFA_CHO_MSG_TYPE nfa_cho_get_msg_type (UINT32 length, UINT8 *p_ndef_msg) 1848{ 1849 UINT8 *p_record; 1850 1851 CHO_TRACE_DEBUG1 ("nfa_cho_get_msg_type () length=%d", length); 1852 1853 p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN); 1854 1855 if (p_record) 1856 { 1857 CHO_TRACE_DEBUG0 ("Found Hr record"); 1858 return NFA_CHO_MSG_HR; 1859 } 1860 1861 p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hs_rec_type, HS_REC_TYPE_LEN); 1862 1863 if (p_record) 1864 { 1865 CHO_TRACE_DEBUG0 ("Found Hs record"); 1866 return NFA_CHO_MSG_HS; 1867 } 1868 1869 p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_MEDIA, 1870 p_bt_oob_rec_type, BT_OOB_REC_TYPE_LEN); 1871 1872 if (p_record) 1873 { 1874 CHO_TRACE_DEBUG0 ("Found simplified BT OOB record"); 1875 return NFA_CHO_MSG_BT_OOB; 1876 } 1877 1878 p_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_MEDIA, 1879 p_wifi_rec_type, (UINT8) strlen ((char *) p_wifi_rec_type)); 1880 1881 if (p_record) 1882 { 1883 CHO_TRACE_DEBUG0 ("Found simplified WiFi record"); 1884 return NFA_CHO_MSG_WIFI; 1885 } 1886 1887 CHO_TRACE_ERROR0 ("Failed to find Hr/Hs record"); 1888 1889 return NFA_CHO_MSG_UNKNOWN; 1890} 1891 1892/******************************************************************************* 1893** 1894** Function nfa_cho_get_local_device_role 1895** 1896** Description Resolve collision and get role of local device 1897** 1898** 1899** Returns tNFA_CHO_ROLE_TYPE 1900** 1901*******************************************************************************/ 1902tNFA_CHO_ROLE_TYPE nfa_cho_get_local_device_role (UINT32 length, UINT8 *p_ndef_msg) 1903{ 1904 UINT16 rx_random_number; 1905 UINT8 version; 1906 1907 CHO_TRACE_DEBUG1 ("nfa_cho_get_local_device_role () length=%d", length); 1908 1909 /* Get random number in Handover Request record */ 1910 if (NDEF_OK != nfa_cho_parse_hr_record (p_ndef_msg, &version, &rx_random_number, NULL, NULL)) 1911 { 1912 CHO_TRACE_ERROR0 ("Failed to parse hr record"); 1913 return NFA_CHO_ROLE_UNDECIDED; 1914 } 1915 1916 CHO_TRACE_DEBUG2 ("tx_random_number=0x%x, rx_random_number=0x%x", 1917 nfa_cho_cb.tx_random_number, rx_random_number); 1918 1919 if (nfa_cho_cb.tx_random_number == rx_random_number) 1920 { 1921 return NFA_CHO_ROLE_UNDECIDED; 1922 } 1923 /* if the least significant bits are same */ 1924 else if (((nfa_cho_cb.tx_random_number ^ rx_random_number) & 0x0001) == 0) 1925 { 1926 if (nfa_cho_cb.tx_random_number > rx_random_number) 1927 return NFA_CHO_ROLE_SELECTOR; 1928 else 1929 return NFA_CHO_ROLE_REQUESTER; 1930 } 1931 else 1932 { 1933 if (nfa_cho_cb.tx_random_number > rx_random_number) 1934 return NFA_CHO_ROLE_REQUESTER; 1935 else 1936 return NFA_CHO_ROLE_SELECTOR; 1937 } 1938} 1939 1940/******************************************************************************* 1941** 1942** Function nfa_cho_update_random_number 1943** 1944** Description Replace random number 1945** 1946** 1947** Returns tNFA_STATUS 1948** 1949*******************************************************************************/ 1950tNFA_STATUS nfa_cho_update_random_number (UINT8 *p_ndef_msg) 1951{ 1952 UINT8 *p_hr_record, *p_hr_payload; 1953 UINT8 *p_cr_record, *p_cr_payload; 1954 UINT32 hr_payload_len, cr_payload_len; 1955 UINT32 temp32; 1956 1957 CHO_TRACE_DEBUG0 ("nfa_cho_update_random_number ()"); 1958 1959 /* get Handover Request record */ 1960 p_hr_record = NDEF_MsgGetFirstRecByType (p_ndef_msg, NDEF_TNF_WKT, hr_rec_type, HR_REC_TYPE_LEN); 1961 1962 if (!p_hr_record) 1963 { 1964 CHO_TRACE_ERROR0 ("Failed to find Hr record"); 1965 return NFA_STATUS_FAILED; 1966 } 1967 1968 p_hr_payload = NDEF_RecGetPayload (p_hr_record, &hr_payload_len); 1969 1970 /* Skip Version */ 1971 p_hr_payload++; 1972 hr_payload_len--; 1973 1974 /* NDEF message for Collision Resolution record and Alternative Carrier records */ 1975 1976 /* find Collision Resolution record */ 1977 p_cr_record = NDEF_MsgGetFirstRecByType (p_hr_payload, NDEF_TNF_WKT, cr_rec_type, CR_REC_TYPE_LEN); 1978 1979 if (!p_cr_record) 1980 { 1981 CHO_TRACE_ERROR0 ("Failed to find cr record"); 1982 return NFA_STATUS_FAILED; 1983 } 1984 1985 /* get start of payload in Collision Resolution record */ 1986 p_cr_payload = NDEF_RecGetPayload (p_cr_record, &cr_payload_len); 1987 1988 /* Get random number from timer */ 1989 temp32 = GKI_get_tick_count (); 1990 nfa_cho_cb.tx_random_number = (UINT16) ((temp32 >> 16) ^ (temp32)); 1991 1992#if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 1993 if (nfa_cho_cb.test_enabled & NFA_CHO_TEST_RANDOM) 1994 { 1995 nfa_cho_cb.tx_random_number = nfa_cho_cb.test_random_number; 1996 } 1997#endif 1998 1999 CHO_TRACE_DEBUG1 ("tx_random_number = 0x%04x", nfa_cho_cb.tx_random_number); 2000 2001 /* update random number in payload */ 2002 UINT16_TO_BE_STREAM (p_cr_payload, nfa_cho_cb.tx_random_number); 2003 2004 return NFA_STATUS_OK; 2005} 2006