Demo using MBED TLS

Dependencies:   EthernetInterface NTPClient iothub_amqp_transport iothub_client mbed-rtos mbed

Fork of iothub_client_sample_amqp by Azure IoT

Committer:
markrad
Date:
Thu Jan 05 00:20:03 2017 +0000
Revision:
58:f50b97b08851
Sample using MBED TLS

Who changed what in which revision?

UserRevisionLine numberNew contents of line
markrad 58:f50b97b08851 1 // Copyright (c) Microsoft. All rights reserved.
markrad 58:f50b97b08851 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
markrad 58:f50b97b08851 3
markrad 58:f50b97b08851 4 #include <stdlib.h>
markrad 58:f50b97b08851 5 #ifdef _CRTDBG_MAP_ALLOC
markrad 58:f50b97b08851 6 #include <crtdbg.h>
markrad 58:f50b97b08851 7 #endif
markrad 58:f50b97b08851 8
markrad 58:f50b97b08851 9 #include <stddef.h>
markrad 58:f50b97b08851 10 #include <stdio.h>
markrad 58:f50b97b08851 11 #include <string.h>
markrad 58:f50b97b08851 12 #include "azure_c_shared_utility/socketio.h"
markrad 58:f50b97b08851 13 #include "azure_c_shared_utility/singlylinkedlist.h"
markrad 58:f50b97b08851 14 #include "azure_c_shared_utility/tcpsocketconnection_c.h"
markrad 58:f50b97b08851 15 #include "azure_c_shared_utility/xlogging.h"
markrad 58:f50b97b08851 16
markrad 58:f50b97b08851 17 #define UNABLE_TO_COMPLETE -2
markrad 58:f50b97b08851 18 #define MBED_RECEIVE_BYTES_VALUE 128
markrad 58:f50b97b08851 19
markrad 58:f50b97b08851 20 typedef enum IO_STATE_TAG
markrad 58:f50b97b08851 21 {
markrad 58:f50b97b08851 22 IO_STATE_CLOSED,
markrad 58:f50b97b08851 23 IO_STATE_OPENING,
markrad 58:f50b97b08851 24 IO_STATE_OPEN,
markrad 58:f50b97b08851 25 IO_STATE_CLOSING,
markrad 58:f50b97b08851 26 IO_STATE_ERROR
markrad 58:f50b97b08851 27 } IO_STATE;
markrad 58:f50b97b08851 28
markrad 58:f50b97b08851 29 typedef struct PENDING_SOCKET_IO_TAG
markrad 58:f50b97b08851 30 {
markrad 58:f50b97b08851 31 unsigned char* bytes;
markrad 58:f50b97b08851 32 size_t size;
markrad 58:f50b97b08851 33 ON_SEND_COMPLETE on_send_complete;
markrad 58:f50b97b08851 34 void* callback_context;
markrad 58:f50b97b08851 35 SINGLYLINKEDLIST_HANDLE pending_io_list;
markrad 58:f50b97b08851 36 } PENDING_SOCKET_IO;
markrad 58:f50b97b08851 37
markrad 58:f50b97b08851 38 typedef struct SOCKET_IO_INSTANCE_TAG
markrad 58:f50b97b08851 39 {
markrad 58:f50b97b08851 40 TCPSOCKETCONNECTION_HANDLE tcp_socket_connection;
markrad 58:f50b97b08851 41 ON_BYTES_RECEIVED on_bytes_received;
markrad 58:f50b97b08851 42 ON_IO_ERROR on_io_error;
markrad 58:f50b97b08851 43 void* on_bytes_received_context;
markrad 58:f50b97b08851 44 void* on_io_error_context;
markrad 58:f50b97b08851 45 char* hostname;
markrad 58:f50b97b08851 46 int port;
markrad 58:f50b97b08851 47 IO_STATE io_state;
markrad 58:f50b97b08851 48 SINGLYLINKEDLIST_HANDLE pending_io_list;
markrad 58:f50b97b08851 49 } SOCKET_IO_INSTANCE;
markrad 58:f50b97b08851 50
markrad 58:f50b97b08851 51 /*this function will clone an option given by name and value*/
markrad 58:f50b97b08851 52 static void* socketio_CloneOption(const char* name, const void* value)
markrad 58:f50b97b08851 53 {
markrad 58:f50b97b08851 54 (void)(name, value);
markrad 58:f50b97b08851 55 return NULL;
markrad 58:f50b97b08851 56 }
markrad 58:f50b97b08851 57
markrad 58:f50b97b08851 58 /*this function destroys an option previously created*/
markrad 58:f50b97b08851 59 static void socketio_DestroyOption(const char* name, const void* value)
markrad 58:f50b97b08851 60 {
markrad 58:f50b97b08851 61 (void)(name, value);
markrad 58:f50b97b08851 62 }
markrad 58:f50b97b08851 63
markrad 58:f50b97b08851 64 static OPTIONHANDLER_HANDLE socketio_retrieveoptions(CONCRETE_IO_HANDLE socket_io)
markrad 58:f50b97b08851 65 {
markrad 58:f50b97b08851 66 OPTIONHANDLER_HANDLE result;
markrad 58:f50b97b08851 67 (void)socket_io;
markrad 58:f50b97b08851 68 result = OptionHandler_Create(socketio_CloneOption, socketio_DestroyOption, socketio_setoption);
markrad 58:f50b97b08851 69 if (result == NULL)
markrad 58:f50b97b08851 70 {
markrad 58:f50b97b08851 71 /*return as is*/
markrad 58:f50b97b08851 72 }
markrad 58:f50b97b08851 73 else
markrad 58:f50b97b08851 74 {
markrad 58:f50b97b08851 75 /*insert here work to add the options to "result" handle*/
markrad 58:f50b97b08851 76 }
markrad 58:f50b97b08851 77 return result;
markrad 58:f50b97b08851 78 }
markrad 58:f50b97b08851 79
markrad 58:f50b97b08851 80 static const IO_INTERFACE_DESCRIPTION socket_io_interface_description =
markrad 58:f50b97b08851 81 {
markrad 58:f50b97b08851 82 socketio_retrieveoptions,
markrad 58:f50b97b08851 83 socketio_create,
markrad 58:f50b97b08851 84 socketio_destroy,
markrad 58:f50b97b08851 85 socketio_open,
markrad 58:f50b97b08851 86 socketio_close,
markrad 58:f50b97b08851 87 socketio_send,
markrad 58:f50b97b08851 88 socketio_dowork,
markrad 58:f50b97b08851 89 socketio_setoption
markrad 58:f50b97b08851 90 };
markrad 58:f50b97b08851 91
markrad 58:f50b97b08851 92 static void indicate_error(SOCKET_IO_INSTANCE* socket_io_instance)
markrad 58:f50b97b08851 93 {
markrad 58:f50b97b08851 94 if (socket_io_instance->on_io_error != NULL)
markrad 58:f50b97b08851 95 {
markrad 58:f50b97b08851 96 socket_io_instance->on_io_error(socket_io_instance->on_io_error_context);
markrad 58:f50b97b08851 97 }
markrad 58:f50b97b08851 98 }
markrad 58:f50b97b08851 99
markrad 58:f50b97b08851 100 static int add_pending_io(SOCKET_IO_INSTANCE* socket_io_instance, const unsigned char* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
markrad 58:f50b97b08851 101 {
markrad 58:f50b97b08851 102 int result;
markrad 58:f50b97b08851 103 PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)malloc(sizeof(PENDING_SOCKET_IO));
markrad 58:f50b97b08851 104 if (pending_socket_io == NULL)
markrad 58:f50b97b08851 105 {
markrad 58:f50b97b08851 106 result = __LINE__;
markrad 58:f50b97b08851 107 }
markrad 58:f50b97b08851 108 else
markrad 58:f50b97b08851 109 {
markrad 58:f50b97b08851 110 pending_socket_io->bytes = (unsigned char*)malloc(size);
markrad 58:f50b97b08851 111 if (pending_socket_io->bytes == NULL)
markrad 58:f50b97b08851 112 {
markrad 58:f50b97b08851 113 free(pending_socket_io);
markrad 58:f50b97b08851 114 result = __LINE__;
markrad 58:f50b97b08851 115 }
markrad 58:f50b97b08851 116 else
markrad 58:f50b97b08851 117 {
markrad 58:f50b97b08851 118 pending_socket_io->size = size;
markrad 58:f50b97b08851 119 pending_socket_io->on_send_complete = on_send_complete;
markrad 58:f50b97b08851 120 pending_socket_io->callback_context = callback_context;
markrad 58:f50b97b08851 121 pending_socket_io->pending_io_list = socket_io_instance->pending_io_list;
markrad 58:f50b97b08851 122 (void)memcpy(pending_socket_io->bytes, buffer, size);
markrad 58:f50b97b08851 123
markrad 58:f50b97b08851 124 if (singlylinkedlist_add(socket_io_instance->pending_io_list, pending_socket_io) == NULL)
markrad 58:f50b97b08851 125 {
markrad 58:f50b97b08851 126 free(pending_socket_io->bytes);
markrad 58:f50b97b08851 127 free(pending_socket_io);
markrad 58:f50b97b08851 128 result = __LINE__;
markrad 58:f50b97b08851 129 }
markrad 58:f50b97b08851 130 else
markrad 58:f50b97b08851 131 {
markrad 58:f50b97b08851 132 result = 0;
markrad 58:f50b97b08851 133 }
markrad 58:f50b97b08851 134 }
markrad 58:f50b97b08851 135 }
markrad 58:f50b97b08851 136
markrad 58:f50b97b08851 137 return result;
markrad 58:f50b97b08851 138 }
markrad 58:f50b97b08851 139
markrad 58:f50b97b08851 140 CONCRETE_IO_HANDLE socketio_create(void* io_create_parameters)
markrad 58:f50b97b08851 141 {
markrad 58:f50b97b08851 142 SOCKETIO_CONFIG* socket_io_config = io_create_parameters;
markrad 58:f50b97b08851 143 SOCKET_IO_INSTANCE* result;
markrad 58:f50b97b08851 144
markrad 58:f50b97b08851 145 if (socket_io_config == NULL)
markrad 58:f50b97b08851 146 {
markrad 58:f50b97b08851 147 result = NULL;
markrad 58:f50b97b08851 148 }
markrad 58:f50b97b08851 149 else
markrad 58:f50b97b08851 150 {
markrad 58:f50b97b08851 151 result = malloc(sizeof(SOCKET_IO_INSTANCE));
markrad 58:f50b97b08851 152 if (result != NULL)
markrad 58:f50b97b08851 153 {
markrad 58:f50b97b08851 154 result->pending_io_list = singlylinkedlist_create();
markrad 58:f50b97b08851 155 if (result->pending_io_list == NULL)
markrad 58:f50b97b08851 156 {
markrad 58:f50b97b08851 157 free(result);
markrad 58:f50b97b08851 158 result = NULL;
markrad 58:f50b97b08851 159 }
markrad 58:f50b97b08851 160 else
markrad 58:f50b97b08851 161 {
markrad 58:f50b97b08851 162 result->hostname = (char*)malloc(strlen(socket_io_config->hostname) + 1);
markrad 58:f50b97b08851 163 if (result->hostname == NULL)
markrad 58:f50b97b08851 164 {
markrad 58:f50b97b08851 165 singlylinkedlist_destroy(result->pending_io_list);
markrad 58:f50b97b08851 166 free(result);
markrad 58:f50b97b08851 167 result = NULL;
markrad 58:f50b97b08851 168 }
markrad 58:f50b97b08851 169 else
markrad 58:f50b97b08851 170 {
markrad 58:f50b97b08851 171 strcpy(result->hostname, socket_io_config->hostname);
markrad 58:f50b97b08851 172 result->port = socket_io_config->port;
markrad 58:f50b97b08851 173 result->on_bytes_received = NULL;
markrad 58:f50b97b08851 174 result->on_io_error = NULL;
markrad 58:f50b97b08851 175 result->on_bytes_received_context = NULL;
markrad 58:f50b97b08851 176 result->on_io_error_context = NULL;
markrad 58:f50b97b08851 177 result->io_state = IO_STATE_CLOSED;
markrad 58:f50b97b08851 178 result->tcp_socket_connection = NULL;
markrad 58:f50b97b08851 179 }
markrad 58:f50b97b08851 180 }
markrad 58:f50b97b08851 181 }
markrad 58:f50b97b08851 182 }
markrad 58:f50b97b08851 183
markrad 58:f50b97b08851 184 return result;
markrad 58:f50b97b08851 185 }
markrad 58:f50b97b08851 186
markrad 58:f50b97b08851 187 void socketio_destroy(CONCRETE_IO_HANDLE socket_io)
markrad 58:f50b97b08851 188 {
markrad 58:f50b97b08851 189 if (socket_io != NULL)
markrad 58:f50b97b08851 190 {
markrad 58:f50b97b08851 191 SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
markrad 58:f50b97b08851 192
markrad 58:f50b97b08851 193 tcpsocketconnection_destroy(socket_io_instance->tcp_socket_connection);
markrad 58:f50b97b08851 194
markrad 58:f50b97b08851 195 /* clear all pending IOs */
markrad 58:f50b97b08851 196 LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 197 while (first_pending_io != NULL)
markrad 58:f50b97b08851 198 {
markrad 58:f50b97b08851 199 PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
markrad 58:f50b97b08851 200 if (pending_socket_io != NULL)
markrad 58:f50b97b08851 201 {
markrad 58:f50b97b08851 202 free(pending_socket_io->bytes);
markrad 58:f50b97b08851 203 free(pending_socket_io);
markrad 58:f50b97b08851 204 }
markrad 58:f50b97b08851 205
markrad 58:f50b97b08851 206 (void)singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io);
markrad 58:f50b97b08851 207 first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 208 }
markrad 58:f50b97b08851 209
markrad 58:f50b97b08851 210 singlylinkedlist_destroy(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 211 free(socket_io_instance->hostname);
markrad 58:f50b97b08851 212 free(socket_io);
markrad 58:f50b97b08851 213 }
markrad 58:f50b97b08851 214 }
markrad 58:f50b97b08851 215
markrad 58:f50b97b08851 216 int socketio_open(CONCRETE_IO_HANDLE socket_io, 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)
markrad 58:f50b97b08851 217 {
markrad 58:f50b97b08851 218 int result;
markrad 58:f50b97b08851 219
markrad 58:f50b97b08851 220 SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
markrad 58:f50b97b08851 221 if (socket_io == NULL)
markrad 58:f50b97b08851 222 {
markrad 58:f50b97b08851 223 result = __LINE__;
markrad 58:f50b97b08851 224 }
markrad 58:f50b97b08851 225 else
markrad 58:f50b97b08851 226 {
markrad 58:f50b97b08851 227 socket_io_instance->tcp_socket_connection = tcpsocketconnection_create();
markrad 58:f50b97b08851 228 if (socket_io_instance->tcp_socket_connection == NULL)
markrad 58:f50b97b08851 229 {
markrad 58:f50b97b08851 230 result = __LINE__;
markrad 58:f50b97b08851 231 }
markrad 58:f50b97b08851 232 else
markrad 58:f50b97b08851 233 {
markrad 58:f50b97b08851 234 if (tcpsocketconnection_connect(socket_io_instance->tcp_socket_connection, socket_io_instance->hostname, socket_io_instance->port) != 0)
markrad 58:f50b97b08851 235 {
markrad 58:f50b97b08851 236 tcpsocketconnection_destroy(socket_io_instance->tcp_socket_connection);
markrad 58:f50b97b08851 237 socket_io_instance->tcp_socket_connection = NULL;
markrad 58:f50b97b08851 238 result = __LINE__;
markrad 58:f50b97b08851 239 }
markrad 58:f50b97b08851 240 else
markrad 58:f50b97b08851 241 {
markrad 58:f50b97b08851 242 tcpsocketconnection_set_blocking(socket_io_instance->tcp_socket_connection, false, 0);
markrad 58:f50b97b08851 243
markrad 58:f50b97b08851 244 socket_io_instance->on_bytes_received = on_bytes_received;
markrad 58:f50b97b08851 245 socket_io_instance->on_bytes_received_context = on_bytes_received_context;
markrad 58:f50b97b08851 246
markrad 58:f50b97b08851 247 socket_io_instance->on_io_error = on_io_error;
markrad 58:f50b97b08851 248 socket_io_instance->on_io_error_context = on_io_error_context;
markrad 58:f50b97b08851 249
markrad 58:f50b97b08851 250 socket_io_instance->io_state = IO_STATE_OPEN;
markrad 58:f50b97b08851 251
markrad 58:f50b97b08851 252 if (on_io_open_complete != NULL)
markrad 58:f50b97b08851 253 {
markrad 58:f50b97b08851 254 on_io_open_complete(on_io_open_complete_context, IO_OPEN_OK);
markrad 58:f50b97b08851 255 }
markrad 58:f50b97b08851 256
markrad 58:f50b97b08851 257 result = 0;
markrad 58:f50b97b08851 258 }
markrad 58:f50b97b08851 259 }
markrad 58:f50b97b08851 260 }
markrad 58:f50b97b08851 261
markrad 58:f50b97b08851 262 return result;
markrad 58:f50b97b08851 263 }
markrad 58:f50b97b08851 264
markrad 58:f50b97b08851 265 int socketio_close(CONCRETE_IO_HANDLE socket_io, ON_IO_CLOSE_COMPLETE on_io_close_complete, void* callback_context)
markrad 58:f50b97b08851 266 {
markrad 58:f50b97b08851 267 int result = 0;
markrad 58:f50b97b08851 268
markrad 58:f50b97b08851 269 if (socket_io == NULL)
markrad 58:f50b97b08851 270 {
markrad 58:f50b97b08851 271 result = __LINE__;
markrad 58:f50b97b08851 272 }
markrad 58:f50b97b08851 273 else
markrad 58:f50b97b08851 274 {
markrad 58:f50b97b08851 275 SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
markrad 58:f50b97b08851 276
markrad 58:f50b97b08851 277 if ((socket_io_instance->io_state == IO_STATE_CLOSED) ||
markrad 58:f50b97b08851 278 (socket_io_instance->io_state == IO_STATE_CLOSING))
markrad 58:f50b97b08851 279 {
markrad 58:f50b97b08851 280 result = __LINE__;
markrad 58:f50b97b08851 281 }
markrad 58:f50b97b08851 282 else
markrad 58:f50b97b08851 283 {
markrad 58:f50b97b08851 284 tcpsocketconnection_close(socket_io_instance->tcp_socket_connection);
markrad 58:f50b97b08851 285 socket_io_instance->tcp_socket_connection = NULL;
markrad 58:f50b97b08851 286 socket_io_instance->io_state = IO_STATE_CLOSED;
markrad 58:f50b97b08851 287
markrad 58:f50b97b08851 288 if (on_io_close_complete != NULL)
markrad 58:f50b97b08851 289 {
markrad 58:f50b97b08851 290 on_io_close_complete(callback_context);
markrad 58:f50b97b08851 291 }
markrad 58:f50b97b08851 292
markrad 58:f50b97b08851 293 result = 0;
markrad 58:f50b97b08851 294 }
markrad 58:f50b97b08851 295 }
markrad 58:f50b97b08851 296
markrad 58:f50b97b08851 297 return result;
markrad 58:f50b97b08851 298 }
markrad 58:f50b97b08851 299
markrad 58:f50b97b08851 300 int socketio_send(CONCRETE_IO_HANDLE socket_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
markrad 58:f50b97b08851 301 {
markrad 58:f50b97b08851 302 int result;
markrad 58:f50b97b08851 303
markrad 58:f50b97b08851 304 if ((socket_io == NULL) ||
markrad 58:f50b97b08851 305 (buffer == NULL) ||
markrad 58:f50b97b08851 306 (size == 0))
markrad 58:f50b97b08851 307 {
markrad 58:f50b97b08851 308 /* Invalid arguments */
markrad 58:f50b97b08851 309 result = __LINE__;
markrad 58:f50b97b08851 310 }
markrad 58:f50b97b08851 311 else
markrad 58:f50b97b08851 312 {
markrad 58:f50b97b08851 313 SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
markrad 58:f50b97b08851 314 if (socket_io_instance->io_state != IO_STATE_OPEN)
markrad 58:f50b97b08851 315 {
markrad 58:f50b97b08851 316 result = __LINE__;
markrad 58:f50b97b08851 317 }
markrad 58:f50b97b08851 318 else
markrad 58:f50b97b08851 319 {
markrad 58:f50b97b08851 320 LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 321 if (first_pending_io != NULL)
markrad 58:f50b97b08851 322 {
markrad 58:f50b97b08851 323 if (add_pending_io(socket_io_instance, buffer, size, on_send_complete, callback_context) != 0)
markrad 58:f50b97b08851 324 {
markrad 58:f50b97b08851 325 result = __LINE__;
markrad 58:f50b97b08851 326 }
markrad 58:f50b97b08851 327 else
markrad 58:f50b97b08851 328 {
markrad 58:f50b97b08851 329 result = 0;
markrad 58:f50b97b08851 330 }
markrad 58:f50b97b08851 331 }
markrad 58:f50b97b08851 332 else
markrad 58:f50b97b08851 333 {
markrad 58:f50b97b08851 334 int send_result = tcpsocketconnection_send(socket_io_instance->tcp_socket_connection, buffer, size);
markrad 58:f50b97b08851 335 if (send_result != size)
markrad 58:f50b97b08851 336 {
markrad 58:f50b97b08851 337 if (send_result < 0)
markrad 58:f50b97b08851 338 {
markrad 58:f50b97b08851 339 send_result = 0;
markrad 58:f50b97b08851 340 }
markrad 58:f50b97b08851 341
markrad 58:f50b97b08851 342 /* queue data */
markrad 58:f50b97b08851 343 if (add_pending_io(socket_io_instance, (unsigned char*)buffer + send_result, size - send_result, on_send_complete, callback_context) != 0)
markrad 58:f50b97b08851 344 {
markrad 58:f50b97b08851 345 result = __LINE__;
markrad 58:f50b97b08851 346 }
markrad 58:f50b97b08851 347 else
markrad 58:f50b97b08851 348 {
markrad 58:f50b97b08851 349 result = 0;
markrad 58:f50b97b08851 350 }
markrad 58:f50b97b08851 351 }
markrad 58:f50b97b08851 352 else
markrad 58:f50b97b08851 353 {
markrad 58:f50b97b08851 354 if (on_send_complete != NULL)
markrad 58:f50b97b08851 355 {
markrad 58:f50b97b08851 356 on_send_complete(callback_context, IO_SEND_OK);
markrad 58:f50b97b08851 357 }
markrad 58:f50b97b08851 358
markrad 58:f50b97b08851 359 result = 0;
markrad 58:f50b97b08851 360 }
markrad 58:f50b97b08851 361 }
markrad 58:f50b97b08851 362 }
markrad 58:f50b97b08851 363 }
markrad 58:f50b97b08851 364
markrad 58:f50b97b08851 365 return result;
markrad 58:f50b97b08851 366 }
markrad 58:f50b97b08851 367
markrad 58:f50b97b08851 368 void socketio_dowork(CONCRETE_IO_HANDLE socket_io)
markrad 58:f50b97b08851 369 {
markrad 58:f50b97b08851 370 if (socket_io != NULL)
markrad 58:f50b97b08851 371 {
markrad 58:f50b97b08851 372 SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;
markrad 58:f50b97b08851 373 if (socket_io_instance->io_state == IO_STATE_OPEN)
markrad 58:f50b97b08851 374 {
markrad 58:f50b97b08851 375 int received = 1;
markrad 58:f50b97b08851 376
markrad 58:f50b97b08851 377 LIST_ITEM_HANDLE first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 378 while (first_pending_io != NULL)
markrad 58:f50b97b08851 379 {
markrad 58:f50b97b08851 380 PENDING_SOCKET_IO* pending_socket_io = (PENDING_SOCKET_IO*)singlylinkedlist_item_get_value(first_pending_io);
markrad 58:f50b97b08851 381 if (pending_socket_io == NULL)
markrad 58:f50b97b08851 382 {
markrad 58:f50b97b08851 383 socket_io_instance->io_state = IO_STATE_ERROR;
markrad 58:f50b97b08851 384 indicate_error(socket_io_instance);
markrad 58:f50b97b08851 385 break;
markrad 58:f50b97b08851 386 }
markrad 58:f50b97b08851 387
markrad 58:f50b97b08851 388 int send_result = tcpsocketconnection_send(socket_io_instance->tcp_socket_connection, (const char*)pending_socket_io->bytes, pending_socket_io->size);
markrad 58:f50b97b08851 389 if (send_result != pending_socket_io->size)
markrad 58:f50b97b08851 390 {
markrad 58:f50b97b08851 391 if (send_result < 0)
markrad 58:f50b97b08851 392 {
markrad 58:f50b97b08851 393 if (send_result < UNABLE_TO_COMPLETE)
markrad 58:f50b97b08851 394 {
markrad 58:f50b97b08851 395 // Bad error. Indicate as much.
markrad 58:f50b97b08851 396 socket_io_instance->io_state = IO_STATE_ERROR;
markrad 58:f50b97b08851 397 indicate_error(socket_io_instance);
markrad 58:f50b97b08851 398 }
markrad 58:f50b97b08851 399 break;
markrad 58:f50b97b08851 400 }
markrad 58:f50b97b08851 401 else
markrad 58:f50b97b08851 402 {
markrad 58:f50b97b08851 403 /* send something, wait for the rest */
markrad 58:f50b97b08851 404 (void)memmove(pending_socket_io->bytes, pending_socket_io->bytes + send_result, pending_socket_io->size - send_result);
markrad 58:f50b97b08851 405 }
markrad 58:f50b97b08851 406 }
markrad 58:f50b97b08851 407 else
markrad 58:f50b97b08851 408 {
markrad 58:f50b97b08851 409 if (pending_socket_io->on_send_complete != NULL)
markrad 58:f50b97b08851 410 {
markrad 58:f50b97b08851 411 pending_socket_io->on_send_complete(pending_socket_io->callback_context, IO_SEND_OK);
markrad 58:f50b97b08851 412 }
markrad 58:f50b97b08851 413
markrad 58:f50b97b08851 414 free(pending_socket_io->bytes);
markrad 58:f50b97b08851 415 free(pending_socket_io);
markrad 58:f50b97b08851 416 if (singlylinkedlist_remove(socket_io_instance->pending_io_list, first_pending_io) != 0)
markrad 58:f50b97b08851 417 {
markrad 58:f50b97b08851 418 socket_io_instance->io_state = IO_STATE_ERROR;
markrad 58:f50b97b08851 419 indicate_error(socket_io_instance);
markrad 58:f50b97b08851 420 }
markrad 58:f50b97b08851 421 }
markrad 58:f50b97b08851 422
markrad 58:f50b97b08851 423 first_pending_io = singlylinkedlist_get_head_item(socket_io_instance->pending_io_list);
markrad 58:f50b97b08851 424 }
markrad 58:f50b97b08851 425
markrad 58:f50b97b08851 426 while (received > 0)
markrad 58:f50b97b08851 427 {
markrad 58:f50b97b08851 428 unsigned char* recv_bytes = malloc(MBED_RECEIVE_BYTES_VALUE);
markrad 58:f50b97b08851 429 if (recv_bytes == NULL)
markrad 58:f50b97b08851 430 {
markrad 58:f50b97b08851 431 LogError("Socketio_Failure: NULL allocating input buffer.");
markrad 58:f50b97b08851 432 indicate_error(socket_io_instance);
markrad 58:f50b97b08851 433 }
markrad 58:f50b97b08851 434 else
markrad 58:f50b97b08851 435 {
markrad 58:f50b97b08851 436 received = tcpsocketconnection_receive(socket_io_instance->tcp_socket_connection, (char*)recv_bytes, MBED_RECEIVE_BYTES_VALUE);
markrad 58:f50b97b08851 437 if (received > 0)
markrad 58:f50b97b08851 438 {
markrad 58:f50b97b08851 439 if (socket_io_instance->on_bytes_received != NULL)
markrad 58:f50b97b08851 440 {
markrad 58:f50b97b08851 441 /* explictly ignoring here the result of the callback */
markrad 58:f50b97b08851 442 (void)socket_io_instance->on_bytes_received(socket_io_instance->on_bytes_received_context, recv_bytes, received);
markrad 58:f50b97b08851 443 }
markrad 58:f50b97b08851 444 }
markrad 58:f50b97b08851 445 free(recv_bytes);
markrad 58:f50b97b08851 446 }
markrad 58:f50b97b08851 447 }
markrad 58:f50b97b08851 448 }
markrad 58:f50b97b08851 449 }
markrad 58:f50b97b08851 450 }
markrad 58:f50b97b08851 451
markrad 58:f50b97b08851 452 int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, const void* value)
markrad 58:f50b97b08851 453 {
markrad 58:f50b97b08851 454 /* Not implementing any options */
markrad 58:f50b97b08851 455 return __LINE__;
markrad 58:f50b97b08851 456 }
markrad 58:f50b97b08851 457
markrad 58:f50b97b08851 458 const IO_INTERFACE_DESCRIPTION* socketio_get_interface_description(void)
markrad 58:f50b97b08851 459 {
markrad 58:f50b97b08851 460 return &socket_io_interface_description;
markrad 58:f50b97b08851 461 }
markrad 58:f50b97b08851 462