1 /*
2  * Copyright (C) 2010 NXP Semiconductors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  * \file  phFriNfc_Desfire.h
19  * \brief NFC Ndef Mapping For Desfire Smart Card.
20  *
21  * Project: NFC-FRI
22  *
23  * $Date: Tue Jul 27 08:58:21 2010 $
24  * $Author: ing02260 $
25  * $Revision: 1.5 $
26  * $Aliases:  $
27  *
28  */
29 
30 #ifndef PHFRINFC_DESFIREMAP_H
31 #define PHFRINFC_DESFIREMAP_H
32 
33 #include <phFriNfc.h>
34 #ifdef PH_HAL4_ENABLE
35 #include <phHal4Nfc.h>
36 #else
37 #include <phHalNfc.h>
38 #endif
39 #include <phNfcTypes.h>
40 #include <phNfcStatus.h>
41 #include <phFriNfc_NdefMap.h>
42 
43 
44 
45 /*!
46  * \name Desfire - Standard constants
47  *
48  */
49 /*@{*/
50 #define PH_FRINFC_NDEFMAP_DESF_READ_OP                              2  /*!< Desfire Operation Flag is Read */
51 #define PH_FRINFC_NDEFMAP_DESF_WRITE_OP                             3  /*!< Desfire Operation Flag is Write */
52 #define PH_FRINFC_NDEFMAP_DESF_NDEF_CHK_OP                          4  /*!< Desfire Operation Flag is Check Ndef */
53 #define PH_FRINFC_NDEFMAP_DESF_GET_LEN_OP                           5
54 #define PH_FRINFC_NDEFMAP_DESF_SET_LEN_OP                           6
55 #define PH_FRINFC_NDEFMAP_DESF_RESP_OFFSET                          2  /*!< Two Status Flag at the end of the
56                                                                             Receive buffer*/
57 #define PH_FRINFC_NDEFMAP_DESF_CAPDU_SMARTTAG_PKT_SIZE              12 /*!< Send Length for Smart Tag function*/
58 #define PH_FRINFC_NDEFMAP_DESF_CAPDU_SELECT_FILE_PKT_SIZE           7  /*!< Send Length for Select File function */
59 #define PH_FRINFC_NDEFMAP_DESF_CAPDU_READ_BIN_PKT_SIZE              5  /*!< Send Length for Reading a Packet */
60 
61 /*!
62  * \name NDEF Mapping - states of the Finite State machine
63  *
64  */
65 /*@{*/
66 #ifdef DESFIRE_EV1
67     #define PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG_EV1       4     /*!< Selection of Smart Tag is going on for Desfire EV1 */
68 #endif /* #ifdef DESFIRE_EV1 */
69 #define PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_SMART_TAG               5     /*!< Selection of Smart Tag is going on */
70 #define PH_FRINFC_NDEFMAP_DESF_STATE_SELECT_FILE                    6     /*!< Selecting a file to read/write */
71 #define PH_FRINFC_NDEFMAP_DESF_STATE_READ_CAP_CONT                  7     /*!< Reading a capability container */
72 #define PH_FRINFC_NDEFMAP_DESF_STATE_READ_BIN                       8     /*!< Reading from the card */
73 #define PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_BEGIN               60    /*!< Writing to the card */
74 #define PH_FRINFC_NDEFMAP_DESF_STATE_UPDATE_BIN_END                 61    /*!< Writing to the card */
75 
76 #define PH_FRINFC_NDEFMAP_DESF_STATE_CHK_NDEF                       10    /*!< Check Ndef is in progress */
77 #define PH_FRINFC_NDEFMAP_DESF_TLV_INDEX                            7     /*!< Specifies the index of TLV Structure */
78 #define PH_FRINFC_NDEFMAP_DESF_NDEF_CNTRL_TLV                       0x04  /*!< Specifies the NDEF File Cntrl TLV */
79 #define PH_FRINFC_NDEFMAP_DESF_PROP_CNTRL_TLV                       0x05  /*!< Specifies the Propreitary File Cntrl TLV */
80 
81 /* Following Constants are used to navigate the Capability Container(CC)*/
82 
83 /*!< Following two indexes represents the CCLEN in CC*/
84 #define PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_FIRST_INDEX               0
85 #define PH_FRINFC_NDEFMAP_DESF_CCLEN_BYTE_SECOND_INDEX              1
86 
87 /*!< Specifies the index of the Mapping Version in CC */
88 #define PH_FRINFC_NDEFMAP_DESF_VER_INDEX                            2
89 
90 /*!< Following two indexes represents the MLe bytes in CC*/
91 #define PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_FIRST_INDEX                 3
92 #define PH_FRINFC_NDEFMAP_DESF_MLE_BYTE_SECOND_INDEX                4
93 
94 /*!< Following two indexes represents the MLc bytes in CC*/
95 #define PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_FIRST_INDEX                 5
96 #define PH_FRINFC_NDEFMAP_DESF_MLC_BYTE_SECOND_INDEX                6
97 
98 /*!< Specifies the index of the TLV in CC */
99 #define PH_FRINFC_NDEFMAP_DESF_TLV_INDEX                            7
100 
101 /*!< Specifies the index of the TLV  length in CC */
102 #define PH_FRINFC_NDEFMAP_DESF_TLV_LEN_INDEX                        8
103 
104 /*!< Following two indexes represents the NDEF file identifier in CC*/
105 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_FIRST_INDEX         9
106 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILEID_BYTE_SECOND_INDEX        10
107 
108 /*!< Following two indexes represents the NDEF file size in CC */
109 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_FIRST_INDEX         11
110 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILESZ_BYTE_SECOND_INDEX        12
111 
112 /*!< Specifies the index of the NDEF file READ access byte in CC */
113 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILERD_ACCESS_INDEX             13
114 
115 /*!< Specifies the index of the NDEF file WRITE access byte in CC */
116 #define PH_FRINFC_NDEFMAP_DESF_NDEF_FILEWR_ACCESS_INDEX             14
117 
118 
119 /* Macros to find Maximum NDEF File Size*/
120 #define PH_NFCFRI_NDEFMAP_DESF_NDEF_FILE_SIZE                       (NdefMap->DesfireCapContainer.NdefFileSize - 2)
121 /* Specifies the size of the NLEN Bytes*/
122 #define PH_FRINFC_NDEFMAP_DESF_NLEN_SIZE_IN_BYTES                    2
123 
124 
125 /* Following constants are used with buffer index's*/
126 #define PH_FRINFC_NDEFMAP_DESF_SW1_INDEX            0
127 #define PH_FRINFC_NDEFMAP_DESF_SW2_INDEX            1
128 
129 
130 /* Following constants are used for SW1 SW2 status codes*/
131 #define PH_FRINFC_NDEFMAP_DESF_RAPDU_SW1_BYTE                    0x90
132 #define PH_FRINFC_NDEFMAP_DESF_RAPDU_SW2_BYTE                    0x00
133 
134 
135 /* Following constatnts for shift bytes*/
136 #define PH_FRINFC_NDEFMAP_DESF_SHL8                             8
137 
138 
139 #define PH_FRINFC_DESF_GET_VER_CMD                          0x60
140 #define PH_FRINFC_DESF_NATIVE_CLASS_BYTE                    0x90
141 #define PH_FRINFC_DESF_NATIVE_OFFSET_P1                     0x00
142 #define PH_FRINFC_DESF_NATIVE_OFFSET_P2                     0x00
143 #define PH_FRINFC_DESF_NATIVE_GETVER_RESP                   0xAF
144 /*!
145 * \name NDEF Mapping - states of the Finite State machine
146 *
147 */
148 /*@{*/
149 
150 typedef enum
151 {
152     PH_FRINFC_DESF_STATE_GET_UID,
153     PH_FRINFC_DESF_STATE_GET_SW_VERSION,
154     PH_FRINFC_DESF_STATE_GET_HW_VERSION
155 
156 }phFriNfc_eMapDesfireState;
157 
158 typedef enum
159 {
160     PH_FRINFC_DESF_IDX_0,
161     PH_FRINFC_DESF_IDX_1,
162     PH_FRINFC_DESF_IDX_2,
163     PH_FRINFC_DESF_IDX_3,
164     PH_FRINFC_DESF_IDX_4,
165     PH_FRINFC_DESF_IDX_5
166 
167 }phFriNfc_eMapDesfireId;
168 
169 #define PH_FRINFC_DESF_ISO_NATIVE_WRAPPER() \
170     do \
171 {\
172     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_0] = PH_FRINFC_DESF_NATIVE_CLASS_BYTE;\
173     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_2] = PH_FRINFC_DESF_NATIVE_OFFSET_P1;\
174     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_3] = PH_FRINFC_DESF_NATIVE_OFFSET_P2;\
175     switch(NdefMap->State)\
176 {\
177     case PH_FRINFC_DESF_STATE_GET_HW_VERSION :\
178     case PH_FRINFC_DESF_STATE_GET_SW_VERSION :\
179     case PH_FRINFC_DESF_STATE_GET_UID :\
180     if ( NdefMap->State == PH_FRINFC_DESF_STATE_GET_HW_VERSION  )\
181 {\
182     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_1] = PH_FRINFC_DESF_GET_VER_CMD;\
183 }\
184         else\
185 {\
186     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_1] = 0xAF;\
187 }\
188     NdefMap->SendRecvBuf[PH_FRINFC_DESF_IDX_4] = 0x00;\
189     NdefMap->SendLength = PH_FRINFC_DESF_IDX_5;\
190     break;\
191     default :\
192     break;\
193 }\
194 } while(0)\
195 
196 
197 
198 
199 
200 /*!
201  * \brief \copydoc page_ovr Initiates Reading of NDEF information from the Remote Device.
202  *
203  * The function initiates the reading of NDEF information from a Remote Device.
204  * It performs a reset of the state and starts the action (state machine).
205  * A periodic call of the \ref phFriNfc_NdefMap_Process has to be done once the action
206  * has been triggered.
207  *
208  * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
209  *                    the component context.
210  *
211  * \param[in] PacketData  Pointer to a location that receives the NDEF Packet.
212  *
213  * \param[in,out] PacketDataLength Pointer to a variable receiving the length of the NDEF packet.
214  *
215  * \param[in] Offset Indicates whether the read operation shall start from the begining of the
216  *            file/card storage \b or continue from the last offset. The last Offset set is stored
217  *            within a context variable (must not be modified by the integration).
218  *            If the caller sets the value to \ref PH_FRINFC_NDEFMAP_SEEK_CUR, the component shall
219  *            start reading from the last offset set (continue where it has stopped before).
220  *            If set to \ref PH_FRINFC_NDEFMAP_SEEK_BEGIN, the component shall start reading
221  *            from the begining of the card (restarted)
222  *
223  * \retval NFCSTATUS_PENDING                       The action has been successfully triggered.
224  * \retval NFCSTATUS_INVALID_DEVICE_REQUEST        If Previous Operation is Write Ndef and Offset
225  *                                                 is Current then this error is displayed.
226  * \retval NFCSTATUS_EOF_NDEF_CONTAINER_REACHED              No Space in the File to read.
227  * \retval NFCSTATUS_MORE_INFORMATION              There are more bytes to read in the card.
228  * \retval NFCSTATUS_SUCCESS                       Last Byte of the card read.
229  * \retval NFCSTATUS_INVALID_DEVICE                The device has not been opened or has been disconnected
230  *                                                 meanwhile.
231  * \retval NFCSTATUS_CMD_ABORTED                   The caller/driver has aborted the request.
232  * \retval NFCSTATUS_BUFFER_TOO_SMALL              The buffer provided by the caller is too small.
233  * \retval NFCSTATUS_RF_TIMEOUT                    No data has been received within the TIMEOUT period.
234  *
235  */
236 
237 NFCSTATUS phFriNfc_Desfire_RdNdef(  phFriNfc_NdefMap_t  *NdefMap,
238                                     uint8_t             *PacketData,
239                                     uint32_t            *PacketDataLength,
240                                     uint8_t             Offset);
241 
242 /*!
243  * \brief \copydoc page_ovr Initiates Writing of NDEF information to the Remote Device.
244  *
245  * The function initiates the writing of NDEF information to a Remote Device.
246  * It performs a reset of the state and starts the action (state machine).
247  * A periodic call of the \ref phFriNfc_NdefMap_Process has to be done once the action
248  * has been triggered.
249  *
250  * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
251  *                    the component context.
252  *
253  * \param[in] PacketData  Pointer to a location that holds the prepared NDEF Packet.
254  *
255  * \param[in,out] PacketDataLength Variable specifying the length of the prepared NDEF packet.
256  *
257  * \param[in] Offset Indicates whether the write operation shall start from the begining of the
258  *            file/card storage \b or continue from the last offset. The last Offset set is stored
259  *            within a context variable (must not be modified by the integration).
260  *            If the caller sets the value to \ref PH_FRINFC_NDEFMAP_SEEK_CUR, the component shall
261  *            start writing from the last offset set (continue where it has stopped before).
262  *            If set to \ref PH_FRINFC_NDEFMAP_SEEK_BEGIN, the component shall start writing
263  *            from the begining of the card (restarted)
264  *
265  * \retval NFCSTATUS_PENDING                        The action has been successfully triggered.
266  * \retval NFCSTATUS_INVALID_DEVICE_REQUEST         If Previous Operation is Write Ndef and Offset
267  *                                                  is Current then this error is displayed.
268  * \retval NFCSTATUS_EOF_NDEF_CONTAINER_REACHED               Last byte is written to the card after this
269  *                                                  no further writing is possible.
270  * \retval NFCSTATUS_SUCCESS                        Buffer provided by the user is completely written
271  *                                                  into the card.
272  * \retval NFCSTATUS_INVALID_DEVICE                 The device has not been opened or has been disconnected
273  *                                                  meanwhile.
274  * \retval NFCSTATUS_CMD_ABORTED                    The caller/driver has aborted the request.
275  * \retval NFCSTATUS_BUFFER_TOO_SMALL               The buffer provided by the caller is too small.
276  * \retval NFCSTATUS_RF_TIMEOUT                     No data has been received within the TIMEOUT period.
277  *
278  */
279 
280 NFCSTATUS phFriNfc_Desfire_WrNdef(  phFriNfc_NdefMap_t  *NdefMap,
281                                     uint8_t             *PacketData,
282                                     uint32_t            *PacketDataLength,
283                                     uint8_t             Offset);
284 
285 /*!
286  * \brief \copydoc page_ovr Check whether a particulat Remote Device is NDEF compliant.
287  *
288  * The function checks whether the peer device is NDEF compliant.
289  *
290  * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
291  *                    the component context.
292  *
293  * \retval NFCSTATUS_PENDING               The action has been successfully triggered.
294  * \retval NFCSTATUS_INVALID_PARAMETER     At least one parameter of the function is invalid.
295  * \retval NFCSTATUS_INVALID_DEVICE         The device has not been opened or has been disconnected
296  *                                          meanwhile.
297  * \retval NFCSTATUS_CMD_ABORTED            The caller/driver has aborted the request.
298  * \retval NFCSTATUS_BUFFER_TOO_SMALL       The buffer provided by the caller is too small.
299  * \retval NFCSTATUS_RF_TIMEOUT             No data has been received within the TIMEOUT period.
300  *
301  */
302 
303 NFCSTATUS phFriNfc_Desfire_ChkNdef( phFriNfc_NdefMap_t  *NdefMap);
304 
305 /*!
306  * \brief \copydoc page_cb Completion Routine, Processing function, needed to avoid long blocking.
307  *
308  * The function call scheme is according to \ref grp_interact. No State reset is performed during operation.
309  *
310  * \copydoc pphFriNfc_Cr_t
311  *
312  * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
313  *       Routine in order to be able to notify the component that an I/O has finished and data are
314  *       ready to be processed.
315  *
316  */
317 
318 void phFriNfc_Desfire_Process(  void        *Context,
319                                 NFCSTATUS   Status);
320 
321 
322 #endif /* PHFRINFC_DESFIREMAP_H */
323 
324