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