Sync the Arduino Library azure-iot-arduino-utility with the latest azure-iot-sdks version
This commit is contained in:
Родитель
faf23264a9
Коммит
261a6436ac
|
@ -4,7 +4,7 @@
|
|||
language: generic
|
||||
env:
|
||||
global:
|
||||
- IDE_VERSION=1.6.8
|
||||
- IDE_VERSION=1.6.12
|
||||
matrix:
|
||||
- BOARD="arduino:samd:arduino_zero_edbg"
|
||||
- BOARD="arduino:samd:mkr1000"
|
||||
|
@ -21,6 +21,7 @@ before_install:
|
|||
- if [[ "$BOARD" =~ "arduino:samd:" ]]; then
|
||||
arduino --install-boards arduino:samd;
|
||||
arduino --install-library WiFi101;
|
||||
arduino --install-library WiFi101;
|
||||
arduino --install-library RTCZero;
|
||||
arduino --install-library NTPClient;
|
||||
fi
|
||||
|
@ -45,6 +46,8 @@ before_install:
|
|||
arduino --verbose-build --verify --board $BOARD $EXAMPLE_SKETCH;
|
||||
}
|
||||
install:
|
||||
- arduino --install-library "AzureIoTUtility"
|
||||
- arduino --install-library "AzureIoTProtocol_HTTP"
|
||||
- ln -s $PWD $HOME/Arduino/libraries/.
|
||||
script:
|
||||
- buildExampleSketch simplesample_http
|
||||
|
|
20
README.md
20
README.md
|
@ -7,7 +7,7 @@ This library is a port of the [Microsoft Azure C Shared Utility](https://github.
|
|||
Currently supported hardware:
|
||||
- Atmel SAMD Based boards
|
||||
- Arduino/Genuino [MKR1000](https://www.arduino.cc/en/Main/ArduinoMKR1000)
|
||||
- Arduino/Genuino [Zero](https://www.arduino.cc/en/Main/ArduinoBoardZero) and [WiFi Shield 101](https://www.arduino.cc/en/Main/ArduinoWiFiShield101)
|
||||
- Arduino/Genuino [Zero](https://www.arduino.cc/en/Main/ArduinoBoardZero) and [WiFi Shield 101](https://www.arduino.cc/en/Main/ArduinoWiFiShield101)
|
||||
- Adafruit [Feather M0](https://www.adafruit.com/products/3010)
|
||||
- ESP8266 based boards with [esp8266/arduino](https://github.com/esp8266/arduino)
|
||||
- SparkFun [Thing](https://www.sparkfun.com/products/13711)
|
||||
|
@ -18,7 +18,7 @@ Currently supported hardware:
|
|||
You should have the following ready before beginning with any board:
|
||||
- [Setup your IoT hub](https://github.com/Azure/azure-iot-sdks/blob/master/doc/setup_iothub.md)
|
||||
- [Provision your device and get its credentials](https://github.com/Azure/azure-iot-sdks/blob/master/doc/manage_iot_hub.md)
|
||||
- [Arduino IDE 1.6.8](https://www.arduino.cc/en/Main/Software)
|
||||
- [Arduino IDE 1.6.12](https://www.arduino.cc/en/Main/Software)
|
||||
- Install the `AzureIoTHub` library via the Arduino IDE Library Manager
|
||||
- Install the `AzureIoTUtility` library via the Arduino IDE Library Manager
|
||||
- Install the `AzureIoTProtocol_HTTP` library via the Arduino IDE Library Manager
|
||||
|
@ -30,7 +30,7 @@ You should have the following ready before beginning with any board:
|
|||
2. Install the `WiFi101` library from the Arduino IDE Library Manager.
|
||||
3. Install the `NTPClient` library from the Arduino IDE Library Manager.
|
||||
4. Install the `RTCZero` library from the Arduino IDE Library Manager.
|
||||
5. Update Wifi SSID/Password in simplesample_http.ino
|
||||
5. Update Wifi SSID/Password in simplesample_http.ino
|
||||
* Ensure you are using a wifi network that does not require additional manual steps after connection, such as opening a web browser.
|
||||
6. Update IoT Hub Connection string in simplesample_http.c
|
||||
|
||||
|
@ -40,12 +40,12 @@ You should have the following ready before beginning with any board:
|
|||
1. Install esp8266 board support into your Arduino IDE.
|
||||
* Start Arduino and open Preferences window.
|
||||
* Enter `http://arduino.esp8266.com/stable/package_esp8266com_index.json` into Additional Board Manager URLs field. You can add multiple URLs, separating them with commas.
|
||||
* Open Boards Manager from Tools > Board menu and install esp8266 platform 2.2.0 or later
|
||||
* Open Boards Manager from Tools > Board menu and install esp8266 platform 2.2.0 or later
|
||||
* Select your ESP8266 board from Tools > Board menu after installation
|
||||
|
||||
|
||||
2. Open the `simplesample_http` example from the Arduino IDE File->Examples->AzureIoTHub menu.
|
||||
3. Update the sketch as directed by comments in the sample to support the ESP8266 board.
|
||||
4. Update Wifi SSID/Password in simplesample_http.ino
|
||||
4. Update Wifi SSID/Password in simplesample_http.ino
|
||||
* Ensure you are using a wifi network that does not require additional manual steps after connection, such as opening a web browser.
|
||||
5. Update IoT Hub Connection string in simplesample_http.c
|
||||
6. Access the [SparkFun Get Started](https://azure.microsoft.com/en-us/documentation/samples/iot-hub-c-thingdev-getstartedkit/) tutorial to learn more about Microsoft Sparkfun Dev Kit.
|
||||
|
@ -56,14 +56,14 @@ You should have the following ready before beginning with any board:
|
|||
1. Install Feather M0 board support into your Arduino IDE.
|
||||
* Start Arduino and open Preferences window.
|
||||
* Enter `https://adafruit.github.io/arduino-board-index/package_adafruit_index.json` into Additional Board Manager URLs field. You can add multiple URLs, separating them with commas.
|
||||
* Open Boards Manager from Tools > Board menu and install Adafruit SAMD Boards 1.0.7 or later.
|
||||
* Select your Adafruit Feather M0 from Tools > Board menu after installation
|
||||
* Open Boards Manager from Tools > Board menu and install `Arduino SAMD Boards` and `Adafruit SAMD Boards` 1.0.7 or later.
|
||||
* Select your `Adafruit Feather M0` from Tools > Board menu after installation
|
||||
2. Install the [Adafruit WINC1500 wifi library](https://learn.adafruit.com/adafruit-feather-m0-wifi-atwinc1500/using-the-wifi-module)
|
||||
3. Install the `RTCZero` library from the Arduino IDE Library Manager.
|
||||
4. Install the `NTPClient` library from the Arduino IDE Library Manager.
|
||||
5. Open the `simplesample_http` example from the Arduino IDE File->Examples->AzureIoTHub menu.
|
||||
6. Update the sketch as directed by comments in the sample to support the ESP8266 board.
|
||||
7. Update Wifi SSID/Password in simplesample_http.ino
|
||||
7. Update Wifi SSID/Password in simplesample_http.ino
|
||||
* Ensure you are using a wifi network that does not require additional manual steps after connection, such as opening a web browser.
|
||||
8. Update IoT Hub Connection string in simplesample_http.c
|
||||
9. Access the [Feather M0 WiFi Get Started](https://azure.microsoft.com/en-us/documentation/samples/iot-hub-c-m0wifi-getstartedkit/) tutorial to learn more about Microsoft Feather M0 WiFi Dev Kit.
|
||||
|
@ -72,5 +72,5 @@ You should have the following ready before beginning with any board:
|
|||
|
||||
See [LICENSE](LICENSE) file.
|
||||
|
||||
[azure-certifiedforiot]: http://azure.com/certifiedforiot
|
||||
[azure-certifiedforiot]: http://azure.com/certifiedforiot
|
||||
[Microsoft-Azure-Certified-Badge]: images/Microsoft-Azure-Certified-150x150.png (Microsoft Azure Certified)
|
||||
|
|
|
@ -48,23 +48,10 @@ Adafruit_WINC1500 WiFi(WINC_CS, WINC_IRQ, WINC_RST);
|
|||
static char ssid[] = "yourNetwork"; // your network SSID (name)
|
||||
static char pass[] = "yourPassword"; // your network password (use for WPA, or use as key for WEP)
|
||||
|
||||
// In the next line we decide each client ssl we'll use.
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
static WiFiClientSecure sslClient; // for ESP8266
|
||||
#elif ARDUINO_SAMD_FEATHER_M0
|
||||
static Adafruit_WINC1500SSLClient sslClient; // for Adafruit WINC1500
|
||||
#else
|
||||
static WiFiSSLClient sslClient;
|
||||
#endif
|
||||
|
||||
static AzureIoTHubClient iotHubClient;
|
||||
|
||||
void setup() {
|
||||
initSerial();
|
||||
initWifi();
|
||||
initTime();
|
||||
|
||||
iotHubClient.begin(sslClient);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
@ -74,7 +61,9 @@ void loop() {
|
|||
void initSerial() {
|
||||
// Start serial and initialize stdout
|
||||
Serial.begin(115200);
|
||||
#ifdef ARDUINO_ARCH_ESP8266
|
||||
Serial.setDebugOutput(true);
|
||||
#endif
|
||||
}
|
||||
|
||||
void initWifi() {
|
||||
|
@ -129,8 +118,6 @@ void initTime() {
|
|||
Serial.print("Fetched NTP epoch time is: ");
|
||||
Serial.println(epochTime);
|
||||
|
||||
iotHubClient.setEpochTime(epochTime);
|
||||
|
||||
#elif ARDUINO_ARCH_ESP8266
|
||||
time_t epochTime;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name=AzureIoTUtility
|
||||
version=1.0.30
|
||||
version=1.0.33
|
||||
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.21"
|
||||
#define AzureIoTUtilityVersion "1.0.33"
|
||||
|
||||
#endif //AZUREIOTUTILITY_H
|
||||
|
|
|
@ -16,7 +16,11 @@ int platform_init(void)
|
|||
/*Codes_SRS_PLATFORM_ARDUINO_21_006: [ The platform_deinit shall free all allocate memory needed to control the platform. ]*/
|
||||
void platform_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
STRING_HANDLE platform_get_platform_info(void)
|
||||
{
|
||||
return STRING_construct("(arduino)");
|
||||
}
|
||||
|
||||
/*Codes_SRS_PLATFORM_ARDUINO_21_002: [ The platform_arduino shall use the tlsio functions defined by the 'xio.h'.*/
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include "ESP8266WiFi.h"
|
||||
#include "WiFiClientSecure.h"
|
||||
static WiFiClientSecure sslClient; // for ESP8266
|
||||
#elif ARDUINO_ARCH_ESP32
|
||||
#include "WiFi.h"
|
||||
#include "WiFiClientSecure.h"
|
||||
static WiFiClientSecure sslClient; // for ESP32
|
||||
#elif ARDUINO_SAMD_FEATHER_M0
|
||||
#include "Adafruit_WINC1500.h"
|
||||
#include "Adafruit_WINC1500Client.h"
|
||||
|
|
|
@ -55,9 +55,9 @@ static const IO_INTERFACE_DESCRIPTION tlsio_handle_interface_description =
|
|||
#define MAX_TLS_CLOSING_RETRY 10
|
||||
#define RECEIVE_BUFFER_SIZE 128
|
||||
|
||||
#define CallErrorCallback() do { if (tlsio_instance->on_io_error != NULL) (void)tlsio_instance->on_io_error(tlsio_instance->on_io_error_context); } while(0)
|
||||
#define CallOpenCallback(status) do { if (tlsio_instance->on_io_open_complete != NULL) (void)tlsio_instance->on_io_open_complete(tlsio_instance->on_io_open_complete_context, status); } while(0)
|
||||
#define CallCloseCallback() do { if (tlsio_instance->on_io_close_complete != NULL) (void)tlsio_instance->on_io_close_complete(tlsio_instance->on_io_close_complete_context); } while(0)
|
||||
#define CallErrorCallback() do { if (tlsio_instance->on_io_error != NULL) (void)tlsio_instance->on_io_error(tlsio_instance->on_io_error_context); } while((void)0,0)
|
||||
#define CallOpenCallback(status) do { if (tlsio_instance->on_io_open_complete != NULL) (void)tlsio_instance->on_io_open_complete(tlsio_instance->on_io_open_complete_context, status); } while((void)0,0)
|
||||
#define CallCloseCallback() do { if (tlsio_instance->on_io_close_complete != NULL) (void)tlsio_instance->on_io_close_complete(tlsio_instance->on_io_close_complete_context); } while((void)0,0)
|
||||
|
||||
|
||||
typedef struct ArduinoTLS_tag
|
||||
|
|
|
@ -15,7 +15,7 @@ EXPORTS
|
|||
BUFFER_u_char
|
||||
BUFFER_unbuild
|
||||
Base64_Decoder
|
||||
Base64_Encode
|
||||
Base64_Encoder
|
||||
Base64_Encode_Bytes
|
||||
COND_RESULTStringStorage
|
||||
COND_RESULTStrings
|
||||
|
|
|
@ -241,12 +241,12 @@ static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t
|
|||
size_t currentPosition = 0;
|
||||
neededSize += (size == 0) ? (0) : ((((size - 1) / 3) + 1) * 4);
|
||||
neededSize += 1; /*+1 because \0 at the end of the string*/
|
||||
/*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Base64_Encode shall return NULL.]*/
|
||||
/*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Base64_Encoder shall return NULL.]*/
|
||||
encoded = (char*)malloc(neededSize);
|
||||
if (encoded == NULL)
|
||||
{
|
||||
result = NULL;
|
||||
LogError("Base64_Encode:: Allocation failed.");
|
||||
LogError("Base64_Encoder:: Allocation failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -302,12 +302,12 @@ static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t
|
|||
|
||||
/*null terminating the string*/
|
||||
encoded[destinationPosition] = '\0';
|
||||
/*Codes_SRS_BASE64_06_007: [Otherwise Base64_Encode shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
|
||||
/*Codes_SRS_BASE64_06_007: [Otherwise Base64_Encoder shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
|
||||
result = STRING_new_with_memory(encoded);
|
||||
if (result == NULL)
|
||||
{
|
||||
free(encoded);
|
||||
LogError("Base64_Encode:: Allocation failed for return value.");
|
||||
LogError("Base64_Encoder:: Allocation failed for return value.");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -333,7 +333,7 @@ STRING_HANDLE Base64_Encode_Bytes(const unsigned char* source, size_t size)
|
|||
return result;
|
||||
}
|
||||
|
||||
STRING_HANDLE Base64_Encode(BUFFER_HANDLE input)
|
||||
STRING_HANDLE Base64_Encoder(BUFFER_HANDLE input)
|
||||
{
|
||||
STRING_HANDLE result;
|
||||
/*the following will happen*/
|
||||
|
@ -343,11 +343,11 @@ STRING_HANDLE Base64_Encode(BUFFER_HANDLE input)
|
|||
/*the encoding will use the optional [=] or [==] at the end of the encoded string, so that other less standard aware libraries can do their work*/
|
||||
/*these are the bits of the 3 normal bytes to be encoded*/
|
||||
|
||||
/*Codes_SRS_BASE64_06_001: [If input is NULL then Base64_Encode shall return NULL.]*/
|
||||
/*Codes_SRS_BASE64_06_001: [If input is NULL then Base64_Encoder shall return NULL.]*/
|
||||
if (input == NULL)
|
||||
{
|
||||
result = NULL;
|
||||
LogError("Base64_Encode:: NULL input");
|
||||
LogError("Base64_Encoder:: NULL input");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -357,7 +357,7 @@ STRING_HANDLE Base64_Encode(BUFFER_HANDLE input)
|
|||
(BUFFER_size(input, &inputSize) != 0))
|
||||
{
|
||||
result = NULL;
|
||||
LogError("Base64_Encode:: BUFFER_routines failure.");
|
||||
LogError("Base64_Encoder:: BUFFER_routines failure.");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -27,17 +27,17 @@ extern "C" {
|
|||
*
|
||||
* @param input The buffer that needs to be base64 encoded.
|
||||
*
|
||||
* Base64_Encode takes as a parameter a pointer to a BUFFER. If @p input is @c NULL then
|
||||
* @c Base64_Encode returns @c NULL. The size of the BUFFER pointed to by @p input may
|
||||
* Base64_Encoder takes as a parameter a pointer to a BUFFER. If @p input is @c NULL then
|
||||
* @c Base64_Encoder returns @c NULL. The size of the BUFFER pointed to by @p input may
|
||||
* be zero. If when allocating memory to produce the encoding a failure occurs, then @c
|
||||
* Base64_Encode returns @c NULL. Otherwise
|
||||
* @c Base64_Encode returns a pointer to a STRING. That string contains the
|
||||
* Base64_Encoder returns @c NULL. Otherwise
|
||||
* @c Base64_Encoder returns a pointer to a STRING. That string contains the
|
||||
* base 64 encoding of the @p input. This encoding of @p input will not contain embedded
|
||||
* line feeds.
|
||||
*
|
||||
* @return A @c STRING_HANDLE containing the base64 encoding of @p input.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, STRING_HANDLE, Base64_Encode, BUFFER_HANDLE, input);
|
||||
MOCKABLE_FUNCTION(, STRING_HANDLE, Base64_Encoder, BUFFER_HANDLE, input);
|
||||
|
||||
/**
|
||||
* @brief Base64 encodes the buffer pointed to by @p source and returns the resulting string.
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/buffer_.h"
|
||||
#include "azure_c_shared_utility/optimize_size.h"
|
||||
|
@ -13,7 +14,7 @@ typedef struct BUFFER_TAG
|
|||
{
|
||||
unsigned char* buffer;
|
||||
size_t size;
|
||||
}BUFFER;
|
||||
} BUFFER;
|
||||
|
||||
/* Codes_SRS_BUFFER_07_001: [BUFFER_new shall allocate a BUFFER_HANDLE that will contain a NULL unsigned char*.] */
|
||||
BUFFER_HANDLE BUFFER_new(void)
|
||||
|
@ -40,6 +41,7 @@ static int BUFFER_safemalloc(BUFFER* handleptr, size_t size)
|
|||
if (handleptr->buffer == NULL)
|
||||
{
|
||||
/*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.]*/
|
||||
LogError("Failure allocating data");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -57,6 +59,7 @@ BUFFER_HANDLE BUFFER_create(const unsigned char* source, size_t size)
|
|||
/*Codes_SRS_BUFFER_02_001: [If source is NULL then BUFFER_create shall return NULL.]*/
|
||||
if (source == NULL)
|
||||
{
|
||||
LogError("invalid parameter source: %p", source);
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -67,6 +70,7 @@ BUFFER_HANDLE BUFFER_create(const unsigned char* source, size_t size)
|
|||
{
|
||||
/*Codes_SRS_BUFFER_02_003: [If allocating memory fails, then BUFFER_create shall return NULL.] */
|
||||
/*fallthrough*/
|
||||
LogError("Failure allocating BUFFER structure");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -140,6 +144,7 @@ int BUFFER_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
|
|||
if (newBuffer == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_010: [BUFFER_build shall return nonzero if any error is encountered.] */
|
||||
LogError("Failure reallocating buffer");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -157,6 +162,59 @@ int BUFFER_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
|
|||
return result;
|
||||
}
|
||||
|
||||
int BUFFER_append_build(BUFFER_HANDLE handle, const unsigned char* source, size_t size)
|
||||
{
|
||||
int result;
|
||||
if (handle == NULL || source == NULL || size == 0)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_029: [ BUFFER_append_build shall return nonzero if handle or source are NULL or if size is 0. ] */
|
||||
LogError("BUFFER_append_build failed invalid parameter handle: %p, source: %p, size: %uz", handle, source, size);
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handle->buffer == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_030: [ if handle->buffer is NULL BUFFER_append_build shall allocate the a buffer of size bytes... ] */
|
||||
if (BUFFER_safemalloc(handle, size) != 0)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
|
||||
LogError("Failure with BUFFER_safemalloc");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_031: [ ... and copy the contents of source to handle->buffer. ] */
|
||||
(void)memcpy(handle->buffer, source, size);
|
||||
/* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_032: [ if handle->buffer is not NULL BUFFER_append_build shall realloc the buffer to be the handle->size + size ] */
|
||||
unsigned char* temp = (unsigned char*)realloc(handle->buffer, handle->size + size);
|
||||
if (temp == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_035: [ If any error is encountered BUFFER_append_build shall return a non-null value. ] */
|
||||
LogError("Failure reallocating temporary buffer");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_033: [ ... and copy the contents of source to the end of the buffer. ] */
|
||||
handle->buffer = temp;
|
||||
// Append the BUFFER
|
||||
(void)memcpy(&handle->buffer[handle->size], source, size);
|
||||
handle->size += size;
|
||||
/* Codes_SRS_BUFFER_07_034: [ On success BUFFER_append_build shall return 0 ] */
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*return 0 if the buffer was pre-build(that is, had its space allocated)*/
|
||||
/*else return different than zero*/
|
||||
/* Codes_SRS_BUFFER_07_005: [BUFFER_pre_build allocates size_t bytes of BUFFER_HANDLE and returns zero on success.] */
|
||||
|
@ -179,6 +237,7 @@ int BUFFER_pre_build(BUFFER_HANDLE handle, size_t size)
|
|||
if (b->buffer != NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_007: [BUFFER_pre_build shall return nonzero if the buffer has been previously allocated and is not NULL.] */
|
||||
LogError("Failure buffer data is NULL");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -186,6 +245,7 @@ int BUFFER_pre_build(BUFFER_HANDLE handle, size_t size)
|
|||
if ((b->buffer = (unsigned char*)malloc(size)) == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_013: [BUFFER_pre_build shall return nonzero if any error is encountered.] */
|
||||
LogError("Failure allocating buffer");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -231,6 +291,7 @@ extern int BUFFER_unbuild(BUFFER_HANDLE handle)
|
|||
BUFFER* b = (BUFFER*)handle;
|
||||
if (b->buffer != NULL)
|
||||
{
|
||||
LogError("Failure buffer data is NULL");
|
||||
free(b->buffer);
|
||||
b->buffer = NULL;
|
||||
b->size = 0;
|
||||
|
@ -252,11 +313,13 @@ int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
|
|||
if (handle == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
|
||||
LogError("Failure: handle is invalid.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else if (enlargeSize == 0)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_017: [BUFFER_enlarge shall return a nonzero result if any parameters are NULL or zero.] */
|
||||
LogError("Failure: enlargeSize size is 0.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -266,6 +329,7 @@ int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
|
|||
if (temp == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_018: [BUFFER_enlarge shall return a nonzero result if any error is encountered.] */
|
||||
LogError("Failure: allocating temp buffer.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -278,6 +342,74 @@ int BUFFER_enlarge(BUFFER_HANDLE handle, size_t enlargeSize)
|
|||
return result;
|
||||
}
|
||||
|
||||
int BUFFER_shrink(BUFFER_HANDLE handle, size_t decreaseSize, bool fromEnd)
|
||||
{
|
||||
int result;
|
||||
if (handle == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_036: [ if handle is NULL, BUFFER_shrink shall return a non-null value ]*/
|
||||
LogError("Failure: handle is invalid.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else if (decreaseSize == 0)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_037: [ If decreaseSize is equal zero, BUFFER_shrink shall return a non-null value ] */
|
||||
LogError("Failure: decrease size is 0.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else if (decreaseSize > handle->size)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_038: [ If decreaseSize is less than the size of the buffer, BUFFER_shrink shall return a non-null value ] */
|
||||
LogError("Failure: decrease size is less than buffer size.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_039: [ BUFFER_shrink shall allocate a temporary buffer of existing buffer size minus decreaseSize. ] */
|
||||
size_t alloc_size = handle->size - decreaseSize;
|
||||
if (alloc_size == 0)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_043: [ If the decreaseSize is equal the buffer size , BUFFER_shrink shall deallocate the buffer and set the size to zero. ] */
|
||||
free(handle->buffer);
|
||||
handle->buffer = NULL;
|
||||
handle->size = 0;
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char* tmp = malloc(alloc_size);
|
||||
if (tmp == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_042: [ If a failure is encountered, BUFFER_shrink shall return a non-null value ] */
|
||||
LogError("Failure: allocating temp buffer.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fromEnd)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_040: [ if the fromEnd variable is true, BUFFER_shrink shall remove the end of the buffer of size decreaseSize. ] */
|
||||
memcpy(tmp, handle->buffer, alloc_size);
|
||||
free(handle->buffer);
|
||||
handle->buffer = tmp;
|
||||
handle->size = alloc_size;
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_041: [ if the fromEnd variable is false, BUFFER_shrink shall remove the beginning of the buffer of size decreaseSize. ] */
|
||||
memcpy(tmp, handle->buffer + decreaseSize, alloc_size);
|
||||
free(handle->buffer);
|
||||
handle->buffer = tmp;
|
||||
handle->size = alloc_size;
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Codes_SRS_BUFFER_07_021: [BUFFER_size shall place the size of the associated buffer in the size variable and return zero on success.] */
|
||||
int BUFFER_size(BUFFER_HANDLE handle, size_t* size)
|
||||
{
|
||||
|
@ -333,6 +465,7 @@ int BUFFER_append(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
|
|||
if (temp == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_07_023: [BUFFER_append shall return a nonzero upon any error that is encountered.] */
|
||||
LogError("Failure: allocating temp buffer.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -387,6 +520,7 @@ int BUFFER_prepend(BUFFER_HANDLE handle1, BUFFER_HANDLE handle2)
|
|||
if (temp == NULL)
|
||||
{
|
||||
/* Codes_SRS_BUFFER_01_005: [ BUFFER_prepend shall return a non-zero upon value any error that is encountered. ]*/
|
||||
LogError("Failure: allocating temp buffer.");
|
||||
result = __FAILURE__;
|
||||
}
|
||||
else
|
||||
|
@ -458,6 +592,7 @@ BUFFER_HANDLE BUFFER_clone(BUFFER_HANDLE handle)
|
|||
{
|
||||
if (BUFFER_safemalloc(b, suppliedBuff->size) != 0)
|
||||
{
|
||||
LogError("Failure: allocating temp buffer.");
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
|
||||
#ifdef __cplusplus
|
||||
#include <cstddef>
|
||||
#include <cstdbool>
|
||||
extern "C"
|
||||
{
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#include "azure_c_shared_utility/umock_c_prod.h"
|
||||
|
@ -21,8 +23,10 @@ MOCKABLE_FUNCTION(, BUFFER_HANDLE, BUFFER_create, const unsigned char*, source,
|
|||
MOCKABLE_FUNCTION(, void, BUFFER_delete, BUFFER_HANDLE, handle);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_pre_build, BUFFER_HANDLE, handle, size_t, size);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_build, BUFFER_HANDLE, handle, const unsigned char*, source, size_t, size);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_append_build, BUFFER_HANDLE, handle, const unsigned char*, source, size_t, size);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_unbuild, BUFFER_HANDLE, handle);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_enlarge, BUFFER_HANDLE, handle, size_t, enlargeSize);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_shrink, BUFFER_HANDLE, handle, size_t, decreaseSize, bool, fromEnd);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_content, BUFFER_HANDLE, handle, const unsigned char**, content);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_size, BUFFER_HANDLE, handle, size_t*, size);
|
||||
MOCKABLE_FUNCTION(, int, BUFFER_append, BUFFER_HANDLE, handle1, BUFFER_HANDLE, handle2);
|
||||
|
|
|
@ -5,13 +5,206 @@
|
|||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
#include "azure_c_shared_utility/consolelogger.h"
|
||||
|
||||
void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, const int line, unsigned int options, const char* format, ...)
|
||||
#if (defined(_MSC_VER)) && (!(defined WINCE))
|
||||
#include "windows.h"
|
||||
|
||||
/*returns a string as if printed by vprintf*/
|
||||
static char* vprintf_alloc(const char* format, va_list va)
|
||||
{
|
||||
char* result;
|
||||
int neededSize = vsnprintf(NULL, 0, format, va);
|
||||
if (neededSize < 0)
|
||||
{
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (char*)malloc(neededSize + 1);
|
||||
if (result == NULL)
|
||||
{
|
||||
/*return as is*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vsnprintf(result, neededSize + 1, format, va) != neededSize)
|
||||
{
|
||||
free(result);
|
||||
result = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*returns a string as if printed by printf*/
|
||||
static char* printf_alloc(const char* format, ...)
|
||||
{
|
||||
char* result;
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
result = vprintf_alloc(format, va);
|
||||
va_end(va);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*returns NULL if it fails*/
|
||||
static char* lastErrorToString(DWORD lastError)
|
||||
{
|
||||
char* result;
|
||||
if (lastError == 0)
|
||||
{
|
||||
result = printf_alloc(""); /*no error should appear*/
|
||||
if (result == NULL)
|
||||
{
|
||||
(void)printf("failure in printf_alloc");
|
||||
}
|
||||
else
|
||||
{
|
||||
/*return as is*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char temp[MESSAGE_BUFFER_SIZE];
|
||||
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, lastError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), temp, MESSAGE_BUFFER_SIZE, NULL) == 0)
|
||||
{
|
||||
result = printf_alloc("GetLastError()=0X%x", lastError);
|
||||
if (result == NULL)
|
||||
{
|
||||
(void)printf("failure in printf_alloc\n");
|
||||
/*return as is*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*return as is*/
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*eliminate the \r or \n from the string*/
|
||||
/*one replace of each is enough*/
|
||||
char* whereAreThey;
|
||||
if ((whereAreThey = strchr(temp, '\r')) != NULL)
|
||||
{
|
||||
*whereAreThey = '\0';
|
||||
}
|
||||
if ((whereAreThey = strchr(temp, '\n')) != NULL)
|
||||
{
|
||||
*whereAreThey = '\0';
|
||||
}
|
||||
|
||||
result = printf_alloc("GetLastError()==0X%x (%s)", lastError, temp);
|
||||
|
||||
if (result == NULL)
|
||||
{
|
||||
(void)printf("failure in printf_alloc\n");
|
||||
/*return as is*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*return as is*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/*this function will use 1x printf (in the happy case) .*/
|
||||
/*more than 1x printf / function call can mean intermingled LogErrors in a multithreaded env*/
|
||||
/*the function will also attempt to produce some human readable strings for GetLastError*/
|
||||
void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...)
|
||||
{
|
||||
DWORD lastError;
|
||||
char* lastErrorAsString;
|
||||
int lastErrorAsString_should_be_freed;
|
||||
time_t t;
|
||||
int systemMessage_should_be_freed;
|
||||
char* systemMessage;
|
||||
int userMessage_should_be_freed;
|
||||
char* userMessage;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
time_t t = time(NULL);
|
||||
/*this is what this case will do:
|
||||
1. snip the last error
|
||||
2. create a string with what that last error means
|
||||
3. printf the system message (__FILE__, __LINE__ etc) + the last error + whatever the user wanted
|
||||
*/
|
||||
/*1. snip the last error*/
|
||||
lastError = GetLastError();
|
||||
|
||||
/*2. create a string with what that last error means*/
|
||||
lastErrorAsString = lastErrorToString(lastError);
|
||||
if (lastErrorAsString == NULL)
|
||||
{
|
||||
(void)printf("failure in lastErrorToString");
|
||||
lastErrorAsString = "";
|
||||
lastErrorAsString_should_be_freed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastErrorAsString_should_be_freed = 1;
|
||||
}
|
||||
|
||||
t = time(NULL);
|
||||
systemMessage = printf_alloc("Error: Time:%.24s File:%s Func:%s Line:%d %s", ctime(&t), file, func, line, lastErrorAsString);
|
||||
|
||||
if (systemMessage == NULL)
|
||||
{
|
||||
systemMessage = "";
|
||||
(void)printf("Error: [FAILED] Time:%.24s File : %s Func : %s Line : %d %s", ctime(&t), file, func, line, lastErrorAsString);
|
||||
systemMessage_should_be_freed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
systemMessage_should_be_freed = 1;
|
||||
}
|
||||
|
||||
userMessage = vprintf_alloc(format, args);
|
||||
if (userMessage == NULL)
|
||||
{
|
||||
(void)printf("[FAILED] ");
|
||||
(void)vprintf(format, args);
|
||||
(void)printf("\n");
|
||||
userMessage_should_be_freed = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*3. printf the system message(__FILE__, __LINE__ etc) + the last error + whatever the user wanted*/
|
||||
(void)printf("%s %s\n", systemMessage, userMessage);
|
||||
userMessage_should_be_freed = 1;
|
||||
}
|
||||
|
||||
if (userMessage_should_be_freed == 1)
|
||||
{
|
||||
free(userMessage);
|
||||
}
|
||||
|
||||
if (systemMessage_should_be_freed == 1)
|
||||
{
|
||||
free(systemMessage);
|
||||
}
|
||||
|
||||
if (lastErrorAsString_should_be_freed == 1)
|
||||
{
|
||||
free(lastErrorAsString);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format (printf, 6, 7)))
|
||||
#endif
|
||||
void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...)
|
||||
{
|
||||
time_t t;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
||||
t = time(NULL);
|
||||
|
||||
switch (log_category)
|
||||
{
|
||||
|
@ -25,12 +218,13 @@ void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char*
|
|||
break;
|
||||
}
|
||||
|
||||
(void)vprintf(format, args);
|
||||
va_end(args);
|
||||
(void)vprintf(format, args);
|
||||
va_end(args);
|
||||
|
||||
(void)log_category;
|
||||
if (options & LOG_LINE)
|
||||
{
|
||||
(void)printf("\r\n");
|
||||
}
|
||||
if (options & LOG_LINE)
|
||||
{
|
||||
(void)printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,11 @@ extern "C" {
|
|||
|
||||
#include "azure_c_shared_utility/xlogging.h"
|
||||
|
||||
extern void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, const int line, unsigned int options, const char* format, ...);
|
||||
extern void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...);
|
||||
|
||||
#if (defined(_MSC_VER)) && (!(defined WINCE))
|
||||
extern void consolelogger_log_with_GetLastError(const char* file, const char* func, int line, const char* format, ...);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -14,9 +14,21 @@
|
|||
#include "azure_c_shared_utility/optimize_size.h"
|
||||
#include "azure_c_shared_utility/crt_abstractions.h"
|
||||
|
||||
// VS 2008 does not have INFINITY and all the nice goodies...
|
||||
#if defined (TIZENRT) || defined (WINCE)
|
||||
#define DEFINE_INFINITY 1
|
||||
#else
|
||||
|
||||
#if defined (WINCE) || defined (TIZENRT)
|
||||
#pragma warning(disable:4756) // warning C4756: overflow in constant arithmetic
|
||||
#if defined _MSC_VER
|
||||
#if _MSC_VER <= 1500
|
||||
#define DEFINE_INFINITY 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined DEFINE_INFINITY
|
||||
|
||||
#pragma warning(disable:4756 4056) // warning C4756: overflow in constant arithmetic
|
||||
|
||||
// These defines are missing in math.h for WEC2013 SDK
|
||||
#ifndef _HUGE_ENUF
|
||||
|
@ -29,8 +41,6 @@
|
|||
#define NAN ((float)(INFINITY * 0.0F))
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#else
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
/** @file ssl_socket.h
|
||||
* @brief Implements socket creation for TLSIO adapters.
|
||||
*/
|
||||
|
||||
#ifndef AZURE_IOT_DNS_H
|
||||
#define AZURE_IOT_DNS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "azure_c_shared_utility/macro_utils.h"
|
||||
#include "azure_c_shared_utility/umock_c_prod.h"
|
||||
|
||||
typedef void* DNS_ASYNC_HANDLE;
|
||||
|
||||
// If options are added in future, DNS_ASYNC_OPTIONS will become a struct containing the options
|
||||
typedef void DNS_ASYNC_OPTIONS;
|
||||
|
||||
/**
|
||||
* @brief Begin the process of an asynchronous DNS lookup.
|
||||
*
|
||||
* @param hostname The url of the host to look up.
|
||||
*
|
||||
* @return @c The newly created DNS_ASYNC_HANDLE.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, DNS_ASYNC_HANDLE, dns_async_create, const char*, hostname, DNS_ASYNC_OPTIONS*, options);
|
||||
|
||||
/**
|
||||
* @brief Continue the lookup process and report its completion state. Must be polled repeatedly for completion.
|
||||
*
|
||||
* @param dns The DNS_ASYNC_HANDLE.
|
||||
*
|
||||
* @return @c A bool to indicate completion.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, bool, dns_async_is_lookup_complete, DNS_ASYNC_HANDLE, dns);
|
||||
|
||||
/**
|
||||
* @brief Return the IPv4 of a completed lookup process. Call only after dns_async_is_lookup_complete indicates completion.
|
||||
*
|
||||
* @param dns The DNS_ASYNC_HANDLE.
|
||||
*
|
||||
* @return @c A uint32_t IPv4 address. 0 indicates failure or not finished.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, uint32_t, dns_async_get_ipv4, DNS_ASYNC_HANDLE, dns);
|
||||
|
||||
/**
|
||||
* @brief Destroy the module.
|
||||
*
|
||||
* @param dns The DNS_ASYNC_HANDLE.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, void, dns_async_destroy, DNS_ASYNC_HANDLE, dns);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AZURE_IOT_DNS_H */
|
|
@ -350,10 +350,10 @@ size_t gballoc_getMaximumMemoryUsed(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Codes_SRS_GBALLOC_01_010: [gballoc_getMaximumMemoryUsed shall return the maximum amount of total memory used recorded since the module initialization.] */
|
||||
/* Codes_SRS_GBALLOC_01_010: [gballoc_getMaximumMemoryUsed shall return the maximum amount of total memory used recorded since the module initialization.] */
|
||||
result = maxSize;
|
||||
Unlock(gballocThreadSafeLock);
|
||||
}
|
||||
(void)Unlock(gballocThreadSafeLock);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -377,9 +377,9 @@ size_t gballoc_getCurrentMemoryUsed(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
/*Codes_SRS_GBALLOC_02_001: [gballoc_getCurrentMemoryUsed shall return the currently used memory size.] */
|
||||
/*Codes_SRS_GBALLOC_02_001: [gballoc_getCurrentMemoryUsed shall return the currently used memory size.] */
|
||||
result = totalSize;
|
||||
Unlock(gballocThreadSafeLock);
|
||||
(void)Unlock(gballocThreadSafeLock);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -218,7 +218,7 @@ int hmacResult(HMACContext *ctx, uint8_t *digest)
|
|||
|
||||
/* perform outer SHA */
|
||||
/* init context for 2nd pass */
|
||||
USHAReset(&ctx->shaContext, ctx->whichSha) ||
|
||||
USHAReset(&ctx->shaContext, (SHAversion)ctx->whichSha) ||
|
||||
|
||||
/* start with outer pad */
|
||||
USHAInput(&ctx->shaContext, ctx->k_opad, ctx->blockSize) ||
|
||||
|
|
|
@ -59,7 +59,7 @@ static CONCRETE_IO_HANDLE http_proxy_io_create(void* io_create_parameters)
|
|||
else
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_003: [ `io_create_parameters` shall be used as an `HTTP_PROXY_IO_CONFIG*`. ]*/
|
||||
HTTP_PROXY_IO_CONFIG* http_proxy_io_config = io_create_parameters;
|
||||
HTTP_PROXY_IO_CONFIG* http_proxy_io_config = (HTTP_PROXY_IO_CONFIG*)io_create_parameters;
|
||||
if ((http_proxy_io_config->hostname == NULL) ||
|
||||
(http_proxy_io_config->proxy_hostname == NULL))
|
||||
{
|
||||
|
@ -79,7 +79,7 @@ static CONCRETE_IO_HANDLE http_proxy_io_create(void* io_create_parameters)
|
|||
else
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_001: [ `http_proxy_io_create` shall create a new instance of the HTTP proxy IO. ]*/
|
||||
result = malloc(sizeof(HTTP_PROXY_IO_INSTANCE));
|
||||
result = (HTTP_PROXY_IO_INSTANCE*)malloc(sizeof(HTTP_PROXY_IO_INSTANCE));
|
||||
if (result == NULL)
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_051: [ If allocating memory for the new instance fails, `http_proxy_io_create` shall fail and return NULL. ]*/
|
||||
|
@ -292,7 +292,11 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
char* plain_auth_string_bytes;
|
||||
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_060: [ - The value of `Proxy-Authorization` shall be the constructed according to RFC 2617. ]*/
|
||||
int plain_auth_string_length = snprintf(NULL, 0, "%s:%s", http_proxy_io_instance->username, (http_proxy_io_instance->password == NULL) ? "" : http_proxy_io_instance->password);
|
||||
int plain_auth_string_length = (int)(strlen(http_proxy_io_instance->username)+1);
|
||||
if (http_proxy_io_instance->password != NULL)
|
||||
{
|
||||
plain_auth_string_length += (int)strlen(http_proxy_io_instance->password);
|
||||
}
|
||||
|
||||
if (plain_auth_string_length < 0)
|
||||
{
|
||||
|
@ -314,7 +318,7 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
/* Codes_SRS_HTTP_PROXY_IO_01_091: [ To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 [7] encoded string in the credentials. ]*/
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_092: [ A client MAY preemptively send the corresponding Authorization header with requests for resources in that space without receipt of another challenge from the server. ]*/
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_093: [ Userids might be case sensitive. ]*/
|
||||
if (snprintf(plain_auth_string_bytes, plain_auth_string_length + 1, "%s:%s", http_proxy_io_instance->username, (http_proxy_io_instance->password == NULL) ? "" : http_proxy_io_instance->password) < 0)
|
||||
if (sprintf(plain_auth_string_bytes, "%s:%s", http_proxy_io_instance->username, (http_proxy_io_instance->password == NULL) ? "" : http_proxy_io_instance->password) < 0)
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the `on_open_complete` callback shall be triggered with `IO_OPEN_ERROR`, passing also the `on_open_complete_context` argument as `context`. ]*/
|
||||
encoded_auth_string = NULL;
|
||||
|
@ -352,7 +356,7 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
const char* auth_string_payload;
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_075: [ The Request-URI portion of the Request-Line is always an 'authority' as defined by URI Generic Syntax [2], which is to say the host name and port number destination of the requested connection separated by a colon: ]*/
|
||||
const char request_format[] = "CONNECT %s:%d HTTP/1.1\r\nHost:%s:%d%s%s\r\n\r\n";
|
||||
|
||||
const char proxy_basic[] = "\r\nProxy-authorization: Basic ";
|
||||
if (http_proxy_io_instance->username != NULL)
|
||||
{
|
||||
auth_string_payload = STRING_c_str(encoded_auth_string);
|
||||
|
@ -363,14 +367,13 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
}
|
||||
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_059: [ - If `username` and `password` have been specified in the arguments passed to `http_proxy_io_create`, then the header `Proxy-Authorization` shall be added to the request. ]*/
|
||||
connect_request_length = snprintf(NULL, 0, request_format,
|
||||
http_proxy_io_instance->hostname,
|
||||
http_proxy_io_instance->port,
|
||||
http_proxy_io_instance->hostname,
|
||||
http_proxy_io_instance->port,
|
||||
(http_proxy_io_instance->username != NULL) ? "\r\nProxy-authorization: Basic " : "",
|
||||
auth_string_payload);
|
||||
|
||||
connect_request_length = (int)(strlen(request_format)+(strlen(http_proxy_io_instance->hostname)*2)+strlen(auth_string_payload)+10);
|
||||
if (http_proxy_io_instance->username != NULL)
|
||||
{
|
||||
connect_request_length += (int)strlen(proxy_basic);
|
||||
}
|
||||
|
||||
if (connect_request_length < 0)
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_062: [ If any failure is encountered while constructing the request, the `on_open_complete` callback shall be triggered with `IO_OPEN_ERROR`, passing also the `on_open_complete_context` argument as `context`. ]*/
|
||||
|
@ -389,12 +392,12 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
else
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_059: [ - If `username` and `password` have been specified in the arguments passed to `http_proxy_io_create`, then the header `Proxy-Authorization` shall be added to the request. ]*/
|
||||
connect_request_length = snprintf(connect_request, connect_request_length + 1, request_format,
|
||||
connect_request_length = sprintf(connect_request, request_format,
|
||||
http_proxy_io_instance->hostname,
|
||||
http_proxy_io_instance->port,
|
||||
http_proxy_io_instance->hostname,
|
||||
http_proxy_io_instance->port,
|
||||
(http_proxy_io_instance->username != NULL) ? "\r\nProxy-authorization: Basic " : "",
|
||||
(http_proxy_io_instance->username != NULL) ? proxy_basic : "",
|
||||
auth_string_payload);
|
||||
|
||||
if (connect_request_length < 0)
|
||||
|
@ -619,7 +622,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
|
|||
case HTTP_PROXY_IO_STATE_WAITING_FOR_CONNECT_RESPONSE:
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_065: [ When bytes are received and the response to the CONNECT request was not yet received, the bytes shall be accumulated until a double new-line is detected. ]*/
|
||||
unsigned char* new_receive_buffer = realloc(http_proxy_io_instance->receive_buffer, http_proxy_io_instance->receive_buffer_size + size + 1);
|
||||
unsigned char* new_receive_buffer = (unsigned char*)realloc(http_proxy_io_instance->receive_buffer, http_proxy_io_instance->receive_buffer_size + size + 1);
|
||||
if (new_receive_buffer == NULL)
|
||||
{
|
||||
/* Codes_SRS_HTTP_PROXY_IO_01_067: [ If allocating memory for the buffered bytes fails, the `on_open_complete` callback shall be triggered with `IO_OPEN_ERROR`, passing also the `on_open_complete_context` argument as `context`. ]*/
|
||||
|
@ -635,7 +638,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
|
|||
|
||||
if (http_proxy_io_instance->receive_buffer_size >= 4)
|
||||
{
|
||||
char* request_end_ptr;
|
||||
const char* request_end_ptr;
|
||||
|
||||
http_proxy_io_instance->receive_buffer[http_proxy_io_instance->receive_buffer_size] = 0;
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ HTTPAPIEX_RESULT HTTPAPIEX_ExecuteRequest(HTTPAPIEX_HANDLE handle, HTTPAPI_REQUE
|
|||
{
|
||||
/*Codes_SRS_HTTPAPIEX_02_035: [HTTPAPIEX_ExecuteRequest shall pass all the saved options (see HTTPAPIEX_SetOption) to the newly create HTTPAPI_HANDLE in step 2 by calling HTTPAPI_SetOption.]*/
|
||||
/*Codes_SRS_HTTPAPIEX_02_036: [If setting the option fails, then the failure shall be ignored.] */
|
||||
HTTPAPIEX_SAVED_OPTION* option = VECTOR_element(handleData->savedOptions, i);
|
||||
HTTPAPIEX_SAVED_OPTION* option = (HTTPAPIEX_SAVED_OPTION*)VECTOR_element(handleData->savedOptions, i);
|
||||
if (HTTPAPI_SetOption(handleData->httpHandle, option->optionName, option->value) != HTTPAPI_OK)
|
||||
{
|
||||
LogError("HTTPAPI_SetOption failed when called for option %s", option->optionName);
|
||||
|
@ -517,7 +517,7 @@ void HTTPAPIEX_Destroy(HTTPAPIEX_HANDLE handle)
|
|||
vectorSize = VECTOR_size(handleData->savedOptions);
|
||||
for (i = 0; i < vectorSize; i++)
|
||||
{
|
||||
HTTPAPIEX_SAVED_OPTION*savedOption = VECTOR_element(handleData->savedOptions, i);
|
||||
HTTPAPIEX_SAVED_OPTION* savedOption = (HTTPAPIEX_SAVED_OPTION*)VECTOR_element(handleData->savedOptions, i);
|
||||
free((void*)savedOption->optionName);
|
||||
free((void*)savedOption->value);
|
||||
}
|
||||
|
@ -533,7 +533,7 @@ void HTTPAPIEX_Destroy(HTTPAPIEX_HANDLE handle)
|
|||
|
||||
static bool sameName(const void* element, const void* value)
|
||||
{
|
||||
return (strcmp(((HTTPAPIEX_SAVED_OPTION*)element)->optionName, value) == 0) ? true : false;
|
||||
return (strcmp(((HTTPAPIEX_SAVED_OPTION*)element)->optionName, (const char*)value) == 0) ? true : false;
|
||||
}
|
||||
|
||||
/*return 0 on success, any other value is error*/
|
||||
|
@ -544,7 +544,7 @@ static int createOrUpdateOption(HTTPAPIEX_HANDLE_DATA* handleData, const char* o
|
|||
int result;
|
||||
|
||||
/*decide bwtween update or create*/
|
||||
HTTPAPIEX_SAVED_OPTION* whereIsIt = VECTOR_find_if(handleData->savedOptions, sameName, optionName);
|
||||
HTTPAPIEX_SAVED_OPTION* whereIsIt = (HTTPAPIEX_SAVED_OPTION*)VECTOR_find_if(handleData->savedOptions, sameName, optionName);
|
||||
if (whereIsIt != NULL)
|
||||
{
|
||||
free((void*)(whereIsIt->value));
|
||||
|
|
|
@ -43,7 +43,7 @@ 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 = malloc(sizeof(HTTPAPIEX_SAS_STATE));
|
||||
HTTPAPIEX_SAS_STATE* state = (HTTPAPIEX_SAS_STATE*)malloc(sizeof(HTTPAPIEX_SAS_STATE));
|
||||
/*Codes_SRS_HTTPAPIEXSAS_06_004: [If there are any other errors in the instantiation of this handle then HTTPAPIEX_SAS_Create shall return NULL.]*/
|
||||
if (state != NULL)
|
||||
{
|
||||
|
|
|
@ -310,7 +310,7 @@ HTTP_HEADERS_HANDLE HTTPHeaders_Clone(HTTP_HEADERS_HANDLE handle)
|
|||
else
|
||||
{
|
||||
/*Codes_SRS_HTTP_HEADERS_02_004: [Otherwise HTTPHeaders_Clone shall clone the content of handle to a new handle.] */
|
||||
result = malloc(sizeof(HTTP_HEADERS_HANDLE_DATA));
|
||||
result = (HTTP_HEADERS_HANDLE_DATA*)malloc(sizeof(HTTP_HEADERS_HANDLE_DATA));
|
||||
if (result == NULL)
|
||||
{
|
||||
/*Codes_SRS_HTTP_HEADERS_02_005: [If cloning fails for any reason, then HTTPHeaders_Clone shall return NULL.] */
|
||||
|
|
|
@ -137,9 +137,9 @@ MAP_HANDLE Map_Clone(MAP_HANDLE handle)
|
|||
}
|
||||
else if ((result->values = Map_CloneVector((const char* const*)handleData->values, handleData->count)) == NULL)
|
||||
{
|
||||
size_t i;
|
||||
/*Codes_SRS_MAP_02_047: [If during cloning, any operation fails, then Map_Clone shall return NULL.] */
|
||||
LogError("unable to clone values");
|
||||
size_t i;
|
||||
for (i = 0; i < result->count; i++)
|
||||
{
|
||||
free(result->keys[i]);
|
||||
|
|
|
@ -8,12 +8,14 @@
|
|||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "azure_c_shared_utility/strings.h"
|
||||
#include "azure_c_shared_utility/xio.h"
|
||||
#include "azure_c_shared_utility/umock_c_prod.h"
|
||||
|
||||
MOCKABLE_FUNCTION(, int, platform_init);
|
||||
MOCKABLE_FUNCTION(, void, platform_deinit);
|
||||
MOCKABLE_FUNCTION(, const IO_INTERFACE_DESCRIPTION*, platform_get_default_tlsio);
|
||||
MOCKABLE_FUNCTION(, STRING_HANDLE, platform_get_platform_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -35,6 +35,12 @@ extern "C"
|
|||
#undef REFCOUNT_USE_STD_ATOMIC
|
||||
#endif
|
||||
|
||||
#if defined(FREERTOS_ARCH_ESP8266)
|
||||
#undef REFCOUNT_USE_STD_ATOMIC
|
||||
#define REFCOUNT_ATOMIC_DONTCARE 1
|
||||
#undef __GNUC__
|
||||
#endif
|
||||
|
||||
#define REFCOUNT_TYPE(type) \
|
||||
struct C2(C2(REFCOUNT_, type), _TAG)
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "azure_c_shared_utility/gballoc.h"
|
||||
#include "azure_c_shared_utility/sastoken.h"
|
||||
#include "azure_c_shared_utility/urlencode.h"
|
||||
|
@ -38,8 +40,8 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
/*Codes_SRS_SASTOKEN_25_025: [**SASToken_Validate shall get the SASToken value by invoking STRING_c_str on the handle.**]***/
|
||||
const char* sasTokenArray = STRING_c_str(sasToken);
|
||||
|
||||
/***Codes_SRS_SASTOKEN_25_024: [**If handle is NULL then SASToken_Validate shall return false.**] ***/
|
||||
/*Codes_SRS_SASTOKEN_25_026: [**If STRING_c_str on handle return NULL then SASToken_Validate shall return false.**]***/
|
||||
/* Codes_SRS_SASTOKEN_25_024: [**If handle is NULL then SASToken_Validate shall return false.**] */
|
||||
/* Codes_SRS_SASTOKEN_25_026: [**If STRING_c_str on handle return NULL then SASToken_Validate shall return false.**] */
|
||||
if (sasToken == NULL || sasTokenArray == NULL)
|
||||
{
|
||||
result = false;
|
||||
|
@ -49,8 +51,8 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
int seStart = -1, seStop = -1;
|
||||
int srStart = -1, srStop = -1;
|
||||
int sigStart = -1, sigStop = -1;
|
||||
int tokenLength = (int) STRING_length(sasToken);
|
||||
int i ;
|
||||
int tokenLength = (int)STRING_length(sasToken);
|
||||
int i;
|
||||
for (i = 0; i < tokenLength; i++)
|
||||
{
|
||||
if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'e' && sasTokenArray[i + 2] == '=') // Look for se=
|
||||
|
@ -74,9 +76,8 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
else
|
||||
seStart = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'r' && sasTokenArray[i + 2] == '=') // Look for sr=
|
||||
else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'r' && sasTokenArray[i + 2] == '=') // Look for sr=
|
||||
{
|
||||
srStart = i + 3;
|
||||
if (seStart > 0 && seStop < 0)
|
||||
|
@ -97,9 +98,8 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
else
|
||||
srStart = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'i' && sasTokenArray[i + 2] == 'g' && sasTokenArray[i + 3] == '=') // Look for sig=
|
||||
else if (sasTokenArray[i] == 's' && sasTokenArray[i + 1] == 'i' && sasTokenArray[i + 2] == 'g' && sasTokenArray[i + 3] == '=') // Look for sig=
|
||||
{
|
||||
sigStart = i + 4;
|
||||
if (srStart > 0 && srStop < 0)
|
||||
|
@ -120,9 +120,9 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
else
|
||||
sigStart = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*Codes_SRS_SASTOKEN_25_027: [**If SASTOKEN does not obey the SASToken format then SASToken_Validate shall return false.**]***/
|
||||
/*Codes_SRS_SASTOKEN_25_028: [**SASToken_validate shall check for the presence of sr, se and sig from the token and return false if not found**]***/
|
||||
if (seStart < 0 || srStart < 0 || sigStart < 0)
|
||||
|
@ -152,7 +152,7 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
}
|
||||
else
|
||||
{
|
||||
char* expiryASCII = malloc(seStop - seStart + 1);
|
||||
char* expiryASCII = (char*)malloc(seStop - seStart + 1);
|
||||
/*Codes_SRS_SASTOKEN_25_031: [**If malloc fails during validation then SASToken_Validate shall return false.**]***/
|
||||
if (expiryASCII == NULL)
|
||||
{
|
||||
|
@ -161,12 +161,18 @@ bool SASToken_Validate(STRING_HANDLE sasToken)
|
|||
else
|
||||
{
|
||||
double expiry;
|
||||
// Add the Null terminator here
|
||||
memset(expiryASCII, 0, seStop - seStart + 1);
|
||||
for (i = seStart; i < seStop; i++)
|
||||
{
|
||||
// The se contains the expiration values, if a & token is encountered then
|
||||
// the se field is complete.
|
||||
if (sasTokenArray[i] == '&')
|
||||
{
|
||||
break;
|
||||
}
|
||||
expiryASCII[i - seStart] = sasTokenArray[i];
|
||||
}
|
||||
expiryASCII[seStop - seStart] = '\0';
|
||||
|
||||
expiry = getExpiryValue(expiryASCII);
|
||||
/*Codes_SRS_SASTOKEN_25_029: [**SASToken_validate shall check for expiry time from token and if token has expired then would return false **]***/
|
||||
if (expiry <= 0)
|
||||
|
@ -265,7 +271,7 @@ static STRING_HANDLE construct_sas_token(const char* key, const char* scope, con
|
|||
/*Codes_SRS_SASTOKEN_06_022: [The string "&skn=" is appended to result.]*/
|
||||
/*Codes_SRS_SASTOKEN_06_023: [The argument keyName is appended to result.]*/
|
||||
if ((HMACSHA256_ComputeHash(outBuf, outLen, inBuf, inLen, hash) != HMACSHA256_OK) ||
|
||||
((base64Signature = Base64_Encode(hash)) == NULL) ||
|
||||
((base64Signature = Base64_Encoder(hash)) == NULL) ||
|
||||
((urlEncodedSignature = URL_Encode(base64Signature)) == NULL) ||
|
||||
(STRING_copy(result, "SharedAccessSignature sr=") != 0) ||
|
||||
(STRING_concat(result, scope) != 0) ||
|
||||
|
|
|
@ -32,6 +32,7 @@ extern "C"
|
|||
static const char* OPTION_CURL_FORBID_REUSE = "CURLOPT_FORBID_REUSE";
|
||||
static const char* OPTION_CURL_VERBOSE = "CURLOPT_VERBOSE";
|
||||
|
||||
static const char* OPTION_NET_INT_MAC_ADDRESS = "net_interface_mac_address";
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
/** @file socket_async.h
|
||||
* @brief Abstracts non-blocking sockets.
|
||||
*/
|
||||
|
||||
#ifndef AZURE_SOCKET_ASYNC_H
|
||||
#define AZURE_SOCKET_ASYNC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "azure_c_shared_utility/macro_utils.h"
|
||||
#include "azure_c_shared_utility/umock_c_prod.h"
|
||||
|
||||
// socket_async exposes asynchronous socket operations while hiding OS-specifics. Committing to
|
||||
// asynchronous operation also simplifies the interface compared to generic sockets.
|
||||
|
||||
#define SOCKET_ASYNC_INVALID_SOCKET -1
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// Keepalive is disabled by default at the TCP level. If keepalive is desired, it
|
||||
// is strongly recommended to use one of the higher level keepalive (ping) options rather
|
||||
// than the TCP level because the higher level options provide server connection status
|
||||
// in addition to keeping the connection open.
|
||||
int keep_alive; // < 0 for system defaults, >= 0 to use supplied keep_alive, idle, interval, and count
|
||||
int keep_idle; // seconds before first keepalive packet (ignored if keep_alive <= 0)
|
||||
int keep_interval; // seconds between keepalive packets (ignored if keep_alive <= 0)
|
||||
int keep_count; // number of times to try before declaring failure (ignored if keep_alive <= 0)
|
||||
// It is acceptable to extend this struct by adding members for future enhancement,
|
||||
// but existing members must not be altered to ensure back-compatibility.
|
||||
} SOCKET_ASYNC_OPTIONS;
|
||||
typedef SOCKET_ASYNC_OPTIONS* SOCKET_ASYNC_OPTIONS_HANDLE;
|
||||
|
||||
typedef int SOCKET_ASYNC_HANDLE;
|
||||
|
||||
/**
|
||||
* @brief Create a non-blocking socket that is correctly configured for asynchronous use.
|
||||
*
|
||||
* @param sock Receives the created SOCKET_ASYNC_HANDLE.
|
||||
*
|
||||
* @param host_ipv4 The IPv4 of the SSL server to be contacted.
|
||||
*
|
||||
* @param port The port of the SSL server to use.
|
||||
*
|
||||
* @param is_UDP True for UDP, false for TCP.
|
||||
*
|
||||
* @param options A pointer to SOCKET_ASYNC_OPTIONS used during socket_async_create
|
||||
* for TCP connections only. May be NULL. Ignored for UDP sockets.
|
||||
* Need only exist for the duration of the socket_async_create call.
|
||||
*
|
||||
* @return @c The created and configured SOCKET_ASYNC_HANDLE if the API call is successful
|
||||
* or SOCKET_ASYNC_INVALID_SOCKET in case it fails. Error logging is
|
||||
* performed by the underlying concrete implementation, so no
|
||||
* further error logging is necessary.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, SOCKET_ASYNC_HANDLE, socket_async_create, uint32_t, host_ipv4, uint16_t, port, bool, is_UDP, SOCKET_ASYNC_OPTIONS_HANDLE, options);
|
||||
|
||||
/**
|
||||
* @brief Check whether a newly-created socket_async has completed its initial connection.
|
||||
*
|
||||
* @param sock The created SOCKET_ASYNC_HANDLE to check for connection completion.
|
||||
*
|
||||
* @param is_created Receives the completion state if successful, set to false on failure.
|
||||
*
|
||||
* @return @c 0 if the API call is successful.
|
||||
* __FAILURE__ means an unexpected error has occurred and the socket must be destroyed.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, int, socket_async_is_create_complete, SOCKET_ASYNC_HANDLE, sock, bool*, is_complete);
|
||||
|
||||
/**
|
||||
* @brief Send a message on the specified socket.
|
||||
*
|
||||
* @param sock The socket to be used.
|
||||
*
|
||||
* @param buffer The buffer containing the message to transmit.
|
||||
*
|
||||
* @param size The number of bytes to transmit.
|
||||
*
|
||||
* @param sent_count Receives the number of bytes transmitted. The N == 0
|
||||
* case means normal operation but the socket's outgoing buffer was full.
|
||||
*
|
||||
* @return @c 0 if successful.
|
||||
* __FAILURE__ means an unexpected error has occurred and the socket must be destroyed.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, int, socket_async_send, SOCKET_ASYNC_HANDLE, sock, const void*, buffer, size_t, size, size_t*, sent_count);
|
||||
|
||||
/**
|
||||
* @brief Receive a message on the specified socket.
|
||||
*
|
||||
* @param sock The socket to be used.
|
||||
*
|
||||
* @param buffer The buffer containing the message to receive.
|
||||
*
|
||||
* @param size The buffer size in bytes.
|
||||
*
|
||||
* @param received_count Receives the number of bytes received into the buffer.
|
||||
*
|
||||
* @return @c 0 if successful.
|
||||
* __FAILURE__ means an unexpected error has occurred and the socket must be destroyed.
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, int, socket_async_receive, SOCKET_ASYNC_HANDLE, sock, void*, buffer, size_t, size, size_t*, received_count);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Close the socket returned by socket_async_create.
|
||||
*
|
||||
* @param sock The socket to be destroyed (closed, in standard socket terms).
|
||||
*/
|
||||
MOCKABLE_FUNCTION(, void, socket_async_destroy, SOCKET_ASYNC_HANDLE, sock);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AZURE_SOCKET_ASYNC_H */
|
|
@ -132,7 +132,7 @@ int STRING_TOKENIZER_get_next_token(STRING_TOKENIZER_HANDLE tokenizer, STRING_HA
|
|||
else
|
||||
{
|
||||
bool foundDelimitter = false;
|
||||
char* endOfTokenPosition=NULL;
|
||||
const char* endOfTokenPosition=NULL;
|
||||
size_t amountOfCharactersToCopy;
|
||||
size_t j;
|
||||
//At this point the Current Pos is pointing to a character that is point to a nonDelimiter. So, now search for a Delimiter, till the end of the String.
|
||||
|
|
|
@ -119,6 +119,9 @@ STRING_HANDLE STRING_construct(const char* psz)
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format (printf, 1, 2)))
|
||||
#endif
|
||||
STRING_HANDLE STRING_construct_sprintf(const char* format, ...)
|
||||
{
|
||||
STRING* result;
|
||||
|
@ -507,6 +510,9 @@ int STRING_copy_n(STRING_HANDLE handle, const char* s2, size_t n)
|
|||
return result;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
int STRING_sprintf(STRING_HANDLE handle, const char* format, ...)
|
||||
{
|
||||
int result;
|
||||
|
|
|
@ -139,7 +139,7 @@ STRING_HANDLE URL_Encode(STRING_HANDLE input)
|
|||
currentUnsignedChar = (unsigned char)(*currentInput++);
|
||||
lengthOfResult += URL_PrintableCharSize(currentUnsignedChar);
|
||||
} while (currentUnsignedChar != 0);
|
||||
if ((encodedURL = malloc(lengthOfResult)) == NULL)
|
||||
if ((encodedURL = (char*)malloc(lengthOfResult)) == NULL)
|
||||
{
|
||||
/*Codes_SRS_URL_ENCODE_06_002: [If an error occurs during the encoding of input then URL_Encode will return NULL.]*/
|
||||
result = NULL;
|
||||
|
|
|
@ -644,7 +644,7 @@ static void indicate_ws_error_and_close(UWS_CLIENT_INSTANCE* uws_client, WS_ERRO
|
|||
|
||||
static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_result)
|
||||
{
|
||||
UWS_CLIENT_HANDLE uws_client = context;
|
||||
UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
|
||||
/* Codes_SRS_UWS_CLIENT_01_401: [ If `on_underlying_io_open_complete` is called with a NULL context, `on_underlying_io_open_complete` shall do nothing. ]*/
|
||||
if (uws_client == NULL)
|
||||
{
|
||||
|
@ -722,12 +722,7 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
"\r\n";
|
||||
const char* base64_nonce_chars = STRING_c_str(base64_nonce);
|
||||
|
||||
upgrade_request_length = snprintf(NULL, 0, upgrade_request_format,
|
||||
uws_client->resource_name,
|
||||
uws_client->hostname,
|
||||
uws_client->port,
|
||||
base64_nonce_chars,
|
||||
uws_client->protocols[0].protocol);
|
||||
upgrade_request_length = (int)(strlen(upgrade_request_format) + strlen(uws_client->resource_name)+strlen(uws_client->hostname) + strlen(base64_nonce_chars) + strlen(uws_client->protocols[0].protocol)+5);
|
||||
if (upgrade_request_length < 0)
|
||||
{
|
||||
/* Codes_SRS_UWS_CLIENT_01_408: [ If constructing of the WebSocket upgrade request fails, 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_CONSTRUCTING_UPGRADE_REQUEST`. ]*/
|
||||
|
@ -745,7 +740,8 @@ static void on_underlying_io_open_complete(void* context, IO_OPEN_RESULT open_re
|
|||
}
|
||||
else
|
||||
{
|
||||
upgrade_request_length = snprintf(upgrade_request, upgrade_request_length + 1, upgrade_request_format,
|
||||
|
||||
upgrade_request_length = sprintf(upgrade_request, upgrade_request_format,
|
||||
uws_client->resource_name,
|
||||
uws_client->hostname,
|
||||
uws_client->port,
|
||||
|
@ -800,7 +796,7 @@ static void on_underlying_io_close_complete(void* context)
|
|||
}
|
||||
else
|
||||
{
|
||||
UWS_CLIENT_HANDLE uws_client = context;
|
||||
UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
|
||||
if (uws_client->uws_state == UWS_STATE_CLOSING_UNDERLYING_IO)
|
||||
{
|
||||
/* Codes_SRS_UWS_CLIENT_01_475: [ When `on_underlying_io_close_complete` is called while closing the underlying IO a subsequent `uws_client_open_async` shall succeed. ]*/
|
||||
|
@ -819,7 +815,7 @@ static void on_underlying_io_close_sent(void* context, IO_SEND_RESULT io_send_re
|
|||
}
|
||||
else
|
||||
{
|
||||
UWS_CLIENT_INSTANCE* uws_client = context;
|
||||
UWS_CLIENT_INSTANCE* uws_client = (UWS_CLIENT_HANDLE)context;
|
||||
|
||||
switch (io_send_result)
|
||||
{
|
||||
|
@ -943,7 +939,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
|
|||
/* Codes_SRS_UWS_CLIENT_01_415: [ If called with a NULL `context` argument, `on_underlying_io_bytes_received` shall do nothing. ]*/
|
||||
if (context != NULL)
|
||||
{
|
||||
UWS_CLIENT_HANDLE uws_client = context;
|
||||
UWS_CLIENT_HANDLE uws_client = (UWS_CLIENT_HANDLE)context;
|
||||
|
||||
if ((buffer == NULL) ||
|
||||
(size == 0))
|
||||
|
@ -1033,7 +1029,7 @@ static void on_underlying_io_bytes_received(void* context, const unsigned char*
|
|||
|
||||
case UWS_STATE_WAITING_FOR_UPGRADE_RESPONSE:
|
||||
{
|
||||
char* request_end_ptr;
|
||||
const char* request_end_ptr;
|
||||
|
||||
/* Make sure it is zero terminated */
|
||||
uws_client->received_bytes[uws_client->received_bytes_count] = '\0';
|
||||
|
@ -1726,7 +1722,7 @@ int uws_client_send_frame_async(UWS_CLIENT_HANDLE uws_client, unsigned char fram
|
|||
/* Codes_SRS_UWS_CLIENT_01_270: [ An endpoint MUST encapsulate the /data/ in a WebSocket frame as defined in Section 5.2. ]*/
|
||||
/* Codes_SRS_UWS_CLIENT_01_272: [ The opcode (frame-opcode) of the first frame containing the data MUST be set to the appropriate value from Section 5.2 for data that is to be interpreted by the recipient as text or binary data. ]*/
|
||||
/* Codes_SRS_UWS_CLIENT_01_274: [ If the data is being sent by the client, the frame(s) MUST be masked as defined in Section 5.3. ]*/
|
||||
non_control_frame_buffer = uws_frame_encoder_encode(frame_type, buffer, size, true, is_final, 0);
|
||||
non_control_frame_buffer = uws_frame_encoder_encode((WS_FRAME_TYPE)frame_type, buffer, size, true, is_final, 0);
|
||||
if (non_control_frame_buffer == NULL)
|
||||
{
|
||||
/* Codes_SRS_UWS_CLIENT_01_426: [ If `uws_frame_encoder_encode` fails, `uws_client_send_frame_async` shall fail and return a non-zero value. ]*/
|
||||
|
|
|
@ -97,7 +97,7 @@ BUFFER_HANDLE uws_frame_encoder_encode(WS_FRAME_TYPE opcode, const unsigned char
|
|||
/* Codes_SRS_UWS_FRAME_ENCODER_01_012: [ * %x9 denotes a ping ]*/
|
||||
/* Codes_SRS_UWS_FRAME_ENCODER_01_013: [ * %xA denotes a pong ]*/
|
||||
/* Codes_SRS_UWS_FRAME_ENCODER_01_014: [ * %xB-F are reserved for further control frames ]*/
|
||||
buffer[0] = opcode;
|
||||
buffer[0] = (unsigned char)opcode;
|
||||
|
||||
/* Codes_SRS_UWS_FRAME_ENCODER_01_002: [ Indicates that this is the final fragment in a message. ]*/
|
||||
/* Codes_SRS_UWS_FRAME_ENCODER_01_003: [ The first fragment MAY also be the final fragment. ]*/
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifdef WINCE
|
||||
#include <stdarg.h>
|
||||
|
||||
void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, const int line, unsigned int options, const char* format, ...)
|
||||
void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
|
@ -42,7 +42,6 @@ void consolelogger_log(LOG_CATEGORY log_category, const char* file, const char*
|
|||
|
||||
LOGGER_LOG global_log_function = consolelogger_log;
|
||||
|
||||
|
||||
void xlogging_set_log_function(LOGGER_LOG log_function)
|
||||
{
|
||||
global_log_function = log_function;
|
||||
|
@ -53,6 +52,21 @@ LOGGER_LOG xlogging_get_log_function(void)
|
|||
return global_log_function;
|
||||
}
|
||||
|
||||
#if (defined(_MSC_VER)) && (!(defined WINCE))
|
||||
|
||||
LOGGER_LOG_GETLASTERROR global_log_function_GetLastError = consolelogger_log_with_GetLastError;
|
||||
|
||||
void xlogging_set_log_function_GetLastError(LOGGER_LOG_GETLASTERROR log_function_GetLastError)
|
||||
{
|
||||
global_log_function_GetLastError = log_function_GetLastError;
|
||||
}
|
||||
|
||||
LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void)
|
||||
{
|
||||
return global_log_function_GetLastError;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Print up to 16 bytes per line. */
|
||||
#define LINE_SIZE 16
|
||||
|
||||
|
@ -71,7 +85,8 @@ void xlogging_dump_buffer(const void* buf, size_t size)
|
|||
const unsigned char* startPos = bufAsChar;
|
||||
|
||||
/* Print the whole buffer. */
|
||||
for (size_t i = 0; i < size; i++)
|
||||
size_t i = 0;
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
/* Store the printable value of the char in the charBuf to print. */
|
||||
charBuf[countbuf] = PRINTABLE(*bufAsChar);
|
||||
|
|
|
@ -30,7 +30,8 @@ typedef enum LOG_CATEGORY_TAG
|
|||
#define FUNC_NAME __func__
|
||||
#endif
|
||||
|
||||
typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const char* func, const int line, unsigned int options, const char* format, ...);
|
||||
typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const char* func, int line, unsigned int options, const char* format, ...);
|
||||
typedef void(*LOGGER_LOG_GETLASTERROR)(const char* file, const char* func, int line, const char* format, ...);
|
||||
|
||||
#define LOG_NONE 0x00
|
||||
#define LOG_LINE 0x01
|
||||
|
@ -52,18 +53,33 @@ typedef void(*LOGGER_LOG)(LOG_CATEGORY log_category, const char* file, const cha
|
|||
#define xlogging_set_log_function(...)
|
||||
#define LogErrorWinHTTPWithGetLastErrorAsString(...)
|
||||
#define UNUSED(x) (void)(x)
|
||||
|
||||
#elif defined(ESP8266_RTOS)
|
||||
#include "c_types.h"
|
||||
#define LogInfo(FORMAT, ...) do { \
|
||||
static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = FORMAT; \
|
||||
printf(flash_str, ##__VA_ARGS__); \
|
||||
printf("\n");\
|
||||
} while((void)0,0)
|
||||
|
||||
#define LogError LogInfo
|
||||
#define LOG(log_category, log_options, FORMAT, ...) { \
|
||||
static const char flash_str[] ICACHE_RODATA_ATTR STORE_ATTR = (FORMAT); \
|
||||
printf(flash_str, ##__VA_ARGS__); \
|
||||
printf("\r\n"); \
|
||||
}
|
||||
|
||||
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
/*
|
||||
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")))
|
||||
#define PROGMEM ICACHE_RODATA_ATTR
|
||||
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
|
||||
const char* __localFORMAT = PSTR(FORMAT);
|
||||
|
||||
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.
|
||||
*/
|
||||
|
@ -90,19 +106,26 @@ so we compacted the log in the macro LogInfo.
|
|||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, __VA_ARGS__); }while(0)
|
||||
#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0)
|
||||
#else
|
||||
#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, ##__VA_ARGS__); }while(0)
|
||||
#define LogInfo(FORMAT, ...) do{LOG(AZ_LOG_INFO, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0)
|
||||
#endif
|
||||
|
||||
#if defined _MSC_VER
|
||||
#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, __VA_ARGS__); }while(0)
|
||||
|
||||
#if !defined(WINCE)
|
||||
extern void xlogging_set_log_function_GetLastError(LOGGER_LOG_GETLASTERROR log_function);
|
||||
extern LOGGER_LOG_GETLASTERROR xlogging_get_log_function_GetLastError(void);
|
||||
#define LogLastError(FORMAT, ...) do{ LOGGER_LOG_GETLASTERROR l = xlogging_get_log_function_GetLastError(); if(l!=NULL) l(__FILE__, FUNC_NAME, __LINE__, FORMAT, __VA_ARGS__); }while((void)0,0)
|
||||
#endif
|
||||
|
||||
#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, __VA_ARGS__); }while((void)0,0)
|
||||
#define TEMP_BUFFER_SIZE 1024
|
||||
#define MESSAGE_BUFFER_SIZE 260
|
||||
#define LogErrorWinHTTPWithGetLastErrorAsString(FORMAT, ...) do { \
|
||||
DWORD errorMessageID = GetLastError(); \
|
||||
char messageBuffer[MESSAGE_BUFFER_SIZE]; \
|
||||
LogError(FORMAT, __VA_ARGS__); \
|
||||
CHAR messageBuffer[MESSAGE_BUFFER_SIZE]; \
|
||||
if (errorMessageID == 0) \
|
||||
{\
|
||||
LogError("GetLastError() returned 0. Make sure you are calling this right after the code that failed. "); \
|
||||
|
@ -128,9 +151,9 @@ so we compacted the log in the macro LogInfo.
|
|||
LogError("GetLastError: %s.", messageBuffer); \
|
||||
}\
|
||||
}\
|
||||
} while(0)
|
||||
} while((void)0,0)
|
||||
#else
|
||||
#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, ##__VA_ARGS__); }while(0)
|
||||
#define LogError(FORMAT, ...) do{ LOG(AZ_LOG_ERROR, LOG_LINE, FORMAT, ##__VA_ARGS__); }while((void)0,0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Загрузка…
Ссылка в новой задаче