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                             &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 
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                                 &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 
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                         &notifyinfo);
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