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