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