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