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