xref: /aosp_15_r20/system/nfc/src/nfa/rw/nfa_rw_api.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
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