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:
Azure.IoT.Build
Date:
Wed Dec 14 15:59:51 2016 -0800
Revision:
54:6dcad9019a64
Parent:
53:1e5a1ca1f274
Child:
55:59b527ab3452
1.1.2

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