• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2013 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 
20 /******************************************************************************
21  *
22  *  This file contains the implementation for Type 3 tag in Reader/Writer
23  *  mode.
24  *
25  ******************************************************************************/
26 #include <string.h>
27 #include "nfc_target.h"
28 #include "bt_types.h"
29 #include "trace_api.h"
30 
31 #include "nfc_api.h"
32 #include "nfc_int.h"
33 #include "nci_hmsgs.h"
34 #include "rw_api.h"
35 #include "rw_int.h"
36 #include "tags_int.h"
37 #include "gki.h"
38 
39 /* Definitions for constructing t3t command messages */
40 #define RW_T3T_FL_PADDING   0x01        /* Padding needed for last NDEF block */
41 #define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT (13)    /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are < 256) */
42 #define RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT (12)    /* Maximum number of NDEF blocks updates that can fit into one command (when all block-numbers are >= 256) */
43 
44 /* Definitions for SENSF_RES */
45 #define RW_T3T_SENSF_RES_RD_OFFSET      17  /* Offset of RD in SENSF_RES from NCI_POLL NTF (includes 1 byte SENSF_RES length) */
46 #define RW_T3T_SENSF_RES_RD_LEN         2   /* Size of RD in SENSF_RES   */
47 
48 /* Timeout definitions for commands */
49 #define RW_T3T_POLL_CMD_TIMEOUT_TICKS                               ((RW_T3T_TOUT_RESP*2*QUICK_TIMER_TICKS_PER_SEC) / 1000)
50 #define RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS                            ((RW_T3T_TOUT_RESP*QUICK_TIMER_TICKS_PER_SEC) / 1000)
51 #define RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS                          (RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * 4)
52 
53 /* Macro to extract major version from NDEF version byte */
54 #define T3T_GET_MAJOR_VERSION(ver)      (ver>>4)
55 
56 /* Enumeration of API commands */
57 enum
58 {
59     RW_T3T_CMD_DETECT_NDEF,
60     RW_T3T_CMD_CHECK_NDEF,
61     RW_T3T_CMD_UPDATE_NDEF,
62     RW_T3T_CMD_CHECK,
63     RW_T3T_CMD_UPDATE,
64     RW_T3T_CMD_SEND_RAW_FRAME,
65     RW_T3T_CMD_GET_SYSTEM_CODES,
66     RW_T3T_CMD_FORMAT,
67     RW_T3T_CMD_SET_READ_ONLY_SOFT,
68     RW_T3T_CMD_SET_READ_ONLY_HARD,
69 
70     RW_T3T_CMD_MAX
71 };
72 
73 /* RW_CBACK events corresponding to API comands */
74 const UINT8 rw_t3t_api_res_evt[RW_T3T_CMD_MAX] =
75 {
76     RW_T3T_NDEF_DETECT_EVT,         /* RW_T3T_CMD_DETECT_NDEF */
77     RW_T3T_CHECK_CPLT_EVT,          /* RW_T3T_CMD_CHECK_NDEF  */
78     RW_T3T_UPDATE_CPLT_EVT,         /* RW_T3T_CMD_UPDATE_NDEF */
79     RW_T3T_CHECK_CPLT_EVT,          /* RW_T3T_CMD_CHECK */
80     RW_T3T_UPDATE_CPLT_EVT,         /* RW_T3T_CMD_UPDATE */
81     RW_T3T_RAW_FRAME_EVT,           /* RW_T3T_CMD_SEND_RAW_FRAME */
82     RW_T3T_GET_SYSTEM_CODES_EVT,    /* RW_T3T_CMD_GET_SYSTEM_CODES */
83     RW_T3T_FORMAT_CPLT_EVT,         /* RW_T3T_CMD_FORMAT */
84     RW_T3T_SET_READ_ONLY_CPLT_EVT   /* RW_T3T_CMD_SET_READ_ONLY */
85 };
86 
87 /* States */
88 enum
89 {
90     RW_T3T_STATE_NOT_ACTIVATED,
91     RW_T3T_STATE_IDLE,
92     RW_T3T_STATE_COMMAND_PENDING
93 };
94 
95 /* Sub-states */
96 enum
97 {
98     /* Sub states for getting system codes */
99     RW_T3T_GET_SC_SST_POLL_WILDCARD,        /* Waiting for wilcard poll response */
100     RW_T3T_GET_SC_SST_POLL_NDEF,            /* Waiting for NDEF poll response */
101     RW_T3T_GET_SC_SST_REQUEST_SC,           /* Waiting for REQUEST_SYSTEM_CODE response */
102 
103     /* Sub states for formatting Felica-Lite */
104     RW_T3T_FMT_SST_POLL_FELICA_LITE,        /* Waiting for POLL Felica-Lite response (for formatting) */
105     RW_T3T_FMT_SST_CHECK_MC_BLK,            /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
106     RW_T3T_FMT_SST_UPDATE_MC_BLK,           /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
107     RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB,      /* Waiting for NDEF attribute block-write to complete */
108 
109     /* Sub states for setting Felica-Lite read only */
110     RW_T3T_SRO_SST_POLL_FELICA_LITE,        /* Waiting for POLL Felica-Lite response (for setting read only) */
111     RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB,      /* Waiting for NDEF attribute block-write to complete */
112     RW_T3T_SRO_SST_CHECK_MC_BLK,            /* Waiting for Felica-Lite MC (MemoryControl) block-read to complete */
113     RW_T3T_SRO_SST_UPDATE_MC_BLK            /* Waiting for Felica-Lite MC (MemoryControl) block-write to complete */
114 };
115 
116 #if (BT_TRACE_VERBOSE == TRUE)
117 static char *rw_t3t_cmd_str (UINT8 cmd_id);
118 static char *rw_t3t_state_str (UINT8 state_id);
119 #endif
120 
121 
122 /* Local static functions */
123 static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[]);
124 static BT_HDR *rw_t3t_get_cmd_buf (void);
125 static tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg);
126 static void rw_t3t_handle_get_system_codes_cplt (void);
127 static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
128 static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
129 static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
130 static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf);
131 
132 
133 /* Default NDEF attribute information block (used when formatting Felica-Lite tags) */
134 #define RW_T3T_DEFAULT_FELICALITE_NBR       4   /* NBr (max block reads per cmd)*/
135 #define RW_T3T_DEFAULT_FELICALITE_NBW       1   /* NBw (max block write per cmd)*/
136 #define RW_T3T_DEFAULT_FELICALITE_NMAXB     (T3T_FELICALITE_NMAXB)
137 #define RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM  ((T3T_MSG_NDEF_VERSION +                    \
138                                                             RW_T3T_DEFAULT_FELICALITE_NBR +         \
139                                                             RW_T3T_DEFAULT_FELICALITE_NBW +         \
140                                                             (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8) +  \
141                                                             (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF) +\
142                                                             T3T_MSG_NDEF_WRITEF_OFF +               \
143                                                             T3T_MSG_NDEF_RWFLAG_RW) & 0xFFFF)
144 
145 const UINT8 rw_t3t_default_attrib_info[T3T_MSG_BLOCKSIZE] =
146 {
147     T3T_MSG_NDEF_VERSION,                   /* Ver                          */
148     RW_T3T_DEFAULT_FELICALITE_NBR,          /* NBr (max block reads per cmd)*/
149     RW_T3T_DEFAULT_FELICALITE_NBW,          /* NBw (max block write per cmd)*/
150     (RW_T3T_DEFAULT_FELICALITE_NMAXB>>8),   /* Nmaxb (max size in blocks)   */
151     (RW_T3T_DEFAULT_FELICALITE_NMAXB&0xFF), /* Nmaxb (max size in blocks)   */
152     0, 0, 0, 0,                             /* Unused                       */
153     T3T_MSG_NDEF_WRITEF_OFF,                /* WriteF                       */
154     T3T_MSG_NDEF_RWFLAG_RW,                 /* RW Flag                      */
155     0, 0, 0,                                /* Ln (current size in bytes)   */
156 
157     (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM >> 8),     /* checksum (high-byte) */
158     (RW_T3T_DEFAULT_FELICALITE_ATTRIB_INFO_CHECKSUM & 0xFF)    /* checksum (low-byte)  */
159 
160 };
161 
162 /*****************************************************************************
163 **  Type3 TAG COMMANDS
164 *****************************************************************************/
165 
166 /*******************************************************************************
167 **
168 ** Function         rw_t3t_process_error
169 **
170 ** Description      Process error (timeout or CRC error)
171 **
172 ** Returns          none
173 **
174 *******************************************************************************/
rw_t3t_process_error(tNFC_STATUS status)175 void rw_t3t_process_error (tNFC_STATUS status)
176 {
177     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
178     UINT8 evt;
179     tRW_DATA evt_data;
180     BT_HDR *p_cmd_buf;
181 
182     if (p_cb->rw_state == RW_T3T_STATE_COMMAND_PENDING)
183     {
184         if (p_cb->cur_cmd == RW_T3T_CMD_GET_SYSTEM_CODES)
185         {
186             /* For GetSystemCode: either tag did not respond to requested POLL, or REQUEST_SYSTEM_CODE command */
187             rw_t3t_handle_get_system_codes_cplt ();
188             return;
189         }
190         /* Retry sending command if retry-count < max */
191         else if (rw_cb.cur_retry < RW_MAX_RETRIES)
192         {
193             /* retry sending the command */
194             rw_cb.cur_retry++;
195 
196             RW_TRACE_DEBUG2 ("T3T retransmission attempt %i of %i", rw_cb.cur_retry, RW_MAX_RETRIES);
197 
198             /* allocate a new buffer for message */
199             if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
200             {
201                 memcpy (p_cmd_buf, p_cb->p_cur_cmd_buf, sizeof (BT_HDR) + p_cb->p_cur_cmd_buf->offset + p_cb->p_cur_cmd_buf->len);
202 
203                 if (rw_t3t_send_to_lower (p_cmd_buf) == NFC_STATUS_OK)
204                 {
205                     /* Start timer for waiting for response */
206                     nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, p_cb->cur_tout);
207                     return;
208                 }
209                 else
210                 {
211                     /* failure - could not send buffer */
212                     GKI_freebuf (p_cmd_buf);
213                 }
214             }
215         }
216         else
217         {
218             RW_TRACE_DEBUG1 ("T3T maximum retransmission attempts reached (%i)", RW_MAX_RETRIES);
219         }
220 
221 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
222         /* update failure count */
223         rw_main_update_fail_stats ();
224 #endif  /* RW_STATS_INCLUDED */
225 
226         p_cb->rw_state = RW_T3T_STATE_IDLE;
227 
228         /* Notify app of result (if there was a pending command) */
229         if (p_cb->cur_cmd < RW_T3T_CMD_MAX)
230         {
231             /* If doing presence check, use status=NFC_STATUS_FAILED, otherwise NFC_STATUS_TIMEOUT */
232             evt_data.status = status;
233             evt = rw_t3t_api_res_evt[p_cb->cur_cmd];
234 
235             /* Set additional flags for RW_T3T_NDEF_DETECT_EVT */
236             if (evt == RW_T3T_NDEF_DETECT_EVT)
237             {
238                 evt_data.ndef.flags = RW_NDEF_FL_UNKNOWN;
239             }
240 
241             (*(rw_cb.p_cback)) (evt, &evt_data);
242         }
243     }
244     else
245     {
246         evt_data.status = status;
247         (*(rw_cb.p_cback)) (RW_T3T_INTF_ERROR_EVT, &evt_data);
248     }
249 }
250 
251 /*******************************************************************************
252 **
253 ** Function         rw_t3t_start_poll_timer
254 **
255 ** Description      Start the timer for T3T POLL Command
256 **
257 ** Returns          none
258 **
259 *******************************************************************************/
rw_t3t_start_poll_timer(tRW_T3T_CB * p_cb)260 void rw_t3t_start_poll_timer (tRW_T3T_CB *p_cb)
261 {
262     nfc_start_quick_timer (&p_cb->poll_timer, NFC_TTYPE_RW_T3T_RESPONSE, RW_T3T_POLL_CMD_TIMEOUT_TICKS);
263 }
264 
265 /*******************************************************************************
266 **
267 ** Function         rw_t3t_handle_nci_poll_ntf
268 **
269 ** Description      Handle NCI_T3T_POLLING_NTF
270 **
271 ** Returns          none
272 **
273 *******************************************************************************/
rw_t3t_handle_nci_poll_ntf(UINT8 nci_status,UINT8 num_responses,UINT8 sensf_res_buf_size,UINT8 * p_sensf_res_buf)274 void rw_t3t_handle_nci_poll_ntf (UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
275 {
276     tRW_DATA evt_data;
277     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
278 
279     /* stop timer for poll response */
280     nfc_stop_quick_timer (&p_cb->poll_timer);
281 
282     /* Stop t3t timer (if started) */
283     if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
284     {
285         p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
286         evt_data.status = nci_status;
287         p_cb->rw_state = RW_T3T_STATE_IDLE;
288         (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
289     }
290     else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
291     {
292         /* Handle POLL ntf in response to get system codes */
293         p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
294         rw_t3t_handle_get_sc_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
295     }
296     else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
297     {
298         /* Handle POLL ntf in response to get system codes */
299         p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
300         rw_t3t_handle_fmt_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
301     }
302     else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
303     {
304         /* Handle POLL ntf in response to get system codes */
305         p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
306         rw_t3t_handle_sro_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
307     }
308     else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
309     {
310         /* Handle POLL ntf in response to ndef detection */
311         p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
312         rw_t3t_handle_ndef_detect_poll_rsp (p_cb, nci_status, num_responses, sensf_res_buf_size, p_sensf_res_buf);
313     }
314     else
315     {
316         /* Handle POLL ntf in response to RW_T3tPoll */
317         if ((evt_data.t3t_poll.status = nci_status) == NCI_STATUS_OK)
318         {
319             evt_data.t3t_poll.rc = p_cb->cur_poll_rc;
320             evt_data.t3t_poll.response_num = num_responses;
321             evt_data.t3t_poll.response_bufsize = sensf_res_buf_size;
322             evt_data.t3t_poll.response_buf = p_sensf_res_buf;
323         }
324 
325         p_cb->rw_state = RW_T3T_STATE_IDLE;
326         (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, &evt_data);
327     }
328 }
329 
330 
331 /*******************************************************************************
332 **
333 ** Function         rw_t3t_handle_get_system_codes_cplt
334 **
335 ** Description      Notify upper layer of system codes
336 **
337 ** Returns          none
338 **
339 *******************************************************************************/
rw_t3t_handle_get_system_codes_cplt(void)340 void rw_t3t_handle_get_system_codes_cplt (void)
341 {
342     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
343     tRW_DATA evt_data;
344     UINT8 i;
345 
346     evt_data.t3t_sc.status = NFC_STATUS_OK;
347     evt_data.t3t_sc.num_system_codes = p_cb->num_system_codes;
348     evt_data.t3t_sc.p_system_codes   = p_cb->system_codes;
349 
350     RW_TRACE_DEBUG1 ("rw_t3t_handle_get_system_codes_cplt, number of systems: %i", evt_data.t3t_sc.num_system_codes);
351     for (i = 0; i < evt_data.t3t_sc.num_system_codes; i++)
352     {
353         RW_TRACE_DEBUG2 ("   system %i: %04X", i, evt_data.t3t_sc.p_system_codes[i]);
354     }
355 
356     p_cb->rw_state = RW_T3T_STATE_IDLE;
357     (*(rw_cb.p_cback)) (RW_T3T_GET_SYSTEM_CODES_EVT, &evt_data);
358 
359 
360 }
361 
362 /*******************************************************************************
363 **
364 ** Function         rw_t3t_format_cplt
365 **
366 ** Description      Notify upper layer of format complete
367 **
368 ** Returns          none
369 **
370 *******************************************************************************/
rw_t3t_format_cplt(tNFC_STATUS status)371 void rw_t3t_format_cplt (tNFC_STATUS status)
372 {
373     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
374     tRW_DATA evt_data;
375 
376     p_cb->rw_state = RW_T3T_STATE_IDLE;
377 
378     /* Update ndef info */
379     p_cb->ndef_attrib.status = status;
380     if (status == NFC_STATUS_OK)
381     {
382         p_cb->ndef_attrib.version = T3T_MSG_NDEF_VERSION;
383         p_cb->ndef_attrib.nbr = RW_T3T_DEFAULT_FELICALITE_NBR;
384         p_cb->ndef_attrib.nbw = RW_T3T_DEFAULT_FELICALITE_NBW;
385         p_cb->ndef_attrib.nmaxb = RW_T3T_DEFAULT_FELICALITE_NMAXB;
386         p_cb->ndef_attrib.writef = T3T_MSG_NDEF_WRITEF_OFF;
387         p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RW;
388         p_cb->ndef_attrib.ln = 0;
389     }
390 
391     /* Notify upper layer of format complete */
392     evt_data.status = status;
393     (*(rw_cb.p_cback)) (RW_T3T_FORMAT_CPLT_EVT, &evt_data);
394 }
395 
396 /*******************************************************************************
397 **
398 ** Function         rw_t3t_set_readonly_cplt
399 **
400 ** Description      Notify upper layer of set read only complete
401 **
402 ** Returns          none
403 **
404 *******************************************************************************/
rw_t3t_set_readonly_cplt(tNFC_STATUS status)405 void rw_t3t_set_readonly_cplt (tNFC_STATUS status)
406 {
407     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
408     tRW_DATA evt_data;
409 
410     p_cb->rw_state = RW_T3T_STATE_IDLE;
411 
412     /* Notify upper layer of format complete */
413     evt_data.status = status;
414     (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
415 }
416 
417 /*******************************************************************************
418 **
419 ** Function         rw_t3t_process_timeout
420 **
421 ** Description      Process timeout
422 **
423 ** Returns          none
424 **
425 *******************************************************************************/
rw_t3t_process_timeout(TIMER_LIST_ENT * p_tle)426 void rw_t3t_process_timeout (TIMER_LIST_ENT *p_tle)
427 {
428     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
429     tRW_DATA evt_data;
430 
431     /* Check which timer timed out */
432     if (p_tle == &p_cb->timer)
433     {
434         /* UPDATE/CHECK response timeout */
435 #if (BT_TRACE_VERBOSE == TRUE)
436         RW_TRACE_ERROR3 ("T3T timeout. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
437 #else
438         RW_TRACE_ERROR2 ("T3T timeout. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
439 #endif
440 
441         rw_t3t_process_error (NFC_STATUS_TIMEOUT);
442     }
443     else
444     {
445         RW_TRACE_ERROR0 ("T3T POLL timeout.");
446 
447         /* POLL response timeout */
448         if (p_cb->flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
449         {
450             /* POLL timeout for presence check */
451             p_cb->flags &= ~RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
452             evt_data.status = NFC_STATUS_FAILED;
453             p_cb->rw_state = RW_T3T_STATE_IDLE;
454             (*(rw_cb.p_cback)) (RW_T3T_PRESENCE_CHECK_EVT, (tRW_DATA *) &evt_data);
455         }
456         else if (p_cb->flags & RW_T3T_FL_W4_GET_SC_POLL_RSP)
457         {
458             /* POLL timeout for getting system codes */
459             p_cb->flags &= ~RW_T3T_FL_W4_GET_SC_POLL_RSP;
460             rw_t3t_handle_get_system_codes_cplt ();
461         }
462         else if (p_cb->flags & RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP)
463         {
464             /* POLL timeout for formatting Felica Lite */
465             p_cb->flags &= ~RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
466             RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
467             rw_t3t_format_cplt (NFC_STATUS_FAILED);
468         }
469         else if (p_cb->flags & RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP)
470         {
471             /* POLL timeout for configuring Felica Lite read only */
472             p_cb->flags &= ~RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
473             RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
474             rw_t3t_set_readonly_cplt (NFC_STATUS_FAILED);
475         }
476         else if (p_cb->flags & RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP)
477         {
478             /* POLL timeout for ndef detection */
479             p_cb->flags &= ~RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
480             rw_t3t_handle_ndef_detect_poll_rsp (p_cb, NFC_STATUS_TIMEOUT, 0, 0, NULL);
481         }
482         else
483         {
484             /* Timeout waiting for response for RW_T3tPoll */
485             evt_data.t3t_poll.status = NFC_STATUS_FAILED;
486             p_cb->rw_state = RW_T3T_STATE_IDLE;
487             (*(rw_cb.p_cback)) (RW_T3T_POLL_EVT, (tRW_DATA *) &evt_data);
488         }
489     }
490 }
491 
492 
493 /*******************************************************************************
494 **
495 ** Function         rw_t3t_process_frame_error
496 **
497 ** Description      Process frame crc error
498 **
499 ** Returns          none
500 **
501 *******************************************************************************/
rw_t3t_process_frame_error(void)502 void rw_t3t_process_frame_error (void)
503 {
504 #if (BT_TRACE_VERBOSE == TRUE)
505     RW_TRACE_ERROR3 ("T3T frame error. state=%s cur_cmd=0x%02X (%s)", rw_t3t_state_str (rw_cb.tcb.t3t.rw_state), rw_cb.tcb.t3t.cur_cmd, rw_t3t_cmd_str (rw_cb.tcb.t3t.cur_cmd));
506 #else
507     RW_TRACE_ERROR2 ("T3T frame error. state=0x%02X cur_cmd=0x%02X", rw_cb.tcb.t3t.rw_state, rw_cb.tcb.t3t.cur_cmd);
508 #endif
509 
510 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
511     /* Update stats */
512     rw_main_update_crc_error_stats ();
513 #endif  /* RW_STATS_INCLUDED */
514 
515     /* Process the error */
516     rw_t3t_process_error (NFC_STATUS_MSG_CORRUPTED);
517 }
518 
519 /*******************************************************************************
520 **
521 ** Function         rw_t3t_send_to_lower
522 **
523 ** Description      Send command to lower layer
524 **
525 ** Returns          status of the send
526 **
527 *******************************************************************************/
rw_t3t_send_to_lower(BT_HDR * p_msg)528 tNFC_STATUS rw_t3t_send_to_lower (BT_HDR *p_msg)
529 {
530     UINT8 *p;
531 
532 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
533     BOOLEAN is_retry;
534     /* Update stats */
535     rw_main_update_tx_stats (p_msg->len, ((rw_cb.cur_retry==0) ? FALSE : TRUE));
536 #endif  /* RW_STATS_INCLUDED */
537 
538     /* Set NFC-F SoD field (payload len + 1) */
539     p_msg->offset -= 1;         /* Point to SoD field */
540     p = (UINT8 *) (p_msg+1) + p_msg->offset;
541     UINT8_TO_STREAM (p, (p_msg->len+1));
542     p_msg->len += 1;            /* Increment len to include SoD */
543 
544 #if (BT_TRACE_PROTOCOL == TRUE)
545     DispT3TagMessage (p_msg, FALSE);
546 #endif
547 
548     return (NFC_SendData (NFC_RF_CONN_ID, p_msg));
549 }
550 
551 /*****************************************************************************
552 **
553 ** Function         rw_t3t_get_cmd_buf
554 **
555 ** Description      Get a buffer for sending T3T messages
556 **
557 ** Returns          BT_HDR *
558 **
559 *****************************************************************************/
rw_t3t_get_cmd_buf(void)560 BT_HDR *rw_t3t_get_cmd_buf (void)
561 {
562     BT_HDR *p_cmd_buf;
563 
564     if ((p_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) != NULL)
565     {
566         /* Reserve offset for NCI_DATA_HDR and NFC-F Sod (LEN) field */
567         p_cmd_buf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE + 1;
568         p_cmd_buf->len = 0;
569     }
570 
571     return (p_cmd_buf);
572 }
573 
574 /*****************************************************************************
575 **
576 ** Function         rw_t3t_send_cmd
577 **
578 ** Description      Send command to tag, and start timer for response
579 **
580 ** Returns          tNFC_STATUS
581 **
582 *****************************************************************************/
rw_t3t_send_cmd(tRW_T3T_CB * p_cb,UINT8 rw_t3t_cmd,BT_HDR * p_cmd_buf,UINT32 timeout_ms)583 tNFC_STATUS rw_t3t_send_cmd (tRW_T3T_CB *p_cb, UINT8 rw_t3t_cmd, BT_HDR *p_cmd_buf, UINT32 timeout_ms)
584 {
585     tNFC_STATUS retval;
586 
587     /* Indicate first attempt to send command, back up cmd buffer in case needed for retransmission */
588     rw_cb.cur_retry = 0;
589     memcpy (p_cb->p_cur_cmd_buf, p_cmd_buf, sizeof (BT_HDR) + p_cmd_buf->offset + p_cmd_buf->len);
590 
591     p_cb->cur_cmd = rw_t3t_cmd;
592     p_cb->cur_tout = timeout_ms;
593     p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
594 
595     if ((retval = rw_t3t_send_to_lower (p_cmd_buf)) == NFC_STATUS_OK)
596     {
597         /* Start timer for waiting for response */
598         nfc_start_quick_timer (&p_cb->timer, NFC_TTYPE_RW_T3T_RESPONSE, timeout_ms);
599     }
600     else
601     {
602         /* Error sending */
603         p_cb->rw_state = RW_T3T_STATE_IDLE;
604     }
605 
606     return (retval);
607 }
608 
609 /*****************************************************************************
610 **
611 ** Function         rw_t3t_send_update_ndef_attribute_cmd
612 **
613 ** Description      Send UPDATE command for Attribute Information
614 **
615 ** Returns          tNFC_STATUS
616 **
617 *****************************************************************************/
rw_t3t_send_update_ndef_attribute_cmd(tRW_T3T_CB * p_cb,BOOLEAN write_in_progress)618 tNFC_STATUS rw_t3t_send_update_ndef_attribute_cmd (tRW_T3T_CB *p_cb, BOOLEAN write_in_progress)
619 {
620     tNFC_STATUS retval = NFC_STATUS_OK;
621     BT_HDR *p_cmd_buf;
622     UINT8 *p_cmd_start, *p;
623     UINT16 checksum, i;
624     UINT8 write_f;
625     UINT32 ln;
626     UINT8 *p_ndef_attr_info_start;
627 
628     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
629     {
630         /* Construct T3T message */
631         p = p_cmd_start  = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
632 
633         /* Add UPDATE opcode to message  */
634         UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
635 
636         /* Add IDm to message */
637         ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
638 
639         /* Add Service code list */
640         UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
641         UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);     /* Service code (little-endian format) */
642 
643         /* Add number of blocks in this UPDATE command */
644         UINT8_TO_STREAM (p, 1);                      /* Number of blocks to write in this command */
645 
646         /* Block List element: the NDEF attribute information block (block 0) */
647         UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
648         UINT8_TO_STREAM (p, 0);
649 
650         /* Add payload (Attribute information block) */
651         p_ndef_attr_info_start = p;                              /* Save start of a NDEF attribute info block for checksum */
652         UINT8_TO_STREAM (p, T3T_MSG_NDEF_VERSION);
653         UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);
654         UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);
655         UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);
656         UINT32_TO_STREAM (p, 0);
657 
658         /* If starting NDEF write: set WriteF=ON, and ln=current ndef length */
659         if (write_in_progress)
660         {
661             write_f = T3T_MSG_NDEF_WRITEF_ON;
662             ln = p_cb->ndef_attrib.ln;
663         }
664         /* If finishing NDEF write: set WriteF=OFF, and ln=new ndef len */
665         else
666         {
667             write_f = T3T_MSG_NDEF_WRITEF_OFF;
668             ln = p_cb->ndef_msg_len;
669         }
670         UINT8_TO_STREAM (p, write_f);
671         UINT8_TO_STREAM (p, p_cb->ndef_attrib.rwflag);
672         UINT8_TO_STREAM (p, (ln>>16) & 0xFF);    /* High byte (of 3) of Ln */
673         UINT8_TO_STREAM (p, (ln>>8) & 0xFF);     /* Middle byte (of 3) of Ln */
674         UINT8_TO_STREAM (p, (ln) & 0xFF);        /* Low byte (of 3) of Ln */
675 
676         /* Calculate and append Checksum */
677         checksum = 0;
678         for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
679         {
680             checksum+=p_ndef_attr_info_start[i];
681         }
682         UINT16_TO_BE_STREAM (p, checksum);
683 
684 
685         /* Calculate length of message */
686         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
687 
688         /* Send the T3T message */
689         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
690     }
691     else
692     {
693         retval = NFC_STATUS_NO_BUFFERS;
694     }
695 
696     return (retval);
697 }
698 
699 /*****************************************************************************
700 **
701 ** Function         rw_t3t_send_next_ndef_update_cmd
702 **
703 ** Description      Send next segment of NDEF message to update
704 **
705 ** Returns          tNFC_STATUS
706 **
707 *****************************************************************************/
rw_t3t_send_next_ndef_update_cmd(tRW_T3T_CB * p_cb)708 tNFC_STATUS rw_t3t_send_next_ndef_update_cmd (tRW_T3T_CB *p_cb)
709 {
710     tNFC_STATUS retval = NFC_STATUS_OK;
711     UINT16 block_id;
712     UINT16 first_block_to_write;
713     UINT16 ndef_blocks_to_write, ndef_blocks_remaining;
714     UINT32 ndef_bytes_remaining, ndef_padding = 0;
715     UINT8 flags = 0;
716     UINT8 *p_cur_ndef_src_offset;
717     BT_HDR *p_cmd_buf;
718     UINT8 *p_cmd_start, *p;
719     UINT8 blocks_per_update;
720     UINT32 timeout;
721 
722     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
723     {
724         /* Construct T3T message */
725         p = p_cmd_start  = (UINT8 *) (p_cmd_buf + 1) + p_cmd_buf->offset;
726 
727         /* Calculate number of ndef bytes remaining to write */
728         ndef_bytes_remaining = p_cb->ndef_msg_len - p_cb->ndef_msg_bytes_sent;
729 
730         /* Calculate number of blocks remaining to write */
731         ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4);      /* ndef blocks remaining (rounded upward) */
732 
733         /* Calculate first NDEF block ID for this UPDATE command */
734         first_block_to_write = (UINT16) ((p_cb->ndef_msg_bytes_sent >> 4) + 1);
735 
736         /* Calculate max number of blocks per write. */
737         if ((first_block_to_write + RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT) < 0x100)
738         {
739             /* All block-numbers are < 0x100 (i.e. can be specified using one-byte format) */
740             blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_1_BYTE_FORMAT;
741         }
742         else
743         {
744             /* Block-numbers are >= 0x100 (i.e. need to be specified using two-byte format) */
745             blocks_per_update = RW_T3T_MAX_NDEF_BLOCKS_PER_UPDATE_2_BYTE_FORMAT;
746         }
747 
748         /* Check if blocks_per_update is bigger than what peer allows */
749         if (blocks_per_update > p_cb->ndef_attrib.nbw)
750             blocks_per_update = p_cb->ndef_attrib.nbw;
751 
752         /* Check if remaining blocks can fit into one UPDATE command */
753         if (ndef_blocks_remaining <= blocks_per_update)
754         {
755             /* remaining blocks can fit into one UPDATE command */
756             ndef_blocks_to_write = ndef_blocks_remaining;
757         }
758         else
759         {
760             /* Remaining blocks cannot fit into one UPDATE command */
761             ndef_blocks_to_write = blocks_per_update;
762         }
763 
764 
765         /* Write to command header for UPDATE */
766 
767         /* Add UPDATE opcode to message  */
768         UINT8_TO_STREAM (p, T3T_MSG_OPC_UPDATE_CMD);
769 
770         /* Add IDm to message */
771         ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
772 
773         /* Add Service code list */
774         UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
775         UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);     /* Service code (little-endian format) */
776 
777 
778         /* Add number of blocks in this UPDATE command */
779         UINT8_TO_STREAM (p, ndef_blocks_to_write);   /* Number of blocks to write in this command */
780         timeout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) ndef_blocks_to_write;
781 
782         for (block_id = first_block_to_write; block_id < (first_block_to_write + ndef_blocks_to_write); block_id++)
783         {
784             if (block_id<256)
785             {
786                 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
787                 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);    /* byte0: len=1; access-mode=0; service code list order=0 */
788                 UINT8_TO_STREAM (p, block_id);                                   /* byte1: block number */
789             }
790             else
791             {
792                 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
793                 UINT8_TO_STREAM (p, 0x00);               /* byte0: len=0; access-mode=0; service code list order=0 */
794                 UINT16_TO_STREAM (p, block_id);          /* byte1-2: block number in little-endian format */
795             }
796 
797         }
798 
799         /* Add NDEF payload */
800 
801         /* If this sending last block of NDEF,  check if padding is needed to make payload a multiple of 16 bytes */
802         if (ndef_blocks_to_write == ndef_blocks_remaining)
803         {
804             ndef_padding = (16 - (ndef_bytes_remaining & 0x0F)) & 0x0F;
805             if (ndef_padding)
806             {
807                 flags |= RW_T3T_FL_PADDING;
808                 ndef_blocks_to_write--;         /* handle the last block separately if it needs padding */
809             }
810         }
811 
812         /* Add NDEF payload to the message */
813         p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
814 
815 
816         ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (ndef_blocks_to_write * 16));
817         p_cb->ndef_msg_bytes_sent += ((UINT32) ndef_blocks_to_write * 16);
818 
819         if (flags & RW_T3T_FL_PADDING)
820         {
821             /* Add last of the NDEF message */
822             p_cur_ndef_src_offset = &p_cb->ndef_msg[p_cb->ndef_msg_bytes_sent];
823             ARRAY_TO_STREAM (p, p_cur_ndef_src_offset, (int) (16-ndef_padding));
824             p_cb->ndef_msg_bytes_sent += (16-ndef_padding);
825 
826             /* Add padding */
827             memset (p, 0, ndef_padding);
828             p+=ndef_padding;
829         }
830 
831         /* Calculate length of message */
832         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
833 
834         /* Send the T3T message */
835         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE_NDEF, p_cmd_buf, timeout);
836     }
837     else
838     {
839         retval = NFC_STATUS_NO_BUFFERS;
840     }
841 
842     return (retval);
843 }
844 
845 
846 
847 /*****************************************************************************
848 **
849 ** Function         rw_t3t_send_next_ndef_check_cmd
850 **
851 ** Description      Send command for reading next segment of NDEF message
852 **
853 ** Returns          tNFC_STATUS
854 **
855 *****************************************************************************/
rw_t3t_send_next_ndef_check_cmd(tRW_T3T_CB * p_cb)856 tNFC_STATUS rw_t3t_send_next_ndef_check_cmd (tRW_T3T_CB *p_cb)
857 {
858     tNFC_STATUS retval = NFC_STATUS_OK;
859     UINT16 block_id;
860     UINT16 ndef_blocks_remaining, first_block_to_read, cur_blocks_to_read;
861     UINT32 ndef_bytes_remaining;
862     BT_HDR *p_cmd_buf;
863     UINT8 *p_cmd_start, *p;
864 
865     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
866     {
867         /* Construct T3T message */
868         p = p_cmd_start  = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
869 
870         /* Calculate number of ndef bytes remaining to read */
871         ndef_bytes_remaining = p_cb->ndef_attrib.ln - p_cb->ndef_rx_offset;
872 
873         /* Calculate number of blocks remaining to read */
874         ndef_blocks_remaining = (UINT16) ((ndef_bytes_remaining+15) >> 4);      /* ndef blocks remaining (rounded upward) */
875 
876         /* Calculate first NDEF block ID */
877         first_block_to_read = (UINT16) ((p_cb->ndef_rx_offset >> 4) + 1);
878 
879         /* Check if remaining blocks can fit into one CHECK command */
880         if (ndef_blocks_remaining <= p_cb->ndef_attrib.nbr)
881         {
882             /* remaining blocks can fit into one CHECK command */
883             cur_blocks_to_read = ndef_blocks_remaining;
884             p_cb->ndef_rx_readlen = ndef_bytes_remaining;
885             p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
886         }
887         else
888         {
889             /* Remaining blocks cannot fit into one CHECK command */
890             cur_blocks_to_read = p_cb->ndef_attrib.nbr;            /* Read maximum number of blocks allowed by the peer */
891             p_cb->ndef_rx_readlen = ((UINT32) p_cb->ndef_attrib.nbr * 16);
892         }
893 
894         RW_TRACE_DEBUG3 ("rw_t3t_send_next_ndef_check_cmd: bytes_remaining: %i, cur_blocks_to_read: %i, is_final: %i",
895             ndef_bytes_remaining, cur_blocks_to_read, (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT));
896 
897         /* Write to command header for UPDATE */
898 
899         /* Add UPDATE opcode to message  */
900         UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
901 
902         /* Add IDm to message */
903         ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
904 
905         /* Add Service code list */
906         UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
907 
908         /* Service code (little-endian format) . If NDEF is read-only, then use T3T_MSG_NDEF_SC_RO, otherwise use T3T_MSG_NDEF_SC_RW */
909         if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
910         {
911             UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);
912         }
913         else
914         {
915             UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RW);
916         }
917 
918         /* Add number of blocks in this UPDATE command */
919         UINT8_TO_STREAM (p, cur_blocks_to_read);     /* Number of blocks to check in this command */
920 
921         for (block_id = first_block_to_read; block_id < (first_block_to_read + cur_blocks_to_read); block_id++)
922         {
923             if (block_id<256)
924             {
925                 /* Block IDs 0-255 can be specified in '2-byte' format: byte0=0, byte1=blocknumber */
926                 UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);    /* byte1: len=0; access-mode=0; service code list order=0 */
927                 UINT8_TO_STREAM (p, block_id);                                   /* byte1: block number */
928             }
929             else
930             {
931                 /* Block IDs 256+ must be specified in '3-byte' format: byte0=80h, followed by blocknumber */
932                 UINT8_TO_STREAM (p, 0x00);           /* byte0: len=1; access-mode=0; service code list order=0 */
933                 UINT16_TO_STREAM (p, block_id);      /* byte1-2: block number in little-endian format */
934             }
935 
936         }
937 
938         /* Calculate length of message */
939         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
940 
941         /* Send the T3T message */
942         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) cur_blocks_to_read);
943     }
944     else
945     {
946         retval = NFC_STATUS_NO_BUFFERS;
947     }
948 
949     return(retval);
950 }
951 
952 
953 /*****************************************************************************
954 **
955 ** Function         rw_t3t_message_set_block_list
956 **
957 ** Description      Add block list to T3T message
958 **
959 ** Returns          Number of bytes added to message
960 **
961 *****************************************************************************/
rw_t3t_message_set_block_list(tRW_T3T_CB * p_cb,UINT8 ** p,UINT8 num_blocks,tT3T_BLOCK_DESC * p_t3t_blocks)962 void rw_t3t_message_set_block_list (tRW_T3T_CB *p_cb, UINT8 **p, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
963 {
964     UINT16 i, cur_service_code;
965     UINT8 service_code_idx, num_services = 0;
966     UINT8 *p_msg_num_services;
967     UINT16 service_list[T3T_MSG_SERVICE_LIST_MAX];
968 
969     /* Add CHECK or UPDATE opcode to message  */
970     UINT8_TO_STREAM ((*p), ((p_cb->cur_cmd == RW_T3T_CMD_CHECK) ? T3T_MSG_OPC_CHECK_CMD:T3T_MSG_OPC_UPDATE_CMD));
971 
972     /* Add IDm to message */
973     ARRAY_TO_STREAM ((*p), p_cb->peer_nfcid2, NCI_NFCID2_LEN);
974 
975     /* Skip over Number of Services field */
976     p_msg_num_services = (*p);      /* pointer to Number of Services offset */
977     (*p)++;
978 
979     /* Count number of different services are specified in the list, and add services to Service Code list */
980     for (i = 0; i < num_blocks; i++)
981     {
982         cur_service_code = p_t3t_blocks[i].service_code;
983 
984         /* Check if current service_code is already in the service_list */
985         for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
986         {
987             if (service_list[service_code_idx] == cur_service_code)
988                 break;
989         }
990 
991         if (service_code_idx == num_services)
992         {
993             /* Service not in the list yet. Add it. */
994             service_list[service_code_idx] = cur_service_code;
995             num_services++;
996 
997             /* Add service code to T3T message */
998             UINT16_TO_STREAM ((*p), cur_service_code);
999         }
1000     }
1001 
1002     /* Add 'Number of Sservices' to the message */
1003     *p_msg_num_services = num_services;
1004 
1005     /* Add 'number of blocks' to the message */
1006     UINT8_TO_STREAM ((*p), num_blocks);
1007 
1008     /* Add block descriptors */
1009     for (i = 0; i < num_blocks; i++)
1010     {
1011         cur_service_code = p_t3t_blocks[i].service_code;
1012 
1013         /* Check if current service_code is already in the service_list */
1014         for (service_code_idx=0; service_code_idx<num_services; service_code_idx++)
1015         {
1016             if (service_list[service_code_idx] == cur_service_code)
1017                 break;
1018         }
1019 
1020         /* Add decriptor to T3T message */
1021         if (p_t3t_blocks[i].block_number > 0xFF)
1022         {
1023             UINT8_TO_STREAM ((*p), service_code_idx);
1024             UINT16_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1025         }
1026         else
1027         {
1028             service_code_idx |= T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT;
1029             UINT8_TO_STREAM ((*p), service_code_idx);
1030             UINT8_TO_STREAM ((*p), p_t3t_blocks[i].block_number);
1031         }
1032     }
1033 }
1034 
1035 /*****************************************************************************
1036 **
1037 ** Function         rw_t3t_send_check_cmd
1038 **
1039 ** Description      Send CHECK command
1040 **
1041 ** Returns          tNFC_STATUS
1042 **
1043 *****************************************************************************/
rw_t3t_send_check_cmd(tRW_T3T_CB * p_cb,UINT8 num_blocks,tT3T_BLOCK_DESC * p_t3t_blocks)1044 tNFC_STATUS rw_t3t_send_check_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks)
1045 {
1046     BT_HDR *p_cmd_buf;
1047     UINT8 *p, *p_cmd_start;
1048     tNFC_STATUS retval = NFC_STATUS_OK;
1049 
1050     p_cb->cur_cmd = RW_T3T_CMD_CHECK;
1051     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1052     {
1053         /* Construct T3T message */
1054         p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1055         rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1056 
1057         /* Calculate length of message */
1058         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1059 
1060         /* Send the T3T message */
1061         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_CHECK, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
1062     }
1063     else
1064     {
1065         retval = NFC_STATUS_NO_BUFFERS;
1066     }
1067 
1068     return(retval);
1069 }
1070 
1071 /*****************************************************************************
1072 **
1073 ** Function         rw_t3t_send_update_cmd
1074 **
1075 ** Description      Send UPDATE command
1076 **
1077 ** Returns          tNFC_STATUS
1078 **
1079 *****************************************************************************/
rw_t3t_send_update_cmd(tRW_T3T_CB * p_cb,UINT8 num_blocks,tT3T_BLOCK_DESC * p_t3t_blocks,UINT8 * p_data)1080 tNFC_STATUS rw_t3t_send_update_cmd (tRW_T3T_CB *p_cb, UINT8 num_blocks, tT3T_BLOCK_DESC *p_t3t_blocks, UINT8 *p_data)
1081 {
1082     BT_HDR *p_cmd_buf;
1083     UINT8 *p, *p_cmd_start;
1084     tNFC_STATUS retval = NFC_STATUS_OK;
1085 
1086     p_cb->cur_cmd = RW_T3T_CMD_UPDATE;
1087     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1088     {
1089         /* Construct T3T message */
1090         p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1091         rw_t3t_message_set_block_list (p_cb, &p, num_blocks, p_t3t_blocks);
1092 
1093         /* Add data blocks to the message */
1094         ARRAY_TO_STREAM (p, p_data, num_blocks*16);
1095 
1096         /* Calculate length of message */
1097         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1098 
1099         /* Send the T3T message */
1100         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_UPDATE, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS * (UINT32) num_blocks);
1101     }
1102     else
1103     {
1104         retval = NFC_STATUS_NO_BUFFERS;
1105     }
1106 
1107     return(retval);
1108 }
1109 
1110 /*****************************************************************************
1111 **
1112 ** Function         rw_t3t_check_mc_block
1113 **
1114 ** Description      Send command to check Memory Configuration Block
1115 **
1116 ** Returns          tNFC_STATUS
1117 **
1118 *****************************************************************************/
rw_t3t_check_mc_block(tRW_T3T_CB * p_cb)1119 tNFC_STATUS rw_t3t_check_mc_block (tRW_T3T_CB *p_cb)
1120 {
1121     BT_HDR *p_cmd_buf;
1122     UINT8 *p, *p_cmd_start;
1123 
1124     /* Read Memory Configuration block */
1125     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1126     {
1127         /* Construct T3T message */
1128         p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1129 
1130         /* Add CHECK opcode to message  */
1131         UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1132 
1133         /* Add IDm to message */
1134         ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1135 
1136         /* Add Service code list */
1137         UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
1138         UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);     /* Service code (little-endian format) */
1139 
1140         /* Number of blocks */
1141         UINT8_TO_STREAM (p, 1);                       /* Number of blocks (only 1 block: Memory Configuration Information ) */
1142 
1143         /* Block List element: the Memory Configuration block (block 0x88) */
1144         UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1145         UINT8_TO_STREAM (p, T3T_MSG_FELICALITE_BLOCK_ID_MC);
1146 
1147         /* Calculate length of message */
1148         p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1149 
1150         /* Send the T3T message */
1151         return rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
1152     }
1153     else
1154     {
1155         RW_TRACE_ERROR0 ("Unable to allocate buffer to read MC block");
1156         return (NFC_STATUS_NO_BUFFERS);
1157     }
1158 }
1159 
1160 /*****************************************************************************
1161 **
1162 ** Function         rw_t3t_send_raw_frame
1163 **
1164 ** Description      Send raw frame
1165 **
1166 ** Returns          tNFC_STATUS
1167 **
1168 *****************************************************************************/
rw_t3t_send_raw_frame(tRW_T3T_CB * p_cb,UINT16 len,UINT8 * p_data)1169 tNFC_STATUS rw_t3t_send_raw_frame (tRW_T3T_CB *p_cb, UINT16 len, UINT8 *p_data)
1170 {
1171     BT_HDR *p_cmd_buf;
1172     UINT8 *p;
1173     tNFC_STATUS retval = NFC_STATUS_OK;
1174 
1175     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1176     {
1177         /* Construct T3T message */
1178         p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1179 
1180         /* Add data blocks to the message */
1181         ARRAY_TO_STREAM (p, p_data, len);
1182 
1183         /* Calculate length of message */
1184         p_cmd_buf->len = len;
1185 
1186         /* Send the T3T message */
1187         retval = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_SEND_RAW_FRAME, p_cmd_buf, RW_T3T_RAW_FRAME_CMD_TIMEOUT_TICKS);
1188     }
1189     else
1190     {
1191         retval = NFC_STATUS_NO_BUFFERS;
1192     }
1193 
1194     return (retval);
1195 }
1196 
1197 
1198 /*****************************************************************************
1199 **  TAG RESPONSE HANDLERS
1200 *****************************************************************************/
1201 
1202 
1203 /*****************************************************************************
1204 **
1205 ** Function         rw_t3t_act_handle_ndef_detect_rsp
1206 **
1207 ** Description      Handle response to NDEF detection
1208 **
1209 ** Returns          Nothing
1210 **
1211 *****************************************************************************/
rw_t3t_act_handle_ndef_detect_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1212 void rw_t3t_act_handle_ndef_detect_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1213 {
1214     UINT8 *p;
1215     UINT32 temp;
1216     UINT8 i;
1217     UINT16 checksum_calc, checksum_rx;
1218     tRW_DETECT_NDEF_DATA evt_data;
1219     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1220 
1221     evt_data.status = NFC_STATUS_FAILED;
1222     evt_data.flags  = RW_NDEF_FL_UNKNOWN;
1223 
1224     /* Check if response code is CHECK resp (for reading NDEF attribute block) */
1225     if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1226     {
1227         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1228         evt_data.status = NFC_STATUS_FAILED;
1229     }
1230     /* Validate status code and NFCID2 response from tag */
1231     else if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                          /* verify response status code */
1232              ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
1233     {
1234         evt_data.status = NFC_STATUS_FAILED;
1235     }
1236     else
1237     {
1238         /* Get checksum from received ndef attribute msg */
1239         p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA+T3T_MSG_NDEF_ATTR_INFO_SIZE];
1240         BE_STREAM_TO_UINT16 (checksum_rx, p);
1241 
1242         /* Calculate checksum - move check for checsum to beginning */
1243         checksum_calc = 0;
1244         p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];
1245         for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
1246         {
1247             checksum_calc+=p[i];
1248         }
1249 
1250         /* Validate checksum */
1251         if (checksum_calc != checksum_rx)
1252         {
1253             p_cb->ndef_attrib.status = NFC_STATUS_FAILED;       /* only ok or failed passed to the app. can be boolean*/
1254 
1255             RW_TRACE_ERROR0 ("RW_T3tDetectNDEF checksum failed");
1256         }
1257         else
1258         {
1259             p_cb->ndef_attrib.status = NFC_STATUS_OK;
1260 
1261             /* Validate version number */
1262             STREAM_TO_UINT8 (p_cb->ndef_attrib.version, p);
1263 
1264             if (T3T_GET_MAJOR_VERSION (T3T_MSG_NDEF_VERSION) < T3T_GET_MAJOR_VERSION (p_cb->ndef_attrib.version))
1265             {
1266                 /* Remote tag's MajorVer is newer than our's. Reject NDEF as per T3TOP RQ_T3T_NDA_024 */
1267                 RW_TRACE_ERROR2 ("RW_T3tDetectNDEF: incompatible NDEF version. Local=0x%02x, Remote=0x%02x", T3T_MSG_NDEF_VERSION, p_cb->ndef_attrib.version);
1268                 p_cb->ndef_attrib.status = NFC_STATUS_FAILED;
1269                 evt_data.status = NFC_STATUS_BAD_RESP;
1270             }
1271             else
1272             {
1273                 /* Remote tag's MajorVer is equal or older than our's. NDEF is compatible with our version. */
1274 
1275                 /* Update NDEF info */
1276                 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbr, p);              /* NBr: number of blocks that can be read using one Check command */
1277                 STREAM_TO_UINT8 (p_cb->ndef_attrib.nbw, p);              /* Nbw: number of blocks that can be written using one Update command */
1278                 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.nmaxb, p);        /* Nmaxb: maximum number of blocks available for NDEF data */
1279                 BE_STREAM_TO_UINT32 (temp, p);
1280                 STREAM_TO_UINT8 (p_cb->ndef_attrib.writef, p);           /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
1281                 STREAM_TO_UINT8 (p_cb->ndef_attrib.rwflag, p);           /* RWFlag: 00h NDEF is read-only; 01h if read/write available */
1282 
1283                 /* Get length (3-byte, big-endian) */
1284                 STREAM_TO_UINT8 (temp, p);                               /* Ln: high-byte */
1285                 BE_STREAM_TO_UINT16 (p_cb->ndef_attrib.ln, p);           /* Ln: lo-word */
1286                 p_cb->ndef_attrib.ln += (temp << 16);
1287 
1288 
1289                 RW_TRACE_DEBUG1 ("Detected NDEF Ver: 0x%02x", p_cb->ndef_attrib.version);
1290                 RW_TRACE_DEBUG6 ("Detected NDEF Attributes: Nbr=%i, Nbw=%i, Nmaxb=%i, WriteF=%i, RWFlag=%i, Ln=%i",
1291                     p_cb->ndef_attrib.nbr,
1292                     p_cb->ndef_attrib.nbw,
1293                     p_cb->ndef_attrib.nmaxb,
1294                     p_cb->ndef_attrib.writef,
1295                     p_cb->ndef_attrib.rwflag,
1296                     p_cb->ndef_attrib.ln);
1297 
1298                 /* Set data for RW_T3T_NDEF_DETECT_EVT */
1299                 evt_data.status = p_cb->ndef_attrib.status;
1300                 evt_data.cur_size = p_cb->ndef_attrib.ln;
1301                 evt_data.max_size = (UINT32) p_cb->ndef_attrib.nmaxb * 16;
1302                 evt_data.protocol = NFC_PROTOCOL_T3T;
1303                 evt_data.flags    = (RW_NDEF_FL_SUPPORTED | RW_NDEF_FL_FORMATED);
1304                 if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)
1305                     evt_data.flags    |= RW_NDEF_FL_READ_ONLY;
1306             }
1307         }
1308     }
1309 
1310     RW_TRACE_DEBUG1 ("RW_T3tDetectNDEF response: %i", evt_data.status);
1311 
1312     p_cb->rw_state = RW_T3T_STATE_IDLE;
1313 
1314     /* Notify app of NDEF detection result */
1315     (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, (tRW_DATA *) &evt_data);
1316 
1317     GKI_freebuf (p_msg_rsp);
1318 }
1319 
1320 
1321 /*****************************************************************************
1322 **
1323 ** Function         rw_t3t_act_handle_check_rsp
1324 **
1325 ** Description      Handle response to CHECK command
1326 **
1327 ** Returns          Nothing
1328 **
1329 *****************************************************************************/
rw_t3t_act_handle_check_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1330 void rw_t3t_act_handle_check_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1331 {
1332     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1333     tRW_READ_DATA evt_data;
1334     tNFC_STATUS nfc_status = NFC_STATUS_OK;
1335 
1336     /* Validate response from tag */
1337     if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
1338         ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
1339     {
1340         nfc_status = NFC_STATUS_FAILED;
1341         GKI_freebuf (p_msg_rsp);
1342     }
1343     else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1344     {
1345         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1346         nfc_status = NFC_STATUS_FAILED;
1347         GKI_freebuf (p_msg_rsp);
1348     }
1349     else
1350     {
1351         /* Copy incoming data into buffer */
1352         p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA;     /* Skip over t3t header */
1353         p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1354         evt_data.status = NFC_STATUS_OK;
1355         evt_data.p_data = p_msg_rsp;
1356         (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &evt_data);
1357     }
1358 
1359 
1360     p_cb->rw_state = RW_T3T_STATE_IDLE;
1361 
1362     (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &nfc_status);
1363 }
1364 
1365 /*****************************************************************************
1366 **
1367 ** Function         rw_t3t_act_handle_update_rsp
1368 **
1369 ** Description      Handle response to UPDATE command
1370 **
1371 ** Returns          Nothing
1372 **
1373 *****************************************************************************/
rw_t3t_act_handle_update_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1374 void rw_t3t_act_handle_update_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1375 {
1376     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1377     tRW_READ_DATA evt_data;
1378 
1379     /* Validate response from tag */
1380     if (   (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                          /* verify response status code */
1381         ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
1382     {
1383         evt_data.status = NFC_STATUS_FAILED;
1384     }
1385     else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1386     {
1387         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1388         evt_data.status = NFC_STATUS_FAILED;
1389     }
1390     else
1391     {
1392         /* Copy incoming data into buffer */
1393         evt_data.status = NFC_STATUS_OK;
1394     }
1395 
1396     p_cb->rw_state = RW_T3T_STATE_IDLE;
1397 
1398     (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *)&evt_data);
1399 
1400     GKI_freebuf (p_msg_rsp);
1401 }
1402 
1403 /*****************************************************************************
1404 **
1405 ** Function         rw_t3t_act_handle_raw_senddata_rsp
1406 **
1407 ** Description      Handle response to NDEF detection
1408 **
1409 ** Returns          Nothing
1410 **
1411 *****************************************************************************/
rw_t3t_act_handle_raw_senddata_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1412 void rw_t3t_act_handle_raw_senddata_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1413 {
1414     tRW_READ_DATA evt_data;
1415 
1416     /* Copy incoming data into buffer */
1417     evt_data.status = NFC_STATUS_OK;
1418     evt_data.p_data = p_msg_rsp;
1419 
1420     p_cb->rw_state = RW_T3T_STATE_IDLE;
1421 
1422     (*(rw_cb.p_cback)) (RW_T3T_RAW_FRAME_EVT, (tRW_DATA *) &evt_data);
1423 }
1424 
1425 /*****************************************************************************
1426 **
1427 ** Function         rw_t3t_act_handle_check_ndef_rsp
1428 **
1429 ** Description      Handle response to NDEF read segment
1430 **
1431 ** Returns          Nothing
1432 **
1433 *****************************************************************************/
rw_t3t_act_handle_check_ndef_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1434 void rw_t3t_act_handle_check_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1435 {
1436     BOOLEAN check_complete = TRUE;
1437     tNFC_STATUS nfc_status = NFC_STATUS_OK;
1438     tRW_READ_DATA read_data;
1439     tRW_DATA evt_data;
1440     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1441     UINT8 rsp_num_bytes_rx;
1442 
1443     /* Validate response from tag */
1444     if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                      /* verify response status code */
1445         ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0) /* verify response IDm */
1446         ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] != ((p_cb->ndef_rx_readlen+15) >> 4))  )     /* verify length of response */
1447     {
1448         RW_TRACE_ERROR2 ("Response error: bad status, nfcid2, or invalid len: %i %i", p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS], ((p_cb->ndef_rx_readlen+15)>>4));
1449         nfc_status = NFC_STATUS_FAILED;
1450         GKI_freebuf (p_msg_rsp);
1451     }
1452     else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1453     {
1454         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1455         nfc_status = NFC_STATUS_FAILED;
1456         GKI_freebuf (p_msg_rsp);
1457     }
1458     else
1459     {
1460         /* Notify app of NDEF segment received */
1461         rsp_num_bytes_rx = p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMBLOCKS] * 16;    /* Number of bytes received, according to header */
1462         p_cb->ndef_rx_offset += p_cb->ndef_rx_readlen;
1463         read_data.status = NFC_STATUS_OK;
1464         p_msg_rsp->offset += T3T_MSG_RSP_OFFSET_CHECK_DATA;     /* Skip over t3t header (point to block data) */
1465         p_msg_rsp->len -= T3T_MSG_RSP_OFFSET_CHECK_DATA;
1466 
1467         /* Verify that the bytes received is really the amount indicated in the check-response header */
1468         if (rsp_num_bytes_rx > p_msg_rsp->len)
1469         {
1470             RW_TRACE_ERROR2 ("Response error: CHECK rsp header indicates %i bytes, but only received %i bytes", rsp_num_bytes_rx, p_msg_rsp->len);
1471             nfc_status = NFC_STATUS_FAILED;
1472             GKI_freebuf (p_msg_rsp);
1473         }
1474         else
1475         {
1476             /* If this is the the final block, then set len to reflect only valid bytes (do not include padding to 16-byte boundary) */
1477             if ((p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT) && (p_cb->ndef_attrib.ln & 0x000F))
1478             {
1479                 rsp_num_bytes_rx -= (16 - (p_cb->ndef_attrib.ln & 0x000F));
1480             }
1481 
1482             p_msg_rsp->len = rsp_num_bytes_rx;
1483             read_data.p_data = p_msg_rsp;
1484             (*(rw_cb.p_cback)) (RW_T3T_CHECK_EVT, (tRW_DATA *) &read_data);
1485 
1486             /* Send CHECK cmd for next NDEF segment, if needed */
1487             if (!(p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT))
1488             {
1489                 if ((nfc_status = rw_t3t_send_next_ndef_check_cmd (p_cb)) == NFC_STATUS_OK)
1490                 {
1491                     /* Still getting more segments. Don't send RW_T3T_CHECK_CPLT_EVT yet */
1492                     check_complete = FALSE;
1493                 }
1494             }
1495         }
1496     }
1497 
1498     /* Notify app of RW_T3T_CHECK_CPLT_EVT if entire NDEF has been read, or if failure */
1499     if (check_complete)
1500     {
1501         p_cb->rw_state = RW_T3T_STATE_IDLE;
1502         evt_data.status = nfc_status;
1503         (*(rw_cb.p_cback)) (RW_T3T_CHECK_CPLT_EVT, (tRW_DATA *) &evt_data);
1504     }
1505 }
1506 
1507 
1508 /*****************************************************************************
1509 **
1510 ** Function         rw_t3t_act_handle_update_ndef_rsp
1511 **
1512 ** Description      Handle response to NDEF write segment
1513 **
1514 ** Returns          Nothing
1515 **
1516 *****************************************************************************/
rw_t3t_act_handle_update_ndef_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1517 void rw_t3t_act_handle_update_ndef_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1518 {
1519     BOOLEAN update_complete = TRUE;
1520     tNFC_STATUS nfc_status = NFC_STATUS_OK;
1521     tRW_DATA evt_data;
1522     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1523 
1524     /* Check nfcid2 and status of response */
1525     if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
1526         ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
1527     {
1528         nfc_status = NFC_STATUS_FAILED;
1529     }
1530     /* Validate response opcode */
1531     else if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1532     {
1533         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_UPDATE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1534         nfc_status = NFC_STATUS_FAILED;
1535     }
1536     /* If this is response to final UPDATE, then update NDEF local size */
1537     else if (p_cb->flags & RW_T3T_FL_IS_FINAL_NDEF_SEGMENT)
1538     {
1539         /* If successful, update current NDEF size */
1540         p_cb->ndef_attrib.ln = p_cb->ndef_msg_len;
1541     }
1542     /*  If any more NDEF bytes to update, then send next UPDATE command */
1543     else if (p_cb->ndef_msg_bytes_sent < p_cb->ndef_msg_len)
1544     {
1545         /* Send UPDATE command for next segment of NDEF */
1546         if ((nfc_status = rw_t3t_send_next_ndef_update_cmd (p_cb)) == NFC_STATUS_OK)
1547         {
1548             /* Wait for update response */
1549             update_complete = FALSE;
1550         }
1551     }
1552     /*  Otherwise, no more NDEF bytes. Send final UPDATE for Attribute Information block */
1553     else
1554     {
1555         p_cb->flags |= RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
1556         if ((nfc_status = rw_t3t_send_update_ndef_attribute_cmd (p_cb, FALSE)) == NFC_STATUS_OK)
1557         {
1558             /* Wait for update response */
1559             update_complete = FALSE;
1560         }
1561     }
1562 
1563     /* If update is completed, then notify app */
1564     if (update_complete)
1565     {
1566         p_cb->rw_state = RW_T3T_STATE_IDLE;
1567         evt_data.status = nfc_status;
1568         (*(rw_cb.p_cback)) (RW_T3T_UPDATE_CPLT_EVT, (tRW_DATA *) &evt_data);
1569     }
1570 
1571 
1572     GKI_freebuf (p_msg_rsp);
1573 
1574     return;
1575 }
1576 
1577 
1578 /*****************************************************************************
1579 **
1580 ** Function         rw_t3t_handle_get_sc_poll_rsp
1581 **
1582 ** Description      Handle POLL response for getting system codes
1583 **
1584 ** Returns          Nothing
1585 **
1586 *****************************************************************************/
rw_t3t_handle_get_sc_poll_rsp(tRW_T3T_CB * p_cb,UINT8 nci_status,UINT8 num_responses,UINT8 sensf_res_buf_size,UINT8 * p_sensf_res_buf)1587 static void rw_t3t_handle_get_sc_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1588 {
1589     BT_HDR *p_cmd_buf;
1590     UINT8 *p, *p_cmd_start;
1591     UINT16 sc;
1592     tNFC_STATUS status = NFC_STATUS_FAILED;
1593 
1594     /* If waiting for wildcard POLL */
1595     if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_WILDCARD)
1596     {
1597         /* Get the system code from the response */
1598         if (  (nci_status == NCI_STATUS_OK)
1599             &&(num_responses > 0)
1600             &&(sensf_res_buf_size >= (RW_T3T_SENSF_RES_RD_OFFSET + RW_T3T_SENSF_RES_RD_LEN))  )
1601         {
1602             p = &p_sensf_res_buf[RW_T3T_SENSF_RES_RD_OFFSET];
1603             BE_STREAM_TO_UINT16 (sc, p);
1604 
1605             /* Handle felica lite */
1606             if (sc == T3T_SYSTEM_CODE_FELICA_LITE)
1607             {
1608                 RW_TRACE_DEBUG1 ("FeliCa Lite tag detected (system code %04X)", sc);
1609                 /* Store system code */
1610                 p_cb->system_codes[p_cb->num_system_codes++] = sc;
1611 
1612                 /* Poll for NDEF system code */
1613                 if ((status = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, 0, 0)) == NCI_STATUS_OK)
1614                 {
1615                     p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_NDEF;
1616                     p_cb->cur_poll_rc = 0;
1617                     p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
1618 
1619                     /* start timer for waiting for responses */
1620                     rw_t3t_start_poll_timer (p_cb);
1621                 }
1622             }
1623             else
1624             {
1625                 /* All other types, send REQUEST_SYSTEM_CODE command */
1626                 if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1627                 {
1628                     p_cb->rw_substate = RW_T3T_GET_SC_SST_REQUEST_SC;
1629 
1630                     /* Construct T3T message */
1631                     p_cmd_start = p = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1632                     UINT8_TO_STREAM (p, T3T_MSG_OPC_REQ_SYSTEMCODE_CMD);
1633                     ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1634 
1635                     /* Fill in length field */
1636                     p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1637 
1638                     /* Send the T3T message */
1639                     status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_GET_SYSTEM_CODES, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
1640                 }
1641             }
1642         }
1643 
1644         /* Error proceeding. Notify upper layer of system codes found so far */
1645         if (status != NFC_STATUS_OK)
1646         {
1647             rw_t3t_handle_get_system_codes_cplt ();
1648         }
1649     }
1650     /* If waiting for NDEF POLL */
1651     else if (p_cb->rw_substate == RW_T3T_GET_SC_SST_POLL_NDEF)
1652     {
1653         /* Validate response for NDEF poll */
1654         if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1655         {
1656             /* Tag responded for NDEF poll */
1657             p_cb->system_codes[p_cb->num_system_codes++] = T3T_SYSTEM_CODE_NDEF;
1658         }
1659         rw_t3t_handle_get_system_codes_cplt ();
1660     }
1661 }
1662 
1663 /*****************************************************************************
1664 **
1665 ** Function         rw_t3t_handle_ndef_detect_poll_rsp
1666 **
1667 ** Description      Handle POLL response for getting system codes
1668 **
1669 ** Returns          Nothing
1670 **
1671 *****************************************************************************/
rw_t3t_handle_ndef_detect_poll_rsp(tRW_T3T_CB * p_cb,UINT8 nci_status,UINT8 num_responses,UINT8 sensf_res_buf_size,UINT8 * p_sensf_res_buf)1672 static void rw_t3t_handle_ndef_detect_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1673 {
1674     BT_HDR *p_cmd_buf;
1675     UINT8 *p, *p_cmd_start;
1676     tRW_DATA evt_data;
1677 
1678     /* Validate response for NDEF poll */
1679     if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1680     {
1681         /* Tag responded for NDEF poll */
1682 
1683         /* Read NDEF attribute block */
1684         if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1685         {
1686             /* Construct T3T message */
1687             p = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1688 
1689             /* Add CHECK opcode to message  */
1690             UINT8_TO_STREAM (p, T3T_MSG_OPC_CHECK_CMD);
1691 
1692             /* Add IDm to message */
1693             ARRAY_TO_STREAM (p, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1694 
1695             /* Add Service code list */
1696             UINT8_TO_STREAM (p, 1);                       /* Number of services (only 1 service: NDEF) */
1697             UINT16_TO_STREAM (p, T3T_MSG_NDEF_SC_RO);     /* Service code (little-endian format) */
1698 
1699             /* Number of blocks */
1700             UINT8_TO_STREAM (p, 1);                       /* Number of blocks (only 1 block: NDEF Attribute Information ) */
1701 
1702             /* Block List element: the NDEF attribute information block (block 0) */
1703             UINT8_TO_STREAM (p, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1704             UINT8_TO_STREAM (p, 0);
1705 
1706             /* Calculate length of message */
1707             p_cmd_buf->len = (UINT16) (p - p_cmd_start);
1708 
1709             /* Send the T3T message */
1710             if ((evt_data.status = rw_t3t_send_cmd (p_cb, RW_T3T_CMD_DETECT_NDEF, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS)) == NFC_STATUS_OK)
1711             {
1712                 /* CHECK command sent. Wait for response */
1713                 return;
1714             }
1715         }
1716         nci_status = NFC_STATUS_FAILED;
1717     }
1718 
1719     /* NDEF detection failed */
1720     p_cb->rw_state = RW_T3T_STATE_IDLE;
1721     evt_data.ndef.status = nci_status;
1722     evt_data.ndef.flags  = RW_NDEF_FL_UNKNOWN;
1723     (*(rw_cb.p_cback)) (RW_T3T_NDEF_DETECT_EVT, &evt_data);
1724 }
1725 
1726 
1727 /*****************************************************************************
1728 **
1729 ** Function         rw_t3t_act_handle_get_sc_rsp
1730 **
1731 ** Description      Handle response for getting system codes
1732 **
1733 ** Returns          Nothing
1734 **
1735 *****************************************************************************/
rw_t3t_act_handle_get_sc_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1736 void rw_t3t_act_handle_get_sc_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1737 {
1738     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1739     UINT8 *p;
1740     UINT16 sc;
1741     UINT8 num_sc, i;
1742 
1743     /* Validate response opcode */
1744     if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_REQ_SYSTEMCODE_RSP)
1745     {
1746         RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_REQ_SYSTEMCODE_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1747     }
1748     else
1749     {
1750         /* Point to number of systems parameter */
1751         p = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_NUMSYS];
1752         STREAM_TO_UINT8 (num_sc, p);
1753 
1754         /* Validate maximum */
1755         if (num_sc>T3T_MAX_SYSTEM_CODES)
1756         {
1757             RW_TRACE_DEBUG2 ("Tag's number of systems (%i) exceeds NFA max (%i)", num_sc, T3T_MAX_SYSTEM_CODES);
1758             num_sc = T3T_MAX_SYSTEM_CODES;
1759         }
1760 
1761         for (i = 0; i < num_sc; i++)
1762         {
1763             BE_STREAM_TO_UINT16 (sc, p);
1764             p_cb->system_codes[p_cb->num_system_codes++] = sc;
1765         }
1766     }
1767     rw_t3t_handle_get_system_codes_cplt ();
1768 
1769     GKI_freebuf (p_msg_rsp);
1770 }
1771 
1772 /*****************************************************************************
1773 **
1774 ** Function         rw_t3t_update_block
1775 **
1776 ** Description      Send UPDATE command for single block
1777 **                  (for formatting/configuring read only)
1778 **
1779 ** Returns          tNFC_STATUS
1780 **
1781 *****************************************************************************/
rw_t3t_update_block(tRW_T3T_CB * p_cb,UINT8 block_id,UINT8 * p_block_data)1782 tNFC_STATUS rw_t3t_update_block (tRW_T3T_CB *p_cb, UINT8 block_id, UINT8 *p_block_data)
1783 {
1784     UINT8 *p_dst, *p_cmd_start;
1785     BT_HDR *p_cmd_buf;
1786     tNFC_STATUS status;
1787 
1788     if ((p_cmd_buf = rw_t3t_get_cmd_buf ()) != NULL)
1789     {
1790         p_dst = p_cmd_start = (UINT8 *) (p_cmd_buf+1) + p_cmd_buf->offset;
1791 
1792         /* Add UPDATE opcode to message  */
1793         UINT8_TO_STREAM (p_dst, T3T_MSG_OPC_UPDATE_CMD);
1794 
1795         /* Add IDm to message */
1796         ARRAY_TO_STREAM (p_dst, p_cb->peer_nfcid2, NCI_NFCID2_LEN);
1797 
1798         /* Add Service code list */
1799         UINT8_TO_STREAM (p_dst, 1);                      /* Number of services (only 1 service: NDEF) */
1800         UINT16_TO_STREAM (p_dst, T3T_MSG_NDEF_SC_RW);    /* Service code (little-endian format) */
1801 
1802         /* Number of blocks */
1803         UINT8_TO_STREAM (p_dst, 1);
1804 
1805         /* Add Block list element for MC */
1806         UINT8_TO_STREAM (p_dst, T3T_MSG_MASK_TWO_BYTE_BLOCK_DESC_FORMAT);
1807         UINT8_TO_STREAM (p_dst, block_id);
1808 
1809         /* Copy MC data to UPDATE message */
1810         ARRAY_TO_STREAM (p_dst, p_block_data, T3T_MSG_BLOCKSIZE);
1811 
1812         /* Calculate length of message */
1813         p_cmd_buf->len = (UINT16) (p_dst - p_cmd_start);
1814 
1815         /* Send the T3T message */
1816         status = rw_t3t_send_cmd (p_cb, p_cb->cur_cmd, p_cmd_buf, RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS);
1817     }
1818     else
1819     {
1820         /* Unable to send UPDATE command */
1821         status = NFC_STATUS_NO_BUFFERS;
1822     }
1823 
1824     return (status);
1825 }
1826 
1827 /*****************************************************************************
1828 **
1829 ** Function         rw_t3t_handle_fmt_poll_rsp
1830 **
1831 ** Description      Handle POLL response for formatting felica-lite
1832 **
1833 ** Returns          Nothing
1834 **
1835 *****************************************************************************/
rw_t3t_handle_fmt_poll_rsp(tRW_T3T_CB * p_cb,UINT8 nci_status,UINT8 num_responses,UINT8 sensf_res_buf_size,UINT8 * p_sensf_res_buf)1836 static void rw_t3t_handle_fmt_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1837 {
1838     tRW_DATA evt_data;
1839 
1840     evt_data.status = NFC_STATUS_OK;
1841 
1842     /* Validate response for poll response */
1843     if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1844     {
1845         /* Tag responded for Felica-Lite poll */
1846         /* Get MemoryControl block */
1847         RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
1848 
1849         p_cb->rw_substate = RW_T3T_FMT_SST_CHECK_MC_BLK;
1850 
1851         /* Send command to check Memory Configuration block */
1852         evt_data.status = rw_t3t_check_mc_block (p_cb);
1853     }
1854     else
1855     {
1856         RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
1857         evt_data.status = NFC_STATUS_FAILED;
1858     }
1859 
1860     /* If error, notify upper layer */
1861     if (evt_data.status != NFC_STATUS_OK)
1862     {
1863         rw_t3t_format_cplt (evt_data.status);
1864     }
1865 }
1866 
1867 /*****************************************************************************
1868 **
1869 ** Function         rw_t3t_act_handle_fmt_rsp
1870 **
1871 ** Description      Handle response for formatting codes
1872 **
1873 ** Returns          Nothing
1874 **
1875 *****************************************************************************/
rw_t3t_act_handle_fmt_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)1876 void rw_t3t_act_handle_fmt_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
1877 {
1878     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
1879     UINT8 *p_mc;
1880     tRW_DATA evt_data;
1881 
1882     evt_data.status = NFC_STATUS_OK;
1883 
1884     /* Check tags's response for reading MemoryControl block */
1885     if (p_cb->rw_substate == RW_T3T_FMT_SST_CHECK_MC_BLK)
1886     {
1887         /* Validate response opcode */
1888         if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
1889         {
1890             RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
1891             evt_data.status = NFC_STATUS_FAILED;
1892         }
1893         /* Validate status code and NFCID2 response from tag */
1894         else if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
1895                  ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
1896         {
1897             evt_data.status = NFC_STATUS_FAILED;
1898         }
1899         else
1900         {
1901             /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
1902             p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];  /* Point to MC data of CHECK response */
1903 
1904             if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
1905             {
1906                 /* Tag is not currently enabled for NDEF. Indicate that we need to update the MC block */
1907 
1908                 /* Set SYS_OP field to 0x01 (enable NDEF) */
1909                 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] = 0x01;
1910 
1911                 /* Set RF_PRM field to 0x07 (procedure of issuance) */
1912                 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
1913 
1914                 /* Construct and send UPDATE message to write MC block */
1915                 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_MC_BLK;
1916                 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
1917             }
1918             else
1919             {
1920                 /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1921                 p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1922                 evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
1923             }
1924         }
1925 
1926         /* If error, notify upper layer */
1927         if (evt_data.status != NFC_STATUS_OK)
1928         {
1929             rw_t3t_format_cplt (evt_data.status);
1930         }
1931     }
1932     else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_MC_BLK)
1933     {
1934         /* Validate response opcode */
1935         if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1936             ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
1937 
1938         {
1939             RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
1940             evt_data.status = NFC_STATUS_FAILED;
1941         }
1942         else
1943         {
1944             /* SYS_OP=1: ndef already enabled. Just need to update attribute information block */
1945             p_cb->rw_substate = RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB;
1946             evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_default_attrib_info);
1947         }
1948 
1949         /* If error, notify upper layer */
1950         if (evt_data.status != NFC_STATUS_OK)
1951         {
1952             rw_t3t_format_cplt (evt_data.status);
1953         }
1954     }
1955     else if (p_cb->rw_substate == RW_T3T_FMT_SST_UPDATE_NDEF_ATTRIB)
1956     {
1957         /* Validate response opcode */
1958         if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
1959             ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
1960 
1961         {
1962             RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
1963             evt_data.status = NFC_STATUS_FAILED;
1964         }
1965 
1966 
1967         rw_t3t_format_cplt (evt_data.status);
1968     }
1969 
1970     GKI_freebuf (p_msg_rsp);
1971 }
1972 
1973 /*****************************************************************************
1974 **
1975 ** Function         rw_t3t_handle_sro_poll_rsp
1976 **
1977 ** Description      Handle POLL response for configuring felica-lite read only
1978 **
1979 ** Returns          Nothing
1980 **
1981 *****************************************************************************/
rw_t3t_handle_sro_poll_rsp(tRW_T3T_CB * p_cb,UINT8 nci_status,UINT8 num_responses,UINT8 sensf_res_buf_size,UINT8 * p_sensf_res_buf)1982 static void rw_t3t_handle_sro_poll_rsp (tRW_T3T_CB *p_cb, UINT8 nci_status, UINT8 num_responses, UINT8 sensf_res_buf_size, UINT8 *p_sensf_res_buf)
1983 {
1984     tRW_DATA evt_data;
1985     UINT8 rw_t3t_ndef_attrib_info[T3T_MSG_BLOCKSIZE];
1986     UINT8 *p;
1987     UINT8 tempU8;
1988     UINT16 checksum, i;
1989     UINT32 tempU32 = 0;
1990 
1991     evt_data.status = NFC_STATUS_OK;
1992 
1993     /* Validate response for poll response */
1994     if ((nci_status == NCI_STATUS_OK) && (num_responses > 0))
1995     {
1996         /* Tag responded for Felica-Lite poll */
1997         if (p_cb->ndef_attrib.rwflag != T3T_MSG_NDEF_RWFLAG_RO)
1998         {
1999             /* First update attribute information block */
2000             RW_TRACE_DEBUG0 ("Felica-Lite tag detected...update NDef attribution block.");
2001 
2002             p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB;
2003 
2004             p = rw_t3t_ndef_attrib_info;
2005 
2006             UINT8_TO_STREAM (p, p_cb->ndef_attrib.version);
2007 
2008             /* Update NDEF info */
2009             UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbr);              /* NBr: number of blocks that can be read using one Check command */
2010             UINT8_TO_STREAM (p, p_cb->ndef_attrib.nbw);              /* Nbw: number of blocks that can be written using one Update command */
2011             UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.nmaxb);        /* Nmaxb: maximum number of blocks available for NDEF data */
2012             UINT32_TO_BE_STREAM (p, tempU32);
2013             UINT8_TO_STREAM (p, p_cb->ndef_attrib.writef);           /* WriteFlag: 00h if writing data finished; 0Fh if writing data in progress */
2014             UINT8_TO_STREAM (p, 0x00);                               /* RWFlag: 00h NDEF is read-only */
2015 
2016             tempU8 = (UINT8) (p_cb->ndef_attrib.ln >> 16);
2017             /* Get length (3-byte, big-endian) */
2018             UINT8_TO_STREAM (p, tempU8);                               /* Ln: high-byte */
2019             UINT16_TO_BE_STREAM (p, p_cb->ndef_attrib.ln);           /* Ln: lo-word */
2020 
2021             /* Calculate and append Checksum */
2022             checksum = 0;
2023             for (i = 0; i < T3T_MSG_NDEF_ATTR_INFO_SIZE; i++)
2024             {
2025                 checksum+=rw_t3t_ndef_attrib_info[i];
2026             }
2027             UINT16_TO_BE_STREAM (p, checksum);
2028 
2029             evt_data.status = rw_t3t_update_block (p_cb, 0, (UINT8 *) rw_t3t_ndef_attrib_info);
2030         }
2031         else if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2032         {
2033             /* NDEF is already read only, Read and update MemoryControl block */
2034             RW_TRACE_DEBUG0 ("Felica-Lite tag detected...getting Memory Control block.");
2035             p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2036 
2037             /* Send command to check Memory Configuration block */
2038             evt_data.status = rw_t3t_check_mc_block (p_cb);
2039         }
2040     }
2041     else
2042     {
2043         RW_TRACE_ERROR0 ("Felica-Lite tag not detected");
2044         evt_data.status = NFC_STATUS_FAILED;
2045     }
2046 
2047     /* If error, notify upper layer */
2048     if (evt_data.status != NFC_STATUS_OK)
2049     {
2050         rw_t3t_set_readonly_cplt (evt_data.status);
2051     }
2052 }
2053 
2054 /*****************************************************************************
2055 **
2056 ** Function         rw_t3t_act_handle_sro_rsp
2057 **
2058 ** Description      Handle response for setting read only codes
2059 **
2060 ** Returns          Nothing
2061 **
2062 *****************************************************************************/
rw_t3t_act_handle_sro_rsp(tRW_T3T_CB * p_cb,BT_HDR * p_msg_rsp)2063 void rw_t3t_act_handle_sro_rsp (tRW_T3T_CB *p_cb, BT_HDR *p_msg_rsp)
2064 {
2065     UINT8 *p_t3t_rsp = (UINT8 *) (p_msg_rsp+1) + p_msg_rsp->offset;
2066     UINT8 *p_mc;
2067     tRW_DATA evt_data;
2068 
2069     evt_data.status = NFC_STATUS_OK;
2070 
2071     if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_NDEF_ATTRIB)
2072     {
2073         /* Validate response opcode */
2074         if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2075             ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
2076 
2077         {
2078             RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
2079             evt_data.status = NFC_STATUS_FAILED;
2080         }
2081         else
2082         {
2083             p_cb->ndef_attrib.rwflag = T3T_MSG_NDEF_RWFLAG_RO;
2084             if (p_cb->cur_cmd == RW_T3T_CMD_SET_READ_ONLY_HARD)
2085             {
2086                 p_cb->rw_substate = RW_T3T_SRO_SST_CHECK_MC_BLK;
2087 
2088                 /* Send command to check Memory Configuration block */
2089                 evt_data.status = rw_t3t_check_mc_block (p_cb);
2090             }
2091             else
2092             {
2093                 rw_t3t_set_readonly_cplt (evt_data.status);
2094             }
2095         }
2096     }
2097     else if (p_cb->rw_substate == RW_T3T_SRO_SST_CHECK_MC_BLK)
2098     {
2099         /* Check tags's response for reading MemoryControl block, Validate response opcode */
2100         if (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_CHECK_RSP)
2101         {
2102             RW_TRACE_ERROR2 ("Response error: expecting rsp_code %02X, but got %02X", T3T_MSG_OPC_CHECK_RSP, p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE]);
2103             evt_data.status = NFC_STATUS_FAILED;
2104         }
2105         /* Validate status code and NFCID2 response from tag */
2106         else if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)                           /* verify response status code */
2107                  ||(memcmp (p_cb->peer_nfcid2, &p_t3t_rsp[T3T_MSG_RSP_OFFSET_IDM], NCI_NFCID2_LEN) != 0)  )   /* verify response IDm */
2108         {
2109             evt_data.status = NFC_STATUS_FAILED;
2110         }
2111         else
2112         {
2113             /* Check if memory configuration (MC) block to see if SYS_OP=1 (NDEF enabled) */
2114             p_mc = &p_t3t_rsp[T3T_MSG_RSP_OFFSET_CHECK_DATA];  /* Point to MC data of CHECK response */
2115 
2116             if (p_mc[T3T_MSG_FELICALITE_MC_OFFSET_SYS_OP] != 0x01)
2117             {
2118                 /* Tag is not currently enabled for NDEF */
2119                 evt_data.status = NFC_STATUS_FAILED;
2120             }
2121             else
2122             {
2123                 /* Set MC_SP field with MC[0] = 0x00 & MC[1] = 0xC0 (Hardlock) to change access permission from RW to RO */
2124                 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP]     = 0x00;
2125                 /* Not changing the access permission of Subtraction Register and MC[0:1] */
2126                 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_MC_SP + 1] = 0xC0;
2127 
2128                /* Set RF_PRM field to 0x07 (procedure of issuance) */
2129                 p_mc[T3T_MSG_FELICALITE_MC_OFFSET_RF_PRM] = 0x07;
2130 
2131                 /* Construct and send UPDATE message to write MC block */
2132                 p_cb->rw_substate = RW_T3T_SRO_SST_UPDATE_MC_BLK;
2133                 evt_data.status = rw_t3t_update_block (p_cb, T3T_MSG_FELICALITE_BLOCK_ID_MC, p_mc);
2134             }
2135         }
2136     }
2137     else if (p_cb->rw_substate == RW_T3T_SRO_SST_UPDATE_MC_BLK)
2138     {
2139         /* Validate response opcode */
2140         if (  (p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE] != T3T_MSG_OPC_UPDATE_RSP)
2141             ||(p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1] != T3T_MSG_RSP_STATUS_OK)  )
2142 
2143         {
2144             RW_TRACE_ERROR2 ("Response error: rsp_code=%02X, status=%02X", p_t3t_rsp[T3T_MSG_RSP_OFFSET_RSPCODE], p_t3t_rsp[T3T_MSG_RSP_OFFSET_STATUS1]);
2145             evt_data.status = NFC_STATUS_FAILED;
2146         }
2147         else
2148         {
2149             rw_t3t_set_readonly_cplt (evt_data.status);
2150         }
2151     }
2152 
2153     /* If error, notify upper layer */
2154     if (evt_data.status != NFC_STATUS_OK)
2155     {
2156         rw_t3t_set_readonly_cplt (evt_data.status);
2157     }
2158 
2159     GKI_freebuf (p_msg_rsp);
2160 }
2161 
2162 /*******************************************************************************
2163 **
2164 ** Function         rw_t3t_data_cback
2165 **
2166 ** Description      This callback function receives the data from NFCC.
2167 **
2168 ** Returns          none
2169 **
2170 *******************************************************************************/
rw_t3t_data_cback(UINT8 conn_id,BT_HDR * p_msg)2171 void rw_t3t_data_cback (UINT8 conn_id, BT_HDR *p_msg)
2172 {
2173     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2174     BOOLEAN free_msg = FALSE;           /* if TRUE, free msg buffer before returning */
2175     UINT8 *p, sod;
2176 
2177     /* Stop rsponse timer */
2178     nfc_stop_quick_timer (&p_cb->timer);
2179 
2180 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2181     /* Update rx stats */
2182     rw_main_update_rx_stats (p_msg->len);
2183 #endif  /* RW_STATS_INCLUDED */
2184 
2185     /* Check if we are expecting a response */
2186     if (p_cb->rw_state != RW_T3T_STATE_COMMAND_PENDING)
2187     {
2188         /*
2189         **  This must be raw frame response
2190         **  send raw frame to app with SoD
2191         */
2192         rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg);
2193     }
2194     /* Sanity check: verify msg len is big enough to contain t3t header */
2195     else if (p_msg->len < T3T_MSG_RSP_COMMON_HDR_LEN)
2196     {
2197         RW_TRACE_ERROR1 ("T3T: invalid Type3 Tag Message (invalid len: %i)", p_msg->len);
2198         free_msg = TRUE;
2199 
2200         rw_t3t_process_frame_error ();
2201     }
2202     else
2203     {
2204         /* Check for RF frame error */
2205         p = (UINT8 *) (p_msg+1) + p_msg->offset;
2206         sod = p[0];
2207         if (p[sod] != NCI_STATUS_OK)
2208         {
2209             RW_TRACE_ERROR1 ("T3T: rf frame error (crc status=%i)", p[sod]);
2210             GKI_freebuf (p_msg);
2211 
2212             rw_t3t_process_frame_error ();
2213             return;
2214         }
2215 
2216 #if (BT_TRACE_PROTOCOL == TRUE)
2217         DispT3TagMessage (p_msg, TRUE);
2218 #endif
2219 
2220         /* Skip over SoD */
2221         p_msg->offset++;
2222         p_msg->len--;
2223 
2224         /* Get response code */
2225         switch (p_cb->cur_cmd)
2226         {
2227             case RW_T3T_CMD_DETECT_NDEF:
2228                 rw_t3t_act_handle_ndef_detect_rsp (p_cb, p_msg);
2229                 break;
2230 
2231             case RW_T3T_CMD_CHECK_NDEF:
2232                 rw_t3t_act_handle_check_ndef_rsp (p_cb, p_msg);
2233                 break;
2234 
2235             case RW_T3T_CMD_UPDATE_NDEF:
2236                 rw_t3t_act_handle_update_ndef_rsp (p_cb, p_msg);
2237                 break;
2238 
2239             case RW_T3T_CMD_CHECK:
2240                 rw_t3t_act_handle_check_rsp (p_cb, p_msg);
2241                 break;
2242 
2243             case RW_T3T_CMD_UPDATE:
2244                 rw_t3t_act_handle_update_rsp (p_cb, p_msg);
2245                 break;
2246 
2247             case RW_T3T_CMD_SEND_RAW_FRAME:
2248                 rw_t3t_act_handle_raw_senddata_rsp (p_cb, p_msg);
2249                 break;
2250 
2251             case RW_T3T_CMD_GET_SYSTEM_CODES:
2252                 rw_t3t_act_handle_get_sc_rsp (p_cb, p_msg);
2253                 break;
2254 
2255             case RW_T3T_CMD_FORMAT:
2256                 rw_t3t_act_handle_fmt_rsp (p_cb, p_msg);
2257                 break;
2258 
2259             case RW_T3T_CMD_SET_READ_ONLY_SOFT:
2260             case RW_T3T_CMD_SET_READ_ONLY_HARD:
2261                 rw_t3t_act_handle_sro_rsp (p_cb, p_msg);
2262                 break;
2263 
2264             default:
2265                 GKI_freebuf (p_msg);
2266                 break;
2267         }
2268     }
2269 
2270     if (free_msg)
2271     {
2272         GKI_freebuf (p_msg);
2273     }
2274 }
2275 
2276 
2277 /*******************************************************************************
2278 **
2279 ** Function         rw_t3t_conn_cback
2280 **
2281 ** Description      This callback function receives the events/data from NFCC.
2282 **
2283 ** Returns          none
2284 **
2285 *******************************************************************************/
rw_t3t_conn_cback(UINT8 conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)2286 void rw_t3t_conn_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
2287 {
2288     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2289     RW_TRACE_DEBUG2 ("rw_t3t_conn_cback: conn_id=%i, evt=0x%02x", conn_id, event);
2290 
2291     /* Only handle NFC_RF_CONN_ID conn_id */
2292     if (conn_id != NFC_RF_CONN_ID)
2293     {
2294         return;
2295     }
2296 
2297     switch (event)
2298     {
2299     case NFC_DEACTIVATE_CEVT:
2300         rw_t3t_unselect (NULL);
2301         break;
2302 
2303     case NFC_DATA_CEVT:     /* check for status in tNFC_CONN */
2304         if (p_data->data.status == NFC_STATUS_OK)
2305         {
2306             rw_t3t_data_cback (conn_id, p_data->data.p_data);
2307             break;
2308         }
2309         /* Data event with error status...fall through to NFC_ERROR_CEVT case */
2310 
2311 
2312     case NFC_ERROR_CEVT:
2313         nfc_stop_quick_timer (&p_cb->timer);
2314 
2315 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2316         rw_main_update_trans_error_stats ();
2317 #endif  /* RW_STATS_INCLUDED */
2318 
2319         if (event == NFC_ERROR_CEVT)
2320             rw_t3t_process_error (NFC_STATUS_TIMEOUT);
2321         else
2322             rw_t3t_process_error (p_data->status);
2323         break;
2324 
2325     default:
2326         break;
2327 
2328     }
2329 }
2330 
2331 
2332 /*******************************************************************************
2333 **
2334 ** Function         rw_t3t_select
2335 **
2336 ** Description      Called by NFC manager when a Type3 tag has been activated
2337 **
2338 ** Returns          NFC_STATUS_OK
2339 **
2340 *******************************************************************************/
rw_t3t_select(UINT8 peer_nfcid2[NCI_RF_F_UID_LEN],UINT8 mrti_check,UINT8 mrti_update)2341 tNFC_STATUS rw_t3t_select (UINT8 peer_nfcid2[NCI_RF_F_UID_LEN], UINT8 mrti_check, UINT8 mrti_update)
2342 {
2343     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2344 
2345     RW_TRACE_API0 ("rw_t3t_select");
2346 
2347     memcpy (p_cb->peer_nfcid2, peer_nfcid2, NCI_NFCID2_LEN); /* Store tag's NFCID2 */
2348     p_cb->ndef_attrib.status = NFC_STATUS_NOT_INITIALIZED;  /* Indicate that NDEF detection has not been performed yet */
2349     p_cb->rw_state = RW_T3T_STATE_IDLE;
2350     p_cb->flags = 0;
2351 
2352     /* Alloc cmd buf for retransmissions */
2353     if (p_cb->p_cur_cmd_buf ==  NULL)
2354     {
2355         if ((p_cb->p_cur_cmd_buf = (BT_HDR *) GKI_getpoolbuf (NFC_RW_POOL_ID)) == NULL)
2356         {
2357             RW_TRACE_ERROR0 ("rw_t3t_select: unable to allocate buffer for retransmission");
2358             p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2359             return (NFC_STATUS_FAILED);
2360         }
2361     }
2362 
2363 
2364     NFC_SetStaticRfCback (rw_t3t_conn_cback);
2365 
2366     return NFC_STATUS_OK;
2367 }
2368 
2369 
2370 /*******************************************************************************
2371 **
2372 ** Function         rw_t3t_unselect
2373 **
2374 ** Description      Called by NFC manager when a Type3 tag has been de-activated
2375 **
2376 ** Returns          NFC_STATUS_OK
2377 **
2378 *******************************************************************************/
rw_t3t_unselect(UINT8 peer_nfcid2[])2379 static tNFC_STATUS rw_t3t_unselect (UINT8 peer_nfcid2[])
2380 {
2381     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2382 
2383 #if (defined (RW_STATS_INCLUDED) && (RW_STATS_INCLUDED == TRUE))
2384     /* Display stats */
2385     rw_main_log_stats ();
2386 #endif  /* RW_STATS_INCLUDED */
2387 
2388     /* Stop t3t timer (if started) */
2389     nfc_stop_quick_timer (&p_cb->timer);
2390 
2391     /* Free cmd buf for retransmissions */
2392     if (p_cb->p_cur_cmd_buf)
2393     {
2394         GKI_freebuf (p_cb->p_cur_cmd_buf);
2395         p_cb->p_cur_cmd_buf = NULL;
2396     }
2397 
2398     p_cb->rw_state = RW_T3T_STATE_NOT_ACTIVATED;
2399     NFC_SetStaticRfCback (NULL);
2400 
2401     return NFC_STATUS_OK;
2402 }
2403 
2404 
2405 #if (BT_TRACE_VERBOSE == TRUE)
2406 /*******************************************************************************
2407 **
2408 ** Function         rw_t3t_cmd_str
2409 **
2410 ** Description      Converts cmd_id to command string for logging
2411 **
2412 ** Returns          command string
2413 **
2414 *******************************************************************************/
rw_t3t_cmd_str(UINT8 cmd_id)2415 static char *rw_t3t_cmd_str (UINT8 cmd_id)
2416 {
2417     switch (cmd_id)
2418     {
2419     case RW_T3T_CMD_DETECT_NDEF:
2420         return "RW_T3T_CMD_DETECT_NDEF";
2421 
2422     case RW_T3T_CMD_CHECK_NDEF:
2423         return "RW_T3T_CMD_CHECK_NDEF";
2424 
2425     case RW_T3T_CMD_UPDATE_NDEF:
2426         return "RW_T3T_CMD_UPDATE_NDEF";
2427 
2428     case RW_T3T_CMD_CHECK:
2429         return "RW_T3T_CMD_CHECK";
2430 
2431     case RW_T3T_CMD_UPDATE:
2432         return "RW_T3T_CMD_UPDATE";
2433 
2434     case RW_T3T_CMD_SEND_RAW_FRAME:
2435         return "RW_T3T_CMD_SEND_RAW_FRAME";
2436 
2437     case RW_T3T_CMD_GET_SYSTEM_CODES:
2438         return "RW_T3T_CMD_GET_SYSTEM_CODES";
2439 
2440     default:
2441         return "Unknown";
2442     }
2443 }
2444 
2445 
2446 /*******************************************************************************
2447 **
2448 ** Function         rw_t3t_state_str
2449 **
2450 ** Description      Converts state_id to command string for logging
2451 **
2452 ** Returns          command string
2453 **
2454 *******************************************************************************/
rw_t3t_state_str(UINT8 state_id)2455 static char *rw_t3t_state_str (UINT8 state_id)
2456 {
2457     switch (state_id)
2458     {
2459     case RW_T3T_STATE_NOT_ACTIVATED:
2460         return "RW_T3T_STATE_NOT_ACTIVATED";
2461 
2462     case RW_T3T_STATE_IDLE:
2463         return "RW_T3T_STATE_IDLE";
2464 
2465     case RW_T3T_STATE_COMMAND_PENDING:
2466         return "RW_T3T_STATE_COMMAND_PENDING";
2467 
2468     default:
2469         return "Unknown";
2470     }
2471 }
2472 #endif
2473 
2474 /*****************************************************************************
2475 **  Type3 Tag API Functions
2476 *****************************************************************************/
2477 
2478 
2479 /*****************************************************************************
2480 **
2481 ** Function         RW_T3tDetectNDef
2482 **
2483 ** Description
2484 **      This function is used to perform NDEF detection on a Type 3 tag, and
2485 **      retrieve the tag's NDEF attribute information (block 0).
2486 **
2487 **      Before using this API, the application must call RW_SelectTagType to
2488 **      indicate that a Type 3 tag has been activated, and to provide the
2489 **      tag's Manufacture ID (IDm) .
2490 **
2491 ** Returns
2492 **      NFC_STATUS_OK: ndef detection procedure started
2493 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2494 **      NFC_STATUS_FAILED: other error
2495 **
2496 *****************************************************************************/
RW_T3tDetectNDef(void)2497 tNFC_STATUS RW_T3tDetectNDef (void)
2498 {
2499     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2500     tNFC_STATUS retval = NFC_STATUS_OK;
2501 
2502     RW_TRACE_API0 ("RW_T3tDetectNDef");
2503 
2504     /* Check if we are in valid state to handle this API */
2505     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2506     {
2507         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2508         return (NFC_STATUS_FAILED);
2509     }
2510 
2511     if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_NDEF, 0, 0)) == NCI_STATUS_OK)
2512     {
2513         p_cb->cur_cmd = RW_T3T_CMD_DETECT_NDEF;
2514         p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2515         p_cb->cur_poll_rc = 0;
2516         p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2517         p_cb->flags |= RW_T3T_FL_W4_NDEF_DETECT_POLL_RSP;
2518 
2519         /* start timer for waiting for responses */
2520         rw_t3t_start_poll_timer (p_cb);
2521     }
2522 
2523     return (retval);
2524 }
2525 
2526 
2527 /*****************************************************************************
2528 **
2529 ** Function         RW_T3tCheckNDef
2530 **
2531 ** Description
2532 **      Retrieve NDEF contents from a Type3 tag.
2533 **
2534 **      The RW_T3T_CHECK_EVT event is used to notify the application for each
2535 **      segment of NDEF data received. The RW_T3T_CHECK_CPLT_EVT event is used to
2536 **      notify the application all segments have been received.
2537 **
2538 **      Before using this API, the RW_T3tDetectNDef function must be called to
2539 **      verify that the tag contains NDEF data, and to retrieve the NDEF
2540 **      attributes.
2541 **
2542 **      Internally, this command will be separated into multiple Tag 3 Check
2543 **      commands (if necessary) - depending on the tag's Nbr (max number of
2544 **      blocks per read) attribute.
2545 **
2546 ** Returns
2547 **      NFC_STATUS_OK: check command started
2548 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2549 **      NFC_STATUS_FAILED: other error
2550 **
2551 *****************************************************************************/
RW_T3tCheckNDef(void)2552 tNFC_STATUS RW_T3tCheckNDef (void)
2553 {
2554     tNFC_STATUS retval = NFC_STATUS_OK;
2555     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2556 
2557     RW_TRACE_API0 ("RW_T3tCheckNDef");
2558 
2559     /* Check if we are in valid state to handle this API */
2560     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2561     {
2562         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2563         return (NFC_STATUS_FAILED);
2564     }
2565     else if (p_cb->ndef_attrib.status != NFC_STATUS_OK)       /* NDEF detection not performed yet? */
2566     {
2567         RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2568         return (NFC_STATUS_NOT_INITIALIZED);
2569     }
2570     else if (p_cb->ndef_attrib.ln == 0)
2571     {
2572         RW_TRACE_ERROR0 ("Type 3 tag contains empty NDEF message");
2573         return (NFC_STATUS_FAILED);
2574     }
2575 
2576     /* Check number of blocks needed for this update */
2577     p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2578     p_cb->ndef_rx_offset = 0;
2579     retval = rw_t3t_send_next_ndef_check_cmd (p_cb);
2580 
2581     return (retval);
2582 }
2583 
2584 /*****************************************************************************
2585 **
2586 ** Function         RW_T3tUpdateNDef
2587 **
2588 ** Description
2589 **      Write NDEF contents to a Type3 tag.
2590 **
2591 **      The RW_T3T_UPDATE_CPLT_EVT callback event will be used to notify the
2592 **      application of the response.
2593 **
2594 **      Before using this API, the RW_T3tDetectNDef function must be called to
2595 **      verify that the tag contains NDEF data, and to retrieve the NDEF
2596 **      attributes.
2597 **
2598 **      Internally, this command will be separated into multiple Tag 3 Update
2599 **      commands (if necessary) - depending on the tag's Nbw (max number of
2600 **      blocks per write) attribute.
2601 **
2602 ** Returns
2603 **      NFC_STATUS_OK: check command started
2604 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2605 **      NFC_STATUS_REFUSED: tag is read-only
2606 **      NFC_STATUS_BUFFER_FULL: len exceeds tag's maximum size
2607 **      NFC_STATUS_FAILED: other error
2608 **
2609 *****************************************************************************/
RW_T3tUpdateNDef(UINT32 len,UINT8 * p_data)2610 tNFC_STATUS RW_T3tUpdateNDef (UINT32 len, UINT8 *p_data)
2611 {
2612     tNFC_STATUS retval = NFC_STATUS_OK;
2613     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2614 
2615     RW_TRACE_API1 ("RW_T3tUpdateNDef (len=%i)", len);
2616 
2617     /* Check if we are in valid state to handle this API */
2618     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2619     {
2620         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2621         return (NFC_STATUS_FAILED);
2622     }
2623     else if (p_cb->ndef_attrib.status != NFC_STATUS_OK)       /* NDEF detection not performed yet? */
2624     {
2625         RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
2626         return (NFC_STATUS_NOT_INITIALIZED);
2627     }
2628     else if (len > (((UINT32)p_cb->ndef_attrib.nmaxb) * 16))                /* Len exceed's tag's NDEF memory? */
2629     {
2630         return (NFC_STATUS_BUFFER_FULL);
2631     }
2632     else if (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO)/* Tag's NDEF memory is read-only? */
2633     {
2634         return (NFC_STATUS_REFUSED);
2635     }
2636 
2637     /* Check number of blocks needed for this update */
2638     p_cb->flags &= ~RW_T3T_FL_IS_FINAL_NDEF_SEGMENT;
2639     p_cb->ndef_msg_bytes_sent = 0;
2640     p_cb->ndef_msg_len = len;
2641     p_cb->ndef_msg = p_data;
2642 
2643     /* Send initial UPDATE command for NDEF Attribute Info */
2644     retval = rw_t3t_send_update_ndef_attribute_cmd (p_cb, TRUE);
2645 
2646     return (retval);
2647 }
2648 
2649 /*****************************************************************************
2650 **
2651 ** Function         RW_T3tCheck
2652 **
2653 ** Description
2654 **      Read (non-NDEF) contents from a Type3 tag.
2655 **
2656 **      The RW_READ_EVT event is used to notify the application for each
2657 **      segment of NDEF data received. The RW_READ_CPLT_EVT event is used to
2658 **      notify the application all segments have been received.
2659 **
2660 **      Before using this API, the application must call RW_SelectTagType to
2661 **      indicate that a Type 3 tag has been activated, and to provide the
2662 **      tag's Manufacture ID (IDm) .
2663 **
2664 ** Returns
2665 **      NFC_STATUS_OK: check command started
2666 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2667 **      NFC_STATUS_FAILED: other error
2668 **
2669 *****************************************************************************/
RW_T3tCheck(UINT8 num_blocks,tT3T_BLOCK_DESC * t3t_blocks)2670 tNFC_STATUS RW_T3tCheck (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks)
2671 {
2672     tNFC_STATUS retval = NFC_STATUS_OK;
2673     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2674 
2675     RW_TRACE_API1 ("RW_T3tCheck (num_blocks = %i)", num_blocks);
2676 
2677     /* Check if we are in valid state to handle this API */
2678     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2679     {
2680         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2681         return (NFC_STATUS_FAILED);
2682     }
2683 
2684     /* Send the CHECK command */
2685     retval = rw_t3t_send_check_cmd (p_cb, num_blocks, t3t_blocks);
2686 
2687     return (retval);
2688 }
2689 
2690 /*****************************************************************************
2691 **
2692 ** Function         RW_T3tUpdate
2693 **
2694 ** Description
2695 **      Write (non-NDEF) contents to a Type3 tag.
2696 **
2697 **      The RW_WRITE_CPLT_EVT event is used to notify the application all
2698 **      segments have been received.
2699 **
2700 **      Before using this API, the application must call RW_SelectTagType to
2701 **      indicate that a Type 3 tag has been activated, and to provide the tag's
2702 **      Manufacture ID (IDm) .
2703 **
2704 ** Returns
2705 **      NFC_STATUS_OK: check command started
2706 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2707 **      NFC_STATUS_FAILED: other error
2708 **
2709 *****************************************************************************/
RW_T3tUpdate(UINT8 num_blocks,tT3T_BLOCK_DESC * t3t_blocks,UINT8 * p_data)2710 tNFC_STATUS RW_T3tUpdate (UINT8 num_blocks, tT3T_BLOCK_DESC *t3t_blocks, UINT8 *p_data)
2711 {
2712     tNFC_STATUS retval = NFC_STATUS_OK;
2713     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2714 
2715     RW_TRACE_API1 ("RW_T3tUpdate (num_blocks = %i)", num_blocks);
2716 
2717     /* Check if we are in valid state to handle this API */
2718     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2719     {
2720         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2721         return (NFC_STATUS_FAILED);
2722     }
2723 
2724     /* Send the UPDATE command */
2725     retval = rw_t3t_send_update_cmd (p_cb, num_blocks, t3t_blocks, p_data);
2726 
2727     return (retval);
2728 }
2729 
2730 /*****************************************************************************
2731 **
2732 ** Function         RW_T3tPresenceCheck
2733 **
2734 ** Description
2735 **      Check if the tag is still in the field.
2736 **
2737 **      The RW_T3T_PRESENCE_CHECK_EVT w/ status is used to indicate presence
2738 **      or non-presence.
2739 **
2740 ** Returns
2741 **      NFC_STATUS_OK, if raw data frame sent
2742 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2743 **      NFC_STATUS_FAILED: other error
2744 **
2745 *****************************************************************************/
RW_T3tPresenceCheck(void)2746 tNFC_STATUS RW_T3tPresenceCheck (void)
2747 {
2748     tNFC_STATUS retval = NFC_STATUS_OK;
2749     tRW_DATA evt_data;
2750     tRW_CB *p_rw_cb = &rw_cb;
2751 
2752     RW_TRACE_API0 ("RW_T3tPresenceCheck");
2753 
2754     /* If RW_SelectTagType was not called (no conn_callback) return failure */
2755     if (!(p_rw_cb->p_cback))
2756     {
2757         retval = NFC_STATUS_FAILED;
2758     }
2759     /* If we are not activated, then RW_T3T_PRESENCE_CHECK_EVT status=FAIL */
2760     else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_NOT_ACTIVATED)
2761     {
2762         evt_data.status = NFC_STATUS_FAILED;
2763         (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2764     }
2765     /* If command is pending */
2766     else if (p_rw_cb->tcb.t3t.rw_state == RW_T3T_STATE_COMMAND_PENDING)
2767     {
2768         /* If already performing presence check, return error */
2769         if (p_rw_cb->tcb.t3t.flags & RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP)
2770         {
2771             RW_TRACE_DEBUG0 ("RW_T3tPresenceCheck already in progress");
2772             retval = NFC_STATUS_FAILED;
2773         }
2774         /* If busy with any other command, assume that the tag is present */
2775         else
2776         {
2777             evt_data.status = NFC_STATUS_OK;
2778             (*p_rw_cb->p_cback) (RW_T3T_PRESENCE_CHECK_EVT, &evt_data);
2779         }
2780     }
2781     else
2782     {
2783         /* IDLE state: send POLL command */
2784         if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2785         {
2786             p_rw_cb->tcb.t3t.flags |= RW_T3T_FL_W4_PRESENCE_CHECK_POLL_RSP;
2787             p_rw_cb->tcb.t3t.rw_state = RW_T3T_STATE_COMMAND_PENDING;
2788             p_rw_cb->tcb.t3t.cur_poll_rc = 0;
2789 
2790             /* start timer for waiting for responses */
2791             rw_t3t_start_poll_timer (&p_rw_cb->tcb.t3t);
2792         }
2793         else
2794         {
2795             RW_TRACE_DEBUG1 ("RW_T3tPresenceCheck error sending NCI_RF_T3T_POLLING cmd (status = 0x%0x)", retval);
2796         }
2797     }
2798 
2799     return (retval);
2800 }
2801 
2802 /*****************************************************************************
2803 **
2804 ** Function         RW_T3tPoll
2805 **
2806 ** Description
2807 **      Send POLL command
2808 **
2809 ** Returns
2810 **      NFC_STATUS_OK, if raw data frame sent
2811 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2812 **      NFC_STATUS_FAILED: other error
2813 **
2814 *****************************************************************************/
RW_T3tPoll(UINT16 system_code,tT3T_POLL_RC rc,UINT8 tsn)2815 tNFC_STATUS RW_T3tPoll (UINT16 system_code, tT3T_POLL_RC rc, UINT8 tsn)
2816 {
2817     tNFC_STATUS retval = NFC_STATUS_OK;
2818     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2819 
2820     RW_TRACE_API0 ("RW_T3tPoll");
2821 
2822     /* Check if we are in valid state to handle this API */
2823     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2824     {
2825         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2826         return (NFC_STATUS_FAILED);
2827     }
2828 
2829     if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (system_code, (UINT8) rc, tsn)) == NCI_STATUS_OK)
2830     {
2831         /* start timer for waiting for responses */
2832         p_cb->cur_poll_rc = rc;
2833         p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2834         rw_t3t_start_poll_timer (p_cb);
2835     }
2836 
2837 
2838     return (retval);
2839 }
2840 
2841 /*****************************************************************************
2842 **
2843 ** Function         RW_T3tSendRawFrame
2844 **
2845 ** Description
2846 **      This function is called to send a raw data frame to the peer device.
2847 **      When type 3 tag receives response from peer, the callback function
2848 **      will be called with a RW_T3T_RAW_FRAME_EVT [Table 6].
2849 **
2850 **      Before using this API, the application must call RW_SelectTagType to
2851 **      indicate that a Type 3 tag has been activated.
2852 **
2853 **      The raw frame should be a properly formatted Type 3 tag message.
2854 **
2855 ** Returns
2856 **      NFC_STATUS_OK, if raw data frame sent
2857 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2858 **      NFC_STATUS_FAILED: other error
2859 **
2860 *****************************************************************************/
RW_T3tSendRawFrame(UINT16 len,UINT8 * p_data)2861 tNFC_STATUS RW_T3tSendRawFrame (UINT16 len, UINT8 *p_data)
2862 {
2863     tNFC_STATUS retval = NFC_STATUS_OK;
2864     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2865 
2866     RW_TRACE_API1 ("RW_T3tSendRawFrame (len = %i)", len);
2867 
2868     /* Check if we are in valid state to handle this API */
2869     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2870     {
2871         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2872         return (NFC_STATUS_FAILED);
2873     }
2874 
2875     /* Send the UPDATE command */
2876     retval = rw_t3t_send_raw_frame (p_cb, len ,p_data);
2877 
2878     return (retval);
2879 }
2880 
2881 /*****************************************************************************
2882 **
2883 ** Function         RW_T3tGetSystemCodes
2884 **
2885 ** Description
2886 **      Get systems codes supported by the activated tag:
2887 **              Poll for wildcard (FFFF):
2888 **                  - If felica-lite code then poll for ndef (12fc)
2889 **                  - Otherwise send RequestSystmCode command to get
2890 **                    system codes.
2891 **
2892 **      Before using this API, the application must call RW_SelectTagType to
2893 **      indicate that a Type 3 tag has been activated.
2894 **
2895 ** Returns
2896 **      NFC_STATUS_OK, if raw data frame sent
2897 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2898 **      NFC_STATUS_FAILED: other error
2899 **
2900 *****************************************************************************/
RW_T3tGetSystemCodes(void)2901 tNFC_STATUS RW_T3tGetSystemCodes (void)
2902 {
2903     tNFC_STATUS retval = NFC_STATUS_OK;
2904     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2905 
2906     RW_TRACE_API0 ("RW_T3tGetSystemCodes");
2907 
2908     /* Check if we are in valid state to handle this API */
2909     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2910     {
2911         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2912         return (NFC_STATUS_FAILED);
2913     }
2914     else
2915     {
2916         if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (0xFFFF, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2917         {
2918             p_cb->cur_cmd = RW_T3T_CMD_GET_SYSTEM_CODES;
2919             p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2920             p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2921             p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2922             p_cb->rw_substate = RW_T3T_GET_SC_SST_POLL_WILDCARD;
2923             p_cb->flags |= RW_T3T_FL_W4_GET_SC_POLL_RSP;
2924             p_cb->num_system_codes = 0;
2925 
2926             /* start timer for waiting for responses */
2927             rw_t3t_start_poll_timer (p_cb);
2928         }
2929     }
2930 
2931 
2932 
2933     return (retval);
2934 }
2935 
2936 /*****************************************************************************
2937 **
2938 ** Function         RW_T3tFormatNDef
2939 **
2940 ** Description
2941 **      Format a type-3 tag for NDEF.
2942 **
2943 **      Only Felica-Lite tags are supported by this API. The
2944 **      RW_T3T_FORMAT_CPLT_EVT is used to notify the status of the operation.
2945 **
2946 ** Returns
2947 **      NFC_STATUS_OK: ndef detection procedure started
2948 **      NFC_STATUS_NO_BUFFERS: unable to allocate a buffer for this operation
2949 **      NFC_STATUS_FAILED: other error
2950 **
2951 *****************************************************************************/
RW_T3tFormatNDef(void)2952 tNFC_STATUS RW_T3tFormatNDef (void)
2953 {
2954     tNFC_STATUS retval = NFC_STATUS_OK;
2955     tRW_T3T_CB *p_cb = &rw_cb.tcb.t3t;
2956 
2957     RW_TRACE_API0 ("RW_T3tFormatNDef");
2958 
2959     /* Check if we are in valid state to handle this API */
2960     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
2961     {
2962         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
2963         return (NFC_STATUS_FAILED);
2964     }
2965     else
2966     {
2967         /* Poll tag, to see if Felica-Lite system is supported */
2968         if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
2969         {
2970             p_cb->cur_cmd = RW_T3T_CMD_FORMAT;
2971             p_cb->cur_tout = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
2972             p_cb->cur_poll_rc = T3T_POLL_RC_SC;
2973             p_cb->rw_state = RW_T3T_STATE_COMMAND_PENDING;
2974             p_cb->rw_substate = RW_T3T_FMT_SST_POLL_FELICA_LITE;
2975             p_cb->flags |= RW_T3T_FL_W4_FMT_FELICA_LITE_POLL_RSP;
2976 
2977             /* start timer for waiting for responses */
2978             rw_t3t_start_poll_timer (p_cb);
2979         }
2980     }
2981 
2982 
2983 
2984     return (retval);
2985 }
2986 
2987 /*****************************************************************************
2988 **
2989 ** Function         RW_T3tSetReadOnly
2990 **
2991 ** Description      This function performs NDEF read-only procedure
2992 **                  Note: Only Felica-Lite tags are supported by this API.
2993 **                        RW_T3tDetectNDef() must be called before using this
2994 **
2995 **                  The RW_T3T_SET_READ_ONLY_CPLT_EVT event will be returned.
2996 **
2997 ** Returns          NFC_STATUS_OK if success
2998 **                  NFC_STATUS_FAILED if T3T is busy or other error
2999 **
3000 *****************************************************************************/
RW_T3tSetReadOnly(BOOLEAN b_hard_lock)3001 tNFC_STATUS RW_T3tSetReadOnly (BOOLEAN b_hard_lock)
3002 {
3003     tNFC_STATUS retval = NFC_STATUS_OK;
3004     tRW_T3T_CB  *p_cb  = &rw_cb.tcb.t3t;
3005     tRW_DATA    evt_data;
3006 
3007     RW_TRACE_API1 ("RW_T3tSetReadOnly (): b_hard_lock=%d", b_hard_lock);
3008 
3009     /* Check if we are in valid state to handle this API */
3010     if (p_cb->rw_state != RW_T3T_STATE_IDLE)
3011     {
3012         RW_TRACE_ERROR1 ("Error: invalid state to handle API (0x%x)", p_cb->rw_state);
3013         return (NFC_STATUS_FAILED);
3014     }
3015 
3016     if (p_cb->ndef_attrib.status != NFC_STATUS_OK)       /* NDEF detection not performed yet? */
3017     {
3018         RW_TRACE_ERROR0 ("Error: NDEF detection not performed yet");
3019         return (NFC_STATUS_NOT_INITIALIZED);
3020     }
3021 
3022     if ((!b_hard_lock) && (p_cb->ndef_attrib.rwflag == T3T_MSG_NDEF_RWFLAG_RO))/* Tag's NDEF memory is read-only already */
3023     {
3024         evt_data.status = NFC_STATUS_OK;
3025         (*(rw_cb.p_cback)) (RW_T3T_SET_READ_ONLY_CPLT_EVT, &evt_data);
3026         return (retval);
3027     }
3028     else
3029     {
3030         /* Poll tag, to see if Felica-Lite system is supported */
3031         if ((retval = (tNFC_STATUS) nci_snd_t3t_polling (T3T_SYSTEM_CODE_FELICA_LITE, T3T_POLL_RC_SC, 0)) == NCI_STATUS_OK)
3032         {
3033             if (b_hard_lock)
3034                 p_cb->cur_cmd     = RW_T3T_CMD_SET_READ_ONLY_HARD;
3035             else
3036                 p_cb->cur_cmd     = RW_T3T_CMD_SET_READ_ONLY_SOFT;
3037             p_cb->cur_tout    = RW_T3T_DEFAULT_CMD_TIMEOUT_TICKS;
3038             p_cb->cur_poll_rc = T3T_POLL_RC_SC;
3039             p_cb->rw_state    = RW_T3T_STATE_COMMAND_PENDING;
3040             p_cb->rw_substate = RW_T3T_SRO_SST_POLL_FELICA_LITE;
3041             p_cb->flags |= RW_T3T_FL_W4_SRO_FELICA_LITE_POLL_RSP;
3042 
3043             /* start timer for waiting for responses */
3044             rw_t3t_start_poll_timer (p_cb);
3045         }
3046     }
3047     return (retval);
3048 }
3049