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