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:
Sat Jan 28 09:34:27 2017 -0800
Revision:
58:15b0d29b2667
Parent:
57:4524910c6445
Child:
59:7e89be231352
1.1.6

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 54:6dcad9019a64 5 #include "azure_c_shared_utility/umock_c_prod.h"
Azure.IoT Build 38:a05929a75111 6 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 16:deba40344375 7
AzureIoTClient 16:deba40344375 8 #include <signal.h>
Azure.IoT Build 35:ceed20da4ba6 9 #include <stddef.h>
Azure.IoT Build 38:a05929a75111 10 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 16:deba40344375 11 #include "iothub_client.h"
AzureIoTClient 16:deba40344375 12 #include "iothub_client_ll.h"
Azure.IoT Build 37:18310e4d888d 13 #include "iothubtransport.h"
Azure.IoT Build 38:a05929a75111 14 #include "azure_c_shared_utility/threadapi.h"
Azure.IoT Build 38:a05929a75111 15 #include "azure_c_shared_utility/lock.h"
Azure.IoT Build 45:54c11b1b1407 16 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 52:1cc3c6d07cad 17 #include "azure_c_shared_utility/singlylinkedlist.h"
Azure.IoT.Build 54:6dcad9019a64 18 #include "azure_c_shared_utility/vector.h"
AzureIoTClient 16:deba40344375 19
AzureIoTClient 55:59b527ab3452 20 struct IOTHUB_QUEUE_CONTEXT_TAG;
AzureIoTClient 55:59b527ab3452 21
AzureIoTClient 16:deba40344375 22 typedef struct IOTHUB_CLIENT_INSTANCE_TAG
AzureIoTClient 16:deba40344375 23 {
AzureIoTClient 16:deba40344375 24 IOTHUB_CLIENT_LL_HANDLE IoTHubClientLLHandle;
AzureIoTClient 42:448eecc3676e 25 TRANSPORT_HANDLE TransportHandle;
AzureIoTClient 16:deba40344375 26 THREAD_HANDLE ThreadHandle;
AzureIoTClient 16:deba40344375 27 LOCK_HANDLE LockHandle;
AzureIoTClient 16:deba40344375 28 sig_atomic_t StopThread;
AzureIoTClient 44:33dd78697616 29 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 52:1cc3c6d07cad 30 SINGLYLINKEDLIST_HANDLE savedDataToBeCleaned; /*list containing UPLOADTOBLOB_SAVED_DATA*/
AzureIoTClient 43:038d8511e817 31 #endif
Azure.IoT.Build 54:6dcad9019a64 32 int created_with_transport_handle;
Azure.IoT.Build 54:6dcad9019a64 33 VECTOR_HANDLE saved_user_callback_list;
Azure.IoT.Build 54:6dcad9019a64 34 IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK desired_state_callback;
Azure.IoT.Build 54:6dcad9019a64 35 IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK event_confirm_callback;
Azure.IoT.Build 54:6dcad9019a64 36 IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reported_state_callback;
Azure.IoT.Build 54:6dcad9019a64 37 IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connection_status_callback;
AzureIoTClient 55:59b527ab3452 38 IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK device_method_callback;
AzureIoTClient 55:59b527ab3452 39 struct IOTHUB_QUEUE_CONTEXT_TAG* devicetwin_user_context;
AzureIoTClient 55:59b527ab3452 40 struct IOTHUB_QUEUE_CONTEXT_TAG* connection_status_user_context;
AzureIoTClient 16:deba40344375 41 } IOTHUB_CLIENT_INSTANCE;
AzureIoTClient 16:deba40344375 42
AzureIoTClient 44:33dd78697616 43 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 44 typedef struct UPLOADTOBLOB_SAVED_DATA_TAG
AzureIoTClient 42:448eecc3676e 45 {
AzureIoTClient 42:448eecc3676e 46 unsigned char* source;
AzureIoTClient 42:448eecc3676e 47 size_t size;
AzureIoTClient 42:448eecc3676e 48 char* destinationFileName;
AzureIoTClient 42:448eecc3676e 49 IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback;
AzureIoTClient 42:448eecc3676e 50 void* context;
AzureIoTClient 42:448eecc3676e 51 THREAD_HANDLE uploadingThreadHandle;
AzureIoTClient 42:448eecc3676e 52 IOTHUB_CLIENT_HANDLE iotHubClientHandle;
AzureIoTClient 42:448eecc3676e 53 LOCK_HANDLE lockGarbage;
AzureIoTClient 42:448eecc3676e 54 int canBeGarbageCollected; /*flag indicating that the UPLOADTOBLOB_SAVED_DATA structure can be freed because the thread deadling with it finished*/
AzureIoTClient 42:448eecc3676e 55 }UPLOADTOBLOB_SAVED_DATA;
AzureIoTClient 43:038d8511e817 56 #endif
AzureIoTClient 42:448eecc3676e 57
Azure.IoT.Build 54:6dcad9019a64 58 #define USER_CALLBACK_TYPE_VALUES \
Azure.IoT.Build 54:6dcad9019a64 59 CALLBACK_TYPE_DEVICE_TWIN, \
Azure.IoT.Build 54:6dcad9019a64 60 CALLBACK_TYPE_EVENT_CONFIRM, \
Azure.IoT.Build 54:6dcad9019a64 61 CALLBACK_TYPE_REPORTED_STATE, \
AzureIoTClient 55:59b527ab3452 62 CALLBACK_TYPE_CONNECTION_STATUS, \
AzureIoTClient 55:59b527ab3452 63 CALLBACK_TYPE_DEVICE_METHOD
Azure.IoT.Build 54:6dcad9019a64 64
Azure.IoT.Build 54:6dcad9019a64 65 DEFINE_ENUM(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
AzureIoTClient 56:fdda9c1244e4 66 DEFINE_ENUM_STRINGS(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
Azure.IoT.Build 54:6dcad9019a64 67
Azure.IoT.Build 54:6dcad9019a64 68 typedef struct DEVICE_TWIN_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 69 {
Azure.IoT.Build 54:6dcad9019a64 70 DEVICE_TWIN_UPDATE_STATE update_state;
Azure.IoT.Build 54:6dcad9019a64 71 unsigned char* payLoad;
Azure.IoT.Build 54:6dcad9019a64 72 size_t size;
Azure.IoT.Build 54:6dcad9019a64 73 } DEVICE_TWIN_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 74
Azure.IoT.Build 54:6dcad9019a64 75 typedef struct EVENT_CONFIRM_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 76 {
Azure.IoT.Build 54:6dcad9019a64 77 IOTHUB_CLIENT_CONFIRMATION_RESULT confirm_result;
Azure.IoT.Build 54:6dcad9019a64 78 } EVENT_CONFIRM_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 79
Azure.IoT.Build 54:6dcad9019a64 80 typedef struct REPORTED_STATE_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 81 {
Azure.IoT.Build 54:6dcad9019a64 82 int status_code;
Azure.IoT.Build 54:6dcad9019a64 83 } REPORTED_STATE_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 84
Azure.IoT.Build 54:6dcad9019a64 85 typedef struct CONNECTION_STATUS_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 86 {
Azure.IoT.Build 54:6dcad9019a64 87 IOTHUB_CLIENT_CONNECTION_STATUS connection_status;
Azure.IoT.Build 54:6dcad9019a64 88 IOTHUB_CLIENT_CONNECTION_STATUS_REASON status_reason;
Azure.IoT.Build 54:6dcad9019a64 89 } CONNECTION_STATUS_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 90
Azure.IoT.Build 54:6dcad9019a64 91 typedef struct METHOD_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 92 {
AzureIoTClient 55:59b527ab3452 93 STRING_HANDLE method_name;
AzureIoTClient 55:59b527ab3452 94 BUFFER_HANDLE payload;
AzureIoTClient 55:59b527ab3452 95 METHOD_HANDLE method_id;
Azure.IoT.Build 54:6dcad9019a64 96 } METHOD_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 97
Azure.IoT.Build 54:6dcad9019a64 98 typedef struct USER_CALLBACK_INFO_TAG
Azure.IoT.Build 54:6dcad9019a64 99 {
Azure.IoT.Build 54:6dcad9019a64 100 USER_CALLBACK_TYPE type;
Azure.IoT.Build 54:6dcad9019a64 101 void* userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 102 union IOTHUB_CALLBACK
Azure.IoT.Build 54:6dcad9019a64 103 {
Azure.IoT.Build 54:6dcad9019a64 104 DEVICE_TWIN_CALLBACK_INFO dev_twin_cb_info;
Azure.IoT.Build 54:6dcad9019a64 105 EVENT_CONFIRM_CALLBACK_INFO event_confirm_cb_info;
Azure.IoT.Build 54:6dcad9019a64 106 REPORTED_STATE_CALLBACK_INFO reported_state_cb_info;
Azure.IoT.Build 54:6dcad9019a64 107 CONNECTION_STATUS_CALLBACK_INFO connection_status_cb_info;
AzureIoTClient 55:59b527ab3452 108 METHOD_CALLBACK_INFO method_cb_info;
Azure.IoT.Build 54:6dcad9019a64 109 } iothub_callback;
Azure.IoT.Build 54:6dcad9019a64 110 } USER_CALLBACK_INFO;
Azure.IoT.Build 54:6dcad9019a64 111
Azure.IoT.Build 54:6dcad9019a64 112 typedef struct IOTHUB_QUEUE_CONTEXT_TAG
Azure.IoT.Build 54:6dcad9019a64 113 {
Azure.IoT.Build 54:6dcad9019a64 114 IOTHUB_CLIENT_INSTANCE* iotHubClientHandle;
Azure.IoT.Build 54:6dcad9019a64 115 void* userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 116 } IOTHUB_QUEUE_CONTEXT;
Azure.IoT.Build 54:6dcad9019a64 117
Azure.IoT Build 35:ceed20da4ba6 118 /*used by unittests only*/
Azure.IoT Build 35:ceed20da4ba6 119 const size_t IoTHubClient_ThreadTerminationOffset = offsetof(IOTHUB_CLIENT_INSTANCE, StopThread);
Azure.IoT Build 35:ceed20da4ba6 120
AzureIoTClient 44:33dd78697616 121 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 122 /*this function is called from _Destroy and from ScheduleWork_Thread to join finished blobUpload threads and free that memory*/
AzureIoTClient 42:448eecc3676e 123 static void garbageCollectorImpl(IOTHUB_CLIENT_INSTANCE* iotHubClientInstance)
AzureIoTClient 42:448eecc3676e 124 {
AzureIoTClient 42:448eecc3676e 125 /*see if any savedData structures can be disposed of*/
AzureIoTClient 42:448eecc3676e 126 /*Codes_SRS_IOTHUBCLIENT_02_072: [ All threads marked as disposable (upon completion of a file upload) shall be joined and the data structures build for them shall be freed. ]*/
AzureIoTClient 52:1cc3c6d07cad 127 LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(iotHubClientInstance->savedDataToBeCleaned);
AzureIoTClient 42:448eecc3676e 128 while (item != NULL)
AzureIoTClient 42:448eecc3676e 129 {
AzureIoTClient 52:1cc3c6d07cad 130 const UPLOADTOBLOB_SAVED_DATA* savedData = (const UPLOADTOBLOB_SAVED_DATA*)singlylinkedlist_item_get_value(item);
AzureIoTClient 42:448eecc3676e 131 LIST_ITEM_HANDLE old_item = item;
AzureIoTClient 52:1cc3c6d07cad 132 item = singlylinkedlist_get_next_item(item);
AzureIoTClient 42:448eecc3676e 133
AzureIoTClient 42:448eecc3676e 134 if (Lock(savedData->lockGarbage) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 135 {
AzureIoTClient 43:038d8511e817 136 LogError("unable to Lock");
AzureIoTClient 42:448eecc3676e 137 }
AzureIoTClient 42:448eecc3676e 138 else
AzureIoTClient 42:448eecc3676e 139 {
AzureIoTClient 42:448eecc3676e 140 if (savedData->canBeGarbageCollected == 1)
AzureIoTClient 42:448eecc3676e 141 {
AzureIoTClient 42:448eecc3676e 142 int notUsed;
AzureIoTClient 42:448eecc3676e 143 if (ThreadAPI_Join(savedData->uploadingThreadHandle, &notUsed) != THREADAPI_OK)
AzureIoTClient 42:448eecc3676e 144 {
AzureIoTClient 42:448eecc3676e 145 LogError("unable to ThreadAPI_Join");
AzureIoTClient 42:448eecc3676e 146 }
AzureIoTClient 52:1cc3c6d07cad 147 (void)singlylinkedlist_remove(iotHubClientInstance->savedDataToBeCleaned, old_item);
AzureIoTClient 42:448eecc3676e 148 free((void*)savedData->source);
AzureIoTClient 42:448eecc3676e 149 free((void*)savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 150
AzureIoTClient 42:448eecc3676e 151 if (Unlock(savedData->lockGarbage) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 152 {
AzureIoTClient 42:448eecc3676e 153 LogError("unable to unlock after locking");
AzureIoTClient 42:448eecc3676e 154 }
AzureIoTClient 42:448eecc3676e 155 (void)Lock_Deinit(savedData->lockGarbage);
AzureIoTClient 42:448eecc3676e 156 free((void*)savedData);
AzureIoTClient 42:448eecc3676e 157 }
AzureIoTClient 42:448eecc3676e 158 else
AzureIoTClient 42:448eecc3676e 159 {
AzureIoTClient 42:448eecc3676e 160 if (Unlock(savedData->lockGarbage) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 161 {
AzureIoTClient 42:448eecc3676e 162 LogError("unable to unlock after locking");
AzureIoTClient 42:448eecc3676e 163 }
AzureIoTClient 42:448eecc3676e 164 }
AzureIoTClient 42:448eecc3676e 165 }
AzureIoTClient 42:448eecc3676e 166 }
AzureIoTClient 42:448eecc3676e 167 }
AzureIoTClient 43:038d8511e817 168 #endif
AzureIoTClient 42:448eecc3676e 169
Azure.IoT.Build 54:6dcad9019a64 170 static IOTHUBMESSAGE_DISPOSITION_RESULT iothub_ll_message_callback(IOTHUB_MESSAGE_HANDLE message, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 171 {
Azure.IoT.Build 54:6dcad9019a64 172 (void)message;
Azure.IoT.Build 54:6dcad9019a64 173 (void)userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 174 return IOTHUBMESSAGE_ABANDONED;
Azure.IoT.Build 54:6dcad9019a64 175 }
Azure.IoT.Build 54:6dcad9019a64 176
AzureIoTClient 55:59b527ab3452 177 static int iothub_ll_inbound_device_method_callback(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 178 {
AzureIoTClient 55:59b527ab3452 179 int result;
AzureIoTClient 55:59b527ab3452 180 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 55:59b527ab3452 181 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [ if userContextCallback is NULL, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a nonNULL value. ] */
AzureIoTClient 55:59b527ab3452 182 if (queue_context != NULL)
AzureIoTClient 55:59b527ab3452 183 {
AzureIoTClient 55:59b527ab3452 184 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [ IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall copy the method_name and payload. ] */
AzureIoTClient 55:59b527ab3452 185 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 55:59b527ab3452 186 queue_cb_info.type = CALLBACK_TYPE_DEVICE_METHOD;
AzureIoTClient 55:59b527ab3452 187 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 55:59b527ab3452 188 queue_cb_info.iothub_callback.method_cb_info.method_id = method_id;
AzureIoTClient 55:59b527ab3452 189 if ( (queue_cb_info.iothub_callback.method_cb_info.method_name = STRING_construct(method_name)) == NULL)
AzureIoTClient 55:59b527ab3452 190 {
AzureIoTClient 55:59b527ab3452 191 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 55:59b527ab3452 192 LogError("Failure: STRING_construct");
AzureIoTClient 55:59b527ab3452 193 result = __LINE__;
AzureIoTClient 55:59b527ab3452 194 }
AzureIoTClient 55:59b527ab3452 195 else if ((queue_cb_info.iothub_callback.method_cb_info.payload = BUFFER_create(payload, size)) == NULL)
AzureIoTClient 55:59b527ab3452 196 {
AzureIoTClient 55:59b527ab3452 197 STRING_delete(queue_cb_info.iothub_callback.method_cb_info.method_name);
AzureIoTClient 55:59b527ab3452 198 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 55:59b527ab3452 199 LogError("Failure: BUFFER_create");
AzureIoTClient 55:59b527ab3452 200 result = __LINE__;
AzureIoTClient 55:59b527ab3452 201 }
AzureIoTClient 55:59b527ab3452 202 else if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 55:59b527ab3452 203 {
AzureIoTClient 55:59b527ab3452 204 STRING_delete(queue_cb_info.iothub_callback.method_cb_info.method_name);
AzureIoTClient 55:59b527ab3452 205 BUFFER_delete(queue_cb_info.iothub_callback.method_cb_info.payload);
AzureIoTClient 55:59b527ab3452 206 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 55:59b527ab3452 207 LogError("connection status callback vector push failed.");
AzureIoTClient 55:59b527ab3452 208 result = __LINE__;
AzureIoTClient 55:59b527ab3452 209 }
AzureIoTClient 55:59b527ab3452 210 else
AzureIoTClient 55:59b527ab3452 211 {
AzureIoTClient 55:59b527ab3452 212 /*Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_004: [ On success IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a 0 value. ]*/
AzureIoTClient 55:59b527ab3452 213 result = 0;
AzureIoTClient 55:59b527ab3452 214 }
AzureIoTClient 55:59b527ab3452 215 free(queue_context);
AzureIoTClient 55:59b527ab3452 216 }
AzureIoTClient 55:59b527ab3452 217 else
AzureIoTClient 55:59b527ab3452 218 {
AzureIoTClient 55:59b527ab3452 219 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 55:59b527ab3452 220 LogError("Invalid parameter: userContextCallback NULL");
AzureIoTClient 55:59b527ab3452 221 result = __LINE__;
AzureIoTClient 55:59b527ab3452 222 }
AzureIoTClient 55:59b527ab3452 223 return result;
Azure.IoT.Build 54:6dcad9019a64 224 }
Azure.IoT.Build 54:6dcad9019a64 225
Azure.IoT.Build 54:6dcad9019a64 226 static void iothub_ll_connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 227 {
Azure.IoT.Build 54:6dcad9019a64 228 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 229 if (queue_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 230 {
Azure.IoT.Build 54:6dcad9019a64 231 USER_CALLBACK_INFO queue_cb_info;
Azure.IoT.Build 54:6dcad9019a64 232 queue_cb_info.type = CALLBACK_TYPE_CONNECTION_STATUS;
Azure.IoT.Build 54:6dcad9019a64 233 queue_cb_info.userContextCallback = queue_context->userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 234 queue_cb_info.iothub_callback.connection_status_cb_info.status_reason = reason;
Azure.IoT.Build 54:6dcad9019a64 235 queue_cb_info.iothub_callback.connection_status_cb_info.connection_status = result;
Azure.IoT.Build 54:6dcad9019a64 236 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
Azure.IoT.Build 54:6dcad9019a64 237 {
Azure.IoT.Build 54:6dcad9019a64 238 LogError("connection status callback vector push failed.");
Azure.IoT.Build 54:6dcad9019a64 239 }
Azure.IoT.Build 54:6dcad9019a64 240 }
Azure.IoT.Build 54:6dcad9019a64 241 }
Azure.IoT.Build 54:6dcad9019a64 242
Azure.IoT.Build 54:6dcad9019a64 243 static void iothub_ll_event_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 244 {
Azure.IoT.Build 54:6dcad9019a64 245 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 246 if (queue_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 247 {
Azure.IoT.Build 54:6dcad9019a64 248 USER_CALLBACK_INFO queue_cb_info;
Azure.IoT.Build 54:6dcad9019a64 249 queue_cb_info.type = CALLBACK_TYPE_EVENT_CONFIRM;
Azure.IoT.Build 54:6dcad9019a64 250 queue_cb_info.userContextCallback = queue_context->userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 251 queue_cb_info.iothub_callback.event_confirm_cb_info.confirm_result = result;
Azure.IoT.Build 54:6dcad9019a64 252 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
Azure.IoT.Build 54:6dcad9019a64 253 {
Azure.IoT.Build 54:6dcad9019a64 254 LogError("event confirm callback vector push failed.");
Azure.IoT.Build 54:6dcad9019a64 255 }
Azure.IoT.Build 54:6dcad9019a64 256 free(queue_context);
Azure.IoT.Build 54:6dcad9019a64 257 }
Azure.IoT.Build 54:6dcad9019a64 258 }
Azure.IoT.Build 54:6dcad9019a64 259
Azure.IoT.Build 54:6dcad9019a64 260 static void iothub_ll_reported_state_callback(int status_code, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 261 {
Azure.IoT.Build 54:6dcad9019a64 262 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 263 if (queue_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 264 {
Azure.IoT.Build 54:6dcad9019a64 265 USER_CALLBACK_INFO queue_cb_info;
Azure.IoT.Build 54:6dcad9019a64 266 queue_cb_info.type = CALLBACK_TYPE_REPORTED_STATE;
Azure.IoT.Build 54:6dcad9019a64 267 queue_cb_info.userContextCallback = queue_context->userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 268 queue_cb_info.iothub_callback.reported_state_cb_info.status_code = status_code;
Azure.IoT.Build 54:6dcad9019a64 269 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
Azure.IoT.Build 54:6dcad9019a64 270 {
Azure.IoT.Build 54:6dcad9019a64 271 LogError("reported state callback vector push failed.");
Azure.IoT.Build 54:6dcad9019a64 272 }
Azure.IoT.Build 54:6dcad9019a64 273 free(queue_context);
Azure.IoT.Build 54:6dcad9019a64 274 }
Azure.IoT.Build 54:6dcad9019a64 275 }
Azure.IoT.Build 54:6dcad9019a64 276
Azure.IoT.Build 54:6dcad9019a64 277 static void iothub_ll_device_twin_callback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
Azure.IoT.Build 54:6dcad9019a64 278 {
Azure.IoT.Build 54:6dcad9019a64 279 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 280 if (queue_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 281 {
AzureIoTClient 55:59b527ab3452 282 int push_to_vector;
AzureIoTClient 55:59b527ab3452 283
Azure.IoT.Build 54:6dcad9019a64 284 USER_CALLBACK_INFO queue_cb_info;
Azure.IoT.Build 54:6dcad9019a64 285 queue_cb_info.type = CALLBACK_TYPE_DEVICE_TWIN;
Azure.IoT.Build 54:6dcad9019a64 286 queue_cb_info.userContextCallback = queue_context->userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 287 queue_cb_info.iothub_callback.dev_twin_cb_info.update_state = update_state;
Azure.IoT.Build 54:6dcad9019a64 288 if (payLoad == NULL)
Azure.IoT.Build 54:6dcad9019a64 289 {
Azure.IoT.Build 54:6dcad9019a64 290 queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = NULL;
Azure.IoT.Build 54:6dcad9019a64 291 queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
AzureIoTClient 55:59b527ab3452 292 push_to_vector = 0;
Azure.IoT.Build 54:6dcad9019a64 293 }
Azure.IoT.Build 54:6dcad9019a64 294 else
Azure.IoT.Build 54:6dcad9019a64 295 {
Azure.IoT.Build 54:6dcad9019a64 296 queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = (unsigned char*)malloc(size);
Azure.IoT.Build 54:6dcad9019a64 297 if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad == NULL)
Azure.IoT.Build 54:6dcad9019a64 298 {
Azure.IoT.Build 54:6dcad9019a64 299 LogError("failure allocating payload in device twin callback.");
Azure.IoT.Build 54:6dcad9019a64 300 queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
AzureIoTClient 55:59b527ab3452 301 push_to_vector = __LINE__;
Azure.IoT.Build 54:6dcad9019a64 302 }
Azure.IoT.Build 54:6dcad9019a64 303 else
Azure.IoT.Build 54:6dcad9019a64 304 {
AzureIoTClient 55:59b527ab3452 305 (void)memcpy(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad, payLoad, size);
Azure.IoT.Build 54:6dcad9019a64 306 queue_cb_info.iothub_callback.dev_twin_cb_info.size = size;
AzureIoTClient 55:59b527ab3452 307 push_to_vector = 0;
Azure.IoT.Build 54:6dcad9019a64 308 }
Azure.IoT.Build 54:6dcad9019a64 309 }
AzureIoTClient 55:59b527ab3452 310 if (push_to_vector == 0)
Azure.IoT.Build 54:6dcad9019a64 311 {
AzureIoTClient 55:59b527ab3452 312 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 55:59b527ab3452 313 {
AzureIoTClient 55:59b527ab3452 314 if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad != NULL)
AzureIoTClient 55:59b527ab3452 315 {
AzureIoTClient 55:59b527ab3452 316 free(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad);
AzureIoTClient 55:59b527ab3452 317 }
AzureIoTClient 55:59b527ab3452 318 LogError("device twin callback userContextCallback vector push failed.");
AzureIoTClient 55:59b527ab3452 319 }
Azure.IoT.Build 54:6dcad9019a64 320 }
Azure.IoT.Build 54:6dcad9019a64 321 }
Azure.IoT.Build 54:6dcad9019a64 322 else
Azure.IoT.Build 54:6dcad9019a64 323 {
Azure.IoT.Build 54:6dcad9019a64 324 LogError("device twin callback userContextCallback NULL");
Azure.IoT.Build 54:6dcad9019a64 325 }
Azure.IoT.Build 54:6dcad9019a64 326 }
Azure.IoT.Build 54:6dcad9019a64 327
Azure.IoT.Build 54:6dcad9019a64 328 static void dispatch_user_callbacks(IOTHUB_CLIENT_INSTANCE* iotHubClientInstance)
Azure.IoT.Build 54:6dcad9019a64 329 {
Azure.IoT.Build 54:6dcad9019a64 330 if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 331 {
Azure.IoT.Build 54:6dcad9019a64 332 size_t callbacks_length = VECTOR_size(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 57:4524910c6445 333 size_t index = 0;
AzureIoTClient 57:4524910c6445 334 for (index = 0; index < callbacks_length; index++)
Azure.IoT.Build 54:6dcad9019a64 335 {
Azure.IoT.Build 54:6dcad9019a64 336 USER_CALLBACK_INFO* queued_cb = (USER_CALLBACK_INFO*)VECTOR_element(iotHubClientInstance->saved_user_callback_list, index);
Azure.IoT.Build 54:6dcad9019a64 337 if (queued_cb != NULL)
Azure.IoT.Build 54:6dcad9019a64 338 {
Azure.IoT.Build 54:6dcad9019a64 339 switch (queued_cb->type)
Azure.IoT.Build 54:6dcad9019a64 340 {
Azure.IoT.Build 54:6dcad9019a64 341 case CALLBACK_TYPE_DEVICE_TWIN:
Azure.IoT.Build 54:6dcad9019a64 342 if (iotHubClientInstance->desired_state_callback)
Azure.IoT.Build 54:6dcad9019a64 343 {
Azure.IoT.Build 54:6dcad9019a64 344 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 345 iotHubClientInstance->desired_state_callback(queued_cb->iothub_callback.dev_twin_cb_info.update_state, queued_cb->iothub_callback.dev_twin_cb_info.payLoad, queued_cb->iothub_callback.dev_twin_cb_info.size, queued_cb->userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 346 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 347 {
Azure.IoT.Build 54:6dcad9019a64 348 LogError("Failed locking desired callback");
Azure.IoT.Build 54:6dcad9019a64 349 }
Azure.IoT.Build 54:6dcad9019a64 350 }
Azure.IoT.Build 54:6dcad9019a64 351 if (queued_cb->iothub_callback.dev_twin_cb_info.payLoad)
Azure.IoT.Build 54:6dcad9019a64 352 {
Azure.IoT.Build 54:6dcad9019a64 353 free(queued_cb->iothub_callback.dev_twin_cb_info.payLoad);
Azure.IoT.Build 54:6dcad9019a64 354 }
Azure.IoT.Build 54:6dcad9019a64 355 break;
Azure.IoT.Build 54:6dcad9019a64 356 case CALLBACK_TYPE_EVENT_CONFIRM:
Azure.IoT.Build 54:6dcad9019a64 357 if (iotHubClientInstance->event_confirm_callback)
Azure.IoT.Build 54:6dcad9019a64 358 {
Azure.IoT.Build 54:6dcad9019a64 359 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 360 iotHubClientInstance->event_confirm_callback(queued_cb->iothub_callback.event_confirm_cb_info.confirm_result, queued_cb->userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 361 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 362 {
Azure.IoT.Build 54:6dcad9019a64 363 LogError("Failed locking after event confirm callback");
Azure.IoT.Build 54:6dcad9019a64 364 }
Azure.IoT.Build 54:6dcad9019a64 365 }
Azure.IoT.Build 54:6dcad9019a64 366 break;
Azure.IoT.Build 54:6dcad9019a64 367 case CALLBACK_TYPE_REPORTED_STATE:
Azure.IoT.Build 54:6dcad9019a64 368 if (iotHubClientInstance->reported_state_callback)
Azure.IoT.Build 54:6dcad9019a64 369 {
Azure.IoT.Build 54:6dcad9019a64 370 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 371 iotHubClientInstance->reported_state_callback(queued_cb->iothub_callback.reported_state_cb_info.status_code, queued_cb->userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 372 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 373 {
Azure.IoT.Build 54:6dcad9019a64 374 LogError("Failed locking after reported state callback");
Azure.IoT.Build 54:6dcad9019a64 375 }
Azure.IoT.Build 54:6dcad9019a64 376 }
Azure.IoT.Build 54:6dcad9019a64 377 break;
Azure.IoT.Build 54:6dcad9019a64 378 case CALLBACK_TYPE_CONNECTION_STATUS:
Azure.IoT.Build 54:6dcad9019a64 379 if (iotHubClientInstance->connection_status_callback)
Azure.IoT.Build 54:6dcad9019a64 380 {
Azure.IoT.Build 54:6dcad9019a64 381 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 382 iotHubClientInstance->connection_status_callback(queued_cb->iothub_callback.connection_status_cb_info.connection_status, queued_cb->iothub_callback.connection_status_cb_info.status_reason, queued_cb->userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 383 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 384 {
Azure.IoT.Build 54:6dcad9019a64 385 LogError("Failed locking after connection status callback");
Azure.IoT.Build 54:6dcad9019a64 386 }
Azure.IoT.Build 54:6dcad9019a64 387 }
Azure.IoT.Build 54:6dcad9019a64 388 break;
AzureIoTClient 55:59b527ab3452 389 case CALLBACK_TYPE_DEVICE_METHOD:
AzureIoTClient 56:fdda9c1244e4 390 if (iotHubClientInstance->device_method_callback)
AzureIoTClient 55:59b527ab3452 391 {
AzureIoTClient 55:59b527ab3452 392 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 55:59b527ab3452 393 const char* method_name = STRING_c_str(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 55:59b527ab3452 394 const unsigned char* payload = BUFFER_u_char(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 55:59b527ab3452 395 size_t payload_len = BUFFER_length(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 55:59b527ab3452 396 iotHubClientInstance->device_method_callback(method_name, payload, payload_len, queued_cb->iothub_callback.method_cb_info.method_id, queued_cb->userContextCallback);
AzureIoTClient 55:59b527ab3452 397 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 55:59b527ab3452 398 {
AzureIoTClient 55:59b527ab3452 399 LogError("Failed locking after connection status callback");
AzureIoTClient 55:59b527ab3452 400 }
AzureIoTClient 55:59b527ab3452 401 BUFFER_delete(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 55:59b527ab3452 402 STRING_delete(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 55:59b527ab3452 403 }
AzureIoTClient 55:59b527ab3452 404 break;
AzureIoTClient 56:fdda9c1244e4 405 default:
AzureIoTClient 56:fdda9c1244e4 406 LogError("Invalid callback type '%s'", ENUM_TO_STRING(USER_CALLBACK_TYPE, queued_cb->type));
AzureIoTClient 56:fdda9c1244e4 407 break;
Azure.IoT.Build 54:6dcad9019a64 408 }
Azure.IoT.Build 54:6dcad9019a64 409 }
Azure.IoT.Build 54:6dcad9019a64 410 }
Azure.IoT.Build 54:6dcad9019a64 411 VECTOR_clear(iotHubClientInstance->saved_user_callback_list);
Azure.IoT.Build 54:6dcad9019a64 412 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 413 }
Azure.IoT.Build 54:6dcad9019a64 414 else
Azure.IoT.Build 54:6dcad9019a64 415 {
Azure.IoT.Build 54:6dcad9019a64 416 LogError("Unable to aquire lock");
Azure.IoT.Build 54:6dcad9019a64 417 }
Azure.IoT.Build 54:6dcad9019a64 418 }
Azure.IoT.Build 54:6dcad9019a64 419
AzureIoTClient 16:deba40344375 420 static int ScheduleWork_Thread(void* threadArgument)
AzureIoTClient 16:deba40344375 421 {
AzureIoTClient 16:deba40344375 422 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)threadArgument;
AzureIoTClient 42:448eecc3676e 423
Azure.IoT Build 37:18310e4d888d 424 while (1)
AzureIoTClient 16:deba40344375 425 {
AzureIoTClient 16:deba40344375 426 if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
AzureIoTClient 16:deba40344375 427 {
Azure.IoT Build 37:18310e4d888d 428 /*Codes_SRS_IOTHUBCLIENT_01_038: [ The thread shall exit when IoTHubClient_Destroy is called. ]*/
Azure.IoT Build 37:18310e4d888d 429 if (iotHubClientInstance->StopThread)
Azure.IoT Build 37:18310e4d888d 430 {
Azure.IoT Build 37:18310e4d888d 431 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT Build 37:18310e4d888d 432 break; /*gets out of the thread*/
Azure.IoT Build 37:18310e4d888d 433 }
Azure.IoT Build 37:18310e4d888d 434 else
Azure.IoT Build 37:18310e4d888d 435 {
Azure.IoT Build 37:18310e4d888d 436 /* Codes_SRS_IOTHUBCLIENT_01_037: [The thread created by IoTHubClient_SendEvent or IoTHubClient_SetMessageCallback shall call IoTHubClient_LL_DoWork every 1 ms.] */
Azure.IoT Build 37:18310e4d888d 437 /* Codes_SRS_IOTHUBCLIENT_01_039: [All calls to IoTHubClient_LL_DoWork shall be protected by the lock created in IotHubClient_Create.] */
Azure.IoT Build 37:18310e4d888d 438 IoTHubClient_LL_DoWork(iotHubClientInstance->IoTHubClientLLHandle);
AzureIoTClient 42:448eecc3676e 439
AzureIoTClient 44:33dd78697616 440 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 441 garbageCollectorImpl(iotHubClientInstance);
AzureIoTClient 43:038d8511e817 442 #endif
Azure.IoT Build 37:18310e4d888d 443 (void)Unlock(iotHubClientInstance->LockHandle);
Azure.IoT Build 37:18310e4d888d 444 }
AzureIoTClient 16:deba40344375 445 }
Azure.IoT Build 37:18310e4d888d 446 else
Azure.IoT Build 37:18310e4d888d 447 {
Azure.IoT Build 37:18310e4d888d 448 /*Codes_SRS_IOTHUBCLIENT_01_040: [If acquiring the lock fails, IoTHubClient_LL_DoWork shall not be called.]*/
Azure.IoT Build 37:18310e4d888d 449 /*no code, shall retry*/
Azure.IoT Build 37:18310e4d888d 450 }
Azure.IoT.Build 54:6dcad9019a64 451 dispatch_user_callbacks(iotHubClientInstance);
Azure.IoT Build 37:18310e4d888d 452 (void)ThreadAPI_Sleep(1);
AzureIoTClient 16:deba40344375 453 }
AzureIoTClient 42:448eecc3676e 454
AzureIoTClient 16:deba40344375 455 return 0;
AzureIoTClient 16:deba40344375 456 }
AzureIoTClient 16:deba40344375 457
Azure.IoT Build 37:18310e4d888d 458 static IOTHUB_CLIENT_RESULT StartWorkerThreadIfNeeded(IOTHUB_CLIENT_INSTANCE* iotHubClientInstance)
AzureIoTClient 16:deba40344375 459 {
AzureIoTClient 42:448eecc3676e 460 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 42:448eecc3676e 461 if (iotHubClientInstance->TransportHandle == NULL)
AzureIoTClient 42:448eecc3676e 462 {
AzureIoTClient 42:448eecc3676e 463 if (iotHubClientInstance->ThreadHandle == NULL)
AzureIoTClient 42:448eecc3676e 464 {
AzureIoTClient 42:448eecc3676e 465 iotHubClientInstance->StopThread = 0;
AzureIoTClient 42:448eecc3676e 466 if (ThreadAPI_Create(&iotHubClientInstance->ThreadHandle, ScheduleWork_Thread, iotHubClientInstance) != THREADAPI_OK)
AzureIoTClient 42:448eecc3676e 467 {
AzureIoTClient 42:448eecc3676e 468 iotHubClientInstance->ThreadHandle = NULL;
AzureIoTClient 42:448eecc3676e 469 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 470 }
AzureIoTClient 42:448eecc3676e 471 else
AzureIoTClient 42:448eecc3676e 472 {
AzureIoTClient 42:448eecc3676e 473 result = IOTHUB_CLIENT_OK;
AzureIoTClient 42:448eecc3676e 474 }
AzureIoTClient 42:448eecc3676e 475 }
AzureIoTClient 42:448eecc3676e 476 else
AzureIoTClient 42:448eecc3676e 477 {
AzureIoTClient 42:448eecc3676e 478 result = IOTHUB_CLIENT_OK;
AzureIoTClient 42:448eecc3676e 479 }
AzureIoTClient 42:448eecc3676e 480 }
AzureIoTClient 42:448eecc3676e 481 else
AzureIoTClient 42:448eecc3676e 482 {
AzureIoTClient 42:448eecc3676e 483 /*Codes_SRS_IOTHUBCLIENT_17_012: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
AzureIoTClient 42:448eecc3676e 484 /*Codes_SRS_IOTHUBCLIENT_17_011: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread*/
AzureIoTClient 42:448eecc3676e 485 result = IoTHubTransport_StartWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientInstance);
AzureIoTClient 42:448eecc3676e 486 }
AzureIoTClient 42:448eecc3676e 487 return result;
AzureIoTClient 16:deba40344375 488 }
AzureIoTClient 16:deba40344375 489
Azure.IoT.Build 54:6dcad9019a64 490 static IOTHUB_CLIENT_INSTANCE* create_iothub_instance(const IOTHUB_CLIENT_CONFIG* config, TRANSPORT_HANDLE transportHandle, const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
AzureIoTClient 16:deba40344375 491 {
AzureIoTClient 16:deba40344375 492 IOTHUB_CLIENT_INSTANCE* result = (IOTHUB_CLIENT_INSTANCE*)malloc(sizeof(IOTHUB_CLIENT_INSTANCE));
AzureIoTClient 16:deba40344375 493
AzureIoTClient 16:deba40344375 494 /* Codes_SRS_IOTHUBCLIENT_01_004: [If allocating memory for the new IoTHubClient instance fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 16:deba40344375 495 if (result != NULL)
AzureIoTClient 16:deba40344375 496 {
AzureIoTClient 16:deba40344375 497 /* Codes_SRS_IOTHUBCLIENT_01_029: [IoTHubClient_Create shall create a lock object to be used later for serializing IoTHubClient calls.] */
Azure.IoT.Build 54:6dcad9019a64 498 if ( (result->saved_user_callback_list = VECTOR_create(sizeof(USER_CALLBACK_INFO)) ) == NULL)
AzureIoTClient 16:deba40344375 499 {
Azure.IoT.Build 54:6dcad9019a64 500 LogError("Failed creating VECTOR");
AzureIoTClient 16:deba40344375 501 free(result);
AzureIoTClient 16:deba40344375 502 result = NULL;
AzureIoTClient 16:deba40344375 503 }
AzureIoTClient 16:deba40344375 504 else
AzureIoTClient 16:deba40344375 505 {
AzureIoTClient 44:33dd78697616 506 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 52:1cc3c6d07cad 507 /*Codes_SRS_IOTHUBCLIENT_02_060: [ IoTHubClient_Create shall create a SINGLYLINKEDLIST_HANDLE containing THREAD_HANDLE (created by future calls to IoTHubClient_UploadToBlobAsync). ]*/
AzureIoTClient 52:1cc3c6d07cad 508 if ((result->savedDataToBeCleaned = singlylinkedlist_create()) == NULL)
AzureIoTClient 16:deba40344375 509 {
AzureIoTClient 52:1cc3c6d07cad 510 /*Codes_SRS_IOTHUBCLIENT_02_061: [ If creating the SINGLYLINKEDLIST_HANDLE fails then IoTHubClient_Create shall fail and return NULL. ]*/
AzureIoTClient 52:1cc3c6d07cad 511 LogError("unable to singlylinkedlist_create");
Azure.IoT.Build 54:6dcad9019a64 512 VECTOR_destroy(result->saved_user_callback_list);
AzureIoTClient 16:deba40344375 513 free(result);
AzureIoTClient 16:deba40344375 514 result = NULL;
AzureIoTClient 16:deba40344375 515 }
AzureIoTClient 42:448eecc3676e 516 else
AzureIoTClient 43:038d8511e817 517 #endif
AzureIoTClient 42:448eecc3676e 518 {
Azure.IoT.Build 54:6dcad9019a64 519 result->TransportHandle = transportHandle;
Azure.IoT.Build 54:6dcad9019a64 520 result->created_with_transport_handle = 0;
Azure.IoT.Build 54:6dcad9019a64 521 if (config != NULL)
Azure.IoT.Build 54:6dcad9019a64 522 {
Azure.IoT.Build 54:6dcad9019a64 523 if (transportHandle != NULL)
Azure.IoT.Build 54:6dcad9019a64 524 {
Azure.IoT.Build 54:6dcad9019a64 525 /*Codes_SRS_IOTHUBCLIENT_17_005: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLock to get the transport lock to be used later for serializing IoTHubClient calls. ]*/
Azure.IoT.Build 54:6dcad9019a64 526 result->LockHandle = IoTHubTransport_GetLock(transportHandle);
Azure.IoT.Build 54:6dcad9019a64 527 if (result->LockHandle == NULL)
Azure.IoT.Build 54:6dcad9019a64 528 {
Azure.IoT.Build 54:6dcad9019a64 529 LogError("unable to IoTHubTransport_GetLock");
Azure.IoT.Build 54:6dcad9019a64 530 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 531 }
Azure.IoT.Build 54:6dcad9019a64 532 else
Azure.IoT.Build 54:6dcad9019a64 533 {
Azure.IoT.Build 54:6dcad9019a64 534 IOTHUB_CLIENT_DEVICE_CONFIG deviceConfig;
Azure.IoT.Build 54:6dcad9019a64 535 deviceConfig.deviceId = config->deviceId;
Azure.IoT.Build 54:6dcad9019a64 536 deviceConfig.deviceKey = config->deviceKey;
Azure.IoT.Build 54:6dcad9019a64 537 deviceConfig.protocol = config->protocol;
Azure.IoT.Build 54:6dcad9019a64 538 deviceConfig.deviceSasToken = config->deviceSasToken;
Azure.IoT.Build 54:6dcad9019a64 539
Azure.IoT.Build 54:6dcad9019a64 540 /*Codes_SRS_IOTHUBCLIENT_17_003: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLLTransport on transportHandle to get lower layer transport. ]*/
Azure.IoT.Build 54:6dcad9019a64 541 deviceConfig.transportHandle = IoTHubTransport_GetLLTransport(transportHandle);
Azure.IoT.Build 54:6dcad9019a64 542 if (deviceConfig.transportHandle == NULL)
Azure.IoT.Build 54:6dcad9019a64 543 {
Azure.IoT.Build 54:6dcad9019a64 544 LogError("unable to IoTHubTransport_GetLLTransport");
Azure.IoT.Build 54:6dcad9019a64 545 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 546 }
Azure.IoT.Build 54:6dcad9019a64 547 else
Azure.IoT.Build 54:6dcad9019a64 548 {
Azure.IoT.Build 54:6dcad9019a64 549 if (Lock(result->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 550 {
Azure.IoT.Build 54:6dcad9019a64 551 LogError("unable to Lock");
Azure.IoT.Build 54:6dcad9019a64 552 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 553 }
Azure.IoT.Build 54:6dcad9019a64 554 else
Azure.IoT.Build 54:6dcad9019a64 555 {
Azure.IoT.Build 54:6dcad9019a64 556 /*Codes_SRS_IOTHUBCLIENT_17_007: [ IoTHubClient_CreateWithTransport shall instantiate a new IoTHubClient_LL instance by calling IoTHubClient_LL_CreateWithTransport and passing the lower layer transport and config argument. ]*/
Azure.IoT.Build 54:6dcad9019a64 557 result->IoTHubClientLLHandle = IoTHubClient_LL_CreateWithTransport(&deviceConfig);
Azure.IoT.Build 54:6dcad9019a64 558 result->created_with_transport_handle = 1;
Azure.IoT.Build 54:6dcad9019a64 559 if (Unlock(result->LockHandle) != LOCK_OK)
Azure.IoT.Build 54:6dcad9019a64 560 {
Azure.IoT.Build 54:6dcad9019a64 561 LogError("unable to Unlock");
Azure.IoT.Build 54:6dcad9019a64 562 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 563 }
Azure.IoT.Build 54:6dcad9019a64 564 }
Azure.IoT.Build 54:6dcad9019a64 565 }
Azure.IoT.Build 54:6dcad9019a64 566 }
Azure.IoT.Build 54:6dcad9019a64 567 }
Azure.IoT.Build 54:6dcad9019a64 568 else
Azure.IoT.Build 54:6dcad9019a64 569 {
Azure.IoT.Build 54:6dcad9019a64 570 result->LockHandle = Lock_Init();
Azure.IoT.Build 54:6dcad9019a64 571 if (result->LockHandle == NULL)
Azure.IoT.Build 54:6dcad9019a64 572 {
Azure.IoT.Build 54:6dcad9019a64 573 /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
Azure.IoT.Build 54:6dcad9019a64 574 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
Azure.IoT.Build 54:6dcad9019a64 575 LogError("Failure creating Lock object");
Azure.IoT.Build 54:6dcad9019a64 576 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 577 }
Azure.IoT.Build 54:6dcad9019a64 578 else
Azure.IoT.Build 54:6dcad9019a64 579 {
Azure.IoT.Build 54:6dcad9019a64 580 /* Codes_SRS_IOTHUBCLIENT_01_002: [IoTHubClient_Create shall instantiate a new IoTHubClient_LL instance by calling IoTHubClient_LL_Create and passing the config argument.] */
Azure.IoT.Build 54:6dcad9019a64 581 result->IoTHubClientLLHandle = IoTHubClient_LL_Create(config);
Azure.IoT.Build 54:6dcad9019a64 582 }
Azure.IoT.Build 54:6dcad9019a64 583 }
Azure.IoT.Build 54:6dcad9019a64 584 }
Azure.IoT.Build 54:6dcad9019a64 585 else
Azure.IoT.Build 54:6dcad9019a64 586 {
Azure.IoT.Build 54:6dcad9019a64 587 result->LockHandle = Lock_Init();
Azure.IoT.Build 54:6dcad9019a64 588 if (result->LockHandle == NULL)
Azure.IoT.Build 54:6dcad9019a64 589 {
Azure.IoT.Build 54:6dcad9019a64 590 /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
Azure.IoT.Build 54:6dcad9019a64 591 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
Azure.IoT.Build 54:6dcad9019a64 592 LogError("Failure creating Lock object");
Azure.IoT.Build 54:6dcad9019a64 593 result->IoTHubClientLLHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 594 }
Azure.IoT.Build 54:6dcad9019a64 595 else
Azure.IoT.Build 54:6dcad9019a64 596 {
Azure.IoT.Build 54:6dcad9019a64 597 /* Codes_SRS_IOTHUBCLIENT_12_006: [IoTHubClient_CreateFromConnectionString shall instantiate a new IoTHubClient_LL instance by calling IoTHubClient_LL_CreateFromConnectionString and passing the connectionString] */
Azure.IoT.Build 54:6dcad9019a64 598 result->IoTHubClientLLHandle = IoTHubClient_LL_CreateFromConnectionString(connectionString, protocol);
Azure.IoT.Build 54:6dcad9019a64 599 }
Azure.IoT.Build 54:6dcad9019a64 600 }
Azure.IoT.Build 54:6dcad9019a64 601
AzureIoTClient 42:448eecc3676e 602 if (result->IoTHubClientLLHandle == NULL)
AzureIoTClient 42:448eecc3676e 603 {
AzureIoTClient 42:448eecc3676e 604 /* Codes_SRS_IOTHUBCLIENT_01_003: [If IoTHubClient_LL_Create fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 42:448eecc3676e 605 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
Azure.IoT.Build 54:6dcad9019a64 606 /* Codes_SRS_IOTHUBCLIENT_17_006: [ If IoTHubTransport_GetLock fails, then IoTHubClient_CreateWithTransport shall return NULL. ]*/
Azure.IoT.Build 54:6dcad9019a64 607 if (transportHandle == NULL)
Azure.IoT.Build 54:6dcad9019a64 608 {
Azure.IoT.Build 54:6dcad9019a64 609 Lock_Deinit(result->LockHandle);
Azure.IoT.Build 54:6dcad9019a64 610 }
AzureIoTClient 44:33dd78697616 611 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 52:1cc3c6d07cad 612 singlylinkedlist_destroy(result->savedDataToBeCleaned);
AzureIoTClient 43:038d8511e817 613 #endif
Azure.IoT.Build 54:6dcad9019a64 614 LogError("Failure creating iothub handle");
Azure.IoT.Build 54:6dcad9019a64 615 VECTOR_destroy(result->saved_user_callback_list);
AzureIoTClient 42:448eecc3676e 616 free(result);
AzureIoTClient 42:448eecc3676e 617 result = NULL;
AzureIoTClient 42:448eecc3676e 618 }
AzureIoTClient 42:448eecc3676e 619 else
AzureIoTClient 42:448eecc3676e 620 {
AzureIoTClient 42:448eecc3676e 621 result->ThreadHandle = NULL;
Azure.IoT.Build 54:6dcad9019a64 622 result->desired_state_callback = NULL;
Azure.IoT.Build 54:6dcad9019a64 623 result->event_confirm_callback = NULL;
Azure.IoT.Build 54:6dcad9019a64 624 result->reported_state_callback = NULL;
Azure.IoT.Build 54:6dcad9019a64 625 result->devicetwin_user_context = NULL;
AzureIoTClient 55:59b527ab3452 626 result->connection_status_callback = NULL;
AzureIoTClient 55:59b527ab3452 627 result->connection_status_user_context = NULL;
AzureIoTClient 42:448eecc3676e 628 }
AzureIoTClient 42:448eecc3676e 629 }
AzureIoTClient 16:deba40344375 630 }
AzureIoTClient 16:deba40344375 631 }
Azure.IoT.Build 54:6dcad9019a64 632 return result;
Azure.IoT.Build 54:6dcad9019a64 633 }
AzureIoTClient 16:deba40344375 634
Azure.IoT.Build 54:6dcad9019a64 635 IOTHUB_CLIENT_HANDLE IoTHubClient_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
Azure.IoT.Build 54:6dcad9019a64 636 {
Azure.IoT.Build 54:6dcad9019a64 637 IOTHUB_CLIENT_INSTANCE* result;
Azure.IoT.Build 54:6dcad9019a64 638
Azure.IoT.Build 54:6dcad9019a64 639 /* Codes_SRS_IOTHUBCLIENT_12_003: [IoTHubClient_CreateFromConnectionString shall verify all input parameters and if any is NULL then return NULL] */
Azure.IoT.Build 54:6dcad9019a64 640 if (connectionString == NULL)
Azure.IoT.Build 54:6dcad9019a64 641 {
Azure.IoT.Build 54:6dcad9019a64 642 LogError("Input parameter is NULL: connectionString");
Azure.IoT.Build 54:6dcad9019a64 643 result = NULL;
Azure.IoT.Build 54:6dcad9019a64 644 }
Azure.IoT.Build 54:6dcad9019a64 645 else if (protocol == NULL)
Azure.IoT.Build 54:6dcad9019a64 646 {
Azure.IoT.Build 54:6dcad9019a64 647 LogError("Input parameter is NULL: protocol");
Azure.IoT.Build 54:6dcad9019a64 648 result = NULL;
Azure.IoT.Build 54:6dcad9019a64 649 }
Azure.IoT.Build 54:6dcad9019a64 650 else
Azure.IoT.Build 54:6dcad9019a64 651 {
Azure.IoT.Build 54:6dcad9019a64 652 result = create_iothub_instance(NULL, NULL, connectionString, protocol);
Azure.IoT.Build 54:6dcad9019a64 653 }
Azure.IoT.Build 54:6dcad9019a64 654 return result;
Azure.IoT.Build 54:6dcad9019a64 655 }
Azure.IoT.Build 54:6dcad9019a64 656
Azure.IoT.Build 54:6dcad9019a64 657 IOTHUB_CLIENT_HANDLE IoTHubClient_Create(const IOTHUB_CLIENT_CONFIG* config)
Azure.IoT.Build 54:6dcad9019a64 658 {
Azure.IoT.Build 54:6dcad9019a64 659 IOTHUB_CLIENT_INSTANCE* result;
Azure.IoT.Build 54:6dcad9019a64 660 if (config == NULL)
Azure.IoT.Build 54:6dcad9019a64 661 {
Azure.IoT.Build 54:6dcad9019a64 662 LogError("Input parameter is NULL: IOTHUB_CLIENT_CONFIG");
Azure.IoT.Build 54:6dcad9019a64 663 result = NULL;
Azure.IoT.Build 54:6dcad9019a64 664 }
Azure.IoT.Build 54:6dcad9019a64 665 else
Azure.IoT.Build 54:6dcad9019a64 666 {
Azure.IoT.Build 54:6dcad9019a64 667 result = create_iothub_instance(config, NULL, NULL, NULL);
Azure.IoT.Build 54:6dcad9019a64 668 }
AzureIoTClient 16:deba40344375 669 return result;
AzureIoTClient 16:deba40344375 670 }
AzureIoTClient 16:deba40344375 671
Azure.IoT Build 37:18310e4d888d 672 IOTHUB_CLIENT_HANDLE IoTHubClient_CreateWithTransport(TRANSPORT_HANDLE transportHandle, const IOTHUB_CLIENT_CONFIG* config)
Azure.IoT Build 37:18310e4d888d 673 {
AzureIoTClient 42:448eecc3676e 674 IOTHUB_CLIENT_INSTANCE* result;
AzureIoTClient 42:448eecc3676e 675 /*Codes_SRS_IOTHUBCLIENT_17_013: [ IoTHubClient_CreateWithTransport shall return NULL if transportHandle is NULL. ]*/
AzureIoTClient 42:448eecc3676e 676 /*Codes_SRS_IOTHUBCLIENT_17_014: [ IoTHubClient_CreateWithTransport shall return NULL if config is NULL. ]*/
AzureIoTClient 42:448eecc3676e 677 if (transportHandle == NULL || config == NULL)
AzureIoTClient 42:448eecc3676e 678 {
AzureIoTClient 43:038d8511e817 679 LogError("invalid parameter TRANSPORT_HANDLE transportHandle=%p, const IOTHUB_CLIENT_CONFIG* config=%p", transportHandle, config);
AzureIoTClient 42:448eecc3676e 680 result = NULL;
AzureIoTClient 42:448eecc3676e 681 }
AzureIoTClient 42:448eecc3676e 682 else
AzureIoTClient 42:448eecc3676e 683 {
Azure.IoT.Build 54:6dcad9019a64 684 result = create_iothub_instance(config, transportHandle, NULL, NULL);
AzureIoTClient 42:448eecc3676e 685 }
AzureIoTClient 42:448eecc3676e 686 return result;
Azure.IoT Build 37:18310e4d888d 687 }
Azure.IoT Build 37:18310e4d888d 688
AzureIoTClient 16:deba40344375 689 /* Codes_SRS_IOTHUBCLIENT_01_005: [IoTHubClient_Destroy shall free all resources associated with the iotHubClientHandle instance.] */
AzureIoTClient 18:1e9adb15c645 690 void IoTHubClient_Destroy(IOTHUB_CLIENT_HANDLE iotHubClientHandle)
AzureIoTClient 16:deba40344375 691 {
AzureIoTClient 16:deba40344375 692 /* Codes_SRS_IOTHUBCLIENT_01_008: [IoTHubClient_Destroy shall do nothing if parameter iotHubClientHandle is NULL.] */
AzureIoTClient 16:deba40344375 693 if (iotHubClientHandle != NULL)
AzureIoTClient 16:deba40344375 694 {
AzureIoTClient 42:448eecc3676e 695 bool okToJoin;
AzureIoTClient 55:59b527ab3452 696 size_t vector_size;
Azure.IoT Build 37:18310e4d888d 697
AzureIoTClient 16:deba40344375 698 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 699
AzureIoTClient 42:448eecc3676e 700 /*Codes_SRS_IOTHUBCLIENT_02_043: [ IoTHubClient_Destroy shall lock the serializing lock and signal the worker thread (if any) to end ]*/
AzureIoTClient 42:448eecc3676e 701 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 702 {
AzureIoTClient 42:448eecc3676e 703 LogError("unable to Lock - - will still proceed to try to end the thread without locking");
AzureIoTClient 42:448eecc3676e 704 }
AzureIoTClient 42:448eecc3676e 705
AzureIoTClient 44:33dd78697616 706 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 707 /*Codes_SRS_IOTHUBCLIENT_02_069: [ IoTHubClient_Destroy shall free all data created by IoTHubClient_UploadToBlobAsync ]*/
AzureIoTClient 42:448eecc3676e 708 /*wait for all uploading threads to finish*/
AzureIoTClient 52:1cc3c6d07cad 709 while (singlylinkedlist_get_head_item(iotHubClientInstance->savedDataToBeCleaned) != NULL)
AzureIoTClient 42:448eecc3676e 710 {
AzureIoTClient 42:448eecc3676e 711 garbageCollectorImpl(iotHubClientInstance);
AzureIoTClient 42:448eecc3676e 712 }
AzureIoTClient 43:038d8511e817 713 #endif
AzureIoTClient 16:deba40344375 714 if (iotHubClientInstance->ThreadHandle != NULL)
AzureIoTClient 16:deba40344375 715 {
AzureIoTClient 42:448eecc3676e 716 iotHubClientInstance->StopThread = 1;
AzureIoTClient 42:448eecc3676e 717 okToJoin = true;
AzureIoTClient 42:448eecc3676e 718 }
AzureIoTClient 42:448eecc3676e 719 else
AzureIoTClient 42:448eecc3676e 720 {
AzureIoTClient 42:448eecc3676e 721 okToJoin = false;
AzureIoTClient 16:deba40344375 722 }
Azure.IoT Build 37:18310e4d888d 723
AzureIoTClient 42:448eecc3676e 724 if (iotHubClientInstance->TransportHandle != NULL)
AzureIoTClient 42:448eecc3676e 725 {
AzureIoTClient 42:448eecc3676e 726 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 42:448eecc3676e 727 okToJoin = IoTHubTransport_SignalEndWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
AzureIoTClient 42:448eecc3676e 728 }
AzureIoTClient 16:deba40344375 729
AzureIoTClient 16:deba40344375 730 /* Codes_SRS_IOTHUBCLIENT_01_006: [That includes destroying the IoTHubClient_LL instance by calling IoTHubClient_LL_Destroy.] */
AzureIoTClient 16:deba40344375 731 IoTHubClient_LL_Destroy(iotHubClientInstance->IoTHubClientLLHandle);
AzureIoTClient 16:deba40344375 732
AzureIoTClient 44:33dd78697616 733 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 43:038d8511e817 734 if (iotHubClientInstance->savedDataToBeCleaned != NULL)
AzureIoTClient 43:038d8511e817 735 {
AzureIoTClient 52:1cc3c6d07cad 736 singlylinkedlist_destroy(iotHubClientInstance->savedDataToBeCleaned);
AzureIoTClient 43:038d8511e817 737 }
AzureIoTClient 43:038d8511e817 738 #endif
AzureIoTClient 43:038d8511e817 739
AzureIoTClient 42:448eecc3676e 740 /*Codes_SRS_IOTHUBCLIENT_02_045: [ IoTHubClient_Destroy shall unlock the serializing lock. ]*/
AzureIoTClient 42:448eecc3676e 741 if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 742 {
AzureIoTClient 42:448eecc3676e 743 LogError("unable to Unlock");
AzureIoTClient 42:448eecc3676e 744 }
Azure.IoT Build 37:18310e4d888d 745
AzureIoTClient 42:448eecc3676e 746 if (okToJoin == true)
AzureIoTClient 42:448eecc3676e 747 {
AzureIoTClient 42:448eecc3676e 748 if (iotHubClientInstance->ThreadHandle != NULL)
AzureIoTClient 42:448eecc3676e 749 {
AzureIoTClient 42:448eecc3676e 750 int res;
AzureIoTClient 42:448eecc3676e 751 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 42:448eecc3676e 752 if (ThreadAPI_Join(iotHubClientInstance->ThreadHandle, &res) != THREADAPI_OK)
AzureIoTClient 42:448eecc3676e 753 {
AzureIoTClient 42:448eecc3676e 754 LogError("ThreadAPI_Join failed");
AzureIoTClient 42:448eecc3676e 755 }
AzureIoTClient 42:448eecc3676e 756 }
Azure.IoT.Build 54:6dcad9019a64 757
AzureIoTClient 42:448eecc3676e 758 if (iotHubClientInstance->TransportHandle != NULL)
AzureIoTClient 42:448eecc3676e 759 {
AzureIoTClient 42:448eecc3676e 760 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 42:448eecc3676e 761 IoTHubTransport_JoinWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
AzureIoTClient 42:448eecc3676e 762 }
AzureIoTClient 42:448eecc3676e 763 }
AzureIoTClient 42:448eecc3676e 764
AzureIoTClient 55:59b527ab3452 765 vector_size = VECTOR_size(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 57:4524910c6445 766 size_t index = 0;
AzureIoTClient 57:4524910c6445 767 for (index = 0; index < vector_size; index++)
AzureIoTClient 55:59b527ab3452 768 {
AzureIoTClient 55:59b527ab3452 769 USER_CALLBACK_INFO* queue_cb_info = (USER_CALLBACK_INFO*)VECTOR_element(iotHubClientInstance->saved_user_callback_list, index);
AzureIoTClient 55:59b527ab3452 770 if (queue_cb_info != NULL)
AzureIoTClient 55:59b527ab3452 771 {
AzureIoTClient 55:59b527ab3452 772 if (queue_cb_info->type == CALLBACK_TYPE_DEVICE_METHOD)
AzureIoTClient 55:59b527ab3452 773 {
AzureIoTClient 55:59b527ab3452 774 STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
AzureIoTClient 55:59b527ab3452 775 BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
AzureIoTClient 55:59b527ab3452 776 }
AzureIoTClient 55:59b527ab3452 777 else if (queue_cb_info->type == CALLBACK_TYPE_DEVICE_TWIN)
AzureIoTClient 55:59b527ab3452 778 {
AzureIoTClient 55:59b527ab3452 779 if (queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad != NULL)
AzureIoTClient 55:59b527ab3452 780 {
AzureIoTClient 55:59b527ab3452 781 free(queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad);
AzureIoTClient 55:59b527ab3452 782 }
AzureIoTClient 55:59b527ab3452 783 }
AzureIoTClient 55:59b527ab3452 784 }
AzureIoTClient 55:59b527ab3452 785 }
Azure.IoT.Build 54:6dcad9019a64 786 VECTOR_destroy(iotHubClientInstance->saved_user_callback_list);
Azure.IoT.Build 54:6dcad9019a64 787
AzureIoTClient 42:448eecc3676e 788 if (iotHubClientInstance->TransportHandle == NULL)
AzureIoTClient 42:448eecc3676e 789 {
AzureIoTClient 42:448eecc3676e 790 /* Codes_SRS_IOTHUBCLIENT_01_032: [If the lock was allocated in IoTHubClient_Create, it shall be also freed..] */
AzureIoTClient 42:448eecc3676e 791 Lock_Deinit(iotHubClientInstance->LockHandle);
AzureIoTClient 42:448eecc3676e 792 }
Azure.IoT.Build 54:6dcad9019a64 793 if (iotHubClientInstance->devicetwin_user_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 794 {
Azure.IoT.Build 54:6dcad9019a64 795 free(iotHubClientInstance->devicetwin_user_context);
Azure.IoT.Build 54:6dcad9019a64 796 }
AzureIoTClient 55:59b527ab3452 797 if (iotHubClientInstance->connection_status_user_context != NULL)
AzureIoTClient 55:59b527ab3452 798 {
AzureIoTClient 55:59b527ab3452 799 free(iotHubClientInstance->connection_status_user_context);
AzureIoTClient 55:59b527ab3452 800 }
AzureIoTClient 16:deba40344375 801 free(iotHubClientInstance);
AzureIoTClient 16:deba40344375 802 }
AzureIoTClient 16:deba40344375 803 }
AzureIoTClient 16:deba40344375 804
AzureIoTClient 16:deba40344375 805 IOTHUB_CLIENT_RESULT IoTHubClient_SendEventAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
AzureIoTClient 16:deba40344375 806 {
AzureIoTClient 16:deba40344375 807 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 16:deba40344375 808
AzureIoTClient 16:deba40344375 809 if (iotHubClientHandle == NULL)
AzureIoTClient 16:deba40344375 810 {
AzureIoTClient 16:deba40344375 811 /* Codes_SRS_IOTHUBCLIENT_01_011: [If iotHubClientHandle is NULL, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 16:deba40344375 812 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 39:2719651a5bee 813 LogError("NULL iothubClientHandle");
AzureIoTClient 16:deba40344375 814 }
AzureIoTClient 16:deba40344375 815 else
AzureIoTClient 16:deba40344375 816 {
AzureIoTClient 16:deba40344375 817 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 818
AzureIoTClient 16:deba40344375 819 /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 820 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 16:deba40344375 821 {
AzureIoTClient 16:deba40344375 822 /* Codes_SRS_IOTHUBCLIENT_01_026: [If acquiring the lock fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 823 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 824 LogError("Could not acquire lock");
AzureIoTClient 16:deba40344375 825 }
AzureIoTClient 16:deba40344375 826 else
AzureIoTClient 16:deba40344375 827 {
Azure.IoT.Build 54:6dcad9019a64 828 if (iotHubClientInstance->created_with_transport_handle == 0)
Azure.IoT.Build 54:6dcad9019a64 829 {
Azure.IoT.Build 54:6dcad9019a64 830 iotHubClientInstance->event_confirm_callback = eventConfirmationCallback;
Azure.IoT.Build 54:6dcad9019a64 831 }
AzureIoTClient 16:deba40344375 832 /* Codes_SRS_IOTHUBCLIENT_01_009: [IoTHubClient_SendEventAsync shall start the worker thread if it was not previously started.] */
Azure.IoT Build 37:18310e4d888d 833 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 16:deba40344375 834 {
AzureIoTClient 16:deba40344375 835 /* Codes_SRS_IOTHUBCLIENT_01_010: [If starting the thread fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 836 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 837 LogError("Could not start worker thread");
AzureIoTClient 16:deba40344375 838 }
AzureIoTClient 16:deba40344375 839 else
AzureIoTClient 16:deba40344375 840 {
Azure.IoT.Build 54:6dcad9019a64 841 if (iotHubClientInstance->created_with_transport_handle != 0 || eventConfirmationCallback == NULL)
Azure.IoT.Build 54:6dcad9019a64 842 {
Azure.IoT.Build 54:6dcad9019a64 843 result = IoTHubClient_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 844 }
Azure.IoT.Build 54:6dcad9019a64 845 else
Azure.IoT.Build 54:6dcad9019a64 846 {
Azure.IoT.Build 54:6dcad9019a64 847 /* Codes_SRS_IOTHUBCLIENT_07_001: [ IoTHubClient_SendEventAsync shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClient_LL_SendEventAsync function as a user context. ] */
Azure.IoT.Build 54:6dcad9019a64 848 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
Azure.IoT.Build 54:6dcad9019a64 849 if (queue_context == NULL)
Azure.IoT.Build 54:6dcad9019a64 850 {
Azure.IoT.Build 54:6dcad9019a64 851 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 54:6dcad9019a64 852 LogError("Failed allocating QUEUE_CONTEXT");
Azure.IoT.Build 54:6dcad9019a64 853 }
Azure.IoT.Build 54:6dcad9019a64 854 else
Azure.IoT.Build 54:6dcad9019a64 855 {
Azure.IoT.Build 54:6dcad9019a64 856 queue_context->iotHubClientHandle = iotHubClientInstance;
Azure.IoT.Build 54:6dcad9019a64 857 queue_context->userContextCallback = userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 858 /* Codes_SRS_IOTHUBCLIENT_01_012: [IoTHubClient_SendEventAsync shall call IoTHubClient_LL_SendEventAsync, while passing the IoTHubClient_LL handle created by IoTHubClient_Create and the parameters eventMessageHandle, eventConfirmationCallback and userContextCallback.] */
Azure.IoT.Build 54:6dcad9019a64 859 /* Codes_SRS_IOTHUBCLIENT_01_013: [When IoTHubClient_LL_SendEventAsync is called, IoTHubClient_SendEventAsync shall return the result of IoTHubClient_LL_SendEventAsync.] */
Azure.IoT.Build 54:6dcad9019a64 860 result = IoTHubClient_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, iothub_ll_event_confirm_callback, queue_context);
Azure.IoT.Build 54:6dcad9019a64 861 if (result != IOTHUB_CLIENT_OK)
Azure.IoT.Build 54:6dcad9019a64 862 {
Azure.IoT.Build 54:6dcad9019a64 863 LogError("IoTHubClient_LL_SendEventAsync failed");
Azure.IoT.Build 54:6dcad9019a64 864 free(queue_context);
Azure.IoT.Build 54:6dcad9019a64 865 }
Azure.IoT.Build 54:6dcad9019a64 866 }
Azure.IoT.Build 54:6dcad9019a64 867 }
AzureIoTClient 16:deba40344375 868 }
AzureIoTClient 16:deba40344375 869
AzureIoTClient 16:deba40344375 870 /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 871 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 16:deba40344375 872 }
AzureIoTClient 16:deba40344375 873 }
AzureIoTClient 16:deba40344375 874
AzureIoTClient 16:deba40344375 875 return result;
AzureIoTClient 16:deba40344375 876 }
AzureIoTClient 16:deba40344375 877
AzureIoTClient 16:deba40344375 878 IOTHUB_CLIENT_RESULT IoTHubClient_GetSendStatus(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
AzureIoTClient 16:deba40344375 879 {
AzureIoTClient 16:deba40344375 880 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 16:deba40344375 881
AzureIoTClient 16:deba40344375 882 if (iotHubClientHandle == NULL)
AzureIoTClient 16:deba40344375 883 {
AzureIoTClient 16:deba40344375 884 /* Codes_SRS_IOTHUBCLIENT_01_023: [If iotHubClientHandle is NULL, IoTHubClient_ GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 16:deba40344375 885 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 39:2719651a5bee 886 LogError("NULL iothubClientHandle");
AzureIoTClient 16:deba40344375 887 }
AzureIoTClient 16:deba40344375 888 else
AzureIoTClient 16:deba40344375 889 {
AzureIoTClient 16:deba40344375 890 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 891
AzureIoTClient 16:deba40344375 892 /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 893 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 16:deba40344375 894 {
AzureIoTClient 16:deba40344375 895 /* Codes_SRS_IOTHUBCLIENT_01_034: [If acquiring the lock fails, IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 896 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 897 LogError("Could not acquire lock");
AzureIoTClient 16:deba40344375 898 }
AzureIoTClient 16:deba40344375 899 else
AzureIoTClient 16:deba40344375 900 {
AzureIoTClient 16:deba40344375 901 /* Codes_SRS_IOTHUBCLIENT_01_022: [IoTHubClient_GetSendStatus shall call IoTHubClient_LL_GetSendStatus, while passing the IoTHubClient_LL handle created by IoTHubClient_Create and the parameter iotHubClientStatus.] */
AzureIoTClient 16:deba40344375 902 /* Codes_SRS_IOTHUBCLIENT_01_024: [Otherwise, IoTHubClient_GetSendStatus shall return the result of IoTHubClient_LL_GetSendStatus.] */
AzureIoTClient 16:deba40344375 903 result = IoTHubClient_LL_GetSendStatus(iotHubClientInstance->IoTHubClientLLHandle, iotHubClientStatus);
AzureIoTClient 16:deba40344375 904
AzureIoTClient 16:deba40344375 905 /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 906 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 16:deba40344375 907 }
AzureIoTClient 16:deba40344375 908 }
AzureIoTClient 16:deba40344375 909
AzureIoTClient 16:deba40344375 910 return result;
AzureIoTClient 16:deba40344375 911 }
AzureIoTClient 16:deba40344375 912
AzureIoTClient 16:deba40344375 913 IOTHUB_CLIENT_RESULT IoTHubClient_SetMessageCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
AzureIoTClient 16:deba40344375 914 {
AzureIoTClient 16:deba40344375 915 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 16:deba40344375 916
AzureIoTClient 16:deba40344375 917 if (iotHubClientHandle == NULL)
AzureIoTClient 16:deba40344375 918 {
AzureIoTClient 16:deba40344375 919 /* Codes_SRS_IOTHUBCLIENT_01_016: [If iotHubClientHandle is NULL, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 16:deba40344375 920 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 39:2719651a5bee 921 LogError("NULL iothubClientHandle");
AzureIoTClient 16:deba40344375 922 }
AzureIoTClient 16:deba40344375 923 else
AzureIoTClient 16:deba40344375 924 {
AzureIoTClient 16:deba40344375 925 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 926
AzureIoTClient 16:deba40344375 927 /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 928 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 16:deba40344375 929 {
AzureIoTClient 16:deba40344375 930 /* Codes_SRS_IOTHUBCLIENT_01_028: [If acquiring the lock fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 931 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 932 LogError("Could not acquire lock");
AzureIoTClient 16:deba40344375 933 }
AzureIoTClient 16:deba40344375 934 else
AzureIoTClient 16:deba40344375 935 {
AzureIoTClient 16:deba40344375 936 /* Codes_SRS_IOTHUBCLIENT_01_014: [IoTHubClient_SetMessageCallback shall start the worker thread if it was not previously started.] */
Azure.IoT Build 37:18310e4d888d 937 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 16:deba40344375 938 {
AzureIoTClient 16:deba40344375 939 /* Codes_SRS_IOTHUBCLIENT_01_015: [If starting the thread fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 940 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 941 LogError("Could not start worker thread");
AzureIoTClient 16:deba40344375 942 }
AzureIoTClient 16:deba40344375 943 else
AzureIoTClient 16:deba40344375 944 {
AzureIoTClient 16:deba40344375 945 /* Codes_SRS_IOTHUBCLIENT_01_017: [IoTHubClient_SetMessageCallback shall call IoTHubClient_LL_SetMessageCallback, while passing the IoTHubClient_LL handle created by IoTHubClient_Create and the parameters messageCallback and userContextCallback.] */
AzureIoTClient 16:deba40344375 946 result = IoTHubClient_LL_SetMessageCallback(iotHubClientInstance->IoTHubClientLLHandle, messageCallback, userContextCallback);
AzureIoTClient 16:deba40344375 947 }
AzureIoTClient 16:deba40344375 948
AzureIoTClient 16:deba40344375 949 /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 53:1e5a1ca1f274 950 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 16:deba40344375 951 }
AzureIoTClient 16:deba40344375 952 }
AzureIoTClient 16:deba40344375 953
AzureIoTClient 16:deba40344375 954 return result;
AzureIoTClient 16:deba40344375 955 }
AzureIoTClient 16:deba40344375 956
AzureIoTClient 53:1e5a1ca1f274 957 IOTHUB_CLIENT_RESULT IoTHubClient_SetConnectionStatusCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
AzureIoTClient 52:1cc3c6d07cad 958 {
AzureIoTClient 53:1e5a1ca1f274 959 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 960
AzureIoTClient 53:1e5a1ca1f274 961 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 962 {
AzureIoTClient 53:1e5a1ca1f274 963 /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
AzureIoTClient 53:1e5a1ca1f274 964 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 965 LogError("NULL iothubClientHandle");
AzureIoTClient 53:1e5a1ca1f274 966 }
AzureIoTClient 53:1e5a1ca1f274 967 else
AzureIoTClient 53:1e5a1ca1f274 968 {
AzureIoTClient 53:1e5a1ca1f274 969 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 52:1cc3c6d07cad 970
AzureIoTClient 53:1e5a1ca1f274 971 /* Codes_SRS_IOTHUBCLIENT_25_087: [ `IoTHubClient_SetConnectionStatusCallback` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ] */
AzureIoTClient 53:1e5a1ca1f274 972 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 973 {
AzureIoTClient 53:1e5a1ca1f274 974 /* Codes_SRS_IOTHUBCLIENT_25_088: [ If acquiring the lock fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 975 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 976 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 977 }
AzureIoTClient 53:1e5a1ca1f274 978 else
AzureIoTClient 53:1e5a1ca1f274 979 {
Azure.IoT.Build 54:6dcad9019a64 980 if (iotHubClientInstance->created_with_transport_handle == 0)
Azure.IoT.Build 54:6dcad9019a64 981 {
Azure.IoT.Build 54:6dcad9019a64 982 iotHubClientInstance->connection_status_callback = connectionStatusCallback;
Azure.IoT.Build 54:6dcad9019a64 983 }
AzureIoTClient 53:1e5a1ca1f274 984 /* Codes_SRS_IOTHUBCLIENT_25_081: [ `IoTHubClient_SetConnectionStatusCallback` shall start the worker thread if it was not previously started. ]*/
AzureIoTClient 53:1e5a1ca1f274 985 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 986 {
AzureIoTClient 53:1e5a1ca1f274 987 /* Codes_SRS_IOTHUBCLIENT_25_083: [ If starting the thread fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 988 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 989 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 990 }
AzureIoTClient 53:1e5a1ca1f274 991 else
AzureIoTClient 53:1e5a1ca1f274 992 {
Azure.IoT.Build 54:6dcad9019a64 993 if (iotHubClientInstance->created_with_transport_handle != 0 || connectionStatusCallback == NULL)
Azure.IoT.Build 54:6dcad9019a64 994 {
Azure.IoT.Build 54:6dcad9019a64 995 /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClient_LL_SetConnectionStatusCallback`, while passing the `IoTHubClient_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
Azure.IoT.Build 54:6dcad9019a64 996 result = IoTHubClient_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, connectionStatusCallback, userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 997 }
Azure.IoT.Build 54:6dcad9019a64 998 else
Azure.IoT.Build 54:6dcad9019a64 999 {
AzureIoTClient 55:59b527ab3452 1000 if (iotHubClientInstance->connection_status_user_context != NULL)
AzureIoTClient 55:59b527ab3452 1001 {
AzureIoTClient 55:59b527ab3452 1002 free(iotHubClientInstance->connection_status_user_context);
AzureIoTClient 55:59b527ab3452 1003 }
AzureIoTClient 55:59b527ab3452 1004 iotHubClientInstance->connection_status_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 55:59b527ab3452 1005 if (iotHubClientInstance->connection_status_user_context == NULL)
Azure.IoT.Build 54:6dcad9019a64 1006 {
Azure.IoT.Build 54:6dcad9019a64 1007 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 54:6dcad9019a64 1008 LogError("Failed allocating QUEUE_CONTEXT");
Azure.IoT.Build 54:6dcad9019a64 1009 }
Azure.IoT.Build 54:6dcad9019a64 1010 else
Azure.IoT.Build 54:6dcad9019a64 1011 {
AzureIoTClient 55:59b527ab3452 1012 iotHubClientInstance->connection_status_user_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 55:59b527ab3452 1013 iotHubClientInstance->connection_status_user_context->userContextCallback = userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 1014
Azure.IoT.Build 54:6dcad9019a64 1015 /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClient_LL_SetConnectionStatusCallback`, while passing the `IoTHubClient_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
AzureIoTClient 55:59b527ab3452 1016 result = IoTHubClient_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_connection_status_callback, iotHubClientInstance->connection_status_user_context);
Azure.IoT.Build 54:6dcad9019a64 1017 if (result != IOTHUB_CLIENT_OK)
Azure.IoT.Build 54:6dcad9019a64 1018 {
Azure.IoT.Build 54:6dcad9019a64 1019 LogError("IoTHubClient_LL_SetConnectionStatusCallback failed");
AzureIoTClient 55:59b527ab3452 1020 free(iotHubClientInstance->connection_status_user_context);
Azure.IoT.Build 54:6dcad9019a64 1021 }
Azure.IoT.Build 54:6dcad9019a64 1022 }
Azure.IoT.Build 54:6dcad9019a64 1023 }
AzureIoTClient 53:1e5a1ca1f274 1024 }
AzureIoTClient 53:1e5a1ca1f274 1025 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1026 }
AzureIoTClient 53:1e5a1ca1f274 1027 }
AzureIoTClient 52:1cc3c6d07cad 1028 return result;
AzureIoTClient 52:1cc3c6d07cad 1029 }
AzureIoTClient 52:1cc3c6d07cad 1030
AzureIoTClient 53:1e5a1ca1f274 1031 IOTHUB_CLIENT_RESULT IoTHubClient_SetRetryPolicy(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
AzureIoTClient 52:1cc3c6d07cad 1032 {
AzureIoTClient 53:1e5a1ca1f274 1033 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 1034
AzureIoTClient 53:1e5a1ca1f274 1035 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 1036 {
AzureIoTClient 53:1e5a1ca1f274 1037 /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
AzureIoTClient 53:1e5a1ca1f274 1038 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1039 LogError("NULL iothubClientHandle");
AzureIoTClient 53:1e5a1ca1f274 1040 }
AzureIoTClient 53:1e5a1ca1f274 1041 else
AzureIoTClient 53:1e5a1ca1f274 1042 {
AzureIoTClient 53:1e5a1ca1f274 1043 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 53:1e5a1ca1f274 1044
AzureIoTClient 53:1e5a1ca1f274 1045 /* Codes_SRS_IOTHUBCLIENT_25_079: [ `IoTHubClient_SetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`.] */
AzureIoTClient 53:1e5a1ca1f274 1046 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 1047 {
AzureIoTClient 53:1e5a1ca1f274 1048 /* Codes_SRS_IOTHUBCLIENT_25_080: [ If acquiring the lock fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1049 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1050 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 1051 }
AzureIoTClient 53:1e5a1ca1f274 1052 else
AzureIoTClient 53:1e5a1ca1f274 1053 {
AzureIoTClient 53:1e5a1ca1f274 1054 /* Codes_SRS_IOTHUBCLIENT_25_073: [ `IoTHubClient_SetRetryPolicy` shall start the worker thread if it was not previously started. ] */
AzureIoTClient 53:1e5a1ca1f274 1055 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1056 {
AzureIoTClient 53:1e5a1ca1f274 1057 /* Codes_SRS_IOTHUBCLIENT_25_075: [ If starting the thread fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1058 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1059 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 1060 }
AzureIoTClient 53:1e5a1ca1f274 1061 else
AzureIoTClient 53:1e5a1ca1f274 1062 {
AzureIoTClient 53:1e5a1ca1f274 1063 /* Codes_SRS_IOTHUBCLIENT_25_077: [ `IoTHubClient_SetRetryPolicy` shall call `IoTHubClient_LL_SetRetryPolicy`, while passing the `IoTHubClient_LL` handle created by `IoTHubClient_Create` and the parameters `retryPolicy` and `retryTimeoutLimitinSeconds`.]*/
AzureIoTClient 53:1e5a1ca1f274 1064 result = IoTHubClient_LL_SetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
AzureIoTClient 53:1e5a1ca1f274 1065 }
AzureIoTClient 53:1e5a1ca1f274 1066
AzureIoTClient 53:1e5a1ca1f274 1067 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1068 }
AzureIoTClient 53:1e5a1ca1f274 1069 }
AzureIoTClient 52:1cc3c6d07cad 1070
AzureIoTClient 52:1cc3c6d07cad 1071 return result;
AzureIoTClient 52:1cc3c6d07cad 1072 }
AzureIoTClient 52:1cc3c6d07cad 1073
Azure.IoT.Build 54:6dcad9019a64 1074 IOTHUB_CLIENT_RESULT IoTHubClient_GetRetryPolicy(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
AzureIoTClient 52:1cc3c6d07cad 1075 {
AzureIoTClient 53:1e5a1ca1f274 1076 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 1077
AzureIoTClient 53:1e5a1ca1f274 1078 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 1079 {
AzureIoTClient 53:1e5a1ca1f274 1080 /* Codes_SRS_IOTHUBCLIENT_25_092: [ If `iotHubClientHandle` is `NULL`, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1081 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1082 LogError("NULL iothubClientHandle");
AzureIoTClient 53:1e5a1ca1f274 1083 }
AzureIoTClient 53:1e5a1ca1f274 1084 else
AzureIoTClient 53:1e5a1ca1f274 1085 {
AzureIoTClient 53:1e5a1ca1f274 1086 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 53:1e5a1ca1f274 1087
AzureIoTClient 53:1e5a1ca1f274 1088 /* Codes_SRS_IOTHUBCLIENT_25_095: [ `IoTHubClient_GetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1089 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 1090 {
AzureIoTClient 53:1e5a1ca1f274 1091 /* Codes_SRS_IOTHUBCLIENT_25_096: [ If acquiring the lock fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1092 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1093 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 1094 }
AzureIoTClient 53:1e5a1ca1f274 1095 else
AzureIoTClient 53:1e5a1ca1f274 1096 {
AzureIoTClient 53:1e5a1ca1f274 1097 /* Codes_SRS_IOTHUBCLIENT_25_089: [ `IoTHubClient_GetRetryPolicy` shall start the worker thread if it was not previously started.]*/
AzureIoTClient 53:1e5a1ca1f274 1098 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1099 {
AzureIoTClient 53:1e5a1ca1f274 1100 /* Codes_SRS_IOTHUBCLIENT_25_091: [ If starting the thread fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`.]*/
AzureIoTClient 53:1e5a1ca1f274 1101 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1102 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 1103 }
AzureIoTClient 53:1e5a1ca1f274 1104 else
AzureIoTClient 53:1e5a1ca1f274 1105 {
AzureIoTClient 53:1e5a1ca1f274 1106 /* Codes_SRS_IOTHUBCLIENT_25_093: [ `IoTHubClient_GetRetryPolicy` shall call `IoTHubClient_LL_GetRetryPolicy`, while passing the `IoTHubClient_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`.]*/
AzureIoTClient 53:1e5a1ca1f274 1107 result = IoTHubClient_LL_GetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
AzureIoTClient 53:1e5a1ca1f274 1108 }
AzureIoTClient 53:1e5a1ca1f274 1109
AzureIoTClient 53:1e5a1ca1f274 1110 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1111 }
AzureIoTClient 53:1e5a1ca1f274 1112 }
AzureIoTClient 52:1cc3c6d07cad 1113
AzureIoTClient 52:1cc3c6d07cad 1114 return result;
AzureIoTClient 52:1cc3c6d07cad 1115 }
AzureIoTClient 52:1cc3c6d07cad 1116
AzureIoTClient 16:deba40344375 1117 IOTHUB_CLIENT_RESULT IoTHubClient_GetLastMessageReceiveTime(IOTHUB_CLIENT_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
AzureIoTClient 16:deba40344375 1118 {
AzureIoTClient 16:deba40344375 1119 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 16:deba40344375 1120
AzureIoTClient 16:deba40344375 1121 if (iotHubClientHandle == NULL)
AzureIoTClient 16:deba40344375 1122 {
AzureIoTClient 16:deba40344375 1123 /* Codes_SRS_IOTHUBCLIENT_01_020: [If iotHubClientHandle is NULL, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 16:deba40344375 1124 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 39:2719651a5bee 1125 LogError("NULL iothubClientHandle");
AzureIoTClient 16:deba40344375 1126 }
AzureIoTClient 16:deba40344375 1127 else
AzureIoTClient 16:deba40344375 1128 {
AzureIoTClient 16:deba40344375 1129 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 1130
AzureIoTClient 16:deba40344375 1131 /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 16:deba40344375 1132 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 16:deba40344375 1133 {
AzureIoTClient 16:deba40344375 1134 /* Codes_SRS_IOTHUBCLIENT_01_036: [If acquiring the lock fails, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 16:deba40344375 1135 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 39:2719651a5bee 1136 LogError("Could not acquire lock");
AzureIoTClient 16:deba40344375 1137 }
AzureIoTClient 16:deba40344375 1138 else
AzureIoTClient 16:deba40344375 1139 {
AzureIoTClient 16:deba40344375 1140 /* Codes_SRS_IOTHUBCLIENT_01_019: [IoTHubClient_GetLastMessageReceiveTime shall call IoTHubClient_LL_GetLastMessageReceiveTime, while passing the IoTHubClient_LL handle created by IoTHubClient_Create and the parameter lastMessageReceiveTime.] */
AzureIoTClient 16:deba40344375 1141 /* Codes_SRS_IOTHUBCLIENT_01_021: [Otherwise, IoTHubClient_GetLastMessageReceiveTime shall return the result of IoTHubClient_LL_GetLastMessageReceiveTime.] */
AzureIoTClient 16:deba40344375 1142 result = IoTHubClient_LL_GetLastMessageReceiveTime(iotHubClientInstance->IoTHubClientLLHandle, lastMessageReceiveTime);
AzureIoTClient 16:deba40344375 1143
AzureIoTClient 16:deba40344375 1144 /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 53:1e5a1ca1f274 1145 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 16:deba40344375 1146 }
AzureIoTClient 16:deba40344375 1147 }
AzureIoTClient 16:deba40344375 1148
AzureIoTClient 16:deba40344375 1149 return result;
AzureIoTClient 16:deba40344375 1150 }
AzureIoTClient 16:deba40344375 1151
AzureIoTClient 16:deba40344375 1152 IOTHUB_CLIENT_RESULT IoTHubClient_SetOption(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* optionName, const void* value)
AzureIoTClient 16:deba40344375 1153 {
AzureIoTClient 16:deba40344375 1154 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 16:deba40344375 1155 /*Codes_SRS_IOTHUBCLIENT_02_034: [If parameter iotHubClientHandle is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 42:448eecc3676e 1156 /*Codes_SRS_IOTHUBCLIENT_02_035: [ If parameter optionName is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 1157 /*Codes_SRS_IOTHUBCLIENT_02_036: [ If parameter value is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 16:deba40344375 1158 if (
AzureIoTClient 16:deba40344375 1159 (iotHubClientHandle == NULL) ||
AzureIoTClient 16:deba40344375 1160 (optionName == NULL) ||
AzureIoTClient 16:deba40344375 1161 (value == NULL)
AzureIoTClient 16:deba40344375 1162 )
AzureIoTClient 16:deba40344375 1163 {
AzureIoTClient 16:deba40344375 1164 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1165 LogError("invalid arg (NULL)");
AzureIoTClient 16:deba40344375 1166 }
AzureIoTClient 16:deba40344375 1167 else
AzureIoTClient 16:deba40344375 1168 {
AzureIoTClient 16:deba40344375 1169 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 16:deba40344375 1170
AzureIoTClient 40:1a94db9139ea 1171 /* Codes_SRS_IOTHUBCLIENT_01_041: [ IoTHubClient_SetOption shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 40:1a94db9139ea 1172 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 40:1a94db9139ea 1173 {
AzureIoTClient 40:1a94db9139ea 1174 /* Codes_SRS_IOTHUBCLIENT_01_042: [ If acquiring the lock fails, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 40:1a94db9139ea 1175 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 40:1a94db9139ea 1176 LogError("Could not acquire lock");
AzureIoTClient 40:1a94db9139ea 1177 }
AzureIoTClient 40:1a94db9139ea 1178 else
AzureIoTClient 16:deba40344375 1179 {
AzureIoTClient 40:1a94db9139ea 1180 /*Codes_SRS_IOTHUBCLIENT_02_038: [If optionName doesn't match one of the options handled by this module then IoTHubClient_SetOption shall call IoTHubClient_LL_SetOption passing the same parameters and return what IoTHubClient_LL_SetOption returns.] */
AzureIoTClient 40:1a94db9139ea 1181 result = IoTHubClient_LL_SetOption(iotHubClientInstance->IoTHubClientLLHandle, optionName, value);
AzureIoTClient 40:1a94db9139ea 1182 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 40:1a94db9139ea 1183 {
AzureIoTClient 40:1a94db9139ea 1184 LogError("IoTHubClient_LL_SetOption failed");
AzureIoTClient 40:1a94db9139ea 1185 }
AzureIoTClient 40:1a94db9139ea 1186
AzureIoTClient 53:1e5a1ca1f274 1187 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1188 }
AzureIoTClient 53:1e5a1ca1f274 1189 }
AzureIoTClient 53:1e5a1ca1f274 1190 return result;
AzureIoTClient 53:1e5a1ca1f274 1191 }
AzureIoTClient 53:1e5a1ca1f274 1192
AzureIoTClient 53:1e5a1ca1f274 1193 IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceTwinCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
AzureIoTClient 53:1e5a1ca1f274 1194 {
AzureIoTClient 53:1e5a1ca1f274 1195 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 1196
AzureIoTClient 53:1e5a1ca1f274 1197 /*Codes_SRS_IOTHUBCLIENT_10_001: [** `IoTHubClient_SetDeviceTwinCallback` shall fail and return `IOTHUB_CLIENT_INVALID_ARG` if parameter `iotHubClientHandle` is `NULL`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1198 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 1199 {
AzureIoTClient 53:1e5a1ca1f274 1200 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1201 LogError("invalid arg (NULL)");
AzureIoTClient 53:1e5a1ca1f274 1202 }
AzureIoTClient 53:1e5a1ca1f274 1203 else
AzureIoTClient 53:1e5a1ca1f274 1204 {
AzureIoTClient 53:1e5a1ca1f274 1205 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 53:1e5a1ca1f274 1206
AzureIoTClient 53:1e5a1ca1f274 1207 /*Codes_SRS_IOTHUBCLIENT_10_020: [** `IoTHubClient_SetDeviceTwinCallback` shall be made thread - safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 53:1e5a1ca1f274 1208 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 1209 {
AzureIoTClient 53:1e5a1ca1f274 1210 /*Codes_SRS_IOTHUBCLIENT_10_002: [** If acquiring the lock fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1211 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1212 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 1213 }
AzureIoTClient 53:1e5a1ca1f274 1214 else
AzureIoTClient 53:1e5a1ca1f274 1215 {
Azure.IoT.Build 54:6dcad9019a64 1216 if (iotHubClientInstance->created_with_transport_handle == 0)
Azure.IoT.Build 54:6dcad9019a64 1217 {
Azure.IoT.Build 54:6dcad9019a64 1218 iotHubClientInstance->desired_state_callback = deviceTwinCallback;
Azure.IoT.Build 54:6dcad9019a64 1219 }
AzureIoTClient 53:1e5a1ca1f274 1220 /*Codes_SRS_IOTHUBCLIENT_10_003: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1221 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1222 {
AzureIoTClient 53:1e5a1ca1f274 1223 /*Codes_SRS_IOTHUBCLIENT_10_004: [** If starting the thread fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1224 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1225 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 1226 }
AzureIoTClient 53:1e5a1ca1f274 1227 else
AzureIoTClient 53:1e5a1ca1f274 1228 {
Azure.IoT.Build 54:6dcad9019a64 1229 if (iotHubClientInstance->created_with_transport_handle != 0 || deviceTwinCallback == NULL)
Azure.IoT.Build 54:6dcad9019a64 1230 {
Azure.IoT.Build 54:6dcad9019a64 1231 /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClient_LL_SetDeviceTwinCallback` shall call `IoTHubClient_LL_SetDeviceTwinCallback`, while passing the `IoTHubClient_LL handle` created by `IoTHubClient_LL_Create` along with the parameters `reportedStateCallback` and `userContextCallback`. ]*/
Azure.IoT.Build 54:6dcad9019a64 1232 result = IoTHubClient_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, deviceTwinCallback, userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 1233 }
Azure.IoT.Build 54:6dcad9019a64 1234 else
AzureIoTClient 53:1e5a1ca1f274 1235 {
Azure.IoT.Build 54:6dcad9019a64 1236 if (iotHubClientInstance->devicetwin_user_context != NULL)
Azure.IoT.Build 54:6dcad9019a64 1237 {
Azure.IoT.Build 54:6dcad9019a64 1238 free(iotHubClientInstance->devicetwin_user_context);
Azure.IoT.Build 54:6dcad9019a64 1239 }
Azure.IoT.Build 54:6dcad9019a64 1240
Azure.IoT.Build 54:6dcad9019a64 1241 /*Codes_SRS_IOTHUBCLIENT_07_002: [ IoTHubClient_SetDeviceTwinCallback shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClient_LL_SetDeviceTwinCallback function as a user context. ]*/
AzureIoTClient 55:59b527ab3452 1242 iotHubClientInstance->devicetwin_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
Azure.IoT.Build 54:6dcad9019a64 1243 if (iotHubClientInstance->devicetwin_user_context == NULL)
Azure.IoT.Build 54:6dcad9019a64 1244 {
Azure.IoT.Build 54:6dcad9019a64 1245 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 54:6dcad9019a64 1246 LogError("Failed allocating QUEUE_CONTEXT");
Azure.IoT.Build 54:6dcad9019a64 1247 }
Azure.IoT.Build 54:6dcad9019a64 1248 else
Azure.IoT.Build 54:6dcad9019a64 1249 {
Azure.IoT.Build 54:6dcad9019a64 1250 /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClient_LL_SetDeviceTwinCallback` shall call `IoTHubClient_LL_SetDeviceTwinCallback`, while passing the `IoTHubClient_LL handle` created by `IoTHubClient_LL_Create` along with the parameters `iothub_ll_device_twin_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
AzureIoTClient 55:59b527ab3452 1251 iotHubClientInstance->devicetwin_user_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 55:59b527ab3452 1252 iotHubClientInstance->devicetwin_user_context->userContextCallback = userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 1253 result = IoTHubClient_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_device_twin_callback, iotHubClientInstance->devicetwin_user_context);
Azure.IoT.Build 54:6dcad9019a64 1254 if (result != IOTHUB_CLIENT_OK)
Azure.IoT.Build 54:6dcad9019a64 1255 {
Azure.IoT.Build 54:6dcad9019a64 1256 LogError("IoTHubClient_LL_SetDeviceTwinCallback failed");
Azure.IoT.Build 54:6dcad9019a64 1257 free(iotHubClientInstance->devicetwin_user_context);
Azure.IoT.Build 54:6dcad9019a64 1258 }
Azure.IoT.Build 54:6dcad9019a64 1259 }
AzureIoTClient 53:1e5a1ca1f274 1260 }
AzureIoTClient 53:1e5a1ca1f274 1261 }
AzureIoTClient 53:1e5a1ca1f274 1262 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 16:deba40344375 1263 }
AzureIoTClient 16:deba40344375 1264 }
AzureIoTClient 16:deba40344375 1265 return result;
AzureIoTClient 16:deba40344375 1266 }
AzureIoTClient 42:448eecc3676e 1267
AzureIoTClient 53:1e5a1ca1f274 1268 IOTHUB_CLIENT_RESULT IoTHubClient_SendReportedState(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
AzureIoTClient 53:1e5a1ca1f274 1269 {
AzureIoTClient 53:1e5a1ca1f274 1270 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 1271
AzureIoTClient 53:1e5a1ca1f274 1272 /*Codes_SRS_IOTHUBCLIENT_10_013: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1273 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 1274 {
AzureIoTClient 53:1e5a1ca1f274 1275 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1276 LogError("invalid arg (NULL)");
AzureIoTClient 53:1e5a1ca1f274 1277 }
AzureIoTClient 53:1e5a1ca1f274 1278 else
AzureIoTClient 53:1e5a1ca1f274 1279 {
AzureIoTClient 53:1e5a1ca1f274 1280 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 53:1e5a1ca1f274 1281
AzureIoTClient 53:1e5a1ca1f274 1282 /*Codes_SRS_IOTHUBCLIENT_10_021: [** `IoTHubClient_SendReportedState` shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 53:1e5a1ca1f274 1283 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 1284 {
AzureIoTClient 53:1e5a1ca1f274 1285 /*Codes_SRS_IOTHUBCLIENT_10_014: [** If acquiring the lock fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1286 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1287 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 1288 }
AzureIoTClient 53:1e5a1ca1f274 1289 else
AzureIoTClient 53:1e5a1ca1f274 1290 {
Azure.IoT.Build 54:6dcad9019a64 1291 if (iotHubClientInstance->created_with_transport_handle == 0)
Azure.IoT.Build 54:6dcad9019a64 1292 {
Azure.IoT.Build 54:6dcad9019a64 1293 iotHubClientInstance->reported_state_callback = reportedStateCallback;
Azure.IoT.Build 54:6dcad9019a64 1294 }
AzureIoTClient 53:1e5a1ca1f274 1295 /*Codes_SRS_IOTHUBCLIENT_10_015: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1296 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1297 {
AzureIoTClient 53:1e5a1ca1f274 1298 /*Codes_SRS_IOTHUBCLIENT_10_016: [** If starting the thread fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 53:1e5a1ca1f274 1299 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1300 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 1301 }
AzureIoTClient 53:1e5a1ca1f274 1302 else
AzureIoTClient 53:1e5a1ca1f274 1303 {
Azure.IoT.Build 54:6dcad9019a64 1304 if (iotHubClientInstance->created_with_transport_handle != 0 || reportedStateCallback == NULL)
Azure.IoT.Build 54:6dcad9019a64 1305 {
Azure.IoT.Build 54:6dcad9019a64 1306 /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClient_LL_SendReportedState`, while passing the `IoTHubClient_LL handle` created by `IoTHubClient_LL_Create` along with the parameters `reportedState`, `size`, `reportedStateCallback`, and `userContextCallback`. ]*/
Azure.IoT.Build 54:6dcad9019a64 1307 /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClient_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClient_LL_SendReportedState`. **]*/
Azure.IoT.Build 54:6dcad9019a64 1308 result = IoTHubClient_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, reportedStateCallback, userContextCallback);
Azure.IoT.Build 54:6dcad9019a64 1309 }
Azure.IoT.Build 54:6dcad9019a64 1310 else
AzureIoTClient 53:1e5a1ca1f274 1311 {
Azure.IoT.Build 54:6dcad9019a64 1312 /* Codes_SRS_IOTHUBCLIENT_07_003: [ IoTHubClient_SendReportedState shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClient_LL_SendReportedState function as a user context. ] */
Azure.IoT.Build 54:6dcad9019a64 1313 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
Azure.IoT.Build 54:6dcad9019a64 1314 if (queue_context == NULL)
Azure.IoT.Build 54:6dcad9019a64 1315 {
Azure.IoT.Build 54:6dcad9019a64 1316 result = IOTHUB_CLIENT_ERROR;
Azure.IoT.Build 54:6dcad9019a64 1317 LogError("Failed allocating QUEUE_CONTEXT");
Azure.IoT.Build 54:6dcad9019a64 1318 }
Azure.IoT.Build 54:6dcad9019a64 1319 else
Azure.IoT.Build 54:6dcad9019a64 1320 {
Azure.IoT.Build 54:6dcad9019a64 1321 queue_context->iotHubClientHandle = iotHubClientInstance;
Azure.IoT.Build 54:6dcad9019a64 1322 queue_context->userContextCallback = userContextCallback;
Azure.IoT.Build 54:6dcad9019a64 1323 /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClient_LL_SendReportedState`, while passing the `IoTHubClient_LL handle` created by `IoTHubClient_LL_Create` along with the parameters `reportedState`, `size`, `iothub_ll_reported_state_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
Azure.IoT.Build 54:6dcad9019a64 1324 /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClient_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClient_LL_SendReportedState`. **]*/
Azure.IoT.Build 54:6dcad9019a64 1325 result = IoTHubClient_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, iothub_ll_reported_state_callback, queue_context);
Azure.IoT.Build 54:6dcad9019a64 1326 if (result != IOTHUB_CLIENT_OK)
Azure.IoT.Build 54:6dcad9019a64 1327 {
Azure.IoT.Build 54:6dcad9019a64 1328 LogError("IoTHubClient_LL_SendReportedState failed");
Azure.IoT.Build 54:6dcad9019a64 1329 free(queue_context);
Azure.IoT.Build 54:6dcad9019a64 1330 }
Azure.IoT.Build 54:6dcad9019a64 1331 }
AzureIoTClient 53:1e5a1ca1f274 1332 }
AzureIoTClient 53:1e5a1ca1f274 1333 }
AzureIoTClient 53:1e5a1ca1f274 1334 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1335 }
AzureIoTClient 53:1e5a1ca1f274 1336 }
AzureIoTClient 53:1e5a1ca1f274 1337 return result;
AzureIoTClient 53:1e5a1ca1f274 1338 }
AzureIoTClient 53:1e5a1ca1f274 1339
AzureIoTClient 53:1e5a1ca1f274 1340 IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
AzureIoTClient 53:1e5a1ca1f274 1341 {
AzureIoTClient 53:1e5a1ca1f274 1342 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 53:1e5a1ca1f274 1343
AzureIoTClient 53:1e5a1ca1f274 1344 /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 53:1e5a1ca1f274 1345 if (iotHubClientHandle == NULL)
AzureIoTClient 53:1e5a1ca1f274 1346 {
AzureIoTClient 53:1e5a1ca1f274 1347 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 53:1e5a1ca1f274 1348 LogError("invalid arg (NULL)");
AzureIoTClient 53:1e5a1ca1f274 1349 }
AzureIoTClient 53:1e5a1ca1f274 1350 else
AzureIoTClient 53:1e5a1ca1f274 1351 {
AzureIoTClient 53:1e5a1ca1f274 1352 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 53:1e5a1ca1f274 1353
AzureIoTClient 53:1e5a1ca1f274 1354 /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 53:1e5a1ca1f274 1355 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 53:1e5a1ca1f274 1356 {
AzureIoTClient 53:1e5a1ca1f274 1357 /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 53:1e5a1ca1f274 1358 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1359 LogError("Could not acquire lock");
AzureIoTClient 53:1e5a1ca1f274 1360 }
AzureIoTClient 53:1e5a1ca1f274 1361 else
AzureIoTClient 53:1e5a1ca1f274 1362 {
AzureIoTClient 53:1e5a1ca1f274 1363 /*Codes_SRS_IOTHUBCLIENT_12_014: [ If the transport handle is null and the worker thread is not initialized, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
AzureIoTClient 53:1e5a1ca1f274 1364 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1365 {
AzureIoTClient 53:1e5a1ca1f274 1366 /*Codes_SRS_IOTHUBCLIENT_12_015: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 53:1e5a1ca1f274 1367 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 53:1e5a1ca1f274 1368 LogError("Could not start worker thread");
AzureIoTClient 53:1e5a1ca1f274 1369 }
AzureIoTClient 53:1e5a1ca1f274 1370 else
AzureIoTClient 53:1e5a1ca1f274 1371 {
AzureIoTClient 53:1e5a1ca1f274 1372 /*Codes_SRS_IOTHUBCLIENT_12_016: [ IoTHubClient_SetDeviceMethodCallback shall call IoTHubClient_LL_SetDeviceMethodCallback, while passing the IoTHubClient_LL_handle created by IoTHubClient_LL_Create along with the parameters deviceMethodCallback and userContextCallback. ]*/
AzureIoTClient 53:1e5a1ca1f274 1373 /*Codes_SRS_IOTHUBCLIENT_12_017: [ When IoTHubClient_LL_SetDeviceMethodCallback is called, IoTHubClient_SetDeviceMethodCallback shall return the result of IoTHubClient_LL_SetDeviceMethodCallback. ]*/
AzureIoTClient 53:1e5a1ca1f274 1374 result = IoTHubClient_LL_SetDeviceMethodCallback(iotHubClientInstance->IoTHubClientLLHandle, deviceMethodCallback, userContextCallback);
AzureIoTClient 53:1e5a1ca1f274 1375 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 53:1e5a1ca1f274 1376 {
AzureIoTClient 53:1e5a1ca1f274 1377 LogError("IoTHubClient_LL_SetDeviceMethodCallback failed");
AzureIoTClient 53:1e5a1ca1f274 1378 }
AzureIoTClient 53:1e5a1ca1f274 1379 }
AzureIoTClient 53:1e5a1ca1f274 1380
AzureIoTClient 53:1e5a1ca1f274 1381 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 53:1e5a1ca1f274 1382 }
AzureIoTClient 53:1e5a1ca1f274 1383 }
AzureIoTClient 53:1e5a1ca1f274 1384 return result;
AzureIoTClient 53:1e5a1ca1f274 1385 }
AzureIoTClient 53:1e5a1ca1f274 1386
AzureIoTClient 55:59b527ab3452 1387 IOTHUB_CLIENT_RESULT IoTHubClient_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
AzureIoTClient 55:59b527ab3452 1388 {
AzureIoTClient 55:59b527ab3452 1389 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 55:59b527ab3452 1390
AzureIoTClient 55:59b527ab3452 1391 /*Codes_SRS_IOTHUBCLIENT_07_001: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 55:59b527ab3452 1392 if (iotHubClientHandle == NULL)
AzureIoTClient 55:59b527ab3452 1393 {
AzureIoTClient 55:59b527ab3452 1394 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 55:59b527ab3452 1395 LogError("invalid arg (NULL)");
AzureIoTClient 55:59b527ab3452 1396 }
AzureIoTClient 55:59b527ab3452 1397 else
AzureIoTClient 55:59b527ab3452 1398 {
AzureIoTClient 55:59b527ab3452 1399 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 55:59b527ab3452 1400
AzureIoTClient 55:59b527ab3452 1401 /*Codes_SRS_IOTHUBCLIENT_07_007: [ IoTHubClient_SetDeviceMethodCallback_Ex shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 55:59b527ab3452 1402 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 55:59b527ab3452 1403 {
AzureIoTClient 55:59b527ab3452 1404 /*Codes_SRS_IOTHUBCLIENT_07_002: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 55:59b527ab3452 1405 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 55:59b527ab3452 1406 LogError("Could not acquire lock");
AzureIoTClient 55:59b527ab3452 1407 }
AzureIoTClient 55:59b527ab3452 1408 else
AzureIoTClient 55:59b527ab3452 1409 {
AzureIoTClient 55:59b527ab3452 1410 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 55:59b527ab3452 1411 {
AzureIoTClient 55:59b527ab3452 1412 iotHubClientInstance->device_method_callback = inboundDeviceMethodCallback;
AzureIoTClient 55:59b527ab3452 1413 }
AzureIoTClient 55:59b527ab3452 1414 /*Codes_SRS_IOTHUBCLIENT_07_003: [ If the transport handle is NULL and the worker thread is not initialized, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
AzureIoTClient 55:59b527ab3452 1415 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 55:59b527ab3452 1416 {
AzureIoTClient 55:59b527ab3452 1417 /*Codes_SRS_IOTHUBCLIENT_07_004: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 55:59b527ab3452 1418 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 55:59b527ab3452 1419 LogError("Could not start worker thread");
AzureIoTClient 55:59b527ab3452 1420 }
AzureIoTClient 55:59b527ab3452 1421 else
AzureIoTClient 55:59b527ab3452 1422 {
AzureIoTClient 55:59b527ab3452 1423 if (iotHubClientInstance->created_with_transport_handle != 0 || inboundDeviceMethodCallback == NULL)
AzureIoTClient 55:59b527ab3452 1424 {
AzureIoTClient 55:59b527ab3452 1425 /* Codes_SRS_IOTHUBCLIENT_07_008: [ If inboundDeviceMethodCallback is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClient_LL_SetDeviceMethodCallback_Ex, passing NULL for the iothub_ll_inbound_device_method_callback. ] */
AzureIoTClient 55:59b527ab3452 1426 result = IoTHubClient_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, NULL);
AzureIoTClient 55:59b527ab3452 1427 }
AzureIoTClient 55:59b527ab3452 1428 else
AzureIoTClient 55:59b527ab3452 1429 {
AzureIoTClient 55:59b527ab3452 1430 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 55:59b527ab3452 1431 if (queue_context == NULL)
AzureIoTClient 55:59b527ab3452 1432 {
AzureIoTClient 55:59b527ab3452 1433 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 55:59b527ab3452 1434 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 55:59b527ab3452 1435 }
AzureIoTClient 55:59b527ab3452 1436 else
AzureIoTClient 55:59b527ab3452 1437 {
AzureIoTClient 55:59b527ab3452 1438 /*Codes_SRS_IOTHUBCLIENT_07_005: [ IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClient_LL_SetDeviceMethodCallback_Ex, while passing the IoTHubClient_LL_handle created by IoTHubClient_LL_Create along with the parameters iothub_ll_inbound_device_method_callback and IOTHUB_QUEUE_CONTEXT. ]*/
AzureIoTClient 55:59b527ab3452 1439 queue_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 55:59b527ab3452 1440 queue_context->userContextCallback = userContextCallback;
AzureIoTClient 55:59b527ab3452 1441 /* Codes_SRS_IOTHUBCLIENT_07_006: [ When IoTHubClient_LL_SetDeviceMethodCallback_Ex is called, IoTHubClient_SetDeviceMethodCallback_Ex shall return the result of IoTHubClient_LL_SetDeviceMethodCallback_Ex. ] */
AzureIoTClient 55:59b527ab3452 1442 result = IoTHubClient_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_inbound_device_method_callback, queue_context);
AzureIoTClient 55:59b527ab3452 1443 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 55:59b527ab3452 1444 {
AzureIoTClient 55:59b527ab3452 1445 LogError("IoTHubClient_LL_SetDeviceMethodCallback failed");
AzureIoTClient 55:59b527ab3452 1446 free(queue_context);
AzureIoTClient 55:59b527ab3452 1447 }
AzureIoTClient 55:59b527ab3452 1448 }
AzureIoTClient 55:59b527ab3452 1449 }
AzureIoTClient 55:59b527ab3452 1450 }
AzureIoTClient 55:59b527ab3452 1451
AzureIoTClient 55:59b527ab3452 1452 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 55:59b527ab3452 1453 }
AzureIoTClient 55:59b527ab3452 1454 }
AzureIoTClient 55:59b527ab3452 1455 return result;
AzureIoTClient 55:59b527ab3452 1456 }
AzureIoTClient 55:59b527ab3452 1457
AzureIoTClient 55:59b527ab3452 1458 IOTHUB_CLIENT_RESULT IoTHubClient_DeviceMethodResponse(IOTHUB_CLIENT_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t respSize, int statusCode)
AzureIoTClient 55:59b527ab3452 1459 {
AzureIoTClient 55:59b527ab3452 1460 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 55:59b527ab3452 1461
AzureIoTClient 55:59b527ab3452 1462 /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 55:59b527ab3452 1463 if (iotHubClientHandle == NULL)
AzureIoTClient 55:59b527ab3452 1464 {
AzureIoTClient 55:59b527ab3452 1465 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 55:59b527ab3452 1466 LogError("invalid arg (NULL)");
AzureIoTClient 55:59b527ab3452 1467 }
AzureIoTClient 55:59b527ab3452 1468 else
AzureIoTClient 55:59b527ab3452 1469 {
AzureIoTClient 55:59b527ab3452 1470 IOTHUB_CLIENT_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
AzureIoTClient 55:59b527ab3452 1471
AzureIoTClient 55:59b527ab3452 1472 /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 55:59b527ab3452 1473 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 55:59b527ab3452 1474 {
AzureIoTClient 55:59b527ab3452 1475 /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 55:59b527ab3452 1476 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 55:59b527ab3452 1477 LogError("Could not acquire lock");
AzureIoTClient 55:59b527ab3452 1478 }
AzureIoTClient 55:59b527ab3452 1479 else
AzureIoTClient 55:59b527ab3452 1480 {
AzureIoTClient 55:59b527ab3452 1481 result = IoTHubClient_LL_DeviceMethodResponse(iotHubClientInstance->IoTHubClientLLHandle, methodId, response, respSize, statusCode);
AzureIoTClient 55:59b527ab3452 1482 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 55:59b527ab3452 1483 {
AzureIoTClient 55:59b527ab3452 1484 LogError("IoTHubClient_LL_DeviceMethodResponse failed");
AzureIoTClient 55:59b527ab3452 1485 }
AzureIoTClient 55:59b527ab3452 1486 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 55:59b527ab3452 1487 }
AzureIoTClient 55:59b527ab3452 1488 }
AzureIoTClient 55:59b527ab3452 1489 return result;
AzureIoTClient 55:59b527ab3452 1490 }
AzureIoTClient 53:1e5a1ca1f274 1491
AzureIoTClient 44:33dd78697616 1492 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 1493 static int uploadingThread(void *data)
AzureIoTClient 42:448eecc3676e 1494 {
AzureIoTClient 42:448eecc3676e 1495 UPLOADTOBLOB_SAVED_DATA* savedData = (UPLOADTOBLOB_SAVED_DATA*)data;
AzureIoTClient 42:448eecc3676e 1496
AzureIoTClient 42:448eecc3676e 1497 /*it so happens that IoTHubClient_LL_UploadToBlob is thread-safe because there's no saved state in the handle and there are no globals, so no need to protect it*/
AzureIoTClient 42:448eecc3676e 1498 /*not having it protected means multiple simultaneous uploads can happen*/
AzureIoTClient 42:448eecc3676e 1499 /*Codes_SRS_IOTHUBCLIENT_02_054: [ The thread shall call IoTHubClient_LL_UploadToBlob passing the information packed in the structure. ]*/
AzureIoTClient 42:448eecc3676e 1500 if (IoTHubClient_LL_UploadToBlob(savedData->iotHubClientHandle->IoTHubClientLLHandle, savedData->destinationFileName, savedData->source, savedData->size) != IOTHUB_CLIENT_OK)
AzureIoTClient 42:448eecc3676e 1501 {
AzureIoTClient 42:448eecc3676e 1502 LogError("unable to IoTHubClient_LL_UploadToBlob");
AzureIoTClient 42:448eecc3676e 1503 /*call the callback*/
AzureIoTClient 42:448eecc3676e 1504 if (savedData->iotHubClientFileUploadCallback != NULL)
AzureIoTClient 42:448eecc3676e 1505 {
AzureIoTClient 42:448eecc3676e 1506 /*Codes_SRS_IOTHUBCLIENT_02_055: [ If IoTHubClient_LL_UploadToBlob fails then the thread shall call iotHubClientFileUploadCallbackInternal passing as result FILE_UPLOAD_ERROR and as context the structure from SRS IOTHUBCLIENT 02 051. ]*/
AzureIoTClient 42:448eecc3676e 1507 savedData->iotHubClientFileUploadCallback(FILE_UPLOAD_ERROR, savedData->context);
AzureIoTClient 42:448eecc3676e 1508 }
AzureIoTClient 42:448eecc3676e 1509 }
AzureIoTClient 42:448eecc3676e 1510 else
AzureIoTClient 42:448eecc3676e 1511 {
AzureIoTClient 42:448eecc3676e 1512 if (savedData->iotHubClientFileUploadCallback != NULL)
AzureIoTClient 42:448eecc3676e 1513 {
AzureIoTClient 42:448eecc3676e 1514 /*Codes_SRS_IOTHUBCLIENT_02_056: [ Otherwise the thread iotHubClientFileUploadCallbackInternal passing as result FILE_UPLOAD_OK and the structure from SRS IOTHUBCLIENT 02 051. ]*/
AzureIoTClient 42:448eecc3676e 1515 savedData->iotHubClientFileUploadCallback(FILE_UPLOAD_OK, savedData->context);
AzureIoTClient 42:448eecc3676e 1516 }
AzureIoTClient 42:448eecc3676e 1517 }
AzureIoTClient 42:448eecc3676e 1518
AzureIoTClient 42:448eecc3676e 1519 /*Codes_SRS_IOTHUBCLIENT_02_071: [ The thread shall mark itself as disposable. ]*/
AzureIoTClient 42:448eecc3676e 1520 if (Lock(savedData->lockGarbage) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 1521 {
AzureIoTClient 42:448eecc3676e 1522 LogError("unable to Lock - trying anyway");
AzureIoTClient 42:448eecc3676e 1523 savedData->canBeGarbageCollected = 1;
AzureIoTClient 42:448eecc3676e 1524 }
AzureIoTClient 42:448eecc3676e 1525 else
AzureIoTClient 42:448eecc3676e 1526 {
AzureIoTClient 42:448eecc3676e 1527 savedData->canBeGarbageCollected = 1;
AzureIoTClient 42:448eecc3676e 1528
AzureIoTClient 42:448eecc3676e 1529 if (Unlock(savedData->lockGarbage) != LOCK_OK)
AzureIoTClient 42:448eecc3676e 1530 {
AzureIoTClient 42:448eecc3676e 1531 LogError("unable to Unlock after locking");
AzureIoTClient 42:448eecc3676e 1532 }
AzureIoTClient 42:448eecc3676e 1533 }
AzureIoTClient 42:448eecc3676e 1534 return 0;
AzureIoTClient 42:448eecc3676e 1535 }
AzureIoTClient 43:038d8511e817 1536 #endif
AzureIoTClient 42:448eecc3676e 1537
AzureIoTClient 44:33dd78697616 1538 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 42:448eecc3676e 1539 IOTHUB_CLIENT_RESULT IoTHubClient_UploadToBlobAsync(IOTHUB_CLIENT_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback, void* context)
AzureIoTClient 42:448eecc3676e 1540 {
AzureIoTClient 42:448eecc3676e 1541 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 42:448eecc3676e 1542 /*Codes_SRS_IOTHUBCLIENT_02_047: [ If iotHubClientHandle is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 1543 /*Codes_SRS_IOTHUBCLIENT_02_048: [ If destinationFileName is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 1544 /*Codes_SRS_IOTHUBCLIENT_02_049: [ If source is NULL and size is greated than 0 then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 42:448eecc3676e 1545 if (
AzureIoTClient 42:448eecc3676e 1546 (iotHubClientHandle == NULL) ||
AzureIoTClient 42:448eecc3676e 1547 (destinationFileName == NULL) ||
AzureIoTClient 42:448eecc3676e 1548 ((source == NULL) && (size > 0))
AzureIoTClient 42:448eecc3676e 1549 )
AzureIoTClient 42:448eecc3676e 1550 {
AzureIoTClient 42:448eecc3676e 1551 LogError("invalid parameters IOTHUB_CLIENT_HANDLE iotHubClientHandle = %p , const char* destinationFileName = %s, const unsigned char* source= %p, size_t size = %zu, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback = %p, void* context = %p",
AzureIoTClient 42:448eecc3676e 1552 iotHubClientHandle,
AzureIoTClient 42:448eecc3676e 1553 destinationFileName,
AzureIoTClient 42:448eecc3676e 1554 source,
AzureIoTClient 42:448eecc3676e 1555 size,
AzureIoTClient 42:448eecc3676e 1556 iotHubClientFileUploadCallback,
AzureIoTClient 42:448eecc3676e 1557 context
AzureIoTClient 42:448eecc3676e 1558 );
AzureIoTClient 42:448eecc3676e 1559 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 42:448eecc3676e 1560 }
AzureIoTClient 42:448eecc3676e 1561 else
AzureIoTClient 42:448eecc3676e 1562 {
AzureIoTClient 42:448eecc3676e 1563 /*Codes_SRS_IOTHUBCLIENT_02_051: [IoTHubClient_UploadToBlobAsync shall copy the souce, size, iotHubClientFileUploadCallback, context into a structure.]*/
AzureIoTClient 42:448eecc3676e 1564 UPLOADTOBLOB_SAVED_DATA *savedData = (UPLOADTOBLOB_SAVED_DATA *)malloc(sizeof(UPLOADTOBLOB_SAVED_DATA));
AzureIoTClient 42:448eecc3676e 1565 if (savedData == NULL)
AzureIoTClient 42:448eecc3676e 1566 {
AzureIoTClient 42:448eecc3676e 1567 /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 42:448eecc3676e 1568 LogError("unable to malloc - oom");
AzureIoTClient 42:448eecc3676e 1569 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1570 }
AzureIoTClient 42:448eecc3676e 1571 else
AzureIoTClient 42:448eecc3676e 1572 {
AzureIoTClient 42:448eecc3676e 1573 if (mallocAndStrcpy_s((char**)&savedData->destinationFileName, destinationFileName) != 0)
AzureIoTClient 42:448eecc3676e 1574 {
AzureIoTClient 42:448eecc3676e 1575 /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 42:448eecc3676e 1576 LogError("unable to mallocAndStrcpy_s");
AzureIoTClient 42:448eecc3676e 1577 free(savedData);
AzureIoTClient 42:448eecc3676e 1578 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1579 }
AzureIoTClient 42:448eecc3676e 1580 else
AzureIoTClient 42:448eecc3676e 1581 {
AzureIoTClient 42:448eecc3676e 1582 savedData->size = size;
AzureIoTClient 42:448eecc3676e 1583 int sourceCloned;
AzureIoTClient 42:448eecc3676e 1584 if (size == 0)
AzureIoTClient 42:448eecc3676e 1585 {
AzureIoTClient 42:448eecc3676e 1586 savedData->source = NULL;
AzureIoTClient 42:448eecc3676e 1587 sourceCloned = 1;
AzureIoTClient 42:448eecc3676e 1588 }
AzureIoTClient 42:448eecc3676e 1589 else
AzureIoTClient 42:448eecc3676e 1590 {
AzureIoTClient 42:448eecc3676e 1591 savedData->source = (unsigned char*)malloc(size);
AzureIoTClient 42:448eecc3676e 1592 if (savedData->source == NULL)
AzureIoTClient 42:448eecc3676e 1593 {
AzureIoTClient 42:448eecc3676e 1594 /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 42:448eecc3676e 1595 LogError("unable to malloc - oom");
AzureIoTClient 42:448eecc3676e 1596 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1597 free(savedData);
AzureIoTClient 42:448eecc3676e 1598 sourceCloned = 0;
AzureIoTClient 42:448eecc3676e 1599 }
AzureIoTClient 42:448eecc3676e 1600 else
AzureIoTClient 42:448eecc3676e 1601 {
AzureIoTClient 42:448eecc3676e 1602 sourceCloned = 1;
AzureIoTClient 42:448eecc3676e 1603 }
AzureIoTClient 42:448eecc3676e 1604 }
AzureIoTClient 42:448eecc3676e 1605
AzureIoTClient 42:448eecc3676e 1606 if (sourceCloned == 0)
AzureIoTClient 42:448eecc3676e 1607 {
AzureIoTClient 42:448eecc3676e 1608 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1609 }
AzureIoTClient 42:448eecc3676e 1610 else
AzureIoTClient 42:448eecc3676e 1611 {
Azure.IoT.Build 54:6dcad9019a64 1612 IOTHUB_CLIENT_INSTANCE* iotHubClientHandleData = (IOTHUB_CLIENT_INSTANCE*)iotHubClientHandle;
Azure.IoT.Build 54:6dcad9019a64 1613
AzureIoTClient 42:448eecc3676e 1614 savedData->iotHubClientFileUploadCallback = iotHubClientFileUploadCallback;
AzureIoTClient 42:448eecc3676e 1615 savedData->context = context;
AzureIoTClient 58:15b0d29b2667 1616 (void)memcpy(savedData->source, source, size);
Azure.IoT.Build 54:6dcad9019a64 1617
AzureIoTClient 42:448eecc3676e 1618 if (Lock(iotHubClientHandleData->LockHandle) != LOCK_OK) /*locking because the next statement is changing blobThreadsToBeJoined*/
AzureIoTClient 42:448eecc3676e 1619 {
AzureIoTClient 42:448eecc3676e 1620 LogError("unable to lock");
AzureIoTClient 42:448eecc3676e 1621 free(savedData->source);
AzureIoTClient 42:448eecc3676e 1622 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1623 free(savedData);
AzureIoTClient 42:448eecc3676e 1624 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1625 }
AzureIoTClient 42:448eecc3676e 1626 else
AzureIoTClient 42:448eecc3676e 1627 {
AzureIoTClient 42:448eecc3676e 1628 if ((result = StartWorkerThreadIfNeeded(iotHubClientHandleData)) != IOTHUB_CLIENT_OK)
AzureIoTClient 42:448eecc3676e 1629 {
AzureIoTClient 42:448eecc3676e 1630 free(savedData->source);
AzureIoTClient 42:448eecc3676e 1631 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1632 free(savedData);
AzureIoTClient 42:448eecc3676e 1633 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1634 LogError("Could not start worker thread");
AzureIoTClient 42:448eecc3676e 1635 }
AzureIoTClient 42:448eecc3676e 1636 else
AzureIoTClient 42:448eecc3676e 1637 {
AzureIoTClient 42:448eecc3676e 1638 /*Codes_SRS_IOTHUBCLIENT_02_058: [ IoTHubClient_UploadToBlobAsync shall add the structure to the list of structures that need to be cleaned once file upload finishes. ]*/
AzureIoTClient 52:1cc3c6d07cad 1639 LIST_ITEM_HANDLE item = singlylinkedlist_add(iotHubClientHandleData->savedDataToBeCleaned, savedData);
AzureIoTClient 42:448eecc3676e 1640 if (item == NULL)
AzureIoTClient 42:448eecc3676e 1641 {
AzureIoTClient 52:1cc3c6d07cad 1642 LogError("unable to singlylinkedlist_add");
AzureIoTClient 42:448eecc3676e 1643 free(savedData->source);
AzureIoTClient 42:448eecc3676e 1644 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1645 free(savedData);
AzureIoTClient 42:448eecc3676e 1646 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1647 }
AzureIoTClient 42:448eecc3676e 1648 else
AzureIoTClient 42:448eecc3676e 1649 {
AzureIoTClient 42:448eecc3676e 1650 savedData->iotHubClientHandle = iotHubClientHandle;
AzureIoTClient 42:448eecc3676e 1651 savedData->canBeGarbageCollected = 0;
AzureIoTClient 42:448eecc3676e 1652 if ((savedData->lockGarbage = Lock_Init()) == NULL)
AzureIoTClient 42:448eecc3676e 1653 {
AzureIoTClient 52:1cc3c6d07cad 1654 (void)singlylinkedlist_remove(iotHubClientHandleData->savedDataToBeCleaned, item);
AzureIoTClient 42:448eecc3676e 1655 free(savedData->source);
AzureIoTClient 42:448eecc3676e 1656 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1657 free(savedData);
AzureIoTClient 42:448eecc3676e 1658 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1659 LogError("unable to Lock_Init");
AzureIoTClient 42:448eecc3676e 1660 }
AzureIoTClient 42:448eecc3676e 1661 else
AzureIoTClient 42:448eecc3676e 1662 {
AzureIoTClient 42:448eecc3676e 1663 /*Codes_SRS_IOTHUBCLIENT_02_052: [ IoTHubClient_UploadToBlobAsync shall spawn a thread passing the structure build in SRS IOTHUBCLIENT 02 051 as thread data.]*/
AzureIoTClient 42:448eecc3676e 1664 if (ThreadAPI_Create(&savedData->uploadingThreadHandle, uploadingThread, savedData) != THREADAPI_OK)
AzureIoTClient 42:448eecc3676e 1665 {
AzureIoTClient 42:448eecc3676e 1666 /*Codes_SRS_IOTHUBCLIENT_02_053: [ If copying to the structure or spawning the thread fails, then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 42:448eecc3676e 1667 LogError("unablet to ThreadAPI_Create");
AzureIoTClient 42:448eecc3676e 1668 (void)Lock_Deinit(savedData->lockGarbage);
AzureIoTClient 52:1cc3c6d07cad 1669 (void)singlylinkedlist_remove(iotHubClientHandleData->savedDataToBeCleaned, item);
AzureIoTClient 42:448eecc3676e 1670 free(savedData->source);
AzureIoTClient 42:448eecc3676e 1671 free(savedData->destinationFileName);
AzureIoTClient 42:448eecc3676e 1672 free(savedData);
AzureIoTClient 42:448eecc3676e 1673 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 42:448eecc3676e 1674 }
AzureIoTClient 42:448eecc3676e 1675 else
AzureIoTClient 42:448eecc3676e 1676 {
AzureIoTClient 42:448eecc3676e 1677 result = IOTHUB_CLIENT_OK;
AzureIoTClient 42:448eecc3676e 1678 }
AzureIoTClient 42:448eecc3676e 1679 }
AzureIoTClient 42:448eecc3676e 1680 }
AzureIoTClient 42:448eecc3676e 1681 }
AzureIoTClient 53:1e5a1ca1f274 1682 (void)Unlock(iotHubClientHandleData->LockHandle);
AzureIoTClient 42:448eecc3676e 1683 }
AzureIoTClient 42:448eecc3676e 1684 }
AzureIoTClient 42:448eecc3676e 1685 }
AzureIoTClient 42:448eecc3676e 1686 }
AzureIoTClient 42:448eecc3676e 1687 }
AzureIoTClient 42:448eecc3676e 1688 return result;
AzureIoTClient 42:448eecc3676e 1689 }
AzureIoTClient 44:33dd78697616 1690 #endif /*DONT_USE_UPLOADTOBLOB*/