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