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 phLlcNfc_Frame.c
19 * \brief To append the I or S or U frames (LLC header).
20 *
21 * Project: NFC-FRI-1.1
22 *
23 * $Date: Tue Jun 1 14:41:26 2010 $
24 * $Author: ing02260 $
25 * $Revision: 1.88 $
26 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
27 *
28 */
29
30 /*************************** Includes *******************************/
31 #include <phNfcTypes.h>
32 #include <phNfcStatus.h>
33 #include <phOsalNfc.h>
34 #include <phOsalNfc_Timer.h>
35 #include <phNfcInterface.h>
36 #include <phLlcNfc_DataTypes.h>
37 #include <phLlcNfc_Frame.h>
38 #include <phLlcNfc_Interface.h>
39 #include <phLlcNfc_Timer.h>
40 #ifdef ANDROID
41 #include <string.h>
42 #endif
43
44 /*********************** End of includes ****************************/
45
46 /***************************** Macros *******************************/
47
48 /************************ End of macros *****************************/
49
50 /***************************** Global variables *******************************/
51
52 #ifdef LLC_RELEASE_FLAG
53 extern uint8_t g_release_flag;
54 #endif /* #ifdef LLC_RELEASE_FLAG */
55 /************************ End of global variables *****************************/
56
57 /*********************** Local functions ****************************/
58 static
59 void
60 phLlcNfc_H_UpdateCrc(
61 uint8_t crcByte,
62 uint16_t *pCrc
63 );
64
65 /**
66 * \ingroup grp_hal_nfc_llc_helper
67 *
68 * \brief LLC helper functions <b>process the received U frame</b> function
69 *
70 * \copydoc page_reg This function is to process the U frame received from
71 * the device
72 *
73 * \param[in] psLlcCtxt Llc main structure information
74 * \param[in] llcPacket LLC packet information, inlcuding length information
75 *
76 * \retval NFCSTATUS_SUCCESS Operation successful.
77 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
78 *
79 */
80 static
81 NFCSTATUS
82 phLlcNfc_H_ProcessUFrame (
83 phLlcNfc_Context_t *psLlcCtxt
84 );
85
86 /**
87 * \ingroup grp_hal_nfc_llc_helper
88 *
89 * \brief LLC helper functions <b>process the received S frame</b> function
90 *
91 * \copydoc page_reg This function is to process the S frame received from
92 * the device
93 *
94 * \param[in] psLlcCtxt Llc main structure information
95 *
96 * \retval NFCSTATUS_SUCCESS Operation successful.
97 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
98 *
99 */
100 static
101 void
102 phLlcNfc_H_ProcessSFrame (
103 phLlcNfc_Context_t *psLlcCtxt
104 );
105
106 /**
107 * \ingroup grp_hal_nfc_llc_helper
108 *
109 * \brief LLC helper functions <b>Update I frame list</b> function
110 *
111 * \copydoc page_reg This function checks the nr value with the stored I frames
112 * and deletes the nodes which has been acknowledged.
113 *
114 * \param[in/out] psFrameInfo Frame structure information
115 * \param[in/out] psListInfo List information
116 *
117 * \retval number of deleted frames
118 *
119 */
120 static
121 uint8_t
122 phLlcNfc_H_UpdateIFrameList(
123 phLlcNfc_Frame_t *psFrameInfo,
124 phLlcNfc_StoreIFrame_t *psListInfo
125 );
126
127 /**
128 * \ingroup grp_hal_nfc_llc_helper
129 *
130 * \brief LLC helper functions \b Delete list function
131 *
132 * \copydoc page_reg Delete the front node from the list
133 *
134 * \param[in] psFrameInfo Frame structure information
135 *
136 * \retval NFCSTATUS_SUCCESS Operation successful.
137 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
138 *
139 */
140 static
141 void
142 phLlcNfc_H_DeleteIFrame (
143 phLlcNfc_StoreIFrame_t *psList
144 );
145
146 /**
147 * \ingroup grp_hal_nfc_llc_helper
148 *
149 * \brief LLC helper functions <b>Get the LLC header</b> function
150 *
151 * \copydoc page_reg This function checks for the correctness fo the llc header
152 *
153 * \param[in] llcHeader The byte which gives the header information
154 *
155 * \retval phLlcNfc_eU_frame U frame type.
156 * \retval phLlcNfc_eI_frame I frame type.
157 * \retval phLlcNfc_eS_frame S frame type.
158 * \retval phLlcNfc_eErr_frame Error type
159 *
160 */
161 static
162 phLlcNfc_FrameType_t
163 phLlcNfc_H_ChkGetLlcFrameType (
164 uint8_t llcHeader
165 );
166
167 /**
168 * \ingroup grp_hal_nfc_llc_helper
169 *
170 * \brief LLC helper functions \b Peek the data function
171 *
172 * \copydoc page_reg Get the packet information from the front node from the list
173 *
174 * \param[in] psListInfo The List information
175 * \param[in] packetinfo The packet information from the front node of the list
176 *
177 * \retval NFCSTATUS_SUCCESS Operation successful.
178 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
179 *
180 */
181 static
182 NFCSTATUS
183 phLlcNfc_H_IFrameList_Peek (
184 phLlcNfc_StoreIFrame_t *psList,
185 phLlcNfc_LlcPacket_t **psPacketinfo,
186 uint8_t position
187 );
188
189 /**
190 * \ingroup grp_hal_nfc_llc_helper
191 *
192 * \brief LLC helper functions <b>Update U frame information</b> function
193 *
194 * \copydoc page_reg This function updates the U frame information in the
195 * phLlcNfc_sFrame_t structure
196 *
197 * \param[in/out] psFrameInfo Frame information structure
198 * \param[in] llcPayload Llc payload information
199 *
200 * \retval NFCSTATUS_SUCCESS Operation successful.
201 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
202 *
203 */
204 static
205 NFCSTATUS
206 phLlcNfc_H_Update_ReceivedRSETInfo (
207 phLlcNfc_Frame_t *psFrameInfo,
208 phLlcNfc_Payload_t llcInfo
209 );
210
211 /**
212 * \ingroup grp_hal_nfc_llc_helper
213 *
214 * \brief LLC Reset frame information function
215 *
216 * \copydoc page_reg resets ns and nr value, when ack for U frame is received
217 *
218 * \param[in, out] psLlcCtxt Llc main structure information
219 *
220 * \retval NFCSTATUS_SUCCESS Operation successful.
221 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
222 *
223 */
224 static
225 void
226 phLlcNfc_H_ResetFrameInfo (
227 phLlcNfc_Context_t *psLlcCtxt
228 );
229
230 /**
231 * \ingroup grp_hal_nfc_llc_helper
232 *
233 * \brief LLC Reset frame sending function
234 *
235 * \copydoc page_reg Send URSET frame to PN544
236 *
237 * \param[in, out] psLlcCtxt Llc main structure information
238 *
239 * \retval NFCSTATUS_SUCCESS Operation successful.
240 * \retval NFCSTATUS_BUSY Write is pended, so wait till it completes.
241 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
242 *
243 */
244 NFCSTATUS
245 phLlcNfc_H_SendRSETFrame (
246 phLlcNfc_Context_t *psLlcCtxt
247 );
248
249 /**
250 * \ingroup grp_hal_nfc_llc_helper
251 *
252 * \brief LLC helper functions <b>process the received I frame</b> function
253 *
254 * \copydoc page_reg This function is to process the I frame received from
255 * the device
256 *
257 * \param[in] psLlcCtxt Llc main structure information
258 *
259 * \retval NFCSTATUS_SUCCESS Operation successful.
260 * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
261 *
262 */
263 void
264 phLlcNfc_H_ProcessIFrame (
265 phLlcNfc_Context_t *psLlcCtxt
266 );
267
268 /******************** End of Local functions ************************/
269
270 /********************** Global variables ****************************/
271
272 /******************** End of Global Variables ***********************/
273
phLlcNfc_H_Frame_Init(phLlcNfc_Context_t * psLlcCtxt)274 void phLlcNfc_H_Frame_Init (
275 phLlcNfc_Context_t *psLlcCtxt
276 )
277 {
278
279 if (NULL != psLlcCtxt)
280 {
281 /* Set all the other values to 0 */
282 (void)memset (&psLlcCtxt->s_frameinfo.s_llcpacket, 0,
283 sizeof(phLlcNfc_LlcPacket_t));
284
285 psLlcCtxt->s_frameinfo.window_size =
286 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE;
287 /* Initialise the window size, N(S) and N(R) */
288 #ifdef PIGGY_BACK
289 psLlcCtxt->s_frameinfo.s_recv_store.winsize_cnt = 0;
290 #endif
291 psLlcCtxt->s_frameinfo.s_send_store.winsize_cnt = 0;
292 psLlcCtxt->s_frameinfo.n_s = 0;
293 psLlcCtxt->s_frameinfo.n_r = 0;
294 psLlcCtxt->s_frameinfo.rejected_ns = DEFAULT_PACKET_INPUT;
295 }
296 }
297
298 void
phLlcNfc_H_Frame_DeInit(phLlcNfc_Frame_t * psFrameInfo)299 phLlcNfc_H_Frame_DeInit (
300 phLlcNfc_Frame_t *psFrameInfo
301 )
302 {
303 if (NULL != psFrameInfo)
304 {
305 /* Empty the frame information */
306 (void)memset(&psFrameInfo->s_llcpacket, 0,
307 sizeof(phLlcNfc_LlcPacket_t));
308 }
309 }
310
311 NFCSTATUS
phLlcNfc_H_CreateUFramePayload(phLlcNfc_Context_t * psLlcCtxt,phLlcNfc_LlcPacket_t * psLlcPacket,uint8_t * pLlcPacketLength,phLlcNfc_LlcCmd_t cmdType)312 phLlcNfc_H_CreateUFramePayload (
313 phLlcNfc_Context_t *psLlcCtxt,
314 phLlcNfc_LlcPacket_t *psLlcPacket,
315 uint8_t *pLlcPacketLength,
316 phLlcNfc_LlcCmd_t cmdType
317 )
318 {
319 /*
320 U frame packet (RSET)
321 Byte 0 = Length (4 to 6 bytes)
322 Byte 1 = Header
323 Byte 2 = window size (2 >= window size <= 4)
324 Byte 3 = capabilities (SREJ option enable/disable) (optional)
325 Byte 4 = Baud rate (optional)
326 Byte 5 = CRC1
327 Byte 6 = CRC2
328 */
329 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC,
330 NFCSTATUS_INVALID_PARAMETER);
331 phLlcNfc_Buffer_t *ps_llc_buf = NULL;
332 uint8_t index = 0;
333
334 if ((NULL != psLlcCtxt) && (NULL != psLlcPacket)
335 && (NULL != pLlcPacketLength) &&
336 ((phLlcNfc_e_rset == cmdType) || (phLlcNfc_e_ua == cmdType)))
337 {
338 result = NFCSTATUS_SUCCESS;
339 ps_llc_buf = &(psLlcPacket->s_llcbuf);
340 /* Get the header information */
341 ps_llc_buf->sllcpayload.llcheader =
342 (uint8_t)PH_LLCNFC_U_HEADER_INIT;
343 if (phLlcNfc_e_rset == cmdType)
344 {
345 /* RSET command */
346 ps_llc_buf->sllcpayload.llcheader =
347 (uint8_t)SET_BITS8(
348 ps_llc_buf->sllcpayload.llcheader,
349 PH_LLCNFC_U_FRAME_START_POS,
350 PH_LLCNFC_U_FRAME_NO_OF_POS,
351 (uint8_t)phLlcNfc_e_rset);
352 /* Default window size */
353 ps_llc_buf->sllcpayload.llcpayload[index] =
354 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE;
355 index++;
356 /* Endpoint capabilities, SREJ not supported */
357 ps_llc_buf->sllcpayload.llcpayload[index] =
358 PH_LLCNFC_SREJ_BYTE_VALUE;
359 index++;
360 #ifdef ENABLE_BAUDRATE
361 /* baud rate 0x00 = 9600, 0x05 = 115200 */
362 ps_llc_buf->sllcpayload.llcpayload[index] =
363 (uint8_t)phLlcNfc_e_115200;
364 index++;
365 #endif /* #ifdef ENABLE_BAUDRATE */
366
367 }
368 else
369 {
370 /* UA frame */
371 ps_llc_buf->sllcpayload.llcheader = (uint8_t)
372 SET_BITS8(ps_llc_buf->sllcpayload.llcheader,
373 PH_LLCNFC_U_FRAME_START_POS,
374 PH_LLCNFC_U_FRAME_NO_OF_POS,
375 (uint8_t)phLlcNfc_e_ua);
376 }
377 /* LLC length byte updated (index + 2 CRC bytes +
378 1 byte of header) */
379 ps_llc_buf->llc_length_byte = (index +
380 PH_LLCNFC_NUM_OF_CRC_BYTES + 1);
381 /* Total LLC buffer size */
382 *pLlcPacketLength = psLlcPacket->llcbuf_len =
383 (ps_llc_buf->llc_length_byte + 1);
384 /*
385 psLlcPacket->s_llcbuf :
386 consists llc length byte + llc header + data + CRC
387 (which needs to be calculated by the below function)
388 psLlcPacket->llcbuf_len :
389 Total length of the above buffer
390 psLlcPacket->llcbuf_len - 2 :
391 -2 because the CRC has to be calculated, only for the
392 bytes which has llc length byte + llc header + data.
393 But total length (llcbuf_len) consists of above mentioned
394 things with 2 byte CRC
395 psLlcPacket->s_llcbuf.sllcpayload.llcpayload :
396 consists only data (no length byte and no llc header)
397 (psLlcPacket->llcbuf_len - 4) :
398 is the array index of the first CRC byte to be calculated
399 (psLlcPacket->llcbuf_len - 3) :
400 is the array index of the second CRC byte to be calculated
401 */
402 index = psLlcPacket->llcbuf_len;
403
404 phLlcNfc_H_ComputeCrc((uint8_t *)ps_llc_buf,
405 (psLlcPacket->llcbuf_len - 2),
406 &(ps_llc_buf->sllcpayload.llcpayload[(index - 4)]),
407 &(ps_llc_buf->sllcpayload.llcpayload[(index - 3)]));
408 }
409
410 return result;
411 }
412
413 NFCSTATUS
phLlcNfc_H_CreateSFramePayload(phLlcNfc_Frame_t * psFrameInfo,phLlcNfc_LlcPacket_t * psLlcPacket,phLlcNfc_LlcCmd_t cmdType)414 phLlcNfc_H_CreateSFramePayload (
415 phLlcNfc_Frame_t *psFrameInfo,
416 phLlcNfc_LlcPacket_t *psLlcPacket,
417 phLlcNfc_LlcCmd_t cmdType
418 )
419 {
420 /*
421 S frame packet (RR or RNR or REJ or SREJ). Total bytes = 4
422 Byte 0 = Length (Length = 3 always for S frame)
423 Byte 1 = Header
424 Byte 2 = CRC1
425 Byte 3 = CRC2
426 */
427 NFCSTATUS result = NFCSTATUS_SUCCESS;
428 phLlcNfc_Buffer_t *ps_llc_buf = NULL;
429 uint8_t length = 0;
430
431 ps_llc_buf = &(psLlcPacket->s_llcbuf);
432
433 /* Initial S frame header */
434 ps_llc_buf->sllcpayload.llcheader = PH_LLCNFC_S_HEADER_INIT;
435 /* Update the N(R) value */
436 ps_llc_buf->sllcpayload.llcheader = (uint8_t)SET_BITS8(
437 ps_llc_buf->sllcpayload.llcheader,
438 PH_LLCNFC_NR_START_BIT_POS,
439 PH_LLCNFC_NR_NS_NO_OF_BITS,
440 psFrameInfo->n_r);
441
442 /* Update the type bits of S frame */
443 ps_llc_buf->sllcpayload.llcheader = (uint8_t)
444 (ps_llc_buf->sllcpayload.llcheader | (uint8_t)cmdType);
445
446 /* Maximum S frame length */
447 psLlcPacket->llcbuf_len = (uint8_t)PH_LLCNFC_MAX_S_FRAME_LEN;
448 /* S frame length byte value */
449 ps_llc_buf->llc_length_byte = (uint8_t)
450 (psLlcPacket->llcbuf_len - 1);
451
452 /*
453 psFrameInfo->s_llcpacket.s_llcbuf :
454 consists llc length byte + llc header + data + CRC
455 (which needs to be calculated by the below function)
456 psFrameInfo->s_llcpacket.llcbuf_len :
457 Total length of the above buffer
458 psFrameInfo->s_llcpacket.llcbuf_len - 2 :
459 -2 because the CRC has to be calculated, only for the
460 bytes which has llc length byte + llc header + data.
461 But total length (llcbuf_len) consists of above mentioned
462 things with 2 byte CRC
463 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload :
464 consists only data (no length byte and no llc header)
465 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload :
466 contains only data sent by user.
467 (psFrameInfo->s_llcpacket.llcbuf_len - 4) :
468 is the array index of the first CRC byte to be calculated
469 (psFrameInfo->s_llcpacket.llcbuf_len - 3) :
470 is the array index of the second CRC byte to be calculated
471 */
472 length = psLlcPacket->llcbuf_len;
473 phLlcNfc_H_ComputeCrc(
474 (uint8_t *)ps_llc_buf, (length - 2),
475 &(ps_llc_buf->sllcpayload.llcpayload[(length - 4)]),
476 &(ps_llc_buf->sllcpayload.llcpayload[(length - 3)]));
477
478 return result;
479 }
480
481 NFCSTATUS
phLlcNfc_H_CreateIFramePayload(phLlcNfc_Frame_t * psFrameInfo,phLlcNfc_LlcPacket_t * psLlcPacket,uint8_t * pLlcBuf,uint8_t llcBufLength)482 phLlcNfc_H_CreateIFramePayload (
483 phLlcNfc_Frame_t *psFrameInfo,
484 phLlcNfc_LlcPacket_t *psLlcPacket,
485 uint8_t *pLlcBuf,
486 uint8_t llcBufLength
487 )
488 {
489 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC,
490 NFCSTATUS_INVALID_PARAMETER);
491 phLlcNfc_Buffer_t *ps_llc_buf = NULL;
492
493 if ((NULL != psFrameInfo) && (NULL != psLlcPacket) &&
494 (NULL != pLlcBuf) && (llcBufLength > 0))
495 {
496 result = NFCSTATUS_SUCCESS;
497 ps_llc_buf = &(psLlcPacket->s_llcbuf);
498
499 (void)memcpy(&(ps_llc_buf->sllcpayload.llcpayload[0]),
500 pLlcBuf, llcBufLength);
501
502 psLlcPacket->llcbuf_len = (uint8_t)llcBufLength;
503
504 /* I frame header byte */
505 ps_llc_buf->sllcpayload.llcheader = PH_LLCNFC_I_HEADER_INIT;
506
507 /* Set the N(S) value */
508 ps_llc_buf->sllcpayload.llcheader = (uint8_t)
509 SET_BITS8(
510 ps_llc_buf->sllcpayload.llcheader,
511 PH_LLCNFC_NS_START_BIT_POS,
512 PH_LLCNFC_NR_NS_NO_OF_BITS,
513 psFrameInfo->n_s);
514
515 /* Set the N(R) value */
516 ps_llc_buf->sllcpayload.llcheader = (uint8_t)
517 SET_BITS8(
518 ps_llc_buf->sllcpayload.llcheader,
519 PH_LLCNFC_NR_START_BIT_POS,
520 PH_LLCNFC_NR_NS_NO_OF_BITS,
521 psFrameInfo->n_r);
522
523 /* Update the length byte, llc length byte value includes
524 data + CRC bytes + llc length byte */
525 ps_llc_buf->llc_length_byte =
526 (psLlcPacket->llcbuf_len +
527 PH_LLCNFC_NUM_OF_CRC_BYTES + 1);
528
529 /* Update total length, Total length is always equal to
530 llc length byte + 1 */
531 psLlcPacket->llcbuf_len =
532 (ps_llc_buf->llc_length_byte + 1);
533
534 /*
535 psFrameInfo->s_llcpacket.s_llcbuf :
536 consists llc length byte + llc header + data + CRC (which
537 needs to be calculated by the below function)
538 psFrameInfo->s_llcpacket.llcbuf_len :
539 Total length of the above buffer
540 psFrameInfo->s_llcpacket.llcbuf_len - 2 :
541 -2 because the CRC has to be calculated, only for the
542 bytes which has llc length byte + llc header + data.
543 But total length (llcbuf_len) consists of above mentioned
544 things with 2 byte CRC
545 psFrameInfo->s_llcpacket.s_llcbuf.sllcpayload.llcpayload :
546 contains only data sent by user.
547 (psFrameInfo->s_llcpacket.llcbuf_len - 4) :
548 is the array index of the first CRC byte to be calculated
549 (psFrameInfo->s_llcpacket.llcbuf_len - 3) :
550 is the array index of the second CRC byte to be calculated
551
552 */
553 phLlcNfc_H_ComputeCrc(
554 (uint8_t*)ps_llc_buf,
555 (psLlcPacket->llcbuf_len - 2),
556 &(ps_llc_buf->sllcpayload.llcpayload
557 [(psLlcPacket->llcbuf_len - 4)]),
558 &(ps_llc_buf->sllcpayload.llcpayload
559 [(psLlcPacket->llcbuf_len - 3)]));
560
561
562 }
563
564 return result;
565 }
566
567 static
568 phLlcNfc_FrameType_t
phLlcNfc_H_ChkGetLlcFrameType(uint8_t llcHeader)569 phLlcNfc_H_ChkGetLlcFrameType (
570 uint8_t llcHeader
571 )
572 {
573 phLlcNfc_FrameType_t frame_type = phLlcNfc_eErr_frame;
574
575 /* Mask the header byte to know the actual frame types */
576 switch((llcHeader & PH_LLCNFC_LLC_HEADER_MASK))
577 {
578 case PH_LLCNFC_U_HEADER_INIT:
579 {
580 frame_type = phLlcNfc_eU_frame;
581 break;
582 }
583
584 case PH_LLCNFC_S_HEADER_INIT:
585 {
586 frame_type = phLlcNfc_eS_frame;
587 break;
588 }
589
590 default:
591 {
592 if (PH_LLCNFC_I_HEADER_INIT ==
593 (PH_LLCNFC_I_FRM_HEADER_MASK & llcHeader))
594 {
595 frame_type = phLlcNfc_eI_frame;
596 }
597 else
598 {
599 frame_type = phLlcNfc_eErr_frame;
600 }
601 break;
602 }
603 }
604 return frame_type;
605 }
606
607 static
608 NFCSTATUS
phLlcNfc_H_Update_ReceivedRSETInfo(phLlcNfc_Frame_t * psFrameInfo,phLlcNfc_Payload_t llcInfo)609 phLlcNfc_H_Update_ReceivedRSETInfo (
610 phLlcNfc_Frame_t *psFrameInfo,
611 phLlcNfc_Payload_t llcInfo
612 )
613 {
614 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT);
615 uint8_t payload_index = 0;
616
617 if ((llcInfo.llcpayload[payload_index] >= PH_LLCNFC_U_FRAME_MIN_WIN_SIZE) &&
618 (llcInfo.llcpayload[payload_index] <= PH_LLCNFC_U_FRAME_MAX_WIN_SIZE))
619 {
620 result = NFCSTATUS_SUCCESS;
621 /* From the received buffer, get the window size from the
622 3rd byte (recvUBufLen[3]) of the buffer */
623 psFrameInfo->window_size = llcInfo.llcpayload[payload_index];
624 payload_index = (uint8_t)(payload_index + 1);
625
626 /* If 4th byte of the receive buffer (pRecvUBuf[4]) is
627 0x01 then SREJ can come from the device*/
628 psFrameInfo->srej_on_off = ((PH_LLCNFC_SREJ_BYTE_VALUE ==
629 llcInfo.llcpayload[payload_index])?
630 PH_LLCNFC_SREJ_BYTE_VALUE:0);
631
632 /* For present implementation, this should be always false
633 later stage remove if statement to work */
634 if (PH_LLCNFC_SREJ_BYTE_VALUE != psFrameInfo->srej_on_off)
635 {
636 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT);
637 }
638 else
639 {
640 payload_index = (uint8_t)(payload_index + 1);
641
642
643 if (llcInfo.llcpayload[payload_index] >
644 (uint8_t)phLlcNfc_e_1228000)
645 {
646 /* Error byte */
647 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT);
648 }
649 else
650 {
651 /* Get the baud rate from the 5th byte of the receive buffer */
652 psFrameInfo->baud_rate = (phLlcNfc_LlcBaudRate_t)
653 (llcInfo.llcpayload[payload_index]);
654 }
655 }
656 }
657
658 return result;
659 }
660
661 static
662 uint8_t
phLlcNfc_H_UpdateIFrameList(phLlcNfc_Frame_t * psFrameInfo,phLlcNfc_StoreIFrame_t * psListInfo)663 phLlcNfc_H_UpdateIFrameList(
664 phLlcNfc_Frame_t *psFrameInfo,
665 phLlcNfc_StoreIFrame_t *psListInfo
666 )
667 {
668 NFCSTATUS result = NFCSTATUS_SUCCESS;
669 phLlcNfc_LlcPacket_t *pspktInfo = NULL;
670 uint8_t while_exit = FALSE;
671 uint8_t nr = 0;
672 uint8_t ns = 0;
673 uint8_t no_of_del_frames = 0;
674
675 PHNFC_UNUSED_VARIABLE(result);
676 if(0 == psListInfo->winsize_cnt)
677 {
678 while_exit = TRUE;
679 }
680 while (FALSE == while_exit)
681 {
682 /* Get the first node from the list */
683 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &pspktInfo,
684 DEFAULT_PACKET_INPUT);
685 if (NULL != pspktInfo)
686 {
687 /* Get the N(R) value of the received packet and N(S) value of the
688 sent stored i frame */
689 ns = (uint8_t)GET_BITS8 (
690 pspktInfo->s_llcbuf.sllcpayload.llcheader,
691 PH_LLCNFC_NS_START_BIT_POS,
692 PH_LLCNFC_NR_NS_NO_OF_BITS);
693
694 nr = (uint8_t)GET_BITS8(
695 psFrameInfo->s_recvpacket.s_llcbuf.sllcpayload.llcheader,
696 PH_LLCNFC_NR_START_BIT_POS,
697 PH_LLCNFC_NR_NS_NO_OF_BITS);
698
699 /* Check the value of each i frame N(S) and
700 received ACKs N(R) */
701 #if 0
702 if(((ns <= nr) && ((nr - ns) <= psFrameInfo->window_size))
703 || ((ns > nr) && (((PH_LLCNFC_MOD_NS_NR + nr) - ns) <=
704 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE)))
705 #endif
706 if(((ns < nr) && ((nr - ns) <= psFrameInfo->window_size))
707 || ((ns > nr) && (((PH_LLCNFC_MOD_NS_NR + nr) - ns) <=
708 PH_LLCNFC_U_FRAME_MAX_WIN_SIZE)))
709 {
710 phLlcNfc_H_DeleteIFrame (psListInfo);
711 no_of_del_frames = (uint8_t)(no_of_del_frames + 1);
712 }
713 else
714 {
715 while_exit = TRUE;
716 }
717
718 if(0 == psListInfo->winsize_cnt)
719 {
720 while_exit = TRUE;
721 }
722 }
723 else
724 {
725 while_exit = TRUE;
726 }
727 }
728 return no_of_del_frames;
729 }
730
731 NFCSTATUS
phLlcNfc_H_SendUserIFrame(phLlcNfc_Context_t * psLlcCtxt,phLlcNfc_StoreIFrame_t * psListInfo)732 phLlcNfc_H_SendUserIFrame (
733 phLlcNfc_Context_t *psLlcCtxt,
734 phLlcNfc_StoreIFrame_t *psListInfo
735 )
736 {
737 NFCSTATUS result = NFCSTATUS_SUCCESS;
738 phLlcNfc_Frame_t *ps_frame_info = NULL;
739 phLlcNfc_LlcPacket_t s_create_packet;
740 phLlcNfc_LlcPacket_t *ps_get_packet = NULL;
741 phLlcNfc_Payload_t *ps_llc_payload = NULL;
742 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
743 uint8_t llc_header = 0,
744 length = 0;
745
746 if ((NULL == psLlcCtxt) || (NULL == psListInfo))
747 {
748 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);
749 }
750 else if (0 == psListInfo->winsize_cnt)
751 {
752 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED);
753 }
754 else
755 {
756 ps_frame_info = &(psLlcCtxt->s_frameinfo);
757 ps_store_frame = &(ps_frame_info->s_send_store);
758
759 if (
760 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt +
761 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR))
762 )
763 {
764 /* Get the stored I frame, only if the new frame is sent
765 from the upper layer */
766 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet,
767 ps_frame_info->n_s);
768 }
769
770 if (NULL != ps_get_packet)
771 {
772 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader;
773
774 /* Update n(r) value for the header */
775 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r);
776
777 /* Create the packet */
778 (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet,
779 sizeof (phLlcNfc_LlcPacket_t));
780
781 s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header;
782 ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload);
783
784 /* Length of the complete llc buffer, sent to PN544 */
785 length = s_create_packet.llcbuf_len;
786
787 /* Compute CRC for the created packet */
788 phLlcNfc_H_ComputeCrc ((uint8_t *)&(s_create_packet.s_llcbuf),
789 (length - 2),
790 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]),
791 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)]));
792
793 /* Send the i frame */
794 result = phLlcNfc_Interface_Write (psLlcCtxt,
795 (uint8_t *)&(s_create_packet.s_llcbuf),
796 (uint32_t)s_create_packet.llcbuf_len);
797
798 ps_frame_info->write_status = result;
799
800 if (NFCSTATUS_BUSY == PHNFCSTATUS (result))
801 {
802 /* The below check is added because, write is already pended by some other
803 operation, so it has to complete, when it completes, then immediately
804 next write shall be called using the below updated variable
805
806 The below variable is checked for the resend or rejected i frame
807 because if due to timer or reject frame from PN544, an I frame
808 has been sent (means write has been pended then the variable shall
809 not be overwritten.
810 */
811 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t)
812 (((resend_i_frame == ps_frame_info->write_wait_call) ||
813 (rejected_i_frame == ps_frame_info->write_wait_call)) ?
814 ps_frame_info->write_wait_call : user_i_frame);
815 }
816 else
817 {
818 if (NFCSTATUS_PENDING == result)
819 {
820 /* Start the timer */
821 (void)phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER,
822 ps_frame_info->n_s);
823
824 /* "sent_frame_type is updated" only if the data is
825 written to the lower layer */
826 ps_frame_info->sent_frame_type = user_i_frame;
827 }
828 }
829 }
830 }
831 return result;
832 }
833
834 NFCSTATUS
phLlcNfc_H_SendRejectedIFrame(phLlcNfc_Context_t * psLlcCtxt,phLlcNfc_StoreIFrame_t * psListInfo,uint8_t ns_rejected)835 phLlcNfc_H_SendRejectedIFrame (
836 phLlcNfc_Context_t *psLlcCtxt,
837 phLlcNfc_StoreIFrame_t *psListInfo,
838 uint8_t ns_rejected
839 )
840 {
841 NFCSTATUS result = NFCSTATUS_SUCCESS;
842 phLlcNfc_Frame_t *ps_frame_info = NULL;
843 phLlcNfc_LlcPacket_t s_create_packet;
844 phLlcNfc_LlcPacket_t *ps_get_packet = NULL;
845 phLlcNfc_Payload_t *ps_llc_payload = NULL;
846 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
847 uint8_t llc_header = 0;
848 uint8_t length = 0;
849
850 if ((NULL == psLlcCtxt) || (NULL == psListInfo))
851 {
852 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);
853 }
854 else if (0 == psListInfo->winsize_cnt)
855 {
856 result = PHNFCSTVAL (CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED);
857 }
858 else
859 {
860 ps_frame_info = &(psLlcCtxt->s_frameinfo);
861 ps_store_frame = &(ps_frame_info->s_send_store);
862
863
864 if (ns_rejected < (uint8_t)(ps_store_frame->winsize_cnt +
865 ps_store_frame->start_pos))
866 {
867 /* To send rejected frame, first thing shall be done is
868 windows size count shall be checked. if the
869 start position
870 */
871 if (invalid_frame !=
872 ps_store_frame->s_llcpacket[ns_rejected].frame_to_send)
873 {
874 /* Above check is added to know only if */
875 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet,
876 ns_rejected);
877 }
878 else
879 {
880 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT;
881 /* Get the stored I frame, only if the new frame is sent
882 from the upper layer */
883 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, psListInfo);
884 }
885 }
886
887 if (NULL != ps_get_packet)
888 {
889 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader;
890
891 /* Update n(r) value for the header */
892 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r);
893
894 /* Create the packet */
895 (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet,
896 sizeof (phLlcNfc_LlcPacket_t));
897
898 s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header;
899 ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload);
900
901 /* Length of the complete llc buffer, sent to PN544 */
902 length = s_create_packet.llcbuf_len;
903
904 /* Compute CRC for the created packet */
905 phLlcNfc_H_ComputeCrc ((uint8_t *)&(s_create_packet.s_llcbuf),
906 (length - 2),
907 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]),
908 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)]));
909
910 /* Send the i frame */
911 result = phLlcNfc_Interface_Write (psLlcCtxt,
912 (uint8_t *)&(s_create_packet.s_llcbuf),
913 (uint32_t)s_create_packet.llcbuf_len);
914
915 ps_frame_info->write_status = result;
916
917 if (NFCSTATUS_BUSY == PHNFCSTATUS (result))
918 {
919 /* Already a frame is sent and response is waited for the sent frame,
920 so update the below variable */
921 ps_frame_info->write_wait_call = (phLlcNfc_eSentFrameType_t)
922 (((ns_rejected != ps_store_frame->start_pos) &&
923 (resend_i_frame != ps_frame_info->write_wait_call))?
924 rejected_i_frame : ps_frame_info->write_wait_call);
925 }
926 else
927 {
928 /* NFCSTATUS_PENDING means that the no other write is pending, apart
929 from the present write
930
931 Start the timer */
932 (void)phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER, ns_rejected);
933
934 /* "sent_frame_type is updated" only if the data is
935 written to the lower layer. This will be used in the write
936 response callback and also indicates, what is the frame sent
937 and why
938 */
939 ps_frame_info->sent_frame_type = rejected_i_frame;
940
941 if ((ns_rejected + 1) < ps_frame_info->n_s)
942 {
943 ps_frame_info->rejected_ns = (uint8_t)(ns_rejected + 1);
944
945 ps_frame_info->write_status = PHNFCSTVAL(CID_NFC_LLC,
946 NFCSTATUS_BUSY);
947
948 if (invalid_frame ==
949 ps_store_frame->s_llcpacket[ns_rejected].frame_to_send)
950 {
951 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT;
952 ps_frame_info->write_wait_call = user_i_frame;
953 }
954 else
955 {
956 ps_frame_info->write_wait_call = rejected_i_frame;
957 }
958 }
959 else
960 {
961 ps_frame_info->rejected_ns = DEFAULT_PACKET_INPUT;
962 /* This check is added to see that new frame has arrived
963 from the upper layer */
964 if (ps_frame_info->n_s < (ps_store_frame->start_pos +
965 ps_store_frame->winsize_cnt))
966 {
967 ps_frame_info->write_wait_call = user_i_frame;
968 }
969 }
970 }
971 }
972 }
973 return result;
974 }
975
976 NFCSTATUS
phLlcNfc_H_SendTimedOutIFrame(phLlcNfc_Context_t * psLlcCtxt,phLlcNfc_StoreIFrame_t * psListInfo,uint8_t frame_to_send)977 phLlcNfc_H_SendTimedOutIFrame (
978 phLlcNfc_Context_t *psLlcCtxt,
979 phLlcNfc_StoreIFrame_t *psListInfo,
980 uint8_t frame_to_send
981 )
982 {
983 NFCSTATUS result = NFCSTATUS_SUCCESS;
984 phLlcNfc_Frame_t *ps_frame_info = NULL;
985 phLlcNfc_Timerinfo_t *ps_timer_info = NULL;
986 phLlcNfc_LlcPacket_t s_create_packet;
987 phLlcNfc_LlcPacket_t *ps_get_packet = NULL;
988 phLlcNfc_Payload_t *ps_llc_payload = NULL;
989 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
990
991 PHNFC_UNUSED_VARIABLE(frame_to_send);
992 if((NULL == psLlcCtxt) || (NULL == psListInfo))
993 {
994 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);
995 }
996 else if (psListInfo->winsize_cnt == 0)
997 {
998 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_NOT_ALLOWED);
999 }
1000 else
1001 {
1002 uint8_t llc_header = 0;
1003 uint8_t length = 0;
1004 uint8_t timer_count = 0;
1005 uint8_t timer_index = 0;
1006 uint8_t ns_index = 0;
1007
1008 ps_frame_info = &(psLlcCtxt->s_frameinfo);
1009 ps_timer_info = &(psLlcCtxt->s_timerinfo);
1010 ps_store_frame = &(ps_frame_info->s_send_store);
1011
1012 timer_index = ps_timer_info->index_to_send;
1013 timer_count = ps_timer_info->guard_to_count;
1014 ns_index = ps_timer_info->timer_ns_value[timer_index];
1015
1016 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL WIN SIZE CNT : 0x%02X\n", ps_store_frame->winsize_cnt);
1017 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL START POS : 0x%02X\n", ps_store_frame->start_pos);
1018 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL N S value : 0x%02X\n", ps_frame_info->n_s);
1019 PH_LLCNFC_DEBUG("SEND TIMEOUT TIMER INDEX : 0x%02X\n", timer_index);
1020 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL frame type : 0x%02X\n", ps_timer_info->frame_type[timer_index]);
1021
1022 if (resend_i_frame == ps_timer_info->frame_type[timer_index])
1023 {
1024 /* Get the stored I frame */
1025 result = phLlcNfc_H_IFrameList_Peek (psListInfo, &ps_get_packet,
1026 ns_index);
1027 }
1028
1029 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Packet : 0x%p\n", ps_get_packet);
1030 if (NULL != ps_get_packet)
1031 {
1032 llc_header = ps_get_packet->s_llcbuf.sllcpayload.llcheader;
1033
1034 /* Update n(r) value for the header */
1035 llc_header = (uint8_t)(llc_header | ps_frame_info->n_r);
1036
1037 /* create the packet */
1038 (void)memcpy ((void *)&(s_create_packet), (void *)ps_get_packet,
1039 sizeof (phLlcNfc_LlcPacket_t));
1040
1041 s_create_packet.s_llcbuf.sllcpayload.llcheader = llc_header;
1042 ps_llc_payload = &(s_create_packet.s_llcbuf.sllcpayload);
1043
1044 /* Length of the complete llc buffer, sent to PN544 */
1045 length = s_create_packet.llcbuf_len;
1046
1047 /* Compute CRC */
1048 phLlcNfc_H_ComputeCrc((uint8_t *)&(s_create_packet.s_llcbuf),
1049 (length - 2),
1050 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 4)]),
1051 (uint8_t *)&(ps_llc_payload->llcpayload[(length - 3)]));
1052
1053 /* Send the i frame */
1054 result = phLlcNfc_Interface_Write (psLlcCtxt,
1055 (uint8_t *)&(s_create_packet.s_llcbuf),
1056 (uint32_t)s_create_packet.llcbuf_len);
1057
1058 ps_frame_info->write_status = result;
1059 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Write status : 0x%02X\n", result);
1060
1061 if (NFCSTATUS_BUSY == PHNFCSTATUS (result))
1062 {
1063 ps_frame_info->write_wait_call = resend_i_frame;
1064 }
1065 else
1066 {
1067 /* result = NFCSTATUS_PENDING and
1068 Timer is not started because the remaining timer
1069 will be running */
1070 uint16_t time_out_value = 0;
1071
1072 /* Each frame has the send count, so increment this
1073 as soon as the frame is sent */
1074 ps_timer_info->iframe_send_count[timer_index] = (uint8_t)
1075 (ps_timer_info->iframe_send_count[timer_index] + 1);
1076
1077 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL timer index : 0x%02X\n", timer_index);
1078
1079 if (timer_index > 0)
1080 {
1081 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL GUARD TO VALUE : 0x%02X\n", ps_timer_info->guard_to_value[(timer_index - 1)]);
1082 /* Copy the maximum time-out value. */
1083 time_out_value = (uint16_t)
1084 ((ps_timer_info->guard_to_value[(timer_index - 1)] >=
1085 PH_LLCNFC_GUARD_TO_VALUE) ?
1086 (ps_timer_info->guard_to_value[(timer_index - 1)] +
1087 PH_LLCNFC_RESOLUTION):
1088 PH_LLCNFC_GUARD_TO_VALUE);
1089 }
1090 else
1091 {
1092 /* If the timer_index is 0 means, the previous timed out
1093 frame is the last frame in the list */
1094 time_out_value = (uint16_t)
1095 ((ps_timer_info->guard_to_value[(timer_count - 1)] >=
1096 PH_LLCNFC_GUARD_TO_VALUE) ?
1097 (ps_timer_info->guard_to_value[(timer_count - 1)] +
1098 PH_LLCNFC_RESOLUTION):
1099 PH_LLCNFC_GUARD_TO_VALUE);
1100 }
1101
1102 ps_timer_info->guard_to_value[timer_index] = time_out_value;
1103
1104 ps_frame_info->sent_frame_type = resend_i_frame;
1105
1106 ps_timer_info->frame_type[timer_index] = invalid_frame;
1107
1108 PH_LLCNFC_DEBUG("SEND TIMEOUT CALL Next frame type : 0x%02X\n", ps_timer_info->frame_type[((timer_index + 1) % PH_LLCNFC_MAX_ACK_GUARD_TIMER)]);
1109 /* Now check if next timer has expired, if yes,
1110 set the index to next, on receiving the write response
1111 callback for this send, then next frame can be sent */
1112 if (resend_i_frame ==
1113 ps_timer_info->frame_type[((timer_index + 1) %
1114 PH_LLCNFC_MAX_ACK_GUARD_TIMER)])
1115 {
1116 /* If next frame has to be sent, then update write wait */
1117 ps_frame_info->write_status = NFCSTATUS_BUSY;
1118 ps_frame_info->write_wait_call = resend_i_frame;
1119 ps_timer_info->index_to_send = (uint8_t)
1120 ((timer_index + 1) %
1121 PH_LLCNFC_MAX_ACK_GUARD_TIMER);
1122 }
1123 else
1124 {
1125 /* Timer is not expired,
1126 Now, Check if the new frame is ready to be sent, if yes,
1127 then update the variable */
1128 if (
1129 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt +
1130 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR))
1131 )
1132 {
1133 ps_frame_info->write_status = PHNFCSTVAL (CID_NFC_LLC,
1134 NFCSTATUS_BUSY);
1135 ps_frame_info->write_wait_call = user_i_frame;
1136 }
1137 }
1138
1139 #if 0
1140 result = phLlcNfc_StartTimers (PH_LLCNFC_GUARDTIMER,
1141 ((llc_header >>
1142 PH_LLCNFC_NS_START_BIT_POS) |
1143 MAX_NS_NR_VALUE));
1144 #endif /* #if 0 */
1145
1146 }
1147 }
1148 else
1149 {
1150 if (
1151 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt +
1152 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR))
1153 )
1154 {
1155 ps_frame_info->write_status = PHNFCSTVAL (CID_NFC_LLC,
1156 NFCSTATUS_BUSY);
1157 ps_frame_info->write_wait_call = user_i_frame;
1158 }
1159 }
1160 }
1161
1162 return result;
1163 }
1164
1165
1166 void
phLlcNfc_H_ProcessIFrame(phLlcNfc_Context_t * psLlcCtxt)1167 phLlcNfc_H_ProcessIFrame (
1168 phLlcNfc_Context_t *psLlcCtxt
1169 )
1170 {
1171 NFCSTATUS result = NFCSTATUS_SUCCESS;
1172 uint8_t ns_index = 0;
1173 #if defined (LLC_SEND_RR_ACK)
1174 /* uint8_t nr_index = 0; */
1175 #endif /* #if defined (LLC_SEND_RR_ACK) */
1176 phLlcNfc_Frame_t *ps_frame_info = NULL;
1177 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
1178 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL;
1179 phLlcNfc_LlcCmd_t cmdtype = phLlcNfc_e_error;
1180 phLlcNfc_eSentFrameType_t eframe_type = invalid_frame;
1181 uint8_t dont_send_s_frame = FALSE;
1182 uint8_t no_of_del_frames = 0;
1183 phNfc_sCompletionInfo_t notifyinfo = {0,0,0};
1184
1185 #ifdef RECV_NR_CHECK_ENABLE
1186 uint8_t recvd_nr = 0;
1187 #endif /* #ifdef RECV_NR_CHECK_ENABLE */
1188
1189 ps_frame_info = &(psLlcCtxt->s_frameinfo);
1190 ps_store_frame = &(ps_frame_info->s_send_store);
1191 ps_recv_pkt = &(ps_frame_info->s_recvpacket);
1192
1193 PHNFC_UNUSED_VARIABLE(result);
1194 /* Received buffer, N(S) value */
1195 ns_index = (uint8_t)GET_BITS8(
1196 ps_recv_pkt->s_llcbuf.sllcpayload.llcheader,
1197 PH_LLCNFC_NS_START_BIT_POS,
1198 PH_LLCNFC_NR_NS_NO_OF_BITS);
1199
1200 PH_LLCNFC_DEBUG("NS START POS BEFORE DEL : 0x%02X\n", ps_store_frame->start_pos);
1201 PH_LLCNFC_DEBUG("WIN SIZE BEFORE DEL : 0x%02X\n", ps_store_frame->winsize_cnt);
1202
1203 /* Correct frame is received, so remove the stored i frame info */
1204 no_of_del_frames = phLlcNfc_H_UpdateIFrameList (ps_frame_info,
1205 &(ps_frame_info->s_send_store));
1206
1207 PH_LLCNFC_DEBUG("NS START POS AFTER DEL : 0x%02X\n", ps_store_frame->start_pos);
1208 PH_LLCNFC_DEBUG("WIN SIZE AFTER DEL : 0x%02X\n", ps_store_frame->winsize_cnt);
1209
1210 #ifdef RECV_NR_CHECK_ENABLE
1211
1212 recvd_nr = (uint8_t)GET_BITS8(
1213 ps_recv_pkt->s_llcbuf.sllcpayload.llcheader,
1214 PH_LLCNFC_NR_START_BIT_POS,
1215 PH_LLCNFC_NR_NS_NO_OF_BITS);
1216
1217 if (((ps_frame_info->n_s > recvd_nr) &&
1218 (0 == ((ps_frame_info->n_s + 1) % PH_LLCNFC_MOD_NS_NR)))
1219 || (recvd_nr > ps_frame_info->n_s))
1220
1221 #else /* #ifdef RECV_NR_CHECK_ENABLE */
1222
1223 if (no_of_del_frames > 0)
1224
1225 #endif /* #ifdef RECV_NR_CHECK_ENABLE */
1226 {
1227 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames);
1228 }
1229
1230 /* Received buffer, N(S) value = N(R) of host (our
1231 structure) then send RR type of s frame else send
1232 REJ type of s frame */
1233 if ((ns_index == ps_frame_info->n_r)
1234 #if defined (LLC_SEND_RR_ACK)
1235
1236 || ((ns_index < ps_frame_info->n_r) &&
1237 ((ps_frame_info->n_r - ns_index) < ps_frame_info->window_size))
1238 || ((ns_index > ps_frame_info->n_r) &&
1239 ((ns_index - ps_frame_info->n_r) > ps_frame_info->window_size))
1240
1241 #endif /* #if defined (LLC_SEND_RR_ACK) */
1242 )
1243 {
1244 PH_LLCNFC_PRINT(" Type bits of S frame to be sent is RR \n");
1245 ps_frame_info->recv_error_count = 0;
1246 ps_frame_info->send_error_count = 0;
1247
1248 psLlcCtxt->recvbuf_length = (ps_recv_pkt->llcbuf_len -
1249 PH_LLCNFC_LEN_APPEND);
1250
1251 (void)memcpy ((void *)psLlcCtxt->precv_buf, (void *)(
1252 ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload),
1253 psLlcCtxt->recvbuf_length);
1254
1255 #if defined (LLC_SEND_RR_ACK)
1256
1257 if (((ns_index < ps_frame_info->n_r) &&
1258 ((ps_frame_info->n_r - ns_index) < ps_frame_info->window_size))
1259 || ((ns_index > ps_frame_info->n_r) &&
1260 ((ns_index - ps_frame_info->n_r) > ps_frame_info->window_size)))
1261 {
1262 ps_frame_info->n_r = ((ns_index + 1)
1263 % PH_LLCNFC_MOD_NS_NR);
1264 }
1265 else
1266
1267 #endif /* #if defined (LLC_SEND_RR_ACK) */
1268 {
1269 /* Update the N(R) value in I and S frame context */
1270 ps_frame_info->n_r = ((ps_frame_info->n_r + 1)
1271 % PH_LLCNFC_MOD_NS_NR);
1272
1273 #ifdef PIGGY_BACK
1274 ps_frame_info->resp_recvd_count = (uint8_t)
1275 (ps_frame_info->resp_recvd_count + 1);
1276 #endif /* #ifdef PIGGY_BACK */
1277
1278 }
1279
1280 if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status))
1281 {
1282 /* Any how write cannot be done and some frame is ready to be sent
1283 so this frame will act as the ACK */
1284 result = phLlcNfc_H_WriteWaitCall (psLlcCtxt);
1285 }
1286 else
1287 {
1288 if (
1289 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt +
1290 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR))
1291 )
1292 {
1293 /* If user has sent a frame and DAL write is busy, then
1294 it has to be sent */
1295 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame);
1296 }
1297 }
1298
1299 if (NFCSTATUS_PENDING == result)
1300 {
1301 dont_send_s_frame = TRUE;
1302 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB
1303 phLlcNfc_H_SendInfo (psLlcCtxt);
1304 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */
1305 }
1306 else
1307 {
1308 cmdtype = phLlcNfc_e_rr;
1309 /* If i frame is sent from the stored list, it got the correct
1310 acknowledge i frame, so now for an i frame , s frame acknowledge
1311 is sent */
1312 eframe_type = ((resend_i_frame == ps_frame_info->sent_frame_type)?
1313 resend_s_frame : s_frame);
1314 }
1315
1316 #ifdef PIGGY_BACK
1317 phLlcNfc_H_SendInfo (psLlcCtxt);
1318 #endif /* #ifdef PIGGY_BACK */
1319
1320 }
1321 else
1322 {
1323 ps_frame_info->send_error_count = (uint8_t)
1324 (ps_frame_info->send_error_count + 1);
1325
1326 #ifdef LLC_SEND_ERROR_COUNT
1327
1328 if (ps_frame_info->send_error_count < RECV_ERROR_FRAME_COUNT)
1329
1330 #endif /* #ifdef LLC_SEND_ERROR_COUNT */
1331 {
1332
1333 #ifdef LLC_RR_INSTEAD_OF_REJ
1334
1335 if (((ps_frame_info->n_r > 0) && (ns_index == (ps_frame_info->n_r - 1)))
1336 || ((0 == ps_frame_info->n_r) &&
1337 (ns_index == (PH_LLCNFC_MOD_NS_NR - 1))))
1338 {
1339 cmdtype = phLlcNfc_e_rr;
1340 eframe_type = rej_rr_s_frame;
1341 }
1342 else
1343
1344 #endif /* #ifdef LLC_RR_INSTEAD_OF_REJ */
1345 {
1346 cmdtype = phLlcNfc_e_rej;
1347 eframe_type = ((resend_i_frame == ps_frame_info->sent_frame_type)?
1348 resend_rej_s_frame : reject_s_frame);
1349 }
1350 }
1351
1352 #ifdef LLC_SEND_ERROR_COUNT
1353 else
1354 {
1355 #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION
1356
1357 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt);
1358
1359 #else /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */
1360
1361 dont_send_s_frame = TRUE;
1362 PH_LLCNFC_DEBUG("SEND ERROR COUNT : 0x%02X\n", ps_frame_info->send_error_count);
1363 /* Error count has reached the limit, raise exception */
1364 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC,
1365 NFCSTATUS_BOARD_COMMUNICATION_ERROR);
1366 #if 0
1367 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
1368 #endif /* #if 0 */
1369 /* Resend done, no answer from the device */
1370 psLlcCtxt->cb_for_if.notify (
1371 psLlcCtxt->cb_for_if.pif_ctxt,
1372 psLlcCtxt->phwinfo,
1373 NFC_NOTIFY_DEVICE_ERROR,
1374 ¬ifyinfo);
1375
1376 #endif /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */
1377 }
1378 #endif /* #ifdef LLC_SEND_ERROR_COUNT */
1379 }
1380
1381 #ifdef LLC_RELEASE_FLAG
1382
1383 if (FALSE == g_release_flag)
1384
1385 #endif /* #ifdef LLC_RELEASE_FLAG */
1386 {
1387 (void)phLlcNfc_Interface_Read(psLlcCtxt,
1388 PH_LLCNFC_READWAIT_OFF,
1389 &(ps_recv_pkt->s_llcbuf.llc_length_byte),
1390 (uint8_t)PH_LLCNFC_BYTES_INIT_READ);
1391
1392 #ifdef PIGGY_BACK
1393 /* Check if any write call is performed or not */
1394 if (NFCSTATUS_PENDING != result)
1395 {
1396 /* No write is performed, So, now check */
1397 if (NFCSTATUS_BUSY == PHNFCSTATUS (ps_frame_info->write_status))
1398 {
1399 /* Any how write cannot be done and some frame is ready to be sent
1400 so this frame will act as the ACK */
1401 result = phLlcNfc_H_WriteWaitCall (psLlcCtxt);
1402 }
1403 }
1404
1405 if (NFCSTATUS_PENDING != result)
1406 {
1407 if (ps_frame_info->window_size == ps_frame_info->resp_recvd_count)
1408 {
1409 phLlcNfc_LlcPacket_t s_packet_info;
1410 /* Create S frame */
1411 (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), cmdtype);
1412
1413 result = phLlcNfc_Interface_Write(psLlcCtxt,
1414 (uint8_t *)&(s_packet_info.s_llcbuf),
1415 (uint32_t)(s_packet_info.llcbuf_len));
1416
1417
1418 if (0 == ps_frame_info->send_error_count)
1419 {
1420 ps_frame_info->write_wait_call = invalid_frame;
1421 }
1422 ps_frame_info->sent_frame_type = eframe_type;
1423 }
1424 else
1425 {
1426 result = phLlcNfc_StartTimers (PH_LLCNFC_ACKTIMER, 0);
1427 }
1428 }
1429 #else /* #ifdef PIGGY_BACK */
1430
1431 if ((TRUE != ps_frame_info->write_pending) &&
1432 (PH_LLCNFC_READPEND_REMAIN_BYTE != ps_frame_info->read_pending) &&
1433 (FALSE == dont_send_s_frame))
1434 {
1435 phLlcNfc_LlcPacket_t s_packet_info = {0};
1436 /* Create S frame */
1437 (void)phLlcNfc_H_CreateSFramePayload (ps_frame_info, &(s_packet_info), cmdtype);
1438
1439 result = phLlcNfc_Interface_Write(psLlcCtxt,
1440 (uint8_t *)&(s_packet_info.s_llcbuf),
1441 (uint32_t)(s_packet_info.llcbuf_len));
1442
1443
1444 if (0 == ps_frame_info->send_error_count)
1445 {
1446 ps_frame_info->write_wait_call = invalid_frame;
1447 }
1448 ps_frame_info->sent_frame_type = eframe_type;
1449 }
1450 #endif /* #ifdef PIGGY_BACK */
1451 }
1452
1453 return ;
1454 }
1455
1456 static
1457 NFCSTATUS
phLlcNfc_H_ProcessUFrame(phLlcNfc_Context_t * psLlcCtxt)1458 phLlcNfc_H_ProcessUFrame (
1459 phLlcNfc_Context_t *psLlcCtxt
1460 )
1461 {
1462 NFCSTATUS result = NFCSTATUS_SUCCESS;
1463 phLlcNfc_Frame_t *ps_frame_info = NULL;
1464 phLlcNfc_LlcPacket_t *ps_uframe_pkt = NULL;
1465 #ifdef LLC_URSET_NO_DELAY
1466 phNfc_sCompletionInfo_t notifyinfo = {0,0,0};
1467 #else /* #ifdef LLC_URSET_NO_DELAY */
1468 uint32_t delay_timer_id =
1469 PH_OSALNFC_INVALID_TIMER_ID;
1470 #endif /* #ifdef LLC_URSET_NO_DELAY */
1471 uint8_t cmdtype = phLlcNfc_e_error;
1472
1473 phLlcNfc_StopTimers(PH_LLCNFC_CONNECTIONTIMER, 0);
1474 ps_frame_info = &(psLlcCtxt->s_frameinfo);
1475 ps_uframe_pkt = &(ps_frame_info->s_recvpacket);
1476 /* Check the command type */
1477 cmdtype = (ps_uframe_pkt->s_llcbuf.sllcpayload.llcheader &
1478 PH_LLCNFC_U_FRAME_MODIFIER_MASK);
1479 PHNFC_UNUSED_VARIABLE(result);
1480 switch(cmdtype)
1481 {
1482 case phLlcNfc_e_rset:
1483 {
1484 psLlcCtxt->s_frameinfo.rset_recvd = TRUE;
1485 /* command type is RSET, so update the U frame parameters */
1486 result = phLlcNfc_H_Update_ReceivedRSETInfo (ps_frame_info,
1487 ps_uframe_pkt->s_llcbuf.sllcpayload);
1488 /* Create a UA frame */
1489 result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt,
1490 ps_uframe_pkt,
1491 &(ps_uframe_pkt->llcbuf_len),
1492 phLlcNfc_e_ua);
1493
1494 if (NFCSTATUS_SUCCESS == result)
1495 {
1496 /* Call DAL write */
1497 result = phLlcNfc_Interface_Write( psLlcCtxt,
1498 (uint8_t*)&(ps_uframe_pkt->s_llcbuf),
1499 (uint32_t)ps_uframe_pkt->llcbuf_len);
1500
1501 phLlcNfc_H_ResetFrameInfo(psLlcCtxt);
1502 ps_frame_info->write_status = result;
1503 ps_frame_info->write_wait_call = invalid_frame;
1504 if (NFCSTATUS_PENDING == result)
1505 {
1506 ps_frame_info->sent_frame_type =
1507 ((ps_frame_info->sent_frame_type != init_u_rset_frame) ?
1508 u_a_frame : init_u_a_frame);
1509 }
1510 else
1511 {
1512 if (NFCSTATUS_BUSY == PHNFCSTATUS(result))
1513 {
1514 ps_frame_info->write_wait_call =
1515 ((ps_frame_info->sent_frame_type != init_u_rset_frame) ?
1516 u_a_frame : init_u_a_frame);
1517 result = NFCSTATUS_PENDING;
1518 }
1519 }
1520 }
1521 break;
1522 }
1523 case phLlcNfc_e_ua:
1524 {
1525 phLlcNfc_H_ResetFrameInfo (psLlcCtxt);
1526 /* Add timer here, to delay the next command to the PN544 */
1527 #ifdef LLC_URSET_NO_DELAY
1528 if (ps_frame_info->s_send_store.winsize_cnt > 0)
1529 {
1530 #if 0
1531 /* Resend I frame */
1532 result = phLlcNfc_H_SendTimedOutIFrame (psLlcCtxt,
1533 &(ps_frame_info->s_send_store, 0);
1534 #else
1535 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt,
1536 &(ps_frame_info->s_send_store));
1537 #endif /* #if 0 */
1538 }
1539 else
1540 {
1541 if ((init_u_rset_frame == ps_frame_info->sent_frame_type) &&
1542 (NULL != psLlcCtxt->cb_for_if.notify))
1543 {
1544 ps_frame_info->sent_frame_type = write_resp_received;
1545 notifyinfo.status = NFCSTATUS_SUCCESS;
1546 /* Send the notification to the upper layer */
1547 psLlcCtxt->cb_for_if.notify(
1548 psLlcCtxt->cb_for_if.pif_ctxt,
1549 psLlcCtxt->phwinfo,
1550 NFC_NOTIFY_INIT_COMPLETED,
1551 ¬ifyinfo);
1552 }
1553 }
1554 #else /* #ifdef LLC_URSET_NO_DELAY */
1555 delay_timer_id = phOsalNfc_Timer_Create ();
1556 phOsalNfc_Timer_Start (delay_timer_id, LLC_URSET_DELAY_TIME_OUT,
1557 phLlcNfc_URSET_Delay_Notify, (void*)0);
1558 #endif /* #ifdef LLC_URSET_NO_DELAY */
1559 break;
1560 }
1561 default:
1562 {
1563 result = PHNFCSTVAL(CID_NFC_LLC,
1564 NFCSTATUS_INVALID_FORMAT);
1565 break;
1566 }
1567 }
1568 return result;
1569 }
1570
1571 static
1572 void
phLlcNfc_H_ProcessSFrame(phLlcNfc_Context_t * psLlcCtxt)1573 phLlcNfc_H_ProcessSFrame (
1574 phLlcNfc_Context_t *psLlcCtxt)
1575 {
1576 NFCSTATUS result = NFCSTATUS_SUCCESS;
1577 uint8_t cmdtype = phLlcNfc_e_error;
1578 #if 0
1579 prev_win_count = 0;
1580 #endif /* #if 0 */
1581 phNfc_sTransactionInfo_t compinfo = {0, 0, 0, 0, 0};
1582 phLlcNfc_Frame_t *ps_frame_info = NULL;
1583 phLlcNfc_StoreIFrame_t *ps_store_frame = NULL;
1584 phLlcNfc_LlcPacket_t *ps_recv_pkt = NULL;
1585 uint8_t no_of_del_frames = 0;
1586 phNfc_sCompletionInfo_t notifyinfo = {0,0,0};
1587
1588 ps_frame_info = &(psLlcCtxt->s_frameinfo);
1589 ps_recv_pkt = &(ps_frame_info->s_recvpacket);
1590 ps_store_frame = &(ps_frame_info->s_send_store);
1591
1592 cmdtype = (ps_recv_pkt->s_llcbuf.sllcpayload.llcheader &
1593 PH_LLCNFC_S_FRAME_TYPE_MASK);
1594 PHNFC_UNUSED_VARIABLE(result);
1595
1596 PH_LLCNFC_DEBUG("NS START POS BEFORE DEL : 0x%02X\n", ps_store_frame->start_pos);
1597 PH_LLCNFC_DEBUG("WIN SIZE BEFORE DEL : 0x%02X\n", ps_store_frame->winsize_cnt);
1598
1599 /* Correct frame is received, so remove the
1600 stored i frame info for the acknowledged frames */
1601 no_of_del_frames = phLlcNfc_H_UpdateIFrameList (ps_frame_info,
1602 &(ps_frame_info->s_send_store));
1603
1604 PH_LLCNFC_DEBUG("NS START POS AFTER DEL : 0x%02X\n", ps_store_frame->start_pos);
1605 PH_LLCNFC_DEBUG("WIN SIZE AFTER DEL : 0x%02X\n", ps_store_frame->winsize_cnt);
1606
1607 #if 0
1608 prev_win_count = ps_frame_info->s_send_store.winsize_cnt;
1609 #endif /* #if 0 */
1610
1611 /* Pend the read */
1612 result = phLlcNfc_Interface_Read (psLlcCtxt,
1613 PH_LLCNFC_READWAIT_OFF,
1614 &(ps_recv_pkt->s_llcbuf.llc_length_byte),
1615 (uint8_t)PH_LLCNFC_BYTES_INIT_READ);
1616 switch(cmdtype)
1617 {
1618 case phLlcNfc_e_rr:
1619 case phLlcNfc_e_rej:
1620 {
1621 /* RR frame received */
1622 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames);
1623
1624 if (phLlcNfc_e_rr == cmdtype)
1625 {
1626 ps_frame_info->recv_error_count = 0;
1627 ps_frame_info->send_error_count = 0;
1628 }
1629 else
1630 {
1631 ps_frame_info->recv_error_count = (uint8_t)
1632 (ps_frame_info->recv_error_count + 1);
1633 }
1634
1635 if (ps_frame_info->recv_error_count >= RECV_ERROR_FRAME_COUNT)
1636 {
1637 /* Do nothing */
1638 }
1639 else if (NFCSTATUS_BUSY == PHNFCSTATUS(ps_frame_info->write_status))
1640 {
1641 result = phLlcNfc_H_WriteWaitCall (psLlcCtxt);
1642 }
1643 else
1644 {
1645 if (
1646 (ps_frame_info->n_s != ((ps_store_frame->winsize_cnt +
1647 ps_store_frame->start_pos) % PH_LLCNFC_MOD_NS_NR))
1648 )
1649 {
1650 /* If user has sent a frame and DAL write is busy, then
1651 it has to be sent */
1652 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame);
1653 }
1654 }
1655
1656 if ((0 != psLlcCtxt->send_cb_len) &&
1657 (ps_store_frame->winsize_cnt < ps_frame_info->window_size))
1658 {
1659 /* Due to the window size count (i.e., count has reached
1660 the limit), send completion was not sent for the previous
1661 send from the upper layer. So to allow next send from the
1662 upper layer, send completion is called */
1663 compinfo.length = (uint16_t)psLlcCtxt->send_cb_len;
1664 compinfo.status = NFCSTATUS_SUCCESS;
1665
1666 if (NULL != psLlcCtxt->cb_for_if.send_complete)
1667 {
1668 psLlcCtxt->send_cb_len = 0;
1669 /* Call the send callback, if the window size
1670 count becomes less than actual window size */
1671 psLlcCtxt->cb_for_if.send_complete (
1672 psLlcCtxt->cb_for_if.pif_ctxt,
1673 psLlcCtxt->phwinfo, &compinfo);
1674 }
1675 }
1676 break;
1677 }
1678
1679 #if 0
1680 case phLlcNfc_e_rej:
1681 {
1682 ps_frame_info->recv_error_count = (uint8_t)
1683 (ps_frame_info->recv_error_count + 1);
1684 /* RR frame received */
1685 phLlcNfc_StopTimers (PH_LLCNFC_GUARDTIMER, no_of_del_frames);
1686
1687 if (ps_frame_info->recv_error_count < RECV_ERROR_FRAME_COUNT)
1688 {
1689 /* Below check is added because if PN544 sends REJ to a frame, but
1690 the next frame has already been sent from PN544, then
1691 Send the user I frame */
1692 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_frame);
1693 }
1694 break;
1695 }
1696 #endif /* #if 0 */
1697
1698 case phLlcNfc_e_rnr:
1699 {
1700 phLlcNfc_StopAllTimers ();
1701 ps_frame_info->recv_error_count = (uint8_t)
1702 (ps_frame_info->recv_error_count + 1);
1703 break;
1704 }
1705
1706 case phLlcNfc_e_srej:
1707 default:
1708 {
1709 ps_frame_info->recv_error_count = (uint8_t)
1710 (ps_frame_info->recv_error_count + 1);
1711 result = PHNFCSTVAL (CID_NFC_LLC,
1712 NFCSTATUS_INVALID_FORMAT);
1713 break;
1714 }
1715 }
1716
1717 if (ps_frame_info->recv_error_count >= RECV_ERROR_FRAME_COUNT)
1718 {
1719 #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION
1720
1721 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt);
1722
1723 #else /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */
1724
1725 PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count);
1726 /* Raise the exception for CRC error received from the */
1727 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC,
1728 NFCSTATUS_BOARD_COMMUNICATION_ERROR);
1729 #if 0
1730 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
1731 #endif /* #if 0 */
1732 /* Resend done, no answer from the device */
1733 psLlcCtxt->cb_for_if.notify (
1734 psLlcCtxt->cb_for_if.pif_ctxt,
1735 psLlcCtxt->phwinfo,
1736 NFC_NOTIFY_DEVICE_ERROR,
1737 ¬ifyinfo);
1738
1739 #endif /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */
1740 }
1741
1742 return ;
1743 }
1744
1745
1746 void
phLlcNfc_H_ComputeCrc(uint8_t * pData,uint8_t length,uint8_t * pCrc1,uint8_t * pCrc2)1747 phLlcNfc_H_ComputeCrc(
1748 uint8_t *pData,
1749 uint8_t length,
1750 uint8_t *pCrc1,
1751 uint8_t *pCrc2
1752 )
1753 {
1754 uint8_t crc_byte = 0,
1755 index = 0;
1756 uint16_t crc = 0;
1757
1758 #ifdef CRC_A
1759 crc = 0x6363; /* ITU-V.41 */
1760 #else
1761 crc = 0xFFFF; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
1762 #endif /* #ifdef CRC_A */
1763
1764 do
1765 {
1766 crc_byte = pData[index];
1767 phLlcNfc_H_UpdateCrc(crc_byte, &crc);
1768 index++;
1769 } while (index < length);
1770
1771 #ifndef INVERT_CRC
1772 crc = ~crc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
1773 #endif /* #ifndef INVERT_CRC */
1774
1775 *pCrc1 = (uint8_t) (crc & 0xFF);
1776 *pCrc2 = (uint8_t) ((crc >> 8) & 0xFF);
1777 return;
1778 }
1779
1780 static
1781 void
phLlcNfc_H_UpdateCrc(uint8_t crcByte,uint16_t * pCrc)1782 phLlcNfc_H_UpdateCrc(
1783 uint8_t crcByte,
1784 uint16_t *pCrc
1785 )
1786 {
1787 crcByte = (crcByte ^ (uint8_t)((*pCrc) & 0x00FF));
1788 crcByte = (crcByte ^ (uint8_t)(crcByte << 4));
1789 *pCrc = (*pCrc >> 8) ^ ((uint16_t)crcByte << 8) ^
1790 ((uint16_t)crcByte << 3) ^
1791 ((uint16_t)crcByte >> 4);
1792 }
1793
1794 NFCSTATUS
phLlcNfc_H_StoreIFrame(phLlcNfc_StoreIFrame_t * psList,phLlcNfc_LlcPacket_t sPacketInfo)1795 phLlcNfc_H_StoreIFrame (
1796 phLlcNfc_StoreIFrame_t *psList,
1797 phLlcNfc_LlcPacket_t sPacketInfo
1798 )
1799 {
1800 NFCSTATUS result = NFCSTATUS_SUCCESS;
1801 uint8_t ns_index = 0,
1802 llc_header = 0;
1803
1804 if ((NULL == psList) || (0 == sPacketInfo.llcbuf_len) ||
1805 (PH_LLCNFC_I_HEADER_INIT !=
1806 (sPacketInfo.s_llcbuf.sllcpayload.llcheader &
1807 PH_LLCNFC_I_FRM_HEADER_MASK)))
1808 {
1809 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);
1810 }
1811 else
1812 {
1813 /* Get the index from the start index */
1814 if(psList->winsize_cnt > 0)
1815 {
1816 ns_index = (uint8_t)((psList->start_pos + psList->winsize_cnt) %
1817 PH_LLCNFC_MOD_NS_NR);
1818 }
1819 else
1820 {
1821 ns_index = psList->start_pos;
1822 }
1823
1824 llc_header = (uint8_t)(PH_LLCNFC_I_HEADER_INIT | (ns_index <<
1825 PH_LLCNFC_NS_START_BIT_POS));
1826 sPacketInfo.s_llcbuf.sllcpayload.llcheader = llc_header;
1827
1828 (void)memcpy (&(psList->s_llcpacket[ns_index]),
1829 &(sPacketInfo), sizeof(phLlcNfc_LlcPacket_t));
1830
1831 /* This variable says that LLC has to send complete
1832 callback for stored I frame */
1833 psList->s_llcpacket[ns_index].frame_to_send = invalid_frame;
1834
1835 psList->winsize_cnt++;
1836 }
1837 return result;
1838 }
1839
1840 static
1841 void
phLlcNfc_H_DeleteIFrame(phLlcNfc_StoreIFrame_t * psList)1842 phLlcNfc_H_DeleteIFrame (
1843 phLlcNfc_StoreIFrame_t *psList
1844 )
1845 {
1846 if (NULL != psList)
1847 {
1848 (void)memset( &(psList->s_llcpacket[psList->start_pos]),
1849 0, sizeof(phLlcNfc_LlcPacket_t));
1850
1851 /* Go to next N(S) position */
1852 psList->start_pos = ((psList->start_pos + 1) %
1853 PH_LLCNFC_MOD_NS_NR);
1854
1855 if (psList->winsize_cnt > 0)
1856 {
1857 psList->winsize_cnt--;
1858 }
1859 }
1860 }
1861
1862 static
1863 NFCSTATUS
phLlcNfc_H_IFrameList_Peek(phLlcNfc_StoreIFrame_t * psList,phLlcNfc_LlcPacket_t ** psPacketinfo,uint8_t position)1864 phLlcNfc_H_IFrameList_Peek (
1865 phLlcNfc_StoreIFrame_t *psList,
1866 phLlcNfc_LlcPacket_t **psPacketinfo,
1867 uint8_t position
1868 )
1869 {
1870 NFCSTATUS result = NFCSTATUS_SUCCESS;
1871 uint8_t index = 0;
1872
1873 *psPacketinfo = NULL;
1874 if ((NULL != psList) && (psList->winsize_cnt > 0))
1875 {
1876 result = NFCSTATUS_SUCCESS;
1877 if ((position < (psList->start_pos + psList->winsize_cnt)) ||
1878 (DEFAULT_PACKET_INPUT == position))
1879 {
1880 index = (uint8_t)((DEFAULT_PACKET_INPUT == position) ?
1881 psList->start_pos : position);
1882 *psPacketinfo = &(psList->s_llcpacket[index]);
1883 }
1884 }
1885
1886 return result;
1887 }
1888
1889 NFCSTATUS
phLlcNfc_H_ProRecvFrame(phLlcNfc_Context_t * psLlcCtxt)1890 phLlcNfc_H_ProRecvFrame (
1891 phLlcNfc_Context_t *psLlcCtxt
1892 )
1893 {
1894 NFCSTATUS result = PHNFCSTVAL(CID_NFC_LLC,
1895 NFCSTATUS_INVALID_PARAMETER);
1896 phLlcNfc_FrameType_t frame_type = phLlcNfc_eErr_frame;
1897 #ifdef LLC_DATA_BYTES
1898 uint8_t *print_buf = (uint8_t *)
1899 &(psLlcCtxt->s_frameinfo.s_recvpacket.s_llcbuf);
1900 uint8_t buf_len =
1901 psLlcCtxt->s_frameinfo.s_recvpacket.llcbuf_len;
1902 PH_LLCNFC_STRING("** Response ");
1903
1904 #endif /* LLC_DATA_BYTES */
1905 if (NULL != psLlcCtxt)
1906 {
1907 result = NFCSTATUS_SUCCESS;
1908 /* Get the received frame type */
1909 frame_type = phLlcNfc_H_ChkGetLlcFrameType(
1910 psLlcCtxt->s_frameinfo.s_recvpacket.s_llcbuf.sllcpayload.llcheader);
1911
1912 /* Depending on the received frame type, process the
1913 received buffer */
1914 switch(frame_type)
1915 {
1916 case phLlcNfc_eU_frame:
1917 {
1918 PH_LLCNFC_PRINT("U frame received \n");
1919 PH_LLCNFC_STRING("U frame ");
1920 PH_LLCNFC_PRINT_DATA(print_buf, buf_len);
1921 PH_LLCNFC_STRING(";\n");
1922 result = phLlcNfc_H_ProcessUFrame(psLlcCtxt);
1923 break;
1924 }
1925 case phLlcNfc_eI_frame:
1926 {
1927 PH_LLCNFC_PRINT("I frame received \n");
1928 PH_LLCNFC_STRING("I frame ");
1929 PH_LLCNFC_PRINT_DATA(print_buf, buf_len);
1930 PH_LLCNFC_STRING(";\n");
1931 phLlcNfc_H_ProcessIFrame(psLlcCtxt);
1932 break;
1933 }
1934 case phLlcNfc_eS_frame:
1935 {
1936 PH_LLCNFC_PRINT("S frame received \n");
1937 PH_LLCNFC_STRING("S frame ");
1938 PH_LLCNFC_PRINT_DATA(print_buf, buf_len);
1939 PH_LLCNFC_STRING(";\n");
1940 phLlcNfc_H_ProcessSFrame(psLlcCtxt);
1941 break;
1942 }
1943 case phLlcNfc_eErr_frame:
1944 default:
1945 {
1946 PH_LLCNFC_PRINT("Error frame received \n");
1947 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_FORMAT);
1948 break;
1949 }
1950 }
1951
1952 }
1953 return result;
1954 }
1955
1956 #ifdef CRC_ERROR_REJ
1957 NFCSTATUS
phLlcNfc_H_SendRejectFrame(phLlcNfc_Context_t * psLlcCtxt)1958 phLlcNfc_H_SendRejectFrame(
1959 phLlcNfc_Context_t *psLlcCtxt
1960 )
1961 {
1962 NFCSTATUS result = NFCSTATUS_SUCCESS;
1963 phLlcNfc_LlcPacket_t s_packet_info = {0};
1964
1965 result = phLlcNfc_H_CreateSFramePayload(
1966 &(psLlcCtxt->s_frameinfo),
1967 &(s_packet_info),
1968 phLlcNfc_e_rej);
1969 /* Send the "S" frame to the lower layer */
1970 result = phLlcNfc_Interface_Write(psLlcCtxt,
1971 (uint8_t *)&(s_packet_info.s_llcbuf),
1972 (uint32_t)(s_packet_info.llcbuf_len));
1973
1974 if (NFCSTATUS_PENDING == result)
1975 {
1976 /* Increment the retry count of the reject frame */
1977 psLlcCtxt->s_frameinfo.recv_error_count =
1978 (psLlcCtxt->s_frameinfo.recv_error_count + 1);
1979 }
1980
1981
1982 return result;
1983 }
1984 #endif /* #ifdef CRC_ERROR_REJ */
1985
1986 static
1987 void
phLlcNfc_H_ResetFrameInfo(phLlcNfc_Context_t * psLlcCtxt)1988 phLlcNfc_H_ResetFrameInfo (
1989 phLlcNfc_Context_t *psLlcCtxt
1990 )
1991 {
1992 uint8_t i = 0,
1993 win_cnt = 0,
1994 pos = 0,
1995 while_exit = FALSE,
1996 index_flag = FALSE;
1997 phLlcNfc_StoreIFrame_t *ps_send_store = NULL;
1998 phLlcNfc_Buffer_t *ps_buffer = NULL;
1999
2000 ps_send_store = &(psLlcCtxt->s_frameinfo.s_send_store);
2001 win_cnt = ps_send_store->winsize_cnt;
2002 pos = ps_send_store->start_pos;
2003 PH_LLCNFC_PRINT ("\n\nLLC : phLlcNfc_H_ResetFrameInfo called\n\n");
2004 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->start_pos %08X\n", ps_send_store->start_pos);
2005 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->winsize_cnt before reset %08X\n", ps_send_store->winsize_cnt);
2006
2007
2008 if (0 != pos)
2009 {
2010 /* If the start position of the ns = 0, then
2011 no need to shift the stored llc data,
2012 Else it has to be shifted to the first
2013 index of the array */
2014 if(TRUE == ((pos + win_cnt) /
2015 PH_LLCNFC_MAX_I_FRAME_STORE))
2016 {
2017 /* 'i' is the array index, So to store data in the array,
2018 windows size count shall be subtracted by 1 */
2019 i = (win_cnt - 1);
2020 /* if window size > 1 and ns for 2 frames are 7 and 0, then
2021 to reset the ns index to 0, the frames are copied from
2022 the reverse order, so to do it a flag is declared */
2023 index_flag = TRUE;
2024 pos = (((pos - 1) + win_cnt) % PH_LLCNFC_MAX_I_FRAME_STORE);
2025 }
2026
2027 while (FALSE == while_exit)
2028 {
2029 (void)memcpy ((void *)&(ps_send_store->s_llcpacket[i]),
2030 (void *)&(ps_send_store->s_llcpacket[pos]),
2031 sizeof (phLlcNfc_LlcPacket_t));
2032
2033 ps_send_store->s_llcpacket[i].frame_to_send = invalid_frame;
2034
2035 ps_buffer = &(ps_send_store->s_llcpacket[i].s_llcbuf);
2036 /* change n(s) value */
2037 ps_buffer->sllcpayload.llcheader = (uint8_t)
2038 (PH_LLCNFC_I_HEADER_INIT |
2039 (i << PH_LLCNFC_NS_START_BIT_POS));
2040 if(TRUE == index_flag)
2041 {
2042 if(0 == i)
2043 {
2044 while_exit = TRUE;
2045 }
2046 else
2047 {
2048 i = ((i - 1) % PH_LLCNFC_MAX_I_FRAME_STORE);
2049 if (0 == pos)
2050 {
2051 pos = (PH_LLCNFC_MAX_I_FRAME_STORE - 1);
2052 }
2053 else
2054 {
2055 pos = ((pos - 1) % PH_LLCNFC_MAX_I_FRAME_STORE);
2056 }
2057 }
2058 }
2059 else
2060 {
2061 if (i >= win_cnt)
2062 {
2063 while_exit = TRUE;
2064 }
2065 else
2066 {
2067 i = ((i + 1) % PH_LLCNFC_MAX_I_FRAME_STORE);
2068 pos = ((pos + 1) % PH_LLCNFC_MAX_I_FRAME_STORE);
2069 }
2070
2071 }
2072 }
2073 }
2074 psLlcCtxt->s_timerinfo.guard_to_count = 0;
2075 psLlcCtxt->s_timerinfo.timer_flag = 0;
2076 ps_send_store->start_pos = 0;
2077 psLlcCtxt->s_frameinfo.n_r = psLlcCtxt->s_frameinfo.n_s = 0;
2078 if (ps_send_store->winsize_cnt > 0)
2079 {
2080 psLlcCtxt->s_frameinfo.rejected_ns = 0;
2081 }
2082 else
2083 {
2084 psLlcCtxt->s_frameinfo.rejected_ns = DEFAULT_PACKET_INPUT;
2085 }
2086
2087 PH_LLCNFC_DEBUG ("\n\nLLC : ps_send_store->winsize_cnt after reset %08X\n", ps_send_store->winsize_cnt);
2088 return;
2089 }
2090
2091 NFCSTATUS
phLlcNfc_H_WriteWaitCall(phLlcNfc_Context_t * psLlcCtxt)2092 phLlcNfc_H_WriteWaitCall (
2093 phLlcNfc_Context_t *psLlcCtxt
2094 )
2095 {
2096 NFCSTATUS result = NFCSTATUS_SUCCESS;
2097 phLlcNfc_StoreIFrame_t *ps_store_info = NULL;
2098 phLlcNfc_Frame_t *ps_frame_info = NULL;
2099
2100 ps_frame_info = &(psLlcCtxt->s_frameinfo);
2101 ps_store_info = &(ps_frame_info->s_send_store);
2102
2103 PH_LLCNFC_PRINT ("\nLLC : phLlcNfc_H_WriteWaitCall call ..\n");
2104 PH_LLCNFC_DEBUG ("\n\nLLC : ps_frame_info->write_wait_call before call %08X\n", ps_frame_info->write_wait_call);
2105
2106 ps_frame_info->write_status = NFCSTATUS_PENDING;
2107 switch (ps_frame_info->write_wait_call)
2108 {
2109 case user_i_frame:
2110 {
2111 ps_frame_info->write_wait_call = invalid_frame;
2112 result = phLlcNfc_H_SendUserIFrame (psLlcCtxt, ps_store_info);
2113 break;
2114 }
2115
2116 case resend_i_frame:
2117 {
2118 ps_frame_info->write_wait_call = invalid_frame;
2119 result = phLlcNfc_H_SendTimedOutIFrame (psLlcCtxt, ps_store_info, 0);
2120 break;
2121 }
2122
2123 case rejected_i_frame:
2124 {
2125 ps_frame_info->write_wait_call = invalid_frame;
2126 result = phLlcNfc_H_SendRejectedIFrame (psLlcCtxt, ps_store_info,
2127 ps_frame_info->rejected_ns);
2128 break;
2129 }
2130
2131 case resend_s_frame:
2132 case reject_s_frame:
2133 case resend_rej_s_frame:
2134 {
2135 ps_frame_info->write_wait_call = invalid_frame;
2136 break;
2137 }
2138
2139 case u_rset_frame:
2140 {
2141 ps_frame_info->write_wait_call = invalid_frame;
2142 result = phLlcNfc_H_SendRSETFrame (psLlcCtxt);
2143 break;
2144 }
2145
2146 default :
2147 {
2148 ps_frame_info->write_wait_call = invalid_frame;
2149 break;
2150 }
2151 }
2152
2153 PH_LLCNFC_DEBUG ("\n\nLLC : ps_frame_info->write_wait_call after call %08X\n", ps_frame_info->write_wait_call);
2154 PH_LLCNFC_PRINT ("\nLLC : phLlcNfc_H_WriteWaitCall end ..\n");
2155 return result;
2156 }
2157
2158 NFCSTATUS
phLlcNfc_H_SendRSETFrame(phLlcNfc_Context_t * psLlcCtxt)2159 phLlcNfc_H_SendRSETFrame (
2160 phLlcNfc_Context_t *psLlcCtxt
2161 )
2162 {
2163 NFCSTATUS result = NFCSTATUS_SUCCESS;
2164 phLlcNfc_LlcPacket_t s_packet_info;
2165 phLlcNfc_Frame_t *ps_frame_info = NULL;
2166
2167 ps_frame_info = &(psLlcCtxt->s_frameinfo);
2168
2169 result = phLlcNfc_H_CreateUFramePayload(psLlcCtxt,
2170 &(s_packet_info),
2171 &(s_packet_info.llcbuf_len),
2172 phLlcNfc_e_rset);
2173
2174 if (NFCSTATUS_SUCCESS == result)
2175 {
2176 /* Call DAL write */
2177 result = phLlcNfc_Interface_Write(psLlcCtxt,
2178 (uint8_t*)&(s_packet_info.s_llcbuf),
2179 (uint32_t)s_packet_info.llcbuf_len);
2180 }
2181
2182 ps_frame_info->write_status = result;
2183 if (NFCSTATUS_PENDING == result)
2184 {
2185 /* Start the timer */
2186 result = phLlcNfc_StartTimers (PH_LLCNFC_CONNECTIONTIMER, 0);
2187 if (NFCSTATUS_SUCCESS == result)
2188 {
2189 ps_frame_info->sent_frame_type = u_rset_frame;
2190 result = NFCSTATUS_PENDING;
2191 }
2192 }
2193 else
2194 {
2195 ps_frame_info->write_wait_call = u_rset_frame;
2196 }
2197
2198 return result;
2199 }
2200
2201
2202