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