WIP. send a large constant string twice a second, in order to test out the transport with something indicative of our required load.

Dependencies:   FXOS8700CQ NTPClient azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Fork of FXOS8700CQ_To_Azure_IoT by Mark Radbourne

Committer:
markrad
Date:
Thu Dec 08 00:11:40 2016 +0000
Revision:
3:c0556ff7b8e3
Hack the code to get restart working

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 3:c0556ff7b8e3 1 // Copyright (c) Microsoft. All rights reserved.
markrad 3:c0556ff7b8e3 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
markrad 3:c0556ff7b8e3 3
markrad 3:c0556ff7b8e3 4 #include <stdlib.h>
markrad 3:c0556ff7b8e3 5 #ifdef _CRTDBG_MAP_ALLOC
markrad 3:c0556ff7b8e3 6 #include <crtdbg.h>
markrad 3:c0556ff7b8e3 7 #endif
markrad 3:c0556ff7b8e3 8 #include <string.h>
markrad 3:c0556ff7b8e3 9 #include "azure_c_shared_utility/gballoc.h"
markrad 3:c0556ff7b8e3 10 #include "azure_c_shared_utility/string_tokenizer.h"
markrad 3:c0556ff7b8e3 11 #include "azure_c_shared_utility/doublylinkedlist.h"
markrad 3:c0556ff7b8e3 12 #include "azure_c_shared_utility/xlogging.h"
markrad 3:c0556ff7b8e3 13 #include "azure_c_shared_utility/tickcounter.h"
markrad 3:c0556ff7b8e3 14 #include "azure_c_shared_utility/constbuffer.h"
markrad 3:c0556ff7b8e3 15
markrad 3:c0556ff7b8e3 16 #include "iothub_client_ll.h"
markrad 3:c0556ff7b8e3 17 #include "iothub_client_private.h"
markrad 3:c0556ff7b8e3 18 #include "iothub_client_version.h"
markrad 3:c0556ff7b8e3 19 #include "iothub_transport_ll.h"
markrad 3:c0556ff7b8e3 20 #include <stdint.h>
markrad 3:c0556ff7b8e3 21
markrad 3:c0556ff7b8e3 22 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 23 #include "iothub_client_ll_uploadtoblob.h"
markrad 3:c0556ff7b8e3 24 #endif
markrad 3:c0556ff7b8e3 25
markrad 3:c0556ff7b8e3 26 #define LOG_ERROR_RESULT LogError("result = %s", ENUM_TO_STRING(IOTHUB_CLIENT_RESULT, result));
markrad 3:c0556ff7b8e3 27 #define INDEFINITE_TIME ((time_t)(-1))
markrad 3:c0556ff7b8e3 28
markrad 3:c0556ff7b8e3 29 DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_RESULT, IOTHUB_CLIENT_RESULT_VALUES);
markrad 3:c0556ff7b8e3 30 DEFINE_ENUM_STRINGS(IOTHUB_CLIENT_CONFIRMATION_RESULT, IOTHUB_CLIENT_CONFIRMATION_RESULT_VALUES);
markrad 3:c0556ff7b8e3 31
markrad 3:c0556ff7b8e3 32 typedef struct IOTHUB_CLIENT_LL_HANDLE_DATA_TAG
markrad 3:c0556ff7b8e3 33 {
markrad 3:c0556ff7b8e3 34 DLIST_ENTRY waitingToSend;
markrad 3:c0556ff7b8e3 35 DLIST_ENTRY iot_msg_queue;
markrad 3:c0556ff7b8e3 36 DLIST_ENTRY iot_ack_queue;
markrad 3:c0556ff7b8e3 37 TRANSPORT_LL_HANDLE transportHandle;
markrad 3:c0556ff7b8e3 38 bool isSharedTransport;
markrad 3:c0556ff7b8e3 39 IOTHUB_DEVICE_HANDLE deviceHandle;
markrad 3:c0556ff7b8e3 40 TRANSPORT_PROVIDER_FIELDS;
markrad 3:c0556ff7b8e3 41 IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback;
markrad 3:c0556ff7b8e3 42 void* messageUserContextCallback;
markrad 3:c0556ff7b8e3 43 IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK conStatusCallback;
markrad 3:c0556ff7b8e3 44 void* conStatusUserContextCallback;
markrad 3:c0556ff7b8e3 45 time_t lastMessageReceiveTime;
markrad 3:c0556ff7b8e3 46 TICK_COUNTER_HANDLE tickCounter; /*shared tickcounter used to track message timeouts in waitingToSend list*/
markrad 3:c0556ff7b8e3 47 uint64_t currentMessageTimeout;
markrad 3:c0556ff7b8e3 48 uint64_t current_device_twin_timeout;
markrad 3:c0556ff7b8e3 49 IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback;
markrad 3:c0556ff7b8e3 50 void* deviceTwinContextCallback;
markrad 3:c0556ff7b8e3 51 IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback;
markrad 3:c0556ff7b8e3 52 void* deviceMethodUserContextCallback;
markrad 3:c0556ff7b8e3 53 IOTHUB_CLIENT_RETRY_POLICY retryPolicy;
markrad 3:c0556ff7b8e3 54 size_t retryTimeoutLimitInSeconds;
markrad 3:c0556ff7b8e3 55 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 56 IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE uploadToBlobHandle;
markrad 3:c0556ff7b8e3 57 #endif
markrad 3:c0556ff7b8e3 58 uint32_t data_msg_id;
markrad 3:c0556ff7b8e3 59 bool complete_twin_update_encountered;
markrad 3:c0556ff7b8e3 60 }IOTHUB_CLIENT_LL_HANDLE_DATA;
markrad 3:c0556ff7b8e3 61
markrad 3:c0556ff7b8e3 62 static const char HOSTNAME_TOKEN[] = "HostName";
markrad 3:c0556ff7b8e3 63 static const char DEVICEID_TOKEN[] = "DeviceId";
markrad 3:c0556ff7b8e3 64 static const char X509_TOKEN[] = "x509";
markrad 3:c0556ff7b8e3 65 static const char X509_TOKEN_ONLY_ACCEPTABLE_VALUE[] = "true";
markrad 3:c0556ff7b8e3 66 static const char DEVICEKEY_TOKEN[] = "SharedAccessKey";
markrad 3:c0556ff7b8e3 67 static const char DEVICESAS_TOKEN[] = "SharedAccessSignature";
markrad 3:c0556ff7b8e3 68 static const char PROTOCOL_GATEWAY_HOST[] = "GatewayHostName";
markrad 3:c0556ff7b8e3 69
markrad 3:c0556ff7b8e3 70 static void device_twin_data_destroy(IOTHUB_DEVICE_TWIN* client_item)
markrad 3:c0556ff7b8e3 71 {
markrad 3:c0556ff7b8e3 72 CONSTBUFFER_Destroy(client_item->report_data_handle);
markrad 3:c0556ff7b8e3 73 free(client_item);
markrad 3:c0556ff7b8e3 74 }
markrad 3:c0556ff7b8e3 75
markrad 3:c0556ff7b8e3 76 static uint32_t get_next_item_id(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData)
markrad 3:c0556ff7b8e3 77 {
markrad 3:c0556ff7b8e3 78 if (handleData->data_msg_id+1 >= UINT32_MAX)
markrad 3:c0556ff7b8e3 79 {
markrad 3:c0556ff7b8e3 80 handleData->data_msg_id = 1;
markrad 3:c0556ff7b8e3 81 }
markrad 3:c0556ff7b8e3 82 else
markrad 3:c0556ff7b8e3 83 {
markrad 3:c0556ff7b8e3 84 handleData->data_msg_id++;
markrad 3:c0556ff7b8e3 85 }
markrad 3:c0556ff7b8e3 86 return handleData->data_msg_id;
markrad 3:c0556ff7b8e3 87 }
markrad 3:c0556ff7b8e3 88
markrad 3:c0556ff7b8e3 89 static IOTHUB_DEVICE_TWIN* dev_twin_data_create(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData, uint32_t id, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 90 {
markrad 3:c0556ff7b8e3 91 IOTHUB_DEVICE_TWIN* result = (IOTHUB_DEVICE_TWIN*)malloc(sizeof(IOTHUB_DEVICE_TWIN) );
markrad 3:c0556ff7b8e3 92 if (result != NULL)
markrad 3:c0556ff7b8e3 93 {
markrad 3:c0556ff7b8e3 94 result->report_data_handle = CONSTBUFFER_Create(reportedState, size);
markrad 3:c0556ff7b8e3 95 if (result->report_data_handle == NULL)
markrad 3:c0556ff7b8e3 96 {
markrad 3:c0556ff7b8e3 97 LogError("Failure allocating reported state data");
markrad 3:c0556ff7b8e3 98 free(result);
markrad 3:c0556ff7b8e3 99 result = NULL;
markrad 3:c0556ff7b8e3 100 }
markrad 3:c0556ff7b8e3 101 else if (tickcounter_get_current_ms(handleData->tickCounter, &result->ms_timesOutAfter) != 0)
markrad 3:c0556ff7b8e3 102 {
markrad 3:c0556ff7b8e3 103 LogError("Failure getting tickcount info");
markrad 3:c0556ff7b8e3 104 CONSTBUFFER_Destroy(result->report_data_handle);
markrad 3:c0556ff7b8e3 105 free(result);
markrad 3:c0556ff7b8e3 106 result = NULL;
markrad 3:c0556ff7b8e3 107 }
markrad 3:c0556ff7b8e3 108 else
markrad 3:c0556ff7b8e3 109 {
markrad 3:c0556ff7b8e3 110 result->item_id = id;
markrad 3:c0556ff7b8e3 111 result->ms_timesOutAfter = 0;
markrad 3:c0556ff7b8e3 112 result->context = userContextCallback;
markrad 3:c0556ff7b8e3 113 result->reported_state_callback = reportedStateCallback;
markrad 3:c0556ff7b8e3 114 }
markrad 3:c0556ff7b8e3 115 }
markrad 3:c0556ff7b8e3 116 else
markrad 3:c0556ff7b8e3 117 {
markrad 3:c0556ff7b8e3 118 LogError("Failure allocating device twin information");
markrad 3:c0556ff7b8e3 119 }
markrad 3:c0556ff7b8e3 120 return result;
markrad 3:c0556ff7b8e3 121 }
markrad 3:c0556ff7b8e3 122
markrad 3:c0556ff7b8e3 123 IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
markrad 3:c0556ff7b8e3 124 {
markrad 3:c0556ff7b8e3 125 IOTHUB_CLIENT_LL_HANDLE result;
markrad 3:c0556ff7b8e3 126
markrad 3:c0556ff7b8e3 127 /*Codes_SRS_IOTHUBCLIENT_LL_05_001: [IoTHubClient_LL_CreateFromConnectionString shall obtain the version string by a call to IoTHubClient_GetVersionString.]*/
markrad 3:c0556ff7b8e3 128 /*Codes_SRS_IOTHUBCLIENT_LL_05_002: [IoTHubClient_LL_CreateFromConnectionString shall print the version string to standard output.]*/
markrad 3:c0556ff7b8e3 129 LogInfo("IoT Hub SDK for C, version %s", IoTHubClient_GetVersionString());
markrad 3:c0556ff7b8e3 130
markrad 3:c0556ff7b8e3 131 /* Codes_SRS_IOTHUBCLIENT_LL_12_003: [IoTHubClient_LL_CreateFromConnectionString shall verify the input parameter and if it is NULL then return NULL] */
markrad 3:c0556ff7b8e3 132 if (connectionString == NULL)
markrad 3:c0556ff7b8e3 133 {
markrad 3:c0556ff7b8e3 134 LogError("Input parameter is NULL: connectionString");
markrad 3:c0556ff7b8e3 135 result = NULL;
markrad 3:c0556ff7b8e3 136 }
markrad 3:c0556ff7b8e3 137 else if (protocol == NULL)
markrad 3:c0556ff7b8e3 138 {
markrad 3:c0556ff7b8e3 139 LogError("Input parameter is NULL: protocol");
markrad 3:c0556ff7b8e3 140 result = NULL;
markrad 3:c0556ff7b8e3 141 }
markrad 3:c0556ff7b8e3 142 else
markrad 3:c0556ff7b8e3 143 {
markrad 3:c0556ff7b8e3 144 /* Codes_SRS_IOTHUBCLIENT_LL_12_004: [IoTHubClient_LL_CreateFromConnectionString shall allocate IOTHUB_CLIENT_CONFIG structure] */
markrad 3:c0556ff7b8e3 145 IOTHUB_CLIENT_CONFIG* config = (IOTHUB_CLIENT_CONFIG*) malloc(sizeof(IOTHUB_CLIENT_CONFIG));
markrad 3:c0556ff7b8e3 146 if (config == NULL)
markrad 3:c0556ff7b8e3 147 {
markrad 3:c0556ff7b8e3 148 /* Codes_SRS_IOTHUBCLIENT_LL_12_012: [If the allocation failed IoTHubClient_LL_CreateFromConnectionString returns NULL] */
markrad 3:c0556ff7b8e3 149 LogError("Malloc failed");
markrad 3:c0556ff7b8e3 150 result = NULL;
markrad 3:c0556ff7b8e3 151 }
markrad 3:c0556ff7b8e3 152 else
markrad 3:c0556ff7b8e3 153 {
markrad 3:c0556ff7b8e3 154 STRING_TOKENIZER_HANDLE tokenizer1 = NULL;
markrad 3:c0556ff7b8e3 155 STRING_HANDLE connString = NULL;
markrad 3:c0556ff7b8e3 156 STRING_HANDLE tokenString = NULL;
markrad 3:c0556ff7b8e3 157 STRING_HANDLE valueString = NULL;
markrad 3:c0556ff7b8e3 158 STRING_HANDLE hostNameString = NULL;
markrad 3:c0556ff7b8e3 159 STRING_HANDLE hostSuffixString = NULL;
markrad 3:c0556ff7b8e3 160 STRING_HANDLE deviceIdString = NULL;
markrad 3:c0556ff7b8e3 161 STRING_HANDLE deviceKeyString = NULL;
markrad 3:c0556ff7b8e3 162 STRING_HANDLE deviceSasTokenString = NULL;
markrad 3:c0556ff7b8e3 163 STRING_HANDLE protocolGateway = NULL;
markrad 3:c0556ff7b8e3 164
markrad 3:c0556ff7b8e3 165 config->protocol = protocol;
markrad 3:c0556ff7b8e3 166
markrad 3:c0556ff7b8e3 167 config->iotHubName = NULL;
markrad 3:c0556ff7b8e3 168 config->iotHubSuffix = NULL;
markrad 3:c0556ff7b8e3 169 config->deviceId = NULL;
markrad 3:c0556ff7b8e3 170 config->deviceKey = NULL;
markrad 3:c0556ff7b8e3 171 config->deviceSasToken = NULL;
markrad 3:c0556ff7b8e3 172
markrad 3:c0556ff7b8e3 173 /* Codes_SRS_IOTHUBCLIENT_LL_04_002: [If it does not, it shall pass the protocolGatewayHostName NULL.] */
markrad 3:c0556ff7b8e3 174 config->protocolGatewayHostName = NULL;
markrad 3:c0556ff7b8e3 175
markrad 3:c0556ff7b8e3 176 if ((connString = STRING_construct(connectionString)) == NULL)
markrad 3:c0556ff7b8e3 177 {
markrad 3:c0556ff7b8e3 178 LogError("Error constructing connectiong String");
markrad 3:c0556ff7b8e3 179 result = NULL;
markrad 3:c0556ff7b8e3 180 }
markrad 3:c0556ff7b8e3 181 else if ((tokenizer1 = STRING_TOKENIZER_create(connString)) == NULL)
markrad 3:c0556ff7b8e3 182 {
markrad 3:c0556ff7b8e3 183 LogError("Error creating Tokenizer");
markrad 3:c0556ff7b8e3 184 result = NULL;
markrad 3:c0556ff7b8e3 185 }
markrad 3:c0556ff7b8e3 186 else if ((tokenString = STRING_new()) == NULL)
markrad 3:c0556ff7b8e3 187 {
markrad 3:c0556ff7b8e3 188 LogError("Error creating Token String");
markrad 3:c0556ff7b8e3 189 result = NULL;
markrad 3:c0556ff7b8e3 190 }
markrad 3:c0556ff7b8e3 191 else if ((valueString = STRING_new()) == NULL)
markrad 3:c0556ff7b8e3 192 {
markrad 3:c0556ff7b8e3 193 LogError("Error creating Value String");
markrad 3:c0556ff7b8e3 194 result = NULL;
markrad 3:c0556ff7b8e3 195 }
markrad 3:c0556ff7b8e3 196 else if ((hostNameString = STRING_new()) == NULL)
markrad 3:c0556ff7b8e3 197 {
markrad 3:c0556ff7b8e3 198 LogError("Error creating HostName String");
markrad 3:c0556ff7b8e3 199 result = NULL;
markrad 3:c0556ff7b8e3 200 }
markrad 3:c0556ff7b8e3 201 else if ((hostSuffixString = STRING_new()) == NULL)
markrad 3:c0556ff7b8e3 202 {
markrad 3:c0556ff7b8e3 203 LogError("Error creating HostSuffix String");
markrad 3:c0556ff7b8e3 204 result = NULL;
markrad 3:c0556ff7b8e3 205 }
markrad 3:c0556ff7b8e3 206 /* Codes_SRS_IOTHUBCLIENT_LL_12_005: [IoTHubClient_LL_CreateFromConnectionString shall try to parse the connectionString input parameter for the following structure: "Key1=value1;key2=value2;key3=value3..."] */
markrad 3:c0556ff7b8e3 207 /* Codes_SRS_IOTHUBCLIENT_LL_12_006: [IoTHubClient_LL_CreateFromConnectionString shall verify the existence of the following Key/Value pairs in the connection string: HostName, DeviceId, SharedAccessKey, SharedAccessSignature or x509] */
markrad 3:c0556ff7b8e3 208 else
markrad 3:c0556ff7b8e3 209 {
markrad 3:c0556ff7b8e3 210 int isx509found = 0;
markrad 3:c0556ff7b8e3 211 while ((STRING_TOKENIZER_get_next_token(tokenizer1, tokenString, "=") == 0))
markrad 3:c0556ff7b8e3 212 {
markrad 3:c0556ff7b8e3 213 if (STRING_TOKENIZER_get_next_token(tokenizer1, valueString, ";") != 0)
markrad 3:c0556ff7b8e3 214 {
markrad 3:c0556ff7b8e3 215 LogError("Tokenizer error");
markrad 3:c0556ff7b8e3 216 break;
markrad 3:c0556ff7b8e3 217 }
markrad 3:c0556ff7b8e3 218 else
markrad 3:c0556ff7b8e3 219 {
markrad 3:c0556ff7b8e3 220 if (tokenString != NULL)
markrad 3:c0556ff7b8e3 221 {
markrad 3:c0556ff7b8e3 222 /* Codes_SRS_IOTHUBCLIENT_LL_12_010: [IoTHubClient_LL_CreateFromConnectionString shall fill up the IOTHUB_CLIENT_CONFIG structure using the following mapping: iotHubName = Name, iotHubSuffix = Suffix, deviceId = DeviceId, deviceKey = SharedAccessKey or deviceSasToken = SharedAccessSignature] */
markrad 3:c0556ff7b8e3 223 const char* s_token = STRING_c_str(tokenString);
markrad 3:c0556ff7b8e3 224 if (strcmp(s_token, HOSTNAME_TOKEN) == 0)
markrad 3:c0556ff7b8e3 225 {
markrad 3:c0556ff7b8e3 226 /* Codes_SRS_IOTHUBCLIENT_LL_12_009: [IoTHubClient_LL_CreateFromConnectionString shall split the value of HostName to Name and Suffix using the first "." as a separator] */
markrad 3:c0556ff7b8e3 227 STRING_TOKENIZER_HANDLE tokenizer2 = NULL;
markrad 3:c0556ff7b8e3 228 if ((tokenizer2 = STRING_TOKENIZER_create(valueString)) == NULL)
markrad 3:c0556ff7b8e3 229 {
markrad 3:c0556ff7b8e3 230 LogError("Error creating Tokenizer");
markrad 3:c0556ff7b8e3 231 break;
markrad 3:c0556ff7b8e3 232 }
markrad 3:c0556ff7b8e3 233 else
markrad 3:c0556ff7b8e3 234 {
markrad 3:c0556ff7b8e3 235 /* Codes_SRS_IOTHUBCLIENT_LL_12_015: [If the string split failed, IoTHubClient_LL_CreateFromConnectionString returns NULL ] */
markrad 3:c0556ff7b8e3 236 if (STRING_TOKENIZER_get_next_token(tokenizer2, hostNameString, ".") != 0)
markrad 3:c0556ff7b8e3 237 {
markrad 3:c0556ff7b8e3 238 LogError("Tokenizer error");
markrad 3:c0556ff7b8e3 239 STRING_TOKENIZER_destroy(tokenizer2);
markrad 3:c0556ff7b8e3 240 break;
markrad 3:c0556ff7b8e3 241 }
markrad 3:c0556ff7b8e3 242 else
markrad 3:c0556ff7b8e3 243 {
markrad 3:c0556ff7b8e3 244 config->iotHubName = STRING_c_str(hostNameString);
markrad 3:c0556ff7b8e3 245 if (STRING_TOKENIZER_get_next_token(tokenizer2, hostSuffixString, ";") != 0)
markrad 3:c0556ff7b8e3 246 {
markrad 3:c0556ff7b8e3 247 LogError("Tokenizer error");
markrad 3:c0556ff7b8e3 248 STRING_TOKENIZER_destroy(tokenizer2);
markrad 3:c0556ff7b8e3 249 break;
markrad 3:c0556ff7b8e3 250 }
markrad 3:c0556ff7b8e3 251 else
markrad 3:c0556ff7b8e3 252 {
markrad 3:c0556ff7b8e3 253 config->iotHubSuffix = STRING_c_str(hostSuffixString);
markrad 3:c0556ff7b8e3 254 }
markrad 3:c0556ff7b8e3 255 }
markrad 3:c0556ff7b8e3 256 STRING_TOKENIZER_destroy(tokenizer2);
markrad 3:c0556ff7b8e3 257 }
markrad 3:c0556ff7b8e3 258 }
markrad 3:c0556ff7b8e3 259 else if (strcmp(s_token, DEVICEID_TOKEN) == 0)
markrad 3:c0556ff7b8e3 260 {
markrad 3:c0556ff7b8e3 261 deviceIdString = STRING_clone(valueString);
markrad 3:c0556ff7b8e3 262 if (deviceIdString != NULL)
markrad 3:c0556ff7b8e3 263 {
markrad 3:c0556ff7b8e3 264 config->deviceId = STRING_c_str(deviceIdString);
markrad 3:c0556ff7b8e3 265 }
markrad 3:c0556ff7b8e3 266 else
markrad 3:c0556ff7b8e3 267 {
markrad 3:c0556ff7b8e3 268 LogError("Failure cloning device id string");
markrad 3:c0556ff7b8e3 269 break;
markrad 3:c0556ff7b8e3 270 }
markrad 3:c0556ff7b8e3 271 }
markrad 3:c0556ff7b8e3 272 else if (strcmp(s_token, DEVICEKEY_TOKEN) == 0)
markrad 3:c0556ff7b8e3 273 {
markrad 3:c0556ff7b8e3 274 deviceKeyString = STRING_clone(valueString);
markrad 3:c0556ff7b8e3 275 if (deviceKeyString != NULL)
markrad 3:c0556ff7b8e3 276 {
markrad 3:c0556ff7b8e3 277 config->deviceKey = STRING_c_str(deviceKeyString);
markrad 3:c0556ff7b8e3 278 }
markrad 3:c0556ff7b8e3 279 else
markrad 3:c0556ff7b8e3 280 {
markrad 3:c0556ff7b8e3 281 LogError("Failure cloning device key string");
markrad 3:c0556ff7b8e3 282 break;
markrad 3:c0556ff7b8e3 283 }
markrad 3:c0556ff7b8e3 284 }
markrad 3:c0556ff7b8e3 285 else if (strcmp(s_token, DEVICESAS_TOKEN) == 0)
markrad 3:c0556ff7b8e3 286 {
markrad 3:c0556ff7b8e3 287 deviceSasTokenString = STRING_clone(valueString);
markrad 3:c0556ff7b8e3 288 if (deviceSasTokenString != NULL)
markrad 3:c0556ff7b8e3 289 {
markrad 3:c0556ff7b8e3 290 config->deviceSasToken = STRING_c_str(deviceSasTokenString);
markrad 3:c0556ff7b8e3 291 }
markrad 3:c0556ff7b8e3 292 else
markrad 3:c0556ff7b8e3 293 {
markrad 3:c0556ff7b8e3 294 LogError("Failure cloning device sasToken string");
markrad 3:c0556ff7b8e3 295 break;
markrad 3:c0556ff7b8e3 296 }
markrad 3:c0556ff7b8e3 297 }
markrad 3:c0556ff7b8e3 298 else if (strcmp(s_token, X509_TOKEN) == 0)
markrad 3:c0556ff7b8e3 299 {
markrad 3:c0556ff7b8e3 300 if (strcmp(STRING_c_str(valueString), X509_TOKEN_ONLY_ACCEPTABLE_VALUE) != 0)
markrad 3:c0556ff7b8e3 301 {
markrad 3:c0556ff7b8e3 302 LogError("x509 option has wrong value, the only acceptable one is \"true\"");
markrad 3:c0556ff7b8e3 303 break;
markrad 3:c0556ff7b8e3 304 }
markrad 3:c0556ff7b8e3 305 else
markrad 3:c0556ff7b8e3 306 {
markrad 3:c0556ff7b8e3 307 isx509found = 1;
markrad 3:c0556ff7b8e3 308 }
markrad 3:c0556ff7b8e3 309 }
markrad 3:c0556ff7b8e3 310 /* Codes_SRS_IOTHUBCLIENT_LL_04_001: [IoTHubClient_LL_CreateFromConnectionString shall verify the existence of key/value pair GatewayHostName. If it does exist it shall pass the value to IoTHubClient_LL_Create API.] */
markrad 3:c0556ff7b8e3 311 else if (strcmp(s_token, PROTOCOL_GATEWAY_HOST) == 0)
markrad 3:c0556ff7b8e3 312 {
markrad 3:c0556ff7b8e3 313 protocolGateway = STRING_clone(valueString);
markrad 3:c0556ff7b8e3 314 if (protocolGateway != NULL)
markrad 3:c0556ff7b8e3 315 {
markrad 3:c0556ff7b8e3 316 config->protocolGatewayHostName = STRING_c_str(protocolGateway);
markrad 3:c0556ff7b8e3 317 }
markrad 3:c0556ff7b8e3 318 else
markrad 3:c0556ff7b8e3 319 {
markrad 3:c0556ff7b8e3 320 LogError("Failure cloning protocol Gateway Name");
markrad 3:c0556ff7b8e3 321 break;
markrad 3:c0556ff7b8e3 322 }
markrad 3:c0556ff7b8e3 323 }
markrad 3:c0556ff7b8e3 324 }
markrad 3:c0556ff7b8e3 325 }
markrad 3:c0556ff7b8e3 326 }
markrad 3:c0556ff7b8e3 327 /* parsing is done - check the result */
markrad 3:c0556ff7b8e3 328 if (config->iotHubName == NULL)
markrad 3:c0556ff7b8e3 329 {
markrad 3:c0556ff7b8e3 330 LogError("iotHubName is not found");
markrad 3:c0556ff7b8e3 331 result = NULL;
markrad 3:c0556ff7b8e3 332 }
markrad 3:c0556ff7b8e3 333 else if (config->iotHubSuffix == NULL)
markrad 3:c0556ff7b8e3 334 {
markrad 3:c0556ff7b8e3 335 LogError("iotHubSuffix is not found");
markrad 3:c0556ff7b8e3 336 result = NULL;
markrad 3:c0556ff7b8e3 337 }
markrad 3:c0556ff7b8e3 338 else if (config->deviceId == NULL)
markrad 3:c0556ff7b8e3 339 {
markrad 3:c0556ff7b8e3 340 LogError("deviceId is not found");
markrad 3:c0556ff7b8e3 341 result = NULL;
markrad 3:c0556ff7b8e3 342 }
markrad 3:c0556ff7b8e3 343 else if (!(
markrad 3:c0556ff7b8e3 344 ((!isx509found) && (config->deviceSasToken == NULL) ^ (config->deviceKey == NULL)) ||
markrad 3:c0556ff7b8e3 345 ((isx509found) && (config->deviceSasToken == NULL) && (config->deviceKey == NULL))
markrad 3:c0556ff7b8e3 346 ))
markrad 3:c0556ff7b8e3 347 {
markrad 3:c0556ff7b8e3 348 LogError("invalid combination of x509, deviceSasToken and deviceKey");
markrad 3:c0556ff7b8e3 349 result = NULL;
markrad 3:c0556ff7b8e3 350 }
markrad 3:c0556ff7b8e3 351 else
markrad 3:c0556ff7b8e3 352 {
markrad 3:c0556ff7b8e3 353 /* Codes_SRS_IOTHUBCLIENT_LL_12_011: [IoTHubClient_LL_CreateFromConnectionString shall call into the IoTHubClient_LL_Create API with the current structure and returns with the return value of it] */
markrad 3:c0556ff7b8e3 354
markrad 3:c0556ff7b8e3 355 result = IoTHubClient_LL_Create(config);
markrad 3:c0556ff7b8e3 356 if (result == NULL)
markrad 3:c0556ff7b8e3 357 {
markrad 3:c0556ff7b8e3 358 LogError("IoTHubClient_LL_Create failed");
markrad 3:c0556ff7b8e3 359 }
markrad 3:c0556ff7b8e3 360 else
markrad 3:c0556ff7b8e3 361 {
markrad 3:c0556ff7b8e3 362 /*return as is*/
markrad 3:c0556ff7b8e3 363 }
markrad 3:c0556ff7b8e3 364 }
markrad 3:c0556ff7b8e3 365 }
markrad 3:c0556ff7b8e3 366 if (deviceSasTokenString != NULL)
markrad 3:c0556ff7b8e3 367 STRING_delete(deviceSasTokenString);
markrad 3:c0556ff7b8e3 368 if (deviceKeyString != NULL)
markrad 3:c0556ff7b8e3 369 STRING_delete(deviceKeyString);
markrad 3:c0556ff7b8e3 370 if (deviceIdString != NULL)
markrad 3:c0556ff7b8e3 371 STRING_delete(deviceIdString);
markrad 3:c0556ff7b8e3 372 if (hostSuffixString != NULL)
markrad 3:c0556ff7b8e3 373 STRING_delete(hostSuffixString);
markrad 3:c0556ff7b8e3 374 if (hostNameString != NULL)
markrad 3:c0556ff7b8e3 375 STRING_delete(hostNameString);
markrad 3:c0556ff7b8e3 376 if (valueString != NULL)
markrad 3:c0556ff7b8e3 377 STRING_delete(valueString);
markrad 3:c0556ff7b8e3 378 if (tokenString != NULL)
markrad 3:c0556ff7b8e3 379 STRING_delete(tokenString);
markrad 3:c0556ff7b8e3 380 if (connString != NULL)
markrad 3:c0556ff7b8e3 381 STRING_delete(connString);
markrad 3:c0556ff7b8e3 382 if (protocolGateway != NULL)
markrad 3:c0556ff7b8e3 383 STRING_delete(protocolGateway);
markrad 3:c0556ff7b8e3 384
markrad 3:c0556ff7b8e3 385 if (tokenizer1 != NULL)
markrad 3:c0556ff7b8e3 386 STRING_TOKENIZER_destroy(tokenizer1);
markrad 3:c0556ff7b8e3 387
markrad 3:c0556ff7b8e3 388 free(config);
markrad 3:c0556ff7b8e3 389 }
markrad 3:c0556ff7b8e3 390 }
markrad 3:c0556ff7b8e3 391 return result;
markrad 3:c0556ff7b8e3 392 }
markrad 3:c0556ff7b8e3 393
markrad 3:c0556ff7b8e3 394 static void setTransportProtocol(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData, TRANSPORT_PROVIDER* protocol)
markrad 3:c0556ff7b8e3 395 {
markrad 3:c0556ff7b8e3 396 handleData->IoTHubTransport_GetHostname = protocol->IoTHubTransport_GetHostname;
markrad 3:c0556ff7b8e3 397 handleData->IoTHubTransport_SetOption = protocol->IoTHubTransport_SetOption;
markrad 3:c0556ff7b8e3 398 handleData->IoTHubTransport_Create = protocol->IoTHubTransport_Create;
markrad 3:c0556ff7b8e3 399 handleData->IoTHubTransport_Destroy = protocol->IoTHubTransport_Destroy;
markrad 3:c0556ff7b8e3 400 handleData->IoTHubTransport_Register = protocol->IoTHubTransport_Register;
markrad 3:c0556ff7b8e3 401 handleData->IoTHubTransport_Unregister = protocol->IoTHubTransport_Unregister;
markrad 3:c0556ff7b8e3 402 handleData->IoTHubTransport_Subscribe = protocol->IoTHubTransport_Subscribe;
markrad 3:c0556ff7b8e3 403 handleData->IoTHubTransport_Unsubscribe = protocol->IoTHubTransport_Unsubscribe;
markrad 3:c0556ff7b8e3 404 handleData->IoTHubTransport_DoWork = protocol->IoTHubTransport_DoWork;
markrad 3:c0556ff7b8e3 405 handleData->IoTHubTransport_SetRetryPolicy = protocol->IoTHubTransport_SetRetryPolicy;
markrad 3:c0556ff7b8e3 406 handleData->IoTHubTransport_GetSendStatus = protocol->IoTHubTransport_GetSendStatus;
markrad 3:c0556ff7b8e3 407 handleData->IoTHubTransport_ProcessItem = protocol->IoTHubTransport_ProcessItem;
markrad 3:c0556ff7b8e3 408 handleData->IoTHubTransport_Subscribe_DeviceTwin = protocol->IoTHubTransport_Subscribe_DeviceTwin;
markrad 3:c0556ff7b8e3 409 handleData->IoTHubTransport_Unsubscribe_DeviceTwin = protocol->IoTHubTransport_Unsubscribe_DeviceTwin;
markrad 3:c0556ff7b8e3 410 handleData->IoTHubTransport_Subscribe_DeviceMethod = protocol->IoTHubTransport_Subscribe_DeviceMethod;
markrad 3:c0556ff7b8e3 411 handleData->IoTHubTransport_Unsubscribe_DeviceMethod = protocol->IoTHubTransport_Unsubscribe_DeviceMethod;
markrad 3:c0556ff7b8e3 412 }
markrad 3:c0556ff7b8e3 413
markrad 3:c0556ff7b8e3 414 IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_Create(const IOTHUB_CLIENT_CONFIG* config)
markrad 3:c0556ff7b8e3 415 {
markrad 3:c0556ff7b8e3 416 IOTHUB_CLIENT_LL_HANDLE result;
markrad 3:c0556ff7b8e3 417 /*Codes_SRS_IOTHUBCLIENT_LL_02_001: [IoTHubClient_LL_Create shall return NULL if config parameter is NULL or protocol field is NULL.]*/
markrad 3:c0556ff7b8e3 418 if(
markrad 3:c0556ff7b8e3 419 (config == NULL) ||
markrad 3:c0556ff7b8e3 420 (config->protocol == NULL)
markrad 3:c0556ff7b8e3 421 )
markrad 3:c0556ff7b8e3 422 {
markrad 3:c0556ff7b8e3 423 result = NULL;
markrad 3:c0556ff7b8e3 424 LogError("invalid configuration (NULL detected)");
markrad 3:c0556ff7b8e3 425 }
markrad 3:c0556ff7b8e3 426 else
markrad 3:c0556ff7b8e3 427 {
markrad 3:c0556ff7b8e3 428 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
markrad 3:c0556ff7b8e3 429 if (handleData == NULL)
markrad 3:c0556ff7b8e3 430 {
markrad 3:c0556ff7b8e3 431 LogError("malloc failed");
markrad 3:c0556ff7b8e3 432 result = NULL;
markrad 3:c0556ff7b8e3 433 }
markrad 3:c0556ff7b8e3 434 else
markrad 3:c0556ff7b8e3 435 {
markrad 3:c0556ff7b8e3 436 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 437 /*Codes_SRS_IOTHUBCLIENT_LL_02_094: [ IoTHubClient_LL_Create shall create a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE from IOTHUB_CLIENT_CONFIG. ]*/
markrad 3:c0556ff7b8e3 438 /*Codes_SRS_IOTHUBCLIENT_LL_02_092: [ IoTHubClient_LL_CreateFromConnectionString shall create a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE from IOTHUB_CLIENT_CONFIG. ]*/
markrad 3:c0556ff7b8e3 439 handleData->uploadToBlobHandle = IoTHubClient_LL_UploadToBlob_Create(config);
markrad 3:c0556ff7b8e3 440 if (handleData->uploadToBlobHandle == NULL)
markrad 3:c0556ff7b8e3 441 {
markrad 3:c0556ff7b8e3 442 /*Codes_SRS_IOTHUBCLIENT_LL_02_093: [ If creating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateFromConnectionString shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 443 /*Codes_SRS_IOTHUBCLIENT_LL_02_095: [ If creating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_Create shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 444 LogError("unable to IoTHubClient_LL_UploadToBlob_Create");
markrad 3:c0556ff7b8e3 445 free(handleData);
markrad 3:c0556ff7b8e3 446 result = NULL;
markrad 3:c0556ff7b8e3 447 }
markrad 3:c0556ff7b8e3 448 else
markrad 3:c0556ff7b8e3 449 #endif
markrad 3:c0556ff7b8e3 450 {
markrad 3:c0556ff7b8e3 451 /*Codes_SRS_IOTHUBCLIENT_LL_02_045: [ Otherwise IoTHubClient_LL_Create shall create a new TICK_COUNTER_HANDLE ]*/
markrad 3:c0556ff7b8e3 452 if ((handleData->tickCounter = tickcounter_create()) == NULL)
markrad 3:c0556ff7b8e3 453 {
markrad 3:c0556ff7b8e3 454 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 455 /*Codes_SRS_IOTHUBCLIENT_LL_02_046: [ If creating the TICK_COUNTER_HANDLE fails then IoTHubClient_LL_Create shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 456 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 457 #endif
markrad 3:c0556ff7b8e3 458 LogError("unable to get a tickcounter");
markrad 3:c0556ff7b8e3 459 free(handleData);
markrad 3:c0556ff7b8e3 460 result = NULL;
markrad 3:c0556ff7b8e3 461 }
markrad 3:c0556ff7b8e3 462 else
markrad 3:c0556ff7b8e3 463 {
markrad 3:c0556ff7b8e3 464 /*Codes_SRS_IOTHUBCLIENT_LL_02_004: [Otherwise IoTHubClient_LL_Create shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
markrad 3:c0556ff7b8e3 465 IOTHUBTRANSPORT_CONFIG lowerLayerConfig;
markrad 3:c0556ff7b8e3 466 DList_InitializeListHead(&(handleData->waitingToSend));
markrad 3:c0556ff7b8e3 467 DList_InitializeListHead(&(handleData->iot_msg_queue));
markrad 3:c0556ff7b8e3 468 DList_InitializeListHead(&(handleData->iot_ack_queue));
markrad 3:c0556ff7b8e3 469 setTransportProtocol(handleData, (TRANSPORT_PROVIDER*)config->protocol());
markrad 3:c0556ff7b8e3 470 handleData->messageCallback = NULL;
markrad 3:c0556ff7b8e3 471 handleData->messageUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 472 handleData->deviceTwinCallback = NULL;
markrad 3:c0556ff7b8e3 473 handleData->deviceTwinContextCallback = NULL;
markrad 3:c0556ff7b8e3 474 handleData->deviceMethodCallback = NULL;
markrad 3:c0556ff7b8e3 475 handleData->deviceMethodUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 476 handleData->lastMessageReceiveTime = INDEFINITE_TIME;
markrad 3:c0556ff7b8e3 477 handleData->data_msg_id = 1;
markrad 3:c0556ff7b8e3 478 handleData->complete_twin_update_encountered = false;
markrad 3:c0556ff7b8e3 479 handleData->conStatusCallback = NULL;
markrad 3:c0556ff7b8e3 480 handleData->conStatusUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 481 handleData->lastMessageReceiveTime = INDEFINITE_TIME;
markrad 3:c0556ff7b8e3 482
markrad 3:c0556ff7b8e3 483 /*Codes_SRS_IOTHUBCLIENT_LL_02_006: [IoTHubClient_LL_Create shall populate a structure of type IOTHUBTRANSPORT_CONFIG with the information from config parameter and the previous DLIST and shall pass that to the underlying layer _Create function.]*/
markrad 3:c0556ff7b8e3 484 lowerLayerConfig.upperConfig = config;
markrad 3:c0556ff7b8e3 485 lowerLayerConfig.waitingToSend = &(handleData->waitingToSend);
markrad 3:c0556ff7b8e3 486 /*Codes_SRS_IOTHUBCLIENT_LL_02_007: [If the underlaying layer _Create function fails them IoTHubClient_LL_Create shall fail and return NULL.] */
markrad 3:c0556ff7b8e3 487 if ((handleData->transportHandle = handleData->IoTHubTransport_Create(&lowerLayerConfig)) == NULL)
markrad 3:c0556ff7b8e3 488 {
markrad 3:c0556ff7b8e3 489 LogError("underlying transport failed");
markrad 3:c0556ff7b8e3 490 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 491 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 492 #endif
markrad 3:c0556ff7b8e3 493 tickcounter_destroy(handleData->tickCounter);
markrad 3:c0556ff7b8e3 494 free(handleData);
markrad 3:c0556ff7b8e3 495 result = NULL;
markrad 3:c0556ff7b8e3 496 }
markrad 3:c0556ff7b8e3 497 else
markrad 3:c0556ff7b8e3 498 {
markrad 3:c0556ff7b8e3 499 IOTHUB_DEVICE_CONFIG deviceConfig;
markrad 3:c0556ff7b8e3 500
markrad 3:c0556ff7b8e3 501 deviceConfig.deviceId = config->deviceId;
markrad 3:c0556ff7b8e3 502 deviceConfig.deviceKey = config->deviceKey;
markrad 3:c0556ff7b8e3 503 deviceConfig.deviceSasToken = config->deviceSasToken;
markrad 3:c0556ff7b8e3 504
markrad 3:c0556ff7b8e3 505 /*Codes_SRS_IOTHUBCLIENT_LL_17_008: [IoTHubClient_LL_Create shall call the transport _Register function with a populated structure of type IOTHUB_DEVICE_CONFIG and waitingToSend list.] */
markrad 3:c0556ff7b8e3 506 if ((handleData->deviceHandle = handleData->IoTHubTransport_Register(handleData->transportHandle, &deviceConfig, handleData, &(handleData->waitingToSend))) == NULL)
markrad 3:c0556ff7b8e3 507 {
markrad 3:c0556ff7b8e3 508 /*Codes_SRS_IOTHUBCLIENT_LL_17_009: [If the _Register function fails, this function shall fail and return NULL.]*/
markrad 3:c0556ff7b8e3 509 LogError("Registering device in transport failed");
markrad 3:c0556ff7b8e3 510 handleData->IoTHubTransport_Destroy(handleData->transportHandle);
markrad 3:c0556ff7b8e3 511 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 512 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 513 #endif
markrad 3:c0556ff7b8e3 514 tickcounter_destroy(handleData->tickCounter);
markrad 3:c0556ff7b8e3 515 free(handleData);
markrad 3:c0556ff7b8e3 516 result = NULL;
markrad 3:c0556ff7b8e3 517 }
markrad 3:c0556ff7b8e3 518 else
markrad 3:c0556ff7b8e3 519 {
markrad 3:c0556ff7b8e3 520 /*Codes_SRS_IOTHUBCLIENT_LL_02_008: [Otherwise, IoTHubClient_LL_Create shall succeed and return a non-NULL handle.] */
markrad 3:c0556ff7b8e3 521 handleData->isSharedTransport = false;
markrad 3:c0556ff7b8e3 522 /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
markrad 3:c0556ff7b8e3 523 handleData->currentMessageTimeout = 0;
markrad 3:c0556ff7b8e3 524 handleData->current_device_twin_timeout = 0;
markrad 3:c0556ff7b8e3 525 result = handleData;
markrad 3:c0556ff7b8e3 526 /*Codes_SRS_IOTHUBCLIENT_LL_25_124: [ `IoTHubClient_LL_Create` shall set the default retry policy as Exponential backoff with jitter and if succeed and return a `non-NULL` handle. ]*/
markrad 3:c0556ff7b8e3 527 if (IoTHubClient_LL_SetRetryPolicy(handleData, IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, 0) != IOTHUB_CLIENT_OK)
markrad 3:c0556ff7b8e3 528 {
markrad 3:c0556ff7b8e3 529 LogError("Setting default retry policy in transport failed");
markrad 3:c0556ff7b8e3 530 IoTHubClient_LL_Destroy(handleData);
markrad 3:c0556ff7b8e3 531 result = NULL;
markrad 3:c0556ff7b8e3 532 }
markrad 3:c0556ff7b8e3 533 }
markrad 3:c0556ff7b8e3 534 }
markrad 3:c0556ff7b8e3 535 }
markrad 3:c0556ff7b8e3 536 }
markrad 3:c0556ff7b8e3 537 }
markrad 3:c0556ff7b8e3 538 }
markrad 3:c0556ff7b8e3 539
markrad 3:c0556ff7b8e3 540 return result;
markrad 3:c0556ff7b8e3 541 }
markrad 3:c0556ff7b8e3 542
markrad 3:c0556ff7b8e3 543 IOTHUB_CLIENT_LL_HANDLE IoTHubClient_LL_CreateWithTransport(const IOTHUB_CLIENT_DEVICE_CONFIG * config)
markrad 3:c0556ff7b8e3 544 {
markrad 3:c0556ff7b8e3 545 IOTHUB_CLIENT_LL_HANDLE result;
markrad 3:c0556ff7b8e3 546 /*Codes_SRS_IOTHUBCLIENT_LL_17_001: [IoTHubClient_LL_CreateWithTransport shall return NULL if config parameter is NULL, or protocol field is NULL or transportHandle is NULL.]*/
markrad 3:c0556ff7b8e3 547 if (
markrad 3:c0556ff7b8e3 548 (config == NULL) ||
markrad 3:c0556ff7b8e3 549 (config->protocol == NULL) ||
markrad 3:c0556ff7b8e3 550 (config->transportHandle == NULL) ||
markrad 3:c0556ff7b8e3 551 /*Codes_SRS_IOTHUBCLIENT_LL_02_098: [ IoTHubClient_LL_CreateWithTransport shall fail and return NULL if both config->deviceKey AND config->deviceSasToken are NULL. ]*/
markrad 3:c0556ff7b8e3 552 ((config->deviceKey == NULL) && (config->deviceSasToken == NULL))
markrad 3:c0556ff7b8e3 553 )
markrad 3:c0556ff7b8e3 554 {
markrad 3:c0556ff7b8e3 555 result = NULL;
markrad 3:c0556ff7b8e3 556 LogError("invalid configuration (NULL detected)");
markrad 3:c0556ff7b8e3 557 }
markrad 3:c0556ff7b8e3 558 else
markrad 3:c0556ff7b8e3 559 {
markrad 3:c0556ff7b8e3 560 /*Codes_SRS_IOTHUBCLIENT_LL_17_002: [IoTHubClient_LL_CreateWithTransport shall allocate data for the IOTHUB_CLIENT_LL_HANDLE.]*/
markrad 3:c0556ff7b8e3 561 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)malloc(sizeof(IOTHUB_CLIENT_LL_HANDLE_DATA));
markrad 3:c0556ff7b8e3 562 if (handleData == NULL)
markrad 3:c0556ff7b8e3 563 {
markrad 3:c0556ff7b8e3 564 /*Codes_SRS_IOTHUBCLIENT_LL_17_003: [If allocation fails, the function shall fail and return NULL.] */
markrad 3:c0556ff7b8e3 565 LogError("malloc failed");
markrad 3:c0556ff7b8e3 566 result = NULL;
markrad 3:c0556ff7b8e3 567 }
markrad 3:c0556ff7b8e3 568 else
markrad 3:c0556ff7b8e3 569 {
markrad 3:c0556ff7b8e3 570 handleData->transportHandle = config->transportHandle;
markrad 3:c0556ff7b8e3 571 setTransportProtocol(handleData, (TRANSPORT_PROVIDER*)config->protocol());
markrad 3:c0556ff7b8e3 572
markrad 3:c0556ff7b8e3 573 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 574 const char* hostname = STRING_c_str(handleData->IoTHubTransport_GetHostname(handleData->transportHandle));
markrad 3:c0556ff7b8e3 575 /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
markrad 3:c0556ff7b8e3 576 /*the first '.' says where the iothubname finishes*/
markrad 3:c0556ff7b8e3 577 const char* whereIsDot = strchr(hostname, '.');
markrad 3:c0556ff7b8e3 578 if (whereIsDot == NULL)
markrad 3:c0556ff7b8e3 579 {
markrad 3:c0556ff7b8e3 580 /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 581 LogError("unable to determine the IoTHub name");
markrad 3:c0556ff7b8e3 582 free(handleData);
markrad 3:c0556ff7b8e3 583 result = NULL;
markrad 3:c0556ff7b8e3 584 }
markrad 3:c0556ff7b8e3 585 else
markrad 3:c0556ff7b8e3 586 {
markrad 3:c0556ff7b8e3 587 /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
markrad 3:c0556ff7b8e3 588 char* IoTHubName = (char*) malloc(whereIsDot - hostname + 1);
markrad 3:c0556ff7b8e3 589 if (IoTHubName == NULL)
markrad 3:c0556ff7b8e3 590 {
markrad 3:c0556ff7b8e3 591 /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 592 LogError("unable to malloc");
markrad 3:c0556ff7b8e3 593 free(handleData);
markrad 3:c0556ff7b8e3 594 result = NULL;
markrad 3:c0556ff7b8e3 595 }
markrad 3:c0556ff7b8e3 596 else
markrad 3:c0556ff7b8e3 597 {
markrad 3:c0556ff7b8e3 598 const char* IotHubSuffix = whereIsDot + 1;
markrad 3:c0556ff7b8e3 599 memcpy(IoTHubName, hostname, whereIsDot - hostname);
markrad 3:c0556ff7b8e3 600 IoTHubName[whereIsDot - hostname ] = '\0';
markrad 3:c0556ff7b8e3 601
markrad 3:c0556ff7b8e3 602 IOTHUB_CLIENT_CONFIG temp;
markrad 3:c0556ff7b8e3 603 temp.deviceId = config->deviceId;
markrad 3:c0556ff7b8e3 604 temp.deviceKey = config->deviceKey;
markrad 3:c0556ff7b8e3 605 temp.deviceSasToken = config->deviceSasToken;
markrad 3:c0556ff7b8e3 606 temp.iotHubName = IoTHubName;
markrad 3:c0556ff7b8e3 607 temp.iotHubSuffix = IotHubSuffix;
markrad 3:c0556ff7b8e3 608 temp.protocol = NULL; /*irrelevant to IoTHubClient_LL_UploadToBlob*/
markrad 3:c0556ff7b8e3 609 temp.protocolGatewayHostName = NULL; /*irrelevant to IoTHubClient_LL_UploadToBlob*/
markrad 3:c0556ff7b8e3 610
markrad 3:c0556ff7b8e3 611 /*Codes_SRS_IOTHUBCLIENT_LL_02_097: [ If creating the data structures fails or instantiating the IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE fails then IoTHubClient_LL_CreateWithTransport shall fail and return NULL. ]*/
markrad 3:c0556ff7b8e3 612 handleData->uploadToBlobHandle = IoTHubClient_LL_UploadToBlob_Create(&temp);
markrad 3:c0556ff7b8e3 613 if (handleData->uploadToBlobHandle == NULL)
markrad 3:c0556ff7b8e3 614 {
markrad 3:c0556ff7b8e3 615 /*Codes_SRS_IOTHUBCLIENT_LL_02_096: [ IoTHubClient_LL_CreateWithTransport shall create the data structures needed to instantiate a IOTHUB_CLIENT_LL_UPLOADTOBLOB_HANDLE. ]*/
markrad 3:c0556ff7b8e3 616 LogError("unable to IoTHubClient_LL_UploadToBlob_Create");
markrad 3:c0556ff7b8e3 617 free(handleData);
markrad 3:c0556ff7b8e3 618 result = NULL;
markrad 3:c0556ff7b8e3 619 }
markrad 3:c0556ff7b8e3 620 else
markrad 3:c0556ff7b8e3 621 #endif
markrad 3:c0556ff7b8e3 622 {
markrad 3:c0556ff7b8e3 623 /*Codes_SRS_IOTHUBCLIENT_LL_02_047: [ IoTHubClient_LL_CreateWithTransport shall create a TICK_COUNTER_HANDLE. ]*/
markrad 3:c0556ff7b8e3 624 if ((handleData->tickCounter = tickcounter_create()) == NULL)
markrad 3:c0556ff7b8e3 625 {
markrad 3:c0556ff7b8e3 626 /*Codes_SRS_IOTHUBCLIENT_LL_02_048: [ If creating the handle fails, then IoTHubClient_LL_CreateWithTransport shall fail and return NULL ]*/
markrad 3:c0556ff7b8e3 627 LogError("unable to get a tickcounter");
markrad 3:c0556ff7b8e3 628 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 629 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 630 #endif
markrad 3:c0556ff7b8e3 631 free(handleData);
markrad 3:c0556ff7b8e3 632 result = NULL;
markrad 3:c0556ff7b8e3 633 }
markrad 3:c0556ff7b8e3 634 else
markrad 3:c0556ff7b8e3 635 {
markrad 3:c0556ff7b8e3 636 /*Codes_SRS_IOTHUBCLIENT_LL_17_004: [IoTHubClient_LL_CreateWithTransport shall initialize a new DLIST (further called "waitingToSend") containing records with fields of the following types: IOTHUB_MESSAGE_HANDLE, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK, void*.]*/
markrad 3:c0556ff7b8e3 637 DList_InitializeListHead(&(handleData->waitingToSend));
markrad 3:c0556ff7b8e3 638 DList_InitializeListHead(&(handleData->iot_msg_queue));
markrad 3:c0556ff7b8e3 639 DList_InitializeListHead(&(handleData->iot_ack_queue));
markrad 3:c0556ff7b8e3 640 handleData->messageCallback = NULL;
markrad 3:c0556ff7b8e3 641 handleData->messageUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 642 handleData->deviceTwinCallback = NULL;
markrad 3:c0556ff7b8e3 643 handleData->deviceTwinContextCallback = NULL;
markrad 3:c0556ff7b8e3 644 handleData->deviceMethodCallback = NULL;
markrad 3:c0556ff7b8e3 645 handleData->deviceMethodUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 646 handleData->lastMessageReceiveTime = INDEFINITE_TIME;
markrad 3:c0556ff7b8e3 647 handleData->data_msg_id = 1;
markrad 3:c0556ff7b8e3 648 handleData->complete_twin_update_encountered = false;
markrad 3:c0556ff7b8e3 649
markrad 3:c0556ff7b8e3 650 IOTHUB_DEVICE_CONFIG deviceConfig;
markrad 3:c0556ff7b8e3 651
markrad 3:c0556ff7b8e3 652 deviceConfig.deviceId = config->deviceId;
markrad 3:c0556ff7b8e3 653 deviceConfig.deviceKey = config->deviceKey;
markrad 3:c0556ff7b8e3 654 deviceConfig.deviceSasToken = config->deviceSasToken;
markrad 3:c0556ff7b8e3 655
markrad 3:c0556ff7b8e3 656 /*Codes_SRS_IOTHUBCLIENT_LL_17_006: [IoTHubClient_LL_CreateWithTransport shall call the transport _Register function with the IOTHUB_DEVICE_CONFIG populated structure and waitingToSend list.]*/
markrad 3:c0556ff7b8e3 657 if ((handleData->deviceHandle = handleData->IoTHubTransport_Register(config->transportHandle, &deviceConfig, handleData, &(handleData->waitingToSend))) == NULL)
markrad 3:c0556ff7b8e3 658 {
markrad 3:c0556ff7b8e3 659 /*Codes_SRS_IOTHUBCLIENT_LL_17_007: [If the _Register function fails, this function shall fail and return NULL.]*/
markrad 3:c0556ff7b8e3 660 LogError("Registering device in transport failed");
markrad 3:c0556ff7b8e3 661 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 662 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 663 #endif
markrad 3:c0556ff7b8e3 664 tickcounter_destroy(handleData->tickCounter);
markrad 3:c0556ff7b8e3 665 free(handleData);
markrad 3:c0556ff7b8e3 666 result = NULL;
markrad 3:c0556ff7b8e3 667 }
markrad 3:c0556ff7b8e3 668 else
markrad 3:c0556ff7b8e3 669 {
markrad 3:c0556ff7b8e3 670 /*Codes_SRS_IOTHUBCLIENT_LL_17_005: [IoTHubClient_LL_CreateWithTransport shall save the transport handle and mark this transport as shared.]*/
markrad 3:c0556ff7b8e3 671 handleData->isSharedTransport = true;
markrad 3:c0556ff7b8e3 672 /*Codes_SRS_IOTHUBCLIENT_LL_02_042: [ By default, messages shall not timeout. ]*/
markrad 3:c0556ff7b8e3 673 handleData->currentMessageTimeout = 0;
markrad 3:c0556ff7b8e3 674 handleData->current_device_twin_timeout = 0;
markrad 3:c0556ff7b8e3 675 result = handleData;
markrad 3:c0556ff7b8e3 676 /*Codes_SRS_IOTHUBCLIENT_LL_25_125: [ `IoTHubClient_LL_CreateWithTransport` shall set the default retry policy as Exponential backoff with jitter and if succeed and return a `non-NULL` handle. ]*/
markrad 3:c0556ff7b8e3 677 if (IoTHubClient_LL_SetRetryPolicy(handleData, IOTHUB_CLIENT_RETRY_EXPONENTIAL_BACKOFF_WITH_JITTER, 0) != IOTHUB_CLIENT_OK)
markrad 3:c0556ff7b8e3 678 {
markrad 3:c0556ff7b8e3 679 LogError("Setting default retry policy in transport failed");
markrad 3:c0556ff7b8e3 680 IoTHubClient_LL_Destroy(handleData);
markrad 3:c0556ff7b8e3 681 result = NULL;
markrad 3:c0556ff7b8e3 682 }
markrad 3:c0556ff7b8e3 683 }
markrad 3:c0556ff7b8e3 684 }
markrad 3:c0556ff7b8e3 685 }
markrad 3:c0556ff7b8e3 686 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 687 free(IoTHubName);
markrad 3:c0556ff7b8e3 688 }
markrad 3:c0556ff7b8e3 689 }
markrad 3:c0556ff7b8e3 690 #endif
markrad 3:c0556ff7b8e3 691 }
markrad 3:c0556ff7b8e3 692 }
markrad 3:c0556ff7b8e3 693
markrad 3:c0556ff7b8e3 694 return result;
markrad 3:c0556ff7b8e3 695 }
markrad 3:c0556ff7b8e3 696
markrad 3:c0556ff7b8e3 697 void IoTHubClient_LL_Destroy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
markrad 3:c0556ff7b8e3 698 {
markrad 3:c0556ff7b8e3 699 /*Codes_SRS_IOTHUBCLIENT_LL_02_009: [IoTHubClient_LL_Destroy shall do nothing if parameter iotHubClientHandle is NULL.]*/
markrad 3:c0556ff7b8e3 700 if (iotHubClientHandle != NULL)
markrad 3:c0556ff7b8e3 701 {
markrad 3:c0556ff7b8e3 702 PDLIST_ENTRY unsend;
markrad 3:c0556ff7b8e3 703 /*Codes_SRS_IOTHUBCLIENT_LL_17_010: [IoTHubClient_LL_Destroy shall call the underlaying layer's _Unregister function] */
markrad 3:c0556ff7b8e3 704 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 705 handleData->IoTHubTransport_Unregister(handleData->deviceHandle);
markrad 3:c0556ff7b8e3 706 if (handleData->isSharedTransport == false)
markrad 3:c0556ff7b8e3 707 {
markrad 3:c0556ff7b8e3 708 /*Codes_SRS_IOTHUBCLIENT_LL_02_010: [If iotHubClientHandle was not created by IoTHubClient_LL_CreateWithTransport, IoTHubClient_LL_Destroy shall call the underlaying layer's _Destroy function.] */
markrad 3:c0556ff7b8e3 709 handleData->IoTHubTransport_Destroy(handleData->transportHandle);
markrad 3:c0556ff7b8e3 710 }
markrad 3:c0556ff7b8e3 711 /*if any, remove the items currently not send*/
markrad 3:c0556ff7b8e3 712 while ((unsend = DList_RemoveHeadList(&(handleData->waitingToSend))) != &(handleData->waitingToSend))
markrad 3:c0556ff7b8e3 713 {
markrad 3:c0556ff7b8e3 714 IOTHUB_MESSAGE_LIST* temp = containingRecord(unsend, IOTHUB_MESSAGE_LIST, entry);
markrad 3:c0556ff7b8e3 715 /*Codes_SRS_IOTHUBCLIENT_LL_02_033: [Otherwise, IoTHubClient_LL_Destroy shall complete all the event message callbacks that are in the waitingToSend list with the result IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY.] */
markrad 3:c0556ff7b8e3 716 if (temp->callback != NULL)
markrad 3:c0556ff7b8e3 717 {
markrad 3:c0556ff7b8e3 718 temp->callback(IOTHUB_CLIENT_CONFIRMATION_BECAUSE_DESTROY, temp->context);
markrad 3:c0556ff7b8e3 719 }
markrad 3:c0556ff7b8e3 720 IoTHubMessage_Destroy(temp->messageHandle);
markrad 3:c0556ff7b8e3 721 free(temp);
markrad 3:c0556ff7b8e3 722 }
markrad 3:c0556ff7b8e3 723
markrad 3:c0556ff7b8e3 724 /* Codes_SRS_IOTHUBCLIENT_LL_07_007: [ IoTHubClient_LL_Destroy shall iterate the device twin queues and destroy any remaining items. ] */
markrad 3:c0556ff7b8e3 725 while ((unsend = DList_RemoveHeadList(&(handleData->iot_msg_queue))) != &(handleData->iot_msg_queue))
markrad 3:c0556ff7b8e3 726 {
markrad 3:c0556ff7b8e3 727 IOTHUB_DEVICE_TWIN* temp = containingRecord(unsend, IOTHUB_DEVICE_TWIN, entry);
markrad 3:c0556ff7b8e3 728 device_twin_data_destroy(temp);
markrad 3:c0556ff7b8e3 729 }
markrad 3:c0556ff7b8e3 730 while ((unsend = DList_RemoveHeadList(&(handleData->iot_ack_queue))) != &(handleData->iot_ack_queue))
markrad 3:c0556ff7b8e3 731 {
markrad 3:c0556ff7b8e3 732 IOTHUB_DEVICE_TWIN* temp = containingRecord(unsend, IOTHUB_DEVICE_TWIN, entry);
markrad 3:c0556ff7b8e3 733 device_twin_data_destroy(temp);
markrad 3:c0556ff7b8e3 734 }
markrad 3:c0556ff7b8e3 735
markrad 3:c0556ff7b8e3 736 /*Codes_SRS_IOTHUBCLIENT_LL_17_011: [IoTHubClient_LL_Destroy shall free the resources allocated by IoTHubClient (if any).] */
markrad 3:c0556ff7b8e3 737 tickcounter_destroy(handleData->tickCounter);
markrad 3:c0556ff7b8e3 738 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 739 IoTHubClient_LL_UploadToBlob_Destroy(handleData->uploadToBlobHandle);
markrad 3:c0556ff7b8e3 740 #endif
markrad 3:c0556ff7b8e3 741 free(handleData);
markrad 3:c0556ff7b8e3 742 }
markrad 3:c0556ff7b8e3 743 }
markrad 3:c0556ff7b8e3 744
markrad 3:c0556ff7b8e3 745 /*Codes_SRS_IOTHUBCLIENT_LL_02_044: [ Messages already delivered to IoTHubClient_LL shall not have their timeouts modified by a new call to IoTHubClient_LL_SetOption. ]*/
markrad 3:c0556ff7b8e3 746 /*returns 0 on success, any other value is error*/
markrad 3:c0556ff7b8e3 747 static int attach_ms_timesOutAfter(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData, IOTHUB_MESSAGE_LIST *newEntry)
markrad 3:c0556ff7b8e3 748 {
markrad 3:c0556ff7b8e3 749 int result;
markrad 3:c0556ff7b8e3 750 /*Codes_SRS_IOTHUBCLIENT_LL_02_043: [ Calling IoTHubClient_LL_SetOption with value set to "0" shall disable the timeout mechanism for all new messages. ]*/
markrad 3:c0556ff7b8e3 751 if (handleData->currentMessageTimeout == 0)
markrad 3:c0556ff7b8e3 752 {
markrad 3:c0556ff7b8e3 753 newEntry->ms_timesOutAfter = 0; /*do not timeout*/
markrad 3:c0556ff7b8e3 754 result = 0;
markrad 3:c0556ff7b8e3 755 }
markrad 3:c0556ff7b8e3 756 else
markrad 3:c0556ff7b8e3 757 {
markrad 3:c0556ff7b8e3 758 /*Codes_SRS_IOTHUBCLIENT_LL_02_039: [ "messageTimeout" - once IoTHubClient_LL_SendEventAsync is called the message shall timeout after value miliseconds. Value is a pointer to a uint64. ]*/
markrad 3:c0556ff7b8e3 759 if (tickcounter_get_current_ms(handleData->tickCounter, &newEntry->ms_timesOutAfter) != 0)
markrad 3:c0556ff7b8e3 760 {
markrad 3:c0556ff7b8e3 761 result = __LINE__;
markrad 3:c0556ff7b8e3 762 LogError("unable to get the current relative tickcount");
markrad 3:c0556ff7b8e3 763 }
markrad 3:c0556ff7b8e3 764 else
markrad 3:c0556ff7b8e3 765 {
markrad 3:c0556ff7b8e3 766 newEntry->ms_timesOutAfter += handleData->currentMessageTimeout;
markrad 3:c0556ff7b8e3 767 result = 0;
markrad 3:c0556ff7b8e3 768 }
markrad 3:c0556ff7b8e3 769 }
markrad 3:c0556ff7b8e3 770 return result;
markrad 3:c0556ff7b8e3 771 }
markrad 3:c0556ff7b8e3 772
markrad 3:c0556ff7b8e3 773 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SendEventAsync(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 774 {
markrad 3:c0556ff7b8e3 775 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 776 /*Codes_SRS_IOTHUBCLIENT_LL_02_011: [IoTHubClient_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle or eventMessageHandle is NULL.]*/
markrad 3:c0556ff7b8e3 777 if (
markrad 3:c0556ff7b8e3 778 (iotHubClientHandle == NULL) ||
markrad 3:c0556ff7b8e3 779 (eventMessageHandle == NULL) ||
markrad 3:c0556ff7b8e3 780 /*Codes_SRS_IOTHUBCLIENT_LL_02_012: [IoTHubClient_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter eventConfirmationCallback is NULL and userContextCallback is not NULL.] */
markrad 3:c0556ff7b8e3 781 ((eventConfirmationCallback == NULL) && (userContextCallback != NULL))
markrad 3:c0556ff7b8e3 782 )
markrad 3:c0556ff7b8e3 783 {
markrad 3:c0556ff7b8e3 784 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 785 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 786 }
markrad 3:c0556ff7b8e3 787 else
markrad 3:c0556ff7b8e3 788 {
markrad 3:c0556ff7b8e3 789 IOTHUB_MESSAGE_LIST *newEntry = (IOTHUB_MESSAGE_LIST*)malloc(sizeof(IOTHUB_MESSAGE_LIST));
markrad 3:c0556ff7b8e3 790 if (newEntry == NULL)
markrad 3:c0556ff7b8e3 791 {
markrad 3:c0556ff7b8e3 792 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 793 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 794 }
markrad 3:c0556ff7b8e3 795 else
markrad 3:c0556ff7b8e3 796 {
markrad 3:c0556ff7b8e3 797 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 798
markrad 3:c0556ff7b8e3 799 if (attach_ms_timesOutAfter(handleData, newEntry) != 0)
markrad 3:c0556ff7b8e3 800 {
markrad 3:c0556ff7b8e3 801 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 802 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 803 free(newEntry);
markrad 3:c0556ff7b8e3 804 }
markrad 3:c0556ff7b8e3 805 else
markrad 3:c0556ff7b8e3 806 {
markrad 3:c0556ff7b8e3 807 /*Codes_SRS_IOTHUBCLIENT_LL_02_013: [IoTHubClient_SendEventAsync shall add the DLIST waitingToSend a new record cloning the information from eventMessageHandle, eventConfirmationCallback, userContextCallback.]*/
markrad 3:c0556ff7b8e3 808 if ((newEntry->messageHandle = IoTHubMessage_Clone(eventMessageHandle)) == NULL)
markrad 3:c0556ff7b8e3 809 {
markrad 3:c0556ff7b8e3 810 /*Codes_SRS_IOTHUBCLIENT_LL_02_014: [If cloning and/or adding the information fails for any reason, IoTHubClient_LL_SendEventAsync shall fail and return IOTHUB_CLIENT_ERROR.] */
markrad 3:c0556ff7b8e3 811 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 812 free(newEntry);
markrad 3:c0556ff7b8e3 813 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 814 }
markrad 3:c0556ff7b8e3 815 else
markrad 3:c0556ff7b8e3 816 {
markrad 3:c0556ff7b8e3 817 /*Codes_SRS_IOTHUBCLIENT_LL_02_013: [IoTHubClient_SendEventAsync shall add the DLIST waitingToSend a new record cloning the information from eventMessageHandle, eventConfirmationCallback, userContextCallback.]*/
markrad 3:c0556ff7b8e3 818 newEntry->callback = eventConfirmationCallback;
markrad 3:c0556ff7b8e3 819 newEntry->context = userContextCallback;
markrad 3:c0556ff7b8e3 820 DList_InsertTailList(&(iotHubClientHandle->waitingToSend), &(newEntry->entry));
markrad 3:c0556ff7b8e3 821 /*Codes_SRS_IOTHUBCLIENT_LL_02_015: [Otherwise IoTHubClient_LL_SendEventAsync shall succeed and return IOTHUB_CLIENT_OK.] */
markrad 3:c0556ff7b8e3 822 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 823 }
markrad 3:c0556ff7b8e3 824 }
markrad 3:c0556ff7b8e3 825 }
markrad 3:c0556ff7b8e3 826 }
markrad 3:c0556ff7b8e3 827 return result;
markrad 3:c0556ff7b8e3 828 }
markrad 3:c0556ff7b8e3 829
markrad 3:c0556ff7b8e3 830 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetMessageCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 831 {
markrad 3:c0556ff7b8e3 832 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 833 /*Codes_SRS_IOTHUBCLIENT_LL_02_016: [IoTHubClient_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.] */
markrad 3:c0556ff7b8e3 834 if (iotHubClientHandle == NULL)
markrad 3:c0556ff7b8e3 835 {
markrad 3:c0556ff7b8e3 836 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 837 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 838 }
markrad 3:c0556ff7b8e3 839 else
markrad 3:c0556ff7b8e3 840 {
markrad 3:c0556ff7b8e3 841 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 842 if (messageCallback == NULL)
markrad 3:c0556ff7b8e3 843 {
markrad 3:c0556ff7b8e3 844 /*Codes_SRS_IOTHUBCLIENT_LL_02_019: [If parameter messageCallback is NULL then IoTHubClient_LL_SetMessageCallback shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
markrad 3:c0556ff7b8e3 845 handleData->IoTHubTransport_Unsubscribe(handleData->deviceHandle);
markrad 3:c0556ff7b8e3 846 handleData->messageCallback = NULL;
markrad 3:c0556ff7b8e3 847 handleData->messageUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 848 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 849 }
markrad 3:c0556ff7b8e3 850 else
markrad 3:c0556ff7b8e3 851 {
markrad 3:c0556ff7b8e3 852 /*Codes_SRS_IOTHUBCLIENT_LL_02_017: [If parameter messageCallback is non-NULL then IoTHubClient_LL_SetMessageCallback shall call the underlying layer's _Subscribe function.]*/
markrad 3:c0556ff7b8e3 853 if (handleData->IoTHubTransport_Subscribe(handleData->deviceHandle) == 0)
markrad 3:c0556ff7b8e3 854 {
markrad 3:c0556ff7b8e3 855 handleData->messageCallback = messageCallback;
markrad 3:c0556ff7b8e3 856 handleData->messageUserContextCallback = userContextCallback;
markrad 3:c0556ff7b8e3 857 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 858 }
markrad 3:c0556ff7b8e3 859 else
markrad 3:c0556ff7b8e3 860 {
markrad 3:c0556ff7b8e3 861 handleData->messageCallback = NULL;
markrad 3:c0556ff7b8e3 862 handleData->messageUserContextCallback = NULL;
markrad 3:c0556ff7b8e3 863 /*Codes_SRS_IOTHUBCLIENT_LL_02_018: [If the underlying layer's _Subscribe function fails, then IoTHubClient_LL_SetMessageCallback shall fail and return IOTHUB_CLIENT_ERROR. Otherwise IoTHubClient_LL_SetMessageCallback shall succeed and return IOTHUB_CLIENT_OK.]*/
markrad 3:c0556ff7b8e3 864 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 865 }
markrad 3:c0556ff7b8e3 866 }
markrad 3:c0556ff7b8e3 867 }
markrad 3:c0556ff7b8e3 868
markrad 3:c0556ff7b8e3 869 return result;
markrad 3:c0556ff7b8e3 870 }
markrad 3:c0556ff7b8e3 871
markrad 3:c0556ff7b8e3 872 static void DoTimeouts(IOTHUB_CLIENT_LL_HANDLE_DATA* handleData)
markrad 3:c0556ff7b8e3 873 {
markrad 3:c0556ff7b8e3 874 uint64_t nowTick;
markrad 3:c0556ff7b8e3 875 if (tickcounter_get_current_ms(handleData->tickCounter, &nowTick) != 0)
markrad 3:c0556ff7b8e3 876 {
markrad 3:c0556ff7b8e3 877 LogError("unable to get the current ms, timeouts will not be processed");
markrad 3:c0556ff7b8e3 878 }
markrad 3:c0556ff7b8e3 879 else
markrad 3:c0556ff7b8e3 880 {
markrad 3:c0556ff7b8e3 881 DLIST_ENTRY* currentItemInWaitingToSend = handleData->waitingToSend.Flink;
markrad 3:c0556ff7b8e3 882 while (currentItemInWaitingToSend != &(handleData->waitingToSend)) /*while we are not at the end of the list*/
markrad 3:c0556ff7b8e3 883 {
markrad 3:c0556ff7b8e3 884 IOTHUB_MESSAGE_LIST* fullEntry = containingRecord(currentItemInWaitingToSend, IOTHUB_MESSAGE_LIST, entry);
markrad 3:c0556ff7b8e3 885 /*Codes_SRS_IOTHUBCLIENT_LL_02_041: [ If more than value miliseconds have passed since the call to IoTHubClient_LL_SendEventAsync then the message callback shall be called with a status code of IOTHUB_CLIENT_CONFIRMATION_TIMEOUT. ]*/
markrad 3:c0556ff7b8e3 886 if ((fullEntry->ms_timesOutAfter != 0) && (fullEntry->ms_timesOutAfter < nowTick))
markrad 3:c0556ff7b8e3 887 {
markrad 3:c0556ff7b8e3 888 PDLIST_ENTRY theNext = currentItemInWaitingToSend->Flink; /*need to save the next item, because the below operations are destructive*/
markrad 3:c0556ff7b8e3 889 DList_RemoveEntryList(currentItemInWaitingToSend);
markrad 3:c0556ff7b8e3 890 if (fullEntry->callback != NULL)
markrad 3:c0556ff7b8e3 891 {
markrad 3:c0556ff7b8e3 892 fullEntry->callback(IOTHUB_CLIENT_CONFIRMATION_MESSAGE_TIMEOUT, fullEntry->context);
markrad 3:c0556ff7b8e3 893 }
markrad 3:c0556ff7b8e3 894 IoTHubMessage_Destroy(fullEntry->messageHandle); /*because it has been cloned*/
markrad 3:c0556ff7b8e3 895 free(fullEntry);
markrad 3:c0556ff7b8e3 896 currentItemInWaitingToSend = theNext;
markrad 3:c0556ff7b8e3 897 }
markrad 3:c0556ff7b8e3 898 else
markrad 3:c0556ff7b8e3 899 {
markrad 3:c0556ff7b8e3 900 currentItemInWaitingToSend = currentItemInWaitingToSend->Flink;
markrad 3:c0556ff7b8e3 901 }
markrad 3:c0556ff7b8e3 902 }
markrad 3:c0556ff7b8e3 903 }
markrad 3:c0556ff7b8e3 904 }
markrad 3:c0556ff7b8e3 905
markrad 3:c0556ff7b8e3 906 void IoTHubClient_LL_DoWork(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle)
markrad 3:c0556ff7b8e3 907 {
markrad 3:c0556ff7b8e3 908 /*Codes_SRS_IOTHUBCLIENT_LL_02_020: [If parameter iotHubClientHandle is NULL then IoTHubClient_LL_DoWork shall not perform any action.] */
markrad 3:c0556ff7b8e3 909 if (iotHubClientHandle != NULL)
markrad 3:c0556ff7b8e3 910 {
markrad 3:c0556ff7b8e3 911 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 912 DoTimeouts(handleData);
markrad 3:c0556ff7b8e3 913
markrad 3:c0556ff7b8e3 914 /*Codes_SRS_IOTHUBCLIENT_LL_07_008: [ IoTHubClient_LL_DoWork shall iterate the message queue and execute the underlying transports IoTHubTransport_ProcessItem function for each item. ] */
markrad 3:c0556ff7b8e3 915 DLIST_ENTRY* client_item = handleData->iot_msg_queue.Flink;
markrad 3:c0556ff7b8e3 916 while (client_item != &(handleData->iot_msg_queue)) /*while we are not at the end of the list*/
markrad 3:c0556ff7b8e3 917 {
markrad 3:c0556ff7b8e3 918 PDLIST_ENTRY next_item = client_item->Flink;
markrad 3:c0556ff7b8e3 919
markrad 3:c0556ff7b8e3 920 IOTHUB_DEVICE_TWIN* queue_data = containingRecord(client_item, IOTHUB_DEVICE_TWIN, entry);
markrad 3:c0556ff7b8e3 921 IOTHUB_IDENTITY_INFO identity_info;
markrad 3:c0556ff7b8e3 922 identity_info.device_twin = queue_data;
markrad 3:c0556ff7b8e3 923 IOTHUB_PROCESS_ITEM_RESULT process_results = handleData->IoTHubTransport_ProcessItem(handleData->transportHandle, IOTHUB_TYPE_DEVICE_TWIN, &identity_info);
markrad 3:c0556ff7b8e3 924 if (process_results == IOTHUB_PROCESS_CONTINUE || process_results == IOTHUB_PROCESS_NOT_CONNECTED)
markrad 3:c0556ff7b8e3 925 {
markrad 3:c0556ff7b8e3 926 /*Codes_SRS_IOTHUBCLIENT_LL_07_010: [ If 'IoTHubTransport_ProcessItem' returns IOTHUB_PROCESS_CONTINUE or IOTHUB_PROCESS_NOT_CONNECTED IoTHubClient_LL_DoWork shall continue on to call the underlaying layer's _DoWork function. ]*/
markrad 3:c0556ff7b8e3 927 break;
markrad 3:c0556ff7b8e3 928 }
markrad 3:c0556ff7b8e3 929 else
markrad 3:c0556ff7b8e3 930 {
markrad 3:c0556ff7b8e3 931 DList_RemoveEntryList(client_item);
markrad 3:c0556ff7b8e3 932 if (process_results == IOTHUB_PROCESS_OK)
markrad 3:c0556ff7b8e3 933 {
markrad 3:c0556ff7b8e3 934 /*Codes_SRS_IOTHUBCLIENT_LL_07_011: [ If 'IoTHubTransport_ProcessItem' returns IOTHUB_PROCESS_OK IoTHubClient_LL_DoWork shall add the IOTHUB_DEVICE_TWIN to the ack queue. ]*/
markrad 3:c0556ff7b8e3 935 DList_InsertTailList(&(iotHubClientHandle->iot_ack_queue), &(queue_data->entry));
markrad 3:c0556ff7b8e3 936 }
markrad 3:c0556ff7b8e3 937 else
markrad 3:c0556ff7b8e3 938 {
markrad 3:c0556ff7b8e3 939 /*Codes_SRS_IOTHUBCLIENT_LL_07_012: [ If 'IoTHubTransport_ProcessItem' returns any other value IoTHubClient_LL_DoWork shall destroy the IOTHUB_DEVICE_TWIN item. ]*/
markrad 3:c0556ff7b8e3 940 LogError("Failure queue processing item");
markrad 3:c0556ff7b8e3 941 device_twin_data_destroy(queue_data);
markrad 3:c0556ff7b8e3 942 }
markrad 3:c0556ff7b8e3 943 }
markrad 3:c0556ff7b8e3 944 // Move along to the next item
markrad 3:c0556ff7b8e3 945 client_item = next_item;
markrad 3:c0556ff7b8e3 946 }
markrad 3:c0556ff7b8e3 947
markrad 3:c0556ff7b8e3 948 /*Codes_SRS_IOTHUBCLIENT_LL_02_021: [Otherwise, IoTHubClient_LL_DoWork shall invoke the underlaying layer's _DoWork function.]*/
markrad 3:c0556ff7b8e3 949 handleData->IoTHubTransport_DoWork(handleData->transportHandle, iotHubClientHandle);
markrad 3:c0556ff7b8e3 950 }
markrad 3:c0556ff7b8e3 951 }
markrad 3:c0556ff7b8e3 952
markrad 3:c0556ff7b8e3 953 IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetSendStatus(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
markrad 3:c0556ff7b8e3 954 {
markrad 3:c0556ff7b8e3 955 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 956
markrad 3:c0556ff7b8e3 957 /* Codes_SRS_IOTHUBCLIENT_09_007: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter] */
markrad 3:c0556ff7b8e3 958 if (iotHubClientHandle == NULL || iotHubClientStatus == NULL)
markrad 3:c0556ff7b8e3 959 {
markrad 3:c0556ff7b8e3 960 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 961 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 962 }
markrad 3:c0556ff7b8e3 963 else
markrad 3:c0556ff7b8e3 964 {
markrad 3:c0556ff7b8e3 965 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 966
markrad 3:c0556ff7b8e3 967 /* Codes_SRS_IOTHUBCLIENT_09_008: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_IDLE if there is currently no items to be sent] */
markrad 3:c0556ff7b8e3 968 /* Codes_SRS_IOTHUBCLIENT_09_009: [IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_OK and status IOTHUB_CLIENT_SEND_STATUS_BUSY if there are currently items to be sent] */
markrad 3:c0556ff7b8e3 969 result = handleData->IoTHubTransport_GetSendStatus(handleData->deviceHandle, iotHubClientStatus);
markrad 3:c0556ff7b8e3 970 }
markrad 3:c0556ff7b8e3 971
markrad 3:c0556ff7b8e3 972 return result;
markrad 3:c0556ff7b8e3 973 }
markrad 3:c0556ff7b8e3 974
markrad 3:c0556ff7b8e3 975 void IoTHubClient_LL_SendComplete(IOTHUB_CLIENT_LL_HANDLE handle, PDLIST_ENTRY completed, IOTHUB_CLIENT_CONFIRMATION_RESULT result)
markrad 3:c0556ff7b8e3 976 {
markrad 3:c0556ff7b8e3 977 /*Codes_SRS_IOTHUBCLIENT_LL_02_022: [If parameter completed is NULL, or parameter handle is NULL then IoTHubClient_LL_SendBatch shall return.]*/
markrad 3:c0556ff7b8e3 978 if (
markrad 3:c0556ff7b8e3 979 (handle == NULL) ||
markrad 3:c0556ff7b8e3 980 (completed == NULL)
markrad 3:c0556ff7b8e3 981 )
markrad 3:c0556ff7b8e3 982 {
markrad 3:c0556ff7b8e3 983 /*"shall return"*/
markrad 3:c0556ff7b8e3 984 LogError("invalid arg");
markrad 3:c0556ff7b8e3 985 }
markrad 3:c0556ff7b8e3 986 else
markrad 3:c0556ff7b8e3 987 {
markrad 3:c0556ff7b8e3 988 /*Codes_SRS_IOTHUBCLIENT_LL_02_027: [If parameter result is IOTHUB_CLIENT_CONFIRMATION_ERROR then IoTHubClient_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_ERROR and the context set to the context passed originally in the SendEventAsync call.] */
markrad 3:c0556ff7b8e3 989 /*Codes_SRS_IOTHUBCLIENT_LL_02_025: [If parameter result is IOTHUB_CLIENT_CONFIRMATION_OK then IoTHubClient_LL_SendComplete shall call all the non-NULL callbacks with the result parameter set to IOTHUB_CLIENT_CONFIRMATION_OK and the context set to the context passed originally in the SendEventAsync call.]*/
markrad 3:c0556ff7b8e3 990 PDLIST_ENTRY oldest;
markrad 3:c0556ff7b8e3 991 while ((oldest = DList_RemoveHeadList(completed)) != completed)
markrad 3:c0556ff7b8e3 992 {
markrad 3:c0556ff7b8e3 993 IOTHUB_MESSAGE_LIST* messageList = (IOTHUB_MESSAGE_LIST*)containingRecord(oldest, IOTHUB_MESSAGE_LIST, entry);
markrad 3:c0556ff7b8e3 994 /*Codes_SRS_IOTHUBCLIENT_LL_02_026: [If any callback is NULL then there shall not be a callback call.]*/
markrad 3:c0556ff7b8e3 995 if (messageList->callback != NULL)
markrad 3:c0556ff7b8e3 996 {
markrad 3:c0556ff7b8e3 997 messageList->callback(result, messageList->context);
markrad 3:c0556ff7b8e3 998 }
markrad 3:c0556ff7b8e3 999 IoTHubMessage_Destroy(messageList->messageHandle);
markrad 3:c0556ff7b8e3 1000 free(messageList);
markrad 3:c0556ff7b8e3 1001 }
markrad 3:c0556ff7b8e3 1002 }
markrad 3:c0556ff7b8e3 1003 }
markrad 3:c0556ff7b8e3 1004
markrad 3:c0556ff7b8e3 1005 int IoTHubClient_LL_DeviceMethodComplete(IOTHUB_CLIENT_LL_HANDLE handle, const char* method_name, const unsigned char* payLoad, size_t size, BUFFER_HANDLE response)
markrad 3:c0556ff7b8e3 1006 {
markrad 3:c0556ff7b8e3 1007 int result;
markrad 3:c0556ff7b8e3 1008 if (handle == NULL || response == NULL)
markrad 3:c0556ff7b8e3 1009 {
markrad 3:c0556ff7b8e3 1010 /* Codes_SRS_IOTHUBCLIENT_LL_07_017: [ If handle or response is NULL then IoTHubClient_LL_DeviceMethodComplete shall return 500. ] */
markrad 3:c0556ff7b8e3 1011 LogError("Invalid argument handle=%p", handle);
markrad 3:c0556ff7b8e3 1012 result = 500;
markrad 3:c0556ff7b8e3 1013 }
markrad 3:c0556ff7b8e3 1014 else
markrad 3:c0556ff7b8e3 1015 {
markrad 3:c0556ff7b8e3 1016 /* Codes_SRS_IOTHUBCLIENT_LL_07_018: [ If deviceMethodCallback is not NULL IoTHubClient_LL_DeviceMethodComplete shall execute deviceMethodCallback and return the status. ] */
markrad 3:c0556ff7b8e3 1017 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)handle;
markrad 3:c0556ff7b8e3 1018 if (handleData->deviceMethodCallback)
markrad 3:c0556ff7b8e3 1019 {
markrad 3:c0556ff7b8e3 1020 unsigned char* payload_resp = NULL;
markrad 3:c0556ff7b8e3 1021 size_t resp_size = 0;
markrad 3:c0556ff7b8e3 1022 result = handleData->deviceMethodCallback(method_name, payLoad, size, &payload_resp, &resp_size, handleData->deviceMethodUserContextCallback);
markrad 3:c0556ff7b8e3 1023 /* Codes_SRS_IOTHUBCLIENT_LL_07_020: [ deviceMethodCallback shall buil the BUFFER_HANDLE with the response payload from the IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC callback. ] */
markrad 3:c0556ff7b8e3 1024 if (payload_resp != NULL && resp_size > 0)
markrad 3:c0556ff7b8e3 1025 {
markrad 3:c0556ff7b8e3 1026 if (BUFFER_build(response, payload_resp, resp_size) != 0)
markrad 3:c0556ff7b8e3 1027 {
markrad 3:c0556ff7b8e3 1028 result = 500;
markrad 3:c0556ff7b8e3 1029 }
markrad 3:c0556ff7b8e3 1030 }
markrad 3:c0556ff7b8e3 1031 if (payload_resp != NULL)
markrad 3:c0556ff7b8e3 1032 {
markrad 3:c0556ff7b8e3 1033 free(payload_resp);
markrad 3:c0556ff7b8e3 1034 }
markrad 3:c0556ff7b8e3 1035 }
markrad 3:c0556ff7b8e3 1036 else
markrad 3:c0556ff7b8e3 1037 {
markrad 3:c0556ff7b8e3 1038 /* Codes_SRS_IOTHUBCLIENT_LL_07_019: [ If deviceMethodCallback is NULL IoTHubClient_LL_DeviceMethodComplete shall return 404. ] */
markrad 3:c0556ff7b8e3 1039 result = 404;
markrad 3:c0556ff7b8e3 1040 }
markrad 3:c0556ff7b8e3 1041 }
markrad 3:c0556ff7b8e3 1042 return result;
markrad 3:c0556ff7b8e3 1043 }
markrad 3:c0556ff7b8e3 1044
markrad 3:c0556ff7b8e3 1045 void IoTHubClient_LL_RetrievePropertyComplete(IOTHUB_CLIENT_LL_HANDLE handle, DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size)
markrad 3:c0556ff7b8e3 1046 {
markrad 3:c0556ff7b8e3 1047 if (handle == NULL)
markrad 3:c0556ff7b8e3 1048 {
markrad 3:c0556ff7b8e3 1049 /* Codes_SRS_IOTHUBCLIENT_LL_07_013: [ If handle is NULL then IoTHubClient_LL_RetrievePropertyComplete shall do nothing.] */
markrad 3:c0556ff7b8e3 1050 LogError("Invalid argument handle=%p", handle);
markrad 3:c0556ff7b8e3 1051 }
markrad 3:c0556ff7b8e3 1052 else
markrad 3:c0556ff7b8e3 1053 {
markrad 3:c0556ff7b8e3 1054 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)handle;
markrad 3:c0556ff7b8e3 1055 /* Codes_SRS_IOTHUBCLIENT_LL_07_014: [ If deviceTwinCallback is NULL then IoTHubClient_LL_RetrievePropertyComplete shall do nothing.] */
markrad 3:c0556ff7b8e3 1056 if (handleData->deviceTwinCallback)
markrad 3:c0556ff7b8e3 1057 {
markrad 3:c0556ff7b8e3 1058 /* Codes_SRS_IOTHUBCLIENT_LL_07_015: [ If the the update_state parameter is DEVICE_TWIN_UPDATE_PARTIAL and a DEVICE_TWIN_UPDATE_COMPLETE has not been previously recieved then IoTHubClient_LL_RetrievePropertyComplete shall do nothing.] */
markrad 3:c0556ff7b8e3 1059 if (update_state == DEVICE_TWIN_UPDATE_COMPLETE)
markrad 3:c0556ff7b8e3 1060 {
markrad 3:c0556ff7b8e3 1061 handleData->complete_twin_update_encountered = true;
markrad 3:c0556ff7b8e3 1062 }
markrad 3:c0556ff7b8e3 1063 if (handleData->complete_twin_update_encountered)
markrad 3:c0556ff7b8e3 1064 {
markrad 3:c0556ff7b8e3 1065 /* Codes_SRS_IOTHUBCLIENT_LL_07_016: [ If deviceTwinCallback is set and DEVICE_TWIN_UPDATE_COMPLETE has been encountered then IoTHubClient_LL_RetrievePropertyComplete shall call deviceTwinCallback.] */
markrad 3:c0556ff7b8e3 1066 handleData->deviceTwinCallback(update_state, payLoad, size, handleData->deviceTwinContextCallback);
markrad 3:c0556ff7b8e3 1067 }
markrad 3:c0556ff7b8e3 1068 }
markrad 3:c0556ff7b8e3 1069 }
markrad 3:c0556ff7b8e3 1070 }
markrad 3:c0556ff7b8e3 1071
markrad 3:c0556ff7b8e3 1072 void IoTHubClient_LL_ReportedStateComplete(IOTHUB_CLIENT_LL_HANDLE handle, uint32_t item_id, int status_code)
markrad 3:c0556ff7b8e3 1073 {
markrad 3:c0556ff7b8e3 1074 /* Codes_SRS_IOTHUBCLIENT_LL_07_002: [ if handle or queue_handle are NULL then IoTHubClient_LL_ReportedStateComplete shall do nothing. ] */
markrad 3:c0556ff7b8e3 1075 if (handle == NULL)
markrad 3:c0556ff7b8e3 1076 {
markrad 3:c0556ff7b8e3 1077 /*"shall return"*/
markrad 3:c0556ff7b8e3 1078 LogError("Invalid argument handle=%p", handle);
markrad 3:c0556ff7b8e3 1079 }
markrad 3:c0556ff7b8e3 1080 else
markrad 3:c0556ff7b8e3 1081 {
markrad 3:c0556ff7b8e3 1082 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)handle;
markrad 3:c0556ff7b8e3 1083
markrad 3:c0556ff7b8e3 1084 /* Codes_SRS_IOTHUBCLIENT_LL_07_003: [ IoTHubClient_LL_ReportedStateComplete shall enumerate through the IOTHUB_DEVICE_TWIN structures in queue_handle. ]*/
markrad 3:c0556ff7b8e3 1085 DLIST_ENTRY* client_item = handleData->iot_ack_queue.Flink;
markrad 3:c0556ff7b8e3 1086 while (client_item != &(handleData->iot_ack_queue)) /*while we are not at the end of the list*/
markrad 3:c0556ff7b8e3 1087 {
markrad 3:c0556ff7b8e3 1088 PDLIST_ENTRY next_item = client_item->Flink;
markrad 3:c0556ff7b8e3 1089 IOTHUB_DEVICE_TWIN* queue_data = containingRecord(client_item, IOTHUB_DEVICE_TWIN, entry);
markrad 3:c0556ff7b8e3 1090 if (queue_data->item_id == item_id)
markrad 3:c0556ff7b8e3 1091 {
markrad 3:c0556ff7b8e3 1092 if (queue_data->reported_state_callback != NULL)
markrad 3:c0556ff7b8e3 1093 {
markrad 3:c0556ff7b8e3 1094 queue_data->reported_state_callback(status_code, queue_data->context);
markrad 3:c0556ff7b8e3 1095 }
markrad 3:c0556ff7b8e3 1096 /*Codes_SRS_IOTHUBCLIENT_LL_07_009: [ IoTHubClient_LL_ReportedStateComplete shall remove the IOTHUB_DEVICE_TWIN item from the ack queue.]*/
markrad 3:c0556ff7b8e3 1097 DList_RemoveEntryList(client_item);
markrad 3:c0556ff7b8e3 1098 device_twin_data_destroy(queue_data);
markrad 3:c0556ff7b8e3 1099 break;
markrad 3:c0556ff7b8e3 1100 }
markrad 3:c0556ff7b8e3 1101 client_item = next_item;
markrad 3:c0556ff7b8e3 1102 }
markrad 3:c0556ff7b8e3 1103 }
markrad 3:c0556ff7b8e3 1104 }
markrad 3:c0556ff7b8e3 1105
markrad 3:c0556ff7b8e3 1106 IOTHUBMESSAGE_DISPOSITION_RESULT IoTHubClient_LL_MessageCallback(IOTHUB_CLIENT_LL_HANDLE handle, IOTHUB_MESSAGE_HANDLE message)
markrad 3:c0556ff7b8e3 1107 {
markrad 3:c0556ff7b8e3 1108 int result;
markrad 3:c0556ff7b8e3 1109 /*Codes_SRS_IOTHUBCLIENT_LL_02_029: [If parameter handle is NULL then IoTHubClient_LL_MessageCallback shall return IOTHUBMESSAGE_ABANDONED.] */
markrad 3:c0556ff7b8e3 1110 if (handle == NULL)
markrad 3:c0556ff7b8e3 1111 {
markrad 3:c0556ff7b8e3 1112 LogError("invalid argument");
markrad 3:c0556ff7b8e3 1113 result = IOTHUBMESSAGE_ABANDONED;
markrad 3:c0556ff7b8e3 1114 }
markrad 3:c0556ff7b8e3 1115 else
markrad 3:c0556ff7b8e3 1116 {
markrad 3:c0556ff7b8e3 1117 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)handle;
markrad 3:c0556ff7b8e3 1118
markrad 3:c0556ff7b8e3 1119 /* Codes_SRS_IOTHUBCLIENT_LL_09_004: [IoTHubClient_LL_GetLastMessageReceiveTime shall return lastMessageReceiveTime in localtime] */
markrad 3:c0556ff7b8e3 1120 handleData->lastMessageReceiveTime = get_time(NULL);
markrad 3:c0556ff7b8e3 1121
markrad 3:c0556ff7b8e3 1122 /*Codes_SRS_IOTHUBCLIENT_LL_02_030: [IoTHubClient_LL_MessageCallback shall invoke the last callback function (the parameter messageCallback to IoTHubClient_LL_SetMessageCallback) passing the message and the passed userContextCallback.]*/
markrad 3:c0556ff7b8e3 1123 if (handleData->messageCallback != NULL)
markrad 3:c0556ff7b8e3 1124 {
markrad 3:c0556ff7b8e3 1125 result = handleData->messageCallback(message, handleData->messageUserContextCallback);
markrad 3:c0556ff7b8e3 1126 }
markrad 3:c0556ff7b8e3 1127 else
markrad 3:c0556ff7b8e3 1128 {
markrad 3:c0556ff7b8e3 1129 /*Codes_SRS_IOTHUBCLIENT_LL_02_032: [If the last callback function was NULL, then IoTHubClient_LL_MessageCallback shall return IOTHUBMESSAGE_ABANDONED.] */
markrad 3:c0556ff7b8e3 1130 LogError("user callback was NULL");
markrad 3:c0556ff7b8e3 1131 result = IOTHUBMESSAGE_ABANDONED;
markrad 3:c0556ff7b8e3 1132 }
markrad 3:c0556ff7b8e3 1133 }
markrad 3:c0556ff7b8e3 1134 /*Codes_SRS_IOTHUBCLIENT_LL_02_031: [Then IoTHubClient_LL_MessageCallback shall return what the user function returns.]*/
markrad 3:c0556ff7b8e3 1135 return (IOTHUBMESSAGE_DISPOSITION_RESULT) result;
markrad 3:c0556ff7b8e3 1136 }
markrad 3:c0556ff7b8e3 1137
markrad 3:c0556ff7b8e3 1138 void IotHubClient_LL_ConnectionStatusCallBack(IOTHUB_CLIENT_LL_HANDLE handle, IOTHUB_CLIENT_CONNECTION_STATUS status, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason)
markrad 3:c0556ff7b8e3 1139 {
markrad 3:c0556ff7b8e3 1140 /*Codes_SRS_IOTHUBCLIENT_LL_25_113: [If parameter connectionStatus is NULL or parameter handle is NULL then IotHubClient_LL_ConnectionStatusCallBack shall return.]*/
markrad 3:c0556ff7b8e3 1141 if (handle == NULL)
markrad 3:c0556ff7b8e3 1142 {
markrad 3:c0556ff7b8e3 1143 /*"shall return"*/
markrad 3:c0556ff7b8e3 1144 LogError("invalid arg");
markrad 3:c0556ff7b8e3 1145 }
markrad 3:c0556ff7b8e3 1146 else
markrad 3:c0556ff7b8e3 1147 {
markrad 3:c0556ff7b8e3 1148 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)handle;
markrad 3:c0556ff7b8e3 1149
markrad 3:c0556ff7b8e3 1150 /*Codes_SRS_IOTHUBCLIENT_LL_25_114: [IotHubClient_LL_ConnectionStatusCallBack shall call non-callback set by the user from IoTHubClient_LL_SetConnectionStatusCallback passing the status, reason and the passed userContextCallback.]*/
markrad 3:c0556ff7b8e3 1151 if (handleData->conStatusCallback != NULL)
markrad 3:c0556ff7b8e3 1152 {
markrad 3:c0556ff7b8e3 1153 handleData->conStatusCallback(status, reason, handleData->conStatusUserContextCallback);
markrad 3:c0556ff7b8e3 1154 }
markrad 3:c0556ff7b8e3 1155 }
markrad 3:c0556ff7b8e3 1156
markrad 3:c0556ff7b8e3 1157 }
markrad 3:c0556ff7b8e3 1158
markrad 3:c0556ff7b8e3 1159 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetConnectionStatusCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
markrad 3:c0556ff7b8e3 1160 {
markrad 3:c0556ff7b8e3 1161 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1162 /*Codes_SRS_IOTHUBCLIENT_LL_25_111: [IoTHubClient_LL_SetConnectionStatusCallback shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL parameter iotHubClientHandle**]** */
markrad 3:c0556ff7b8e3 1163 if (iotHubClientHandle == NULL)
markrad 3:c0556ff7b8e3 1164 {
markrad 3:c0556ff7b8e3 1165 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1166 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1167 }
markrad 3:c0556ff7b8e3 1168 else
markrad 3:c0556ff7b8e3 1169 {
markrad 3:c0556ff7b8e3 1170 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1171 /*Codes_SRS_IOTHUBCLIENT_LL_25_112: [IoTHubClient_LL_SetConnectionStatusCallback shall return IOTHUB_CLIENT_OK and save the callback and userContext as a member of the handle.] */
markrad 3:c0556ff7b8e3 1172 handleData->conStatusCallback = connectionStatusCallback;
markrad 3:c0556ff7b8e3 1173 handleData->conStatusUserContextCallback = userContextCallback;
markrad 3:c0556ff7b8e3 1174 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1175 }
markrad 3:c0556ff7b8e3 1176
markrad 3:c0556ff7b8e3 1177 return result;
markrad 3:c0556ff7b8e3 1178 }
markrad 3:c0556ff7b8e3 1179
markrad 3:c0556ff7b8e3 1180 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetRetryPolicy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
markrad 3:c0556ff7b8e3 1181 {
markrad 3:c0556ff7b8e3 1182 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1183 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1184
markrad 3:c0556ff7b8e3 1185 /* Codes_SRS_IOTHUBCLIENT_LL_25_116: [**IoTHubClient_LL_SetRetryPolicy shall return IOTHUB_CLIENT_INVALID_ARG if called with NULL iotHubClientHandle]*/
markrad 3:c0556ff7b8e3 1186 if (handleData == NULL)
markrad 3:c0556ff7b8e3 1187 {
markrad 3:c0556ff7b8e3 1188 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1189 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1190 }
markrad 3:c0556ff7b8e3 1191 else
markrad 3:c0556ff7b8e3 1192 {
markrad 3:c0556ff7b8e3 1193 if (handleData->transportHandle == NULL)
markrad 3:c0556ff7b8e3 1194 {
markrad 3:c0556ff7b8e3 1195 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1196 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1197 }
markrad 3:c0556ff7b8e3 1198 else
markrad 3:c0556ff7b8e3 1199 {
markrad 3:c0556ff7b8e3 1200 if (handleData->IoTHubTransport_SetRetryPolicy(handleData->transportHandle, retryPolicy, retryTimeoutLimitInSeconds) != 0)
markrad 3:c0556ff7b8e3 1201 {
markrad 3:c0556ff7b8e3 1202 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1203 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1204 }
markrad 3:c0556ff7b8e3 1205 else
markrad 3:c0556ff7b8e3 1206 {
markrad 3:c0556ff7b8e3 1207 /*Codes_SRS_IOTHUBCLIENT_LL_25_118: [**IoTHubClient_LL_SetRetryPolicy shall save connection retry policies specified by the user to retryPolicy in struct IOTHUB_CLIENT_LL_HANDLE_DATA]*/
markrad 3:c0556ff7b8e3 1208 /*Codes_SRS_IOTHUBCLIENT_LL_25_119: [**IoTHubClient_LL_SetRetryPolicy shall save retryTimeoutLimitInSeconds in seconds to retryTimeout in struct IOTHUB_CLIENT_LL_HANDLE_DATA]*/
markrad 3:c0556ff7b8e3 1209 handleData->retryPolicy = retryPolicy;
markrad 3:c0556ff7b8e3 1210 handleData->retryTimeoutLimitInSeconds = retryTimeoutLimitInSeconds;
markrad 3:c0556ff7b8e3 1211 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1212 }
markrad 3:c0556ff7b8e3 1213 }
markrad 3:c0556ff7b8e3 1214 }
markrad 3:c0556ff7b8e3 1215 return result;
markrad 3:c0556ff7b8e3 1216 }
markrad 3:c0556ff7b8e3 1217
markrad 3:c0556ff7b8e3 1218 IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetRetryPolicy(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
markrad 3:c0556ff7b8e3 1219 {
markrad 3:c0556ff7b8e3 1220 IOTHUB_CLIENT_RESULT result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1221 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1222
markrad 3:c0556ff7b8e3 1223 /* Codes_SRS_IOTHUBCLIENT_LL_09_001: [IoTHubClient_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG if any of the arguments is NULL] */
markrad 3:c0556ff7b8e3 1224 if (handleData == NULL || retryPolicy == NULL || retryTimeoutLimitInSeconds == NULL)
markrad 3:c0556ff7b8e3 1225 {
markrad 3:c0556ff7b8e3 1226 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1227 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1228 }
markrad 3:c0556ff7b8e3 1229 else
markrad 3:c0556ff7b8e3 1230 {
markrad 3:c0556ff7b8e3 1231 *retryPolicy = handleData->retryPolicy;
markrad 3:c0556ff7b8e3 1232 *retryTimeoutLimitInSeconds = handleData->retryTimeoutLimitInSeconds;
markrad 3:c0556ff7b8e3 1233 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1234 }
markrad 3:c0556ff7b8e3 1235
markrad 3:c0556ff7b8e3 1236 return result;
markrad 3:c0556ff7b8e3 1237 }
markrad 3:c0556ff7b8e3 1238
markrad 3:c0556ff7b8e3 1239 IOTHUB_CLIENT_RESULT IoTHubClient_LL_GetLastMessageReceiveTime(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
markrad 3:c0556ff7b8e3 1240 {
markrad 3:c0556ff7b8e3 1241 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1242 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1243
markrad 3:c0556ff7b8e3 1244 /* Codes_SRS_IOTHUBCLIENT_LL_09_001: [IoTHubClient_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG if any of the arguments is NULL] */
markrad 3:c0556ff7b8e3 1245 if (handleData == NULL || lastMessageReceiveTime == NULL)
markrad 3:c0556ff7b8e3 1246 {
markrad 3:c0556ff7b8e3 1247 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1248 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1249 }
markrad 3:c0556ff7b8e3 1250 else
markrad 3:c0556ff7b8e3 1251 {
markrad 3:c0556ff7b8e3 1252 /* Codes_SRS_IOTHUBCLIENT_LL_09_002: [IoTHubClient_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INDEFINITE_TIME - and not set 'lastMessageReceiveTime' - if it is unable to provide the time for the last commands] */
markrad 3:c0556ff7b8e3 1253 if (handleData->lastMessageReceiveTime == INDEFINITE_TIME)
markrad 3:c0556ff7b8e3 1254 {
markrad 3:c0556ff7b8e3 1255 result = IOTHUB_CLIENT_INDEFINITE_TIME;
markrad 3:c0556ff7b8e3 1256 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1257 }
markrad 3:c0556ff7b8e3 1258 else
markrad 3:c0556ff7b8e3 1259 {
markrad 3:c0556ff7b8e3 1260 /* Codes_SRS_IOTHUBCLIENT_LL_09_003: [IoTHubClient_LL_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_OK if it wrote in the lastMessageReceiveTime the time when the last command was received] */
markrad 3:c0556ff7b8e3 1261 /* Codes_SRS_IOTHUBCLIENT_LL_09_004: [IoTHubClient_LL_GetLastMessageReceiveTime shall return lastMessageReceiveTime in localtime] */
markrad 3:c0556ff7b8e3 1262 *lastMessageReceiveTime = handleData->lastMessageReceiveTime;
markrad 3:c0556ff7b8e3 1263 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1264 }
markrad 3:c0556ff7b8e3 1265 }
markrad 3:c0556ff7b8e3 1266
markrad 3:c0556ff7b8e3 1267 return result;
markrad 3:c0556ff7b8e3 1268 }
markrad 3:c0556ff7b8e3 1269
markrad 3:c0556ff7b8e3 1270 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetOption(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* optionName, const void* value)
markrad 3:c0556ff7b8e3 1271 {
markrad 3:c0556ff7b8e3 1272
markrad 3:c0556ff7b8e3 1273 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1274 /*Codes_SRS_IOTHUBCLIENT_LL_02_034: [If iotHubClientHandle is NULL then IoTHubClient_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.]*/
markrad 3:c0556ff7b8e3 1275 /*Codes_SRS_IOTHUBCLIENT_LL_02_035: [If optionName is NULL then IoTHubClient_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
markrad 3:c0556ff7b8e3 1276 /*Codes_SRS_IOTHUBCLIENT_LL_02_036: [If value is NULL then IoTHubClient_LL_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
markrad 3:c0556ff7b8e3 1277 if (
markrad 3:c0556ff7b8e3 1278 (iotHubClientHandle == NULL) ||
markrad 3:c0556ff7b8e3 1279 (optionName == NULL) ||
markrad 3:c0556ff7b8e3 1280 (value == NULL)
markrad 3:c0556ff7b8e3 1281 )
markrad 3:c0556ff7b8e3 1282 {
markrad 3:c0556ff7b8e3 1283 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1284 LogError("invalid argument (NULL)");
markrad 3:c0556ff7b8e3 1285 }
markrad 3:c0556ff7b8e3 1286 else
markrad 3:c0556ff7b8e3 1287 {
markrad 3:c0556ff7b8e3 1288 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1289
markrad 3:c0556ff7b8e3 1290 /*Codes_SRS_IOTHUBCLIENT_LL_02_039: [ "messageTimeout" - once IoTHubClient_LL_SendEventAsync is called the message shall timeout after value miliseconds. Value is a pointer to a uint64. ]*/
markrad 3:c0556ff7b8e3 1291 if (strcmp(optionName, "messageTimeout") == 0)
markrad 3:c0556ff7b8e3 1292 {
markrad 3:c0556ff7b8e3 1293 /*this is an option handled by IoTHubClient_LL*/
markrad 3:c0556ff7b8e3 1294 /*Codes_SRS_IOTHUBCLIENT_LL_02_043: [ Calling IoTHubClient_LL_SetOption with value set to "0" shall disable the timeout mechanism for all new messages. ]*/
markrad 3:c0556ff7b8e3 1295 handleData->currentMessageTimeout = *(const uint64_t*)value;
markrad 3:c0556ff7b8e3 1296 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1297 }
markrad 3:c0556ff7b8e3 1298 else
markrad 3:c0556ff7b8e3 1299 {
markrad 3:c0556ff7b8e3 1300
markrad 3:c0556ff7b8e3 1301 /*Codes_SRS_IOTHUBCLIENT_LL_02_099: [ IoTHubClient_LL_SetOption shall return according to the table below ]*/
markrad 3:c0556ff7b8e3 1302 IOTHUB_CLIENT_RESULT uploadToBlob_result;
markrad 3:c0556ff7b8e3 1303 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 1304 uploadToBlob_result = IoTHubClient_LL_UploadToBlob_SetOption(handleData->uploadToBlobHandle, optionName, value);
markrad 3:c0556ff7b8e3 1305 if(uploadToBlob_result == IOTHUB_CLIENT_ERROR)
markrad 3:c0556ff7b8e3 1306 {
markrad 3:c0556ff7b8e3 1307 LogError("unable to IoTHubClient_LL_UploadToBlob_SetOption");
markrad 3:c0556ff7b8e3 1308 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1309 }
markrad 3:c0556ff7b8e3 1310 #else
markrad 3:c0556ff7b8e3 1311 uploadToBlob_result = IOTHUB_CLIENT_INVALID_ARG; /*harmless value (IOTHUB_CLIENT_INVALID_ARG)in the case when uploadtoblob is not compiled in, otherwise whatever IoTHubClient_LL_UploadToBlob_SetOption returned*/
markrad 3:c0556ff7b8e3 1312 #endif /*DONT_USE_UPLOADTOBLOB*/
markrad 3:c0556ff7b8e3 1313
markrad 3:c0556ff7b8e3 1314
markrad 3:c0556ff7b8e3 1315 result =
markrad 3:c0556ff7b8e3 1316 /*based on uploadToBlob_result value this is what happens:*/
markrad 3:c0556ff7b8e3 1317 /*IOTHUB_CLIENT_INVALID_ARG always returns what IoTHubTransport_SetOption returns*/
markrad 3:c0556ff7b8e3 1318 /*IOTHUB_CLIENT_ERROR always returns IOTHUB_CLIENT_ERROR */
markrad 3:c0556ff7b8e3 1319 /*IOTHUB_CLIENT_OK returns OK
markrad 3:c0556ff7b8e3 1320 IOTHUB_CLIENT_OK if IoTHubTransport_SetOption returns OK or INVALID_ARG
markrad 3:c0556ff7b8e3 1321 IOTHUB_CLIENT_ERROR if IoTHubTransport_SetOption returns ERROR*/
markrad 3:c0556ff7b8e3 1322
markrad 3:c0556ff7b8e3 1323 (uploadToBlob_result == IOTHUB_CLIENT_INVALID_ARG) ? handleData->IoTHubTransport_SetOption(handleData->transportHandle, optionName, value) :
markrad 3:c0556ff7b8e3 1324 (uploadToBlob_result == IOTHUB_CLIENT_ERROR) ? IOTHUB_CLIENT_ERROR :
markrad 3:c0556ff7b8e3 1325 (handleData->IoTHubTransport_SetOption(handleData->transportHandle, optionName, value) == IOTHUB_CLIENT_ERROR) ? IOTHUB_CLIENT_ERROR : IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1326
markrad 3:c0556ff7b8e3 1327 if (result != IOTHUB_CLIENT_OK)
markrad 3:c0556ff7b8e3 1328 {
markrad 3:c0556ff7b8e3 1329 LogError("underlying transport failed, returned = %s", ENUM_TO_STRING(IOTHUB_CLIENT_RESULT, result));
markrad 3:c0556ff7b8e3 1330 }
markrad 3:c0556ff7b8e3 1331 }
markrad 3:c0556ff7b8e3 1332 }
markrad 3:c0556ff7b8e3 1333 return result;
markrad 3:c0556ff7b8e3 1334 }
markrad 3:c0556ff7b8e3 1335
markrad 3:c0556ff7b8e3 1336 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceTwinCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 1337 {
markrad 3:c0556ff7b8e3 1338 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1339 /* Codes_SRS_IOTHUBCLIENT_LL_10_001: [ IoTHubClient_LL_SetDeviceTwinCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL.] */
markrad 3:c0556ff7b8e3 1340 if (iotHubClientHandle == NULL)
markrad 3:c0556ff7b8e3 1341 {
markrad 3:c0556ff7b8e3 1342 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1343 LogError("Invalid argument specified iothubClientHandle=%p", iotHubClientHandle);
markrad 3:c0556ff7b8e3 1344 }
markrad 3:c0556ff7b8e3 1345 else
markrad 3:c0556ff7b8e3 1346 {
markrad 3:c0556ff7b8e3 1347 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1348 if (deviceTwinCallback == NULL)
markrad 3:c0556ff7b8e3 1349 {
markrad 3:c0556ff7b8e3 1350 /* Codes_SRS_IOTHUBCLIENT_LL_10_006: [ If deviceTwinCallback is NULL, then IoTHubClient_LL_SetDeviceTwinCallback shall call the underlying layer's _Unsubscribe function and return IOTHUB_CLIENT_OK.] */
markrad 3:c0556ff7b8e3 1351 handleData->IoTHubTransport_Unsubscribe_DeviceTwin(handleData->transportHandle);
markrad 3:c0556ff7b8e3 1352 handleData->deviceTwinCallback = NULL;
markrad 3:c0556ff7b8e3 1353 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1354 }
markrad 3:c0556ff7b8e3 1355 else
markrad 3:c0556ff7b8e3 1356 {
markrad 3:c0556ff7b8e3 1357 /* Codes_SRS_IOTHUBCLIENT_LL_10_002: [ If deviceTwinCallback is not NULL, then IoTHubClient_LL_SetDeviceTwinCallback shall call the underlying layer's _Subscribe function.] */
markrad 3:c0556ff7b8e3 1358 if (handleData->IoTHubTransport_Subscribe_DeviceTwin(handleData->transportHandle) == 0)
markrad 3:c0556ff7b8e3 1359 {
markrad 3:c0556ff7b8e3 1360 handleData->deviceTwinCallback = deviceTwinCallback;
markrad 3:c0556ff7b8e3 1361 handleData->deviceTwinContextCallback = userContextCallback;
markrad 3:c0556ff7b8e3 1362 /* Codes_SRS_IOTHUBCLIENT_LL_10_005: [ Otherwise IoTHubClient_LL_SetDeviceTwinCallback shall succeed and return IOTHUB_CLIENT_OK.] */
markrad 3:c0556ff7b8e3 1363 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1364 }
markrad 3:c0556ff7b8e3 1365 else
markrad 3:c0556ff7b8e3 1366 {
markrad 3:c0556ff7b8e3 1367 /* Codes_SRS_IOTHUBCLIENT_LL_10_003: [ If the underlying layer's _Subscribe function fails, then IoTHubClient_LL_SetDeviceTwinCallback shall fail and return IOTHUB_CLIENT_ERROR.] */
markrad 3:c0556ff7b8e3 1368 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1369 }
markrad 3:c0556ff7b8e3 1370 }
markrad 3:c0556ff7b8e3 1371 }
markrad 3:c0556ff7b8e3 1372 return result;
markrad 3:c0556ff7b8e3 1373 }
markrad 3:c0556ff7b8e3 1374
markrad 3:c0556ff7b8e3 1375 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SendReportedState(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 1376 {
markrad 3:c0556ff7b8e3 1377 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1378 /* Codes_SRS_IOTHUBCLIENT_LL_10_012: [ IoTHubClient_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL. ] */
markrad 3:c0556ff7b8e3 1379 /* Codes_SRS_IOTHUBCLIENT_LL_10_013: [ IoTHubClient_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter reportedState is NULL] */
markrad 3:c0556ff7b8e3 1380 /* Codes_SRS_IOTHUBCLIENT_LL_07_005: [ IoTHubClient_LL_SendReportedState shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter size is equal to 0. ] */
markrad 3:c0556ff7b8e3 1381 if (iotHubClientHandle == NULL || (reportedState == NULL || size == 0) )
markrad 3:c0556ff7b8e3 1382 {
markrad 3:c0556ff7b8e3 1383 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1384 LogError("Invalid argument specified iothubClientHandle=%p, reportedState=%p, size=%zu", iotHubClientHandle, reportedState, size);
markrad 3:c0556ff7b8e3 1385 }
markrad 3:c0556ff7b8e3 1386 else
markrad 3:c0556ff7b8e3 1387 {
markrad 3:c0556ff7b8e3 1388 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1389 /* Codes_SRS_IOTHUBCLIENT_LL_10_014: [IoTHubClient_LL_SendReportedState shall construct and queue the reported a Device_Twin structure for transmition by the underlying transport.] */
markrad 3:c0556ff7b8e3 1390 IOTHUB_DEVICE_TWIN* client_data = dev_twin_data_create(handleData, get_next_item_id(handleData), reportedState, size, reportedStateCallback, userContextCallback);
markrad 3:c0556ff7b8e3 1391 if (client_data == NULL)
markrad 3:c0556ff7b8e3 1392 {
markrad 3:c0556ff7b8e3 1393 /* Codes_SRS_IOTHUBCLIENT_LL_10_015: [If any error is encountered IoTHubClient_LL_SendReportedState shall return IOTHUB_CLIENT_ERROR.] */
markrad 3:c0556ff7b8e3 1394 LogError("Failure constructing device twin data");
markrad 3:c0556ff7b8e3 1395 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1396 }
markrad 3:c0556ff7b8e3 1397 else
markrad 3:c0556ff7b8e3 1398 {
markrad 3:c0556ff7b8e3 1399 if (handleData->IoTHubTransport_Subscribe_DeviceTwin(handleData->transportHandle) != 0)
markrad 3:c0556ff7b8e3 1400 {
markrad 3:c0556ff7b8e3 1401 LogError("Failure adding device twin data to queue");
markrad 3:c0556ff7b8e3 1402 device_twin_data_destroy(client_data);
markrad 3:c0556ff7b8e3 1403 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1404 }
markrad 3:c0556ff7b8e3 1405 else
markrad 3:c0556ff7b8e3 1406 {
markrad 3:c0556ff7b8e3 1407 /* Codes_SRS_IOTHUBCLIENT_LL_07_001: [ IoTHubClient_LL_SendReportedState shall queue the constructed reportedState data to be consumed by the targeted transport. ] */
markrad 3:c0556ff7b8e3 1408 DList_InsertTailList(&(iotHubClientHandle->iot_msg_queue), &(client_data->entry));
markrad 3:c0556ff7b8e3 1409
markrad 3:c0556ff7b8e3 1410 /* Codes_SRS_IOTHUBCLIENT_LL_10_016: [ Otherwise IoTHubClient_LL_SendReportedState shall succeed and return IOTHUB_CLIENT_OK.] */
markrad 3:c0556ff7b8e3 1411 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1412 }
markrad 3:c0556ff7b8e3 1413 }
markrad 3:c0556ff7b8e3 1414 }
markrad 3:c0556ff7b8e3 1415 return result;
markrad 3:c0556ff7b8e3 1416 }
markrad 3:c0556ff7b8e3 1417
markrad 3:c0556ff7b8e3 1418 IOTHUB_CLIENT_RESULT IoTHubClient_LL_SetDeviceMethodCallback(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
markrad 3:c0556ff7b8e3 1419 {
markrad 3:c0556ff7b8e3 1420 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1421
markrad 3:c0556ff7b8e3 1422 /*Codes_SRS_IOTHUBCLIENT_LL_12_017: [ IoTHubClient_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_INVALID_ARG if parameter iotHubClientHandle is NULL. ] */
markrad 3:c0556ff7b8e3 1423 if (iotHubClientHandle == NULL)
markrad 3:c0556ff7b8e3 1424 {
markrad 3:c0556ff7b8e3 1425 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1426 LOG_ERROR_RESULT;
markrad 3:c0556ff7b8e3 1427 }
markrad 3:c0556ff7b8e3 1428 else
markrad 3:c0556ff7b8e3 1429 {
markrad 3:c0556ff7b8e3 1430 IOTHUB_CLIENT_LL_HANDLE_DATA* handleData = (IOTHUB_CLIENT_LL_HANDLE_DATA*)iotHubClientHandle;
markrad 3:c0556ff7b8e3 1431 if (deviceMethodCallback == NULL)
markrad 3:c0556ff7b8e3 1432 {
markrad 3:c0556ff7b8e3 1433 /*Codes_SRS_IOTHUBCLIENT_LL_12_018: [If deviceMethodCallback is NULL, then IoTHubClient_LL_SetDeviceMethodCallback shall call the underlying layer's IoTHubTransport_Unsubscribe_DeviceMethod function and return IOTHUB_CLIENT_OK. ] */
markrad 3:c0556ff7b8e3 1434 /*Codes_SRS_IOTHUBCLIENT_LL_12_022: [ Otherwise IoTHubClient_LL_SetDeviceMethodCallback shall succeed and return IOTHUB_CLIENT_OK. ]*/
markrad 3:c0556ff7b8e3 1435 handleData->IoTHubTransport_Unsubscribe_DeviceMethod(handleData->transportHandle);
markrad 3:c0556ff7b8e3 1436 handleData->deviceMethodCallback = NULL;
markrad 3:c0556ff7b8e3 1437 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1438 }
markrad 3:c0556ff7b8e3 1439 else
markrad 3:c0556ff7b8e3 1440 {
markrad 3:c0556ff7b8e3 1441 /*Codes_SRS_IOTHUBCLIENT_LL_12_019: [ If deviceMethodCallback is not NULL, then IoTHubClient_LL_SetDeviceMethodCallback shall call the underlying layer's IoTHubTransport_Subscribe_DeviceMethod function. ]*/
markrad 3:c0556ff7b8e3 1442 if (handleData->IoTHubTransport_Subscribe_DeviceMethod(handleData->deviceHandle) == 0)
markrad 3:c0556ff7b8e3 1443 {
markrad 3:c0556ff7b8e3 1444 /*Codes_SRS_IOTHUBCLIENT_LL_12_022: [ Otherwise IoTHubClient_LL_SetDeviceMethodCallback shall succeed and return IOTHUB_CLIENT_OK. ]*/
markrad 3:c0556ff7b8e3 1445 handleData->deviceMethodCallback = deviceMethodCallback;
markrad 3:c0556ff7b8e3 1446 handleData->deviceMethodUserContextCallback = userContextCallback;
markrad 3:c0556ff7b8e3 1447 result = IOTHUB_CLIENT_OK;
markrad 3:c0556ff7b8e3 1448 }
markrad 3:c0556ff7b8e3 1449 else
markrad 3:c0556ff7b8e3 1450 {
markrad 3:c0556ff7b8e3 1451 /*Codes_SRS_IOTHUBCLIENT_LL_12_020: [ If the underlying layer's IoTHubTransport_Subscribe_DeviceMethod function fails, then IoTHubClient_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ]*/
markrad 3:c0556ff7b8e3 1452 /*Codes_SRS_IOTHUBCLIENT_LL_12_021: [ If adding the information fails for any reason, IoTHubClient_LL_SetDeviceMethodCallback shall fail and return IOTHUB_CLIENT_ERROR. ]*/
markrad 3:c0556ff7b8e3 1453 result = IOTHUB_CLIENT_ERROR;
markrad 3:c0556ff7b8e3 1454 }
markrad 3:c0556ff7b8e3 1455 }
markrad 3:c0556ff7b8e3 1456 }
markrad 3:c0556ff7b8e3 1457 return result;
markrad 3:c0556ff7b8e3 1458 }
markrad 3:c0556ff7b8e3 1459
markrad 3:c0556ff7b8e3 1460 #ifndef DONT_USE_UPLOADTOBLOB
markrad 3:c0556ff7b8e3 1461 IOTHUB_CLIENT_RESULT IoTHubClient_LL_UploadToBlob(IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size)
markrad 3:c0556ff7b8e3 1462 {
markrad 3:c0556ff7b8e3 1463 IOTHUB_CLIENT_RESULT result;
markrad 3:c0556ff7b8e3 1464 /*Codes_SRS_IOTHUBCLIENT_LL_02_061: [ If iotHubClientHandle is NULL then IoTHubClient_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
markrad 3:c0556ff7b8e3 1465 /*Codes_SRS_IOTHUBCLIENT_LL_02_062: [ If destinationFileName is NULL then IoTHubClient_LL_UploadToBlob shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
markrad 3:c0556ff7b8e3 1466 if (
markrad 3:c0556ff7b8e3 1467 (iotHubClientHandle == NULL) ||
markrad 3:c0556ff7b8e3 1468 (destinationFileName == NULL) ||
markrad 3:c0556ff7b8e3 1469 ((source == NULL) && (size >0))
markrad 3:c0556ff7b8e3 1470 )
markrad 3:c0556ff7b8e3 1471 {
markrad 3:c0556ff7b8e3 1472 LogError("invalid parameters IOTHUB_CLIENT_LL_HANDLE iotHubClientHandle=%p, const char* destinationFileName=%s, const unsigned char* source=%p, size_t size=%zu", iotHubClientHandle, destinationFileName, source, size);
markrad 3:c0556ff7b8e3 1473 result = IOTHUB_CLIENT_INVALID_ARG;
markrad 3:c0556ff7b8e3 1474 }
markrad 3:c0556ff7b8e3 1475 else
markrad 3:c0556ff7b8e3 1476 {
markrad 3:c0556ff7b8e3 1477 result = IoTHubClient_LL_UploadToBlob_Impl(iotHubClientHandle->uploadToBlobHandle, destinationFileName, source, size);
markrad 3:c0556ff7b8e3 1478 }
markrad 3:c0556ff7b8e3 1479 return result;
markrad 3:c0556ff7b8e3 1480 }
markrad 3:c0556ff7b8e3 1481 #endif