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