nfa_rw_act.c revision 85b7e84f6cc61506c94e98844cac9ce50bbbe9dc
1/******************************************************************************
2 *
3 *  Copyright (C) 2010-2013 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  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        conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_inventory.status;
1160        conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_INVENTORY;
1161
1162        conn_evt_data.i93_cmd_cplt.params.inventory.dsfid = p_rw_data->i93_inventory.dsfid;
1163        memcpy (conn_evt_data.i93_cmd_cplt.params.inventory.uid,
1164                p_rw_data->i93_inventory.uid,
1165                I93_UID_BYTE_LEN);
1166
1167        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1168
1169        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1170        break;
1171
1172    case RW_I93_DATA_EVT:                       /* Response of Read, Get Multi Security */
1173
1174        /* Command complete - perform cleanup, notify app */
1175        nfa_rw_command_complete();
1176
1177        conn_evt_data.data.p_data = (UINT8 *)(p_rw_data->i93_data.p_data + 1) + p_rw_data->i93_data.p_data->offset;
1178
1179        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1180        {
1181            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1182
1183            i93_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE|I93_INFO_FLAG_AFI);
1184            i93_params.i93.afi        = *(conn_evt_data.data.p_data + nfa_rw_cb.i93_afi_location % nfa_rw_cb.i93_block_size);
1185            i93_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
1186            i93_params.i93.block_size = nfa_rw_cb.i93_block_size;
1187            i93_params.i93.num_block  = nfa_rw_cb.i93_num_block;
1188            memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1189
1190            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1191        }
1192        else
1193        {
1194            conn_evt_data.data.len    = p_rw_data->i93_data.p_data->len;
1195
1196            nfa_dm_act_conn_cback_notify(NFA_DATA_EVT, &conn_evt_data);
1197        }
1198
1199        GKI_freebuf(p_rw_data->i93_data.p_data);
1200        p_rw_data->i93_data.p_data = NULL;
1201
1202        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1203        break;
1204
1205    case RW_I93_SYS_INFO_EVT:                   /* Response of System Information     */
1206
1207        /* Command complete - perform cleanup, notify app */
1208        nfa_rw_command_complete();
1209
1210        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1211        {
1212            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1213
1214            nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1215            nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
1216
1217            i93_params.i93.info_flags   = p_rw_data->i93_sys_info.info_flags;
1218            i93_params.i93.dsfid        = p_rw_data->i93_sys_info.dsfid;
1219            i93_params.i93.afi          = p_rw_data->i93_sys_info.afi;
1220            i93_params.i93.num_block    = p_rw_data->i93_sys_info.num_block;
1221            i93_params.i93.block_size   = p_rw_data->i93_sys_info.block_size;
1222            i93_params.i93.IC_reference = p_rw_data->i93_sys_info.IC_reference;
1223            memcpy (i93_params.i93.uid, p_rw_data->i93_sys_info.uid, I93_UID_BYTE_LEN);
1224
1225            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1226        }
1227        else
1228        {
1229            conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_sys_info.status;
1230            conn_evt_data.i93_cmd_cplt.sent_command = I93_CMD_GET_SYS_INFO;
1231
1232            conn_evt_data.i93_cmd_cplt.params.sys_info.info_flags = p_rw_data->i93_sys_info.info_flags;
1233            memcpy (conn_evt_data.i93_cmd_cplt.params.sys_info.uid,
1234                    p_rw_data->i93_sys_info.uid,
1235                    I93_UID_BYTE_LEN);
1236            conn_evt_data.i93_cmd_cplt.params.sys_info.dsfid        = p_rw_data->i93_sys_info.dsfid;
1237            conn_evt_data.i93_cmd_cplt.params.sys_info.afi          = p_rw_data->i93_sys_info.afi;
1238            conn_evt_data.i93_cmd_cplt.params.sys_info.num_block    = p_rw_data->i93_sys_info.num_block;
1239            conn_evt_data.i93_cmd_cplt.params.sys_info.block_size   = p_rw_data->i93_sys_info.block_size;
1240            conn_evt_data.i93_cmd_cplt.params.sys_info.IC_reference = p_rw_data->i93_sys_info.IC_reference;
1241
1242            /* store tag memory information for writing blocks */
1243            nfa_rw_cb.i93_block_size = p_rw_data->i93_sys_info.block_size;
1244            nfa_rw_cb.i93_num_block  = p_rw_data->i93_sys_info.num_block;
1245
1246            nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1247        }
1248
1249        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1250        break;
1251
1252    case RW_I93_CMD_CMPL_EVT:                   /* Command complete                   */
1253        /* Command complete - perform cleanup, notify app */
1254        nfa_rw_command_complete();
1255
1256        if (nfa_rw_cb.flags & NFA_RW_FL_ACTIVATION_NTF_PENDING)
1257        {
1258            /* Reader got error code from tag */
1259
1260            nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
1261
1262            memset (&i93_params, 0x00, sizeof(i93_params));
1263            memcpy (i93_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
1264
1265            nfa_dm_notify_activation_status (NFA_STATUS_OK, &i93_params);
1266        }
1267        else
1268        {
1269            conn_evt_data.i93_cmd_cplt.status       = p_rw_data->i93_cmd_cmpl.status;
1270            conn_evt_data.i93_cmd_cplt.sent_command = p_rw_data->i93_cmd_cmpl.command;
1271
1272            if (conn_evt_data.i93_cmd_cplt.status != NFC_STATUS_OK)
1273                conn_evt_data.i93_cmd_cplt.params.error_code = p_rw_data->i93_cmd_cmpl.error_code;
1274
1275            nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
1276        }
1277
1278        nfa_rw_cb.cur_op = NFA_RW_OP_MAX; /* clear current operation */
1279        break;
1280
1281    default:
1282        NFA_TRACE_DEBUG1("nfa_rw_handle_i93_evt(); Unhandled RW event 0x%X", event);
1283        break;
1284    }
1285}
1286
1287/*******************************************************************************
1288**
1289** Function         nfa_rw_cback
1290**
1291** Description      Callback for reader/writer event notification
1292**
1293** Returns          Nothing
1294**
1295*******************************************************************************/
1296static void nfa_rw_cback (tRW_EVENT event, tRW_DATA *p_rw_data)
1297{
1298    NFA_TRACE_DEBUG1("nfa_rw_cback: event=0x%02x", event);
1299
1300    /* Call appropriate event handler for tag type */
1301    if (event < RW_T1T_MAX_EVT)
1302    {
1303        /* Handle Type-1 tag events */
1304        nfa_rw_handle_t1t_evt(event, p_rw_data);
1305    }
1306    else if (event < RW_T2T_MAX_EVT)
1307    {
1308        /* Handle Type-2 tag events */
1309        nfa_rw_handle_t2t_evt(event, p_rw_data);
1310    }
1311    else if (event < RW_T3T_MAX_EVT)
1312    {
1313        /* Handle Type-3 tag events */
1314        nfa_rw_handle_t3t_evt(event, p_rw_data);
1315    }
1316    else if (event < RW_T4T_MAX_EVT)
1317    {
1318        /* Handle Type-4 tag events */
1319        nfa_rw_handle_t4t_evt(event, p_rw_data);
1320    }
1321    else if (event < RW_I93_MAX_EVT)
1322    {
1323        /* Handle ISO 15693 tag events */
1324        nfa_rw_handle_i93_evt(event, p_rw_data);
1325    }
1326    else
1327    {
1328        NFA_TRACE_ERROR1("nfa_rw_cback: unhandled event=0x%02x", event);
1329    }
1330}
1331
1332/*******************************************************************************
1333**
1334** Function         nfa_rw_start_ndef_detection
1335**
1336** Description      Start NDEF detection on activated tag
1337**
1338** Returns          Nothing
1339**
1340*******************************************************************************/
1341static tNFC_STATUS nfa_rw_start_ndef_detection(void)
1342{
1343    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1344    tNFC_STATUS status = NFC_STATUS_FAILED;
1345
1346    switch (protocol)
1347    {
1348    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1349        status = RW_T1tDetectNDef();
1350        break;
1351
1352    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1353        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1354            status = RW_T2tDetectNDef();
1355        break;
1356
1357    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1358        status = RW_T3tDetectNDef();
1359        break;
1360
1361    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1362        status = RW_T4tDetectNDef();
1363        break;
1364
1365    case NFC_PROTOCOL_15693:       /* ISO 15693 */
1366        status = RW_I93DetectNDef();
1367        break;
1368
1369    default:
1370        break;
1371    }
1372
1373    return(status);
1374}
1375
1376/*******************************************************************************
1377**
1378** Function         nfa_rw_start_ndef_read
1379**
1380** Description      Start NDEF read on activated tag
1381**
1382** Returns          Nothing
1383**
1384*******************************************************************************/
1385static tNFC_STATUS nfa_rw_start_ndef_read(void)
1386{
1387    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1388    tNFC_STATUS status = NFC_STATUS_FAILED;
1389    tNFA_CONN_EVT_DATA conn_evt_data;
1390
1391    /* Handle zero length NDEF message */
1392    if (nfa_rw_cb.ndef_cur_size == 0)
1393    {
1394        NFA_TRACE_DEBUG0("NDEF message is zero-length");
1395
1396        /* Send zero-lengh NDEF message to ndef callback */
1397        nfa_dm_ndef_handle_message(NFA_STATUS_OK, NULL, 0);
1398
1399        /* Command complete - perform cleanup, notify app */
1400        nfa_rw_command_complete();
1401        conn_evt_data.status = NFA_STATUS_OK;
1402        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1403        return NFC_STATUS_OK;
1404    }
1405
1406    /* Allocate buffer for incoming NDEF message (free previous NDEF rx buffer, if needed) */
1407    nfa_rw_free_ndef_rx_buf ();
1408    if ((nfa_rw_cb.p_ndef_buf = (UINT8 *)nfa_mem_co_alloc(nfa_rw_cb.ndef_cur_size)) == NULL)
1409    {
1410        NFA_TRACE_ERROR1("Unable to allocate a buffer for reading NDEF (size=%i)", nfa_rw_cb.ndef_cur_size);
1411
1412        /* Command complete - perform cleanup, notify app */
1413        nfa_rw_command_complete();
1414        conn_evt_data.status = NFA_STATUS_FAILED;
1415        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1416        return NFC_STATUS_FAILED;
1417    }
1418    nfa_rw_cb.ndef_rd_offset = 0;
1419
1420    switch (protocol)
1421    {
1422    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1423        status = RW_T1tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
1424        break;
1425
1426    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1427        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1428            status = RW_T2tReadNDef(nfa_rw_cb.p_ndef_buf,(UINT16)nfa_rw_cb.ndef_cur_size);
1429
1430        break;
1431
1432    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1433        status = RW_T3tCheckNDef();
1434        break;
1435
1436    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1437        status = RW_T4tReadNDef();
1438        break;
1439
1440    case NFC_PROTOCOL_15693:       /* ISO 15693 */
1441        status = RW_I93ReadNDef();
1442        break;
1443
1444    default:
1445        break;
1446    }
1447    return(status);
1448}
1449
1450/*******************************************************************************
1451**
1452** Function         nfa_rw_detect_ndef
1453**
1454** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1455**
1456** Returns          TRUE (message buffer to be freed by caller)
1457**
1458*******************************************************************************/
1459static BOOLEAN nfa_rw_detect_ndef(tNFA_RW_MSG *p_data)
1460{
1461    tNFA_CONN_EVT_DATA conn_evt_data;
1462    NFA_TRACE_DEBUG0("nfa_rw_detect_ndef");
1463
1464    if ((conn_evt_data.ndef_detect.status = nfa_rw_start_ndef_detection()) != NFC_STATUS_OK)
1465    {
1466        /* Command complete - perform cleanup, notify app */
1467        nfa_rw_command_complete();
1468        conn_evt_data.ndef_detect.cur_size = 0;
1469        conn_evt_data.ndef_detect.max_size = 0;
1470        conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
1471        nfa_dm_act_conn_cback_notify(NFA_NDEF_DETECT_EVT, &conn_evt_data);
1472    }
1473
1474    return TRUE;
1475}
1476
1477/*******************************************************************************
1478**
1479** Function         nfa_rw_start_ndef_write
1480**
1481** Description      Start NDEF write on activated tag
1482**
1483** Returns          Nothing
1484**
1485*******************************************************************************/
1486static tNFC_STATUS nfa_rw_start_ndef_write(void)
1487{
1488    tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
1489    tNFC_STATUS status = NFC_STATUS_FAILED;
1490
1491    if (nfa_rw_cb.flags & NFA_RW_FL_TAG_IS_READONLY)
1492    {
1493        /* error: ndef tag is read-only */
1494        status = NFC_STATUS_FAILED;
1495        NFA_TRACE_ERROR0("Unable to write NDEF. Tag is read-only")
1496    }
1497    else if (nfa_rw_cb.ndef_max_size < nfa_rw_cb.ndef_wr_len)
1498    {
1499        /* error: ndef tag size is too small */
1500        status = NFC_STATUS_BUFFER_FULL;
1501        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)
1502    }
1503    else
1504    {
1505        switch (protocol)
1506        {
1507        case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1508            status = RW_T1tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1509            break;
1510
1511        case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1512
1513            if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1514                status = RW_T2tWriteNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1515            break;
1516
1517        case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1518            status = RW_T3tUpdateNDef(nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1519            break;
1520
1521        case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1522            status = RW_T4tUpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1523            break;
1524
1525        case NFC_PROTOCOL_15693:       /* ISO 15693 */
1526            status = RW_I93UpdateNDef((UINT16)nfa_rw_cb.ndef_wr_len, nfa_rw_cb.p_ndef_wr_buf);
1527            break;
1528
1529        default:
1530            break;
1531        }
1532    }
1533
1534    return(status);
1535}
1536
1537/*******************************************************************************
1538**
1539** Function         nfa_rw_read_ndef
1540**
1541** Description      Handler for NFA_RW_API_READ_NDEF_EVT
1542**
1543** Returns          TRUE (message buffer to be freed by caller)
1544**
1545*******************************************************************************/
1546static BOOLEAN nfa_rw_read_ndef(tNFA_RW_MSG *p_data)
1547{
1548    tNFA_STATUS status = NFA_STATUS_OK;
1549    tNFA_CONN_EVT_DATA conn_evt_data;
1550
1551    NFA_TRACE_DEBUG0("nfa_rw_read_ndef");
1552
1553    /* Check if ndef detection has been performed yet */
1554    if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
1555    {
1556        /* Perform ndef detection first */
1557        status = nfa_rw_start_ndef_detection();
1558    }
1559    else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
1560    {
1561        /* Tag is not NDEF */
1562        status = NFA_STATUS_FAILED;
1563    }
1564    else
1565    {
1566        /* Perform the NDEF read operation */
1567        status = nfa_rw_start_ndef_read();
1568    }
1569
1570    /* Handle failure */
1571    if (status != NFA_STATUS_OK)
1572    {
1573        /* Command complete - perform cleanup, notify app */
1574        nfa_rw_command_complete();
1575        conn_evt_data.status = status;
1576        nfa_dm_act_conn_cback_notify(NFA_READ_CPLT_EVT, &conn_evt_data);
1577    }
1578
1579
1580    return TRUE;
1581}
1582
1583/*******************************************************************************
1584**
1585** Function         nfa_rw_write_ndef
1586**
1587** Description      Handler for NFA_RW_API_WRITE_NDEF_EVT
1588**
1589** Returns          TRUE (message buffer to be freed by caller)
1590**
1591*******************************************************************************/
1592static BOOLEAN nfa_rw_write_ndef(tNFA_RW_MSG *p_data)
1593{
1594    tNDEF_STATUS ndef_status;
1595    tNFA_STATUS write_status = NFA_STATUS_OK;
1596    tNFA_CONN_EVT_DATA conn_evt_data;
1597    NFA_TRACE_DEBUG0("nfa_rw_write_ndef");
1598
1599    /* Validate NDEF message */
1600    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)
1601    {
1602        NFA_TRACE_ERROR1("Invalid NDEF message. NDEF_MsgValidate returned %i", ndef_status);
1603
1604        /* Command complete - perform cleanup, notify app */
1605        nfa_rw_command_complete();
1606        conn_evt_data.status = NFA_STATUS_FAILED;
1607        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1608        return TRUE;
1609    }
1610
1611    /* Store pointer to source NDEF */
1612    nfa_rw_cb.p_ndef_wr_buf = p_data->op_req.params.write_ndef.p_data;
1613    nfa_rw_cb.ndef_wr_len = p_data->op_req.params.write_ndef.len;
1614
1615    /* Check if ndef detection has been performed yet */
1616    if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_UNKNOWN)
1617    {
1618        /* Perform ndef detection first */
1619        write_status = nfa_rw_start_ndef_detection();
1620    }
1621    else if (nfa_rw_cb.ndef_st == NFA_RW_NDEF_ST_FALSE)
1622    {
1623        /* Tag is not NDEF */
1624        write_status = NFA_STATUS_FAILED;
1625    }
1626    else
1627    {
1628        /* Perform the NDEF read operation */
1629        write_status = nfa_rw_start_ndef_write();
1630    }
1631
1632    /* Handle failure */
1633    if (write_status != NFA_STATUS_OK)
1634    {
1635        /* Command complete - perform cleanup, notify app */
1636        nfa_rw_command_complete();
1637        conn_evt_data.status = write_status;
1638        nfa_dm_act_conn_cback_notify(NFA_WRITE_CPLT_EVT, &conn_evt_data);
1639    }
1640
1641    return TRUE;
1642}
1643
1644/*******************************************************************************
1645**
1646** Function         nfa_rw_presence_check
1647**
1648** Description      Handler for NFA_RW_API_PRESENCE_CHECK
1649**
1650** Returns          Nothing
1651**
1652*******************************************************************************/
1653void nfa_rw_presence_check (tNFA_RW_MSG *p_data)
1654{
1655    tNFC_PROTOCOL       protocol = nfa_rw_cb.protocol;
1656    UINT8               sel_res  = nfa_rw_cb.pa_sel_res;
1657    tNFC_STATUS         status   = NFC_STATUS_FAILED;
1658
1659    switch (protocol)
1660    {
1661    case NFC_PROTOCOL_T1T:    /* Type1Tag    - NFC-A */
1662        status = RW_T1tPresenceCheck();
1663        break;
1664
1665    case NFC_PROTOCOL_T3T:   /* Type3Tag    - NFC-F */
1666        status = RW_T3tPresenceCheck();
1667        break;
1668
1669    case NFC_PROTOCOL_ISO_DEP:     /* ISODEP/4A,4B- NFC-A or NFC-B */
1670        status = RW_T4tPresenceCheck();
1671        break;
1672
1673    case NFC_PROTOCOL_15693:       /* ISO 15693 */
1674        status = RW_I93PresenceCheck();
1675        break;
1676
1677    case NFC_PROTOCOL_T2T:   /* Type2Tag    - NFC-A */
1678        /* If T2T NFC-Forum, then let RW handle presence check; otherwise fall through */
1679        if (sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1680        {
1681            status = RW_T2tPresenceCheck();
1682            break;
1683        }
1684
1685    default:
1686        /* Protocol unsupported by RW module... */
1687        /* Let DM perform presence check (by putting tag to sleep and then waking it up) */
1688        status = nfa_dm_disc_presence_check();
1689        break;
1690    }
1691
1692    /* Handle presence check failure */
1693    if (status != NFC_STATUS_OK)
1694        nfa_rw_handle_presence_check_rsp(NFC_STATUS_FAILED);
1695}
1696
1697
1698/*******************************************************************************
1699**
1700** Function         nfa_rw_presence_check_tick
1701**
1702** Description      Called on expiration of NFA_RW_PRESENCE_CHECK_INTERVAL
1703**                  Initiate presence check
1704**
1705** Returns          TRUE (caller frees message buffer)
1706**
1707*******************************************************************************/
1708BOOLEAN nfa_rw_presence_check_tick(tNFA_RW_MSG *p_data)
1709{
1710    /* Store the current operation */
1711    nfa_rw_cb.cur_op = NFA_RW_OP_PRESENCE_CHECK;
1712    nfa_rw_cb.flags |= NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY;
1713    NFA_TRACE_DEBUG0("Auto-presence check starting...");
1714
1715    /* Perform presence check */
1716    nfa_rw_presence_check(NULL);
1717
1718    return TRUE;
1719}
1720
1721/*******************************************************************************
1722**
1723** Function         nfa_rw_format_tag
1724**
1725** Description      Handler for NFA_RW_API_FORMAT_TAG
1726**
1727** Returns          Nothing
1728**
1729*******************************************************************************/
1730static void nfa_rw_format_tag (tNFA_RW_MSG *p_data)
1731{
1732    tNFC_PROTOCOL   protocol = nfa_rw_cb.protocol;
1733    tNFC_STATUS     status   = NFC_STATUS_FAILED;
1734
1735    if (protocol == NFC_PROTOCOL_T1T)
1736    {
1737        status = RW_T1tFormatNDef();
1738    }
1739    else if (  (protocol  == NFC_PROTOCOL_T2T)
1740             &&(nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T) )
1741    {
1742        status = RW_T2tFormatNDef();
1743    }
1744    else if (protocol == NFC_PROTOCOL_T3T)
1745    {
1746        status = RW_T3tFormatNDef();
1747    }
1748    else if (protocol == NFC_PROTOCOL_15693)
1749    {
1750        status = RW_I93FormatNDef();
1751    }
1752
1753    /* If unable to format NDEF, notify the app */
1754    if (status != NFC_STATUS_OK)
1755        nfa_rw_error_cleanup (NFA_FORMAT_CPLT_EVT);
1756}
1757
1758/*******************************************************************************
1759**
1760** Function         nfa_rw_detect_tlv
1761**
1762** Description      Handler for NFA_RW_API_DETECT_NDEF_EVT
1763**
1764** Returns          TRUE (message buffer to be freed by caller)
1765**
1766*******************************************************************************/
1767static BOOLEAN nfa_rw_detect_tlv (tNFA_RW_MSG *p_data, UINT8 tlv)
1768{
1769    NFA_TRACE_DEBUG0("nfa_rw_detect_tlv");
1770
1771    switch (nfa_rw_cb.protocol)
1772    {
1773    case NFC_PROTOCOL_T1T:
1774        if (RW_T1tLocateTlv(tlv) != NFC_STATUS_OK)
1775            nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
1776        break;
1777
1778    case NFC_PROTOCOL_T2T:
1779        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1780        {
1781            if (RW_T2tLocateTlv(tlv) != NFC_STATUS_OK)
1782                nfa_rw_error_cleanup (NFA_TLV_DETECT_EVT);
1783        }
1784        break;
1785
1786    default:
1787        break;
1788    }
1789
1790    return TRUE;
1791}
1792
1793/*******************************************************************************
1794**
1795** Function         nfa_rw_config_tag_ro
1796**
1797** Description      Handler for NFA_RW_OP_SET_TAG_RO
1798**
1799** Returns          TRUE (message buffer to be freed by caller)
1800**
1801*******************************************************************************/
1802static tNFC_STATUS nfa_rw_config_tag_ro (BOOLEAN b_hard_lock)
1803{
1804    tNFC_PROTOCOL                       protocol        = nfa_rw_cb.protocol;
1805    tNFC_STATUS                         status          = NFC_STATUS_FAILED;
1806
1807    NFA_TRACE_DEBUG0("nfa_rw_config_tag_ro");
1808
1809    switch (protocol)
1810    {
1811    case NFC_PROTOCOL_T1T:
1812        if(  (nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED)
1813           ||(nfa_rw_cb.tlv_st == NFA_RW_TLV_DETECT_ST_MEM_TLV_OP_COMPLETE) )
1814        {
1815            status = RW_T1tLocateTlv(TAG_LOCK_CTRL_TLV);
1816        }
1817        else if ( (status = RW_T1tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK)
1818        {
1819            nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
1820        }
1821        else
1822        {
1823            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1824        }
1825        break;
1826
1827    case NFC_PROTOCOL_T2T:
1828        if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
1829        {
1830            if ( (status = RW_T2tSetTagReadOnly(b_hard_lock)) != NFC_STATUS_OK)
1831            {
1832                nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
1833            }
1834            else
1835            {
1836                nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1837            }
1838        }
1839        break;
1840
1841    case NFC_PROTOCOL_15693:
1842        if ( (status = RW_I93SetTagReadOnly()) != NFC_STATUS_OK)
1843            nfa_rw_error_cleanup (NFA_SET_TAG_RO_EVT);
1844        break;
1845
1846    default:
1847        /* NOTE: type type-3 and type-4 protocol does not define transition to read-only */
1848        break;
1849
1850    }
1851    return (status);
1852}
1853
1854/*******************************************************************************
1855**
1856** Function         nfa_rw_t1t_rid
1857**
1858** Description      Handler for T1T_RID API
1859**
1860** Returns          TRUE (message buffer to be freed by caller)
1861**
1862*******************************************************************************/
1863static BOOLEAN nfa_rw_t1t_rid(tNFA_RW_MSG *p_data)
1864{
1865    if (RW_T1tRid () != NFC_STATUS_OK)
1866        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1867
1868    return TRUE;
1869}
1870
1871/*******************************************************************************
1872**
1873** Function         nfa_rw_t1t_rall
1874**
1875** Description      Handler for T1T_ReadAll API
1876**
1877** Returns          TRUE (message buffer to be freed by caller)
1878**
1879*******************************************************************************/
1880static BOOLEAN nfa_rw_t1t_rall(tNFA_RW_MSG *p_data)
1881{
1882    if (RW_T1tReadAll() != NFC_STATUS_OK)
1883        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1884
1885    return TRUE;
1886}
1887
1888/*******************************************************************************
1889**
1890** Function         nfa_rw_t1t_read
1891**
1892** Description      Handler for T1T_Read API
1893**
1894** Returns          TRUE (message buffer to be freed by caller)
1895**
1896*******************************************************************************/
1897static BOOLEAN nfa_rw_t1t_read (tNFA_RW_MSG *p_data)
1898{
1899    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
1900
1901    if (RW_T1tRead (p_t1t_read->block_number, p_t1t_read->index) != NFC_STATUS_OK)
1902        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1903
1904    return TRUE;
1905}
1906
1907/*******************************************************************************
1908**
1909** Function         nfa_rw_t1t_write
1910**
1911** Description      Handler for T1T_WriteErase/T1T_WriteNoErase API
1912**
1913** Returns          TRUE (message buffer to be freed by caller)
1914**
1915*******************************************************************************/
1916static BOOLEAN nfa_rw_t1t_write (tNFA_RW_MSG *p_data)
1917{
1918    tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
1919    tNFC_STATUS                 status;
1920
1921    if (p_t1t_write->b_erase)
1922    {
1923        status = RW_T1tWriteErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
1924    }
1925    else
1926    {
1927        status = RW_T1tWriteNoErase (p_t1t_write->block_number,p_t1t_write->index,p_t1t_write->p_block_data[0]);
1928    }
1929
1930    if (status != NFC_STATUS_OK)
1931    {
1932        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
1933    }
1934    else
1935    {
1936        if (p_t1t_write->block_number == 0x01)
1937            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
1938    }
1939
1940    return TRUE;
1941}
1942
1943/*******************************************************************************
1944**
1945** Function         nfa_rw_t1t_rseg
1946**
1947** Description      Handler for T1t_ReadSeg API
1948**
1949** Returns          TRUE (message buffer to be freed by caller)
1950**
1951*******************************************************************************/
1952static BOOLEAN nfa_rw_t1t_rseg (tNFA_RW_MSG *p_data)
1953{
1954    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
1955
1956    if (RW_T1tReadSeg (p_t1t_read->segment_number) != NFC_STATUS_OK)
1957        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1958
1959    return TRUE;
1960}
1961
1962/*******************************************************************************
1963**
1964** Function         nfa_rw_t1t_read8
1965**
1966** Description      Handler for T1T_Read8 API
1967**
1968** Returns          TRUE (message buffer to be freed by caller)
1969**
1970*******************************************************************************/
1971static BOOLEAN nfa_rw_t1t_read8 (tNFA_RW_MSG *p_data)
1972{
1973    tNFA_RW_OP_PARAMS_T1T_READ *p_t1t_read = (tNFA_RW_OP_PARAMS_T1T_READ *)&(p_data->op_req.params.t1t_read);
1974
1975    if (RW_T1tRead8 (p_t1t_read->block_number) != NFC_STATUS_OK)
1976        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
1977
1978    return TRUE;
1979}
1980
1981/*******************************************************************************
1982**
1983** Function         nfa_rw_t1t_write8
1984**
1985** Description      Handler for T1T_WriteErase8/T1T_WriteNoErase8 API
1986**
1987** Returns          TRUE (message buffer to be freed by caller)
1988**
1989*******************************************************************************/
1990static BOOLEAN nfa_rw_t1t_write8 (tNFA_RW_MSG *p_data)
1991{
1992    tNFA_RW_OP_PARAMS_T1T_WRITE *p_t1t_write = (tNFA_RW_OP_PARAMS_T1T_WRITE *)&(p_data->op_req.params.t1t_write);
1993    tNFC_STATUS                 status;
1994
1995    if (p_t1t_write->b_erase)
1996    {
1997        status = RW_T1tWriteErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
1998    }
1999    else
2000    {
2001        status = RW_T1tWriteNoErase8 (p_t1t_write->block_number,p_t1t_write->p_block_data);
2002    }
2003
2004    if (status != NFC_STATUS_OK)
2005    {
2006        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2007    }
2008    else
2009    {
2010        if (p_t1t_write->block_number == 0x01)
2011            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2012    }
2013
2014    return TRUE;
2015}
2016
2017/*******************************************************************************
2018**
2019** Function         nfa_rw_t2t_read
2020**
2021** Description      Handler for T2T_Read API
2022**
2023** Returns          TRUE (message buffer to be freed by caller)
2024**
2025*******************************************************************************/
2026static BOOLEAN nfa_rw_t2t_read (tNFA_RW_MSG *p_data)
2027{
2028    tNFA_RW_OP_PARAMS_T2T_READ *p_t2t_read = (tNFA_RW_OP_PARAMS_T2T_READ *)&(p_data->op_req.params.t2t_read);
2029    tNFC_STATUS                status = NFC_STATUS_FAILED;
2030
2031    if (nfa_rw_cb.pa_sel_res == NFC_SEL_RES_NFC_FORUM_T2T)
2032        status = RW_T2tRead (p_t2t_read->block_number);
2033
2034    if (status != NFC_STATUS_OK)
2035        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2036
2037    return TRUE;
2038}
2039
2040/*******************************************************************************
2041**
2042** Function         nfa_rw_t2t_write
2043**
2044** Description      Handler for T2T_Write API
2045**
2046** Returns          TRUE (message buffer to be freed by caller)
2047**
2048*******************************************************************************/
2049static BOOLEAN nfa_rw_t2t_write (tNFA_RW_MSG *p_data)
2050{
2051    tNFA_RW_OP_PARAMS_T2T_WRITE *p_t2t_write = (tNFA_RW_OP_PARAMS_T2T_WRITE *)&(p_data->op_req.params.t2t_write);
2052
2053    if (RW_T2tWrite (p_t2t_write->block_number,p_t2t_write->p_block_data) != NFC_STATUS_OK)
2054    {
2055        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2056    }
2057    else
2058    {
2059        if (p_t2t_write->block_number == 0x03)
2060            nfa_rw_cb.ndef_st = NFA_RW_NDEF_ST_UNKNOWN;
2061    }
2062
2063    return TRUE;
2064}
2065
2066/*******************************************************************************
2067**
2068** Function         nfa_rw_t2t_sector_select
2069**
2070** Description      Handler for T2T_Sector_Select API
2071**
2072** Returns          TRUE (message buffer to be freed by caller)
2073**
2074*******************************************************************************/
2075static BOOLEAN nfa_rw_t2t_sector_select(tNFA_RW_MSG *p_data)
2076{
2077    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);
2078
2079    if (RW_T2tSectorSelect (p_t2t_sector_select->sector_number) != NFC_STATUS_OK)
2080        nfa_rw_error_cleanup (NFA_SELECT_CPLT_EVT);
2081
2082    return TRUE;
2083}
2084
2085/*******************************************************************************
2086**
2087** Function         nfa_rw_t3t_read
2088**
2089** Description      Handler for T3T_Read API
2090**
2091** Returns          TRUE (message buffer to be freed by caller)
2092**
2093*******************************************************************************/
2094static BOOLEAN nfa_rw_t3t_read (tNFA_RW_MSG *p_data)
2095{
2096    tNFA_RW_OP_PARAMS_T3T_READ *p_t3t_read = (tNFA_RW_OP_PARAMS_T3T_READ *)&(p_data->op_req.params.t3t_read);
2097
2098    if (RW_T3tCheck (p_t3t_read->num_blocks, (tT3T_BLOCK_DESC *)p_t3t_read->p_block_desc) != NFC_STATUS_OK)
2099        nfa_rw_error_cleanup (NFA_READ_CPLT_EVT);
2100
2101    return TRUE;
2102}
2103
2104/*******************************************************************************
2105**
2106** Function         nfa_rw_t3t_write
2107**
2108** Description      Handler for T3T_Write API
2109**
2110** Returns          TRUE (message buffer to be freed by caller)
2111**
2112*******************************************************************************/
2113static BOOLEAN nfa_rw_t3t_write (tNFA_RW_MSG *p_data)
2114{
2115    tNFA_RW_OP_PARAMS_T3T_WRITE *p_t3t_write = (tNFA_RW_OP_PARAMS_T3T_WRITE *)&(p_data->op_req.params.t3t_write);
2116
2117    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)
2118        nfa_rw_error_cleanup (NFA_WRITE_CPLT_EVT);
2119
2120    return TRUE;
2121}
2122
2123/*******************************************************************************
2124**
2125** Function         nfa_rw_t3t_get_system_codes
2126**
2127** Description      Get system codes (initiated by NFA after activation)
2128**
2129** Returns          TRUE (message buffer to be freed by caller)
2130**
2131*******************************************************************************/
2132static BOOLEAN nfa_rw_t3t_get_system_codes (tNFA_RW_MSG *p_data)
2133{
2134    tNFC_STATUS     status;
2135    tNFA_TAG_PARAMS tag_params;
2136
2137    status = RW_T3tGetSystemCodes();
2138
2139    if (status != NFC_STATUS_OK)
2140    {
2141        /* Command complete - perform cleanup, notify app */
2142        nfa_rw_command_complete();
2143        tag_params.t3t.num_system_codes = 0;
2144        tag_params.t3t.p_system_codes   = NULL;
2145
2146        nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
2147    }
2148
2149    return TRUE;
2150}
2151
2152/*******************************************************************************
2153**
2154** Function         nfa_rw_i93_command
2155**
2156** Description      Handler for ISO 15693 command
2157**
2158** Returns          TRUE (message buffer to be freed by caller)
2159**
2160*******************************************************************************/
2161static BOOLEAN nfa_rw_i93_command (tNFA_RW_MSG *p_data)
2162{
2163    tNFA_CONN_EVT_DATA conn_evt_data;
2164    tNFC_STATUS        status = NFC_STATUS_OK;
2165    UINT8              i93_command = I93_CMD_STAY_QUIET;
2166
2167    switch (p_data->op_req.op)
2168    {
2169    case NFA_RW_OP_I93_INVENTORY:
2170        i93_command = I93_CMD_INVENTORY;
2171        if (p_data->op_req.params.i93_cmd.uid_present)
2172        {
2173            status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi,
2174                                      p_data->op_req.params.i93_cmd.uid);
2175        }
2176        else
2177        {
2178            status = RW_I93Inventory (p_data->op_req.params.i93_cmd.afi, NULL);
2179        }
2180        break;
2181
2182    case NFA_RW_OP_I93_STAY_QUIET:
2183        i93_command = I93_CMD_STAY_QUIET;
2184        status = RW_I93StayQuiet ();
2185        break;
2186
2187    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2188        i93_command = I93_CMD_READ_SINGLE_BLOCK;
2189        status = RW_I93ReadSingleBlock (p_data->op_req.params.i93_cmd.first_block_number);
2190        break;
2191
2192    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2193        i93_command = I93_CMD_WRITE_SINGLE_BLOCK;
2194        status = RW_I93WriteSingleBlock (p_data->op_req.params.i93_cmd.first_block_number,
2195                                         p_data->op_req.params.i93_cmd.p_data);
2196        break;
2197
2198    case NFA_RW_OP_I93_LOCK_BLOCK:
2199        i93_command = I93_CMD_LOCK_BLOCK;
2200        status = RW_I93LockBlock ((UINT8)p_data->op_req.params.i93_cmd.first_block_number);
2201        break;
2202
2203    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2204        i93_command = I93_CMD_READ_MULTI_BLOCK;
2205        status = RW_I93ReadMultipleBlocks (p_data->op_req.params.i93_cmd.first_block_number,
2206                                           p_data->op_req.params.i93_cmd.number_blocks);
2207        break;
2208
2209    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2210        i93_command = I93_CMD_WRITE_MULTI_BLOCK;
2211        status = RW_I93WriteMultipleBlocks ((UINT8)p_data->op_req.params.i93_cmd.first_block_number,
2212                                            p_data->op_req.params.i93_cmd.number_blocks,
2213                                            p_data->op_req.params.i93_cmd.p_data);
2214        break;
2215
2216    case NFA_RW_OP_I93_SELECT:
2217        i93_command = I93_CMD_SELECT;
2218        status = RW_I93Select (p_data->op_req.params.i93_cmd.p_data);
2219        break;
2220
2221    case NFA_RW_OP_I93_RESET_TO_READY:
2222        i93_command = I93_CMD_RESET_TO_READY;
2223        status = RW_I93ResetToReady ();
2224        break;
2225
2226    case NFA_RW_OP_I93_WRITE_AFI:
2227        i93_command = I93_CMD_WRITE_AFI;
2228        status = RW_I93WriteAFI (p_data->op_req.params.i93_cmd.afi);
2229        break;
2230
2231    case NFA_RW_OP_I93_LOCK_AFI:
2232        i93_command = I93_CMD_LOCK_AFI;
2233        status = RW_I93LockAFI ();
2234        break;
2235
2236    case NFA_RW_OP_I93_WRITE_DSFID:
2237        i93_command = I93_CMD_WRITE_DSFID;
2238        status = RW_I93WriteDSFID (p_data->op_req.params.i93_cmd.dsfid);
2239        break;
2240
2241    case NFA_RW_OP_I93_LOCK_DSFID:
2242        i93_command = I93_CMD_LOCK_DSFID;
2243        status = RW_I93LockDSFID ();
2244        break;
2245
2246    case NFA_RW_OP_I93_GET_SYS_INFO:
2247        i93_command = I93_CMD_GET_SYS_INFO;
2248        if (p_data->op_req.params.i93_cmd.uid_present)
2249        {
2250            status = RW_I93GetSysInfo (p_data->op_req.params.i93_cmd.uid);
2251        }
2252        else
2253        {
2254            status = RW_I93GetSysInfo (NULL);
2255        }
2256        break;
2257
2258    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2259        i93_command = I93_CMD_GET_MULTI_BLK_SEC;
2260        status = RW_I93GetMultiBlockSecurityStatus (p_data->op_req.params.i93_cmd.first_block_number,
2261                                                    p_data->op_req.params.i93_cmd.number_blocks);
2262        break;
2263
2264    default:
2265        break;
2266    }
2267
2268    if (status != NFC_STATUS_OK)
2269    {
2270        /* Command complete - perform cleanup, notify app */
2271        nfa_rw_command_complete();
2272
2273        conn_evt_data.i93_cmd_cplt.status       = NFA_STATUS_FAILED;
2274        conn_evt_data.i93_cmd_cplt.sent_command = i93_command;
2275
2276        nfa_dm_act_conn_cback_notify(NFA_I93_CMD_CPLT_EVT, &conn_evt_data);
2277    }
2278
2279    return TRUE;
2280}
2281
2282/*******************************************************************************
2283**
2284** Function         nfa_rw_raw_mode_data_cback
2285**
2286** Description      Handler for incoming tag data for unsupported tag protocols
2287**                  (forward data to upper layer)
2288**
2289** Returns          nothing
2290**
2291*******************************************************************************/
2292static void nfa_rw_raw_mode_data_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
2293{
2294    BT_HDR             *p_msg = (BT_HDR *)p_data->data.p_data;
2295    tNFA_CONN_EVT_DATA evt_data;
2296
2297    NFA_TRACE_DEBUG1 ("nfa_rw_raw_mode_data_cback(): event = 0x%X", event);
2298
2299    if ((event == NFC_DATA_CEVT) && (p_data->data.status == NFC_STATUS_OK))
2300    {
2301        if (p_msg)
2302        {
2303            evt_data.data.p_data = (UINT8 *)(p_msg + 1) + p_msg->offset;
2304            evt_data.data.len    = p_msg->len;
2305
2306            nfa_dm_conn_cback_event_notify (NFA_DATA_EVT, &evt_data);
2307
2308            GKI_freebuf (p_msg);
2309        }
2310        else
2311        {
2312            NFA_TRACE_ERROR0 ("nfa_rw_raw_mode_data_cback (): received NFC_DATA_CEVT with NULL data pointer");
2313        }
2314    }
2315    else if (event == NFC_DEACTIVATE_CEVT)
2316    {
2317        NFC_SetStaticRfCback (NULL);
2318    }
2319}
2320
2321
2322/*******************************************************************************
2323**
2324** Function         nfa_rw_activate_ntf
2325**
2326** Description      Handler for NFA_RW_ACTIVATE_NTF
2327**
2328** Returns          TRUE (message buffer to be freed by caller)
2329**
2330*******************************************************************************/
2331BOOLEAN nfa_rw_activate_ntf(tNFA_RW_MSG *p_data)
2332{
2333    tNFC_ACTIVATE_DEVT *p_activate_params = p_data->activate_ntf.p_activate_params;
2334    tNFA_TAG_PARAMS    tag_params;
2335    tNFA_RW_OPERATION  msg;
2336    BOOLEAN            activate_notify = TRUE;
2337    UINT8              *p;
2338
2339    NFA_TRACE_DEBUG0("nfa_rw_activate_ntf");
2340
2341    /* Initialize control block */
2342    nfa_rw_cb.protocol   = p_activate_params->protocol;
2343    nfa_rw_cb.pa_sel_res = p_activate_params->rf_tech_param.param.pa.sel_rsp;
2344    nfa_rw_cb.flags      = NFA_RW_FL_ACTIVATED;
2345    nfa_rw_cb.cur_op     = NFA_RW_OP_MAX;
2346    nfa_rw_cb.ndef_st    = NFA_RW_NDEF_ST_UNKNOWN;
2347    nfa_rw_cb.tlv_st     = NFA_RW_TLV_DETECT_ST_OP_NOT_STARTED;
2348
2349    memset (&tag_params, 0, sizeof(tNFA_TAG_PARAMS));
2350
2351    /* Check if we are in exclusive RF mode */
2352    if (p_data->activate_ntf.excl_rf_not_active)
2353    {
2354        /* Not in exclusive RF mode */
2355        nfa_rw_cb.flags |= NFA_RW_FL_NOT_EXCL_RF_MODE;
2356    }
2357
2358    /* If protocol not supported by RW module, notify app of NFA_ACTIVATED_EVT and start presence check if needed */
2359    if (!nfa_dm_is_protocol_supported(p_activate_params->protocol, p_activate_params->rf_tech_param.param.pa.sel_rsp))
2360    {
2361        /* Set data callback (pass all incoming data to upper layer using NFA_DATA_EVT) */
2362        NFC_SetStaticRfCback(nfa_rw_raw_mode_data_cback);
2363
2364        /* Notify app of NFA_ACTIVATED_EVT and start presence check timer */
2365        nfa_dm_notify_activation_status (NFA_STATUS_OK, NULL);
2366        nfa_rw_check_start_presence_check_timer ();
2367        return TRUE;
2368    }
2369
2370    /* Initialize RW module */
2371    if ((RW_SetActivatedTagType (p_activate_params, nfa_rw_cback)) != NFC_STATUS_OK)
2372    {
2373        /* Log error (stay in NFA_RW_ST_ACTIVATED state until deactivation) */
2374        NFA_TRACE_ERROR0("RW_SetActivatedTagType failed.");
2375        return TRUE;
2376    }
2377
2378    /* Perform protocol-specific actions */
2379    switch (nfa_rw_cb.protocol)
2380    {
2381    case NFC_PROTOCOL_T1T:
2382        /* Retrieve HR and UID fields from activation notification */
2383        memcpy (tag_params.t1t.hr, p_activate_params->intf_param.intf_param.frame.param, NFA_T1T_HR_LEN);
2384        memcpy (tag_params.t1t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2385        break;
2386
2387    case NFC_PROTOCOL_T2T:
2388        /* Retrieve UID fields from activation notification */
2389        memcpy (tag_params.t2t.uid, p_activate_params->rf_tech_param.param.pa.nfcid1, p_activate_params->rf_tech_param.param.pa.nfcid1_len);
2390        break;
2391
2392    case NFC_PROTOCOL_T3T:
2393        /* Issue command to get Felica system codes */
2394        activate_notify = FALSE;                    /* Delay notifying upper layer of NFA_ACTIVATED_EVT until system codes are retrieved */
2395        msg.op = NFA_RW_OP_T3T_GET_SYSTEM_CODES;
2396        nfa_rw_handle_op_req((tNFA_RW_MSG *)&msg);
2397        break;
2398
2399    case NFC_PROTOCOL_15693:
2400        /* Delay notifying upper layer of NFA_ACTIVATED_EVT to retrieve additional tag infomation */
2401        nfa_rw_cb.flags |= NFA_RW_FL_ACTIVATION_NTF_PENDING;
2402        activate_notify = FALSE;
2403
2404        /* store DSFID and UID from activation NTF */
2405        nfa_rw_cb.i93_dsfid = p_activate_params->rf_tech_param.param.pi93.dsfid;
2406
2407        p = nfa_rw_cb.i93_uid;
2408        ARRAY8_TO_STREAM (p, p_activate_params->rf_tech_param.param.pi93.uid);
2409
2410        if ((nfa_rw_cb.i93_uid[1] == I93_UID_IC_MFG_CODE_TI)
2411          &&(((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_STD_CHIP_INLAY)
2412           ||((nfa_rw_cb.i93_uid[2] & I93_UID_TAG_IT_HF_I_PRODUCT_ID_MASK) == I93_UID_TAG_IT_HF_I_PRO_CHIP_INLAY)))
2413        {
2414            /* these don't support Get System Information Command */
2415            nfa_rw_cb.i93_block_size    = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_BLK_SIZE;
2416            nfa_rw_cb.i93_afi_location  = I93_TAG_IT_HF_I_STD_PRO_CHIP_INLAY_AFI_LOCATION;
2417
2418            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)
2419            {
2420                nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_STD_CHIP_INLAY_NUM_TOTAL_BLK;
2421            }
2422            else
2423            {
2424                nfa_rw_cb.i93_num_block     = I93_TAG_IT_HF_I_PRO_CHIP_INLAY_NUM_TOTAL_BLK;
2425            }
2426
2427            /* read AFI */
2428            if (RW_I93ReadSingleBlock ((UINT8)(nfa_rw_cb.i93_afi_location / nfa_rw_cb.i93_block_size)) != NFC_STATUS_OK)
2429            {
2430                /* notify activation without AFI/IC-Ref */
2431                nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2432                activate_notify = TRUE;
2433
2434                tag_params.i93.info_flags = (I93_INFO_FLAG_DSFID|I93_INFO_FLAG_MEM_SIZE);
2435                tag_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
2436                tag_params.i93.block_size = nfa_rw_cb.i93_block_size;
2437                tag_params.i93.num_block  = nfa_rw_cb.i93_num_block;
2438                memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2439            }
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            if (RW_I93GetSysInfo (nfa_rw_cb.i93_uid) != NFC_STATUS_OK)
2448            {
2449                /* notify activation without AFI/MEM size/IC-Ref */
2450                nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATION_NTF_PENDING;
2451                activate_notify = TRUE;
2452
2453                tag_params.i93.info_flags = I93_INFO_FLAG_DSFID;
2454                tag_params.i93.dsfid      = nfa_rw_cb.i93_dsfid;
2455                tag_params.i93.block_size = 0;
2456                tag_params.i93.num_block  = 0;
2457                memcpy (tag_params.i93.uid, nfa_rw_cb.i93_uid, I93_UID_BYTE_LEN);
2458            }
2459            else
2460            {
2461                /* reset memory size */
2462                nfa_rw_cb.i93_block_size = 0;
2463                nfa_rw_cb.i93_num_block  = 0;
2464            }
2465        }
2466        break;
2467
2468
2469    default:
2470        /* No action needed for other protocols */
2471        break;
2472    }
2473
2474    /* Notify upper layer of NFA_ACTIVATED_EVT if needed, and start presence check timer */
2475    if (activate_notify)
2476    {
2477        nfa_dm_notify_activation_status (NFA_STATUS_OK, &tag_params);
2478        nfa_rw_check_start_presence_check_timer ();
2479    }
2480
2481
2482    return TRUE;
2483}
2484
2485
2486/*******************************************************************************
2487**
2488** Function         nfa_rw_deactivate_ntf
2489**
2490** Description      Handler for NFA_RW_DEACTIVATE_NTF
2491**
2492** Returns          TRUE (message buffer to be freed by caller)
2493**
2494*******************************************************************************/
2495BOOLEAN nfa_rw_deactivate_ntf(tNFA_RW_MSG *p_data)
2496{
2497    /* Clear the activated flag */
2498    nfa_rw_cb.flags &= ~NFA_RW_FL_ACTIVATED;
2499
2500    /* Free buffer for incoming NDEF message, in case we were in the middle of a read operation */
2501    nfa_rw_free_ndef_rx_buf();
2502
2503    /* If there is a pending command message, then free it */
2504    if (nfa_rw_cb.p_pending_msg)
2505    {
2506        GKI_freebuf(nfa_rw_cb.p_pending_msg);
2507        nfa_rw_cb.p_pending_msg = NULL;
2508    }
2509
2510    /* Stop presence check timer (if started) */
2511    nfa_rw_stop_presence_check_timer();
2512
2513    return TRUE;
2514}
2515
2516/*******************************************************************************
2517**
2518** Function         nfa_rw_handle_op_req
2519**
2520** Description      Handler for NFA_RW_OP_REQUEST_EVT, operation request
2521**
2522** Returns          TRUE if caller should free p_data
2523**                  FALSE if caller does not need to free p_data
2524**
2525*******************************************************************************/
2526BOOLEAN nfa_rw_handle_op_req (tNFA_RW_MSG *p_data)
2527{
2528    BOOLEAN freebuf = TRUE;
2529
2530    /* Check if activated */
2531    if (!(nfa_rw_cb.flags & NFA_RW_FL_ACTIVATED))
2532    {
2533        NFA_TRACE_ERROR0("nfa_rw_handle_op_req: not activated");
2534        return TRUE;
2535    }
2536    /* Check if currently busy with another API call */
2537    else if (nfa_rw_cb.flags & NFA_RW_FL_API_BUSY)
2538    {
2539        return (nfa_rw_op_req_while_busy(p_data));
2540    }
2541    /* Check if currently busy with auto-presence check */
2542    else if (nfa_rw_cb.flags & NFA_RW_FL_AUTO_PRESENCE_CHECK_BUSY)
2543    {
2544        /* Cache the command (will be handled once auto-presence check is completed) */
2545        NFA_TRACE_DEBUG1("Deferring operation %i until after auto-presence check is completed", p_data->op_req.op);
2546        nfa_rw_cb.p_pending_msg = p_data;
2547        nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2548        return (freebuf);
2549    }
2550
2551    NFA_TRACE_DEBUG1("nfa_rw_handle_op_req: op=0x%02x", p_data->op_req.op);
2552
2553    nfa_rw_cb.flags |= NFA_RW_FL_API_BUSY;
2554
2555    /* Stop the presence check timer */
2556    nfa_rw_stop_presence_check_timer();
2557
2558    /* Store the current operation */
2559    nfa_rw_cb.cur_op = p_data->op_req.op;
2560
2561    /* Call appropriate handler for requested operation */
2562    switch (p_data->op_req.op)
2563    {
2564    case NFA_RW_OP_DETECT_NDEF:
2565        nfa_rw_detect_ndef(p_data);
2566        break;
2567
2568    case NFA_RW_OP_READ_NDEF:
2569        nfa_rw_read_ndef(p_data);
2570        break;
2571
2572    case NFA_RW_OP_WRITE_NDEF:
2573        nfa_rw_write_ndef(p_data);
2574        break;
2575
2576    case NFA_RW_OP_SEND_RAW_FRAME:
2577        NFC_SendData (NFC_RF_CONN_ID, p_data->op_req.params.send_raw_frame.p_data);
2578
2579        /* Command complete - perform cleanup */
2580        nfa_rw_command_complete();
2581        break;
2582
2583    case NFA_RW_OP_PRESENCE_CHECK:
2584        nfa_rw_presence_check(p_data);
2585        break;
2586
2587    case NFA_RW_OP_FORMAT_TAG:
2588        nfa_rw_format_tag(p_data);
2589        break;
2590
2591    case NFA_RW_OP_DETECT_LOCK_TLV:
2592        nfa_rw_detect_tlv(p_data, TAG_LOCK_CTRL_TLV);
2593        break;
2594
2595    case NFA_RW_OP_DETECT_MEM_TLV:
2596        nfa_rw_detect_tlv(p_data, TAG_MEM_CTRL_TLV);
2597        break;
2598
2599    case NFA_RW_OP_SET_TAG_RO:
2600        nfa_rw_cb.b_hard_lock = p_data->op_req.params.set_readonly.b_hard_lock;
2601        nfa_rw_config_tag_ro(nfa_rw_cb.b_hard_lock);
2602        break;
2603
2604    case NFA_RW_OP_T1T_RID:
2605        nfa_rw_t1t_rid(p_data);
2606        break;
2607
2608    case NFA_RW_OP_T1T_RALL:
2609        nfa_rw_t1t_rall(p_data);
2610        break;
2611
2612    case NFA_RW_OP_T1T_READ:
2613        nfa_rw_t1t_read(p_data);
2614        break;
2615
2616    case NFA_RW_OP_T1T_WRITE:
2617        nfa_rw_t1t_write(p_data);
2618        break;
2619
2620    case NFA_RW_OP_T1T_RSEG:
2621        nfa_rw_t1t_rseg(p_data);
2622        break;
2623
2624    case NFA_RW_OP_T1T_READ8:
2625        nfa_rw_t1t_read8(p_data);
2626        break;
2627
2628    case NFA_RW_OP_T1T_WRITE8:
2629        nfa_rw_t1t_write8(p_data);
2630        break;
2631
2632        /* Type-2 tag commands */
2633    case NFA_RW_OP_T2T_READ:
2634        nfa_rw_t2t_read(p_data);
2635        break;
2636
2637    case NFA_RW_OP_T2T_WRITE:
2638        nfa_rw_t2t_write(p_data);
2639        break;
2640
2641    case NFA_RW_OP_T2T_SECTOR_SELECT:
2642        nfa_rw_t2t_sector_select(p_data);
2643        break;
2644
2645        /* Type-3 tag commands */
2646    case NFA_RW_OP_T3T_READ:
2647        nfa_rw_t3t_read(p_data);
2648        break;
2649
2650    case NFA_RW_OP_T3T_WRITE:
2651        nfa_rw_t3t_write(p_data);
2652        break;
2653
2654    case NFA_RW_OP_T3T_GET_SYSTEM_CODES:
2655        nfa_rw_t3t_get_system_codes(p_data);
2656        break;
2657
2658        /* ISO 15693 tag commands */
2659    case NFA_RW_OP_I93_INVENTORY:
2660    case NFA_RW_OP_I93_STAY_QUIET:
2661    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2662    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2663    case NFA_RW_OP_I93_LOCK_BLOCK:
2664    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2665    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2666    case NFA_RW_OP_I93_SELECT:
2667    case NFA_RW_OP_I93_RESET_TO_READY:
2668    case NFA_RW_OP_I93_WRITE_AFI:
2669    case NFA_RW_OP_I93_LOCK_AFI:
2670    case NFA_RW_OP_I93_WRITE_DSFID:
2671    case NFA_RW_OP_I93_LOCK_DSFID:
2672    case NFA_RW_OP_I93_GET_SYS_INFO:
2673    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2674        nfa_rw_i93_command (p_data);
2675        break;
2676
2677    default:
2678        NFA_TRACE_ERROR1("nfa_rw_handle_api: unhandled operation: %i", p_data->op_req.op);
2679        break;
2680    }
2681
2682    return (freebuf);
2683}
2684
2685
2686/*******************************************************************************
2687**
2688** Function         nfa_rw_op_req_while_busy
2689**
2690** Description      Handle operation request while busy
2691**
2692** Returns          TRUE if caller should free p_data
2693**                  FALSE if caller does not need to free p_data
2694**
2695*******************************************************************************/
2696static BOOLEAN nfa_rw_op_req_while_busy(tNFA_RW_MSG *p_data)
2697{
2698    BOOLEAN             freebuf = TRUE;
2699    tNFA_CONN_EVT_DATA  conn_evt_data;
2700    UINT8               event;
2701
2702    NFA_TRACE_ERROR0("nfa_rw_op_req_while_busy: unable to handle API");
2703
2704    /* Return appropriate event for requested API, with status=BUSY */
2705    conn_evt_data.status = NFA_STATUS_BUSY;
2706
2707    switch (p_data->op_req.op)
2708    {
2709    case NFA_RW_OP_DETECT_NDEF:
2710        conn_evt_data.ndef_detect.cur_size = 0;
2711        conn_evt_data.ndef_detect.max_size = 0;
2712        conn_evt_data.ndef_detect.flags    = RW_NDEF_FL_UNKNOWN;
2713        event = NFA_NDEF_DETECT_EVT;
2714        break;
2715    case NFA_RW_OP_READ_NDEF:
2716    case NFA_RW_OP_T1T_RID:
2717    case NFA_RW_OP_T1T_RALL:
2718    case NFA_RW_OP_T1T_READ:
2719    case NFA_RW_OP_T1T_RSEG:
2720    case NFA_RW_OP_T1T_READ8:
2721    case NFA_RW_OP_T2T_READ:
2722    case NFA_RW_OP_T3T_READ:
2723        event = NFA_READ_CPLT_EVT;
2724        break;
2725    case NFA_RW_OP_WRITE_NDEF:
2726    case NFA_RW_OP_T1T_WRITE:
2727    case NFA_RW_OP_T1T_WRITE8:
2728    case NFA_RW_OP_T2T_WRITE:
2729    case NFA_RW_OP_T3T_WRITE:
2730        event = NFA_WRITE_CPLT_EVT;
2731        break;
2732    case NFA_RW_OP_FORMAT_TAG:
2733        event = NFA_FORMAT_CPLT_EVT;
2734        break;
2735        case NFA_RW_OP_DETECT_LOCK_TLV:
2736    case NFA_RW_OP_DETECT_MEM_TLV:
2737        event = NFA_TLV_DETECT_EVT;
2738        break;
2739    case NFA_RW_OP_SET_TAG_RO:
2740        event = NFA_SET_TAG_RO_EVT;
2741        break;
2742    case NFA_RW_OP_T2T_SECTOR_SELECT:
2743        event = NFA_SELECT_CPLT_EVT;
2744        break;
2745    case NFA_RW_OP_I93_INVENTORY:
2746    case NFA_RW_OP_I93_STAY_QUIET:
2747    case NFA_RW_OP_I93_READ_SINGLE_BLOCK:
2748    case NFA_RW_OP_I93_WRITE_SINGLE_BLOCK:
2749    case NFA_RW_OP_I93_LOCK_BLOCK:
2750    case NFA_RW_OP_I93_READ_MULTI_BLOCK:
2751    case NFA_RW_OP_I93_WRITE_MULTI_BLOCK:
2752    case NFA_RW_OP_I93_SELECT:
2753    case NFA_RW_OP_I93_RESET_TO_READY:
2754    case NFA_RW_OP_I93_WRITE_AFI:
2755    case NFA_RW_OP_I93_LOCK_AFI:
2756    case NFA_RW_OP_I93_WRITE_DSFID:
2757    case NFA_RW_OP_I93_LOCK_DSFID:
2758    case NFA_RW_OP_I93_GET_SYS_INFO:
2759    case NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS:
2760        event = NFA_I93_CMD_CPLT_EVT;
2761        break;
2762    default:
2763        return (freebuf);
2764    }
2765    nfa_dm_act_conn_cback_notify(event, &conn_evt_data);
2766
2767    return (freebuf);
2768}
2769
2770/*******************************************************************************
2771**
2772** Function         nfa_rw_command_complete
2773**
2774** Description      Handle command complete: clear the busy flag,
2775**                  and start the presence check timer if applicable.
2776**
2777** Returns          None
2778**
2779*******************************************************************************/
2780void nfa_rw_command_complete(void)
2781{
2782    /* Clear the busy flag */
2783    nfa_rw_cb.flags &= ~NFA_RW_FL_API_BUSY;
2784
2785    /* Restart presence_check timer */
2786    nfa_rw_check_start_presence_check_timer ();
2787}
2788