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  *  This file contains the action functions the NFA_RW state machine.
     22  *
     23  ******************************************************************************/
     24 #include <string.h>
     25 #include "ndef_utils.h"
     26 #include "nfa_dm_int.h"
     27 #include "nfa_mem_co.h"
     28 #include "nfa_rw_int.h"
     29 #include "nfa_sys_int.h"
     30 #include "rw_api.h"
     31 
     32 #define NFA_RW_OPTION_INVALID 0xFF
     33 
     34 /* Local static function prototypes */
     35 static tNFC_STATUS nfa_rw_start_ndef_read(void);
     36 static tNFC_STATUS nfa_rw_start_ndef_write(void);
     37 static tNFC_STATUS nfa_rw_start_ndef_detection(void);
     38 static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock);
     39 static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data);
     40 static void nfa_rw_error_cleanup(uint8_t event);
     41 static void nfa_rw_presence_check(tNFA_RW_MSG* p_data);
     42 static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data);
     43 static bool nfa_rw_detect_ndef(tNFA_RW_MSG* p_data);
     44 static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data);
     45 
     46 /*******************************************************************************
     47 **
     48 ** Function         nfa_rw_free_ndef_rx_buf
     49 **
     50 ** Description      Free buffer allocated to hold incoming NDEF message
     51 **
     52 ** Returns          Nothing
     53 **
     54 *******************************************************************************/
     55 void nfa_rw_free_ndef_rx_buf(void) {
     56   if (nfa_rw_cb.p_ndef_buf) {
     57     nfa_mem_co_free(nfa_rw_cb.p_ndef_buf);
     58     nfa_rw_cb.p_ndef_buf = NULL;
     59   }
     60 }
     61 
     62 /*******************************************************************************
     63 **
     64 ** Function         nfa_rw_store_ndef_rx_buf
     65 **
     66 ** Description      Store data into NDEF buffer
     67 **
     68 ** Returns          Nothing
     69 **
     70 *******************************************************************************/
     71 static void nfa_rw_store_ndef_rx_buf(tRW_DATA* p_rw_data) {
     72   uint8_t* p;
     73 
     74   p = (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
     75 
     76   /* Save data into buffer */
     77   memcpy(&nfa_rw_cb.p_ndef_buf[nfa_rw_cb.ndef_rd_offset], p,
     78          p_rw_data->data.p_data->len);
     79   nfa_rw_cb.ndef_rd_offset += p_rw_data->data.p_data->len;
     80 
     81   GKI_freebuf(p_rw_data->data.p_data);
     82   p_rw_data->data.p_data = NULL;
     83 }
     84 
     85 /*******************************************************************************
     86 **
     87 ** Function         nfa_rw_send_data_to_upper
     88 **
     89 ** Description      Send data to upper layer
     90 **
     91 ** Returns          Nothing
     92 **
     93 *******************************************************************************/
     94 static void nfa_rw_send_data_to_upper(tRW_DATA* p_rw_data) {
     95   tNFA_CONN_EVT_DATA conn_evt_data;
     96 
     97   if ((p_rw_data->status == NFC_STATUS_TIMEOUT) ||
     98       (p_rw_data->data.p_data == NULL))
     99     return;
    100 
    101 #if (BT_TRACE_VERBOSE == TRUE)
    102   NFA_TRACE_DEBUG2("nfa_rw_send_data_to_upper: Len [0x%X] Status [%s]",
    103                    p_rw_data->data.p_data->len,
    104                    NFC_GetStatusName(p_rw_data->data.status));
    105 #else
    106   NFA_TRACE_DEBUG2("nfa_rw_send_data_to_upper: Len [0x%X] Status [0x%X]",
    107                    p_rw_data->data.p_data->len, p_rw_data->data.status);
    108 #endif
    109 
    110   /* Notify conn cback of NFA_DATA_EVT */
    111   conn_evt_data.data.status = p_rw_data->data.status;
    112   conn_evt_data.data.p_data =
    113       (uint8_t*)(p_rw_data->data.p_data + 1) + p_rw_data->data.p_data->offset;
    114   conn_evt_data.data.len = p_rw_data->data.p_data->len;
    115 
    116   nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
    117 
    118   GKI_freebuf(p_rw_data->data.p_data);
    119   p_rw_data->data.p_data = NULL;
    120 }
    121 
    122 /*******************************************************************************
    123 **
    124 ** Function         nfa_rw_error_cleanup
    125 **
    126 ** Description      Handle failure - signal command complete and notify app
    127 **
    128 ** Returns          Nothing
    129 **
    130 *******************************************************************************/
    131 static void nfa_rw_error_cleanup(uint8_t event) {
    132   tNFA_CONN_EVT_DATA conn_evt_data;
    133 
    134   nfa_rw_command_complete();
    135 
    136   conn_evt_data.status = NFA_STATUS_FAILED;
    137 
    138   nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
    139 }
    140 
    141 /*******************************************************************************
    142 **
    143 ** Function         nfa_rw_check_start_presence_check_timer
    144 **
    145 ** Description      Start timer to wait for specified time before presence check
    146 **
    147 ** Returns          Nothing
    148 **
    149 *******************************************************************************/
    150 static void nfa_rw_check_start_presence_check_timer(
    151     uint16_t presence_check_start_delay) {
    152   if (!p_nfa_dm_cfg->auto_presence_check) return;
    153 
    154   if (nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) {
    155     if (presence_check_start_delay) {
    156       NFA_TRACE_DEBUG0("Starting presence check timer...");
    157       nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TICK_EVT,
    158                           presence_check_start_delay);
    159     } else {
    160       /* Presence check now */
    161       nfa_rw_presence_check(NULL);
    162     }
    163   }
    164 }
    165 
    166 /*******************************************************************************
    167 **
    168 ** Function         nfa_rw_stop_presence_check_timer
    169 **
    170 ** Description      Stop timer for presence check
    171 **
    172 ** Returns          Nothing
    173 **
    174 *******************************************************************************/
    175 void nfa_rw_stop_presence_check_timer(void) {
    176   nfa_sys_stop_timer(&nfa_rw_cb.tle);
    177   NFA_TRACE_DEBUG0("Stopped presence check timer (if started)");
    178 }
    179 
    180 /*******************************************************************************
    181 **
    182 ** Function         nfa_rw_handle_ndef_detect
    183 **
    184 ** Description      Handler for NDEF detection reader/writer event
    185 **
    186 ** Returns          Nothing
    187 **
    188 *******************************************************************************/
    189 static void nfa_rw_handle_ndef_detect(tRW_EVENT event, tRW_DATA* p_rw_data) {
    190   tNFA_CONN_EVT_DATA conn_evt_data;
    191 
    192   NFA_TRACE_DEBUG3(
    193       "NDEF Detection completed: cur_size=%i, max_size=%i, flags=0x%x",
    194       p_rw_data->ndef.cur_size, p_rw_data->ndef.max_size,
    195       p_rw_data->ndef.flags);
    196 
    197   /* Check if NDEF detection succeeded */
    198   if (p_rw_data->ndef.status == NFC_STATUS_OK) {
    199     /* Set NDEF detection state */
    200     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_TRUE;
    201     nfa_rw_cb.flags |= NFA_RW_FL_NDEF_OK;
    202 
    203     /* Store ndef properties */
    204     conn_evt_data.ndef_detect.status = NFA_STATUS_OK;
    205     conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
    206     conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
    207         p_rw_data->ndef.cur_size;
    208     conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
    209         p_rw_data->ndef.max_size;
    210     conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
    211 
    212     if (p_rw_data->ndef.flags & RW_NDEF_FL_READ_ONLY)
    213       nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
    214     else
    215       nfa_rw_cb.flags &= ~NFA_RW_FL_TAG_IS_READONLY;
    216 
    217     /* Determine what operation triggered the NDEF detection procedure */
    218     if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    219       /* if ndef detection was done as part of ndef-read operation, then perform
    220        * ndef read now */
    221       conn_evt_data.status = nfa_rw_start_ndef_read();
    222       if (conn_evt_data.status != NFA_STATUS_OK) {
    223         /* Failed to start NDEF Read */
    224 
    225         /* Command complete - perform cleanup, notify app */
    226         nfa_rw_command_complete();
    227         nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    228       }
    229     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    230       /* if ndef detection was done as part of ndef-write operation, then
    231        * perform ndef write now */
    232       conn_evt_data.status = nfa_rw_start_ndef_write();
    233       if (conn_evt_data.status != NFA_STATUS_OK) {
    234         /* Failed to start NDEF Write.  */
    235 
    236         /* Command complete - perform cleanup, notify app */
    237         nfa_rw_command_complete();
    238         nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    239       }
    240     } else {
    241       /* current op was stand-alone NFA_DetectNDef. Command complete - perform
    242        * cleanup and notify app */
    243       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
    244       nfa_rw_command_complete();
    245 
    246       nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
    247     }
    248   } else {
    249     /* NDEF detection failed... */
    250 
    251     /* Command complete - perform cleanup, notify app */
    252     nfa_rw_command_complete();
    253     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
    254     conn_evt_data.status = p_rw_data->ndef.status;
    255 
    256     if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    257       /* if ndef detection was done as part of ndef-read operation, then notify
    258        * NDEF handlers of failure */
    259       nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
    260 
    261       /* Notify app of read status */
    262       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    263     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    264       /* if ndef detection was done as part of ndef-write operation, then notify
    265        * app of failure */
    266       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    267     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_NDEF) {
    268       conn_evt_data.ndef_detect.protocol = p_rw_data->ndef.protocol;
    269       /* current op was stand-alone NFA_DetectNDef. Notify app of failure */
    270       if (p_rw_data->ndef.status == NFC_STATUS_TIMEOUT) {
    271         /* Tag could have moved away */
    272         conn_evt_data.ndef_detect.cur_size = 0;
    273         conn_evt_data.ndef_detect.max_size = 0;
    274         conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
    275         conn_evt_data.ndef_detect.status = NFA_STATUS_TIMEOUT;
    276       } else {
    277         /* NDEF Detection failed for other reasons */
    278         conn_evt_data.ndef_detect.cur_size = nfa_rw_cb.ndef_cur_size =
    279             p_rw_data->ndef.cur_size;
    280         conn_evt_data.ndef_detect.max_size = nfa_rw_cb.ndef_max_size =
    281             p_rw_data->ndef.max_size;
    282         conn_evt_data.ndef_detect.flags = p_rw_data->ndef.flags;
    283       }
    284       nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
    285     }
    286 
    287     nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
    288   }
    289 }
    290 
    291 /*******************************************************************************
    292 **
    293 ** Function         nfa_rw_handle_tlv_detect
    294 **
    295 ** Description      Handler for TLV detection reader/writer event
    296 **
    297 ** Returns          Nothing
    298 **
    299 *******************************************************************************/
    300 static void nfa_rw_handle_tlv_detect(tRW_EVENT event, tRW_DATA* p_rw_data) {
    301   tNFA_CONN_EVT_DATA conn_evt_data;
    302 
    303   /* Set TLV detection state */
    304   if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
    305     if (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) {
    306       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
    307     } else {
    308       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
    309     }
    310   } else {
    311     if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) {
    312       nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_LOCK_TLV_OP_COMPLETE;
    313     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV) {
    314       nfa_rw_cb.tlv_st |= NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE;
    315     }
    316   }
    317 
    318   /* Check if TLV detection succeeded */
    319   if (p_rw_data->tlv.status == NFC_STATUS_OK) {
    320     NFA_TRACE_DEBUG1("TLV Detection succeeded: num_bytes=%i",
    321                      p_rw_data->tlv.num_bytes);
    322 
    323     /* Store tlv properties */
    324     conn_evt_data.tlv_detect.status = NFA_STATUS_OK;
    325     conn_evt_data.tlv_detect.protocol = p_rw_data->tlv.protocol;
    326     conn_evt_data.tlv_detect.num_bytes = p_rw_data->tlv.num_bytes;
    327 
    328     /* Determine what operation triggered the TLV detection procedure */
    329     if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
    330       if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
    331         /* Failed to set tag read only */
    332         conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
    333         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
    334       }
    335     } else {
    336       /* current op was stand-alone NFA_DetectTlv. Command complete - perform
    337        * cleanup and notify app */
    338       nfa_rw_command_complete();
    339       nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
    340     }
    341   }
    342 
    343   /* Handle failures */
    344   if (p_rw_data->tlv.status != NFC_STATUS_OK) {
    345     /* Command complete - perform cleanup, notify the app */
    346     nfa_rw_command_complete();
    347 
    348     conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
    349     if ((nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_LOCK_TLV) ||
    350         (nfa_rw_cb.cur_op == NFA_RW_OP_DETECT_MEM_TLV)) {
    351       nfa_dm_act_conn_cback_notify(NFA_TLV_DETECT_EVT, &conn_evt_data);
    352     } else if (nfa_rw_cb.cur_op == NFA_RW_OP_SET_TAG_RO) {
    353       if (nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock) != NFC_STATUS_OK) {
    354         /* Failed to set tag read only */
    355         conn_evt_data.tlv_detect.status = NFA_STATUS_FAILED;
    356         nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
    357       }
    358     }
    359   }
    360 }
    361 
    362 /*******************************************************************************
    363 **
    364 ** Function         nfa_rw_handle_sleep_wakeup_rsp
    365 **
    366 ** Description      Handl sleep wakeup
    367 **
    368 ** Returns          Nothing
    369 **
    370 *******************************************************************************/
    371 void nfa_rw_handle_sleep_wakeup_rsp(tNFC_STATUS status) {
    372   tNFC_ACTIVATE_DEVT activate_params;
    373   tRW_EVENT event;
    374 
    375   if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
    376       (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
    377       (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
    378       (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
    379     NFA_TRACE_DEBUG0(
    380         "nfa_rw_handle_sleep_wakeup_rsp; Attempt to wake up Type 2 tag from "
    381         "HALT State is complete");
    382     if (status == NFC_STATUS_OK) {
    383       /* Type 2 Tag is wakeup from HALT state */
    384       NFA_TRACE_DEBUG0(
    385           "nfa_rw_handle_sleep_wakeup_rsp; Handle the NACK rsp received now");
    386       /* Initialize control block */
    387       activate_params.protocol = nfa_rw_cb.protocol;
    388       activate_params.rf_tech_param.param.pa.sel_rsp = nfa_rw_cb.pa_sel_res;
    389       activate_params.rf_tech_param.mode = nfa_rw_cb.activated_tech_mode;
    390 
    391       /* Initialize RW module */
    392       if ((RW_SetActivatedTagType(&activate_params, nfa_rw_cback)) !=
    393           NFC_STATUS_OK) {
    394         /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
    395         NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
    396         if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
    397           if (nfa_rw_cb.rw_data.data.p_data)
    398             GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
    399           nfa_rw_cb.rw_data.data.p_data = NULL;
    400         }
    401         /* Do not try to detect NDEF again but just notify current operation
    402          * failed */
    403         nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
    404       }
    405     }
    406 
    407     /* The current operation failed with NACK rsp from type 2 tag */
    408     nfa_rw_cb.rw_data.status = NFC_STATUS_FAILED;
    409     event = nfa_rw_cb.halt_event;
    410 
    411     /* Got NACK rsp during presence check and legacy presence check performed */
    412     if (nfa_rw_cb.cur_op == NFA_RW_OP_PRESENCE_CHECK)
    413       nfa_rw_cb.rw_data.status = status;
    414 
    415     /* If cannot Sleep wakeup tag, then NDEF Detect operation is complete */
    416     if ((status != NFC_STATUS_OK) &&
    417         (nfa_rw_cb.halt_event == RW_T2T_NDEF_DETECT_EVT))
    418       nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
    419 
    420     nfa_rw_handle_t2t_evt(event, &nfa_rw_cb.rw_data);
    421     nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
    422 
    423     /* If Type 2 tag sleep wakeup failed and If in normal mode (not-exclusive RF
    424      * mode) then deactivate the link if sleep wakeup failed */
    425     if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
    426         (status != NFC_STATUS_OK)) {
    427       NFA_TRACE_DEBUG0("Sleep wakeup failed. Deactivating...");
    428       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    429     }
    430   } else {
    431     NFA_TRACE_DEBUG0(
    432         "nfa_rw_handle_sleep_wakeup_rsp; Legacy presence check performed");
    433     /* Legacy presence check performed */
    434     nfa_rw_handle_presence_check_rsp(status);
    435   }
    436 }
    437 
    438 /*******************************************************************************
    439 **
    440 ** Function         nfa_rw_handle_presence_check_rsp
    441 **
    442 ** Description      Handler RW_T#t_PRESENCE_CHECK_EVT
    443 **
    444 ** Returns          Nothing
    445 **
    446 *******************************************************************************/
    447 void nfa_rw_handle_presence_check_rsp(tNFC_STATUS status) {
    448   NFC_HDR* p_pending_msg;
    449 
    450   /* Stop the presence check timer - timer may have been started when presence
    451    * check started */
    452   nfa_rw_stop_presence_check_timer();
    453   if (status == NFA_STATUS_OK) {
    454     /* Clear the BUSY flag and restart the presence-check timer */
    455     nfa_rw_command_complete();
    456   } else {
    457     /* If presence check failed just clear the BUSY flag */
    458     nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
    459   }
    460 
    461   /* Handle presence check due to auto-presence-check  */
    462   if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
    463     nfa_rw_cb.flags &= ~NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
    464 
    465     /* If an API was called during auto-presence-check, then handle it now */
    466     if (nfa_rw_cb.p_pending_msg) {
    467       /* If NFA_RwPresenceCheck was called during auto-presence-check, notify
    468        * app of result */
    469       if (nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_PRESENCE_CHECK) {
    470         /* Notify app of presence check status */
    471         nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT,
    472                                      (tNFA_CONN_EVT_DATA*)&status);
    473         GKI_freebuf(nfa_rw_cb.p_pending_msg);
    474         nfa_rw_cb.p_pending_msg = NULL;
    475       }
    476       /* For all other APIs called during auto-presence check, perform the
    477          command now (if tag is still present) */
    478       else if (status == NFC_STATUS_OK) {
    479         NFA_TRACE_DEBUG0(
    480             "Performing deferred operation after presence check...");
    481         p_pending_msg = (NFC_HDR*)nfa_rw_cb.p_pending_msg;
    482         nfa_rw_cb.p_pending_msg = NULL;
    483         nfa_rw_handle_event(p_pending_msg);
    484         GKI_freebuf(p_pending_msg);
    485       } else {
    486         /* Tag no longer present. Free command for pending API command */
    487         GKI_freebuf(nfa_rw_cb.p_pending_msg);
    488         nfa_rw_cb.p_pending_msg = NULL;
    489       }
    490     }
    491 
    492     /* Auto-presence check failed. Deactivate */
    493     if (status != NFC_STATUS_OK) {
    494       NFA_TRACE_DEBUG0("Auto presence check failed. Deactivating...");
    495       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    496     }
    497   }
    498   /* Handle presence check due to NFA_RwPresenceCheck API call */
    499   else {
    500     /* Notify app of presence check status */
    501     nfa_dm_act_conn_cback_notify(NFA_PRESENCE_CHECK_EVT,
    502                                  (tNFA_CONN_EVT_DATA*)&status);
    503 
    504     /* If in normal mode (not-exclusive RF mode) then deactivate the link if
    505      * presence check failed */
    506     if ((nfa_rw_cb.flags & NFA_RW_FL_NOT_EXCL_RF_MODE) &&
    507         (status != NFC_STATUS_OK)) {
    508       NFA_TRACE_DEBUG0("Presence check failed. Deactivating...");
    509       nfa_dm_rf_deactivate(NFA_DEACTIVATE_TYPE_DISCOVERY);
    510     }
    511   }
    512 }
    513 
    514 /*******************************************************************************
    515 **
    516 ** Function         nfa_rw_handle_t1t_evt
    517 **
    518 ** Description      Handler for Type-1 tag reader/writer events
    519 **
    520 ** Returns          Nothing
    521 **
    522 *******************************************************************************/
    523 static void nfa_rw_handle_t1t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
    524   tNFA_CONN_EVT_DATA conn_evt_data;
    525   tNFA_TAG_PARAMS tag_params;
    526   uint8_t* p_rid_rsp;
    527   tNFA_STATUS activation_status;
    528 
    529   conn_evt_data.status = p_rw_data->data.status;
    530   switch (event) {
    531     case RW_T1T_RID_EVT:
    532       if (p_rw_data->data.p_data != NULL) {
    533         /* Assume the data is just the response byte sequence */
    534         p_rid_rsp = (uint8_t*)(p_rw_data->data.p_data + 1) +
    535                     p_rw_data->data.p_data->offset;
    536         /* Fetch HR from RID response message */
    537         STREAM_TO_ARRAY(tag_params.t1t.hr, p_rid_rsp, T1T_HR_LEN);
    538         /* Fetch UID0-3 from RID response message */
    539         STREAM_TO_ARRAY(tag_params.t1t.uid, p_rid_rsp, T1T_CMD_UID_LEN);
    540         GKI_freebuf(p_rw_data->data.p_data);
    541         p_rw_data->data.p_data = NULL;
    542       }
    543 
    544       /* Command complete - perform cleanup, notify the app */
    545       nfa_rw_command_complete();
    546 
    547       if (p_rw_data->status == NFC_STATUS_TIMEOUT) {
    548         activation_status = NFA_STATUS_TIMEOUT;
    549       } else {
    550         activation_status = NFA_STATUS_OK;
    551       }
    552 
    553       nfa_dm_notify_activation_status(activation_status, &tag_params);
    554       break;
    555 
    556     case RW_T1T_RALL_CPLT_EVT:
    557     case RW_T1T_READ_CPLT_EVT:
    558     case RW_T1T_RSEG_CPLT_EVT:
    559     case RW_T1T_READ8_CPLT_EVT:
    560       nfa_rw_send_data_to_upper(p_rw_data);
    561 
    562       /* Command complete - perform cleanup, notify the app */
    563       nfa_rw_command_complete();
    564       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    565       break;
    566 
    567     case RW_T1T_WRITE_E_CPLT_EVT:
    568     case RW_T1T_WRITE_NE_CPLT_EVT:
    569     case RW_T1T_WRITE_E8_CPLT_EVT:
    570     case RW_T1T_WRITE_NE8_CPLT_EVT:
    571       nfa_rw_send_data_to_upper(p_rw_data);
    572 
    573       /* Command complete - perform cleanup, notify the app */
    574       nfa_rw_command_complete();
    575       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    576       break;
    577 
    578     case RW_T1T_TLV_DETECT_EVT:
    579       nfa_rw_handle_tlv_detect(event, p_rw_data);
    580       break;
    581 
    582     case RW_T1T_NDEF_DETECT_EVT:
    583       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
    584 
    585       if ((p_rw_data->status != NFC_STATUS_OK) &&
    586           (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) &&
    587           (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATABLE) &&
    588           (!(p_rw_data->ndef.flags & NFA_RW_NDEF_FL_FORMATED)) &&
    589           (p_rw_data->ndef.flags & NFA_RW_NDEF_FL_SUPPORTED)) {
    590         /* Tag is in Initialized state, Format the tag first and then Write NDEF
    591          */
    592         if (RW_T1tFormatNDef() == NFC_STATUS_OK) break;
    593       }
    594 
    595       nfa_rw_handle_ndef_detect(event, p_rw_data);
    596 
    597       break;
    598 
    599     case RW_T1T_NDEF_READ_EVT:
    600       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
    601       if (p_rw_data->status == NFC_STATUS_OK) {
    602         /* Process the ndef record */
    603         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
    604                                    nfa_rw_cb.ndef_cur_size);
    605       } else {
    606         /* Notify app of failure */
    607         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    608           /* If current operation is READ_NDEF, then notify ndef handlers of
    609            * failure */
    610           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
    611         }
    612       }
    613 
    614       /* Command complete - perform cleanup, notify the app */
    615       nfa_rw_command_complete();
    616       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    617 
    618       /* Free ndef buffer */
    619       nfa_rw_free_ndef_rx_buf();
    620       break;
    621 
    622     case RW_T1T_NDEF_WRITE_EVT:
    623       if (p_rw_data->data.status != NFA_STATUS_OK)
    624         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
    625       nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_COMPLETE;
    626 
    627       /* Command complete - perform cleanup, notify the app */
    628       nfa_rw_command_complete();
    629 
    630       /* Notify app */
    631       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
    632                                  ? NFA_STATUS_OK
    633                                  : NFA_STATUS_FAILED;
    634       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    635         /* Update local cursize of ndef message */
    636         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
    637       }
    638 
    639       /* Notify app of ndef write complete status */
    640       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    641       break;
    642 
    643     case RW_T1T_SET_TAG_RO_EVT:
    644       /* Command complete - perform cleanup, notify the app */
    645       nfa_rw_command_complete();
    646       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
    647       break;
    648 
    649     case RW_T1T_RAW_FRAME_EVT:
    650       nfa_rw_send_data_to_upper(p_rw_data);
    651       /* Command complete - perform cleanup */
    652       nfa_rw_command_complete();
    653       break;
    654 
    655     case RW_T1T_PRESENCE_CHECK_EVT: /* Presence check completed */
    656       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
    657       break;
    658 
    659     case RW_T1T_FORMAT_CPLT_EVT:
    660 
    661       if (p_rw_data->data.status == NFA_STATUS_OK)
    662         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
    663 
    664       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    665         /* if format operation was done as part of ndef-write operation, now
    666          * start NDEF Write */
    667         if ((p_rw_data->data.status != NFA_STATUS_OK) ||
    668             ((conn_evt_data.status = RW_T1tDetectNDef()) != NFC_STATUS_OK)) {
    669           /* Command complete - perform cleanup, notify app */
    670           nfa_rw_command_complete();
    671           nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_FALSE;
    672 
    673           /* if format operation failed or ndef detection did not start, then
    674            * notify app of ndef-write operation failure */
    675           conn_evt_data.status = NFA_STATUS_FAILED;
    676           nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    677         }
    678       } else {
    679         /* Command complete - perform cleanup, notify the app */
    680         nfa_rw_command_complete();
    681         nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
    682       }
    683       break;
    684 
    685     case RW_T1T_INTF_ERROR_EVT:
    686       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
    687       break;
    688   }
    689 }
    690 
    691 /*******************************************************************************
    692 **
    693 ** Function         nfa_rw_handle_t2t_evt
    694 **
    695 ** Description      Handler for Type-2 tag reader/writer events
    696 **
    697 ** Returns          Nothing
    698 **
    699 *******************************************************************************/
    700 static void nfa_rw_handle_t2t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
    701   tNFA_CONN_EVT_DATA conn_evt_data;
    702 
    703   conn_evt_data.status = p_rw_data->status;
    704 
    705   if (p_rw_data->status == NFC_STATUS_REJECTED) {
    706     NFA_TRACE_DEBUG0(
    707         "nfa_rw_handle_t2t_evt(); Waking the tag first before handling the "
    708         "response!");
    709     /* Received NACK. Let DM wakeup the tag first (by putting tag to sleep and
    710      * then waking it up) */
    711     p_rw_data->status = nfa_dm_disc_sleep_wakeup();
    712     if (p_rw_data->status == NFC_STATUS_OK) {
    713       nfa_rw_cb.halt_event = event;
    714       memcpy(&nfa_rw_cb.rw_data, p_rw_data, sizeof(tRW_DATA));
    715       return;
    716     }
    717   }
    718 
    719   switch (event) {
    720     case RW_T2T_READ_CPLT_EVT: /* Read completed          */
    721       nfa_rw_send_data_to_upper(p_rw_data);
    722       /* Command complete - perform cleanup, notify the app */
    723       nfa_rw_command_complete();
    724       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    725       break;
    726 
    727     case RW_T2T_WRITE_CPLT_EVT: /* Write completed         */
    728       /* Command complete - perform cleanup, notify the app */
    729       nfa_rw_command_complete();
    730       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    731       break;
    732 
    733     case RW_T2T_SELECT_CPLT_EVT: /* Sector select completed */
    734       /* Command complete - perform cleanup, notify the app */
    735       nfa_rw_command_complete();
    736       nfa_dm_act_conn_cback_notify(NFA_SELECT_CPLT_EVT, &conn_evt_data);
    737       break;
    738 
    739     case RW_T2T_NDEF_DETECT_EVT: /* NDEF detection complete */
    740       if ((p_rw_data->status == NFC_STATUS_OK) ||
    741           ((p_rw_data->status == NFC_STATUS_FAILED) &&
    742            ((p_rw_data->ndef.flags == NFA_RW_NDEF_FL_UNKNOWN) ||
    743             (nfa_rw_cb.halt_event == RW_T2T_MAX_EVT))) ||
    744           (nfa_rw_cb.skip_dyn_locks == true)) {
    745         /* NDEF Detection is complete */
    746         nfa_rw_cb.skip_dyn_locks = false;
    747         nfa_rw_handle_ndef_detect(event, p_rw_data);
    748       } else {
    749         /* Try to detect NDEF again, this time without reading dynamic lock
    750          * bytes */
    751         nfa_rw_cb.skip_dyn_locks = true;
    752         nfa_rw_detect_ndef(NULL);
    753       }
    754       break;
    755 
    756     case RW_T2T_TLV_DETECT_EVT: /* Lock control/Mem/Prop tlv detection complete
    757                                    */
    758       nfa_rw_handle_tlv_detect(event, p_rw_data);
    759       break;
    760 
    761     case RW_T2T_NDEF_READ_EVT: /* NDEF read completed     */
    762       if (p_rw_data->status == NFC_STATUS_OK) {
    763         /* Process the ndef record */
    764         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
    765                                    nfa_rw_cb.ndef_cur_size);
    766       } else {
    767         /* Notify app of failure */
    768         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    769           /* If current operation is READ_NDEF, then notify ndef handlers of
    770            * failure */
    771           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
    772         }
    773       }
    774 
    775       /* Notify app of read status */
    776       conn_evt_data.status = p_rw_data->status;
    777       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    778       /* Free ndef buffer */
    779       nfa_rw_free_ndef_rx_buf();
    780 
    781       /* Command complete - perform cleanup */
    782       nfa_rw_command_complete();
    783       break;
    784 
    785     case RW_T2T_NDEF_WRITE_EVT: /* NDEF write complete     */
    786 
    787       /* Command complete - perform cleanup, notify the app */
    788       nfa_rw_command_complete();
    789 
    790       /* Notify app */
    791       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
    792                                  ? NFA_STATUS_OK
    793                                  : NFA_STATUS_FAILED;
    794       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    795         /* Update local cursize of ndef message */
    796         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
    797       }
    798 
    799       /* Notify app of ndef write complete status */
    800       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    801 
    802       break;
    803 
    804     case RW_T2T_SET_TAG_RO_EVT:
    805       /* Command complete - perform cleanup, notify the app */
    806       nfa_rw_command_complete();
    807       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
    808       break;
    809 
    810     case RW_T2T_RAW_FRAME_EVT:
    811       nfa_rw_send_data_to_upper(p_rw_data);
    812       /* Command complete - perform cleanup */
    813       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
    814         nfa_rw_command_complete();
    815       }
    816       break;
    817 
    818     case RW_T2T_PRESENCE_CHECK_EVT: /* Presence check completed */
    819       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
    820       break;
    821 
    822     case RW_T2T_FORMAT_CPLT_EVT:
    823       if (p_rw_data->data.status == NFA_STATUS_OK)
    824         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
    825 
    826       /* Command complete - perform cleanup, notify the app */
    827       nfa_rw_command_complete();
    828       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
    829       break;
    830 
    831     case RW_T2T_INTF_ERROR_EVT:
    832       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
    833       break;
    834   }
    835 }
    836 
    837 /*******************************************************************************
    838 **
    839 ** Function         nfa_rw_handle_t3t_evt
    840 **
    841 ** Description      Handler for Type-3 tag reader/writer events
    842 **
    843 ** Returns          Nothing
    844 **
    845 *******************************************************************************/
    846 static void nfa_rw_handle_t3t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
    847   tNFA_CONN_EVT_DATA conn_evt_data;
    848   tNFA_TAG_PARAMS tag_params;
    849 
    850   switch (event) {
    851     case RW_T3T_NDEF_DETECT_EVT: /* NDEF detection complete */
    852       nfa_rw_handle_ndef_detect(event, p_rw_data);
    853       break;
    854 
    855     case RW_T3T_UPDATE_CPLT_EVT: /* Write completed */
    856       /* Command complete - perform cleanup, notify the app */
    857       nfa_rw_command_complete();
    858 
    859       /* Notify app */
    860       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
    861                                  ? NFA_STATUS_OK
    862                                  : NFA_STATUS_FAILED;
    863       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
    864         /* Update local cursize of ndef message */
    865         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
    866       }
    867 
    868       /* Notify app of ndef write complete status */
    869       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
    870 
    871       break;
    872 
    873     case RW_T3T_CHECK_CPLT_EVT: /* Read completed */
    874       if (p_rw_data->status == NFC_STATUS_OK) {
    875         /* Process the ndef record */
    876         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
    877                                    nfa_rw_cb.ndef_cur_size);
    878       } else {
    879         /* Notify app of failure */
    880         if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    881           /* If current operation is READ_NDEF, then notify ndef handlers of
    882            * failure */
    883           nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
    884         }
    885       }
    886 
    887       /* Free ndef buffer */
    888       nfa_rw_free_ndef_rx_buf();
    889 
    890       /* Command complete - perform cleanup, notify the app */
    891       nfa_rw_command_complete();
    892       conn_evt_data.status = p_rw_data->status;
    893       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
    894       break;
    895 
    896     case RW_T3T_CHECK_EVT: /* Segment of data received from type 3 tag */
    897       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    898         nfa_rw_store_ndef_rx_buf(p_rw_data);
    899       } else {
    900         nfa_rw_send_data_to_upper(p_rw_data);
    901       }
    902       break;
    903 
    904     case RW_T3T_RAW_FRAME_EVT: /* SendRawFrame response */
    905       nfa_rw_send_data_to_upper(p_rw_data);
    906 
    907       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
    908         /* Command complete - perform cleanup */
    909         nfa_rw_command_complete();
    910       }
    911       break;
    912 
    913     case RW_T3T_PRESENCE_CHECK_EVT: /* Presence check completed */
    914       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
    915       break;
    916 
    917     case RW_T3T_GET_SYSTEM_CODES_EVT: /* Presence check completed */
    918       /* Command complete - perform cleanup */
    919       nfa_rw_command_complete();
    920 
    921       /* System codes retrieved - notify app of ACTIVATION */
    922       if (p_rw_data->status == NFC_STATUS_OK) {
    923         tag_params.t3t.num_system_codes = p_rw_data->t3t_sc.num_system_codes;
    924         tag_params.t3t.p_system_codes = p_rw_data->t3t_sc.p_system_codes;
    925       } else {
    926         tag_params.t3t.num_system_codes = 0;
    927         tag_params.t3t.p_system_codes = NULL;
    928       }
    929 
    930       nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
    931       break;
    932 
    933     case RW_T3T_FORMAT_CPLT_EVT: /* Format completed */
    934       /* Command complete - perform cleanup, notify the app */
    935       nfa_rw_command_complete();
    936 
    937       /* Notify app */
    938       conn_evt_data.status = (p_rw_data->data.status == NFC_STATUS_OK)
    939                                  ? NFA_STATUS_OK
    940                                  : NFA_STATUS_FAILED;
    941 
    942       /* Notify app of ndef write complete status */
    943       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
    944       break;
    945 
    946     case RW_T3T_INTF_ERROR_EVT:
    947       conn_evt_data.status = p_rw_data->status;
    948       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
    949       break;
    950 
    951     case RW_T3T_SET_READ_ONLY_CPLT_EVT:
    952       /* Command complete - perform cleanup, notify the app */
    953       nfa_rw_command_complete();
    954 
    955       conn_evt_data.status = p_rw_data->status;
    956       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
    957       break;
    958 
    959     default:
    960       NFA_TRACE_DEBUG1("nfa_rw_handle_t3t_evt(); Unhandled RW event 0x%X",
    961                        event);
    962       break;
    963   }
    964 }
    965 
    966 /*******************************************************************************
    967 **
    968 ** Function         nfa_rw_handle_t4t_evt
    969 **
    970 ** Description      Handler for Type-4 tag reader/writer events
    971 **
    972 ** Returns          Nothing
    973 **
    974 *******************************************************************************/
    975 static void nfa_rw_handle_t4t_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
    976   tNFA_CONN_EVT_DATA conn_evt_data;
    977 
    978   switch (event) {
    979     case RW_T4T_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
    980       nfa_rw_handle_ndef_detect(event, p_rw_data);
    981       break;
    982 
    983     case RW_T4T_NDEF_FORMAT_CPLT_EVT:
    984       /* Command complete - perform cleanup, notify the app */
    985       nfa_rw_command_complete();
    986       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
    987       nfa_rw_cb.ndef_cur_size = p_rw_data->ndef.cur_size;
    988       nfa_rw_cb.ndef_max_size = p_rw_data->ndef.max_size;
    989       conn_evt_data.status = (p_rw_data->status == NFC_STATUS_OK)
    990                                  ? NFA_STATUS_OK
    991                                  : NFA_STATUS_FAILED;
    992 
    993       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
    994       break;
    995 
    996     case RW_T4T_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
    997       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
    998         nfa_rw_store_ndef_rx_buf(p_rw_data);
    999       } else {
   1000         nfa_rw_send_data_to_upper(p_rw_data);
   1001       }
   1002       break;
   1003 
   1004     case RW_T4T_NDEF_READ_CPLT_EVT: /* Read operation completed           */
   1005       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
   1006         nfa_rw_store_ndef_rx_buf(p_rw_data);
   1007 
   1008         /* Process the ndef record */
   1009         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
   1010                                    nfa_rw_cb.ndef_cur_size);
   1011 
   1012         /* Free ndef buffer */
   1013         nfa_rw_free_ndef_rx_buf();
   1014       } else {
   1015         nfa_rw_send_data_to_upper(p_rw_data);
   1016       }
   1017 
   1018       /* Command complete - perform cleanup, notify the app */
   1019       nfa_rw_command_complete();
   1020       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1021       conn_evt_data.status = NFC_STATUS_OK;
   1022       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1023       break;
   1024 
   1025     case RW_T4T_NDEF_READ_FAIL_EVT: /* Read operation failed              */
   1026       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
   1027         /* If current operation is READ_NDEF, then notify ndef handlers of
   1028          * failure */
   1029         nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
   1030 
   1031         /* Free ndef buffer */
   1032         nfa_rw_free_ndef_rx_buf();
   1033       }
   1034 
   1035       /* Command complete - perform cleanup, notify the app */
   1036       nfa_rw_command_complete();
   1037       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1038       conn_evt_data.status = NFA_STATUS_FAILED;
   1039       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1040       break;
   1041 
   1042     case RW_T4T_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
   1043     case RW_T4T_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
   1044 
   1045       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
   1046         /* Update local cursize of ndef message */
   1047         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
   1048       }
   1049 
   1050       /* Notify app */
   1051       if (event == RW_T4T_NDEF_UPDATE_CPLT_EVT)
   1052         conn_evt_data.status = NFA_STATUS_OK;
   1053       else
   1054         conn_evt_data.status = NFA_STATUS_FAILED;
   1055 
   1056       /* Command complete - perform cleanup, notify the app */
   1057       nfa_rw_command_complete();
   1058       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1059       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
   1060       break;
   1061 
   1062     case RW_T4T_RAW_FRAME_EVT: /* Raw Frame data event         */
   1063       nfa_rw_send_data_to_upper(p_rw_data);
   1064 
   1065       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
   1066         /* Command complete - perform cleanup */
   1067         nfa_rw_command_complete();
   1068         nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1069       }
   1070       break;
   1071 
   1072     case RW_T4T_SET_TO_RO_EVT: /* Tag is set as read only          */
   1073       conn_evt_data.status = p_rw_data->status;
   1074       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
   1075 
   1076       nfa_rw_command_complete();
   1077       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1078       break;
   1079 
   1080     case RW_T4T_INTF_ERROR_EVT: /* RF Interface error event         */
   1081       conn_evt_data.status = p_rw_data->status;
   1082       nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
   1083 
   1084       nfa_rw_command_complete();
   1085       nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   1086       break;
   1087 
   1088     case RW_T4T_PRESENCE_CHECK_EVT: /* Presence check completed */
   1089       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
   1090       break;
   1091 
   1092     default:
   1093       NFA_TRACE_DEBUG1("nfa_rw_handle_t4t_evt(); Unhandled RW event 0x%X",
   1094                        event);
   1095       break;
   1096   }
   1097 }
   1098 
   1099 /*******************************************************************************
   1100 **
   1101 ** Function         nfa_rw_handle_i93_evt
   1102 **
   1103 ** Description      Handler for ISO 15693 tag reader/writer events
   1104 **
   1105 ** Returns          Nothing
   1106 **
   1107 *******************************************************************************/
   1108 static void nfa_rw_handle_i93_evt(tRW_EVENT event, tRW_DATA* p_rw_data) {
   1109   tNFA_CONN_EVT_DATA conn_evt_data;
   1110   tNFA_TAG_PARAMS i93_params;
   1111 
   1112   switch (event) {
   1113     case RW_I93_NDEF_DETECT_EVT: /* Result of NDEF detection procedure */
   1114       nfa_rw_handle_ndef_detect(event, p_rw_data);
   1115       break;
   1116 
   1117     case RW_I93_NDEF_READ_EVT: /* Segment of data received from type 4 tag */
   1118       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
   1119         nfa_rw_store_ndef_rx_buf(p_rw_data);
   1120       } else {
   1121         nfa_rw_send_data_to_upper(p_rw_data);
   1122       }
   1123       break;
   1124 
   1125     case RW_I93_NDEF_READ_CPLT_EVT: /* Read operation completed           */
   1126       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
   1127         nfa_rw_store_ndef_rx_buf(p_rw_data);
   1128 
   1129         /* Process the ndef record */
   1130         nfa_dm_ndef_handle_message(NFA_STATUS_OK, nfa_rw_cb.p_ndef_buf,
   1131                                    nfa_rw_cb.ndef_cur_size);
   1132 
   1133         /* Free ndef buffer */
   1134         nfa_rw_free_ndef_rx_buf();
   1135       } else {
   1136         nfa_rw_send_data_to_upper(p_rw_data);
   1137       }
   1138 
   1139       /* Command complete - perform cleanup, notify app */
   1140       nfa_rw_command_complete();
   1141       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1142       conn_evt_data.status = NFC_STATUS_OK;
   1143       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1144       break;
   1145 
   1146     case RW_I93_NDEF_READ_FAIL_EVT: /* Read operation failed              */
   1147       if (nfa_rw_cb.cur_op == NFA_RW_OP_READ_NDEF) {
   1148         /* If current operation is READ_NDEF, then notify ndef handlers of
   1149          * failure */
   1150         nfa_dm_ndef_handle_message(NFA_STATUS_FAILED, NULL, 0);
   1151 
   1152         /* Free ndef buffer */
   1153         nfa_rw_free_ndef_rx_buf();
   1154       }
   1155 
   1156       /* Command complete - perform cleanup, notify app */
   1157       nfa_rw_command_complete();
   1158       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1159       conn_evt_data.status = NFA_STATUS_FAILED;
   1160       nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1161       break;
   1162 
   1163     case RW_I93_NDEF_UPDATE_CPLT_EVT: /* Update operation completed         */
   1164     case RW_I93_NDEF_UPDATE_FAIL_EVT: /* Update operation failed            */
   1165 
   1166       if (nfa_rw_cb.cur_op == NFA_RW_OP_WRITE_NDEF) {
   1167         /* Update local cursize of ndef message */
   1168         nfa_rw_cb.ndef_cur_size = nfa_rw_cb.ndef_wr_len;
   1169       }
   1170 
   1171       /* Command complete - perform cleanup, notify app */
   1172       nfa_rw_command_complete();
   1173       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1174 
   1175       if (event == RW_I93_NDEF_UPDATE_CPLT_EVT)
   1176         conn_evt_data.status = NFA_STATUS_OK;
   1177       else
   1178         conn_evt_data.status = NFA_STATUS_FAILED;
   1179 
   1180       /* Notify app of ndef write complete status */
   1181       nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
   1182       break;
   1183 
   1184     case RW_I93_RAW_FRAME_EVT: /* Raw Frame data event         */
   1185       nfa_rw_send_data_to_upper(p_rw_data);
   1186       if (p_rw_data->status != NFC_STATUS_CONTINUE) {
   1187         /* Command complete - perform cleanup */
   1188         nfa_rw_command_complete();
   1189       }
   1190       break;
   1191 
   1192     case RW_I93_INTF_ERROR_EVT: /* RF Interface error event         */
   1193       /* Command complete - perform cleanup, notify app */
   1194       nfa_rw_command_complete();
   1195 
   1196       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
   1197         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   1198 
   1199         memset(&i93_params, 0x00, sizeof(tNFA_TAG_PARAMS));
   1200         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
   1201 
   1202         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
   1203       } else {
   1204         conn_evt_data.status = p_rw_data->status;
   1205         nfa_dm_act_conn_cback_notify(NFA_RW_INTF_ERROR_EVT, &conn_evt_data);
   1206       }
   1207 
   1208       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1209       break;
   1210 
   1211     case RW_I93_PRESENCE_CHECK_EVT: /* Presence check completed */
   1212       nfa_rw_handle_presence_check_rsp(p_rw_data->status);
   1213       break;
   1214 
   1215     case RW_I93_FORMAT_CPLT_EVT: /* Format procedure complete          */
   1216       if (p_rw_data->data.status == NFA_STATUS_OK)
   1217         nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   1218 
   1219       /* Command complete - perform cleanup, notify app */
   1220       nfa_rw_command_complete();
   1221       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1222       conn_evt_data.status = p_rw_data->status;
   1223       nfa_dm_act_conn_cback_notify(NFA_FORMAT_CPLT_EVT, &conn_evt_data);
   1224       break;
   1225 
   1226     case RW_I93_SET_TAG_RO_EVT: /* Set read-only procedure complete   */
   1227       nfa_rw_cb.flags |= NFA_RW_FL_TAG_IS_READONLY;
   1228 
   1229       /* Command complete - perform cleanup, notify app */
   1230       nfa_rw_command_complete();
   1231       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1232       conn_evt_data.status = p_rw_data->status;
   1233       nfa_dm_act_conn_cback_notify(NFA_SET_TAG_RO_EVT, &conn_evt_data);
   1234       break;
   1235 
   1236     case RW_I93_INVENTORY_EVT: /* Response of Inventory              */
   1237 
   1238       /* Command complete - perform cleanup, notify app */
   1239       nfa_rw_command_complete();
   1240 
   1241       conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_inventory.status;
   1242       conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
   1243 
   1244       conn_evt_data.i93_cmd_cplt.params.inventory.dsfid =
   1245           p_rw_data->i93_inventory.dsfid;
   1246       memcpy(conn_evt_data.i93_cmd_cplt.params.inventory.uid,
   1247              p_rw_data->i93_inventory.uid, I93_UID_BYTE_LEN);
   1248 
   1249       nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
   1250 
   1251       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1252       break;
   1253 
   1254     case RW_I93_DATA_EVT: /* Response of Read, Get Multi Security */
   1255 
   1256       /* Command complete - perform cleanup, notify app */
   1257       nfa_rw_command_complete();
   1258 
   1259       conn_evt_data.data.p_data = (uint8_t*)(p_rw_data->i93_data.p_data + 1) +
   1260                                   p_rw_data->i93_data.p_data->offset;
   1261 
   1262       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
   1263         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   1264 
   1265         i93_params.i93.info_flags =
   1266             (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE | I93_INFO_FLAG_AFI);
   1267         i93_params.i93.afi =
   1268             *(conn_evt_data.data.p_data +
   1269               nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
   1270         i93_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
   1271         i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
   1272         i93_params.i93.num_block = nfa_rw_cb.i93_num_block;
   1273         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
   1274 
   1275         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
   1276       } else {
   1277         conn_evt_data.data.len = p_rw_data->i93_data.p_data->len;
   1278 
   1279         nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
   1280       }
   1281 
   1282       GKI_freebuf(p_rw_data->i93_data.p_data);
   1283       p_rw_data->i93_data.p_data = NULL;
   1284 
   1285       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1286       break;
   1287 
   1288     case RW_I93_SYS_INFO_EVT: /* Response of System Information     */
   1289 
   1290       /* Command complete - perform cleanup, notify app */
   1291       nfa_rw_command_complete();
   1292 
   1293       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
   1294         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   1295 
   1296         nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
   1297         nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
   1298 
   1299         i93_params.i93.info_flags = p_rw_data->i93_sys_info.info_flags;
   1300         i93_params.i93.dsfid = p_rw_data->i93_sys_info.dsfid;
   1301         i93_params.i93.afi = p_rw_data->i93_sys_info.afi;
   1302         i93_params.i93.num_block = p_rw_data->i93_sys_info.num_block;
   1303         i93_params.i93.block_size = p_rw_data->i93_sys_info.block_size;
   1304         i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
   1305         memcpy(i93_params.i93.uid, p_rw_data->i93_sys_info.uid,
   1306                I93_UID_BYTE_LEN);
   1307 
   1308         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
   1309       } else {
   1310         conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_sys_info.status;
   1311         conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
   1312 
   1313         conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags =
   1314             p_rw_data->i93_sys_info.info_flags;
   1315         memcpy(conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
   1316                p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
   1317         conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid =
   1318             p_rw_data->i93_sys_info.dsfid;
   1319         conn_evt_data.i93_cmd_cplt.params.sys_info.afi =
   1320             p_rw_data->i93_sys_info.afi;
   1321         conn_evt_data.i93_cmd_cplt.params.sys_info.num_block =
   1322             p_rw_data->i93_sys_info.num_block;
   1323         conn_evt_data.i93_cmd_cplt.params.sys_info.block_size =
   1324             p_rw_data->i93_sys_info.block_size;
   1325         conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference =
   1326             p_rw_data->i93_sys_info.IC_reference;
   1327 
   1328         /* store tag memory information for writing blocks */
   1329         nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
   1330         nfa_rw_cb.i93_num_block = p_rw_data->i93_sys_info.num_block;
   1331 
   1332         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
   1333       }
   1334 
   1335       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1336       break;
   1337 
   1338     case RW_I93_CMD_CMPL_EVT: /* Command complete                   */
   1339       /* Command complete - perform cleanup, notify app */
   1340       nfa_rw_command_complete();
   1341 
   1342       if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING) {
   1343         /* Reader got error code from tag */
   1344 
   1345         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   1346 
   1347         memset(&i93_params, 0x00, sizeof(i93_params));
   1348         memcpy(i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
   1349 
   1350         nfa_dm_notify_activation_status(NFA_STATUS_OK, &i93_params);
   1351       } else {
   1352         conn_evt_data.i93_cmd_cplt.status = p_rw_data->i93_cmd_cmpl.status;
   1353         conn_evt_data.i93_cmd_cplt.sent_command =
   1354             p_rw_data->i93_cmd_cmpl.command;
   1355 
   1356         if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
   1357           conn_evt_data.i93_cmd_cplt.params.error_code =
   1358               p_rw_data->i93_cmd_cmpl.error_code;
   1359 
   1360         nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
   1361       }
   1362 
   1363       nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
   1364       break;
   1365 
   1366     default:
   1367       NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X",
   1368                        event);
   1369       break;
   1370   }
   1371 }
   1372 
   1373 /*******************************************************************************
   1374 **
   1375 ** Function         nfa_rw_cback
   1376 **
   1377 ** Description      Callback for reader/writer event notification
   1378 **
   1379 ** Returns          Nothing
   1380 **
   1381 *******************************************************************************/
   1382 static void nfa_rw_cback(tRW_EVENT event, tRW_DATA* p_rw_data) {
   1383   NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event);
   1384 
   1385   /* Call appropriate event handler for tag type */
   1386   if (event < RW_T1T_MAX_EVT) {
   1387     /* Handle Type-1 tag events */
   1388     nfa_rw_handle_t1t_evt(event, p_rw_data);
   1389   } else if (event < RW_T2T_MAX_EVT) {
   1390     /* Handle Type-2 tag events */
   1391     nfa_rw_handle_t2t_evt(event, p_rw_data);
   1392   } else if (event < RW_T3T_MAX_EVT) {
   1393     /* Handle Type-3 tag events */
   1394     nfa_rw_handle_t3t_evt(event, p_rw_data);
   1395   } else if (event < RW_T4T_MAX_EVT) {
   1396     /* Handle Type-4 tag events */
   1397     nfa_rw_handle_t4t_evt(event, p_rw_data);
   1398   } else if (event < RW_I93_MAX_EVT) {
   1399     /* Handle ISO 15693 tag events */
   1400     nfa_rw_handle_i93_evt(event, p_rw_data);
   1401   } else {
   1402     NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event);
   1403   }
   1404 }
   1405 
   1406 /*******************************************************************************
   1407 **
   1408 ** Function         nfa_rw_start_ndef_detection
   1409 **
   1410 ** Description      Start NDEF detection on activated tag
   1411 **
   1412 ** Returns          Nothing
   1413 **
   1414 *******************************************************************************/
   1415 static tNFC_STATUS nfa_rw_start_ndef_detection(void) {
   1416   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1417   tNFC_STATUS status = NFC_STATUS_FAILED;
   1418 
   1419   if (NFC_PROTOCOL_T1T == protocol) {
   1420     /* Type1Tag    - NFC-A */
   1421     status = RW_T1tDetectNDef();
   1422   } else if (NFC_PROTOCOL_T2T == protocol) {
   1423     /* Type2Tag    - NFC-A */
   1424     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1425       status = RW_T2tDetectNDef(nfa_rw_cb.skip_dyn_locks);
   1426     }
   1427   } else if (NFC_PROTOCOL_T3T == protocol) {
   1428     /* Type3Tag    - NFC-F */
   1429     status = RW_T3tDetectNDef();
   1430   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
   1431     /* ISODEP/4A,4B- NFC-A or NFC-B */
   1432     status = RW_T4tDetectNDef();
   1433   } else if (NFC_PROTOCOL_15693 == protocol) {
   1434     /* ISO 15693 */
   1435     status = RW_I93DetectNDef();
   1436   }
   1437 
   1438   return (status);
   1439 }
   1440 
   1441 /*******************************************************************************
   1442 **
   1443 ** Function         nfa_rw_start_ndef_read
   1444 **
   1445 ** Description      Start NDEF read on activated tag
   1446 **
   1447 ** Returns          Nothing
   1448 **
   1449 *******************************************************************************/
   1450 static tNFC_STATUS nfa_rw_start_ndef_read(void) {
   1451   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1452   tNFC_STATUS status = NFC_STATUS_FAILED;
   1453   tNFA_CONN_EVT_DATA conn_evt_data;
   1454 
   1455   /* Handle zero length NDEF message */
   1456   if (nfa_rw_cb.ndef_cur_size == 0) {
   1457     NFA_TRACE_DEBUG0("NDEF message is zero-length");
   1458 
   1459     /* Send zero-lengh NDEF message to ndef callback */
   1460     nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
   1461 
   1462     /* Command complete - perform cleanup, notify app */
   1463     nfa_rw_command_complete();
   1464     conn_evt_data.status = NFA_STATUS_OK;
   1465     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1466     return NFC_STATUS_OK;
   1467   }
   1468 
   1469   /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if
   1470    * needed) */
   1471   nfa_rw_free_ndef_rx_buf();
   1472   nfa_rw_cb.p_ndef_buf = (uint8_t*)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size);
   1473   if (nfa_rw_cb.p_ndef_buf == NULL) {
   1474     NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)",
   1475                      nfa_rw_cb.ndef_cur_size);
   1476 
   1477     /* Command complete - perform cleanup, notify app */
   1478     nfa_rw_command_complete();
   1479     conn_evt_data.status = NFA_STATUS_FAILED;
   1480     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1481     return NFC_STATUS_FAILED;
   1482   }
   1483   nfa_rw_cb.ndef_rd_offset = 0;
   1484 
   1485   if (NFC_PROTOCOL_T1T == protocol) {
   1486     /* Type1Tag    - NFC-A */
   1487     status =
   1488         RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf, (uint16_t)nfa_rw_cb.ndef_cur_size);
   1489   } else if (NFC_PROTOCOL_T2T == protocol) {
   1490     /* Type2Tag    - NFC-A */
   1491     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1492       status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,
   1493                               (uint16_t)nfa_rw_cb.ndef_cur_size);
   1494     }
   1495   } else if (NFC_PROTOCOL_T3T == protocol) {
   1496     /* Type3Tag    - NFC-F */
   1497     status = RW_T3tCheckNDef();
   1498   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
   1499     /* ISODEP/4A,4B- NFC-A or NFC-B */
   1500     status = RW_T4tReadNDef();
   1501   } else if (NFC_PROTOCOL_15693 == protocol) {
   1502     /* ISO 15693 */
   1503     status = RW_I93ReadNDef();
   1504   }
   1505 
   1506   return (status);
   1507 }
   1508 
   1509 /*******************************************************************************
   1510 **
   1511 ** Function         nfa_rw_detect_ndef
   1512 **
   1513 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
   1514 **
   1515 ** Returns          TRUE (message buffer to be freed by caller)
   1516 **
   1517 *******************************************************************************/
   1518 static bool nfa_rw_detect_ndef(tNFA_RW_MSG* p_data) {
   1519   tNFA_CONN_EVT_DATA conn_evt_data;
   1520   NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
   1521 
   1522   conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection();
   1523   if (conn_evt_data.ndef_detect.status != NFC_STATUS_OK) {
   1524     /* Command complete - perform cleanup, notify app */
   1525     nfa_rw_command_complete();
   1526     conn_evt_data.ndef_detect.cur_size = 0;
   1527     conn_evt_data.ndef_detect.max_size = 0;
   1528     conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
   1529     nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
   1530   }
   1531 
   1532   return true;
   1533 }
   1534 
   1535 /*******************************************************************************
   1536 **
   1537 ** Function         nfa_rw_start_ndef_write
   1538 **
   1539 ** Description      Start NDEF write on activated tag
   1540 **
   1541 ** Returns          Nothing
   1542 **
   1543 *******************************************************************************/
   1544 static tNFC_STATUS nfa_rw_start_ndef_write(void) {
   1545   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1546   tNFC_STATUS status = NFC_STATUS_FAILED;
   1547 
   1548   if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY) {
   1549     /* error: ndef tag is read-only */
   1550     status = NFC_STATUS_FAILED;
   1551     NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
   1552   } else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len) {
   1553     /* error: ndef tag size is too small */
   1554     status = NFC_STATUS_BUFFER_FULL;
   1555     NFA_TRACE_ERROR2(
   1556         "Unable to write NDEF. Tag maxsize=%i, request write size=%i",
   1557         nfa_rw_cb.ndef_max_size, nfa_rw_cb.ndef_wr_len)
   1558   } else {
   1559     if (NFC_PROTOCOL_T1T == protocol) {
   1560       /* Type1Tag    - NFC-A */
   1561       status = RW_T1tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
   1562                                nfa_rw_cb.p_ndef_wr_buf);
   1563     } else if (NFC_PROTOCOL_T2T == protocol) {
   1564       /* Type2Tag    - NFC-A */
   1565       if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1566         status = RW_T2tWriteNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
   1567                                  nfa_rw_cb.p_ndef_wr_buf);
   1568       }
   1569     } else if (NFC_PROTOCOL_T3T == protocol) {
   1570       /* Type3Tag    - NFC-F */
   1571       status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
   1572     } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
   1573       /* ISODEP/4A,4B- NFC-A or NFC-B */
   1574       status = RW_T4tUpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
   1575                                 nfa_rw_cb.p_ndef_wr_buf);
   1576     } else if (NFC_PROTOCOL_15693 == protocol) {
   1577       /* ISO 15693 */
   1578       status = RW_I93UpdateNDef((uint16_t)nfa_rw_cb.ndef_wr_len,
   1579                                 nfa_rw_cb.p_ndef_wr_buf);
   1580     }
   1581   }
   1582 
   1583   return (status);
   1584 }
   1585 
   1586 /*******************************************************************************
   1587 **
   1588 ** Function         nfa_rw_read_ndef
   1589 **
   1590 ** Description      Handler for NFA_RW_API_READ_NDEF_EVT
   1591 **
   1592 ** Returns          TRUE (message buffer to be freed by caller)
   1593 **
   1594 *******************************************************************************/
   1595 static bool nfa_rw_read_ndef(tNFA_RW_MSG* p_data) {
   1596   tNFA_STATUS status = NFA_STATUS_OK;
   1597   tNFA_CONN_EVT_DATA conn_evt_data;
   1598 
   1599   NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
   1600 
   1601   /* Check if ndef detection has been performed yet */
   1602   if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
   1603     /* Perform ndef detection first */
   1604     status = nfa_rw_start_ndef_detection();
   1605   } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
   1606     /* Tag is not NDEF */
   1607     status = NFA_STATUS_FAILED;
   1608   } else {
   1609     /* Perform the NDEF read operation */
   1610     status = nfa_rw_start_ndef_read();
   1611   }
   1612 
   1613   /* Handle failure */
   1614   if (status != NFA_STATUS_OK) {
   1615     /* Command complete - perform cleanup, notify app */
   1616     nfa_rw_command_complete();
   1617     conn_evt_data.status = status;
   1618     nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
   1619   }
   1620 
   1621   return true;
   1622 }
   1623 
   1624 /*******************************************************************************
   1625 **
   1626 ** Function         nfa_rw_write_ndef
   1627 **
   1628 ** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
   1629 **
   1630 ** Returns          TRUE (message buffer to be freed by caller)
   1631 **
   1632 *******************************************************************************/
   1633 static bool nfa_rw_write_ndef(tNFA_RW_MSG* p_data) {
   1634   tNDEF_STATUS ndef_status;
   1635   tNFA_STATUS write_status = NFA_STATUS_OK;
   1636   tNFA_CONN_EVT_DATA conn_evt_data;
   1637   NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
   1638 
   1639   /* Validate NDEF message */
   1640   ndef_status = NDEF_MsgValidate(p_data->op_req.params.write_ndef.p_data,
   1641                                  p_data->op_req.params.write_ndef.len, false);
   1642   if (ndef_status != NDEF_OK) {
   1643     NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i",
   1644                      ndef_status);
   1645 
   1646     /* Command complete - perform cleanup, notify app */
   1647     nfa_rw_command_complete();
   1648     conn_evt_data.status = NFA_STATUS_FAILED;
   1649     nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
   1650     return true;
   1651   }
   1652 
   1653   /* Store pointer to source NDEF */
   1654   nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
   1655   nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
   1656 
   1657   /* Check if ndef detection has been performed yet */
   1658   if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN) {
   1659     /* Perform ndef detection first */
   1660     write_status = nfa_rw_start_ndef_detection();
   1661   } else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE) {
   1662     if (nfa_rw_cb.protocol == NFC_PROTOCOL_T1T) {
   1663       /* For Type 1 tag, NDEF can be written on Initialized tag
   1664       *  Perform ndef detection first to check if tag is in Initialized state to
   1665       * Write NDEF */
   1666       write_status = nfa_rw_start_ndef_detection();
   1667     } else {
   1668       /* Tag is not NDEF */
   1669       write_status = NFA_STATUS_FAILED;
   1670     }
   1671   } else {
   1672     /* Perform the NDEF read operation */
   1673     write_status = nfa_rw_start_ndef_write();
   1674   }
   1675 
   1676   /* Handle failure */
   1677   if (write_status != NFA_STATUS_OK) {
   1678     /* Command complete - perform cleanup, notify app */
   1679     nfa_rw_command_complete();
   1680     conn_evt_data.status = write_status;
   1681     nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
   1682   }
   1683 
   1684   return true;
   1685 }
   1686 
   1687 /*******************************************************************************
   1688 **
   1689 ** Function         nfa_rw_presence_check
   1690 **
   1691 ** Description      Handler for NFA_RW_API_PRESENCE_CHECK
   1692 **
   1693 ** Returns          Nothing
   1694 **
   1695 *******************************************************************************/
   1696 void nfa_rw_presence_check(tNFA_RW_MSG* p_data) {
   1697   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1698   uint8_t sel_res = nfa_rw_cb.pa_sel_res;
   1699   tNFC_STATUS status = NFC_STATUS_FAILED;
   1700   bool unsupported = false;
   1701   uint8_t option = NFA_RW_OPTION_INVALID;
   1702   tNFA_RW_PRES_CHK_OPTION op_param = NFA_RW_PRES_CHK_DEFAULT;
   1703 
   1704   if (NFC_PROTOCOL_T1T == protocol) {
   1705     /* Type1Tag    - NFC-A */
   1706     status = RW_T1tPresenceCheck();
   1707   } else if (NFC_PROTOCOL_T2T == protocol) {
   1708     /* If T2T NFC-Forum, then let RW handle presence check */
   1709     if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1710       /* Type 2 tag have not sent NACK after activation */
   1711       status = RW_T2tPresenceCheck();
   1712     } else {
   1713       /* Will fall back to deactivate/reactivate */
   1714       unsupported = true;
   1715     }
   1716   } else if (NFC_PROTOCOL_T3T == protocol) {
   1717     /* Type3Tag    - NFC-F */
   1718     status = RW_T3tPresenceCheck();
   1719   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
   1720     /* ISODEP/4A,4B- NFC-A or NFC-B */
   1721     if (p_data) {
   1722       op_param = p_data->op_req.params.option;
   1723     }
   1724 
   1725     switch (op_param) {
   1726       case NFA_RW_PRES_CHK_I_BLOCK:
   1727         option = RW_T4T_CHK_EMPTY_I_BLOCK;
   1728         break;
   1729 
   1730       case NFA_RW_PRES_CHK_RESET:
   1731         /* option is initialized to NFA_RW_OPTION_INVALID, which will Deactivate
   1732          * to Sleep; Re-activate */
   1733         break;
   1734 
   1735       case NFA_RW_PRES_CHK_RB_CH0:
   1736         option = RW_T4T_CHK_READ_BINARY_CH0;
   1737         break;
   1738 
   1739       case NFA_RW_PRES_CHK_RB_CH3:
   1740         option = RW_T4T_CHK_READ_BINARY_CH3;
   1741         break;
   1742 
   1743       default:
   1744         if (nfa_rw_cb.flags & NFA_RW_FL_NDEF_OK) {
   1745           /* read binary on channel 0 */
   1746           option = RW_T4T_CHK_READ_BINARY_CH0;
   1747         } else {
   1748           /* NDEF DETECT failed.*/
   1749           if (nfa_dm_is_raw_frame_session()) {
   1750             /* NFA_SendRawFrame() is called */
   1751             if (p_nfa_dm_cfg->presence_check_option &
   1752                 NFA_DM_PCO_EMPTY_I_BLOCK) {
   1753               /* empty I block */
   1754               option = RW_T4T_CHK_EMPTY_I_BLOCK;
   1755             } else {
   1756               /* read binary on channel 3 */
   1757               option = RW_T4T_CHK_READ_BINARY_CH3;
   1758             }
   1759           } else if (!(p_nfa_dm_cfg->presence_check_option &
   1760                        NFA_DM_PCO_ISO_SLEEP_WAKE) &&
   1761                      (nfa_rw_cb.intf_type == NFC_INTERFACE_ISO_DEP)) {
   1762             /* the option indicates to use empty I block && ISODEP interface is
   1763              * activated */
   1764             option = RW_T4T_CHK_EMPTY_I_BLOCK;
   1765           }
   1766         }
   1767     }
   1768 
   1769     if (option != NFA_RW_OPTION_INVALID) {
   1770       /* use the presence check with the chosen option */
   1771       status = RW_T4tPresenceCheck(option);
   1772     } else {
   1773       /* use sleep/wake for presence check */
   1774       unsupported = true;
   1775     }
   1776   } else if (NFC_PROTOCOL_15693 == protocol) {
   1777     /* ISO 15693 */
   1778     status = RW_I93PresenceCheck();
   1779   } else {
   1780     /* Protocol unsupported by RW module... */
   1781     unsupported = true;
   1782   }
   1783 
   1784   if (unsupported) {
   1785     if (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_KOVIO) {
   1786       /* start Kovio presence check (deactivate and wait for activation) */
   1787       status = nfa_dm_disc_start_kovio_presence_check();
   1788     } else {
   1789       /* Let DM perform presence check (by putting tag to sleep and then waking
   1790        * it up) */
   1791       status = nfa_dm_disc_sleep_wakeup();
   1792     }
   1793   }
   1794 
   1795   /* Handle presence check failure */
   1796   if (status != NFC_STATUS_OK)
   1797     nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
   1798   else if (!unsupported) {
   1799     nfa_sys_start_timer(&nfa_rw_cb.tle, NFA_RW_PRESENCE_CHECK_TIMEOUT_EVT,
   1800                         p_nfa_dm_cfg->presence_check_timeout);
   1801   }
   1802 }
   1803 
   1804 /*******************************************************************************
   1805 **
   1806 ** Function         nfa_rw_presence_check_tick
   1807 **
   1808 ** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
   1809 **                  Initiate presence check
   1810 **
   1811 ** Returns          TRUE (caller frees message buffer)
   1812 **
   1813 *******************************************************************************/
   1814 bool nfa_rw_presence_check_tick(tNFA_RW_MSG* p_data) {
   1815   /* Store the current operation */
   1816   nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
   1817   nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
   1818   NFA_TRACE_DEBUG0("Auto-presence check starting...");
   1819 
   1820   /* Perform presence check */
   1821   nfa_rw_presence_check(NULL);
   1822 
   1823   return true;
   1824 }
   1825 
   1826 /*******************************************************************************
   1827 **
   1828 ** Function         nfa_rw_presence_check_timeout
   1829 **
   1830 ** Description      presence check timeout: report presence check failure
   1831 **
   1832 ** Returns          TRUE (caller frees message buffer)
   1833 **
   1834 *******************************************************************************/
   1835 bool nfa_rw_presence_check_timeout(tNFA_RW_MSG* p_data) {
   1836   nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
   1837   return true;
   1838 }
   1839 
   1840 /*******************************************************************************
   1841 **
   1842 ** Function         nfa_rw_format_tag
   1843 **
   1844 ** Description      Handler for NFA_RW_API_FORMAT_TAG
   1845 **
   1846 ** Returns          Nothing
   1847 **
   1848 *******************************************************************************/
   1849 static void nfa_rw_format_tag(tNFA_RW_MSG* p_data) {
   1850   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1851   tNFC_STATUS status = NFC_STATUS_FAILED;
   1852 
   1853   if (protocol == NFC_PROTOCOL_T1T) {
   1854     status = RW_T1tFormatNDef();
   1855   } else if ((protocol == NFC_PROTOCOL_T2T) &&
   1856              (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
   1857     status = RW_T2tFormatNDef();
   1858   } else if (protocol == NFC_PROTOCOL_T3T) {
   1859     status = RW_T3tFormatNDef();
   1860   } else if (protocol == NFC_PROTOCOL_15693) {
   1861     status = RW_I93FormatNDef();
   1862   } else if (protocol == NFC_PROTOCOL_ISO_DEP) {
   1863     status = RW_T4tFormatNDef();
   1864   }
   1865 
   1866   /* If unable to format NDEF, notify the app */
   1867   if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_FORMAT_CPLT_EVT);
   1868 }
   1869 
   1870 /*******************************************************************************
   1871 **
   1872 ** Function         nfa_rw_detect_tlv
   1873 **
   1874 ** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
   1875 **
   1876 ** Returns          TRUE (message buffer to be freed by caller)
   1877 **
   1878 *******************************************************************************/
   1879 static bool nfa_rw_detect_tlv(tNFA_RW_MSG* p_data, uint8_t tlv) {
   1880   NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
   1881 
   1882   switch (nfa_rw_cb.protocol) {
   1883     case NFC_PROTOCOL_T1T:
   1884       if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
   1885         nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
   1886       break;
   1887 
   1888     case NFC_PROTOCOL_T2T:
   1889       if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1890         if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
   1891           nfa_rw_error_cleanup(NFA_TLV_DETECT_EVT);
   1892       }
   1893       break;
   1894 
   1895     default:
   1896       break;
   1897   }
   1898 
   1899   return true;
   1900 }
   1901 
   1902 /*******************************************************************************
   1903 **
   1904 ** Function         nfa_rw_config_tag_ro
   1905 **
   1906 ** Description      Handler for NFA_RW_OP_SET_TAG_RO
   1907 **
   1908 ** Returns          TRUE (message buffer to be freed by caller)
   1909 **
   1910 *******************************************************************************/
   1911 static tNFC_STATUS nfa_rw_config_tag_ro(bool b_hard_lock) {
   1912   tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
   1913   tNFC_STATUS status = NFC_STATUS_FAILED;
   1914 
   1915   NFA_TRACE_DEBUG0("nfa_rw_config_tag_ro ()");
   1916 
   1917   if (NFC_PROTOCOL_T1T == protocol) {
   1918     /* Type1Tag    - NFC-A */
   1919     if ((nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED) ||
   1920         (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE)) {
   1921       status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
   1922       return (status);
   1923     } else {
   1924       status = RW_T1tSetTagReadOnly(b_hard_lock);
   1925     }
   1926   } else if (NFC_PROTOCOL_T2T == protocol) {
   1927     /* Type2Tag    - NFC-A */
   1928     if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) {
   1929       status = RW_T2tSetTagReadOnly(b_hard_lock);
   1930     }
   1931   } else if (NFC_PROTOCOL_T3T == protocol) {
   1932     /* Type3Tag    - NFC-F */
   1933     status = RW_T3tSetReadOnly(b_hard_lock);
   1934   } else if (NFC_PROTOCOL_ISO_DEP == protocol) {
   1935     /* ISODEP/4A,4B- NFC-A or NFC-B */
   1936     status = RW_T4tSetNDefReadOnly();
   1937   } else if (NFC_PROTOCOL_15693 == protocol) {
   1938     /* ISO 15693 */
   1939     status = RW_I93SetTagReadOnly();
   1940   }
   1941 
   1942   if (status == NFC_STATUS_OK) {
   1943     nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   1944   } else {
   1945     nfa_rw_error_cleanup(NFA_SET_TAG_RO_EVT);
   1946   }
   1947 
   1948   return (status);
   1949 }
   1950 
   1951 /*******************************************************************************
   1952 **
   1953 ** Function         nfa_rw_t1t_rid
   1954 **
   1955 ** Description      Handler for T1T_RID API
   1956 **
   1957 ** Returns          TRUE (message buffer to be freed by caller)
   1958 **
   1959 *******************************************************************************/
   1960 static bool nfa_rw_t1t_rid(tNFA_RW_MSG* p_data) {
   1961   if (RW_T1tRid() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   1962 
   1963   return true;
   1964 }
   1965 
   1966 /*******************************************************************************
   1967 **
   1968 ** Function         nfa_rw_t1t_rall
   1969 **
   1970 ** Description      Handler for T1T_ReadAll API
   1971 **
   1972 ** Returns          TRUE (message buffer to be freed by caller)
   1973 **
   1974 *******************************************************************************/
   1975 static bool nfa_rw_t1t_rall(tNFA_RW_MSG* p_data) {
   1976   if (RW_T1tReadAll() != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   1977 
   1978   return true;
   1979 }
   1980 
   1981 /*******************************************************************************
   1982 **
   1983 ** Function         nfa_rw_t1t_read
   1984 **
   1985 ** Description      Handler for T1T_Read API
   1986 **
   1987 ** Returns          TRUE (message buffer to be freed by caller)
   1988 **
   1989 *******************************************************************************/
   1990 static bool nfa_rw_t1t_read(tNFA_RW_MSG* p_data) {
   1991   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
   1992       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
   1993 
   1994   if (RW_T1tRead(p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
   1995     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   1996 
   1997   return true;
   1998 }
   1999 
   2000 /*******************************************************************************
   2001 **
   2002 ** Function         nfa_rw_t1t_write
   2003 **
   2004 ** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
   2005 **
   2006 ** Returns          TRUE (message buffer to be freed by caller)
   2007 **
   2008 *******************************************************************************/
   2009 static bool nfa_rw_t1t_write(tNFA_RW_MSG* p_data) {
   2010   tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
   2011       (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
   2012   tNFC_STATUS status;
   2013 
   2014   if (p_t1t_write->b_erase) {
   2015     status = RW_T1tWriteErase(p_t1t_write->block_number, p_t1t_write->index,
   2016                               p_t1t_write->p_block_data[0]);
   2017   } else {
   2018     status = RW_T1tWriteNoErase(p_t1t_write->block_number, p_t1t_write->index,
   2019                                 p_t1t_write->p_block_data[0]);
   2020   }
   2021 
   2022   if (status != NFC_STATUS_OK) {
   2023     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
   2024   } else {
   2025     if (p_t1t_write->block_number == 0x01)
   2026       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   2027   }
   2028 
   2029   return true;
   2030 }
   2031 
   2032 /*******************************************************************************
   2033 **
   2034 ** Function         nfa_rw_t1t_rseg
   2035 **
   2036 ** Description      Handler for T1t_ReadSeg API
   2037 **
   2038 ** Returns          TRUE (message buffer to be freed by caller)
   2039 **
   2040 *******************************************************************************/
   2041 static bool nfa_rw_t1t_rseg(tNFA_RW_MSG* p_data) {
   2042   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
   2043       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
   2044 
   2045   if (RW_T1tReadSeg(p_t1t_read->segment_number) != NFC_STATUS_OK)
   2046     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   2047 
   2048   return true;
   2049 }
   2050 
   2051 /*******************************************************************************
   2052 **
   2053 ** Function         nfa_rw_t1t_read8
   2054 **
   2055 ** Description      Handler for T1T_Read8 API
   2056 **
   2057 ** Returns          TRUE (message buffer to be freed by caller)
   2058 **
   2059 *******************************************************************************/
   2060 static bool nfa_rw_t1t_read8(tNFA_RW_MSG* p_data) {
   2061   tNFA_RW_OP_PARAMS_T1T_READ* p_t1t_read =
   2062       (tNFA_RW_OP_PARAMS_T1T_READ*)&(p_data->op_req.params.t1t_read);
   2063 
   2064   if (RW_T1tRead8(p_t1t_read->block_number) != NFC_STATUS_OK)
   2065     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   2066 
   2067   return true;
   2068 }
   2069 
   2070 /*******************************************************************************
   2071 **
   2072 ** Function         nfa_rw_t1t_write8
   2073 **
   2074 ** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
   2075 **
   2076 ** Returns          TRUE (message buffer to be freed by caller)
   2077 **
   2078 *******************************************************************************/
   2079 static bool nfa_rw_t1t_write8(tNFA_RW_MSG* p_data) {
   2080   tNFA_RW_OP_PARAMS_T1T_WRITE* p_t1t_write =
   2081       (tNFA_RW_OP_PARAMS_T1T_WRITE*)&(p_data->op_req.params.t1t_write);
   2082   tNFC_STATUS status;
   2083 
   2084   if (p_t1t_write->b_erase) {
   2085     status =
   2086         RW_T1tWriteErase8(p_t1t_write->block_number, p_t1t_write->p_block_data);
   2087   } else {
   2088     status = RW_T1tWriteNoErase8(p_t1t_write->block_number,
   2089                                  p_t1t_write->p_block_data);
   2090   }
   2091 
   2092   if (status != NFC_STATUS_OK) {
   2093     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
   2094   } else {
   2095     if (p_t1t_write->block_number == 0x01)
   2096       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   2097   }
   2098 
   2099   return true;
   2100 }
   2101 
   2102 /*******************************************************************************
   2103 **
   2104 ** Function         nfa_rw_t2t_read
   2105 **
   2106 ** Description      Handler for T2T_Read API
   2107 **
   2108 ** Returns          TRUE (message buffer to be freed by caller)
   2109 **
   2110 *******************************************************************************/
   2111 static bool nfa_rw_t2t_read(tNFA_RW_MSG* p_data) {
   2112   tNFA_RW_OP_PARAMS_T2T_READ* p_t2t_read =
   2113       (tNFA_RW_OP_PARAMS_T2T_READ*)&(p_data->op_req.params.t2t_read);
   2114   tNFC_STATUS status = NFC_STATUS_FAILED;
   2115 
   2116   if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
   2117     status = RW_T2tRead(p_t2t_read->block_number);
   2118 
   2119   if (status != NFC_STATUS_OK) nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   2120 
   2121   return true;
   2122 }
   2123 
   2124 /*******************************************************************************
   2125 **
   2126 ** Function         nfa_rw_t2t_write
   2127 **
   2128 ** Description      Handler for T2T_Write API
   2129 **
   2130 ** Returns          TRUE (message buffer to be freed by caller)
   2131 **
   2132 *******************************************************************************/
   2133 static bool nfa_rw_t2t_write(tNFA_RW_MSG* p_data) {
   2134   tNFA_RW_OP_PARAMS_T2T_WRITE* p_t2t_write =
   2135       (tNFA_RW_OP_PARAMS_T2T_WRITE*)&(p_data->op_req.params.t2t_write);
   2136 
   2137   if (RW_T2tWrite(p_t2t_write->block_number, p_t2t_write->p_block_data) !=
   2138       NFC_STATUS_OK) {
   2139     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
   2140   } else {
   2141     if (p_t2t_write->block_number == 0x03)
   2142       nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   2143   }
   2144 
   2145   return true;
   2146 }
   2147 
   2148 /*******************************************************************************
   2149 **
   2150 ** Function         nfa_rw_t2t_sector_select
   2151 **
   2152 ** Description      Handler for T2T_Sector_Select API
   2153 **
   2154 ** Returns          TRUE (message buffer to be freed by caller)
   2155 **
   2156 *******************************************************************************/
   2157 static bool nfa_rw_t2t_sector_select(tNFA_RW_MSG* p_data) {
   2158   tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT* p_t2t_sector_select =
   2159       (tNFA_RW_OP_PARAMS_T2T_SECTOR_SELECT*)&(
   2160           p_data->op_req.params.t2t_sector_select);
   2161 
   2162   if (RW_T2tSectorSelect(p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
   2163     nfa_rw_error_cleanup(NFA_SELECT_CPLT_EVT);
   2164 
   2165   return true;
   2166 }
   2167 
   2168 /*******************************************************************************
   2169 **
   2170 ** Function         nfa_rw_t3t_read
   2171 **
   2172 ** Description      Handler for T3T_Read API
   2173 **
   2174 ** Returns          TRUE (message buffer to be freed by caller)
   2175 **
   2176 *******************************************************************************/
   2177 static bool nfa_rw_t3t_read(tNFA_RW_MSG* p_data) {
   2178   tNFA_RW_OP_PARAMS_T3T_READ* p_t3t_read =
   2179       (tNFA_RW_OP_PARAMS_T3T_READ*)&(p_data->op_req.params.t3t_read);
   2180 
   2181   if (RW_T3tCheck(p_t3t_read->num_blocks,
   2182                   (tT3T_BLOCK_DESC*)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
   2183     nfa_rw_error_cleanup(NFA_READ_CPLT_EVT);
   2184 
   2185   return true;
   2186 }
   2187 
   2188 /*******************************************************************************
   2189 **
   2190 ** Function         nfa_rw_t3t_write
   2191 **
   2192 ** Description      Handler for T3T_Write API
   2193 **
   2194 ** Returns          TRUE (message buffer to be freed by caller)
   2195 **
   2196 *******************************************************************************/
   2197 static bool nfa_rw_t3t_write(tNFA_RW_MSG* p_data) {
   2198   tNFA_RW_OP_PARAMS_T3T_WRITE* p_t3t_write =
   2199       (tNFA_RW_OP_PARAMS_T3T_WRITE*)&(p_data->op_req.params.t3t_write);
   2200 
   2201   if (RW_T3tUpdate(p_t3t_write->num_blocks,
   2202                    (tT3T_BLOCK_DESC*)p_t3t_write->p_block_desc,
   2203                    p_t3t_write->p_block_data) != NFC_STATUS_OK)
   2204     nfa_rw_error_cleanup(NFA_WRITE_CPLT_EVT);
   2205 
   2206   return true;
   2207 }
   2208 
   2209 /*******************************************************************************
   2210 **
   2211 ** Function         nfa_rw_t3t_get_system_codes
   2212 **
   2213 ** Description      Get system codes (initiated by NFA after activation)
   2214 **
   2215 ** Returns          TRUE (message buffer to be freed by caller)
   2216 **
   2217 *******************************************************************************/
   2218 static bool nfa_rw_t3t_get_system_codes(tNFA_RW_MSG* p_data) {
   2219   tNFC_STATUS status;
   2220   tNFA_TAG_PARAMS tag_params;
   2221 
   2222   status = RW_T3tGetSystemCodes();
   2223 
   2224   if (status != NFC_STATUS_OK) {
   2225     /* Command complete - perform cleanup, notify app */
   2226     nfa_rw_command_complete();
   2227     tag_params.t3t.num_system_codes = 0;
   2228     tag_params.t3t.p_system_codes = NULL;
   2229 
   2230     nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
   2231   }
   2232 
   2233   return true;
   2234 }
   2235 
   2236 /*******************************************************************************
   2237 **
   2238 ** Function         nfa_rw_i93_command
   2239 **
   2240 ** Description      Handler for ISO 15693 command
   2241 **
   2242 ** Returns          TRUE (message buffer to be freed by caller)
   2243 **
   2244 *******************************************************************************/
   2245 static bool nfa_rw_i93_command(tNFA_RW_MSG* p_data) {
   2246   tNFA_CONN_EVT_DATA conn_evt_data;
   2247   tNFC_STATUS status = NFC_STATUS_OK;
   2248   uint8_t i93_command = I93_CMD_STAY_QUIET;
   2249 
   2250   switch (p_data->op_req.op) {
   2251     case NFA_RW_OP_I93_INVENTORY:
   2252       i93_command = I93_CMD_INVENTORY;
   2253       if (p_data->op_req.params.i93_cmd.uid_present) {
   2254         status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
   2255                                  p_data->op_req.params.i93_cmd.afi,
   2256                                  p_data->op_req.params.i93_cmd.uid);
   2257       } else {
   2258         status = RW_I93Inventory(p_data->op_req.params.i93_cmd.afi_present,
   2259                                  p_data->op_req.params.i93_cmd.afi, NULL);
   2260       }
   2261       break;
   2262 
   2263     case NFA_RW_OP_I93_STAY_QUIET:
   2264       i93_command = I93_CMD_STAY_QUIET;
   2265       status = RW_I93StayQuiet();
   2266       break;
   2267 
   2268     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
   2269       i93_command = I93_CMD_READ_SINGLE_BLOCK;
   2270       status = RW_I93ReadSingleBlock(
   2271           p_data->op_req.params.i93_cmd.first_block_number);
   2272       break;
   2273 
   2274     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
   2275       i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
   2276       status = RW_I93WriteSingleBlock(
   2277           p_data->op_req.params.i93_cmd.first_block_number,
   2278           p_data->op_req.params.i93_cmd.p_data);
   2279       break;
   2280 
   2281     case NFA_RW_OP_I93_LOCK_BLOCK:
   2282       i93_command = I93_CMD_LOCK_BLOCK;
   2283       status = RW_I93LockBlock(
   2284           (uint8_t)p_data->op_req.params.i93_cmd.first_block_number);
   2285       break;
   2286 
   2287     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
   2288       i93_command = I93_CMD_READ_MULTI_BLOCK;
   2289       status = RW_I93ReadMultipleBlocks(
   2290           p_data->op_req.params.i93_cmd.first_block_number,
   2291           p_data->op_req.params.i93_cmd.number_blocks);
   2292       break;
   2293 
   2294     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
   2295       i93_command = I93_CMD_WRITE_MULTI_BLOCK;
   2296       status = RW_I93WriteMultipleBlocks(
   2297           (uint8_t)p_data->op_req.params.i93_cmd.first_block_number,
   2298           p_data->op_req.params.i93_cmd.number_blocks,
   2299           p_data->op_req.params.i93_cmd.p_data);
   2300       break;
   2301 
   2302     case NFA_RW_OP_I93_SELECT:
   2303       i93_command = I93_CMD_SELECT;
   2304       status = RW_I93Select(p_data->op_req.params.i93_cmd.p_data);
   2305       break;
   2306 
   2307     case NFA_RW_OP_I93_RESET_TO_READY:
   2308       i93_command = I93_CMD_RESET_TO_READY;
   2309       status = RW_I93ResetToReady();
   2310       break;
   2311 
   2312     case NFA_RW_OP_I93_WRITE_AFI:
   2313       i93_command = I93_CMD_WRITE_AFI;
   2314       status = RW_I93WriteAFI(p_data->op_req.params.i93_cmd.afi);
   2315       break;
   2316 
   2317     case NFA_RW_OP_I93_LOCK_AFI:
   2318       i93_command = I93_CMD_LOCK_AFI;
   2319       status = RW_I93LockAFI();
   2320       break;
   2321 
   2322     case NFA_RW_OP_I93_WRITE_DSFID:
   2323       i93_command = I93_CMD_WRITE_DSFID;
   2324       status = RW_I93WriteDSFID(p_data->op_req.params.i93_cmd.dsfid);
   2325       break;
   2326 
   2327     case NFA_RW_OP_I93_LOCK_DSFID:
   2328       i93_command = I93_CMD_LOCK_DSFID;
   2329       status = RW_I93LockDSFID();
   2330       break;
   2331 
   2332     case NFA_RW_OP_I93_GET_SYS_INFO:
   2333       i93_command = I93_CMD_GET_SYS_INFO;
   2334       if (p_data->op_req.params.i93_cmd.uid_present) {
   2335         status = RW_I93GetSysInfo(p_data->op_req.params.i93_cmd.uid);
   2336       } else {
   2337         status = RW_I93GetSysInfo(NULL);
   2338       }
   2339       break;
   2340 
   2341     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
   2342       i93_command = I93_CMD_GET_MULTI_BLK_SEC;
   2343       status = RW_I93GetMultiBlockSecurityStatus(
   2344           p_data->op_req.params.i93_cmd.first_block_number,
   2345           p_data->op_req.params.i93_cmd.number_blocks);
   2346       break;
   2347 
   2348     default:
   2349       break;
   2350   }
   2351 
   2352   if (status != NFC_STATUS_OK) {
   2353     /* Command complete - perform cleanup, notify app */
   2354     nfa_rw_command_complete();
   2355 
   2356     conn_evt_data.i93_cmd_cplt.status = NFA_STATUS_FAILED;
   2357     conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
   2358 
   2359     nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
   2360   }
   2361 
   2362   return true;
   2363 }
   2364 
   2365 /*******************************************************************************
   2366 **
   2367 ** Function         nfa_rw_raw_mode_data_cback
   2368 **
   2369 ** Description      Handler for incoming tag data for unsupported tag protocols
   2370 **                  (forward data to upper layer)
   2371 **
   2372 ** Returns          nothing
   2373 **
   2374 *******************************************************************************/
   2375 static void nfa_rw_raw_mode_data_cback(uint8_t conn_id, tNFC_CONN_EVT event,
   2376                                        tNFC_CONN* p_data) {
   2377   NFC_HDR* p_msg;
   2378   tNFA_CONN_EVT_DATA evt_data;
   2379 
   2380   NFA_TRACE_DEBUG1("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
   2381 
   2382   if ((event == NFC_DATA_CEVT) &&
   2383       ((p_data->data.status == NFC_STATUS_OK) ||
   2384        (p_data->data.status == NFC_STATUS_CONTINUE))) {
   2385     p_msg = (NFC_HDR*)p_data->data.p_data;
   2386 
   2387     if (p_msg) {
   2388       evt_data.data.status = p_data->data.status;
   2389       evt_data.data.p_data = (uint8_t*)(p_msg + 1) + p_msg->offset;
   2390       evt_data.data.len = p_msg->len;
   2391 
   2392       nfa_dm_conn_cback_event_notify(NFA_DATA_EVT, &evt_data);
   2393 
   2394       GKI_freebuf(p_msg);
   2395     } else {
   2396       NFA_TRACE_ERROR0(
   2397           "nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL "
   2398           "data pointer");
   2399     }
   2400   } else if (event == NFC_DEACTIVATE_CEVT) {
   2401     NFC_SetStaticRfCback(NULL);
   2402   }
   2403 }
   2404 
   2405 /*******************************************************************************
   2406 **
   2407 ** Function         nfa_rw_activate_ntf
   2408 **
   2409 ** Description      Handler for NFA_RW_ACTIVATE_NTF
   2410 **
   2411 ** Returns          TRUE (message buffer to be freed by caller)
   2412 **
   2413 *******************************************************************************/
   2414 bool nfa_rw_activate_ntf(tNFA_RW_MSG* p_data) {
   2415   tNFC_ACTIVATE_DEVT* p_activate_params =
   2416       p_data->activate_ntf.p_activate_params;
   2417   tNFA_TAG_PARAMS tag_params;
   2418   tNFA_RW_OPERATION msg;
   2419   bool activate_notify = true;
   2420   uint8_t* p;
   2421 
   2422   if ((nfa_rw_cb.halt_event != RW_T2T_MAX_EVT) &&
   2423       (nfa_rw_cb.activated_tech_mode == NFC_DISCOVERY_TYPE_POLL_A) &&
   2424       (nfa_rw_cb.protocol == NFC_PROTOCOL_T2T) &&
   2425       (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)) {
   2426     /* Type 2 tag is wake up from HALT State */
   2427     if (nfa_dm_cb.p_activate_ntf != NULL) {
   2428       GKI_freebuf(nfa_dm_cb.p_activate_ntf);
   2429       nfa_dm_cb.p_activate_ntf = NULL;
   2430     }
   2431     NFA_TRACE_DEBUG0(
   2432         "nfa_rw_activate_ntf () - Type 2 tag wake up from HALT State");
   2433     return true;
   2434   }
   2435 
   2436   NFA_TRACE_DEBUG0("nfa_rw_activate_ntf");
   2437 
   2438   /* Initialize control block */
   2439   nfa_rw_cb.protocol = p_activate_params->protocol;
   2440   nfa_rw_cb.intf_type = p_activate_params->intf_param.type;
   2441   nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
   2442   nfa_rw_cb.activated_tech_mode = p_activate_params->rf_tech_param.mode;
   2443   nfa_rw_cb.flags = NFA_RW_FL_ACTIVATED;
   2444   nfa_rw_cb.cur_op = NFA_RW_OP_MAX;
   2445   nfa_rw_cb.halt_event = RW_T2T_MAX_EVT;
   2446   nfa_rw_cb.skip_dyn_locks = false;
   2447   nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
   2448   nfa_rw_cb.tlv_st = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
   2449 
   2450   memset(&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
   2451 
   2452   /* Check if we are in exclusive RF mode */
   2453   if (p_data->activate_ntf.excl_rf_not_active) {
   2454     /* Not in exclusive RF mode */
   2455     nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
   2456   }
   2457 
   2458   /* check if the protocol is activated with supported interface */
   2459   if (p_activate_params->intf_param.type == NCI_INTERFACE_FRAME) {
   2460     if ((p_activate_params->protocol != NFA_PROTOCOL_T1T) &&
   2461         (p_activate_params->protocol != NFA_PROTOCOL_T2T) &&
   2462         (p_activate_params->protocol != NFA_PROTOCOL_T3T) &&
   2463         (p_activate_params->protocol != NFC_PROTOCOL_15693)) {
   2464       nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
   2465     }
   2466   } else if (p_activate_params->intf_param.type == NCI_INTERFACE_ISO_DEP) {
   2467     if (p_activate_params->protocol != NFA_PROTOCOL_ISO_DEP) {
   2468       nfa_rw_cb.protocol = NFA_PROTOCOL_INVALID;
   2469     }
   2470   }
   2471 
   2472   if (nfa_rw_cb.protocol == NFA_PROTOCOL_INVALID) {
   2473     /* Only sending raw frame and presence check are supported in this state */
   2474 
   2475     NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
   2476 
   2477     /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
   2478     nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
   2479     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
   2480     return true;
   2481   }
   2482 
   2483   /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and
   2484    * start presence check if needed */
   2485   if (!nfa_dm_is_protocol_supported(
   2486           p_activate_params->protocol,
   2487           p_activate_params->rf_tech_param.param.pa.sel_rsp)) {
   2488     /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence
   2489      * check timer */
   2490     /* Set data callback (pass all incoming data to upper layer using
   2491      * NFA_DATA_EVT) */
   2492     NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
   2493 
   2494     /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
   2495     nfa_dm_notify_activation_status(NFA_STATUS_OK, NULL);
   2496     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
   2497     return true;
   2498   }
   2499 
   2500   /* Initialize RW module */
   2501   if ((RW_SetActivatedTagType(p_activate_params, nfa_rw_cback)) !=
   2502       NFC_STATUS_OK) {
   2503     /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
   2504     NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
   2505     return true;
   2506   }
   2507 
   2508   /* Perform protocol-specific actions */
   2509   if (NFC_PROTOCOL_T1T == nfa_rw_cb.protocol) {
   2510     /* Retrieve HR and UID fields from activation notification */
   2511     memcpy(tag_params.t1t.hr,
   2512            p_activate_params->intf_param.intf_param.frame.param,
   2513            NFA_T1T_HR_LEN);
   2514     memcpy(tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
   2515            p_activate_params->rf_tech_param.param.pa.nfcid1_len);
   2516     msg.op = NFA_RW_OP_T1T_RID;
   2517     nfa_rw_handle_op_req((tNFA_RW_MSG*)&msg);
   2518     activate_notify = false; /* Delay notifying upper layer of NFA_ACTIVATED_EVT
   2519                                 until HR0/HR1 is received */
   2520   } else if (NFC_PROTOCOL_T2T == nfa_rw_cb.protocol) {
   2521     /* Retrieve UID fields from activation notification */
   2522     memcpy(tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1,
   2523            p_activate_params->rf_tech_param.param.pa.nfcid1_len);
   2524   } else if (NFC_PROTOCOL_T3T == nfa_rw_cb.protocol) {
   2525     /* Issue command to get Felica system codes */
   2526     activate_notify =
   2527         false; /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system
   2528                   codes are retrieved */
   2529     msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
   2530     nfa_rw_handle_op_req((tNFA_RW_MSG*)&msg);
   2531   } else if (NFC_PROTOCOL_15693 == nfa_rw_cb.protocol) {
   2532     /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional
   2533      * tag infomation */
   2534     nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
   2535     activate_notify = false;
   2536 
   2537     /* store DSFID and UID from activation NTF */
   2538     nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid;
   2539 
   2540     p = nfa_rw_cb.i93_uid;
   2541     ARRAY8_TO_STREAM(p, p_activate_params->rf_tech_param.param.pi93.uid);
   2542 
   2543     if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI) &&
   2544         (((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
   2545           I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) ||
   2546          ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
   2547           I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY))) {
   2548       /* these don't support Get System Information Command */
   2549       nfa_rw_cb.i93_block_size = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
   2550       nfa_rw_cb.i93_afi_location =
   2551           I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
   2552 
   2553       if ((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) ==
   2554           I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY) {
   2555         nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
   2556       } else {
   2557         nfa_rw_cb.i93_num_block = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
   2558       }
   2559 
   2560       /* read AFI */
   2561       if (RW_I93ReadSingleBlock((uint8_t)(nfa_rw_cb.i93_afi_location /
   2562                                           nfa_rw_cb.i93_block_size)) !=
   2563           NFC_STATUS_OK) {
   2564         /* notify activation without AFI/IC-Ref */
   2565         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   2566         activate_notify = true;
   2567 
   2568         tag_params.i93.info_flags =
   2569             (I93_INFO_FLAG_DSFID | I93_INFO_FLAG_MEM_SIZE);
   2570         tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
   2571         tag_params.i93.block_size = nfa_rw_cb.i93_block_size;
   2572         tag_params.i93.num_block = nfa_rw_cb.i93_num_block;
   2573         memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
   2574       }
   2575     } else {
   2576       /* All of ICODE supports Get System Information Command */
   2577       /* Tag-it HF-I Plus Chip/Inlay supports Get System Information Command */
   2578       /* just try for others */
   2579 
   2580       if (RW_I93GetSysInfo(nfa_rw_cb.i93_uid) != NFC_STATUS_OK) {
   2581         /* notify activation without AFI/MEM size/IC-Ref */
   2582         nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
   2583         activate_notify = true;
   2584 
   2585         tag_params.i93.info_flags = I93_INFO_FLAG_DSFID;
   2586         tag_params.i93.dsfid = nfa_rw_cb.i93_dsfid;
   2587         tag_params.i93.block_size = 0;
   2588         tag_params.i93.num_block = 0;
   2589         memcpy(tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
   2590       } else {
   2591         /* reset memory size */
   2592         nfa_rw_cb.i93_block_size = 0;
   2593         nfa_rw_cb.i93_num_block = 0;
   2594       }
   2595     }
   2596   }
   2597 
   2598   /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check
   2599    * timer */
   2600   if (activate_notify) {
   2601     nfa_dm_notify_activation_status(NFA_STATUS_OK, &tag_params);
   2602     nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
   2603   }
   2604 
   2605   return true;
   2606 }
   2607 
   2608 /*******************************************************************************
   2609 **
   2610 ** Function         nfa_rw_deactivate_ntf
   2611 **
   2612 ** Description      Handler for NFA_RW_DEACTIVATE_NTF
   2613 **
   2614 ** Returns          TRUE (message buffer to be freed by caller)
   2615 **
   2616 *******************************************************************************/
   2617 bool nfa_rw_deactivate_ntf(tNFA_RW_MSG* p_data) {
   2618   /* Clear the activated flag */
   2619   nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
   2620 
   2621   /* Free buffer for incoming NDEF message, in case we were in the middle of a
   2622    * read operation */
   2623   nfa_rw_free_ndef_rx_buf();
   2624 
   2625   /* If there is a pending command message, then free it */
   2626   if (nfa_rw_cb.p_pending_msg) {
   2627     if ((nfa_rw_cb.p_pending_msg->op_req.op == NFA_RW_OP_SEND_RAW_FRAME) &&
   2628         (nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data)) {
   2629       GKI_freebuf(nfa_rw_cb.p_pending_msg->op_req.params.send_raw_frame.p_data);
   2630     }
   2631 
   2632     GKI_freebuf(nfa_rw_cb.p_pending_msg);
   2633     nfa_rw_cb.p_pending_msg = NULL;
   2634   }
   2635 
   2636   /* If we are in the process of waking up tag from HALT state */
   2637   if (nfa_rw_cb.halt_event == RW_T2T_READ_CPLT_EVT) {
   2638     if (nfa_rw_cb.rw_data.data.p_data)
   2639       GKI_freebuf(nfa_rw_cb.rw_data.data.p_data);
   2640     nfa_rw_cb.rw_data.data.p_data = NULL;
   2641   }
   2642 
   2643   /* Stop presence check timer (if started) */
   2644   nfa_rw_stop_presence_check_timer();
   2645 
   2646   return true;
   2647 }
   2648 
   2649 /*******************************************************************************
   2650 **
   2651 ** Function         nfa_rw_handle_op_req
   2652 **
   2653 ** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
   2654 **
   2655 ** Returns          TRUE if caller should free p_data
   2656 **                  FALSE if caller does not need to free p_data
   2657 **
   2658 *******************************************************************************/
   2659 bool nfa_rw_handle_op_req(tNFA_RW_MSG* p_data) {
   2660   bool freebuf = true;
   2661   uint16_t presence_check_start_delay = 0;
   2662 
   2663   /* Check if activated */
   2664   if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED)) {
   2665     NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated");
   2666     return true;
   2667   }
   2668   /* Check if currently busy with another API call */
   2669   else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY) {
   2670     return (nfa_rw_op_req_while_busy(p_data));
   2671   }
   2672   /* Check if currently busy with auto-presence check */
   2673   else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY) {
   2674     /* Cache the command (will be handled once auto-presence check is completed)
   2675      */
   2676     NFA_TRACE_DEBUG1(
   2677         "Deferring operation %i until after auto-presence check is completed",
   2678         p_data->op_req.op);
   2679     nfa_rw_cb.p_pending_msg = p_data;
   2680     nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
   2681     return false;
   2682   }
   2683 
   2684   NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
   2685 
   2686   nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
   2687 
   2688   /* Stop the presence check timer */
   2689   nfa_rw_stop_presence_check_timer();
   2690 
   2691   /* Store the current operation */
   2692   nfa_rw_cb.cur_op = p_data->op_req.op;
   2693 
   2694   /* Call appropriate handler for requested operation */
   2695   switch (p_data->op_req.op) {
   2696     case NFA_RW_OP_DETECT_NDEF:
   2697       nfa_rw_cb.skip_dyn_locks = false;
   2698       nfa_rw_detect_ndef(p_data);
   2699       break;
   2700 
   2701     case NFA_RW_OP_READ_NDEF:
   2702       nfa_rw_read_ndef(p_data);
   2703       break;
   2704 
   2705     case NFA_RW_OP_WRITE_NDEF:
   2706       nfa_rw_write_ndef(p_data);
   2707       break;
   2708 
   2709     case NFA_RW_OP_SEND_RAW_FRAME:
   2710       presence_check_start_delay =
   2711           p_data->op_req.params.send_raw_frame.p_data->layer_specific;
   2712 
   2713       NFC_SendData(NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
   2714 
   2715       /* Clear the busy flag */
   2716       nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
   2717 
   2718       /* Start presence_check after specified delay */
   2719       nfa_rw_check_start_presence_check_timer(presence_check_start_delay);
   2720       break;
   2721 
   2722     case NFA_RW_OP_PRESENCE_CHECK:
   2723       nfa_rw_presence_check(p_data);
   2724       break;
   2725 
   2726     case NFA_RW_OP_FORMAT_TAG:
   2727       nfa_rw_format_tag(p_data);
   2728       break;
   2729 
   2730     case NFA_RW_OP_DETECT_LOCK_TLV:
   2731       nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV);
   2732       break;
   2733 
   2734     case NFA_RW_OP_DETECT_MEM_TLV:
   2735       nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV);
   2736       break;
   2737 
   2738     case NFA_RW_OP_SET_TAG_RO:
   2739       nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
   2740       nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
   2741       break;
   2742 
   2743     case NFA_RW_OP_T1T_RID:
   2744       nfa_rw_t1t_rid(p_data);
   2745       break;
   2746 
   2747     case NFA_RW_OP_T1T_RALL:
   2748       nfa_rw_t1t_rall(p_data);
   2749       break;
   2750 
   2751     case NFA_RW_OP_T1T_READ:
   2752       nfa_rw_t1t_read(p_data);
   2753       break;
   2754 
   2755     case NFA_RW_OP_T1T_WRITE:
   2756       nfa_rw_t1t_write(p_data);
   2757       break;
   2758 
   2759     case NFA_RW_OP_T1T_RSEG:
   2760       nfa_rw_t1t_rseg(p_data);
   2761       break;
   2762 
   2763     case NFA_RW_OP_T1T_READ8:
   2764       nfa_rw_t1t_read8(p_data);
   2765       break;
   2766 
   2767     case NFA_RW_OP_T1T_WRITE8:
   2768       nfa_rw_t1t_write8(p_data);
   2769       break;
   2770 
   2771     /* Type-2 tag commands */
   2772     case NFA_RW_OP_T2T_READ:
   2773       nfa_rw_t2t_read(p_data);
   2774       break;
   2775 
   2776     case NFA_RW_OP_T2T_WRITE:
   2777       nfa_rw_t2t_write(p_data);
   2778       break;
   2779 
   2780     case NFA_RW_OP_T2T_SECTOR_SELECT:
   2781       nfa_rw_t2t_sector_select(p_data);
   2782       break;
   2783 
   2784     /* Type-3 tag commands */
   2785     case NFA_RW_OP_T3T_READ:
   2786       nfa_rw_t3t_read(p_data);
   2787       break;
   2788 
   2789     case NFA_RW_OP_T3T_WRITE:
   2790       nfa_rw_t3t_write(p_data);
   2791       break;
   2792 
   2793     case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
   2794       nfa_rw_t3t_get_system_codes(p_data);
   2795       break;
   2796 
   2797     /* ISO 15693 tag commands */
   2798     case NFA_RW_OP_I93_INVENTORY:
   2799     case NFA_RW_OP_I93_STAY_QUIET:
   2800     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
   2801     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
   2802     case NFA_RW_OP_I93_LOCK_BLOCK:
   2803     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
   2804     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
   2805     case NFA_RW_OP_I93_SELECT:
   2806     case NFA_RW_OP_I93_RESET_TO_READY:
   2807     case NFA_RW_OP_I93_WRITE_AFI:
   2808     case NFA_RW_OP_I93_LOCK_AFI:
   2809     case NFA_RW_OP_I93_WRITE_DSFID:
   2810     case NFA_RW_OP_I93_LOCK_DSFID:
   2811     case NFA_RW_OP_I93_GET_SYS_INFO:
   2812     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
   2813       nfa_rw_i93_command(p_data);
   2814       break;
   2815 
   2816     default:
   2817       NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i",
   2818                        p_data->op_req.op);
   2819       break;
   2820   }
   2821 
   2822   return (freebuf);
   2823 }
   2824 
   2825 /*******************************************************************************
   2826 **
   2827 ** Function         nfa_rw_op_req_while_busy
   2828 **
   2829 ** Description      Handle operation request while busy
   2830 **
   2831 ** Returns          TRUE if caller should free p_data
   2832 **                  FALSE if caller does not need to free p_data
   2833 **
   2834 *******************************************************************************/
   2835 static bool nfa_rw_op_req_while_busy(tNFA_RW_MSG* p_data) {
   2836   bool freebuf = true;
   2837   tNFA_CONN_EVT_DATA conn_evt_data;
   2838   uint8_t event;
   2839 
   2840   NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
   2841 
   2842   /* Return appropriate event for requested API, with status=BUSY */
   2843   conn_evt_data.status = NFA_STATUS_BUSY;
   2844 
   2845   switch (p_data->op_req.op) {
   2846     case NFA_RW_OP_DETECT_NDEF:
   2847       conn_evt_data.ndef_detect.cur_size = 0;
   2848       conn_evt_data.ndef_detect.max_size = 0;
   2849       conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
   2850       event = NFA_NDEF_DETECT_EVT;
   2851       break;
   2852     case NFA_RW_OP_READ_NDEF:
   2853     case NFA_RW_OP_T1T_RID:
   2854     case NFA_RW_OP_T1T_RALL:
   2855     case NFA_RW_OP_T1T_READ:
   2856     case NFA_RW_OP_T1T_RSEG:
   2857     case NFA_RW_OP_T1T_READ8:
   2858     case NFA_RW_OP_T2T_READ:
   2859     case NFA_RW_OP_T3T_READ:
   2860       event = NFA_READ_CPLT_EVT;
   2861       break;
   2862     case NFA_RW_OP_WRITE_NDEF:
   2863     case NFA_RW_OP_T1T_WRITE:
   2864     case NFA_RW_OP_T1T_WRITE8:
   2865     case NFA_RW_OP_T2T_WRITE:
   2866     case NFA_RW_OP_T3T_WRITE:
   2867       event = NFA_WRITE_CPLT_EVT;
   2868       break;
   2869     case NFA_RW_OP_FORMAT_TAG:
   2870       event = NFA_FORMAT_CPLT_EVT;
   2871       break;
   2872     case NFA_RW_OP_DETECT_LOCK_TLV:
   2873     case NFA_RW_OP_DETECT_MEM_TLV:
   2874       event = NFA_TLV_DETECT_EVT;
   2875       break;
   2876     case NFA_RW_OP_SET_TAG_RO:
   2877       event = NFA_SET_TAG_RO_EVT;
   2878       break;
   2879     case NFA_RW_OP_T2T_SECTOR_SELECT:
   2880       event = NFA_SELECT_CPLT_EVT;
   2881       break;
   2882     case NFA_RW_OP_I93_INVENTORY:
   2883     case NFA_RW_OP_I93_STAY_QUIET:
   2884     case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
   2885     case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
   2886     case NFA_RW_OP_I93_LOCK_BLOCK:
   2887     case NFA_RW_OP_I93_READ_MULTI_BLOCK:
   2888     case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
   2889     case NFA_RW_OP_I93_SELECT:
   2890     case NFA_RW_OP_I93_RESET_TO_READY:
   2891     case NFA_RW_OP_I93_WRITE_AFI:
   2892     case NFA_RW_OP_I93_LOCK_AFI:
   2893     case NFA_RW_OP_I93_WRITE_DSFID:
   2894     case NFA_RW_OP_I93_LOCK_DSFID:
   2895     case NFA_RW_OP_I93_GET_SYS_INFO:
   2896     case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
   2897       event = NFA_I93_CMD_CPLT_EVT;
   2898       break;
   2899     default:
   2900       return (freebuf);
   2901   }
   2902   nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
   2903 
   2904   return (freebuf);
   2905 }
   2906 
   2907 /*******************************************************************************
   2908 **
   2909 ** Function         nfa_rw_command_complete
   2910 **
   2911 ** Description      Handle command complete: clear the busy flag,
   2912 **                  and start the presence check timer if applicable.
   2913 **
   2914 ** Returns          None
   2915 **
   2916 *******************************************************************************/
   2917 void nfa_rw_command_complete(void) {
   2918   /* Clear the busy flag */
   2919   nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
   2920 
   2921   /* Restart presence_check timer */
   2922   nfa_rw_check_start_presence_check_timer(NFA_RW_PRESENCE_CHECK_INTERVAL);
   2923 }
   2924