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