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