From 6e61fb94cb7df501c871a424de3fe1a391bca647 Mon Sep 17 00:00:00 2001 From: mamokarz Date: Mon, 9 Jan 2017 13:19:33 -0800 Subject: [PATCH] Sync the Arduino Library azure-iot-arduino-utility with the latest azure-iot-sdks version --- library.properties | 2 +- src/AzureIoTUtility.h | 2 +- .../aziotsharedutil.def | 250 ++++++++++++++++++ .../connection_string_parser.c | 133 ++++++++++ .../connection_string_parser.h | 22 ++ src/azure_c_shared_utility/string_tokenizer.c | 1 + src/azure_c_shared_utility/xlogging.h | 14 +- 7 files changed, 415 insertions(+), 9 deletions(-) create mode 100644 src/azure_c_shared_utility/aziotsharedutil.def create mode 100644 src/azure_c_shared_utility/connection_string_parser.c create mode 100644 src/azure_c_shared_utility/connection_string_parser.h diff --git a/library.properties b/library.properties index bb9e19f..c1b237a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AzureIoTUtility -version=1.0.17 +version=1.0.21 author=Microsoft maintainer=Microsoft sentence=Azure C shared utility library for Arduino. For the Arduino MKR1000 or Zero and WiFi Shield 101, Adafruit Huzzah and Feather M0, or SparkFun Thing. diff --git a/src/AzureIoTUtility.h b/src/AzureIoTUtility.h index 20c19e1..7af2f91 100644 --- a/src/AzureIoTUtility.h +++ b/src/AzureIoTUtility.h @@ -7,6 +7,6 @@ #include "azure_c_shared_utility/lock.h" #include "azure_c_shared_utility/threadapi.h" -#define AzureIoTUtilityVersion "1.0.17" +#define AzureIoTUtilityVersion "1.0.21" #endif //AZUREIOTUTILITY_H diff --git a/src/azure_c_shared_utility/aziotsharedutil.def b/src/azure_c_shared_utility/aziotsharedutil.def new file mode 100644 index 0000000..1cb742c --- /dev/null +++ b/src/azure_c_shared_utility/aziotsharedutil.def @@ -0,0 +1,250 @@ +LIBRARY aziotsharedutil +EXPORTS + x509_schannel_create + x509_schannel_destroy + x509_schannel_get_certificate_context + tlsio_schannel_create + tlsio_schannel_destroy + tlsio_schannel_open + tlsio_schannel_close + tlsio_schannel_send + tlsio_schannel_dowork + tlsio_schannel_setoption + tlsio_schannel_get_interface_description + HTTPAPI_RESULTStringStorage + HTTPAPI_RESULTStrings + HTTPAPI_RESULT_FromString + HTTPAPI_Init + HTTPAPI_Deinit + HTTPAPI_CreateConnection + HTTPAPI_CloseConnection + HTTPAPI_ExecuteRequest + HTTPAPI_SetOption + HTTPAPI_CloneOption + HTTP_HEADERS_RESULTStringStorage + HTTP_HEADERS_RESULTStrings + HTTP_HEADERS_RESULT_FromString + HTTPHeaders_Alloc + HTTPHeaders_Free + HTTPHeaders_AddHeaderNameValuePair + HTTPHeaders_ReplaceHeaderNameValuePair + HTTPHeaders_FindHeaderValue + HTTPHeaders_GetHeaderCount + HTTPHeaders_GetHeader + HTTPHeaders_Clone + HTTPAPIEX_SAS_Create + HTTPAPIEX_SAS_Destroy + HTTPAPIEX_SAS_ExecuteRequest + HTTPAPIEX_RESULTStringStorage + HTTPAPIEX_RESULTStrings + HTTPAPIEX_RESULT_FromString + HTTPAPIEX_Create + HTTPAPIEX_ExecuteRequest + HTTPAPIEX_Destroy + HTTPAPIEX_SetOption + UNIQUEID_RESULTStringStorage + UNIQUEID_RESULTStrings + UNIQUEID_RESULT_FromString + UniqueId_Generate + THREADAPI_RESULTStringStorage + THREADAPI_RESULTStrings + THREADAPI_RESULT_FromString + ThreadAPI_Create + ThreadAPI_Join + ThreadAPI_Exit + ThreadAPI_Sleep + tickcounter_create + tickcounter_destroy + tickcounter_get_current_ms + socketio_create + socketio_destroy + socketio_open + socketio_close + socketio_send + socketio_dowork + socketio_setoption + socketio_get_interface_description + platform_init + platform_deinit + platform_get_default_tlsio + LOCK_RESULTStringStorage + LOCK_RESULTStrings + LOCK_RESULT_FromString + Lock_Init + Lock + Unlock + Lock_Deinit + COND_RESULTStringStorage + COND_RESULTStrings + COND_RESULT_FromString + Condition_Init + Condition_Post + Condition_Wait + Condition_Deinit + get_time + get_gmtime + get_mktime + get_ctime + get_difftime + OptionHandler_Create + OptionHandler_AddOption + OptionHandler_FeedOptions + OptionHandler_Destroy + global_log_function + xlogging_set_log_function + xlogging_get_log_function + xlogging_dump_buffer + VECTOR_create + VECTOR_destroy + VECTOR_push_back + VECTOR_erase + VECTOR_clear + VECTOR_element + VECTOR_front + VECTOR_back + VECTOR_find_if + VECTOR_size + USHAReset + USHAInput + USHAFinalBits + USHAResult + USHABlockSize + USHAHashSize + USHAHashSizeBits + URL_EncodeString + URL_Encode + STRING_TOKENIZER_create + STRING_TOKENIZER_create_from_char + STRING_TOKENIZER_get_next_token + STRING_TOKENIZER_destroy + STRING_new + STRING_clone + STRING_construct + STRING_construct_n + STRING_new_with_memory + STRING_new_quoted + STRING_new_JSON + STRING_from_byte_array + STRING_delete + STRING_concat + STRING_concat_with_STRING + STRING_quote + STRING_copy + STRING_copy_n + STRING_c_str + STRING_empty + STRING_length + STRING_compare + STRING_construct_sprintf + STRING_sprintf + SHA384Reset + SHA384Input + SHA384FinalBits + SHA384Result + SHA512Reset + SHA512Input + SHA512FinalBits + SHA512Result + SHA224Reset + SHA224Input + SHA224FinalBits + SHA224Result + SHA256Reset + SHA256Input + SHA256FinalBits + SHA256Result + SHA1Reset + SHA1Input + SHA1FinalBits + SHA1Result + SASToken_Validate + SASToken_Create + MAP_RESULTStringStorage + MAP_RESULTStrings + MAP_RESULT_FromString + Map_Create + Map_Destroy + Map_Clone + Map_Add + Map_AddOrUpdate + Map_Delete + Map_ContainsKey + Map_ContainsValue + Map_GetValueFromKey + Map_GetInternals + Map_ToJSON + singlylinkedlist_create + singlylinkedlist_destroy + singlylinkedlist_add + singlylinkedlist_remove + singlylinkedlist_get_head_item + singlylinkedlist_get_next_item + singlylinkedlist_find + singlylinkedlist_item_get_value + xio_create + xio_destroy + xio_open + xio_close + xio_send + xio_dowork + xio_setoption + xio_retrieveoptions + HMACSHA256_ComputeHash + hmac + hmacReset + hmacInput + hmacFinalBits + hmacResult + gballoc_init + gballoc_deinit + gballoc_malloc + gballoc_calloc + gballoc_realloc + gballoc_free + gballoc_getMaximumMemoryUsed + gballoc_getCurrentMemoryUsed + DList_InitializeListHead + DList_IsListEmpty + DList_InsertTailList + DList_InsertHeadList + DList_AppendTailList + DList_RemoveEntryList + DList_RemoveHeadList + CONSTMAP_RESULTStringStorage + CONSTMAP_RESULTStrings + CONSTMAP_RESULT_FromString + ConstMap_Create + ConstMap_Destroy + ConstMap_Clone + ConstMap_CloneWriteable + ConstMap_ContainsKey + ConstMap_ContainsValue + ConstMap_GetValue + ConstMap_GetInternals + mallocAndStrcpy_s + unsignedIntToString + size_tToString + consolelogger_log + CONSTBUFFER_Create + CONSTBUFFER_CreateFromBuffer + CONSTBUFFER_Clone + CONSTBUFFER_GetContent + CONSTBUFFER_Destroy + connectionstringparser_parse + BUFFER_new + BUFFER_create + BUFFER_delete + BUFFER_pre_build + BUFFER_build + BUFFER_unbuild + BUFFER_enlarge + BUFFER_content + BUFFER_size + BUFFER_append + BUFFER_prepend + BUFFER_u_char + BUFFER_length + BUFFER_clone + Base64_Encode + Base64_Encode_Bytes + Base64_Decoder diff --git a/src/azure_c_shared_utility/connection_string_parser.c b/src/azure_c_shared_utility/connection_string_parser.c new file mode 100644 index 0000000..5d0d43c --- /dev/null +++ b/src/azure_c_shared_utility/connection_string_parser.c @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#include "azure_c_shared_utility/connection_string_parser.h" +#include "azure_c_shared_utility/map.h" +#include "azure_c_shared_utility/strings.h" +#include "azure_c_shared_utility/string_tokenizer.h" +#include +#include "azure_c_shared_utility/xlogging.h" + +/* Codes_SRS_CONNECTIONSTRINGPARSER_01_001: [connectionstringparser_parse shall parse all key value pairs from the connection_string passed in as argument and return a new map that holds the key/value pairs.] */ +MAP_HANDLE connectionstringparser_parse(STRING_HANDLE connection_string) +{ + MAP_HANDLE result; + + if (connection_string == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_002: [If connection_string is NULL then connectionstringparser_parse shall fail and return NULL.] */ + result = NULL; + LogError("NULL connection string passed to tokenizer.\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_003: [connectionstringparser_parse shall create a STRING tokenizer to be used for parsing the connection string, by calling STRING_TOKENIZER_create.] */ + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_004: [connectionstringparser_parse shall start scanning at the beginning of the connection string.] */ + STRING_TOKENIZER_HANDLE tokenizer = STRING_TOKENIZER_create(connection_string); + if (tokenizer == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_015: [If STRING_TOKENIZER_create fails, connectionstringparser_parse shall fail and return NULL.] */ + result = NULL; + LogError("Error creating STRING tokenizer.\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_016: [2 STRINGs shall be allocated in order to hold the to be parsed key and value tokens.] */ + STRING_HANDLE token_key_string = STRING_new(); + if (token_key_string == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */ + result = NULL; + LogError("Error creating key token STRING.\r\n"); + } + else + { + STRING_HANDLE token_value_string = STRING_new(); + if (token_value_string == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_017: [If allocating the STRINGs fails connectionstringparser_parse shall fail and return NULL.] */ + result = NULL; + LogError("Error creating value token STRING.\r\n"); + } + else + { + result = Map_Create(NULL); + if (result == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_018: [If creating the result map fails, then connectionstringparser_parse shall return NULL.] */ + LogError("Error creating Map\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_005: [The following actions shall be repeated until parsing is complete:] */ + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_006: [connectionstringparser_parse shall find a token (the key of the key/value pair) delimited by the `=` character, by calling STRING_TOKENIZER_get_next_token.] */ + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_007: [If STRING_TOKENIZER_get_next_token fails, parsing shall be considered complete.] */ + while (STRING_TOKENIZER_get_next_token(tokenizer, token_key_string, "=") == 0) + { + bool is_error = false; + + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_008: [connectionstringparser_parse shall find a token (the value of the key/value pair) delimited by the `;` character, by calling STRING_TOKENIZER_get_next_token.] */ + if (STRING_TOKENIZER_get_next_token(tokenizer, token_value_string, ";") != 0) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_009: [If STRING_TOKENIZER_get_next_token fails, connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ + is_error = true; + LogError("Error reading value token from the connection string.\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */ + const char* token = STRING_c_str(token_key_string); + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ + if ((token == NULL) || + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_019: [If the key length is zero then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ + (strlen(token) == 0)) + { + is_error = true; + LogError("The key token is NULL or empty.\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_011: [The C strings for the key and value shall be extracted from the previously parsed STRINGs by using STRING_c_str.] */ + const char* value = STRING_c_str(token_value_string); + if (value == NULL) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_013: [If STRING_c_str fails then connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ + is_error = true; + LogError("Could not get C string for value token.\r\n"); + } + else + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_010: [The key and value shall be added to the result map by using Map_Add.] */ + if (Map_Add(result, token, value) != 0) + { + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_012: [If Map_Add fails connectionstringparser_parse shall fail and return NULL (freeing the allocated result map).] */ + is_error = true; + LogError("Could not add the key/value pair to the result map.\r\n"); + } + } + } + } + + if (is_error) + { + LogError("Error parsing connection string.\r\n"); + Map_Destroy(result); + result = NULL; + break; + } + } + } + + STRING_delete(token_value_string); + } + + STRING_delete(token_key_string); + } + + /* Codes_SRS_CONNECTIONSTRINGPARSER_01_014: [After the parsing is complete the previously allocated STRINGs and STRING tokenizer shall be freed by calling STRING_TOKENIZER_destroy.] */ + STRING_TOKENIZER_destroy(tokenizer); + } + } + + return result; +} diff --git a/src/azure_c_shared_utility/connection_string_parser.h b/src/azure_c_shared_utility/connection_string_parser.h new file mode 100644 index 0000000..183eb45 --- /dev/null +++ b/src/azure_c_shared_utility/connection_string_parser.h @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#ifndef CONNECTION_STRING_PARSER_H +#define CONNECTION_STRING_PARSER_H + +#include "azure_c_shared_utility/umock_c_prod.h" +#include "azure_c_shared_utility/map.h" +#include "azure_c_shared_utility/strings.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + MOCKABLE_FUNCTION(, MAP_HANDLE, connectionstringparser_parse, STRING_HANDLE, connection_string); + +#ifdef __cplusplus +} +#endif + +#endif /* CONNECTION_STRING_PARSER_H */ diff --git a/src/azure_c_shared_utility/string_tokenizer.c b/src/azure_c_shared_utility/string_tokenizer.c index c0dab80..1e0e5f1 100644 --- a/src/azure_c_shared_utility/string_tokenizer.c +++ b/src/azure_c_shared_utility/string_tokenizer.c @@ -13,6 +13,7 @@ // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE // +#include #include #include "azure_c_shared_utility/string_tokenizer.h" #include "azure_c_shared_utility/xlogging.h" diff --git a/src/azure_c_shared_utility/xlogging.h b/src/azure_c_shared_utility/xlogging.h index 48ee1a3..1ca810a 100644 --- a/src/azure_c_shared_utility/xlogging.h +++ b/src/azure_c_shared_utility/xlogging.h @@ -41,9 +41,9 @@ typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const cha #define UNUSED(x) (void)(x) #elif defined(ARDUINO_ARCH_ESP8266) /* -The ESP8266 compiler don’t do a good job compiling this code, it do not understand that the ‘format’ is -a ‘cont char*’ and moves it to the RAM as a global variable, increasing a lot the .bss. So, we create a -specific LogInfo that explicitly pin the ‘format’ on the PROGMEM (flash) using a _localFORMAT variable +The ESP8266 compiler doesn't do a good job compiling this code; it doesn't understand that the 'format' is +a 'const char*' and moves it to RAM as a global variable, increasing the .bss size. So we create a +specific LogInfo that explicitly pins the 'format' on the PROGMEM (flash) using a _localFORMAT variable with the macro PSTR. #define ICACHE_FLASH_ATTR __attribute__((section(".irom0.text"))) @@ -51,7 +51,7 @@ with the macro PSTR. #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) const char* __localFORMAT = PSTR(FORMAT); -On the other hand, vsprintf do not support the pinned ‘format’ and os_printf do not works with va_list, +On the other hand, vsprintf does not support the pinned 'format' and os_printf does not work with va_list, so we compacted the log in the macro LogInfo. */ #include "esp8266/azcpgmspace.h" @@ -141,11 +141,11 @@ extern "C" { /** * @brief Print the memory content byte pre byte in hexadecimal and as a char it the byte correspond to any printable ASCII chars. * - * This function prints the ‘size’ bytes in the ‘buf’ to the log. It will print in portions of 16 bytes, + * This function prints the 'size' bytes in the 'buf' to the log. It will print in portions of 16 bytes, * and will print the byte as a hexadecimal value, and, it is a printable, this function will print * the correspondent ASCII character. - * Non printable characters will shows as a single ‘.’. - * For this function, printable characters are all characters between ‘ ‘ (0x20) and ‘~’ (0x7E). + * Non printable characters will shows as a single '.'. + * For this function, printable characters are all characters between ' ' (0x20) and '~' (0x7E). * * @param buf Pointer to the memory address with the buffer to print. * @param size Number of bytes to print.