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