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