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 2 tag NDEF operation in
22 * Reader/Writer mode.
23 *
24 ******************************************************************************/
25 #include <android-base/stringprintf.h>
26 #include <base/logging.h>
27 #include <log/log.h>
28 #include <string.h>
29
30 #include "nci_hmsgs.h"
31 #include "nfc_api.h"
32 #include "nfc_target.h"
33 #include "rw_api.h"
34 #include "rw_int.h"
35
36 using android::base::StringPrintf;
37
38 extern bool nfc_debug_enabled;
39
40 #if (RW_NDEF_INCLUDED == TRUE)
41
42 /* Local static functions */
43 static void rw_t2t_handle_cc_read_rsp(void);
44 static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data);
45 static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data);
46 static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data);
47 static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data);
48 static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data);
49 static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data);
50 static uint8_t rw_t2t_get_tag_size(uint8_t* p_data);
51 static void rw_t2t_extract_default_locks_info(void);
52 static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
53 bool b_update_len);
54 static uint8_t rw_t2t_get_ndef_flags(void);
55 static uint16_t rw_t2t_get_ndef_max_size(void);
56 static tNFC_STATUS rw_t2t_read_locks(void);
57 static tNFC_STATUS rw_t2t_read_ndef_last_block(void);
58 static void rw_t2t_update_attributes(void);
59 static void rw_t2t_update_lock_attributes(void);
60 static bool rw_t2t_is_lock_res_byte(uint16_t index);
61 static tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len,
62 bool b_update_len);
63 static tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block,
64 uint16_t msg_len,
65 bool b_update_len);
66 static tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block);
67 static tNFC_STATUS rw_t2t_add_terminator_tlv(void);
68 static bool rw_t2t_is_read_before_write_block(uint16_t block,
69 uint16_t* p_block_to_read);
70 static tNFC_STATUS rw_t2t_set_cc(uint8_t tms);
71 static tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
72 uint16_t locked_area_size);
73 static tNFC_STATUS rw_t2t_format_tag(void);
74 static tNFC_STATUS rw_t2t_soft_lock_tag(void);
75 static tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data);
76 static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status);
77
78 const uint8_t rw_t2t_mask_bits[8] = {0x01, 0x02, 0x04, 0x08,
79 0x10, 0x20, 0x40, 0x80};
80
81 /*******************************************************************************
82 **
83 ** Function rw_t2t_handle_rsp
84 **
85 ** Description This function handles response to command sent during
86 ** NDEF and other tlv operation
87 **
88 ** Returns None
89 **
90 *******************************************************************************/
rw_t2t_handle_rsp(uint8_t * p_data)91 void rw_t2t_handle_rsp(uint8_t* p_data) {
92 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
93
94 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
95 p_t2t->b_read_hdr = true;
96 memcpy(p_t2t->tag_hdr, p_data, T2T_READ_DATA_LEN);
97 }
98
99 switch (p_t2t->state) {
100 case RW_T2T_STATE_DETECT_TLV:
101 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
102 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
103 rw_t2t_handle_cc_read_rsp();
104 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
105 rw_t2t_handle_lock_read_rsp(p_data);
106 } else {
107 rw_t2t_handle_tlv_detect_rsp(p_data);
108 }
109 } else if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
110 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
111 if (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] == T2T_CC0_NMN) {
112 rw_t2t_handle_cc_read_rsp();
113 } else {
114 LOG(WARNING) << StringPrintf(
115 "NDEF Detection failed!, CC[0]: 0x%02x, CC[1]: 0x%02x, CC[3]: "
116 "0x%02x",
117 p_t2t->tag_hdr[T2T_CC0_NMN_BYTE],
118 p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
119 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
120 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
121 }
122 } else if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_LOCKS) {
123 rw_t2t_handle_lock_read_rsp(p_data);
124 } else {
125 rw_t2t_handle_tlv_detect_rsp(p_data);
126 }
127 } else {
128 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_READ_CC) {
129 rw_t2t_handle_cc_read_rsp();
130 } else {
131 rw_t2t_handle_tlv_detect_rsp(p_data);
132 }
133 }
134 break;
135
136 case RW_T2T_STATE_SET_TAG_RO:
137 rw_t2t_handle_config_tag_readonly(p_data);
138 break;
139
140 case RW_T2T_STATE_FORMAT_TAG:
141 rw_t2t_handle_format_tag_rsp(p_data);
142 break;
143
144 case RW_T2T_STATE_READ_NDEF:
145 rw_t2t_handle_ndef_read_rsp(p_data);
146 break;
147
148 case RW_T2T_STATE_WRITE_NDEF:
149 rw_t2t_handle_ndef_write_rsp(p_data);
150 break;
151 }
152 }
153
154 /*******************************************************************************
155 **
156 ** Function rw_t2t_info_to_event
157 **
158 ** Description This function returns RW event code based on the current
159 ** state
160 **
161 ** Returns RW event code
162 **
163 *******************************************************************************/
rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO * p_info)164 tRW_EVENT rw_t2t_info_to_event(const tT2T_CMD_RSP_INFO* p_info) {
165 tRW_EVENT rw_event;
166 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
167
168 switch (p_t2t->state) {
169 case RW_T2T_STATE_DETECT_TLV:
170 if (p_t2t->tlv_detect == TAG_NDEF_TLV)
171 rw_event = RW_T2T_NDEF_DETECT_EVT;
172 else
173 rw_event = RW_T2T_TLV_DETECT_EVT;
174
175 break;
176
177 case RW_T2T_STATE_READ_NDEF:
178 rw_event = RW_T2T_NDEF_READ_EVT;
179 break;
180
181 case RW_T2T_STATE_WRITE_NDEF:
182 rw_event = RW_T2T_NDEF_WRITE_EVT;
183 break;
184
185 case RW_T2T_STATE_SET_TAG_RO:
186 rw_event = RW_T2T_SET_TAG_RO_EVT;
187 break;
188
189 case RW_T2T_STATE_CHECK_PRESENCE:
190 rw_event = RW_T2T_PRESENCE_CHECK_EVT;
191 break;
192
193 case RW_T2T_STATE_FORMAT_TAG:
194 rw_event = RW_T2T_FORMAT_CPLT_EVT;
195 break;
196
197 default:
198 rw_event = t2t_info_to_evt(p_info);
199 break;
200 }
201 return rw_event;
202 }
203
204 /*******************************************************************************
205 **
206 ** Function rw_t2t_handle_cc_read_rsp
207 **
208 ** Description Handle read cc bytes
209 **
210 ** Returns none
211 **
212 *******************************************************************************/
rw_t2t_handle_cc_read_rsp(void)213 static void rw_t2t_handle_cc_read_rsp(void) {
214 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
215
216 if (((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) &&
217 (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RO)) ||
218 ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
219 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
220 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
221 /* Invalid Version number or RWA byte */
222 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
223 return;
224 }
225
226 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
227
228 if (rw_t2t_read((uint16_t)T2T_FIRST_DATA_BLOCK) != NFC_STATUS_OK) {
229 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
230 }
231 }
232
233 /*******************************************************************************
234 **
235 ** Function rw_t2t_ntf_tlv_detect_complete
236 **
237 ** Description Notify TLV detection complete to upper layer
238 **
239 ** Returns none
240 **
241 *******************************************************************************/
rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status)242 static void rw_t2t_ntf_tlv_detect_complete(tNFC_STATUS status) {
243 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
244 uint8_t xx;
245
246 if (p_t2t->tlv_detect == TAG_NDEF_TLV) {
247 /* Notify upper layer the result of NDEF detect op */
248 tRW_DETECT_NDEF_DATA ndef_data = {};
249 ndef_data.status = status;
250 ndef_data.protocol = NFC_PROTOCOL_T2T;
251 ndef_data.flags = rw_t2t_get_ndef_flags();
252 ndef_data.cur_size = p_t2t->ndef_msg_len;
253
254 if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_FORMATED;
255
256 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] == T2T_CC3_RWA_RW)
257 ndef_data.max_size = (uint32_t)rw_t2t_get_ndef_max_size();
258 else
259 ndef_data.max_size = ndef_data.cur_size;
260
261 if (ndef_data.max_size < ndef_data.cur_size) {
262 ndef_data.flags |= RW_NDEF_FL_READ_ONLY;
263 ndef_data.max_size = ndef_data.cur_size;
264 }
265
266 if (!(ndef_data.flags & RW_NDEF_FL_READ_ONLY)) {
267 ndef_data.flags |= RW_NDEF_FL_SOFT_LOCKABLE;
268 if (status == NFC_STATUS_OK) ndef_data.flags |= RW_NDEF_FL_HARD_LOCKABLE;
269 }
270
271 rw_t2t_handle_op_complete();
272 tRW_DATA rw_data;
273 rw_data.ndef = ndef_data;
274 (*rw_cb.p_cback)(RW_T2T_NDEF_DETECT_EVT, &rw_data);
275 } else if (p_t2t->tlv_detect == TAG_PROPRIETARY_TLV) {
276 tRW_T2T_DETECT evt_data;
277 evt_data.msg_len = p_t2t->prop_msg_len;
278 evt_data.status = status;
279 rw_t2t_handle_op_complete();
280 /* FIXME: Unsafe cast */
281 (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, (tRW_DATA*)&evt_data);
282 } else {
283 /* Notify upper layer the result of Lock/Mem TLV detect op */
284 tRW_DETECT_TLV_DATA tlv_data;
285 tlv_data.protocol = NFC_PROTOCOL_T2T;
286 if (p_t2t->tlv_detect == TAG_LOCK_CTRL_TLV) {
287 tlv_data.num_bytes = p_t2t->num_lockbytes;
288 } else {
289 tlv_data.num_bytes = 0;
290 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++) {
291 tlv_data.num_bytes += p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes;
292 }
293 }
294 tlv_data.status = status;
295 rw_t2t_handle_op_complete();
296 tRW_DATA rw_data;
297 rw_data.tlv = tlv_data;
298 (*rw_cb.p_cback)(RW_T2T_TLV_DETECT_EVT, &rw_data);
299 }
300 }
301
302 /*******************************************************************************
303 **
304 ** Function rw_t2t_handle_lock_read_rsp
305 **
306 ** Description Handle response to reading lock bytes
307 **
308 ** Returns none
309 **
310 *******************************************************************************/
rw_t2t_handle_lock_read_rsp(uint8_t * p_data)311 static void rw_t2t_handle_lock_read_rsp(uint8_t* p_data) {
312 uint8_t updated_lock_byte;
313 uint8_t num_locks;
314 uint8_t offset = 0;
315 uint16_t lock_offset;
316 uint16_t base_lock_offset = 0;
317 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
318 uint16_t block;
319
320 /* Prepare NDEF/TLV attributes (based on current op) for sending response to
321 * upper layer */
322
323 num_locks = 0;
324 updated_lock_byte = 0;
325
326 /* Extract all lock bytes present in the read 16 bytes
327 * but atleast one lock byte (base lock) should be present in the read 16
328 * bytes */
329
330 while (num_locks < p_t2t->num_lockbytes) {
331 if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
332 lock_offset =
333 p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
334 p_t2t->lockbyte[num_locks].byte_index;
335 if (updated_lock_byte == 0) {
336 /* The offset of the first lock byte present in the 16 bytes read using
337 * READ command */
338 base_lock_offset = lock_offset;
339 /* Block number used to read may not be the block where lock offset is
340 * present */
341 offset = (uint8_t)(lock_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
342 /* Update the lock byte value in the control block */
343 p_t2t->lockbyte[num_locks].lock_byte = p_data[offset];
344 p_t2t->lockbyte[num_locks].b_lock_read = true;
345 updated_lock_byte++;
346 } else if (lock_offset > base_lock_offset) {
347 /* Atleast one lock byte will get updated in the control block */
348 if ((lock_offset - base_lock_offset + offset) < T2T_READ_DATA_LEN) {
349 /* And this lock byte is also present in the read data */
350 p_t2t->lockbyte[num_locks].lock_byte =
351 p_data[lock_offset - base_lock_offset + offset];
352 p_t2t->lockbyte[num_locks].b_lock_read = true;
353 updated_lock_byte++;
354 } else {
355 /* This lock byte is not present in the read data */
356 block = (uint16_t)(lock_offset / T2T_BLOCK_LEN);
357 block -= block % T2T_READ_BLOCKS;
358 /* send READ command to read this lock byte */
359 if (NFC_STATUS_OK != rw_t2t_read((uint16_t)block)) {
360 /* Unable to send Read command, notify failure status to upper layer
361 */
362 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
363 }
364 break;
365 }
366 } else {
367 /* This Lock byte is not present in the read 16 bytes
368 * send READ command to read the lock byte */
369 if (NFC_STATUS_OK !=
370 rw_t2t_read((uint16_t)(lock_offset / T2T_BLOCK_LEN))) {
371 /* Unable to send Read command, notify failure status to upper layer
372 */
373 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_FAILED);
374 }
375 break;
376 }
377 }
378 num_locks++;
379 }
380 if (num_locks == p_t2t->num_lockbytes) {
381 /* All locks are read, notify upper layer */
382 rw_t2t_update_lock_attributes();
383 rw_t2t_ntf_tlv_detect_complete(NFC_STATUS_OK);
384 }
385 }
386
387 /*******************************************************************************
388 **
389 ** Function rw_t2t_handle_tlv_detect_rsp
390 **
391 ** Description Handle TLV detection.
392 **
393 ** Returns none
394 **
395 *******************************************************************************/
rw_t2t_handle_tlv_detect_rsp(uint8_t * p_data)396 static void rw_t2t_handle_tlv_detect_rsp(uint8_t* p_data) {
397 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
398 uint16_t offset;
399 uint16_t len = 0;
400 bool failed = false;
401 bool found = false;
402 uint8_t index;
403 uint16_t count = 0;
404 uint8_t xx;
405 tNFC_STATUS status;
406 tT2T_CMD_RSP_INFO* p_cmd_rsp_info =
407 (tT2T_CMD_RSP_INFO*)rw_cb.tcb.t2t.p_cmd_rsp_info;
408 uint8_t tlvtype = p_t2t->tlv_detect;
409
410 if (p_t2t->work_offset == 0) {
411 /* Skip UID,Static Lock block,CC*/
412 p_t2t->work_offset = T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN;
413 p_t2t->b_read_data = true;
414 memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
415 }
416
417 p_t2t->segment = 0;
418
419 for (offset = 0; offset < T2T_READ_DATA_LEN && !failed && !found;) {
420 if (rw_t2t_is_lock_res_byte((uint16_t)(p_t2t->work_offset + offset)) ==
421 true) {
422 /* Skip locks, reserved bytes while searching for TLV */
423 offset++;
424 continue;
425 }
426 switch (p_t2t->substate) {
427 case RW_T2T_SUBSTATE_WAIT_TLV_DETECT:
428 /* Search for the tlv */
429 p_t2t->found_tlv = p_data[offset++];
430 switch (p_t2t->found_tlv) {
431 case TAG_NULL_TLV: /* May be used for padding. SHALL ignore this */
432 break;
433
434 case TAG_NDEF_TLV:
435 if (tlvtype == TAG_NDEF_TLV) {
436 /* NDEF Detected, now collect NDEF Attributes including NDEF
437 * Length */
438 index = (offset % T2T_BLOCK_SIZE);
439 /* Backup ndef first block */
440 memcpy(p_t2t->ndef_first_block, &p_data[offset - index], index);
441 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
442 } else if (tlvtype == TAG_PROPRIETARY_TLV) {
443 /* Proprietary TLV can exist after NDEF Tlv so we continue
444 * searching */
445 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
446 } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
447 (p_t2t->num_lockbytes > 0)) ||
448 ((tlvtype == TAG_MEM_CTRL_TLV) &&
449 (p_t2t->num_mem_tlvs > 0))) {
450 /* Lock / Memory control tlv cannot exist after NDEF TLV
451 * So when NDEF is found, we stop searching for Lock and Memory
452 * control tlv */
453 found = true;
454 } else {
455 /* While searching for Lock / Memory control tlv, if NDEF TLV is
456 * found
457 * first then our search for Lock /Memory control tlv failed and
458 * we stop here */
459 failed = true;
460 }
461 break;
462
463 case TAG_LOCK_CTRL_TLV:
464 case TAG_MEM_CTRL_TLV:
465 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
466 break;
467
468 case TAG_PROPRIETARY_TLV:
469 if (tlvtype == TAG_PROPRIETARY_TLV) {
470 index = (offset % T2T_BLOCK_SIZE);
471 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
472 } else {
473 /* NDEF/LOCK/MEM TLV can exist after Proprietary Tlv so we
474 * continue searching, skiping proprietary tlv */
475 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN;
476 }
477 break;
478
479 case TAG_TERMINATOR_TLV: /* Last TLV block in the data area. Must be
480 no NDEF nessage */
481 if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
482 (p_t2t->num_lockbytes > 0)) ||
483 ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
484 /* No more Lock/Memory TLV control tlv in the tag, so stop
485 * searching */
486 found = true;
487 } else {
488 /* NDEF/Lock/Memory/Proprietary TLV cannot exist after Terminator
489 * Tlv */
490 failed = true;
491 }
492 break;
493 default:
494 failed = true;
495 }
496 break;
497
498 case RW_T2T_SUBSTATE_WAIT_FIND_LEN_FIELD_LEN:
499 len = p_data[offset];
500 switch (p_t2t->found_tlv) {
501 case TAG_NDEF_TLV:
502 p_t2t->ndef_header_offset = offset + p_t2t->work_offset;
503 if (len == TAG_LONG_NDEF_LEN_FIELD_BYTE0) {
504 /* The next two bytes constitute length bytes */
505 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
506 } else {
507 /* one byte length field */
508 p_t2t->ndef_msg_len = len;
509 p_t2t->bytes_count = p_t2t->ndef_msg_len;
510 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
511 }
512 break;
513
514 case TAG_PROPRIETARY_TLV:
515 if (len == T2T_LONG_NDEF_LEN_FIELD_BYTE0) {
516 /* The next two bytes constitute length bytes */
517 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0;
518 } else {
519 /* one byte length field */
520 p_t2t->prop_msg_len = len;
521 p_t2t->bytes_count = p_t2t->prop_msg_len;
522 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
523 }
524 break;
525 }
526 offset++;
527 break;
528
529 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN0:
530 switch (p_t2t->found_tlv) {
531 case TAG_LOCK_CTRL_TLV:
532 case TAG_MEM_CTRL_TLV:
533
534 len = p_data[offset];
535 if (len == TAG_DEFAULT_TLV_LEN) {
536 /* Valid Lock control TLV */
537 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
538 p_t2t->bytes_count = TAG_DEFAULT_TLV_LEN;
539 } else if (((tlvtype == TAG_LOCK_CTRL_TLV) &&
540 (p_t2t->num_lockbytes > 0)) ||
541 ((tlvtype == TAG_MEM_CTRL_TLV) &&
542 (p_t2t->num_mem_tlvs > 0))) {
543 /* Stop searching for Lock/ Memory control tlv */
544 found = true;
545 } else {
546 failed = true;
547 }
548 break;
549
550 case TAG_NDEF_TLV:
551 case TAG_PROPRIETARY_TLV:
552 /* The first length byte */
553 p_t2t->bytes_count = (uint8_t)p_data[offset];
554 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1;
555 break;
556 }
557 offset++;
558 break;
559
560 case RW_T2T_SUBSTATE_WAIT_READ_TLV_LEN1:
561 /* Prepare NDEF Message length */
562 p_t2t->bytes_count = (p_t2t->bytes_count << 8) + p_data[offset];
563 if (p_t2t->found_tlv == TAG_NDEF_TLV) {
564 p_t2t->ndef_msg_len = p_t2t->bytes_count;
565 } else if (p_t2t->found_tlv == TAG_PROPRIETARY_TLV) {
566 p_t2t->prop_msg_len = p_t2t->bytes_count;
567 }
568 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE;
569 offset++;
570 break;
571
572 case RW_T2T_SUBSTATE_WAIT_READ_TLV_VALUE:
573 switch (p_t2t->found_tlv) {
574 case TAG_NDEF_TLV:
575 if ((p_t2t->bytes_count == p_t2t->ndef_msg_len) &&
576 (tlvtype == TAG_NDEF_TLV)) {
577 /* The first byte offset after length field */
578 p_t2t->ndef_msg_offset = offset + p_t2t->work_offset;
579 }
580 /* Reduce number of NDEF bytes remaining to pass over NDEF TLV */
581 if (p_t2t->bytes_count > 0) p_t2t->bytes_count--;
582
583 if (tlvtype == TAG_NDEF_TLV) {
584 found = true;
585 p_t2t->ndef_status = T2T_NDEF_DETECTED;
586 } else if (p_t2t->bytes_count == 0) {
587 /* Next byte could be a different TLV */
588 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
589 }
590 break;
591
592 case TAG_LOCK_CTRL_TLV:
593 if (p_t2t->bytes_count > 0) {
594 p_t2t->bytes_count--;
595 } else {
596 LOG(ERROR) << StringPrintf("Underflow p_t2t->bytes_count!");
597 android_errorWriteLog(0x534e4554, "120506143");
598 failed = true;
599 break;
600 }
601 if ((tlvtype == TAG_LOCK_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
602 if (p_t2t->num_lockbytes > 0) {
603 LOG(ERROR) << StringPrintf("Malformed tag!");
604 android_errorWriteLog(0x534e4554, "147309942");
605 failed = true;
606 break;
607 }
608 /* Collect Lock TLV */
609 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
610 if (p_t2t->bytes_count == 0) {
611 /* Lock TLV is collected and buffered in tlv_value, now decode
612 * it */
613 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
614 (p_t2t->tlv_value[0] >> 4) & 0x0F;
615 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset *=
616 (uint16_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
617 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset +=
618 p_t2t->tlv_value[0] & 0x0F;
619 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
620 (uint16_t)tags_pow(2, ((p_t2t->tlv_value[2] & 0xF0) >> 4));
621 /* Note: 0 value in DLA_NbrLockBits means 256 bits */
622 count = p_t2t->tlv_value[1];
623 /* Set it to max value that can be stored in lockbytes */
624 if (count == 0) {
625 count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
626 }
627 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = count;
628 count = count / TAG_BITS_PER_BYTE +
629 ((count % TAG_BITS_PER_BYTE != 0) ? 1 : 0);
630
631 /* Extract lockbytes info addressed by this Lock TLV */
632 xx = 0;
633 if (count > RW_T2T_MAX_LOCK_BYTES) {
634 count = RW_T2T_MAX_LOCK_BYTES;
635 android_errorWriteLog(0x534e4554, "112161557");
636 }
637 while (xx < count) {
638 p_t2t->lockbyte[p_t2t->num_lockbytes].tlv_index =
639 p_t2t->num_lock_tlvs;
640 p_t2t->lockbyte[p_t2t->num_lockbytes].byte_index = xx;
641 p_t2t->lockbyte[p_t2t->num_lockbytes].b_lock_read = false;
642 xx++;
643 p_t2t->num_lockbytes++;
644 }
645 p_t2t->num_lock_tlvs++;
646 rw_t2t_update_attributes();
647 /* Next byte could be a different TLV */
648 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
649 }
650 } else {
651 /* If not looking for lock/ndef tlv, just skip this Lock TLV */
652 if (p_t2t->bytes_count == 0) {
653 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
654 }
655 }
656 break;
657
658 case TAG_MEM_CTRL_TLV:
659 if (p_t2t->bytes_count > 0) {
660 p_t2t->bytes_count--;
661 } else {
662 LOG(ERROR) << StringPrintf("bytes_count underflow!");
663 android_errorWriteLog(0x534e4554, "120506143");
664 failed = true;
665 break;
666 }
667 if ((tlvtype == TAG_MEM_CTRL_TLV) || (tlvtype == TAG_NDEF_TLV)) {
668 p_t2t->tlv_value[2 - p_t2t->bytes_count] = p_data[offset];
669 if (p_t2t->bytes_count == 0) {
670 if (p_t2t->num_mem_tlvs >= RW_T2T_MAX_MEM_TLVS) {
671 LOG(ERROR) << StringPrintf(
672 "rw_t2t_handle_tlv_detect_rsp - Maximum buffer allocated "
673 "for Memory tlv has reached");
674 failed = true;
675 } else {
676 /* Extract memory control tlv */
677 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset =
678 (p_t2t->tlv_value[0] >> 4) & 0x0F;
679 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset *=
680 (uint16_t)tags_pow(2, p_t2t->tlv_value[2] & 0x0F);
681
682 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].offset +=
683 p_t2t->tlv_value[0] & 0x0F;
684 count = p_t2t->tlv_value[1];
685 /* Note: 0 value in Rsvd_Area_Size means 256 bytes */
686 if (count == 0) {
687 count = RW_T2T_MAX_LOCK_BYTES * TAG_BITS_PER_BYTE;
688 }
689 p_t2t->mem_tlv[p_t2t->num_mem_tlvs].num_bytes = count;
690
691 p_t2t->num_mem_tlvs++;
692 rw_t2t_update_attributes();
693 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
694 }
695 }
696 } else {
697 if (p_t2t->bytes_count == 0) {
698 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
699 }
700 }
701 break;
702
703 case TAG_PROPRIETARY_TLV:
704 if (p_t2t->bytes_count > 0) {
705 p_t2t->bytes_count--;
706 } else {
707 LOG(ERROR) << StringPrintf("bytes_count underflow!");
708 android_errorWriteLog(0x534e4554, "120506143");
709 failed = true;
710 break;
711 }
712 if (tlvtype == TAG_PROPRIETARY_TLV) {
713 found = true;
714 p_t2t->prop_msg_len = len;
715 } else {
716 if (p_t2t->bytes_count == 0) {
717 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
718 }
719 }
720 break;
721 }
722 offset++;
723 break;
724 default:
725 LOG(ERROR) << StringPrintf("Unknown p_t2t->substate=%d",
726 p_t2t->substate);
727 failed = true;
728 }
729 }
730
731 p_t2t->work_offset += T2T_READ_DATA_LEN;
732
733 rw_t2t_info_to_event(p_cmd_rsp_info);
734
735 /* If not found and not failed, read next block and search tlv */
736 if (!found && !failed) {
737 if (p_t2t->work_offset >=
738 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR +
739 T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN)) {
740 if (((tlvtype == TAG_LOCK_CTRL_TLV) && (p_t2t->num_lockbytes > 0)) ||
741 ((tlvtype == TAG_MEM_CTRL_TLV) && (p_t2t->num_mem_tlvs > 0))) {
742 found = true;
743 } else {
744 failed = true;
745 }
746 } else {
747 if (rw_t2t_read((uint16_t)(p_t2t->work_offset / T2T_BLOCK_LEN)) !=
748 NFC_STATUS_OK)
749 failed = true;
750 }
751 }
752
753 if (failed || found) {
754 if (tlvtype == TAG_LOCK_CTRL_TLV) {
755 /* Incase no Lock control tlv is present then look for default dynamic
756 * lock bytes */
757 rw_t2t_extract_default_locks_info();
758
759 /* Send command to read the dynamic lock bytes */
760 status = rw_t2t_read_locks();
761
762 if (status != NFC_STATUS_CONTINUE) {
763 /* If unable to read a lock/all locks read, notify upper layer */
764 rw_t2t_update_lock_attributes();
765 rw_t2t_ntf_tlv_detect_complete(status);
766 }
767 } else if (tlvtype == TAG_NDEF_TLV) {
768 rw_t2t_extract_default_locks_info();
769
770 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
771 rw_t2t_ntf_tlv_detect_complete(status);
772 } else {
773 /* Notify Memory/ Proprietary tlv detect result */
774 status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
775 rw_t2t_ntf_tlv_detect_complete(status);
776 }
777 }
778 }
779
780 /*******************************************************************************
781 **
782 ** Function rw_t2t_read_locks
783 **
784 ** Description This function will send command to read next unread locks
785 **
786 ** Returns NFC_STATUS_OK, if all locks are read successfully
787 ** NFC_STATUS_FAILED, if reading locks failed
788 ** NFC_STATUS_CONTINUE, if reading locks is in progress
789 **
790 *******************************************************************************/
rw_t2t_read_locks(void)791 tNFC_STATUS rw_t2t_read_locks(void) {
792 uint8_t num_locks = 0;
793 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
794 tNFC_STATUS status = NFC_STATUS_CONTINUE;
795 uint16_t offset;
796 uint16_t block;
797
798 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) ||
799 (p_t2t->skip_dyn_locks)) {
800 /* Skip reading dynamic lock bytes if CC is set as Read only or layer above
801 * instructs to skip */
802 while (num_locks < p_t2t->num_lockbytes) {
803 p_t2t->lockbyte[num_locks].lock_byte = 0x00;
804 p_t2t->lockbyte[num_locks].b_lock_read = true;
805 num_locks++;
806 }
807 }
808
809 while (num_locks < p_t2t->num_lockbytes) {
810 if (p_t2t->lockbyte[num_locks].b_lock_read == false) {
811 /* Send Read command to read the first un read locks */
812 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
813 p_t2t->lockbyte[num_locks].byte_index;
814
815 /* Read 16 bytes where this lock byte is present */
816 block = (uint16_t)(offset / T2T_BLOCK_LEN);
817 block -= block % T2T_READ_BLOCKS;
818
819 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_LOCKS;
820 /* send READ8 command */
821 status = rw_t2t_read((uint16_t)block);
822 if (status == NFC_STATUS_OK) {
823 /* Reading Locks */
824 status = NFC_STATUS_CONTINUE;
825 } else {
826 status = NFC_STATUS_FAILED;
827 }
828 break;
829 }
830 num_locks++;
831 }
832 if (num_locks == p_t2t->num_lockbytes) {
833 /* All locks are read */
834 status = NFC_STATUS_OK;
835 }
836
837 return status;
838 }
839
840 /*******************************************************************************
841 **
842 ** Function rw_t2t_extract_default_locks_info
843 **
844 ** Description This function will prepare lockbytes information for default
845 ** locks present in the tag in the absence of lock control tlv.
846 ** Adding a virtual lock control tlv for these lock bytes for
847 ** easier manipulation.
848 **
849 ** Returns None
850 **
851 *******************************************************************************/
rw_t2t_extract_default_locks_info(void)852 void rw_t2t_extract_default_locks_info(void) {
853 uint8_t num_dynamic_lock_bits;
854 uint8_t num_dynamic_lock_bytes;
855 uint8_t xx;
856 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
857 const tT2T_INIT_TAG* p_ret;
858 uint8_t bytes_locked_per_lock_bit = T2T_DEFAULT_LOCK_BLPB;
859 uint16_t t2t_dyn_lock_area_size;
860
861 if ((p_t2t->num_lock_tlvs == 0) &&
862 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] > T2T_CC2_TMS_STATIC)) {
863 /* No Lock control tlv is detected. Indicates lock bytes are present in
864 * default location */
865 /* Add a virtual Lock tlv to map this default lock location */
866 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
867 if (p_ret != nullptr) bytes_locked_per_lock_bit = p_ret->default_lock_blpb;
868
869 t2t_dyn_lock_area_size =
870 ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) -
871 (T2T_STATIC_SIZE - T2T_HEADER_SIZE));
872 num_dynamic_lock_bits = t2t_dyn_lock_area_size / bytes_locked_per_lock_bit;
873 num_dynamic_lock_bits += (t2t_dyn_lock_area_size % 8 == 0) ? 0 : 1;
874
875 num_dynamic_lock_bytes = num_dynamic_lock_bits / 8;
876 num_dynamic_lock_bytes += (num_dynamic_lock_bits % 8 == 0) ? 0 : 1;
877 if (num_dynamic_lock_bytes > RW_T2T_MAX_LOCK_BYTES) {
878 LOG(ERROR) << StringPrintf(
879 "rw_t2t_extract_default_locks_info - buffer size: %u less than "
880 "DynLock area sise: %u",
881 RW_T2T_MAX_LOCK_BYTES, num_dynamic_lock_bytes);
882 num_dynamic_lock_bytes = RW_T2T_MAX_LOCK_BYTES;
883 android_errorWriteLog(0x534e4554, "147310721");
884 }
885
886 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].offset =
887 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
888 (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
889 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].bytes_locked_per_bit =
890 bytes_locked_per_lock_bit;
891 p_t2t->lock_tlv[p_t2t->num_lock_tlvs].num_bits = num_dynamic_lock_bits;
892
893 /* Based on tag data size the number of locks present in the default
894 * location changes */
895 for (xx = 0; xx < num_dynamic_lock_bytes; xx++) {
896 p_t2t->lockbyte[xx].tlv_index = p_t2t->num_lock_tlvs;
897 p_t2t->lockbyte[xx].byte_index = xx;
898 p_t2t->lockbyte[xx].b_lock_read = false;
899 }
900 p_t2t->num_lockbytes = num_dynamic_lock_bytes;
901 p_t2t->num_lock_tlvs = 1;
902 }
903 }
904
905 /*******************************************************************************
906 **
907 ** Function rw_t2t_read_ndef_last_block
908 **
909 ** Description This function will locate and read the last ndef block.
910 ** The last ndef block refers to the tag block where last byte
911 ** of new ndef message will reside. Also this function will
912 ** locate the offset of Terminator TLV based on the size of
913 ** new NDEF Message
914 **
915 ** Returns NCI_STATUS_OK, if able to locate last ndef block & read
916 ** started. Otherwise, error status.
917 **
918 *******************************************************************************/
rw_t2t_read_ndef_last_block(void)919 tNFC_STATUS rw_t2t_read_ndef_last_block(void) {
920 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
921 uint16_t header_len = (p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN)
922 ? T2T_LONG_NDEF_LEN_FIELD_LEN
923 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
924 uint16_t num_ndef_bytes;
925 uint16_t total_ndef_bytes;
926 uint16_t last_ndef_byte_offset;
927 uint16_t terminator_tlv_byte_index;
928 tNFC_STATUS status = NFC_STATUS_OK;
929
930 total_ndef_bytes = header_len + p_t2t->new_ndef_msg_len;
931 num_ndef_bytes = 0;
932 last_ndef_byte_offset = p_t2t->ndef_header_offset;
933
934 /* Locate NDEF final block based on the size of new NDEF Message */
935 while (num_ndef_bytes < total_ndef_bytes) {
936 if (rw_t2t_is_lock_res_byte((uint16_t)(last_ndef_byte_offset)) == false)
937 num_ndef_bytes++;
938
939 last_ndef_byte_offset++;
940 }
941 p_t2t->ndef_last_block_num =
942 (uint16_t)((last_ndef_byte_offset - 1) / T2T_BLOCK_SIZE);
943
944 if ((p_t2t->new_ndef_msg_len + 1) <= p_t2t->max_ndef_msg_len) {
945 /* Locate Terminator TLV Block */
946 terminator_tlv_byte_index = last_ndef_byte_offset;
947
948 if (rw_t2t_is_lock_res_byte((uint16_t)terminator_tlv_byte_index) == false)
949 p_t2t->terminator_byte_index = terminator_tlv_byte_index;
950 else
951 p_t2t->terminator_byte_index = 0x00;
952 } else {
953 /* No space for Terminator TLV */
954 p_t2t->terminator_byte_index = 0x00;
955 }
956
957 return status;
958 }
959
960 /*******************************************************************************
961 **
962 ** Function rw_t2t_read_ndef_next_block
963 **
964 ** Description This function will read the tag block passed as argument
965 **
966 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
967 **
968 *******************************************************************************/
rw_t2t_read_ndef_next_block(uint16_t block)969 tNFC_STATUS rw_t2t_read_ndef_next_block(uint16_t block) {
970 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
971 tNFC_STATUS status;
972
973 /* Send read command to read base block (Block % 4==0) where this block is
974 * also read as part of 16 bytes */
975 block -= block % T2T_READ_BLOCKS;
976
977 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK;
978 /* Read the block */
979 status = rw_t2t_read(block);
980
981 return status;
982 }
983
984 /*******************************************************************************
985 **
986 ** Function rw_t2t_is_read_before_write_block
987 **
988 ** Description This function will check if the block has to be read before
989 ** writting to avoid over writting in to lock/reserved bytes
990 ** present in the block.
991 ** If no bytes in the block can be overwritten it moves in to
992 ** next block and check. Finally it finds a block where part of
993 ** ndef bytes can exist and check if the whole block can be
994 ** updated or only part of block can be modified.
995 **
996 ** Returns TRUE, if the block returned should be read before writting
997 ** FALSE, if the block need not be read as it was already
998 ** read or during NDEF write we may completely overwrite
999 ** the block and there is no reserved or locked bytes in
1000 ** that block
1001 **
1002 *******************************************************************************/
rw_t2t_is_read_before_write_block(uint16_t block,uint16_t * p_block_to_read)1003 static bool rw_t2t_is_read_before_write_block(uint16_t block,
1004 uint16_t* p_block_to_read) {
1005 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1006 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1007 uint8_t count;
1008 uint8_t index;
1009 uint16_t tag_size = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1010 bool read_before_write = true;
1011
1012 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1013 /* First NDEF block is already read */
1014 read_before_write = false;
1015 memcpy(p_t2t->ndef_read_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1016 } else if (block == p_t2t->ndef_last_block_num) {
1017 /* Last NDEF block is already read */
1018 read_before_write = false;
1019 memcpy(p_t2t->ndef_read_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1020 } else if (block == p_t2t->terminator_byte_index / T2T_BLOCK_SIZE) {
1021 /* Terminator tlv block is already read */
1022 read_before_write = false;
1023 memcpy(p_t2t->ndef_read_block, p_t2t->terminator_tlv_block, T2T_BLOCK_SIZE);
1024 } else {
1025 count = 0;
1026 while (block < tag_size) {
1027 index = 0;
1028
1029 while (index < T2T_BLOCK_SIZE) {
1030 /* check if it is a reserved or locked byte */
1031 if (rw_t2t_is_lock_res_byte(
1032 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1033 count++;
1034 }
1035 index++;
1036 }
1037 if (count == T2T_BLOCK_SIZE) {
1038 /* All the bytes in the block are free to NDEF write */
1039 read_before_write = false;
1040 break;
1041 } else if (count == 0) {
1042 /* The complete block is not free for NDEF write */
1043 index = 0;
1044 block++;
1045 } else {
1046 /* The block has reseved byte (s) or locked byte (s) or both */
1047 read_before_write = true;
1048 break;
1049 }
1050 }
1051 }
1052 /* Return the block to read next before NDEF write */
1053 *p_block_to_read = block;
1054 return read_before_write;
1055 }
1056
1057 /*******************************************************************************
1058 **
1059 ** Function rw_t2t_write_ndef_first_block
1060 **
1061 ** Description This function will write the first NDEF block with Length
1062 ** field reset to zero.
1063 ** Also after writting NDEF this function may be called to
1064 ** update new NDEF length
1065 **
1066 ** Returns NCI_STATUS_OK, if write was started.
1067 ** Otherwise, error status.
1068 **
1069 *******************************************************************************/
rw_t2t_write_ndef_first_block(uint16_t msg_len,bool b_update_len)1070 tNFC_STATUS rw_t2t_write_ndef_first_block(uint16_t msg_len, bool b_update_len) {
1071 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1072 uint8_t new_lengthfield_len;
1073 uint8_t write_block[4];
1074 uint8_t block;
1075 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1076 uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1077 tNFC_STATUS status;
1078 uint8_t length_field[3];
1079 uint8_t index;
1080
1081 p_t2t->work_offset = 0;
1082 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1083 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1084 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1085 if (new_lengthfield_len == 3) {
1086 /* New NDEF is Long NDEF */
1087 if (msg_len == 0) {
1088 /* Clear NDEF length field */
1089 length_field[0] = 0x00;
1090 length_field[1] = 0x00;
1091 length_field[2] = 0x00;
1092 } else {
1093 /* Update NDEF length field with new NDEF Msg len */
1094 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1095 length_field[1] = (uint8_t)(msg_len >> 8);
1096 length_field[2] = (uint8_t)(msg_len);
1097 }
1098 } else {
1099 /* New NDEF is Short NDEF */
1100 length_field[0] = (uint8_t)(msg_len);
1101 }
1102
1103 /* updating ndef_first_block with new ndef message */
1104 memcpy(write_block, p_t2t->ndef_first_block, T2T_BLOCK_SIZE);
1105
1106 index = p_t2t->ndef_header_offset % T2T_BLOCK_SIZE;
1107 block = (uint8_t)(p_t2t->ndef_header_offset / T2T_BLOCK_SIZE);
1108
1109 while (p_t2t->work_offset == 0 && block < total_blocks) {
1110 /* update length field */
1111 while (index < T2T_BLOCK_SIZE &&
1112 p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1113 if (rw_t2t_is_lock_res_byte(
1114 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1115 write_block[index] = length_field[p_t2t->work_offset];
1116 p_t2t->work_offset++;
1117 }
1118 index++;
1119 if (p_t2t->work_offset == new_lengthfield_len) {
1120 break;
1121 }
1122 }
1123 /* If more space in this block then add ndef message */
1124 while (index < T2T_BLOCK_SIZE &&
1125 p_t2t->work_offset <
1126 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1127 if (rw_t2t_is_lock_res_byte(
1128 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1129 write_block[index] =
1130 p_t2t->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1131 p_t2t->work_offset++;
1132 }
1133 index++;
1134 }
1135 if (p_t2t->work_offset == 0) {
1136 /* If no bytes are written move to next block */
1137 index = 0;
1138 block++;
1139 if (block == p_t2t->ndef_last_block_num) {
1140 memcpy(write_block, p_t2t->ndef_last_block, T2T_BLOCK_SIZE);
1141 }
1142 }
1143 }
1144 if (p_t2t->work_offset == 0) {
1145 status = NFC_STATUS_FAILED;
1146 } else {
1147 rw_t2t_update_cb(block, write_block, b_update_len);
1148 /* Update the identified block with newly prepared data */
1149 status = rw_t2t_write(block, write_block);
1150 if (status == NFC_STATUS_OK) {
1151 p_t2t->b_read_data = false;
1152 }
1153 }
1154 return status;
1155 }
1156
1157 /*******************************************************************************
1158 **
1159 ** Function rw_t2t_write_ndef_next_block
1160 **
1161 ** Description This function can be called to write an NDEF message block
1162 **
1163 ** Returns NCI_STATUS_OK, if write was started.
1164 ** Otherwise, error status.
1165 **
1166 *******************************************************************************/
rw_t2t_write_ndef_next_block(uint16_t block,uint16_t msg_len,bool b_update_len)1167 tNFC_STATUS rw_t2t_write_ndef_next_block(uint16_t block, uint16_t msg_len,
1168 bool b_update_len) {
1169 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1170 uint8_t new_lengthfield_len;
1171 uint8_t write_block[4];
1172 uint8_t* p_cc = &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE];
1173 uint16_t total_blocks = p_cc[2] * 2 + T2T_FIRST_DATA_BLOCK;
1174 uint16_t initial_offset;
1175 uint8_t length_field[3];
1176 uint8_t index;
1177 tNFC_STATUS status;
1178
1179 /* Write NDEF Message */
1180 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1181 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1182 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1183
1184 index = 0;
1185
1186 memcpy(write_block, p_t2t->ndef_read_block, T2T_BLOCK_SIZE);
1187
1188 if (p_t2t->work_offset >= new_lengthfield_len) {
1189 /* Length field is updated, write ndef message field */
1190 initial_offset = p_t2t->work_offset;
1191 while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1192 while (index < T2T_BLOCK_SIZE &&
1193 p_t2t->work_offset <
1194 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1195 if (rw_t2t_is_lock_res_byte(
1196 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1197 write_block[index] =
1198 p_t2t
1199 ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1200 p_t2t->work_offset++;
1201 }
1202 index++;
1203 }
1204 if (p_t2t->work_offset == initial_offset) {
1205 index = 0;
1206 block++;
1207 }
1208 }
1209 } else {
1210 /* Complete writting Length field and then write ndef message */
1211 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1212 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1213 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1214 if (new_lengthfield_len == 3) {
1215 /* New NDEF is Long NDEF */
1216 if (msg_len == 0) {
1217 length_field[0] = 0x00;
1218 length_field[1] = 0x00;
1219 length_field[2] = 0x00;
1220 } else {
1221 length_field[0] = T2T_LONG_NDEF_LEN_FIELD_BYTE0;
1222 length_field[1] = (uint8_t)(msg_len >> 8);
1223 length_field[2] = (uint8_t)(msg_len);
1224 }
1225 } else {
1226 /* New NDEF is short NDEF */
1227 length_field[0] = (uint8_t)(msg_len);
1228 }
1229 initial_offset = p_t2t->work_offset;
1230 while (p_t2t->work_offset == initial_offset && block < total_blocks) {
1231 /* Update length field */
1232 while (index < T2T_BLOCK_SIZE &&
1233 p_t2t->work_offset < p_t2t->new_ndef_msg_len) {
1234 if (rw_t2t_is_lock_res_byte(
1235 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1236 write_block[index] = length_field[p_t2t->work_offset];
1237 p_t2t->work_offset++;
1238 }
1239 index++;
1240 if (p_t2t->work_offset == new_lengthfield_len) {
1241 break;
1242 }
1243 }
1244 /* Update ndef message field */
1245 while (index < T2T_BLOCK_SIZE &&
1246 p_t2t->work_offset <
1247 (p_t2t->new_ndef_msg_len + new_lengthfield_len)) {
1248 if (rw_t2t_is_lock_res_byte(
1249 (uint16_t)((block * T2T_BLOCK_SIZE) + index)) == false) {
1250 write_block[index] =
1251 p_t2t
1252 ->p_new_ndef_buffer[p_t2t->work_offset - new_lengthfield_len];
1253 p_t2t->work_offset++;
1254 }
1255 index++;
1256 }
1257 if (p_t2t->work_offset == initial_offset) {
1258 index = 0;
1259 block++;
1260 }
1261 }
1262 }
1263 if (p_t2t->work_offset == initial_offset) {
1264 status = NFC_STATUS_FAILED;
1265 } else {
1266 rw_t2t_update_cb(block, write_block, b_update_len);
1267 /* Write the NDEF Block */
1268 status = rw_t2t_write(block, write_block);
1269 }
1270
1271 return status;
1272 }
1273
1274 /*******************************************************************************
1275 **
1276 ** Function rw_t2t_update_cb
1277 **
1278 ** Description This function can be called to write an NDEF message block
1279 **
1280 ** Returns NCI_STATUS_OK, if write was started.
1281 ** Otherwise, error status.
1282 **
1283 *******************************************************************************/
rw_t2t_update_cb(uint16_t block,uint8_t * p_write_block,bool b_update_len)1284 static void rw_t2t_update_cb(uint16_t block, uint8_t* p_write_block,
1285 bool b_update_len) {
1286 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1287 uint8_t new_lengthfield_len;
1288
1289 /* Write NDEF Message */
1290 new_lengthfield_len = p_t2t->new_ndef_msg_len >= T2T_LONG_NDEF_MIN_LEN
1291 ? T2T_LONG_NDEF_LEN_FIELD_LEN
1292 : T2T_SHORT_NDEF_LEN_FIELD_LEN;
1293
1294 if (block == p_t2t->ndef_header_offset / T2T_BLOCK_SIZE) {
1295 /* Update ndef first block if the 'block' points to ndef first block */
1296 memcpy(p_t2t->ndef_first_block, p_write_block, T2T_BLOCK_SIZE);
1297 }
1298 if (p_t2t->terminator_byte_index / T2T_BLOCK_SIZE == block) {
1299 /* Update terminator block if the 'block' points to terminator tlv block */
1300 memcpy(p_t2t->terminator_tlv_block, p_write_block, T2T_BLOCK_LEN);
1301 }
1302 if (b_update_len == false) {
1303 if (block == p_t2t->ndef_last_block_num) {
1304 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK;
1305 p_t2t->work_offset = 0;
1306 /* Update ndef final block if the 'block' points to ndef final block */
1307 memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1308 } else {
1309 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK;
1310 }
1311 } else {
1312 if (block == p_t2t->ndef_last_block_num) {
1313 /* Update the backup of Ndef final block TLV block */
1314 memcpy(p_t2t->ndef_last_block, p_write_block, T2T_BLOCK_SIZE);
1315 }
1316
1317 if (p_t2t->work_offset >= new_lengthfield_len) {
1318 if (p_t2t->terminator_byte_index != 0) {
1319 /* Add Terminator TLV as part of NDEF Write operation */
1320 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK;
1321 } else {
1322 /* Skip adding Terminator TLV */
1323 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1324 }
1325 } else {
1326 /* Part of NDEF Message Len should be added in the next block */
1327 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK;
1328 }
1329 }
1330 }
1331
1332 /*******************************************************************************
1333 **
1334 ** Function rw_t2t_get_ndef_flags
1335 **
1336 ** Description Prepare NDEF Flags
1337 **
1338 ** Returns NDEF Flag value
1339 **
1340 *******************************************************************************/
rw_t2t_get_ndef_flags(void)1341 static uint8_t rw_t2t_get_ndef_flags(void) {
1342 uint8_t flags = 0;
1343 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1344 const tT2T_INIT_TAG* p_ret;
1345
1346 flags |= RW_NDEF_FL_SUPPORTED;
1347
1348 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC) ||
1349 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == 0))
1350 flags |= RW_NDEF_FL_FORMATABLE;
1351
1352 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO)
1353 flags |= RW_NDEF_FL_READ_ONLY;
1354
1355 if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != nullptr) &&
1356 (p_ret->b_otp)) {
1357 /* Set otp flag */
1358 flags |= RW_NDEF_FL_OTP;
1359
1360 /* Set Read only flag if otp tag already has NDEF Message */
1361 if (p_t2t->ndef_msg_len) flags |= RW_NDEF_FL_READ_ONLY;
1362 }
1363 return flags;
1364 }
1365
1366 /*******************************************************************************
1367 **
1368 ** Function rw_t2t_get_ndef_max_size
1369 **
1370 ** Description Calculate maximum size of NDEF message that can be written
1371 ** on to the tag
1372 **
1373 ** Returns Maximum size of NDEF Message
1374 **
1375 *******************************************************************************/
rw_t2t_get_ndef_max_size(void)1376 static uint16_t rw_t2t_get_ndef_max_size(void) {
1377 uint16_t offset;
1378 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1379 uint16_t tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR);
1380
1381 DLOG_IF(INFO, nfc_debug_enabled)
1382 << StringPrintf("%s - T2T_Area size: %d", __func__, tag_size);
1383
1384 /* Add header to compute max T2T NDEF data offset */
1385 tag_size += (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_LEN);
1386
1387 offset = p_t2t->ndef_msg_offset;
1388 p_t2t->max_ndef_msg_len = 0;
1389
1390 if ((tag_size <= T2T_STATIC_SIZE) ||
1391 ((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN) &&
1392 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0))) {
1393 /* Tag not formated, assume static tag */
1394 p_t2t->max_ndef_msg_len = T2T_STATIC_SIZE - T2T_HEADER_SIZE -
1395 T2T_TLV_TYPE_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN;
1396 DLOG_IF(INFO, nfc_debug_enabled)
1397 << StringPrintf("%s - Tag assumed static : max_ndef_msg_len=%d",
1398 __func__, p_t2t->max_ndef_msg_len);
1399 return p_t2t->max_ndef_msg_len;
1400 }
1401
1402 /* Starting from NDEF Message offset find the first locked data byte */
1403 while (offset < tag_size) {
1404 if (rw_t2t_is_lock_res_byte((uint16_t)offset) == false) {
1405 p_t2t->max_ndef_msg_len++;
1406 }
1407 offset++;
1408 }
1409
1410 /* NDEF Length field length changes based on NDEF size */
1411 if ((p_t2t->max_ndef_msg_len >= T2T_LONG_NDEF_LEN_FIELD_BYTE0) &&
1412 ((p_t2t->ndef_msg_offset - p_t2t->ndef_header_offset) ==
1413 T2T_SHORT_NDEF_LEN_FIELD_LEN)) {
1414 p_t2t->max_ndef_msg_len -=
1415 (T2T_LONG_NDEF_LEN_FIELD_LEN - T2T_SHORT_NDEF_LEN_FIELD_LEN);
1416 }
1417
1418 DLOG_IF(INFO, nfc_debug_enabled)
1419 << StringPrintf("%s - Max NDEF data storage: max_ndef_msg_len=%d",
1420 __func__, p_t2t->max_ndef_msg_len);
1421
1422 return p_t2t->max_ndef_msg_len;
1423 }
1424
1425 /*******************************************************************************
1426 **
1427 ** Function rw_t2t_add_terminator_tlv
1428 **
1429 ** Description This function will add terminator TLV after NDEF Message
1430 **
1431 ** Returns NCI_STATUS_OK, if write was started.
1432 ** Otherwise, error status.
1433 **
1434 *******************************************************************************/
rw_t2t_add_terminator_tlv(void)1435 tNFC_STATUS rw_t2t_add_terminator_tlv(void) {
1436 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1437 tNFC_STATUS status;
1438 uint16_t block;
1439 uint8_t term_byte_idx;
1440
1441 /* Add Terminator TLV after NDEF Message */
1442 block = p_t2t->terminator_byte_index / T2T_BLOCK_LEN;
1443
1444 if (block == p_t2t->ndef_last_block_num) {
1445 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1446 "%s - Terminator TLV in same block %d as last NDEF"
1447 " bytes",
1448 __func__, block);
1449
1450 /* If Terminator TLV will reside on the NDEF Final block */
1451 memcpy(p_t2t->terminator_tlv_block, p_t2t->ndef_last_block, T2T_BLOCK_LEN);
1452
1453 term_byte_idx = p_t2t->terminator_byte_index % T2T_BLOCK_LEN;
1454
1455 p_t2t->terminator_tlv_block[term_byte_idx] = TAG_TERMINATOR_TLV;
1456 if (term_byte_idx < (T2T_BLOCK_LEN - 1)) {
1457 for (int i = term_byte_idx + 1; i < T2T_BLOCK_LEN; i++)
1458 p_t2t->terminator_tlv_block[i] = 0x00;
1459 }
1460
1461 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1462 status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
1463
1464 } else if (p_t2t->terminator_byte_index != 0) {
1465 /* If there is space for Terminator TLV and if it will reside outside
1466 * NDEF Final block */
1467 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1468 "%s - Terminator TLV in block %d following the last NDEF block",
1469 __func__, block);
1470 p_t2t->terminator_tlv_block[0] = TAG_TERMINATOR_TLV;
1471 p_t2t->terminator_tlv_block[1] = 0x00;
1472 p_t2t->terminator_tlv_block[2] = 0x00;
1473 p_t2t->terminator_tlv_block[3] = 0x00;
1474
1475 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT;
1476 status = rw_t2t_write(block, p_t2t->terminator_tlv_block);
1477
1478 } else {
1479 /* If there is no space for Terminator TLV, conclude NDEF procedure */
1480 status = NFC_STATUS_CONTINUE;
1481 }
1482
1483 return status;
1484 }
1485
1486 /*******************************************************************************
1487 **
1488 ** Function rw_t2t_handle_ndef_read_rsp
1489 **
1490 ** Description This function handles reading an NDEF message.
1491 **
1492 ** Returns none
1493 **
1494 *******************************************************************************/
rw_t2t_handle_ndef_read_rsp(uint8_t * p_data)1495 static void rw_t2t_handle_ndef_read_rsp(uint8_t* p_data) {
1496 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1497 tRW_READ_DATA evt_data;
1498 uint16_t len;
1499 uint16_t offset;
1500 bool failed = false;
1501 bool done = false;
1502
1503 /* On the first read, adjust for any partial block offset */
1504 offset = 0;
1505 len = T2T_READ_DATA_LEN;
1506
1507 if (p_t2t->work_offset == 0) {
1508 /* The Ndef Message offset may be present in the read 16 bytes */
1509 offset = (p_t2t->ndef_msg_offset - (p_t2t->block_read * T2T_BLOCK_SIZE));
1510 }
1511
1512 /* Skip all reserved and lock bytes */
1513 while ((offset < len) && (p_t2t->work_offset < p_t2t->ndef_msg_len))
1514
1515 {
1516 if (rw_t2t_is_lock_res_byte(
1517 (uint16_t)(offset + p_t2t->block_read * T2T_BLOCK_LEN)) == false) {
1518 /* Collect the NDEF Message */
1519 p_t2t->p_ndef_buffer[p_t2t->work_offset] = p_data[offset];
1520 p_t2t->work_offset++;
1521 }
1522 offset++;
1523 }
1524
1525 if (p_t2t->work_offset >= p_t2t->ndef_msg_len) {
1526 done = true;
1527 p_t2t->ndef_status = T2T_NDEF_READ;
1528 } else {
1529 /* Read next 4 blocks */
1530 if (rw_t2t_read((uint16_t)(p_t2t->block_read + T2T_READ_BLOCKS)) !=
1531 NFC_STATUS_OK)
1532 failed = true;
1533 }
1534
1535 if (failed || done) {
1536 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1537 evt_data.p_data = nullptr;
1538 rw_t2t_handle_op_complete();
1539 tRW_DATA rw_data;
1540 rw_data.data = evt_data;
1541 (*rw_cb.p_cback)(RW_T2T_NDEF_READ_EVT, &rw_data);
1542 }
1543 }
1544
1545 /*******************************************************************************
1546 **
1547 ** Function rw_t2t_handle_ndef_write_rsp
1548 **
1549 ** Description Handle response received to reading (or part of) NDEF
1550 ** message.
1551 **
1552 ** Returns none
1553 **
1554 *******************************************************************************/
rw_t2t_handle_ndef_write_rsp(uint8_t * p_data)1555 static void rw_t2t_handle_ndef_write_rsp(uint8_t* p_data) {
1556 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1557 tRW_READ_DATA evt_data;
1558 bool failed = false;
1559 bool done = false;
1560 uint16_t block;
1561 uint8_t offset;
1562 tNFC_STATUS status = NFC_STATUS_FAILED;
1563
1564 switch (p_t2t->substate) {
1565 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK:
1566
1567 /* Backup the read NDEF first block */
1568 memcpy(p_t2t->ndef_first_block, p_data, T2T_BLOCK_LEN);
1569 /* Read ndef final block */
1570 if (rw_t2t_read_ndef_last_block() != NFC_STATUS_OK) failed = true;
1571 memset(p_t2t->terminator_tlv_block, 0, T2T_BLOCK_LEN);
1572
1573 if (rw_t2t_write_ndef_first_block(0x0000, false) != NFC_STATUS_OK)
1574 failed = true;
1575 break;
1576
1577 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_NEXT_BLOCK:
1578
1579 offset = (uint8_t)(p_t2t->ndef_read_block_num - p_t2t->block_read) *
1580 T2T_BLOCK_SIZE;
1581 /* Backup read block */
1582 memcpy(p_t2t->ndef_read_block, &p_data[offset], T2T_BLOCK_LEN);
1583
1584 /* Update the block with new NDEF Message */
1585 if (rw_t2t_write_ndef_next_block(p_t2t->ndef_read_block_num, 0x0000,
1586 false) != NFC_STATUS_OK)
1587 failed = true;
1588 break;
1589
1590 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_NEXT_BLOCK:
1591 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK:
1592 if (rw_t2t_is_read_before_write_block(
1593 (uint16_t)(p_t2t->block_written + 1), &block) == true) {
1594 p_t2t->ndef_read_block_num = block;
1595 /* If only part of the block is going to be updated read the block to
1596 retain previous data for
1597 unchanged part of the block */
1598 if (rw_t2t_read_ndef_next_block(block) != NFC_STATUS_OK) failed = true;
1599 } else {
1600 if (p_t2t->substate == RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_NEXT_BLOCK) {
1601 /* Directly write the block with new NDEF contents as whole block is
1602 * going to be updated */
1603 if (rw_t2t_write_ndef_next_block(block, p_t2t->new_ndef_msg_len,
1604 true) != NFC_STATUS_OK)
1605 failed = true;
1606 } else {
1607 /* Directly write the block with new NDEF contents as whole block is
1608 * going to be updated */
1609 if (rw_t2t_write_ndef_next_block(block, 0x0000, false) !=
1610 NFC_STATUS_OK)
1611 failed = true;
1612 }
1613 }
1614 break;
1615
1616 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LAST_BLOCK:
1617 /* Write the next block for new NDEF Message */
1618 p_t2t->ndef_write_block = p_t2t->ndef_header_offset / T2T_BLOCK_SIZE;
1619 if (rw_t2t_is_read_before_write_block((uint16_t)(p_t2t->ndef_write_block),
1620 &block) == true) {
1621 /* If only part of the block is going to be updated read the block to
1622 retain previous data for
1623 part of the block thats not going to be changed */
1624 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK;
1625 if (rw_t2t_read(block) != NFC_STATUS_OK) failed = true;
1626
1627 } else {
1628 /* Update NDEF Message Length in the Tag */
1629 if (rw_t2t_write_ndef_first_block(p_t2t->new_ndef_msg_len, true) !=
1630 NFC_STATUS_OK)
1631 failed = true;
1632 }
1633 break;
1634
1635 case RW_T2T_SUBSTATE_WAIT_READ_NDEF_LEN_BLOCK:
1636 /* Backup read block */
1637 memcpy(p_t2t->ndef_read_block, p_data, T2T_BLOCK_LEN);
1638
1639 /* Update the block with new NDEF Message */
1640 if (rw_t2t_write_ndef_next_block(p_t2t->block_read,
1641 p_t2t->new_ndef_msg_len,
1642 true) == NFC_STATUS_OK)
1643 p_t2t->ndef_write_block = p_t2t->block_read + 1;
1644 else
1645 failed = true;
1646
1647 break;
1648
1649 case RW_T2T_SUBSTATE_WAIT_WRITE_NDEF_LEN_BLOCK:
1650 status = rw_t2t_add_terminator_tlv();
1651 if (status == NFC_STATUS_CONTINUE)
1652 done = true;
1653 else if (status != NFC_STATUS_OK)
1654 failed = true;
1655 break;
1656
1657 case RW_T2T_SUBSTATE_WAIT_WRITE_TERM_TLV_CMPLT:
1658 done = true;
1659 break;
1660
1661 default:
1662 break;
1663 }
1664
1665 if (failed || done) {
1666 evt_data.p_data = nullptr;
1667 /* NDEF WRITE Operation is done, inform up the stack */
1668 evt_data.status = failed ? NFC_STATUS_FAILED : NFC_STATUS_OK;
1669 if (done) {
1670 if ((p_t2t->ndef_msg_len >= 0x00FF) &&
1671 (p_t2t->new_ndef_msg_len < 0x00FF)) {
1672 p_t2t->ndef_msg_offset -= 2;
1673 } else if ((p_t2t->new_ndef_msg_len >= 0x00FF) &&
1674 (p_t2t->ndef_msg_len < 0x00FF)) {
1675 p_t2t->ndef_msg_offset += 2;
1676 }
1677 p_t2t->ndef_msg_len = p_t2t->new_ndef_msg_len;
1678 }
1679 rw_t2t_handle_op_complete();
1680 tRW_DATA rw_data;
1681 rw_data.data = evt_data;
1682 (*rw_cb.p_cback)(RW_T2T_NDEF_WRITE_EVT, &rw_data);
1683 }
1684 }
1685
1686 /*******************************************************************************
1687 **
1688 ** Function rw_t2t_get_tag_size
1689 **
1690 ** Description This function calculates tag data area size from data read
1691 ** from block with version number
1692 **
1693 ** Returns TMS of the tag
1694 **
1695 *******************************************************************************/
rw_t2t_get_tag_size(uint8_t * p_data)1696 static uint8_t rw_t2t_get_tag_size(uint8_t* p_data) {
1697 uint16_t LchunkSize = 0;
1698 uint16_t Num_LChuncks = 0;
1699 uint16_t tms = 0;
1700
1701 LchunkSize = (uint16_t)p_data[2] << 8 | p_data[3];
1702 Num_LChuncks = (uint16_t)p_data[4] << 8 | p_data[5];
1703
1704 tms = (uint16_t)(LchunkSize * Num_LChuncks);
1705
1706 tms += (T2T_STATIC_SIZE - T2T_HEADER_SIZE);
1707
1708 tms /= 0x08;
1709
1710 return (uint8_t)tms;
1711 }
1712
1713 /*******************************************************************************
1714 **
1715 ** Function rw_t2t_handle_config_tag_readonly
1716 **
1717 ** Description This function handles configure type 2 tag as read only
1718 **
1719 ** Returns none
1720 **
1721 *******************************************************************************/
rw_t2t_handle_config_tag_readonly(uint8_t * p_data)1722 static void rw_t2t_handle_config_tag_readonly(uint8_t* p_data) {
1723 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1724 tNFC_STATUS status = NFC_STATUS_FAILED;
1725 bool b_notify = false;
1726 uint8_t write_block[T2T_BLOCK_SIZE];
1727 bool b_pending = false;
1728 uint8_t num_locks = 0;
1729 uint16_t offset;
1730
1731 switch (p_t2t->substate) {
1732 case RW_T2T_SUBSTATE_WAIT_READ_CC:
1733
1734 /* First soft lock the tag */
1735 rw_t2t_soft_lock_tag();
1736 if (p_t2t->b_hard_lock) {
1737 /* Tag configuration not complete */
1738 status = NFC_STATUS_OK;
1739 }
1740 break;
1741
1742 case RW_T2T_SUBSTATE_WAIT_SET_CC_RO:
1743
1744 /* Successfully soft locked! Update Tag header for future reference */
1745 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] = T2T_CC3_RWA_RO;
1746 if (!p_t2t->b_hard_lock) {
1747 /* Tag configuration complete */
1748 status = NFC_STATUS_OK;
1749 b_notify = true;
1750 break;
1751 } else {
1752 /* Tag configuration not complete */
1753 status = NFC_STATUS_OK;
1754 /* Copy the internal bytes */
1755 memcpy(write_block,
1756 &p_t2t->tag_hdr[T2T_STATIC_LOCK0 - T2T_INTERNAL_BYTES_LEN],
1757 T2T_INTERNAL_BYTES_LEN);
1758 /* Set all Static lock bits */
1759 write_block[T2T_STATIC_LOCK0 % T2T_BLOCK_SIZE] = 0xFF;
1760 write_block[T2T_STATIC_LOCK1 % T2T_BLOCK_SIZE] = 0xFF;
1761 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
1762 status = rw_t2t_write((T2T_STATIC_LOCK0 / T2T_BLOCK_SIZE), write_block);
1763 }
1764 break;
1765
1766 case RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS:
1767
1768 num_locks = 0;
1769
1770 while (num_locks < p_t2t->num_lockbytes) {
1771 if (p_t2t->lockbyte[num_locks].lock_status ==
1772 RW_T2T_LOCK_UPDATE_INITIATED) {
1773 /* Update control block as one or more dynamic lock byte (s) are set
1774 */
1775 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_UPDATED;
1776 }
1777 if (!b_pending &&
1778 p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
1779 /* One or more dynamic lock bits are not set */
1780 if (num_locks == 0) {
1781 offset = p_t2t->lock_tlv[p_t2t->lockbyte[0].tlv_index].offset +
1782 p_t2t->lockbyte[0].byte_index;
1783 if (offset % T2T_BLOCK_SIZE) {
1784 /* For backward compatibility in case the DynLock_Area is not
1785 * aligned to a block boundary, first read the block not to
1786 * overwrite possible NDEF or Reserved data
1787 */
1788 b_pending = true;
1789 } else {
1790 /* Write zero in internal byte */
1791 memset(write_block, 0, T2T_BLOCK_SIZE);
1792 }
1793 }
1794 }
1795 num_locks++;
1796 }
1797
1798 if (b_pending) {
1799 /* Read the block where dynamic lock bits are present to avoid writing
1800 * to NDEF bytes in the same block */
1801 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK;
1802 status = rw_t2t_read((uint16_t)(offset / T2T_BLOCK_LEN));
1803 } else {
1804 /* Now set the dynamic lock bits present in the block read now */
1805 status = rw_t2t_set_dynamic_lock_bits(write_block);
1806 if (status == NFC_STATUS_CONTINUE) {
1807 /* Tag configuration complete */
1808 status = NFC_STATUS_OK;
1809 b_notify = true;
1810 }
1811 }
1812
1813 break;
1814
1815 case RW_T2T_SUBSTATE_WAIT_READ_DYN_LOCK_BYTE_BLOCK:
1816 /* Now set the dynamic lock bits present in the block read now */
1817 status = rw_t2t_set_dynamic_lock_bits(p_data);
1818 break;
1819 }
1820
1821 if (status != NFC_STATUS_OK || b_notify) {
1822 /* Notify upper layer the result of Configuring Tag as Read only */
1823 tRW_DATA evt;
1824 evt.status = status;
1825 rw_t2t_handle_op_complete();
1826 (*rw_cb.p_cback)(RW_T2T_SET_TAG_RO_EVT, &evt);
1827 }
1828 }
1829
1830 /*******************************************************************************
1831 **
1832 ** Function rw_t2t_handle_format_tag_rsp
1833 **
1834 ** Description This function handles formating a type 2 tag
1835 **
1836 ** Returns none
1837 **
1838 *******************************************************************************/
rw_t2t_handle_format_tag_rsp(uint8_t * p_data)1839 static void rw_t2t_handle_format_tag_rsp(uint8_t* p_data) {
1840 uint8_t* p;
1841 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1842 tNFC_STATUS status = NFC_STATUS_FAILED;
1843 uint16_t version_no;
1844 const tT2T_INIT_TAG* p_ret;
1845 uint8_t tms;
1846 uint8_t next_block = T2T_FIRST_DATA_BLOCK + 1;
1847 uint16_t addr, locked_area;
1848 bool b_notify = false;
1849
1850 p = p_t2t->ndef_final_block;
1851 UINT8_TO_BE_STREAM(p, p_t2t->tlv_value[2]);
1852
1853 switch (p_t2t->substate) {
1854 case RW_T2T_SUBSTATE_WAIT_READ_CC:
1855 /* Start format operation */
1856 status = rw_t2t_format_tag();
1857 break;
1858
1859 case RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO:
1860
1861 memcpy(p_t2t->tag_data, p_data, T2T_READ_DATA_LEN);
1862 p_t2t->b_read_data = true;
1863 version_no = (uint16_t)p_data[0] << 8 | p_data[1];
1864 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no);
1865 if (p_ret != nullptr) {
1866 /* Valid Version Number */
1867 if (p_ret->b_calc_cc) /* Calculate tag size from Version Information */
1868 tms = rw_t2t_get_tag_size(p_data);
1869
1870 else
1871 /* Tag size from Look up table */
1872 tms = p_ret->tms;
1873
1874 /* Set CC with the Tag size from look up table or from calculated value
1875 */
1876 status = rw_t2t_set_cc(tms);
1877 }
1878 break;
1879
1880 case RW_T2T_SUBSTATE_WAIT_SET_CC:
1881
1882 version_no = (uint16_t)p_t2t->tag_data[0] << 8 | p_t2t->tag_data[1];
1883 if ((version_no == 0) ||
1884 ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], true, version_no)) ==
1885 nullptr) ||
1886 (!p_ret->b_multi_version) || (!p_ret->b_calc_cc)) {
1887 /* Currently Formating a non blank tag or a blank tag with manufacturer
1888 * has only one variant of tag. Set Null NDEF TLV and complete Format
1889 * Operation */
1890 next_block = T2T_FIRST_DATA_BLOCK;
1891 p = p_t2t->ndef_final_block;
1892 } else {
1893 addr = (uint16_t)(((uint16_t)p_t2t->tag_data[2] << 8 |
1894 p_t2t->tag_data[3]) *
1895 ((uint16_t)p_t2t->tag_data[4] << 8 |
1896 p_t2t->tag_data[5]) +
1897 T2T_STATIC_SIZE);
1898 locked_area = ((uint16_t)p_t2t->tag_data[2] << 8 | p_t2t->tag_data[3]) *
1899 ((uint16_t)p_t2t->tag_data[6]);
1900
1901 status = rw_t2t_set_lock_tlv(addr, p_t2t->tag_data[7], locked_area);
1902 if (status == NFC_STATUS_REJECTED) {
1903 /* Cannot calculate Lock TLV. Set Null NDEF TLV and complete Format
1904 * Operation */
1905 next_block = T2T_FIRST_DATA_BLOCK;
1906 p = p_t2t->ndef_final_block;
1907 } else
1908 break;
1909 }
1910 FALLTHROUGH_INTENDED;
1911
1912 case RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV:
1913
1914 /* Prepare NULL NDEF TLV, TERMINATOR_TLV */
1915 UINT8_TO_BE_STREAM(p, TAG_NDEF_TLV);
1916 UINT8_TO_BE_STREAM(p, 0);
1917
1918 if (((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) !=
1919 nullptr) &&
1920 (!p_ret->b_otp)) {
1921 UINT8_TO_BE_STREAM(p, TAG_TERMINATOR_TLV);
1922 } else
1923 UINT8_TO_BE_STREAM(p, 0);
1924
1925 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF;
1926 /* send WRITE-E8 command */
1927 status = rw_t2t_write(next_block, p_t2t->ndef_final_block);
1928 if (status == NFC_STATUS_OK) p_t2t->b_read_data = false;
1929 break;
1930
1931 case RW_T2T_SUBSTATE_WAIT_SET_NULL_NDEF:
1932 /* Tag Formated successfully */
1933 status = NFC_STATUS_OK;
1934 b_notify = true;
1935 break;
1936
1937 default:
1938 break;
1939 }
1940
1941 if (status != NFC_STATUS_OK || b_notify) {
1942 /* Notify upper layer the result of Format op */
1943 tRW_DATA evt;
1944 evt.status = status;
1945 rw_t2t_handle_op_complete();
1946 (*rw_cb.p_cback)(RW_T2T_FORMAT_CPLT_EVT, &evt);
1947 }
1948 }
1949
1950 /*******************************************************************************
1951 **
1952 ** Function rw_t2t_update_attributes
1953 **
1954 ** Description This function will update attribute for the current segment
1955 ** based on lock and reserved bytes
1956 **
1957 ** Returns None
1958 **
1959 *******************************************************************************/
rw_t2t_update_attributes(void)1960 static void rw_t2t_update_attributes(void) {
1961 uint8_t count = 0;
1962 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
1963 uint16_t lower_offset;
1964 uint16_t upper_offset;
1965 uint16_t offset;
1966 uint16_t offset_in_seg;
1967 uint16_t block_boundary;
1968 uint8_t num_internal_bytes;
1969 uint16_t num_bytes;
1970
1971 /* Prepare attr for the current segment */
1972 memset(p_t2t->attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
1973
1974 /* calculate offset where the current segment starts in the tag */
1975 lower_offset = p_t2t->segment * RW_T2T_SEGMENT_BYTES;
1976 /* calculate offset where the current segment ends in the tag */
1977 upper_offset = (p_t2t->segment + 1) * RW_T2T_SEGMENT_BYTES;
1978
1979 /* check offset of lock bytes in the tag and update p_t2t->attr
1980 * for every lock byte that is present in the current segment */
1981 count = 0;
1982 while (count < p_t2t->num_lockbytes) {
1983 offset = p_t2t->lock_tlv[p_t2t->lockbyte[count].tlv_index].offset +
1984 p_t2t->lockbyte[count].byte_index;
1985 if (offset >= lower_offset && offset < upper_offset) {
1986 /* Calculate offset in the current segment as p_t2t->attr is prepared for
1987 * one segment only */
1988 offset_in_seg = offset % RW_T2T_SEGMENT_BYTES;
1989 /* Every bit in p_t2t->attr indicates one byte of the tag is either a
1990 * lock/reserved byte or not
1991 * So, each array element in p_t2t->attr covers two blocks in the tag as
1992 * T2 block size is 4 and array element size is 8
1993 * Set the corresponding bit in attr to indicate - reserved byte */
1994 p_t2t->attr[offset_in_seg / TAG_BITS_PER_BYTE] |=
1995 rw_t2t_mask_bits[offset_in_seg % TAG_BITS_PER_BYTE];
1996 }
1997 count++;
1998 }
1999
2000 block_boundary = (offset + 1) % T2T_BLOCK_LEN;
2001 if (block_boundary) {
2002 /* End of DynLock_Area is not aligned to a block boundary. The bytes that
2003 * are not part of the area within the same block are Internal Bytes (see
2004 * [T2T-TS] section 4.7).
2005 * According to REQ 4.4.1.5, either write them to 00h or to their existing
2006 * values. However according to the NDEF Write procedure, REQ 7.5.5.5,
2007 * symbol 5, the Reader SHALL not write to the DynLock_Area and the
2008 * Rsvd_Area(s), as indicated by the Lock Control TLV or the Memory
2009 * Control TLVs, if any.
2010 * Choice is made to consider the bytes within the same block as the
2011 * DynLock_Area last bytes as lock bytes i.e. they will not be written
2012 * and therefore previously read (steps anyhow not expected by NFC Forum
2013 * Test Specifications).
2014 */
2015 num_internal_bytes = T2T_BLOCK_LEN - block_boundary;
2016 count = 1;
2017
2018 while (count <= num_internal_bytes) {
2019 offset++;
2020 if (offset >= lower_offset && offset < upper_offset) {
2021 /* Calculate offset in the current segment as p_t2t->attr is prepared
2022 * for one segment only */
2023 offset_in_seg = offset % RW_T2T_SEGMENT_BYTES;
2024 /* Every bit in p_t2t->attr indicates one byte of the tag is either a
2025 * lock/reserved/internal byte or not
2026 * So, each array element in p_t2t->attr covers two blocks in the tag as
2027 * T2 block size is 4 and array element size is 8
2028 * Set the corresponding bit in attr to indicate - reserved byte */
2029 p_t2t->attr[offset_in_seg / TAG_BITS_PER_BYTE] |=
2030 rw_t2t_mask_bits[offset_in_seg % TAG_BITS_PER_BYTE];
2031 }
2032 count++;
2033 }
2034 }
2035 /* Search reserved bytes identified by all memory tlvs present in the tag */
2036 count = 0;
2037 while (count < p_t2t->num_mem_tlvs) {
2038 /* check the offset of reserved bytes in the tag and update p_t2t->attr
2039 * for every reserved byte that is present in the current segment */
2040 num_bytes = 0;
2041 while (num_bytes < p_t2t->mem_tlv[count].num_bytes) {
2042 offset = p_t2t->mem_tlv[count].offset + num_bytes;
2043 if (offset >= lower_offset && offset < upper_offset) {
2044 /* Let offset represents offset in the current segment as p_t2t->attr is
2045 * prepared for one segment only */
2046 offset %= RW_T2T_SEGMENT_BYTES;
2047 /* Every bit in p_t2t->attr indicates one byte of the tag is either a
2048 * lock/reserved byte or not
2049 * So, each array element in p_t2t->attr covers two blocks in the tag as
2050 * T2 block size is 4 and array element size is 8
2051 * Set the corresponding bit in attr to indicate - reserved byte */
2052 p_t2t->attr[offset / TAG_BITS_PER_BYTE] |=
2053 rw_t2t_mask_bits[offset % TAG_BITS_PER_BYTE];
2054 }
2055 num_bytes++;
2056 }
2057 count++;
2058 }
2059 }
2060
2061 /*******************************************************************************
2062 **
2063 ** Function rw_t2t_get_lock_bits_for_segment
2064 **
2065 ** Description This function returns the offset of lock bits associated for
2066 ** the specified segment
2067 **
2068 ** Parameters: segment: The segment number to which lock bits are
2069 ** associated
2070 ** p_start_byte: The offset of lock byte that contains the
2071 ** first lock bit for the segment
2072 ** p_start_bit: The offset of the lock bit in the lock byte
2073 **
2074 ** p_end_byte: The offset of the last bit associcated to the
2075 ** segment
2076 **
2077 ** Returns Total number of lock bits assigned to the specified segment
2078 **
2079 *******************************************************************************/
rw_t2t_get_lock_bits_for_segment(uint8_t segment,uint8_t * p_start_byte,uint8_t * p_start_bit,uint8_t * p_end_byte)2080 static uint8_t rw_t2t_get_lock_bits_for_segment(uint8_t segment,
2081 uint8_t* p_start_byte,
2082 uint8_t* p_start_bit,
2083 uint8_t* p_end_byte) {
2084 uint8_t total_bits = 0;
2085 uint16_t byte_count = 0;
2086 uint16_t lower_offset, upper_offset;
2087 uint8_t num_dynamic_locks = 0;
2088 uint8_t bit_count = 0;
2089 uint16_t bytes_locked_per_bit;
2090 uint8_t num_bits;
2091 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2092 bool b_all_bits_are_locks = true;
2093 uint16_t tag_size;
2094 uint8_t xx;
2095
2096 tag_size = (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] * T2T_TMS_TAG_FACTOR) +
2097 (T2T_FIRST_DATA_BLOCK * T2T_BLOCK_SIZE) + p_t2t->num_lockbytes;
2098
2099 for (xx = 0; xx < p_t2t->num_mem_tlvs; xx++)
2100 tag_size += p_t2t->mem_tlv[xx].num_bytes;
2101
2102 lower_offset = segment * RW_T2T_SEGMENT_BYTES;
2103 if (segment == 0) {
2104 lower_offset += T2T_STATIC_SIZE;
2105 }
2106 upper_offset = (segment + 1) * RW_T2T_SEGMENT_BYTES;
2107
2108 byte_count = T2T_STATIC_SIZE;
2109 if (tag_size < upper_offset) {
2110 upper_offset = tag_size;
2111 }
2112
2113 *p_start_byte = num_dynamic_locks;
2114 *p_start_bit = 0;
2115
2116 while ((byte_count <= lower_offset) &&
2117 (num_dynamic_locks < p_t2t->num_lockbytes)) {
2118 bytes_locked_per_bit =
2119 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2120 .bytes_locked_per_bit;
2121 /* Number of bits in the current lock byte */
2122 b_all_bits_are_locks =
2123 ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2124 TAG_BITS_PER_BYTE <=
2125 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2126 .num_bits);
2127 num_bits =
2128 b_all_bits_are_locks
2129 ? TAG_BITS_PER_BYTE
2130 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2131 .num_bits %
2132 TAG_BITS_PER_BYTE;
2133
2134 if (((bytes_locked_per_bit * num_bits) + byte_count) <= lower_offset) {
2135 /* Skip this lock byte as it covers different segment */
2136 byte_count += bytes_locked_per_bit * num_bits;
2137 num_dynamic_locks++;
2138 } else {
2139 bit_count = 0;
2140 while (bit_count < num_bits) {
2141 byte_count += bytes_locked_per_bit;
2142 if (byte_count > lower_offset) {
2143 /* First lock bit that is used to lock this segment */
2144 *p_start_byte = num_dynamic_locks;
2145 *p_end_byte = num_dynamic_locks;
2146 *p_start_bit = bit_count;
2147 bit_count++;
2148 total_bits = 1;
2149 break;
2150 }
2151 bit_count++;
2152 }
2153 }
2154 }
2155 if (num_dynamic_locks == p_t2t->num_lockbytes) {
2156 return 0;
2157 }
2158 while ((byte_count < upper_offset) &&
2159 (num_dynamic_locks < p_t2t->num_lockbytes)) {
2160 bytes_locked_per_bit =
2161 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2162 .bytes_locked_per_bit;
2163 /* Number of bits in the current lock byte */
2164 b_all_bits_are_locks =
2165 ((p_t2t->lockbyte[num_dynamic_locks].byte_index + 1) *
2166 TAG_BITS_PER_BYTE <=
2167 p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2168 .num_bits);
2169 num_bits =
2170 b_all_bits_are_locks
2171 ? TAG_BITS_PER_BYTE
2172 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dynamic_locks].tlv_index]
2173 .num_bits %
2174 TAG_BITS_PER_BYTE;
2175
2176 if ((bytes_locked_per_bit * (num_bits - bit_count)) + byte_count <
2177 upper_offset) {
2178 /* Collect all lock bits that covers the current segment */
2179 byte_count += bytes_locked_per_bit * (num_bits - bit_count);
2180 total_bits += num_bits - bit_count;
2181 bit_count = 0;
2182 *p_end_byte = num_dynamic_locks;
2183 num_dynamic_locks++;
2184 } else {
2185 /* The last lock byte that covers the current segment */
2186 bit_count = 0;
2187 while (bit_count < num_bits) {
2188 /* The last lock bit that is used to lock this segment */
2189 byte_count += bytes_locked_per_bit;
2190 if (byte_count >= upper_offset) {
2191 *p_end_byte = num_dynamic_locks;
2192 total_bits += (bit_count + 1);
2193 break;
2194 }
2195 bit_count++;
2196 }
2197 }
2198 }
2199 return total_bits;
2200 }
2201
2202 /*******************************************************************************
2203 **
2204 ** Function rw_t2t_update_lock_attributes
2205 **
2206 ** Description This function will check if the tag index passed as
2207 ** argument is a locked byte and return TRUE or FALSE
2208 **
2209 ** Parameters: index, the index of the byte in the tag
2210 **
2211 **
2212 ** Returns TRUE, if the specified index in the tag is a locked or
2213 ** reserved or otp byte
2214 ** FALSE, otherwise
2215 **
2216 *******************************************************************************/
rw_t2t_update_lock_attributes(void)2217 static void rw_t2t_update_lock_attributes(void) {
2218 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2219 uint8_t xx = 0;
2220 uint8_t num_static_lock_bytes = 0;
2221 uint8_t num_dyn_lock_bytes = 0;
2222 uint8_t bits_covered = 0;
2223 uint16_t bytes_covered = 0;
2224 uint8_t block_count = 0;
2225 bool b_all_bits_are_locks = true;
2226 uint16_t bytes_locked_per_lock_bit;
2227 uint8_t start_lock_byte;
2228 uint8_t start_lock_bit;
2229 uint8_t end_lock_byte;
2230 uint8_t num_lock_bits;
2231 uint8_t total_bits;
2232
2233 /* Prepare lock_attr for the current segment */
2234 memset(p_t2t->lock_attr, 0, RW_T2T_SEGMENT_SIZE * sizeof(uint8_t));
2235
2236 block_count = 0;
2237 if (p_t2t->segment == 0) {
2238 /* Update lock_attributes based on static lock bytes */
2239 xx = 0;
2240 num_static_lock_bytes = 0;
2241 block_count = 0;
2242 num_lock_bits =
2243 TAG_BITS_PER_BYTE - 1; /* the inner while loop increases xx by 2. need
2244 (-1) to avoid coverity overrun error */
2245
2246 while (num_static_lock_bytes < T2T_NUM_STATIC_LOCK_BYTES) {
2247 /* Update lock attribute based on 2 static locks */
2248 while (xx < num_lock_bits) {
2249 p_t2t->lock_attr[block_count] = 0x00;
2250
2251 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2252 rw_t2t_mask_bits[xx++]) {
2253 /* If the bit is set then 1 block is locked */
2254 p_t2t->lock_attr[block_count] = 0x0F;
2255 }
2256
2257 if (p_t2t->tag_hdr[T2T_STATIC_LOCK0 + num_static_lock_bytes] &
2258 rw_t2t_mask_bits[xx++]) {
2259 /* If the bit is set then 1 block is locked */
2260 p_t2t->lock_attr[block_count] |= 0xF0;
2261 }
2262 block_count++;
2263 }
2264 num_static_lock_bytes++;
2265 xx = 0;
2266 }
2267 /* UID is always locked, irrespective of the lock value */
2268 p_t2t->lock_attr[0x00] = 0xFF;
2269 }
2270
2271 /* Get lock bits applicable for the current segment */
2272 total_bits = rw_t2t_get_lock_bits_for_segment(
2273 p_t2t->segment, &start_lock_byte, &start_lock_bit, &end_lock_byte);
2274 if (total_bits != 0) {
2275 /* update lock_attributes based on current segment using dynamic lock bytes
2276 */
2277 xx = start_lock_bit;
2278 num_dyn_lock_bytes = start_lock_byte;
2279 bits_covered = 0;
2280 bytes_covered = 0;
2281 num_lock_bits = TAG_BITS_PER_BYTE;
2282 p_t2t->lock_attr[block_count] = 0;
2283
2284 while (num_dyn_lock_bytes <= end_lock_byte) {
2285 bytes_locked_per_lock_bit =
2286 p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2287 .bytes_locked_per_bit;
2288 /* Find number of bits in the byte are lock bits */
2289 b_all_bits_are_locks =
2290 ((p_t2t->lockbyte[num_dyn_lock_bytes].byte_index + 1) *
2291 TAG_BITS_PER_BYTE <=
2292 p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2293 .num_bits);
2294 num_lock_bits =
2295 b_all_bits_are_locks
2296 ? TAG_BITS_PER_BYTE
2297 : p_t2t->lock_tlv[p_t2t->lockbyte[num_dyn_lock_bytes].tlv_index]
2298 .num_bits %
2299 TAG_BITS_PER_BYTE;
2300
2301 while (xx < num_lock_bits) {
2302 bytes_covered = 0;
2303 while (bytes_covered < bytes_locked_per_lock_bit) {
2304 if (p_t2t->lockbyte[num_dyn_lock_bytes].lock_byte &
2305 rw_t2t_mask_bits[xx]) {
2306 /* If the bit is set then it is locked */
2307 if (block_count < RW_T2T_SEGMENT_SIZE)
2308 p_t2t->lock_attr[block_count] |= 0x01 << bits_covered;
2309 }
2310 bytes_covered++;
2311 bits_covered++;
2312 if (bits_covered == TAG_BITS_PER_BYTE) {
2313 /* Move to next 8 bytes */
2314 bits_covered = 0;
2315 block_count++;
2316 /* Assume unlocked before updating using locks */
2317 if (block_count < RW_T2T_SEGMENT_SIZE)
2318 p_t2t->lock_attr[block_count] = 0;
2319 }
2320 }
2321 xx++;
2322 }
2323 num_dyn_lock_bytes++;
2324 xx = 0;
2325 }
2326 }
2327 }
2328
2329 /*******************************************************************************
2330 **
2331 ** Function rw_t2t_is_lock_res_byte
2332 **
2333 ** Description This function will check if the tag index passed as
2334 ** argument is a lock or reserved or otp byte and return
2335 ** TRUE or FALSE
2336 **
2337 ** Parameters: index, the index of the byte in the tag
2338 **
2339 **
2340 ** Returns TRUE, if the specified index in the tag is a locked or
2341 ** reserved or otp byte
2342 ** FALSE, otherwise
2343 **
2344 *******************************************************************************/
rw_t2t_is_lock_res_byte(uint16_t index)2345 static bool rw_t2t_is_lock_res_byte(uint16_t index) {
2346 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2347
2348 p_t2t->segment = (uint8_t)(index / RW_T2T_SEGMENT_BYTES);
2349
2350 if (p_t2t->attr_seg != p_t2t->segment) {
2351 /* Update attributes for the current segment */
2352 rw_t2t_update_attributes();
2353 p_t2t->attr_seg = p_t2t->segment;
2354 }
2355
2356 index = index % RW_T2T_SEGMENT_BYTES;
2357 /* Every bit in p_t2t->attr indicates one specific byte of the tag is either a
2358 * lock/reserved byte or not
2359 * So, each array element in p_t2t->attr covers two blocks in the tag as T2
2360 * block size is 4 and array element size is 8
2361 * Find the block and offset for the index (passed as argument) and Check if
2362 * the offset bit in the
2363 * p_t2t->attr[block/2] is set or not. If the bit is set then it is a
2364 * lock/reserved byte, otherwise not */
2365
2366 return ((p_t2t->attr[index / 8] & rw_t2t_mask_bits[index % 8]) == 0) ? false
2367 : true;
2368 }
2369
2370 /*******************************************************************************
2371 **
2372 ** Function rw_t2t_set_dynamic_lock_bits
2373 **
2374 ** Description This function will set dynamic lock bits as part of
2375 ** configuring tag as read only
2376 **
2377 ** Returns
2378 ** NFC_STATUS_OK, Command sent to set dynamic lock bits
2379 ** NFC_STATUS_FAILED: otherwise
2380 **
2381 *******************************************************************************/
rw_t2t_set_dynamic_lock_bits(uint8_t * p_data)2382 tNFC_STATUS rw_t2t_set_dynamic_lock_bits(uint8_t* p_data) {
2383 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2384 uint8_t write_block[T2T_BLOCK_SIZE];
2385 uint16_t offset;
2386 uint16_t next_offset;
2387 uint8_t num_bits;
2388 uint8_t next_num_bits;
2389 tNFC_STATUS status = NFC_STATUS_FAILED;
2390 uint8_t num_locks;
2391 uint8_t lock_count;
2392 bool b_all_bits_are_locks = true;
2393
2394 num_locks = 0;
2395
2396 memcpy(write_block, p_data, T2T_BLOCK_SIZE);
2397 while (num_locks < p_t2t->num_lockbytes) {
2398 if (p_t2t->lockbyte[num_locks].lock_status == RW_T2T_LOCK_NOT_UPDATED) {
2399 offset = p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].offset +
2400 p_t2t->lockbyte[num_locks].byte_index;
2401
2402 /* Check if all bits are lock bits in the byte */
2403 b_all_bits_are_locks =
2404 ((p_t2t->lockbyte[num_locks].byte_index + 1) * TAG_BITS_PER_BYTE <=
2405 p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits);
2406 num_bits =
2407 b_all_bits_are_locks
2408 ? TAG_BITS_PER_BYTE
2409 : p_t2t->lock_tlv[p_t2t->lockbyte[num_locks].tlv_index].num_bits %
2410 TAG_BITS_PER_BYTE;
2411
2412 write_block[(uint8_t)(offset % T2T_BLOCK_SIZE)] |=
2413 tags_pow(2, num_bits) - 1;
2414 lock_count = num_locks + 1;
2415
2416 /* Set all the lock bits in the block using a sing block write command */
2417 while (lock_count < p_t2t->num_lockbytes) {
2418 next_offset =
2419 p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].offset +
2420 p_t2t->lockbyte[lock_count].byte_index;
2421
2422 /* Check if all bits are lock bits in the byte */
2423 b_all_bits_are_locks =
2424 ((p_t2t->lockbyte[lock_count].byte_index + 1) * TAG_BITS_PER_BYTE <=
2425 p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index].num_bits);
2426 next_num_bits =
2427 b_all_bits_are_locks
2428 ? TAG_BITS_PER_BYTE
2429 : p_t2t->lock_tlv[p_t2t->lockbyte[lock_count].tlv_index]
2430 .num_bits %
2431 TAG_BITS_PER_BYTE;
2432
2433 if (next_offset / T2T_BLOCK_SIZE == offset / T2T_BLOCK_SIZE) {
2434 write_block[(uint8_t)(next_offset % T2T_BLOCK_SIZE)] |=
2435 tags_pow(2, next_num_bits) - 1;
2436 } else
2437 break;
2438 lock_count++;
2439 }
2440
2441 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_DYN_LOCK_BITS;
2442 /* send WRITE command to set dynamic lock bits */
2443 status = rw_t2t_write((uint16_t)(offset / T2T_BLOCK_SIZE), write_block);
2444 if (status == NFC_STATUS_OK) {
2445 while (lock_count > num_locks) {
2446 /* Set update initiated flag to indicate a write command is sent to
2447 * set dynamic lock bits of the block */
2448 p_t2t->lockbyte[lock_count - 1].lock_status =
2449 RW_T2T_LOCK_UPDATE_INITIATED;
2450 lock_count--;
2451 }
2452 } else
2453 status = NFC_STATUS_FAILED;
2454
2455 break;
2456
2457 } else {
2458 status = NFC_STATUS_CONTINUE;
2459 }
2460 num_locks++;
2461 }
2462
2463 return status;
2464 }
2465
2466 /*******************************************************************************
2467 **
2468 ** Function rw_t2t_set_lock_tlv
2469 **
2470 ** Description This function will set lock control tlv on the blank
2471 ** activated type 2 tag based on values read from version block
2472 **
2473 ** Parameters: TAG data memory size
2474 **
2475 ** Returns
2476 ** NFC_STATUS_OK, Command sent to set Lock TLV
2477 ** NFC_STATUS_FAILED: otherwise
2478 **
2479 *******************************************************************************/
rw_t2t_set_lock_tlv(uint16_t addr,uint8_t num_dyn_lock_bits,uint16_t locked_area_size)2480 tNFC_STATUS rw_t2t_set_lock_tlv(uint16_t addr, uint8_t num_dyn_lock_bits,
2481 uint16_t locked_area_size) {
2482 tNFC_STATUS status = NFC_STATUS_FAILED;
2483 int8_t PageAddr = 0;
2484 int8_t BytePerPage = 0;
2485 int8_t ByteOffset = 0;
2486 uint8_t a;
2487 uint8_t data_block[T2T_BLOCK_SIZE];
2488 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2489 uint8_t* p;
2490 uint8_t xx;
2491
2492 for (xx = 15; xx > 0; xx--) {
2493 a = (uint8_t)(addr / xx);
2494 a += (addr % xx) ? 1 : 0;
2495
2496 BytePerPage = (int8_t)tags_log2(a);
2497 ByteOffset = (int8_t)(addr - xx * tags_pow(2, BytePerPage));
2498
2499 if (ByteOffset < 16) {
2500 PageAddr = xx;
2501 break;
2502 }
2503 }
2504
2505 if ((ByteOffset < 16) && (BytePerPage < 16) && (PageAddr < 16)) {
2506 memset(data_block, 0, T2T_BLOCK_SIZE);
2507 p = data_block;
2508 UINT8_TO_BE_STREAM(p, T2T_TLV_TYPE_LOCK_CTRL);
2509 UINT8_TO_BE_STREAM(p, T2T_TLEN_LOCK_CTRL_TLV);
2510 UINT8_TO_BE_STREAM(p, (PageAddr << 4 | ByteOffset));
2511 UINT8_TO_BE_STREAM(p, num_dyn_lock_bits);
2512
2513 p_t2t->tlv_value[0] = PageAddr << 4 | ByteOffset;
2514 p_t2t->tlv_value[1] = num_dyn_lock_bits;
2515 p_t2t->tlv_value[2] =
2516 (uint8_t)(BytePerPage << 4 | tags_log2(locked_area_size));
2517
2518 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_LOCK_TLV;
2519
2520 /* send WRITE-E8 command */
2521 status = rw_t2t_write(T2T_FIRST_DATA_BLOCK, data_block);
2522 if (status == NFC_STATUS_OK) {
2523 p_t2t->b_read_data = false;
2524 } else
2525 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2526 } else
2527 status = NFC_STATUS_REJECTED;
2528
2529 return status;
2530 }
2531
2532 /*******************************************************************************
2533 **
2534 ** Function rw_t2t_set_cc
2535 **
2536 ** Description This function will set Capability Container on the activated
2537 ** type 2 tag with default values of CC0, CC1, CC4 and
2538 ** specified CC3 value
2539 **
2540 ** Parameters: CC3 value of the tag
2541 **
2542 ** Returns
2543 ** NFC_STATUS_OK, Command sent to set CC
2544 ** NFC_STATUS_FAILED: otherwise
2545 **
2546 *******************************************************************************/
rw_t2t_set_cc(uint8_t tms)2547 tNFC_STATUS rw_t2t_set_cc(uint8_t tms) {
2548 uint8_t cc_block[T2T_BLOCK_SIZE];
2549 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2550 tNFC_STATUS status = NFC_STATUS_FAILED;
2551 uint8_t* p;
2552
2553 memset(cc_block, 0, T2T_BLOCK_SIZE);
2554 memset(p_t2t->ndef_final_block, 0, T2T_BLOCK_SIZE);
2555 p = cc_block;
2556
2557 /* Prepare Capability Container */
2558 UINT8_TO_BE_STREAM(p, T2T_CC0_NMN);
2559 UINT8_TO_BE_STREAM(p, T2T_CC1_VNO);
2560 UINT8_TO_BE_STREAM(p, tms);
2561 UINT8_TO_BE_STREAM(p, T2T_CC3_RWA_RW);
2562
2563 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC;
2564
2565 /* send WRITE-E8 command */
2566 status = rw_t2t_write(T2T_CC_BLOCK, cc_block);
2567 if (status == NFC_STATUS_OK) {
2568 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2569 p_t2t->b_read_hdr = false;
2570 } else
2571 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2572
2573 return status;
2574 }
2575
2576 /*******************************************************************************
2577 **
2578 ** Function rw_t2t_format_tag
2579 **
2580 ** Description This function will format tag based on Manufacturer ID
2581 **
2582 ** Returns
2583 ** NFC_STATUS_OK, Command sent to format Tag
2584 ** NFC_STATUS_FAILED: otherwise
2585 **
2586 *******************************************************************************/
rw_t2t_format_tag(void)2587 tNFC_STATUS rw_t2t_format_tag(void) {
2588 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2589 const tT2T_INIT_TAG* p_ret;
2590 uint8_t tms;
2591 tNFC_STATUS status = NFC_STATUS_FAILED;
2592 bool b_blank_tag = true;
2593
2594 p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0);
2595 if (p_ret == nullptr) {
2596 LOG(WARNING) << StringPrintf(
2597 "rw_t2t_format_tag - Unknown Manufacturer ID: %u, Cannot Format the "
2598 "tag!",
2599 p_t2t->tag_hdr[0]);
2600 return (NFC_STATUS_FAILED);
2601 }
2602
2603 if (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != 0) {
2604 /* If OTP tag has valid NDEF Message, cannot format the tag */
2605 if ((p_t2t->ndef_msg_len > 0) && (p_ret->b_otp)) {
2606 LOG(WARNING) << StringPrintf(
2607 "rw_t2t_format_tag - Cannot Format a OTP tag with NDEF Message!");
2608 return (NFC_STATUS_FAILED);
2609 }
2610
2611 if (((p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != 0) &&
2612 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) ||
2613 ((p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != 0) &&
2614 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_LEGACY_VNO) &&
2615 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_VNO) &&
2616 (p_t2t->tag_hdr[T2T_CC1_VNO_BYTE] != T2T_CC1_NEW_VNO))) {
2617 LOG(WARNING) << StringPrintf(
2618 "rw_t2t_format_tag - Tag not blank to Format!");
2619 return (NFC_STATUS_FAILED);
2620 } else {
2621 tms = p_t2t->tag_hdr[T2T_CC2_TMS_BYTE];
2622 b_blank_tag = false;
2623 }
2624 } else
2625 tms = p_ret->tms;
2626
2627 memset(p_t2t->tag_data, 0, T2T_READ_DATA_LEN);
2628
2629 if (!b_blank_tag || !p_ret->b_multi_version) {
2630 status = rw_t2t_set_cc(tms);
2631 } else if (p_ret->version_block != 0) {
2632 /* If Version number is not read, READ it now */
2633 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2634
2635 status = rw_t2t_read(p_ret->version_block);
2636 if (status == NFC_STATUS_OK)
2637 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2638 else
2639 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2640 } else {
2641 /* UID block is the version block */
2642 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2643 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_VERSION_INFO;
2644 rw_t2t_handle_format_tag_rsp(p_t2t->tag_hdr);
2645 }
2646
2647 return status;
2648 }
2649
2650 /*******************************************************************************
2651 **
2652 ** Function rw_t2t_soft_lock_tag
2653 **
2654 ** Description This function will soft lock the tag after validating CC.
2655 **
2656 ** Returns
2657 ** NFC_STATUS_OK, Command sent to soft lock the tag
2658 ** NFC_STATUS_FAILED: otherwise
2659 **
2660 *******************************************************************************/
rw_t2t_soft_lock_tag(void)2661 tNFC_STATUS rw_t2t_soft_lock_tag(void) {
2662 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2663 tNFC_STATUS status = NFC_STATUS_FAILED;
2664 uint8_t write_block[T2T_BLOCK_SIZE];
2665 uint8_t num_locks;
2666
2667 /* If CC block is read and cc3 is soft locked, reject the command */
2668 if ((p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] & T2T_CC3_RWA_RO) == T2T_CC3_RWA_RO) {
2669 LOG(ERROR) << StringPrintf(
2670 "rw_t2t_soft_lock_tag: Error: Type 2 tag is in Read only state, CC3: "
2671 "%u",
2672 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2673 return (NFC_STATUS_FAILED);
2674 }
2675
2676 if (p_t2t->b_hard_lock) {
2677 /* Should have performed NDEF Detection on dynamic memory structure tag,
2678 * before permanently converting to Read only
2679 * Even when no lock control tlv is present, default lock bytes should be
2680 * present */
2681
2682 if ((p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] != T2T_CC2_TMS_STATIC) &&
2683 (p_t2t->num_lockbytes == 0)) {
2684 LOG(ERROR) << StringPrintf(
2685 "rw_t2t_soft_lock_tag: Error: Lock TLV not detected! Cannot hard "
2686 "lock the tag");
2687 return (NFC_STATUS_FAILED);
2688 }
2689
2690 /* On dynamic memory structure tag, reset all lock bytes status to 'Not
2691 * Updated' if not in Updated status */
2692 num_locks = 0;
2693 while (num_locks < p_t2t->num_lockbytes) {
2694 if (p_t2t->lockbyte[num_locks].lock_status != RW_T2T_LOCK_UPDATED)
2695 p_t2t->lockbyte[num_locks].lock_status = RW_T2T_LOCK_NOT_UPDATED;
2696 num_locks++;
2697 }
2698 }
2699
2700 memcpy(write_block, &p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], T2T_BLOCK_SIZE);
2701 write_block[(T2T_CC3_RWA_BYTE % T2T_BLOCK_SIZE)] = T2T_CC3_RWA_RO;
2702
2703 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_SET_CC_RO;
2704 /* First Soft lock the tag */
2705 status = rw_t2t_write(T2T_CC_BLOCK, write_block);
2706 if (status == NFC_STATUS_OK) {
2707 p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
2708 p_t2t->b_read_hdr = false;
2709 } else {
2710 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2711 }
2712 return status;
2713 }
2714
2715 /*****************************************************************************
2716 **
2717 ** Function RW_T2tFormatNDef
2718 **
2719 ** Description
2720 ** Format Tag content
2721 **
2722 ** Returns
2723 ** NFC_STATUS_OK, Command sent to format Tag
2724 ** NFC_STATUS_FAILED: otherwise
2725 **
2726 *****************************************************************************/
RW_T2tFormatNDef(void)2727 tNFC_STATUS RW_T2tFormatNDef(void) {
2728 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2729 tNFC_STATUS status = NFC_STATUS_FAILED;
2730
2731 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2732 LOG(WARNING) << StringPrintf(
2733 "RW_T2tFormatNDef - Tag not initialized/ Busy! State: %u",
2734 p_t2t->state);
2735 return (NFC_STATUS_FAILED);
2736 }
2737
2738 if (!p_t2t->b_read_hdr) {
2739 /* If UID is not read, READ it now */
2740 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2741
2742 status = rw_t2t_read(0);
2743 if (status == NFC_STATUS_OK)
2744 p_t2t->state = RW_T2T_STATE_FORMAT_TAG;
2745 else
2746 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2747 } else {
2748 status = rw_t2t_format_tag();
2749 if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
2750 }
2751 return status;
2752 }
2753
2754 /*******************************************************************************
2755 **
2756 ** Function RW_T2tLocateTlv
2757 **
2758 ** Description This function is used to perform TLV detection on a Type 2
2759 ** tag, and retrieve the tag's TLV attribute information.
2760 **
2761 ** Before using this API, the application must call
2762 ** RW_SelectTagType to indicate that a Type 2 tag has been
2763 ** activated.
2764 **
2765 ** Parameters: tlv_type : TLV to detect
2766 **
2767 ** Returns NCI_STATUS_OK, if detection was started. Otherwise, error
2768 ** status.
2769 **
2770 *******************************************************************************/
RW_T2tLocateTlv(uint8_t tlv_type)2771 tNFC_STATUS RW_T2tLocateTlv(uint8_t tlv_type) {
2772 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2773 tNFC_STATUS status;
2774 uint16_t block;
2775
2776 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2777 LOG(ERROR) << StringPrintf(
2778 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2779 return (NFC_STATUS_BUSY);
2780 }
2781
2782 if ((tlv_type != TAG_LOCK_CTRL_TLV) && (tlv_type != TAG_MEM_CTRL_TLV) &&
2783 (tlv_type != TAG_NDEF_TLV) && (tlv_type != TAG_PROPRIETARY_TLV)) {
2784 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2785 "RW_T2tLocateTlv - Cannot search TLV: 0x%02x", tlv_type);
2786 return (NFC_STATUS_FAILED);
2787 }
2788
2789 if ((tlv_type == TAG_LOCK_CTRL_TLV) && (p_t2t->b_read_hdr) &&
2790 (p_t2t->tag_hdr[T2T_CC2_TMS_BYTE] == T2T_CC2_TMS_STATIC)) {
2791 p_t2t->b_read_hdr = false;
2792 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
2793 "RW_T2tLocateTlv - No Lock tlv in static structure tag, CC[0]: 0x%02x",
2794 p_t2t->tag_hdr[T2T_CC2_TMS_BYTE]);
2795 return (NFC_STATUS_FAILED);
2796 }
2797
2798 if ((tlv_type == TAG_NDEF_TLV) && (p_t2t->b_read_hdr) &&
2799 (p_t2t->tag_hdr[T2T_CC0_NMN_BYTE] != T2T_CC0_NMN)) {
2800 p_t2t->b_read_hdr = false;
2801 LOG(WARNING) << StringPrintf(
2802 "RW_T2tLocateTlv - Invalid NDEF Magic Number!, CC[0]: 0x%02x, CC[1]: "
2803 "0x%02x, CC[3]: 0x%02x",
2804 p_t2t->tag_hdr[T2T_CC0_NMN_BYTE], p_t2t->tag_hdr[T2T_CC1_VNO_BYTE],
2805 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2806 return (NFC_STATUS_FAILED);
2807 }
2808
2809 p_t2t->work_offset = 0;
2810 p_t2t->tlv_detect = tlv_type;
2811
2812 /* Reset control block variables based on type of tlv to detect */
2813 if (tlv_type == TAG_LOCK_CTRL_TLV) {
2814 p_t2t->num_lockbytes = 0;
2815 p_t2t->num_lock_tlvs = 0;
2816 } else if (tlv_type == TAG_MEM_CTRL_TLV) {
2817 p_t2t->num_mem_tlvs = 0;
2818 } else if (tlv_type == TAG_NDEF_TLV) {
2819 p_t2t->ndef_msg_offset = 0;
2820 p_t2t->num_lockbytes = 0;
2821 p_t2t->num_lock_tlvs = 0;
2822 p_t2t->num_mem_tlvs = 0;
2823 p_t2t->ndef_msg_len = 0;
2824 p_t2t->ndef_status = T2T_NDEF_NOT_DETECTED;
2825 } else {
2826 p_t2t->prop_msg_len = 0;
2827 }
2828
2829 if (!p_t2t->b_read_hdr) {
2830 /* First read CC block */
2831 block = 0;
2832 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
2833 } else {
2834 /* Read first data block */
2835 block = T2T_FIRST_DATA_BLOCK;
2836 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_TLV_DETECT;
2837 }
2838
2839 /* Start reading tag, looking for the specified TLV */
2840 status = rw_t2t_read((uint16_t)block);
2841 if (status == NFC_STATUS_OK) {
2842 p_t2t->state = RW_T2T_STATE_DETECT_TLV;
2843 } else {
2844 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2845 }
2846 return (status);
2847 }
2848
2849 /*******************************************************************************
2850 **
2851 ** Function RW_T2tDetectNDef
2852 **
2853 ** Description This function is used to perform NDEF detection on a Type 2
2854 ** tag, and retrieve the tag's NDEF attribute information.
2855 **
2856 ** Before using this API, the application must call
2857 ** RW_SelectTagType to indicate that a Type 2 tag has been
2858 ** activated.
2859 **
2860 ** Parameters: none
2861 **
2862 ** Returns NCI_STATUS_OK,if detect op started.Otherwise,error status.
2863 **
2864 *******************************************************************************/
RW_T2tDetectNDef(bool skip_dyn_locks)2865 tNFC_STATUS RW_T2tDetectNDef(bool skip_dyn_locks) {
2866 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2867
2868 p_t2t->skip_dyn_locks = skip_dyn_locks;
2869
2870 return RW_T2tLocateTlv(TAG_NDEF_TLV);
2871 }
2872
2873 /*******************************************************************************
2874 **
2875 ** Function RW_T2tReadNDef
2876 **
2877 ** Description Retrieve NDEF contents from a Type2 tag.
2878 **
2879 ** The RW_T2T_NDEF_READ_EVT event is used to notify the
2880 ** application after reading the NDEF message.
2881 **
2882 ** Before using this API, the RW_T2tDetectNDef function must
2883 ** be called to verify that the tag contains NDEF data, and to
2884 ** retrieve the NDEF attributes.
2885 **
2886 ** Internally, this command will be separated into multiple
2887 ** Tag2 Read commands (if necessary) - depending on the NDEF
2888 ** Msg size
2889 **
2890 ** Parameters: p_buffer: The buffer into which to read the NDEF message
2891 ** buf_len: The length of the buffer
2892 **
2893 ** Returns NCI_STATUS_OK, if read was started. Otherwise, error status.
2894 **
2895 *******************************************************************************/
RW_T2tReadNDef(uint8_t * p_buffer,uint16_t buf_len)2896 tNFC_STATUS RW_T2tReadNDef(uint8_t* p_buffer, uint16_t buf_len) {
2897 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2898 tNFC_STATUS status = NFC_STATUS_OK;
2899 uint16_t block;
2900
2901 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2902 LOG(ERROR) << StringPrintf(
2903 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2904 return (NFC_STATUS_FAILED);
2905 }
2906
2907 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
2908 LOG(ERROR) << StringPrintf(
2909 "RW_T2tReadNDef - Error: NDEF detection not performed yet");
2910 return (NFC_STATUS_FAILED);
2911 }
2912
2913 if (buf_len < p_t2t->ndef_msg_len) {
2914 LOG(WARNING) << StringPrintf(
2915 "RW_T2tReadNDef - buffer size: %u less than NDEF msg sise: %u",
2916 buf_len, p_t2t->ndef_msg_len);
2917 return (NFC_STATUS_FAILED);
2918 }
2919
2920 if (!p_t2t->ndef_msg_len) {
2921 LOG(WARNING) << StringPrintf(
2922 "RW_T2tReadNDef - NDEF Message length is zero");
2923 return (NFC_STATUS_NOT_INITIALIZED);
2924 }
2925
2926 p_t2t->p_ndef_buffer = p_buffer;
2927 p_t2t->work_offset = 0;
2928
2929 block = (uint16_t)(p_t2t->ndef_msg_offset / T2T_BLOCK_LEN);
2930 block -= block % T2T_READ_BLOCKS;
2931
2932 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
2933
2934 if ((block == T2T_FIRST_DATA_BLOCK) && (p_t2t->b_read_data)) {
2935 p_t2t->state = RW_T2T_STATE_READ_NDEF;
2936 p_t2t->block_read = T2T_FIRST_DATA_BLOCK;
2937 rw_t2t_handle_ndef_read_rsp(p_t2t->tag_data);
2938 } else {
2939 /* Start reading NDEF Message */
2940 status = rw_t2t_read(block);
2941 if (status == NFC_STATUS_OK) {
2942 p_t2t->state = RW_T2T_STATE_READ_NDEF;
2943 }
2944 }
2945
2946 return (status);
2947 }
2948
2949 /*******************************************************************************
2950 **
2951 ** Function RW_T2tWriteNDef
2952 **
2953 ** Description Write NDEF contents to a Type2 tag.
2954 **
2955 ** Before using this API, the RW_T2tDetectNDef
2956 ** function must be called to verify that the tag contains
2957 ** NDEF data, and to retrieve the NDEF attributes.
2958 **
2959 ** The RW_T2T_NDEF_WRITE_EVT callback event will be used to
2960 ** notify the application of the response.
2961 **
2962 ** Internally, this command will be separated into multiple
2963 ** Tag2 Write commands (if necessary) - depending on the NDEF
2964 ** Msg size
2965 **
2966 ** Parameters: msg_len: The length of the buffer
2967 ** p_msg: The NDEF message to write
2968 **
2969 ** Returns NCI_STATUS_OK,if write was started. Otherwise, error status
2970 **
2971 *******************************************************************************/
RW_T2tWriteNDef(uint16_t msg_len,uint8_t * p_msg)2972 tNFC_STATUS RW_T2tWriteNDef(uint16_t msg_len, uint8_t* p_msg) {
2973 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
2974 uint16_t block;
2975 const tT2T_INIT_TAG* p_ret;
2976
2977 tNFC_STATUS status = NFC_STATUS_OK;
2978
2979 if (p_t2t->state != RW_T2T_STATE_IDLE) {
2980 LOG(ERROR) << StringPrintf(
2981 "Error: Type 2 tag not activated or Busy - State: %u", p_t2t->state);
2982 return (NFC_STATUS_FAILED);
2983 }
2984
2985 if (p_t2t->ndef_status == T2T_NDEF_NOT_DETECTED) {
2986 LOG(ERROR) << StringPrintf(
2987 "RW_T2tWriteNDef - Error: NDEF detection not performed!");
2988 return (NFC_STATUS_FAILED);
2989 }
2990
2991 if (p_t2t->tag_hdr[T2T_CC3_RWA_BYTE] != T2T_CC3_RWA_RW) {
2992 LOG(ERROR) << StringPrintf(
2993 "RW_T2tWriteNDef - Write access not granted - CC3: %u",
2994 p_t2t->tag_hdr[T2T_CC3_RWA_BYTE]);
2995 return (NFC_STATUS_REFUSED);
2996 }
2997
2998 /* Check if there is enough memory on the tag */
2999 if (msg_len > p_t2t->max_ndef_msg_len) {
3000 LOG(ERROR) << StringPrintf(
3001 "RW_T2tWriteNDef - Cannot write NDEF of size greater than %u bytes",
3002 p_t2t->max_ndef_msg_len);
3003 return (NFC_STATUS_FAILED);
3004 }
3005
3006 /* If OTP tag and tag has valid NDEF Message, stop writting new NDEF Message
3007 * as it may corrupt the tag */
3008 if ((p_t2t->ndef_msg_len > 0) &&
3009 ((p_ret = t2t_tag_init_data(p_t2t->tag_hdr[0], false, 0)) != nullptr) &&
3010 (p_ret->b_otp)) {
3011 LOG(WARNING) << StringPrintf(
3012 "RW_T2tWriteNDef - Cannot Overwrite NDEF Message on a OTP tag!");
3013 return (NFC_STATUS_FAILED);
3014 }
3015 p_t2t->p_new_ndef_buffer = p_msg;
3016 p_t2t->new_ndef_msg_len = msg_len;
3017 p_t2t->work_offset = 0;
3018
3019 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_NDEF_FIRST_BLOCK;
3020 /* Read first NDEF Block before updating NDEF */
3021
3022 block = (uint16_t)(p_t2t->ndef_header_offset / T2T_BLOCK_LEN);
3023
3024 if ((block < (T2T_FIRST_DATA_BLOCK + T2T_READ_BLOCKS)) &&
3025 (p_t2t->b_read_data)) {
3026 p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3027 p_t2t->block_read = block;
3028 rw_t2t_handle_ndef_write_rsp(
3029 &p_t2t->tag_data[(block - T2T_FIRST_DATA_BLOCK) * T2T_BLOCK_LEN]);
3030 } else {
3031 status = rw_t2t_read(block);
3032 if (status == NFC_STATUS_OK)
3033 p_t2t->state = RW_T2T_STATE_WRITE_NDEF;
3034 else
3035 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3036 }
3037
3038 return status;
3039 }
3040
3041 /*******************************************************************************
3042 **
3043 ** Function RW_T2tSetTagReadOnly
3044 **
3045 ** Description This function can be called to set T2 tag as read only.
3046 **
3047 ** Parameters: b_hard_lock: To indicate hard lock the tag or not
3048 **
3049 ** Returns NCI_STATUS_OK, if setting tag as read only was started.
3050 ** Otherwise, error status.
3051 **
3052 *******************************************************************************/
RW_T2tSetTagReadOnly(bool b_hard_lock)3053 tNFC_STATUS RW_T2tSetTagReadOnly(bool b_hard_lock) {
3054 tNFC_STATUS status = NFC_STATUS_FAILED;
3055 tRW_T2T_CB* p_t2t = &rw_cb.tcb.t2t;
3056
3057 if (p_t2t->state != RW_T2T_STATE_IDLE) {
3058 LOG(ERROR) << StringPrintf(
3059 "RW_T2tSetTagReadOnly: Error: Type 2 tag not activated or Busy - "
3060 "State: %u",
3061 p_t2t->state);
3062 return (NFC_STATUS_FAILED);
3063 }
3064
3065 p_t2t->b_hard_lock = b_hard_lock;
3066
3067 if (!p_t2t->b_read_hdr) {
3068 /* Read CC block before configuring tag as Read only */
3069 p_t2t->substate = RW_T2T_SUBSTATE_WAIT_READ_CC;
3070 status = rw_t2t_read((uint16_t)0);
3071 if (status == NFC_STATUS_OK) {
3072 p_t2t->state = RW_T2T_STATE_SET_TAG_RO;
3073 } else
3074 p_t2t->substate = RW_T2T_SUBSTATE_NONE;
3075 } else {
3076 status = rw_t2t_soft_lock_tag();
3077 if (status != NFC_STATUS_OK) p_t2t->b_read_hdr = false;
3078 }
3079
3080 return status;
3081 }
3082
3083 #endif /* (RW_NDEF_INCLUDED == TRUE) */
3084