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