Microsoft Azure IoTHub client libraries

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more

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

Committer:
AzureIoTClient
Date:
Fri Jan 13 18:40:33 2017 -0800
Revision:
56:fdda9c1244e4
Parent:
55:59b527ab3452
Child:
57:4524910c6445
1.1.4

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