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
150typedef 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
158typedef 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
237NFCSTATUS 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
280NFCSTATUS 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
303NFCSTATUS 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
318void phFriNfc_Desfire_Process(  void        *Context,
319                                NFCSTATUS   Status);
320
321
322#endif /* PHFRINFC_DESFIREMAP_H */
323
324