WIP. send a large constant string twice a second, in order to test out the transport with something indicative of our required load.

Dependencies:   FXOS8700CQ NTPClient azure_umqtt_c iothub_mqtt_transport mbed-rtos mbed wolfSSL Socket lwip-eth lwip-sys lwip

Fork of FXOS8700CQ_To_Azure_IoT by Mark Radbourne

Committer:
markrad
Date:
Thu Dec 08 00:11:40 2016 +0000
Revision:
3:c0556ff7b8e3
Hack the code to get restart working

Who changed what in which revision?

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