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