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