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_FelicaMap.c
19 * \brief This component encapsulates read/write/check ndef/process functionalities,
20 * for the Felica Smart Card.
21 *
22 * Project: NFC-FRI
23 *
24 * $Date: Thu May 6 14:01:35 2010 $
25 * $Author: ing07385 $
26 * $Revision: 1.10 $
27 * $Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $
28 *
29 */
30
31 #ifndef PH_FRINFC_MAP_FELICA_DISABLED
32
33 #include <phNfcTypes.h>
34 #include <phFriNfc_OvrHal.h>
35 #include <phFriNfc_FelicaMap.h>
36 #include <phFriNfc_MapTools.h>
37
38
39 /*! \ingroup grp_file_attributes
40 * \name NDEF Mapping
41 *
42 * File: \ref phFriNfc_FelicaMap.c
43 *
44 */
45 /*@{*/
46
47 #define PHFRINFCNDEFMAP_FILEREVISION "$Revision: 1.10 $"
48 #define PHFRINFCNDEFMAP_FILEALIASES "$Aliases: NFC_FRI1.1_WK1017_R34_4,NFC_FRI1.1_WK1023_R35_1 $"
49
50 /*@}*/
51
52 /* Helpers for Read and updating the attribute informations*/
53 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap);
54 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap);
55 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
56 uint8_t StartIndex,
57 uint8_t EndIndex,
58 uint16_t RecvChkSum);
59
60 /* Helpers for Poll Related Operations*/
61 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
62 const uint8_t sysCode[],
63 uint8_t state);
64
65 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap);
66
67 /*Helpers for Reading Operations*/
68 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset);
69 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap,uint8_t NbcOrNmaxb );
70 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap);
71 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset);
72 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc);
73 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap);
74
75 /* Helpers for Writing Operations*/
76 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap);
77 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
78 uint32_t NdefLen);
79 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted);
80 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap);
81 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap);
82
83 /* Write Empty NDEF Message*/
84 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap);
85
86 /*Helpers for common checks*/
87 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap);
88 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap,
89 uint8_t CrIndex,
90 NFCSTATUS Status);
91
92 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer);
93
94 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n );
95
96 /*!
97 * \brief returns maximum number of blocks can be read from the Felica Smart Card.
98 *
99 * The function is useful in reading of NDEF information from a felica tag.
100 */
101
phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t * NdefMap,uint8_t NbcOrNmaxb)102 static uint16_t phFriNfc_Felica_HGetMaximumBlksToRead(const phFriNfc_NdefMap_t *NdefMap, uint8_t NbcOrNmaxb )
103 {
104 uint16_t BlksToRead=0;
105 uint32_t DataLen = 0;
106 /* This part of the code is useful if we take account of Nbc blks reading*/
107 if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NBC )
108 {
109 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
110 NdefMap->FelicaAttrInfo.LenBytes[1],
111 NdefMap->FelicaAttrInfo.LenBytes[2],
112 DataLen);
113 /* Calculate Nbc*/
114 BlksToRead = (uint16_t) ( ((DataLen % 16) == 0) ? (DataLen >> 4) : ((DataLen >> 4) +1) );
115
116
117 }
118 else if ( NbcOrNmaxb == PH_NFCFRI_NDEFMAP_FELI_NMAXB)
119 {
120 BlksToRead = NdefMap->FelicaAttrInfo.Nmaxb;
121 }
122 else
123 {
124 /* WARNING !!! code should not reach this point*/
125 ;
126 }
127 return (BlksToRead);
128 }
129
130 /*!
131 * \brief Initiates Reading of NDEF information from the Felica Card.
132 *
133 * The function initiates the reading of NDEF information from a Remote Device.
134 * It performs a reset of the state and starts the action (state machine).
135 * A periodic call of the \ref phFriNfcNdefMap_Process has to be
136 * done once the action has been triggered.
137 */
138
phFriNfc_Felica_RdNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)139 NFCSTATUS phFriNfc_Felica_RdNdef( phFriNfc_NdefMap_t *NdefMap,
140 uint8_t *PacketData,
141 uint32_t *PacketDataLength,
142 uint8_t Offset)
143 {
144
145 NFCSTATUS status = NFCSTATUS_PENDING;
146 uint32_t Nbc = 0;
147
148 NdefMap->ApduBufferSize = *PacketDataLength;
149 /*Store the packet data buffer*/
150 NdefMap->ApduBuffer = PacketData;
151
152 NdefMap->NumOfBytesRead = PacketDataLength ;
153 *NdefMap->NumOfBytesRead = 0;
154 NdefMap->ApduBuffIndex = 0;
155
156 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_READ_OPE;
157 NdefMap->Felica.Offset = Offset;
158
159 if( ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )||( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_WRITE_OPE))
160 {
161 NdefMap->Felica.CurBlockNo = 0;
162 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP;
163 NdefMap->Felica.IntermediateCpyFlag = FALSE;
164 NdefMap->Felica.IntermediateCpyLen = 0;
165 NdefMap->Felica.Rd_NoBytesToCopy = 0;
166 NdefMap->Felica.EofCardReachedFlag= FALSE ;
167 NdefMap->Felica.LastBlkReachedFlag = FALSE;
168 NdefMap->Felica.CurrBytesRead = 0;
169
170 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Rd_BytesToCopyBuff);
171
172 /* send request to read attribute information*/
173 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
174 /* handle the error in Transc function*/
175 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
176 {
177 /* call respective CR */
178 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
179 }
180 }
181 else
182 {
183 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
184
185 /* Offset = Current, but the read has reached the End of NBC Blocks */
186 if(( ( Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) && (NdefMap->Felica.CurBlockNo == Nbc)) &&
187 (NdefMap->Felica.EofCardReachedFlag == FELICA_RD_WR_EOF_CARD_REACHED ))
188 {
189 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
190 }
191 else
192 {
193
194 NdefMap->Felica.CurrBytesRead = ((NdefMap->Felica.CurBlockNo * 16)- NdefMap->Felica.Rd_NoBytesToCopy);
195 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
196
197 }
198 }
199 return (status);
200 }
201
202 /*Read Operation Related Helper Routines*/
203
204 /*!
205 * \brief Used in Read Opearation.Sets the Trx Buffer Len calls Transc Cmd.
206 * After a successful read operation, function does checks the user buffer size
207 * sets the status flags.
208 */
209
phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t * NdefMap,uint8_t offset)210 static NFCSTATUS phFriNfc_Felica_HReadData(phFriNfc_NdefMap_t *NdefMap,uint8_t offset)
211 {
212 NFCSTATUS status = NFCSTATUS_PENDING;
213 uint16_t Nbc=0,TranscLen=0;
214
215 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
216 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0) && (NdefMap->Felica.CurBlockNo < Nbc ))
217 {
218 /* if data is present in the internal buffer*/
219 if (NdefMap->Felica.Rd_NoBytesToCopy > 0 )
220 {
221 /* copy data to external buffer*/
222 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
223 /*Check the size of user buffer*/
224 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap);
225 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE ))
226 {
227 /* set the transc len and call transc cmd*/
228 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
229 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
230 }
231 else
232 {
233 /* Nothing to be done , if IntermediateRdFlag is set to zero*/
234 ;
235 }
236 }
237 else
238 {
239 /* set the transc len and call transc cmd*/
240 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
241 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
242 }
243 }
244 else
245 {
246 /* Chk the Buffer size*/
247 status = phFriNfc_Felica_HChkApduBuff_Size(NdefMap);
248 if ( (status != NFCSTATUS_SUCCESS) && (NdefMap->Felica.IntermediateRdFlag == TRUE ))
249 {
250 TranscLen = phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
251 status= phFriNfc_Felica_HSetTransceiveForRead(NdefMap,TranscLen,offset);
252 }
253 }
254 return (status);
255 }
256
257 /*!
258 * \brief Used in Read Opearation.Sets the Trx Buffer Len.
259 */
260
phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t * NdefMap,uint16_t Nbc)261 static uint16_t phFriNfc_Felica_HSetTrxLen(phFriNfc_NdefMap_t *NdefMap,uint16_t Nbc)
262 {
263 uint16_t TranscLen = 0,BlocksToRead=0;
264
265 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)% 16) == 0)
266 {
267 BlocksToRead = (uint16_t)( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16 );
268 }
269 else
270 {
271 BlocksToRead = (uint16_t)(((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16) +1);
272 }
273 if ( (BlocksToRead > Nbc) ||( (BlocksToRead) > ( Nbc - NdefMap->Felica.CurBlockNo)) )
274 {
275 BlocksToRead = Nbc - NdefMap->Felica.CurBlockNo;
276 }
277
278
279 if ( BlocksToRead >= NdefMap->FelicaAttrInfo.Nbr)
280 {
281 if( NdefMap->FelicaAttrInfo.Nbr < Nbc )
282 {
283 TranscLen = NdefMap->FelicaAttrInfo.Nbr*16;
284 }
285 else
286 {
287 TranscLen = Nbc*16;
288 NdefMap->Felica.LastBlkReachedFlag =1;
289 }
290 }
291 else
292 {
293 if (BlocksToRead <= Nbc )
294 {
295 if ( ( BlocksToRead * 16) == ((Nbc *16) - (NdefMap->Felica.CurBlockNo * 16)))
296 {
297 NdefMap->Felica.LastBlkReachedFlag =1;
298
299 }
300 TranscLen = BlocksToRead*16;
301
302 }
303 else
304 {
305 TranscLen = Nbc*16;
306 }
307 }
308 /* As Cur Blk changes, to remember the exact len what we had set
309 in the begining of each read operation*/
310 NdefMap->Felica.TrxLen = TranscLen;
311 return (TranscLen);
312 }
313
314 /*!
315 * \brief Used in Read Opearation.After a successful read operation,
316 * Copies the data to user buffer.
317 */
318
phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t * NdefMap)319 static void phFriNfc_Felica_HAfterRead_CopyDataToBuff(phFriNfc_NdefMap_t *NdefMap)
320 {
321 uint8_t ResetFlag = FALSE, ExtrBytesToCpy = FALSE;
322 uint16_t Nbc=0;
323 uint32_t DataLen=0;
324
325 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC );
326
327 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
328 NdefMap->FelicaAttrInfo.LenBytes[1],
329 NdefMap->FelicaAttrInfo.LenBytes[2],
330 DataLen);
331 /* Internal Buffer has some old read bytes to cpy to user buffer*/
332 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
333 {
334 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.Rd_NoBytesToCopy )
335 {
336 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
337
338 if (NdefMap->Felica.IntermediateCpyFlag == TRUE )
339 {
340 /*Copy data from the internal buffer to user buffer*/
341 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
342 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
343 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
344
345
346
347 /* Store number of bytes copied frm internal buffer to User Buffer */
348 NdefMap->Felica.IntermediateCpyLen += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
349 NdefMap->Felica.IntermediateCpyFlag = 1;
350
351 /* check do we reach len bytes any chance*/
352 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
353 NdefMap->FelicaAttrInfo.LenBytes[1],
354 NdefMap->FelicaAttrInfo.LenBytes[2],
355 DataLen);
356 /* Internal buffer has zero bytes for copy operation*/
357 if ( NdefMap->Felica.Rd_NoBytesToCopy == 0)
358 {
359 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
360 }
361 }
362 else
363 {
364 /*Copy data from the internal buffer to apdu buffer*/
365 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
366 NdefMap->Felica.Rd_BytesToCopyBuff,
367 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
368 }
369 NdefMap->ApduBuffIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
370
371 }
372 else if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.Rd_NoBytesToCopy )
373 {
374 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
375 {
376 /*Copy data internal buff to apdubuffer*/
377 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
378 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
379 NdefMap->Felica.Rd_NoBytesToCopy);
380 }
381 else
382 {
383 /*Copy data internal buff to apdubuffer*/
384 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
385 NdefMap->Felica.Rd_BytesToCopyBuff,
386 NdefMap->Felica.Rd_NoBytesToCopy);
387 }
388
389 /*increment the index,internal buffer len*/
390 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
391 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBuffIndex);
392
393 /* To reset the parameters*/
394 ResetFlag = TRUE;
395 }
396 else
397 {
398 /* Extra Bytes to Copy from internal buffer to external buffer*/
399 if ( NdefMap->Felica.IntermediateCpyFlag == TRUE )
400 {
401 /*Copy data internal buff to apdubuffer*/
402 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
403 (&(NdefMap->Felica.Rd_BytesToCopyBuff[NdefMap->Felica.IntermediateCpyLen])),
404 NdefMap->Felica.Rd_NoBytesToCopy);
405 }
406 else
407 {
408 /*Copy data internal buff to apdubuffer*/
409 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
410 NdefMap->Felica.Rd_BytesToCopyBuff,
411 NdefMap->Felica.Rd_NoBytesToCopy);
412 }
413 /*increment the index*/
414 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
415
416 /* To reset the parameters*/
417 ResetFlag = TRUE;
418 }
419 }/*End of Internal Buffer has some old read bytes to cpy to user buffer*/
420 else
421 {
422 /* check if last block is reached*/
423 if ( ((NdefMap->Felica.LastBlkReachedFlag == 1) && (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= 16)) )
424 {
425 /* greater than 16 but less than the data len size*/
426 if (( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= DataLen)
427 {
428 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen) - (NdefMap->Felica.CurrBytesRead +
429 NdefMap->ApduBuffIndex));
430
431 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
432 (&(NdefMap->SendRecvBuf[13])),
433 NdefMap->Felica.CurrBytesRead);
434
435 NdefMap->ApduBuffIndex += NdefMap->Felica.CurrBytesRead;
436 if ( NdefMap->ApduBuffIndex == DataLen)
437 {
438 ResetFlag = TRUE;
439 }
440 }
441 else
442 {
443 /* need to check exact no. of bytes to copy to buffer*/
444 if( ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= NdefMap->Felica.TrxLen )||
445 ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) <= DataLen ))
446 {
447
448 ExtrBytesToCpy = TRUE;
449 }
450 else
451 {
452 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - (DataLen)));
453
454 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
455 {
456 /*Reduce already copied bytes from the internal buffer*/
457 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
458 ExtrBytesToCpy = TRUE;
459 }
460 else
461 {
462 ExtrBytesToCpy = FALSE;
463 }
464 }
465 if ( ExtrBytesToCpy == TRUE )
466 {
467 NdefMap->Felica.CurrBytesRead = (uint16_t)((DataLen)- (NdefMap->Felica.CurrBytesRead +
468 NdefMap->ApduBuffIndex));
469
470 if(NdefMap->Felica.CurrBytesRead <
471 (uint16_t)(NdefMap->ApduBufferSize -
472 NdefMap->ApduBuffIndex))
473 {
474 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
475 (&(NdefMap->SendRecvBuf[13])),
476 NdefMap->Felica.CurrBytesRead);
477 }
478 else
479 {
480 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
481 (&( NdefMap->SendRecvBuf[13])),
482 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
483 }
484
485 if ( NdefMap->Felica.LastBlkReachedFlag == 1 )
486 {
487 NdefMap->Felica.Rd_NoBytesToCopy =
488 (uint8_t)((NdefMap->Felica.CurrBytesRead >
489 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))?
490 (NdefMap->Felica.CurrBytesRead -
491 (uint16_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)):
492 0);
493
494 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy == 0)?TRUE:FALSE);
495
496 }
497 else
498 {
499 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)( NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
500 }
501
502 /* Copy remained bytes back into internal buffer*/
503 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff,
504 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])),
505 NdefMap->Felica.Rd_NoBytesToCopy);
506
507 /* set the intermediate flag : This flag remembers that there are still X no. bytes remained in
508 Internal Buffer Ex: User has given only one byte buffer,needs to cpy one byte at a time*/
509 NdefMap->Felica.IntermediateCpyFlag = TRUE;
510
511 NdefMap->ApduBuffIndex += ((NdefMap->Felica.CurrBytesRead <
512 (uint16_t)(NdefMap->ApduBufferSize -
513 NdefMap->ApduBuffIndex))?
514 NdefMap->Felica.CurrBytesRead:
515 (uint16_t)(NdefMap->ApduBufferSize -
516 NdefMap->ApduBuffIndex));
517 }
518 else
519 {
520 /*Copy data from the internal buffer to user buffer*/
521 (void)memcpy( (&( NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
522 (&( NdefMap->SendRecvBuf[13])),
523 NdefMap->Felica.Rd_NoBytesToCopy);
524
525 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
526 ResetFlag = TRUE;
527
528 }
529 }
530
531 }
532 else
533 {
534 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) < NdefMap->Felica.TrxLen )
535 {
536 /* Calculate exactly remained bytes to copy to internal buffer and set it*/
537 if ( NdefMap->Felica.LastBlkReachedFlag == 1)
538 {
539 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(16-(( Nbc * 16) - DataLen));
540
541 if ( NdefMap->Felica.Rd_NoBytesToCopy > (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex))
542 {
543 /*Reduce already copied bytes from the internal buffer*/
544 NdefMap->Felica.Rd_NoBytesToCopy -= (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
545 ExtrBytesToCpy = TRUE;
546 }
547 }
548 else
549 {
550 NdefMap->Felica.Rd_NoBytesToCopy = (uint8_t)(NdefMap->Felica.TrxLen - (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
551 ExtrBytesToCpy = TRUE;
552 }
553 if ( ExtrBytesToCpy == TRUE )
554 {
555 /*Copy the read data from trx buffer to apdu of size apdu*/
556 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
557 (&(NdefMap->SendRecvBuf[13])),
558 NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
559
560 /*copy bytesToCopy to internal buffer*/
561 (void)memcpy( NdefMap->Felica.Rd_BytesToCopyBuff,
562 (&(NdefMap->SendRecvBuf[13+(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)])),
563 NdefMap->Felica.Rd_NoBytesToCopy);
564
565 NdefMap->Felica.IntermediateCpyFlag = TRUE;
566 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex;
567 }
568 else
569 {
570 /*Copy data from the internal buffer to user buffer*/
571 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
572 (&(NdefMap->SendRecvBuf[13])),
573 NdefMap->Felica.Rd_NoBytesToCopy);
574
575 NdefMap->ApduBuffIndex += NdefMap->Felica.Rd_NoBytesToCopy;
576 ResetFlag = TRUE;
577
578 }
579 if ( DataLen <= (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) )
580 {
581 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
582 }
583 else
584 {
585 ;
586 }
587 }
588 else if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) == NdefMap->Felica.TrxLen )
589 {
590 /*Copy exactly remained last bytes to user buffer and increment the index*/
591 /*13 : 1+12 : 1st byte entire pkt length + 12 bytes to skip manuf details*/
592 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
593 (&(NdefMap->SendRecvBuf[13])),
594 (NdefMap->Felica.TrxLen ));
595
596 NdefMap->ApduBuffIndex += NdefMap->Felica.TrxLen;
597 }
598 else
599 {
600 if ((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > NdefMap->Felica.TrxLen )
601 {
602 /*Copy the data to apdu buffer and increment the index */
603 (void)memcpy( (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
604 (&(NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_RESP_HEADER_LEN])),
605 NdefMap->Felica.TrxLen);
606
607 NdefMap->ApduBuffIndex += (uint16_t)NdefMap->Felica.TrxLen;
608 }
609 }
610 }
611 }
612 if ( ResetFlag == TRUE )
613 {
614 /* reset the internal buffer variables*/
615 NdefMap->Felica.Rd_NoBytesToCopy =0;
616 NdefMap->Felica.IntermediateCpyLen =0;
617 NdefMap->Felica.IntermediateCpyFlag =FALSE;
618 }
619 return;
620 }
621
622
623 /*!
624 * \brief Used in Read Opearation.After a successful read operation,
625 Checks the relavent buffer sizes and set the status.Following function is used
626 when we read the Nmaxb blocks. Retained for future purpose.
627 */
628
phFriNfc_Felica_HChkApduBuff_Size(phFriNfc_NdefMap_t * NdefMap)629 static NFCSTATUS phFriNfc_Felica_HChkApduBuff_Size( phFriNfc_NdefMap_t *NdefMap)
630 {
631 NFCSTATUS status = NFCSTATUS_PENDING;
632 uint8_t ResetFlag = FALSE;
633 uint32_t Nbc = 0;
634
635 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
636
637 /* set status to Success : User Buffer is full and Curblk < nmaxb*/
638 if ( (( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
639 (NdefMap->Felica.CurBlockNo < Nbc ))
640 {
641 status = PHNFCSTVAL(CID_NFC_NONE,
642 NFCSTATUS_SUCCESS);
643 /*Reset the index, internal buffer counters back to zero*/
644 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
645 NdefMap->ApduBuffIndex = 0;
646
647 }/*if( (NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb )*/
648 else
649 {
650 if (( ( NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0) &&
651 (NdefMap->Felica.CurBlockNo == Nbc ))
652 {
653 status = PHNFCSTVAL(CID_NFC_NONE,
654 NFCSTATUS_SUCCESS);
655
656 ResetFlag = ((NdefMap->Felica.Rd_NoBytesToCopy > 0 )?
657 FALSE:
658 TRUE);
659 if( ResetFlag== FALSE)
660 {
661 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
662 /*Reset the index, internal buffer counters back to zero*/
663 NdefMap->ApduBuffIndex = 0;
664 }
665 }/*if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )== 0 && NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb )*/
666 else
667 {
668 /* reached reading all the blks available in the card: set EOF flag*/
669 if ( NdefMap->ApduBuffIndex == (Nbc*16))
670 {
671 status = PHNFCSTVAL(CID_NFC_NONE,
672 NFCSTATUS_SUCCESS);
673 ResetFlag = TRUE;
674 }
675 else
676 {
677 if ((NdefMap->ApduBufferSize-NdefMap->ApduBuffIndex )> 0 )
678 {
679 if ( NdefMap->Felica.CurBlockNo == Nbc )
680 {
681 /* bytes pending in internal buffer , No Space in User Buffer*/
682 if ( NdefMap->Felica.Rd_NoBytesToCopy > 0)
683 {
684 if ( NdefMap->Felica.EofCardReachedFlag == TRUE )
685 {
686 status = PHNFCSTVAL(CID_NFC_NONE,
687 NFCSTATUS_SUCCESS);
688 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
689 NdefMap->ApduBuffIndex=0;
690 }
691 else
692 {
693 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
694 if( NdefMap->Felica.Rd_NoBytesToCopy > 0 )
695 {
696 status = PHNFCSTVAL(CID_NFC_NONE,
697 NFCSTATUS_SUCCESS);
698 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
699 NdefMap->ApduBuffIndex=0;
700 }
701 else
702 {
703 /* EOF Card Reached set the internal EOF Flag*/
704 status = PHNFCSTVAL(CID_NFC_NONE,
705 NFCSTATUS_SUCCESS);
706
707 ResetFlag = TRUE;
708 }
709 }
710 }
711 /* All bytes from internal buffer are copied and set eof flag*/
712 else
713 {
714 status = PHNFCSTVAL(CID_NFC_NONE,
715 NFCSTATUS_SUCCESS);
716 ResetFlag = TRUE;
717 }
718 }
719 else
720 {
721 /* This flag is set to ensure that, need of Read Opearation
722 we completed coying the data from internal buffer to external buffer
723 left some more bytes,in User bufer so initiate the read operation */
724 NdefMap->Felica.IntermediateRdFlag = TRUE;
725 }
726 }
727 else
728 {
729 status = PHNFCSTVAL(CID_NFC_NONE,
730 NFCSTATUS_SUCCESS);
731 }
732 }
733 }
734 if ( ResetFlag == TRUE)
735 {
736 *NdefMap->NumOfBytesRead = NdefMap->ApduBuffIndex;
737 /*Reset the index, internal buffer counters back to zero*/
738 NdefMap->ApduBuffIndex = 0;
739 NdefMap->Felica.Rd_NoBytesToCopy=0;
740 NdefMap->Felica.EofCardReachedFlag=FELICA_RD_WR_EOF_CARD_REACHED;
741
742 }
743
744 }
745 return( status);
746 }
747
748 /*!
749 * \brief Used in Read Opearation.Sets the transceive Command for read.
750 */
phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t * NdefMap,uint16_t TrxLen,uint8_t Offset)751 static NFCSTATUS phFriNfc_Felica_HSetTransceiveForRead(phFriNfc_NdefMap_t *NdefMap,uint16_t TrxLen,uint8_t Offset)
752 {
753 NFCSTATUS TrxStatus = NFCSTATUS_PENDING;
754 uint16_t BufIndex=0,i=0;
755
756 /* set the felica cmd */
757 #ifdef PH_HAL4_ENABLE
758 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
759 #else
760 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
761 #endif /* #ifdef PH_HAL4_ENABLE */
762
763 /*Change the state to Read */
764 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK;
765
766 /* set the complition routines for the mifare operations */
767 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
768 NdefMap->MapCompletionInfo.Context = NdefMap;
769
770 /*set the additional informations for the data exchange*/
771 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
772 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
773
774 /* pkt len : updated at the end*/
775 NdefMap->SendRecvBuf[BufIndex] = 0x00;
776 BufIndex ++;
777
778 NdefMap->SendRecvBuf[BufIndex] = 0x06;
779 BufIndex++;
780
781 /* IDm - Manufacturer Id : 8bytes*/
782 #ifdef PH_HAL4_ENABLE
783 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
784 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
785 8);
786 #else
787 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
788 (void * )(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
789 8);
790 #endif /* #ifdef PH_HAL4_ENABLE */
791
792 BufIndex+=8;
793
794 /*Number of Services (n=1 ==> 0x80)*/
795 NdefMap->SendRecvBuf[BufIndex] = 0x01;
796 BufIndex++;
797
798 /*Service Code List*/
799 NdefMap->SendRecvBuf[BufIndex] = 0x0B;
800 BufIndex++;
801
802 NdefMap->SendRecvBuf[BufIndex] = 0x00;
803 BufIndex++;
804
805 /*Number of Blocks to read*/
806 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TrxLen/16);
807 BufIndex++;
808 /* Set the Blk numbers as per the offset set by the user : Block List*/
809 if ( Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN )
810 {
811 for ( i=0;i<(TrxLen/16);i++)
812 {
813 /*1st Service Code list : byte 1*/
814 NdefMap->SendRecvBuf[BufIndex] = 0x80;
815 BufIndex++;
816
817 /* No. Of Blocks*/
818 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(i + 1);
819 BufIndex++;
820 }
821 }
822 else
823 {
824 for ( i= 1;i<=(TrxLen/16);i++)
825 {
826 /*1st Service Code list : byte 1*/
827 NdefMap->SendRecvBuf[BufIndex] = 0x80;
828 BufIndex++;
829
830 /* No. Of Blocks*/
831 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(NdefMap->Felica.CurBlockNo + i);
832 BufIndex++;
833 }
834 }
835
836 /* len of entire pkt*/
837 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = (uint8_t) BufIndex;
838
839 /* Set the Pkt Len*/
840 NdefMap->SendLength = BufIndex;
841
842 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
843
844 TrxStatus = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
845 &NdefMap->MapCompletionInfo,
846 NdefMap->psRemoteDevInfo,
847 NdefMap->Cmd,
848 &NdefMap->psDepAdditionalInfo,
849 NdefMap->SendRecvBuf,
850 NdefMap->SendLength,
851 NdefMap->SendRecvBuf,
852 NdefMap->SendRecvLength);
853 return (TrxStatus);
854 }
855
856 /*!
857 * \brief Initiates Writing of NDEF information to the Remote Device.
858 *
859 * The function initiates the writing of NDEF information to a Remote Device.
860 * It performs a reset of the state and starts the action (state machine).
861 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
862 * has been triggered.
863 */
864
phFriNfc_Felica_WrNdef(phFriNfc_NdefMap_t * NdefMap,uint8_t * PacketData,uint32_t * PacketDataLength,uint8_t Offset)865 NFCSTATUS phFriNfc_Felica_WrNdef( phFriNfc_NdefMap_t *NdefMap,
866 uint8_t *PacketData,
867 uint32_t *PacketDataLength,
868 uint8_t Offset)
869 {
870
871 NFCSTATUS status = NFCSTATUS_PENDING;
872
873 NdefMap->ApduBufferSize = *PacketDataLength;
874 /*Store the packet data buffer*/
875 NdefMap->ApduBuffer = PacketData;
876
877 /* To Update the Acutal written bytes to context*/
878 NdefMap->WrNdefPacketLength = PacketDataLength;
879 *NdefMap->WrNdefPacketLength = 0;
880
881
882 NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
883 NdefMap->Felica.Offset = Offset;
884
885 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP;
886 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
887 /* handle the error in Transc function*/
888 if ( (status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
889 {
890 /* call respective CR */
891 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,status);
892 }
893 return (status);
894 }
895
896 /*!
897 * \brief Initiates Writing of Empty NDEF information to the Remote Device.
898 *
899 * The function initiates the writing empty of NDEF information to a Remote Device.
900 * It performs a reset of the state and starts the action (state machine).
901 * A periodic call of the \ref phFriNfcNdefMap_Process has to be done once the action
902 * has been triggered.
903 */
904
phFriNfc_Felica_EraseNdef(phFriNfc_NdefMap_t * NdefMap)905 NFCSTATUS phFriNfc_Felica_EraseNdef( phFriNfc_NdefMap_t *NdefMap)
906 {
907
908 NFCSTATUS status = NFCSTATUS_PENDING;
909 static uint32_t PktDtLength =0;
910
911 if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_INVALID )
912 {
913 /* Card is in invalid state, cannot have any read/write
914 operations*/
915 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
916 NFCSTATUS_INVALID_FORMAT);
917 }
918 else if ( NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY )
919 {
920 /*Can't write to the card :No Grants */
921 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
922 NFCSTATUS_WRITE_FAILED);
923 /* set the no. bytes written is zero*/
924 NdefMap->WrNdefPacketLength = &PktDtLength;
925 *NdefMap->WrNdefPacketLength = 0;
926 }
927 else
928 {
929
930 /* set the Operation*/
931 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP;
932
933 status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
934 }
935 return (status);
936 }
937
938
939 /*!
940 * \brief Used in Write Opearation.
941 * check the value set for the Write Flag, in first write operation(begin), sets the
942 * WR flag in attribute blck.
943 * After a successful write operation, This function sets the WR flag off and updates
944 * the LEN bytes in attribute Block.
945 */
946
phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t * NdefMap,uint8_t isStarted)947 static NFCSTATUS phFriNfc_Felica_HUpdateAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap,uint8_t isStarted)
948 {
949 NFCSTATUS status = NFCSTATUS_PENDING;
950
951 uint16_t ChkSum=0,index=0;
952 uint8_t BufIndex=0, ErrFlag = FALSE;
953 uint32_t TotNoWrittenBytes=0;
954
955 /* Write Operation : Begin/End Check*/
956
957 NdefMap->State =
958 (( isStarted == FELICA_WRITE_STARTED )?
959 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN:
960 PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END);
961
962 if( ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN)||
963 ( NdefMap->State == PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END) )
964 {
965
966 /* Set the Felica Cmd*/
967 #ifdef PH_HAL4_ENABLE
968 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
969 #else
970 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
971 #endif /* #ifdef PH_HAL4_ENABLE */
972
973 /* 1st byte represents the length of the cmd packet*/
974 NdefMap->SendRecvBuf[BufIndex] = 0x00;
975 BufIndex++;
976
977 /* Write/Update command code*/
978 NdefMap->SendRecvBuf[BufIndex] = 0x08;
979 BufIndex++;
980
981 /* IDm - Manufacturer Id : 8bytes*/
982 #ifdef PH_HAL4_ENABLE
983 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
984 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
985 8);
986 #else
987 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
988 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
989 8);
990 #endif /* #ifdef PH_HAL4_ENABLE */
991
992 BufIndex+=8;
993
994 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
995 BufIndex++;
996
997 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
998 BufIndex++;
999
1000 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1001 BufIndex++;
1002
1003 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/
1004 BufIndex++;
1005
1006 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
1007 BufIndex++;
1008
1009 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
1010 BufIndex++;
1011
1012 /* Fill Attribute Blk Information*/
1013 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version;
1014 BufIndex++;
1015
1016 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr;
1017 BufIndex++;
1018
1019 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1020 BufIndex++;
1021
1022 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1023 BufIndex++;
1024
1025 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1026 BufIndex++;
1027
1028 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1029 BufIndex++;
1030
1031 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1032 BufIndex++;
1033
1034 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1035 BufIndex++;
1036
1037 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1038 BufIndex++;
1039
1040 if (isStarted == FELICA_WRITE_STARTED )
1041 {
1042 NdefMap->SendRecvBuf[BufIndex] = 0x0F; /* Write Flag Made On*/
1043 BufIndex++;
1044
1045 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1046 BufIndex++;
1047
1048 /* Len Bytes*/
1049 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[0];
1050 BufIndex++;
1051
1052 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[1];
1053 BufIndex++;
1054
1055 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.LenBytes[2];
1056 BufIndex++;
1057 }
1058 else
1059 {
1060 /* Case: Previous Write Operation failed and integration context continues with write
1061 operation with offset set to Current. In this case, if we find Internal Bytes remained in the
1062 felica context is true(>0) and current block number is Zero. Then we shouldn't allow the module
1063 to write the data to card, as this is a invalid case*/
1064 if ( (NdefMap->Felica.Wr_BytesRemained > 0) && (NdefMap->Felica.CurBlockNo == 0))
1065 {
1066 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1067 NFCSTATUS_INVALID_PARAMETER);
1068 ErrFlag = TRUE;
1069 }
1070 else
1071 {
1072
1073 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Write Flag Made Off*/
1074 BufIndex++;
1075
1076 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1077 BufIndex++;
1078
1079 if ( NdefMap->Felica.Wr_BytesRemained > 0 )
1080 {
1081 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1082 }
1083 else
1084 {
1085 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1086
1087 }
1088
1089 /* Update Len Bytes*/
1090 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(( TotNoWrittenBytes & 0x00ff0000) >> 16);
1091 BufIndex++;
1092
1093 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((TotNoWrittenBytes & 0x0000ff00) >> 8);
1094 BufIndex++;
1095
1096 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(TotNoWrittenBytes & 0x000000ff);
1097 BufIndex++;
1098 }
1099 }
1100
1101 if ( ErrFlag != TRUE )
1102 {
1103 /* check sum update*/
1104 for ( index = 16 ; index < 30 ; index ++)
1105 {
1106 ChkSum += NdefMap->SendRecvBuf[index];
1107 }
1108
1109 /* fill check sum in command pkt*/
1110 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1111 BufIndex++;
1112
1113 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1114 BufIndex++;
1115
1116 /* update length of the cmd pkt*/
1117 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1118
1119 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1120
1121 /* Update the Send Len*/
1122 NdefMap->SendLength = BufIndex;
1123
1124 /*set the completion routines for the desfire card operations*/
1125 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1126 NdefMap->MapCompletionInfo.Context = NdefMap;
1127
1128 /*set the additional informations for the data exchange*/
1129 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1130 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1131
1132 /*Call the Overlapped HAL Transceive function */
1133 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1134 &NdefMap->MapCompletionInfo,
1135 NdefMap->psRemoteDevInfo,
1136 NdefMap->Cmd,
1137 &NdefMap->psDepAdditionalInfo,
1138 NdefMap->SendRecvBuf,
1139 NdefMap->SendLength,
1140 NdefMap->SendRecvBuf,
1141 NdefMap->SendRecvLength);
1142 }
1143 }
1144 else
1145 {
1146 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1147 NFCSTATUS_INVALID_PARAMETER);
1148
1149 }
1150 return (status);
1151 }
1152
phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t * NdefMap)1153 static NFCSTATUS phFriNfc_Felica_HWrEmptyMsg(phFriNfc_NdefMap_t *NdefMap)
1154 {
1155 NFCSTATUS status = NFCSTATUS_PENDING;
1156
1157 uint16_t ChkSum=0,index=0;
1158 uint8_t BufIndex=0;
1159
1160 /* Write Operation : To Erase the present NDEF Data*/
1161
1162 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG;
1163
1164 /* Set the Felica Cmd*/
1165 #ifdef PH_HAL4_ENABLE
1166 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
1167 #else
1168 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
1169 #endif /* #ifdef PH_HAL4_ENABLE */
1170
1171 /* 1st byte represents the length of the cmd packet*/
1172 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1173 BufIndex++;
1174
1175 /* Write/Update command code*/
1176 NdefMap->SendRecvBuf[BufIndex] = 0x08;
1177 BufIndex++;
1178
1179 /* IDm - Manufacturer Id : 8bytes*/
1180 #ifdef PH_HAL4_ENABLE
1181 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1182 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1183 8);
1184 #else
1185 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1186 (void*)(&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1187 8);
1188 #endif /* #ifdef PH_HAL4_ENABLE */
1189
1190
1191 BufIndex+=8;
1192
1193 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
1194 BufIndex++;
1195
1196 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
1197 BufIndex++;
1198
1199 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1200 BufIndex++;
1201
1202 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to Write*/
1203 BufIndex++;
1204
1205 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
1206 BufIndex++;
1207
1208 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
1209 BufIndex++;
1210
1211 /* Fill Attribute Blk Information*/
1212 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Version;
1213 BufIndex++;
1214
1215 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbr;
1216 BufIndex++;
1217
1218 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1219 BufIndex++;
1220
1221 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) >> 8);
1222 BufIndex++;
1223
1224 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb) & (0x00ff));
1225 BufIndex++;
1226
1227 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1228 BufIndex++;
1229
1230 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1231 BufIndex++;
1232
1233 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1234 BufIndex++;
1235
1236 NdefMap->SendRecvBuf[BufIndex] = 0x00; /*RFU*/
1237 BufIndex++;
1238
1239 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.WriteFlag;
1240 BufIndex++;
1241
1242 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.RdWrFlag; /* Read write flag*/
1243 BufIndex++;
1244
1245 /* Len Bytes are set to 0 : Empty Msg*/
1246 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1247 BufIndex++;
1248
1249 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1250 BufIndex++;
1251
1252 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1253 BufIndex++;
1254
1255 /* check sum update*/
1256 for ( index = 16 ; index < 30 ; index ++)
1257 {
1258 ChkSum += NdefMap->SendRecvBuf[index];
1259 }
1260
1261 /* fill check sum in command pkt*/
1262 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)(ChkSum >> 8);
1263 BufIndex++;
1264
1265 NdefMap->SendRecvBuf[BufIndex] = (uint8_t )(ChkSum & 0x00ff);
1266 BufIndex++;
1267
1268 /* update length of the cmd pkt*/
1269 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1270
1271 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
1272
1273 /* Update the Send Len*/
1274 NdefMap->SendLength = BufIndex;
1275
1276 /*set the completion routines for the desfire card operations*/
1277 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
1278 NdefMap->MapCompletionInfo.Context = NdefMap;
1279
1280 /*set the additional informations for the data exchange*/
1281 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
1282 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
1283
1284 /*Call the Overlapped HAL Transceive function */
1285 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
1286 &NdefMap->MapCompletionInfo,
1287 NdefMap->psRemoteDevInfo,
1288 NdefMap->Cmd,
1289 &NdefMap->psDepAdditionalInfo,
1290 NdefMap->SendRecvBuf,
1291 NdefMap->SendLength,
1292 NdefMap->SendRecvBuf,
1293 NdefMap->SendRecvLength);
1294
1295 return (status);
1296 }
1297
1298
1299
1300
1301 /*!
1302 * \brief Used in Write Opearation.
1303 * This Function is called after a successful validation and storing of attribution block
1304 * content in to context.
1305 * If the write operation is initiated with begin,function initiates the write operation with
1306 * RdWr flag.
1307 * If the Offset is set to Current, Checks for the EOF card reached status and writes data to
1308 * The Card
1309 */
1310
phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t * NdefMap)1311 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForWrOp(phFriNfc_NdefMap_t *NdefMap)
1312 {
1313 NFCSTATUS status = NFCSTATUS_PENDING;
1314 uint32_t DataLen=0;
1315
1316 /*check RW Flag Access Rights*/
1317 /* set to read only cannot write*/
1318 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00)
1319
1320 {
1321 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1322 NFCSTATUS_INVALID_DEVICE_REQUEST);
1323 }
1324 else
1325 {
1326 if ( ( NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_BEGIN) ||
1327 ( ( NdefMap->PrevOperation == PH_FRINFC_NDEFMAP_READ_OPE) &&
1328 (NdefMap->Felica.Offset != PH_FRINFC_NDEFMAP_SEEK_BEGIN ) ))
1329 {
1330 /* check allready written number of bytes and apdu buffer size*/
1331 if (NdefMap->ApduBufferSize > (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16))
1332 {
1333 NdefMap->Felica.EofCardReachedFlag = FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET;
1334 }
1335 else
1336 {
1337 NdefMap->Felica.EofCardReachedFlag = FALSE;
1338 }
1339
1340
1341 /* reset the internal variables initiate toupdate the attribute blk*/
1342 NdefMap->Felica.Wr_BytesRemained = 0;
1343 NdefMap->Felica.CurBlockNo = 0;
1344 NdefMap->Felica.NoBlocksWritten = 0;
1345 phFriNfc_Felica_HInitInternalBuf(NdefMap->Felica.Wr_RemainedBytesBuff);
1346 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1347
1348 }
1349 else
1350 {
1351 if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )
1352 {
1353 /* Calculate the Allready Written No. Of Blocks*/
1354 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
1355 NdefMap->FelicaAttrInfo.LenBytes[1],
1356 NdefMap->FelicaAttrInfo.LenBytes[2],
1357 DataLen);
1358
1359 if (( NdefMap->ApduBufferSize + (DataLen )) >
1360 (uint32_t)( NdefMap->FelicaAttrInfo.Nmaxb *16))
1361 {
1362 if(( DataLen ) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb *16) )
1363 {
1364 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
1365 NFCSTATUS_EOF_NDEF_CONTAINER_REACHED);
1366 }
1367 else
1368 {
1369
1370 NdefMap->Felica.EofCardReachedFlag =FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET;
1371 NdefMap->ApduBuffIndex =0;
1372 NdefMap->Felica.NoBlocksWritten = 0;
1373 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1374 }
1375 }
1376 else
1377 {
1378 NdefMap->ApduBuffIndex =0;
1379 NdefMap->Felica.NoBlocksWritten = 0;
1380 status= phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_STARTED);
1381 }
1382 }/*if (NdefMap->Felica.Offset == PH_FRINFC_NDEFMAP_SEEK_CUR )*/
1383 }
1384 }
1385 return (status);
1386 }
1387
1388 /*!
1389 * \brief Used in Read Opearation.
1390 * This Function is called after a successful validation and storing of attribution block
1391 * content in to context.
1392 * While Offset is set to Current, Checks for the EOF card reached status and reads data from
1393 * The Card
1394 */
1395
phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t * NdefMap,uint32_t NdefLen)1396 static NFCSTATUS phFriNfc_Felica_HChkAttrBlkForRdOp(phFriNfc_NdefMap_t *NdefMap,
1397 uint32_t NdefLen)
1398 {
1399 NFCSTATUS status = NFCSTATUS_PENDING;
1400
1401 /*check WR Flag Access Rights*/
1402 /* set to still writing data state only cannot Read*/
1403 if ( NdefMap->FelicaAttrInfo.WriteFlag == 0x0F )
1404 {
1405 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_READ_FAILED);
1406 /* As we are not able to continue with reading data
1407 bytes read set to zero*/
1408 *NdefMap->NumOfBytesRead = 0;
1409 }
1410 else
1411 {
1412 status = phFriNfc_MapTool_SetCardState( NdefMap,NdefLen);
1413 if ( status == NFCSTATUS_SUCCESS)
1414 {
1415 /* Read data From the card*/
1416 status = phFriNfc_Felica_HReadData(NdefMap,NdefMap->Felica.Offset);
1417 }
1418 }
1419
1420 return (status);
1421 }
1422
1423 /*!
1424 * \brief Used in Write Opearation.
1425 * This function writes the data in terms of blocks.
1426 * Each write operation supports,minimum Nbw blocks of bytes.
1427 * Also checks for the EOF,>=NBW,<NBW etc
1428 */
phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t * NdefMap)1429 static NFCSTATUS phFriNfc_Felica_HUpdateData(phFriNfc_NdefMap_t *NdefMap)
1430 {
1431 NFCSTATUS status = NFCSTATUS_PENDING;
1432
1433 uint8_t BufIndex=0,
1434 i=0,
1435 BlkNo=0,
1436 PadBytes=0,
1437 CurBlk=1,
1438 NoOfBlks=0,
1439 NbwCheck=0,
1440 TotNoBlks=0;
1441
1442 uint32_t BytesRemainedInCard=0,
1443 BytesRemained=0,
1444 TotNoWrittenBytes=0;
1445
1446 if( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) > 0 )
1447 {
1448 /* Prepare the write cmd pkt for felica*/
1449 /* 1st byte represents the length of the cmd packet*/
1450 NdefMap->SendRecvBuf[BufIndex] = 0x00;
1451 BufIndex++;
1452
1453 /* Write/Update command code*/
1454 NdefMap->SendRecvBuf[BufIndex] = 0x08;
1455 BufIndex++;
1456
1457 /* IDm - Manufacturer Id : 8bytes*/
1458 #ifdef PH_HAL4_ENABLE
1459 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1460 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm)),
1461 8);
1462 #else
1463 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1464 (&(NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t)),
1465 8);
1466 #endif /* #ifdef PH_HAL4_ENABLE */
1467
1468 BufIndex+=8;
1469
1470 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
1471 BufIndex++;
1472
1473 NdefMap->SendRecvBuf[BufIndex] = 0x09; /* Service Code List*/
1474 BufIndex++;
1475
1476 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
1477 BufIndex++;
1478
1479 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_BEGIN_OFFSET)
1480 {
1481 /* check for the eof card reached flag.Need to write only mamximum bytes(memory)to card.
1482 Used when, offset set to begin case*/
1483 BytesRemainedInCard= ( (NdefMap->FelicaAttrInfo.Nmaxb*16) - (NdefMap->Felica.CurBlockNo * 16));
1484 }
1485 else
1486 {
1487 /* Offset : Cuurent*/
1488 if ( NdefMap->Felica.EofCardReachedFlag == FELICA_EOF_REACHED_WR_WITH_CURR_OFFSET )
1489 {
1490 /* caculate previously written Ndef blks*/
1491 (void)phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
1492
1493 if ( NdefMap->Felica.Wr_BytesRemained )
1494 {
1495 TotNoWrittenBytes = ( (NdefMap->Felica.CurBlockNo *16)- (16 - (NdefMap->Felica.Wr_BytesRemained)));
1496 }
1497 else
1498 {
1499 TotNoWrittenBytes = ( NdefMap->Felica.CurBlockNo *16);
1500 }
1501 /* Determine exactly, how many bytes we can write*/
1502 BytesRemainedInCard = (NdefMap->FelicaAttrInfo.Nmaxb*16 - (TotNoWrittenBytes));
1503 }
1504
1505 }
1506 /* Write Data Pending in the Internal Buffer*/
1507 if(NdefMap->Felica.Wr_BytesRemained > 0)
1508 {
1509 /* update the number of blocks to write with the block list elements*/
1510 /* Total Number of blocks to write*/
1511 NdefMap->SendRecvBuf[BufIndex] = 0;
1512 BufIndex++;
1513
1514 /* Update this Total no. Bloks later*/
1515 NoOfBlks = BufIndex;
1516
1517 /* As we are writing atleast one block*/
1518 TotNoBlks = 1;
1519
1520 /* check do we have some extra bytes to write? in User Buffer*/
1521 if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))
1522 {
1523 /* Have we reached EOF?*/
1524 if ( NdefMap->Felica.EofCardReachedFlag )
1525 {
1526 BytesRemained = BytesRemainedInCard;
1527 }
1528 else
1529 {
1530 /* This value tells how many extra bytes we can write other than internal buffer bytes*/
1531 BytesRemained = (uint8_t)NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained);
1532 }
1533
1534 if ( BytesRemained )
1535 {
1536 /* Not reached EOF*/
1537 if (!NdefMap->Felica.EofCardReachedFlag)
1538 {
1539 /* Calculate How many blks we need to write*/
1540 BlkNo =((uint8_t)( BytesRemained )/16);
1541
1542 /* check blocks to write exceeds nbw*/
1543 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1544 {
1545 BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1546 /* No. Blks to write are more than Nbw*/
1547 NbwCheck = 1;
1548 }
1549 else
1550 {
1551 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1552 {
1553 BlkNo=1;
1554 }
1555 }
1556 /* check do we need pad bytes?*/
1557 if( (!NbwCheck && (uint8_t)( BytesRemained)%16) != 0)
1558 {
1559 BlkNo++;
1560 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1561 NdefMap->Felica.PadByteFlag = TRUE;
1562 NdefMap->Felica.NoBlocksWritten = BlkNo;
1563 TotNoBlks += BlkNo;
1564
1565 }
1566 else
1567 {
1568 if ( NbwCheck )
1569 {
1570 /* as we have to write only 8 blocks and already we have pad bytes so we have
1571 to strat from previous block*/
1572 TotNoBlks += BlkNo - 1;
1573 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1574 }
1575 else
1576 {
1577 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1578 {
1579 TotNoBlks += BlkNo;
1580 }
1581 else
1582 {
1583
1584 }
1585 if ( NdefMap->Felica.PadByteFlag )
1586 {
1587 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1588
1589 }
1590 }
1591 }
1592 }
1593 else
1594 {
1595 /* we have reached the eof card & hv bytes to write*/
1596 BlkNo =(uint8_t)(( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained)) )/16);
1597
1598 /* check are we exceeding the NBW limit, while a write?*/
1599 if ( BlkNo >= NdefMap->FelicaAttrInfo.Nbw )
1600 {
1601 BlkNo = NdefMap->FelicaAttrInfo.Nbw;
1602
1603 /* No. Blks to write are more than Nbw*/
1604 NbwCheck = 1;
1605
1606 }
1607 else
1608 {
1609 if ((( BytesRemained %16) == 0)&& (BlkNo == 0 ))
1610 {
1611 BlkNo=1;
1612 }
1613 }
1614
1615 /*check Total how many blocks to write*/
1616 if(((!NbwCheck) &&( BytesRemained- (16 - NdefMap->Felica.Wr_BytesRemained))%16) != 0)
1617 {
1618 BlkNo++;
1619 PadBytes = (BlkNo * 16) - (uint8_t)( BytesRemained);
1620 NdefMap->Felica.PadByteFlag = TRUE;
1621 NdefMap->Felica.NoBlocksWritten = BlkNo;
1622 TotNoBlks += BlkNo;
1623
1624 }
1625 else
1626 {
1627 if ( NbwCheck )
1628 {
1629 /* as we have to write only 8 blocks and already we have pad bytes so we have
1630 to strat from previous last block*/
1631 TotNoBlks += BlkNo - 1;
1632 NdefMap->Felica.NoBlocksWritten = TotNoBlks-1;
1633 }
1634 else
1635 {
1636 /* we need to write only one block ( bytesremanind + internal buffer size = 16)*/
1637 if ( !(BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained)== 0 ))
1638 {
1639 TotNoBlks += BlkNo;
1640 }
1641 else
1642 {
1643 ;/* we are not incrementing the Total no. of blocks to write*/
1644 }
1645
1646 if ( NdefMap->Felica.PadByteFlag )
1647 {
1648 NdefMap->Felica.NoBlocksWritten = TotNoBlks -1;
1649
1650 }
1651 }
1652 }
1653 }
1654 }/*if ( BytesRemained )*/
1655 else
1656 {
1657 ; /*Nothing to process here*/
1658 }
1659 }/*if ( NdefMap->ApduBufferSize >(uint32_t) (16 - NdefMap->Felica.Wr_BytesRemained))*/
1660 else
1661 {
1662 /* No new blks to write*/
1663 NdefMap->Felica.NoBlocksWritten = 0;
1664 }
1665 /* Prepare the Blk List for Write Operation*/
1666 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1667 for ( i=0; i< TotNoBlks; i++)
1668 {
1669 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1670 BufIndex++;
1671 /* remember the previous Blk no and continue from there*/
1672 if ( NdefMap->Felica.PadByteFlag == TRUE )
1673 {
1674 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1675 BufIndex++;
1676 }
1677 else
1678 {
1679 CurBlk = NdefMap->Felica.CurBlockNo +1;
1680 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i;
1681 BufIndex++;
1682 }
1683 }
1684 /* Copy relevant data to Transc buffer*/
1685 if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))
1686 {
1687
1688 /*Copy the Remained bytes from the internal buffer to trxbuffer */
1689 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1690 NdefMap->Felica.Wr_RemainedBytesBuff,
1691 NdefMap->Felica.Wr_BytesRemained);
1692
1693 /*Increment the buff index*/
1694 BufIndex += NdefMap->Felica.Wr_BytesRemained;
1695
1696
1697 /*append copy 16-bytesToPad to trxBuffer*/
1698 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1699 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1700 (16 - NdefMap->Felica.Wr_BytesRemained));
1701
1702 /* Update Number Of Bytes Writtened*/
1703 NdefMap->NumOfBytesWritten = 16 - NdefMap->Felica.Wr_BytesRemained;
1704
1705 /* increment the index*/
1706 BufIndex += 16 - NdefMap->Felica.Wr_BytesRemained;
1707
1708 if ( BytesRemained )
1709 {
1710 if (!NdefMap->Felica.EofCardReachedFlag)
1711 {
1712 /* check nbw limit*/
1713 if ( NbwCheck != 1 )
1714 {
1715 /* Copy Extra Bytes other than the internal buffer bytes*/
1716 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1717 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1718 (NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained)));
1719
1720
1721 /* Update Number Of Bytes Writtened*/
1722 NdefMap->NumOfBytesWritten += (uint16_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1723
1724 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - (16 - NdefMap->Felica.Wr_BytesRemained));
1725
1726 if ( PadBytes )
1727 {
1728 for(i= 0; i< PadBytes; i++)
1729 {
1730 NdefMap->SendRecvBuf[BufIndex] =0x00;
1731 BufIndex++;
1732 }
1733 /* no of bytes remained copy*/
1734 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1735
1736 /*copy the data to internal buffer : Bytes remained*/
1737 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff,
1738 (&( NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])),
1739 ( NdefMap->Felica.Wr_BytesRemained));
1740 }
1741 else
1742 {
1743 /* No Bytes in Internal buffer*/
1744 NdefMap->Felica.Wr_BytesRemained = 0;
1745 }
1746
1747 }
1748 else
1749 {
1750
1751 /*Copy Nbw*16 bytes of data to the trx buffer*/
1752 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1753 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1754 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16);
1755
1756 /* increment the Buffindex*/
1757 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1758
1759 NdefMap->Felica.Wr_BytesRemained = 0;
1760 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1761 NdefMap->Felica.PadByteFlag =FALSE;
1762 }
1763 }/*if (!NdefMap->Felica.EofCardReachedFlag)*/
1764 else
1765 {
1766 /* check nbw limit*/
1767 if ( NbwCheck != 1 )
1768 {
1769 /* handle EOF card reached case*/
1770 (void)memcpy( (&(NdefMap->SendRecvBuf[BufIndex])),
1771 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1772 ( BytesRemained - ((16 -NdefMap->Felica.Wr_BytesRemained) )));
1773
1774 /* Update Number Of Bytes Writtened*/
1775 NdefMap->NumOfBytesWritten += (uint16_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1776
1777 BufIndex += (uint8_t)( BytesRemained - (16 -NdefMap->Felica.Wr_BytesRemained));
1778
1779 if ( PadBytes )
1780 {
1781 for(i= 0; i< PadBytes; i++)
1782 {
1783 NdefMap->SendRecvBuf[BufIndex] =0x00;
1784 BufIndex++;
1785 }
1786
1787 /*no of bytes remained copy*/
1788 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
1789
1790 /*copy the data to internal buffer : Bytes remained*/
1791 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff,
1792 (&(NdefMap->ApduBuffer[(NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained)])),
1793 (NdefMap->Felica.Wr_BytesRemained));
1794
1795 }
1796 else
1797 {
1798 NdefMap->Felica.Wr_BytesRemained = 0;
1799 }
1800 }
1801 else
1802 {
1803
1804 /*Copy Nbw*16 bytes of data to the trx buffer*/
1805 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1806 (&(NdefMap->ApduBuffer[(16 - NdefMap->Felica.Wr_BytesRemained)])),
1807 (NdefMap->FelicaAttrInfo.Nbw - 1) * 16);
1808
1809 /* increment the Buffindex*/
1810 BufIndex += ((NdefMap->FelicaAttrInfo.Nbw - 1 )*16);
1811
1812 NdefMap->Felica.Wr_BytesRemained = 0;
1813 NdefMap->NumOfBytesWritten+= ((NdefMap->FelicaAttrInfo.Nbw -1)*16);
1814
1815 NdefMap->Felica.PadByteFlag =FALSE;
1816 }
1817 }
1818 }/*if ( BytesRemained )*/
1819 else
1820 {
1821 NdefMap->Felica.Wr_BytesRemained = 0;
1822 }
1823 /* Update Total No. of blocks writtened*/
1824 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks;
1825 }/*if((NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16 - NdefMap->Felica.Wr_BytesRemained))*/
1826 else
1827 {
1828 /*copy the internal buffer data to trx buffer*/
1829 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1830 NdefMap->Felica.Wr_RemainedBytesBuff,
1831 (NdefMap->Felica.Wr_BytesRemained));
1832
1833 /* increment the index*/
1834 BufIndex+=NdefMap->Felica.Wr_BytesRemained;
1835
1836 /*append the apdusize data to the trx buffer*/
1837 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1838 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1839 NdefMap->ApduBufferSize);
1840
1841 /* Index increment*/
1842 BufIndex+= (uint8_t)NdefMap->ApduBufferSize;
1843
1844 /* Tells how many bytes present in the internal buffer*/
1845 BytesRemained = NdefMap->Felica.Wr_BytesRemained + NdefMap->ApduBufferSize;
1846
1847 PadBytes = (uint8_t)(16-BytesRemained);
1848
1849 /* Pad empty bytes with Zeroes to complete 16 bytes*/
1850 for(i= 0; i< PadBytes; i++)
1851 {
1852 NdefMap->SendRecvBuf[BufIndex] =0x00;
1853 BufIndex++;
1854 }
1855
1856 /* Update Number Of Bytes Writtened*/
1857 NdefMap->NumOfBytesWritten = (uint16_t)NdefMap->ApduBufferSize;
1858
1859 /* Flag set to understand that , we have received less no. of bytes than
1860 present in the internal buffer*/
1861 NdefMap->Felica.IntermediateWrFlag = TRUE;
1862
1863 if ( NdefMap->Felica.PadByteFlag )
1864 {
1865 NdefMap->Felica.NoBlocksWritten = 0;
1866 }
1867 }
1868
1869 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1870 NdefMap->SendLength = BufIndex;
1871 /* Update Total No. of blocks writtened*/
1872 NdefMap->SendRecvBuf[NoOfBlks -1 ]=TotNoBlks;
1873 }
1874 else
1875 {
1876 /*Fresh write, starting from a new block*/
1877 if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw ))
1878 {
1879 /* check for the card size and write Nbw Blks*/
1880 if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)
1881 {
1882 /* update the number of blocks to write with the block list elements*/
1883 /* Total Number of blocks to write*/
1884 NdefMap->SendRecvBuf[BufIndex] = NdefMap->FelicaAttrInfo.Nbw;
1885 BufIndex++;
1886
1887 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1888 for ( i=1; i<= NdefMap->FelicaAttrInfo.Nbw; i++)
1889 {
1890 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1891 BufIndex++;
1892
1893 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1894 BufIndex++;
1895 }
1896 /*Copy Nbw*16 bytes of data to the trx buffer*/
1897
1898 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1899 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1900 NdefMap->FelicaAttrInfo.Nbw * 16);
1901
1902 /* increment the Buffindex*/
1903 BufIndex += (NdefMap->FelicaAttrInfo.Nbw*16);
1904
1905 /* update the length*/
1906 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1907
1908 NdefMap->Felica.Wr_BytesRemained = 0;
1909 NdefMap->NumOfBytesWritten = (NdefMap->FelicaAttrInfo.Nbw*16);
1910 NdefMap->Felica.NoBlocksWritten = NdefMap->FelicaAttrInfo.Nbw;
1911
1912 /* update the Send length*/
1913 NdefMap->SendLength = BufIndex;
1914
1915 NdefMap->Felica.PadByteFlag = FALSE;
1916 }/*if ( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo >= NdefMap->FelicaAttrInfo.Nbw)*/
1917 else
1918 {
1919 /* we need to write less than nbw blks*/
1920 /* update the number of blocks to write with the block list elements*/
1921 /* Total Number of blocks to write*/
1922 NdefMap->SendRecvBuf[BufIndex] = (uint8_t)( NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo);
1923 BufIndex++;
1924
1925 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1926 for ( i=1; i<= (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo); i++)
1927 {
1928 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1929 BufIndex++;
1930 NdefMap->SendRecvBuf[BufIndex] = NdefMap->Felica.CurBlockNo + i;
1931 BufIndex++;
1932 }
1933
1934 /*Copy Nbw*16 bytes of data to the trx buffer*/
1935 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
1936 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
1937 (NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16);
1938
1939 /* increment the Buffindex*/
1940 BufIndex += (uint8_t)((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo )*16);
1941
1942 /* update the length*/
1943 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
1944
1945 NdefMap->NumOfBytesWritten = ((NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo)*16);
1946 NdefMap->Felica.NoBlocksWritten = (uint8_t)(NdefMap->FelicaAttrInfo.Nmaxb - NdefMap->Felica.CurBlockNo);
1947
1948 /* update the Send length*/
1949 NdefMap->SendLength = BufIndex;
1950
1951 NdefMap->Felica.PadByteFlag =FALSE;
1952 NdefMap->Felica.Wr_BytesRemained = 0;
1953 }
1954 }/* if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
1955 else
1956 {
1957 /*chk eof reached*/
1958 if ( NdefMap->Felica.EofCardReachedFlag)
1959 {
1960 BlkNo =((uint8_t)(BytesRemainedInCard )/16);
1961 if(((uint8_t)( BytesRemainedInCard )%16) != 0)
1962 {
1963 BlkNo++;
1964 PadBytes = ((BlkNo * 16) - (uint8_t)(BytesRemainedInCard ));
1965 NdefMap->Felica.PadByteFlag = TRUE;
1966 }
1967 }
1968 else
1969 {
1970
1971 BlkNo =((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)/16);
1972 if(((uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex)%16) != 0)
1973 {
1974 BlkNo++;
1975 PadBytes = (BlkNo * 16) - (uint8_t)( NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
1976 NdefMap->Felica.PadByteFlag = TRUE;
1977
1978 }
1979
1980
1981 }
1982
1983 /* update the number of blocks to write with the block list elements*/
1984 /* Total Number of blocks to write*/
1985 NdefMap->SendRecvBuf[BufIndex] = BlkNo;
1986 BufIndex++;
1987
1988 NdefMap->Felica.NoBlocksWritten = BlkNo;
1989
1990 /* Block List for NBw : 1st byte : two byte len list: 2nd byte is the block number*/
1991 for ( i=0; i< BlkNo; i++)
1992 {
1993 NdefMap->SendRecvBuf[BufIndex] = 0x80;
1994 BufIndex++;
1995 {
1996 CurBlk = NdefMap->Felica.CurBlockNo +1;
1997 NdefMap->SendRecvBuf[BufIndex] = CurBlk + i;
1998 BufIndex++;
1999 }
2000 }
2001 if ( NdefMap->Felica.EofCardReachedFlag )
2002 {
2003 /*Copy last data to the trx buffer*/
2004 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2005 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2006 BytesRemainedInCard );
2007
2008 /* increment the bufindex and bytes written*/
2009 BufIndex += (uint8_t )BytesRemainedInCard ;
2010 NdefMap->NumOfBytesWritten = (uint16_t)BytesRemainedInCard ;
2011 }
2012 else
2013 {
2014 /*Copy data to the trx buffer*/
2015 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2016 (&(NdefMap->ApduBuffer[NdefMap->ApduBuffIndex])),
2017 (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex));
2018
2019 /* increment the bufindex and bytes written*/
2020 BufIndex += (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2021 NdefMap->NumOfBytesWritten = (uint8_t)(NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex);
2022 }
2023 if ( PadBytes )
2024 {
2025 for(i= 0; i< PadBytes; i++)
2026 {
2027 NdefMap->SendRecvBuf[BufIndex] =0x00;
2028 BufIndex++;
2029 }
2030 /*no of bytes remained copy*/
2031 NdefMap->Felica.Wr_BytesRemained = (uint8_t)(16 - PadBytes);
2032
2033 if ( NdefMap->Felica.EofCardReachedFlag )
2034 {
2035 /*copy the data to internal buffer : Bytes remained*/
2036 (void)memcpy(NdefMap->Felica.Wr_RemainedBytesBuff,
2037 (&(NdefMap->ApduBuffer[((BytesRemainedInCard - (BytesRemainedInCard % 16)))])),
2038 ( NdefMap->Felica.Wr_BytesRemained));
2039
2040 }
2041 else
2042 {
2043 /*copy the data to internal buffer : Bytes remained*/
2044 (void)memcpy( NdefMap->Felica.Wr_RemainedBytesBuff,
2045 (&(NdefMap->ApduBuffer[((NdefMap->ApduBufferSize - NdefMap->Felica.Wr_BytesRemained))])),
2046 ( NdefMap->Felica.Wr_BytesRemained));
2047
2048 }
2049 }/*if ( PadBytes )*/
2050 else
2051 {
2052 NdefMap->Felica.Wr_BytesRemained = 0;
2053 NdefMap->Felica.PadByteFlag = FALSE;
2054 }
2055 /* update the pkt len*/
2056 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
2057 NdefMap->SendLength = BufIndex;
2058 }
2059 }/* else of if ( (NdefMap->ApduBufferSize - NdefMap->ApduBuffIndex) >= (uint32_t)(16* NdefMap->FelicaAttrInfo.Nbw )) */
2060 status = phFriNfc_Felica_HWriteDataBlk(NdefMap);
2061 }
2062 else
2063 {
2064 /*0 represents the write operation ended*/
2065 status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2066 }
2067 return (status);
2068 }
2069
2070
2071 /*!
2072 * \brief Used in Write Opearation.
2073 * This function prepares and sends transcc Cmd Pkt.
2074 */
2075
phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t * NdefMap)2076 static NFCSTATUS phFriNfc_Felica_HWriteDataBlk(phFriNfc_NdefMap_t *NdefMap)
2077 {
2078 NFCSTATUS status = NFCSTATUS_PENDING;
2079
2080 /*set the additional informations for the data exchange*/
2081 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2082 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2083
2084 /*Set the ISO14434 command*/
2085 #ifdef PH_HAL4_ENABLE
2086 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2087 #else
2088 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2089 #endif /* #ifdef PH_HAL4_ENABLE */
2090
2091 /* set the state*/
2092 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK;
2093
2094 /* set send receive length*/
2095 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2096
2097 /*Call the Overlapped HAL Transceive function */
2098 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2099 &NdefMap->MapCompletionInfo,
2100 NdefMap->psRemoteDevInfo,
2101 NdefMap->Cmd,
2102 &NdefMap->psDepAdditionalInfo,
2103 NdefMap->SendRecvBuf,
2104 NdefMap->SendLength,
2105 NdefMap->SendRecvBuf,
2106 NdefMap->SendRecvLength);
2107 return (status);
2108 }
2109
2110 /*!
2111 * \brief Check whether a particular Remote Device is NDEF compliant.
2112 * The function checks whether the peer device is NDEF compliant.
2113 */
2114
phFriNfc_Felica_ChkNdef(phFriNfc_NdefMap_t * NdefMap)2115 NFCSTATUS phFriNfc_Felica_ChkNdef( phFriNfc_NdefMap_t *NdefMap)
2116 {
2117 NFCSTATUS status = NFCSTATUS_PENDING;
2118 uint8_t sysCode[2];
2119
2120 /* set the system code for selecting the wild card*/
2121 sysCode[0] = 0x12;
2122 sysCode[1] = 0xFC;
2123
2124 status = phFriNfc_Felica_HPollCard( NdefMap,sysCode,PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP);
2125
2126 return (status);
2127
2128 }
2129 /*!
2130 * \brief Check whether a particular Remote Device is NDEF compliant.
2131 * selects the sysCode and then NFC Forum Reference Applications
2132 */
2133 #ifdef PH_HAL4_ENABLE
phFriNfc_Felica_HPollCard(phFriNfc_NdefMap_t * NdefMap,const uint8_t sysCode[],uint8_t state)2134 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
2135 const uint8_t sysCode[],
2136 uint8_t state)
2137 {
2138 NFCSTATUS status = NFCSTATUS_PENDING;
2139
2140 /*Format the Poll Packet for selecting the system code passed as parameter */
2141 NdefMap->SendRecvBuf[0] = 0x06;
2142 NdefMap->SendRecvBuf[1] = 0x00;
2143 NdefMap->SendRecvBuf[2] = sysCode[0];
2144 NdefMap->SendRecvBuf[3] = sysCode[1];
2145 NdefMap->SendRecvBuf[4] = 0x01;
2146 NdefMap->SendRecvBuf[5] = 0x03;
2147
2148 NdefMap->SendLength = 6;
2149
2150 /*set the completion routines for the felica card operations*/
2151 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2152 NdefMap->MapCompletionInfo.Context = NdefMap;
2153
2154 /*Set Ndef State*/
2155 NdefMap->State = state;
2156
2157 /* set the felica cmd */
2158 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2159
2160 /*set the additional informations for the data exchange*/
2161 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2162 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2163
2164 status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
2165 &NdefMap->MapCompletionInfo,
2166 NdefMap->psRemoteDevInfo,
2167 NdefMap->Cmd,
2168 &NdefMap->psDepAdditionalInfo,
2169 NdefMap->SendRecvBuf,
2170 NdefMap->SendLength,
2171 NdefMap->SendRecvBuf,
2172 NdefMap->SendRecvLength);
2173 return (status);
2174 }
2175 #endif
2176
2177
2178 #ifndef PH_HAL4_ENABLE
phFriNfc_Felica_HPollCard(phFriNfc_NdefMap_t * NdefMap,const uint8_t sysCode[],uint8_t state)2179 static NFCSTATUS phFriNfc_Felica_HPollCard( phFriNfc_NdefMap_t *NdefMap,
2180 const uint8_t sysCode[],
2181 uint8_t state)
2182 {
2183 NFCSTATUS status = NFCSTATUS_PENDING;
2184
2185 /*Format the Poll Packet for selecting the wild card "0xff 0xff as system code*/
2186 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[0] = 0x00;
2187 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[1] = sysCode[0];
2188 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[2] = sysCode[1];
2189 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[3] = 0x01;
2190 NdefMap->FelicaPollDetails.DevInputParam->FelicaPollPayload[4] = 0x03;
2191
2192 /* set the length to zero*/
2193 NdefMap->FelicaPollDetails.DevInputParam->GeneralByteLength =0x00;
2194
2195 NdefMap->NoOfDevices = PH_FRINFC_NDEFMAP_FELI_NUM_DEVICE_TO_DETECT;
2196
2197 /*set the completion routines for the felica card operations*/
2198 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_Felica_Process;
2199 NdefMap->MapCompletionInfo.Context = NdefMap;
2200
2201 /*Set Ndef State*/
2202 NdefMap->State = state;
2203
2204 /* Harsha: This is a special case for felica.
2205 Make a copy of the remote device information and send it for
2206 polling. Return the original remote device information to the
2207 caller. The user does not need the updated results of the poll
2208 that we are going to call now. This is only used for checking
2209 whether the felica card is NDEF compliant or not. */
2210 (void) memcpy( &NdefMap->FelicaPollDetails.psTempRemoteDevInfo,
2211 NdefMap->psRemoteDevInfo,
2212 sizeof(phHal_sRemoteDevInformation_t));
2213
2214 /* Reset the session opened flag */
2215 NdefMap->FelicaPollDetails.psTempRemoteDevInfo.SessionOpened = 0x00;
2216
2217 /*Call the Overlapped HAL POLL function */
2218 status = phFriNfc_OvrHal_Poll( NdefMap->LowerDevice,
2219 &NdefMap->MapCompletionInfo,
2220 NdefMap->OpModeType,
2221 &NdefMap->FelicaPollDetails.psTempRemoteDevInfo,
2222 &NdefMap->NoOfDevices,
2223 NdefMap->FelicaPollDetails.DevInputParam);
2224
2225 return (status);
2226 }
2227 #endif /* #ifndef PH_HAL4_ENABLE */
2228 /*!
2229 * \brief Checks validity of system code sent from the lower device, during poll operation.
2230 */
2231
phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t * NdefMap)2232 static NFCSTATUS phFriNfc_Felica_HUpdateManufIdDetails(const phFriNfc_NdefMap_t *NdefMap)
2233 {
2234 NFCSTATUS status = NFCSTATUS_PENDING;
2235
2236 /* Get the details from Poll Response packet */
2237 if (NdefMap->SendRecvLength >= 20)
2238 {
2239 (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2240 (uint8_t *)&NdefMap->SendRecvBuf[2], 8);
2241 (void)memcpy( (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm,
2242 (uint8_t *)&NdefMap->SendRecvBuf[10], 8);
2243 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] = NdefMap->SendRecvBuf[18];
2244 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] = NdefMap->SendRecvBuf[19];
2245 NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDmLength = 8;
2246
2247 /* copy the IDm and PMm in Manufacture Details Structure*/
2248 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufID),
2249 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2250 8);
2251 (void)memcpy( (uint8_t *)(NdefMap->FelicaManufDetails.ManufParameter),
2252 (uint8_t *)NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.PMm,
2253 8);
2254 if((NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[1] == 0x12)
2255 && (NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.SystemCode[0] == 0xFC))
2256 {
2257 status = PHNFCSTVAL(CID_NFC_NONE, NFCSTATUS_SUCCESS);
2258 }
2259 else
2260 {
2261 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2262 NFCSTATUS_NO_NDEF_SUPPORT);
2263 }
2264 }
2265 else
2266 {
2267 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2268 NFCSTATUS_NO_NDEF_SUPPORT);
2269 }
2270
2271 return (status);
2272 }
2273
2274
2275 /*!
2276 * \brief Completion Routine, Processing function, needed to avoid long blocking.
2277 * \note The lower (Overlapped HAL) layer must register a pointer to this function as a Completion
2278 * Routine in order to be able to notify the component that an I/O has finished and data are
2279 * ready to be processed.
2280 */
2281
phFriNfc_Felica_Process(void * Context,NFCSTATUS Status)2282 void phFriNfc_Felica_Process(void *Context,
2283 NFCSTATUS Status)
2284 {
2285 uint8_t CRFlag = FALSE;
2286 uint16_t RecvTxLen = 0,
2287 BytesToRecv = 0,
2288 Nbc = 0;
2289 uint32_t TotNoWrittenBytes = 0,
2290 NDEFLen=0;
2291
2292 /*Set the context to Map Module*/
2293 phFriNfc_NdefMap_t *NdefMap = (phFriNfc_NdefMap_t *)Context;
2294
2295 if ( Status == NFCSTATUS_SUCCESS )
2296 {
2297 switch (NdefMap->State)
2298 {
2299 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP:
2300
2301 /* check the ndef compliency with the system code reecived in the RemoteDevInfo*/
2302 Status = phFriNfc_Felica_HUpdateManufIdDetails(NdefMap);
2303
2304 if (Status == NFCSTATUS_SUCCESS)
2305 {
2306 /* Mantis ID : 645*/
2307 /* set the operation type to Check ndef type*/
2308 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP;
2309 Status = phFriNfc_Felica_HRdAttrInfo(NdefMap);
2310 /* handle the error in Transc function*/
2311 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2312 {
2313 CRFlag = TRUE;
2314 }
2315 }
2316 else
2317 {
2318 CRFlag = TRUE;
2319 }
2320 if ( CRFlag == TRUE )
2321 {
2322 /* call respective CR */
2323 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status);
2324
2325 }
2326 break;
2327
2328 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR:
2329 /* check for the status flag1 and status flag2for the successful read operation*/
2330 if ( NdefMap->SendRecvBuf[10] == 0x00)
2331 {
2332 /* check the Manuf Id in the receive buffer*/
2333 Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2334 if ( Status == NFCSTATUS_SUCCESS)
2335 {
2336 /* Update the Attribute Information in to the context structure*/
2337 Status = phFriNfc_Felica_HUpdateAttrInfo(NdefMap);
2338 if ( Status == NFCSTATUS_SUCCESS )
2339 {
2340 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2341 NdefMap->FelicaAttrInfo.LenBytes[1],
2342 NdefMap->FelicaAttrInfo.LenBytes[2],
2343 NDEFLen);
2344
2345 if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_ATTR_RD_OP )
2346 {
2347 /* Proceed With Write Functinality*/
2348 Status = phFriNfc_Felica_HChkAttrBlkForWrOp(NdefMap);
2349 /* handle the error in Transc function*/
2350 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2351 {
2352 /* call respective CR */
2353 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2354 }
2355 }
2356 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_RD_ATTR_RD_OP )
2357 {
2358 /* Proceed With Read Functinality*/
2359 Status = phFriNfc_Felica_HChkAttrBlkForRdOp(NdefMap,NDEFLen);
2360 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2361 {
2362 /* call respective CR */
2363 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2364 }
2365 }
2366 else if( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_CHK_NDEF_OP )
2367 {
2368
2369 Status = phFriNfc_MapTool_SetCardState( NdefMap,
2370 NDEFLen);
2371 /* check status value*/
2372 NdefMap->CardType = PH_FRINFC_NDEFMAP_FELICA_SMART_CARD;
2373 /*reset the buffer index*/
2374 NdefMap->ApduBuffIndex = 0;
2375 /* set the Next operation Flag to indicate need of reading attribute information*/
2376 NdefMap->Felica.OpFlag = PH_FRINFC_NDEFMAP_FELI_OP_NONE;
2377 /* call respective CR */
2378 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_CHK_NDEF,Status);
2379 }
2380 else if ( NdefMap->Felica.OpFlag == PH_FRINFC_NDEFMAP_FELI_WR_EMPTY_MSG_OP )
2381 {
2382 /* Proceed With Write Functinality*/
2383 Status = phFriNfc_Felica_HWrEmptyMsg(NdefMap);
2384 /* handle the error in Transc function*/
2385 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2386 {
2387 /* call respective CR */
2388 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_ERASE_NDEF,Status);
2389 }
2390 }
2391 else
2392 {
2393
2394 /* invalid operation occured*/
2395 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2396 NFCSTATUS_INVALID_DEVICE_REQUEST);
2397 CRFlag =TRUE ;
2398 }
2399 }
2400 else
2401 {
2402 CRFlag =TRUE ;
2403 }
2404 }
2405 else
2406 {
2407 CRFlag =TRUE ;
2408 }
2409 }
2410 else
2411 {
2412 CRFlag =TRUE;
2413 /*handle the Error case*/
2414 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2415 NFCSTATUS_READ_FAILED);
2416 }
2417 if ( CRFlag == TRUE )
2418 {
2419 /* call respective CR */
2420 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2421 }
2422 break;
2423
2424 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN:
2425 /* chk the status flags 1 and 2*/
2426 if ( NdefMap->SendRecvBuf[10] == 0x00 )
2427 {
2428 /* Update Data Call*/
2429 Status =phFriNfc_Felica_HUpdateData(NdefMap);
2430 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2431 {
2432 /* call respective CR */
2433 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2434 }
2435 }
2436 else
2437 {
2438 /*handle the Error case*/
2439 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2440 NFCSTATUS_WRITE_FAILED);
2441 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2442
2443 }
2444 break;
2445 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END:
2446
2447 /* chk the status flags 1 and 2*/
2448 if ( NdefMap->SendRecvBuf[10] == 0x00)
2449 {
2450 /* Entire Write Operation is complete*/
2451 Status = PHNFCSTVAL(CID_NFC_NONE,\
2452 NFCSTATUS_SUCCESS);
2453 }
2454 else
2455 {
2456 /*handle the Error case*/
2457 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2458 NFCSTATUS_WRITE_FAILED);
2459 }
2460 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2461 break;
2462
2463 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_EMPTY_MSG :
2464
2465 /* chk the status flags 1 and 2*/
2466 if ( NdefMap->SendRecvBuf[10] == 0x00)
2467 {
2468 /* Entire Write Operation is complete*/
2469 Status = PHNFCSTVAL(CID_NFC_NONE,\
2470 NFCSTATUS_SUCCESS);
2471 }
2472 else
2473 {
2474 /*handle the Error case*/
2475 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2476 NFCSTATUS_WRITE_FAILED);
2477 }
2478 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2479 break;
2480
2481 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK :
2482 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )
2483 {
2484 /* chk the status flags 1 and 2*/
2485 if ( NdefMap->SendRecvBuf[10] == 0x00 )
2486 {
2487 /* This is used when we have bytes less than 16 bytes*/
2488 if ( NdefMap->Felica.IntermediateWrFlag == TRUE )
2489 {
2490 /* after Successful write copy the last writtened bytes back to the
2491 internal buffer*/
2492 (void)memcpy( (&(NdefMap->Felica.Wr_RemainedBytesBuff[NdefMap->Felica.Wr_BytesRemained])),
2493 NdefMap->ApduBuffer,
2494 NdefMap->NumOfBytesWritten);
2495
2496 NdefMap->Felica.Wr_BytesRemained +=
2497 (uint8_t)( NdefMap->NumOfBytesWritten);
2498
2499 /* Increment the Send Buffer index */
2500 NdefMap->ApduBuffIndex +=
2501 NdefMap->NumOfBytesWritten;
2502
2503 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2504 NdefMap->Felica.IntermediateWrFlag = FALSE;
2505 /* Call Update Data()*/
2506 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2507 }
2508 else
2509 {
2510 /* update the index and bytes writtened*/
2511 NdefMap->ApduBuffIndex += NdefMap->NumOfBytesWritten;
2512 *NdefMap->WrNdefPacketLength = NdefMap->ApduBuffIndex;
2513 if ( NdefMap->Felica.EofCardReachedFlag )
2514 {
2515 if ( NdefMap->Felica.CurBlockNo < NdefMap->FelicaAttrInfo.Nmaxb)
2516 {
2517 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2518 }
2519 if (( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2520 ( NdefMap->ApduBuffIndex == (NdefMap->FelicaAttrInfo.Nmaxb*16)))
2521 {
2522 NdefMap->Felica.EofCardReachedFlag = FELICA_RD_WR_EOF_CARD_REACHED ;
2523 /*0 represents the write ended*/
2524 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2525 if( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2526 {
2527 /* call respective CR */
2528 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2529 }
2530 }
2531 else
2532 {
2533 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES(NdefMap->FelicaAttrInfo.LenBytes[0],
2534 NdefMap->FelicaAttrInfo.LenBytes[1],
2535 NdefMap->FelicaAttrInfo.LenBytes[2],
2536 TotNoWrittenBytes);
2537 if ( ( NdefMap->Felica.CurBlockNo == NdefMap->FelicaAttrInfo.Nmaxb) &&
2538 ((TotNoWrittenBytes + NdefMap->ApduBuffIndex) == (uint32_t)(NdefMap->FelicaAttrInfo.Nmaxb*16)))
2539 {
2540 NdefMap->Felica.EofCardReachedFlag =FELICA_RD_WR_EOF_CARD_REACHED;
2541 /*0 represents the write ended*/
2542 Status = phFriNfc_Felica_HUpdateAttrBlkForWrOp(NdefMap,FELICA_WRITE_ENDED);
2543 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2544 {
2545 /* call respective CR */
2546 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2547 }
2548 }
2549 else
2550 {
2551 /* Call Update Data()*/
2552 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2553 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2554 {
2555 /* call respective CR */
2556 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2557 }
2558 }
2559 }
2560 }/*if ( NdefMap->Felica.EofCardReachedFlag )*/
2561 else
2562 {
2563 NdefMap->Felica.CurBlockNo += NdefMap->Felica.NoBlocksWritten;
2564 /* Call Update Data()*/
2565 Status = phFriNfc_Felica_HUpdateData(NdefMap);
2566 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2567 {
2568 /* call respective CR */
2569 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2570 }
2571 }
2572 }
2573 }/*if ( NdefMap->SendRecvBuf[10] == 0x00 )*/
2574 else
2575 {
2576 /*handle the Error case*/
2577 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2578 NFCSTATUS_WRITE_FAILED);
2579 CRFlag = TRUE;
2580
2581 }
2582 }/*if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_WR_RESP_BYTE )*/
2583 else
2584 {
2585 /*return Error "Invalid Write Response Code"*/
2586 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2587 NFCSTATUS_WRITE_FAILED);
2588 CRFlag = TRUE;
2589
2590 }
2591 if ( CRFlag == TRUE )
2592 {
2593 /* Reset following parameters*/
2594 NdefMap->ApduBuffIndex=0;
2595 NdefMap->Felica.Wr_BytesRemained = 0;
2596 NdefMap->ApduBufferSize = 0;
2597 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_WR_NDEF,Status);
2598 }
2599
2600 break;
2601
2602 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2603
2604 /* check the Manuf Id in the receive buffer*/
2605 Status = phFriNfc_Felica_HCheckManufId(NdefMap);
2606 if ( Status == NFCSTATUS_SUCCESS )
2607 {
2608 if(NdefMap->SendRecvBuf[1] == PH_NFCFRI_NDEFMAP_FELI_RD_RESP_BYTE )
2609 {
2610 /* calculate the Nmaxb*/
2611 Nbc = phFriNfc_Felica_HGetMaximumBlksToRead(NdefMap,PH_NFCFRI_NDEFMAP_FELI_NBC);
2612 /*get Receive length from the card for corss verifications*/
2613 RecvTxLen= phFriNfc_Felica_HSetTrxLen(NdefMap,Nbc);
2614 BytesToRecv = NdefMap->SendRecvBuf[12]*16;
2615
2616 /* chk the status flags 1 */
2617 if ( NdefMap->SendRecvBuf[10] == 0x00)
2618 {
2619 if ( RecvTxLen == BytesToRecv)
2620 {
2621 NdefMap->Felica.CurBlockNo += (uint8_t)(RecvTxLen/16);
2622 phFriNfc_Felica_HAfterRead_CopyDataToBuff(NdefMap);
2623 Status = phFriNfc_Felica_HReadData(NdefMap,PH_FRINFC_NDEFMAP_SEEK_CUR);
2624 /* handle the error in Transc function*/
2625 if ( (Status & PHNFCSTBLOWER) != (NFCSTATUS_PENDING & PHNFCSTBLOWER))
2626 {
2627 CRFlag =TRUE;
2628 }
2629 }
2630 else
2631 {
2632 CRFlag =TRUE;
2633 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2634 NFCSTATUS_INVALID_RECEIVE_LENGTH);
2635 /*set the buffer index back to zero*/
2636 NdefMap->ApduBuffIndex = 0;
2637 NdefMap->Felica.Rd_NoBytesToCopy = 0;
2638 }
2639 }
2640 else
2641 {
2642 NdefMap->ApduBuffIndex=0;
2643 /*handle the Error case*/
2644 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,\
2645 NFCSTATUS_READ_FAILED);
2646 CRFlag =TRUE;
2647 }
2648 }
2649 else
2650 {
2651 CRFlag =TRUE;
2652 NdefMap->ApduBuffIndex=0;
2653 /*return Error "Invalid Read Response Code"*/
2654 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2655 NFCSTATUS_READ_FAILED);
2656 }
2657 }
2658 else
2659 {
2660 CRFlag =TRUE;
2661 }
2662 if ( CRFlag ==TRUE )
2663 {
2664 /* call respective CR */
2665 phFriNfc_Felica_HCrHandler(NdefMap,PH_FRINFC_NDEFMAP_CR_RD_NDEF,Status);
2666 }
2667 break;
2668
2669 default:
2670 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2671 NFCSTATUS_INVALID_DEVICE_REQUEST);
2672 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status);
2673 break;
2674
2675
2676 }
2677 }
2678 else
2679 {
2680 /* Call CR for unknown Error's*/
2681 switch ( NdefMap->State)
2682 {
2683 case PH_FRINFC_NDEFMAP_FELI_STATE_CHK_NDEF :
2684 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_WILD_CARD :
2685 case PH_NFCFRI_NDEFMAP_FELI_STATE_SELECT_NDEF_APP :
2686 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR :
2687 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_CHK_NDEF,
2688 Status);
2689 break;
2690 case PH_NFCFRI_NDEFMAP_FELI_STATE_WR_BLOCK :
2691 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_BEGIN :
2692 case PH_NFCFRI_NDEFMAP_FELI_STATE_ATTR_BLK_WR_END :
2693 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_WR_NDEF,
2694 Status);
2695 break;
2696 case PH_NFCFRI_NDEFMAP_FELI_STATE_RD_BLOCK :
2697 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_RD_NDEF,
2698 Status);
2699 break;
2700 default :
2701 /*set the invalid state*/
2702 Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_DEVICE_REQUEST);
2703 phFriNfc_Felica_HCrHandler(NdefMap, PH_FRINFC_NDEFMAP_CR_INVALID_OPE, Status);
2704 break;
2705 }
2706 }
2707
2708 }
2709
2710 /*!
2711 * \brief Prepares Cmd Pkt for reading attribute Blk information.
2712 */
phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t * NdefMap)2713 static NFCSTATUS phFriNfc_Felica_HRdAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2714 {
2715
2716 NFCSTATUS status = NFCSTATUS_PENDING;
2717 uint8_t BufIndex = 0;
2718
2719 /* Set the Felica Cmd*/
2720 #ifdef PH_HAL4_ENABLE
2721 NdefMap->Cmd.FelCmd = phHal_eFelica_Raw;
2722 #else
2723 NdefMap->Cmd.FelCmd = phHal_eFelicaCmdListFelicaCmd;
2724 #endif /* #ifdef PH_HAL4_ENABLE */
2725
2726 /*set the additional informations for the data exchange*/
2727 NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
2728 NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
2729
2730 /* 1st byte represents the length of the cmd packet*/
2731 NdefMap->SendRecvBuf[BufIndex] = 0x00;
2732 BufIndex++;
2733
2734 /* Read/check command code*/
2735 NdefMap->SendRecvBuf[BufIndex] = 0x06;
2736 BufIndex++;
2737
2738 /* IDm - Manufacturer Id : 8bytes*/
2739 #ifdef PH_HAL4_ENABLE
2740 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2741 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.Felica_Info.IDm,
2742 8);
2743 #else
2744 (void)memcpy((&(NdefMap->SendRecvBuf[BufIndex])),
2745 (void * )&NdefMap->psRemoteDevInfo->RemoteDevInfo.CardInfo212_424.Startup212_424.NFCID2t,
2746 8);
2747
2748 #endif /* #ifdef PH_HAL4_ENABLE */
2749
2750 BufIndex+=8;
2751
2752 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Services (n=1 ==> 0x80)*/
2753 BufIndex++;
2754
2755 NdefMap->SendRecvBuf[BufIndex] = 0x0B; /* Service Code List*/
2756 BufIndex++;
2757
2758 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* Service Code List*/
2759 BufIndex++;
2760
2761 NdefMap->SendRecvBuf[BufIndex] = 0x01; /* Number of Blocks to read)*/
2762 BufIndex++;
2763
2764 NdefMap->SendRecvBuf[BufIndex] = 0x80; /* 1st Block Element : byte 1*/
2765 BufIndex++;
2766
2767 NdefMap->SendRecvBuf[BufIndex] = 0x00; /* 1st Block Element : byte 2, block 1*/
2768 BufIndex++;
2769
2770 NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_PKT_LEN_INDEX] = BufIndex;
2771
2772 *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
2773
2774 /* Update the Send Len*/
2775 NdefMap->SendLength = BufIndex;
2776
2777 /* Change the state to PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR */
2778 NdefMap->State = PH_NFCFRI_NDEFMAP_FELI_STATE_RD_ATTR;
2779
2780 /*set the completion routines for the desfire card operations*/
2781 NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_NdefMap_Process;
2782 NdefMap->MapCompletionInfo.Context = NdefMap;
2783
2784 /*Call the Overlapped HAL Transceive function */
2785 status = phFriNfc_OvrHal_Transceive( NdefMap->LowerDevice,
2786 &NdefMap->MapCompletionInfo,
2787 NdefMap->psRemoteDevInfo,
2788 NdefMap->Cmd,
2789 &NdefMap->psDepAdditionalInfo,
2790 NdefMap->SendRecvBuf,
2791 NdefMap->SendLength,
2792 NdefMap->SendRecvBuf,
2793 NdefMap->SendRecvLength);
2794 return (status);
2795
2796 }
2797
2798 /*!
2799 * \brief Validated manufacturer Details, during the read/write operations.
2800 */
2801
phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t * NdefMap)2802 static NFCSTATUS phFriNfc_Felica_HCheckManufId(const phFriNfc_NdefMap_t *NdefMap)
2803 {
2804 NFCSTATUS status = NFCSTATUS_PENDING;
2805
2806 uint8_t result = 0;
2807
2808 /* check the stored manufacture id with the received manufacture id*/
2809 result = (uint8_t)(phFriNfc_Felica_MemCompare( (void *)(&(NdefMap->SendRecvBuf[2])),
2810 (void *)NdefMap->FelicaManufDetails.ManufID,
2811 8));
2812
2813 if ( result != 0)
2814 {
2815 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_REMOTE_DEVICE);
2816
2817 }
2818 else
2819 {
2820 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
2821
2822 }
2823 return (status);
2824 }
2825
phFriNfc_Felica_HCalCheckSum(const uint8_t * TempBuffer,uint8_t StartIndex,uint8_t EndIndex,uint16_t RecvChkSum)2826 static NFCSTATUS phFriNfc_Felica_HCalCheckSum(const uint8_t *TempBuffer,
2827 uint8_t StartIndex,
2828 uint8_t EndIndex,
2829 uint16_t RecvChkSum)
2830 {
2831 NFCSTATUS Result = NFCSTATUS_SUCCESS;
2832 uint16_t CheckSum=0,
2833 BufIndex=0;
2834
2835 for(BufIndex = StartIndex;BufIndex <=EndIndex;BufIndex++)
2836 {
2837 CheckSum += TempBuffer[BufIndex];
2838 }
2839 if( RecvChkSum != CheckSum )
2840 {
2841 Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
2842 NFCSTATUS_INVALID_FORMAT);
2843 }
2844 return (Result);
2845 }
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857 /*!
2858 * \brief On successful read attribute blk information, this function validates and stores the
2859 * Attribute informations in to the context.
2860 */
phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t * NdefMap)2861 static NFCSTATUS phFriNfc_Felica_HUpdateAttrInfo(phFriNfc_NdefMap_t *NdefMap)
2862 {
2863 NFCSTATUS status = NFCSTATUS_PENDING;
2864 uint8_t CRFlag = FALSE,
2865 Nmaxb1, Nmaxb2 = 0,
2866 ChkSum1 = 0, ChkSum2=0;
2867
2868 uint16_t Nmaxblk = 0,
2869 RecvChkSum=0,
2870 NdefBlk = 0;
2871 uint32_t DataLen =0;
2872
2873
2874 /* Validate T3VNo and NFCDevVNo */
2875 status = phFriNfc_MapTool_ChkSpcVer(NdefMap,
2876 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX);
2877 if ( status != NFCSTATUS_SUCCESS )
2878 {
2879 CRFlag = TRUE;
2880 }
2881 else
2882 {
2883 /* get the Nmaxb from the receive buffer*/
2884 Nmaxb1 = NdefMap->SendRecvBuf[16];
2885 Nmaxb2 = NdefMap->SendRecvBuf[17];
2886
2887 Nmaxblk = (((uint16_t)Nmaxb1 << 8) | (Nmaxb2 & 0x00ff));
2888
2889 if ( Nmaxblk != 0 )
2890 {
2891 /* check the Nbr against the Nmaxb*/
2892 if ( NdefMap->SendRecvBuf[14] > Nmaxblk )
2893 {
2894 CRFlag = TRUE;
2895 }
2896 else
2897 {
2898 /*check Nbw > Nmaxb*/
2899 /*check the write flag validity*/
2900 /*check for the RFU bytes validity*/
2901 if ( (NdefMap->SendRecvBuf[15] > Nmaxblk) ||
2902 ((NdefMap->SendRecvBuf[22] != 0x00) && (NdefMap->SendRecvBuf[22] !=0x0f ))||
2903 ( (NdefMap->SendRecvBuf[23] != 0x00) && (NdefMap->SendRecvBuf[23] !=0x01 ))||
2904 ( NdefMap->SendRecvBuf[18] != 0x00) ||
2905 ( NdefMap->SendRecvBuf[19] != 0x00) ||
2906 ( NdefMap->SendRecvBuf[20] != 0x00) ||
2907 ( NdefMap->SendRecvBuf[21] != 0x00))
2908
2909 {
2910 CRFlag = TRUE;
2911 }
2912 else
2913 {
2914 /* check the validity of the actual ndef data len*/
2915 PH_NFCFRI_NDEFMAP_FELI_CAL_LEN_BYTES( NdefMap->SendRecvBuf[24],
2916 NdefMap->SendRecvBuf[25],
2917 NdefMap->SendRecvBuf[26],
2918 DataLen);
2919
2920
2921 /* Calculate Nbc*/
2922 NdefBlk = (uint16_t )((( DataLen % 16) == 0 ) ? (DataLen >> 4) : ((DataLen >> 4) +1));
2923
2924 /* check Nbc against Nmaxb*/
2925 if ((NdefBlk > Nmaxblk))
2926 {
2927 CRFlag = TRUE;
2928 }
2929 else
2930 {
2931 /*Store the attribute information in phFriNfc_Felica_AttrInfo*/
2932 NdefMap->FelicaAttrInfo.Version = NdefMap->SendRecvBuf[PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX];
2933 NdefMap->FelicaAttrInfo.Nbr = NdefMap->SendRecvBuf[14];
2934 NdefMap->FelicaAttrInfo.Nbw = NdefMap->SendRecvBuf[15];
2935
2936 NdefMap->FelicaAttrInfo.Nmaxb = Nmaxblk;
2937
2938 NdefMap->FelicaAttrInfo.WriteFlag = NdefMap->SendRecvBuf[22];
2939 NdefMap->FelicaAttrInfo.RdWrFlag = NdefMap->SendRecvBuf[23];
2940
2941 /* Get CheckSum*/
2942 ChkSum1 = NdefMap->SendRecvBuf[27];
2943 ChkSum2 = NdefMap->SendRecvBuf[28];
2944
2945 RecvChkSum = (((uint16_t)ChkSum1 << 8) | (ChkSum2 & 0x00ff));
2946
2947 /* Check the check sum validity?*/
2948 status = phFriNfc_Felica_HCalCheckSum(NdefMap->SendRecvBuf,
2949 PH_NFCFRI_NDEFMAP_FELI_VERSION_INDEX,
2950 26,
2951 RecvChkSum);
2952 if ( status != NFCSTATUS_SUCCESS )
2953 {
2954 CRFlag = TRUE;
2955 }
2956 else
2957 {
2958 /*check RW Flag Access Rights*/
2959 /* set to read only cannot write*/
2960 if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x00 )
2961 {
2962 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_ONLY;
2963 }
2964 else if ( NdefMap->FelicaAttrInfo.RdWrFlag == 0x01 ) // additional check for R/W access
2965 {
2966 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_READ_WRITE;
2967 }
2968 else // otherwise invalid
2969 {
2970 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2971 }
2972
2973 NdefMap->FelicaAttrInfo.LenBytes[0] = NdefMap->SendRecvBuf[24];
2974 NdefMap->FelicaAttrInfo.LenBytes[1] = NdefMap->SendRecvBuf[25];
2975 NdefMap->FelicaAttrInfo.LenBytes[2] = NdefMap->SendRecvBuf[26];
2976 status = PHNFCSTVAL(CID_NFC_NONE,NFCSTATUS_SUCCESS);
2977 }
2978 }
2979 }
2980 }
2981 }
2982 else
2983 {
2984 CRFlag = TRUE;
2985 }
2986 }
2987 if ( (status == NFCSTATUS_INVALID_FORMAT ) && (CRFlag == TRUE ))
2988 {
2989 NdefMap->CardState = PH_NDEFMAP_CARD_STATE_INVALID;
2990 }
2991 if ( CRFlag == TRUE )
2992 {
2993 /*Return Status Error � Invalid Format�*/
2994 status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,NFCSTATUS_INVALID_FORMAT);
2995 }
2996
2997 return (status);
2998 }
2999
3000 /*!
3001 * \brief this shall notify the integration software with respective
3002 * success/error status along with the completion routines.
3003 */
phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t * NdefMap,uint8_t CrIndex,NFCSTATUS Status)3004 static void phFriNfc_Felica_HCrHandler(phFriNfc_NdefMap_t *NdefMap,
3005 uint8_t CrIndex,
3006 NFCSTATUS Status)
3007 {
3008 /* set the state back to the Reset_Init state*/
3009 NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RESET_INIT;
3010
3011 /* set the completion routine*/
3012 NdefMap->CompletionRoutine[CrIndex].
3013 CompletionRoutine(NdefMap->CompletionRoutine->Context, Status);
3014 }
3015
3016 /*!
3017 * \brief this shall initialise the internal buffer data to zero.
3018 */
phFriNfc_Felica_HInitInternalBuf(uint8_t * Buffer)3019 static void phFriNfc_Felica_HInitInternalBuf(uint8_t *Buffer)
3020 {
3021 uint8_t index=0;
3022
3023 for( index = 0; index< 16 ; index++)
3024 {
3025 Buffer[index] = 0;
3026 }
3027 }
3028
phFriNfc_Felica_MemCompare(void * s1,void * s2,unsigned int n)3029 static int phFriNfc_Felica_MemCompare ( void *s1, void *s2, unsigned int n )
3030 {
3031 int8_t diff = 0;
3032 int8_t *char_1 =(int8_t *)s1;
3033 int8_t *char_2 =(int8_t *)s2;
3034 if(NULL == s1 || NULL == s2)
3035 {
3036 PHDBG_CRITICAL_ERROR("NULL pointer passed to memcompare");
3037 }
3038 else
3039 {
3040 for(;((n>0)&&(diff==0));n--,char_1++,char_2++)
3041 {
3042 diff = *char_1 - *char_2;
3043 }
3044 }
3045 return (int)diff;
3046 }
3047
3048
3049 #ifdef UNIT_TEST
3050 #include <phUnitTestNfc_Felica_static.c>
3051 #endif
3052
3053 #endif /* PH_FRINFC_MAP_FELICA_DISABLED */
3054