Microsoft Azure IoTHub client libraries

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more

This library implements the Microsoft Azure IoTHub client library. The code is replicated from https://github.com/Azure/azure-iot-sdks

Committer:
AzureIoTClient
Date:
Fri Mar 10 11:47:36 2017 -0800
Revision:
61:8b85a4e797cf
Parent:
60:41648c4e7036
Child:
62:5a4cdacf5090
1.1.9

Who changed what in which revision?

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