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