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