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