15d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*
25d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Copyright (C) 2010 NXP Semiconductors
35d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
45d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Licensed under the Apache License, Version 2.0 (the "License");
55d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * you may not use this file except in compliance with the License.
65d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * You may obtain a copy of the License at
75d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
85d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *      http://www.apache.org/licenses/LICENSE-2.0
95d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Unless required by applicable law or agreed to in writing, software
115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * distributed under the License is distributed on an "AS IS" BASIS,
125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * See the License for the specific language governing permissions and
145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * limitations under the License.
155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \file  phFriNfc_Llcp.c
195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * \brief NFC LLCP core
205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Project: NFC-FRI
225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly *
235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/*include files*/
265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phNfcTypes.h>
275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phNfcHalTypes.h>
285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phLibNfcStatus.h>
295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phFriNfc_LlcpUtils.h>
305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly#include <phFriNfc_Llcp.h>
315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyNFCSTATUS phFriNfc_Llcp_DecodeTLV( phNfc_sData_t  *psRawData,
335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint32_t       *pOffset,
345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint8_t        *pType,
355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   phNfc_sData_t  *psValueBuffer )
365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t type;
385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t length;
395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t offset = *pOffset;
405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check for NULL pointers */
425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if ((psRawData == NULL) || (pOffset == NULL) || (pType == NULL) || (psValueBuffer == NULL))
435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check offset */
485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if (offset > psRawData->length)
495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check if enough room for Type and Length (with overflow check) */
545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if ((offset+2 > psRawData->length) && (offset+2 > offset))
555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Get Type and Length from current TLV, and update offset */
605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   type = psRawData->buffer[offset];
615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   length = psRawData->buffer[offset+1];
625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   offset += 2;
635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check if enough room for Value with announced Length (with overflow check) */
655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if ((offset+length > psRawData->length) && (offset+length > offset))
665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Save response, and update offset */
715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   *pType = type;
725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psValueBuffer->buffer = psRawData->buffer + offset;
735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psValueBuffer->length = length;
745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   offset += length;
755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Save updated offset */
775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   *pOffset = offset;
785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return NFCSTATUS_SUCCESS;
805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick PellyNFCSTATUS phFriNfc_Llcp_EncodeTLV( phNfc_sData_t  *psValueBuffer,
835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint32_t       *pOffset,
845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint8_t        type,
855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint8_t        length,
865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                   uint8_t        *pValue)
875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t offset = *pOffset;
897b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   uint32_t finalOffset = offset + 2 + length; /* 2 stands for Type and Length fields size */
905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t i;
915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check for NULL pointers */
935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if ((psValueBuffer == NULL) || (pOffset == NULL) || (pValue == NULL))
945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Check offset */
995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if (offset > psValueBuffer->length)
1005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
1015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
1025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
1035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1047b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Check if enough room for Type, Length and Value (with overflow check) */
1057b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   if ((finalOffset > psValueBuffer->length) || (finalOffset < offset))
1065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
1075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
1085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
1095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Set the TYPE */
1115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psValueBuffer->buffer[offset] = type;
1125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   offset += 1;
1135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Set the LENGTH */
1155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psValueBuffer->buffer[offset] = length;
1165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   offset += 1;
1175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Set the VALUE */
1195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   for(i=0;i<length;i++,offset++)
1205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
1215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      psValueBuffer->buffer[offset]  = pValue[i];
1225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
1235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* Save updated offset */
1255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   *pOffset = offset;
1265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return NFCSTATUS_SUCCESS;
1285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
1295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1307b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil JogiNFCSTATUS phFriNfc_Llcp_AppendTLV( phNfc_sData_t  *psValueBuffer,
1317b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi                                   uint32_t       nTlvOffset,
1327b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi                                   uint32_t       *pCurrentOffset,
1337b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi                                   uint8_t        length,
1347b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi                                   uint8_t        *pValue)
1357b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi{
1367b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   uint32_t offset = *pCurrentOffset;
1377b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   uint32_t finalOffset = offset + length;
1387b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1397b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Check for NULL pointers */
1407b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   if ((psValueBuffer == NULL) || (pCurrentOffset == NULL) || (pValue == NULL))
1417b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   {
1427b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
1437b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   }
1447b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1457b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Check offset */
1467b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   if (offset > psValueBuffer->length)
1477b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   {
1487b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
1497b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   }
1507b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1517b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Check if enough room for Type and Length (with overflow check) */
1527b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   if ((finalOffset > psValueBuffer->length) || (finalOffset < offset))
1537b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   {
1547b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi      return PHNFCSTVAL(CID_FRI_NFC_LLCP, NFCSTATUS_INVALID_PARAMETER);
1557b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   }
1567b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1577b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Update the LENGTH */
1587b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   psValueBuffer->buffer[nTlvOffset+1] += length;
1597b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1607b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Set the VALUE */
1617b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   memcpy(psValueBuffer->buffer + offset, pValue, length);
1627b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   offset += length;
1637b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1647b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   /* Save updated offset */
1657b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   *pCurrentOffset = offset;
1667b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1677b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi   return NFCSTATUS_SUCCESS;
1687b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi}
1697b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1707b187e70a5f0ffc021cc06a9f1a2bf2c0f8f8767Sunil Jogi
1715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/* TODO: comment function EncodeMIUX */
172e1c9fcfb918da43ab24f95c9341da3b6bf3b1250Jeff Hamiltonvoid phFriNfc_Llcp_EncodeMIUX(uint16_t miux,
173e1c9fcfb918da43ab24f95c9341da3b6bf3b1250Jeff Hamilton                              uint8_t* pMiuxEncoded)
1745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
1755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* MASK */
1765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   miux = miux & PHFRINFC_LLCP_TLV_MIUX_MASK;
1775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
178e1c9fcfb918da43ab24f95c9341da3b6bf3b1250Jeff Hamilton   pMiuxEncoded[0] = miux >> 8;
179e1c9fcfb918da43ab24f95c9341da3b6bf3b1250Jeff Hamilton   pMiuxEncoded[1] = miux & 0xff;
1805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
1815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/* TODO: comment function EncodeRW */
1835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phFriNfc_Llcp_EncodeRW(uint8_t *pRw)
1845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
1855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   /* MASK */
1865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   *pRw = *pRw & PHFRINFC_LLCP_TLV_RW_MASK;
1875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
1885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
1895d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
1905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Initializes a Fifo Cyclic Buffer to point to some allocated memory.
1915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
1925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phFriNfc_Llcp_CyclicFifoInit(P_UTIL_FIFO_BUFFER   pUtilFifo,
1935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                  const uint8_t        *pBuffStart,
1945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                  uint32_t             buffLength)
1955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
1965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pBuffStart = (uint8_t *)pBuffStart;
1975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pBuffEnd   = (uint8_t *)pBuffStart + buffLength-1;
1985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pIn        = (uint8_t *)pBuffStart;
1995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pOut       = (uint8_t *)pBuffStart;
2005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->bFull      = FALSE;
2015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
2045d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Clears the Fifo Cyclic Buffer - loosing any data that was in it.
2055d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyvoid phFriNfc_Llcp_CyclicFifoClear(P_UTIL_FIFO_BUFFER pUtilFifo)
2075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pIn = pUtilFifo->pBuffStart;
2095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->pOut = pUtilFifo->pBuffStart;
2105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pUtilFifo->bFull      = FALSE;
2115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
2145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Attempts to write dataLength bytes to the specified Fifo Cyclic Buffer.
2155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_CyclicFifoWrite(P_UTIL_FIFO_BUFFER   pUtilFifo,
2175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                       uint8_t              *pData,
2185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                       uint32_t             dataLength)
2195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t dataLengthWritten = 0;
2215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pNext;
2225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   while(dataLengthWritten < dataLength)
2245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
2255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      pNext = (uint8_t*)pUtilFifo->pIn+1;
2265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(pNext > pUtilFifo->pBuffEnd)
2285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
2295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         //Wrap around
2305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         pNext = pUtilFifo->pBuffStart;
2315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
2325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(pUtilFifo->bFull)
2345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
2355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         //Full
2365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         break;
2375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
2385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(pNext == pUtilFifo->pOut)
2405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
2415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         // Trigger Full flag
2425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         pUtilFifo->bFull = TRUE;
2435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
2445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      dataLengthWritten++;
2465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      *pNext = *pData++;
2475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      pUtilFifo->pIn = pNext;
2485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
2495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return dataLengthWritten;
2515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
2545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Attempts to read dataLength bytes from the specified  Fifo Cyclic Buffer.
2555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_CyclicFifoFifoRead(P_UTIL_FIFO_BUFFER   pUtilFifo,
2575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                          uint8_t              *pBuffer,
2585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly                                          uint32_t             dataLength)
2595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
2605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t  dataLengthRead = 0;
2615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pNext;
2625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   while(dataLengthRead < dataLength)
2645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
2655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if((pUtilFifo->pOut == pUtilFifo->pIn) && (pUtilFifo->bFull == FALSE))
2665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
2675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         //No more bytes in buffer
2685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         break;
2695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
2705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      else
2715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
2725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLengthRead++;
2735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         if(pUtilFifo->pOut == pUtilFifo->pBuffEnd)
2755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         {
2765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly            /* Wrap around */
2775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly            pNext = pUtilFifo->pBuffStart;
2785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         }
2795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         else
2805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         {
2815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly            pNext = (uint8_t*)pUtilFifo->pOut + 1;
2825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         }
2835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         *pBuffer++ = *pNext;
2855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         pUtilFifo->pOut = pNext;
2875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2885d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         pUtilFifo->bFull = FALSE;
2895d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
2905d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
2915d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2925d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return dataLengthRead;
2935d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
2945d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
2955d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
2965d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Returns the number of bytes currently stored in Fifo Cyclic Buffer.
2975d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
2985d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_CyclicFifoUsage(P_UTIL_FIFO_BUFFER pUtilFifo)
2995d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3005d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t dataLength;
3015d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pIn        = (uint8_t *)pUtilFifo->pIn;
3025d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pOut       = (uint8_t *)pUtilFifo->pOut;
3035d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3045d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if (pUtilFifo->bFull)
3055d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
3065d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      dataLength = pUtilFifo->pBuffEnd - pUtilFifo->pBuffStart + 1;
3075d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
3085d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   else
3095d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
3105d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(pIn >= pOut)
3115d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
3125d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLength = pIn - pOut;
3135d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
3145d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      else
3155d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
3165d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLength = pUtilFifo->pBuffEnd - pOut;
3175d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLength += (pIn+1) - pUtilFifo->pBuffStart;
3185d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
3195d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
3205d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3215d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return dataLength;
3225d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3235d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3245d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3255d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly/**
3265d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly * Returns the available room for writing in Fifo Cyclic Buffer.
3275d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly */
3285d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_CyclicFifoAvailable(P_UTIL_FIFO_BUFFER pUtilFifo)
3295d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3305d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t dataLength;
3315d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t  size;
3325d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pIn         = (uint8_t *)pUtilFifo->pIn;
3335d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint8_t * pOut        = (uint8_t *)pUtilFifo->pOut;
3345d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3355d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   if (pUtilFifo->bFull)
3365d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
3375d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      dataLength = 0;
3385d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
3395d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   else
3405d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   {
3415d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      if(pIn >= pOut)
3425d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
3435d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         size = pUtilFifo->pBuffEnd - pUtilFifo->pBuffStart + 1;
3445d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLength = size - (pIn - pOut);
3455d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
3465d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      else
3475d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      {
3485d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly         dataLength = pOut - pIn;
3495d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly      }
3505d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   }
3515d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3525d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return dataLength;
3535d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3545d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3555d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3565d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3575d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_Header2Buffer( phFriNfc_Llcp_sPacketHeader_t *psHeader, uint8_t *pBuffer, uint32_t nOffset )
3585d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3595d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t nOriginalOffset = nOffset;
3605d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pBuffer[nOffset++] = (uint8_t)((psHeader->dsap << 2)  | (psHeader->ptype >> 2));
3615d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pBuffer[nOffset++] = (uint8_t)((psHeader->ptype << 6) | psHeader->ssap);
3625d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return nOffset - nOriginalOffset;
3635d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3645d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3655d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_Sequence2Buffer( phFriNfc_Llcp_sPacketSequence_t *psSequence, uint8_t *pBuffer, uint32_t nOffset )
3665d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3675d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   uint32_t nOriginalOffset = nOffset;
3685d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   pBuffer[nOffset++] = (uint8_t)((psSequence->ns << 4) | (psSequence->nr));
3695d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return nOffset - nOriginalOffset;
3705d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3715d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3725d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_Buffer2Header( uint8_t *pBuffer, uint32_t nOffset, phFriNfc_Llcp_sPacketHeader_t *psHeader )
3735d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3745d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psHeader->dsap  = (pBuffer[nOffset] & 0xFC) >> 2;
3755d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psHeader->ptype = ((pBuffer[nOffset]  & 0x03) << 2) | ((pBuffer[nOffset+1] & 0xC0) >> 6);
3765d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psHeader->ssap  = pBuffer[nOffset+1] & 0x3F;
3775d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return PHFRINFC_LLCP_PACKET_HEADER_SIZE;
3785d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3795d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3805d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pellyuint32_t phFriNfc_Llcp_Buffer2Sequence( uint8_t *pBuffer, uint32_t nOffset, phFriNfc_Llcp_sPacketSequence_t *psSequence )
3815d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly{
3825d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psSequence->ns = pBuffer[nOffset] >> 4;
3835d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   psSequence->nr = pBuffer[nOffset] & 0x0F;
3845d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly   return PHFRINFC_LLCP_PACKET_SEQUENCE_SIZE;
3855d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly}
3865d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
3875d9927ba30ba449badb9f6df0fbeb4d6aedc6e2aNick Pelly
388