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