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