Sync Arduino libraries with latest Azure IoT SDK 1.0.45

This commit is contained in:
aziotclb 2018-06-14 10:40:09 -07:00
Родитель 5065b8be07
Коммит d398b7ee1c
20 изменённых файлов: 577 добавлений и 251 удалений

Просмотреть файл

@ -1,5 +1,5 @@
name=AzureIoTUtility
version=1.0.44
version=1.0.45
author=Microsoft
maintainer=Microsoft <iotcert@microsoft.com>
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.

Просмотреть файл

@ -7,6 +7,6 @@
#include "azure_c_shared_utility/lock.h"
#include "azure_c_shared_utility/threadapi.h"
#define AzureIoTUtilityVersion "1.0.43"
#define AzureIoTUtilityVersion "1.0.45"
#endif //AZUREIOTUTILITY_H

Просмотреть файл

@ -19,6 +19,10 @@ EXPORTS
Base64_Decoder
Base64_Encoder
Base64_Encode_Bytes
Base32_Decode
Base32_Decode_String
Base32_Encode
Base32_Encode_Bytes
COND_RESULTStringStorage
COND_RESULTStrings
COND_RESULT_FromString
@ -165,6 +169,8 @@ EXPORTS
UNIQUEID_RESULT_FromString
URL_Encode
URL_EncodeString
URL_Decode
URL_DecodeString
USHABlockSize
USHAFinalBits
USHAHashSize
@ -203,6 +209,8 @@ EXPORTS
gballoc_init
gballoc_malloc
gballoc_realloc
gbnetwork_init
gbnetwork_deinit
get_ctime
get_difftime
get_gmtime

Просмотреть файл

@ -12,7 +12,6 @@
#include "azure_c_shared_utility/base32.h"
static const unsigned char BASE32_MAX_VALUE = 31;
static const unsigned char BASE32_EQUAL_SIGN = 32;
static const char BASE32_VALUES[] = "abcdefghijklmnopqrstuvwxyz234567=";
@ -33,25 +32,6 @@ static size_t base32_decoding_length(size_t src_len)
return ((src_len*TARGET_BLOCK_SIZE) / 8);
}
static size_t get_char_position(char pos_char)
{
size_t result;
// Validate characters
if (pos_char >= '2' && pos_char <= '7')
{
result = 25+(pos_char - '2');
}
else if (pos_char >= 'a' && pos_char <= 'z')
{
result = (pos_char - 'a');
}
else
{
result = INVALID_CHAR_POS;
}
return result;
}
static unsigned char convert_value_to_base32_char(unsigned char value)
{
unsigned char result;

Просмотреть файл

@ -0,0 +1,18 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#ifndef CONST_DEFINES_H
#define CONST_DEFINES_H
// Used to remove GCC warning unused
#ifdef __GNUC__
#define STATIC_VAR_UNUSED __attribute__ ((unused))
#else
#define STATIC_VAR_UNUSED
#endif
#ifndef AZURE_UNREFERENCED_PARAMETER
#define AZURE_UNREFERENCED_PARAMETER(param) (void)(param)
#endif
#endif // CONST_DEFINES

Просмотреть файл

@ -50,8 +50,8 @@ typedef bool _Bool;
#else // __cplusplus
typedef unsigned char bool;
#define false 0
#define true 1
#define false 0
#define true 1
#endif // __cplusplus
#endif // _WIN32_WCE
@ -83,7 +83,6 @@ typedef unsigned char bool;
/* Codes_SRS_CRT_ABSTRACTIONS_99_002: [CRTAbstractions module shall expose the following API]*/
#ifdef _MSC_VER
#else // _MSC_VER
#include "inttypes.h"
/* Adding definitions from errno.h & crtdefs.h */
#if !defined (_TRUNCATE)
@ -144,25 +143,6 @@ extern "C++" {
#endif // __STDC_VERSION__
#endif // _MSC_VER
#ifdef _MSC_VER
#define INT64_PRINTF "%I64d"
#else
#if defined __STDC_VERSION__
#if ((__STDC_VERSION__ == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
/*C99 compiler or C11*/
#define INT64_PRINTF "%" PRId64 ""
#else // ((__STDC_VERSION__ == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
#error update this file to contain the latest C standard.
#endif // ((__STDC_VERSION__ == 199901L) || (__STDC_VERSION__ == 201000L) || (__STDC_VERSION__ == 201112L))
#else // __STDC_VERSION__
#ifdef __cplusplus
#define INT64_PRINTF "%" PRId64 ""
#else // __cplusplus
#error unknown (or C89) compiler, provide INT64_PRINTF with the same meaning as PRIdN in C99 standard
#endif // __cplusplus
#endif // __STDC_VERSION__
#endif // _MSC_VER
#ifdef __cplusplus
}
#endif // __cplusplus

Просмотреть файл

@ -93,37 +93,37 @@ void* gballoc_malloc(size_t size)
}
else
{
ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
if (allocation == NULL)
{
result = NULL;
}
else
{
/* Codes_SRS_GBALLOC_01_003: [gb_malloc shall call the C99 malloc function and return its result.] */
result = malloc(size);
if (result == NULL)
ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
if (allocation == NULL)
{
/* Codes_SRS_GBALLOC_01_012: [When the underlying malloc call fails, gballoc_malloc shall return NULL and size should not be counted towards total memory used.] */
free(allocation);
result = NULL;
}
else
{
/* Codes_SRS_GBALLOC_01_004: [If the underlying malloc call is successful, gb_malloc shall increment the total memory used with the amount indicated by size.] */
allocation->ptr = result;
allocation->size = size;
allocation->next = head;
head = allocation;
g_allocations++;
totalSize += size;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
/* Codes_SRS_GBALLOC_01_003: [gb_malloc shall call the C99 malloc function and return its result.] */
result = malloc(size);
if (result == NULL)
{
maxSize = totalSize;
/* Codes_SRS_GBALLOC_01_012: [When the underlying malloc call fails, gballoc_malloc shall return NULL and size should not be counted towards total memory used.] */
free(allocation);
}
else
{
/* Codes_SRS_GBALLOC_01_004: [If the underlying malloc call is successful, gb_malloc shall increment the total memory used with the amount indicated by size.] */
allocation->ptr = result;
allocation->size = size;
allocation->next = head;
head = allocation;
g_allocations++;
totalSize += size;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
{
maxSize = totalSize;
}
}
}
}
(void)Unlock(gballocThreadSafeLock);
}
@ -149,36 +149,36 @@ void* gballoc_calloc(size_t nmemb, size_t size)
}
else
{
ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
if (allocation == NULL)
{
result = NULL;
}
else
{
/* Codes_SRS_GBALLOC_01_020: [gballoc_calloc shall call the C99 calloc function and return its result.] */
result = calloc(nmemb, size);
if (result == NULL)
ALLOCATION* allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
if (allocation == NULL)
{
/* Codes_SRS_GBALLOC_01_022: [When the underlying calloc call fails, gballoc_calloc shall return NULL and size should not be counted towards total memory used.] */
free(allocation);
result = NULL;
}
else
{
/* Codes_SRS_GBALLOC_01_021: [If the underlying calloc call is successful, gballoc_calloc shall increment the total memory used with nmemb*size.] */
allocation->ptr = result;
allocation->size = nmemb * size;
allocation->next = head;
head = allocation;
g_allocations++;
totalSize += allocation->size;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
/* Codes_SRS_GBALLOC_01_020: [gballoc_calloc shall call the C99 calloc function and return its result.] */
result = calloc(nmemb, size);
if (result == NULL)
{
maxSize = totalSize;
/* Codes_SRS_GBALLOC_01_022: [When the underlying calloc call fails, gballoc_calloc shall return NULL and size should not be counted towards total memory used.] */
free(allocation);
}
else
{
/* Codes_SRS_GBALLOC_01_021: [If the underlying calloc call is successful, gballoc_calloc shall increment the total memory used with nmemb*size.] */
allocation->ptr = result;
allocation->size = nmemb * size;
allocation->next = head;
head = allocation;
g_allocations++;
totalSize += allocation->size;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
{
maxSize = totalSize;
}
}
}
}
(void)Unlock(gballocThreadSafeLock);
@ -207,74 +207,74 @@ void* gballoc_realloc(void* ptr, size_t size)
}
else
{
if (ptr == NULL)
{
/* Codes_SRS_GBALLOC_01_017: [When ptr is NULL, gballoc_realloc shall call the underlying realloc with ptr being NULL and the realloc result shall be tracked by gballoc.] */
allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
}
else
{
curr = head;
while (curr != NULL)
if (ptr == NULL)
{
if (curr->ptr == ptr)
{
allocation = curr;
break;
}
else
{
curr = (ALLOCATION*)curr->next;
}
}
}
if (allocation == NULL)
{
/* Codes_SRS_GBALLOC_01_015: [When allocating memory used for tracking by gballoc_realloc fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
/* Codes_SRS_GBALLOC_01_016: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_realloc shall return NULL and the underlying realloc shall not be called.] */
result = NULL;
}
else
{
result = realloc(ptr, size);
if (result == NULL)
{
/* Codes_SRS_GBALLOC_01_014: [When the underlying realloc call fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
if (ptr == NULL)
{
free(allocation);
}
/* Codes_SRS_GBALLOC_01_017: [When ptr is NULL, gballoc_realloc shall call the underlying realloc with ptr being NULL and the realloc result shall be tracked by gballoc.] */
allocation = (ALLOCATION*)malloc(sizeof(ALLOCATION));
}
else
{
if (ptr != NULL)
curr = head;
while (curr != NULL)
{
/* Codes_SRS_GBALLOC_01_006: [If the underlying realloc call is successful, gballoc_realloc shall look up the size associated with the pointer ptr and decrease the total memory used with that size.] */
allocation->ptr = result;
totalSize -= allocation->size;
allocation->size = size;
if (curr->ptr == ptr)
{
allocation = curr;
break;
}
else
{
curr = (ALLOCATION*)curr->next;
}
}
}
if (allocation == NULL)
{
/* Codes_SRS_GBALLOC_01_015: [When allocating memory used for tracking by gballoc_realloc fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
/* Codes_SRS_GBALLOC_01_016: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_realloc shall return NULL and the underlying realloc shall not be called.] */
result = NULL;
}
else
{
result = realloc(ptr, size);
if (result == NULL)
{
/* Codes_SRS_GBALLOC_01_014: [When the underlying realloc call fails, gballoc_realloc shall return NULL and no change should be made to the counted total memory usage.] */
if (ptr == NULL)
{
free(allocation);
}
}
else
{
/* add block */
allocation->ptr = result;
allocation->size = size;
allocation->next = head;
head = allocation;
}
if (ptr != NULL)
{
/* Codes_SRS_GBALLOC_01_006: [If the underlying realloc call is successful, gballoc_realloc shall look up the size associated with the pointer ptr and decrease the total memory used with that size.] */
allocation->ptr = result;
totalSize -= allocation->size;
allocation->size = size;
}
else
{
/* add block */
allocation->ptr = result;
allocation->size = size;
allocation->next = head;
head = allocation;
}
/* Codes_SRS_GBALLOC_01_007: [If realloc is successful, gballoc_realloc shall also increment the total memory used value tracked by this module.] */
totalSize += size;
g_allocations++;
/* Codes_SRS_GBALLOC_01_007: [If realloc is successful, gballoc_realloc shall also increment the total memory used value tracked by this module.] */
totalSize += size;
g_allocations++;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
{
maxSize = totalSize;
/* Codes_SRS_GBALLOC_01_011: [The maximum total memory used shall be the maximum of the total memory used at any point.] */
if (maxSize < totalSize)
{
maxSize = totalSize;
}
}
}
}
(void)Unlock(gballocThreadSafeLock);
}
@ -300,38 +300,38 @@ void gballoc_free(void* ptr)
}
else
{
/* Codes_SRS_GBALLOC_01_009: [gballoc_free shall also look up the size associated with the ptr pointer and decrease the total memory used with the associated size amount.] */
while (curr != NULL)
{
if (curr->ptr == ptr)
/* Codes_SRS_GBALLOC_01_009: [gballoc_free shall also look up the size associated with the ptr pointer and decrease the total memory used with the associated size amount.] */
while (curr != NULL)
{
/* Codes_SRS_GBALLOC_01_008: [gballoc_free shall call the C99 free function.] */
free(ptr);
totalSize -= curr->size;
if (prev != NULL)
if (curr->ptr == ptr)
{
prev->next = curr->next;
}
else
{
head = (ALLOCATION*)curr->next;
/* Codes_SRS_GBALLOC_01_008: [gballoc_free shall call the C99 free function.] */
free(ptr);
totalSize -= curr->size;
if (prev != NULL)
{
prev->next = curr->next;
}
else
{
head = (ALLOCATION*)curr->next;
}
free(curr);
break;
}
free(curr);
break;
prev = curr;
curr = (ALLOCATION*)curr->next;
}
prev = curr;
curr = (ALLOCATION*)curr->next;
}
if ((curr == NULL) && (ptr != NULL))
{
/* Codes_SRS_GBALLOC_01_019: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_free shall not free any memory.] */
{
/* Codes_SRS_GBALLOC_01_019: [When the ptr pointer cannot be found in the pointers tracked by gballoc, gballoc_free shall not free any memory.] */
/* could not find the allocation */
LogError("Could not free allocation for address %p (not found)", ptr);
}
/* could not find the allocation */
LogError("Could not free allocation for address %p (not found)", ptr);
}
(void)Unlock(gballocThreadSafeLock);
}
}

Просмотреть файл

@ -234,6 +234,14 @@ static void indicate_open_complete_error_and_close(HTTP_PROXY_IO_INSTANCE* http_
http_proxy_io_instance->on_io_open_complete(http_proxy_io_instance->on_io_open_complete_context, IO_OPEN_ERROR);
}
// This callback usage needs to be either verified and commented or integrated into
// the state machine.
static void unchecked_on_send_complete(void* context, IO_SEND_RESULT send_result)
{
(void)context;
(void)send_result;
}
static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
{
if (context == NULL)
@ -409,7 +417,7 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
else
{
/* Codes_SRS_HTTP_PROXY_IO_01_063: [ The request shall be sent by calling `xio_send` and passing NULL as `on_send_complete` callback. ]*/
if (xio_send(http_proxy_io_instance->underlying_io, connect_request, connect_request_length, NULL, NULL) != 0)
if (xio_send(http_proxy_io_instance->underlying_io, connect_request, connect_request_length, unchecked_on_send_complete, NULL) != 0)
{
/* Codes_SRS_HTTP_PROXY_IO_01_064: [ If `xio_send` fails, the `on_open_complete` callback shall be triggered with `IO_OPEN_ERROR`, passing also the `on_open_complete_context` argument as `context`. ]*/
LogError("Could not send CONNECT request");

Просмотреть файл

@ -68,6 +68,8 @@ DEFINE_ENUM(HTTPAPI_RESULT, HTTPAPI_RESULT_VALUES);
DEFINE_ENUM(HTTPAPI_REQUEST_TYPE, HTTPAPI_REQUEST_TYPE_VALUES);
#define MAX_HOSTNAME_LEN 65
#define MAX_USERNAME_LEN 65
#define MAX_PASSWORD_LEN 65
/**
* @brief Global initialization for the HTTP API component.

Просмотреть файл

@ -13,14 +13,69 @@
#include "azure_c_shared_utility/httpapiex.h"
#include "azure_c_shared_utility/httpapiexsas.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/crt_abstractions.h"
typedef struct HTTPAPIEX_SAS_STATE_TAG
{
STRING_HANDLE key;
STRING_HANDLE uriResource;
STRING_HANDLE keyName;
}HTTPAPIEX_SAS_STATE;
char* key;
char* uriResource;
char* keyName;
} HTTPAPIEX_SAS_STATE;
static HTTPAPIEX_SAS_STATE* construct_httpex_sas(const char* key, const char* uriResource, const char* keyName)
{
HTTPAPIEX_SAS_STATE* result;
result = (HTTPAPIEX_SAS_STATE*)malloc(sizeof(HTTPAPIEX_SAS_STATE));
if (result == NULL)
{
LogError("Failure allocating HTTPAPIEX_SAS_Create.");
}
else
{
(void)memset(result, 0, sizeof(HTTPAPIEX_SAS_STATE));
if (mallocAndStrcpy_s(&result->key, key) != 0)
{
/*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
LogError("Failure allocating sas key.");
HTTPAPIEX_SAS_Destroy(result);
result = NULL;
}
else if (mallocAndStrcpy_s(&result->uriResource, uriResource) != 0)
{
/*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
LogError("Failure allocating sas uriResource.");
HTTPAPIEX_SAS_Destroy(result);
result = NULL;
}
else if (keyName != NULL && mallocAndStrcpy_s(&result->keyName, keyName) != 0)
{
/*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
LogError("Failure allocating sas keyName.");
HTTPAPIEX_SAS_Destroy(result);
result = NULL;
}
}
return result;
}
HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create_From_String(const char* key, const char* uriResource, const char* keyName)
{
HTTPAPIEX_SAS_HANDLE result = NULL;
if (key == NULL || uriResource == NULL)
{
/* Codes_SRS_HTTPAPIEXSAS_07_001: [ If the parameter key or uriResource is NULL then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */
LogError("Invalid parameter key: %p, uriResource: %p", key, uriResource);
result = NULL;
}
else
{
/* Codes_SRS_HTTPAPIEXSAS_07_002: [ If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create_From_String shall return NULL. ] */
result = construct_httpex_sas(key, uriResource, keyName);
}
/* Codes_SRS_HTTPAPIEXSAS_07_003: [ HTTPAPIEX_SAS_Create_From_String shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it ] */
return result;
}
HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create(STRING_HANDLE key, STRING_HANDLE uriResource, STRING_HANDLE keyName)
{
@ -37,27 +92,9 @@ HTTPAPIEX_SAS_HANDLE HTTPAPIEX_SAS_Create(STRING_HANDLE key, STRING_HANDLE uriRe
}
else
{
/*Codes_SRS_HTTPAPIEXSAS_01_001: [ HTTPAPIEX_SAS_Create shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it. ]*/
HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)malloc(sizeof(HTTPAPIEX_SAS_STATE));
/*Codes_SRS_HTTPAPIEXSAS_06_003: [The parameter keyName for HTTPAPIEX_SAS_Create is optional and can be NULL.]*/
if (state != NULL)
{
state->key = NULL;
state->uriResource = NULL;
state->keyName = NULL;
if (((state->key = STRING_clone(key)) == NULL) ||
((state->uriResource = STRING_clone(uriResource)) == NULL) ||
((keyName != NULL) && ((state->keyName = STRING_clone(keyName)) == NULL)))
{
/*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
LogError("Unable to clone the arguments.");
HTTPAPIEX_SAS_Destroy(state);
}
else
{
result = state;
}
}
/*Codes_SRS_HTTPAPIEXSAS_01_001: [ HTTPAPIEX_SAS_Create shall create a new instance of HTTPAPIEX_SAS and return a non-NULL handle to it. ]*/
result = construct_httpex_sas(STRING_c_str(key), STRING_c_str(uriResource), STRING_c_str(keyName) );
}
return result;
}
@ -71,15 +108,15 @@ void HTTPAPIEX_SAS_Destroy(HTTPAPIEX_SAS_HANDLE handle)
/*Codes_SRS_HTTPAPIEXSAS_06_006: [HTTAPIEX_SAS_Destroy shall deallocate any structures denoted by the parameter handle.]*/
if (state->key)
{
STRING_delete(state->key);
free(state->key);
}
if (state->uriResource)
{
STRING_delete(state->uriResource);
free(state->uriResource);
}
if (state->keyName)
{
STRING_delete(state->keyName);
free(state->keyName);
}
free(state);
}
@ -110,7 +147,7 @@ HTTPAPIEX_RESULT HTTPAPIEX_SAS_ExecuteRequest(HTTPAPIEX_SAS_HANDLE sasHandle, HT
/*Codes_SRS_HTTPAPIEXSAS_06_011: [SASToken_Create shall be invoked.]*/
/*Codes_SRS_HTTPAPIEXSAS_06_012: [If the return result of SASToken_Create is NULL then fallthrough.]*/
size_t expiry = (size_t)(difftime(currentTime, 0) + 3600);
STRING_HANDLE newSASToken = SASToken_Create(state->key, state->uriResource, state->keyName, expiry);
STRING_HANDLE newSASToken = SASToken_CreateString(state->key, state->uriResource, state->keyName, expiry);
if (newSASToken != NULL)
{
/*Codes_SRS_HTTPAPIEXSAS_06_013: [HTTPHeaders_ReplaceHeaderNameValuePair shall be invoked with "Authorization" as its second argument and STRING_c_str (newSASToken) as its third argument.]*/

Просмотреть файл

@ -19,6 +19,8 @@ typedef struct HTTPAPIEX_SAS_STATE_TAG* HTTPAPIEX_SAS_HANDLE;
MOCKABLE_FUNCTION(, HTTPAPIEX_SAS_HANDLE, HTTPAPIEX_SAS_Create, STRING_HANDLE, key, STRING_HANDLE, uriResource, STRING_HANDLE, keyName);
MOCKABLE_FUNCTION(, HTTPAPIEX_SAS_HANDLE, HTTPAPIEX_SAS_Create_From_String, const char*, key, const char*, uriResource, const char*, keyName);
MOCKABLE_FUNCTION(, void, HTTPAPIEX_SAS_Destroy, HTTPAPIEX_SAS_HANDLE, handle);
MOCKABLE_FUNCTION(, HTTPAPIEX_RESULT, HTTPAPIEX_SAS_ExecuteRequest, HTTPAPIEX_SAS_HANDLE, sasHandle, HTTPAPIEX_HANDLE, handle, HTTPAPI_REQUEST_TYPE, requestType, const char*, relativePath, HTTP_HEADERS_HANDLE, requestHttpHeadersHandle, BUFFER_HANDLE, requestContent, unsigned int*, statusCode, HTTP_HEADERS_HANDLE, responseHeadersHandle, BUFFER_HANDLE, responseContent);

Просмотреть файл

@ -4,7 +4,11 @@
/*THIS FILE IS GENERATED*/
/*DO NOT EDIT BY HAND!!!*/
/*instead edit macro_utils.tt here: http://www.github.com/azure/azure-macro-utils-c.git */
/*and then copy the generated file overwriting this one*/
/*and then propagate the generated file to all the repos*/
/* !!! CAUTION!!! This file is copied to multiple places */
/* in https://github.com/Azure/azure-c-shared-utility.git, */
/* and all of these copies must be located and replaced. */
#ifndef MACRO_UTILS_H
@ -12577,7 +12581,7 @@ IF(X, "true", "false") => "true"
#define DEFINE_ENUM_STRINGS(enumName, ...) const char* C2(enumName, StringStorage)[COUNT_ARG(__VA_ARGS__)] = {FOR_EACH_1(DEFINE_ENUMERATION_CONSTANT_AS_STRING, __VA_ARGS__)}; \
const char* C2(enumName,Strings)(enumName value) \
{ \
if((int)value<0 || (int)value>=COUNT_ARG(__VA_ARGS__)) \
if((int)value<0 || (int)value>=COUNT_ARG(__VA_ARGS__)) \
{ \
/*this is an error case*/ \
return NULL; \
@ -12612,9 +12616,9 @@ int C2(enumName, _FromString)(const char* enumAsString, enumName* destination)
#define DEFINE_LOCAL_ENUM(enumName, ...) typedef enum C2(enumName, _TAG) { FOR_EACH_1(DEFINE_ENUMERATION_CONSTANT, __VA_ARGS__)} enumName; \
static const char* C2(enumName, StringStorage)[COUNT_ARG(__VA_ARGS__)] = {FOR_EACH_1(DEFINE_ENUMERATION_CONSTANT_AS_STRING, __VA_ARGS__)}; \
static const char* C2(enumName,Strings)(enumName value) \
static const char* C2(enumName,Strings)(enumName value) \
{ \
if((int)value<0 || (int)value>=COUNT_ARG(__VA_ARGS__)) \
if((int)value<0 || (int)value>=COUNT_ARG(__VA_ARGS__)) \
{ \
/*this is an error case*/ \
return NULL; \
@ -12625,12 +12629,13 @@ static const char* C2(enumName,Strings)(enumName value) \
} \
}
#define ENUM_TO_STRING(enumName, enumValue) C2(enumName, Strings)(enumValue)
#define STRING_TO_ENUM(stringValue, enumName, addressOfEnumVariable) C2(enumName, _FromString)(stringValue, addressOfEnumVariable)
#define DEFINE_MICROMOCK_ENUM_TO_STRING(type, ...) MICROMOCK_ENUM_TO_STRING(type, FOR_EACH_1(DEFINE_ENUMERATION_CONSTANT_AS_WIDESTRING, __VA_ARGS__));
#define EMPTY()
#define DELAY(id) id EMPTY LPAREN )
#define MACRO_UTILS_DELAY(id) id EMPTY LPAREN )
#endif /*MACRO_UTILS_H*/

Просмотреть файл

@ -4,6 +4,8 @@
#ifndef SHARED_UTIL_OPTIONS_H
#define SHARED_UTIL_OPTIONS_H
#include "azure_c_shared_utility/const_defines.h"
#ifdef __cplusplus
extern "C"
{
@ -17,24 +19,27 @@ extern "C"
const char* password;
} HTTP_PROXY_OPTIONS;
static const char* OPTION_HTTP_PROXY = "proxy_data";
static const char* OPTION_HTTP_TIMEOUT = "timeout";
static STATIC_VAR_UNUSED const char* const OPTION_HTTP_PROXY = "proxy_data";
static STATIC_VAR_UNUSED const char* const OPTION_HTTP_TIMEOUT = "timeout";
static const char* OPTION_TRUSTED_CERT = "TrustedCerts";
static STATIC_VAR_UNUSED const char* const OPTION_TRUSTED_CERT = "TrustedCerts";
static const char* SU_OPTION_X509_CERT = "x509certificate";
static const char* SU_OPTION_X509_PRIVATE_KEY = "x509privatekey";
static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_CERT = "x509certificate";
static STATIC_VAR_UNUSED const char* const SU_OPTION_X509_PRIVATE_KEY = "x509privatekey";
static const char* OPTION_X509_ECC_CERT = "x509EccCertificate";
static const char* OPTION_X509_ECC_KEY = "x509EccAliasKey";
static STATIC_VAR_UNUSED const char* const OPTION_X509_ECC_CERT = "x509EccCertificate";
static STATIC_VAR_UNUSED const char* const OPTION_X509_ECC_KEY = "x509EccAliasKey";
static const char* OPTION_CURL_LOW_SPEED_LIMIT = "CURLOPT_LOW_SPEED_LIMIT";
static const char* OPTION_CURL_LOW_SPEED_TIME = "CURLOPT_LOW_SPEED_TIME";
static const char* OPTION_CURL_FRESH_CONNECT = "CURLOPT_FRESH_CONNECT";
static const char* OPTION_CURL_FORBID_REUSE = "CURLOPT_FORBID_REUSE";
static const char* OPTION_CURL_VERBOSE = "CURLOPT_VERBOSE";
static STATIC_VAR_UNUSED const char* const OPTION_CURL_LOW_SPEED_LIMIT = "CURLOPT_LOW_SPEED_LIMIT";
static STATIC_VAR_UNUSED const char* const OPTION_CURL_LOW_SPEED_TIME = "CURLOPT_LOW_SPEED_TIME";
static STATIC_VAR_UNUSED const char* const OPTION_CURL_FRESH_CONNECT = "CURLOPT_FRESH_CONNECT";
static STATIC_VAR_UNUSED const char* const OPTION_CURL_FORBID_REUSE = "CURLOPT_FORBID_REUSE";
static STATIC_VAR_UNUSED const char* const OPTION_CURL_VERBOSE = "CURLOPT_VERBOSE";
static STATIC_VAR_UNUSED const char* const OPTION_NET_INT_MAC_ADDRESS = "net_interface_mac_address";
static STATIC_VAR_UNUSED const char* const OPTION_TLS_VERSION = "tls_version";
static const char* OPTION_NET_INT_MAC_ADDRESS = "net_interface_mac_address";
#ifdef __cplusplus
}
#endif

Просмотреть файл

@ -41,6 +41,7 @@ STRING_HANDLE STRING_new(void)
else
{
/* Codes_SRS_STRING_07_002: [STRING_new shall return an NULL STRING_HANDLE on any error that is encountered.] */
LogError("Failure allocating in STRING_new.");
free(result);
result = NULL;
}
@ -67,6 +68,7 @@ STRING_HANDLE STRING_clone(STRING_HANDLE handle)
size_t sourceLen = strlen(source->s);
if ((result->s = (char*)malloc(sourceLen + 1)) == NULL)
{
LogError("Failure allocating clone value.");
free(result);
result = NULL;
}
@ -106,6 +108,7 @@ STRING_HANDLE STRING_construct(const char* psz)
/* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
else
{
LogError("Failure allocating constructed value.");
free(str);
result = NULL;
}
@ -113,6 +116,7 @@ STRING_HANDLE STRING_construct(const char* psz)
else
{
/* Codes_SRS_STRING_07_032: [STRING_construct encounters any error it shall return a NULL value.] */
LogError("Failure allocating value.");
result = NULL;
}
}
@ -167,7 +171,7 @@ STRING_HANDLE STRING_construct_sprintf(const char* format, ...)
/* Codes_SRS_STRING_07_040: [If any error is encountered STRING_construct_sprintf shall return NULL.] */
free(result);
result = NULL;
LogError("Failure: allocation failed.");
LogError("Failure: allocation sprintf value failed.");
}
}
else
@ -213,6 +217,10 @@ STRING_HANDLE STRING_new_with_memory(const char* memory)
{
result->s = (char*)memory;
}
else
{
LogError("Failure: allocating memory string");
}
}
return (STRING_HANDLE)result;
}
@ -239,6 +247,7 @@ STRING_HANDLE STRING_new_quoted(const char* source)
else
{
/* Codes_SRS_STRING_07_031: [STRING_new_quoted shall return a NULL STRING_HANDLE if any error is encountered.] */
LogError("Failure allocating quoted string value.");
free(result);
result = NULL;
}
@ -299,7 +308,7 @@ STRING_HANDLE STRING_new_JSON(const char* source)
if ((result = (STRING*)malloc(sizeof(STRING))) == NULL)
{
/*Codes_SRS_STRING_02_021: [If the complete JSON representation cannot be produced, then STRING_new_JSON shall fail and return NULL.] */
LogError("malloc failure");
LogError("malloc json failure");
}
else if ((result->s = (char*)malloc(vlen + 5 * nControlCharacters + nEscapeCharacters + 3)) == NULL)
{
@ -381,6 +390,7 @@ int STRING_concat(STRING_HANDLE handle, const char* s2)
if (temp == NULL)
{
/* Codes_SRS_STRING_07_013: [STRING_concat shall return a nonzero number if an error is encountered.] */
LogError("Failure reallocating value.");
result = __FAILURE__;
}
else
@ -403,6 +413,7 @@ int STRING_concat_with_STRING(STRING_HANDLE s1, STRING_HANDLE s2)
if ((s1 == NULL) || (s2 == NULL))
{
/* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
LogError("Invalid argument specified");
result = __FAILURE__;
}
else
@ -416,6 +427,7 @@ int STRING_concat_with_STRING(STRING_HANDLE s1, STRING_HANDLE s2)
if (temp == NULL)
{
/* Codes_SRS_STRING_07_035: [String_Concat_with_STRING shall return a nonzero number if an error is encountered.] */
LogError("Failure reallocating value");
result = __FAILURE__;
}
else
@ -451,6 +463,7 @@ int STRING_copy(STRING_HANDLE handle, const char* s2)
char* temp = (char*)realloc(s1->s, s2Length + 1);
if (temp == NULL)
{
LogError("Failure reallocating value.");
/* Codes_SRS_STRING_07_027: [STRING_copy shall return a nonzero value if any error is encountered.] */
result = __FAILURE__;
}
@ -495,6 +508,7 @@ int STRING_copy_n(STRING_HANDLE handle, const char* s2, size_t n)
temp = (char*)realloc(s1->s, s2Length + 1);
if (temp == NULL)
{
LogError("Failure reallocating value.");
/* Codes_SRS_STRING_07_028: [STRING_copy_n shall return a nonzero value if any error is encountered.] */
result = __FAILURE__;
}
@ -604,6 +618,7 @@ int STRING_quote(STRING_HANDLE handle)
char* temp = (char*)realloc(s1->s, s1Length + 2 + 1);/*2 because 2 quotes, 1 because '\0'*/
if (temp == NULL)
{
LogError("Failure reallocating value.");
/* Codes_SRS_STRING_07_029: [STRING_quote shall return a nonzero value if any error is encountered.] */
result = __FAILURE__;
}
@ -636,6 +651,7 @@ int STRING_empty(STRING_HANDLE handle)
char* temp = (char*)realloc(s1->s, 1);
if (temp == NULL)
{
LogError("Failure reallocating value.");
/* Codes_SRS_STRING_07_030: [STRING_empty shall return a nonzero value if the STRING_HANDLE is NULL.] */
result = __FAILURE__;
}
@ -725,6 +741,7 @@ STRING_HANDLE STRING_construct_n(const char* psz, size_t n)
/* Codes_SRS_STRING_02_010: [In all other error cases, STRING_construct_n shall return NULL.] */
else
{
LogError("Failure allocating value.");
free(str);
result = NULL;
}

Просмотреть файл

@ -8,8 +8,15 @@
#include "azure_c_shared_utility/urlencode.h"
#include "azure_c_shared_utility/xlogging.h"
#include "azure_c_shared_utility/strings.h"
#include "azure_c_shared_utility/crt_abstractions.h"
#define NIBBLE_STR(c) (char)(c < 10 ? c + '0' : c - 10 + 'a')
#define NIBBLE_TO_STRING(c) (char)((c) < 10 ? (c) + '0' : (c) - 10 + 'a')
#define NIBBLE_FROM_STRING(c) (char)(ISDIGIT(c) ? (c) - '0' : TOUPPER(c) + 10 - 'A')
#define IS_HEXDIGIT(c) ( \
((c >= '0') && (c <= '9')) || \
((c >= 'A') && (c <= 'F')) || \
((c >= 'a') && (c <= 'f')) \
)
#define IS_PRINTABLE(c) ( \
(c == 0) || \
(c == '!') || \
@ -21,6 +28,29 @@
((c >= 'a') && (c <= 'z')) \
)
/*The below macros are to be called on the big nibble of a hex value*/
#define IS_IN_ASCII_RANGE(c) ( \
(c >= '0') && (c <= '7') \
)
#define IS_IN_EXTENDED_ASCII_RANGE(c) ( \
((c >= '8') && (c <= '9')) || \
((c >= 'A') && (c <= 'F')) || \
((c >= 'a') && (c <= 'f')) \
)
#define IS_IN_CONTINUATION_BYTE_RANGE(c) ( \
(c == '8') || (c == '9') || \
(c == 'A') || (c == 'B') || \
(c == 'a') || (c == 'b') \
)
#define IS_IN_LEADING_BYTE_RANGE(c) ( \
((c >= 'C') && (c <= 'F')) || \
((c >= 'c') && (c <= 'f')) \
)
#define IS_IN_UNSUPPORTED_LEADING_BYTE_RANGE(c) ( \
((c >= 'D') && (c <= 'F')) || \
((c >= 'd') && (c <= 'f')) \
)
static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
{
size_t size;
@ -41,8 +71,8 @@ static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
bigNibbleVal -= 0x04;
}
bigNibbleStr = NIBBLE_STR(bigNibbleVal);
littleNibbleStr = NIBBLE_STR(littleNibbleVal);
bigNibbleStr = NIBBLE_TO_STRING(bigNibbleVal);
littleNibbleStr = NIBBLE_TO_STRING(littleNibbleVal);
buffer[0] = '%';
@ -73,6 +103,100 @@ static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
return size;
}
static size_t calculateDecodedStringSize(const char* encodedString, size_t len)
{
size_t decodedSize = 0;
if (encodedString == NULL)
{
LogError("Null encoded string");
}
else if (len == 0)
{
decodedSize = 1; //for null terminator
}
else
{
size_t remaining_len = len;
size_t next_step = 0;
size_t i = 0;
while (i < len)
{
//percent encoded character
if (encodedString[i] == '%')
{
if (remaining_len < 3 || !IS_HEXDIGIT(encodedString[i+1]) || !IS_HEXDIGIT(encodedString[i+2]))
{
LogError("Incomplete or invalid percent encoding");
break;
}
else if (!IS_IN_ASCII_RANGE(encodedString[i+1]))
{
LogError("Out of range of characters accepted by this decoder");
break;
}
else
{
decodedSize++;
next_step = 3;
}
}
else if (!IS_PRINTABLE(encodedString[i]))
{
LogError("Unprintable value in encoded string");
break;
}
//safe character
else
{
decodedSize++;
next_step = 1;
}
i += next_step;
remaining_len -= next_step;
}
if (encodedString[i] != '\0') //i.e. broke out of above loop due to error
{
decodedSize = 0;
}
else
{
decodedSize++; //add space for the null terminator
}
}
return decodedSize;
}
static unsigned char charFromNibbles(char bigNibbleStr, char littleNibbleStr)
{
unsigned char bigNibbleVal = NIBBLE_FROM_STRING(bigNibbleStr);
unsigned char littleNibbleVal = NIBBLE_FROM_STRING(littleNibbleStr);
return bigNibbleVal << 4 | littleNibbleVal;
}
static void createDecodedString(const char* input, size_t input_size, char* output)
{
/* Note that there is no danger of reckless indexing here, as calculateDecodedStringSize()
has already checked lengths of strings to ensure the formatting is always correct*/
size_t i = 0;
while (i <= input_size) //the <= instead of < ensures the '\0' will be copied
{
if (input[i] != '%')
{
*output++ = input[i];
i++;
}
else
{
*output++ = charFromNibbles(input[i+1], input[i+2]);
i += 3;
}
}
}
static size_t URL_PrintableCharSize(unsigned char charVal)
{
size_t size;
@ -166,3 +290,64 @@ STRING_HANDLE URL_Encode(STRING_HANDLE input)
return result;
}
STRING_HANDLE URL_DecodeString(const char* textDecode)
{
STRING_HANDLE result;
if (textDecode == NULL)
{
result = NULL;
}
else
{
STRING_HANDLE tempString = STRING_construct(textDecode);
if (tempString == NULL)
{
result = NULL;
}
else
{
result = URL_Decode(tempString);
STRING_delete(tempString);
}
}
return result;
}
STRING_HANDLE URL_Decode(STRING_HANDLE input)
{
STRING_HANDLE result;
if (input == NULL)
{
LogError("URL_Decode:: NULL input");
result = NULL;
}
else
{
size_t decodedStringSize;
char* decodedString;
const char* inputString = STRING_c_str(input);
size_t inputLen = strlen(inputString);
if ((decodedStringSize = calculateDecodedStringSize(inputString, inputLen)) == 0)
{
LogError("URL_Decode:: Invalid input string");
result = NULL;
}
else if ((decodedString = (char*)malloc(decodedStringSize)) == NULL)
{
LogError("URL_Decode:: MALLOC failure on decode.");
result = NULL;
}
else
{
createDecodedString(inputString, inputLen, decodedString);
result = STRING_new_with_memory(decodedString);
if (result == NULL)
{
LogError("URL_Decode:: MALLOC failure on decode");
free(decodedString);
}
}
}
return result;
}

Просмотреть файл

@ -12,8 +12,30 @@
extern "C" {
#endif
MOCKABLE_FUNCTION(, STRING_HANDLE, URL_EncodeString, const char*, textEncode);
/* @brief URL Encode (aka percent encode) a string.
* Please note that while the URL encoder accepts the full range of 8-bit extended ASCII,
* it has unpredictable behavior beyond the 7-bit ASCII standard. This function does NOT
* guarantee correctness of output for characters outside this range.
*
* @param URL Encode can be done on a const char* or a STRING_HANDLE, use the appropriate
* function depending on input type, they both behave the same way.
*
* @return Returns a STRING_HANDLE with the encoded string, or NULL on failure.
*/
MOCKABLE_FUNCTION(, STRING_HANDLE, URL_Encode, STRING_HANDLE, input);
MOCKABLE_FUNCTION(, STRING_HANDLE, URL_EncodeString, const char*, textEncode);
/* @brief URL Decode (aka percent decode) a string.
* Please note that the URL decoder only supports decoding characters that fall within the
* 7-bit ASCII range. It does NOT support 8-bit extended ASCII, and will fail if you try.
*
* @param URL Decode can be done on a const char* or a STRING_HANDLE, use the appropriate
* function depending on input type, they both behave the same way.
*
* @return Returns a STRING_HANDLE with the decoded string, or NULL on failure.
*/
MOCKABLE_FUNCTION(, STRING_HANDLE, URL_Decode, STRING_HANDLE, input);
MOCKABLE_FUNCTION(, STRING_HANDLE, URL_DecodeString, const char*, textDecode);
#ifdef __cplusplus
}

Просмотреть файл

@ -5,9 +5,9 @@
#define UUID_H
#ifdef __cplusplus
extern "C" {
#include <cstddef>
#include <cstdint>
extern "C" {
#else
#include <stddef.h>
#include <stdint.h>

Просмотреть файл

@ -202,6 +202,8 @@ UWS_CLIENT_HANDLE uws_client_create(const char* hostname, unsigned int port, con
socketio_config.port = port;
socketio_config.accepted_socket = NULL;
tlsio_config.hostname = hostname;
tlsio_config.port = port;
tlsio_config.underlying_io_interface = socketio_get_interface_description();
tlsio_config.underlying_io_parameters = &socketio_config;
@ -593,6 +595,14 @@ static void indicate_ws_close_complete(UWS_CLIENT_INSTANCE* uws_client)
}
}
// This callback usage needs to be either verified and commented or integrated into
// the state machine.
static void unchecked_on_send_complete(void* context, IO_SEND_RESULT send_result)
{
(void)context;
(void)send_result;
}
static int send_close_frame(UWS_CLIENT_INSTANCE* uws_client, unsigned int close_error_code)
{
unsigned char* close_frame;
@ -617,7 +627,7 @@ static int send_close_frame(UWS_CLIENT_INSTANCE* uws_client, unsigned int close_
close_frame_length = BUFFER_length(close_frame_buffer);
/* Codes_SRS_UWS_CLIENT_01_471: [ The callback `on_underlying_io_close_sent` shall be passed as argument to `xio_send`. ]*/
if (xio_send(uws_client->underlying_io, close_frame, close_frame_length, NULL, NULL) != 0)
if (xio_send(uws_client->underlying_io, close_frame, close_frame_length, unchecked_on_send_complete, NULL) != 0)
{
LogError("Sending CLOSE frame failed.");
result = __FAILURE__;
@ -751,7 +761,7 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
/* No need to have any send complete here, as we are monitoring the received bytes */
/* Codes_SRS_UWS_CLIENT_01_372: [ Once prepared the WebSocket upgrade request shall be sent by calling `xio_send`. ]*/
/* Codes_SRS_UWS_CLIENT_01_080: [ Once a connection to the server has been established (including a connection via a proxy or over a TLS-encrypted tunnel), the client MUST send an opening handshake to the server. ]*/
if (xio_send(uws_client->underlying_io, upgrade_request, upgrade_request_length, NULL, NULL) != 0)
if (xio_send(uws_client->underlying_io, upgrade_request, upgrade_request_length, unchecked_on_send_complete, NULL) != 0)
{
/* Codes_SRS_UWS_CLIENT_01_373: [ If `xio_send` fails then uws shall report that the open failed by calling the `on_ws_open_complete` callback passed to `uws_client_open_async` with `WS_OPEN_ERROR_CANNOT_SEND_UPGRADE_REQUEST`. ]*/
LogError("Cannot send upgrade request");
@ -1109,7 +1119,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
if (uws_client->received_bytes_count >= needed_bytes)
{
/* Codes_SRS_UWS_CLIENT_01_167: [ Multibyte length quantities are expressed in network byte order. ]*/
length = ((uint64_t)(uws_client->received_bytes[2]) << 8) + uws_client->received_bytes[3];
length = ((size_t)(uws_client->received_bytes[2]) << 8) + (size_t)uws_client->received_bytes[3];
if (length < 126)
{
@ -1359,7 +1369,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
/* Codes_SRS_UWS_CLIENT_01_248: [ A Ping frame MAY include "Application data". ]*/
pong_frame = BUFFER_u_char(pong_frame_buffer);
pong_frame_length = BUFFER_length(pong_frame_buffer);
if (xio_send(uws_client->underlying_io, pong_frame, pong_frame_length, NULL, NULL) != 0)
if (xio_send(uws_client->underlying_io, pong_frame, pong_frame_length, unchecked_on_send_complete, NULL) != 0)
{
LogError("Sending CLOSE frame failed.");
}
@ -1785,7 +1795,7 @@ int uws_client_send_frame_async(UWS_CLIENT_HANDLE uws_client, unsigned char fram
free(ws_pending_send);
}
result = __FAILURE__;
result = __FAILURE__;
}
else
{

Просмотреть файл

@ -67,5 +67,72 @@ LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void)
}
#endif
/* Print up to 16 bytes per line. */
#define LINE_SIZE 16
/* Return the printable char for the provided value. */
#define PRINTABLE(c) ((c >= ' ') && (c <= '~')) ? (char)c : '.'
/* Convert the lower nibble of the provided byte to a hexadecimal printable char. */
#define HEX_STR(c) (((c) & 0xF) < 0xA) ? (char)(((c) & 0xF) + '0') : (char)(((c) & 0xF) - 0xA + 'A')
void LogBinary(const char* comment, const void* data, size_t size)
{
char charBuf[LINE_SIZE + 1];
char hexBuf[LINE_SIZE * 3 + 1];
size_t countbuf = 0;
size_t i = 0;
const unsigned char* bufAsChar = (const unsigned char*)data;
const unsigned char* startPos = bufAsChar;
LOG(AZ_LOG_TRACE, LOG_LINE, "%s %u bytes", comment, size);
/* Print the whole buffer. */
for (i = 0; i < size; i++)
{
/* Store the printable value of the char in the charBuf to print. */
charBuf[countbuf] = PRINTABLE(*bufAsChar);
/* Convert the high nibble to a printable hexadecimal value. */
hexBuf[countbuf * 3] = HEX_STR(*bufAsChar >> 4);
/* Convert the low nibble to a printable hexadecimal value. */
hexBuf[countbuf * 3 + 1] = HEX_STR(*bufAsChar);
hexBuf[countbuf * 3 + 2] = ' ';
countbuf++;
bufAsChar++;
/* If the line is full, print it to start another one. */
if (countbuf == LINE_SIZE)
{
charBuf[countbuf] = '\0';
hexBuf[countbuf * 3] = '\0';
LOG(AZ_LOG_TRACE, LOG_LINE, "%p: %s %s", startPos, hexBuf, charBuf);
countbuf = 0;
startPos = bufAsChar;
}
}
/* If the last line does not fit the line size. */
if (countbuf > 0)
{
/* Close the charBuf string. */
charBuf[countbuf] = '\0';
/* Fill the hexBuf with spaces to keep the charBuf alignment. */
while ((countbuf++) < LINE_SIZE - 1)
{
hexBuf[countbuf * 3] = ' ';
hexBuf[countbuf * 3 + 1] = ' ';
hexBuf[countbuf * 3 + 2] = ' ';
}
hexBuf[countbuf * 3] = '\0';
/* Print the last line. */
LOG(AZ_LOG_TRACE, LOG_LINE, "%p: %s %s", startPos, hexBuf, charBuf);
}
}
#endif

Просмотреть файл

@ -1,20 +0,0 @@
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#if defined(ARDUINO_ARCH_ESP8266)
#include <time.h>
extern "C" {
double difftime(time_t _time2, time_t _time1)
{
return (double)_time2 - (double)_time1;
}
size_t strftime(char *s, size_t maxsize, const char* format, const struct tm *timeptr)
{
/*For now esp8266 will not report time.*/
(void)(s, maxsize, format, timeptr);
return 0;
}
}
#endif