From: youngman Date: Tue, 19 Apr 2016 06:36:04 +0000 (+0900) Subject: Merge branch 'upstream' into tizen X-Git-Tag: accepted/tizen/mobile/20160423.055559 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Ftags%2Faccepted%2Ftizen%2Fmobile%2F20160423.055559;p=platform%2Fupstream%2Fiotivity.git Merge branch 'upstream' into tizen Change-Id: I5f0484c94f6b5da87c54c54e1f78eaafba10f8e1 --- 7225939b069c31661c5512510fdc262ebef7b4ce diff --cc build_common/external_libs.scons index 62d2816,2e28220..99a64ff --- a/build_common/external_libs.scons +++ b/build_common/external_libs.scons @@@ -135,5 -139,5 +139,5 @@@ env.AddMethod(__download, "Download" env.AddMethod(__install_head_file, "InstallHeadFile") env.AddMethod(__install_lib, "InstallLib") -if env.get('SECURED') == '1': +if env.get('SECURED') == '1' and target_os != 'tizen': - SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'sqlite3', 'SConscript')) + SConscript(os.path.join(env.get('SRC_DIR'), 'extlibs', 'sqlite3', 'SConscript')) diff --cc extlibs/tinycbor/tinycbor/.tag index 0000000,0000000..658911e new file mode 100644 --- /dev/null +++ b/extlibs/tinycbor/tinycbor/.tag @@@ -1,0 -1,0 +1,1 @@@ ++ddd99e434c45f30c186e320a79bb04856d0b0e5a diff --cc extlibs/tinycbor/tinycbor/.travis.yml index 0000000,0000000..f7a5dec new file mode 100644 --- /dev/null +++ b/extlibs/tinycbor/tinycbor/.travis.yml @@@ -1,0 -1,0 +1,25 @@@ ++language: cpp ++os: ++ - linux ++ - osx ++env: ++ - CFLAGS="-O0 -g" QMAKEFLAGS="-config debug" PATH=/opt/qt56/bin:/usr/local/opt/qt5/bin:$PATH ++install: ++ - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ++ sudo apt-add-repository -y ppa:beineri/opt-qt56; ++ sudo apt-add-repository -y ppa:ubuntu-toolchain-r/test; ++ sudo apt-get update -qq; ++ sudo apt-get install -y qt56base valgrind g++-5; ++ else ++ brew install qt5; ++ fi ++script: ++ - if [ "${TRAVIS_OS_NAME}" = "linux" ]; then ++ sudo ln -sf g++-5 /usr/bin/g++; ++ fi ++ - make -s -f Makefile.configure configure | tee .config ++ - make ++ CFLAGS="$CFLAGS" ++ all tests/Makefile ++ - cd tests && make check -k ++ TESTRUNNER=`which valgrind 2>/dev/null` diff --cc extlibs/tinycbor/tinycbor/LICENSE index 0000000,0000000..89de354 new file mode 100644 --- /dev/null +++ b/extlibs/tinycbor/tinycbor/LICENSE @@@ -1,0 -1,0 +1,17 @@@ ++Permission is hereby granted, free of charge, to any person obtaining a copy ++of this software and associated documentation files (the "Software"), to deal ++in the Software without restriction, including without limitation the rights ++to use, copy, modify, merge, publish, distribute, sublicense, and/or sell ++copies of the Software, and to permit persons to whom the Software is ++furnished to do so, subject to the following conditions: ++ ++The above copyright notice and this permission notice shall be included in ++all copies or substantial portions of the Software. ++ ++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE ++AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER ++LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, ++OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN ++THE SOFTWARE. diff --cc extlibs/tinycbor/tinycbor/examples/simplereader.c index bb1798d,0000000..256191f mode 100644,000000..100644 --- a/extlibs/tinycbor/tinycbor/examples/simplereader.c +++ b/extlibs/tinycbor/tinycbor/examples/simplereader.c @@@ -1,175 -1,0 +1,181 @@@ +#include "../src/cbor.h" + +#include +#include +#include +#include +#include + - static char *readfile(const char *fname, size_t *size) ++static uint8_t *readfile(const char *fname, size_t *size) +{ + struct stat st; + FILE *f = fopen(fname, "rb"); + if (!f) + return NULL; + if (fstat(fileno(f), &st) == -1) + return NULL; - char *buf = malloc(st.st_size); ++ uint8_t *buf = malloc(st.st_size); + *size = fread(buf, st.st_size, 1, f); + fclose(f); + return buf; +} + +static void indent(int nestingLevel) +{ + while (nestingLevel--) + puts(" "); +} + - static void dumpbytes(const char *buf, size_t len) ++static void dumpbytes(const uint8_t *buf, size_t len) +{ + while (len--) - printf("%02X ", (unsigned char)*buf++); ++ printf("%02X ", *buf++); +} + +static bool dumprecursive(CborValue *it, int nestingLevel) +{ + while (!cbor_value_at_end(it)) { + CborError err; + CborType type = cbor_value_get_type(it); + + indent(nestingLevel); + switch (type) { + case CborArrayType: + case CborMapType: { + // recursive type + CborValue recursed; + assert(cbor_value_is_container(it)); + puts(type == CborArrayType ? "Array[" : "Map["); + err = cbor_value_enter_container(it, &recursed); + if (err) + return err; // parse error + err = dumprecursive(&recursed, nestingLevel + 1); + if (err) + return err; // parse error + err = cbor_value_leave_container(it, &recursed); + if (err) + return err; // parse error + indent(nestingLevel); + puts("]"); + continue; + } + + case CborIntegerType: { + int64_t val; + cbor_value_get_int64(it, &val); // can't fail + printf("%lld\n", (long long)val); + break; + } + - case CborByteStringType: ++ case CborByteStringType: { ++ uint8_t *buf; ++ size_t n; ++ err = cbor_value_dup_byte_string(it, &buf, &n, it); ++ if (err) ++ return err; // parse error ++ dumpbytes(buf, n); ++ puts(""); ++ free(buf); ++ continue; ++ } ++ + case CborTextStringType: { + char *buf; + size_t n; - err = cbor_value_dup_string(it, &buf, &n, it); ++ err = cbor_value_dup_text_string(it, &buf, &n, it); + if (err) + return err; // parse error - if (type == CborByteStringType) { - dumpbytes(buf, n); - puts(""); - } else { - puts(buf); - } ++ puts(buf); + free(buf); + continue; + } + + case CborTagType: { + CborTag tag; + cbor_value_get_tag(it, &tag); // can't fail + printf("Tag(%lld)\n", (long long)tag); + break; + } + + case CborSimpleType: { + uint8_t type; + cbor_value_get_simple_type(it, &type); // can't fail + printf("simple(%u)\n", type); + break; + } + + case CborNullType: + puts("null"); + break; + + case CborUndefinedType: + puts("undefined"); + break; + + case CborBooleanType: { + bool val; + cbor_value_get_boolean(it, &val); // can't fail + puts(val ? "true" : "false"); + break; + } + + case CborDoubleType: { + double val; + if (false) { + float f; + case CborFloatType: + cbor_value_get_float(it, &f); + val = f; + } else { + cbor_value_get_double(it, &val); + } + printf("%g\n", val); + break; + } + case CborHalfFloatType: { + uint16_t val; + cbor_value_get_half_float(it, &val); + printf("__f16(%04x)\n", val); + break; + } + + case CborInvalidType: + assert(false); // can't happen + break; + } + + err = cbor_value_advance_fixed(it); + if (err) + return err; + } + return CborNoError; +} + +int main(int argc, char **argv) +{ + if (argc == 1) { + puts("simplereader "); + return 0; + } + + size_t length; - char *buf = readfile(argv[1], &length); ++ uint8_t *buf = readfile(argv[1], &length); + if (!buf) { + perror("readfile"); + return 1; + } + + CborParser parser; + CborValue it; + CborError err = cbor_parser_init(buf, length, 0, &parser, &it); + if (!err) + err = dumprecursive(&it, 0); + free(buf); + + if (err) { + fprintf(stderr, "CBOR parsing failure at offset %ld: %s\n", + it.ptr - buf, cbor_error_string(err)); + return 1; + } + return 0; +} diff --cc extlibs/tinycbor/tinycbor/src/cborparser.c index ab3cae1,0000000..61c378a mode 100644,000000..100644 --- a/extlibs/tinycbor/tinycbor/src/cborparser.c +++ b/extlibs/tinycbor/tinycbor/src/cborparser.c @@@ -1,736 -1,0 +1,738 @@@ +/**************************************************************************** +** +** Copyright (C) 2015 Intel Corporation +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +** THE SOFTWARE. +** +****************************************************************************/ + +#define _BSD_SOURCE 1 +#include "cbor.h" +#include "cborconstants_p.h" +#include "compilersupport_p.h" +#include "extract_number_p.h" + +#include +#include +#include + +#include "assert_p.h" /* Always include last */ + +#ifndef CBOR_PARSER_MAX_RECURSIONS +# define CBOR_PARSER_MAX_RECURSIONS 1024 +#endif + +/** + * \typedef CborValue + * This type contains one value parsed from the CBOR stream. + * + * To get the actual type, use cbor_value_get_type(). Then extract the value + * using one of the corresponding functions: cbor_value_get_boolean(), cbor_value_get_int64(), + * cbor_value_get_int(), cbor_value_copy_string(), cbor_value_get_array(), cbor_value_get_map(), + * cbor_value_get_double(), cbor_value_get_float(). + * + * In C++ and C11 modes, you can additionally use the cbor_value_get_integer() + * and cbor_value_get_floating_point() generic functions. + * + * \omit + * Implementation details: the CborValue contains these fields: + * \list + * \li ptr: pointer to the actual data + * \li flags: flags from the decoder + * \li extra: partially decoded integer value (0, 1 or 2 bytes) + * \li remaining: remaining items in this collection after this item or UINT32_MAX if length is unknown + * \endlist + * \endomit + */ + +static CborError extract_length(const CborParser *parser, const uint8_t **ptr, size_t *len) +{ + uint64_t v; + CborError err = extract_number(ptr, parser->end, &v); - if (err) ++ if (err) { ++ *len = 0; + return err; ++ } + + *len = v; + if (v != *len) + return CborErrorDataTooLarge; + return CborNoError; +} + +static bool is_fixed_type(uint8_t type) +{ + return type != CborTextStringType && type != CborByteStringType && type != CborArrayType && + type != CborMapType; +} + +static CborError preparse_value(CborValue *it) +{ + const CborParser *parser = it->parser; + it->type = CborInvalidType; + + // are we at the end? + if (it->ptr == parser->end) + return CborErrorUnexpectedEOF; + + uint8_t descriptor = *it->ptr; + uint8_t type = descriptor & MajorTypeMask; + it->type = type; + it->flags = 0; + it->extra = (descriptor &= SmallValueMask); + + if (descriptor > Value64Bit) { + if (unlikely(descriptor != IndefiniteLength)) + return type == CborSimpleType ? CborErrorUnknownType : CborErrorIllegalNumber; + if (likely(!is_fixed_type(type))) { + // special case + it->flags |= CborIteratorFlag_UnknownLength; + it->type = type; + return CborNoError; + } + return type == CborSimpleType ? CborErrorUnexpectedBreak : CborErrorIllegalNumber; + } + + size_t bytesNeeded = descriptor < Value8Bit ? 0 : (1 << (descriptor - Value8Bit)); + if (bytesNeeded + 1 > (size_t)(parser->end - it->ptr)) + return CborErrorUnexpectedEOF; + + uint8_t majortype = type >> MajorTypeShift; + if (majortype == NegativeIntegerType) { + it->flags |= CborIteratorFlag_NegativeInteger; + it->type = CborIntegerType; + } else if (majortype == SimpleTypesType) { + switch (descriptor) { + case FalseValue: + it->extra = false; + it->type = CborBooleanType; + break; + + case SinglePrecisionFloat: + case DoublePrecisionFloat: + it->flags |= CborIteratorFlag_IntegerValueTooLarge; + // fall through + case TrueValue: + case NullValue: + case UndefinedValue: + case HalfPrecisionFloat: + it->type = *it->ptr; + break; + + case SimpleTypeInNextByte: + it->extra = (uint8_t)it->ptr[1]; +#ifndef CBOR_PARSER_NO_STRICT_CHECKS + if (unlikely(it->extra < 32)) { + it->type = CborInvalidType; + return CborErrorIllegalSimpleType; + } +#endif + break; + + case 28: + case 29: + case 30: + case Break: + assert(false); // these conditions can't be reached + return CborErrorUnexpectedBreak; + } + return CborNoError; + } + + // try to decode up to 16 bits + if (descriptor < Value8Bit) + return CborNoError; + + if (descriptor == Value8Bit) + it->extra = (uint8_t)it->ptr[1]; + else if (descriptor == Value16Bit) + it->extra = get16(it->ptr + 1); + else + it->flags |= CborIteratorFlag_IntegerValueTooLarge; // Value32Bit or Value64Bit + return CborNoError; +} + +static CborError preparse_next_value(CborValue *it) +{ + if (it->remaining != UINT32_MAX) { + // don't decrement the item count if the current item is tag: they don't count + if (it->type != CborTagType && !--it->remaining) { + it->type = CborInvalidType; + return CborNoError; + } + } else if (it->remaining == UINT32_MAX && it->ptr != it->parser->end && *it->ptr == (uint8_t)BreakByte) { + // end of map or array + ++it->ptr; + it->type = CborInvalidType; + it->remaining = 0; + return CborNoError; + } + + return preparse_value(it); +} + +static CborError advance_internal(CborValue *it) +{ + uint64_t length; + CborError err = extract_number(&it->ptr, it->parser->end, &length); + assert(err == CborNoError); + + if (it->type == CborByteStringType || it->type == CborTextStringType) { + assert(length == (size_t)length); + assert((it->flags & CborIteratorFlag_UnknownLength) == 0); + it->ptr += length; + } + + return preparse_next_value(it); +} + +/** \internal + * + * Decodes the CBOR integer value when it is larger than the 16 bits available + * in value->extra. This function requires that value->flags have the + * CborIteratorFlag_IntegerValueTooLarge flag set. + * + * This function is also used to extract single- and double-precision floating + * point values (SinglePrecisionFloat == Value32Bit and DoublePrecisionFloat == + * Value64Bit). + */ +uint64_t _cbor_value_decode_int64_internal(const CborValue *value) +{ + assert(value->flags & CborIteratorFlag_IntegerValueTooLarge || + value->type == CborFloatType || value->type == CborDoubleType); + + // since the additional information can only be Value32Bit or Value64Bit, + // we just need to test for the one bit those two options differ + assert((*value->ptr & SmallValueMask) == Value32Bit || (*value->ptr & SmallValueMask) == Value64Bit); + if ((*value->ptr & 1) == (Value32Bit & 1)) + return get32(value->ptr + 1); + + assert((*value->ptr & SmallValueMask) == Value64Bit); + return get64(value->ptr + 1); +} + +/** + * Initializes the CBOR parser for parsing \a size bytes beginning at \a + * buffer. Parsing will use flags set in \a flags. The iterator to the first + * element is returned in \a it. + * + * The \a parser structure needs to remain valid throughout the decoding + * process. It is not thread-safe to share one CborParser among multiple + * threads iterating at the same time, but the object can be copied so multiple + * threads can iterate. + * + * ### Write how to determine the end pointer + * ### Write how to do limited-buffer windowed decoding + */ +CborError cbor_parser_init(const uint8_t *buffer, size_t size, int flags, CborParser *parser, CborValue *it) +{ + memset(parser, 0, sizeof(*parser)); + parser->end = buffer + size; + parser->flags = flags; + it->parser = parser; + it->ptr = buffer; + it->remaining = 1; // there's one type altogether, usually an array or map + return preparse_value(it); +} + +/** + * Advances the CBOR value \a it by one fixed-size position. Fixed-size types + * are: integers, tags, simple types (including boolean, null and undefined + * values) and floating point types. + * + * \sa cbor_value_at_end(), cbor_value_advance(), cbor_value_begin_recurse(), cbor_value_end_recurse() + */ +CborError cbor_value_advance_fixed(CborValue *it) +{ + assert(it->type != CborInvalidType); + assert(is_fixed_type(it->type)); + if (!it->remaining) + return CborErrorAdvancePastEOF; + return advance_internal(it); +} + +static CborError advance_recursive(CborValue *it, int nestingLevel) +{ + if (is_fixed_type(it->type)) + return advance_internal(it); + + if (!cbor_value_is_container(it)) { + size_t len = SIZE_MAX; + return _cbor_value_copy_string(it, NULL, &len, it); + } + + // map or array + if (nestingLevel == CBOR_PARSER_MAX_RECURSIONS) + return CborErrorNestingTooDeep; + + CborError err; + CborValue recursed; + err = cbor_value_enter_container(it, &recursed); + if (err) + return err; + while (!cbor_value_at_end(&recursed)) { + err = advance_recursive(&recursed, nestingLevel + 1); + if (err) + return err; + } + return cbor_value_leave_container(it, &recursed); +} + + +/** + * Advances the CBOR value \a it by one element, skipping over containers. + * Unlike cbor_value_advance_fixed(), this function can be called on a CBOR + * value of any type. However, if the type is a container (map or array) or a + * string with a chunked payload, this function will not run in constant time + * and will recurse into itself (it will run on O(n) time for the number of + * elements or chunks and will use O(n) memory for the number of nested + * containers). + * + * \sa cbor_value_at_end(), cbor_value_advance_fixed(), cbor_value_begin_recurse(), cbor_value_end_recurse() + */ +CborError cbor_value_advance(CborValue *it) +{ + assert(it->type != CborInvalidType); + if (!it->remaining) + return CborErrorAdvancePastEOF; + return advance_recursive(it, 0); +} + +/** + * Advances the CBOR value \a it until it no longer points to a tag. If \a it is + * already not pointing to a tag, then this function returns it unchanged. + * + * \sa cbor_value_advance_fixed(), cbor_value_advance() + */ +CborError cbor_value_skip_tag(CborValue *it) +{ + while (cbor_value_is_tag(it)) { + CborError err = cbor_value_advance_fixed(it); + if (err) + return err; + } + return CborNoError; +} + +/** + * \fn bool cbor_value_is_container(const CborValue *it) + * + * Returns true if the \a it value is a container and requires recursion in + * order to decode (maps and arrays), false otherwise. + */ + +/** + * Creates a CborValue iterator pointing to the first element of the container + * represented by \a it and saves it in \a recursed. The \a it container object + * needs to be kept and passed again to cbor_value_leave_container() in order + * to continue iterating past this container. + * + * \sa cbor_value_is_container(), cbor_value_leave_container(), cbor_value_advance() + */ +CborError cbor_value_enter_container(const CborValue *it, CborValue *recursed) +{ + CborError err; + assert(cbor_value_is_container(it)); + *recursed = *it; + + if (it->flags & CborIteratorFlag_UnknownLength) { + recursed->remaining = UINT32_MAX; + ++recursed->ptr; + err = preparse_value(recursed); + if (err != CborErrorUnexpectedBreak) + return err; + // actually, break was expected here + // it's just an empty container + ++recursed->ptr; + } else { + uint64_t len; + err = extract_number(&recursed->ptr, recursed->parser->end, &len); + assert(err == CborNoError); + + recursed->remaining = len; + if (recursed->remaining != len || len == UINT32_MAX) { + // back track the pointer to indicate where the error occurred + recursed->ptr = it->ptr; + return CborErrorDataTooLarge; + } + if (recursed->type == CborMapType) { + // maps have keys and values, so we need to multiply by 2 + if (recursed->remaining > UINT32_MAX / 2) { + // back track the pointer to indicate where the error occurred + recursed->ptr = it->ptr; + return CborErrorDataTooLarge; + } + recursed->remaining *= 2; + } + if (len != 0) + return preparse_value(recursed); + } + + // the case of the empty container + recursed->type = CborInvalidType; + recursed->remaining = 0; + return CborNoError; +} + +/** + * Updates \a it to point to the next element after the container. The \a + * recursed object needs to point to the element obtained either by advancing + * the last element of the container (via cbor_value_advance(), + * cbor_value_advance_fixed(), a nested cbor_value_leave_container(), or the \c + * next pointer from cbor_value_copy_string() or cbor_value_dup_string()). + * + * \sa cbor_value_enter_container(), cbor_value_at_end() + */ +CborError cbor_value_leave_container(CborValue *it, const CborValue *recursed) +{ + assert(cbor_value_is_container(it)); + assert(recursed->type == CborInvalidType); + it->ptr = recursed->ptr; + return preparse_next_value(it); +} + +/** + * Calculates the length of the string in \a value and stores the result in \a + * len. This function is different from cbor_value_get_string_length() in that + * it calculates the length even for strings sent in chunks. For that reason, + * this function may not run in constant time (it will run in O(n) time on the + * number of chunks). + * + * \note On 32-bit platforms, this function will return error condition of \ref + * CborErrorDataTooLarge if the stream indicates a length that is too big to + * fit in 32-bit. + * + * \sa cbor_value_get_string_length(), cbor_value_copy_string(), cbor_value_is_length_known() + */ +CborError cbor_value_calculate_string_length(const CborValue *value, size_t *len) +{ + *len = SIZE_MAX; + return _cbor_value_copy_string(value, NULL, len, NULL); +} + +/** + * \fn CborError cbor_value_dup_text_string(const CborValue *value, char **buffer, size_t *buflen, CborValue *next) + * + * Allocates memory for the string pointed by \a value and copies it into this + * buffer. The pointer to the buffer is stored in \a buffer and the number of + * bytes copied is stored in \a len (those variables must not be NULL). + * + * If \c malloc returns a NULL pointer, this function will return error + * condition \ref CborErrorOutOfMemory. + * + * On success, \c{*buffer} will contain a valid pointer that must be freed by + * calling \c{free()}. This is the case even for zero-length strings. + * + * The \a next pointer, if not null, will be updated to point to the next item + * after this string. If \a value points to the last item, then \a next will be + * invalid. + * + * \note This function does not perform UTF-8 validation on the incoming text + * string. + * + * \sa cbor_value_copy_text_string(), cbor_value_dup_byte_string() + */ + +/** + * \fn CborError cbor_value_dup_byte_string(const CborValue *value, uint8_t **buffer, size_t *buflen, CborValue *next) + * + * Allocates memory for the string pointed by \a value and copies it into this + * buffer. The pointer to the buffer is stored in \a buffer and the number of + * bytes copied is stored in \a len (those variables must not be NULL). + * + * If \c malloc returns a NULL pointer, this function will return error + * condition \ref CborErrorOutOfMemory. + * + * On success, \c{*buffer} will contain a valid pointer that must be freed by + * calling \c{free()}. This is the case even for zero-length strings. + * + * The \a next pointer, if not null, will be updated to point to the next item + * after this string. If \a value points to the last item, then \a next will be + * invalid. + * + * \sa cbor_value_copy_byte_string(), cbor_value_dup_text_string() + */ +CborError _cbor_value_dup_string(const CborValue *value, void **buffer, size_t *buflen, CborValue *next) +{ + assert(buffer); + assert(buflen); + *buflen = SIZE_MAX; + CborError err = _cbor_value_copy_string(value, NULL, buflen, NULL); + if (err) + return err; + + ++*buflen; + *buffer = malloc(*buflen); + if (!*buffer) { + // out of memory + return CborErrorOutOfMemory; + } + err = _cbor_value_copy_string(value, *buffer, buflen, next); + if (err) { + free(*buffer); + return err; + } + return CborNoError; +} + +// We return uintptr_t so that we can pass memcpy directly as the iteration +// function. The choice is to optimize for memcpy, which is used in the base +// parser API (cbor_value_copy_string), while memcmp is used in convenience API +// only. +typedef uintptr_t (*IterateFunction)(char *, const uint8_t *, size_t); + +static uintptr_t iterate_noop(char *dest, const uint8_t *src, size_t len) +{ + (void)dest; + (void)src; + (void)len; + return true; +} + +static uintptr_t iterate_memcmp(char *s1, const uint8_t *s2, size_t len) +{ + return memcmp(s1, (const char *)s2, len) == 0; +} + +static CborError iterate_string_chunks(const CborValue *value, char *buffer, size_t *buflen, + bool *result, CborValue *next, IterateFunction func) +{ + assert(cbor_value_is_byte_string(value) || cbor_value_is_text_string(value)); + + size_t total; + CborError err; + const uint8_t *ptr = value->ptr; + if (cbor_value_is_length_known(value)) { + // easy case: fixed length + err = extract_length(value->parser, &ptr, &total); + if (err) + return err; + if (total > (size_t)(value->parser->end - ptr)) + return CborErrorUnexpectedEOF; + if (total <= *buflen) + *result = func(buffer, ptr, total); + else + *result = false; + ptr += total; + } else { + // chunked + ++ptr; + total = 0; + *result = true; + while (true) { + size_t chunkLen; + size_t newTotal; + + if (ptr == value->parser->end) + return CborErrorUnexpectedEOF; + + if (*ptr == (uint8_t)BreakByte) { + ++ptr; + break; + } + + // is this the right type? + if ((*ptr & MajorTypeMask) != value->type) + return CborErrorIllegalType; + + err = extract_length(value->parser, &ptr, &chunkLen); + if (err) + return err; + + if (unlikely(add_check_overflow(total, chunkLen, &newTotal))) + return CborErrorDataTooLarge; + + if (chunkLen > (size_t)(value->parser->end - ptr)) + return CborErrorUnexpectedEOF; + + if (*result && *buflen >= newTotal) + *result = func(buffer + total, ptr, chunkLen); + else + *result = false; + + ptr += chunkLen; + total = newTotal; + } + } + + // is there enough room for the ending NUL byte? + if (*result && *buflen > total) + *result = func(buffer + total, (const uint8_t *)"", 1); + *buflen = total; + + if (next) { + *next = *value; + next->ptr = ptr; + return preparse_next_value(next); + } + return CborNoError; +} + +/** + * \fn CborError cbor_value_copy_text_string(const CborValue *value, char *buffer, size_t *buflen, CborValue *next) + * + * Copies the string pointed by \a value into the buffer provided at \a buffer + * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not + * copy anything and will only update the \a next value. + * + * If the provided buffer length was too small, this function returns an error + * condition of \ref CborErrorOutOfMemory. If you need to calculate the length + * of the string in order to preallocate a buffer, use + * cbor_value_calculate_string_length(). + * + * On success, this function sets the number of bytes copied to \c{*buflen}. If + * the buffer is large enough, this function will insert a null byte after the + * last copied byte, to facilitate manipulation of text strings. That byte is + * not included in the returned value of \c{*buflen}. + * + * The \a next pointer, if not null, will be updated to point to the next item + * after this string. If \a value points to the last item, then \a next will be + * invalid. + * + * \note This function does not perform UTF-8 validation on the incoming text + * string. + * + * \sa cbor_value_dup_text_string(), cbor_value_copy_byte_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length() + */ + +/** + * \fn CborError cbor_value_copy_byte_string(const CborValue *value, uint8_t *buffer, size_t *buflen, CborValue *next) + * + * Copies the string pointed by \a value into the buffer provided at \a buffer + * of \a buflen bytes. If \a buffer is a NULL pointer, this function will not + * copy anything and will only update the \a next value. + * + * If the provided buffer length was too small, this function returns an error + * condition of \ref CborErrorOutOfMemory. If you need to calculate the length + * of the string in order to preallocate a buffer, use + * cbor_value_calculate_string_length(). + * + * On success, this function sets the number of bytes copied to \c{*buflen}. If + * the buffer is large enough, this function will insert a null byte after the + * last copied byte, to facilitate manipulation of null-terminated strings. + * That byte is not included in the returned value of \c{*buflen}. + * + * The \a next pointer, if not null, will be updated to point to the next item + * after this string. If \a value points to the last item, then \a next will be + * invalid. + * + * \sa cbor_value_dup_text_string(), cbor_value_copy_text_string(), cbor_value_get_string_length(), cbor_value_calculate_string_length() + */ + +CborError _cbor_value_copy_string(const CborValue *value, void *buffer, + size_t *buflen, CborValue *next) +{ + bool copied_all; + CborError err = iterate_string_chunks(value, (char*)buffer, buflen, &copied_all, next, + buffer ? (IterateFunction)memcpy : iterate_noop); + return err ? err : + copied_all ? CborNoError : CborErrorOutOfMemory; +} + +/** + * Compares the entry \a value with the string \a string and store the result + * in \a result. If the value is different from \a string or if it is not a + * text string, \a result will contain \c false. + * + * The entry at \a value may be a tagged string. If \a is not a string or a + * tagged string, the comparison result will be false. + */ +CborError cbor_value_text_string_equals(const CborValue *value, const char *string, bool *result) +{ + CborValue copy = *value; + CborError err = cbor_value_skip_tag(©); + if (err) + return err; + if (!cbor_value_is_text_string(©)) { + *result = false; + return CborNoError; + } + + size_t len = strlen(string); + return iterate_string_chunks(©, CONST_CAST(char *, string), &len, result, NULL, iterate_memcmp); +} + +/** + * Attempts to find the value in map \a map that corresponds to the text string + * entry \a string. If the item is found, it is stored in \a result. If no item + * is found matching the key, then \a result will contain an element of type + * \ref CborInvalidType. + * + * \note This function may be expensive to execute. + */ +CborError cbor_value_map_find_value(const CborValue *map, const char *string, CborValue *element) +{ + assert(cbor_value_is_map(map)); + size_t len = strlen(string); + CborError err = cbor_value_enter_container(map, element); + if (err) + goto error; + + while (!cbor_value_at_end(element)) { + // find the non-tag so we can compare + err = cbor_value_skip_tag(element); + if (err) + goto error; + if (cbor_value_is_text_string(element)) { + bool equals; + size_t dummyLen = len; + err = iterate_string_chunks(element, CONST_CAST(char *, string), &dummyLen, + &equals, element, iterate_memcmp); + if (err) + goto error; + if (equals) + return preparse_value(element); + } else { + // skip this key + err = cbor_value_advance(element); + if (err) + goto error; + } + + // skip this value + err = cbor_value_skip_tag(element); + if (err) + goto error; + err = cbor_value_advance(element); + if (err) + goto error; + } + + // not found + element->type = CborInvalidType; + return CborNoError; + +error: + element->type = CborInvalidType; + return err; +} + +/** + * Extracts a half-precision floating point from \a value and stores it in \a + * result. + */ +CborError cbor_value_get_half_float(const CborValue *value, void *result) +{ + assert(value->type == CborHalfFloatType); + + // size has been computed already + uint16_t v = get16(value->ptr + 1); + memcpy(result, &v, sizeof(v)); + return CborNoError; +} diff --cc extlibs/tinycbor/tinycbor/src/extract_number_p.h index d6a430e,0000000..a813b76 mode 100644,000000..100644 --- a/extlibs/tinycbor/tinycbor/src/extract_number_p.h +++ b/extlibs/tinycbor/tinycbor/src/extract_number_p.h @@@ -1,76 -1,0 +1,77 @@@ +/**************************************************************************** +** +** Copyright (C) 2015 Intel Corporation +** +** Permission is hereby granted, free of charge, to any person obtaining a copy +** of this software and associated documentation files (the "Software"), to deal +** in the Software without restriction, including without limitation the rights +** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +** copies of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be included in +** all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +** THE SOFTWARE. +** +****************************************************************************/ + +#define _BSD_SOURCE 1 +#include "cbor.h" +#include "cborconstants_p.h" +#include "compilersupport_p.h" ++#include + +static inline uint16_t get16(const uint8_t *ptr) +{ + uint16_t result; + memcpy(&result, ptr, sizeof(result)); + return cbor_ntohs(result); +} + +static inline uint32_t get32(const uint8_t *ptr) +{ + uint32_t result; + memcpy(&result, ptr, sizeof(result)); + return cbor_ntohl(result); +} + +static inline uint64_t get64(const uint8_t *ptr) +{ + uint64_t result; + memcpy(&result, ptr, sizeof(result)); + return cbor_ntohll(result); +} + +static CborError extract_number(const uint8_t **ptr, const uint8_t *end, uint64_t *len) +{ + uint8_t additional_information = **ptr & SmallValueMask; + ++*ptr; + if (additional_information < Value8Bit) { + *len = additional_information; + return CborNoError; + } + if (unlikely(additional_information > Value64Bit)) + return CborErrorIllegalNumber; + + size_t bytesNeeded = 1 << (additional_information - Value8Bit); + if (unlikely(bytesNeeded > (size_t)(end - *ptr))) { + return CborErrorUnexpectedEOF; + } else if (bytesNeeded == 1) { + *len = (uint8_t)(*ptr)[0]; + } else if (bytesNeeded == 2) { + *len = get16(*ptr); + } else if (bytesNeeded == 4) { + *len = get32(*ptr); + } else { + *len = get64(*ptr); + } + *ptr += bytesNeeded; + return CborNoError; +} diff --cc packaging/iotivity-test.manifest index 6b4e7e1,4030dc1..8002174 --- a/packaging/iotivity-test.manifest +++ b/packaging/iotivity-test.manifest @@@ -5,11 -5,8 +5,10 @@@ + + - - + diff --cc packaging/iotivity.spec index ac06cee,0f0fc35..c335968 --- a/packaging/iotivity.spec +++ b/packaging/iotivity.spec @@@ -148,17 -152,21 +152,20 @@@ cp out/tizen/*/%{build_mode}/resource/e cp out/tizen/*/%{build_mode}/resource/examples/simpleserver %{ex_install_dir} cp out/tizen/*/%{build_mode}/resource/examples/simpleserverHQ %{ex_install_dir} cp out/tizen/*/%{build_mode}/resource/examples/threadingsample %{ex_install_dir} - cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_server.json %{ex_install_dir} - cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_client.json %{ex_install_dir} + cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_server.dat %{ex_install_dir} + cp out/tizen/*/%{build_mode}/resource/examples/oic_svr_db_client.dat %{ex_install_dir} -cp out/tizen/*/%{build_mode}/libcoap.a %{buildroot}%{_libdir} %if 0%{?SECURED} == 1 mkdir -p %{ex_install_dir}/provisioning - cp out/tizen/*/%{build_mode}/resource/provisioning/examples/oic_svr_db_client.json %{ex_install_dir}/provisioning/ - cp out/tizen/*/%{build_mode}/resource/provisioning/examples/provisioningclient %{ex_install_dir}/provisioning/ + mkdir -p %{ex_install_dir}/provision-sample + + cp ./resource/csdk/security/include/pinoxmcommon.h %{buildroot}%{_includedir} + cp ./resource/csdk/security/provisioning/include/oxm/*.h %{buildroot}%{_includedir} + cp ./resource/csdk/security/provisioning/include/internal/*.h %{buildroot}%{_includedir} + cp ./resource/csdk/security/provisioning/include/*.h %{buildroot}%{_includedir} + cp ./resource/csdk/security/provisioning/sample/oic_svr_db_server_justworks.dat %{buildroot}%{_libdir}/oic_svr_db_server.dat + %endif - # For iotcon - cp resource/csdk/stack/include/ocpayload.h %{buildroot}%{_includedir}/resource - cp resource/c_common/ocrandom/include/ocrandom.h %{buildroot}%{_includedir}/resource %if 0%{?tizen_version_major} < 3 mkdir -p %{buildroot}/%{_datadir}/license