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