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:
Wed Nov 16 21:37:53 2016 -0800
Revision:
53:1e5a1ca1f274
Parent:
45:54c11b1b1407
Child:
57:4524910c6445
1.0.10

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 37:18310e4d888d 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 37:18310e4d888d 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 37:18310e4d888d 3
Azure.IoT Build 37:18310e4d888d 4 #include <stdlib.h>
Azure.IoT Build 37:18310e4d888d 5 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 37:18310e4d888d 6 #include <crtdbg.h>
Azure.IoT Build 37:18310e4d888d 7 #endif
Azure.IoT Build 37:18310e4d888d 8
Azure.IoT Build 38:a05929a75111 9 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 37:18310e4d888d 10
Azure.IoT Build 37:18310e4d888d 11 #include <stdlib.h>
Azure.IoT Build 37:18310e4d888d 12 #include <signal.h>
Azure.IoT Build 37:18310e4d888d 13 #include <stddef.h>
Azure.IoT Build 38:a05929a75111 14 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 37:18310e4d888d 15 #include "iothubtransport.h"
Azure.IoT Build 37:18310e4d888d 16 #include "iothub_client.h"
Azure.IoT Build 37:18310e4d888d 17 #include "iothub_client_private.h"
Azure.IoT Build 38:a05929a75111 18 #include "azure_c_shared_utility/threadapi.h"
Azure.IoT Build 38:a05929a75111 19 #include "azure_c_shared_utility/lock.h"
Azure.IoT Build 45:54c11b1b1407 20 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 38:a05929a75111 21 #include "azure_c_shared_utility/vector.h"
Azure.IoT Build 37:18310e4d888d 22
Azure.IoT Build 37:18310e4d888d 23 typedef struct TRANSPORT_HANDLE_DATA_TAG
Azure.IoT Build 37:18310e4d888d 24 {
Azure.IoT Build 37:18310e4d888d 25 TRANSPORT_LL_HANDLE transportLLHandle;
Azure.IoT Build 37:18310e4d888d 26 THREAD_HANDLE workerThreadHandle;
Azure.IoT Build 37:18310e4d888d 27 LOCK_HANDLE lockHandle;
Azure.IoT Build 37:18310e4d888d 28 sig_atomic_t stopThread;
Azure.IoT Build 37:18310e4d888d 29 TRANSPORT_PROVIDER_FIELDS;
Azure.IoT Build 37:18310e4d888d 30 VECTOR_HANDLE clients;
Azure.IoT Build 37:18310e4d888d 31 } TRANSPORT_HANDLE_DATA;
Azure.IoT Build 37:18310e4d888d 32
Azure.IoT Build 37:18310e4d888d 33 /* Used for Unit test */
Azure.IoT Build 37:18310e4d888d 34 const size_t IoTHubTransport_ThreadTerminationOffset = offsetof(TRANSPORT_HANDLE_DATA, stopThread);
Azure.IoT Build 37:18310e4d888d 35
Azure.IoT Build 37:18310e4d888d 36 TRANSPORT_HANDLE IoTHubTransport_Create(IOTHUB_CLIENT_TRANSPORT_PROVIDER protocol, const char* iotHubName, const char* iotHubSuffix)
Azure.IoT Build 37:18310e4d888d 37 {
AzureIoTClient 53:1e5a1ca1f274 38 TRANSPORT_HANDLE_DATA *result;
Azure.IoT Build 37:18310e4d888d 39
Azure.IoT Build 37:18310e4d888d 40 if (protocol == NULL || iotHubName == NULL || iotHubSuffix == NULL)
Azure.IoT Build 37:18310e4d888d 41 {
Azure.IoT Build 37:18310e4d888d 42 /*Codes_SRS_IOTHUBTRANSPORT_17_002: [ If protocol is NULL, this function shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 43 /*Codes_SRS_IOTHUBTRANSPORT_17_003: [ If iotHubName is NULL, this function shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 44 /*Codes_SRS_IOTHUBTRANSPORT_17_004: [ If iotHubSuffix is NULL, this function shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 45 LogError("Invalid NULL argument, protocol [%p], name [%p], suffix [%p].", protocol, iotHubName, iotHubSuffix);
Azure.IoT Build 37:18310e4d888d 46 result = NULL;
Azure.IoT Build 37:18310e4d888d 47 }
Azure.IoT Build 37:18310e4d888d 48 else
Azure.IoT Build 37:18310e4d888d 49 {
Azure.IoT Build 37:18310e4d888d 50 /*Codes_SRS_IOTHUBTRANSPORT_17_032: [ IoTHubTransport_Create shall allocate memory for the transport data. ]*/
Azure.IoT Build 37:18310e4d888d 51 result = (TRANSPORT_HANDLE_DATA*)malloc(sizeof(TRANSPORT_HANDLE_DATA));
Azure.IoT Build 37:18310e4d888d 52 if (result == NULL)
Azure.IoT Build 37:18310e4d888d 53 {
Azure.IoT Build 37:18310e4d888d 54 /*Codes_SRS_IOTHUBTRANSPORT_17_040: [ If memory allocation fails, IoTHubTransport_Create shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 55 LogError("Transport handle was not allocated.");
Azure.IoT Build 37:18310e4d888d 56 }
Azure.IoT Build 37:18310e4d888d 57 else
Azure.IoT Build 37:18310e4d888d 58 {
Azure.IoT Build 37:18310e4d888d 59 TRANSPORT_PROVIDER * transportProtocol = (TRANSPORT_PROVIDER*)(protocol());
Azure.IoT Build 37:18310e4d888d 60 IOTHUB_CLIENT_CONFIG upperConfig;
Azure.IoT Build 37:18310e4d888d 61 upperConfig.deviceId = NULL;
Azure.IoT Build 37:18310e4d888d 62 upperConfig.deviceKey = NULL;
Azure.IoT Build 37:18310e4d888d 63 upperConfig.iotHubName = iotHubName;
Azure.IoT Build 37:18310e4d888d 64 upperConfig.iotHubSuffix = iotHubSuffix;
Azure.IoT Build 37:18310e4d888d 65 upperConfig.protocol = protocol;
Azure.IoT Build 37:18310e4d888d 66 upperConfig.protocolGatewayHostName = NULL;
Azure.IoT Build 37:18310e4d888d 67
Azure.IoT Build 37:18310e4d888d 68 IOTHUBTRANSPORT_CONFIG transportLLConfig;
Azure.IoT Build 37:18310e4d888d 69 transportLLConfig.upperConfig = &upperConfig;
Azure.IoT Build 37:18310e4d888d 70 transportLLConfig.waitingToSend = NULL;
Azure.IoT Build 37:18310e4d888d 71
Azure.IoT Build 37:18310e4d888d 72 /*Codes_SRS_IOTHUBTRANSPORT_17_005: [ IoTHubTransport_Create shall create the lower layer transport by calling the protocol's IoTHubTransport_Create function. ]*/
Azure.IoT Build 37:18310e4d888d 73 result->transportLLHandle = transportProtocol->IoTHubTransport_Create(&transportLLConfig);
Azure.IoT Build 37:18310e4d888d 74 if (result->transportLLHandle == NULL)
Azure.IoT Build 37:18310e4d888d 75 {
Azure.IoT Build 37:18310e4d888d 76 /*Codes_SRS_IOTHUBTRANSPORT_17_006: [ If the creation of the transport fails, IoTHubTransport_Create shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 77 LogError("Lower Layer transport not created.");
Azure.IoT Build 37:18310e4d888d 78 free(result);
Azure.IoT Build 37:18310e4d888d 79 result = NULL;
Azure.IoT Build 37:18310e4d888d 80 }
Azure.IoT Build 37:18310e4d888d 81 else
Azure.IoT Build 37:18310e4d888d 82 {
Azure.IoT Build 37:18310e4d888d 83 /*Codes_SRS_IOTHUBTRANSPORT_17_007: [ IoTHubTransport_Create shall create the transport lock by Calling Lock_Init. ]*/
Azure.IoT Build 37:18310e4d888d 84 result->lockHandle = Lock_Init();
Azure.IoT Build 37:18310e4d888d 85 if (result->lockHandle == NULL)
Azure.IoT Build 37:18310e4d888d 86 {
Azure.IoT Build 37:18310e4d888d 87 /*Codes_SRS_IOTHUBTRANSPORT_17_008: [ If the lock creation fails, IoTHubTransport_Create shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 88 LogError("transport Lock not created.");
Azure.IoT Build 37:18310e4d888d 89 transportProtocol->IoTHubTransport_Destroy(result->transportLLHandle);
Azure.IoT Build 37:18310e4d888d 90 free(result);
Azure.IoT Build 37:18310e4d888d 91 result = NULL;
Azure.IoT Build 37:18310e4d888d 92 }
Azure.IoT Build 37:18310e4d888d 93 else
Azure.IoT Build 37:18310e4d888d 94 {
Azure.IoT Build 37:18310e4d888d 95 /*Codes_SRS_IOTHUBTRANSPORT_17_038: [ IoTHubTransport_Create shall call VECTOR_Create to make a list of IOTHUB_CLIENT_HANDLE using this transport. ]*/
Azure.IoT Build 37:18310e4d888d 96 result->clients = VECTOR_create(sizeof(IOTHUB_CLIENT_HANDLE));
Azure.IoT Build 37:18310e4d888d 97 if (result->clients == NULL)
Azure.IoT Build 37:18310e4d888d 98 {
Azure.IoT Build 37:18310e4d888d 99 /*Codes_SRS_IOTHUBTRANSPORT_17_039: [ If the Vector creation fails, IoTHubTransport_Create shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 100 /*Codes_SRS_IOTHUBTRANSPORT_17_009: [ IoTHubTransport_Create shall clean up any resources it creates if the function does not succeed. ]*/
Azure.IoT Build 37:18310e4d888d 101 LogError("clients list not created.");
Azure.IoT Build 37:18310e4d888d 102 Lock_Deinit(result->lockHandle);
Azure.IoT Build 37:18310e4d888d 103 transportProtocol->IoTHubTransport_Destroy(result->transportLLHandle);
Azure.IoT Build 37:18310e4d888d 104 free(result);
Azure.IoT Build 37:18310e4d888d 105 result = NULL;
Azure.IoT Build 37:18310e4d888d 106 }
Azure.IoT Build 37:18310e4d888d 107 else
Azure.IoT Build 37:18310e4d888d 108 {
Azure.IoT Build 37:18310e4d888d 109 /*Codes_SRS_IOTHUBTRANSPORT_17_001: [ IoTHubTransport_Create shall return a non-NULL handle on success.]*/
Azure.IoT Build 37:18310e4d888d 110 result->stopThread = 1;
Azure.IoT Build 37:18310e4d888d 111 result->workerThreadHandle = NULL; /* create thread when work needs to be done */
AzureIoTClient 43:038d8511e817 112 result->IoTHubTransport_GetHostname = transportProtocol->IoTHubTransport_GetHostname;
Azure.IoT Build 37:18310e4d888d 113 result->IoTHubTransport_SetOption = transportProtocol->IoTHubTransport_SetOption;
Azure.IoT Build 37:18310e4d888d 114 result->IoTHubTransport_Create = transportProtocol->IoTHubTransport_Create;
Azure.IoT Build 37:18310e4d888d 115 result->IoTHubTransport_Destroy = transportProtocol->IoTHubTransport_Destroy;
Azure.IoT Build 37:18310e4d888d 116 result->IoTHubTransport_Register = transportProtocol->IoTHubTransport_Register;
Azure.IoT Build 37:18310e4d888d 117 result->IoTHubTransport_Unregister = transportProtocol->IoTHubTransport_Unregister;
Azure.IoT Build 37:18310e4d888d 118 result->IoTHubTransport_Subscribe = transportProtocol->IoTHubTransport_Subscribe;
Azure.IoT Build 37:18310e4d888d 119 result->IoTHubTransport_Unsubscribe = transportProtocol->IoTHubTransport_Unsubscribe;
Azure.IoT Build 37:18310e4d888d 120 result->IoTHubTransport_DoWork = transportProtocol->IoTHubTransport_DoWork;
AzureIoTClient 53:1e5a1ca1f274 121 result->IoTHubTransport_SetRetryPolicy = transportProtocol->IoTHubTransport_SetRetryPolicy;
Azure.IoT Build 37:18310e4d888d 122 result->IoTHubTransport_GetSendStatus = transportProtocol->IoTHubTransport_GetSendStatus;
Azure.IoT Build 37:18310e4d888d 123 }
Azure.IoT Build 37:18310e4d888d 124 }
Azure.IoT Build 37:18310e4d888d 125 }
Azure.IoT Build 37:18310e4d888d 126 }
Azure.IoT Build 37:18310e4d888d 127 }
Azure.IoT Build 37:18310e4d888d 128
Azure.IoT Build 37:18310e4d888d 129 return result;
Azure.IoT Build 37:18310e4d888d 130 }
Azure.IoT Build 37:18310e4d888d 131
Azure.IoT Build 37:18310e4d888d 132 static int transport_worker_thread(void* threadArgument)
Azure.IoT Build 37:18310e4d888d 133 {
Azure.IoT Build 37:18310e4d888d 134 TRANSPORT_HANDLE_DATA* transportData = (TRANSPORT_HANDLE_DATA*)threadArgument;
Azure.IoT Build 37:18310e4d888d 135
Azure.IoT Build 37:18310e4d888d 136 while (1)
Azure.IoT Build 37:18310e4d888d 137 {
Azure.IoT Build 37:18310e4d888d 138 /*Codes_SRS_IOTHUBTRANSPORT_17_030: [ All calls to lower layer transport DoWork shall be protected by the lock created in IoTHubTransport_Create. ]*/
Azure.IoT Build 37:18310e4d888d 139 if (Lock(transportData->lockHandle) == LOCK_OK)
Azure.IoT Build 37:18310e4d888d 140 {
Azure.IoT Build 37:18310e4d888d 141 /*Codes_SRS_IOTHUBTRANSPORT_17_031: [ If acquiring the lock fails, lower layer transport DoWork shall not be called. ]*/
Azure.IoT Build 37:18310e4d888d 142 if (transportData->stopThread)
Azure.IoT Build 37:18310e4d888d 143 {
Azure.IoT Build 37:18310e4d888d 144 /*Codes_SRS_IOTHUBTRANSPORT_17_028: [ The thread shall exit when IoTHubTransport_EndWorkerThread has been called for each clientHandle which invoked IoTHubTransport_StartWorkerThread. ]*/
Azure.IoT Build 37:18310e4d888d 145 (void)Unlock(transportData->lockHandle);
Azure.IoT Build 37:18310e4d888d 146 break;
Azure.IoT Build 37:18310e4d888d 147 }
Azure.IoT Build 37:18310e4d888d 148 else
Azure.IoT Build 37:18310e4d888d 149 {
Azure.IoT Build 37:18310e4d888d 150 (transportData->IoTHubTransport_DoWork)(transportData->transportLLHandle, NULL);
Azure.IoT Build 37:18310e4d888d 151 (void)Unlock(transportData->lockHandle);
Azure.IoT Build 37:18310e4d888d 152 }
Azure.IoT Build 37:18310e4d888d 153 }
Azure.IoT Build 37:18310e4d888d 154 /*Codes_SRS_IOTHUBTRANSPORT_17_029: [ The thread shall call lower layer transport DoWork every 1 ms. ]*/
Azure.IoT Build 37:18310e4d888d 155 ThreadAPI_Sleep(1);
Azure.IoT Build 37:18310e4d888d 156 }
Azure.IoT Build 37:18310e4d888d 157
Azure.IoT Build 37:18310e4d888d 158 return 0;
Azure.IoT Build 37:18310e4d888d 159 }
Azure.IoT Build 37:18310e4d888d 160
Azure.IoT Build 37:18310e4d888d 161 static bool find_by_handle(const void* element, const void* value)
Azure.IoT Build 37:18310e4d888d 162 {
Azure.IoT Build 37:18310e4d888d 163 /* data stored at element is device handle */
Azure.IoT Build 37:18310e4d888d 164 const IOTHUB_CLIENT_HANDLE * guess = (const IOTHUB_CLIENT_HANDLE *)element;
Azure.IoT Build 37:18310e4d888d 165 const IOTHUB_CLIENT_HANDLE match = (const IOTHUB_CLIENT_HANDLE)value;
Azure.IoT Build 37:18310e4d888d 166 return (*guess == match);
Azure.IoT Build 37:18310e4d888d 167 }
Azure.IoT Build 37:18310e4d888d 168
Azure.IoT Build 37:18310e4d888d 169 static IOTHUB_CLIENT_RESULT start_worker_if_needed(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_HANDLE clientHandle)
Azure.IoT Build 37:18310e4d888d 170 {
Azure.IoT Build 37:18310e4d888d 171 IOTHUB_CLIENT_RESULT result;
Azure.IoT Build 37:18310e4d888d 172 if (transportData->workerThreadHandle == NULL)
Azure.IoT Build 37:18310e4d888d 173 {
Azure.IoT Build 37:18310e4d888d 174 /*Codes_SRS_IOTHUBTRANSPORT_17_018: [ If the worker thread does not exist, IoTHubTransport_StartWorkerThread shall start the thread using ThreadAPI_Create. ]*/
Azure.IoT Build 37:18310e4d888d 175 transportData->stopThread = 0;
Azure.IoT Build 37:18310e4d888d 176 if (ThreadAPI_Create(&transportData->workerThreadHandle, transport_worker_thread, transportData) != THREADAPI_OK)
Azure.IoT Build 37:18310e4d888d 177 {
Azure.IoT Build 37:18310e4d888d 178 transportData->workerThreadHandle = NULL;
Azure.IoT Build 37:18310e4d888d 179 }
Azure.IoT Build 37:18310e4d888d 180 }
Azure.IoT Build 37:18310e4d888d 181 if (transportData->workerThreadHandle != NULL)
Azure.IoT Build 37:18310e4d888d 182 {
Azure.IoT Build 37:18310e4d888d 183 /*Codes_SRS_IOTHUBTRANSPORT_17_020: [ IoTHubTransport_StartWorkerThread shall search for IoTHubClient clientHandle in the list of IoTHubClient handles. ]*/
Azure.IoT Build 37:18310e4d888d 184 bool addToList = ((VECTOR_size(transportData->clients) == 0) || (VECTOR_find_if(transportData->clients, find_by_handle, clientHandle) == NULL));
Azure.IoT Build 37:18310e4d888d 185 if (addToList)
Azure.IoT Build 37:18310e4d888d 186 {
Azure.IoT Build 37:18310e4d888d 187 /*Codes_SRS_IOTHUBTRANSPORT_17_021: [ If handle is not found, then clientHandle shall be added to the list. ]*/
Azure.IoT Build 37:18310e4d888d 188 if (VECTOR_push_back(transportData->clients, &clientHandle, 1) != 0)
Azure.IoT Build 37:18310e4d888d 189 {
Azure.IoT Build 37:18310e4d888d 190 /*Codes_SRS_IOTHUBTRANSPORT_17_042: [ If Adding to the client list fails, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_ERROR. ]*/
Azure.IoT Build 37:18310e4d888d 191 result = IOTHUB_CLIENT_ERROR;
Azure.IoT Build 37:18310e4d888d 192 }
Azure.IoT Build 37:18310e4d888d 193 else
Azure.IoT Build 37:18310e4d888d 194 {
Azure.IoT Build 37:18310e4d888d 195 result = IOTHUB_CLIENT_OK;
Azure.IoT Build 37:18310e4d888d 196 }
Azure.IoT Build 37:18310e4d888d 197 }
Azure.IoT Build 37:18310e4d888d 198 else
Azure.IoT Build 37:18310e4d888d 199 {
Azure.IoT Build 37:18310e4d888d 200 result = IOTHUB_CLIENT_OK;
Azure.IoT Build 37:18310e4d888d 201 }
Azure.IoT Build 37:18310e4d888d 202 }
Azure.IoT Build 37:18310e4d888d 203 else
Azure.IoT Build 37:18310e4d888d 204 {
Azure.IoT Build 37:18310e4d888d 205 result = IOTHUB_CLIENT_ERROR;
Azure.IoT Build 37:18310e4d888d 206 }
Azure.IoT Build 37:18310e4d888d 207 return result;
Azure.IoT Build 37:18310e4d888d 208 }
Azure.IoT Build 37:18310e4d888d 209
Azure.IoT Build 37:18310e4d888d 210 static void stop_worker_thread(TRANSPORT_HANDLE_DATA * transportData)
Azure.IoT Build 37:18310e4d888d 211 {
Azure.IoT Build 37:18310e4d888d 212 /*Codes_SRS_IOTHUBTRANSPORT_17_043: [** IoTHubTransport_SignalEndWorkerThread shall signal the worker thread to end.*/
Azure.IoT Build 37:18310e4d888d 213 transportData->stopThread = 1;
Azure.IoT Build 37:18310e4d888d 214 }
Azure.IoT Build 37:18310e4d888d 215
Azure.IoT Build 37:18310e4d888d 216 static void wait_worker_thread(TRANSPORT_HANDLE_DATA * transportData)
Azure.IoT Build 37:18310e4d888d 217 {
Azure.IoT Build 37:18310e4d888d 218 if (transportData->workerThreadHandle != NULL)
Azure.IoT Build 37:18310e4d888d 219 {
Azure.IoT Build 37:18310e4d888d 220 int res;
Azure.IoT Build 37:18310e4d888d 221 /*Codes_SRS_IOTHUBTRANSPORT_17_027: [ If handle list is empty, IoTHubTransport_EndWorkerThread shall be joined. ]*/
Azure.IoT Build 37:18310e4d888d 222 if (ThreadAPI_Join(transportData->workerThreadHandle, &res) != THREADAPI_OK)
Azure.IoT Build 37:18310e4d888d 223 {
Azure.IoT Build 37:18310e4d888d 224 LogError("ThreadAPI_Join failed");
Azure.IoT Build 37:18310e4d888d 225 }
Azure.IoT Build 37:18310e4d888d 226 else
Azure.IoT Build 37:18310e4d888d 227 {
Azure.IoT Build 37:18310e4d888d 228 transportData->workerThreadHandle = NULL;
Azure.IoT Build 37:18310e4d888d 229 }
Azure.IoT Build 37:18310e4d888d 230 }
Azure.IoT Build 37:18310e4d888d 231 }
Azure.IoT Build 37:18310e4d888d 232
Azure.IoT Build 37:18310e4d888d 233 static bool signal_end_worker_thread(TRANSPORT_HANDLE_DATA * transportData, IOTHUB_CLIENT_HANDLE clientHandle)
Azure.IoT Build 37:18310e4d888d 234 {
Azure.IoT Build 37:18310e4d888d 235 bool okToJoin;
Azure.IoT Build 37:18310e4d888d 236 void* element = VECTOR_find_if(transportData->clients, find_by_handle, clientHandle);
Azure.IoT Build 37:18310e4d888d 237 if (element != NULL)
Azure.IoT Build 37:18310e4d888d 238 {
Azure.IoT Build 37:18310e4d888d 239 /*Codes_SRS_IOTHUBTRANSPORT_17_026: [ IoTHubTransport_EndWorkerThread shall remove clientHandlehandle from handle list. ]*/
Azure.IoT Build 37:18310e4d888d 240 VECTOR_erase(transportData->clients, element, 1);
Azure.IoT Build 37:18310e4d888d 241 }
Azure.IoT Build 37:18310e4d888d 242 /*Codes_SRS_IOTHUBTRANSPORT_17_025: [ If the worker thread does not exist, then IoTHubTransport_EndWorkerThread shall return. ]*/
Azure.IoT Build 37:18310e4d888d 243 if (transportData->workerThreadHandle != NULL)
Azure.IoT Build 37:18310e4d888d 244 {
Azure.IoT Build 37:18310e4d888d 245 if (VECTOR_size(transportData->clients) == 0)
Azure.IoT Build 37:18310e4d888d 246 {
Azure.IoT Build 37:18310e4d888d 247 stop_worker_thread(transportData);
Azure.IoT Build 37:18310e4d888d 248 okToJoin = true;
Azure.IoT Build 37:18310e4d888d 249 }
Azure.IoT Build 37:18310e4d888d 250 else
Azure.IoT Build 37:18310e4d888d 251 {
Azure.IoT Build 37:18310e4d888d 252 okToJoin = false;
Azure.IoT Build 37:18310e4d888d 253 }
Azure.IoT Build 37:18310e4d888d 254 }
Azure.IoT Build 37:18310e4d888d 255 else
Azure.IoT Build 37:18310e4d888d 256 {
Azure.IoT Build 37:18310e4d888d 257 okToJoin = false;
Azure.IoT Build 37:18310e4d888d 258 }
Azure.IoT Build 37:18310e4d888d 259 return okToJoin;
Azure.IoT Build 37:18310e4d888d 260 }
Azure.IoT Build 37:18310e4d888d 261
Azure.IoT Build 38:a05929a75111 262 void IoTHubTransport_Destroy(TRANSPORT_HANDLE transportHandle)
Azure.IoT Build 37:18310e4d888d 263 {
Azure.IoT Build 38:a05929a75111 264 /*Codes_SRS_IOTHUBTRANSPORT_17_011: [ IoTHubTransport_Destroy shall do nothing if transportHandle is NULL. ]*/
Azure.IoT Build 38:a05929a75111 265 if (transportHandle != NULL)
Azure.IoT Build 37:18310e4d888d 266 {
Azure.IoT Build 38:a05929a75111 267 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 268 /*Codes_SRS_IOTHUBTRANSPORT_17_033: [ IoTHubTransport_Destroy shall lock the transport lock. ]*/
Azure.IoT Build 37:18310e4d888d 269 if (Lock(transportData->lockHandle) != LOCK_OK)
Azure.IoT Build 37:18310e4d888d 270 {
Azure.IoT Build 37:18310e4d888d 271 LogError("Unable to lock - will still attempt to end thread without thread safety");
Azure.IoT Build 37:18310e4d888d 272 stop_worker_thread(transportData);
Azure.IoT Build 37:18310e4d888d 273 }
Azure.IoT Build 37:18310e4d888d 274 else
Azure.IoT Build 37:18310e4d888d 275 {
Azure.IoT Build 37:18310e4d888d 276 stop_worker_thread(transportData);
Azure.IoT Build 37:18310e4d888d 277 (void)Unlock(transportData->lockHandle);
Azure.IoT Build 37:18310e4d888d 278 }
Azure.IoT Build 37:18310e4d888d 279 wait_worker_thread(transportData);
Azure.IoT Build 37:18310e4d888d 280 /*Codes_SRS_IOTHUBTRANSPORT_17_010: [ IoTHubTransport_Destroy shall free all resources. ]*/
Azure.IoT Build 37:18310e4d888d 281 Lock_Deinit(transportData->lockHandle);
Azure.IoT Build 37:18310e4d888d 282 (transportData->IoTHubTransport_Destroy)(transportData->transportLLHandle);
Azure.IoT Build 37:18310e4d888d 283 VECTOR_destroy(transportData->clients);
Azure.IoT Build 38:a05929a75111 284 free(transportHandle);
Azure.IoT Build 37:18310e4d888d 285 }
Azure.IoT Build 37:18310e4d888d 286 }
Azure.IoT Build 37:18310e4d888d 287
Azure.IoT Build 38:a05929a75111 288 LOCK_HANDLE IoTHubTransport_GetLock(TRANSPORT_HANDLE transportHandle)
Azure.IoT Build 37:18310e4d888d 289 {
Azure.IoT Build 37:18310e4d888d 290 LOCK_HANDLE lock;
Azure.IoT Build 38:a05929a75111 291 if (transportHandle == NULL)
Azure.IoT Build 37:18310e4d888d 292 {
Azure.IoT Build 38:a05929a75111 293 /*Codes_SRS_IOTHUBTRANSPORT_17_013: [ If transportHandle is NULL, IoTHubTransport_GetLock shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 294 lock = NULL;
Azure.IoT Build 37:18310e4d888d 295 }
Azure.IoT Build 37:18310e4d888d 296 else
Azure.IoT Build 37:18310e4d888d 297 {
Azure.IoT Build 37:18310e4d888d 298 /*Codes_SRS_IOTHUBTRANSPORT_17_012: [ IoTHubTransport_GetLock shall return a handle to the transport lock. ]*/
Azure.IoT Build 38:a05929a75111 299 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 300 lock = transportData->lockHandle;
Azure.IoT Build 37:18310e4d888d 301 }
Azure.IoT Build 37:18310e4d888d 302 return lock;
Azure.IoT Build 37:18310e4d888d 303 }
Azure.IoT Build 37:18310e4d888d 304
Azure.IoT Build 38:a05929a75111 305 TRANSPORT_LL_HANDLE IoTHubTransport_GetLLTransport(TRANSPORT_HANDLE transportHandle)
Azure.IoT Build 37:18310e4d888d 306 {
Azure.IoT Build 37:18310e4d888d 307 TRANSPORT_LL_HANDLE llTransport;
Azure.IoT Build 38:a05929a75111 308 if (transportHandle == NULL)
Azure.IoT Build 37:18310e4d888d 309 {
Azure.IoT Build 38:a05929a75111 310 /*Codes_SRS_IOTHUBTRANSPORT_17_015: [ If transportHandle is NULL, IoTHubTransport_GetLLTransport shall return NULL. ]*/
Azure.IoT Build 37:18310e4d888d 311 llTransport = NULL;
Azure.IoT Build 37:18310e4d888d 312 }
Azure.IoT Build 37:18310e4d888d 313 else
Azure.IoT Build 37:18310e4d888d 314 {
Azure.IoT Build 37:18310e4d888d 315 /*Codes_SRS_IOTHUBTRANSPORT_17_014: [ IoTHubTransport_GetLLTransport shall return a handle to the lower layer transport. ]*/
Azure.IoT Build 38:a05929a75111 316 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 317 llTransport = transportData->transportLLHandle;
Azure.IoT Build 37:18310e4d888d 318 }
Azure.IoT Build 37:18310e4d888d 319 return llTransport;
Azure.IoT Build 37:18310e4d888d 320 }
Azure.IoT Build 37:18310e4d888d 321
Azure.IoT Build 38:a05929a75111 322 IOTHUB_CLIENT_RESULT IoTHubTransport_StartWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_HANDLE clientHandle)
Azure.IoT Build 37:18310e4d888d 323 {
Azure.IoT Build 37:18310e4d888d 324 IOTHUB_CLIENT_RESULT result;
Azure.IoT Build 38:a05929a75111 325 if (transportHandle == NULL || clientHandle == NULL)
Azure.IoT Build 37:18310e4d888d 326 {
Azure.IoT Build 38:a05929a75111 327 /*Codes_SRS_IOTHUBTRANSPORT_17_016: [ If transportHandle is NULL, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
Azure.IoT Build 37:18310e4d888d 328 /*Codes_SRS_IOTHUBTRANSPORT_17_017: [ If clientHandle is NULL, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_INVALID_ARG. ]*/
Azure.IoT Build 37:18310e4d888d 329 result = IOTHUB_CLIENT_INVALID_ARG;
Azure.IoT Build 37:18310e4d888d 330 }
Azure.IoT Build 37:18310e4d888d 331 else
Azure.IoT Build 37:18310e4d888d 332 {
Azure.IoT Build 38:a05929a75111 333 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 334
Azure.IoT Build 37:18310e4d888d 335 if ((result = start_worker_if_needed(transportData, clientHandle)) != IOTHUB_CLIENT_OK)
Azure.IoT Build 37:18310e4d888d 336 {
Azure.IoT Build 37:18310e4d888d 337 /*Codes_SRS_IOTHUBTRANSPORT_17_019: [ If thread creation fails, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_ERROR. */
Azure.IoT Build 37:18310e4d888d 338 LogError("Unable to start thread safely");
Azure.IoT Build 37:18310e4d888d 339 }
Azure.IoT Build 37:18310e4d888d 340 else
Azure.IoT Build 37:18310e4d888d 341 {
Azure.IoT Build 37:18310e4d888d 342 /*Codes_SRS_IOTHUBTRANSPORT_17_022: [ Upon success, IoTHubTransport_StartWorkerThread shall return IOTHUB_CLIENT_OK. ]*/
Azure.IoT Build 37:18310e4d888d 343 result = IOTHUB_CLIENT_OK;
Azure.IoT Build 37:18310e4d888d 344 }
Azure.IoT Build 37:18310e4d888d 345 }
Azure.IoT Build 37:18310e4d888d 346 return result;
Azure.IoT Build 37:18310e4d888d 347 }
Azure.IoT Build 37:18310e4d888d 348
Azure.IoT Build 38:a05929a75111 349 bool IoTHubTransport_SignalEndWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_HANDLE clientHandle)
Azure.IoT Build 37:18310e4d888d 350 {
Azure.IoT Build 37:18310e4d888d 351 bool okToJoin;
Azure.IoT Build 38:a05929a75111 352 /*Codes_SRS_IOTHUBTRANSPORT_17_023: [ If transportHandle is NULL, IoTHubTransport_EndWorkerThread shall return. ]*/
Azure.IoT Build 37:18310e4d888d 353 /*Codes_SRS_IOTHUBTRANSPORT_17_024: [ If clientHandle is NULL, IoTHubTransport_EndWorkerThread shall return. ]*/
Azure.IoT Build 38:a05929a75111 354 if (!(transportHandle == NULL || clientHandle == NULL))
Azure.IoT Build 37:18310e4d888d 355 {
Azure.IoT Build 38:a05929a75111 356 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 357 okToJoin = signal_end_worker_thread(transportData, clientHandle);
Azure.IoT Build 37:18310e4d888d 358 }
Azure.IoT Build 37:18310e4d888d 359 else
Azure.IoT Build 37:18310e4d888d 360 {
Azure.IoT Build 37:18310e4d888d 361 okToJoin = false;
Azure.IoT Build 37:18310e4d888d 362 }
Azure.IoT Build 37:18310e4d888d 363 return okToJoin;
Azure.IoT Build 37:18310e4d888d 364 }
Azure.IoT Build 37:18310e4d888d 365
Azure.IoT Build 38:a05929a75111 366 void IoTHubTransport_JoinWorkerThread(TRANSPORT_HANDLE transportHandle, IOTHUB_CLIENT_HANDLE clientHandle)
Azure.IoT Build 37:18310e4d888d 367 {
Azure.IoT Build 38:a05929a75111 368 /*Codes_SRS_IOTHUBTRANSPORT_17_044: [ If transportHandle is NULL, IoTHubTransport_JoinWorkerThread shall do nothing. ]*/
Azure.IoT Build 37:18310e4d888d 369 /*Codes_SRS_IOTHUBTRANSPORT_17_045: [ If clientHandle is NULL, IoTHubTransport_JoinWorkerThread shall do nothing. ]*/
Azure.IoT Build 38:a05929a75111 370 if (!(transportHandle == NULL || clientHandle == NULL))
Azure.IoT Build 37:18310e4d888d 371 {
Azure.IoT Build 38:a05929a75111 372 TRANSPORT_HANDLE_DATA * transportData = (TRANSPORT_HANDLE_DATA*)transportHandle;
Azure.IoT Build 37:18310e4d888d 373 /*Codes_SRS_IOTHUBTRANSPORT_17_027: [ The worker thread shall be joined. ]*/
Azure.IoT Build 37:18310e4d888d 374 wait_worker_thread(transportData);
Azure.IoT Build 37:18310e4d888d 375 }
Azure.IoT Build 37:18310e4d888d 376 }