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