blob: 9efff94779bbca3ec5f6052e19239083c595081e [file] [log] [blame]
Nick Pelly5d9927b2010-09-23 12:47:58 -07001/*
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_OvrHal.c
19 * \brief Overlapped HAL
20 *
21 * Project: NFC-FRI
22 * Creator: Gerald Kersch
23 *
24 * $Date: Wed May 5 10:47:27 2010 $
25 * Changed by: $Author: ing02260 $
26 * $Revision: 1.37 $
27 * $Aliases: NFC_FRI1.1_WK1017_R34_3,NFC_FRI1.1_WK1023_R35_1 $
28 *
29 */
30
31#include <phFriNfc_OvrHal.h>
32#include <phOsalNfc.h>
33#include <phFriNfc_NdefMap.h>
34#include <phFriNfc_SmtCrdFmt.h>
35
36
Nick Pelly5d9927b2010-09-23 12:47:58 -070037#ifdef PHFRINFC_OVRHAL_MOCKUP /* */
38//#include <phLibNfc_Gen.h>
39#endif /* PHFRINFC_OVRHAL_MOCKUP */
40/*
41*
42
43*/
44#define MAX_MIF_PACKET_LEN 0x0FU
Jan Brands3043b522010-11-29 22:22:54 +010045#define MIFARE_PLUS_UID_INDEX_TO_COPY 0x03U
Nick Pelly5d9927b2010-09-23 12:47:58 -070046#define MIFARE_PLUS_UID_LENGTH 0x07U
47#define MIFARE_CLASSIC_UID_LENGTH 0x04U
48#define MIFARE_UID_LEN_TO_COPY 0x04U
49
50static void phFriNfc_OvrHal_CB_Send(void *context,
51 NFCSTATUS status);
52static void phFriNfc_OvrHal_CB_Receive(void *context,
53 phNfc_sData_t *pDataInfo,
54 NFCSTATUS status);
55static void phFriNfc_OvrHal_CB_Transceive(void *context,
56 phHal_sRemoteDevInformation_t *RemoteDevHandle,
57 phNfc_sData_t *pRecvdata,
58 NFCSTATUS status
59 );
60static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
61 phHal_sRemoteDevInformation_t *RemoteDevHandle,
62 NFCSTATUS status
63 );
64
65static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
66 phFriNfc_CplRt_t *CompletionInfo,
67 uint8_t Operation);
68
69NFCSTATUS phFriNfc_OvrHal_Transceive(phFriNfc_OvrHal_t *OvrHal,
70 phFriNfc_CplRt_t *CompletionInfo,
71 phHal_sRemoteDevInformation_t *RemoteDevInfo,
72 phHal_uCmdList_t Cmd,
73 phHal_sDepAdditionalInfo_t *DepAdditionalInfo,
74 uint8_t *SendBuf,
75 uint16_t SendLength,
76 uint8_t *RecvBuf,
77 uint16_t *RecvLength)
78{
79 NFCSTATUS status = NFCSTATUS_PENDING;
80 uint8_t i = 0;
81 uint32_t length = SendLength;
82
83 /* To remove "warning (VS C4100) : unreferenced formal parameter" */
84 PHNFC_UNUSED_VARIABLE(DepAdditionalInfo);
85
86 /* Check the Input Parameters */
87 if ((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo)
88 || (NULL == (void*)SendBuf) || (NULL == RecvBuf) || (NULL == RecvLength)
89 || ((phHal_eJewel_PICC != RemoteDevInfo->RemDevType) && (0 == SendLength)))
90
91 {
92 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL, NFCSTATUS_INVALID_PARAMETER);
93 }
94 else
95 {
96 /* 16 is the maximum data, that can be sent to the mifare standard */
97 static uint8_t mif_send_buf[MAX_MIF_PACKET_LEN] = {0};
98 /* Populate the Transfer info structure */
99 OvrHal->TranceiveInfo.cmd = Cmd;
100
101 /* Populate the Send Buffer Info */
102 if((phHal_eMifare_PICC == RemoteDevInfo->RemDevType)
103 || (phHal_eISO14443_3A_PICC == RemoteDevInfo->RemDevType))
104 {
105 OvrHal->TranceiveInfo.addr = SendBuf[i++];
106 length = (SendLength - i);
107
108 if ((phHal_eMifareAuthentA == Cmd.MfCmd)
109 || (phHal_eMifareAuthentB == Cmd.MfCmd))
110 {
111 uint8_t uid_index = 0;
112 /* Authentication requires UID in the send buffer */
113 uint8_t uid_len =
114 RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.UidLength;
115 OvrHal->TranceiveInfo.sSendData.buffer = mif_send_buf;
116
117 switch (uid_len)
118 {
119 case MIFARE_PLUS_UID_LENGTH:
120 {
121 uid_index = MIFARE_PLUS_UID_INDEX_TO_COPY;
122 uid_len = MIFARE_UID_LEN_TO_COPY;
123 break;
124 }
125
126 case MIFARE_CLASSIC_UID_LENGTH:
127 {
128 uid_index = 0;
129 break;
130 }
131
132 default:
133 {
134 status = PHNFCSTVAL (CID_FRI_NFC_OVR_HAL,
135 NFCSTATUS_READ_FAILED);
136 break;
137 }
138 }
139
140 if (NFCSTATUS_PENDING == status)
141 {
142 /* copy uid to the send buffer for the authentication */
143 (void)memcpy ((void *)mif_send_buf,
144 (void *)&RemoteDevInfo->RemoteDevInfo.Iso14443A_Info.Uid[uid_index],
145 uid_len);
146
147 (void)memcpy((mif_send_buf + uid_len), &(SendBuf[i]), length);
148 length += uid_len;
149 }
150 }
151 else
152 {
153 OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];
154 }
155 OvrHal->TranceiveInfo.sSendData.length = length;
156 }
157 else
158 {
159 OvrHal->TranceiveInfo.sSendData.buffer = &SendBuf[i++];
160 OvrHal->TranceiveInfo.sSendData.length = length;
161 }
162
163 if (NFCSTATUS_PENDING == status)
164 {
165 /* Populate the Receive buffer */
166 OvrHal->TranceiveInfo.sRecvData.buffer = RecvBuf;
167 OvrHal->TranceiveInfo.sRecvData.length = *RecvLength;
168 OvrHal->pndef_recv_length = RecvLength;
169 phFriNfc_OvrHal_SetComplInfo(OvrHal,CompletionInfo, PH_FRINFC_OVRHAL_TRX);
170
171 /* Call the HAL 4.0 Transceive Function */
172 status = phHal4Nfc_Transceive (OvrHal->psHwReference,
173 &OvrHal->TranceiveInfo, RemoteDevInfo,
174 phFriNfc_OvrHal_CB_Transceive, (void *)OvrHal);
175 }
176
177 }
178 return status;
179
180}
181
182NFCSTATUS phFriNfc_OvrHal_Receive(phFriNfc_OvrHal_t *OvrHal,
183 phFriNfc_CplRt_t *CompletionInfo,
184 phHal_sRemoteDevInformation_t *RemoteDevInfo,
185 uint8_t *RecvBuf,
186 uint16_t *RecvLength)
187{
188 NFCSTATUS status = NFCSTATUS_PENDING;
189
190 /* Check the Input Parameters */
191 if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo)
192 || (NULL==RecvBuf) || (NULL==RecvLength) )
193 {
194 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
195 }
196 else
197 {
198 /* Get the remote dev type */
199 OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
200 /* Save the receive buffer for use in callback */
201 OvrHal->sReceiveData.buffer = RecvBuf;
202 OvrHal->sReceiveData.length = *RecvLength;
203
204 OvrHal->pndef_recv_length = RecvLength;
205
206 /* Set the callback */
207 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_RCV);
208
209 /* Call the HAL 4.0 Receive Function */
210 status = phHal4Nfc_Receive( OvrHal->psHwReference,
211 &OvrHal->TransactInfo,
212 phFriNfc_OvrHal_CB_Receive,
213 (void *)OvrHal);
214 }
215 return status;
216}
217
218NFCSTATUS phFriNfc_OvrHal_Send(phFriNfc_OvrHal_t *OvrHal,
219 phFriNfc_CplRt_t *CompletionInfo,
220 phHal_sRemoteDevInformation_t *RemoteDevInfo,
221 uint8_t *SendBuf,
222 uint16_t SendLength)
223{
224 NFCSTATUS status = NFCSTATUS_PENDING;
225
226 /* Check the Input Parameters */
227 if( (NULL==OvrHal) || (NULL==CompletionInfo) || (NULL==RemoteDevInfo) || (NULL==SendBuf) )
228 {
229 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
230 }
231 else
232 {
233 /* Get the remote dev type */
234 OvrHal->TransactInfo.remotePCDType = RemoteDevInfo->RemDevType;
235 /* Save the receive buffer for use in callback */
236 OvrHal->sSendData.buffer = SendBuf;
237 OvrHal->sSendData.length = SendLength;
238
239 /* Set the callback */
240 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_SND);
241
242 /* Call the HAL 4.0 Receive Function */
243 status = phHal4Nfc_Send( OvrHal->psHwReference,
244 &OvrHal->TransactInfo,
245 OvrHal->sSendData,
246 phFriNfc_OvrHal_CB_Send,
247 (void *)OvrHal);
248 }
249 return status;
250}
251
252#ifndef PH_FRINFC_MAP_MIFARESTD_DISABLED
253
254
255NFCSTATUS phFriNfc_OvrHal_Reconnect(phFriNfc_OvrHal_t *OvrHal,
256 phFriNfc_CplRt_t *CompletionInfo,
257 phHal_sRemoteDevInformation_t *RemoteDevInfo)
258{
259 NFCSTATUS status = NFCSTATUS_PENDING;
260
261 /* Check the Input Parameters */
262 if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo))
263 {
264 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
265 }
266 else
267 {
268 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_DIS);
269
270 status = phHal4Nfc_Connect(
271 OvrHal->psHwReference,
272 RemoteDevInfo,
273 phFriNfc_OvrHal_CB_ConnectDisconnect,
274 (void *)OvrHal);
275 }
276
277 return status;
278}
279
280
281
282NFCSTATUS phFriNfc_OvrHal_Connect(phFriNfc_OvrHal_t *OvrHal,
283 phFriNfc_CplRt_t *CompletionInfo,
284 phHal_sRemoteDevInformation_t *RemoteDevInfo,
285 phHal_sDevInputParam_t *DevInputParam)
286{
287 NFCSTATUS status = NFCSTATUS_PENDING;
288
289 /* Check the Input Parameters */
290 if((NULL == OvrHal) || (NULL == CompletionInfo) || (NULL == RemoteDevInfo) ||
291 (NULL == DevInputParam))
292 {
293 status = PHNFCSTVAL(CID_FRI_NFC_OVR_HAL ,NFCSTATUS_INVALID_PARAMETER);
294 }
295 else
296 {
297 phFriNfc_OvrHal_SetComplInfo(OvrHal, CompletionInfo, PH_FRINFC_OVRHAL_CON);
298
299 status = phHal4Nfc_Connect(
300 OvrHal->psHwReference,
301 RemoteDevInfo,
302 phFriNfc_OvrHal_CB_ConnectDisconnect,
303 (void *)OvrHal
304 );
305 }
306
307 return status;
308}
309
310#endif
311
312static void phFriNfc_OvrHal_CB_Transceive(void *context,
313 phHal_sRemoteDevInformation_t *RemoteDevHandle,
314 phNfc_sData_t *pRecvdata,
315 NFCSTATUS status
316 )
317
318{
319 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
320
321 if (NULL != OvrHal)
322 {
daniel_Tomas143acf02010-11-25 15:48:33 +0100323 if(NULL != pRecvdata && OvrHal->TranceiveInfo.sRecvData.buffer != NULL && pRecvdata->buffer != NULL)
Nick Pelly5d9927b2010-09-23 12:47:58 -0700324 {
325 /* Work-around for the NFCIP Tranceive API */
Nick Kralevich2e2afad2012-07-17 09:28:13 -0700326 if (OvrHal->TranceiveInfo.sRecvData.buffer != pRecvdata->buffer)
327 {
328 memcpy(OvrHal->TranceiveInfo.sRecvData.buffer, pRecvdata->buffer, pRecvdata->length);
329 }
Nick Pelly5d9927b2010-09-23 12:47:58 -0700330 if (OvrHal->pndef_recv_length != NULL)
331 {
332 *OvrHal->pndef_recv_length = (uint16_t) pRecvdata->length;
333 }
334 }
335 if(NULL != RemoteDevHandle)
336 {
337 /* Fix for Warning 4100 */
338 RemoteDevHandle=RemoteDevHandle;
339 }
340
341 if (NULL != OvrHal->TemporaryCompletionInfo.CompletionRoutine)
342 {
343 OvrHal->TemporaryCompletionInfo.CompletionRoutine(
344 OvrHal->TemporaryCompletionInfo.Context,
345 status);
346 }
347 }
348}
349
350static void phFriNfc_OvrHal_CB_Send(void *context,
351 NFCSTATUS status)
352{
353 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
354
355 if (NULL != OvrHal)
356 {
357 if (NULL != OvrHal->TemporarySndCompletionInfo.CompletionRoutine)
358 {
359 OvrHal->TemporarySndCompletionInfo.CompletionRoutine(
360 OvrHal->TemporarySndCompletionInfo.Context,
361 status);
362 }
363 }
364}
365
366static void phFriNfc_OvrHal_CB_Receive(void *context,
367 phNfc_sData_t *pDataInfo,
368 NFCSTATUS status)
369{
370 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
371
372 if (NULL != OvrHal)
373 {
374 /* Copy the received buffer */
daniel_Tomas143acf02010-11-25 15:48:33 +0100375 if(NULL != pDataInfo && OvrHal->sReceiveData.buffer != NULL && pDataInfo->buffer != NULL)
Nick Pelly5d9927b2010-09-23 12:47:58 -0700376 {
377 memcpy(OvrHal->sReceiveData.buffer, pDataInfo->buffer, pDataInfo->length);
378 *OvrHal->pndef_recv_length = (uint16_t) pDataInfo->length;
379 }
380
381 if (NULL != OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine)
382 {
383 OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine(
384 OvrHal->TemporaryRcvCompletionInfo.Context,
385 status);
386 }
387 }
388}
389
390static void phFriNfc_OvrHal_CB_ConnectDisconnect(void *context,
391 phHal_sRemoteDevInformation_t *RemoteDevHandle,
392 NFCSTATUS status
393 )
394
395{
396 phFriNfc_OvrHal_t *OvrHal = (phFriNfc_OvrHal_t *)context;
397
398 if (NULL != OvrHal)
399 {
400 if (RemoteDevHandle != NULL)
401 {
402 /* Fix for Warning 4100 */
403 RemoteDevHandle = RemoteDevHandle;
404 }
405 else
406 {
407 status = NFCSTATUS_FAILED;
408 }
409
410 OvrHal->TemporaryCompletionInfo.CompletionRoutine(
411 OvrHal->TemporaryCompletionInfo.Context, status);
412 }
413
414}
415
416static void phFriNfc_OvrHal_SetComplInfo(phFriNfc_OvrHal_t *OvrHal,
417 phFriNfc_CplRt_t *CompletionInfo,
418 uint8_t Operation)
419
420{
421 OvrHal->Operation = Operation;
422 switch(Operation)
423 {
424 case PH_FRINFC_OVRHAL_RCV:
425 {
426 OvrHal->TemporaryRcvCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
427 OvrHal->TemporaryRcvCompletionInfo.Context = CompletionInfo->Context;
428 break;
429 }
430 case PH_FRINFC_OVRHAL_SND:
431 {
432 OvrHal->TemporarySndCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
433 OvrHal->TemporarySndCompletionInfo.Context = CompletionInfo->Context;
434 break;
435 }
436 default:
437 {
438 OvrHal->TemporaryCompletionInfo.CompletionRoutine = CompletionInfo->CompletionRoutine;
439 OvrHal->TemporaryCompletionInfo.Context = CompletionInfo->Context;
440 break;
441 }
442 }
443}