Etherios Cloud Connector very first porting for mbed. Tested in an LPC1768

Etherios Cloud Connector for Embedded v2.1.0.3 library for mbed. Early porting.

This port is centered mainly in the platform code. So it should work properly with the provided examples of send_data, device_request, data_points, RCI and firmware_update (stub implementation, not a real one... yet ;-)). Filesystem is not implemented yet, and some examples might need changes.

To run, it needs the following libraries: - mbed - mbed-rtos - EthernetInterface

Find more information (and the source code!) about Etherios Cloud Connector for Embedded here: http://www.etherios.com/products/devicecloud/support/connector and in: http://www.etherios.com

Committer:
spastor
Date:
Tue Dec 03 13:34:02 2013 +0000
Revision:
0:1c358ea10753
First commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
spastor 0:1c358ea10753 1 /*
spastor 0:1c358ea10753 2 * Copyright (c) 2013 Digi International Inc.,
spastor 0:1c358ea10753 3 * All rights not expressly granted are reserved.
spastor 0:1c358ea10753 4 *
spastor 0:1c358ea10753 5 * This Source Code Form is subject to the terms of the Mozilla Public
spastor 0:1c358ea10753 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
spastor 0:1c358ea10753 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
spastor 0:1c358ea10753 8 *
spastor 0:1c358ea10753 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
spastor 0:1c358ea10753 10 * =======================================================================
spastor 0:1c358ea10753 11 */
spastor 0:1c358ea10753 12 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 13 static connector_status_t sm_decode_segment(connector_data_t * const connector_ptr, connector_sm_packet_t * const recv_ptr)
spastor 0:1c358ea10753 14 {
spastor 0:1c358ea10753 15 size_t const data_size = 1 + ((recv_ptr->total_bytes - recv_ptr->processed_bytes) * 4)/5;
spastor 0:1c358ea10753 16 void * data_ptr = NULL;
spastor 0:1c358ea10753 17 connector_status_t result = malloc_data_buffer(connector_ptr, data_size, named_buffer_id(sm_data_block), &data_ptr);
spastor 0:1c358ea10753 18
spastor 0:1c358ea10753 19 if (result == connector_working)
spastor 0:1c358ea10753 20 {
spastor 0:1c358ea10753 21 recv_ptr->total_bytes = sm_decode85(data_ptr, data_size, recv_ptr->data + recv_ptr->processed_bytes, recv_ptr->total_bytes - recv_ptr->processed_bytes);
spastor 0:1c358ea10753 22 memcpy(recv_ptr->data, data_ptr, recv_ptr->total_bytes);
spastor 0:1c358ea10753 23 result = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), data_ptr);
spastor 0:1c358ea10753 24 }
spastor 0:1c358ea10753 25
spastor 0:1c358ea10753 26 return result;
spastor 0:1c358ea10753 27 }
spastor 0:1c358ea10753 28
spastor 0:1c358ea10753 29 static connector_status_t sm_verify_sms_preamble(connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 30 {
spastor 0:1c358ea10753 31 connector_status_t result = connector_working;
spastor 0:1c358ea10753 32
spastor 0:1c358ea10753 33 if (sm_ptr->transport.id_length > 0)
spastor 0:1c358ea10753 34 {
spastor 0:1c358ea10753 35 uint8_t * const data_ptr = sm_ptr->network.recv_packet.data;
spastor 0:1c358ea10753 36 char const prefix = '(';
spastor 0:1c358ea10753 37 char const suffix[] = "):";
spastor 0:1c358ea10753 38 size_t const suffix_bytes = sizeof suffix - 1;
spastor 0:1c358ea10753 39 size_t const prefix_bytes = sizeof prefix;
spastor 0:1c358ea10753 40 size_t const suffix_position = prefix_bytes + sm_ptr->transport.id_length;
spastor 0:1c358ea10753 41 connector_bool_t const valid_prefix = connector_bool(*data_ptr == prefix);
spastor 0:1c358ea10753 42 connector_bool_t const valid_shared_key = connector_bool(memcmp(data_ptr + prefix_bytes, sm_ptr->transport.id, sm_ptr->transport.id_length) == 0);
spastor 0:1c358ea10753 43 connector_bool_t const valid_suffix = connector_bool(memcmp(data_ptr + suffix_position, suffix, suffix_bytes) == 0);
spastor 0:1c358ea10753 44
spastor 0:1c358ea10753 45 if (valid_prefix && valid_shared_key && valid_suffix)
spastor 0:1c358ea10753 46 sm_ptr->network.recv_packet.processed_bytes = suffix_position + suffix_bytes;
spastor 0:1c358ea10753 47 else
spastor 0:1c358ea10753 48 {
spastor 0:1c358ea10753 49 connector_debug_printf("sm_verify_sms_preamble: valid_prefix=%d, valid_shared_key=%d, valid_suffix=%d\n", valid_prefix, valid_shared_key, valid_suffix);
spastor 0:1c358ea10753 50 connector_debug_printf("%s\n",(char *)data_ptr);
spastor 0:1c358ea10753 51
spastor 0:1c358ea10753 52 result = connector_invalid_response;
spastor 0:1c358ea10753 53 }
spastor 0:1c358ea10753 54 }
spastor 0:1c358ea10753 55
spastor 0:1c358ea10753 56 return result;
spastor 0:1c358ea10753 57 }
spastor 0:1c358ea10753 58 #endif
spastor 0:1c358ea10753 59
spastor 0:1c358ea10753 60 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 61 static connector_status_t sm_verify_udp_header(connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 62 {
spastor 0:1c358ea10753 63 connector_status_t result = connector_invalid_response;
spastor 0:1c358ea10753 64 connector_sm_packet_t * const recv_ptr = &sm_ptr->network.recv_packet;
spastor 0:1c358ea10753 65 uint8_t * data_ptr = recv_ptr->data;
spastor 0:1c358ea10753 66 uint8_t const version_and_type = *data_ptr++;
spastor 0:1c358ea10753 67 uint8_t const version = version_and_type >> 4;
spastor 0:1c358ea10753 68 connector_sm_id_type_t const type = (connector_sm_id_type_t)(version_and_type & 0x0F);
spastor 0:1c358ea10753 69
spastor 0:1c358ea10753 70 if (version != SM_UDP_VERSION)
spastor 0:1c358ea10753 71 {
spastor 0:1c358ea10753 72 connector_debug_printf("sm_verify_udp_header: invalid SM UDP version [%d]\n", version);
spastor 0:1c358ea10753 73 result = connector_abort;
spastor 0:1c358ea10753 74 goto error;
spastor 0:1c358ea10753 75 }
spastor 0:1c358ea10753 76
spastor 0:1c358ea10753 77 if (type != sm_ptr->transport.id_type)
spastor 0:1c358ea10753 78 goto done;
spastor 0:1c358ea10753 79
spastor 0:1c358ea10753 80 if (memcmp(data_ptr, sm_ptr->transport.id, sm_ptr->transport.id_length))
spastor 0:1c358ea10753 81 goto done; /* not for us */
spastor 0:1c358ea10753 82
spastor 0:1c358ea10753 83 recv_ptr->processed_bytes = sm_ptr->transport.id_length + 1;
spastor 0:1c358ea10753 84 result = connector_working;
spastor 0:1c358ea10753 85
spastor 0:1c358ea10753 86 done:
spastor 0:1c358ea10753 87 error:
spastor 0:1c358ea10753 88 return result;
spastor 0:1c358ea10753 89 }
spastor 0:1c358ea10753 90 #endif
spastor 0:1c358ea10753 91
spastor 0:1c358ea10753 92 #if (defined CONNECTOR_SM_MULTIPART)
spastor 0:1c358ea10753 93 static connector_status_t sm_multipart_allocate(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 94 {
spastor 0:1c358ea10753 95 connector_status_t status = connector_working;
spastor 0:1c358ea10753 96 size_t const max_payload_bytes = sm_get_max_payload_bytes(sm_ptr);
spastor 0:1c358ea10753 97 size_t const max_session_bytes = (((max_payload_bytes * session->segments.count) + 3)/4) * 4; /* make sure it is word aligned */
spastor 0:1c358ea10753 98 size_t const size_array_bytes = sizeof(*session->segments.size_array) * session->segments.count;
spastor 0:1c358ea10753 99
spastor 0:1c358ea10753 100 ASSERT_GOTO(session->in.data == NULL, error);
spastor 0:1c358ea10753 101 session->in.bytes = max_session_bytes + size_array_bytes;
spastor 0:1c358ea10753 102 status = sm_allocate_user_buffer(connector_ptr, &session->in);
spastor 0:1c358ea10753 103 ASSERT_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 104 session->segments.size_array = (void *)(session->in.data + max_session_bytes); /* alignment issue is taken care where max_session_bytes is defined */
spastor 0:1c358ea10753 105 memset(session->segments.size_array, 0, size_array_bytes);
spastor 0:1c358ea10753 106
spastor 0:1c358ea10753 107 error:
spastor 0:1c358ea10753 108 return status;
spastor 0:1c358ea10753 109 }
spastor 0:1c358ea10753 110 #endif
spastor 0:1c358ea10753 111
spastor 0:1c358ea10753 112 static connector_status_t sm_more_data_callback(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 113 {
spastor 0:1c358ea10753 114 connector_status_t result;
spastor 0:1c358ea10753 115 connector_request_id_t request_id;
spastor 0:1c358ea10753 116 connector_callback_status_t callback_status;
spastor 0:1c358ea10753 117 connector_sm_more_data_t cb_data;
spastor 0:1c358ea10753 118
spastor 0:1c358ea10753 119 cb_data.transport = sm_ptr->network.transport;
spastor 0:1c358ea10753 120 request_id.sm_request = connector_request_id_sm_more_data;
spastor 0:1c358ea10753 121 callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cb_data);
spastor 0:1c358ea10753 122 result = sm_map_callback_status_to_connector_status(callback_status);
spastor 0:1c358ea10753 123
spastor 0:1c358ea10753 124 return result;
spastor 0:1c358ea10753 125 }
spastor 0:1c358ea10753 126
spastor 0:1c358ea10753 127 typedef struct
spastor 0:1c358ea10753 128 {
spastor 0:1c358ea10753 129 uint32_t request_id;
spastor 0:1c358ea10753 130 size_t bytes;
spastor 0:1c358ea10753 131
spastor 0:1c358ea10753 132 connector_bool_t isRequest;
spastor 0:1c358ea10753 133 connector_bool_t isResponseNeeded;
spastor 0:1c358ea10753 134 connector_bool_t isPackCmd;
spastor 0:1c358ea10753 135 connector_bool_t isMultipart;
spastor 0:1c358ea10753 136 connector_bool_t isCompressed;
spastor 0:1c358ea10753 137 connector_bool_t isError;
spastor 0:1c358ea10753 138
spastor 0:1c358ea10753 139 connector_sm_cmd_t command;
spastor 0:1c358ea10753 140
spastor 0:1c358ea10753 141 enum
spastor 0:1c358ea10753 142 {
spastor 0:1c358ea10753 143 sm_single_segment,
spastor 0:1c358ea10753 144 sm_multipart_first_segment,
spastor 0:1c358ea10753 145 sm_multipart_subsequent_segment
spastor 0:1c358ea10753 146 } type;
spastor 0:1c358ea10753 147
spastor 0:1c358ea10753 148 struct
spastor 0:1c358ea10753 149 {
spastor 0:1c358ea10753 150 uint8_t count;
spastor 0:1c358ea10753 151 uint8_t number;
spastor 0:1c358ea10753 152 } segment;
spastor 0:1c358ea10753 153
spastor 0:1c358ea10753 154 uint16_t crc16;
spastor 0:1c358ea10753 155 uint8_t cmd_status;
spastor 0:1c358ea10753 156 } sm_header_t;
spastor 0:1c358ea10753 157
spastor 0:1c358ea10753 158 static connector_status_t sm_process_header(connector_sm_packet_t * const recv_ptr, sm_header_t * const header)
spastor 0:1c358ea10753 159 {
spastor 0:1c358ea10753 160 connector_status_t result = connector_invalid_payload_packet;
spastor 0:1c358ea10753 161 uint8_t * data_ptr = &recv_ptr->data[recv_ptr->processed_bytes];
spastor 0:1c358ea10753 162 uint8_t * const segment = data_ptr;
spastor 0:1c358ea10753 163
spastor 0:1c358ea10753 164 header->segment.count = 1;
spastor 0:1c358ea10753 165 header->segment.number = 0;
spastor 0:1c358ea10753 166 header->bytes = 0;
spastor 0:1c358ea10753 167 header->command = connector_sm_cmd_opaque_response;
spastor 0:1c358ea10753 168 header->isError = connector_false;
spastor 0:1c358ea10753 169 header->isCompressed = connector_false;
spastor 0:1c358ea10753 170
spastor 0:1c358ea10753 171 {
spastor 0:1c358ea10753 172 uint8_t const info_field = message_load_u8(segment, info);
spastor 0:1c358ea10753 173 uint8_t const request_id_high_bits_mask = 0x03;
spastor 0:1c358ea10753 174
spastor 0:1c358ea10753 175 header->request_id = (info_field & request_id_high_bits_mask) << 8;
spastor 0:1c358ea10753 176 header->request_id |= message_load_u8(segment, request);
spastor 0:1c358ea10753 177
spastor 0:1c358ea10753 178 header->isMultipart = SmIsMultiPart(info_field);
spastor 0:1c358ea10753 179 header->isRequest = SmIsRequest(info_field);
spastor 0:1c358ea10753 180 header->isResponseNeeded = SmIsResponseNeeded(info_field);
spastor 0:1c358ea10753 181 }
spastor 0:1c358ea10753 182
spastor 0:1c358ea10753 183 if (header->isMultipart)
spastor 0:1c358ea10753 184 {
spastor 0:1c358ea10753 185 #if (defined CONNECTOR_SM_MULTIPART)
spastor 0:1c358ea10753 186 {
spastor 0:1c358ea10753 187 uint8_t * const segment0 = data_ptr;
spastor 0:1c358ea10753 188
spastor 0:1c358ea10753 189 header->segment.number = message_load_u8(segment0, segment);
spastor 0:1c358ea10753 190 if (header->segment.number > 0)
spastor 0:1c358ea10753 191 {
spastor 0:1c358ea10753 192 uint8_t * const segmentn = data_ptr;
spastor 0:1c358ea10753 193
spastor 0:1c358ea10753 194 header->cmd_status = 0;
spastor 0:1c358ea10753 195 header->type = sm_multipart_subsequent_segment;
spastor 0:1c358ea10753 196
spastor 0:1c358ea10753 197 if (header->isPackCmd)
spastor 0:1c358ea10753 198 {
spastor 0:1c358ea10753 199 header->bytes = record_end(segmentn) - sizeof header->crc16;
spastor 0:1c358ea10753 200 }
spastor 0:1c358ea10753 201 else
spastor 0:1c358ea10753 202 {
spastor 0:1c358ea10753 203 header->crc16 = message_load_be16(segmentn, crc);
spastor 0:1c358ea10753 204 message_store_be16(segmentn, crc, 0);
spastor 0:1c358ea10753 205 header->bytes = record_end(segmentn);
spastor 0:1c358ea10753 206 }
spastor 0:1c358ea10753 207 }
spastor 0:1c358ea10753 208 else
spastor 0:1c358ea10753 209 {
spastor 0:1c358ea10753 210 header->type = sm_multipart_first_segment;
spastor 0:1c358ea10753 211 header->segment.count = message_load_u8(segment0, count);
spastor 0:1c358ea10753 212 header->cmd_status = message_load_u8(segment0, cmd_status);
spastor 0:1c358ea10753 213
spastor 0:1c358ea10753 214 if (header->isPackCmd)
spastor 0:1c358ea10753 215 {
spastor 0:1c358ea10753 216 header->bytes = record_end(segment0) - sizeof header->crc16;
spastor 0:1c358ea10753 217 }
spastor 0:1c358ea10753 218 else
spastor 0:1c358ea10753 219 {
spastor 0:1c358ea10753 220 header->crc16 = message_load_be16(segment0, crc);
spastor 0:1c358ea10753 221 message_store_be16(segment0, crc, 0);
spastor 0:1c358ea10753 222 header->bytes = record_end(segment0);
spastor 0:1c358ea10753 223 }
spastor 0:1c358ea10753 224 }
spastor 0:1c358ea10753 225 }
spastor 0:1c358ea10753 226 #else
spastor 0:1c358ea10753 227 {
spastor 0:1c358ea10753 228 connector_debug_printf("Received multipart packet, but multipart is disabled\n");
spastor 0:1c358ea10753 229 connector_debug_printf("Review CONNECTOR_SM_MULTIPART and CONNECTOR_SM_MAX_RX_SEGMENTS defines\n");
spastor 0:1c358ea10753 230 goto error;
spastor 0:1c358ea10753 231 }
spastor 0:1c358ea10753 232 #endif
spastor 0:1c358ea10753 233 }
spastor 0:1c358ea10753 234 else
spastor 0:1c358ea10753 235 {
spastor 0:1c358ea10753 236 header->cmd_status = message_load_u8(segment, cmd_status);
spastor 0:1c358ea10753 237 if (header->isPackCmd)
spastor 0:1c358ea10753 238 {
spastor 0:1c358ea10753 239 header->bytes = record_end(segment) - sizeof header->crc16;
spastor 0:1c358ea10753 240 }
spastor 0:1c358ea10753 241 else
spastor 0:1c358ea10753 242 {
spastor 0:1c358ea10753 243 header->crc16 = message_load_be16(segment, crc);
spastor 0:1c358ea10753 244 message_store_be16(segment, crc, 0);
spastor 0:1c358ea10753 245 header->bytes = record_end(segment);
spastor 0:1c358ea10753 246 }
spastor 0:1c358ea10753 247 }
spastor 0:1c358ea10753 248
spastor 0:1c358ea10753 249 header->isCompressed = SmIsCompressed(header->cmd_status);
spastor 0:1c358ea10753 250 #if !(defined CONNECTOR_COMPRESSION)
spastor 0:1c358ea10753 251 if (header->isCompressed)
spastor 0:1c358ea10753 252 {
spastor 0:1c358ea10753 253 connector_debug_printf("sm_process_header: Received compressed packet, but compression is disabled!\n");
spastor 0:1c358ea10753 254 goto error;
spastor 0:1c358ea10753 255 }
spastor 0:1c358ea10753 256 #endif
spastor 0:1c358ea10753 257
spastor 0:1c358ea10753 258 if (header->isRequest)
spastor 0:1c358ea10753 259 {
spastor 0:1c358ea10753 260 header->command = (connector_sm_cmd_t)(header->cmd_status & 0x7F);
spastor 0:1c358ea10753 261 if (header->isPackCmd && (header->command == connector_sm_cmd_pack))
spastor 0:1c358ea10753 262 {
spastor 0:1c358ea10753 263 connector_debug_printf("sm_process_header: Pack command inside a pack command is not allowed!\n");
spastor 0:1c358ea10753 264 goto error;
spastor 0:1c358ea10753 265 }
spastor 0:1c358ea10753 266 header->isError = connector_false;
spastor 0:1c358ea10753 267 }
spastor 0:1c358ea10753 268 else
spastor 0:1c358ea10753 269 {
spastor 0:1c358ea10753 270 header->isError = SmIsError(header->cmd_status);
spastor 0:1c358ea10753 271 header->command = connector_sm_cmd_opaque_response;
spastor 0:1c358ea10753 272 }
spastor 0:1c358ea10753 273
spastor 0:1c358ea10753 274 if (!header->isPackCmd)
spastor 0:1c358ea10753 275 {
spastor 0:1c358ea10753 276 size_t const sm_bytes = recv_ptr->total_bytes - recv_ptr->processed_bytes;
spastor 0:1c358ea10753 277 uint16_t calculated_crc = 0;
spastor 0:1c358ea10753 278
spastor 0:1c358ea10753 279 calculated_crc = sm_calculate_crc16(calculated_crc, data_ptr, sm_bytes);
spastor 0:1c358ea10753 280 if(calculated_crc != header->crc16)
spastor 0:1c358ea10753 281 {
spastor 0:1c358ea10753 282 connector_debug_printf("sm_process_header: crc error!\n");
spastor 0:1c358ea10753 283 goto error;
spastor 0:1c358ea10753 284 }
spastor 0:1c358ea10753 285
spastor 0:1c358ea10753 286 if (header->isRequest)
spastor 0:1c358ea10753 287 header->isPackCmd = connector_bool(header->command == connector_sm_cmd_pack);
spastor 0:1c358ea10753 288 }
spastor 0:1c358ea10753 289
spastor 0:1c358ea10753 290 recv_ptr->processed_bytes += header->bytes;
spastor 0:1c358ea10753 291 result = connector_working;
spastor 0:1c358ea10753 292
spastor 0:1c358ea10753 293 error:
spastor 0:1c358ea10753 294 return result;
spastor 0:1c358ea10753 295 }
spastor 0:1c358ea10753 296
spastor 0:1c358ea10753 297 static connector_status_t sm_update_session(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr,
spastor 0:1c358ea10753 298 sm_header_t * const header, size_t const payload_bytes)
spastor 0:1c358ea10753 299 {
spastor 0:1c358ea10753 300 connector_status_t result = connector_invalid_payload_packet;
spastor 0:1c358ea10753 301 connector_sm_packet_t * const recv_ptr = &sm_ptr->network.recv_packet;
spastor 0:1c358ea10753 302 connector_bool_t const client_originated = connector_bool(!header->isRequest);
spastor 0:1c358ea10753 303 connector_sm_session_t * session = get_sm_session(sm_ptr, header->request_id, client_originated);
spastor 0:1c358ea10753 304
spastor 0:1c358ea10753 305 if (session == NULL)
spastor 0:1c358ea10753 306 {
spastor 0:1c358ea10753 307 session = sm_create_session(connector_ptr, sm_ptr, connector_false);
spastor 0:1c358ea10753 308 if (session == NULL)
spastor 0:1c358ea10753 309 {
spastor 0:1c358ea10753 310 result = connector_pending;
spastor 0:1c358ea10753 311 goto error;
spastor 0:1c358ea10753 312 }
spastor 0:1c358ea10753 313
spastor 0:1c358ea10753 314 session->request_id = header->request_id;
spastor 0:1c358ea10753 315 session->command = client_originated ? connector_sm_cmd_opaque_response : header->command;
spastor 0:1c358ea10753 316 }
spastor 0:1c358ea10753 317
spastor 0:1c358ea10753 318 if (header->segment.number == 0)
spastor 0:1c358ea10753 319 {
spastor 0:1c358ea10753 320 if (header->isCompressed) SmSetCompressed(session->flags);
spastor 0:1c358ea10753 321
spastor 0:1c358ea10753 322 if (header->isRequest)
spastor 0:1c358ea10753 323 {
spastor 0:1c358ea10753 324 if (header->isResponseNeeded) SmSetResponseNeeded(session->flags);
spastor 0:1c358ea10753 325 /* If the first segment of a multipart SMS that arrived was not segment0, previously stored session->command information is wrong as
spastor 0:1c358ea10753 326 * for multipart messages, type is only included in the 0th segment. Update it here */
spastor 0:1c358ea10753 327 session->command = header->command;
spastor 0:1c358ea10753 328 }
spastor 0:1c358ea10753 329 else if (header->isError)
spastor 0:1c358ea10753 330 {
spastor 0:1c358ea10753 331 uint16_t const error_value = LoadBE16(&recv_ptr->data[recv_ptr->processed_bytes]);
spastor 0:1c358ea10753 332
spastor 0:1c358ea10753 333 switch (error_value)
spastor 0:1c358ea10753 334 {
spastor 0:1c358ea10753 335 case connector_sm_error_in_request:
spastor 0:1c358ea10753 336 session->error = connector_sm_error_in_request;
spastor 0:1c358ea10753 337 break;
spastor 0:1c358ea10753 338
spastor 0:1c358ea10753 339 case connector_sm_error_unavailable:
spastor 0:1c358ea10753 340 session->error = connector_sm_error_unavailable;
spastor 0:1c358ea10753 341 break;
spastor 0:1c358ea10753 342
spastor 0:1c358ea10753 343 default:
spastor 0:1c358ea10753 344 session->error = connector_sm_error_unknown;
spastor 0:1c358ea10753 345 break;
spastor 0:1c358ea10753 346 }
spastor 0:1c358ea10753 347
spastor 0:1c358ea10753 348 SmSetError(session->flags);
spastor 0:1c358ea10753 349 recv_ptr->processed_bytes += sizeof error_value;
spastor 0:1c358ea10753 350 }
spastor 0:1c358ea10753 351
spastor 0:1c358ea10753 352 session->segments.count = header->segment.count;
spastor 0:1c358ea10753 353 }
spastor 0:1c358ea10753 354
spastor 0:1c358ea10753 355 #if (defined CONNECTOR_SM_MULTIPART)
spastor 0:1c358ea10753 356 if (header->isMultipart)
spastor 0:1c358ea10753 357 {
spastor 0:1c358ea10753 358 SmSetMultiPart(session->flags);
spastor 0:1c358ea10753 359 if (session->in.data == NULL)
spastor 0:1c358ea10753 360 {
spastor 0:1c358ea10753 361 if (header->segment.number > 0)
spastor 0:1c358ea10753 362 session->segments.count = sm_ptr->session.max_segments;
spastor 0:1c358ea10753 363
spastor 0:1c358ea10753 364 result = sm_multipart_allocate(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 365 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 366 ASSERT_GOTO(session->in.data != NULL, error);
spastor 0:1c358ea10753 367 }
spastor 0:1c358ea10753 368
spastor 0:1c358ea10753 369 if (session->segments.size_array[header->segment.number] == 0)
spastor 0:1c358ea10753 370 {
spastor 0:1c358ea10753 371 size_t const max_payload_bytes = sm_get_max_payload_bytes(sm_ptr);
spastor 0:1c358ea10753 372 uint8_t * copy_to = session->in.data + (header->segment.number * max_payload_bytes);
spastor 0:1c358ea10753 373
spastor 0:1c358ea10753 374 session->segments.size_array[header->segment.number] = payload_bytes;
spastor 0:1c358ea10753 375 memcpy(copy_to, &recv_ptr->data[recv_ptr->processed_bytes], payload_bytes);
spastor 0:1c358ea10753 376 session->segments.processed++;
spastor 0:1c358ea10753 377 }
spastor 0:1c358ea10753 378 else
spastor 0:1c358ea10753 379 {
spastor 0:1c358ea10753 380 connector_debug_printf("sm_update_session: duplicate segment %d, in id %d\n", header->segment.number, session->request_id);
spastor 0:1c358ea10753 381 }
spastor 0:1c358ea10753 382 }
spastor 0:1c358ea10753 383 else
spastor 0:1c358ea10753 384 #endif
spastor 0:1c358ea10753 385 {
spastor 0:1c358ea10753 386 session->in.bytes = payload_bytes;
spastor 0:1c358ea10753 387 if (payload_bytes > 0)
spastor 0:1c358ea10753 388 {
spastor 0:1c358ea10753 389 result = sm_allocate_user_buffer(connector_ptr, &session->in);
spastor 0:1c358ea10753 390 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 391 memcpy(session->in.data, &recv_ptr->data[recv_ptr->processed_bytes], payload_bytes);
spastor 0:1c358ea10753 392 }
spastor 0:1c358ea10753 393 else
spastor 0:1c358ea10753 394 session->in.data = NULL;
spastor 0:1c358ea10753 395 session->segments.processed++;
spastor 0:1c358ea10753 396 }
spastor 0:1c358ea10753 397
spastor 0:1c358ea10753 398 if (session->segments.processed >= session->segments.count)
spastor 0:1c358ea10753 399 {
spastor 0:1c358ea10753 400 session->bytes_processed = 0;
spastor 0:1c358ea10753 401 session->segments.processed = 0;
spastor 0:1c358ea10753 402 session->sm_state = connector_sm_state_process_payload;
spastor 0:1c358ea10753 403
spastor 0:1c358ea10753 404 #if (defined CONNECTOR_COMPRESSION)
spastor 0:1c358ea10753 405 if (SmIsCompressed(session->flags))
spastor 0:1c358ea10753 406 {
spastor 0:1c358ea10753 407 session->compress.out.data = NULL;
spastor 0:1c358ea10753 408 session->sm_state = connector_sm_state_decompress;
spastor 0:1c358ea10753 409 }
spastor 0:1c358ea10753 410 #endif
spastor 0:1c358ea10753 411 }
spastor 0:1c358ea10753 412
spastor 0:1c358ea10753 413 recv_ptr->processed_bytes += payload_bytes;
spastor 0:1c358ea10753 414 result = connector_working;
spastor 0:1c358ea10753 415
spastor 0:1c358ea10753 416 error:
spastor 0:1c358ea10753 417 return result;
spastor 0:1c358ea10753 418 }
spastor 0:1c358ea10753 419
spastor 0:1c358ea10753 420 static connector_status_t sm_process_packet(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 421 {
spastor 0:1c358ea10753 422 sm_header_t sm_header;
spastor 0:1c358ea10753 423 connector_status_t result;
spastor 0:1c358ea10753 424 connector_sm_packet_t * const recv_ptr = &sm_ptr->network.recv_packet;
spastor 0:1c358ea10753 425 size_t sm_bytes = recv_ptr->total_bytes - recv_ptr->processed_bytes;
spastor 0:1c358ea10753 426
spastor 0:1c358ea10753 427 sm_header.isPackCmd = connector_false;
spastor 0:1c358ea10753 428 sm_header.crc16 = 0;
spastor 0:1c358ea10753 429 do
spastor 0:1c358ea10753 430 {
spastor 0:1c358ea10753 431 result = sm_process_header(recv_ptr, &sm_header);
spastor 0:1c358ea10753 432 if (result != connector_working) goto error;
spastor 0:1c358ea10753 433
spastor 0:1c358ea10753 434 if ((sm_header.segment.count > sm_ptr->session.max_segments) || (sm_header.segment.number >= sm_ptr->session.max_segments))
spastor 0:1c358ea10753 435 {
spastor 0:1c358ea10753 436 connector_debug_printf("sm_process_packet: Exceeded maximum segments [%" PRIsize "/%" PRIsize "]!\n", sm_header.segment.count, sm_ptr->session.max_segments);
spastor 0:1c358ea10753 437 connector_debug_printf("Review CONNECTOR_SM_MULTIPART and CONNECTOR_SM_MAX_RX_SEGMENTS defines\n");
spastor 0:1c358ea10753 438 goto error;
spastor 0:1c358ea10753 439 }
spastor 0:1c358ea10753 440
spastor 0:1c358ea10753 441 if (sm_header.command == connector_sm_cmd_pack)
spastor 0:1c358ea10753 442 {
spastor 0:1c358ea10753 443 enum sm_pack_t
spastor 0:1c358ea10753 444 {
spastor 0:1c358ea10753 445 field_define(pack_header, flag, uint8_t),
spastor 0:1c358ea10753 446 field_define(pack_header, length, uint16_t),
spastor 0:1c358ea10753 447 record_end(pack_header)
spastor 0:1c358ea10753 448 };
spastor 0:1c358ea10753 449 uint8_t * const pack_header = &recv_ptr->data[recv_ptr->processed_bytes];
spastor 0:1c358ea10753 450 uint8_t const flag = message_load_u8(pack_header, flag);
spastor 0:1c358ea10753 451
spastor 0:1c358ea10753 452 #define SM_MESSAGE_PENDING 0x01
spastor 0:1c358ea10753 453 if ((flag & SM_MESSAGE_PENDING) == SM_MESSAGE_PENDING)
spastor 0:1c358ea10753 454 {
spastor 0:1c358ea10753 455 result = sm_more_data_callback(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 456 if (result != connector_working) goto error;
spastor 0:1c358ea10753 457 }
spastor 0:1c358ea10753 458 #undef SM_MESSAGE_PENDING
spastor 0:1c358ea10753 459
spastor 0:1c358ea10753 460 sm_bytes = message_load_be16(pack_header, length);
spastor 0:1c358ea10753 461 recv_ptr->processed_bytes += record_end(pack_header);
spastor 0:1c358ea10753 462 continue;
spastor 0:1c358ea10753 463 }
spastor 0:1c358ea10753 464
spastor 0:1c358ea10753 465 {
spastor 0:1c358ea10753 466 size_t const payload_bytes = sm_bytes - sm_header.bytes;
spastor 0:1c358ea10753 467
spastor 0:1c358ea10753 468 ASSERT(sm_bytes >= sm_header.bytes);
spastor 0:1c358ea10753 469 result = sm_update_session(connector_ptr, sm_ptr, &sm_header, payload_bytes);
spastor 0:1c358ea10753 470 }
spastor 0:1c358ea10753 471
spastor 0:1c358ea10753 472 if (!sm_header.isPackCmd) break;
spastor 0:1c358ea10753 473
spastor 0:1c358ea10753 474 {
spastor 0:1c358ea10753 475 size_t const sm_header_size = 5;
spastor 0:1c358ea10753 476 size_t const remaining_bytes = recv_ptr->total_bytes - recv_ptr->processed_bytes;
spastor 0:1c358ea10753 477
spastor 0:1c358ea10753 478 if (remaining_bytes < sm_header_size) break;
spastor 0:1c358ea10753 479 }
spastor 0:1c358ea10753 480
spastor 0:1c358ea10753 481 sm_bytes = LoadBE16(&recv_ptr->data[recv_ptr->processed_bytes]);
spastor 0:1c358ea10753 482 recv_ptr->processed_bytes += sizeof(uint16_t);
spastor 0:1c358ea10753 483
spastor 0:1c358ea10753 484 } while (recv_ptr->processed_bytes < recv_ptr->total_bytes);
spastor 0:1c358ea10753 485
spastor 0:1c358ea10753 486 result = connector_working;
spastor 0:1c358ea10753 487
spastor 0:1c358ea10753 488 error:
spastor 0:1c358ea10753 489 if (result == connector_invalid_payload_packet) /* unreliable method, so silently ignore the packet */
spastor 0:1c358ea10753 490 result = connector_working;
spastor 0:1c358ea10753 491
spastor 0:1c358ea10753 492 recv_ptr->total_bytes = 0;
spastor 0:1c358ea10753 493 recv_ptr->processed_bytes = 0;
spastor 0:1c358ea10753 494
spastor 0:1c358ea10753 495 return result;
spastor 0:1c358ea10753 496 }
spastor 0:1c358ea10753 497
spastor 0:1c358ea10753 498 static connector_status_t sm_receive_data(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 499 {
spastor 0:1c358ea10753 500 connector_status_t result = connector_pending;
spastor 0:1c358ea10753 501 connector_sm_packet_t * const recv_ptr = &sm_ptr->network.recv_packet;
spastor 0:1c358ea10753 502 connector_callback_status_t status;
spastor 0:1c358ea10753 503 connector_request_id_t request_id;
spastor 0:1c358ea10753 504 connector_network_receive_t read_data;
spastor 0:1c358ea10753 505
spastor 0:1c358ea10753 506 if (recv_ptr->total_bytes > 0) goto done;
spastor 0:1c358ea10753 507
spastor 0:1c358ea10753 508 read_data.handle = sm_ptr->network.handle;
spastor 0:1c358ea10753 509 read_data.buffer = recv_ptr->data;
spastor 0:1c358ea10753 510 read_data.bytes_available = sm_ptr->transport.mtu;
spastor 0:1c358ea10753 511 read_data.bytes_used = 0;
spastor 0:1c358ea10753 512
spastor 0:1c358ea10753 513 request_id.network_request = connector_request_id_network_receive;
spastor 0:1c358ea10753 514 status = connector_callback(connector_ptr->callback, sm_ptr->network.class_id, request_id, &read_data);
spastor 0:1c358ea10753 515 ASSERT(status != connector_callback_unrecognized);
spastor 0:1c358ea10753 516 switch (status)
spastor 0:1c358ea10753 517 {
spastor 0:1c358ea10753 518 case connector_callback_busy:
spastor 0:1c358ea10753 519 result = connector_idle;
spastor 0:1c358ea10753 520 goto done;
spastor 0:1c358ea10753 521
spastor 0:1c358ea10753 522 case connector_callback_continue:
spastor 0:1c358ea10753 523 recv_ptr->total_bytes = read_data.bytes_used;
spastor 0:1c358ea10753 524 recv_ptr->processed_bytes = 0;
spastor 0:1c358ea10753 525
spastor 0:1c358ea10753 526 switch (sm_ptr->network.transport)
spastor 0:1c358ea10753 527 {
spastor 0:1c358ea10753 528 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 529 case connector_transport_sms:
spastor 0:1c358ea10753 530 result = sm_verify_sms_preamble(sm_ptr);
spastor 0:1c358ea10753 531 switch(result)
spastor 0:1c358ea10753 532 {
spastor 0:1c358ea10753 533 case connector_working:
spastor 0:1c358ea10753 534 break;
spastor 0:1c358ea10753 535 case connector_invalid_response:
spastor 0:1c358ea10753 536 /* not Device Cloud packet? Ignore the packet */
spastor 0:1c358ea10753 537 recv_ptr->total_bytes = 0;
spastor 0:1c358ea10753 538 recv_ptr->processed_bytes = 0;
spastor 0:1c358ea10753 539 result = connector_working;
spastor 0:1c358ea10753 540 goto done;
spastor 0:1c358ea10753 541 default:
spastor 0:1c358ea10753 542 goto done;
spastor 0:1c358ea10753 543 }
spastor 0:1c358ea10753 544
spastor 0:1c358ea10753 545 result = sm_decode_segment(connector_ptr, recv_ptr);
spastor 0:1c358ea10753 546
spastor 0:1c358ea10753 547 /* Remove sms preamble */
spastor 0:1c358ea10753 548 sm_ptr->network.recv_packet.processed_bytes = 0;
spastor 0:1c358ea10753 549
spastor 0:1c358ea10753 550 break;
spastor 0:1c358ea10753 551 #endif
spastor 0:1c358ea10753 552
spastor 0:1c358ea10753 553 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 554 case connector_transport_udp:
spastor 0:1c358ea10753 555 result = sm_verify_udp_header(sm_ptr);
spastor 0:1c358ea10753 556 break;
spastor 0:1c358ea10753 557 #endif
spastor 0:1c358ea10753 558
spastor 0:1c358ea10753 559 default:
spastor 0:1c358ea10753 560 ASSERT_GOTO(connector_false, done);
spastor 0:1c358ea10753 561 break;
spastor 0:1c358ea10753 562 }
spastor 0:1c358ea10753 563
spastor 0:1c358ea10753 564 if(result != connector_working) goto done; /* not Device Cloud packet? */
spastor 0:1c358ea10753 565 result = sm_process_packet(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 566 break;
spastor 0:1c358ea10753 567
spastor 0:1c358ea10753 568 case connector_callback_abort:
spastor 0:1c358ea10753 569 result = connector_abort;
spastor 0:1c358ea10753 570 break;
spastor 0:1c358ea10753 571
spastor 0:1c358ea10753 572 default:
spastor 0:1c358ea10753 573 connector_debug_printf("sm_receive_data: callback returned error [%d]\n", status);
spastor 0:1c358ea10753 574 result = connector_device_error;
spastor 0:1c358ea10753 575 break;
spastor 0:1c358ea10753 576 }
spastor 0:1c358ea10753 577
spastor 0:1c358ea10753 578 sm_verify_result(sm_ptr, &result);
spastor 0:1c358ea10753 579
spastor 0:1c358ea10753 580 done:
spastor 0:1c358ea10753 581 return result;
spastor 0:1c358ea10753 582 }
spastor 0:1c358ea10753 583
spastor 0:1c358ea10753 584 #if (defined CONNECTOR_COMPRESSION)
spastor 0:1c358ea10753 585 static connector_status_t sm_decompress_data(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 586 {
spastor 0:1c358ea10753 587 connector_status_t status = connector_working;
spastor 0:1c358ea10753 588 size_t const max_payload_bytes = sm_get_max_payload_bytes(sm_ptr);
spastor 0:1c358ea10753 589 uint8_t zlib_header[] = {0x58, 0xC3};
spastor 0:1c358ea10753 590 z_streamp const zlib_ptr = &session->compress.zlib;
spastor 0:1c358ea10753 591 int zret;
spastor 0:1c358ea10753 592
spastor 0:1c358ea10753 593 if (session->compress.out.data == NULL)
spastor 0:1c358ea10753 594 {
spastor 0:1c358ea10753 595 session->compress.out.bytes = max_payload_bytes;
spastor 0:1c358ea10753 596 status = sm_allocate_user_buffer(connector_ptr, &session->compress.out);
spastor 0:1c358ea10753 597 ASSERT_GOTO(status == connector_working, done);
spastor 0:1c358ea10753 598
spastor 0:1c358ea10753 599 memset(zlib_ptr, 0, sizeof *zlib_ptr);
spastor 0:1c358ea10753 600 zret = inflateInit(zlib_ptr);
spastor 0:1c358ea10753 601 ASSERT_GOTO(zret == Z_OK, error);
spastor 0:1c358ea10753 602 zlib_ptr->next_out = session->compress.out.data;
spastor 0:1c358ea10753 603 zlib_ptr->avail_out = session->compress.out.bytes;
spastor 0:1c358ea10753 604 zlib_ptr->next_in = zlib_header;
spastor 0:1c358ea10753 605 zlib_ptr->avail_in = sizeof zlib_header;
spastor 0:1c358ea10753 606 }
spastor 0:1c358ea10753 607
spastor 0:1c358ea10753 608 while (zlib_ptr->avail_out > 0)
spastor 0:1c358ea10753 609 {
spastor 0:1c358ea10753 610 if (zlib_ptr->avail_in == 0)
spastor 0:1c358ea10753 611 {
spastor 0:1c358ea10753 612 if (session->segments.processed == session->segments.count)
spastor 0:1c358ea10753 613 {
spastor 0:1c358ea10753 614 SmSetLastData(session->flags);
spastor 0:1c358ea10753 615 break;
spastor 0:1c358ea10753 616 }
spastor 0:1c358ea10753 617 else
spastor 0:1c358ea10753 618 {
spastor 0:1c358ea10753 619 size_t const data_index = session->segments.processed * max_payload_bytes;
spastor 0:1c358ea10753 620
spastor 0:1c358ea10753 621 zlib_ptr->next_in = &session->in.data[data_index];
spastor 0:1c358ea10753 622 zlib_ptr->avail_in = SmIsMultiPart(session->flags) ? session->segments.size_array[session->segments.processed] : session->in.bytes;
spastor 0:1c358ea10753 623 session->segments.processed++;
spastor 0:1c358ea10753 624 }
spastor 0:1c358ea10753 625 }
spastor 0:1c358ea10753 626
spastor 0:1c358ea10753 627 zret = inflate(zlib_ptr, Z_NO_FLUSH);
spastor 0:1c358ea10753 628 switch(zret)
spastor 0:1c358ea10753 629 {
spastor 0:1c358ea10753 630 case Z_STREAM_END:
spastor 0:1c358ea10753 631 case Z_BUF_ERROR:
spastor 0:1c358ea10753 632 case Z_OK:
spastor 0:1c358ea10753 633 break;
spastor 0:1c358ea10753 634
spastor 0:1c358ea10753 635 default:
spastor 0:1c358ea10753 636 status = connector_abort;
spastor 0:1c358ea10753 637 connector_debug_printf("ZLIB Return value [%d]\n", zret);
spastor 0:1c358ea10753 638 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 639 break;
spastor 0:1c358ea10753 640 }
spastor 0:1c358ea10753 641 }
spastor 0:1c358ea10753 642
spastor 0:1c358ea10753 643 {
spastor 0:1c358ea10753 644 size_t const payload_bytes = session->compress.out.bytes - zlib_ptr->avail_out;
spastor 0:1c358ea10753 645
spastor 0:1c358ea10753 646 status = sm_pass_user_data(connector_ptr, session, session->compress.out.data, payload_bytes);
spastor 0:1c358ea10753 647 switch (status)
spastor 0:1c358ea10753 648 {
spastor 0:1c358ea10753 649 case connector_pending:
spastor 0:1c358ea10753 650 goto done;
spastor 0:1c358ea10753 651
spastor 0:1c358ea10753 652 case connector_working:
spastor 0:1c358ea10753 653 if (SmIsNotLastData(session->flags))
spastor 0:1c358ea10753 654 {
spastor 0:1c358ea10753 655 zlib_ptr->next_out = session->compress.out.data;
spastor 0:1c358ea10753 656 zlib_ptr->avail_out = session->compress.out.bytes;
spastor 0:1c358ea10753 657 goto done;
spastor 0:1c358ea10753 658 }
spastor 0:1c358ea10753 659 break;
spastor 0:1c358ea10753 660
spastor 0:1c358ea10753 661 default:
spastor 0:1c358ea10753 662 break;
spastor 0:1c358ea10753 663 }
spastor 0:1c358ea10753 664 }
spastor 0:1c358ea10753 665
spastor 0:1c358ea10753 666 error:
spastor 0:1c358ea10753 667 zret = inflateEnd(zlib_ptr);
spastor 0:1c358ea10753 668 ASSERT(zret == Z_OK);
spastor 0:1c358ea10753 669
spastor 0:1c358ea10753 670 if (status != connector_abort)
spastor 0:1c358ea10753 671 {
spastor 0:1c358ea10753 672 status = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->compress.out.data);
spastor 0:1c358ea10753 673 session->compress.out.data = NULL;
spastor 0:1c358ea10753 674 }
spastor 0:1c358ea10753 675
spastor 0:1c358ea10753 676 done:
spastor 0:1c358ea10753 677 return status;
spastor 0:1c358ea10753 678 }
spastor 0:1c358ea10753 679 #endif
spastor 0:1c358ea10753 680
spastor 0:1c358ea10753 681 static connector_status_t sm_handle_error(connector_data_t * const connector_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 682 {
spastor 0:1c358ea10753 683 connector_status_t result = connector_working;
spastor 0:1c358ea10753 684 connector_sm_state_t next_state = connector_sm_state_complete;
spastor 0:1c358ea10753 685
spastor 0:1c358ea10753 686 if (SmIsCloudOwned(session->flags) && SmIsRequest(session->flags))
spastor 0:1c358ea10753 687 next_state = connector_sm_state_send_data;
spastor 0:1c358ea10753 688
spastor 0:1c358ea10753 689 SmSetError(session->flags);
spastor 0:1c358ea10753 690 if (session->user.context != NULL) /* let the user know */
spastor 0:1c358ea10753 691 {
spastor 0:1c358ea10753 692 result = sm_inform_session_complete(connector_ptr, session);
spastor 0:1c358ea10753 693 if (result != connector_working) goto error;
spastor 0:1c358ea10753 694 }
spastor 0:1c358ea10753 695
spastor 0:1c358ea10753 696 result = sm_switch_path(connector_ptr, session, next_state);
spastor 0:1c358ea10753 697
spastor 0:1c358ea10753 698 error:
spastor 0:1c358ea10753 699 return result;
spastor 0:1c358ea10753 700 }
spastor 0:1c358ea10753 701
spastor 0:1c358ea10753 702 static connector_status_t sm_handle_complete(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 703 {
spastor 0:1c358ea10753 704 connector_status_t result = connector_working;
spastor 0:1c358ea10753 705
spastor 0:1c358ea10753 706 if (session->in.data != NULL)
spastor 0:1c358ea10753 707 {
spastor 0:1c358ea10753 708 result = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->in.data);
spastor 0:1c358ea10753 709 if (result != connector_working) goto error;
spastor 0:1c358ea10753 710 }
spastor 0:1c358ea10753 711
spastor 0:1c358ea10753 712 if (SmIsReboot(session->flags))
spastor 0:1c358ea10753 713 result = sm_process_reboot(connector_ptr);
spastor 0:1c358ea10753 714
spastor 0:1c358ea10753 715 switch(result)
spastor 0:1c358ea10753 716 {
spastor 0:1c358ea10753 717 case connector_abort:
spastor 0:1c358ea10753 718 /* Keep connector_abort as the result */
spastor 0:1c358ea10753 719 sm_delete_session(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 720 break;
spastor 0:1c358ea10753 721 case connector_pending:
spastor 0:1c358ea10753 722 break;
spastor 0:1c358ea10753 723 default:
spastor 0:1c358ea10753 724 result = sm_delete_session(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 725 }
spastor 0:1c358ea10753 726
spastor 0:1c358ea10753 727 error:
spastor 0:1c358ea10753 728 return result;
spastor 0:1c358ea10753 729 }
spastor 0:1c358ea10753 730
spastor 0:1c358ea10753 731 static connector_status_t sm_process_recv_path(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 732 {
spastor 0:1c358ea10753 733 connector_status_t result = connector_abort;
spastor 0:1c358ea10753 734
spastor 0:1c358ea10753 735 ASSERT_GOTO(session != NULL, error);
spastor 0:1c358ea10753 736 switch (session->sm_state)
spastor 0:1c358ea10753 737 {
spastor 0:1c358ea10753 738 case connector_sm_state_receive_data:
spastor 0:1c358ea10753 739 if (sm_ptr->timeout_in_seconds != SM_WAIT_FOREVER)
spastor 0:1c358ea10753 740 {
spastor 0:1c358ea10753 741 unsigned long current_time = 0;
spastor 0:1c358ea10753 742
spastor 0:1c358ea10753 743 result = get_system_time(connector_ptr, &current_time);
spastor 0:1c358ea10753 744 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 745 if (current_time > (session->start_time + sm_ptr->timeout_in_seconds))
spastor 0:1c358ea10753 746 {
spastor 0:1c358ea10753 747 session->sm_state = connector_sm_state_error;
spastor 0:1c358ea10753 748 session->error = connector_sm_error_timeout;
spastor 0:1c358ea10753 749 connector_debug_printf("Sm session [%u] timeout... start time:%u, current time:%u\n", session->request_id, session->start_time, current_time);
spastor 0:1c358ea10753 750 }
spastor 0:1c358ea10753 751 }
spastor 0:1c358ea10753 752
spastor 0:1c358ea10753 753 result = connector_idle; /* still receiving data, handled in sm_receive_data() */
spastor 0:1c358ea10753 754 break;
spastor 0:1c358ea10753 755
spastor 0:1c358ea10753 756 #if (defined CONNECTOR_COMPRESSION)
spastor 0:1c358ea10753 757 case connector_sm_state_decompress:
spastor 0:1c358ea10753 758 result = sm_decompress_data(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 759 break;
spastor 0:1c358ea10753 760 #endif
spastor 0:1c358ea10753 761
spastor 0:1c358ea10753 762 case connector_sm_state_process_payload:
spastor 0:1c358ea10753 763 result = sm_process_payload(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 764 break;
spastor 0:1c358ea10753 765
spastor 0:1c358ea10753 766 case connector_sm_state_complete:
spastor 0:1c358ea10753 767 result = sm_handle_complete(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 768 break;
spastor 0:1c358ea10753 769
spastor 0:1c358ea10753 770 case connector_sm_state_error:
spastor 0:1c358ea10753 771 result = sm_handle_error(connector_ptr, session);
spastor 0:1c358ea10753 772 break;
spastor 0:1c358ea10753 773
spastor 0:1c358ea10753 774 default:
spastor 0:1c358ea10753 775 ASSERT(connector_false);
spastor 0:1c358ea10753 776 break;
spastor 0:1c358ea10753 777 }
spastor 0:1c358ea10753 778
spastor 0:1c358ea10753 779 sm_verify_result(sm_ptr, &result);
spastor 0:1c358ea10753 780
spastor 0:1c358ea10753 781 error:
spastor 0:1c358ea10753 782 return result;
spastor 0:1c358ea10753 783 }
spastor 0:1c358ea10753 784