Home | History | Annotate | Download | only in ce
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2011-2014 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 card emulation
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "nfa_api.h"
     26 #include "nfa_ce_int.h"
     27 #include "nfa_sys.h"
     28 #include "nfa_sys_int.h"
     29 
     30 /*******************************************************************************
     31 **
     32 ** Function         nfa_ce_api_deregister_listen
     33 **
     34 ** Description      Internal function called by listening for Felica system
     35 **                  code, ISO-DEP AID, or UICC technology
     36 **
     37 ** Returns:
     38 **                  NFA_STATUS_OK,            if command accepted
     39 **                  NFA_STATUS_BAD_HANDLE     invalid handle
     40 **                  NFA_STATUS_FAILED:        otherwise
     41 **
     42 *******************************************************************************/
     43 tNFA_STATUS nfa_ce_api_deregister_listen(tNFA_HANDLE handle,
     44                                          uint32_t listen_info) {
     45   tNFA_CE_MSG* p_ce_msg;
     46 
     47   /* Validate handle */
     48   if ((listen_info != NFA_CE_LISTEN_INFO_UICC) &&
     49       ((handle & NFA_HANDLE_GROUP_MASK) != NFA_HANDLE_GROUP_CE)) {
     50     NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Invalid handle");
     51     return (NFA_STATUS_BAD_HANDLE);
     52   }
     53 
     54   p_ce_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)(sizeof(tNFA_CE_MSG)));
     55   if (p_ce_msg != NULL) {
     56     p_ce_msg->hdr.event = NFA_CE_API_DEREG_LISTEN_EVT;
     57     p_ce_msg->dereg_listen.handle = handle;
     58     p_ce_msg->dereg_listen.listen_info = listen_info;
     59 
     60     nfa_sys_sendmsg(p_ce_msg);
     61 
     62     return (NFA_STATUS_OK);
     63   } else {
     64     NFA_TRACE_ERROR0("nfa_ce_api_reregister_listen: Out of buffers");
     65     return (NFA_STATUS_FAILED);
     66   }
     67 }
     68 
     69 /*****************************************************************************
     70 **  APIs
     71 *****************************************************************************/
     72 
     73 /*******************************************************************************
     74 **
     75 ** Function         NFA_CeConfigureLocalTag
     76 **
     77 ** Description      Configure local NDEF tag.
     78 **
     79 **                  Tag events will be notifed using the tNFA_CONN_CBACK
     80 **                  (registered during NFA_Enable)
     81 **
     82 **                  The NFA_CE_LOCAL_TAG_CONFIGURED_EVT reports the status of
     83 **                  the operation.
     84 **
     85 **                  Activation and deactivation are reported using the
     86 **                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
     87 **
     88 **                  If a write-request is received to update the tag memory,
     89 **                  an NFA_CE_NDEF_WRITE_CPLT_EVT will notify the application,
     90 **                  along with a buffer containing the updated contents.
     91 **
     92 **                  To disable the local NDEF tag, set protocol_mask=0
     93 **
     94 **                  The NDEF data provided by p_ndef_data must be persistent
     95 **                  as long as the local NDEF tag is enabled.
     96 **
     97 **
     98 ** Note:            If RF discovery is started,
     99 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    100 **                  happen before calling this function. Also, Input parameters
    101 **                  p_uid and uid_len are reserved for future use.
    102 **
    103 ** Returns:
    104 **                  NFA_STATUS_OK,            if command accepted
    105 **                  NFA_STATUS_INVALID_PARAM,
    106 **                      if protocol_maks is not 0 and p_ndef_data is NULL
    107 **                  (or)uid_len is not 0
    108 **                  (or)if protocol mask is set for Type 1 or Type 2
    109 **
    110 **                  NFA_STATUS_FAILED:        otherwise
    111 **
    112 *******************************************************************************/
    113 tNFA_STATUS NFA_CeConfigureLocalTag(tNFA_PROTOCOL_MASK protocol_mask,
    114                                     uint8_t* p_ndef_data,
    115                                     uint16_t ndef_cur_size,
    116                                     uint16_t ndef_max_size, bool read_only,
    117                                     uint8_t uid_len, uint8_t* p_uid)
    118 
    119 {
    120   tNFA_CE_MSG* p_msg;
    121 
    122   NFA_TRACE_API0("NFA_CeConfigureLocalTag ()");
    123 
    124   if (protocol_mask) {
    125     /* If any protocols are specified, then NDEF buffer pointer must be non-NULL
    126      */
    127     if (p_ndef_data == NULL) {
    128       NFA_TRACE_ERROR0("NFA_CeConfigureLocalTag: NULL ndef data pointer");
    129       return (NFA_STATUS_INVALID_PARAM);
    130     }
    131 
    132     if ((protocol_mask & NFA_PROTOCOL_MASK_T1T) ||
    133         (protocol_mask & NFA_PROTOCOL_MASK_T2T)) {
    134       NFA_TRACE_ERROR0(
    135           "NFA_CeConfigureLocalTag: Cannot emulate Type 1 / Type 2 tag");
    136       return (NFA_STATUS_INVALID_PARAM);
    137     }
    138 
    139     if (uid_len) {
    140       NFA_TRACE_ERROR1(
    141           "NFA_CeConfigureLocalTag: Cannot Set UID for Protocol_mask: 0x%x",
    142           protocol_mask);
    143       return (NFA_STATUS_INVALID_PARAM);
    144     }
    145   }
    146   p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
    147   if (p_msg != NULL) {
    148     p_msg->local_tag.hdr.event = NFA_CE_API_CFG_LOCAL_TAG_EVT;
    149 
    150     /* Copy ndef info */
    151     p_msg->local_tag.protocol_mask = protocol_mask;
    152     p_msg->local_tag.p_ndef_data = p_ndef_data;
    153     p_msg->local_tag.ndef_cur_size = ndef_cur_size;
    154     p_msg->local_tag.ndef_max_size = ndef_max_size;
    155     p_msg->local_tag.read_only = read_only;
    156     p_msg->local_tag.uid_len = uid_len;
    157 
    158     if (uid_len) memcpy(p_msg->local_tag.uid, p_uid, uid_len);
    159 
    160     nfa_sys_sendmsg(p_msg);
    161 
    162     return (NFA_STATUS_OK);
    163   }
    164 
    165   return (NFA_STATUS_FAILED);
    166 }
    167 
    168 /*******************************************************************************
    169 **
    170 ** Function         NFA_CeConfigureUiccListenTech
    171 **
    172 ** Description      Configure listening for the UICC, using the specified
    173 **                  technologies.
    174 **
    175 **                  Events will be notifed using the tNFA_CONN_CBACK
    176 **                  (registered during NFA_Enable)
    177 **
    178 **                  The NFA_CE_UICC_LISTEN_CONFIGURED_EVT reports the status of
    179 **                  the operation.
    180 **
    181 **                  Activation and deactivation are reported using the
    182 **                  NFA_ACTIVATED_EVT and NFA_DEACTIVATED_EVT events
    183 **
    184 ** Note:            If RF discovery is started,
    185 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    186 **                  happen before calling this function
    187 **
    188 ** Returns:
    189 **                  NFA_STATUS_OK, if command accepted
    190 **                  NFA_STATUS_FAILED: otherwise
    191 **
    192 *******************************************************************************/
    193 tNFA_STATUS NFA_CeConfigureUiccListenTech(tNFA_HANDLE ee_handle,
    194                                           tNFA_TECHNOLOGY_MASK tech_mask) {
    195 #if (NFC_NFCEE_INCLUDED == TRUE)
    196   tNFA_CE_MSG* p_msg;
    197 
    198   NFA_TRACE_API1("NFA_CeConfigureUiccListenTech () ee_handle = 0x%x",
    199                  ee_handle);
    200 
    201   /* If tech_mask is zero, then app is disabling listening for specified uicc */
    202   if (tech_mask == 0) {
    203     return (nfa_ce_api_deregister_listen(ee_handle, NFA_CE_LISTEN_INFO_UICC));
    204   }
    205 
    206   /* Otherwise then app is configuring uicc listen for the specificed
    207    * technologies */
    208   p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
    209   if (p_msg != NULL) {
    210     p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
    211     p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_UICC;
    212 
    213     p_msg->reg_listen.ee_handle = ee_handle;
    214     p_msg->reg_listen.tech_mask = tech_mask;
    215 
    216     nfa_sys_sendmsg(p_msg);
    217 
    218     return (NFA_STATUS_OK);
    219   }
    220 #else
    221   NFA_TRACE_ERROR0(
    222       "NFA_CeConfigureUiccListenTech () NFCEE related functions are not "
    223       "enabled!");
    224 #endif
    225   return (NFA_STATUS_FAILED);
    226 }
    227 
    228 /*******************************************************************************
    229 **
    230 ** Function         NFA_CeRegisterFelicaSystemCodeOnDH
    231 **
    232 ** Description      Register listening callback for Felica system code
    233 **
    234 **                  The NFA_CE_REGISTERED_EVT reports the status of the
    235 **                  operation.
    236 **
    237 ** Note:            If RF discovery is started,
    238 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    239 **                  happen before calling this function
    240 **
    241 ** Returns:
    242 **                  NFA_STATUS_OK, if command accepted
    243 **                  NFA_STATUS_FAILED: otherwise
    244 **
    245 *******************************************************************************/
    246 tNFA_STATUS NFA_CeRegisterFelicaSystemCodeOnDH(uint16_t system_code,
    247                                                uint8_t nfcid2[NCI_RF_F_UID_LEN],
    248                                                tNFA_CONN_CBACK* p_conn_cback) {
    249   tNFA_CE_MSG* p_msg;
    250 
    251   NFA_TRACE_API0("NFA_CeRegisterFelicaSystemCodeOnDH ()");
    252 
    253   /* Validate parameters */
    254   if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM);
    255 
    256   p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
    257   if (p_msg != NULL) {
    258     p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
    259     p_msg->reg_listen.p_conn_cback = p_conn_cback;
    260     p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_FELICA;
    261 
    262     /* Listen info */
    263     memcpy(p_msg->reg_listen.nfcid2, nfcid2, NCI_RF_F_UID_LEN);
    264     p_msg->reg_listen.system_code = system_code;
    265 
    266     nfa_sys_sendmsg(p_msg);
    267 
    268     return (NFA_STATUS_OK);
    269   }
    270 
    271   return (NFA_STATUS_FAILED);
    272 }
    273 
    274 /*******************************************************************************
    275 **
    276 ** Function         NFA_CeDeregisterFelicaSystemCodeOnDH
    277 **
    278 ** Description      Deregister listening callback for Felica
    279 **                  (previously registered using
    280 **                  NFA_CeRegisterFelicaSystemCodeOnDH)
    281 **
    282 **                  The NFA_CE_DEREGISTERED_EVT reports the status of the
    283 **                  operation.
    284 **
    285 ** Note:            If RF discovery is started,
    286 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    287 **                  happen before calling this function
    288 **
    289 ** Returns          NFA_STATUS_OK if successfully initiated
    290 **                  NFA_STATUS_BAD_HANDLE if invalid handle
    291 **                  NFA_STATUS_FAILED otherwise
    292 **
    293 *******************************************************************************/
    294 tNFA_STATUS NFA_CeDeregisterFelicaSystemCodeOnDH(tNFA_HANDLE handle) {
    295   NFA_TRACE_API1("NFA_CeDeregisterFelicaSystemCodeOnDH (): handle:0x%X",
    296                  handle);
    297   return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_FELICA));
    298 }
    299 
    300 /*******************************************************************************
    301 **
    302 ** Function         NFA_CeRegisterAidOnDH
    303 **
    304 ** Description      Register listening callback for the specified ISODEP AID
    305 **
    306 **                  The NFA_CE_REGISTERED_EVT reports the status of the
    307 **                  operation.
    308 **
    309 **                  If no AID is specified (aid_len=0), then p_conn_cback will
    310 **                  will get notifications for any AIDs routed to the DH. This
    311 **                  over-rides callbacks registered for specific AIDs.
    312 **
    313 ** Note:            If RF discovery is started,
    314 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    315 **                  happen before calling this function
    316 **
    317 ** Returns:
    318 **                  NFA_STATUS_OK, if command accepted
    319 **                  NFA_STATUS_FAILED: otherwise
    320 **
    321 *******************************************************************************/
    322 tNFA_STATUS NFA_CeRegisterAidOnDH(uint8_t aid[NFC_MAX_AID_LEN], uint8_t aid_len,
    323                                   tNFA_CONN_CBACK* p_conn_cback) {
    324   tNFA_CE_MSG* p_msg;
    325 
    326   NFA_TRACE_API0("NFA_CeRegisterAidOnDH ()");
    327 
    328   /* Validate parameters */
    329   if (p_conn_cback == NULL) return (NFA_STATUS_INVALID_PARAM);
    330 
    331   p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
    332   if (p_msg != NULL) {
    333     p_msg->reg_listen.hdr.event = NFA_CE_API_REG_LISTEN_EVT;
    334     p_msg->reg_listen.p_conn_cback = p_conn_cback;
    335     p_msg->reg_listen.listen_type = NFA_CE_REG_TYPE_ISO_DEP;
    336 
    337     /* Listen info */
    338     memcpy(p_msg->reg_listen.aid, aid, aid_len);
    339     p_msg->reg_listen.aid_len = aid_len;
    340 
    341     nfa_sys_sendmsg(p_msg);
    342 
    343     return (NFA_STATUS_OK);
    344   }
    345 
    346   return (NFA_STATUS_FAILED);
    347 }
    348 
    349 /*******************************************************************************
    350 **
    351 ** Function         NFA_CeDeregisterAidOnDH
    352 **
    353 ** Description      Deregister listening callback for ISODEP AID
    354 **                  (previously registered using NFA_CeRegisterAidOnDH)
    355 **
    356 **                  The NFA_CE_DEREGISTERED_EVT reports the status of the
    357 **                  operation.
    358 **
    359 ** Note:            If RF discovery is started,
    360 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    361 **                  happen before calling this function
    362 **
    363 ** Returns          NFA_STATUS_OK if successfully initiated
    364 **                  NFA_STATUS_BAD_HANDLE if invalid handle
    365 **                  NFA_STATUS_FAILED otherwise
    366 **
    367 *******************************************************************************/
    368 tNFA_STATUS NFA_CeDeregisterAidOnDH(tNFA_HANDLE handle) {
    369   NFA_TRACE_API1("NFA_CeDeregisterAidOnDH (): handle:0x%X", handle);
    370   return (nfa_ce_api_deregister_listen(handle, NFA_CE_LISTEN_INFO_T4T_AID));
    371 }
    372 
    373 /*******************************************************************************
    374 **
    375 ** Function         NFA_CeSetIsoDepListenTech
    376 **
    377 ** Description      Set the technologies (NFC-A and/or NFC-B) to listen for when
    378 **                  NFA_CeConfigureLocalTag or NFA_CeDeregisterAidOnDH are
    379 **                  called.
    380 **
    381 **                  By default (if this API is not called), NFA will listen
    382 **                  for both NFC-A and NFC-B for ISODEP.
    383 **
    384 ** Note:            If listening for ISODEP on UICC, the DH listen callbacks
    385 **                  may still get activate notifications for ISODEP if the
    386 **                  reader/writer selects an AID that is not routed to the UICC
    387 **                  (regardless of whether A or B was disabled using
    388 **                  NFA_CeSetIsoDepListenTech)
    389 **
    390 ** Note:            If RF discovery is started,
    391 **                  NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should
    392 **                  happen before calling this function
    393 **
    394 ** Returns:
    395 **                  NFA_STATUS_OK, if command accepted
    396 **                  NFA_STATUS_FAILED: otherwise
    397 **
    398 *******************************************************************************/
    399 tNFA_STATUS NFA_CeSetIsoDepListenTech(tNFA_TECHNOLOGY_MASK tech_mask) {
    400   tNFA_CE_MSG* p_msg;
    401   tNFA_TECHNOLOGY_MASK use_mask =
    402       (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B);
    403 
    404   NFA_TRACE_API1("NFA_CeSetIsoDepListenTech (): 0x%x", tech_mask);
    405   if (((tech_mask & use_mask) == 0) || ((tech_mask & ~use_mask) != 0)) {
    406     NFA_TRACE_ERROR0("NFA_CeSetIsoDepListenTech: Invalid technology mask");
    407     return (NFA_STATUS_INVALID_PARAM);
    408   }
    409 
    410   p_msg = (tNFA_CE_MSG*)GKI_getbuf((uint16_t)sizeof(tNFA_CE_MSG));
    411   if (p_msg != NULL) {
    412     p_msg->hdr.event = NFA_CE_API_CFG_ISODEP_TECH_EVT;
    413     p_msg->hdr.layer_specific = tech_mask;
    414 
    415     nfa_sys_sendmsg(p_msg);
    416 
    417     return (NFA_STATUS_OK);
    418   }
    419 
    420   return (NFA_STATUS_FAILED);
    421 }
    422