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