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