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