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 * NFA interface for connection handover 22 * 23 ******************************************************************************/ 24 #include <string.h> 25 #include "nfc_api.h" 26 #include "nfa_sys.h" 27 #include "nfa_sys_int.h" 28 #include "nfa_p2p_api.h" 29 #include "nfa_cho_api.h" 30 #include "nfa_cho_int.h" 31 #include "nfa_mem_co.h" 32 33 /***************************************************************************** 34 ** Constants 35 *****************************************************************************/ 36 37 /******************************************************************************* 38 ** 39 ** Function NFA_ChoRegister 40 ** 41 ** Description This function is called to register callback function to receive 42 ** connection handover events. 43 ** 44 ** On this registration, "urn:nfc:sn:handover" server will be 45 ** registered on LLCP if enable_server is TRUE. 46 ** 47 ** The result of the registration is reported with NFA_CHO_REG_EVT. 48 ** 49 ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT 50 ** should happen before calling this function 51 ** 52 ** Returns NFA_STATUS_OK if successfully initiated 53 ** NFA_STATUS_FAILED otherwise 54 ** 55 *******************************************************************************/ 56 tNFA_STATUS NFA_ChoRegister (BOOLEAN enable_server, 57 tNFA_CHO_CBACK *p_cback) 58 { 59 tNFA_CHO_API_REG *p_msg; 60 61 CHO_TRACE_API1 ("NFA_ChoRegister (): enable_server=%d", enable_server); 62 63 if ( (nfa_cho_cb.state != NFA_CHO_ST_DISABLED) 64 ||(nfa_cho_cb.p_cback != NULL) ) 65 { 66 CHO_TRACE_ERROR0 ("NFA_ChoRegister (): Already registered or callback is not provided"); 67 return (NFA_STATUS_FAILED); 68 } 69 70 if ((p_msg = (tNFA_CHO_API_REG *) GKI_getbuf (sizeof (tNFA_CHO_API_REG))) != NULL) 71 { 72 p_msg->hdr.event = NFA_CHO_API_REG_EVT; 73 74 p_msg->enable_server = enable_server; 75 p_msg->p_cback = p_cback; 76 77 nfa_sys_sendmsg (p_msg); 78 79 return (NFA_STATUS_OK); 80 } 81 82 return (NFA_STATUS_FAILED); 83 } 84 85 /******************************************************************************* 86 ** 87 ** Function NFA_ChoDeregister 88 ** 89 ** Description This function is called to deregister callback function from NFA 90 ** Connection Handover Application. 91 ** 92 ** If this is the valid deregistration, NFA Connection Handover 93 ** Application will close the service with "urn:nfc:sn:handover" 94 ** on LLCP and deregister NDEF type handler if any. 95 ** 96 ** Note: If RF discovery is started, NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT 97 ** should happen before calling this function 98 ** 99 ** Returns NFA_STATUS_OK if successfully initiated 100 ** NFA_STATUS_FAILED otherwise 101 ** 102 *******************************************************************************/ 103 tNFA_STATUS NFA_ChoDeregister (void) 104 { 105 tNFA_CHO_API_DEREG *p_msg; 106 107 CHO_TRACE_API0 ("NFA_ChoDeregister ()"); 108 109 if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED) 110 { 111 CHO_TRACE_ERROR0 ("NFA_ChoDeregister (): Not registered"); 112 return (NFA_STATUS_FAILED); 113 } 114 115 if ((p_msg = (tNFA_CHO_API_DEREG *) GKI_getbuf (sizeof (tNFA_CHO_API_DEREG))) != NULL) 116 { 117 p_msg->event = NFA_CHO_API_DEREG_EVT; 118 119 nfa_sys_sendmsg (p_msg); 120 121 return (NFA_STATUS_OK); 122 } 123 124 return (NFA_STATUS_FAILED); 125 } 126 127 /******************************************************************************* 128 ** 129 ** Function NFA_ChoConnect 130 ** 131 ** Description This function is called to create data link connection to 132 ** Connection Handover server on peer device. 133 ** 134 ** It must be called after receiving NFA_CHO_ACTIVATED_EVT. 135 ** NFA_CHO_CONNECTED_EVT will be returned if successful. 136 ** Otherwise, NFA_CHO_DISCONNECTED_EVT will be returned. 137 ** 138 ** If NFA_CHO_ROLE_REQUESTER is returned in NFA_CHO_CONNECTED_EVT, 139 ** Handover Request Message can be sent. 140 ** If NFA_CHO_ROLE_SELECTOR is returned in NFA_CHO_CONNECTED_EVT 141 ** because of collision, application must wait for Handover 142 ** Request Message. 143 ** 144 ** Returns NFA_STATUS_OK if successfully initiated 145 ** NFA_STATUS_FAILED otherwise 146 ** 147 *******************************************************************************/ 148 tNFA_STATUS NFA_ChoConnect (void) 149 { 150 tNFA_CHO_API_CONNECT *p_msg; 151 152 CHO_TRACE_API0 ("NFA_ChoConnect ()"); 153 154 if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED) 155 { 156 CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Not registered"); 157 return (NFA_STATUS_FAILED); 158 } 159 else if (nfa_cho_cb.state == NFA_CHO_ST_CONNECTED) 160 { 161 CHO_TRACE_ERROR0 ("NFA_ChoConnect (): Already connected"); 162 return (NFA_STATUS_FAILED); 163 } 164 165 if ((p_msg = (tNFA_CHO_API_CONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_CONNECT))) != NULL) 166 { 167 p_msg->event = NFA_CHO_API_CONNECT_EVT; 168 169 nfa_sys_sendmsg (p_msg); 170 171 return (NFA_STATUS_OK); 172 } 173 174 return (NFA_STATUS_FAILED); 175 } 176 177 /******************************************************************************* 178 ** 179 ** Function NFA_ChoDisconnect 180 ** 181 ** Description This function is called to disconnect data link connection with 182 ** Connection Handover server on peer device. 183 ** 184 ** NFA_CHO_DISCONNECTED_EVT will be returned. 185 ** 186 ** Returns NFA_STATUS_OK if successfully initiated 187 ** NFA_STATUS_FAILED otherwise 188 ** 189 *******************************************************************************/ 190 tNFA_STATUS NFA_ChoDisconnect (void) 191 { 192 tNFA_CHO_API_DISCONNECT *p_msg; 193 194 CHO_TRACE_API0 ("NFA_ChoDisconnect ()"); 195 196 if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED) 197 { 198 CHO_TRACE_ERROR0 ("NFA_ChoDisconnect (): Not registered"); 199 return (NFA_STATUS_FAILED); 200 } 201 202 if ((p_msg = (tNFA_CHO_API_DISCONNECT *) GKI_getbuf (sizeof (tNFA_CHO_API_DISCONNECT))) != NULL) 203 { 204 p_msg->event = NFA_CHO_API_DISCONNECT_EVT; 205 206 nfa_sys_sendmsg (p_msg); 207 208 return (NFA_STATUS_OK); 209 } 210 211 return (NFA_STATUS_FAILED); 212 } 213 214 /******************************************************************************* 215 ** 216 ** Function NFA_ChoSendHr 217 ** 218 ** Description This function is called to send Handover Request Message with 219 ** Handover Carrier records or Alternative Carrier records. 220 ** 221 ** It must be called after receiving NFA_CHO_CONNECTED_EVT. 222 ** 223 ** NDEF may include one or more Handover Carrier records or Alternative 224 ** Carrier records with auxiliary data. 225 ** The records in NDEF must be matched with tNFA_CHO_AC_INFO in order. 226 ** Payload ID must be unique and Payload ID length must be less than 227 ** or equal to NFA_CHO_MAX_REF_NAME_LEN. 228 ** 229 ** The alternative carrier information of Handover Select record 230 ** will be sent to application by NFA_CHO_SELECT_EVT. Application 231 ** may receive NFA_CHO_REQUEST_EVT because of handover collision. 232 ** 233 ** Returns NFA_STATUS_OK if successfully initiated 234 ** NFA_STATUS_FAILED otherwise 235 ** 236 *******************************************************************************/ 237 tNFA_STATUS NFA_ChoSendHr (UINT8 num_ac_info, 238 tNFA_CHO_AC_INFO *p_ac_info, 239 UINT8 *p_ndef, 240 UINT32 ndef_len) 241 { 242 tNFA_CHO_API_SEND_HR *p_msg; 243 UINT16 msg_size; 244 UINT8 *p_ndef_buf; 245 246 CHO_TRACE_API2 ("NFA_ChoSendHr (): num_ac_info=%d, ndef_len=%d", num_ac_info, ndef_len); 247 248 if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED) 249 { 250 CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Not connected"); 251 return (NFA_STATUS_FAILED); 252 } 253 254 if (num_ac_info > NFA_CHO_MAX_AC_INFO) 255 { 256 CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Too many AC information"); 257 return (NFA_STATUS_FAILED); 258 } 259 260 p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 261 262 if (!p_ndef_buf) 263 { 264 CHO_TRACE_ERROR0 ("NFA_ChoSendHr (): Failed to allocate buffer for NDEF"); 265 return NFA_STATUS_FAILED; 266 } 267 else if (ndef_len > LLCP_POOL_BUF_SIZE) 268 { 269 CHO_TRACE_ERROR1 ("NFA_ChoSendHr (): Failed to allocate buffer for %d bytes", ndef_len); 270 GKI_freebuf (p_ndef_buf); 271 return NFA_STATUS_FAILED; 272 } 273 274 msg_size = sizeof (tNFA_CHO_API_SEND_HR) + num_ac_info * sizeof (tNFA_CHO_AC_INFO); 275 276 if ((p_msg = (tNFA_CHO_API_SEND_HR *) GKI_getbuf (msg_size)) != NULL) 277 { 278 p_msg->hdr.event = NFA_CHO_API_SEND_HR_EVT; 279 280 memcpy (p_ndef_buf, p_ndef, ndef_len); 281 p_msg->p_ndef = p_ndef_buf; 282 p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE; 283 p_msg->cur_ndef_size = ndef_len; 284 285 p_msg->num_ac_info = num_ac_info; 286 p_msg->p_ac_info = (tNFA_CHO_AC_INFO *) (p_msg + 1); 287 memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO)); 288 289 nfa_sys_sendmsg (p_msg); 290 return (NFA_STATUS_OK); 291 } 292 else 293 { 294 GKI_freebuf (p_ndef_buf); 295 return (NFA_STATUS_FAILED); 296 } 297 } 298 299 /******************************************************************************* 300 ** 301 ** Function NFA_ChoSendHs 302 ** 303 ** Description This function is called to send Handover Select message with 304 ** Alternative Carrier records as response to Handover Request 305 ** message. 306 ** 307 ** NDEF may include one or more Alternative Carrier records with 308 ** auxiliary data. 309 ** The records in NDEF must be matched with tNFA_CHO_AC_INFO in order. 310 ** Payload ID must be unique and Payload ID length must be less than 311 ** or equal to NFA_CHO_MAX_REF_NAME_LEN. 312 ** 313 ** Returns NFA_STATUS_OK if successfully initiated 314 ** NFA_STATUS_FAILED otherwise 315 ** 316 *******************************************************************************/ 317 tNFA_STATUS NFA_ChoSendHs (UINT8 num_ac_info, 318 tNFA_CHO_AC_INFO *p_ac_info, 319 UINT8 *p_ndef, 320 UINT32 ndef_len) 321 { 322 tNFA_CHO_API_SEND_HS *p_msg; 323 UINT16 msg_size; 324 UINT8 *p_ndef_buf; 325 326 CHO_TRACE_API2 ("NFA_ChoSendHs(): num_ac_info=%d, ndef_len=%d", 327 num_ac_info, ndef_len); 328 329 if (nfa_cho_cb.state != NFA_CHO_ST_CONNECTED) 330 { 331 CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Not connected"); 332 return (NFA_STATUS_FAILED); 333 } 334 335 if (num_ac_info > NFA_CHO_MAX_AC_INFO) 336 { 337 CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Too many AC information"); 338 return (NFA_STATUS_FAILED); 339 } 340 341 p_ndef_buf = (UINT8 *) GKI_getpoolbuf (LLCP_POOL_ID); 342 if (!p_ndef_buf) 343 { 344 CHO_TRACE_ERROR0 ("NFA_ChoSendHs (): Failed to allocate buffer for NDEF"); 345 return NFA_STATUS_FAILED; 346 } 347 else if (ndef_len > LLCP_POOL_BUF_SIZE) 348 { 349 CHO_TRACE_ERROR1 ("NFA_ChoSendHs (): Failed to allocate buffer for %d bytes", ndef_len); 350 GKI_freebuf (p_ndef_buf); 351 return NFA_STATUS_FAILED; 352 } 353 354 msg_size = sizeof (tNFA_CHO_API_SEND_HS) + num_ac_info * sizeof (tNFA_CHO_AC_INFO); 355 356 if ((p_msg = (tNFA_CHO_API_SEND_HS *) GKI_getbuf (msg_size)) != NULL) 357 { 358 p_msg->hdr.event = NFA_CHO_API_SEND_HS_EVT; 359 360 memcpy (p_ndef_buf, p_ndef, ndef_len); 361 p_msg->p_ndef = p_ndef_buf; 362 p_msg->max_ndef_size = LLCP_POOL_BUF_SIZE; 363 p_msg->cur_ndef_size = ndef_len; 364 365 p_msg->num_ac_info = num_ac_info; 366 p_msg->p_ac_info = (tNFA_CHO_AC_INFO *) (p_msg + 1); 367 memcpy (p_msg->p_ac_info, p_ac_info, num_ac_info * sizeof (tNFA_CHO_AC_INFO)); 368 369 nfa_sys_sendmsg (p_msg); 370 return (NFA_STATUS_OK); 371 } 372 else 373 { 374 GKI_freebuf (p_ndef_buf); 375 return (NFA_STATUS_FAILED); 376 } 377 } 378 379 /******************************************************************************* 380 ** 381 ** Function NFA_ChoSendSelectError 382 ** 383 ** Description This function is called to send Error record to indicate failure 384 ** to process the most recently received Handover Request message. 385 ** 386 ** error_reason : NFA_CHO_ERROR_TEMP_MEM 387 ** NFA_CHO_ERROR_PERM_MEM 388 ** NFA_CHO_ERROR_CARRIER 389 ** 390 ** Returns NFA_STATUS_OK if successfully initiated 391 ** NFA_STATUS_FAILED otherwise 392 ** 393 *******************************************************************************/ 394 tNFA_STATUS NFA_ChoSendSelectError (UINT8 error_reason, 395 UINT32 error_data) 396 { 397 tNFA_CHO_API_SEL_ERR *p_msg; 398 399 CHO_TRACE_API2 ("NFA_ChoSendSelectError (): error_reason=0x%x, error_data=0x%x", 400 error_reason, error_data); 401 402 if (nfa_cho_cb.state == NFA_CHO_ST_DISABLED) 403 { 404 CHO_TRACE_ERROR0 ("NFA_ChoSendSelectError (): Not registered"); 405 return (NFA_STATUS_FAILED); 406 } 407 408 if ((p_msg = (tNFA_CHO_API_SEL_ERR *) GKI_getbuf (sizeof (tNFA_CHO_API_SEL_ERR))) != NULL) 409 { 410 p_msg->hdr.event = NFA_CHO_API_SEL_ERR_EVT; 411 412 p_msg->error_reason = error_reason; 413 p_msg->error_data = error_data; 414 415 nfa_sys_sendmsg (p_msg); 416 417 return (NFA_STATUS_OK); 418 } 419 420 return (NFA_STATUS_FAILED); 421 } 422 423 /******************************************************************************* 424 ** 425 ** Function NFA_ChoSetTraceLevel 426 ** 427 ** Description This function sets the trace level for CHO. If called with 428 ** a value of 0xFF, it simply returns the current trace level. 429 ** 430 ** Returns The new or current trace level 431 ** 432 *******************************************************************************/ 433 UINT8 NFA_ChoSetTraceLevel (UINT8 new_level) 434 { 435 if (new_level != 0xFF) 436 nfa_cho_cb.trace_level = new_level; 437 438 return (nfa_cho_cb.trace_level); 439 } 440 441 #if (defined (NFA_CHO_TEST_INCLUDED) && (NFA_CHO_TEST_INCLUDED == TRUE)) 442 /******************************************************************************* 443 ** 444 ** Function NFA_ChoSetTestParam 445 ** 446 ** Description This function is called to set test parameters. 447 ** 448 *******************************************************************************/ 449 void NFA_ChoSetTestParam (UINT8 test_enable, 450 UINT8 test_version, 451 UINT16 test_random_number) 452 { 453 nfa_cho_cb.test_enabled = test_enable; 454 nfa_cho_cb.test_version = test_version; 455 nfa_cho_cb.test_random_number = test_random_number; 456 } 457 #endif 458