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