2 * Copyright (C) 2010 NXP Semiconductors
\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
8 * http://www.apache.org/licenses/LICENSE-2.0
\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
18 * \file phLlcNfc_Interface.c
\r
19 * \brief Interface for both LLC and transport layer
\r
21 * Project: NFC-FRI-1.1
\r
23 * $Date: Tue Jun 1 14:41:26 2010 $
\r
24 * $Author: ing02260 $
\r
26 * $Aliases: NFC_FRI1.1_WK1023_R35_1 $
\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
43 #ifdef PH_LLCNFC_DALINT
\r
44 #include <phDal4Nfc.h>
\r
46 #define LOG_TAG "NFC-LLC"
\r
48 #include <utils/Log.h>
\r
49 /*********************** End of includes ****************************/
\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
56 /*********************** Local functions ****************************/
\r
62 phNfc_sTransactionInfo_t *pCompInfo
\r
70 phNfc_sTransactionInfo_t *pCompInfo
\r
73 /******************** End of Local functions ************************/
\r
75 /********************** Global variables ****************************/
\r
76 int libnfc_llc_error_count = 0;
\r
78 /******************** End of Global Variables ***********************/
\r
81 phLlcNfc_Interface_Register(
\r
82 phLlcNfc_Context_t *psLlcCtxt,
\r
83 phNfcLayer_sCfg_t *psIFConfig
\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
90 if ((NULL == psLlcCtxt) || (NULL == psIFConfig))
\r
92 result = PHNFCSTVAL(CID_NFC_LLC,
\r
93 NFCSTATUS_INVALID_PARAMETER);
\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
110 if ((NULL != psIFConfig->layer_next) &&
\r
111 (NULL != psIFConfig->layer_next->layer_registry))
\r
113 result = psIFConfig->layer_next->layer_registry(
\r
116 (void *)&psIFConfig[(psIFConfig->layer_index - 1)]);
\r
118 #endif /* #ifdef PH_LLCNFC_DALINT */
\r
120 PH_LLCNFC_DEBUG("Llc Dal Interface Register result : 0x%x\n", result);
\r
125 phLlcNfc_Interface_Init(
\r
126 phLlcNfc_Context_t *psLlcCtxt
\r
130 1. Get the pointer of the main llc context
\r
132 NFCSTATUS result = NFCSTATUS_SUCCESS;
\r
133 if ((NULL == psLlcCtxt) ||
\r
134 (NULL == psLlcCtxt->lower_if.init))
\r
136 result = PHNFCSTVAL(CID_NFC_LLC,
\r
137 NFCSTATUS_INVALID_PARAMETER);
\r
141 /* Initialise the main context */
\r
142 result = psLlcCtxt->lower_if.init( psLlcCtxt->lower_if.pcontext,
\r
143 psLlcCtxt->phwinfo);
\r
145 PH_LLCNFC_DEBUG("Llc Dal Interface Init result : 0x%x\n", result);
\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
157 NFCSTATUS result = NFCSTATUS_PENDING;
\r
159 1. Call DAL or TL read with "phLlcNfc_LlcTl_RdResp_Cb" as
\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
167 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_INVALID_PARAMETER);
\r
169 else if (PH_LLCNFC_READPEND_FLAG_OFF !=
\r
170 psLlcCtxt->s_frameinfo.read_pending)
\r
176 if (PH_LLCNFC_READWAIT_OFF == readWaitOn)
\r
178 result = psLlcCtxt->lower_if.receive(
\r
179 psLlcCtxt->lower_if.pcontext,
\r
180 psLlcCtxt->phwinfo,
\r
182 (uint8_t)llcBufferLength);
\r
186 result = psLlcCtxt->lower_if.receive_wait(
\r
187 psLlcCtxt->lower_if.pcontext,
\r
188 psLlcCtxt->phwinfo,
\r
190 (uint16_t)llcBufferLength);
\r
193 if(NFCSTATUS_PENDING == result)
\r
195 if (PH_LLCNFC_READPEND_ONE_BYTE == llcBufferLength)
\r
197 psLlcCtxt->s_frameinfo.read_pending =
\r
198 PH_LLCNFC_READPEND_ONE_BYTE;
\r
202 psLlcCtxt->s_frameinfo.read_pending =
\r
203 PH_LLCNFC_READPEND_REMAIN_BYTE;
\r
207 PH_LLCNFC_DEBUG("Llc Dal Interface Read result : 0x%x\n", result);
\r
212 phLlcNfc_Interface_Write(
\r
213 phLlcNfc_Context_t *psLlcCtxt,
\r
214 uint8_t *pLlcBuffer,
\r
215 uint32_t llcBufferLength
\r
218 NFCSTATUS result = NFCSTATUS_PENDING;
\r
220 PH_LLCNFC_PRINT("Llc Dal Interface Write called\n");
\r
222 1. Call DAL or TL write with "phLlcNfc_LlcTl_WrResp_Cb" as
\r
225 if ((NULL == psLlcCtxt) || (NULL == pLlcBuffer) ||
\r
226 (0 == llcBufferLength) ||
\r
227 (NULL == psLlcCtxt->lower_if.send))
\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
236 PH_LLCNFC_PRINT("Buffer to be send to Dal : \n");
\r
237 PH_LLCNFC_PRINT_BUFFER(pLlcBuffer, llcBufferLength);
\r
239 if ((TRUE == psLlcCtxt->s_frameinfo.write_pending) ||
\r
240 (PH_LLCNFC_READPEND_REMAIN_BYTE ==
\r
241 psLlcCtxt->s_frameinfo.read_pending))
\r
243 result = PHNFCSTVAL(CID_NFC_LLC, NFCSTATUS_BUSY);
\r
247 #ifdef LLC_DATA_BYTES
\r
249 PH_LLCNFC_PRINT_DATA (pLlcBuffer, llcBufferLength);
\r
250 PH_LLCNFC_STRING (";\n");
\r
252 #endif /* LLC_DATA_BYTES */
\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
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
264 psLlcCtxt->s_frameinfo.write_pending = TRUE;
\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
274 PH_LLCNFC_DEBUG("Llc Dal Interface Write result : 0x%x\n", result);
\r
280 phLlcNfc_WrResp_Cb(
\r
283 phNfc_sTransactionInfo_t *pCompInfo
\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
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
299 PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB CALLED\n\n");
\r
301 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo))
\r
303 ps_llc_ctxt->s_frameinfo.write_pending = FALSE;
\r
305 PHNFC_UNUSED_VARIABLE(result);
\r
307 if(NFCSTATUS_SUCCESS == pCompInfo->status)
\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
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
322 switch(ps_frame_info->sent_frame_type)
\r
324 case init_u_rset_frame:
\r
326 /* First U frame sent properly, update sent frame type
\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
333 if (NFCSTATUS_BUSY ==
\r
334 PHNFCSTATUS (ps_frame_info->write_status))
\r
336 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
337 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\r
342 case init_u_a_frame:
\r
344 /* First UA frame sent properly, update sent frame type
\r
345 in the callback. Send the notification to the
\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
353 if(NULL != ps_llc_ctxt->cb_for_if.notify)
\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
367 /* Retries has failed to work, so U frame is sent */
\r
368 ps_frame_info->sent_frame_type = write_resp_received;
\r
370 if (NFCSTATUS_BUSY ==
\r
371 PHNFCSTATUS (ps_frame_info->write_status))
\r
373 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
374 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\r
381 /* Send complete */
\r
382 count = ps_frame_info->n_s;
\r
384 ps_store_frame->s_llcpacket[count].frame_to_send =
\r
385 ps_frame_info->sent_frame_type = write_resp_received;
\r
387 /* N(S) shall be incremented now, because, this callback
\r
388 ensures that packet is sent */
\r
390 ps_frame_info->n_s = ((ps_frame_info->n_s + 1) %
\r
391 PH_LLCNFC_MOD_NS_NR);
\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
398 if (NFCSTATUS_BUSY ==
\r
399 PHNFCSTATUS (ps_frame_info->write_status))
\r
401 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
402 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\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
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
416 ps_llc_ctxt->send_cb_len = (pCompInfo->length -
\r
417 PH_LLCNFC_APPEND_LEN);
\r
421 /* Send completion is sent to upper layer
\r
422 Actually, this allows the upper layer to send data, if any
\r
424 if (NULL != ps_llc_ctxt->cb_for_if.send_complete)
\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
439 uint8_t i_frame_ns_value = 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
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
453 PH_LLCNFC_DEBUG("Actual ns value : 0x%02X\n",
\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
462 if (NFCSTATUS_BUSY ==
\r
463 PHNFCSTATUS(ps_frame_info->write_status))
\r
465 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
466 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\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
474 #ifdef LLC_RR_INSTEAD_OF_REJ
\r
475 case rej_rr_s_frame:
\r
477 if (NFCSTATUS_BUSY ==
\r
478 PHNFCSTATUS(ps_frame_info->write_status))
\r
480 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
481 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\r
485 #endif /* #ifdef LLC_RR_INSTEAD_OF_REJ */
\r
487 case resend_i_frame:
\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
498 if (NFCSTATUS_BUSY == PHNFCSTATUS(ps_frame_info->write_status))
\r
500 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
501 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\r
504 if (ps_store_frame->winsize_cnt ==
\r
505 ps_frame_info->window_size)
\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
514 /* ***** This notification needs to be disabled ***** */
\r
515 if(NULL != ps_llc_ctxt->cb_for_if.send_complete)
\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
525 if(user_i_frame ==
\r
526 ps_store_frame->s_llcpacket[count].frame_to_send)
\r
528 /* Send complete */
\r
529 ps_store_frame->s_llcpacket[count].frame_to_send =
\r
535 case rejected_i_frame:
\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
545 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
546 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\r
551 case resend_s_frame:
\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
561 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
562 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\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
571 case reject_s_frame:
\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
578 if (NFCSTATUS_BUSY ==
\r
579 PHNFCSTATUS(ps_frame_info->write_status))
\r
581 ps_frame_info->write_status = NFCSTATUS_PENDING;
\r
582 result = phLlcNfc_H_WriteWaitCall (ps_llc_ctxt);
\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
594 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt);
\r
596 if(ps_frame_info->s_send_store.winsize_cnt > 0)
\r
598 result = phLlcNfc_H_SendUserIFrame (ps_llc_ctxt,
\r
599 &(ps_frame_info->s_send_store));
\r
604 case resend_rej_s_frame:
\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
611 PH_LLCNFC_DEBUG("WIN SIZE : 0x%02X\n", ps_frame_info->s_send_store.winsize_cnt);
\r
613 if(ps_frame_info->s_send_store.winsize_cnt > 0)
\r
615 result = phLlcNfc_H_SendTimedOutIFrame (ps_llc_ctxt,
\r
616 &(ps_frame_info->s_send_store), 0);
\r
629 /* Write not successful */
\r
630 if(NULL != ps_llc_ctxt->cb_for_if.send_complete)
\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
641 PH_LLCNFC_PRINT("\n\nLLC : WRITE RESP CB END\n\n");
\r
646 phLlcNfc_RdResp_Cb(
\r
649 phNfc_sTransactionInfo_t *pCompInfo
\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
659 NFCSTATUS result = NFCSTATUS_SUCCESS;
\r
660 phLlcNfc_Context_t *ps_llc_ctxt = (phLlcNfc_Context_t*)pContext;
\r
661 void *p_upperctxt = NULL;
\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
670 PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB CALLED\n\n");
\r
672 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo) && (NULL != pHwInfo)
\r
673 && (NULL != pCompInfo->buffer))
\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
679 ps_llc_ctxt->s_frameinfo.read_pending = PH_LLCNFC_READPEND_FLAG_OFF;
\r
681 if (NFCSTATUS_SUCCESS == pCompInfo->status)
\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
687 PH_LLCNFC_PRINT("Buffer received : \n");
\r
688 PH_LLCNFC_PRINT_BUFFER(pCompInfo->buffer, pCompInfo->length);
\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
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
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
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
713 /* Wrong result, so Init failed sent */
\r
714 notifyul(p_upperctxt, pHwInfo,
\r
715 NFC_NOTIFY_INIT_FAILED, ¬ifyinfo);
\r
718 else if (TRUE == ps_llc_ctxt->s_frameinfo.write_pending)
\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
725 ps_recv_pkt->s_llcbuf.llc_length_byte),
\r
726 PH_LLCNFC_MIN_BUFLEN_RECVD);
\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
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
736 /* Receive is complete, so move the state to INITIALISED */
\r
737 if (phLlcNfc_Resend_State != ps_llc_ctxt->state)
\r
739 result = phLlcNfc_H_ChangeState(ps_llc_ctxt,
\r
740 phLlcNfc_Initialised_State);
\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
746 (void)memcpy(ps_llc_payload, pCompInfo->buffer,
\r
747 pCompInfo->length);
\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
769 phLlcNfc_H_ComputeCrc((uint8_t *)&(ps_recv_pkt->s_llcbuf),
\r
770 (ps_recv_pkt->llcbuf_len - 2),
\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
778 result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt);
\r
780 #ifdef LLC_DISABLE_CRC
\r
783 result = phLlcNfc_H_ProRecvFrame(ps_llc_ctxt);
\r
786 else if (ps_frame_info->recv_error_count <
\r
787 PH_LLCNFC_MAX_REJ_RETRY_COUNT)
\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
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
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
805 #endif /* #ifdef CRC_ERROR_REJ */
\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
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
820 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
\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
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
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
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
845 phOsalNfc_RaiseException(phOsalNfc_e_UnrecovFirmwareErr,1);
\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
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
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
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
868 #ifdef CRC_ERROR_REJ
\r
870 /* Send REJ (S frame), as the CRC received has error */
\r
871 result = phLlcNfc_H_SendRejectFrame (ps_llc_ctxt);
\r
873 #endif /* #ifdef CRC_ERROR_REJ */
\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
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
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
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
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
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
915 ps_llc_ctxt->cb_for_if.receive_complete(
\r
916 ps_llc_ctxt->cb_for_if.pif_ctxt,
\r
917 pHwInfo, pCompInfo);
\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
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
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
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
944 ps_llc_ctxt->cb_for_if.receive_complete(
\r
945 ps_llc_ctxt->cb_for_if.pif_ctxt,
\r
946 pHwInfo, pCompInfo);
\r
952 if ((NULL != ps_llc_ctxt) && (NULL != pCompInfo)
\r
953 && (NULL != ps_llc_ctxt->cb_for_if.receive_complete))
\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
961 PH_LLCNFC_PRINT("\n\nLLC : READ RESP CB END\n\n");
\r
965 phLlcNfc_H_SendInfo (
\r
966 phLlcNfc_Context_t *psLlcCtxt
\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
973 ps_frame_info = &(psLlcCtxt->s_frameinfo);
\r
974 ps_recv_pkt = &(ps_frame_info->s_recvpacket);
\r
976 if ((ps_recv_pkt->llcbuf_len > 0) &&
\r
977 (ps_recv_pkt->llcbuf_len <= PH_LLCNFC_MAX_LLC_PAYLOAD))
\r
979 comp_info.status = NFCSTATUS_SUCCESS;
\r
980 /* Chop the extra Llc bytes received */
\r
982 comp_info.length = (ps_recv_pkt->llcbuf_len -
\r
983 PH_LLCNFC_LEN_APPEND);
\r
985 comp_info.length = (uint16_t)psLlcCtxt->recvbuf_length;
\r
988 if (0 != comp_info.length)
\r
991 (void)memcpy ((void *)psLlcCtxt->precv_buf, (void *)(
\r
992 ps_recv_pkt->s_llcbuf.sllcpayload.llcpayload),
\r
995 comp_info.buffer = psLlcCtxt->precv_buf;
\r
999 comp_info.buffer = NULL;
\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
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
1015 if ((NFCSTATUS_SUCCESS == comp_info.status) &&
\r
1016 (0 == comp_info.length))
\r
1018 /* May be a NULL I frame received from PN544, so dont do
\r
1023 if ((NULL != psLlcCtxt->cb_for_if.receive_complete) &&
\r
1024 (TRUE == ps_frame_info->upper_recv_call))
\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
1034 if (NULL != psLlcCtxt->cb_for_if.notify)
\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