Home | History | Annotate | Download | only in cho
      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