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