Microsoft Azure IoTHub client libraries

Dependents:   sht15_remote_monitoring RobotArmDemo iothub_client_sample_amqp f767zi_mqtt ... more

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

Committer:
AzureIoTClient
Date:
Mon Jun 11 15:39:23 2018 -0700
Revision:
88:248736be106e
Child:
89:a2ed767a532e
1.2.5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AzureIoTClient 88:248736be106e 1 // Copyright (c) Microsoft. All rights reserved.
AzureIoTClient 88:248736be106e 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
AzureIoTClient 88:248736be106e 3
AzureIoTClient 88:248736be106e 4 #include <stdlib.h>
AzureIoTClient 88:248736be106e 5 #include "azure_c_shared_utility/umock_c_prod.h"
AzureIoTClient 88:248736be106e 6 #include "azure_c_shared_utility/gballoc.h"
AzureIoTClient 88:248736be106e 7
AzureIoTClient 88:248736be106e 8 #include <signal.h>
AzureIoTClient 88:248736be106e 9 #include <stddef.h>
AzureIoTClient 88:248736be106e 10 #include "azure_c_shared_utility/optimize_size.h"
AzureIoTClient 88:248736be106e 11 #include "azure_c_shared_utility/crt_abstractions.h"
AzureIoTClient 88:248736be106e 12 #include "iothub_client_core.h"
AzureIoTClient 88:248736be106e 13 #include "iothub_client_core_ll.h"
AzureIoTClient 88:248736be106e 14 #include "internal/iothubtransport.h"
AzureIoTClient 88:248736be106e 15 #include "internal/iothub_client_private.h"
AzureIoTClient 88:248736be106e 16 #include "internal/iothubtransport.h"
AzureIoTClient 88:248736be106e 17 #include "azure_c_shared_utility/threadapi.h"
AzureIoTClient 88:248736be106e 18 #include "azure_c_shared_utility/lock.h"
AzureIoTClient 88:248736be106e 19 #include "azure_c_shared_utility/xlogging.h"
AzureIoTClient 88:248736be106e 20 #include "azure_c_shared_utility/singlylinkedlist.h"
AzureIoTClient 88:248736be106e 21 #include "azure_c_shared_utility/vector.h"
AzureIoTClient 88:248736be106e 22
AzureIoTClient 88:248736be106e 23 struct IOTHUB_QUEUE_CONTEXT_TAG;
AzureIoTClient 88:248736be106e 24
AzureIoTClient 88:248736be106e 25 typedef struct IOTHUB_CLIENT_CORE_INSTANCE_TAG
AzureIoTClient 88:248736be106e 26 {
AzureIoTClient 88:248736be106e 27 IOTHUB_CLIENT_CORE_LL_HANDLE IoTHubClientLLHandle;
AzureIoTClient 88:248736be106e 28 TRANSPORT_HANDLE TransportHandle;
AzureIoTClient 88:248736be106e 29 THREAD_HANDLE ThreadHandle;
AzureIoTClient 88:248736be106e 30 LOCK_HANDLE LockHandle;
AzureIoTClient 88:248736be106e 31 sig_atomic_t StopThread;
AzureIoTClient 88:248736be106e 32 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 33 SINGLYLINKEDLIST_HANDLE savedDataToBeCleaned; /*list containing UPLOADTOBLOB_SAVED_DATA*/
AzureIoTClient 88:248736be106e 34 #endif
AzureIoTClient 88:248736be106e 35 int created_with_transport_handle;
AzureIoTClient 88:248736be106e 36 VECTOR_HANDLE saved_user_callback_list;
AzureIoTClient 88:248736be106e 37 IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK desired_state_callback;
AzureIoTClient 88:248736be106e 38 IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK event_confirm_callback;
AzureIoTClient 88:248736be106e 39 IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reported_state_callback;
AzureIoTClient 88:248736be106e 40 IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connection_status_callback;
AzureIoTClient 88:248736be106e 41 IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC device_method_callback;
AzureIoTClient 88:248736be106e 42 IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inbound_device_method_callback;
AzureIoTClient 88:248736be106e 43 IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC message_callback;
AzureIoTClient 88:248736be106e 44 struct IOTHUB_QUEUE_CONTEXT_TAG* devicetwin_user_context;
AzureIoTClient 88:248736be106e 45 struct IOTHUB_QUEUE_CONTEXT_TAG* connection_status_user_context;
AzureIoTClient 88:248736be106e 46 struct IOTHUB_QUEUE_CONTEXT_TAG* message_user_context;
AzureIoTClient 88:248736be106e 47 struct IOTHUB_QUEUE_CONTEXT_TAG* method_user_context;
AzureIoTClient 88:248736be106e 48 } IOTHUB_CLIENT_CORE_INSTANCE;
AzureIoTClient 88:248736be106e 49
AzureIoTClient 88:248736be106e 50 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 51 typedef struct UPLOADTOBLOB_SAVED_DATA_TAG
AzureIoTClient 88:248736be106e 52 {
AzureIoTClient 88:248736be106e 53 unsigned char* source;
AzureIoTClient 88:248736be106e 54 size_t size;
AzureIoTClient 88:248736be106e 55 IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback;
AzureIoTClient 88:248736be106e 56 }UPLOADTOBLOB_SAVED_DATA;
AzureIoTClient 88:248736be106e 57
AzureIoTClient 88:248736be106e 58 typedef struct UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA_TAG
AzureIoTClient 88:248736be106e 59 {
AzureIoTClient 88:248736be106e 60 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback;
AzureIoTClient 88:248736be106e 61 IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx;
AzureIoTClient 88:248736be106e 62 }UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA;
AzureIoTClient 88:248736be106e 63
AzureIoTClient 88:248736be106e 64 typedef struct UPLOADTOBLOB_THREAD_INFO_TAG
AzureIoTClient 88:248736be106e 65 {
AzureIoTClient 88:248736be106e 66 char* destinationFileName;
AzureIoTClient 88:248736be106e 67 THREAD_HANDLE uploadingThreadHandle;
AzureIoTClient 88:248736be106e 68 LOCK_HANDLE lockGarbage;
AzureIoTClient 88:248736be106e 69 int canBeGarbageCollected; /*flag indicating that the UPLOADTOBLOB_SAVED_DATA structure can be freed because the thread deadling with it finished*/
AzureIoTClient 88:248736be106e 70 IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle;
AzureIoTClient 88:248736be106e 71 void* context;
AzureIoTClient 88:248736be106e 72 UPLOADTOBLOB_SAVED_DATA uploadBlobSavedData;
AzureIoTClient 88:248736be106e 73 UPLOADTOBLOB_MULTIBLOCK_SAVED_DATA uploadBlobMultiblockSavedData;
AzureIoTClient 88:248736be106e 74 }UPLOADTOBLOB_THREAD_INFO;
AzureIoTClient 88:248736be106e 75
AzureIoTClient 88:248736be106e 76 #endif
AzureIoTClient 88:248736be106e 77
AzureIoTClient 88:248736be106e 78 #define USER_CALLBACK_TYPE_VALUES \
AzureIoTClient 88:248736be106e 79 CALLBACK_TYPE_DEVICE_TWIN, \
AzureIoTClient 88:248736be106e 80 CALLBACK_TYPE_EVENT_CONFIRM, \
AzureIoTClient 88:248736be106e 81 CALLBACK_TYPE_REPORTED_STATE, \
AzureIoTClient 88:248736be106e 82 CALLBACK_TYPE_CONNECTION_STATUS, \
AzureIoTClient 88:248736be106e 83 CALLBACK_TYPE_DEVICE_METHOD, \
AzureIoTClient 88:248736be106e 84 CALLBACK_TYPE_INBOUD_DEVICE_METHOD, \
AzureIoTClient 88:248736be106e 85 CALLBACK_TYPE_MESSAGE
AzureIoTClient 88:248736be106e 86
AzureIoTClient 88:248736be106e 87 DEFINE_ENUM(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
AzureIoTClient 88:248736be106e 88 DEFINE_ENUM_STRINGS(USER_CALLBACK_TYPE, USER_CALLBACK_TYPE_VALUES)
AzureIoTClient 88:248736be106e 89
AzureIoTClient 88:248736be106e 90 typedef struct DEVICE_TWIN_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 91 {
AzureIoTClient 88:248736be106e 92 DEVICE_TWIN_UPDATE_STATE update_state;
AzureIoTClient 88:248736be106e 93 unsigned char* payLoad;
AzureIoTClient 88:248736be106e 94 size_t size;
AzureIoTClient 88:248736be106e 95 } DEVICE_TWIN_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 96
AzureIoTClient 88:248736be106e 97 typedef struct EVENT_CONFIRM_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 98 {
AzureIoTClient 88:248736be106e 99 IOTHUB_CLIENT_CONFIRMATION_RESULT confirm_result;
AzureIoTClient 88:248736be106e 100 } EVENT_CONFIRM_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 101
AzureIoTClient 88:248736be106e 102 typedef struct REPORTED_STATE_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 103 {
AzureIoTClient 88:248736be106e 104 int status_code;
AzureIoTClient 88:248736be106e 105 } REPORTED_STATE_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 106
AzureIoTClient 88:248736be106e 107 typedef struct CONNECTION_STATUS_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 108 {
AzureIoTClient 88:248736be106e 109 IOTHUB_CLIENT_CONNECTION_STATUS connection_status;
AzureIoTClient 88:248736be106e 110 IOTHUB_CLIENT_CONNECTION_STATUS_REASON status_reason;
AzureIoTClient 88:248736be106e 111 } CONNECTION_STATUS_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 112
AzureIoTClient 88:248736be106e 113 typedef struct METHOD_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 114 {
AzureIoTClient 88:248736be106e 115 STRING_HANDLE method_name;
AzureIoTClient 88:248736be106e 116 BUFFER_HANDLE payload;
AzureIoTClient 88:248736be106e 117 METHOD_HANDLE method_id;
AzureIoTClient 88:248736be106e 118 } METHOD_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 119
AzureIoTClient 88:248736be106e 120 typedef struct USER_CALLBACK_INFO_TAG
AzureIoTClient 88:248736be106e 121 {
AzureIoTClient 88:248736be106e 122 USER_CALLBACK_TYPE type;
AzureIoTClient 88:248736be106e 123 void* userContextCallback;
AzureIoTClient 88:248736be106e 124 union IOTHUB_CALLBACK
AzureIoTClient 88:248736be106e 125 {
AzureIoTClient 88:248736be106e 126 DEVICE_TWIN_CALLBACK_INFO dev_twin_cb_info;
AzureIoTClient 88:248736be106e 127 EVENT_CONFIRM_CALLBACK_INFO event_confirm_cb_info;
AzureIoTClient 88:248736be106e 128 REPORTED_STATE_CALLBACK_INFO reported_state_cb_info;
AzureIoTClient 88:248736be106e 129 CONNECTION_STATUS_CALLBACK_INFO connection_status_cb_info;
AzureIoTClient 88:248736be106e 130 METHOD_CALLBACK_INFO method_cb_info;
AzureIoTClient 88:248736be106e 131 MESSAGE_CALLBACK_INFO* message_cb_info;
AzureIoTClient 88:248736be106e 132 } iothub_callback;
AzureIoTClient 88:248736be106e 133 } USER_CALLBACK_INFO;
AzureIoTClient 88:248736be106e 134
AzureIoTClient 88:248736be106e 135 typedef struct IOTHUB_QUEUE_CONTEXT_TAG
AzureIoTClient 88:248736be106e 136 {
AzureIoTClient 88:248736be106e 137 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientHandle;
AzureIoTClient 88:248736be106e 138 void* userContextCallback;
AzureIoTClient 88:248736be106e 139 } IOTHUB_QUEUE_CONTEXT;
AzureIoTClient 88:248736be106e 140
AzureIoTClient 88:248736be106e 141 /*used by unittests only*/
AzureIoTClient 88:248736be106e 142 const size_t IoTHubClientCore_ThreadTerminationOffset = offsetof(IOTHUB_CLIENT_CORE_INSTANCE, StopThread);
AzureIoTClient 88:248736be106e 143
AzureIoTClient 88:248736be106e 144 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 145 static void freeUploadToBlobThreadInfo(UPLOADTOBLOB_THREAD_INFO* threadInfo)
AzureIoTClient 88:248736be106e 146 {
AzureIoTClient 88:248736be106e 147 Lock_Deinit(threadInfo->lockGarbage);
AzureIoTClient 88:248736be106e 148 free(threadInfo->uploadBlobSavedData.source);
AzureIoTClient 88:248736be106e 149 free(threadInfo->destinationFileName);
AzureIoTClient 88:248736be106e 150 free(threadInfo);
AzureIoTClient 88:248736be106e 151 }
AzureIoTClient 88:248736be106e 152
AzureIoTClient 88:248736be106e 153 /*this function is called from _Destroy and from ScheduleWork_Thread to join finished blobUpload threads and free that memory*/
AzureIoTClient 88:248736be106e 154 static void garbageCollectorImpl(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance)
AzureIoTClient 88:248736be106e 155 {
AzureIoTClient 88:248736be106e 156 /*see if any savedData structures can be disposed of*/
AzureIoTClient 88:248736be106e 157 /*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 88:248736be106e 158 LIST_ITEM_HANDLE item = singlylinkedlist_get_head_item(iotHubClientInstance->savedDataToBeCleaned);
AzureIoTClient 88:248736be106e 159 while (item != NULL)
AzureIoTClient 88:248736be106e 160 {
AzureIoTClient 88:248736be106e 161 UPLOADTOBLOB_THREAD_INFO* threadInfo = (UPLOADTOBLOB_THREAD_INFO*)singlylinkedlist_item_get_value(item);
AzureIoTClient 88:248736be106e 162 LIST_ITEM_HANDLE old_item = item;
AzureIoTClient 88:248736be106e 163 item = singlylinkedlist_get_next_item(item);
AzureIoTClient 88:248736be106e 164
AzureIoTClient 88:248736be106e 165 if (Lock(threadInfo->lockGarbage) != LOCK_OK)
AzureIoTClient 88:248736be106e 166 {
AzureIoTClient 88:248736be106e 167 LogError("unable to Lock");
AzureIoTClient 88:248736be106e 168 }
AzureIoTClient 88:248736be106e 169 else
AzureIoTClient 88:248736be106e 170 {
AzureIoTClient 88:248736be106e 171 if (threadInfo->canBeGarbageCollected == 1)
AzureIoTClient 88:248736be106e 172 {
AzureIoTClient 88:248736be106e 173 int notUsed;
AzureIoTClient 88:248736be106e 174 if (ThreadAPI_Join(threadInfo->uploadingThreadHandle, &notUsed) != THREADAPI_OK)
AzureIoTClient 88:248736be106e 175 {
AzureIoTClient 88:248736be106e 176 LogError("unable to ThreadAPI_Join");
AzureIoTClient 88:248736be106e 177 }
AzureIoTClient 88:248736be106e 178 (void)singlylinkedlist_remove(iotHubClientInstance->savedDataToBeCleaned, old_item);
AzureIoTClient 88:248736be106e 179
AzureIoTClient 88:248736be106e 180 if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
AzureIoTClient 88:248736be106e 181 {
AzureIoTClient 88:248736be106e 182 LogError("unable to unlock after locking");
AzureIoTClient 88:248736be106e 183 }
AzureIoTClient 88:248736be106e 184 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 185 }
AzureIoTClient 88:248736be106e 186 else
AzureIoTClient 88:248736be106e 187 {
AzureIoTClient 88:248736be106e 188 if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
AzureIoTClient 88:248736be106e 189 {
AzureIoTClient 88:248736be106e 190 LogError("unable to unlock after locking");
AzureIoTClient 88:248736be106e 191 }
AzureIoTClient 88:248736be106e 192 }
AzureIoTClient 88:248736be106e 193 }
AzureIoTClient 88:248736be106e 194 }
AzureIoTClient 88:248736be106e 195 }
AzureIoTClient 88:248736be106e 196 #endif
AzureIoTClient 88:248736be106e 197
AzureIoTClient 88:248736be106e 198 static bool iothub_ll_message_callback(MESSAGE_CALLBACK_INFO* messageData, void* userContextCallback)
AzureIoTClient 88:248736be106e 199 {
AzureIoTClient 88:248736be106e 200 bool result;
AzureIoTClient 88:248736be106e 201 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 202 if (queue_context == NULL)
AzureIoTClient 88:248736be106e 203 {
AzureIoTClient 88:248736be106e 204 LogError("invalid parameter userContextCallback(NULL)");
AzureIoTClient 88:248736be106e 205 result = false;
AzureIoTClient 88:248736be106e 206 }
AzureIoTClient 88:248736be106e 207 else
AzureIoTClient 88:248736be106e 208 {
AzureIoTClient 88:248736be106e 209 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 210 queue_cb_info.type = CALLBACK_TYPE_MESSAGE;
AzureIoTClient 88:248736be106e 211 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 212 queue_cb_info.iothub_callback.message_cb_info = messageData;
AzureIoTClient 88:248736be106e 213 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) == 0)
AzureIoTClient 88:248736be106e 214 {
AzureIoTClient 88:248736be106e 215 result = true;
AzureIoTClient 88:248736be106e 216 }
AzureIoTClient 88:248736be106e 217 else
AzureIoTClient 88:248736be106e 218 {
AzureIoTClient 88:248736be106e 219 LogError("message callback vector push failed.");
AzureIoTClient 88:248736be106e 220 result = false;
AzureIoTClient 88:248736be106e 221 }
AzureIoTClient 88:248736be106e 222 }
AzureIoTClient 88:248736be106e 223 return result;
AzureIoTClient 88:248736be106e 224 }
AzureIoTClient 88:248736be106e 225
AzureIoTClient 88:248736be106e 226 static int make_method_calback_queue_context(USER_CALLBACK_INFO* queue_cb_info, const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, IOTHUB_QUEUE_CONTEXT* queue_context)
AzureIoTClient 88:248736be106e 227 {
AzureIoTClient 88:248736be106e 228 int result;
AzureIoTClient 88:248736be106e 229 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_002: [ IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall copy the method_name and payload. ] */
AzureIoTClient 88:248736be106e 230 queue_cb_info->userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 231 queue_cb_info->iothub_callback.method_cb_info.method_id = method_id;
AzureIoTClient 88:248736be106e 232 if ((queue_cb_info->iothub_callback.method_cb_info.method_name = STRING_construct(method_name)) == NULL)
AzureIoTClient 88:248736be106e 233 {
AzureIoTClient 88:248736be106e 234 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 88:248736be106e 235 LogError("STRING_construct failed");
AzureIoTClient 88:248736be106e 236 result = __FAILURE__;
AzureIoTClient 88:248736be106e 237 }
AzureIoTClient 88:248736be106e 238 else
AzureIoTClient 88:248736be106e 239 {
AzureIoTClient 88:248736be106e 240 if ((queue_cb_info->iothub_callback.method_cb_info.payload = BUFFER_create(payload, size)) == NULL)
AzureIoTClient 88:248736be106e 241 {
AzureIoTClient 88:248736be106e 242 STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 243 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 88:248736be106e 244 LogError("BUFFER_create failed");
AzureIoTClient 88:248736be106e 245 result = __FAILURE__;
AzureIoTClient 88:248736be106e 246 }
AzureIoTClient 88:248736be106e 247 else
AzureIoTClient 88:248736be106e 248 {
AzureIoTClient 88:248736be106e 249 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, queue_cb_info, 1) == 0)
AzureIoTClient 88:248736be106e 250 {
AzureIoTClient 88:248736be106e 251 result = 0;
AzureIoTClient 88:248736be106e 252 }
AzureIoTClient 88:248736be106e 253 else
AzureIoTClient 88:248736be106e 254 {
AzureIoTClient 88:248736be106e 255 STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 256 BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 257 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_003: [ If a failure is encountered IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a non-NULL value. ]*/
AzureIoTClient 88:248736be106e 258 LogError("VECTOR_push_back failed");
AzureIoTClient 88:248736be106e 259 result = __FAILURE__;
AzureIoTClient 88:248736be106e 260 }
AzureIoTClient 88:248736be106e 261 }
AzureIoTClient 88:248736be106e 262 }
AzureIoTClient 88:248736be106e 263 return result;
AzureIoTClient 88:248736be106e 264 }
AzureIoTClient 88:248736be106e 265
AzureIoTClient 88:248736be106e 266 static int iothub_ll_device_method_callback(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback)
AzureIoTClient 88:248736be106e 267 {
AzureIoTClient 88:248736be106e 268 int result;
AzureIoTClient 88:248736be106e 269 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [ if userContextCallback is NULL, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a nonNULL value. ] */
AzureIoTClient 88:248736be106e 270 if (userContextCallback == NULL)
AzureIoTClient 88:248736be106e 271 {
AzureIoTClient 88:248736be106e 272 LogError("invalid parameter userContextCallback(NULL)");
AzureIoTClient 88:248736be106e 273 result = __FAILURE__;
AzureIoTClient 88:248736be106e 274 }
AzureIoTClient 88:248736be106e 275 else
AzureIoTClient 88:248736be106e 276 {
AzureIoTClient 88:248736be106e 277 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 278
AzureIoTClient 88:248736be106e 279 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 280 queue_cb_info.type = CALLBACK_TYPE_DEVICE_METHOD;
AzureIoTClient 88:248736be106e 281
AzureIoTClient 88:248736be106e 282 result = make_method_calback_queue_context(&queue_cb_info, method_name, payload, size, method_id, queue_context);
AzureIoTClient 88:248736be106e 283 if (result != 0)
AzureIoTClient 88:248736be106e 284 {
AzureIoTClient 88:248736be106e 285 LogError("construction of method calback queue context failed");
AzureIoTClient 88:248736be106e 286 result = __FAILURE__;
AzureIoTClient 88:248736be106e 287 }
AzureIoTClient 88:248736be106e 288 }
AzureIoTClient 88:248736be106e 289 return result;
AzureIoTClient 88:248736be106e 290 }
AzureIoTClient 88:248736be106e 291
AzureIoTClient 88:248736be106e 292 static int iothub_ll_inbound_device_method_callback(const char* method_name, const unsigned char* payload, size_t size, METHOD_HANDLE method_id, void* userContextCallback)
AzureIoTClient 88:248736be106e 293 {
AzureIoTClient 88:248736be106e 294 int result;
AzureIoTClient 88:248736be106e 295 /* Codes_SRS_IOTHUB_MQTT_TRANSPORT_07_001: [ if userContextCallback is NULL, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK shall return a nonNULL value. ] */
AzureIoTClient 88:248736be106e 296 if (userContextCallback == NULL)
AzureIoTClient 88:248736be106e 297 {
AzureIoTClient 88:248736be106e 298 LogError("invalid parameter userContextCallback(NULL)");
AzureIoTClient 88:248736be106e 299 result = __FAILURE__;
AzureIoTClient 88:248736be106e 300 }
AzureIoTClient 88:248736be106e 301 else
AzureIoTClient 88:248736be106e 302 {
AzureIoTClient 88:248736be106e 303 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 304
AzureIoTClient 88:248736be106e 305 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 306 queue_cb_info.type = CALLBACK_TYPE_INBOUD_DEVICE_METHOD;
AzureIoTClient 88:248736be106e 307
AzureIoTClient 88:248736be106e 308 result = make_method_calback_queue_context(&queue_cb_info, method_name, payload, size, method_id, queue_context);
AzureIoTClient 88:248736be106e 309 if (result != 0)
AzureIoTClient 88:248736be106e 310 {
AzureIoTClient 88:248736be106e 311 LogError("construction of method calback queue context failed");
AzureIoTClient 88:248736be106e 312 result = __FAILURE__;
AzureIoTClient 88:248736be106e 313 }
AzureIoTClient 88:248736be106e 314 }
AzureIoTClient 88:248736be106e 315 return result;
AzureIoTClient 88:248736be106e 316 }
AzureIoTClient 88:248736be106e 317
AzureIoTClient 88:248736be106e 318 static void iothub_ll_connection_status_callback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void* userContextCallback)
AzureIoTClient 88:248736be106e 319 {
AzureIoTClient 88:248736be106e 320 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 321 if (queue_context != NULL)
AzureIoTClient 88:248736be106e 322 {
AzureIoTClient 88:248736be106e 323 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 324 queue_cb_info.type = CALLBACK_TYPE_CONNECTION_STATUS;
AzureIoTClient 88:248736be106e 325 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 326 queue_cb_info.iothub_callback.connection_status_cb_info.status_reason = reason;
AzureIoTClient 88:248736be106e 327 queue_cb_info.iothub_callback.connection_status_cb_info.connection_status = result;
AzureIoTClient 88:248736be106e 328 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 88:248736be106e 329 {
AzureIoTClient 88:248736be106e 330 LogError("connection status callback vector push failed.");
AzureIoTClient 88:248736be106e 331 }
AzureIoTClient 88:248736be106e 332 }
AzureIoTClient 88:248736be106e 333 }
AzureIoTClient 88:248736be106e 334
AzureIoTClient 88:248736be106e 335 static void iothub_ll_event_confirm_callback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void* userContextCallback)
AzureIoTClient 88:248736be106e 336 {
AzureIoTClient 88:248736be106e 337 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 338 if (queue_context != NULL)
AzureIoTClient 88:248736be106e 339 {
AzureIoTClient 88:248736be106e 340 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 341 queue_cb_info.type = CALLBACK_TYPE_EVENT_CONFIRM;
AzureIoTClient 88:248736be106e 342 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 343 queue_cb_info.iothub_callback.event_confirm_cb_info.confirm_result = result;
AzureIoTClient 88:248736be106e 344 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 88:248736be106e 345 {
AzureIoTClient 88:248736be106e 346 LogError("event confirm callback vector push failed.");
AzureIoTClient 88:248736be106e 347 }
AzureIoTClient 88:248736be106e 348 free(queue_context);
AzureIoTClient 88:248736be106e 349 }
AzureIoTClient 88:248736be106e 350 }
AzureIoTClient 88:248736be106e 351
AzureIoTClient 88:248736be106e 352 static void iothub_ll_reported_state_callback(int status_code, void* userContextCallback)
AzureIoTClient 88:248736be106e 353 {
AzureIoTClient 88:248736be106e 354 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 355 if (queue_context != NULL)
AzureIoTClient 88:248736be106e 356 {
AzureIoTClient 88:248736be106e 357 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 358 queue_cb_info.type = CALLBACK_TYPE_REPORTED_STATE;
AzureIoTClient 88:248736be106e 359 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 360 queue_cb_info.iothub_callback.reported_state_cb_info.status_code = status_code;
AzureIoTClient 88:248736be106e 361 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 88:248736be106e 362 {
AzureIoTClient 88:248736be106e 363 LogError("reported state callback vector push failed.");
AzureIoTClient 88:248736be106e 364 }
AzureIoTClient 88:248736be106e 365 free(queue_context);
AzureIoTClient 88:248736be106e 366 }
AzureIoTClient 88:248736be106e 367 }
AzureIoTClient 88:248736be106e 368
AzureIoTClient 88:248736be106e 369 static void iothub_ll_device_twin_callback(DEVICE_TWIN_UPDATE_STATE update_state, const unsigned char* payLoad, size_t size, void* userContextCallback)
AzureIoTClient 88:248736be106e 370 {
AzureIoTClient 88:248736be106e 371 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)userContextCallback;
AzureIoTClient 88:248736be106e 372 if (queue_context != NULL)
AzureIoTClient 88:248736be106e 373 {
AzureIoTClient 88:248736be106e 374 int push_to_vector;
AzureIoTClient 88:248736be106e 375
AzureIoTClient 88:248736be106e 376 USER_CALLBACK_INFO queue_cb_info;
AzureIoTClient 88:248736be106e 377 queue_cb_info.type = CALLBACK_TYPE_DEVICE_TWIN;
AzureIoTClient 88:248736be106e 378 queue_cb_info.userContextCallback = queue_context->userContextCallback;
AzureIoTClient 88:248736be106e 379 queue_cb_info.iothub_callback.dev_twin_cb_info.update_state = update_state;
AzureIoTClient 88:248736be106e 380 if (payLoad == NULL)
AzureIoTClient 88:248736be106e 381 {
AzureIoTClient 88:248736be106e 382 queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = NULL;
AzureIoTClient 88:248736be106e 383 queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
AzureIoTClient 88:248736be106e 384 push_to_vector = 0;
AzureIoTClient 88:248736be106e 385 }
AzureIoTClient 88:248736be106e 386 else
AzureIoTClient 88:248736be106e 387 {
AzureIoTClient 88:248736be106e 388 queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad = (unsigned char*)malloc(size);
AzureIoTClient 88:248736be106e 389 if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad == NULL)
AzureIoTClient 88:248736be106e 390 {
AzureIoTClient 88:248736be106e 391 LogError("failure allocating payload in device twin callback.");
AzureIoTClient 88:248736be106e 392 queue_cb_info.iothub_callback.dev_twin_cb_info.size = 0;
AzureIoTClient 88:248736be106e 393 push_to_vector = __FAILURE__;
AzureIoTClient 88:248736be106e 394 }
AzureIoTClient 88:248736be106e 395 else
AzureIoTClient 88:248736be106e 396 {
AzureIoTClient 88:248736be106e 397 (void)memcpy(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad, payLoad, size);
AzureIoTClient 88:248736be106e 398 queue_cb_info.iothub_callback.dev_twin_cb_info.size = size;
AzureIoTClient 88:248736be106e 399 push_to_vector = 0;
AzureIoTClient 88:248736be106e 400 }
AzureIoTClient 88:248736be106e 401 }
AzureIoTClient 88:248736be106e 402 if (push_to_vector == 0)
AzureIoTClient 88:248736be106e 403 {
AzureIoTClient 88:248736be106e 404 if (VECTOR_push_back(queue_context->iotHubClientHandle->saved_user_callback_list, &queue_cb_info, 1) != 0)
AzureIoTClient 88:248736be106e 405 {
AzureIoTClient 88:248736be106e 406 if (queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad != NULL)
AzureIoTClient 88:248736be106e 407 {
AzureIoTClient 88:248736be106e 408 free(queue_cb_info.iothub_callback.dev_twin_cb_info.payLoad);
AzureIoTClient 88:248736be106e 409 }
AzureIoTClient 88:248736be106e 410 LogError("device twin callback userContextCallback vector push failed.");
AzureIoTClient 88:248736be106e 411 }
AzureIoTClient 88:248736be106e 412 }
AzureIoTClient 88:248736be106e 413 }
AzureIoTClient 88:248736be106e 414 else
AzureIoTClient 88:248736be106e 415 {
AzureIoTClient 88:248736be106e 416 LogError("device twin callback userContextCallback NULL");
AzureIoTClient 88:248736be106e 417 }
AzureIoTClient 88:248736be106e 418 }
AzureIoTClient 88:248736be106e 419
AzureIoTClient 88:248736be106e 420 static void dispatch_user_callbacks(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance, VECTOR_HANDLE call_backs)
AzureIoTClient 88:248736be106e 421 {
AzureIoTClient 88:248736be106e 422 size_t callbacks_length = VECTOR_size(call_backs);
AzureIoTClient 88:248736be106e 423 size_t index;
AzureIoTClient 88:248736be106e 424
AzureIoTClient 88:248736be106e 425 IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK desired_state_callback = NULL;
AzureIoTClient 88:248736be106e 426 IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK event_confirm_callback = NULL;
AzureIoTClient 88:248736be106e 427 IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reported_state_callback = NULL;
AzureIoTClient 88:248736be106e 428 IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connection_status_callback = NULL;
AzureIoTClient 88:248736be106e 429 IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC device_method_callback = NULL;
AzureIoTClient 88:248736be106e 430 IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inbound_device_method_callback = NULL;
AzureIoTClient 88:248736be106e 431 IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC message_callback = NULL;
AzureIoTClient 88:248736be106e 432 IOTHUB_CLIENT_CORE_HANDLE message_user_context_handle = NULL;
AzureIoTClient 88:248736be106e 433 IOTHUB_CLIENT_CORE_HANDLE method_user_context_handle = NULL;
AzureIoTClient 88:248736be106e 434
AzureIoTClient 88:248736be106e 435 // Make a local copy of these callbacks, as we don't run with a lock held and iotHubClientInstance may change mid-run.
AzureIoTClient 88:248736be106e 436 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 437 {
AzureIoTClient 88:248736be106e 438 LogError("failed locking for dispatch_user_callbacks");
AzureIoTClient 88:248736be106e 439 }
AzureIoTClient 88:248736be106e 440 else
AzureIoTClient 88:248736be106e 441 {
AzureIoTClient 88:248736be106e 442 desired_state_callback = iotHubClientInstance->desired_state_callback;
AzureIoTClient 88:248736be106e 443 event_confirm_callback = iotHubClientInstance->event_confirm_callback;
AzureIoTClient 88:248736be106e 444 reported_state_callback = iotHubClientInstance->reported_state_callback;
AzureIoTClient 88:248736be106e 445 connection_status_callback = iotHubClientInstance->connection_status_callback;
AzureIoTClient 88:248736be106e 446 device_method_callback = iotHubClientInstance->device_method_callback;
AzureIoTClient 88:248736be106e 447 inbound_device_method_callback = iotHubClientInstance->inbound_device_method_callback;
AzureIoTClient 88:248736be106e 448 message_callback = iotHubClientInstance->message_callback;
AzureIoTClient 88:248736be106e 449 if (iotHubClientInstance->method_user_context)
AzureIoTClient 88:248736be106e 450 {
AzureIoTClient 88:248736be106e 451 method_user_context_handle = iotHubClientInstance->method_user_context->iotHubClientHandle;
AzureIoTClient 88:248736be106e 452 }
AzureIoTClient 88:248736be106e 453 if (iotHubClientInstance->message_user_context)
AzureIoTClient 88:248736be106e 454 {
AzureIoTClient 88:248736be106e 455 message_user_context_handle = iotHubClientInstance->message_user_context->iotHubClientHandle;
AzureIoTClient 88:248736be106e 456 }
AzureIoTClient 88:248736be106e 457
AzureIoTClient 88:248736be106e 458 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 459 }
AzureIoTClient 88:248736be106e 460
AzureIoTClient 88:248736be106e 461
AzureIoTClient 88:248736be106e 462 for (index = 0; index < callbacks_length; index++)
AzureIoTClient 88:248736be106e 463 {
AzureIoTClient 88:248736be106e 464 USER_CALLBACK_INFO* queued_cb = (USER_CALLBACK_INFO*)VECTOR_element(call_backs, index);
AzureIoTClient 88:248736be106e 465 if (queued_cb == NULL)
AzureIoTClient 88:248736be106e 466 {
AzureIoTClient 88:248736be106e 467 LogError("VECTOR_element at index %zd is NULL.", index);
AzureIoTClient 88:248736be106e 468 }
AzureIoTClient 88:248736be106e 469 else
AzureIoTClient 88:248736be106e 470 {
AzureIoTClient 88:248736be106e 471 switch (queued_cb->type)
AzureIoTClient 88:248736be106e 472 {
AzureIoTClient 88:248736be106e 473 case CALLBACK_TYPE_DEVICE_TWIN:
AzureIoTClient 88:248736be106e 474 {
AzureIoTClient 88:248736be106e 475 if (desired_state_callback)
AzureIoTClient 88:248736be106e 476 {
AzureIoTClient 88:248736be106e 477 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);
AzureIoTClient 88:248736be106e 478 }
AzureIoTClient 88:248736be106e 479
AzureIoTClient 88:248736be106e 480 if (queued_cb->iothub_callback.dev_twin_cb_info.payLoad)
AzureIoTClient 88:248736be106e 481 {
AzureIoTClient 88:248736be106e 482 free(queued_cb->iothub_callback.dev_twin_cb_info.payLoad);
AzureIoTClient 88:248736be106e 483 }
AzureIoTClient 88:248736be106e 484 break;
AzureIoTClient 88:248736be106e 485 }
AzureIoTClient 88:248736be106e 486 case CALLBACK_TYPE_EVENT_CONFIRM:
AzureIoTClient 88:248736be106e 487 if (event_confirm_callback)
AzureIoTClient 88:248736be106e 488 {
AzureIoTClient 88:248736be106e 489 event_confirm_callback(queued_cb->iothub_callback.event_confirm_cb_info.confirm_result, queued_cb->userContextCallback);
AzureIoTClient 88:248736be106e 490 }
AzureIoTClient 88:248736be106e 491 break;
AzureIoTClient 88:248736be106e 492 case CALLBACK_TYPE_REPORTED_STATE:
AzureIoTClient 88:248736be106e 493 if (reported_state_callback)
AzureIoTClient 88:248736be106e 494 {
AzureIoTClient 88:248736be106e 495 reported_state_callback(queued_cb->iothub_callback.reported_state_cb_info.status_code, queued_cb->userContextCallback);
AzureIoTClient 88:248736be106e 496 }
AzureIoTClient 88:248736be106e 497 break;
AzureIoTClient 88:248736be106e 498 case CALLBACK_TYPE_CONNECTION_STATUS:
AzureIoTClient 88:248736be106e 499 if (connection_status_callback)
AzureIoTClient 88:248736be106e 500 {
AzureIoTClient 88:248736be106e 501 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);
AzureIoTClient 88:248736be106e 502 }
AzureIoTClient 88:248736be106e 503 break;
AzureIoTClient 88:248736be106e 504 case CALLBACK_TYPE_DEVICE_METHOD:
AzureIoTClient 88:248736be106e 505 if (device_method_callback)
AzureIoTClient 88:248736be106e 506 {
AzureIoTClient 88:248736be106e 507 const char* method_name = STRING_c_str(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 508 const unsigned char* payload = BUFFER_u_char(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 509 size_t payload_len = BUFFER_length(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 510
AzureIoTClient 88:248736be106e 511 unsigned char* payload_resp = NULL;
AzureIoTClient 88:248736be106e 512 size_t response_size = 0;
AzureIoTClient 88:248736be106e 513 int status = device_method_callback(method_name, payload, payload_len, &payload_resp, &response_size, queued_cb->userContextCallback);
AzureIoTClient 88:248736be106e 514
AzureIoTClient 88:248736be106e 515 if (payload_resp && (response_size > 0))
AzureIoTClient 88:248736be106e 516 {
AzureIoTClient 88:248736be106e 517 IOTHUB_CLIENT_RESULT result = IoTHubClientCore_DeviceMethodResponse(method_user_context_handle, queued_cb->iothub_callback.method_cb_info.method_id, (const unsigned char*)payload_resp, response_size, status);
AzureIoTClient 88:248736be106e 518 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 519 {
AzureIoTClient 88:248736be106e 520 LogError("IoTHubClientCore_LL_DeviceMethodResponse failed");
AzureIoTClient 88:248736be106e 521 }
AzureIoTClient 88:248736be106e 522 }
AzureIoTClient 88:248736be106e 523
AzureIoTClient 88:248736be106e 524 BUFFER_delete(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 525 STRING_delete(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 526
AzureIoTClient 88:248736be106e 527 if (payload_resp)
AzureIoTClient 88:248736be106e 528 {
AzureIoTClient 88:248736be106e 529 free(payload_resp);
AzureIoTClient 88:248736be106e 530 }
AzureIoTClient 88:248736be106e 531 }
AzureIoTClient 88:248736be106e 532 break;
AzureIoTClient 88:248736be106e 533 case CALLBACK_TYPE_INBOUD_DEVICE_METHOD:
AzureIoTClient 88:248736be106e 534 if (inbound_device_method_callback)
AzureIoTClient 88:248736be106e 535 {
AzureIoTClient 88:248736be106e 536 const char* method_name = STRING_c_str(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 537 const unsigned char* payload = BUFFER_u_char(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 538 size_t payload_len = BUFFER_length(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 539
AzureIoTClient 88:248736be106e 540 inbound_device_method_callback(method_name, payload, payload_len, queued_cb->iothub_callback.method_cb_info.method_id, queued_cb->userContextCallback);
AzureIoTClient 88:248736be106e 541
AzureIoTClient 88:248736be106e 542 BUFFER_delete(queued_cb->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 543 STRING_delete(queued_cb->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 544 }
AzureIoTClient 88:248736be106e 545 break;
AzureIoTClient 88:248736be106e 546 case CALLBACK_TYPE_MESSAGE:
AzureIoTClient 88:248736be106e 547 if (message_callback)
AzureIoTClient 88:248736be106e 548 {
AzureIoTClient 88:248736be106e 549 IOTHUBMESSAGE_DISPOSITION_RESULT disposition = message_callback(queued_cb->iothub_callback.message_cb_info->messageHandle, queued_cb->userContextCallback);
AzureIoTClient 88:248736be106e 550
AzureIoTClient 88:248736be106e 551 if (Lock(message_user_context_handle->LockHandle) == LOCK_OK)
AzureIoTClient 88:248736be106e 552 {
AzureIoTClient 88:248736be106e 553 IOTHUB_CLIENT_RESULT result = IoTHubClientCore_LL_SendMessageDisposition(message_user_context_handle->IoTHubClientLLHandle, queued_cb->iothub_callback.message_cb_info, disposition);
AzureIoTClient 88:248736be106e 554 (void)Unlock(message_user_context_handle->LockHandle);
AzureIoTClient 88:248736be106e 555 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 556 {
AzureIoTClient 88:248736be106e 557 LogError("IoTHubClientCore_LL_SendMessageDisposition failed");
AzureIoTClient 88:248736be106e 558 }
AzureIoTClient 88:248736be106e 559 }
AzureIoTClient 88:248736be106e 560 else
AzureIoTClient 88:248736be106e 561 {
AzureIoTClient 88:248736be106e 562 LogError("Lock failed");
AzureIoTClient 88:248736be106e 563 }
AzureIoTClient 88:248736be106e 564 }
AzureIoTClient 88:248736be106e 565 break;
AzureIoTClient 88:248736be106e 566 default:
AzureIoTClient 88:248736be106e 567 LogError("Invalid callback type '%s'", ENUM_TO_STRING(USER_CALLBACK_TYPE, queued_cb->type));
AzureIoTClient 88:248736be106e 568 break;
AzureIoTClient 88:248736be106e 569 }
AzureIoTClient 88:248736be106e 570 }
AzureIoTClient 88:248736be106e 571 }
AzureIoTClient 88:248736be106e 572 VECTOR_destroy(call_backs);
AzureIoTClient 88:248736be106e 573 }
AzureIoTClient 88:248736be106e 574
AzureIoTClient 88:248736be106e 575 static void ScheduleWork_Thread_ForMultiplexing(void* iotHubClientHandle)
AzureIoTClient 88:248736be106e 576 {
AzureIoTClient 88:248736be106e 577 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 578
AzureIoTClient 88:248736be106e 579 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 580 garbageCollectorImpl(iotHubClientInstance);
AzureIoTClient 88:248736be106e 581 #endif
AzureIoTClient 88:248736be106e 582 if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
AzureIoTClient 88:248736be106e 583 {
AzureIoTClient 88:248736be106e 584 VECTOR_HANDLE call_backs = VECTOR_move(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 88:248736be106e 585 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 586
AzureIoTClient 88:248736be106e 587 if (call_backs == NULL)
AzureIoTClient 88:248736be106e 588 {
AzureIoTClient 88:248736be106e 589 LogError("Failed moving user callbacks");
AzureIoTClient 88:248736be106e 590 }
AzureIoTClient 88:248736be106e 591 else
AzureIoTClient 88:248736be106e 592 {
AzureIoTClient 88:248736be106e 593 dispatch_user_callbacks(iotHubClientInstance, call_backs);
AzureIoTClient 88:248736be106e 594 }
AzureIoTClient 88:248736be106e 595 }
AzureIoTClient 88:248736be106e 596 else
AzureIoTClient 88:248736be106e 597 {
AzureIoTClient 88:248736be106e 598 LogError("failed locking for ScheduleWork_Thread_ForMultiplexing");
AzureIoTClient 88:248736be106e 599 }
AzureIoTClient 88:248736be106e 600 }
AzureIoTClient 88:248736be106e 601
AzureIoTClient 88:248736be106e 602 static int ScheduleWork_Thread(void* threadArgument)
AzureIoTClient 88:248736be106e 603 {
AzureIoTClient 88:248736be106e 604 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)threadArgument;
AzureIoTClient 88:248736be106e 605
AzureIoTClient 88:248736be106e 606 while (1)
AzureIoTClient 88:248736be106e 607 {
AzureIoTClient 88:248736be106e 608 if (Lock(iotHubClientInstance->LockHandle) == LOCK_OK)
AzureIoTClient 88:248736be106e 609 {
AzureIoTClient 88:248736be106e 610 /*Codes_SRS_IOTHUBCLIENT_01_038: [ The thread shall exit when IoTHubClient_Destroy is called. ]*/
AzureIoTClient 88:248736be106e 611 if (iotHubClientInstance->StopThread)
AzureIoTClient 88:248736be106e 612 {
AzureIoTClient 88:248736be106e 613 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 614 break; /*gets out of the thread*/
AzureIoTClient 88:248736be106e 615 }
AzureIoTClient 88:248736be106e 616 else
AzureIoTClient 88:248736be106e 617 {
AzureIoTClient 88:248736be106e 618 /* Codes_SRS_IOTHUBCLIENT_01_037: [The thread created by IoTHubClient_SendEvent or IoTHubClient_SetMessageCallback shall call IoTHubClientCore_LL_DoWork every 1 ms.] */
AzureIoTClient 88:248736be106e 619 /* Codes_SRS_IOTHUBCLIENT_01_039: [All calls to IoTHubClientCore_LL_DoWork shall be protected by the lock created in IotHubClient_Create.] */
AzureIoTClient 88:248736be106e 620 IoTHubClientCore_LL_DoWork(iotHubClientInstance->IoTHubClientLLHandle);
AzureIoTClient 88:248736be106e 621
AzureIoTClient 88:248736be106e 622 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 623 garbageCollectorImpl(iotHubClientInstance);
AzureIoTClient 88:248736be106e 624 #endif
AzureIoTClient 88:248736be106e 625 VECTOR_HANDLE call_backs = VECTOR_move(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 88:248736be106e 626 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 627 if (call_backs == NULL)
AzureIoTClient 88:248736be106e 628 {
AzureIoTClient 88:248736be106e 629 LogError("VECTOR_move failed");
AzureIoTClient 88:248736be106e 630 }
AzureIoTClient 88:248736be106e 631 else
AzureIoTClient 88:248736be106e 632 {
AzureIoTClient 88:248736be106e 633 dispatch_user_callbacks(iotHubClientInstance, call_backs);
AzureIoTClient 88:248736be106e 634 }
AzureIoTClient 88:248736be106e 635 }
AzureIoTClient 88:248736be106e 636 }
AzureIoTClient 88:248736be106e 637 else
AzureIoTClient 88:248736be106e 638 {
AzureIoTClient 88:248736be106e 639 /*Codes_SRS_IOTHUBCLIENT_01_040: [If acquiring the lock fails, IoTHubClientCore_LL_DoWork shall not be called.]*/
AzureIoTClient 88:248736be106e 640 /*no code, shall retry*/
AzureIoTClient 88:248736be106e 641 }
AzureIoTClient 88:248736be106e 642 (void)ThreadAPI_Sleep(1);
AzureIoTClient 88:248736be106e 643 }
AzureIoTClient 88:248736be106e 644
AzureIoTClient 88:248736be106e 645 ThreadAPI_Exit(0);
AzureIoTClient 88:248736be106e 646 return 0;
AzureIoTClient 88:248736be106e 647 }
AzureIoTClient 88:248736be106e 648
AzureIoTClient 88:248736be106e 649 static IOTHUB_CLIENT_RESULT StartWorkerThreadIfNeeded(IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance)
AzureIoTClient 88:248736be106e 650 {
AzureIoTClient 88:248736be106e 651 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 652 if (iotHubClientInstance->TransportHandle == NULL)
AzureIoTClient 88:248736be106e 653 {
AzureIoTClient 88:248736be106e 654 if (iotHubClientInstance->ThreadHandle == NULL)
AzureIoTClient 88:248736be106e 655 {
AzureIoTClient 88:248736be106e 656 iotHubClientInstance->StopThread = 0;
AzureIoTClient 88:248736be106e 657 if (ThreadAPI_Create(&iotHubClientInstance->ThreadHandle, ScheduleWork_Thread, iotHubClientInstance) != THREADAPI_OK)
AzureIoTClient 88:248736be106e 658 {
AzureIoTClient 88:248736be106e 659 LogError("ThreadAPI_Create failed");
AzureIoTClient 88:248736be106e 660 iotHubClientInstance->ThreadHandle = NULL;
AzureIoTClient 88:248736be106e 661 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 662 }
AzureIoTClient 88:248736be106e 663 else
AzureIoTClient 88:248736be106e 664 {
AzureIoTClient 88:248736be106e 665 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 666 }
AzureIoTClient 88:248736be106e 667 }
AzureIoTClient 88:248736be106e 668 else
AzureIoTClient 88:248736be106e 669 {
AzureIoTClient 88:248736be106e 670 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 671 }
AzureIoTClient 88:248736be106e 672 }
AzureIoTClient 88:248736be106e 673 else
AzureIoTClient 88:248736be106e 674 {
AzureIoTClient 88:248736be106e 675 /*Codes_SRS_IOTHUBCLIENT_17_012: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
AzureIoTClient 88:248736be106e 676 /*Codes_SRS_IOTHUBCLIENT_17_011: [ If the transport connection is shared, the thread shall be started by calling IoTHubTransport_StartWorkerThread*/
AzureIoTClient 88:248736be106e 677 result = IoTHubTransport_StartWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientInstance, ScheduleWork_Thread_ForMultiplexing);
AzureIoTClient 88:248736be106e 678 }
AzureIoTClient 88:248736be106e 679 return result;
AzureIoTClient 88:248736be106e 680 }
AzureIoTClient 88:248736be106e 681
AzureIoTClient 88:248736be106e 682 static IOTHUB_CLIENT_CORE_INSTANCE* create_iothub_instance(const IOTHUB_CLIENT_CONFIG* config, TRANSPORT_HANDLE transportHandle, const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol, const char* iothub_uri, const char* device_id)
AzureIoTClient 88:248736be106e 683 {
AzureIoTClient 88:248736be106e 684 /* Codes_SRS_IOTHUBCLIENT_12_020: [** `IoTHubClient_CreateFromDeviceAuth` shall allocate a new `IoTHubClient` instance. **] */
AzureIoTClient 88:248736be106e 685 IOTHUB_CLIENT_CORE_INSTANCE* result = (IOTHUB_CLIENT_CORE_INSTANCE*)malloc(sizeof(IOTHUB_CLIENT_CORE_INSTANCE));
AzureIoTClient 88:248736be106e 686
AzureIoTClient 88:248736be106e 687 /* Codes_SRS_IOTHUBCLIENT_12_021: [** If allocating memory for the new `IoTHubClient` instance fails, then `IoTHubClient_CreateFromDeviceAuth` shall return `NULL`. **] */
AzureIoTClient 88:248736be106e 688 /* Codes_SRS_IOTHUBCLIENT_01_004: [If allocating memory for the new IoTHubClient instance fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 88:248736be106e 689 if (result != NULL)
AzureIoTClient 88:248736be106e 690 {
AzureIoTClient 88:248736be106e 691 /* Codes_SRS_IOTHUBCLIENT_01_029: [IoTHubClient_Create shall create a lock object to be used later for serializing IoTHubClient calls.] */
AzureIoTClient 88:248736be106e 692 if ((result->saved_user_callback_list = VECTOR_create(sizeof(USER_CALLBACK_INFO))) == NULL)
AzureIoTClient 88:248736be106e 693 {
AzureIoTClient 88:248736be106e 694 LogError("Failed creating VECTOR");
AzureIoTClient 88:248736be106e 695 free(result);
AzureIoTClient 88:248736be106e 696 result = NULL;
AzureIoTClient 88:248736be106e 697 }
AzureIoTClient 88:248736be106e 698 else
AzureIoTClient 88:248736be106e 699 {
AzureIoTClient 88:248736be106e 700 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 701 /*Codes_SRS_IOTHUBCLIENT_02_060: [ IoTHubClient_Create shall create a SINGLYLINKEDLIST_HANDLE containing THREAD_HANDLE (created by future calls to IoTHubClient_UploadToBlobAsync). ]*/
AzureIoTClient 88:248736be106e 702 if ((result->savedDataToBeCleaned = singlylinkedlist_create()) == NULL)
AzureIoTClient 88:248736be106e 703 {
AzureIoTClient 88:248736be106e 704 /*Codes_SRS_IOTHUBCLIENT_02_061: [ If creating the SINGLYLINKEDLIST_HANDLE fails then IoTHubClient_Create shall fail and return NULL. ]*/
AzureIoTClient 88:248736be106e 705 LogError("unable to singlylinkedlist_create");
AzureIoTClient 88:248736be106e 706 VECTOR_destroy(result->saved_user_callback_list);
AzureIoTClient 88:248736be106e 707 free(result);
AzureIoTClient 88:248736be106e 708 result = NULL;
AzureIoTClient 88:248736be106e 709 }
AzureIoTClient 88:248736be106e 710 else
AzureIoTClient 88:248736be106e 711 #endif
AzureIoTClient 88:248736be106e 712 {
AzureIoTClient 88:248736be106e 713 result->TransportHandle = transportHandle;
AzureIoTClient 88:248736be106e 714 result->created_with_transport_handle = 0;
AzureIoTClient 88:248736be106e 715 if (config != NULL)
AzureIoTClient 88:248736be106e 716 {
AzureIoTClient 88:248736be106e 717 if (transportHandle != NULL)
AzureIoTClient 88:248736be106e 718 {
AzureIoTClient 88:248736be106e 719 /*Codes_SRS_IOTHUBCLIENT_17_005: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLock to get the transport lock to be used later for serializing IoTHubClient calls. ]*/
AzureIoTClient 88:248736be106e 720 result->LockHandle = IoTHubTransport_GetLock(transportHandle);
AzureIoTClient 88:248736be106e 721 if (result->LockHandle == NULL)
AzureIoTClient 88:248736be106e 722 {
AzureIoTClient 88:248736be106e 723 LogError("unable to IoTHubTransport_GetLock");
AzureIoTClient 88:248736be106e 724 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 725 }
AzureIoTClient 88:248736be106e 726 else
AzureIoTClient 88:248736be106e 727 {
AzureIoTClient 88:248736be106e 728 IOTHUB_CLIENT_DEVICE_CONFIG deviceConfig;
AzureIoTClient 88:248736be106e 729 deviceConfig.deviceId = config->deviceId;
AzureIoTClient 88:248736be106e 730 deviceConfig.deviceKey = config->deviceKey;
AzureIoTClient 88:248736be106e 731 deviceConfig.protocol = config->protocol;
AzureIoTClient 88:248736be106e 732 deviceConfig.deviceSasToken = config->deviceSasToken;
AzureIoTClient 88:248736be106e 733
AzureIoTClient 88:248736be106e 734 /*Codes_SRS_IOTHUBCLIENT_17_003: [ IoTHubClient_CreateWithTransport shall call IoTHubTransport_GetLLTransport on transportHandle to get lower layer transport. ]*/
AzureIoTClient 88:248736be106e 735 deviceConfig.transportHandle = IoTHubTransport_GetLLTransport(transportHandle);
AzureIoTClient 88:248736be106e 736 if (deviceConfig.transportHandle == NULL)
AzureIoTClient 88:248736be106e 737 {
AzureIoTClient 88:248736be106e 738 LogError("unable to IoTHubTransport_GetLLTransport");
AzureIoTClient 88:248736be106e 739 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 740 }
AzureIoTClient 88:248736be106e 741 else
AzureIoTClient 88:248736be106e 742 {
AzureIoTClient 88:248736be106e 743 if (Lock(result->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 744 {
AzureIoTClient 88:248736be106e 745 LogError("unable to Lock");
AzureIoTClient 88:248736be106e 746 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 747 }
AzureIoTClient 88:248736be106e 748 else
AzureIoTClient 88:248736be106e 749 {
AzureIoTClient 88:248736be106e 750 /*Codes_SRS_IOTHUBCLIENT_17_007: [ IoTHubClient_CreateWithTransport shall instantiate a new IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_CreateWithTransport and passing the lower layer transport and config argument. ]*/
AzureIoTClient 88:248736be106e 751 result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateWithTransport(&deviceConfig);
AzureIoTClient 88:248736be106e 752 result->created_with_transport_handle = 1;
AzureIoTClient 88:248736be106e 753 if (Unlock(result->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 754 {
AzureIoTClient 88:248736be106e 755 LogError("unable to Unlock");
AzureIoTClient 88:248736be106e 756 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 757 }
AzureIoTClient 88:248736be106e 758 }
AzureIoTClient 88:248736be106e 759 }
AzureIoTClient 88:248736be106e 760 }
AzureIoTClient 88:248736be106e 761 }
AzureIoTClient 88:248736be106e 762 else
AzureIoTClient 88:248736be106e 763 {
AzureIoTClient 88:248736be106e 764 result->LockHandle = Lock_Init();
AzureIoTClient 88:248736be106e 765 if (result->LockHandle == NULL)
AzureIoTClient 88:248736be106e 766 {
AzureIoTClient 88:248736be106e 767 /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 88:248736be106e 768 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
AzureIoTClient 88:248736be106e 769 LogError("Failure creating Lock object");
AzureIoTClient 88:248736be106e 770 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 771 }
AzureIoTClient 88:248736be106e 772 else
AzureIoTClient 88:248736be106e 773 {
AzureIoTClient 88:248736be106e 774 /* Codes_SRS_IOTHUBCLIENT_01_002: [IoTHubClient_Create shall instantiate a new IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_Create and passing the config argument.] */
AzureIoTClient 88:248736be106e 775 result->IoTHubClientLLHandle = IoTHubClientCore_LL_Create(config);
AzureIoTClient 88:248736be106e 776 }
AzureIoTClient 88:248736be106e 777 }
AzureIoTClient 88:248736be106e 778 }
AzureIoTClient 88:248736be106e 779 else if (iothub_uri != NULL)
AzureIoTClient 88:248736be106e 780 {
AzureIoTClient 88:248736be106e 781 #ifdef USE_PROV_MODULE
AzureIoTClient 88:248736be106e 782 /* Codes_SRS_IOTHUBCLIENT_12_022: [** `IoTHubClient_CreateFromDeviceAuth` shall create a lock object to be used later for serializing IoTHubClient calls. **] */
AzureIoTClient 88:248736be106e 783 result->LockHandle = Lock_Init();
AzureIoTClient 88:248736be106e 784 if (result->LockHandle == NULL)
AzureIoTClient 88:248736be106e 785 {
AzureIoTClient 88:248736be106e 786 /* Codes_SRS_IOTHUBCLIENT_12_023: [** If creating the lock fails, then IoTHubClient_CreateFromDeviceAuth shall return NULL. **] */
AzureIoTClient 88:248736be106e 787 LogError("Failure creating Lock object");
AzureIoTClient 88:248736be106e 788 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 789 }
AzureIoTClient 88:248736be106e 790 else
AzureIoTClient 88:248736be106e 791 {
AzureIoTClient 88:248736be106e 792 /* Codes_SRS_IOTHUBCLIENT_12_025: [** `IoTHubClient_CreateFromDeviceAuth` shall instantiate a new `IoTHubClientCore_LL` instance by calling `IoTHubClientCore_LL_CreateFromDeviceAuth` and passing iothub_uri, device_id and protocol argument. **] */
AzureIoTClient 88:248736be106e 793 result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateFromDeviceAuth(iothub_uri, device_id, protocol);
AzureIoTClient 88:248736be106e 794 }
AzureIoTClient 88:248736be106e 795 #else
AzureIoTClient 88:248736be106e 796 (void)device_id;
AzureIoTClient 88:248736be106e 797 LogError("Provisioning is not enabled for the build");
AzureIoTClient 88:248736be106e 798 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 799 #endif
AzureIoTClient 88:248736be106e 800 }
AzureIoTClient 88:248736be106e 801 else
AzureIoTClient 88:248736be106e 802 {
AzureIoTClient 88:248736be106e 803 result->LockHandle = Lock_Init();
AzureIoTClient 88:248736be106e 804 if (result->LockHandle == NULL)
AzureIoTClient 88:248736be106e 805 {
AzureIoTClient 88:248736be106e 806 /* Codes_SRS_IOTHUBCLIENT_01_030: [If creating the lock fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 88:248736be106e 807 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
AzureIoTClient 88:248736be106e 808 LogError("Failure creating Lock object");
AzureIoTClient 88:248736be106e 809 result->IoTHubClientLLHandle = NULL;
AzureIoTClient 88:248736be106e 810 }
AzureIoTClient 88:248736be106e 811 else
AzureIoTClient 88:248736be106e 812 {
AzureIoTClient 88:248736be106e 813 result->IoTHubClientLLHandle = IoTHubClientCore_LL_CreateFromConnectionString(connectionString, protocol);
AzureIoTClient 88:248736be106e 814 }
AzureIoTClient 88:248736be106e 815 }
AzureIoTClient 88:248736be106e 816
AzureIoTClient 88:248736be106e 817 if (result->IoTHubClientLLHandle == NULL)
AzureIoTClient 88:248736be106e 818 {
AzureIoTClient 88:248736be106e 819 /* Codes_SRS_IOTHUBCLIENT_01_003: [If IoTHubClientCore_LL_Create fails, then IoTHubClient_Create shall return NULL.] */
AzureIoTClient 88:248736be106e 820 /* Codes_SRS_IOTHUBCLIENT_01_031: [If IoTHubClient_Create fails, all resources allocated by it shall be freed.] */
AzureIoTClient 88:248736be106e 821 /* Codes_SRS_IOTHUBCLIENT_17_006: [ If IoTHubTransport_GetLock fails, then IoTHubClient_CreateWithTransport shall return NULL. ]*/
AzureIoTClient 88:248736be106e 822 if (transportHandle == NULL)
AzureIoTClient 88:248736be106e 823 {
AzureIoTClient 88:248736be106e 824 Lock_Deinit(result->LockHandle);
AzureIoTClient 88:248736be106e 825 }
AzureIoTClient 88:248736be106e 826 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 827 singlylinkedlist_destroy(result->savedDataToBeCleaned);
AzureIoTClient 88:248736be106e 828 #endif
AzureIoTClient 88:248736be106e 829 LogError("Failure creating iothub handle");
AzureIoTClient 88:248736be106e 830 VECTOR_destroy(result->saved_user_callback_list);
AzureIoTClient 88:248736be106e 831 free(result);
AzureIoTClient 88:248736be106e 832 result = NULL;
AzureIoTClient 88:248736be106e 833 }
AzureIoTClient 88:248736be106e 834 else
AzureIoTClient 88:248736be106e 835 {
AzureIoTClient 88:248736be106e 836 result->ThreadHandle = NULL;
AzureIoTClient 88:248736be106e 837 result->desired_state_callback = NULL;
AzureIoTClient 88:248736be106e 838 result->event_confirm_callback = NULL;
AzureIoTClient 88:248736be106e 839 result->reported_state_callback = NULL;
AzureIoTClient 88:248736be106e 840 result->devicetwin_user_context = NULL;
AzureIoTClient 88:248736be106e 841 result->connection_status_callback = NULL;
AzureIoTClient 88:248736be106e 842 result->connection_status_user_context = NULL;
AzureIoTClient 88:248736be106e 843 result->message_callback = NULL;
AzureIoTClient 88:248736be106e 844 result->message_user_context = NULL;
AzureIoTClient 88:248736be106e 845 result->method_user_context = NULL;
AzureIoTClient 88:248736be106e 846 }
AzureIoTClient 88:248736be106e 847 }
AzureIoTClient 88:248736be106e 848 }
AzureIoTClient 88:248736be106e 849 }
AzureIoTClient 88:248736be106e 850 return result;
AzureIoTClient 88:248736be106e 851 }
AzureIoTClient 88:248736be106e 852
AzureIoTClient 88:248736be106e 853 IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateFromConnectionString(const char* connectionString, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
AzureIoTClient 88:248736be106e 854 {
AzureIoTClient 88:248736be106e 855 IOTHUB_CLIENT_CORE_INSTANCE* result;
AzureIoTClient 88:248736be106e 856
AzureIoTClient 88:248736be106e 857 if (connectionString == NULL)
AzureIoTClient 88:248736be106e 858 {
AzureIoTClient 88:248736be106e 859 LogError("Input parameter is NULL: connectionString");
AzureIoTClient 88:248736be106e 860 result = NULL;
AzureIoTClient 88:248736be106e 861 }
AzureIoTClient 88:248736be106e 862 else if (protocol == NULL)
AzureIoTClient 88:248736be106e 863 {
AzureIoTClient 88:248736be106e 864 LogError("Input parameter is NULL: protocol");
AzureIoTClient 88:248736be106e 865 result = NULL;
AzureIoTClient 88:248736be106e 866 }
AzureIoTClient 88:248736be106e 867 else
AzureIoTClient 88:248736be106e 868 {
AzureIoTClient 88:248736be106e 869 result = create_iothub_instance(NULL, NULL, connectionString, protocol, NULL, NULL);
AzureIoTClient 88:248736be106e 870 }
AzureIoTClient 88:248736be106e 871 return result;
AzureIoTClient 88:248736be106e 872 }
AzureIoTClient 88:248736be106e 873
AzureIoTClient 88:248736be106e 874 IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_Create(const IOTHUB_CLIENT_CONFIG* config)
AzureIoTClient 88:248736be106e 875 {
AzureIoTClient 88:248736be106e 876 IOTHUB_CLIENT_CORE_INSTANCE* result;
AzureIoTClient 88:248736be106e 877 if (config == NULL)
AzureIoTClient 88:248736be106e 878 {
AzureIoTClient 88:248736be106e 879 LogError("Input parameter is NULL: IOTHUB_CLIENT_CONFIG");
AzureIoTClient 88:248736be106e 880 result = NULL;
AzureIoTClient 88:248736be106e 881 }
AzureIoTClient 88:248736be106e 882 else
AzureIoTClient 88:248736be106e 883 {
AzureIoTClient 88:248736be106e 884 result = create_iothub_instance(config, NULL, NULL, NULL, NULL, NULL);
AzureIoTClient 88:248736be106e 885 }
AzureIoTClient 88:248736be106e 886 return result;
AzureIoTClient 88:248736be106e 887 }
AzureIoTClient 88:248736be106e 888
AzureIoTClient 88:248736be106e 889 IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateWithTransport(TRANSPORT_HANDLE transportHandle, const IOTHUB_CLIENT_CONFIG* config)
AzureIoTClient 88:248736be106e 890 {
AzureIoTClient 88:248736be106e 891 IOTHUB_CLIENT_CORE_INSTANCE* result;
AzureIoTClient 88:248736be106e 892 /*Codes_SRS_IOTHUBCLIENT_17_013: [ IoTHubClient_CreateWithTransport shall return NULL if transportHandle is NULL. ]*/
AzureIoTClient 88:248736be106e 893 /*Codes_SRS_IOTHUBCLIENT_17_014: [ IoTHubClient_CreateWithTransport shall return NULL if config is NULL. ]*/
AzureIoTClient 88:248736be106e 894 if (transportHandle == NULL || config == NULL)
AzureIoTClient 88:248736be106e 895 {
AzureIoTClient 88:248736be106e 896 LogError("invalid parameter TRANSPORT_HANDLE transportHandle=%p, const IOTHUB_CLIENT_CONFIG* config=%p", transportHandle, config);
AzureIoTClient 88:248736be106e 897 result = NULL;
AzureIoTClient 88:248736be106e 898 }
AzureIoTClient 88:248736be106e 899 else
AzureIoTClient 88:248736be106e 900 {
AzureIoTClient 88:248736be106e 901 result = create_iothub_instance(config, transportHandle, NULL, NULL, NULL, NULL);
AzureIoTClient 88:248736be106e 902 }
AzureIoTClient 88:248736be106e 903 return result;
AzureIoTClient 88:248736be106e 904 }
AzureIoTClient 88:248736be106e 905
AzureIoTClient 88:248736be106e 906 IOTHUB_CLIENT_CORE_HANDLE IoTHubClientCore_CreateFromDeviceAuth(const char* iothub_uri, const char* device_id, IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol)
AzureIoTClient 88:248736be106e 907 {
AzureIoTClient 88:248736be106e 908 IOTHUB_CLIENT_CORE_INSTANCE* result;
AzureIoTClient 88:248736be106e 909
AzureIoTClient 88:248736be106e 910 /* Codes_SRS_IOTHUBCLIENT_12_019: [** `IoTHubClient_CreateFromDeviceAuth` shall verify the input parameters and if any of them `NULL` then return `NULL`. **] */
AzureIoTClient 88:248736be106e 911 if (iothub_uri == NULL)
AzureIoTClient 88:248736be106e 912 {
AzureIoTClient 88:248736be106e 913 LogError("Input parameter is NULL: iothub_uri");
AzureIoTClient 88:248736be106e 914 result = NULL;
AzureIoTClient 88:248736be106e 915 }
AzureIoTClient 88:248736be106e 916 else if (device_id == NULL)
AzureIoTClient 88:248736be106e 917 {
AzureIoTClient 88:248736be106e 918 LogError("Input parameter is NULL: device_id");
AzureIoTClient 88:248736be106e 919 result = NULL;
AzureIoTClient 88:248736be106e 920 }
AzureIoTClient 88:248736be106e 921 else if (protocol == NULL)
AzureIoTClient 88:248736be106e 922 {
AzureIoTClient 88:248736be106e 923 LogError("Input parameter is NULL: protocol");
AzureIoTClient 88:248736be106e 924 result = NULL;
AzureIoTClient 88:248736be106e 925 }
AzureIoTClient 88:248736be106e 926 else
AzureIoTClient 88:248736be106e 927 {
AzureIoTClient 88:248736be106e 928 /* Codes_SRS_IOTHUBCLIENT_12_020: [** `IoTHubClient_CreateFromDeviceAuth` shall allocate a new `IoTHubClient` instance. **] */
AzureIoTClient 88:248736be106e 929 /* Codes_SRS_IOTHUBCLIENT_12_021: [** If allocating memory for the new `IoTHubClient` instance fails, then `IoTHubClient_CreateFromDeviceAuth` shall return `NULL`. **] */
AzureIoTClient 88:248736be106e 930 /* Codes_SRS_IOTHUBCLIENT_12_022: [** `IoTHubClient_CreateFromDeviceAuth` shall create a lock object to be used later for serializing IoTHubClient calls. **] */
AzureIoTClient 88:248736be106e 931 /* Codes_SRS_IOTHUBCLIENT_12_023: [** If creating the lock fails, then IoTHubClient_CreateFromDeviceAuth shall return NULL. **] */
AzureIoTClient 88:248736be106e 932 /* Codes_SRS_IOTHUBCLIENT_12_024: [** If IoTHubClient_CreateFromDeviceAuth fails, all resources allocated by it shall be freed. **] */
AzureIoTClient 88:248736be106e 933 /* Codes_SRS_IOTHUBCLIENT_12_025: [** `IoTHubClient_CreateFromDeviceAuth` shall instantiate a new `IoTHubClientCore_LL` instance by calling `IoTHubClientCore_LL_CreateFromDeviceAuth` and passing iothub_uri, device_id and protocol argument. **] */
AzureIoTClient 88:248736be106e 934 result = create_iothub_instance(NULL, NULL, NULL, protocol, iothub_uri, device_id);
AzureIoTClient 88:248736be106e 935 }
AzureIoTClient 88:248736be106e 936 return result;
AzureIoTClient 88:248736be106e 937 }
AzureIoTClient 88:248736be106e 938
AzureIoTClient 88:248736be106e 939 /* Codes_SRS_IOTHUBCLIENT_01_005: [IoTHubClient_Destroy shall free all resources associated with the iotHubClientHandle instance.] */
AzureIoTClient 88:248736be106e 940 void IoTHubClientCore_Destroy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle)
AzureIoTClient 88:248736be106e 941 {
AzureIoTClient 88:248736be106e 942 /* Codes_SRS_IOTHUBCLIENT_01_008: [IoTHubClient_Destroy shall do nothing if parameter iotHubClientHandle is NULL.] */
AzureIoTClient 88:248736be106e 943 if (iotHubClientHandle != NULL)
AzureIoTClient 88:248736be106e 944 {
AzureIoTClient 88:248736be106e 945 bool joinClientThread;
AzureIoTClient 88:248736be106e 946 bool joinTransportThread;
AzureIoTClient 88:248736be106e 947 size_t vector_size;
AzureIoTClient 88:248736be106e 948
AzureIoTClient 88:248736be106e 949 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 950
AzureIoTClient 88:248736be106e 951 if (iotHubClientInstance->TransportHandle != NULL)
AzureIoTClient 88:248736be106e 952 {
AzureIoTClient 88:248736be106e 953 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 88:248736be106e 954 joinTransportThread = IoTHubTransport_SignalEndWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
AzureIoTClient 88:248736be106e 955 }
AzureIoTClient 88:248736be106e 956 else
AzureIoTClient 88:248736be106e 957 {
AzureIoTClient 88:248736be106e 958 joinTransportThread = false;
AzureIoTClient 88:248736be106e 959 }
AzureIoTClient 88:248736be106e 960
AzureIoTClient 88:248736be106e 961 /*Codes_SRS_IOTHUBCLIENT_02_043: [ IoTHubClient_Destroy shall lock the serializing lock and signal the worker thread (if any) to end ]*/
AzureIoTClient 88:248736be106e 962 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 963 {
AzureIoTClient 88:248736be106e 964 LogError("unable to Lock - - will still proceed to try to end the thread without locking");
AzureIoTClient 88:248736be106e 965 }
AzureIoTClient 88:248736be106e 966
AzureIoTClient 88:248736be106e 967 if (iotHubClientInstance->ThreadHandle != NULL)
AzureIoTClient 88:248736be106e 968 {
AzureIoTClient 88:248736be106e 969 iotHubClientInstance->StopThread = 1;
AzureIoTClient 88:248736be106e 970 joinClientThread = true;
AzureIoTClient 88:248736be106e 971 }
AzureIoTClient 88:248736be106e 972 else
AzureIoTClient 88:248736be106e 973 {
AzureIoTClient 88:248736be106e 974 joinClientThread = false;
AzureIoTClient 88:248736be106e 975 }
AzureIoTClient 88:248736be106e 976
AzureIoTClient 88:248736be106e 977 /*Codes_SRS_IOTHUBCLIENT_02_045: [ IoTHubClient_Destroy shall unlock the serializing lock. ]*/
AzureIoTClient 88:248736be106e 978 if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 979 {
AzureIoTClient 88:248736be106e 980 LogError("unable to Unlock");
AzureIoTClient 88:248736be106e 981 }
AzureIoTClient 88:248736be106e 982
AzureIoTClient 88:248736be106e 983 if (joinClientThread == true)
AzureIoTClient 88:248736be106e 984 {
AzureIoTClient 88:248736be106e 985 int res;
AzureIoTClient 88:248736be106e 986 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 88:248736be106e 987 if (ThreadAPI_Join(iotHubClientInstance->ThreadHandle, &res) != THREADAPI_OK)
AzureIoTClient 88:248736be106e 988 {
AzureIoTClient 88:248736be106e 989 LogError("ThreadAPI_Join failed");
AzureIoTClient 88:248736be106e 990 }
AzureIoTClient 88:248736be106e 991 }
AzureIoTClient 88:248736be106e 992
AzureIoTClient 88:248736be106e 993 if (joinTransportThread == true)
AzureIoTClient 88:248736be106e 994 {
AzureIoTClient 88:248736be106e 995 /*Codes_SRS_IOTHUBCLIENT_01_007: [ The thread created as part of executing IoTHubClient_SendEventAsync or IoTHubClient_SetNotificationMessageCallback shall be joined. ]*/
AzureIoTClient 88:248736be106e 996 IoTHubTransport_JoinWorkerThread(iotHubClientInstance->TransportHandle, iotHubClientHandle);
AzureIoTClient 88:248736be106e 997 }
AzureIoTClient 88:248736be106e 998
AzureIoTClient 88:248736be106e 999 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1000 {
AzureIoTClient 88:248736be106e 1001 LogError("unable to Lock - - will still proceed to try to end the thread without locking");
AzureIoTClient 88:248736be106e 1002 }
AzureIoTClient 88:248736be106e 1003
AzureIoTClient 88:248736be106e 1004 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 1005 /*Codes_SRS_IOTHUBCLIENT_02_069: [ IoTHubClient_Destroy shall free all data created by IoTHubClient_UploadToBlobAsync ]*/
AzureIoTClient 88:248736be106e 1006 /*wait for all uploading threads to finish*/
AzureIoTClient 88:248736be106e 1007 while (singlylinkedlist_get_head_item(iotHubClientInstance->savedDataToBeCleaned) != NULL)
AzureIoTClient 88:248736be106e 1008 {
AzureIoTClient 88:248736be106e 1009 garbageCollectorImpl(iotHubClientInstance);
AzureIoTClient 88:248736be106e 1010 }
AzureIoTClient 88:248736be106e 1011
AzureIoTClient 88:248736be106e 1012 if (iotHubClientInstance->savedDataToBeCleaned != NULL)
AzureIoTClient 88:248736be106e 1013 {
AzureIoTClient 88:248736be106e 1014 singlylinkedlist_destroy(iotHubClientInstance->savedDataToBeCleaned);
AzureIoTClient 88:248736be106e 1015 }
AzureIoTClient 88:248736be106e 1016 #endif
AzureIoTClient 88:248736be106e 1017
AzureIoTClient 88:248736be106e 1018 /* Codes_SRS_IOTHUBCLIENT_01_006: [That includes destroying the IoTHubClientCore_LL instance by calling IoTHubClientCore_LL_Destroy.] */
AzureIoTClient 88:248736be106e 1019 IoTHubClientCore_LL_Destroy(iotHubClientInstance->IoTHubClientLLHandle);
AzureIoTClient 88:248736be106e 1020
AzureIoTClient 88:248736be106e 1021 if (Unlock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1022 {
AzureIoTClient 88:248736be106e 1023 LogError("unable to Unlock");
AzureIoTClient 88:248736be106e 1024 }
AzureIoTClient 88:248736be106e 1025
AzureIoTClient 88:248736be106e 1026
AzureIoTClient 88:248736be106e 1027 vector_size = VECTOR_size(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 88:248736be106e 1028 size_t index = 0;
AzureIoTClient 88:248736be106e 1029 for (index = 0; index < vector_size; index++)
AzureIoTClient 88:248736be106e 1030 {
AzureIoTClient 88:248736be106e 1031 USER_CALLBACK_INFO* queue_cb_info = (USER_CALLBACK_INFO*)VECTOR_element(iotHubClientInstance->saved_user_callback_list, index);
AzureIoTClient 88:248736be106e 1032 if (queue_cb_info != NULL)
AzureIoTClient 88:248736be106e 1033 {
AzureIoTClient 88:248736be106e 1034 if ((queue_cb_info->type == CALLBACK_TYPE_DEVICE_METHOD) || (queue_cb_info->type == CALLBACK_TYPE_INBOUD_DEVICE_METHOD))
AzureIoTClient 88:248736be106e 1035 {
AzureIoTClient 88:248736be106e 1036 STRING_delete(queue_cb_info->iothub_callback.method_cb_info.method_name);
AzureIoTClient 88:248736be106e 1037 BUFFER_delete(queue_cb_info->iothub_callback.method_cb_info.payload);
AzureIoTClient 88:248736be106e 1038 }
AzureIoTClient 88:248736be106e 1039 else if (queue_cb_info->type == CALLBACK_TYPE_DEVICE_TWIN)
AzureIoTClient 88:248736be106e 1040 {
AzureIoTClient 88:248736be106e 1041 if (queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad != NULL)
AzureIoTClient 88:248736be106e 1042 {
AzureIoTClient 88:248736be106e 1043 free(queue_cb_info->iothub_callback.dev_twin_cb_info.payLoad);
AzureIoTClient 88:248736be106e 1044 }
AzureIoTClient 88:248736be106e 1045 }
AzureIoTClient 88:248736be106e 1046 else if (queue_cb_info->type == CALLBACK_TYPE_EVENT_CONFIRM)
AzureIoTClient 88:248736be106e 1047 {
AzureIoTClient 88:248736be106e 1048 if (iotHubClientInstance->event_confirm_callback)
AzureIoTClient 88:248736be106e 1049 {
AzureIoTClient 88:248736be106e 1050 iotHubClientInstance->event_confirm_callback(queue_cb_info->iothub_callback.event_confirm_cb_info.confirm_result, queue_cb_info->userContextCallback);
AzureIoTClient 88:248736be106e 1051 }
AzureIoTClient 88:248736be106e 1052 }
AzureIoTClient 88:248736be106e 1053 }
AzureIoTClient 88:248736be106e 1054 }
AzureIoTClient 88:248736be106e 1055 VECTOR_destroy(iotHubClientInstance->saved_user_callback_list);
AzureIoTClient 88:248736be106e 1056
AzureIoTClient 88:248736be106e 1057 if (iotHubClientInstance->TransportHandle == NULL)
AzureIoTClient 88:248736be106e 1058 {
AzureIoTClient 88:248736be106e 1059 /* Codes_SRS_IOTHUBCLIENT_01_032: [If the lock was allocated in IoTHubClient_Create, it shall be also freed..] */
AzureIoTClient 88:248736be106e 1060 Lock_Deinit(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1061 }
AzureIoTClient 88:248736be106e 1062 if (iotHubClientInstance->devicetwin_user_context != NULL)
AzureIoTClient 88:248736be106e 1063 {
AzureIoTClient 88:248736be106e 1064 free(iotHubClientInstance->devicetwin_user_context);
AzureIoTClient 88:248736be106e 1065 }
AzureIoTClient 88:248736be106e 1066 if (iotHubClientInstance->connection_status_user_context != NULL)
AzureIoTClient 88:248736be106e 1067 {
AzureIoTClient 88:248736be106e 1068 free(iotHubClientInstance->connection_status_user_context);
AzureIoTClient 88:248736be106e 1069 }
AzureIoTClient 88:248736be106e 1070 if (iotHubClientInstance->message_user_context != NULL)
AzureIoTClient 88:248736be106e 1071 {
AzureIoTClient 88:248736be106e 1072 free(iotHubClientInstance->message_user_context);
AzureIoTClient 88:248736be106e 1073 }
AzureIoTClient 88:248736be106e 1074 if (iotHubClientInstance->method_user_context != NULL)
AzureIoTClient 88:248736be106e 1075 {
AzureIoTClient 88:248736be106e 1076 free(iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1077 }
AzureIoTClient 88:248736be106e 1078 free(iotHubClientInstance);
AzureIoTClient 88:248736be106e 1079 }
AzureIoTClient 88:248736be106e 1080 }
AzureIoTClient 88:248736be106e 1081
AzureIoTClient 88:248736be106e 1082 IOTHUB_CLIENT_RESULT IoTHubClientCore_SendEventAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_MESSAGE_HANDLE eventMessageHandle, IOTHUB_CLIENT_EVENT_CONFIRMATION_CALLBACK eventConfirmationCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1083 {
AzureIoTClient 88:248736be106e 1084 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1085
AzureIoTClient 88:248736be106e 1086 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1087 {
AzureIoTClient 88:248736be106e 1088 /* Codes_SRS_IOTHUBCLIENT_01_011: [If iotHubClientHandle is NULL, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 88:248736be106e 1089 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1090 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1091 }
AzureIoTClient 88:248736be106e 1092 else
AzureIoTClient 88:248736be106e 1093 {
AzureIoTClient 88:248736be106e 1094 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1095
AzureIoTClient 88:248736be106e 1096 /* Codes_SRS_IOTHUBCLIENT_01_009: [IoTHubClient_SendEventAsync shall start the worker thread if it was not previously started.] */
AzureIoTClient 88:248736be106e 1097 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1098 {
AzureIoTClient 88:248736be106e 1099 /* Codes_SRS_IOTHUBCLIENT_01_010: [If starting the thread fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1100 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1101 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1102 }
AzureIoTClient 88:248736be106e 1103 else
AzureIoTClient 88:248736be106e 1104 {
AzureIoTClient 88:248736be106e 1105 /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1106 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1107 {
AzureIoTClient 88:248736be106e 1108 /* Codes_SRS_IOTHUBCLIENT_01_026: [If acquiring the lock fails, IoTHubClient_SendEventAsync shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1109 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1110 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1111 }
AzureIoTClient 88:248736be106e 1112 else
AzureIoTClient 88:248736be106e 1113 {
AzureIoTClient 88:248736be106e 1114 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1115 {
AzureIoTClient 88:248736be106e 1116 iotHubClientInstance->event_confirm_callback = eventConfirmationCallback;
AzureIoTClient 88:248736be106e 1117 }
AzureIoTClient 88:248736be106e 1118
AzureIoTClient 88:248736be106e 1119 if (iotHubClientInstance->created_with_transport_handle != 0 || eventConfirmationCallback == NULL)
AzureIoTClient 88:248736be106e 1120 {
AzureIoTClient 88:248736be106e 1121 result = IoTHubClientCore_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, eventConfirmationCallback, userContextCallback);
AzureIoTClient 88:248736be106e 1122 }
AzureIoTClient 88:248736be106e 1123 else
AzureIoTClient 88:248736be106e 1124 {
AzureIoTClient 88:248736be106e 1125 /* Codes_SRS_IOTHUBCLIENT_07_001: [ IoTHubClient_SendEventAsync shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SendEventAsync function as a user context. ] */
AzureIoTClient 88:248736be106e 1126 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1127 if (queue_context == NULL)
AzureIoTClient 88:248736be106e 1128 {
AzureIoTClient 88:248736be106e 1129 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1130 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1131 }
AzureIoTClient 88:248736be106e 1132 else
AzureIoTClient 88:248736be106e 1133 {
AzureIoTClient 88:248736be106e 1134 queue_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 88:248736be106e 1135 queue_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1136 /* Codes_SRS_IOTHUBCLIENT_01_012: [IoTHubClient_SendEventAsync shall call IoTHubClientCore_LL_SendEventAsync, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameters eventMessageHandle, eventConfirmationCallback and userContextCallback.] */
AzureIoTClient 88:248736be106e 1137 /* Codes_SRS_IOTHUBCLIENT_01_013: [When IoTHubClientCore_LL_SendEventAsync is called, IoTHubClient_SendEventAsync shall return the result of IoTHubClientCore_LL_SendEventAsync.] */
AzureIoTClient 88:248736be106e 1138 result = IoTHubClientCore_LL_SendEventAsync(iotHubClientInstance->IoTHubClientLLHandle, eventMessageHandle, iothub_ll_event_confirm_callback, queue_context);
AzureIoTClient 88:248736be106e 1139 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1140 {
AzureIoTClient 88:248736be106e 1141 LogError("IoTHubClientCore_LL_SendEventAsync failed");
AzureIoTClient 88:248736be106e 1142 free(queue_context);
AzureIoTClient 88:248736be106e 1143 }
AzureIoTClient 88:248736be106e 1144 }
AzureIoTClient 88:248736be106e 1145 }
AzureIoTClient 88:248736be106e 1146
AzureIoTClient 88:248736be106e 1147 /* Codes_SRS_IOTHUBCLIENT_01_025: [IoTHubClient_SendEventAsync shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1148 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1149 }
AzureIoTClient 88:248736be106e 1150 }
AzureIoTClient 88:248736be106e 1151 }
AzureIoTClient 88:248736be106e 1152
AzureIoTClient 88:248736be106e 1153 return result;
AzureIoTClient 88:248736be106e 1154 }
AzureIoTClient 88:248736be106e 1155
AzureIoTClient 88:248736be106e 1156 IOTHUB_CLIENT_RESULT IoTHubClientCore_GetSendStatus(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_STATUS *iotHubClientStatus)
AzureIoTClient 88:248736be106e 1157 {
AzureIoTClient 88:248736be106e 1158 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1159
AzureIoTClient 88:248736be106e 1160 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1161 {
AzureIoTClient 88:248736be106e 1162 /* Codes_SRS_IOTHUBCLIENT_01_023: [If iotHubClientHandle is NULL, IoTHubClient_ GetSendStatus shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 88:248736be106e 1163 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1164 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1165 }
AzureIoTClient 88:248736be106e 1166 else
AzureIoTClient 88:248736be106e 1167 {
AzureIoTClient 88:248736be106e 1168 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1169
AzureIoTClient 88:248736be106e 1170 /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1171 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1172 {
AzureIoTClient 88:248736be106e 1173 /* Codes_SRS_IOTHUBCLIENT_01_034: [If acquiring the lock fails, IoTHubClient_GetSendStatus shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1174 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1175 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1176 }
AzureIoTClient 88:248736be106e 1177 else
AzureIoTClient 88:248736be106e 1178 {
AzureIoTClient 88:248736be106e 1179 /* Codes_SRS_IOTHUBCLIENT_01_022: [IoTHubClient_GetSendStatus shall call IoTHubClientCore_LL_GetSendStatus, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameter iotHubClientStatus.] */
AzureIoTClient 88:248736be106e 1180 /* Codes_SRS_IOTHUBCLIENT_01_024: [Otherwise, IoTHubClient_GetSendStatus shall return the result of IoTHubClientCore_LL_GetSendStatus.] */
AzureIoTClient 88:248736be106e 1181 result = IoTHubClientCore_LL_GetSendStatus(iotHubClientInstance->IoTHubClientLLHandle, iotHubClientStatus);
AzureIoTClient 88:248736be106e 1182
AzureIoTClient 88:248736be106e 1183 /* Codes_SRS_IOTHUBCLIENT_01_033: [IoTHubClient_GetSendStatus shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1184 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1185 }
AzureIoTClient 88:248736be106e 1186 }
AzureIoTClient 88:248736be106e 1187
AzureIoTClient 88:248736be106e 1188 return result;
AzureIoTClient 88:248736be106e 1189 }
AzureIoTClient 88:248736be106e 1190
AzureIoTClient 88:248736be106e 1191 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetMessageCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_MESSAGE_CALLBACK_ASYNC messageCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1192 {
AzureIoTClient 88:248736be106e 1193 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1194
AzureIoTClient 88:248736be106e 1195 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1196 {
AzureIoTClient 88:248736be106e 1197 /* Codes_SRS_IOTHUBCLIENT_01_016: [If iotHubClientHandle is NULL, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 88:248736be106e 1198 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1199 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1200 }
AzureIoTClient 88:248736be106e 1201 else
AzureIoTClient 88:248736be106e 1202 {
AzureIoTClient 88:248736be106e 1203 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1204
AzureIoTClient 88:248736be106e 1205 /* Codes_SRS_IOTHUBCLIENT_01_014: [IoTHubClient_SetMessageCallback shall start the worker thread if it was not previously started.] */
AzureIoTClient 88:248736be106e 1206 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1207 {
AzureIoTClient 88:248736be106e 1208 /* Codes_SRS_IOTHUBCLIENT_01_015: [If starting the thread fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1209 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1210 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1211 }
AzureIoTClient 88:248736be106e 1212 else
AzureIoTClient 88:248736be106e 1213 {
AzureIoTClient 88:248736be106e 1214 /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1215 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1216 {
AzureIoTClient 88:248736be106e 1217 /* Codes_SRS_IOTHUBCLIENT_01_028: [If acquiring the lock fails, IoTHubClient_SetMessageCallback shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1218 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1219 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1220 }
AzureIoTClient 88:248736be106e 1221 else
AzureIoTClient 88:248736be106e 1222 {
AzureIoTClient 88:248736be106e 1223 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1224 {
AzureIoTClient 88:248736be106e 1225 iotHubClientInstance->message_callback = messageCallback;
AzureIoTClient 88:248736be106e 1226 }
AzureIoTClient 88:248736be106e 1227 if (iotHubClientInstance->message_user_context != NULL)
AzureIoTClient 88:248736be106e 1228 {
AzureIoTClient 88:248736be106e 1229 free(iotHubClientInstance->message_user_context);
AzureIoTClient 88:248736be106e 1230 iotHubClientInstance->message_user_context = NULL;
AzureIoTClient 88:248736be106e 1231 }
AzureIoTClient 88:248736be106e 1232 if (messageCallback == NULL)
AzureIoTClient 88:248736be106e 1233 {
AzureIoTClient 88:248736be106e 1234 result = IoTHubClientCore_LL_SetMessageCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, iotHubClientInstance->message_user_context);
AzureIoTClient 88:248736be106e 1235 }
AzureIoTClient 88:248736be106e 1236 else if (iotHubClientInstance->created_with_transport_handle != 0)
AzureIoTClient 88:248736be106e 1237 {
AzureIoTClient 88:248736be106e 1238 result = IoTHubClientCore_LL_SetMessageCallback(iotHubClientInstance->IoTHubClientLLHandle, messageCallback, userContextCallback);
AzureIoTClient 88:248736be106e 1239 }
AzureIoTClient 88:248736be106e 1240 else
AzureIoTClient 88:248736be106e 1241 {
AzureIoTClient 88:248736be106e 1242 iotHubClientInstance->message_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1243 if (iotHubClientInstance->message_user_context == NULL)
AzureIoTClient 88:248736be106e 1244 {
AzureIoTClient 88:248736be106e 1245 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1246 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1247 }
AzureIoTClient 88:248736be106e 1248 else
AzureIoTClient 88:248736be106e 1249 {
AzureIoTClient 88:248736be106e 1250 iotHubClientInstance->message_user_context->iotHubClientHandle = iotHubClientHandle;
AzureIoTClient 88:248736be106e 1251 iotHubClientInstance->message_user_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1252
AzureIoTClient 88:248736be106e 1253 /* Codes_SRS_IOTHUBCLIENT_01_017: [IoTHubClient_SetMessageCallback shall call IoTHubClientCore_LL_SetMessageCallback_Ex, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the local iothub_ll_message_callback wrapper of messageCallback and userContextCallback.] */
AzureIoTClient 88:248736be106e 1254 /* Codes_SRS_IOTHUBCLIENT_01_018: [When IoTHubClientCore_LL_SetMessageCallback_Ex is called, IoTHubClient_SetMessageCallback shall return the result of IoTHubClientCore_LL_SetMessageCallback_Ex.] */
AzureIoTClient 88:248736be106e 1255 result = IoTHubClientCore_LL_SetMessageCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_message_callback, iotHubClientInstance->message_user_context);
AzureIoTClient 88:248736be106e 1256 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1257 {
AzureIoTClient 88:248736be106e 1258 LogError("IoTHubClientCore_LL_SetMessageCallback failed");
AzureIoTClient 88:248736be106e 1259 free(iotHubClientInstance->message_user_context);
AzureIoTClient 88:248736be106e 1260 iotHubClientInstance->message_user_context = NULL;
AzureIoTClient 88:248736be106e 1261 }
AzureIoTClient 88:248736be106e 1262 }
AzureIoTClient 88:248736be106e 1263 }
AzureIoTClient 88:248736be106e 1264
AzureIoTClient 88:248736be106e 1265 /* Codes_SRS_IOTHUBCLIENT_01_027: [IoTHubClient_SetMessageCallback shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1266 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1267 }
AzureIoTClient 88:248736be106e 1268 }
AzureIoTClient 88:248736be106e 1269 }
AzureIoTClient 88:248736be106e 1270
AzureIoTClient 88:248736be106e 1271 return result;
AzureIoTClient 88:248736be106e 1272 }
AzureIoTClient 88:248736be106e 1273
AzureIoTClient 88:248736be106e 1274 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetConnectionStatusCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_CONNECTION_STATUS_CALLBACK connectionStatusCallback, void * userContextCallback)
AzureIoTClient 88:248736be106e 1275 {
AzureIoTClient 88:248736be106e 1276 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1277
AzureIoTClient 88:248736be106e 1278 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1279 {
AzureIoTClient 88:248736be106e 1280 /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
AzureIoTClient 88:248736be106e 1281 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1282 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1283 }
AzureIoTClient 88:248736be106e 1284 else
AzureIoTClient 88:248736be106e 1285 {
AzureIoTClient 88:248736be106e 1286 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1287
AzureIoTClient 88:248736be106e 1288 /* Codes_SRS_IOTHUBCLIENT_25_081: [ `IoTHubClient_SetConnectionStatusCallback` shall start the worker thread if it was not previously started. ]*/
AzureIoTClient 88:248736be106e 1289 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1290 {
AzureIoTClient 88:248736be106e 1291 /* Codes_SRS_IOTHUBCLIENT_25_083: [ If starting the thread fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1292 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1293 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1294 }
AzureIoTClient 88:248736be106e 1295 else
AzureIoTClient 88:248736be106e 1296 {
AzureIoTClient 88:248736be106e 1297 /* Codes_SRS_IOTHUBCLIENT_25_087: [ `IoTHubClient_SetConnectionStatusCallback` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ] */
AzureIoTClient 88:248736be106e 1298 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1299 {
AzureIoTClient 88:248736be106e 1300 /* Codes_SRS_IOTHUBCLIENT_25_088: [ If acquiring the lock fails, `IoTHubClient_SetConnectionStatusCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1301 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1302 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1303 }
AzureIoTClient 88:248736be106e 1304 else
AzureIoTClient 88:248736be106e 1305 {
AzureIoTClient 88:248736be106e 1306 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1307 {
AzureIoTClient 88:248736be106e 1308 iotHubClientInstance->connection_status_callback = connectionStatusCallback;
AzureIoTClient 88:248736be106e 1309 }
AzureIoTClient 88:248736be106e 1310
AzureIoTClient 88:248736be106e 1311 if (iotHubClientInstance->created_with_transport_handle != 0 || connectionStatusCallback == NULL)
AzureIoTClient 88:248736be106e 1312 {
AzureIoTClient 88:248736be106e 1313 /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClientCore_LL_SetConnectionStatusCallback`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
AzureIoTClient 88:248736be106e 1314 result = IoTHubClientCore_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, connectionStatusCallback, userContextCallback);
AzureIoTClient 88:248736be106e 1315 }
AzureIoTClient 88:248736be106e 1316 else
AzureIoTClient 88:248736be106e 1317 {
AzureIoTClient 88:248736be106e 1318 if (iotHubClientInstance->connection_status_user_context != NULL)
AzureIoTClient 88:248736be106e 1319 {
AzureIoTClient 88:248736be106e 1320 free(iotHubClientInstance->connection_status_user_context);
AzureIoTClient 88:248736be106e 1321 }
AzureIoTClient 88:248736be106e 1322 iotHubClientInstance->connection_status_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1323 if (iotHubClientInstance->connection_status_user_context == NULL)
AzureIoTClient 88:248736be106e 1324 {
AzureIoTClient 88:248736be106e 1325 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1326 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1327 }
AzureIoTClient 88:248736be106e 1328 else
AzureIoTClient 88:248736be106e 1329 {
AzureIoTClient 88:248736be106e 1330 iotHubClientInstance->connection_status_user_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 88:248736be106e 1331 iotHubClientInstance->connection_status_user_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1332
AzureIoTClient 88:248736be106e 1333 /* Codes_SRS_IOTHUBCLIENT_25_085: [ `IoTHubClient_SetConnectionStatusCallback` shall call `IoTHubClientCore_LL_SetConnectionStatusCallback`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`. ]*/
AzureIoTClient 88:248736be106e 1334 result = IoTHubClientCore_LL_SetConnectionStatusCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_connection_status_callback, iotHubClientInstance->connection_status_user_context);
AzureIoTClient 88:248736be106e 1335 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1336 {
AzureIoTClient 88:248736be106e 1337 LogError("IoTHubClientCore_LL_SetConnectionStatusCallback failed");
AzureIoTClient 88:248736be106e 1338 free(iotHubClientInstance->connection_status_user_context);
AzureIoTClient 88:248736be106e 1339 iotHubClientInstance->connection_status_user_context = NULL;
AzureIoTClient 88:248736be106e 1340 }
AzureIoTClient 88:248736be106e 1341 }
AzureIoTClient 88:248736be106e 1342 }
AzureIoTClient 88:248736be106e 1343 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1344 }
AzureIoTClient 88:248736be106e 1345 }
AzureIoTClient 88:248736be106e 1346 }
AzureIoTClient 88:248736be106e 1347 return result;
AzureIoTClient 88:248736be106e 1348 }
AzureIoTClient 88:248736be106e 1349
AzureIoTClient 88:248736be106e 1350 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetRetryPolicy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY retryPolicy, size_t retryTimeoutLimitInSeconds)
AzureIoTClient 88:248736be106e 1351 {
AzureIoTClient 88:248736be106e 1352 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1353
AzureIoTClient 88:248736be106e 1354 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1355 {
AzureIoTClient 88:248736be106e 1356 /* Codes_SRS_IOTHUBCLIENT_25_076: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ] */
AzureIoTClient 88:248736be106e 1357 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1358 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1359 }
AzureIoTClient 88:248736be106e 1360 else
AzureIoTClient 88:248736be106e 1361 {
AzureIoTClient 88:248736be106e 1362 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1363
AzureIoTClient 88:248736be106e 1364 /* Codes_SRS_IOTHUBCLIENT_25_073: [ `IoTHubClient_SetRetryPolicy` shall start the worker thread if it was not previously started. ] */
AzureIoTClient 88:248736be106e 1365 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1366 {
AzureIoTClient 88:248736be106e 1367 /* Codes_SRS_IOTHUBCLIENT_25_075: [ If starting the thread fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1368 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1369 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1370 }
AzureIoTClient 88:248736be106e 1371 else
AzureIoTClient 88:248736be106e 1372 {
AzureIoTClient 88:248736be106e 1373 /* Codes_SRS_IOTHUBCLIENT_25_079: [ `IoTHubClient_SetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`.] */
AzureIoTClient 88:248736be106e 1374 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1375 {
AzureIoTClient 88:248736be106e 1376 /* Codes_SRS_IOTHUBCLIENT_25_080: [ If acquiring the lock fails, `IoTHubClient_SetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1377 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1378 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1379 }
AzureIoTClient 88:248736be106e 1380 else
AzureIoTClient 88:248736be106e 1381 {
AzureIoTClient 88:248736be106e 1382 /* Codes_SRS_IOTHUBCLIENT_25_077: [ `IoTHubClient_SetRetryPolicy` shall call `IoTHubClientCore_LL_SetRetryPolicy`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `retryPolicy` and `retryTimeoutLimitinSeconds`.]*/
AzureIoTClient 88:248736be106e 1383 result = IoTHubClientCore_LL_SetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
AzureIoTClient 88:248736be106e 1384 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1385 }
AzureIoTClient 88:248736be106e 1386
AzureIoTClient 88:248736be106e 1387 }
AzureIoTClient 88:248736be106e 1388 }
AzureIoTClient 88:248736be106e 1389
AzureIoTClient 88:248736be106e 1390 return result;
AzureIoTClient 88:248736be106e 1391 }
AzureIoTClient 88:248736be106e 1392
AzureIoTClient 88:248736be106e 1393 IOTHUB_CLIENT_RESULT IoTHubClientCore_GetRetryPolicy(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_RETRY_POLICY* retryPolicy, size_t* retryTimeoutLimitInSeconds)
AzureIoTClient 88:248736be106e 1394 {
AzureIoTClient 88:248736be106e 1395 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1396
AzureIoTClient 88:248736be106e 1397 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1398 {
AzureIoTClient 88:248736be106e 1399 /* Codes_SRS_IOTHUBCLIENT_25_092: [ If `iotHubClientHandle` is `NULL`, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 88:248736be106e 1400 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1401 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1402 }
AzureIoTClient 88:248736be106e 1403 else
AzureIoTClient 88:248736be106e 1404 {
AzureIoTClient 88:248736be106e 1405 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1406
AzureIoTClient 88:248736be106e 1407 /* Codes_SRS_IOTHUBCLIENT_25_089: [ `IoTHubClient_GetRetryPolicy` shall start the worker thread if it was not previously started.]*/
AzureIoTClient 88:248736be106e 1408 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1409 {
AzureIoTClient 88:248736be106e 1410 /* Codes_SRS_IOTHUBCLIENT_25_091: [ If starting the thread fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`.]*/
AzureIoTClient 88:248736be106e 1411 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1412 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1413 }
AzureIoTClient 88:248736be106e 1414 else
AzureIoTClient 88:248736be106e 1415 {
AzureIoTClient 88:248736be106e 1416 /* Codes_SRS_IOTHUBCLIENT_25_095: [ `IoTHubClient_GetRetryPolicy` shall be made thread-safe by using the lock created in `IoTHubClient_Create`. ]*/
AzureIoTClient 88:248736be106e 1417 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1418 {
AzureIoTClient 88:248736be106e 1419 /* Codes_SRS_IOTHUBCLIENT_25_096: [ If acquiring the lock fails, `IoTHubClient_GetRetryPolicy` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1420 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1421 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1422 }
AzureIoTClient 88:248736be106e 1423 else
AzureIoTClient 88:248736be106e 1424 {
AzureIoTClient 88:248736be106e 1425 /* Codes_SRS_IOTHUBCLIENT_25_093: [ `IoTHubClient_GetRetryPolicy` shall call `IoTHubClientCore_LL_GetRetryPolicy`, while passing the `IoTHubClientCore_LL` handle created by `IoTHubClient_Create` and the parameters `connectionStatusCallback` and `userContextCallback`.]*/
AzureIoTClient 88:248736be106e 1426 result = IoTHubClientCore_LL_GetRetryPolicy(iotHubClientInstance->IoTHubClientLLHandle, retryPolicy, retryTimeoutLimitInSeconds);
AzureIoTClient 88:248736be106e 1427 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1428 }
AzureIoTClient 88:248736be106e 1429 }
AzureIoTClient 88:248736be106e 1430 }
AzureIoTClient 88:248736be106e 1431
AzureIoTClient 88:248736be106e 1432 return result;
AzureIoTClient 88:248736be106e 1433 }
AzureIoTClient 88:248736be106e 1434
AzureIoTClient 88:248736be106e 1435 IOTHUB_CLIENT_RESULT IoTHubClientCore_GetLastMessageReceiveTime(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, time_t* lastMessageReceiveTime)
AzureIoTClient 88:248736be106e 1436 {
AzureIoTClient 88:248736be106e 1437 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1438
AzureIoTClient 88:248736be106e 1439 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1440 {
AzureIoTClient 88:248736be106e 1441 /* Codes_SRS_IOTHUBCLIENT_01_020: [If iotHubClientHandle is NULL, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 88:248736be106e 1442 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1443 LogError("NULL iothubClientHandle");
AzureIoTClient 88:248736be106e 1444 }
AzureIoTClient 88:248736be106e 1445 else
AzureIoTClient 88:248736be106e 1446 {
AzureIoTClient 88:248736be106e 1447 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1448
AzureIoTClient 88:248736be106e 1449 /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1450 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1451 {
AzureIoTClient 88:248736be106e 1452 /* Codes_SRS_IOTHUBCLIENT_01_036: [If acquiring the lock fails, IoTHubClient_GetLastMessageReceiveTime shall return IOTHUB_CLIENT_ERROR.] */
AzureIoTClient 88:248736be106e 1453 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1454 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1455 }
AzureIoTClient 88:248736be106e 1456 else
AzureIoTClient 88:248736be106e 1457 {
AzureIoTClient 88:248736be106e 1458 /* Codes_SRS_IOTHUBCLIENT_01_019: [IoTHubClient_GetLastMessageReceiveTime shall call IoTHubClientCore_LL_GetLastMessageReceiveTime, while passing the IoTHubClientCore_LL handle created by IoTHubClient_Create and the parameter lastMessageReceiveTime.] */
AzureIoTClient 88:248736be106e 1459 /* Codes_SRS_IOTHUBCLIENT_01_021: [Otherwise, IoTHubClient_GetLastMessageReceiveTime shall return the result of IoTHubClientCore_LL_GetLastMessageReceiveTime.] */
AzureIoTClient 88:248736be106e 1460 result = IoTHubClientCore_LL_GetLastMessageReceiveTime(iotHubClientInstance->IoTHubClientLLHandle, lastMessageReceiveTime);
AzureIoTClient 88:248736be106e 1461
AzureIoTClient 88:248736be106e 1462 /* Codes_SRS_IOTHUBCLIENT_01_035: [IoTHubClient_GetLastMessageReceiveTime shall be made thread-safe by using the lock created in IoTHubClient_Create.] */
AzureIoTClient 88:248736be106e 1463 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1464 }
AzureIoTClient 88:248736be106e 1465 }
AzureIoTClient 88:248736be106e 1466
AzureIoTClient 88:248736be106e 1467 return result;
AzureIoTClient 88:248736be106e 1468 }
AzureIoTClient 88:248736be106e 1469
AzureIoTClient 88:248736be106e 1470 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetOption(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* optionName, const void* value)
AzureIoTClient 88:248736be106e 1471 {
AzureIoTClient 88:248736be106e 1472 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1473 /*Codes_SRS_IOTHUBCLIENT_02_034: [If parameter iotHubClientHandle is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG.] */
AzureIoTClient 88:248736be106e 1474 /*Codes_SRS_IOTHUBCLIENT_02_035: [ If parameter optionName is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 1475 /*Codes_SRS_IOTHUBCLIENT_02_036: [ If parameter value is NULL then IoTHubClient_SetOption shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 1476 if (
AzureIoTClient 88:248736be106e 1477 (iotHubClientHandle == NULL) ||
AzureIoTClient 88:248736be106e 1478 (optionName == NULL) ||
AzureIoTClient 88:248736be106e 1479 (value == NULL)
AzureIoTClient 88:248736be106e 1480 )
AzureIoTClient 88:248736be106e 1481 {
AzureIoTClient 88:248736be106e 1482 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1483 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1484 }
AzureIoTClient 88:248736be106e 1485 else
AzureIoTClient 88:248736be106e 1486 {
AzureIoTClient 88:248736be106e 1487 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1488
AzureIoTClient 88:248736be106e 1489 /* Codes_SRS_IOTHUBCLIENT_01_041: [ IoTHubClient_SetOption shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1490 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1491 {
AzureIoTClient 88:248736be106e 1492 /* Codes_SRS_IOTHUBCLIENT_01_042: [ If acquiring the lock fails, IoTHubClient_SetOption shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1493 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1494 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1495 }
AzureIoTClient 88:248736be106e 1496 else
AzureIoTClient 88:248736be106e 1497 {
AzureIoTClient 88:248736be106e 1498 /*Codes_SRS_IOTHUBCLIENT_02_038: [If optionName doesn't match one of the options handled by this module then IoTHubClient_SetOption shall call IoTHubClientCore_LL_SetOption passing the same parameters and return what IoTHubClientCore_LL_SetOption returns.] */
AzureIoTClient 88:248736be106e 1499 result = IoTHubClientCore_LL_SetOption(iotHubClientInstance->IoTHubClientLLHandle, optionName, value);
AzureIoTClient 88:248736be106e 1500 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1501 {
AzureIoTClient 88:248736be106e 1502 LogError("IoTHubClientCore_LL_SetOption failed");
AzureIoTClient 88:248736be106e 1503 }
AzureIoTClient 88:248736be106e 1504
AzureIoTClient 88:248736be106e 1505 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1506 }
AzureIoTClient 88:248736be106e 1507 }
AzureIoTClient 88:248736be106e 1508 return result;
AzureIoTClient 88:248736be106e 1509 }
AzureIoTClient 88:248736be106e 1510
AzureIoTClient 88:248736be106e 1511 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceTwinCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_TWIN_CALLBACK deviceTwinCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1512 {
AzureIoTClient 88:248736be106e 1513 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1514
AzureIoTClient 88:248736be106e 1515 /*Codes_SRS_IOTHUBCLIENT_10_001: [** `IoTHubClient_SetDeviceTwinCallback` shall fail and return `IOTHUB_CLIENT_INVALID_ARG` if parameter `iotHubClientHandle` is `NULL`. ]*/
AzureIoTClient 88:248736be106e 1516 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1517 {
AzureIoTClient 88:248736be106e 1518 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1519 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1520 }
AzureIoTClient 88:248736be106e 1521 else
AzureIoTClient 88:248736be106e 1522 {
AzureIoTClient 88:248736be106e 1523 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1524
AzureIoTClient 88:248736be106e 1525 /*Codes_SRS_IOTHUBCLIENT_10_003: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
AzureIoTClient 88:248736be106e 1526 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1527 {
AzureIoTClient 88:248736be106e 1528 /*Codes_SRS_IOTHUBCLIENT_10_004: [** If starting the thread fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1529 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1530 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1531 }
AzureIoTClient 88:248736be106e 1532 else
AzureIoTClient 88:248736be106e 1533 {
AzureIoTClient 88:248736be106e 1534 /*Codes_SRS_IOTHUBCLIENT_10_020: [** `IoTHubClient_SetDeviceTwinCallback` shall be made thread - safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1535 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1536 {
AzureIoTClient 88:248736be106e 1537 /*Codes_SRS_IOTHUBCLIENT_10_002: [** If acquiring the lock fails, `IoTHubClient_SetDeviceTwinCallback` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1538 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1539 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1540 }
AzureIoTClient 88:248736be106e 1541 else
AzureIoTClient 88:248736be106e 1542 {
AzureIoTClient 88:248736be106e 1543 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1544 {
AzureIoTClient 88:248736be106e 1545 iotHubClientInstance->desired_state_callback = deviceTwinCallback;
AzureIoTClient 88:248736be106e 1546 }
AzureIoTClient 88:248736be106e 1547
AzureIoTClient 88:248736be106e 1548 if (iotHubClientInstance->created_with_transport_handle != 0 || deviceTwinCallback == NULL)
AzureIoTClient 88:248736be106e 1549 {
AzureIoTClient 88:248736be106e 1550 /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClientCore_LL_SetDeviceTwinCallback` shall call `IoTHubClientCore_LL_SetDeviceTwinCallback`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedStateCallback` and `userContextCallback`. ]*/
AzureIoTClient 88:248736be106e 1551 result = IoTHubClientCore_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, deviceTwinCallback, userContextCallback);
AzureIoTClient 88:248736be106e 1552 }
AzureIoTClient 88:248736be106e 1553 else
AzureIoTClient 88:248736be106e 1554 {
AzureIoTClient 88:248736be106e 1555 if (iotHubClientInstance->devicetwin_user_context != NULL)
AzureIoTClient 88:248736be106e 1556 {
AzureIoTClient 88:248736be106e 1557 free(iotHubClientInstance->devicetwin_user_context);
AzureIoTClient 88:248736be106e 1558 }
AzureIoTClient 88:248736be106e 1559
AzureIoTClient 88:248736be106e 1560 /*Codes_SRS_IOTHUBCLIENT_07_002: [ IoTHubClient_SetDeviceTwinCallback shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SetDeviceTwinCallback function as a user context. ]*/
AzureIoTClient 88:248736be106e 1561 iotHubClientInstance->devicetwin_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1562 if (iotHubClientInstance->devicetwin_user_context == NULL)
AzureIoTClient 88:248736be106e 1563 {
AzureIoTClient 88:248736be106e 1564 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1565 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1566 }
AzureIoTClient 88:248736be106e 1567 else
AzureIoTClient 88:248736be106e 1568 {
AzureIoTClient 88:248736be106e 1569 /*Codes_SRS_IOTHUBCLIENT_10_005: [** `IoTHubClientCore_LL_SetDeviceTwinCallback` shall call `IoTHubClientCore_LL_SetDeviceTwinCallback`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `iothub_ll_device_twin_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
AzureIoTClient 88:248736be106e 1570 iotHubClientInstance->devicetwin_user_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 88:248736be106e 1571 iotHubClientInstance->devicetwin_user_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1572 result = IoTHubClientCore_LL_SetDeviceTwinCallback(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_device_twin_callback, iotHubClientInstance->devicetwin_user_context);
AzureIoTClient 88:248736be106e 1573 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1574 {
AzureIoTClient 88:248736be106e 1575 LogError("IoTHubClientCore_LL_SetDeviceTwinCallback failed");
AzureIoTClient 88:248736be106e 1576 free(iotHubClientInstance->devicetwin_user_context);
AzureIoTClient 88:248736be106e 1577 iotHubClientInstance->devicetwin_user_context = NULL;
AzureIoTClient 88:248736be106e 1578 }
AzureIoTClient 88:248736be106e 1579 }
AzureIoTClient 88:248736be106e 1580 }
AzureIoTClient 88:248736be106e 1581
AzureIoTClient 88:248736be106e 1582 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1583 }
AzureIoTClient 88:248736be106e 1584 }
AzureIoTClient 88:248736be106e 1585 }
AzureIoTClient 88:248736be106e 1586 return result;
AzureIoTClient 88:248736be106e 1587 }
AzureIoTClient 88:248736be106e 1588
AzureIoTClient 88:248736be106e 1589 IOTHUB_CLIENT_RESULT IoTHubClientCore_SendReportedState(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const unsigned char* reportedState, size_t size, IOTHUB_CLIENT_REPORTED_STATE_CALLBACK reportedStateCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1590 {
AzureIoTClient 88:248736be106e 1591 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1592
AzureIoTClient 88:248736be106e 1593 /*Codes_SRS_IOTHUBCLIENT_10_013: [** If `iotHubClientHandle` is `NULL`, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 88:248736be106e 1594 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1595 {
AzureIoTClient 88:248736be106e 1596 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1597 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1598 }
AzureIoTClient 88:248736be106e 1599 else
AzureIoTClient 88:248736be106e 1600 {
AzureIoTClient 88:248736be106e 1601 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1602
AzureIoTClient 88:248736be106e 1603 /*Codes_SRS_IOTHUBCLIENT_10_015: [** If the transport connection is shared, the thread shall be started by calling `IoTHubTransport_StartWorkerThread`. ]*/
AzureIoTClient 88:248736be106e 1604 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1605 {
AzureIoTClient 88:248736be106e 1606 /*Codes_SRS_IOTHUBCLIENT_10_016: [** If starting the thread fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1607 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1608 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1609 }
AzureIoTClient 88:248736be106e 1610 else
AzureIoTClient 88:248736be106e 1611 {
AzureIoTClient 88:248736be106e 1612 /*Codes_SRS_IOTHUBCLIENT_10_021: [** `IoTHubClient_SendReportedState` shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1613 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1614 {
AzureIoTClient 88:248736be106e 1615 /*Codes_SRS_IOTHUBCLIENT_10_014: [** If acquiring the lock fails, `IoTHubClient_SendReportedState` shall return `IOTHUB_CLIENT_ERROR`. ]*/
AzureIoTClient 88:248736be106e 1616 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1617 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1618 }
AzureIoTClient 88:248736be106e 1619 else
AzureIoTClient 88:248736be106e 1620 {
AzureIoTClient 88:248736be106e 1621 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1622 {
AzureIoTClient 88:248736be106e 1623 iotHubClientInstance->reported_state_callback = reportedStateCallback;
AzureIoTClient 88:248736be106e 1624 }
AzureIoTClient 88:248736be106e 1625
AzureIoTClient 88:248736be106e 1626 if (iotHubClientInstance->created_with_transport_handle != 0 || reportedStateCallback == NULL)
AzureIoTClient 88:248736be106e 1627 {
AzureIoTClient 88:248736be106e 1628 /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClientCore_LL_SendReportedState`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedState`, `size`, `reportedStateCallback`, and `userContextCallback`. ]*/
AzureIoTClient 88:248736be106e 1629 /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClientCore_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClientCore_LL_SendReportedState`. **]*/
AzureIoTClient 88:248736be106e 1630 result = IoTHubClientCore_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, reportedStateCallback, userContextCallback);
AzureIoTClient 88:248736be106e 1631 }
AzureIoTClient 88:248736be106e 1632 else
AzureIoTClient 88:248736be106e 1633 {
AzureIoTClient 88:248736be106e 1634 /* Codes_SRS_IOTHUBCLIENT_07_003: [ IoTHubClient_SendReportedState shall allocate a IOTHUB_QUEUE_CONTEXT object to be sent to the IoTHubClientCore_LL_SendReportedState function as a user context. ] */
AzureIoTClient 88:248736be106e 1635 IOTHUB_QUEUE_CONTEXT* queue_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1636 if (queue_context == NULL)
AzureIoTClient 88:248736be106e 1637 {
AzureIoTClient 88:248736be106e 1638 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1639 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1640 }
AzureIoTClient 88:248736be106e 1641 else
AzureIoTClient 88:248736be106e 1642 {
AzureIoTClient 88:248736be106e 1643 queue_context->iotHubClientHandle = iotHubClientInstance;
AzureIoTClient 88:248736be106e 1644 queue_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1645 /*Codes_SRS_IOTHUBCLIENT_10_017: [** `IoTHubClient_SendReportedState` shall call `IoTHubClientCore_LL_SendReportedState`, while passing the `IoTHubClientCore_LL handle` created by `IoTHubClientCore_LL_Create` along with the parameters `reportedState`, `size`, `iothub_ll_reported_state_callback` and IOTHUB_QUEUE_CONTEXT variable. ]*/
AzureIoTClient 88:248736be106e 1646 /*Codes_SRS_IOTHUBCLIENT_10_018: [** When `IoTHubClientCore_LL_SendReportedState` is called, `IoTHubClient_SendReportedState` shall return the result of `IoTHubClientCore_LL_SendReportedState`. **]*/
AzureIoTClient 88:248736be106e 1647 result = IoTHubClientCore_LL_SendReportedState(iotHubClientInstance->IoTHubClientLLHandle, reportedState, size, iothub_ll_reported_state_callback, queue_context);
AzureIoTClient 88:248736be106e 1648 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1649 {
AzureIoTClient 88:248736be106e 1650 LogError("IoTHubClientCore_LL_SendReportedState failed");
AzureIoTClient 88:248736be106e 1651 free(queue_context);
AzureIoTClient 88:248736be106e 1652 }
AzureIoTClient 88:248736be106e 1653 }
AzureIoTClient 88:248736be106e 1654 }
AzureIoTClient 88:248736be106e 1655
AzureIoTClient 88:248736be106e 1656 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1657 }
AzureIoTClient 88:248736be106e 1658 }
AzureIoTClient 88:248736be106e 1659 }
AzureIoTClient 88:248736be106e 1660 return result;
AzureIoTClient 88:248736be106e 1661 }
AzureIoTClient 88:248736be106e 1662
AzureIoTClient 88:248736be106e 1663 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceMethodCallback(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_DEVICE_METHOD_CALLBACK_ASYNC deviceMethodCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1664 {
AzureIoTClient 88:248736be106e 1665 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1666
AzureIoTClient 88:248736be106e 1667 /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 1668 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1669 {
AzureIoTClient 88:248736be106e 1670 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1671 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1672 }
AzureIoTClient 88:248736be106e 1673 else
AzureIoTClient 88:248736be106e 1674 {
AzureIoTClient 88:248736be106e 1675 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1676
AzureIoTClient 88:248736be106e 1677 /*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 88:248736be106e 1678 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1679 {
AzureIoTClient 88:248736be106e 1680 /*Codes_SRS_IOTHUBCLIENT_12_015: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1681 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1682 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1683 }
AzureIoTClient 88:248736be106e 1684 else
AzureIoTClient 88:248736be106e 1685 {
AzureIoTClient 88:248736be106e 1686 /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1687 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1688 {
AzureIoTClient 88:248736be106e 1689 /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1690 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1691 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1692 }
AzureIoTClient 88:248736be106e 1693 else
AzureIoTClient 88:248736be106e 1694 {
AzureIoTClient 88:248736be106e 1695 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1696 {
AzureIoTClient 88:248736be106e 1697 iotHubClientInstance->device_method_callback = deviceMethodCallback;
AzureIoTClient 88:248736be106e 1698 }
AzureIoTClient 88:248736be106e 1699
AzureIoTClient 88:248736be106e 1700 if (iotHubClientInstance->method_user_context)
AzureIoTClient 88:248736be106e 1701 {
AzureIoTClient 88:248736be106e 1702 free(iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1703 iotHubClientInstance->method_user_context = NULL;
AzureIoTClient 88:248736be106e 1704 }
AzureIoTClient 88:248736be106e 1705 if (deviceMethodCallback == NULL)
AzureIoTClient 88:248736be106e 1706 {
AzureIoTClient 88:248736be106e 1707 result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, NULL);
AzureIoTClient 88:248736be106e 1708 }
AzureIoTClient 88:248736be106e 1709 else
AzureIoTClient 88:248736be106e 1710 {
AzureIoTClient 88:248736be106e 1711 iotHubClientInstance->method_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1712 if (iotHubClientInstance->method_user_context == NULL)
AzureIoTClient 88:248736be106e 1713 {
AzureIoTClient 88:248736be106e 1714 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1715 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1716 }
AzureIoTClient 88:248736be106e 1717 else
AzureIoTClient 88:248736be106e 1718 {
AzureIoTClient 88:248736be106e 1719 iotHubClientInstance->method_user_context->iotHubClientHandle = iotHubClientHandle;
AzureIoTClient 88:248736be106e 1720 iotHubClientInstance->method_user_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1721
AzureIoTClient 88:248736be106e 1722 /*Codes_SRS_IOTHUBCLIENT_12_016: [ IoTHubClient_SetDeviceMethodCallback shall call IoTHubClientCore_LL_SetDeviceMethodCallback, while passing the IoTHubClientCore_LL_handle created by IoTHubClientCore_LL_Create along with the parameters deviceMethodCallback and userContextCallback. ]*/
AzureIoTClient 88:248736be106e 1723 /*Codes_SRS_IOTHUBCLIENT_12_017: [ When IoTHubClientCore_LL_SetDeviceMethodCallback is called, IoTHubClient_SetDeviceMethodCallback shall return the result of IoTHubClientCore_LL_SetDeviceMethodCallback. ]*/
AzureIoTClient 88:248736be106e 1724 result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_device_method_callback, iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1725 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1726 {
AzureIoTClient 88:248736be106e 1727 LogError("IoTHubClientCore_LL_SetDeviceMethodCallback_Ex failed");
AzureIoTClient 88:248736be106e 1728 free(iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1729 iotHubClientInstance->method_user_context = NULL;
AzureIoTClient 88:248736be106e 1730 }
AzureIoTClient 88:248736be106e 1731 else
AzureIoTClient 88:248736be106e 1732 {
AzureIoTClient 88:248736be106e 1733 iotHubClientInstance->device_method_callback = deviceMethodCallback;
AzureIoTClient 88:248736be106e 1734 }
AzureIoTClient 88:248736be106e 1735 }
AzureIoTClient 88:248736be106e 1736 }
AzureIoTClient 88:248736be106e 1737
AzureIoTClient 88:248736be106e 1738 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1739 }
AzureIoTClient 88:248736be106e 1740
AzureIoTClient 88:248736be106e 1741 }
AzureIoTClient 88:248736be106e 1742 }
AzureIoTClient 88:248736be106e 1743 return result;
AzureIoTClient 88:248736be106e 1744 }
AzureIoTClient 88:248736be106e 1745
AzureIoTClient 88:248736be106e 1746 IOTHUB_CLIENT_RESULT IoTHubClientCore_SetDeviceMethodCallback_Ex(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, IOTHUB_CLIENT_INBOUND_DEVICE_METHOD_CALLBACK inboundDeviceMethodCallback, void* userContextCallback)
AzureIoTClient 88:248736be106e 1747 {
AzureIoTClient 88:248736be106e 1748 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1749
AzureIoTClient 88:248736be106e 1750 /*Codes_SRS_IOTHUBCLIENT_07_001: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 1751 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1752 {
AzureIoTClient 88:248736be106e 1753 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1754 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1755 }
AzureIoTClient 88:248736be106e 1756 else
AzureIoTClient 88:248736be106e 1757 {
AzureIoTClient 88:248736be106e 1758 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1759
AzureIoTClient 88:248736be106e 1760 /*Codes_SRS_IOTHUBCLIENT_07_003: [ If the transport handle is NULL and the worker thread is not initialized, the thread shall be started by calling IoTHubTransport_StartWorkerThread. ]*/
AzureIoTClient 88:248736be106e 1761 if ((result = StartWorkerThreadIfNeeded(iotHubClientInstance)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1762 {
AzureIoTClient 88:248736be106e 1763 /*Codes_SRS_IOTHUBCLIENT_07_004: [ If starting the thread fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1764 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1765 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 1766 }
AzureIoTClient 88:248736be106e 1767 else
AzureIoTClient 88:248736be106e 1768 {
AzureIoTClient 88:248736be106e 1769 /*Codes_SRS_IOTHUBCLIENT_07_007: [ IoTHubClient_SetDeviceMethodCallback_Ex shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1770 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1771 {
AzureIoTClient 88:248736be106e 1772 /*Codes_SRS_IOTHUBCLIENT_07_002: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback_Ex shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1773 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1774 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1775 }
AzureIoTClient 88:248736be106e 1776 else
AzureIoTClient 88:248736be106e 1777 {
AzureIoTClient 88:248736be106e 1778 if (iotHubClientInstance->created_with_transport_handle == 0)
AzureIoTClient 88:248736be106e 1779 {
AzureIoTClient 88:248736be106e 1780 iotHubClientInstance->inbound_device_method_callback = inboundDeviceMethodCallback;
AzureIoTClient 88:248736be106e 1781 }
AzureIoTClient 88:248736be106e 1782
AzureIoTClient 88:248736be106e 1783 if (iotHubClientInstance->method_user_context)
AzureIoTClient 88:248736be106e 1784 {
AzureIoTClient 88:248736be106e 1785 free(iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1786 iotHubClientInstance->method_user_context = NULL;
AzureIoTClient 88:248736be106e 1787 }
AzureIoTClient 88:248736be106e 1788 if (inboundDeviceMethodCallback == NULL)
AzureIoTClient 88:248736be106e 1789 {
AzureIoTClient 88:248736be106e 1790 /* Codes_SRS_IOTHUBCLIENT_07_008: [ If inboundDeviceMethodCallback is NULL, IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, passing NULL for the iothub_ll_inbound_device_method_callback. ] */
AzureIoTClient 88:248736be106e 1791 result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, NULL, NULL);
AzureIoTClient 88:248736be106e 1792 }
AzureIoTClient 88:248736be106e 1793 else
AzureIoTClient 88:248736be106e 1794 {
AzureIoTClient 88:248736be106e 1795 iotHubClientInstance->method_user_context = (IOTHUB_QUEUE_CONTEXT*)malloc(sizeof(IOTHUB_QUEUE_CONTEXT));
AzureIoTClient 88:248736be106e 1796 if (iotHubClientInstance->method_user_context == NULL)
AzureIoTClient 88:248736be106e 1797 {
AzureIoTClient 88:248736be106e 1798 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1799 LogError("Failed allocating QUEUE_CONTEXT");
AzureIoTClient 88:248736be106e 1800 }
AzureIoTClient 88:248736be106e 1801 else
AzureIoTClient 88:248736be106e 1802 {
AzureIoTClient 88:248736be106e 1803 /*Codes_SRS_IOTHUBCLIENT_07_005: [ IoTHubClient_SetDeviceMethodCallback_Ex shall call IoTHubClientCore_LL_SetDeviceMethodCallback_Ex, while passing the IoTHubClientCore_LL_handle created by IoTHubClientCore_LL_Create along with the parameters iothub_ll_inbound_device_method_callback and IOTHUB_QUEUE_CONTEXT. ]*/
AzureIoTClient 88:248736be106e 1804 iotHubClientInstance->method_user_context->iotHubClientHandle = iotHubClientHandle;
AzureIoTClient 88:248736be106e 1805 iotHubClientInstance->method_user_context->userContextCallback = userContextCallback;
AzureIoTClient 88:248736be106e 1806
AzureIoTClient 88:248736be106e 1807 /* Codes_SRS_IOTHUBCLIENT_07_006: [ When IoTHubClientCore_LL_SetDeviceMethodCallback_Ex is called, IoTHubClient_SetDeviceMethodCallback_Ex shall return the result of IoTHubClientCore_LL_SetDeviceMethodCallback_Ex. ] */
AzureIoTClient 88:248736be106e 1808 result = IoTHubClientCore_LL_SetDeviceMethodCallback_Ex(iotHubClientInstance->IoTHubClientLLHandle, iothub_ll_inbound_device_method_callback, iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1809 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1810 {
AzureIoTClient 88:248736be106e 1811 LogError("IoTHubClientCore_LL_SetDeviceMethodCallback_Ex failed");
AzureIoTClient 88:248736be106e 1812 free(iotHubClientInstance->method_user_context);
AzureIoTClient 88:248736be106e 1813 iotHubClientInstance->method_user_context = NULL;
AzureIoTClient 88:248736be106e 1814 }
AzureIoTClient 88:248736be106e 1815 else
AzureIoTClient 88:248736be106e 1816 {
AzureIoTClient 88:248736be106e 1817 iotHubClientInstance->inbound_device_method_callback = inboundDeviceMethodCallback;
AzureIoTClient 88:248736be106e 1818 }
AzureIoTClient 88:248736be106e 1819 }
AzureIoTClient 88:248736be106e 1820 }
AzureIoTClient 88:248736be106e 1821
AzureIoTClient 88:248736be106e 1822 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1823 }
AzureIoTClient 88:248736be106e 1824 }
AzureIoTClient 88:248736be106e 1825 }
AzureIoTClient 88:248736be106e 1826 return result;
AzureIoTClient 88:248736be106e 1827 }
AzureIoTClient 88:248736be106e 1828
AzureIoTClient 88:248736be106e 1829 IOTHUB_CLIENT_RESULT IoTHubClientCore_DeviceMethodResponse(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, METHOD_HANDLE methodId, const unsigned char* response, size_t respSize, int statusCode)
AzureIoTClient 88:248736be106e 1830 {
AzureIoTClient 88:248736be106e 1831 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1832
AzureIoTClient 88:248736be106e 1833 /*Codes_SRS_IOTHUBCLIENT_12_012: [ If iotHubClientHandle is NULL, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 1834 if (iotHubClientHandle == NULL)
AzureIoTClient 88:248736be106e 1835 {
AzureIoTClient 88:248736be106e 1836 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 1837 LogError("invalid arg (NULL)");
AzureIoTClient 88:248736be106e 1838 }
AzureIoTClient 88:248736be106e 1839 else
AzureIoTClient 88:248736be106e 1840 {
AzureIoTClient 88:248736be106e 1841 IOTHUB_CLIENT_CORE_INSTANCE* iotHubClientInstance = (IOTHUB_CLIENT_CORE_INSTANCE*)iotHubClientHandle;
AzureIoTClient 88:248736be106e 1842
AzureIoTClient 88:248736be106e 1843 /*Codes_SRS_IOTHUBCLIENT_12_018: [ IoTHubClient_SetDeviceMethodCallback shall be made thread-safe by using the lock created in IoTHubClient_Create. ]*/
AzureIoTClient 88:248736be106e 1844 if (Lock(iotHubClientInstance->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1845 {
AzureIoTClient 88:248736be106e 1846 /*Codes_SRS_IOTHUBCLIENT_12_013: [ If acquiring the lock fails, IoTHubClient_SetDeviceMethodCallback shall return IOTHUB_CLIENT_ERROR. ]*/
AzureIoTClient 88:248736be106e 1847 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1848 LogError("Could not acquire lock");
AzureIoTClient 88:248736be106e 1849 }
AzureIoTClient 88:248736be106e 1850 else
AzureIoTClient 88:248736be106e 1851 {
AzureIoTClient 88:248736be106e 1852 result = IoTHubClientCore_LL_DeviceMethodResponse(iotHubClientInstance->IoTHubClientLLHandle, methodId, response, respSize, statusCode);
AzureIoTClient 88:248736be106e 1853 if (result != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1854 {
AzureIoTClient 88:248736be106e 1855 LogError("IoTHubClientCore_LL_DeviceMethodResponse failed");
AzureIoTClient 88:248736be106e 1856 }
AzureIoTClient 88:248736be106e 1857 (void)Unlock(iotHubClientInstance->LockHandle);
AzureIoTClient 88:248736be106e 1858 }
AzureIoTClient 88:248736be106e 1859 }
AzureIoTClient 88:248736be106e 1860 return result;
AzureIoTClient 88:248736be106e 1861 }
AzureIoTClient 88:248736be106e 1862
AzureIoTClient 88:248736be106e 1863 #ifndef DONT_USE_UPLOADTOBLOB
AzureIoTClient 88:248736be106e 1864 static IOTHUB_CLIENT_RESULT startUploadToBlobWorkerThread(UPLOADTOBLOB_THREAD_INFO* threadInfo, THREAD_START_FUNC uploadThreadFunc)
AzureIoTClient 88:248736be106e 1865 {
AzureIoTClient 88:248736be106e 1866 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1867
AzureIoTClient 88:248736be106e 1868 LIST_ITEM_HANDLE item;
AzureIoTClient 88:248736be106e 1869
AzureIoTClient 88:248736be106e 1870 if (Lock(threadInfo->iotHubClientHandle->LockHandle) != LOCK_OK)
AzureIoTClient 88:248736be106e 1871 {
AzureIoTClient 88:248736be106e 1872 LogError("Lock failed");
AzureIoTClient 88:248736be106e 1873 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1874 }
AzureIoTClient 88:248736be106e 1875 else
AzureIoTClient 88:248736be106e 1876 {
AzureIoTClient 88:248736be106e 1877 if ((item = singlylinkedlist_add(threadInfo->iotHubClientHandle->savedDataToBeCleaned, threadInfo)) == NULL)
AzureIoTClient 88:248736be106e 1878 {
AzureIoTClient 88:248736be106e 1879 LogError("Adding item to list failed");
AzureIoTClient 88:248736be106e 1880 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1881 }
AzureIoTClient 88:248736be106e 1882 else if (ThreadAPI_Create(&threadInfo->uploadingThreadHandle, uploadThreadFunc, threadInfo) != THREADAPI_OK)
AzureIoTClient 88:248736be106e 1883 {
AzureIoTClient 88:248736be106e 1884 /*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 88:248736be106e 1885 LogError("unable to ThreadAPI_Create");
AzureIoTClient 88:248736be106e 1886 // Remove the item from linked list here, while we're still under lock. Final garbage collector also does it under lock.
AzureIoTClient 88:248736be106e 1887 (void)singlylinkedlist_remove(threadInfo->iotHubClientHandle->savedDataToBeCleaned, item);
AzureIoTClient 88:248736be106e 1888 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1889 }
AzureIoTClient 88:248736be106e 1890 else
AzureIoTClient 88:248736be106e 1891 {
AzureIoTClient 88:248736be106e 1892 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 1893 }
AzureIoTClient 88:248736be106e 1894 (void)Unlock(threadInfo->iotHubClientHandle->LockHandle);
AzureIoTClient 88:248736be106e 1895 }
AzureIoTClient 88:248736be106e 1896
AzureIoTClient 88:248736be106e 1897 return result;
AzureIoTClient 88:248736be106e 1898 }
AzureIoTClient 88:248736be106e 1899
AzureIoTClient 88:248736be106e 1900 static UPLOADTOBLOB_THREAD_INFO* allocateUploadToBlob(const char* destinationFileName, IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, void* context)
AzureIoTClient 88:248736be106e 1901 {
AzureIoTClient 88:248736be106e 1902 UPLOADTOBLOB_THREAD_INFO* threadInfo = (UPLOADTOBLOB_THREAD_INFO*)malloc(sizeof(UPLOADTOBLOB_THREAD_INFO));
AzureIoTClient 88:248736be106e 1903 if (threadInfo == NULL)
AzureIoTClient 88:248736be106e 1904 {
AzureIoTClient 88:248736be106e 1905 LogError("unable to allocate thread object");
AzureIoTClient 88:248736be106e 1906 }
AzureIoTClient 88:248736be106e 1907 else
AzureIoTClient 88:248736be106e 1908 {
AzureIoTClient 88:248736be106e 1909 memset(threadInfo, 0, sizeof(UPLOADTOBLOB_THREAD_INFO));
AzureIoTClient 88:248736be106e 1910 threadInfo->iotHubClientHandle = iotHubClientHandle;
AzureIoTClient 88:248736be106e 1911 threadInfo->context = context;
AzureIoTClient 88:248736be106e 1912
AzureIoTClient 88:248736be106e 1913 if (mallocAndStrcpy_s(&threadInfo->destinationFileName, destinationFileName) != 0)
AzureIoTClient 88:248736be106e 1914 {
AzureIoTClient 88:248736be106e 1915 /*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 88:248736be106e 1916 LogError("unable to mallocAndStrcpy_s");
AzureIoTClient 88:248736be106e 1917 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 1918 threadInfo = NULL;
AzureIoTClient 88:248736be106e 1919 }
AzureIoTClient 88:248736be106e 1920 else if ((threadInfo->lockGarbage = Lock_Init()) == NULL)
AzureIoTClient 88:248736be106e 1921 {
AzureIoTClient 88:248736be106e 1922 LogError("unable to allocate a lock");
AzureIoTClient 88:248736be106e 1923 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 1924 threadInfo = NULL;
AzureIoTClient 88:248736be106e 1925 }
AzureIoTClient 88:248736be106e 1926 }
AzureIoTClient 88:248736be106e 1927
AzureIoTClient 88:248736be106e 1928 return threadInfo;
AzureIoTClient 88:248736be106e 1929 }
AzureIoTClient 88:248736be106e 1930
AzureIoTClient 88:248736be106e 1931 static int markThreadReadyToBeGarbageCollected(UPLOADTOBLOB_THREAD_INFO* threadInfo)
AzureIoTClient 88:248736be106e 1932 {
AzureIoTClient 88:248736be106e 1933 /*Codes_SRS_IOTHUBCLIENT_02_071: [ The thread shall mark itself as disposable. ]*/
AzureIoTClient 88:248736be106e 1934 if (Lock(threadInfo->lockGarbage) != LOCK_OK)
AzureIoTClient 88:248736be106e 1935 {
AzureIoTClient 88:248736be106e 1936 LogError("unable to Lock - trying anyway");
AzureIoTClient 88:248736be106e 1937 threadInfo->canBeGarbageCollected = 1;
AzureIoTClient 88:248736be106e 1938 }
AzureIoTClient 88:248736be106e 1939 else
AzureIoTClient 88:248736be106e 1940 {
AzureIoTClient 88:248736be106e 1941 threadInfo->canBeGarbageCollected = 1;
AzureIoTClient 88:248736be106e 1942
AzureIoTClient 88:248736be106e 1943 if (Unlock(threadInfo->lockGarbage) != LOCK_OK)
AzureIoTClient 88:248736be106e 1944 {
AzureIoTClient 88:248736be106e 1945 LogError("unable to Unlock after locking");
AzureIoTClient 88:248736be106e 1946 }
AzureIoTClient 88:248736be106e 1947 }
AzureIoTClient 88:248736be106e 1948
AzureIoTClient 88:248736be106e 1949 ThreadAPI_Exit(0);
AzureIoTClient 88:248736be106e 1950 return 0;
AzureIoTClient 88:248736be106e 1951 }
AzureIoTClient 88:248736be106e 1952
AzureIoTClient 88:248736be106e 1953 static IOTHUB_CLIENT_RESULT initializeUploadToBlobData(UPLOADTOBLOB_THREAD_INFO* threadInfo, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback)
AzureIoTClient 88:248736be106e 1954 {
AzureIoTClient 88:248736be106e 1955 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 1956
AzureIoTClient 88:248736be106e 1957 threadInfo->uploadBlobSavedData.size = size;
AzureIoTClient 88:248736be106e 1958 threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback = iotHubClientFileUploadCallback;
AzureIoTClient 88:248736be106e 1959
AzureIoTClient 88:248736be106e 1960 if (size != 0)
AzureIoTClient 88:248736be106e 1961 {
AzureIoTClient 88:248736be106e 1962 if ((threadInfo->uploadBlobSavedData.source = (unsigned char*)malloc(size)) == NULL)
AzureIoTClient 88:248736be106e 1963 {
AzureIoTClient 88:248736be106e 1964 LogError("Cannot allocate source field");
AzureIoTClient 88:248736be106e 1965 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 1966 }
AzureIoTClient 88:248736be106e 1967 else
AzureIoTClient 88:248736be106e 1968 {
AzureIoTClient 88:248736be106e 1969 memcpy(threadInfo->uploadBlobSavedData.source, source, size);
AzureIoTClient 88:248736be106e 1970 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 1971 }
AzureIoTClient 88:248736be106e 1972 }
AzureIoTClient 88:248736be106e 1973 else
AzureIoTClient 88:248736be106e 1974 {
AzureIoTClient 88:248736be106e 1975 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 1976 }
AzureIoTClient 88:248736be106e 1977
AzureIoTClient 88:248736be106e 1978 return result;
AzureIoTClient 88:248736be106e 1979 }
AzureIoTClient 88:248736be106e 1980
AzureIoTClient 88:248736be106e 1981
AzureIoTClient 88:248736be106e 1982 static int uploadingThread(void *data)
AzureIoTClient 88:248736be106e 1983 {
AzureIoTClient 88:248736be106e 1984 IOTHUB_CLIENT_FILE_UPLOAD_RESULT upload_result;
AzureIoTClient 88:248736be106e 1985 UPLOADTOBLOB_THREAD_INFO* threadInfo = (UPLOADTOBLOB_THREAD_INFO*)data;
AzureIoTClient 88:248736be106e 1986
AzureIoTClient 88:248736be106e 1987 /*it so happens that IoTHubClientCore_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 88:248736be106e 1988 /*not having it protected means multiple simultaneous uploads can happen*/
AzureIoTClient 88:248736be106e 1989 /*Codes_SRS_IOTHUBCLIENT_02_054: [ The thread shall call IoTHubClientCore_LL_UploadToBlob passing the information packed in the structure. ]*/
AzureIoTClient 88:248736be106e 1990 if (IoTHubClientCore_LL_UploadToBlob(threadInfo->iotHubClientHandle->IoTHubClientLLHandle, threadInfo->destinationFileName, threadInfo->uploadBlobSavedData.source, threadInfo->uploadBlobSavedData.size) == IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 1991 {
AzureIoTClient 88:248736be106e 1992 upload_result = FILE_UPLOAD_OK;
AzureIoTClient 88:248736be106e 1993 }
AzureIoTClient 88:248736be106e 1994 else
AzureIoTClient 88:248736be106e 1995 {
AzureIoTClient 88:248736be106e 1996 LogError("unable to IoTHubClientCore_LL_UploadToBlob");
AzureIoTClient 88:248736be106e 1997 upload_result = FILE_UPLOAD_ERROR;
AzureIoTClient 88:248736be106e 1998 }
AzureIoTClient 88:248736be106e 1999
AzureIoTClient 88:248736be106e 2000 if (threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback != NULL)
AzureIoTClient 88:248736be106e 2001 {
AzureIoTClient 88:248736be106e 2002 /*Codes_SRS_IOTHUBCLIENT_02_055: [ If IoTHubClientCore_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 88:248736be106e 2003 threadInfo->uploadBlobSavedData.iotHubClientFileUploadCallback(upload_result, threadInfo->context);
AzureIoTClient 88:248736be106e 2004 }
AzureIoTClient 88:248736be106e 2005
AzureIoTClient 88:248736be106e 2006 return markThreadReadyToBeGarbageCollected(threadInfo);
AzureIoTClient 88:248736be106e 2007 }
AzureIoTClient 88:248736be106e 2008
AzureIoTClient 88:248736be106e 2009 IOTHUB_CLIENT_RESULT IoTHubClientCore_UploadToBlobAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* destinationFileName, const unsigned char* source, size_t size, IOTHUB_CLIENT_FILE_UPLOAD_CALLBACK iotHubClientFileUploadCallback, void* context)
AzureIoTClient 88:248736be106e 2010 {
AzureIoTClient 88:248736be106e 2011 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 2012 /*Codes_SRS_IOTHUBCLIENT_02_047: [ If iotHubClientHandle is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 2013 /*Codes_SRS_IOTHUBCLIENT_02_048: [ If destinationFileName is NULL then IoTHubClient_UploadToBlobAsync shall fail and return IOTHUB_CLIENT_INVALID_ARG. ]*/
AzureIoTClient 88:248736be106e 2014 /*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 88:248736be106e 2015 if (
AzureIoTClient 88:248736be106e 2016 (iotHubClientHandle == NULL) ||
AzureIoTClient 88:248736be106e 2017 (destinationFileName == NULL) ||
AzureIoTClient 88:248736be106e 2018 ((source == NULL) && (size > 0))
AzureIoTClient 88:248736be106e 2019 )
AzureIoTClient 88:248736be106e 2020 {
AzureIoTClient 88:248736be106e 2021 LogError("invalid parameters IOTHUB_CLIENT_CORE_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 88:248736be106e 2022 iotHubClientHandle,
AzureIoTClient 88:248736be106e 2023 destinationFileName,
AzureIoTClient 88:248736be106e 2024 source,
AzureIoTClient 88:248736be106e 2025 size,
AzureIoTClient 88:248736be106e 2026 iotHubClientFileUploadCallback,
AzureIoTClient 88:248736be106e 2027 context
AzureIoTClient 88:248736be106e 2028 );
AzureIoTClient 88:248736be106e 2029 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 2030 }
AzureIoTClient 88:248736be106e 2031 else
AzureIoTClient 88:248736be106e 2032 {
AzureIoTClient 88:248736be106e 2033 /*Codes_SRS_IOTHUBCLIENT_02_051: [IoTHubClient_UploadToBlobAsync shall copy the souce, size, iotHubClientFileUploadCallback, context into a structure.]*/
AzureIoTClient 88:248736be106e 2034 UPLOADTOBLOB_THREAD_INFO *threadInfo = allocateUploadToBlob(destinationFileName, iotHubClientHandle, context);
AzureIoTClient 88:248736be106e 2035 if (threadInfo == NULL)
AzureIoTClient 88:248736be106e 2036 {
AzureIoTClient 88:248736be106e 2037 /*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 88:248736be106e 2038 LogError("unable to create upload thread info");
AzureIoTClient 88:248736be106e 2039 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 2040 }
AzureIoTClient 88:248736be106e 2041 else if ((result = initializeUploadToBlobData(threadInfo, source, size, iotHubClientFileUploadCallback)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 2042 {
AzureIoTClient 88:248736be106e 2043 /*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 88:248736be106e 2044 LogError("unable to initialize upload blob info");
AzureIoTClient 88:248736be106e 2045 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 2046 }
AzureIoTClient 88:248736be106e 2047 else if ((result = StartWorkerThreadIfNeeded(iotHubClientHandle)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 2048 {
AzureIoTClient 88:248736be106e 2049 /*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 88:248736be106e 2050 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 2051 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 2052 }
AzureIoTClient 88:248736be106e 2053 /*Codes_SRS_IOTHUBCLIENT_02_052: [ IoTHubClient_UploadToBlobAsync shall spawn a thread passing the structure build in SRS IOTHUBCLIENT 02 051 as thread data.]*/
AzureIoTClient 88:248736be106e 2054 else if ((result = startUploadToBlobWorkerThread(threadInfo, uploadingThread)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 2055 {
AzureIoTClient 88:248736be106e 2056 /*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 88:248736be106e 2057 LogError("unable to start upload thread");
AzureIoTClient 88:248736be106e 2058 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 2059 }
AzureIoTClient 88:248736be106e 2060 else
AzureIoTClient 88:248736be106e 2061 {
AzureIoTClient 88:248736be106e 2062 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 2063 }
AzureIoTClient 88:248736be106e 2064 }
AzureIoTClient 88:248736be106e 2065
AzureIoTClient 88:248736be106e 2066 return result;
AzureIoTClient 88:248736be106e 2067 }
AzureIoTClient 88:248736be106e 2068
AzureIoTClient 88:248736be106e 2069 static int uploadMultipleBlock_thread(void* data)
AzureIoTClient 88:248736be106e 2070 {
AzureIoTClient 88:248736be106e 2071 UPLOADTOBLOB_THREAD_INFO* threadInfo = (UPLOADTOBLOB_THREAD_INFO*)data;
AzureIoTClient 88:248736be106e 2072 IOTHUB_CLIENT_CORE_LL_HANDLE llHandle = threadInfo->iotHubClientHandle->IoTHubClientLLHandle;
AzureIoTClient 88:248736be106e 2073
AzureIoTClient 88:248736be106e 2074 /*Codes_SRS_IOTHUBCLIENT_99_078: [ The thread shall call `IoTHubClientCore_LL_UploadMultipleBlocksToBlob` or `IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx` passing the information packed in the structure. ]*/
AzureIoTClient 88:248736be106e 2075 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 2076
AzureIoTClient 88:248736be106e 2077 if (threadInfo->uploadBlobMultiblockSavedData.getDataCallback != NULL)
AzureIoTClient 88:248736be106e 2078 {
AzureIoTClient 88:248736be106e 2079 result = IoTHubClientCore_LL_UploadMultipleBlocksToBlob(llHandle, threadInfo->destinationFileName, threadInfo->uploadBlobMultiblockSavedData.getDataCallback, threadInfo->context);
AzureIoTClient 88:248736be106e 2080 }
AzureIoTClient 88:248736be106e 2081 else
AzureIoTClient 88:248736be106e 2082 {
AzureIoTClient 88:248736be106e 2083 result = IoTHubClientCore_LL_UploadMultipleBlocksToBlobEx(llHandle, threadInfo->destinationFileName, threadInfo->uploadBlobMultiblockSavedData.getDataCallbackEx, threadInfo->context);
AzureIoTClient 88:248736be106e 2084 }
AzureIoTClient 88:248736be106e 2085 (void)markThreadReadyToBeGarbageCollected(threadInfo);
AzureIoTClient 88:248736be106e 2086
AzureIoTClient 88:248736be106e 2087 return result;
AzureIoTClient 88:248736be106e 2088 }
AzureIoTClient 88:248736be106e 2089
AzureIoTClient 88:248736be106e 2090 IOTHUB_CLIENT_RESULT IoTHubClientCore_UploadMultipleBlocksToBlobAsync(IOTHUB_CLIENT_CORE_HANDLE iotHubClientHandle, const char* destinationFileName, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK getDataCallback, IOTHUB_CLIENT_FILE_UPLOAD_GET_DATA_CALLBACK_EX getDataCallbackEx, void* context)
AzureIoTClient 88:248736be106e 2091 {
AzureIoTClient 88:248736be106e 2092 IOTHUB_CLIENT_RESULT result;
AzureIoTClient 88:248736be106e 2093
AzureIoTClient 88:248736be106e 2094 /*Codes_SRS_IOTHUBCLIENT_99_072: [ If `iotHubClientHandle` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 88:248736be106e 2095 /*Codes_SRS_IOTHUBCLIENT_99_073: [ If `destinationFileName` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 88:248736be106e 2096 /*Codes_SRS_IOTHUBCLIENT_99_074: [ If `getDataCallback` is `NULL` then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall fail and return `IOTHUB_CLIENT_INVALID_ARG`. ]*/
AzureIoTClient 88:248736be106e 2097 if (
AzureIoTClient 88:248736be106e 2098 (iotHubClientHandle == NULL) ||
AzureIoTClient 88:248736be106e 2099 (destinationFileName == NULL) ||
AzureIoTClient 88:248736be106e 2100 ((getDataCallback == NULL) && (getDataCallbackEx == NULL))
AzureIoTClient 88:248736be106e 2101 )
AzureIoTClient 88:248736be106e 2102 {
AzureIoTClient 88:248736be106e 2103 LogError("invalid parameters iotHubClientHandle = %p , destinationFileName = %p, getDataCallback = %p, getDataCallbackEx = %p",
AzureIoTClient 88:248736be106e 2104 iotHubClientHandle,
AzureIoTClient 88:248736be106e 2105 destinationFileName,
AzureIoTClient 88:248736be106e 2106 getDataCallback,
AzureIoTClient 88:248736be106e 2107 getDataCallbackEx
AzureIoTClient 88:248736be106e 2108 );
AzureIoTClient 88:248736be106e 2109 result = IOTHUB_CLIENT_INVALID_ARG;
AzureIoTClient 88:248736be106e 2110 }
AzureIoTClient 88:248736be106e 2111 else
AzureIoTClient 88:248736be106e 2112 {
AzureIoTClient 88:248736be106e 2113 /*Codes_SRS_IOTHUBCLIENT_99_075: [ `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall copy the `destinationFileName`, `getDataCallback`, `context` and `iotHubClientHandle` into a structure. ]*/
AzureIoTClient 88:248736be106e 2114 UPLOADTOBLOB_THREAD_INFO *threadInfo = allocateUploadToBlob(destinationFileName, iotHubClientHandle, context);
AzureIoTClient 88:248736be106e 2115 if (threadInfo == NULL)
AzureIoTClient 88:248736be106e 2116 {
AzureIoTClient 88:248736be106e 2117 /*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 88:248736be106e 2118 LogError("unable to create upload thread info");
AzureIoTClient 88:248736be106e 2119 result = IOTHUB_CLIENT_ERROR;
AzureIoTClient 88:248736be106e 2120 }
AzureIoTClient 88:248736be106e 2121 else
AzureIoTClient 88:248736be106e 2122 {
AzureIoTClient 88:248736be106e 2123 /*Codes_SRS_IOTHUBCLIENT_99_075: [ `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall copy the `destinationFileName`, `getDataCallback`, `context` and `iotHubClientHandle` into a structure. ]*/
AzureIoTClient 88:248736be106e 2124 threadInfo->uploadBlobMultiblockSavedData.getDataCallback = getDataCallback;
AzureIoTClient 88:248736be106e 2125 threadInfo->uploadBlobMultiblockSavedData.getDataCallbackEx = getDataCallbackEx;
AzureIoTClient 88:248736be106e 2126
AzureIoTClient 88:248736be106e 2127 if ((result = StartWorkerThreadIfNeeded(iotHubClientHandle)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 2128 {
AzureIoTClient 88:248736be106e 2129 /*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 88:248736be106e 2130 LogError("Could not start worker thread");
AzureIoTClient 88:248736be106e 2131 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 2132 }
AzureIoTClient 88:248736be106e 2133 else if ((result = startUploadToBlobWorkerThread(threadInfo, uploadMultipleBlock_thread)) != IOTHUB_CLIENT_OK)
AzureIoTClient 88:248736be106e 2134 {
AzureIoTClient 88:248736be106e 2135 /*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 88:248736be106e 2136 LogError("unable to start upload thread");
AzureIoTClient 88:248736be106e 2137 freeUploadToBlobThreadInfo(threadInfo);
AzureIoTClient 88:248736be106e 2138 }
AzureIoTClient 88:248736be106e 2139 else
AzureIoTClient 88:248736be106e 2140 {
AzureIoTClient 88:248736be106e 2141 /*Codes_SRS_IOTHUBCLIENT_99_077: [ If copying to the structure and spawning the thread succeeds, then `IoTHubClient_UploadMultipleBlocksToBlobAsync(Ex)` shall return `IOTHUB_CLIENT_OK`. ]*/
AzureIoTClient 88:248736be106e 2142 result = IOTHUB_CLIENT_OK;
AzureIoTClient 88:248736be106e 2143 }
AzureIoTClient 88:248736be106e 2144 }
AzureIoTClient 88:248736be106e 2145 }
AzureIoTClient 88:248736be106e 2146 return result;
AzureIoTClient 88:248736be106e 2147 }
AzureIoTClient 88:248736be106e 2148
AzureIoTClient 88:248736be106e 2149 #endif /*DONT_USE_UPLOADTOBLOB*/