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