Home | History | Annotate | Download | only in rw
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-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 tag Reader/Writer
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 
     26 #include <android-base/stringprintf.h>
     27 #include <base/logging.h>
     28 
     29 #include "nfa_api.h"
     30 #include "nfa_rw_int.h"
     31 
     32 using android::base::StringPrintf;
     33 
     34 extern bool nfc_debug_enabled;
     35 
     36 /*****************************************************************************
     37 **  Constants
     38 *****************************************************************************/
     39 
     40 /*****************************************************************************
     41 **  APIs
     42 *****************************************************************************/
     43 
     44 /*******************************************************************************
     45 **
     46 ** Function         NFA_RwDetectNDef
     47 **
     48 ** Description      Perform the NDEF detection procedure  using the appropriate
     49 **                  method for the currently activated tag.
     50 **
     51 **                  Upon successful completion of NDEF detection, a
     52 **                  NFA_NDEF_DETECT_EVT will be sent, to notify the application
     53 **                  of the NDEF attributes (NDEF total memory size, current
     54 **                  size, etc.).
     55 **
     56 **                  It is not mandatory to call this function -  NFA_RwReadNDef
     57 **                  and NFA_RwWriteNDef will perform NDEF detection internally
     58 **                  if not performed already. This API may be called to get a
     59 **                  tag's NDEF size before issuing a write-request.
     60 **
     61 ** Returns:
     62 **                  NFA_STATUS_OK if successfully initiated
     63 **                  NFC_STATUS_REFUSED if tag does not support NDEF
     64 **                  NFA_STATUS_FAILED otherwise
     65 **
     66 *******************************************************************************/
     67 tNFA_STATUS NFA_RwDetectNDef(void) {
     68   tNFA_RW_OPERATION* p_msg;
     69 
     70   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
     71 
     72   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
     73   if (p_msg != NULL) {
     74     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
     75     p_msg->op = NFA_RW_OP_DETECT_NDEF;
     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_RwReadNDef
     88 **
     89 ** Description      Read NDEF message from tag. This function will internally
     90 **                  perform the NDEF detection procedure (if not performed
     91 **                  previously), and read the NDEF tag data using the
     92 **                  appropriate method for the currently activated tag.
     93 **
     94 **                  Upon successful completion of NDEF detection (if performed),
     95 **                  a NFA_NDEF_DETECT_EVT will be sent, to notify the
     96 **                  application of the NDEF attributes (NDEF total memory size,
     97 **                  current size, etc.).
     98 **
     99 **                  Upon receiving the NDEF message, the message will be sent to
    100 **                  the handler registered with NFA_RegisterNDefTypeHandler or
    101 **                  NFA_RequestExclusiveRfControl (if exclusive RF mode is
    102 **                  active)
    103 **
    104 ** Returns:
    105 **                  NFA_STATUS_OK if successfully initiated
    106 **                  NFC_STATUS_REFUSED if tag does not support NDEF
    107 **                  NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the
    108 **                  tag
    109 **                  NFA_STATUS_FAILED otherwise
    110 **
    111 *******************************************************************************/
    112 tNFA_STATUS NFA_RwReadNDef(void) {
    113   tNFA_RW_OPERATION* p_msg;
    114 
    115   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    116 
    117   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    118   if (p_msg != NULL) {
    119     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    120     p_msg->op = NFA_RW_OP_READ_NDEF;
    121 
    122     nfa_sys_sendmsg(p_msg);
    123 
    124     return (NFA_STATUS_OK);
    125   }
    126 
    127   return (NFA_STATUS_FAILED);
    128 }
    129 
    130 /*******************************************************************************
    131 **
    132 ** Function         NFA_RwWriteNDef
    133 **
    134 ** Description      Write NDEF data to the activated tag. This function will
    135 **                  internally perform NDEF detection if necessary, and write
    136 **                  the NDEF tag data using the appropriate method for the
    137 **                  currently activated tag.
    138 **
    139 **                  When the entire message has been written, or if an error
    140 **                  occurs, the app will be notified with NFA_WRITE_CPLT_EVT.
    141 **
    142 **                  p_data needs to be persistent until NFA_WRITE_CPLT_EVT
    143 **
    144 **
    145 ** Returns:
    146 **                  NFA_STATUS_OK if successfully initiated
    147 **                  NFC_STATUS_REFUSED if tag does not support NDEF/locked
    148 **                  NFA_STATUS_FAILED otherwise
    149 **
    150 *******************************************************************************/
    151 tNFA_STATUS NFA_RwWriteNDef(uint8_t* p_data, uint32_t len) {
    152   tNFA_RW_OPERATION* p_msg;
    153 
    154   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("ndef len: %i", len);
    155 
    156   /* Validate parameters */
    157   if (p_data == NULL) return (NFA_STATUS_INVALID_PARAM);
    158 
    159   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    160   if (p_msg != NULL) {
    161     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    162     p_msg->op = NFA_RW_OP_WRITE_NDEF;
    163     p_msg->params.write_ndef.len = len;
    164     p_msg->params.write_ndef.p_data = p_data;
    165     nfa_sys_sendmsg(p_msg);
    166 
    167     return (NFA_STATUS_OK);
    168   }
    169 
    170   return (NFA_STATUS_FAILED);
    171 }
    172 
    173 /*****************************************************************************
    174 **
    175 ** Function         NFA_RwPresenceCheck
    176 **
    177 ** Description      Check if the tag is still in the field.
    178 **
    179 **                  The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
    180 **                  indicate presence or non-presence.
    181 **
    182 **                  option is used only with ISO-DEP protocol
    183 **
    184 ** Returns
    185 **                  NFA_STATUS_OK if successfully initiated
    186 **                  NFA_STATUS_FAILED otherwise
    187 **
    188 *****************************************************************************/
    189 tNFA_STATUS NFA_RwPresenceCheck(tNFA_RW_PRES_CHK_OPTION option) {
    190   tNFA_RW_OPERATION* p_msg;
    191 
    192   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    193 
    194   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    195   if (p_msg != NULL) {
    196     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    197     p_msg->op = NFA_RW_OP_PRESENCE_CHECK;
    198     p_msg->params.option = option;
    199 
    200     nfa_sys_sendmsg(p_msg);
    201 
    202     return (NFA_STATUS_OK);
    203   }
    204 
    205   return (NFA_STATUS_FAILED);
    206 }
    207 
    208 /*****************************************************************************
    209 **
    210 ** Function         NFA_RwFormatTag
    211 **
    212 ** Description      Check if the tag is NDEF Formatable. If yes Format the tag
    213 **
    214 **                  The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
    215 **                  indicate if tag is successfully formated or not
    216 **
    217 ** Returns
    218 **                  NFA_STATUS_OK if successfully initiated
    219 **                  NFA_STATUS_FAILED otherwise
    220 **
    221 *****************************************************************************/
    222 tNFA_STATUS NFA_RwFormatTag(void) {
    223   tNFA_RW_OPERATION* p_msg;
    224 
    225   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    226 
    227   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    228   if (p_msg != NULL) {
    229     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    230     p_msg->op = NFA_RW_OP_FORMAT_TAG;
    231 
    232     nfa_sys_sendmsg(p_msg);
    233 
    234     return (NFA_STATUS_OK);
    235   }
    236 
    237   return (NFA_STATUS_FAILED);
    238 }
    239 
    240 /*******************************************************************************
    241 **
    242 ** Function         NFA_RwSetTagReadOnly
    243 **
    244 ** Description:
    245 **      Sets tag as read only.
    246 **
    247 **      When tag is set as read only, or if an error occurs, the app will be
    248 **      notified with NFA_SET_TAG_RO_EVT.
    249 **
    250 ** Returns:
    251 **      NFA_STATUS_OK if successfully initiated
    252 **      NFA_STATUS_REJECTED if protocol is not T1/T2/T5T
    253 **                 (or) if hard lock is not requested for protocol T5T
    254 **      NFA_STATUS_FAILED otherwise
    255 **
    256 *******************************************************************************/
    257 tNFA_STATUS NFA_RwSetTagReadOnly(bool b_hard_lock) {
    258   tNFA_RW_OPERATION* p_msg;
    259   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
    260 
    261   if ((protocol != NFC_PROTOCOL_T1T) && (protocol != NFC_PROTOCOL_T2T) &&
    262       (protocol != NFC_PROTOCOL_T5T) && (protocol != NFC_PROTOCOL_ISO_DEP) &&
    263       (protocol != NFC_PROTOCOL_T3T)) {
    264     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
    265         "Cannot Configure as read only for Protocol: "
    266         "%d",
    267         protocol);
    268     return (NFA_STATUS_REJECTED);
    269   }
    270 
    271   if ((!b_hard_lock && (protocol == NFC_PROTOCOL_T5T)) ||
    272       (b_hard_lock && (protocol == NFC_PROTOCOL_ISO_DEP))) {
    273     DLOG_IF(INFO, nfc_debug_enabled)
    274         << StringPrintf("Cannot %s for Protocol: %d",
    275                         b_hard_lock ? "Hard lock" : "Soft lock", protocol);
    276     return (NFA_STATUS_REJECTED);
    277   }
    278 
    279   DLOG_IF(INFO, nfc_debug_enabled)
    280       << StringPrintf("%s", b_hard_lock ? "Hard lock" : "Soft lock");
    281 
    282   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    283   if (p_msg != NULL) {
    284     /* Fill in tNFA_RW_OPERATION struct */
    285     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    286     p_msg->op = NFA_RW_OP_SET_TAG_RO;
    287     p_msg->params.set_readonly.b_hard_lock = b_hard_lock;
    288 
    289     nfa_sys_sendmsg(p_msg);
    290     return (NFA_STATUS_OK);
    291   }
    292   return (NFA_STATUS_FAILED);
    293 }
    294 
    295 /*******************************************************************************
    296 ** Tag specific APIs
    297 ** (note: for Type-4 tags, use NFA_SendRawFrame to exchange APDUs)
    298 *******************************************************************************/
    299 
    300 /*******************************************************************************
    301 **
    302 ** Function         NFA_RwLocateTlv
    303 **
    304 ** Description:
    305 **      Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
    306 **
    307 **      Data is returned to the application using the NFA_TLV_DETECT_EVT. When
    308 **      search operation has completed, or if an error occurs, the app will be
    309 **      notified with NFA_TLV_DETECT_EVT.
    310 **
    311 ** Description      Perform the TLV detection procedure  using the appropriate
    312 **                  method for the currently activated tag.
    313 **
    314 **                  Upon successful completion of TLV detection in T1/T2 tag, a
    315 **                  NFA_TLV_DETECT_EVT will be sent, to notify the application
    316 **                  of the TLV attributes (total lock/reserved bytes etc.).
    317 **                  However if the TLV type specified is NDEF then it is same as
    318 **                  calling NFA_RwDetectNDef and should expect to receive
    319 **                  NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
    320 **
    321 **                  It is not mandatory to call this function -
    322 **                  NFA_RwDetectNDef, NFA_RwReadNDef and NFA_RwWriteNDef will
    323 **                  perform TLV detection internally if not performed already.
    324 **                  An application may call this API to check the a
    325 **                  tag/card-emulator's total Reserved/
    326 **                  Lock bytes before issuing a write-request.
    327 **
    328 ** Returns:
    329 **                  NFA_STATUS_OK if successfully initiated
    330 **                  NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support
    331 **                  NDEF
    332 **                  NFA_STATUS_FAILED otherwise
    333 **
    334 *******************************************************************************/
    335 tNFA_STATUS NFA_RwLocateTlv(uint8_t tlv_type) {
    336   tNFA_RW_OPERATION* p_msg;
    337 
    338   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    339 
    340   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    341   if (p_msg != NULL) {
    342     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    343 
    344     if (tlv_type == TAG_LOCK_CTRL_TLV) {
    345       p_msg->op = NFA_RW_OP_DETECT_LOCK_TLV;
    346     } else if (tlv_type == TAG_MEM_CTRL_TLV) {
    347       p_msg->op = NFA_RW_OP_DETECT_MEM_TLV;
    348     } else if (tlv_type == TAG_NDEF_TLV) {
    349       p_msg->op = NFA_RW_OP_DETECT_NDEF;
    350     } else
    351       return (NFA_STATUS_FAILED);
    352 
    353     nfa_sys_sendmsg(p_msg);
    354 
    355     return (NFA_STATUS_OK);
    356   }
    357 
    358   return (NFA_STATUS_FAILED);
    359 }
    360 
    361 /*******************************************************************************
    362 **
    363 ** Function         NFA_RwT1tRid
    364 **
    365 ** Description:
    366 **      Send a RID command to the activated Type 1 tag.
    367 **
    368 **      Data is returned to the application using the NFA_DATA_EVT. When the
    369 **      read operation has completed, or if an error occurs, the app will be
    370 **      notified with NFA_READ_CPLT_EVT.
    371 **
    372 ** Returns:
    373 **      NFA_STATUS_OK if successfully initiated
    374 **      NFA_STATUS_FAILED otherwise
    375 **
    376 *******************************************************************************/
    377 tNFA_STATUS NFA_RwT1tRid(void) {
    378   tNFA_RW_OPERATION* p_msg;
    379 
    380   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    381   if (p_msg != NULL) {
    382     /* Fill in tNFA_RW_OPERATION struct */
    383     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    384     p_msg->op = NFA_RW_OP_T1T_RID;
    385 
    386     nfa_sys_sendmsg(p_msg);
    387     return (NFA_STATUS_OK);
    388   }
    389   return (NFA_STATUS_FAILED);
    390 }
    391 
    392 /*******************************************************************************
    393 **
    394 ** Function         NFA_RwT1tReadAll
    395 **
    396 ** Description:
    397 **      Send a RALL command to the activated Type 1 tag.
    398 **
    399 **      Data is returned to the application using the NFA_DATA_EVT. When the
    400 **      read operation has completed, or if an error occurs, the app will be
    401 **      notified with NFA_READ_CPLT_EVT.
    402 **
    403 ** Returns:
    404 **      NFA_STATUS_OK if successfully initiated
    405 **      NFA_STATUS_FAILED otherwise
    406 **
    407 *******************************************************************************/
    408 tNFA_STATUS NFA_RwT1tReadAll(void) {
    409   tNFA_RW_OPERATION* p_msg;
    410 
    411   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    412   if (p_msg != NULL) {
    413     /* Fill in tNFA_RW_OPERATION struct */
    414     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    415     p_msg->op = NFA_RW_OP_T1T_RALL;
    416 
    417     nfa_sys_sendmsg(p_msg);
    418     return (NFA_STATUS_OK);
    419   }
    420   return (NFA_STATUS_FAILED);
    421 }
    422 
    423 /*******************************************************************************
    424 **
    425 ** Function         NFA_RwT1tRead
    426 **
    427 ** Description:
    428 **      Send a READ command to the activated Type 1 tag.
    429 **
    430 **      Data is returned to the application using the NFA_DATA_EVT. When the
    431 **      read operation has completed, or if an error occurs, the app will be
    432 **      notified with NFA_READ_CPLT_EVT.
    433 **
    434 ** Returns:
    435 **      NFA_STATUS_OK if successfully initiated
    436 **      NFA_STATUS_FAILED otherwise
    437 **
    438 *******************************************************************************/
    439 tNFA_STATUS NFA_RwT1tRead(uint8_t block_number, uint8_t index) {
    440   tNFA_RW_OPERATION* p_msg;
    441 
    442   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    443   if (p_msg != NULL) {
    444     /* Fill in tNFA_RW_OPERATION struct */
    445     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    446     p_msg->op = NFA_RW_OP_T1T_READ;
    447     p_msg->params.t1t_read.block_number = block_number;
    448     p_msg->params.t1t_read.index = index;
    449 
    450     nfa_sys_sendmsg(p_msg);
    451     return (NFA_STATUS_OK);
    452   }
    453   return (NFA_STATUS_FAILED);
    454 }
    455 
    456 /*******************************************************************************
    457 **
    458 ** Function         NFA_RwT1tWrite
    459 **
    460 ** Description:
    461 **      Send a WRITE command to the activated Type 1 tag.
    462 **
    463 **      Data is returned to the application using the NFA_DATA_EVT. When the
    464 **      write operation has completed, or if an error occurs, the app will be
    465 **      notified with NFA_WRITE_CPLT_EVT.
    466 **
    467 ** Returns:
    468 **      NFA_STATUS_OK if successfully initiated
    469 **      NFA_STATUS_FAILED otherwise
    470 **
    471 *******************************************************************************/
    472 tNFA_STATUS NFA_RwT1tWrite(uint8_t block_number, uint8_t index, uint8_t data,
    473                            bool b_erase) {
    474   tNFA_RW_OPERATION* p_msg;
    475 
    476   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    477   if (p_msg != NULL) {
    478     /* Fill in tNFA_RW_OPERATION struct */
    479     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    480     p_msg->params.t1t_write.b_erase = b_erase;
    481     p_msg->op = NFA_RW_OP_T1T_WRITE;
    482     p_msg->params.t1t_write.block_number = block_number;
    483     p_msg->params.t1t_write.index = index;
    484     p_msg->params.t1t_write.p_block_data[0] = data;
    485 
    486     nfa_sys_sendmsg(p_msg);
    487     return (NFA_STATUS_OK);
    488   }
    489   return (NFA_STATUS_FAILED);
    490 }
    491 
    492 /*******************************************************************************
    493 **
    494 ** Function         NFA_RwT1tReadSeg
    495 **
    496 ** Description:
    497 **      Send a RSEG command to the activated Type 1 tag.
    498 **
    499 **      Data is returned to the application using the NFA_DATA_EVT. When the
    500 **      read operation has completed, or if an error occurs, the app will be
    501 **      notified with NFA_READ_CPLT_EVT.
    502 **
    503 ** Returns:
    504 **      NFA_STATUS_OK if successfully initiated
    505 **      NFA_STATUS_FAILED otherwise
    506 **
    507 *******************************************************************************/
    508 tNFA_STATUS NFA_RwT1tReadSeg(uint8_t segment_number) {
    509   tNFA_RW_OPERATION* p_msg;
    510 
    511   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    512   if (p_msg != NULL) {
    513     /* Fill in tNFA_RW_OPERATION struct */
    514     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    515     p_msg->op = NFA_RW_OP_T1T_RSEG;
    516     p_msg->params.t1t_read.segment_number = segment_number;
    517 
    518     nfa_sys_sendmsg(p_msg);
    519     return (NFA_STATUS_OK);
    520   }
    521   return (NFA_STATUS_FAILED);
    522 }
    523 
    524 /*******************************************************************************
    525 **
    526 ** Function         NFA_RwT1tRead8
    527 **
    528 ** Description:
    529 **      Send a READ8 command to the activated Type 1 tag.
    530 **
    531 **      Data is returned to the application using the NFA_DATA_EVT. When the
    532 **      read operation has completed, or if an error occurs, the app will be
    533 **      notified with NFA_READ_CPLT_EVT.
    534 **
    535 ** Returns:
    536 **      NFA_STATUS_OK if successfully initiated
    537 **      NFA_STATUS_FAILED otherwise
    538 **
    539 *******************************************************************************/
    540 tNFA_STATUS NFA_RwT1tRead8(uint8_t block_number) {
    541   tNFA_RW_OPERATION* p_msg;
    542 
    543   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    544   if (p_msg != NULL) {
    545     /* Fill in tNFA_RW_OPERATION struct */
    546     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    547     p_msg->op = NFA_RW_OP_T1T_READ8;
    548     p_msg->params.t1t_write.block_number = block_number;
    549 
    550     nfa_sys_sendmsg(p_msg);
    551     return (NFA_STATUS_OK);
    552   }
    553   return (NFA_STATUS_FAILED);
    554 }
    555 
    556 /*******************************************************************************
    557 **
    558 ** Function         NFA_RwT1tWrite8
    559 **
    560 ** Description:
    561 **      Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
    562 **
    563 **      Data is returned to the application using the NFA_DATA_EVT. When the
    564 **      read operation has completed, or if an error occurs, the app will be
    565 **      notified with NFA_READ_CPLT_EVT.
    566 **
    567 ** Returns:
    568 **      NFA_STATUS_OK if successfully initiated
    569 **      NFA_STATUS_FAILED otherwise
    570 **
    571 *******************************************************************************/
    572 tNFA_STATUS NFA_RwT1tWrite8(uint8_t block_number, uint8_t* p_data,
    573                             bool b_erase) {
    574   tNFA_RW_OPERATION* p_msg;
    575 
    576   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    577   if (p_msg != NULL) {
    578     /* Fill in tNFA_RW_OPERATION struct */
    579     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    580     p_msg->params.t1t_write.b_erase = b_erase;
    581     p_msg->op = NFA_RW_OP_T1T_WRITE8;
    582     p_msg->params.t1t_write.block_number = block_number;
    583 
    584     memcpy(p_msg->params.t1t_write.p_block_data, p_data, 8);
    585 
    586     nfa_sys_sendmsg(p_msg);
    587     return (NFA_STATUS_OK);
    588   }
    589   return (NFA_STATUS_FAILED);
    590 }
    591 
    592 /*******************************************************************************
    593 **
    594 ** Function         NFA_RwT2tRead
    595 **
    596 ** Description:
    597 **      Send a READ command to the activated Type 2 tag.
    598 **
    599 **      Data is returned to the application using the NFA_DATA_EVT. When the
    600 **      read operation has completed, or if an error occurs, the app will be
    601 **      notified with NFA_READ_CPLT_EVT.
    602 **
    603 ** Returns:
    604 **      NFA_STATUS_OK if successfully initiated
    605 **      NFA_STATUS_FAILED otherwise
    606 **
    607 *******************************************************************************/
    608 tNFA_STATUS NFA_RwT2tRead(uint8_t block_number) {
    609   tNFA_RW_OPERATION* p_msg;
    610 
    611   DLOG_IF(INFO, nfc_debug_enabled)
    612       << StringPrintf("Block to read: %d", block_number);
    613 
    614   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    615   if (p_msg != NULL) {
    616     /* Fill in tNFA_RW_OPERATION struct */
    617     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    618     p_msg->op = NFA_RW_OP_T2T_READ;
    619     p_msg->params.t2t_read.block_number = block_number;
    620 
    621     nfa_sys_sendmsg(p_msg);
    622     return (NFA_STATUS_OK);
    623   }
    624   return (NFA_STATUS_FAILED);
    625 }
    626 
    627 /*******************************************************************************
    628 **
    629 ** Function         NFA_RwT2tWrite
    630 **
    631 ** Description:
    632 **      Send an WRITE command to the activated Type 2 tag.
    633 **
    634 **      When the write operation has completed (or if an error occurs), the
    635 **      app will be notified with NFA_WRITE_CPLT_EVT.
    636 **
    637 ** Returns:
    638 **      NFA_STATUS_OK if successfully initiated
    639 **      NFA_STATUS_FAILED otherwise
    640 **
    641 *******************************************************************************/
    642 tNFA_STATUS NFA_RwT2tWrite(uint8_t block_number, uint8_t* p_data) {
    643   tNFA_RW_OPERATION* p_msg;
    644 
    645   DLOG_IF(INFO, nfc_debug_enabled)
    646       << StringPrintf("Block to write: %d", block_number);
    647 
    648   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    649   if (p_msg != NULL) {
    650     /* Fill in tNFA_RW_OPERATION struct */
    651     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    652     p_msg->op = NFA_RW_OP_T2T_WRITE;
    653 
    654     p_msg->params.t2t_write.block_number = block_number;
    655 
    656     memcpy(p_msg->params.t2t_write.p_block_data, p_data, 4);
    657 
    658     nfa_sys_sendmsg(p_msg);
    659     return (NFA_STATUS_OK);
    660   }
    661   return (NFA_STATUS_FAILED);
    662 }
    663 
    664 /*******************************************************************************
    665 **
    666 ** Function         NFA_RwT2tSectorSelect
    667 **
    668 ** Description:
    669 **      Send SECTOR SELECT command to the activated Type 2 tag.
    670 **
    671 **      When the sector select operation has completed (or if an error occurs),
    672 **      the app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
    673 **
    674 ** Returns:
    675 **      NFA_STATUS_OK if successfully initiated
    676 **      NFA_STATUS_FAILED otherwise
    677 **
    678 *******************************************************************************/
    679 tNFA_STATUS NFA_RwT2tSectorSelect(uint8_t sector_number) {
    680   tNFA_RW_OPERATION* p_msg;
    681 
    682   DLOG_IF(INFO, nfc_debug_enabled)
    683       << StringPrintf("sector to select: %d", sector_number);
    684 
    685   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    686   if (p_msg != NULL) {
    687     /* Fill in tNFA_RW_OPERATION struct */
    688     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    689     p_msg->op = NFA_RW_OP_T2T_SECTOR_SELECT;
    690 
    691     p_msg->params.t2t_sector_select.sector_number = sector_number;
    692 
    693     nfa_sys_sendmsg(p_msg);
    694     return (NFA_STATUS_OK);
    695   }
    696   return (NFA_STATUS_FAILED);
    697 }
    698 
    699 /*******************************************************************************
    700 **
    701 ** Function         NFA_RwT3tRead
    702 **
    703 ** Description:
    704 **      Send a CHECK (read) command to the activated Type 3 tag.
    705 **
    706 **      Data is returned to the application using the NFA_DATA_EVT. When the
    707 **      read operation has completed, or if an error occurs, the app will be
    708 **      notified with NFA_READ_CPLT_EVT.
    709 **
    710 ** Returns:
    711 **      NFA_STATUS_OK if successfully initiated
    712 **      NFA_STATUS_FAILED otherwise
    713 **
    714 *******************************************************************************/
    715 tNFA_STATUS NFA_RwT3tRead(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks) {
    716   tNFA_RW_OPERATION* p_msg;
    717   uint8_t* p_block_desc;
    718 
    719   DLOG_IF(INFO, nfc_debug_enabled)
    720       << StringPrintf("num_blocks to read: %i", num_blocks);
    721 
    722   /* Validate parameters */
    723   if ((num_blocks == 0) || (t3t_blocks == NULL))
    724     return (NFA_STATUS_INVALID_PARAM);
    725 
    726   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(
    727       sizeof(tNFA_RW_OPERATION) + (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC))));
    728   if (p_msg != NULL) {
    729     /* point to area after tNFA_RW_OPERATION */
    730     p_block_desc = (uint8_t*)(p_msg + 1);
    731 
    732     /* Fill in tNFA_RW_OPERATION struct */
    733     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    734     p_msg->op = NFA_RW_OP_T3T_READ;
    735 
    736     p_msg->params.t3t_read.num_blocks = num_blocks;
    737     p_msg->params.t3t_read.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
    738 
    739     /* Copy block descriptor list */
    740     memcpy(p_block_desc, t3t_blocks,
    741            (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
    742 
    743     nfa_sys_sendmsg(p_msg);
    744 
    745     return (NFA_STATUS_OK);
    746   }
    747 
    748   return (NFA_STATUS_FAILED);
    749 }
    750 
    751 /*******************************************************************************
    752 **
    753 ** Function         NFA_RwT3tWrite
    754 **
    755 ** Description:
    756 **      Send an UPDATE (write) command to the activated Type 3 tag.
    757 **
    758 **      When the write operation has completed (or if an error occurs), the
    759 **      app will be notified with NFA_WRITE_CPLT_EVT.
    760 **
    761 ** Returns:
    762 **      NFA_STATUS_OK if successfully initiated
    763 **      NFA_STATUS_FAILED otherwise
    764 **
    765 *******************************************************************************/
    766 tNFA_STATUS NFA_RwT3tWrite(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks,
    767                            uint8_t* p_data) {
    768   tNFA_RW_OPERATION* p_msg;
    769   uint8_t *p_block_desc, *p_data_area;
    770 
    771   DLOG_IF(INFO, nfc_debug_enabled)
    772       << StringPrintf("num_blocks to write: %i", num_blocks);
    773 
    774   /* Validate parameters */
    775   if ((num_blocks == 0) || (t3t_blocks == NULL) | (p_data == NULL))
    776     return (NFA_STATUS_INVALID_PARAM);
    777 
    778   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
    779       (uint16_t)(sizeof(tNFA_RW_OPERATION) +
    780                  (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC) + 16))));
    781   if (p_msg != NULL) {
    782     /* point to block descriptor and data areas after tNFA_RW_OPERATION */
    783     p_block_desc = (uint8_t*)(p_msg + 1);
    784     p_data_area = p_block_desc + (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC)));
    785 
    786     /* Fill in tNFA_RW_OPERATION struct */
    787     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    788     p_msg->op = NFA_RW_OP_T3T_WRITE;
    789 
    790     p_msg->params.t3t_write.num_blocks = num_blocks;
    791     p_msg->params.t3t_write.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
    792     p_msg->params.t3t_write.p_block_data = p_data_area;
    793 
    794     /* Copy block descriptor list */
    795     memcpy(p_block_desc, t3t_blocks,
    796            (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
    797 
    798     /* Copy data */
    799     memcpy(p_data_area, p_data, (num_blocks * 16));
    800 
    801     nfa_sys_sendmsg(p_msg);
    802 
    803     return (NFA_STATUS_OK);
    804   }
    805 
    806   return (NFA_STATUS_FAILED);
    807 }
    808 
    809 /*******************************************************************************
    810 **
    811 ** Function         NFA_RwI93Inventory
    812 **
    813 ** Description:
    814 **      Send Inventory command to the activated ISO T5T tag with/without AFI
    815 **      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
    816 **
    817 **      When the operation has completed (or if an error occurs), the
    818 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
    819 **
    820 ** Returns:
    821 **      NFA_STATUS_OK if successfully initiated
    822 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
    823 **      NFA_STATUS_FAILED otherwise
    824 **
    825 *******************************************************************************/
    826 tNFA_STATUS NFA_RwI93Inventory(bool afi_present, uint8_t afi, uint8_t* p_uid) {
    827   tNFA_RW_OPERATION* p_msg;
    828 
    829   DLOG_IF(INFO, nfc_debug_enabled)
    830       << StringPrintf("afi_present:%d, AFI: 0x%02X", afi_present, afi);
    831 
    832   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
    833     return (NFA_STATUS_WRONG_PROTOCOL);
    834   }
    835 
    836   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    837   if (p_msg != NULL) {
    838     /* Fill in tNFA_RW_OPERATION struct */
    839     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    840     p_msg->op = NFA_RW_OP_I93_INVENTORY;
    841 
    842     p_msg->params.i93_cmd.afi_present = afi_present;
    843     p_msg->params.i93_cmd.afi = afi;
    844 
    845     if (p_uid) {
    846       p_msg->params.i93_cmd.uid_present = true;
    847       memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
    848     } else {
    849       p_msg->params.i93_cmd.uid_present = false;
    850     }
    851 
    852     nfa_sys_sendmsg(p_msg);
    853 
    854     return (NFA_STATUS_OK);
    855   }
    856 
    857   return (NFA_STATUS_FAILED);
    858 }
    859 
    860 /*******************************************************************************
    861 **
    862 ** Function         NFA_RwI93StayQuiet
    863 **
    864 ** Description:
    865 **      Send Stay Quiet command to the activated T5T tag.
    866 **
    867 **      When the operation has completed (or if an error occurs), the
    868 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
    869 **
    870 ** Returns:
    871 **      NFA_STATUS_OK if successfully initiated
    872 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
    873 **      NFA_STATUS_FAILED otherwise
    874 **
    875 *******************************************************************************/
    876 tNFA_STATUS NFA_RwI93StayQuiet(void) {
    877   tNFA_RW_OPERATION* p_msg;
    878 
    879   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
    880 
    881   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
    882     return (NFA_STATUS_WRONG_PROTOCOL);
    883   }
    884 
    885   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    886   if (p_msg != NULL) {
    887     /* Fill in tNFA_RW_OPERATION struct */
    888     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    889     p_msg->op = NFA_RW_OP_I93_STAY_QUIET;
    890 
    891     nfa_sys_sendmsg(p_msg);
    892 
    893     return (NFA_STATUS_OK);
    894   }
    895 
    896   return (NFA_STATUS_FAILED);
    897 }
    898 
    899 /*******************************************************************************
    900 **
    901 ** Function         NFA_RwI93ReadSingleBlock
    902 **
    903 ** Description:
    904 **      Send Read Single Block command to the activated T5T tag.
    905 **
    906 **      Data is returned to the application using the NFA_DATA_EVT. When the
    907 **      read operation has completed, or if an error occurs, the app will be
    908 **      notified with NFA_I93_CMD_CPLT_EVT.
    909 **
    910 ** Returns:
    911 **      NFA_STATUS_OK if successfully initiated
    912 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
    913 **      NFA_STATUS_FAILED otherwise
    914 **
    915 *******************************************************************************/
    916 tNFA_STATUS NFA_RwI93ReadSingleBlock(uint8_t block_number) {
    917   tNFA_RW_OPERATION* p_msg;
    918 
    919   DLOG_IF(INFO, nfc_debug_enabled)
    920       << StringPrintf("block_number: 0x%02X", block_number);
    921 
    922   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
    923     return (NFA_STATUS_WRONG_PROTOCOL);
    924   }
    925 
    926   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
    927   if (p_msg != NULL) {
    928     /* Fill in tNFA_RW_OPERATION struct */
    929     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    930     p_msg->op = NFA_RW_OP_I93_READ_SINGLE_BLOCK;
    931 
    932     p_msg->params.i93_cmd.first_block_number = block_number;
    933 
    934     nfa_sys_sendmsg(p_msg);
    935 
    936     return (NFA_STATUS_OK);
    937   }
    938 
    939   return (NFA_STATUS_FAILED);
    940 }
    941 
    942 /*******************************************************************************
    943 **
    944 ** Function         NFA_RwI93WriteSingleBlock
    945 **
    946 ** Description:
    947 **      Send Write Single Block command to the activated T5T tag.
    948 **
    949 **      When the write operation has completed (or if an error occurs), the
    950 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
    951 **
    952 ** Returns:
    953 **      NFA_STATUS_OK if successfully initiated
    954 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
    955 **      NFA_STATUS_FAILED otherwise
    956 **
    957 *******************************************************************************/
    958 tNFA_STATUS NFA_RwI93WriteSingleBlock(uint8_t block_number, uint8_t* p_data) {
    959   tNFA_RW_OPERATION* p_msg;
    960 
    961   DLOG_IF(INFO, nfc_debug_enabled)
    962       << StringPrintf("block_number: 0x%02X", block_number);
    963 
    964   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
    965     return (NFA_STATUS_WRONG_PROTOCOL);
    966   }
    967 
    968   /* we don't know block size of tag */
    969   if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
    970     return (NFA_STATUS_FAILED);
    971   }
    972 
    973   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
    974       (uint16_t)(sizeof(tNFA_RW_OPERATION) + nfa_rw_cb.i93_block_size));
    975   if (p_msg != NULL) {
    976     /* Fill in tNFA_RW_OPERATION struct */
    977     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
    978     p_msg->op = NFA_RW_OP_I93_WRITE_SINGLE_BLOCK;
    979 
    980     p_msg->params.i93_cmd.first_block_number = block_number;
    981     p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
    982 
    983     memcpy(p_msg->params.i93_cmd.p_data, p_data, nfa_rw_cb.i93_block_size);
    984 
    985     nfa_sys_sendmsg(p_msg);
    986 
    987     return (NFA_STATUS_OK);
    988   }
    989 
    990   return (NFA_STATUS_FAILED);
    991 }
    992 
    993 /*******************************************************************************
    994 **
    995 ** Function         NFA_RwI93LockBlock
    996 **
    997 ** Description:
    998 **      Send Lock block command to the activated T5T tag.
    999 **
   1000 **      When the operation has completed (or if an error occurs), the
   1001 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1002 **
   1003 ** Returns:
   1004 **      NFA_STATUS_OK if successfully initiated
   1005 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1006 **      NFA_STATUS_FAILED otherwise
   1007 **
   1008 *******************************************************************************/
   1009 tNFA_STATUS NFA_RwI93LockBlock(uint8_t block_number) {
   1010   tNFA_RW_OPERATION* p_msg;
   1011 
   1012   DLOG_IF(INFO, nfc_debug_enabled)
   1013       << StringPrintf("block_number: 0x%02X", block_number);
   1014 
   1015   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1016     return (NFA_STATUS_WRONG_PROTOCOL);
   1017   }
   1018 
   1019   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1020   if (p_msg != NULL) {
   1021     /* Fill in tNFA_RW_OPERATION struct */
   1022     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1023     p_msg->op = NFA_RW_OP_I93_LOCK_BLOCK;
   1024 
   1025     p_msg->params.i93_cmd.first_block_number = block_number;
   1026 
   1027     nfa_sys_sendmsg(p_msg);
   1028 
   1029     return (NFA_STATUS_OK);
   1030   }
   1031 
   1032   return (NFA_STATUS_FAILED);
   1033 }
   1034 
   1035 /*******************************************************************************
   1036 **
   1037 ** Function         NFA_RwI93ReadMultipleBlocks
   1038 **
   1039 ** Description:
   1040 **      Send Read Multiple Block command to the activated T5T tag.
   1041 **
   1042 **      Data is returned to the application using the NFA_DATA_EVT. When the
   1043 **      read operation has completed, or if an error occurs, the app will be
   1044 **      notified with NFA_I93_CMD_CPLT_EVT.
   1045 **
   1046 ** Returns:
   1047 **      NFA_STATUS_OK if successfully initiated
   1048 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1049 **      NFA_STATUS_FAILED otherwise
   1050 **
   1051 *******************************************************************************/
   1052 tNFA_STATUS NFA_RwI93ReadMultipleBlocks(uint8_t first_block_number,
   1053                                         uint16_t number_blocks) {
   1054   tNFA_RW_OPERATION* p_msg;
   1055 
   1056   DLOG_IF(INFO, nfc_debug_enabled)
   1057       << StringPrintf("%d, %d", first_block_number, number_blocks);
   1058 
   1059   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1060     return (NFA_STATUS_WRONG_PROTOCOL);
   1061   }
   1062 
   1063   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1064   if (p_msg != NULL) {
   1065     /* Fill in tNFA_RW_OPERATION struct */
   1066     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1067     p_msg->op = NFA_RW_OP_I93_READ_MULTI_BLOCK;
   1068 
   1069     p_msg->params.i93_cmd.first_block_number = first_block_number;
   1070     p_msg->params.i93_cmd.number_blocks = number_blocks;
   1071 
   1072     nfa_sys_sendmsg(p_msg);
   1073 
   1074     return (NFA_STATUS_OK);
   1075   }
   1076 
   1077   return (NFA_STATUS_FAILED);
   1078 }
   1079 
   1080 /*******************************************************************************
   1081 **
   1082 ** Function         NFA_RwI93WriteMultipleBlocks
   1083 **
   1084 ** Description:
   1085 **      Send Write Multiple Block command to the activated T5T tag.
   1086 **
   1087 **      When the write operation has completed (or if an error occurs), the
   1088 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1089 **
   1090 ** Returns:
   1091 **      NFA_STATUS_OK if successfully initiated
   1092 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1093 **      NFA_STATUS_FAILED otherwise
   1094 **
   1095 *******************************************************************************/
   1096 tNFA_STATUS NFA_RwI93WriteMultipleBlocks(uint8_t first_block_number,
   1097                                          uint16_t number_blocks,
   1098                                          uint8_t* p_data) {
   1099   tNFA_RW_OPERATION* p_msg;
   1100   uint16_t data_length;
   1101 
   1102   DLOG_IF(INFO, nfc_debug_enabled)
   1103       << StringPrintf("%d, %d", first_block_number, number_blocks);
   1104 
   1105   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1106     return (NFA_STATUS_WRONG_PROTOCOL);
   1107   }
   1108 
   1109   /* we don't know block size of tag */
   1110   if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
   1111     return (NFA_STATUS_FAILED);
   1112   }
   1113 
   1114   data_length = nfa_rw_cb.i93_block_size * number_blocks;
   1115 
   1116   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
   1117       (uint16_t)(sizeof(tNFA_RW_OPERATION) + data_length));
   1118   if (p_msg != NULL) {
   1119     /* Fill in tNFA_RW_OPERATION struct */
   1120     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1121     p_msg->op = NFA_RW_OP_I93_WRITE_MULTI_BLOCK;
   1122 
   1123     p_msg->params.i93_cmd.first_block_number = first_block_number;
   1124     p_msg->params.i93_cmd.number_blocks = number_blocks;
   1125     p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
   1126 
   1127     memcpy(p_msg->params.i93_cmd.p_data, p_data, data_length);
   1128 
   1129     nfa_sys_sendmsg(p_msg);
   1130 
   1131     return (NFA_STATUS_OK);
   1132   }
   1133 
   1134   return (NFA_STATUS_FAILED);
   1135 }
   1136 
   1137 /*******************************************************************************
   1138 **
   1139 ** Function         NFA_RwI93Select
   1140 **
   1141 ** Description:
   1142 **      Send Select command to the activated T5T tag.
   1143 **
   1144 **      UID[0]: 0xE0, MSB
   1145 **      UID[1]: IC Mfg Code
   1146 **      ...
   1147 **      UID[7]: LSB
   1148 **
   1149 **      When the operation has completed (or if an error occurs), the
   1150 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1151 **
   1152 ** Returns:
   1153 **      NFA_STATUS_OK if successfully initiated
   1154 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1155 **      NFA_STATUS_FAILED otherwise
   1156 **
   1157 *******************************************************************************/
   1158 tNFA_STATUS NFA_RwI93Select(uint8_t* p_uid) {
   1159   tNFA_RW_OPERATION* p_msg;
   1160 
   1161   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
   1162       "UID: [%02X%02X%02X...]", *(p_uid), *(p_uid + 1), *(p_uid + 2));
   1163 
   1164   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1165     return (NFA_STATUS_WRONG_PROTOCOL);
   1166   }
   1167 
   1168   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
   1169       (uint16_t)(sizeof(tNFA_RW_OPERATION) + I93_UID_BYTE_LEN));
   1170   if (p_msg != NULL) {
   1171     /* Fill in tNFA_RW_OPERATION struct */
   1172     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1173     p_msg->op = NFA_RW_OP_I93_SELECT;
   1174 
   1175     p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
   1176     memcpy(p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
   1177 
   1178     nfa_sys_sendmsg(p_msg);
   1179 
   1180     return (NFA_STATUS_OK);
   1181   }
   1182 
   1183   return (NFA_STATUS_FAILED);
   1184 }
   1185 
   1186 /*******************************************************************************
   1187 **
   1188 ** Function         NFA_RwI93ResetToReady
   1189 **
   1190 ** Description:
   1191 **      Send Reset to ready command to the activated T5T tag.
   1192 **
   1193 **      When the operation has completed (or if an error occurs), the
   1194 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1195 **
   1196 ** Returns:
   1197 **      NFA_STATUS_OK if successfully initiated
   1198 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1199 **      NFA_STATUS_FAILED otherwise
   1200 **
   1201 *******************************************************************************/
   1202 tNFA_STATUS NFA_RwI93ResetToReady(void) {
   1203   tNFA_RW_OPERATION* p_msg;
   1204 
   1205   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1206 
   1207   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1208     return (NFA_STATUS_WRONG_PROTOCOL);
   1209   }
   1210 
   1211   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1212   if (p_msg != NULL) {
   1213     /* Fill in tNFA_RW_OPERATION struct */
   1214     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1215     p_msg->op = NFA_RW_OP_I93_RESET_TO_READY;
   1216 
   1217     nfa_sys_sendmsg(p_msg);
   1218 
   1219     return (NFA_STATUS_OK);
   1220   }
   1221 
   1222   return (NFA_STATUS_FAILED);
   1223 }
   1224 
   1225 /*******************************************************************************
   1226 **
   1227 ** Function         NFA_RwI93WriteAFI
   1228 **
   1229 ** Description:
   1230 **      Send Write AFI command to the activated T5T tag.
   1231 **
   1232 **      When the operation has completed (or if an error occurs), the
   1233 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1234 **
   1235 ** Returns:
   1236 **      NFA_STATUS_OK if successfully initiated
   1237 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1238 **      NFA_STATUS_FAILED otherwise
   1239 **
   1240 *******************************************************************************/
   1241 tNFA_STATUS NFA_RwI93WriteAFI(uint8_t afi) {
   1242   tNFA_RW_OPERATION* p_msg;
   1243 
   1244   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("AFI: 0x%02X", afi);
   1245 
   1246   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1247     return (NFA_STATUS_WRONG_PROTOCOL);
   1248   }
   1249 
   1250   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1251   if (p_msg != NULL) {
   1252     /* Fill in tNFA_RW_OPERATION struct */
   1253     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1254     p_msg->op = NFA_RW_OP_I93_WRITE_AFI;
   1255 
   1256     p_msg->params.i93_cmd.afi = afi;
   1257 
   1258     nfa_sys_sendmsg(p_msg);
   1259 
   1260     return (NFA_STATUS_OK);
   1261   }
   1262 
   1263   return (NFA_STATUS_FAILED);
   1264 }
   1265 
   1266 /*******************************************************************************
   1267 **
   1268 ** Function         NFA_RwI93LockAFI
   1269 **
   1270 ** Description:
   1271 **      Send Lock AFI command to the activated T5T tag.
   1272 **
   1273 **      When the operation has completed (or if an error occurs), the
   1274 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1275 **
   1276 ** Returns:
   1277 **      NFA_STATUS_OK if successfully initiated
   1278 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1279 **      NFA_STATUS_FAILED otherwise
   1280 **
   1281 *******************************************************************************/
   1282 tNFA_STATUS NFA_RwI93LockAFI(void) {
   1283   tNFA_RW_OPERATION* p_msg;
   1284 
   1285   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1286 
   1287   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1288     return (NFA_STATUS_WRONG_PROTOCOL);
   1289   }
   1290 
   1291   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1292   if (p_msg != NULL) {
   1293     /* Fill in tNFA_RW_OPERATION struct */
   1294     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1295     p_msg->op = NFA_RW_OP_I93_LOCK_AFI;
   1296 
   1297     nfa_sys_sendmsg(p_msg);
   1298 
   1299     return (NFA_STATUS_OK);
   1300   }
   1301 
   1302   return (NFA_STATUS_FAILED);
   1303 }
   1304 
   1305 /*******************************************************************************
   1306 **
   1307 ** Function         NFA_RwI93WriteDSFID
   1308 **
   1309 ** Description:
   1310 **      Send Write DSFID command to the activated T5T tag.
   1311 **
   1312 **      When the operation has completed (or if an error occurs), the
   1313 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1314 **
   1315 ** Returns:
   1316 **      NFA_STATUS_OK if successfully initiated
   1317 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1318 **      NFA_STATUS_FAILED otherwise
   1319 **
   1320 *******************************************************************************/
   1321 tNFA_STATUS NFA_RwI93WriteDSFID(uint8_t dsfid) {
   1322   tNFA_RW_OPERATION* p_msg;
   1323 
   1324   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("DSFID: 0x%02X", dsfid);
   1325 
   1326   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1327     return (NFA_STATUS_WRONG_PROTOCOL);
   1328   }
   1329 
   1330   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1331   if (p_msg != NULL) {
   1332     /* Fill in tNFA_RW_OPERATION struct */
   1333     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1334     p_msg->op = NFA_RW_OP_I93_WRITE_DSFID;
   1335 
   1336     p_msg->params.i93_cmd.dsfid = dsfid;
   1337 
   1338     nfa_sys_sendmsg(p_msg);
   1339 
   1340     return (NFA_STATUS_OK);
   1341   }
   1342 
   1343   return (NFA_STATUS_FAILED);
   1344 }
   1345 
   1346 /*******************************************************************************
   1347 **
   1348 ** Function         NFA_RwI93LockDSFID
   1349 **
   1350 ** Description:
   1351 **      Send Lock DSFID command to the activated T5T tag.
   1352 **
   1353 **      When the operation has completed (or if an error occurs), the
   1354 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1355 **
   1356 ** Returns:
   1357 **      NFA_STATUS_OK if successfully initiated
   1358 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1359 **      NFA_STATUS_FAILED otherwise
   1360 **
   1361 *******************************************************************************/
   1362 tNFA_STATUS NFA_RwI93LockDSFID(void) {
   1363   tNFA_RW_OPERATION* p_msg;
   1364 
   1365   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1366 
   1367   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1368     return (NFA_STATUS_WRONG_PROTOCOL);
   1369   }
   1370 
   1371   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1372   if (p_msg != NULL) {
   1373     /* Fill in tNFA_RW_OPERATION struct */
   1374     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1375     p_msg->op = NFA_RW_OP_I93_LOCK_DSFID;
   1376 
   1377     nfa_sys_sendmsg(p_msg);
   1378 
   1379     return (NFA_STATUS_OK);
   1380   }
   1381 
   1382   return (NFA_STATUS_FAILED);
   1383 }
   1384 
   1385 /*******************************************************************************
   1386 **
   1387 ** Function         NFA_RwI93GetSysInfo
   1388 **
   1389 ** Description:
   1390 **      Send Get system information command to the activated T5T tag.
   1391 **      If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
   1392 **
   1393 **      When the operation has completed (or if an error occurs), the
   1394 **      app will be notified with NFA_I93_CMD_CPLT_EVT.
   1395 **
   1396 ** Returns:
   1397 **      NFA_STATUS_OK if successfully initiated
   1398 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1399 **      NFA_STATUS_FAILED otherwise
   1400 **
   1401 *******************************************************************************/
   1402 tNFA_STATUS NFA_RwI93GetSysInfo(uint8_t* p_uid) {
   1403   tNFA_RW_OPERATION* p_msg;
   1404 
   1405   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
   1406 
   1407   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1408     return (NFA_STATUS_WRONG_PROTOCOL);
   1409   }
   1410 
   1411   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1412   if (p_msg != NULL) {
   1413     /* Fill in tNFA_RW_OPERATION struct */
   1414     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1415     p_msg->op = NFA_RW_OP_I93_GET_SYS_INFO;
   1416 
   1417     if (p_uid) {
   1418       p_msg->params.i93_cmd.uid_present = true;
   1419       memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
   1420     } else {
   1421       p_msg->params.i93_cmd.uid_present = false;
   1422     }
   1423 
   1424     nfa_sys_sendmsg(p_msg);
   1425 
   1426     return (NFA_STATUS_OK);
   1427   }
   1428 
   1429   return (NFA_STATUS_FAILED);
   1430 }
   1431 
   1432 /*******************************************************************************
   1433 **
   1434 ** Function         NFA_RwI93GetMultiBlockSecurityStatus
   1435 **
   1436 ** Description:
   1437 **      Send Get Multiple block security status command to the activated
   1438 **      T5T tag.
   1439 **
   1440 **      Data is returned to the application using the NFA_DATA_EVT. When the
   1441 **      read operation has completed, or if an error occurs, the app will be
   1442 **      notified with NFA_I93_CMD_CPLT_EVT.
   1443 **
   1444 ** Returns:
   1445 **      NFA_STATUS_OK if successfully initiated
   1446 **      NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
   1447 **      NFA_STATUS_FAILED otherwise
   1448 **
   1449 *******************************************************************************/
   1450 tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus(uint8_t first_block_number,
   1451                                                  uint16_t number_blocks) {
   1452   tNFA_RW_OPERATION* p_msg;
   1453 
   1454   DLOG_IF(INFO, nfc_debug_enabled)
   1455       << StringPrintf("%d, %d", first_block_number, number_blocks);
   1456 
   1457   if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
   1458     return (NFA_STATUS_WRONG_PROTOCOL);
   1459   }
   1460 
   1461   p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
   1462   if (p_msg != NULL) {
   1463     /* Fill in tNFA_RW_OPERATION struct */
   1464     p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
   1465     p_msg->op = NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS;
   1466 
   1467     p_msg->params.i93_cmd.first_block_number = first_block_number;
   1468     p_msg->params.i93_cmd.number_blocks = number_blocks;
   1469 
   1470     nfa_sys_sendmsg(p_msg);
   1471 
   1472     return (NFA_STATUS_OK);
   1473   }
   1474 
   1475   return (NFA_STATUS_FAILED);
   1476 }
   1477