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