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