Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed
Fork of iothub_client_sample_amqp by
xio.c
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 #include <stdlib.h> 00005 #ifdef _CRTDBG_MAP_ALLOC 00006 #include <crtdbg.h> 00007 #endif 00008 #include <stddef.h> 00009 #include "azure_c_shared_utility/gballoc.h" 00010 #include "azure_c_shared_utility/xio.h" 00011 00012 static const char* CONCRETE_OPTIONS = "concreteOptions"; 00013 00014 typedef struct XIO_INSTANCE_TAG 00015 { 00016 const IO_INTERFACE_DESCRIPTION* io_interface_description; 00017 XIO_HANDLE concrete_xio_handle; 00018 } XIO_INSTANCE; 00019 00020 XIO_HANDLE xio_create(const IO_INTERFACE_DESCRIPTION* io_interface_description, const void* xio_create_parameters) 00021 { 00022 XIO_INSTANCE* xio_instance; 00023 /* Codes_SRS_XIO_01_003: [If the argument io_interface_description is NULL, xio_create shall return NULL.] */ 00024 if ((io_interface_description == NULL) || 00025 /* Codes_SRS_XIO_01_004: [If any io_interface_description member is NULL, xio_create shall return NULL.] */ 00026 (io_interface_description->concrete_io_retrieveoptions == NULL) || 00027 (io_interface_description->concrete_io_create == NULL) || 00028 (io_interface_description->concrete_io_destroy == NULL) || 00029 (io_interface_description->concrete_io_open == NULL) || 00030 (io_interface_description->concrete_io_close == NULL) || 00031 (io_interface_description->concrete_io_send == NULL) || 00032 (io_interface_description->concrete_io_dowork == NULL) || 00033 (io_interface_description->concrete_io_setoption == NULL)) 00034 { 00035 xio_instance = NULL; 00036 } 00037 else 00038 { 00039 xio_instance = (XIO_INSTANCE*)malloc(sizeof(XIO_INSTANCE)); 00040 00041 /* Codes_SRS_XIO_01_017: [If allocating the memory needed for the IO interface fails then xio_create shall return NULL.] */ 00042 if (xio_instance != NULL) 00043 { 00044 /* Codes_SRS_XIO_01_001: [xio_create shall return on success a non-NULL handle to a new IO interface.] */ 00045 xio_instance->io_interface_description = io_interface_description; 00046 00047 /* Codes_SRS_XIO_01_002: [In order to instantiate the concrete IO implementation the function concrete_io_create from the io_interface_description shall be called, passing the xio_create_parameters argument.] */ 00048 xio_instance->concrete_xio_handle = xio_instance->io_interface_description->concrete_io_create((void*)xio_create_parameters); 00049 00050 /* Codes_SRS_XIO_01_016: [If the underlying concrete_io_create call fails, xio_create shall return NULL.] */ 00051 if (xio_instance->concrete_xio_handle == NULL) 00052 { 00053 free(xio_instance); 00054 xio_instance = NULL; 00055 } 00056 } 00057 } 00058 return (XIO_HANDLE)xio_instance; 00059 } 00060 00061 void xio_destroy(XIO_HANDLE xio) 00062 { 00063 /* Codes_SRS_XIO_01_007: [If the argument io is NULL, xio_destroy shall do nothing.] */ 00064 if (xio != NULL) 00065 { 00066 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00067 00068 /* Codes_SRS_XIO_01_006: [xio_destroy shall also call the concrete_io_destroy function that is member of the io_interface_description argument passed to xio_create, while passing as argument to concrete_io_destroy the result of the underlying concrete_io_create handle that was called as part of the xio_create call.] */ 00069 xio_instance->io_interface_description->concrete_io_destroy(xio_instance->concrete_xio_handle); 00070 00071 /* Codes_SRS_XIO_01_005: [xio_destroy shall free all resources associated with the IO handle.] */ 00072 free(xio_instance); 00073 } 00074 } 00075 00076 int xio_open(XIO_HANDLE xio, ON_IO_OPEN_COMPLETE on_io_open_complete, void* on_io_open_complete_context, ON_BYTES_RECEIVED on_bytes_received, void* on_bytes_received_context, ON_IO_ERROR on_io_error, void* on_io_error_context) 00077 { 00078 int result; 00079 00080 if (xio == NULL) 00081 { 00082 /* Codes_SRS_XIO_01_021: [If handle is NULL, xio_open shall return a non-zero value.] */ 00083 result = __LINE__; 00084 } 00085 else 00086 { 00087 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00088 00089 /* Codes_SRS_XIO_01_019: [xio_open shall call the specific concrete_xio_open function specified in xio_create, passing callback function and context arguments for three events: open completed, bytes received, and IO error.] */ 00090 if (xio_instance->io_interface_description->concrete_io_open(xio_instance->concrete_xio_handle, on_io_open_complete, on_io_open_complete_context, on_bytes_received, on_bytes_received_context, on_io_error, on_io_error_context) != 0) 00091 { 00092 /* Codes_SRS_XIO_01_022: [If the underlying concrete_io_open fails, xio_open shall return a non-zero value.] */ 00093 result = __LINE__; 00094 } 00095 else 00096 { 00097 /* Codes_SRS_XIO_01_020: [On success, xio_open shall return 0.] */ 00098 result = 0; 00099 } 00100 } 00101 00102 return result; 00103 } 00104 00105 int xio_close(XIO_HANDLE xio, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context) 00106 { 00107 int result; 00108 00109 if (xio == NULL) 00110 { 00111 /* Codes_SRS_XIO_01_025: [If handle is NULL, xio_close shall return a non-zero value.] */ 00112 result = __LINE__; 00113 } 00114 else 00115 { 00116 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00117 00118 /* Codes_SRS_XIO_01_023: [xio_close shall call the specific concrete_io_close function specified in xio_create.] */ 00119 if (xio_instance->io_interface_description->concrete_io_close(xio_instance->concrete_xio_handle, on_io_close_complete, callback_context) != 0) 00120 { 00121 /* Codes_SRS_XIO_01_026: [If the underlying concrete_io_close fails, xio_close shall return a non-zero value.] */ 00122 result = __LINE__; 00123 } 00124 else 00125 { 00126 /* Codes_SRS_XIO_01_024: [On success, xio_close shall return 0.] */ 00127 result = 0; 00128 } 00129 } 00130 00131 return result; 00132 } 00133 00134 int xio_send(XIO_HANDLE xio, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context) 00135 { 00136 int result; 00137 00138 /* Codes_SRS_XIO_01_011: [No error check shall be performed on buffer and size.] */ 00139 /* Codes_SRS_XIO_01_010: [If handle is NULL, xio_send shall return a non-zero value.] */ 00140 if (xio == NULL) 00141 { 00142 result = __LINE__; 00143 } 00144 else 00145 { 00146 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00147 00148 /* Codes_SRS_XIO_01_008: [xio_send shall pass the sequence of bytes pointed to by buffer to the concrete IO implementation specified in xio_create, by calling the concrete_io_send function while passing down the buffer and size arguments to it.] */ 00149 /* Codes_SRS_XIO_01_009: [On success, xio_send shall return 0.] */ 00150 /* Codes_SRS_XIO_01_015: [If the underlying concrete_io_send fails, xio_send shall return a non-zero value.] */ 00151 /* Codes_SRS_XIO_01_027: [xio_send shall pass to the concrete_io_send function the on_send_complete and callback_context arguments.] */ 00152 result = xio_instance->io_interface_description->concrete_io_send(xio_instance->concrete_xio_handle, buffer, size, on_send_complete, callback_context); 00153 } 00154 00155 return result; 00156 } 00157 00158 void xio_dowork(XIO_HANDLE xio) 00159 { 00160 /* Codes_SRS_XIO_01_018: [When the handle argument is NULL, xio_dowork shall do nothing.] */ 00161 if (xio != NULL) 00162 { 00163 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00164 00165 /* Codes_SRS_XIO_01_012: [xio_dowork shall call the concrete XIO implementation specified in xio_create, by calling the concrete_io_dowork function.] */ 00166 xio_instance->io_interface_description->concrete_io_dowork(xio_instance->concrete_xio_handle); 00167 } 00168 } 00169 00170 int xio_setoption(XIO_HANDLE xio, const char* optionName, const void* value) 00171 { 00172 int result; 00173 00174 /* Codes_SRS_XIO_03_030: [If the xio argument or the optionName argument is NULL, xio_setoption shall return a non-zero value.] */ 00175 if (xio == NULL || optionName == NULL) 00176 { 00177 result = __LINE__; 00178 } 00179 else 00180 { 00181 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00182 00183 if (strcmp(CONCRETE_OPTIONS, optionName) == 0) 00184 { 00185 /*then value is a pointer to OPTIONHANDLER_HANDLE*/ 00186 if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, xio_instance->concrete_xio_handle) != OPTIONHANDLER_OK) 00187 { 00188 LogError("unable to OptionHandler_FeedOptions"); 00189 result = __LINE__; 00190 } 00191 else 00192 { 00193 result = 0; 00194 } 00195 } 00196 else /*passthrough*/ 00197 { 00198 /* Codes_SRS_XIO_003_028: [xio_setoption shall pass the optionName and value to the concrete IO implementation specified in xio_create by invoking the concrete_xio_setoption function.] */ 00199 /* Codes_SRS_XIO_03_029: [xio_setoption shall return 0 upon success.] */ 00200 /* Codes_SRS_XIO_03_031: [If the underlying concrete_xio_setoption fails, xio_setOption shall return a non-zero value.] */ 00201 result = xio_instance->io_interface_description->concrete_io_setoption(xio_instance->concrete_xio_handle, optionName, value); 00202 } 00203 } 00204 00205 return result; 00206 } 00207 00208 static void* xio_CloneOption(const char* name, const void* value) 00209 { 00210 void *result; 00211 if ( 00212 (name == NULL) || 00213 (value == NULL) 00214 ) 00215 { 00216 LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value); 00217 result = NULL; 00218 } 00219 else 00220 { 00221 if (strcmp(name, CONCRETE_OPTIONS) == 0) 00222 { 00223 result = (void*)value; 00224 } 00225 else 00226 { 00227 LogError("unknown option: %s", name); 00228 result = NULL; 00229 } 00230 } 00231 return result; 00232 } 00233 00234 00235 static void xio_DestroyOption(const char* name, const void* value) 00236 { 00237 if ( 00238 (name == NULL) || 00239 (value == NULL) 00240 ) 00241 { 00242 LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value); 00243 } 00244 else 00245 { 00246 if (strcmp(name, CONCRETE_OPTIONS) == 0) 00247 { 00248 OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value); 00249 } 00250 else 00251 { 00252 LogError("unknown option: %s", name); 00253 } 00254 } 00255 } 00256 00257 OPTIONHANDLER_HANDLE xio_retrieveoptions(XIO_HANDLE xio) 00258 { 00259 OPTIONHANDLER_HANDLE result; 00260 00261 if (xio == NULL) 00262 { 00263 LogError("invalid argument detected: XIO_HANDLE xio=%p", xio); 00264 result = NULL; 00265 } 00266 else 00267 { 00268 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio; 00269 /*xio_retrieveoptions shall return a OPTIONHANDLER_HANDLE that has 1 option called "underlyingOptions" which is of type OPTIONHANDLER_HANDLE*/ 00270 result = OptionHandler_Create(xio_CloneOption, xio_DestroyOption, (pfSetOption)xio_setoption); 00271 if (result == NULL) 00272 { 00273 LogError("unable to OptionHandler_Create"); 00274 /*return as is*/ 00275 } 00276 else 00277 { 00278 OPTIONHANDLER_HANDLE concreteOptions = xio_instance->io_interface_description->concrete_io_retrieveoptions(xio_instance->concrete_xio_handle); 00279 if (concreteOptions == NULL) 00280 { 00281 LogError("unable to concrete_io_retrieveoptions"); 00282 OptionHandler_Destroy(result); 00283 result = NULL; 00284 } 00285 else 00286 { 00287 if (OptionHandler_AddOption(result, CONCRETE_OPTIONS, concreteOptions) != OPTIONHANDLER_OK) 00288 { 00289 LogError("unable to OptionHandler_AddOption"); 00290 OptionHandler_Destroy(concreteOptions); 00291 OptionHandler_Destroy(result); 00292 result = NULL; 00293 } 00294 else 00295 { 00296 /*all is fine*/ 00297 } 00298 } 00299 } 00300 } 00301 00302 return result; 00303 } 00304
Generated on Tue Jul 12 2022 12:43:25 by
