source: azure_iot_hub/trunk/azure_iohub/c-utility/src/xio.c@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 11.4 KB
Line 
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4#include <stdlib.h>
5#include <stddef.h>
6#include "azure_c_shared_utility/gballoc.h"
7#include "azure_c_shared_utility/optimize_size.h"
8#include "azure_c_shared_utility/xio.h"
9#include "azure_c_shared_utility/xlogging.h"
10
11static const char* CONCRETE_OPTIONS = "concreteOptions";
12
13typedef struct XIO_INSTANCE_TAG
14{
15 const IO_INTERFACE_DESCRIPTION* io_interface_description;
16 CONCRETE_IO_HANDLE concrete_xio_handle;
17} XIO_INSTANCE;
18
19XIO_HANDLE xio_create(const IO_INTERFACE_DESCRIPTION* io_interface_description, const void* xio_create_parameters)
20{
21 XIO_INSTANCE* xio_instance;
22 /* Codes_SRS_XIO_01_003: [If the argument io_interface_description is NULL, xio_create shall return NULL.] */
23 if ((io_interface_description == NULL) ||
24 /* Codes_SRS_XIO_01_004: [If any io_interface_description member is NULL, xio_create shall return NULL.] */
25 (io_interface_description->concrete_io_retrieveoptions == NULL) ||
26 (io_interface_description->concrete_io_create == NULL) ||
27 (io_interface_description->concrete_io_destroy == NULL) ||
28 (io_interface_description->concrete_io_open == NULL) ||
29 (io_interface_description->concrete_io_close == NULL) ||
30 (io_interface_description->concrete_io_send == NULL) ||
31 (io_interface_description->concrete_io_dowork == NULL) ||
32 (io_interface_description->concrete_io_setoption == NULL))
33 {
34 xio_instance = NULL;
35 }
36 else
37 {
38 xio_instance = (XIO_INSTANCE*)malloc(sizeof(XIO_INSTANCE));
39
40 /* Codes_SRS_XIO_01_017: [If allocating the memory needed for the IO interface fails then xio_create shall return NULL.] */
41 if (xio_instance != NULL)
42 {
43 /* Codes_SRS_XIO_01_001: [xio_create shall return on success a non-NULL handle to a new IO interface.] */
44 xio_instance->io_interface_description = io_interface_description;
45
46 /* 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.] */
47 xio_instance->concrete_xio_handle = xio_instance->io_interface_description->concrete_io_create((void*)xio_create_parameters);
48
49 /* Codes_SRS_XIO_01_016: [If the underlying concrete_io_create call fails, xio_create shall return NULL.] */
50 if (xio_instance->concrete_xio_handle == NULL)
51 {
52 free(xio_instance);
53 xio_instance = NULL;
54 }
55 }
56 }
57 return (XIO_HANDLE)xio_instance;
58}
59
60void xio_destroy(XIO_HANDLE xio)
61{
62 /* Codes_SRS_XIO_01_007: [If the argument io is NULL, xio_destroy shall do nothing.] */
63 if (xio != NULL)
64 {
65 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
66
67 /* 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.] */
68 xio_instance->io_interface_description->concrete_io_destroy(xio_instance->concrete_xio_handle);
69
70 /* Codes_SRS_XIO_01_005: [xio_destroy shall free all resources associated with the IO handle.] */
71 free(xio_instance);
72 }
73}
74
75int 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)
76{
77 int result;
78
79 if (xio == NULL)
80 {
81 /* Codes_SRS_XIO_01_021: [If handle is NULL, xio_open shall return a non-zero value.] */
82 result = MU_FAILURE;
83 }
84 else
85 {
86 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
87
88 /* 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.] */
89 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)
90 {
91 /* Codes_SRS_XIO_01_022: [If the underlying concrete_io_open fails, xio_open shall return a non-zero value.] */
92 result = MU_FAILURE;
93 }
94 else
95 {
96 /* Codes_SRS_XIO_01_020: [On success, xio_open shall return 0.] */
97 result = 0;
98 }
99 }
100
101 return result;
102}
103
104int xio_close(XIO_HANDLE xio, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
105{
106 int result;
107
108 if (xio == NULL)
109 {
110 /* Codes_SRS_XIO_01_025: [If handle is NULL, xio_close shall return a non-zero value.] */
111 result = MU_FAILURE;
112 }
113 else
114 {
115 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
116
117 /* Codes_SRS_XIO_01_023: [xio_close shall call the specific concrete_io_close function specified in xio_create.] */
118 if (xio_instance->io_interface_description->concrete_io_close(xio_instance->concrete_xio_handle, on_io_close_complete, callback_context) != 0)
119 {
120 /* Codes_SRS_XIO_01_026: [If the underlying concrete_io_close fails, xio_close shall return a non-zero value.] */
121 result = MU_FAILURE;
122 }
123 else
124 {
125 /* Codes_SRS_XIO_01_024: [On success, xio_close shall return 0.] */
126 result = 0;
127 }
128 }
129
130 return result;
131}
132
133int xio_send(XIO_HANDLE xio, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
134{
135 int result;
136
137 /* Codes_SRS_XIO_01_011: [No error check shall be performed on buffer and size.] */
138 /* Codes_SRS_XIO_01_010: [If handle is NULL, xio_send shall return a non-zero value.] */
139 if (xio == NULL)
140 {
141 result = MU_FAILURE;
142 }
143 else
144 {
145 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
146
147 /* 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.] */
148 /* Codes_SRS_XIO_01_009: [On success, xio_send shall return 0.] */
149 /* Codes_SRS_XIO_01_015: [If the underlying concrete_io_send fails, xio_send shall return a non-zero value.] */
150 /* Codes_SRS_XIO_01_027: [xio_send shall pass to the concrete_io_send function the on_send_complete and callback_context arguments.] */
151 result = xio_instance->io_interface_description->concrete_io_send(xio_instance->concrete_xio_handle, buffer, size, on_send_complete, callback_context);
152 }
153
154 return result;
155}
156
157void xio_dowork(XIO_HANDLE xio)
158{
159 /* Codes_SRS_XIO_01_018: [When the handle argument is NULL, xio_dowork shall do nothing.] */
160 if (xio != NULL)
161 {
162 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
163
164 /* Codes_SRS_XIO_01_012: [xio_dowork shall call the concrete XIO implementation specified in xio_create, by calling the concrete_io_dowork function.] */
165 xio_instance->io_interface_description->concrete_io_dowork(xio_instance->concrete_xio_handle);
166 }
167}
168
169int xio_setoption(XIO_HANDLE xio, const char* optionName, const void* value)
170{
171 int result;
172
173 /* Codes_SRS_XIO_03_030: [If the xio argument or the optionName argument is NULL, xio_setoption shall return a non-zero value.] */
174 if (xio == NULL || optionName == NULL)
175 {
176 result = MU_FAILURE;
177 }
178 else
179 {
180 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
181
182 if (strcmp(CONCRETE_OPTIONS, optionName) == 0)
183 {
184 /*then value is a pointer to OPTIONHANDLER_HANDLE*/
185 if (OptionHandler_FeedOptions((OPTIONHANDLER_HANDLE)value, xio_instance->concrete_xio_handle) != OPTIONHANDLER_OK)
186 {
187 LogError("unable to OptionHandler_FeedOptions");
188 result = MU_FAILURE;
189 }
190 else
191 {
192 result = 0;
193 }
194 }
195 else /*passthrough*/
196 {
197 /* 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.] */
198 /* Codes_SRS_XIO_03_029: [xio_setoption shall return 0 upon success.] */
199 /* Codes_SRS_XIO_03_031: [If the underlying concrete_xio_setoption fails, xio_setOption shall return a non-zero value.] */
200 result = xio_instance->io_interface_description->concrete_io_setoption(xio_instance->concrete_xio_handle, optionName, value);
201 }
202 }
203
204 return result;
205}
206
207static void* xio_CloneOption(const char* name, const void* value)
208{
209 void *result;
210 if (
211 (name == NULL) ||
212 (value == NULL)
213 )
214 {
215 LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
216 result = NULL;
217 }
218 else
219 {
220 if (strcmp(name, CONCRETE_OPTIONS) == 0)
221 {
222 result = (void*)value;
223 }
224 else
225 {
226 LogError("unknown option: %s", name);
227 result = NULL;
228 }
229 }
230 return result;
231}
232
233
234static void xio_DestroyOption(const char* name, const void* value)
235{
236 if (
237 (name == NULL) ||
238 (value == NULL)
239 )
240 {
241 LogError("invalid argument detected: const char* name=%p, const void* value=%p", name, value);
242 }
243 else
244 {
245 if (strcmp(name, CONCRETE_OPTIONS) == 0)
246 {
247 OptionHandler_Destroy((OPTIONHANDLER_HANDLE)value);
248 }
249 else
250 {
251 LogError("unknown option: %s", name);
252 }
253 }
254}
255
256OPTIONHANDLER_HANDLE xio_retrieveoptions(XIO_HANDLE xio)
257{
258 OPTIONHANDLER_HANDLE result;
259
260 if (xio == NULL)
261 {
262 LogError("invalid argument detected: XIO_HANDLE xio=%p", xio);
263 result = NULL;
264 }
265 else
266 {
267 XIO_INSTANCE* xio_instance = (XIO_INSTANCE*)xio;
268 /*xio_retrieveoptions shall return a OPTIONHANDLER_HANDLE that has 1 option called "underlyingOptions" which is of type OPTIONHANDLER_HANDLE*/
269 result = OptionHandler_Create(xio_CloneOption, xio_DestroyOption, (pfSetOption)xio_setoption);
270 if (result == NULL)
271 {
272 LogError("unable to OptionHandler_Create");
273 /*return as is*/
274 }
275 else
276 {
277 OPTIONHANDLER_HANDLE concreteOptions = xio_instance->io_interface_description->concrete_io_retrieveoptions(xio_instance->concrete_xio_handle);
278 if (concreteOptions == NULL)
279 {
280 LogError("unable to concrete_io_retrieveoptions");
281 OptionHandler_Destroy(result);
282 result = NULL;
283 }
284 else
285 {
286 if (OptionHandler_AddOption(result, CONCRETE_OPTIONS, concreteOptions) != OPTIONHANDLER_OK)
287 {
288 LogError("unable to OptionHandler_AddOption");
289 OptionHandler_Destroy(concreteOptions);
290 OptionHandler_Destroy(result);
291 result = NULL;
292 }
293 else
294 {
295 /*all is fine*/
296 }
297 }
298 }
299 }
300
301 return result;
302}
303
Note: See TracBrowser for help on using the repository browser.