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