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