code update
[adaptation/devices/nfc-plugin-nxp.git] / src / phLlcNfc_Interface.c
1 /*\r
2  * Copyright (C) 2010 NXP Semiconductors\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /*!\r
18 * \file  phLlcNfc_Interface.c\r
19 * \brief Interface for both LLC and transport layer\r
20 *\r
21 * Project: NFC-FRI-1.1\r
22 *\r
23 * $Date: Tue Jun  1 14:41:26 2010 $\r
24 * $Author: ing02260 $\r
25 * $Revision: 1.75 $\r
26 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $\r
27 *\r
28 */\r
29 \r
30 /*************************** Includes *******************************/\r
31 #include <phNfcTypes.h>\r
32 #include <phNfcStatus.h>\r
33 #include <phOsalNfc.h>\r
34 #include <phNfcInterface.h>\r
35 #include <phLlcNfc_DataTypes.h>\r
36 #include <phLlcNfc_Timer.h>\r
37 #include <phLlcNfc_Frame.h>\r
38 #include <phLlcNfc.h>\r
39 #include <phLlcNfc_Interface.h>\r
40 #ifdef PH_LLCNFC_STUB\r
41 #include <phDalNfc_Stub.h>\r
42 #endif\r
43 #ifdef PH_LLCNFC_DALINT\r
44 #include <phDal4Nfc.h>\r
45 #endif\r
46 #define LOG_TAG "NFC-LLC"\r
47 \r
48 #include <utils/Log.h>\r
49 /*********************** End of includes ****************************/\r
50 \r
51 /***************************** Macros *******************************/\r
52 #define PH_LLCNFC_APPEND_LEN                        (4)\r
53 #define LLC_NS_FRAME_HEADER_MASK                    (0x38U)\r
54 /************************ End of macros *****************************/\r
55 \r
56 /*********************** Local functions ****************************/\r
57 static\r
58 void \r
59 phLlcNfc_WrResp_Cb(\r
60                    void                        *pContext, \r
61                    void                        *pHwInfo, \r
62                    phNfc_sTransactionInfo_t    *pCompInfo\r
63                    );\r
64 \r
65 static\r
66 void \r
67 phLlcNfc_RdResp_Cb(\r
68                    void                        *pContext,\r
69                    void                        *pHwInfo, \r
70                    phNfc_sTransactionInfo_t    *pCompInfo\r
71                    );\r
72 \r
73 /******************** End of Local functions ************************/\r
74 \r
75 /********************** Global variables ****************************/\r
76 int libnfc_llc_error_count = 0;\r
77 \r
78 /******************** End of Global Variables ***********************/\r
79 \r
80 NFCSTATUS \r
81 phLlcNfc_Interface_Register(\r
82     phLlcNfc_Context_t          *psLlcCtxt, \r
83     phNfcLayer_sCfg_t           *psIFConfig\r
84 )\r
85 {\r
86     NFCSTATUS                   result = NFCSTATUS_SUCCESS;\r
87     phNfcIF_sCallBack_t         if_cb = {0,0,0,0};\r
88     phNfcIF_sReference_t        sreference = {0,0,0};\r
89     \r
90     if ((NULL == psLlcCtxt) || (NULL == psIFConfig))\r
91     {\r
92         result = PHNFCSTVAL(CID_NFC_LLC, \r
93                             NFCSTATUS_INVALID_PARAMETER);\r
94     }\r
95     else \r
96     {\r
97         result = NFCSTATUS_SUCCESS;\r
98         if_cb.notify = NULL;\r
99         if_cb.receive_complete = (pphNfcIF_Transact_Completion_CB_t)&phLlcNfc_RdResp_Cb;\r
100         if_cb.send_complete = (pphNfcIF_Transact_Completion_CB_t)&phLlcNfc_WrResp_Cb;\r
101         if_cb.pif_ctxt = psLlcCtxt; \r
102         sreference.plower_if = &(psLlcCtxt->lower_if);\r
103         result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);\r
104 #ifdef PH_LLCNFC_STUB\r
105         result = phDalNfc_StubRegister(&sreference, if_cb, psIFConfig->layer_next);\r
106 #endif /* #ifdef PH_LLCNFC_STUB */\r
107 #ifdef PH_LLCNFC_DALINT\r
108         result = phDal4Nfc_Register(&sreference, if_cb, psIFConfig->layer_next);\r
109 #else\r
110         if ((NULL != psIFConfig->layer_next) && \r
111             (NULL != psIFConfig->layer_next->layer_registry))\r
112         {\r
113             result = psIFConfig->layer_next->layer_registry(\r
114                         &sreference, \r
115                         if_cb, \r
116                         (void *)&psIFConfig[(psIFConfig->layer_index - 1)]);\r
117         }\r
118 #endif /* #ifdef PH_LLCNFC_DALINT */\r
119     }\r
120     PH_LLCNFC_DEBUG("Llc Dal Interface Register result : 0x%x\n", result);\r
121     return result;\r
122 }\r
123  \r
124 NFCSTATUS \r
125 phLlcNfc_Interface_Init(\r
126     phLlcNfc_Context_t      *psLlcCtxt\r
127 )\r
128 {\r
129     /*\r
130         1. Get the pointer of the main llc context\r
131     */\r
132     NFCSTATUS   result = NFCSTATUS_SUCCESS;\r
133     if ((NULL == psLlcCtxt) ||  \r
134         (NULL == psLlcCtxt->lower_if.init))\r
135     {\r
136         result = PHNFCSTVAL(CID_NFC_LLC, \r
137                             NFCSTATUS_INVALID_PARAMETER);\r
138     }\r
139     else\r
140     {        \r
141         /* Initialise the main context */\r
142         result = psLlcCtxt->lower_if.init(  psLlcCtxt->lower_if.pcontext, \r
143                                             psLlcCtxt->phwinfo);        \r
144     }\r
145     PH_LLCNFC_DEBUG("Llc Dal Interface Init result : 0x%x\n", result);\r
146     return result;\r
147 }\r
148 \r
149 NFCSTATUS \r
150 phLlcNfc_Interface_Read(\r
151     phLlcNfc_Context_t      *psLlcCtxt, \r
152     uint8_t                 readWaitOn, \r
153     uint8_t                 *pLlcBuffer, \r
154     uint32_t                llcBufferLength\r
155 )\r
156 {\r
157     NFCSTATUS   result = NFCSTATUS_PENDING;\r
158     /*\r
159         1. Call DAL or TL read with "phLlcNfc_LlcTl_RdResp_Cb" as \r
160             callback function\r
161     */\r
162     PH_LLCNFC_PRINT("Llc Dal Interface Read called\n");\r
163     if ((NULL == psLlcCtxt) || (NULL == pLlcBuffer) || \r
164         (0 == llcBufferLength) || (NULL == psLlcCtxt->lower_if.receive) || \r
165         (readWaitOn > PH_LLCNFC_READWAIT_ON))\r
166     {\r
167         result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);\r
168     }\r
169     else if (PH_LLCNFC_READPEND_FLAG_OFF != \r
170             psLlcCtxt->s_frameinfo.read_pending)\r
171     {\r
172         /* do nothing */\r
173     } \r
174     else \r
175     {\r
176         if (PH_LLCNFC_READWAIT_OFF == readWaitOn)\r
177         {   \r
178             result = psLlcCtxt->lower_if.receive(\r
179                             psLlcCtxt->lower_if.pcontext, \r
180                             psLlcCtxt->phwinfo, \r
181                             pLlcBuffer, \r
182                             (uint8_t)llcBufferLength);\r
183         } \r
184         else\r
185         {\r
186             result = psLlcCtxt->lower_if.receive_wait(\r
187                             psLlcCtxt->lower_if.pcontext, \r
188                             psLlcCtxt->phwinfo, \r
189                             pLlcBuffer, \r
190                             (uint16_t)llcBufferLength);\r
191         }\r
192 \r
193         if(NFCSTATUS_PENDING == result)\r
194         {\r
195             if (PH_LLCNFC_READPEND_ONE_BYTE == llcBufferLength)\r
196             {\r
197                 psLlcCtxt->s_frameinfo.read_pending = \r
198                                     PH_LLCNFC_READPEND_ONE_BYTE;\r
199             }\r
200             else\r
201             {\r
202                 psLlcCtxt->s_frameinfo.read_pending = \r
203                                     PH_LLCNFC_READPEND_REMAIN_BYTE;\r
204             }\r
205         }\r
206     }\r
207     PH_LLCNFC_DEBUG("Llc Dal Interface Read result : 0x%x\n", result);\r
208     return result;\r
209 }\r
210 \r
211 NFCSTATUS \r
212 phLlcNfc_Interface_Write(\r
213     phLlcNfc_Context_t      *psLlcCtxt,\r
214     uint8_t             *pLlcBuffer, \r
215     uint32_t            llcBufferLength\r
216 )\r
217 {\r
218     NFCSTATUS   result = NFCSTATUS_PENDING;\r
219 \r
220     PH_LLCNFC_PRINT("Llc Dal Interface Write called\n");\r
221     /*\r
222         1. Call DAL or TL write with "phLlcNfc_LlcTl_WrResp_Cb" as \r
223             callback function\r
224     */\r
225     if ((NULL == psLlcCtxt) || (NULL == pLlcBuffer) || \r
226         (0 == llcBufferLength) || \r
227         (NULL == psLlcCtxt->lower_if.send))\r
228     {\r
229         PH_LLCNFC_DEBUG ("psLlcCtxt : 0x%p\n", psLlcCtxt);\r
230         PH_LLCNFC_DEBUG ("pLlcBuffer : 0x%p\n", pLlcBuffer);\r
231         PH_LLCNFC_DEBUG ("llcBufferLength : 0x%08X\n", llcBufferLength);\r
232         result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);\r
233     }\r
234     else \r
235     {        \r
236         PH_LLCNFC_PRINT("Buffer to be send to Dal : \n");\r
237         PH_LLCNFC_PRINT_BUFFER(pLlcBuffer, llcBufferLength);\r
238 \r
239         if ((TRUE == psLlcCtxt->s_frameinfo.write_pending) || \r
240             (PH_LLCNFC_READPEND_REMAIN_BYTE == \r
241             psLlcCtxt->s_frameinfo.read_pending))\r
242         {\r
243             result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_BUSY);\r
244         }\r
245         else\r
246         {\r
247 #ifdef LLC_DATA_BYTES\r
248 \r
249             PH_LLCNFC_PRINT_DATA (pLlcBuffer, llcBufferLength);\r
250             PH_LLCNFC_STRING (";\n");\r
251     \r
252 #endif /* LLC_DATA_BYTES */\r
253 \r
254             psLlcCtxt->s_frameinfo.s_llcpacket.llcbuf_len = (uint8_t)llcBufferLength;\r
255             (void)memcpy ((void *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf),\r
256                         (void *)pLlcBuffer, llcBufferLength);\r
257 \r
258             result = psLlcCtxt->lower_if.send(psLlcCtxt->lower_if.pcontext, \r
259                                                 psLlcCtxt->phwinfo, \r
260                                                 (uint8_t *)&(psLlcCtxt->s_frameinfo.s_llcpacket.s_llcbuf),\r
261                                                 (uint16_t)llcBufferLength);\r
262             if(NFCSTATUS_PENDING == result)\r
263             {\r
264                 psLlcCtxt->s_frameinfo.write_pending = TRUE;\r
265 #ifdef PIGGY_BACK\r
266                 /* Stop the ACK timer, as the ACK or I frame is sent */\r
267                 phLlcNfc_StopTimers (PH_LLCNFC_ACKTIMER, 0);\r
268                 /* ACK is sent, so reset the response received count */\r
269                 psLlcCtxt->s_frameinfo.resp_recvd_count = 0;\r
270 #endif /* #ifdef PIGGY_BACK */\r
271             }\r
272         }\r
273     }\r
274     PH_LLCNFC_DEBUG("Llc Dal Interface Write result : 0x%x\n", result);\r
275     return result;\r
276 }\r
277 \r
278 static\r
279 void \r
280 phLlcNfc_WrResp_Cb(\r
281     void                        *pContext, \r
282     void                        *pHwInfo, \r
283     phNfc_sTransactionInfo_t    *pCompInfo\r
284 )\r
285 {\r
286     /* \r
287         1. Check the window size, if window size = windows\r
288         1. Call the send callback, which has been registered by upper \r
289             layer\r
290     */\r
291     NFCSTATUS                   result = NFCSTATUS_SUCCESS;\r
292     phLlcNfc_Context_t          *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;\r
293     phLlcNfc_Frame_t            *ps_frame_info = NULL;\r
294     phLlcNfc_LlcPacket_t        *ps_recv_pkt = NULL;\r
295     phLlcNfc_StoreIFrame_t      *ps_store_frame = NULL;\r
296     phNfc_sCompletionInfo_t     notifyinfo = {0,0,0};\r
297     uint8_t                     count = 0;\r
298 \r
299     PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB CALLED\n\n");\r
300     \r
301     if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo))\r
302     {\r
303         ps_llc_ctxt->s_frameinfo.write_pending = FALSE;\r
304 \r
305         PHNFC_UNUSED_VARIABLE(result);\r
306         \r
307         if(NFCSTATUS_SUCCESS == pCompInfo->status)\r
308         {\r
309             ps_frame_info = &(ps_llc_ctxt->s_frameinfo);\r
310             ps_recv_pkt = &(ps_frame_info->s_recvpacket);\r
311             ps_store_frame = &(ps_frame_info->s_send_store);\r
312             count = ps_frame_info->s_send_store.start_pos;\r
313 \r
314             PH_LLCNFC_DEBUG("RECEIVE length : 0x%02X\n", ps_recv_pkt->llcbuf_len);\r
315             PH_LLCNFC_DEBUG("SENT frame type : 0x%02X\n", ps_frame_info->sent_frame_type);\r
316             PH_LLCNFC_DEBUG("WRITE PENDING : 0x%02X\n", ps_frame_info->write_pending);\r
317             PH_LLCNFC_DEBUG("WRITE PENDING status : 0x%04X\n", ps_frame_info->write_status);\r
318             PH_LLCNFC_DEBUG("WRITE wait frame type : 0x%02X\n", ps_frame_info->write_wait_call);\r
319             PH_LLCNFC_DEBUG("NS START POS : 0x%02X\n", ps_store_frame->start_pos);\r
320             PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_store_frame->winsize_cnt);\r
321 \r
322             switch(ps_frame_info->sent_frame_type)\r
323             {\r
324                 case init_u_rset_frame:\r
325                 {\r
326                     /* First U frame sent properly, update sent frame type \r
327                         in the callback */\r
328                     result = phLlcNfc_Interface_Read (ps_llc_ctxt, \r
329                                     PH_LLCNFC_READWAIT_OFF, \r
330                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
331                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
332 \r
333                     if (NFCSTATUS_BUSY == \r
334                         PHNFCSTATUS (ps_frame_info->write_status))\r
335                     {\r
336                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
337                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
338                     }\r
339                     break;\r
340                 }\r
341 \r
342                 case init_u_a_frame:\r
343                 {\r
344                     /* First UA frame sent properly, update sent frame type \r
345                         in the callback. Send the notification to the \r
346                         upper layer */\r
347                     ps_frame_info->sent_frame_type = write_resp_received;\r
348                     result = phLlcNfc_Interface_Read (ps_llc_ctxt, \r
349                                     PH_LLCNFC_READWAIT_OFF, \r
350                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
351                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
352 \r
353                     if(NULL != ps_llc_ctxt->cb_for_if.notify)\r
354                     {\r
355                         notifyinfo.status = NFCSTATUS_SUCCESS;\r
356                         ps_llc_ctxt->cb_for_if.notify (\r
357                                         ps_llc_ctxt->cb_for_if.pif_ctxt, \r
358                                         ps_llc_ctxt->phwinfo, \r
359                                         NFC_NOTIFY_INIT_COMPLETED, \r
360                                         &notifyinfo);\r
361                     }                    \r
362                     break;\r
363                 }\r
364 \r
365                 case u_rset_frame:\r
366                 {\r
367                     /* Retries has failed to work, so U frame is sent */\r
368                     ps_frame_info->sent_frame_type = write_resp_received;\r
369 \r
370                     if (NFCSTATUS_BUSY == \r
371                         PHNFCSTATUS (ps_frame_info->write_status))\r
372                     {\r
373                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
374                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
375                     }\r
376                     break;\r
377                 }\r
378 \r
379                 case user_i_frame:\r
380                 {\r
381                     /* Send complete */\r
382                     count = ps_frame_info->n_s;\r
383 \r
384                     ps_store_frame->s_llcpacket[count].frame_to_send = \r
385                     ps_frame_info->sent_frame_type = write_resp_received;\r
386 \r
387                     /* N(S) shall be incremented now, because, this callback\r
388                         ensures that packet is sent */\r
389                     count = \r
390                     ps_frame_info->n_s = ((ps_frame_info->n_s + 1) % \r
391                                             PH_LLCNFC_MOD_NS_NR);\r
392 \r
393                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
394                                     PH_LLCNFC_READWAIT_OFF, \r
395                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
396                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
397 \r
398                     if (NFCSTATUS_BUSY == \r
399                         PHNFCSTATUS (ps_frame_info->write_status))\r
400                     {\r
401                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
402                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
403                     }\r
404                    \r
405 \r
406                     if ((((ps_store_frame->start_pos + ps_store_frame->winsize_cnt) % \r
407                         PH_LLCNFC_MOD_NS_NR) == ps_frame_info->n_s) && \r
408                         (ps_frame_info->window_size == ps_store_frame->winsize_cnt))\r
409                     {\r
410                         /* Don't call the upper layer send completion callback, \r
411                             because last sent frame is the maximum that can be \r
412                             held by LLC due to windowing\r
413                             store the callback info, call send completion shall \r
414                             be sent to upper layer only after the ACK is received for the \r
415                             I frames */\r
416                         ps_llc_ctxt->send_cb_len = (pCompInfo->length - \r
417                                                     PH_LLCNFC_APPEND_LEN);\r
418                     }\r
419                     else \r
420                     {\r
421                         /* Send completion is sent to upper layer \r
422                         Actually, this allows the upper layer to send data, if any\r
423                         */\r
424                         if (NULL != ps_llc_ctxt->cb_for_if.send_complete) \r
425                         {                            \r
426                             pCompInfo->length = (pCompInfo->length - \r
427                                                 PH_LLCNFC_APPEND_LEN);\r
428                             ps_llc_ctxt->cb_for_if.send_complete (\r
429                                         ps_llc_ctxt->cb_for_if.pif_ctxt, \r
430                                         pHwInfo, pCompInfo);\r
431                         }\r
432                     }\r
433                     break;\r
434                 }\r
435 \r
436                 case s_frame:\r
437                 {\r
438 #if 0\r
439                     uint8_t         i_frame_ns_value = 0;\r
440 #endif /* #if 0 */\r
441                     /* S frame is only sent when ever a I frame is received from  \r
442                         the PN544 in the read response callback, so the received I \r
443                         frame is acknowledged with S frame. The write response \r
444                         callback for sent S frame is in progress. */\r
445                     ps_frame_info->sent_frame_type = write_resp_received;\r
446 \r
447 #if 0\r
448                     i_frame_ns_value = \r
449                         ((ps_store_frame->s_llcpacket[count].s_llcbuf.sllcpayload.llcheader \r
450                         & LLC_NS_FRAME_HEADER_MASK) >> PH_LLCNFC_NS_START_BIT_POS);\r
451 \r
452 \r
453                      PH_LLCNFC_DEBUG("Actual ns value : 0x%02X\n",\r
454                                                   i_frame_ns_value);\r
455 #endif /* #if 0 */\r
456 \r
457                      PH_LLCNFC_DEBUG("Window size : 0x%02X\n",\r
458                                        ps_frame_info->s_send_store.winsize_cnt);\r
459                      PH_LLCNFC_DEBUG("frame to send : 0x%02X\n",\r
460                               ps_store_frame->s_llcpacket[count].frame_to_send);\r
461 \r
462                     if (NFCSTATUS_BUSY == \r
463                         PHNFCSTATUS(ps_frame_info->write_status))\r
464                     {\r
465                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
466                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
467                     }\r
468 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB\r
469                     phLlcNfc_H_SendInfo (ps_llc_ctxt);\r
470 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */\r
471                     break;\r
472                 }\r
473 \r
474 #ifdef LLC_RR_INSTEAD_OF_REJ\r
475                 case rej_rr_s_frame:\r
476                 {\r
477                     if (NFCSTATUS_BUSY == \r
478                         PHNFCSTATUS(ps_frame_info->write_status))\r
479                     {\r
480                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
481                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
482                     }\r
483                     break;\r
484                 }\r
485 #endif /* #ifdef LLC_RR_INSTEAD_OF_REJ */\r
486 \r
487                 case resend_i_frame:\r
488                 {\r
489                     /* The code reaches here, only if stored I frame is sent \r
490                         No changes here, but send next I frame from the stored list, \r
491                         in the read response callback, only if proper S or I frame \r
492                         is received from the PN544 */                    \r
493                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
494                                     PH_LLCNFC_READWAIT_OFF, \r
495                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
496                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
497 \r
498                     if (NFCSTATUS_BUSY == PHNFCSTATUS(ps_frame_info->write_status))\r
499                     {\r
500                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
501                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
502                     }\r
503 \r
504                     if (ps_store_frame->winsize_cnt == \r
505                         ps_frame_info->window_size)\r
506                     {\r
507                         /* Don't call the upper layer send completion callback, \r
508                             store the callback info, call send completion after \r
509                             ack for written frame \r
510                         ps_llc_ctxt->send_cb_len = pCompInfo->length; */\r
511                     }\r
512                     else \r
513                     {\r
514                         /* ***** This notification needs to be disabled ***** */\r
515                         if(NULL != ps_llc_ctxt->cb_for_if.send_complete) \r
516                         {\r
517                             pCompInfo->length = (pCompInfo->length - \r
518                                                 PH_LLCNFC_APPEND_LEN);\r
519                             ps_llc_ctxt->cb_for_if.send_complete(\r
520                                         ps_llc_ctxt->cb_for_if.pif_ctxt, \r
521                                         pHwInfo, pCompInfo);\r
522                         }\r
523                     } \r
524 \r
525                     if(user_i_frame == \r
526                         ps_store_frame->s_llcpacket[count].frame_to_send)\r
527                     {\r
528                         /* Send complete */\r
529                         ps_store_frame->s_llcpacket[count].frame_to_send = \r
530                                                             resend_i_frame;\r
531                     }\r
532                     break;\r
533                 }\r
534 \r
535                 case rejected_i_frame:\r
536                 {\r
537                     /* Update the sent frame type, if window size count is 0 */\r
538                     ps_frame_info->sent_frame_type = write_resp_received;\r
539                     /* The code enters here, whenever a I frame is resent and for \r
540                         this resent I frame, an I frame received from PN544. \r
541                         So the S frame is sent as the acknowledgment */\r
542                     if (NFCSTATUS_BUSY == \r
543                             PHNFCSTATUS(ps_frame_info->write_status))\r
544                     {\r
545                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
546                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
547                     }\r
548                     break;\r
549                 }\r
550 \r
551                 case resend_s_frame:\r
552                 {\r
553                     /* Update the sent frame type, if window size count is 0 */\r
554                     ps_frame_info->sent_frame_type = write_resp_received;\r
555                     /* The code enters here, whenever a I frame is resent and for \r
556                         this resent I frame, an I frame received from PN544. \r
557                         So the S frame is sent as the acknowledgment */\r
558                     if (NFCSTATUS_BUSY == \r
559                             PHNFCSTATUS(ps_frame_info->write_status))\r
560                     {\r
561                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
562                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
563                     }\r
564                     \r
565 #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB\r
566                     phLlcNfc_H_SendInfo (ps_llc_ctxt);\r
567 #endif /* #ifdef LLC_UPP_LAYER_NTFY_WRITE_RSP_CB */\r
568                     break;\r
569                 }\r
570 \r
571                 case reject_s_frame:\r
572                 {\r
573                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
574                                     PH_LLCNFC_READWAIT_OFF, \r
575                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
576                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
577 \r
578                     if (NFCSTATUS_BUSY == \r
579                         PHNFCSTATUS(ps_frame_info->write_status))\r
580                     {\r
581                         ps_frame_info->write_status = NFCSTATUS_PENDING;\r
582                         result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);\r
583                     }\r
584                     break;\r
585                 }\r
586 \r
587                 case u_a_frame:\r
588                 {\r
589                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
590                                     PH_LLCNFC_READWAIT_OFF, \r
591                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
592                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
593 \r
594                     PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt);\r
595 \r
596                     if(ps_frame_info->s_send_store.winsize_cnt > 0)\r
597                     {\r
598                         result = phLlcNfc_H_SendUserIFrame (ps_llc_ctxt,\r
599                                             &(ps_frame_info->s_send_store));\r
600                     }\r
601                     break;\r
602                 }\r
603 \r
604                 case resend_rej_s_frame:\r
605                 {\r
606                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
607                                     PH_LLCNFC_READWAIT_OFF, \r
608                                     &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
609                                     (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
610 \r
611                     PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt);\r
612 \r
613                     if(ps_frame_info->s_send_store.winsize_cnt > 0)\r
614                     {\r
615                         result = phLlcNfc_H_SendTimedOutIFrame (ps_llc_ctxt,\r
616                                             &(ps_frame_info->s_send_store), 0);\r
617                     }\r
618                     break;\r
619                 }\r
620 \r
621                 default :\r
622                 {\r
623                     break;\r
624                 }\r
625             }\r
626         }\r
627         else\r
628         {\r
629             /* Write not successful */\r
630             if(NULL != ps_llc_ctxt->cb_for_if.send_complete)\r
631             {\r
632                 phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, \r
633                                     ps_llc_ctxt->s_timerinfo.guard_to_count);\r
634                 PH_LLCNFC_DEBUG("Error status received : 0x%x\n", pCompInfo->status);\r
635                 ps_llc_ctxt->cb_for_if.send_complete(\r
636                                     ps_llc_ctxt->cb_for_if.pif_ctxt, \r
637                                     pHwInfo, pCompInfo);\r
638             }\r
639         }\r
640     }\r
641     PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB END\n\n");\r
642 }\r
643 \r
644 static\r
645 void \r
646 phLlcNfc_RdResp_Cb(\r
647     void                        *pContext,\r
648     void                        *pHwInfo,\r
649     phNfc_sTransactionInfo_t    *pCompInfo\r
650 )\r
651 {\r
652     /*\r
653         1. LLC Receive has been called by the upper layer, the response \r
654             for this function is called by the lower layer\r
655         2. Get the frame information from the receive buffer\r
656         3. Depending on the received frame type, process the received \r
657             buffer\r
658     */\r
659     NFCSTATUS                   result = NFCSTATUS_SUCCESS;\r
660     phLlcNfc_Context_t          *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;\r
661     void                        *p_upperctxt = NULL;\r
662     uint8_t                     crc1 = 0, \r
663                                 crc2 = 0;\r
664     phLlcNfc_Frame_t            *ps_frame_info = NULL;\r
665     phLlcNfc_LlcPacket_t        *ps_recv_pkt = NULL;\r
666     phLlcNfc_Payload_t          *ps_llc_payload = NULL;\r
667     pphNfcIF_Notification_CB_t  notifyul = NULL;\r
668     phNfc_sCompletionInfo_t     notifyinfo = {0,0,0};\r
669 \r
670     PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB CALLED\n\n");\r
671     \r
672     if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo)\r
673        && (NULL != pCompInfo->buffer))\r
674     {\r
675         ps_frame_info = &(ps_llc_ctxt->s_frameinfo);\r
676         ps_recv_pkt = &(ps_frame_info->s_recvpacket);\r
677         ps_llc_payload = &(ps_recv_pkt->s_llcbuf.sllcpayload);\r
678 \r
679         ps_llc_ctxt->s_frameinfo.read_pending = PH_LLCNFC_READPEND_FLAG_OFF;\r
680         \r
681         if (NFCSTATUS_SUCCESS == pCompInfo->status)\r
682         {\r
683             if ((PH_LLCNFC_MIN_BUFLEN_RECVD == pCompInfo->length) &&\r
684                 (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < *(pCompInfo->buffer)) &&\r
685                 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > *(pCompInfo->buffer))))\r
686             {\r
687                 PH_LLCNFC_PRINT("Buffer received : \n");\r
688                 PH_LLCNFC_PRINT_BUFFER(pCompInfo->buffer, pCompInfo->length);\r
689 \r
690 #if 0\r
691                 /* Received length is 1 and receive buffer \r
692                 contains the length field which is greater than 2, \r
693                 so read the remaining bytes*/\r
694                 ps_recv_pkt->s_llcbuf.llc_length_byte = pCompInfo->buffer[0];\r
695 #endif\r
696                 result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
697                                 PH_LLCNFC_READWAIT_OFF, \r
698                                 (uint8_t *)ps_llc_payload, \r
699                                 (uint32_t)(ps_recv_pkt->s_llcbuf.llc_length_byte));\r
700 \r
701                 if ((init_u_rset_frame == ps_frame_info->sent_frame_type) && \r
702                     (NFCSTATUS_PENDING != result) && \r
703                     (NULL != ps_llc_ctxt->cb_for_if.notify))\r
704                 {\r
705                     PH_LLCNFC_PRINT("Initialised error\n");\r
706                     notifyinfo.status = result;\r
707                     /* Copy the upper layer callback pointer and the upper \r
708                         layer context, after that call release */\r
709                     notifyul = ps_llc_ctxt->cb_for_if.notify;\r
710                     p_upperctxt = ps_llc_ctxt->cb_for_if.pif_ctxt;\r
711                     result = phLlcNfc_Release(ps_llc_ctxt, pHwInfo);\r
712 \r
713                     /* Wrong result, so Init failed sent */\r
714                     notifyul(p_upperctxt, pHwInfo, \r
715                             NFC_NOTIFY_INIT_FAILED, &notifyinfo);\r
716                 }\r
717             }\r
718             else if (TRUE == ps_llc_ctxt->s_frameinfo.write_pending)\r
719             {\r
720                 /* Ignore the bytes as write is not complete and \r
721                 pend a read for reading 1 byte */\r
722                 result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
723                                 PH_LLCNFC_READWAIT_OFF, \r
724                                 (uint8_t *)&(\r
725                                 ps_recv_pkt->s_llcbuf.llc_length_byte), \r
726                                 PH_LLCNFC_MIN_BUFLEN_RECVD);\r
727             }\r
728             else if (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < pCompInfo->length) &&\r
729                 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && \r
730                 (pCompInfo->length == ps_recv_pkt->s_llcbuf.llc_length_byte))\r
731             {\r
732                 PH_LLCNFC_PRINT("Buffer received : \n");\r
733                 PH_LLCNFC_PRINT_BUFFER(pCompInfo->buffer, pCompInfo->length);\r
734                 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt);\r
735 \r
736                 /* Receive is complete, so move the state to INITIALISED */\r
737                 if (phLlcNfc_Resend_State != ps_llc_ctxt->state)\r
738                 {\r
739                     result = phLlcNfc_H_ChangeState(ps_llc_ctxt, \r
740                                                     phLlcNfc_Initialised_State);\r
741                 }\r
742                 /* Copy the received buffer and length */\r
743                 ps_recv_pkt->llcbuf_len = (uint8_t)\r
744                                 (ps_recv_pkt->s_llcbuf.llc_length_byte + 1);\r
745 #if 0\r
746                 (void)memcpy(ps_llc_payload, pCompInfo->buffer, \r
747                             pCompInfo->length);\r
748 #endif\r
749 \r
750                 /* \r
751                 Check the CRC\r
752                 ps_llc_ctxt->s_frameinfo.s_recvpacket.s_llcbuf : \r
753                         consists llc length byte + llc header + data + CRC \r
754                         (which needs to be calculated by the below function)\r
755                 ps_llc_ctxt->s_frameinfo.s_recvpacket.llcbuf_len : \r
756                         Total length of the above buffer\r
757                 ps_llc_ctxt->s_frameinfo.s_recvpacket.llcbuf_len - 2 : \r
758                         -2 because the CRC has to be calculated, only for the \r
759                         bytes which has llc length byte + llc header + data. \r
760                         But total length (llcbuf_len) consists of above mentioned \r
761                         things with 2 byte CRC \r
762                 ps_llc_ctxt->s_frameinfo.s_recvpacket.s_llcbuf.sllcpayload.llcpayload : \r
763                         consists only data (no length byte and no llc header)\r
764                         (psllcctxt->s_frameinfo.s_recvpacket.llcbuf_len - 4) : \r
765                         is the array index of the first CRC byte to be calculated\r
766                         (psllcctxt->s_frameinfo.s_recvpacket.llcbuf_len - 3) : \r
767                         is the array index of the second CRC byte to be calculated\r
768                 */\r
769                 phLlcNfc_H_ComputeCrc((uint8_t *)&(ps_recv_pkt->s_llcbuf), \r
770                                     (ps_recv_pkt->llcbuf_len - 2), \r
771                                     &crc1, &crc2);\r
772 \r
773                 if ((crc1 == ps_llc_payload->llcpayload[\r
774                             (ps_recv_pkt->llcbuf_len - 4)]) \r
775                     && (crc2 == ps_llc_payload->llcpayload[\r
776                             (ps_recv_pkt->llcbuf_len - 3)]))\r
777                 {\r
778                     result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt);\r
779                 }\r
780 #ifdef LLC_DISABLE_CRC\r
781                 else\r
782                 {   \r
783                     result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt);\r
784                 }\r
785 #else\r
786                 else if (ps_frame_info->recv_error_count < \r
787                     PH_LLCNFC_MAX_REJ_RETRY_COUNT)\r
788                 {\r
789                     LOGW("LLC bad crc");\r
790                     PH_LLCNFC_PRINT("CRC ERROR RECVD \n");\r
791                     PH_LLCNFC_DEBUG("RECV ERROR COUNT : 0x%02X\n", ps_frame_info->recv_error_count);\r
792 \r
793                     ps_frame_info->recv_error_count = (uint8_t)\r
794                                     (ps_frame_info->recv_error_count + 1);\r
795                     libnfc_llc_error_count++;\r
796 \r
797                     result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
798                         PH_LLCNFC_READWAIT_OFF, \r
799                         (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
800                         PH_LLCNFC_BYTES_INIT_READ);\r
801 #ifdef CRC_ERROR_REJ\r
802                     /* Send REJ (S frame), as the CRC received has error  */\r
803                     result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt);\r
804 \r
805 #endif /* #ifdef CRC_ERROR_REJ */\r
806 \r
807                 }\r
808                 else\r
809                 {\r
810                     LOGE("max LLC retries exceeded, stack restart");\r
811                     result = phLlcNfc_Interface_Read (ps_llc_ctxt, \r
812                                 PH_LLCNFC_READWAIT_OFF, \r
813                                 (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
814                                 PH_LLCNFC_BYTES_INIT_READ);\r
815 \r
816                     /* Raise the exception for CRC error received from the  */\r
817                     notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, \r
818                                             NFCSTATUS_BOARD_COMMUNICATION_ERROR);\r
819 #if 0\r
820                     phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); \r
821 #endif /* #if 0 */\r
822                         /* Resend done, no answer from the device */\r
823                     ps_llc_ctxt->cb_for_if.notify (\r
824                                     ps_llc_ctxt->cb_for_if.pif_ctxt,\r
825                                     ps_llc_ctxt->phwinfo, \r
826                                     NFC_NOTIFY_DEVICE_ERROR, \r
827                                     &notifyinfo);\r
828                 }\r
829 \r
830 #endif /* #ifdef LLC_DISABLE_CRC */\r
831             } /* read more than 1 byte */\r
832             else if (ps_frame_info->recv_error_count >= \r
833                     PH_LLCNFC_MAX_REJ_RETRY_COUNT)\r
834             {\r
835                 LOGE("max LLC retries exceeded, stack restart");\r
836                 result = phLlcNfc_Interface_Read (ps_llc_ctxt, \r
837                         PH_LLCNFC_READWAIT_OFF, \r
838                         (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
839                         PH_LLCNFC_BYTES_INIT_READ);\r
840 \r
841                 /* Raise the exception for CRC error received from the  */\r
842                 notifyinfo.status = PHNFCSTVAL(CID_NFC_LLC, \r
843                                         NFCSTATUS_BOARD_COMMUNICATION_ERROR);\r
844 #if 0\r
845                 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1); \r
846 #endif /* #if 0 */\r
847                     /* Resend done, no answer from the device */\r
848                 ps_llc_ctxt->cb_for_if.notify (\r
849                                 ps_llc_ctxt->cb_for_if.pif_ctxt,\r
850                                 ps_llc_ctxt->phwinfo, \r
851                                 NFC_NOTIFY_DEVICE_ERROR, \r
852                                 &notifyinfo);\r
853             }\r
854             else if (((PH_LLCNFC_MIN_BUFLEN_RECVD + 1) < pCompInfo->length) &&\r
855                 (PH_LLCNFC_MAX_BUFLEN_RECV_SEND > pCompInfo->length) && \r
856                 (pCompInfo->length != ps_recv_pkt->s_llcbuf.llc_length_byte))\r
857             {\r
858                 LOGE("bad LLC length1 %d", pCompInfo->length);\r
859                 ps_frame_info->recv_error_count = (uint8_t)\r
860                                     (ps_frame_info->recv_error_count + 1);\r
861                 libnfc_llc_error_count++;\r
862 \r
863                 result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
864                         PH_LLCNFC_READWAIT_OFF, \r
865                         (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
866                         PH_LLCNFC_BYTES_INIT_READ);\r
867 \r
868 #ifdef CRC_ERROR_REJ\r
869 \r
870                 /* Send REJ (S frame), as the CRC received has error  */\r
871                 result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt);\r
872 \r
873 #endif /* #ifdef CRC_ERROR_REJ */\r
874             }\r
875             else if ((PH_LLCNFC_MIN_BUFLEN_RECVD == pCompInfo->length) &&\r
876                 ((*(pCompInfo->buffer) > (PH_LLCNFC_MAX_BUFLEN_RECV_SEND - 1))\r
877                 ||(*(pCompInfo->buffer) <= (PH_LLCNFC_MIN_BUFLEN_RECVD + 1))))\r
878             {\r
879                 /* Temporary fix for the 0xFF data received  \r
880                     Solution for the read one byte, giving error in buffer\r
881                     PH_LLCNFC_MAX_BUFLEN_RECV_SEND (0x21) is the maximum \r
882                     bytes expected by LLC, if the buffer \r
883                     value is greater than (0x21 - 1), then pend a read to \r
884                     get 1 byte again\r
885                 */\r
886                 LOGW("bad LLC length byte %x\n", *(pCompInfo->buffer));\r
887                 ps_frame_info->recv_error_count = (uint8_t)\r
888                                     (ps_frame_info->recv_error_count + 1);\r
889                 libnfc_llc_error_count++;\r
890 \r
891                 result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
892                         PH_LLCNFC_READWAIT_OFF, \r
893                         (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
894                         PH_LLCNFC_BYTES_INIT_READ);\r
895             }\r
896             else\r
897             {\r
898                 LOGW("unknown LLC error1");\r
899                 ps_frame_info->recv_error_count = (uint8_t)\r
900                                     (ps_frame_info->recv_error_count + 1);\r
901                 libnfc_llc_error_count++;\r
902 \r
903                 phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, \r
904                                     ps_llc_ctxt->s_timerinfo.guard_to_count);\r
905                 pCompInfo->status = PHNFCSTVAL(CID_NFC_LLC, \r
906                                                 NFCSTATUS_INVALID_FORMAT);\r
907                 pCompInfo->buffer = NULL;\r
908                 pCompInfo->length = 0;\r
909                 result = phLlcNfc_Interface_Read(ps_llc_ctxt, \r
910                         PH_LLCNFC_READWAIT_OFF, \r
911                         (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte), \r
912                         PH_LLCNFC_BYTES_INIT_READ);\r
913                 if (NULL != ps_llc_ctxt->cb_for_if.receive_complete)\r
914                 {\r
915                     ps_llc_ctxt->cb_for_if.receive_complete(\r
916                                         ps_llc_ctxt->cb_for_if.pif_ctxt, \r
917                                         pHwInfo, pCompInfo);\r
918                 }\r
919             }\r
920         } else if (NFCSTATUS_READ_FAILED == pCompInfo->status) {\r
921             // partial read - try reading the length byte again\r
922             LOGW("LLC length mis-match\n");\r
923             ps_frame_info->recv_error_count = (uint8_t)\r
924                                 (ps_frame_info->recv_error_count + 1);\r
925             libnfc_llc_error_count++;\r
926 \r
927             result = phLlcNfc_Interface_Read(ps_llc_ctxt,\r
928                     PH_LLCNFC_READWAIT_OFF,\r
929                     (uint8_t *)&(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
930                     PH_LLCNFC_BYTES_INIT_READ);\r
931         }\r
932         else\r
933         {\r
934             LOGW("unknown LLC error2");\r
935             ps_frame_info->recv_error_count = (uint8_t)\r
936                                     (ps_frame_info->recv_error_count + 1);\r
937             libnfc_llc_error_count++;\r
938 \r
939             phLlcNfc_StopTimers(PH_LLCNFC_GUARDTIMER, \r
940                                 ps_llc_ctxt->s_timerinfo.guard_to_count);\r
941             PH_LLCNFC_DEBUG("Status Error : 0x%x\n", pCompInfo->status);\r
942             if (NULL != ps_llc_ctxt->cb_for_if.receive_complete)\r
943             {\r
944                 ps_llc_ctxt->cb_for_if.receive_complete(\r
945                                     ps_llc_ctxt->cb_for_if.pif_ctxt, \r
946                                     pHwInfo, pCompInfo);\r
947             }\r
948         }\r
949     }\r
950     else\r
951     {\r
952         if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) \r
953             && (NULL != ps_llc_ctxt->cb_for_if.receive_complete))\r
954         {\r
955             ps_llc_ctxt->cb_for_if.receive_complete(\r
956                                     ps_llc_ctxt->cb_for_if.pif_ctxt, \r
957                                     pHwInfo, pCompInfo);\r
958         }\r
959     }\r
960 \r
961     PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB END\n\n");\r
962 }\r
963 \r
964 void \r
965 phLlcNfc_H_SendInfo (\r
966                     phLlcNfc_Context_t          *psLlcCtxt\r
967                     )\r
968 {\r
969     phLlcNfc_LlcPacket_t        *ps_recv_pkt = NULL;\r
970     phLlcNfc_Frame_t            *ps_frame_info = NULL;\r
971     phNfc_sTransactionInfo_t    comp_info = {0,0,0,0,0};\r
972 \r
973     ps_frame_info = &(psLlcCtxt->s_frameinfo);\r
974     ps_recv_pkt = &(ps_frame_info->s_recvpacket);\r
975 \r
976     if ((ps_recv_pkt->llcbuf_len > 0) && \r
977         (ps_recv_pkt->llcbuf_len <= PH_LLCNFC_MAX_LLC_PAYLOAD))\r
978     {\r
979         comp_info.status = NFCSTATUS_SUCCESS;\r
980         /* Chop the extra Llc bytes received */\r
981 #if 0\r
982         comp_info.length = (ps_recv_pkt->llcbuf_len - \r
983                             PH_LLCNFC_LEN_APPEND);\r
984 #else\r
985         comp_info.length = (uint16_t)psLlcCtxt->recvbuf_length;\r
986 #endif /*  */\r
987 \r
988         if (0 != comp_info.length)\r
989         {\r
990 #if 0\r
991             (void)memcpy ((void *)psLlcCtxt->precv_buf, (void *)(\r
992                         ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload), \r
993                         comp_info.length);\r
994 #endif /* #if 0 */\r
995             comp_info.buffer = psLlcCtxt->precv_buf;\r
996         }\r
997         else\r
998         {\r
999             comp_info.buffer = NULL;\r
1000         }\r
1001     }\r
1002     else\r
1003     {\r
1004         comp_info.status = PHNFCSTVAL(CID_NFC_LLC, \r
1005                                     NFCSTATUS_INVALID_FORMAT);\r
1006         comp_info.length = 0;\r
1007         comp_info.buffer = NULL;\r
1008     }\r
1009 \r
1010     (void)phLlcNfc_Interface_Read(psLlcCtxt, \r
1011                         PH_LLCNFC_READWAIT_OFF, \r
1012                         &(ps_recv_pkt->s_llcbuf.llc_length_byte),\r
1013                         (uint8_t)PH_LLCNFC_BYTES_INIT_READ);\r
1014 \r
1015     if ((NFCSTATUS_SUCCESS == comp_info.status) && \r
1016         (0 == comp_info.length))\r
1017     {\r
1018         /* May be a NULL I frame received from PN544, so dont do \r
1019             any thing */\r
1020     }\r
1021     else\r
1022     {\r
1023         if ((NULL != psLlcCtxt->cb_for_if.receive_complete) && \r
1024             (TRUE == ps_frame_info->upper_recv_call))\r
1025         {\r
1026             ps_frame_info->upper_recv_call = FALSE;\r
1027             psLlcCtxt->cb_for_if.receive_complete(\r
1028                                 psLlcCtxt->cb_for_if.pif_ctxt, \r
1029                                 psLlcCtxt->phwinfo, \r
1030                                 &comp_info);\r
1031         }\r
1032         else\r
1033         {\r
1034             if (NULL != psLlcCtxt->cb_for_if.notify)\r
1035             {\r
1036                     psLlcCtxt->cb_for_if.notify(\r
1037                             psLlcCtxt->cb_for_if.pif_ctxt, \r
1038                             psLlcCtxt->phwinfo, \r
1039                             NFC_NOTIFY_RECV_COMPLETED, \r
1040                             &comp_info);\r
1041             }\r
1042         }\r
1043     }\r
1044     return;\r
1045 }\r
1046 \r