From d18ae43123fcd7604d1c36a1ec8450dbe6071824 Mon Sep 17 00:00:00 2001 From: Luca Muscariello Date: Thu, 23 Feb 2017 20:44:26 +0100 Subject: Initial commit: ccnxlibs. Change-Id: I1b376527a7dd01a6b9e083a6cb646955902f45c0 Signed-off-by: Luca Muscariello --- .../ccnxCodecSchemaV1_FixedHeaderDecoder.c | 210 +++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100755 libccnx-common/ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeaderDecoder.c (limited to 'libccnx-common/ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeaderDecoder.c') diff --git a/libccnx-common/ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeaderDecoder.c b/libccnx-common/ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeaderDecoder.c new file mode 100755 index 00000000..fcec49b3 --- /dev/null +++ b/libccnx-common/ccnx/common/codec/schema_v1/ccnxCodecSchemaV1_FixedHeaderDecoder.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + */ + +#include + +#include +#include + +#include + +#include +#include + +#include +#include +#include + +static const size_t _fixedHeaderBytes = 8; + +static const int _fixedHeader_VersionOffset = 0; +static const int _fixedHeader_PacketTypeOffset = 1; +static const int _fixedHeader_PacketLengthOffset = 2; +static const int _fixedHeader_HopLimitOffset = 4; +static const int _fixedHeader_ReturnCodeOffset = 5; +static const int _fixedHeader_FlagsOffset = 6; +static const int _fixedHeader_HeaderLengthOffset = 7; + +bool +ccnxCodecSchemaV1FixedHeaderDecoder_Decode(CCNxCodecTlvDecoder *decoder, CCNxTlvDictionary *packetDictionary) +{ + if (ccnxCodecTlvDecoder_EnsureRemaining(decoder, _fixedHeaderBytes)) { + PARCBuffer *buffer = ccnxCodecTlvDecoder_GetValue(decoder, _fixedHeaderBytes); + bool success = ccnxTlvDictionary_PutBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader, buffer); + + // validation + parcBuffer_SetPosition(buffer, _fixedHeader_VersionOffset); + uint8_t version = parcBuffer_GetUint8(buffer); + + parcBuffer_SetPosition(buffer, _fixedHeader_PacketLengthOffset); + uint16_t packetLength = parcBuffer_GetUint16(buffer); + + parcBuffer_SetPosition(buffer, _fixedHeader_ReturnCodeOffset); + uint8_t interestReturnCode = parcBuffer_GetUint8(buffer); + + parcBuffer_SetPosition(buffer, _fixedHeader_HopLimitOffset); + uint8_t hopLimit = parcBuffer_GetUint8(buffer); + + parcBuffer_SetPosition(buffer, _fixedHeader_HeaderLengthOffset); + uint8_t headerLength = parcBuffer_GetUint8(buffer); + + if (version != 1) { + CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_VERSION, __func__, __LINE__, _fixedHeader_VersionOffset); + ccnxCodecTlvDecoder_SetError(decoder, error); + ccnxCodecError_Release(&error); + success = false; + } else if (packetLength < _fixedHeaderBytes) { + CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_PACKETLENGTH_TOO_SHORT, __func__, __LINE__, _fixedHeader_PacketTypeOffset); + ccnxCodecTlvDecoder_SetError(decoder, error); + ccnxCodecError_Release(&error); + success = false; + } else if (headerLength < _fixedHeaderBytes) { + CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_HEADERLENGTH_TOO_SHORT, __func__, __LINE__, _fixedHeader_HeaderLengthOffset); + ccnxCodecTlvDecoder_SetError(decoder, error); + ccnxCodecError_Release(&error); + success = false; + } else if (packetLength < headerLength) { + CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_PACKETLENGTHSHORTER, __func__, __LINE__, _fixedHeader_PacketTypeOffset); + ccnxCodecTlvDecoder_SetError(decoder, error); + ccnxCodecError_Release(&error); + success = false; + } + + // decoder now points to just past the fixed header + parcBuffer_Release(&buffer); + + // Set the hoplimit in the dictionary. + ccnxTlvDictionary_PutInteger(packetDictionary, + CCNxCodecSchemaV1TlvDictionary_MessageFastArray_HOPLIMIT, hopLimit); + + // Set the InterestReturn code in the dictionary. + ccnxTlvDictionary_PutInteger(packetDictionary, + CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_InterestReturnCode, + interestReturnCode); + + return success; + } else { + CCNxCodecError *error = ccnxCodecError_Create(TLV_ERR_DECODE, __func__, __LINE__, ccnxCodecTlvDecoder_Position(decoder)); + ccnxCodecTlvDecoder_SetError(decoder, error); + ccnxCodecError_Release(&error); + return false; + } +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetVersion(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_VersionOffset); + uint8_t version = parcBuffer_GetUint8(fixedHeader); + return version; + } + + return -1; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetPacketType(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_PacketTypeOffset); + uint8_t packetType = parcBuffer_GetUint8(fixedHeader); + return packetType; + } + + return -1; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetPacketLength(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_PacketLengthOffset); + uint16_t payloadLength = parcBuffer_GetUint16(fixedHeader); + return payloadLength; + } + + return -1; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetHeaderLength(CCNxTlvDictionary *packetDictionary) +{ + int length = -1; + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_HeaderLengthOffset); + uint8_t headerLength = parcBuffer_GetUint8(fixedHeader); + + // 8 is the minimum size of headerLength + if (headerLength >= _fixedHeaderBytes) { + length = headerLength; + } + } + + return length; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetOptionalHeaderLength(CCNxTlvDictionary *packetDictionary) +{ + int headerLength = ccnxCodecSchemaV1FixedHeaderDecoder_GetHeaderLength(packetDictionary); + return headerLength - _fixedHeaderBytes; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetHopLimit(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_HopLimitOffset); + uint8_t hopLimit = parcBuffer_GetUint8(fixedHeader); + return hopLimit; + } + + return -1; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetReturnCode(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_ReturnCodeOffset); + uint8_t returnCode = parcBuffer_GetUint8(fixedHeader); + return returnCode; + } + + return -1; +} + +int +ccnxCodecSchemaV1FixedHeaderDecoder_GetFlags(CCNxTlvDictionary *packetDictionary) +{ + PARCBuffer *fixedHeader = ccnxTlvDictionary_GetBuffer(packetDictionary, CCNxCodecSchemaV1TlvDictionary_HeadersFastArray_FixedHeader); + if (fixedHeader != NULL) { + parcBuffer_SetPosition(fixedHeader, _fixedHeader_FlagsOffset); + uint8_t flags = parcBuffer_GetUint8(fixedHeader); + return flags; + } + + return -1; +} -- cgit 1.2.3-korg