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 ****************************/
58static
59void
60phLlcNfc_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*/
80static
81NFCSTATUS
82phLlcNfc_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*/
100static
101void
102phLlcNfc_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*/
120static
121uint8_t
122phLlcNfc_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*/
140static
141void
142phLlcNfc_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*/
161static
162phLlcNfc_FrameType_t
163phLlcNfc_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*/
181static
182NFCSTATUS
183phLlcNfc_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*/
204static
205NFCSTATUS
206phLlcNfc_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*/
224static
225void
226phLlcNfc_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*/
244NFCSTATUS
245phLlcNfc_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*/
263void
264phLlcNfc_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
274void 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
298void
299phLlcNfc_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
311NFCSTATUS
312phLlcNfc_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
413NFCSTATUS
414phLlcNfc_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
481NFCSTATUS
482phLlcNfc_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
567static
568phLlcNfc_FrameType_t
569phLlcNfc_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
607static
608NFCSTATUS
609phLlcNfc_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
661static
662uint8_t
663phLlcNfc_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
731NFCSTATUS
732phLlcNfc_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
834NFCSTATUS
835phLlcNfc_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
976NFCSTATUS
977phLlcNfc_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
1166void
1167phLlcNfc_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                            &notifyinfo);
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
1456static
1457NFCSTATUS
1458phLlcNfc_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                                &notifyinfo);
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
1571static
1572void
1573phLlcNfc_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                        &notifyinfo);
1738
1739#endif /* #ifdef LLC_RSET_INSTEAD_OF_EXCEPTION */
1740    }
1741
1742    return ;
1743}
1744
1745
1746void
1747phLlcNfc_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
1780static
1781void
1782phLlcNfc_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
1794NFCSTATUS
1795phLlcNfc_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
1840static
1841void
1842phLlcNfc_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
1862static
1863NFCSTATUS
1864phLlcNfc_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
1889NFCSTATUS
1890phLlcNfc_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
1957NFCSTATUS
1958phLlcNfc_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
1986static
1987void
1988phLlcNfc_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
2091NFCSTATUS
2092phLlcNfc_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
2158NFCSTATUS
2159phLlcNfc_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