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 * NFA interface for tag Reader/Writer
22 *
23 ******************************************************************************/
24 #include <string.h>
25
26 #include <android-base/stringprintf.h>
27 #include <base/logging.h>
28 #include <log/log.h>
29
30 #include "nfa_api.h"
31 #include "nfa_rw_int.h"
32
33 using android::base::StringPrintf;
34
35 extern bool nfc_debug_enabled;
36
37 /*****************************************************************************
38 ** Constants
39 *****************************************************************************/
40
41 /*****************************************************************************
42 ** APIs
43 *****************************************************************************/
44
45 /*******************************************************************************
46 **
47 ** Function NFA_RwDetectNDef
48 **
49 ** Description Perform the NDEF detection procedure using the appropriate
50 ** method for the currently activated tag.
51 **
52 ** Upon successful completion of NDEF detection, a
53 ** NFA_NDEF_DETECT_EVT will be sent, to notify the application
54 ** of the NDEF attributes (NDEF total memory size, current
55 ** size, etc.).
56 **
57 ** It is not mandatory to call this function - NFA_RwReadNDef
58 ** and NFA_RwWriteNDef will perform NDEF detection internally
59 ** if not performed already. This API may be called to get a
60 ** tag's NDEF size before issuing a write-request.
61 **
62 ** Returns:
63 ** NFA_STATUS_OK if successfully initiated
64 ** NFC_STATUS_REFUSED if tag does not support NDEF
65 ** NFA_STATUS_FAILED otherwise
66 **
67 *******************************************************************************/
NFA_RwDetectNDef(void)68 tNFA_STATUS NFA_RwDetectNDef(void) {
69 tNFA_RW_OPERATION* p_msg;
70
71 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
72
73 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
74 if (p_msg != nullptr) {
75 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
76 p_msg->op = NFA_RW_OP_DETECT_NDEF;
77
78 nfa_sys_sendmsg(p_msg);
79
80 return (NFA_STATUS_OK);
81 }
82
83 return (NFA_STATUS_FAILED);
84 }
85
86 /*******************************************************************************
87 **
88 ** Function NFA_RwReadNDef
89 **
90 ** Description Read NDEF message from tag. This function will internally
91 ** perform the NDEF detection procedure (if not performed
92 ** previously), and read the NDEF tag data using the
93 ** appropriate method for the currently activated tag.
94 **
95 ** Upon successful completion of NDEF detection (if performed),
96 ** a NFA_NDEF_DETECT_EVT will be sent, to notify the
97 ** application of the NDEF attributes (NDEF total memory size,
98 ** current size, etc.).
99 **
100 ** Upon receiving the NDEF message, the message will be sent to
101 ** the handler registered with NFA_RegisterNDefTypeHandler or
102 ** NFA_RequestExclusiveRfControl (if exclusive RF mode is
103 ** active)
104 **
105 ** Returns:
106 ** NFA_STATUS_OK if successfully initiated
107 ** NFC_STATUS_REFUSED if tag does not support NDEF
108 ** NFC_STATUS_NOT_INITIALIZED if NULL NDEF was detected on the
109 ** tag
110 ** NFA_STATUS_FAILED otherwise
111 **
112 *******************************************************************************/
NFA_RwReadNDef(void)113 tNFA_STATUS NFA_RwReadNDef(void) {
114 tNFA_RW_OPERATION* p_msg;
115
116 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
117
118 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
119 if (p_msg != nullptr) {
120 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
121 p_msg->op = NFA_RW_OP_READ_NDEF;
122
123 nfa_sys_sendmsg(p_msg);
124
125 return (NFA_STATUS_OK);
126 }
127
128 return (NFA_STATUS_FAILED);
129 }
130
131 /*******************************************************************************
132 **
133 ** Function NFA_RwWriteNDef
134 **
135 ** Description Write NDEF data to the activated tag. This function will
136 ** internally perform NDEF detection if necessary, and write
137 ** the NDEF tag data using the appropriate method for the
138 ** currently activated tag.
139 **
140 ** When the entire message has been written, or if an error
141 ** occurs, the app will be notified with NFA_WRITE_CPLT_EVT.
142 **
143 ** p_data needs to be persistent until NFA_WRITE_CPLT_EVT
144 **
145 **
146 ** Returns:
147 ** NFA_STATUS_OK if successfully initiated
148 ** NFC_STATUS_REFUSED if tag does not support NDEF/locked
149 ** NFA_STATUS_FAILED otherwise
150 **
151 *******************************************************************************/
NFA_RwWriteNDef(uint8_t * p_data,uint32_t len)152 tNFA_STATUS NFA_RwWriteNDef(uint8_t* p_data, uint32_t len) {
153 tNFA_RW_OPERATION* p_msg;
154
155 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("ndef len: %i", len);
156
157 /* Validate parameters */
158 if (p_data == nullptr) return (NFA_STATUS_INVALID_PARAM);
159
160 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
161 if (p_msg != nullptr) {
162 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
163 p_msg->op = NFA_RW_OP_WRITE_NDEF;
164 p_msg->params.write_ndef.len = len;
165 p_msg->params.write_ndef.p_data = p_data;
166 nfa_sys_sendmsg(p_msg);
167
168 return (NFA_STATUS_OK);
169 }
170
171 return (NFA_STATUS_FAILED);
172 }
173
174 /*****************************************************************************
175 **
176 ** Function NFA_RwPresenceCheck
177 **
178 ** Description Check if the tag is still in the field.
179 **
180 ** The NFA_RW_PRESENCE_CHECK_EVT w/ status is used to
181 ** indicate presence or non-presence.
182 **
183 ** option is used only with ISO-DEP protocol
184 **
185 ** Returns
186 ** NFA_STATUS_OK if successfully initiated
187 ** NFA_STATUS_FAILED otherwise
188 **
189 *****************************************************************************/
NFA_RwPresenceCheck(tNFA_RW_PRES_CHK_OPTION option)190 tNFA_STATUS NFA_RwPresenceCheck(tNFA_RW_PRES_CHK_OPTION option) {
191 tNFA_RW_OPERATION* p_msg;
192
193 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
194
195 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
196 if (p_msg != nullptr) {
197 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
198 p_msg->op = NFA_RW_OP_PRESENCE_CHECK;
199 p_msg->params.option = option;
200
201 nfa_sys_sendmsg(p_msg);
202
203 return (NFA_STATUS_OK);
204 }
205
206 return (NFA_STATUS_FAILED);
207 }
208
209 /*****************************************************************************
210 **
211 ** Function NFA_RwFormatTag
212 **
213 ** Description Check if the tag is NDEF Formatable. If yes Format the tag
214 **
215 ** The NFA_RW_FORMAT_CPLT_EVT w/ status is used to
216 ** indicate if tag is successfully formated or not
217 **
218 ** Returns
219 ** NFA_STATUS_OK if successfully initiated
220 ** NFA_STATUS_FAILED otherwise
221 **
222 *****************************************************************************/
NFA_RwFormatTag(void)223 tNFA_STATUS NFA_RwFormatTag(void) {
224 tNFA_RW_OPERATION* p_msg;
225
226 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
227
228 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
229 if (p_msg != nullptr) {
230 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
231 p_msg->op = NFA_RW_OP_FORMAT_TAG;
232
233 nfa_sys_sendmsg(p_msg);
234
235 return (NFA_STATUS_OK);
236 }
237
238 return (NFA_STATUS_FAILED);
239 }
240
241 /*******************************************************************************
242 **
243 ** Function NFA_RwSetTagReadOnly
244 **
245 ** Description:
246 ** Sets tag as read only.
247 **
248 ** When tag is set as read only, or if an error occurs, the app will be
249 ** notified with NFA_SET_TAG_RO_EVT.
250 **
251 ** Returns:
252 ** NFA_STATUS_OK if successfully initiated
253 ** NFA_STATUS_REJECTED if protocol is not T1/T2/T5T
254 ** (or) if hard lock is not requested for protocol T5T
255 ** NFA_STATUS_FAILED otherwise
256 **
257 *******************************************************************************/
NFA_RwSetTagReadOnly(bool b_hard_lock)258 tNFA_STATUS NFA_RwSetTagReadOnly(bool b_hard_lock) {
259 tNFA_RW_OPERATION* p_msg;
260 tNFC_PROTOCOL protocol = nfa_rw_cb.protocol;
261
262 if ((protocol != NFC_PROTOCOL_T1T) && (protocol != NFC_PROTOCOL_T2T) &&
263 (protocol != NFC_PROTOCOL_T5T) && (protocol != NFC_PROTOCOL_ISO_DEP) &&
264 (protocol != NFC_PROTOCOL_T3T)) {
265 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
266 "Cannot Configure as read only for Protocol: "
267 "%d",
268 protocol);
269 return (NFA_STATUS_REJECTED);
270 }
271
272 if ((!b_hard_lock && (protocol == NFC_PROTOCOL_T5T)) ||
273 (b_hard_lock && (protocol == NFC_PROTOCOL_ISO_DEP))) {
274 DLOG_IF(INFO, nfc_debug_enabled)
275 << StringPrintf("Cannot %s for Protocol: %d",
276 b_hard_lock ? "Hard lock" : "Soft lock", protocol);
277 return (NFA_STATUS_REJECTED);
278 }
279
280 DLOG_IF(INFO, nfc_debug_enabled)
281 << StringPrintf("%s", b_hard_lock ? "Hard lock" : "Soft lock");
282
283 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
284 if (p_msg != nullptr) {
285 /* Fill in tNFA_RW_OPERATION struct */
286 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
287 p_msg->op = NFA_RW_OP_SET_TAG_RO;
288 p_msg->params.set_readonly.b_hard_lock = b_hard_lock;
289
290 nfa_sys_sendmsg(p_msg);
291 return (NFA_STATUS_OK);
292 }
293 return (NFA_STATUS_FAILED);
294 }
295
296 /*******************************************************************************
297 ** Tag specific APIs
298 ** (note: for Type-4 tags, use NFA_SendRawFrame to exchange APDUs)
299 *******************************************************************************/
300
301 /*******************************************************************************
302 **
303 ** Function NFA_RwLocateTlv
304 **
305 ** Description:
306 ** Search for the Lock/Memory contril TLV on the activated Type1/Type2 tag
307 **
308 ** Data is returned to the application using the NFA_TLV_DETECT_EVT. When
309 ** search operation has completed, or if an error occurs, the app will be
310 ** notified with NFA_TLV_DETECT_EVT.
311 **
312 ** Description Perform the TLV detection procedure using the appropriate
313 ** method for the currently activated tag.
314 **
315 ** Upon successful completion of TLV detection in T1/T2 tag, a
316 ** NFA_TLV_DETECT_EVT will be sent, to notify the application
317 ** of the TLV attributes (total lock/reserved bytes etc.).
318 ** However if the TLV type specified is NDEF then it is same as
319 ** calling NFA_RwDetectNDef and should expect to receive
320 ** NFA_NDEF_DETECT_EVT instead of NFA_TLV_DETECT_EVT
321 **
322 ** It is not mandatory to call this function -
323 ** NFA_RwDetectNDef, NFA_RwReadNDef and NFA_RwWriteNDef will
324 ** perform TLV detection internally if not performed already.
325 ** An application may call this API to check the a
326 ** tag/card-emulator's total Reserved/
327 ** Lock bytes before issuing a write-request.
328 **
329 ** Returns:
330 ** NFA_STATUS_OK if successfully initiated
331 ** NFC_STATUS_REFUSED if tlv_type is NDEF & tag won't support
332 ** NDEF
333 ** NFA_STATUS_FAILED otherwise
334 **
335 *******************************************************************************/
NFA_RwLocateTlv(uint8_t tlv_type)336 tNFA_STATUS NFA_RwLocateTlv(uint8_t tlv_type) {
337 tNFA_RW_OPERATION* p_msg;
338
339 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
340
341 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
342 if (p_msg != nullptr) {
343 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
344
345 if (tlv_type == TAG_LOCK_CTRL_TLV) {
346 p_msg->op = NFA_RW_OP_DETECT_LOCK_TLV;
347 } else if (tlv_type == TAG_MEM_CTRL_TLV) {
348 p_msg->op = NFA_RW_OP_DETECT_MEM_TLV;
349 } else if (tlv_type == TAG_NDEF_TLV) {
350 p_msg->op = NFA_RW_OP_DETECT_NDEF;
351 } else
352 return (NFA_STATUS_FAILED);
353
354 nfa_sys_sendmsg(p_msg);
355
356 return (NFA_STATUS_OK);
357 }
358
359 return (NFA_STATUS_FAILED);
360 }
361
362 /*******************************************************************************
363 **
364 ** Function NFA_RwT1tRid
365 **
366 ** Description:
367 ** Send a RID command to the activated Type 1 tag.
368 **
369 ** Data is returned to the application using the NFA_DATA_EVT. When the
370 ** read operation has completed, or if an error occurs, the app will be
371 ** notified with NFA_READ_CPLT_EVT.
372 **
373 ** Returns:
374 ** NFA_STATUS_OK if successfully initiated
375 ** NFA_STATUS_FAILED otherwise
376 **
377 *******************************************************************************/
NFA_RwT1tRid(void)378 tNFA_STATUS NFA_RwT1tRid(void) {
379 tNFA_RW_OPERATION* p_msg;
380
381 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
382 if (p_msg != nullptr) {
383 /* Fill in tNFA_RW_OPERATION struct */
384 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
385 p_msg->op = NFA_RW_OP_T1T_RID;
386
387 nfa_sys_sendmsg(p_msg);
388 return (NFA_STATUS_OK);
389 }
390 return (NFA_STATUS_FAILED);
391 }
392
393 /*******************************************************************************
394 **
395 ** Function NFA_RwT1tReadAll
396 **
397 ** Description:
398 ** Send a RALL command to the activated Type 1 tag.
399 **
400 ** Data is returned to the application using the NFA_DATA_EVT. When the
401 ** read operation has completed, or if an error occurs, the app will be
402 ** notified with NFA_READ_CPLT_EVT.
403 **
404 ** Returns:
405 ** NFA_STATUS_OK if successfully initiated
406 ** NFA_STATUS_FAILED otherwise
407 **
408 *******************************************************************************/
NFA_RwT1tReadAll(void)409 tNFA_STATUS NFA_RwT1tReadAll(void) {
410 tNFA_RW_OPERATION* p_msg;
411
412 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
413 if (p_msg != nullptr) {
414 /* Fill in tNFA_RW_OPERATION struct */
415 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
416 p_msg->op = NFA_RW_OP_T1T_RALL;
417
418 nfa_sys_sendmsg(p_msg);
419 return (NFA_STATUS_OK);
420 }
421 return (NFA_STATUS_FAILED);
422 }
423
424 /*******************************************************************************
425 **
426 ** Function NFA_RwT1tRead
427 **
428 ** Description:
429 ** Send a READ command to the activated Type 1 tag.
430 **
431 ** Data is returned to the application using the NFA_DATA_EVT. When the
432 ** read operation has completed, or if an error occurs, the app will be
433 ** notified with NFA_READ_CPLT_EVT.
434 **
435 ** Returns:
436 ** NFA_STATUS_OK if successfully initiated
437 ** NFA_STATUS_FAILED otherwise
438 **
439 *******************************************************************************/
NFA_RwT1tRead(uint8_t block_number,uint8_t index)440 tNFA_STATUS NFA_RwT1tRead(uint8_t block_number, uint8_t index) {
441 tNFA_RW_OPERATION* p_msg;
442
443 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
444 if (p_msg != nullptr) {
445 /* Fill in tNFA_RW_OPERATION struct */
446 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
447 p_msg->op = NFA_RW_OP_T1T_READ;
448 p_msg->params.t1t_read.block_number = block_number;
449 p_msg->params.t1t_read.index = index;
450
451 nfa_sys_sendmsg(p_msg);
452 return (NFA_STATUS_OK);
453 }
454 return (NFA_STATUS_FAILED);
455 }
456
457 /*******************************************************************************
458 **
459 ** Function NFA_RwT1tWrite
460 **
461 ** Description:
462 ** Send a WRITE command to the activated Type 1 tag.
463 **
464 ** Data is returned to the application using the NFA_DATA_EVT. When the
465 ** write operation has completed, or if an error occurs, the app will be
466 ** notified with NFA_WRITE_CPLT_EVT.
467 **
468 ** Returns:
469 ** NFA_STATUS_OK if successfully initiated
470 ** NFA_STATUS_FAILED otherwise
471 **
472 *******************************************************************************/
NFA_RwT1tWrite(uint8_t block_number,uint8_t index,uint8_t data,bool b_erase)473 tNFA_STATUS NFA_RwT1tWrite(uint8_t block_number, uint8_t index, uint8_t data,
474 bool b_erase) {
475 tNFA_RW_OPERATION* p_msg;
476
477 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
478 if (p_msg != nullptr) {
479 /* Fill in tNFA_RW_OPERATION struct */
480 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
481 p_msg->params.t1t_write.b_erase = b_erase;
482 p_msg->op = NFA_RW_OP_T1T_WRITE;
483 p_msg->params.t1t_write.block_number = block_number;
484 p_msg->params.t1t_write.index = index;
485 p_msg->params.t1t_write.p_block_data[0] = data;
486
487 nfa_sys_sendmsg(p_msg);
488 return (NFA_STATUS_OK);
489 }
490 return (NFA_STATUS_FAILED);
491 }
492
493 /*******************************************************************************
494 **
495 ** Function NFA_RwT1tReadSeg
496 **
497 ** Description:
498 ** Send a RSEG command to the activated Type 1 tag.
499 **
500 ** Data is returned to the application using the NFA_DATA_EVT. When the
501 ** read operation has completed, or if an error occurs, the app will be
502 ** notified with NFA_READ_CPLT_EVT.
503 **
504 ** Returns:
505 ** NFA_STATUS_OK if successfully initiated
506 ** NFA_STATUS_FAILED otherwise
507 **
508 *******************************************************************************/
NFA_RwT1tReadSeg(uint8_t segment_number)509 tNFA_STATUS NFA_RwT1tReadSeg(uint8_t segment_number) {
510 tNFA_RW_OPERATION* p_msg;
511
512 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
513 if (p_msg != nullptr) {
514 /* Fill in tNFA_RW_OPERATION struct */
515 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
516 p_msg->op = NFA_RW_OP_T1T_RSEG;
517 p_msg->params.t1t_read.segment_number = segment_number;
518
519 nfa_sys_sendmsg(p_msg);
520 return (NFA_STATUS_OK);
521 }
522 return (NFA_STATUS_FAILED);
523 }
524
525 /*******************************************************************************
526 **
527 ** Function NFA_RwT1tRead8
528 **
529 ** Description:
530 ** Send a READ8 command to the activated Type 1 tag.
531 **
532 ** Data is returned to the application using the NFA_DATA_EVT. When the
533 ** read operation has completed, or if an error occurs, the app will be
534 ** notified with NFA_READ_CPLT_EVT.
535 **
536 ** Returns:
537 ** NFA_STATUS_OK if successfully initiated
538 ** NFA_STATUS_FAILED otherwise
539 **
540 *******************************************************************************/
NFA_RwT1tRead8(uint8_t block_number)541 tNFA_STATUS NFA_RwT1tRead8(uint8_t block_number) {
542 tNFA_RW_OPERATION* p_msg;
543
544 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
545 if (p_msg != nullptr) {
546 /* Fill in tNFA_RW_OPERATION struct */
547 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
548 p_msg->op = NFA_RW_OP_T1T_READ8;
549 p_msg->params.t1t_write.block_number = block_number;
550
551 nfa_sys_sendmsg(p_msg);
552 return (NFA_STATUS_OK);
553 }
554 return (NFA_STATUS_FAILED);
555 }
556
557 /*******************************************************************************
558 **
559 ** Function NFA_RwT1tWrite8
560 **
561 ** Description:
562 ** Send a WRITE8_E / WRITE8_NE command to the activated Type 1 tag.
563 **
564 ** Data is returned to the application using the NFA_DATA_EVT. When the
565 ** read operation has completed, or if an error occurs, the app will be
566 ** notified with NFA_READ_CPLT_EVT.
567 **
568 ** Returns:
569 ** NFA_STATUS_OK if successfully initiated
570 ** NFA_STATUS_FAILED otherwise
571 **
572 *******************************************************************************/
NFA_RwT1tWrite8(uint8_t block_number,uint8_t * p_data,bool b_erase)573 tNFA_STATUS NFA_RwT1tWrite8(uint8_t block_number, uint8_t* p_data,
574 bool b_erase) {
575 tNFA_RW_OPERATION* p_msg;
576
577 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
578 if (p_msg != nullptr) {
579 /* Fill in tNFA_RW_OPERATION struct */
580 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
581 p_msg->params.t1t_write.b_erase = b_erase;
582 p_msg->op = NFA_RW_OP_T1T_WRITE8;
583 p_msg->params.t1t_write.block_number = block_number;
584
585 memcpy(p_msg->params.t1t_write.p_block_data, p_data, 8);
586
587 nfa_sys_sendmsg(p_msg);
588 return (NFA_STATUS_OK);
589 }
590 return (NFA_STATUS_FAILED);
591 }
592
593 /*******************************************************************************
594 **
595 ** Function NFA_RwT2tRead
596 **
597 ** Description:
598 ** Send a READ command to the activated Type 2 tag.
599 **
600 ** Data is returned to the application using the NFA_DATA_EVT. When the
601 ** read operation has completed, or if an error occurs, the app will be
602 ** notified with NFA_READ_CPLT_EVT.
603 **
604 ** Returns:
605 ** NFA_STATUS_OK if successfully initiated
606 ** NFA_STATUS_FAILED otherwise
607 **
608 *******************************************************************************/
NFA_RwT2tRead(uint8_t block_number)609 tNFA_STATUS NFA_RwT2tRead(uint8_t block_number) {
610 tNFA_RW_OPERATION* p_msg;
611
612 DLOG_IF(INFO, nfc_debug_enabled)
613 << StringPrintf("Block to read: %d", block_number);
614
615 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
616 if (p_msg != nullptr) {
617 /* Fill in tNFA_RW_OPERATION struct */
618 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
619 p_msg->op = NFA_RW_OP_T2T_READ;
620 p_msg->params.t2t_read.block_number = block_number;
621
622 nfa_sys_sendmsg(p_msg);
623 return (NFA_STATUS_OK);
624 }
625 return (NFA_STATUS_FAILED);
626 }
627
628 /*******************************************************************************
629 **
630 ** Function NFA_RwT2tWrite
631 **
632 ** Description:
633 ** Send an WRITE command to the activated Type 2 tag.
634 **
635 ** When the write operation has completed (or if an error occurs), the
636 ** app will be notified with NFA_WRITE_CPLT_EVT.
637 **
638 ** Returns:
639 ** NFA_STATUS_OK if successfully initiated
640 ** NFA_STATUS_FAILED otherwise
641 **
642 *******************************************************************************/
NFA_RwT2tWrite(uint8_t block_number,uint8_t * p_data)643 tNFA_STATUS NFA_RwT2tWrite(uint8_t block_number, uint8_t* p_data) {
644 tNFA_RW_OPERATION* p_msg;
645
646 DLOG_IF(INFO, nfc_debug_enabled)
647 << StringPrintf("Block to write: %d", block_number);
648
649 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
650 if (p_msg != nullptr) {
651 /* Fill in tNFA_RW_OPERATION struct */
652 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
653 p_msg->op = NFA_RW_OP_T2T_WRITE;
654
655 p_msg->params.t2t_write.block_number = block_number;
656
657 memcpy(p_msg->params.t2t_write.p_block_data, p_data, 4);
658
659 nfa_sys_sendmsg(p_msg);
660 return (NFA_STATUS_OK);
661 }
662 return (NFA_STATUS_FAILED);
663 }
664
665 /*******************************************************************************
666 **
667 ** Function NFA_RwT2tSectorSelect
668 **
669 ** Description:
670 ** Send SECTOR SELECT command to the activated Type 2 tag.
671 **
672 ** When the sector select operation has completed (or if an error occurs),
673 ** the app will be notified with NFA_SECTOR_SELECT_CPLT_EVT.
674 **
675 ** Returns:
676 ** NFA_STATUS_OK if successfully initiated
677 ** NFA_STATUS_FAILED otherwise
678 **
679 *******************************************************************************/
NFA_RwT2tSectorSelect(uint8_t sector_number)680 tNFA_STATUS NFA_RwT2tSectorSelect(uint8_t sector_number) {
681 tNFA_RW_OPERATION* p_msg;
682
683 DLOG_IF(INFO, nfc_debug_enabled)
684 << StringPrintf("sector to select: %d", sector_number);
685
686 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
687 if (p_msg != nullptr) {
688 /* Fill in tNFA_RW_OPERATION struct */
689 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
690 p_msg->op = NFA_RW_OP_T2T_SECTOR_SELECT;
691
692 p_msg->params.t2t_sector_select.sector_number = sector_number;
693
694 nfa_sys_sendmsg(p_msg);
695 return (NFA_STATUS_OK);
696 }
697 return (NFA_STATUS_FAILED);
698 }
699
700 /*******************************************************************************
701 **
702 ** Function NFA_RwT2tReadDynLockBytes
703 **
704 ** Description:
705 ** Configure NFA skip_dyn_locks flag.
706 **
707 ** This API must be called after activation but before NFA_RwDetectNDef()
708 ** or NFA_RwReadNDef() and NFA_RwWriteNDef() in case NDEF Detection is
709 ** triggered internally. It overwrites skip_dyn_locks default setting
710 ** set to false at activation. If not called, at the end of the NDEF
711 ** Detection, the DynLock_Area will be read and its content used to define
712 ** max_ndef_msg_len.
713 **
714 ** When the operation has completed (or if an error occurs), the app will
715 ** be notified with NFA_T2T_CMD_CPLT_EVT.
716 **
717 ** Returns:
718 ** NFA_STATUS_OK if successfully initiated
719 ** NFA_STATUS_FAILED otherwise
720 **
721 *******************************************************************************/
NFA_RwT2tReadDynLockBytes(bool read_dyn_locks)722 tNFA_STATUS NFA_RwT2tReadDynLockBytes(bool read_dyn_locks) {
723 tNFA_RW_OPERATION* p_msg;
724
725 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
726 "%s - read DynLock_Area bytes: %d", __func__, read_dyn_locks);
727
728 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
729 if (p_msg != nullptr) {
730 /* Fill in tNFA_RW_OPERATION struct */
731 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
732 p_msg->op = NFA_RW_OP_T2T_READ_DYN_LOCKS;
733
734 p_msg->params.t2t_read_dyn_locks.read_dyn_locks = read_dyn_locks;
735
736 nfa_sys_sendmsg(p_msg);
737 return (NFA_STATUS_OK);
738 }
739 return (NFA_STATUS_FAILED);
740 }
741
742 /*******************************************************************************
743 **
744 ** Function NFA_RwT3tRead
745 **
746 ** Description:
747 ** Send a CHECK (read) command to the activated Type 3 tag.
748 **
749 ** Data is returned to the application using the NFA_DATA_EVT. When the
750 ** read operation has completed, or if an error occurs, the app will be
751 ** notified with NFA_READ_CPLT_EVT.
752 **
753 ** Returns:
754 ** NFA_STATUS_OK if successfully initiated
755 ** NFA_STATUS_FAILED otherwise
756 **
757 *******************************************************************************/
NFA_RwT3tRead(uint8_t num_blocks,tNFA_T3T_BLOCK_DESC * t3t_blocks)758 tNFA_STATUS NFA_RwT3tRead(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks) {
759 tNFA_RW_OPERATION* p_msg;
760 uint8_t* p_block_desc;
761
762 DLOG_IF(INFO, nfc_debug_enabled)
763 << StringPrintf("num_blocks to read: %i", num_blocks);
764
765 /* Validate parameters */
766 if ((num_blocks == 0) || (t3t_blocks == nullptr))
767 return (NFA_STATUS_INVALID_PARAM);
768
769 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(
770 sizeof(tNFA_RW_OPERATION) + (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC))));
771 if (p_msg != nullptr) {
772 /* point to area after tNFA_RW_OPERATION */
773 p_block_desc = (uint8_t*)(p_msg + 1);
774
775 /* Fill in tNFA_RW_OPERATION struct */
776 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
777 p_msg->op = NFA_RW_OP_T3T_READ;
778
779 p_msg->params.t3t_read.num_blocks = num_blocks;
780 p_msg->params.t3t_read.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
781
782 /* Copy block descriptor list */
783 memcpy(p_block_desc, t3t_blocks,
784 (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
785
786 nfa_sys_sendmsg(p_msg);
787
788 return (NFA_STATUS_OK);
789 }
790
791 return (NFA_STATUS_FAILED);
792 }
793
794 /*******************************************************************************
795 **
796 ** Function NFA_RwT3tWrite
797 **
798 ** Description:
799 ** Send an UPDATE (write) command to the activated Type 3 tag.
800 **
801 ** When the write operation has completed (or if an error occurs), the
802 ** app will be notified with NFA_WRITE_CPLT_EVT.
803 **
804 ** Returns:
805 ** NFA_STATUS_OK if successfully initiated
806 ** NFA_STATUS_FAILED otherwise
807 **
808 *******************************************************************************/
NFA_RwT3tWrite(uint8_t num_blocks,tNFA_T3T_BLOCK_DESC * t3t_blocks,uint8_t * p_data)809 tNFA_STATUS NFA_RwT3tWrite(uint8_t num_blocks, tNFA_T3T_BLOCK_DESC* t3t_blocks,
810 uint8_t* p_data) {
811 tNFA_RW_OPERATION* p_msg;
812 uint8_t *p_block_desc, *p_data_area;
813
814 DLOG_IF(INFO, nfc_debug_enabled)
815 << StringPrintf("num_blocks to write: %i", num_blocks);
816
817 /* Validate parameters */
818 if ((num_blocks == 0) || (t3t_blocks == nullptr) | (p_data == nullptr))
819 return (NFA_STATUS_INVALID_PARAM);
820
821 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
822 (uint16_t)(sizeof(tNFA_RW_OPERATION) +
823 (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC) + 16))));
824 if (p_msg != nullptr) {
825 /* point to block descriptor and data areas after tNFA_RW_OPERATION */
826 p_block_desc = (uint8_t*)(p_msg + 1);
827 p_data_area = p_block_desc + (num_blocks * (sizeof(tNFA_T3T_BLOCK_DESC)));
828
829 /* Fill in tNFA_RW_OPERATION struct */
830 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
831 p_msg->op = NFA_RW_OP_T3T_WRITE;
832
833 p_msg->params.t3t_write.num_blocks = num_blocks;
834 p_msg->params.t3t_write.p_block_desc = (tNFA_T3T_BLOCK_DESC*)p_block_desc;
835 p_msg->params.t3t_write.p_block_data = p_data_area;
836
837 /* Copy block descriptor list */
838 memcpy(p_block_desc, t3t_blocks,
839 (num_blocks * sizeof(tNFA_T3T_BLOCK_DESC)));
840
841 /* Copy data */
842 memcpy(p_data_area, p_data, (num_blocks * 16));
843
844 nfa_sys_sendmsg(p_msg);
845
846 return (NFA_STATUS_OK);
847 }
848
849 return (NFA_STATUS_FAILED);
850 }
851
852 /*******************************************************************************
853 **
854 ** Function NFA_RwI93Inventory
855 **
856 ** Description:
857 ** Send Inventory command to the activated ISO T5T tag with/without AFI
858 ** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
859 **
860 ** When the operation has completed (or if an error occurs), the
861 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
862 **
863 ** Returns:
864 ** NFA_STATUS_OK if successfully initiated
865 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
866 ** NFA_STATUS_FAILED otherwise
867 **
868 *******************************************************************************/
NFA_RwI93Inventory(bool afi_present,uint8_t afi,uint8_t * p_uid)869 tNFA_STATUS NFA_RwI93Inventory(bool afi_present, uint8_t afi, uint8_t* p_uid) {
870 tNFA_RW_OPERATION* p_msg;
871
872 DLOG_IF(INFO, nfc_debug_enabled)
873 << StringPrintf("afi_present:%d, AFI: 0x%02X", afi_present, afi);
874
875 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
876 return (NFA_STATUS_WRONG_PROTOCOL);
877 }
878
879 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
880 if (p_msg != nullptr) {
881 /* Fill in tNFA_RW_OPERATION struct */
882 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
883 p_msg->op = NFA_RW_OP_I93_INVENTORY;
884
885 p_msg->params.i93_cmd.afi_present = afi_present;
886 p_msg->params.i93_cmd.afi = afi;
887
888 if (p_uid) {
889 p_msg->params.i93_cmd.uid_present = true;
890 memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
891 } else {
892 p_msg->params.i93_cmd.uid_present = false;
893 }
894
895 nfa_sys_sendmsg(p_msg);
896
897 return (NFA_STATUS_OK);
898 }
899
900 return (NFA_STATUS_FAILED);
901 }
902
903 /*******************************************************************************
904 **
905 ** Function NFA_RwI93StayQuiet
906 **
907 ** Description:
908 ** Send Stay Quiet command to the activated T5T tag.
909 **
910 ** When the operation has completed (or if an error occurs), the
911 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
912 **
913 ** Returns:
914 ** NFA_STATUS_OK if successfully initiated
915 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
916 ** NFA_STATUS_FAILED otherwise
917 **
918 *******************************************************************************/
NFA_RwI93StayQuiet(uint8_t * p_uid)919 tNFA_STATUS NFA_RwI93StayQuiet(uint8_t* p_uid) {
920 tNFA_RW_OPERATION* p_msg;
921
922 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
923
924 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
925 return (NFA_STATUS_WRONG_PROTOCOL);
926 }
927
928 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
929 if (p_msg != nullptr) {
930 /* Fill in tNFA_RW_OPERATION struct */
931 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
932 p_msg->op = NFA_RW_OP_I93_STAY_QUIET;
933 p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
934 memcpy(p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
935
936 nfa_sys_sendmsg(p_msg);
937
938 return (NFA_STATUS_OK);
939 }
940
941 return (NFA_STATUS_FAILED);
942 }
943
944 /*******************************************************************************
945 **
946 ** Function NFA_RwI93ReadSingleBlock
947 **
948 ** Description:
949 ** Send Read Single Block command to the activated T5T tag.
950 **
951 ** Data is returned to the application using the NFA_DATA_EVT. When the
952 ** read operation has completed, or if an error occurs, the app will be
953 ** notified with NFA_I93_CMD_CPLT_EVT.
954 **
955 ** Returns:
956 ** NFA_STATUS_OK if successfully initiated
957 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
958 ** NFA_STATUS_FAILED otherwise
959 **
960 *******************************************************************************/
NFA_RwI93ReadSingleBlock(uint8_t block_number)961 tNFA_STATUS NFA_RwI93ReadSingleBlock(uint8_t block_number) {
962 tNFA_RW_OPERATION* p_msg;
963
964 DLOG_IF(INFO, nfc_debug_enabled)
965 << StringPrintf("block_number: 0x%02X", block_number);
966
967 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
968 return (NFA_STATUS_WRONG_PROTOCOL);
969 }
970
971 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
972 if (p_msg != nullptr) {
973 /* Fill in tNFA_RW_OPERATION struct */
974 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
975 p_msg->op = NFA_RW_OP_I93_READ_SINGLE_BLOCK;
976
977 p_msg->params.i93_cmd.first_block_number = block_number;
978
979 nfa_sys_sendmsg(p_msg);
980
981 return (NFA_STATUS_OK);
982 }
983
984 return (NFA_STATUS_FAILED);
985 }
986
987 /*******************************************************************************
988 **
989 ** Function NFA_RwI93WriteSingleBlock
990 **
991 ** Description:
992 ** Send Write Single Block command to the activated T5T tag.
993 **
994 ** When the write operation has completed (or if an error occurs), the
995 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
996 **
997 ** Returns:
998 ** NFA_STATUS_OK if successfully initiated
999 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1000 ** NFA_STATUS_FAILED otherwise
1001 **
1002 *******************************************************************************/
NFA_RwI93WriteSingleBlock(uint8_t block_number,uint8_t * p_data)1003 tNFA_STATUS NFA_RwI93WriteSingleBlock(uint8_t block_number, uint8_t* p_data) {
1004 tNFA_RW_OPERATION* p_msg;
1005
1006 DLOG_IF(INFO, nfc_debug_enabled)
1007 << StringPrintf("block_number: 0x%02X", block_number);
1008
1009 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1010 return (NFA_STATUS_WRONG_PROTOCOL);
1011 }
1012
1013 /* we don't know block size of tag */
1014 if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
1015 return (NFA_STATUS_FAILED);
1016 }
1017
1018 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
1019 (uint16_t)(sizeof(tNFA_RW_OPERATION) + nfa_rw_cb.i93_block_size));
1020 if (p_msg != nullptr) {
1021 /* Fill in tNFA_RW_OPERATION struct */
1022 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1023 p_msg->op = NFA_RW_OP_I93_WRITE_SINGLE_BLOCK;
1024
1025 p_msg->params.i93_cmd.first_block_number = block_number;
1026 p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
1027
1028 memcpy(p_msg->params.i93_cmd.p_data, p_data, nfa_rw_cb.i93_block_size);
1029
1030 nfa_sys_sendmsg(p_msg);
1031
1032 return (NFA_STATUS_OK);
1033 }
1034
1035 return (NFA_STATUS_FAILED);
1036 }
1037
1038 /*******************************************************************************
1039 **
1040 ** Function NFA_RwI93LockBlock
1041 **
1042 ** Description:
1043 ** Send Lock block command to the activated T5T tag.
1044 **
1045 ** When the operation has completed (or if an error occurs), the
1046 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1047 **
1048 ** Returns:
1049 ** NFA_STATUS_OK if successfully initiated
1050 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1051 ** NFA_STATUS_FAILED otherwise
1052 **
1053 *******************************************************************************/
NFA_RwI93LockBlock(uint8_t block_number)1054 tNFA_STATUS NFA_RwI93LockBlock(uint8_t block_number) {
1055 tNFA_RW_OPERATION* p_msg;
1056
1057 DLOG_IF(INFO, nfc_debug_enabled)
1058 << StringPrintf("block_number: 0x%02X", block_number);
1059
1060 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1061 return (NFA_STATUS_WRONG_PROTOCOL);
1062 }
1063
1064 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1065 if (p_msg != nullptr) {
1066 /* Fill in tNFA_RW_OPERATION struct */
1067 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1068 p_msg->op = NFA_RW_OP_I93_LOCK_BLOCK;
1069
1070 p_msg->params.i93_cmd.first_block_number = block_number;
1071
1072 nfa_sys_sendmsg(p_msg);
1073
1074 return (NFA_STATUS_OK);
1075 }
1076
1077 return (NFA_STATUS_FAILED);
1078 }
1079
1080 /*******************************************************************************
1081 **
1082 ** Function NFA_RwI93ReadMultipleBlocks
1083 **
1084 ** Description:
1085 ** Send Read Multiple Block command to the activated T5T tag.
1086 **
1087 ** Data is returned to the application using the NFA_DATA_EVT. When the
1088 ** read operation has completed, or if an error occurs, the app will be
1089 ** notified with NFA_I93_CMD_CPLT_EVT.
1090 **
1091 ** Returns:
1092 ** NFA_STATUS_OK if successfully initiated
1093 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1094 ** NFA_STATUS_FAILED otherwise
1095 **
1096 *******************************************************************************/
NFA_RwI93ReadMultipleBlocks(uint8_t first_block_number,uint16_t number_blocks)1097 tNFA_STATUS NFA_RwI93ReadMultipleBlocks(uint8_t first_block_number,
1098 uint16_t number_blocks) {
1099 tNFA_RW_OPERATION* p_msg;
1100
1101 DLOG_IF(INFO, nfc_debug_enabled)
1102 << StringPrintf("%d, %d", first_block_number, number_blocks);
1103
1104 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1105 return (NFA_STATUS_WRONG_PROTOCOL);
1106 }
1107
1108 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1109 if (p_msg != nullptr) {
1110 /* Fill in tNFA_RW_OPERATION struct */
1111 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1112 p_msg->op = NFA_RW_OP_I93_READ_MULTI_BLOCK;
1113
1114 p_msg->params.i93_cmd.first_block_number = first_block_number;
1115 p_msg->params.i93_cmd.number_blocks = number_blocks;
1116
1117 nfa_sys_sendmsg(p_msg);
1118
1119 return (NFA_STATUS_OK);
1120 }
1121
1122 return (NFA_STATUS_FAILED);
1123 }
1124
1125 /*******************************************************************************
1126 **
1127 ** Function NFA_RwI93WriteMultipleBlocks
1128 **
1129 ** Description:
1130 ** Send Write Multiple Block command to the activated T5T tag.
1131 **
1132 ** When the write operation has completed (or if an error occurs), the
1133 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1134 **
1135 ** Returns:
1136 ** NFA_STATUS_OK if successfully initiated
1137 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1138 ** NFA_STATUS_FAILED otherwise
1139 **
1140 *******************************************************************************/
NFA_RwI93WriteMultipleBlocks(uint8_t first_block_number,uint16_t number_blocks,uint8_t * p_data)1141 tNFA_STATUS NFA_RwI93WriteMultipleBlocks(uint8_t first_block_number,
1142 uint16_t number_blocks,
1143 uint8_t* p_data) {
1144 tNFA_RW_OPERATION* p_msg;
1145 uint32_t data_length;
1146
1147 DLOG_IF(INFO, nfc_debug_enabled)
1148 << StringPrintf("%d, %d", first_block_number, number_blocks);
1149
1150 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1151 return (NFA_STATUS_WRONG_PROTOCOL);
1152 }
1153
1154 /* we don't know block size of tag */
1155 if ((nfa_rw_cb.i93_block_size == 0) || (nfa_rw_cb.i93_num_block == 0)) {
1156 return (NFA_STATUS_FAILED);
1157 }
1158
1159 data_length = nfa_rw_cb.i93_block_size * number_blocks;
1160
1161 if (data_length + sizeof(tNFA_RW_OPERATION) > UINT16_MAX) {
1162 android_errorWriteLog(0x534e4554, "157650338");
1163 return (NFA_STATUS_FAILED);
1164 }
1165
1166 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
1167 (uint16_t)(sizeof(tNFA_RW_OPERATION) + data_length));
1168 if (p_msg != nullptr) {
1169 /* Fill in tNFA_RW_OPERATION struct */
1170 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1171 p_msg->op = NFA_RW_OP_I93_WRITE_MULTI_BLOCK;
1172
1173 p_msg->params.i93_cmd.first_block_number = first_block_number;
1174 p_msg->params.i93_cmd.number_blocks = number_blocks;
1175 p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
1176
1177 memcpy(p_msg->params.i93_cmd.p_data, p_data, data_length);
1178
1179 nfa_sys_sendmsg(p_msg);
1180
1181 return (NFA_STATUS_OK);
1182 }
1183
1184 return (NFA_STATUS_FAILED);
1185 }
1186
1187 /*******************************************************************************
1188 **
1189 ** Function NFA_RwI93Select
1190 **
1191 ** Description:
1192 ** Send Select command to the activated T5T tag.
1193 **
1194 ** UID[0]: 0xE0, MSB
1195 ** UID[1]: IC Mfg Code
1196 ** ...
1197 ** UID[7]: LSB
1198 **
1199 ** When the operation has completed (or if an error occurs), the
1200 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1201 **
1202 ** Returns:
1203 ** NFA_STATUS_OK if successfully initiated
1204 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1205 ** NFA_STATUS_FAILED otherwise
1206 **
1207 *******************************************************************************/
NFA_RwI93Select(uint8_t * p_uid)1208 tNFA_STATUS NFA_RwI93Select(uint8_t* p_uid) {
1209 tNFA_RW_OPERATION* p_msg;
1210
1211 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1212 "UID: [%02X%02X%02X...]", *(p_uid), *(p_uid + 1), *(p_uid + 2));
1213
1214 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1215 return (NFA_STATUS_WRONG_PROTOCOL);
1216 }
1217
1218 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf(
1219 (uint16_t)(sizeof(tNFA_RW_OPERATION) + I93_UID_BYTE_LEN));
1220 if (p_msg != nullptr) {
1221 /* Fill in tNFA_RW_OPERATION struct */
1222 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1223 p_msg->op = NFA_RW_OP_I93_SELECT;
1224
1225 p_msg->params.i93_cmd.p_data = (uint8_t*)(p_msg + 1);
1226 memcpy(p_msg->params.i93_cmd.p_data, p_uid, I93_UID_BYTE_LEN);
1227
1228 nfa_sys_sendmsg(p_msg);
1229
1230 return (NFA_STATUS_OK);
1231 }
1232
1233 return (NFA_STATUS_FAILED);
1234 }
1235
1236 /*******************************************************************************
1237 **
1238 ** Function NFA_RwI93ResetToReady
1239 **
1240 ** Description:
1241 ** Send Reset to ready command to the activated T5T tag.
1242 **
1243 ** When the operation has completed (or if an error occurs), the
1244 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1245 **
1246 ** Returns:
1247 ** NFA_STATUS_OK if successfully initiated
1248 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1249 ** NFA_STATUS_FAILED otherwise
1250 **
1251 *******************************************************************************/
NFA_RwI93ResetToReady(void)1252 tNFA_STATUS NFA_RwI93ResetToReady(void) {
1253 tNFA_RW_OPERATION* p_msg;
1254
1255 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1256
1257 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1258 return (NFA_STATUS_WRONG_PROTOCOL);
1259 }
1260
1261 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1262 if (p_msg != nullptr) {
1263 /* Fill in tNFA_RW_OPERATION struct */
1264 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1265 p_msg->op = NFA_RW_OP_I93_RESET_TO_READY;
1266
1267 nfa_sys_sendmsg(p_msg);
1268
1269 return (NFA_STATUS_OK);
1270 }
1271
1272 return (NFA_STATUS_FAILED);
1273 }
1274
1275 /*******************************************************************************
1276 **
1277 ** Function NFA_RwI93WriteAFI
1278 **
1279 ** Description:
1280 ** Send Write AFI command to the activated T5T tag.
1281 **
1282 ** When the operation has completed (or if an error occurs), the
1283 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1284 **
1285 ** Returns:
1286 ** NFA_STATUS_OK if successfully initiated
1287 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1288 ** NFA_STATUS_FAILED otherwise
1289 **
1290 *******************************************************************************/
NFA_RwI93WriteAFI(uint8_t afi)1291 tNFA_STATUS NFA_RwI93WriteAFI(uint8_t afi) {
1292 tNFA_RW_OPERATION* p_msg;
1293
1294 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("AFI: 0x%02X", afi);
1295
1296 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1297 return (NFA_STATUS_WRONG_PROTOCOL);
1298 }
1299
1300 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1301 if (p_msg != nullptr) {
1302 /* Fill in tNFA_RW_OPERATION struct */
1303 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1304 p_msg->op = NFA_RW_OP_I93_WRITE_AFI;
1305
1306 p_msg->params.i93_cmd.afi = afi;
1307
1308 nfa_sys_sendmsg(p_msg);
1309
1310 return (NFA_STATUS_OK);
1311 }
1312
1313 return (NFA_STATUS_FAILED);
1314 }
1315
1316 /*******************************************************************************
1317 **
1318 ** Function NFA_RwI93LockAFI
1319 **
1320 ** Description:
1321 ** Send Lock AFI command to the activated T5T tag.
1322 **
1323 ** When the operation has completed (or if an error occurs), the
1324 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1325 **
1326 ** Returns:
1327 ** NFA_STATUS_OK if successfully initiated
1328 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1329 ** NFA_STATUS_FAILED otherwise
1330 **
1331 *******************************************************************************/
NFA_RwI93LockAFI(void)1332 tNFA_STATUS NFA_RwI93LockAFI(void) {
1333 tNFA_RW_OPERATION* p_msg;
1334
1335 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1336
1337 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1338 return (NFA_STATUS_WRONG_PROTOCOL);
1339 }
1340
1341 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1342 if (p_msg != nullptr) {
1343 /* Fill in tNFA_RW_OPERATION struct */
1344 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1345 p_msg->op = NFA_RW_OP_I93_LOCK_AFI;
1346
1347 nfa_sys_sendmsg(p_msg);
1348
1349 return (NFA_STATUS_OK);
1350 }
1351
1352 return (NFA_STATUS_FAILED);
1353 }
1354
1355 /*******************************************************************************
1356 **
1357 ** Function NFA_RwI93WriteDSFID
1358 **
1359 ** Description:
1360 ** Send Write DSFID command to the activated T5T tag.
1361 **
1362 ** When the operation has completed (or if an error occurs), the
1363 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1364 **
1365 ** Returns:
1366 ** NFA_STATUS_OK if successfully initiated
1367 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1368 ** NFA_STATUS_FAILED otherwise
1369 **
1370 *******************************************************************************/
NFA_RwI93WriteDSFID(uint8_t dsfid)1371 tNFA_STATUS NFA_RwI93WriteDSFID(uint8_t dsfid) {
1372 tNFA_RW_OPERATION* p_msg;
1373
1374 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("DSFID: 0x%02X", dsfid);
1375
1376 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1377 return (NFA_STATUS_WRONG_PROTOCOL);
1378 }
1379
1380 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1381 if (p_msg != nullptr) {
1382 /* Fill in tNFA_RW_OPERATION struct */
1383 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1384 p_msg->op = NFA_RW_OP_I93_WRITE_DSFID;
1385
1386 p_msg->params.i93_cmd.dsfid = dsfid;
1387
1388 nfa_sys_sendmsg(p_msg);
1389
1390 return (NFA_STATUS_OK);
1391 }
1392
1393 return (NFA_STATUS_FAILED);
1394 }
1395
1396 /*******************************************************************************
1397 **
1398 ** Function NFA_RwI93LockDSFID
1399 **
1400 ** Description:
1401 ** Send Lock DSFID command to the activated T5T tag.
1402 **
1403 ** When the operation has completed (or if an error occurs), the
1404 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1405 **
1406 ** Returns:
1407 ** NFA_STATUS_OK if successfully initiated
1408 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1409 ** NFA_STATUS_FAILED otherwise
1410 **
1411 *******************************************************************************/
NFA_RwI93LockDSFID(void)1412 tNFA_STATUS NFA_RwI93LockDSFID(void) {
1413 tNFA_RW_OPERATION* p_msg;
1414
1415 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1416
1417 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1418 return (NFA_STATUS_WRONG_PROTOCOL);
1419 }
1420
1421 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1422 if (p_msg != nullptr) {
1423 /* Fill in tNFA_RW_OPERATION struct */
1424 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1425 p_msg->op = NFA_RW_OP_I93_LOCK_DSFID;
1426
1427 nfa_sys_sendmsg(p_msg);
1428
1429 return (NFA_STATUS_OK);
1430 }
1431
1432 return (NFA_STATUS_FAILED);
1433 }
1434
1435 /*******************************************************************************
1436 **
1437 ** Function NFA_RwI93GetSysInfo
1438 **
1439 ** Description:
1440 ** Send Get system information command to the activated T5T tag.
1441 ** If UID is provided then set UID[0]:MSB, ... UID[7]:LSB
1442 **
1443 ** When the operation has completed (or if an error occurs), the
1444 ** app will be notified with NFA_I93_CMD_CPLT_EVT.
1445 **
1446 ** Returns:
1447 ** NFA_STATUS_OK if successfully initiated
1448 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1449 ** NFA_STATUS_FAILED otherwise
1450 **
1451 *******************************************************************************/
NFA_RwI93GetSysInfo(uint8_t * p_uid)1452 tNFA_STATUS NFA_RwI93GetSysInfo(uint8_t* p_uid) {
1453 tNFA_RW_OPERATION* p_msg;
1454
1455 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1456
1457 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1458 return (NFA_STATUS_WRONG_PROTOCOL);
1459 }
1460
1461 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1462 if (p_msg != nullptr) {
1463 /* Fill in tNFA_RW_OPERATION struct */
1464 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1465 p_msg->op = NFA_RW_OP_I93_GET_SYS_INFO;
1466
1467 if (p_uid) {
1468 p_msg->params.i93_cmd.uid_present = true;
1469 memcpy(p_msg->params.i93_cmd.uid, p_uid, I93_UID_BYTE_LEN);
1470 } else {
1471 p_msg->params.i93_cmd.uid_present = false;
1472 }
1473
1474 nfa_sys_sendmsg(p_msg);
1475
1476 return (NFA_STATUS_OK);
1477 }
1478
1479 return (NFA_STATUS_FAILED);
1480 }
1481
1482 /*******************************************************************************
1483 **
1484 ** Function NFA_RwI93GetMultiBlockSecurityStatus
1485 **
1486 ** Description:
1487 ** Send Get Multiple block security status command to the activated
1488 ** T5T tag.
1489 **
1490 ** Data is returned to the application using the NFA_DATA_EVT. When the
1491 ** read operation has completed, or if an error occurs, the app will be
1492 ** notified with NFA_I93_CMD_CPLT_EVT.
1493 **
1494 ** Returns:
1495 ** NFA_STATUS_OK if successfully initiated
1496 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1497 ** NFA_STATUS_FAILED otherwise
1498 **
1499 *******************************************************************************/
NFA_RwI93GetMultiBlockSecurityStatus(uint8_t first_block_number,uint16_t number_blocks)1500 tNFA_STATUS NFA_RwI93GetMultiBlockSecurityStatus(uint8_t first_block_number,
1501 uint16_t number_blocks) {
1502 tNFA_RW_OPERATION* p_msg;
1503
1504 DLOG_IF(INFO, nfc_debug_enabled)
1505 << StringPrintf("%d, %d", first_block_number, number_blocks);
1506
1507 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1508 return (NFA_STATUS_WRONG_PROTOCOL);
1509 }
1510
1511 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1512 if (p_msg != nullptr) {
1513 /* Fill in tNFA_RW_OPERATION struct */
1514 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1515 p_msg->op = NFA_RW_OP_I93_GET_MULTI_BLOCK_STATUS;
1516
1517 p_msg->params.i93_cmd.first_block_number = first_block_number;
1518 p_msg->params.i93_cmd.number_blocks = number_blocks;
1519
1520 nfa_sys_sendmsg(p_msg);
1521
1522 return (NFA_STATUS_OK);
1523 }
1524
1525 return (NFA_STATUS_FAILED);
1526 }
1527
1528 /*******************************************************************************
1529 **
1530 ** Function NFA_RwI93SetAddressingMode
1531 **
1532 ** Description:
1533 ** Set addressing mode to use to communicate with T5T tag.
1534 ** mode = true: addressed (default if API not called)
1535 ** mode = false: non-addressed
1536 **
1537 ** Returns:
1538 ** NFA_STATUS_OK if successfully initiated
1539 ** NFA_STATUS_WRONG_PROTOCOL: T5T tag not activated
1540 ** NFA_STATUS_FAILED otherwise
1541 **
1542 *******************************************************************************/
NFA_RwI93SetAddressingMode(bool mode)1543 tNFA_STATUS NFA_RwI93SetAddressingMode(bool mode) {
1544 tNFA_RW_OPERATION* p_msg;
1545
1546 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s - %d", __func__, mode);
1547
1548 if (nfa_rw_cb.protocol != NFC_PROTOCOL_T5T) {
1549 return (NFA_STATUS_WRONG_PROTOCOL);
1550 }
1551
1552 p_msg = (tNFA_RW_OPERATION*)GKI_getbuf((uint16_t)(sizeof(tNFA_RW_OPERATION)));
1553 if (p_msg != nullptr) {
1554 /* Fill in tNFA_RW_OPERATION struct */
1555 p_msg->hdr.event = NFA_RW_OP_REQUEST_EVT;
1556 p_msg->op = NFA_RW_OP_I93_SET_ADDR_MODE;
1557
1558 p_msg->params.i93_cmd.addr_mode = mode;
1559
1560 nfa_sys_sendmsg(p_msg);
1561
1562 return (NFA_STATUS_OK);
1563 }
1564
1565 return (NFA_STATUS_FAILED);
1566 }
1567