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 #include "connector_sm_utils.h"
spastor 0:1c358ea10753 13 #include "connector_sm_cmd.h"
spastor 0:1c358ea10753 14 #include "connector_sm_session.h"
spastor 0:1c358ea10753 15 #include "connector_sm_send.h"
spastor 0:1c358ea10753 16 #include "connector_sm_recv.h"
spastor 0:1c358ea10753 17
spastor 0:1c358ea10753 18 static connector_sm_data_t * get_sm_data(connector_data_t * const connector_ptr, connector_transport_t const transport)
spastor 0:1c358ea10753 19 {
spastor 0:1c358ea10753 20 connector_sm_data_t * sm_ptr = NULL;
spastor 0:1c358ea10753 21
spastor 0:1c358ea10753 22 switch (transport)
spastor 0:1c358ea10753 23 {
spastor 0:1c358ea10753 24 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 25 case connector_transport_udp:
spastor 0:1c358ea10753 26 sm_ptr = &connector_ptr->sm_udp;
spastor 0:1c358ea10753 27 break;
spastor 0:1c358ea10753 28 #endif
spastor 0:1c358ea10753 29
spastor 0:1c358ea10753 30 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 31 case connector_transport_sms:
spastor 0:1c358ea10753 32 sm_ptr = &connector_ptr->sm_sms;
spastor 0:1c358ea10753 33 break;
spastor 0:1c358ea10753 34 #endif
spastor 0:1c358ea10753 35
spastor 0:1c358ea10753 36 default:
spastor 0:1c358ea10753 37 ASSERT(connector_false);
spastor 0:1c358ea10753 38 break;
spastor 0:1c358ea10753 39 }
spastor 0:1c358ea10753 40
spastor 0:1c358ea10753 41 return sm_ptr;
spastor 0:1c358ea10753 42 }
spastor 0:1c358ea10753 43
spastor 0:1c358ea10753 44 static connector_status_t sm_initialize(connector_data_t * const connector_ptr, connector_transport_t const transport)
spastor 0:1c358ea10753 45 {
spastor 0:1c358ea10753 46 connector_status_t result = connector_init_error;
spastor 0:1c358ea10753 47 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, transport);
spastor 0:1c358ea10753 48
spastor 0:1c358ea10753 49 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 50 switch (transport)
spastor 0:1c358ea10753 51 {
spastor 0:1c358ea10753 52 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 53 case connector_transport_udp:
spastor 0:1c358ea10753 54 {
spastor 0:1c358ea10753 55 size_t const sm_udp_version_length = 1;
spastor 0:1c358ea10753 56
spastor 0:1c358ea10753 57 sm_ptr->transport.id_type = connector_sm_id_type_device_id;
spastor 0:1c358ea10753 58 sm_ptr->transport.id = connector_ptr->device_id;
spastor 0:1c358ea10753 59 sm_ptr->transport.id_length = DEVICE_ID_LENGTH;
spastor 0:1c358ea10753 60
spastor 0:1c358ea10753 61 sm_ptr->network.class_id = connector_class_id_network_udp;
spastor 0:1c358ea10753 62 sm_ptr->network.transport = connector_transport_udp;
spastor 0:1c358ea10753 63 sm_ptr->transport.mtu = SM_PACKET_SIZE_UDP;
spastor 0:1c358ea10753 64 sm_ptr->transport.sm_mtu_tx = sm_ptr->transport.mtu - (sm_ptr->transport.id_length + sm_udp_version_length);
spastor 0:1c358ea10753 65 sm_ptr->transport.sm_mtu_rx = sm_ptr->transport.sm_mtu_tx;
spastor 0:1c358ea10753 66 break;
spastor 0:1c358ea10753 67 }
spastor 0:1c358ea10753 68 #endif
spastor 0:1c358ea10753 69
spastor 0:1c358ea10753 70 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 71 case connector_transport_sms:
spastor 0:1c358ea10753 72 {
spastor 0:1c358ea10753 73 #if (defined CONNECTOR_CLOUD_SERVICE_ID)
spastor 0:1c358ea10753 74 static uint8_t service_id[] = CONNECTOR_CLOUD_SERVICE_ID;
spastor 0:1c358ea10753 75 size_t const service_id_length = sizeof service_id -1;
spastor 0:1c358ea10753 76 #else
spastor 0:1c358ea10753 77 size_t service_id_length = connector_ptr->device_cloud_service_id_length;
spastor 0:1c358ea10753 78 char * service_id = connector_ptr->device_cloud_service_id;
spastor 0:1c358ea10753 79 #endif
spastor 0:1c358ea10753 80
spastor 0:1c358ea10753 81 if (service_id_length)
spastor 0:1c358ea10753 82 {
spastor 0:1c358ea10753 83 sm_ptr->transport.id_type = connector_sm_id_type_service_id;
spastor 0:1c358ea10753 84 sm_ptr->transport.id = (uint8_t *)service_id;
spastor 0:1c358ea10753 85 sm_ptr->transport.id_length = service_id_length;
spastor 0:1c358ea10753 86 }
spastor 0:1c358ea10753 87 else
spastor 0:1c358ea10753 88 {
spastor 0:1c358ea10753 89 /* No shared codes used */
spastor 0:1c358ea10753 90 sm_ptr->transport.id_type = connector_sm_id_type_none;
spastor 0:1c358ea10753 91 sm_ptr->transport.id_length = 0;
spastor 0:1c358ea10753 92 }
spastor 0:1c358ea10753 93
spastor 0:1c358ea10753 94 sm_ptr->network.class_id = connector_class_id_network_sms;
spastor 0:1c358ea10753 95 sm_ptr->network.transport = connector_transport_sms;
spastor 0:1c358ea10753 96 sm_ptr->transport.mtu = SM_PACKET_SIZE_SMS_ENCODED;
spastor 0:1c358ea10753 97 {
spastor 0:1c358ea10753 98 if ((sm_ptr->transport.id != NULL) && (sm_ptr->transport.id_length > 0))
spastor 0:1c358ea10753 99 {
spastor 0:1c358ea10753 100 /* Preamble is NOT encoded85, so for a service-id like 'idgp': */
spastor 0:1c358ea10753 101 /*
spastor 0:1c358ea10753 102 For Tx: 'idgp '
spastor 0:1c358ea10753 103 There is room for 160-5=155 not encoded85 characters. After encoding, that will lead to a max payload of 155*4/5=124 bytes.
spastor 0:1c358ea10753 104 */
spastor 0:1c358ea10753 105 sm_ptr->transport.sm_mtu_tx = (((sm_ptr->transport.mtu - (sm_ptr->transport.id_length + SMS_SERVICEID_WRAPPER_TX_SIZE))*4) / 5);
spastor 0:1c358ea10753 106 /*
spastor 0:1c358ea10753 107 For Rx: '(idgp):'
spastor 0:1c358ea10753 108 There is room for 160-7=153 not encoded85 characters. After encoding, that will lead to a max payload of 153*4/5=122 bytes.
spastor 0:1c358ea10753 109 */
spastor 0:1c358ea10753 110
spastor 0:1c358ea10753 111 sm_ptr->transport.sm_mtu_rx = (((sm_ptr->transport.mtu - (sm_ptr->transport.id_length + SMS_SERVICEID_WRAPPER_RX_SIZE))*4) / 5);
spastor 0:1c358ea10753 112 }
spastor 0:1c358ea10753 113 else
spastor 0:1c358ea10753 114 {
spastor 0:1c358ea10753 115 sm_ptr->transport.sm_mtu_tx = ((sm_ptr->transport.mtu *4) / 5);
spastor 0:1c358ea10753 116 sm_ptr->transport.sm_mtu_rx = sm_ptr->transport.sm_mtu_tx;
spastor 0:1c358ea10753 117 }
spastor 0:1c358ea10753 118 }
spastor 0:1c358ea10753 119 break;
spastor 0:1c358ea10753 120 }
spastor 0:1c358ea10753 121 #endif
spastor 0:1c358ea10753 122
spastor 0:1c358ea10753 123 default:
spastor 0:1c358ea10753 124 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 125 break;
spastor 0:1c358ea10753 126 }
spastor 0:1c358ea10753 127
spastor 0:1c358ea10753 128 sm_ptr->transport.state = connector_transport_idle;
spastor 0:1c358ea10753 129 sm_ptr->pending.data = NULL;
spastor 0:1c358ea10753 130 sm_ptr->session.head = NULL;
spastor 0:1c358ea10753 131 sm_ptr->session.tail = NULL;
spastor 0:1c358ea10753 132 sm_ptr->session.current = NULL;
spastor 0:1c358ea10753 133 #if (defined CONNECTOR_SM_MAX_SESSIONS)
spastor 0:1c358ea10753 134 sm_ptr->session.max_sessions = CONNECTOR_SM_MAX_SESSIONS;
spastor 0:1c358ea10753 135 #else
spastor 0:1c358ea10753 136 sm_ptr->session.max_sessions = 2;
spastor 0:1c358ea10753 137 #endif
spastor 0:1c358ea10753 138 sm_ptr->session.active_client_sessions = 0;
spastor 0:1c358ea10753 139 sm_ptr->session.active_cloud_sessions = 0;
spastor 0:1c358ea10753 140
spastor 0:1c358ea10753 141 #if (defined CONNECTOR_SM_MAX_RX_SEGMENTS) && (CONNECTOR_SM_MAX_RX_SEGMENTS > 1) && (!defined CONNECTOR_SM_MULTIPART)
spastor 0:1c358ea10753 142 #error "You must define CONNECTOR_SM_MULTIPART in order to set CONNECTOR_SM_MAX_RX_SEGMENTS bigger than 1"
spastor 0:1c358ea10753 143 #endif
spastor 0:1c358ea10753 144
spastor 0:1c358ea10753 145 #if (defined CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS) && (CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS > 1) && (!defined CONNECTOR_SM_MULTIPART)
spastor 0:1c358ea10753 146 #error "You must define CONNECTOR_SM_MULTIPART in order to set CONNECTOR_SM_MAX_DATA_POINTS_SEGMENTS bigger than 1"
spastor 0:1c358ea10753 147 #endif
spastor 0:1c358ea10753 148
spastor 0:1c358ea10753 149 #if (defined CONNECTOR_SM_MAX_RX_SEGMENTS)
spastor 0:1c358ea10753 150 sm_ptr->session.max_segments = CONNECTOR_SM_MAX_RX_SEGMENTS;
spastor 0:1c358ea10753 151 #else
spastor 0:1c358ea10753 152 sm_ptr->session.max_segments = 1;
spastor 0:1c358ea10753 153 #endif
spastor 0:1c358ea10753 154 #if (defined CONNECTOR_SM_TIMEOUT)
spastor 0:1c358ea10753 155 sm_ptr->timeout_in_seconds = CONNECTOR_SM_TIMEOUT;
spastor 0:1c358ea10753 156 #else
spastor 0:1c358ea10753 157 sm_ptr->timeout_in_seconds = SM_WAIT_FOREVER;
spastor 0:1c358ea10753 158 #endif
spastor 0:1c358ea10753 159 sm_ptr->network.handle = NULL;
spastor 0:1c358ea10753 160 sm_ptr->close.status = connector_close_status_device_error;
spastor 0:1c358ea10753 161 sm_ptr->close.callback_needed = connector_true;
spastor 0:1c358ea10753 162 sm_ptr->close.stop_condition = connector_stop_immediately;
spastor 0:1c358ea10753 163
spastor 0:1c358ea10753 164 switch (transport)
spastor 0:1c358ea10753 165 {
spastor 0:1c358ea10753 166 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 167 case connector_transport_udp:
spastor 0:1c358ea10753 168 {
spastor 0:1c358ea10753 169 #if !(defined CONNECTOR_NETWORK_UDP_START)
spastor 0:1c358ea10753 170 {
spastor 0:1c358ea10753 171 connector_config_connect_type_t config_connect;
spastor 0:1c358ea10753 172
spastor 0:1c358ea10753 173 result = get_config_connect_status(connector_ptr, connector_request_id_config_network_udp, &config_connect);
spastor 0:1c358ea10753 174 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 175
spastor 0:1c358ea10753 176 sm_ptr->transport.connect_type = config_connect.type;
spastor 0:1c358ea10753 177 }
spastor 0:1c358ea10753 178 #else
spastor 0:1c358ea10753 179 ASSERT((CONNECTOR_NETWORK_UDP_START == connector_connect_auto) || (CONNECTOR_NETWORK_UDP_START == connector_connect_manual));
spastor 0:1c358ea10753 180 sm_ptr->transport.connect_type = CONNECTOR_NETWORK_UDP_START;
spastor 0:1c358ea10753 181 result = connector_working;
spastor 0:1c358ea10753 182 #endif
spastor 0:1c358ea10753 183 break;
spastor 0:1c358ea10753 184 }
spastor 0:1c358ea10753 185 #endif
spastor 0:1c358ea10753 186
spastor 0:1c358ea10753 187 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 188 case connector_transport_sms:
spastor 0:1c358ea10753 189 {
spastor 0:1c358ea10753 190 #if !(defined CONNECTOR_NETWORK_SMS_START)
spastor 0:1c358ea10753 191 {
spastor 0:1c358ea10753 192 connector_config_connect_type_t config_connect;
spastor 0:1c358ea10753 193
spastor 0:1c358ea10753 194 result = get_config_connect_status(connector_ptr, connector_request_id_config_network_sms, &config_connect);
spastor 0:1c358ea10753 195 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 196
spastor 0:1c358ea10753 197 sm_ptr->transport.connect_type = config_connect.type;
spastor 0:1c358ea10753 198 }
spastor 0:1c358ea10753 199 #else
spastor 0:1c358ea10753 200 ASSERT((CONNECTOR_NETWORK_SMS_START == connector_connect_auto) || (CONNECTOR_NETWORK_SMS_START == connector_connect_manual));
spastor 0:1c358ea10753 201 sm_ptr->transport.connect_type = CONNECTOR_NETWORK_SMS_START;
spastor 0:1c358ea10753 202 result = connector_working;
spastor 0:1c358ea10753 203 #endif
spastor 0:1c358ea10753 204 break;
spastor 0:1c358ea10753 205 }
spastor 0:1c358ea10753 206 #endif
spastor 0:1c358ea10753 207
spastor 0:1c358ea10753 208 default:
spastor 0:1c358ea10753 209 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 210 break;
spastor 0:1c358ea10753 211 }
spastor 0:1c358ea10753 212
spastor 0:1c358ea10753 213 error:
spastor 0:1c358ea10753 214 return result;
spastor 0:1c358ea10753 215 }
spastor 0:1c358ea10753 216
spastor 0:1c358ea10753 217 static connector_status_t connector_sm_init(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 218 {
spastor 0:1c358ea10753 219 connector_status_t status;
spastor 0:1c358ea10753 220
spastor 0:1c358ea10753 221 connector_ptr->last_request_id = SM_DEFAULT_REQUEST_ID;
spastor 0:1c358ea10753 222
spastor 0:1c358ea10753 223 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 224 status = sm_initialize(connector_ptr, connector_transport_udp);
spastor 0:1c358ea10753 225 ASSERT_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 226 #endif
spastor 0:1c358ea10753 227
spastor 0:1c358ea10753 228 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 229 status = sm_initialize(connector_ptr, connector_transport_sms);
spastor 0:1c358ea10753 230 ASSERT_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 231 #endif
spastor 0:1c358ea10753 232
spastor 0:1c358ea10753 233 error:
spastor 0:1c358ea10753 234 return status;
spastor 0:1c358ea10753 235 }
spastor 0:1c358ea10753 236
spastor 0:1c358ea10753 237 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 238 /* Return request_data's request_id field. This varies depending on the request. If this can't be done, set request_id to NULL */
spastor 0:1c358ea10753 239 static uint32_t * get_request_id_ptr(connector_initiate_request_t const request, void const * const request_data)
spastor 0:1c358ea10753 240 {
spastor 0:1c358ea10753 241 uint32_t * request_id;
spastor 0:1c358ea10753 242 switch (request)
spastor 0:1c358ea10753 243 {
spastor 0:1c358ea10753 244 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 245 case connector_initiate_data_point_single:
spastor 0:1c358ea10753 246 {
spastor 0:1c358ea10753 247 connector_request_data_point_single_t const * const data = request_data;
spastor 0:1c358ea10753 248
spastor 0:1c358ea10753 249 request_id = data->request_id;
spastor 0:1c358ea10753 250 break;
spastor 0:1c358ea10753 251 }
spastor 0:1c358ea10753 252 case connector_initiate_data_point_binary:
spastor 0:1c358ea10753 253 {
spastor 0:1c358ea10753 254 connector_request_data_point_binary_t const * const data = request_data;
spastor 0:1c358ea10753 255
spastor 0:1c358ea10753 256 request_id = data->request_id;
spastor 0:1c358ea10753 257 break;
spastor 0:1c358ea10753 258 }
spastor 0:1c358ea10753 259 #endif
spastor 0:1c358ea10753 260 #if (defined CONNECTOR_DATA_SERVICE)
spastor 0:1c358ea10753 261 case connector_initiate_send_data:
spastor 0:1c358ea10753 262 {
spastor 0:1c358ea10753 263 connector_request_data_service_send_t const * const data = request_data;
spastor 0:1c358ea10753 264
spastor 0:1c358ea10753 265 request_id = data->request_id;
spastor 0:1c358ea10753 266 break;
spastor 0:1c358ea10753 267 }
spastor 0:1c358ea10753 268 #endif
spastor 0:1c358ea10753 269 case connector_initiate_ping_request:
spastor 0:1c358ea10753 270 {
spastor 0:1c358ea10753 271 connector_sm_send_ping_request_t const * const data = request_data;
spastor 0:1c358ea10753 272
spastor 0:1c358ea10753 273 request_id = data->request_id;
spastor 0:1c358ea10753 274 break;
spastor 0:1c358ea10753 275 }
spastor 0:1c358ea10753 276 default:
spastor 0:1c358ea10753 277 request_id = NULL;
spastor 0:1c358ea10753 278 break;
spastor 0:1c358ea10753 279 }
spastor 0:1c358ea10753 280
spastor 0:1c358ea10753 281 return request_id;
spastor 0:1c358ea10753 282 }
spastor 0:1c358ea10753 283 #endif
spastor 0:1c358ea10753 284
spastor 0:1c358ea10753 285 static connector_status_t sm_initiate_action(connector_handle_t const handle, connector_initiate_request_t const request, void const * const request_data)
spastor 0:1c358ea10753 286 {
spastor 0:1c358ea10753 287 connector_status_t result = connector_service_busy;
spastor 0:1c358ea10753 288 connector_data_t * const connector_ptr = (connector_data_t *)handle;
spastor 0:1c358ea10753 289 connector_transport_t const * const transport_ptr = request_data;
spastor 0:1c358ea10753 290
spastor 0:1c358ea10753 291 ASSERT_GOTO(handle != NULL, error);
spastor 0:1c358ea10753 292 ASSERT_GOTO((request_data != NULL) || (request == connector_initiate_terminate), error);
spastor 0:1c358ea10753 293
spastor 0:1c358ea10753 294 switch (request)
spastor 0:1c358ea10753 295 {
spastor 0:1c358ea10753 296 case connector_initiate_transport_start:
spastor 0:1c358ea10753 297 {
spastor 0:1c358ea10753 298 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, *transport_ptr);
spastor 0:1c358ea10753 299
spastor 0:1c358ea10753 300 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 301 switch (sm_ptr->transport.state)
spastor 0:1c358ea10753 302 {
spastor 0:1c358ea10753 303 case connector_transport_idle:
spastor 0:1c358ea10753 304 case connector_transport_close:
spastor 0:1c358ea10753 305 break;
spastor 0:1c358ea10753 306
spastor 0:1c358ea10753 307 case connector_transport_terminate:
spastor 0:1c358ea10753 308 result = connector_device_terminated;
spastor 0:1c358ea10753 309 goto error;
spastor 0:1c358ea10753 310
spastor 0:1c358ea10753 311 default:
spastor 0:1c358ea10753 312 goto done;
spastor 0:1c358ea10753 313 }
spastor 0:1c358ea10753 314
spastor 0:1c358ea10753 315 if (sm_ptr->pending.data != NULL) goto error;
spastor 0:1c358ea10753 316 sm_ptr->pending.data = &sm_ptr->close.stop_condition; /* dummy */
spastor 0:1c358ea10753 317 sm_ptr->pending.request = request;
spastor 0:1c358ea10753 318 break;
spastor 0:1c358ea10753 319 }
spastor 0:1c358ea10753 320
spastor 0:1c358ea10753 321 case connector_initiate_terminate:
spastor 0:1c358ea10753 322 if (transport_ptr == NULL)
spastor 0:1c358ea10753 323 {
spastor 0:1c358ea10753 324 connector_transport_t transport;
spastor 0:1c358ea10753 325
spastor 0:1c358ea10753 326 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 327 transport = connector_transport_udp;
spastor 0:1c358ea10753 328 result = sm_initiate_action(handle, request, &transport); /* intended recursive */
spastor 0:1c358ea10753 329 if (result != connector_success) goto error;
spastor 0:1c358ea10753 330 #endif
spastor 0:1c358ea10753 331
spastor 0:1c358ea10753 332 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 333 transport = connector_transport_sms;
spastor 0:1c358ea10753 334 result = sm_initiate_action(handle, request, &transport); /* intended recursive */
spastor 0:1c358ea10753 335 if (result != connector_success) goto error;
spastor 0:1c358ea10753 336 #endif
spastor 0:1c358ea10753 337 }
spastor 0:1c358ea10753 338 else
spastor 0:1c358ea10753 339 {
spastor 0:1c358ea10753 340 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, *transport_ptr);
spastor 0:1c358ea10753 341
spastor 0:1c358ea10753 342 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 343 if (sm_ptr->transport.state != connector_transport_terminate)
spastor 0:1c358ea10753 344 {
spastor 0:1c358ea10753 345 sm_ptr->transport.state = connector_transport_close;
spastor 0:1c358ea10753 346 sm_ptr->close.callback_needed = connector_false;
spastor 0:1c358ea10753 347 sm_ptr->close.status = connector_close_status_device_terminated;
spastor 0:1c358ea10753 348 }
spastor 0:1c358ea10753 349 }
spastor 0:1c358ea10753 350 break;
spastor 0:1c358ea10753 351
spastor 0:1c358ea10753 352 case connector_initiate_transport_stop:
spastor 0:1c358ea10753 353 if (*transport_ptr == connector_transport_all)
spastor 0:1c358ea10753 354 {
spastor 0:1c358ea10753 355 connector_initiate_stop_request_t stop_request;
spastor 0:1c358ea10753 356
spastor 0:1c358ea10753 357 memcpy(&stop_request, request_data, sizeof stop_request);
spastor 0:1c358ea10753 358 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 359 stop_request.transport = connector_transport_udp;
spastor 0:1c358ea10753 360 result = sm_initiate_action(handle, request, &stop_request); /* intended recursive */
spastor 0:1c358ea10753 361 if (result == connector_success)
spastor 0:1c358ea10753 362 {
spastor 0:1c358ea10753 363 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, connector_transport_udp);
spastor 0:1c358ea10753 364
spastor 0:1c358ea10753 365 sm_ptr->close.callback_needed = connector_false;
spastor 0:1c358ea10753 366 }
spastor 0:1c358ea10753 367 else
spastor 0:1c358ea10753 368 goto error;
spastor 0:1c358ea10753 369 #endif
spastor 0:1c358ea10753 370
spastor 0:1c358ea10753 371 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 372 stop_request.transport = connector_transport_sms;
spastor 0:1c358ea10753 373 result = sm_initiate_action(handle, request, &stop_request); /* intended recursive */
spastor 0:1c358ea10753 374 if (result == connector_success)
spastor 0:1c358ea10753 375 {
spastor 0:1c358ea10753 376 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, connector_transport_sms);
spastor 0:1c358ea10753 377
spastor 0:1c358ea10753 378 sm_ptr->close.callback_needed = connector_false;
spastor 0:1c358ea10753 379 }
spastor 0:1c358ea10753 380 else
spastor 0:1c358ea10753 381 goto error;
spastor 0:1c358ea10753 382 #endif
spastor 0:1c358ea10753 383 }
spastor 0:1c358ea10753 384 else
spastor 0:1c358ea10753 385 {
spastor 0:1c358ea10753 386 connector_initiate_stop_request_t const * const stop_ptr = request_data;
spastor 0:1c358ea10753 387 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, stop_ptr->transport);
spastor 0:1c358ea10753 388
spastor 0:1c358ea10753 389 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 390 switch (sm_ptr->transport.state)
spastor 0:1c358ea10753 391 {
spastor 0:1c358ea10753 392 case connector_transport_terminate:
spastor 0:1c358ea10753 393 result = connector_device_terminated;
spastor 0:1c358ea10753 394 goto error;
spastor 0:1c358ea10753 395
spastor 0:1c358ea10753 396 case connector_transport_close:
spastor 0:1c358ea10753 397 result = connector_service_busy;
spastor 0:1c358ea10753 398 goto error;
spastor 0:1c358ea10753 399
spastor 0:1c358ea10753 400 default:
spastor 0:1c358ea10753 401 {
spastor 0:1c358ea10753 402 connector_initiate_stop_request_t const * const stop_request = request_data;
spastor 0:1c358ea10753 403
spastor 0:1c358ea10753 404 sm_ptr->close.status = connector_close_status_device_stopped;
spastor 0:1c358ea10753 405 sm_ptr->close.user_context = stop_ptr->user_context;
spastor 0:1c358ea10753 406 sm_ptr->close.stop_condition = stop_request->condition;
spastor 0:1c358ea10753 407 if ((stop_request->condition == connector_stop_immediately) || (sm_ptr->session.head == NULL))
spastor 0:1c358ea10753 408 sm_ptr->transport.state = connector_transport_close;
spastor 0:1c358ea10753 409 break;
spastor 0:1c358ea10753 410 }
spastor 0:1c358ea10753 411 }
spastor 0:1c358ea10753 412 }
spastor 0:1c358ea10753 413
spastor 0:1c358ea10753 414 break;
spastor 0:1c358ea10753 415
spastor 0:1c358ea10753 416 case connector_initiate_session_cancel:
spastor 0:1c358ea10753 417 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 418 case connector_initiate_session_cancel_all:
spastor 0:1c358ea10753 419 #endif
spastor 0:1c358ea10753 420 {
spastor 0:1c358ea10753 421 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, *transport_ptr);
spastor 0:1c358ea10753 422
spastor 0:1c358ea10753 423 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 424
spastor 0:1c358ea10753 425 if (sm_ptr->close.stop_condition == connector_wait_sessions_complete)
spastor 0:1c358ea10753 426 {
spastor 0:1c358ea10753 427 result = connector_unavailable;
spastor 0:1c358ea10753 428 goto error;
spastor 0:1c358ea10753 429 }
spastor 0:1c358ea10753 430
spastor 0:1c358ea10753 431 if (sm_ptr->pending.data != NULL)
spastor 0:1c358ea10753 432 goto error;
spastor 0:1c358ea10753 433
spastor 0:1c358ea10753 434 sm_ptr->pending.data = request_data;
spastor 0:1c358ea10753 435 sm_ptr->pending.request = request;
spastor 0:1c358ea10753 436 sm_ptr->pending.pending_internal = connector_false;
spastor 0:1c358ea10753 437 break;
spastor 0:1c358ea10753 438 }
spastor 0:1c358ea10753 439
spastor 0:1c358ea10753 440 case connector_initiate_ping_request:
spastor 0:1c358ea10753 441 #if (defined CONNECTOR_DATA_SERVICE)
spastor 0:1c358ea10753 442 case connector_initiate_send_data:
spastor 0:1c358ea10753 443 #endif
spastor 0:1c358ea10753 444 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 445 case connector_initiate_data_point_binary:
spastor 0:1c358ea10753 446 case connector_initiate_data_point_single:
spastor 0:1c358ea10753 447 #endif
spastor 0:1c358ea10753 448 {
spastor 0:1c358ea10753 449 connector_sm_data_t * const sm_ptr = get_sm_data(connector_ptr, *transport_ptr);
spastor 0:1c358ea10753 450
spastor 0:1c358ea10753 451 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 452
spastor 0:1c358ea10753 453 if (sm_ptr->close.stop_condition == connector_wait_sessions_complete)
spastor 0:1c358ea10753 454 {
spastor 0:1c358ea10753 455 result = connector_unavailable;
spastor 0:1c358ea10753 456 goto error;
spastor 0:1c358ea10753 457 }
spastor 0:1c358ea10753 458
spastor 0:1c358ea10753 459 switch (sm_ptr->transport.state)
spastor 0:1c358ea10753 460 {
spastor 0:1c358ea10753 461 case connector_transport_idle:
spastor 0:1c358ea10753 462 case connector_transport_open:
spastor 0:1c358ea10753 463 case connector_transport_close:
spastor 0:1c358ea10753 464 case connector_transport_terminate:
spastor 0:1c358ea10753 465 case connector_transport_wait_for_reconnect:
spastor 0:1c358ea10753 466 result = connector_unavailable;
spastor 0:1c358ea10753 467 goto error;
spastor 0:1c358ea10753 468 case connector_transport_send:
spastor 0:1c358ea10753 469 case connector_transport_receive:
spastor 0:1c358ea10753 470 case connector_transport_redirect:
spastor 0:1c358ea10753 471 {
spastor 0:1c358ea10753 472 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 473 uint32_t * request_id = NULL;
spastor 0:1c358ea10753 474 #endif
spastor 0:1c358ea10753 475 if (sm_ptr->close.stop_condition == connector_wait_sessions_complete)
spastor 0:1c358ea10753 476 {
spastor 0:1c358ea10753 477 result = connector_unavailable;
spastor 0:1c358ea10753 478 goto error;
spastor 0:1c358ea10753 479 }
spastor 0:1c358ea10753 480 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 481 request_id = get_request_id_ptr(request, request_data);
spastor 0:1c358ea10753 482 /* dp_initiate_data_point_single/binary() convert a connector_initiate_data_point_single/binary
spastor 0:1c358ea10753 483 * to a connector_initiate_send_data, but we want that that "hidden" connector_initiate_send_data
spastor 0:1c358ea10753 484 * use the same request_id, which has been already set by dp_send_message().
spastor 0:1c358ea10753 485 * */
spastor 0:1c358ea10753 486 if (sm_ptr->pending.pending_internal)
spastor 0:1c358ea10753 487 {
spastor 0:1c358ea10753 488 sm_ptr->pending.pending_internal = connector_false;
spastor 0:1c358ea10753 489 if (request_id != NULL)
spastor 0:1c358ea10753 490 {
spastor 0:1c358ea10753 491 /* Use the same request_id */
spastor 0:1c358ea10753 492 sm_ptr->pending.request_id = *request_id;
spastor 0:1c358ea10753 493 }
spastor 0:1c358ea10753 494 else
spastor 0:1c358ea10753 495 {
spastor 0:1c358ea10753 496 /* Update request_id */
spastor 0:1c358ea10753 497 result = sm_get_request_id(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 498 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 499 sm_ptr->pending.request_id = connector_ptr->last_request_id;
spastor 0:1c358ea10753 500 }
spastor 0:1c358ea10753 501 }
spastor 0:1c358ea10753 502 else
spastor 0:1c358ea10753 503 {
spastor 0:1c358ea10753 504 /* Update request_id */
spastor 0:1c358ea10753 505 result = sm_get_request_id(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 506 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 507 sm_ptr->pending.request_id = connector_ptr->last_request_id;
spastor 0:1c358ea10753 508 if (request_id != NULL)
spastor 0:1c358ea10753 509 *request_id = sm_ptr->pending.request_id;
spastor 0:1c358ea10753 510 }
spastor 0:1c358ea10753 511 #endif
spastor 0:1c358ea10753 512
spastor 0:1c358ea10753 513 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 514 switch (request)
spastor 0:1c358ea10753 515 {
spastor 0:1c358ea10753 516 case connector_initiate_data_point_single:
spastor 0:1c358ea10753 517 {
spastor 0:1c358ea10753 518 sm_ptr->pending.pending_internal = connector_true;
spastor 0:1c358ea10753 519 result = dp_initiate_data_point_single(request_data);
spastor 0:1c358ea10753 520 goto done_datapoints;
spastor 0:1c358ea10753 521 }
spastor 0:1c358ea10753 522 case connector_initiate_data_point_binary:
spastor 0:1c358ea10753 523 {
spastor 0:1c358ea10753 524 sm_ptr->pending.pending_internal = connector_true;
spastor 0:1c358ea10753 525 result = dp_initiate_data_point_binary(request_data);
spastor 0:1c358ea10753 526 goto done_datapoints;
spastor 0:1c358ea10753 527 }
spastor 0:1c358ea10753 528
spastor 0:1c358ea10753 529 default:
spastor 0:1c358ea10753 530 break;
spastor 0:1c358ea10753 531 }
spastor 0:1c358ea10753 532 #endif
spastor 0:1c358ea10753 533 if (sm_ptr->pending.data != NULL)
spastor 0:1c358ea10753 534 {
spastor 0:1c358ea10753 535 result = connector_service_busy;
spastor 0:1c358ea10753 536 goto error;
spastor 0:1c358ea10753 537 }
spastor 0:1c358ea10753 538 sm_ptr->pending.data = request_data;
spastor 0:1c358ea10753 539 sm_ptr->pending.request = request;
spastor 0:1c358ea10753 540 break;
spastor 0:1c358ea10753 541 }
spastor 0:1c358ea10753 542 default:
spastor 0:1c358ea10753 543 ASSERT(connector_false);
spastor 0:1c358ea10753 544 break;
spastor 0:1c358ea10753 545 }
spastor 0:1c358ea10753 546 break;
spastor 0:1c358ea10753 547 }
spastor 0:1c358ea10753 548 default:
spastor 0:1c358ea10753 549 ASSERT(connector_false);
spastor 0:1c358ea10753 550 break;
spastor 0:1c358ea10753 551 }
spastor 0:1c358ea10753 552
spastor 0:1c358ea10753 553 done:
spastor 0:1c358ea10753 554 result = connector_success;
spastor 0:1c358ea10753 555
spastor 0:1c358ea10753 556 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 557 done_datapoints:
spastor 0:1c358ea10753 558 #endif
spastor 0:1c358ea10753 559 error:
spastor 0:1c358ea10753 560 return result;
spastor 0:1c358ea10753 561 }
spastor 0:1c358ea10753 562
spastor 0:1c358ea10753 563 static void sm_init_network_packet(connector_sm_packet_t * const packet, void * const ptr)
spastor 0:1c358ea10753 564 {
spastor 0:1c358ea10753 565 packet->data = ptr;
spastor 0:1c358ea10753 566 packet->total_bytes = 0;
spastor 0:1c358ea10753 567 packet->processed_bytes = 0;
spastor 0:1c358ea10753 568 packet->pending_session = NULL;
spastor 0:1c358ea10753 569 }
spastor 0:1c358ea10753 570
spastor 0:1c358ea10753 571 static connector_status_t sm_open_transport(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 572 {
spastor 0:1c358ea10753 573 connector_status_t result;
spastor 0:1c358ea10753 574
spastor 0:1c358ea10753 575 {
spastor 0:1c358ea10753 576 connector_callback_status_t status;
spastor 0:1c358ea10753 577 connector_network_open_t open_data;
spastor 0:1c358ea10753 578 connector_request_id_t request_id;
spastor 0:1c358ea10753 579
spastor 0:1c358ea10753 580 switch(sm_ptr->network.class_id)
spastor 0:1c358ea10753 581 {
spastor 0:1c358ea10753 582 case connector_class_id_network_sms:
spastor 0:1c358ea10753 583 open_data.device_cloud_url = connector_ptr->device_cloud_phone;
spastor 0:1c358ea10753 584 break;
spastor 0:1c358ea10753 585
spastor 0:1c358ea10753 586 default:
spastor 0:1c358ea10753 587 open_data.device_cloud_url = connector_ptr->device_cloud_url;
spastor 0:1c358ea10753 588 break;
spastor 0:1c358ea10753 589 }
spastor 0:1c358ea10753 590 open_data.handle = NULL;
spastor 0:1c358ea10753 591
spastor 0:1c358ea10753 592 request_id.network_request = connector_request_id_network_open;
spastor 0:1c358ea10753 593 status = connector_callback(connector_ptr->callback, sm_ptr->network.class_id, request_id, &open_data);
spastor 0:1c358ea10753 594 ASSERT(status != connector_callback_unrecognized);
spastor 0:1c358ea10753 595 switch (status)
spastor 0:1c358ea10753 596 {
spastor 0:1c358ea10753 597 case connector_callback_continue:
spastor 0:1c358ea10753 598 result = connector_working;
spastor 0:1c358ea10753 599 sm_ptr->network.handle = open_data.handle;
spastor 0:1c358ea10753 600 break;
spastor 0:1c358ea10753 601
spastor 0:1c358ea10753 602 case connector_callback_abort:
spastor 0:1c358ea10753 603 result = connector_abort;
spastor 0:1c358ea10753 604 goto error;
spastor 0:1c358ea10753 605
spastor 0:1c358ea10753 606 case connector_callback_unrecognized:
spastor 0:1c358ea10753 607 result = connector_unavailable;
spastor 0:1c358ea10753 608 goto error;
spastor 0:1c358ea10753 609
spastor 0:1c358ea10753 610 case connector_callback_error:
spastor 0:1c358ea10753 611 result = connector_open_error;
spastor 0:1c358ea10753 612 goto error;
spastor 0:1c358ea10753 613
spastor 0:1c358ea10753 614 case connector_callback_busy:
spastor 0:1c358ea10753 615 result = connector_pending;
spastor 0:1c358ea10753 616 goto error;
spastor 0:1c358ea10753 617 }
spastor 0:1c358ea10753 618 }
spastor 0:1c358ea10753 619
spastor 0:1c358ea10753 620 {
spastor 0:1c358ea10753 621 void * data_ptr;
spastor 0:1c358ea10753 622 size_t const data_size = 2 * sm_ptr->transport.mtu;
spastor 0:1c358ea10753 623
spastor 0:1c358ea10753 624 result = malloc_data_buffer(connector_ptr, data_size, named_buffer_id(sm_packet), &data_ptr);
spastor 0:1c358ea10753 625 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 626
spastor 0:1c358ea10753 627 {
spastor 0:1c358ea10753 628 uint8_t * const send_data_ptr = data_ptr;
spastor 0:1c358ea10753 629 uint8_t * const recv_data_ptr = send_data_ptr + sm_ptr->transport.mtu;
spastor 0:1c358ea10753 630
spastor 0:1c358ea10753 631 sm_init_network_packet(&sm_ptr->network.send_packet, send_data_ptr);
spastor 0:1c358ea10753 632 sm_init_network_packet(&sm_ptr->network.recv_packet, recv_data_ptr);
spastor 0:1c358ea10753 633 }
spastor 0:1c358ea10753 634 }
spastor 0:1c358ea10753 635
spastor 0:1c358ea10753 636 error:
spastor 0:1c358ea10753 637 return result;
spastor 0:1c358ea10753 638 }
spastor 0:1c358ea10753 639
spastor 0:1c358ea10753 640 static connector_status_t sm_close_transport(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 641 {
spastor 0:1c358ea10753 642 connector_status_t result = sm_cancel_session(connector_ptr, sm_ptr, NULL);
spastor 0:1c358ea10753 643
spastor 0:1c358ea10753 644 if (result == connector_abort)
spastor 0:1c358ea10753 645 sm_ptr->close.status = connector_close_status_abort;
spastor 0:1c358ea10753 646
spastor 0:1c358ea10753 647 if (sm_ptr->network.handle != NULL)
spastor 0:1c358ea10753 648 {
spastor 0:1c358ea10753 649 connector_callback_status_t callback_status;
spastor 0:1c358ea10753 650 connector_request_id_t request_id;
spastor 0:1c358ea10753 651 connector_network_close_t close_data;
spastor 0:1c358ea10753 652
spastor 0:1c358ea10753 653 close_data.handle = sm_ptr->network.handle;
spastor 0:1c358ea10753 654 close_data.status = sm_ptr->close.status;
spastor 0:1c358ea10753 655
spastor 0:1c358ea10753 656 connector_debug_printf("sm_close_transport: status %d\n", sm_ptr->close.status);
spastor 0:1c358ea10753 657 request_id.network_request = connector_request_id_network_close;
spastor 0:1c358ea10753 658 callback_status = connector_callback(connector_ptr->callback, sm_ptr->network.class_id, request_id, &close_data);
spastor 0:1c358ea10753 659 ASSERT(callback_status != connector_callback_unrecognized);
spastor 0:1c358ea10753 660 switch (callback_status)
spastor 0:1c358ea10753 661 {
spastor 0:1c358ea10753 662 case connector_callback_busy:
spastor 0:1c358ea10753 663 result = connector_pending;
spastor 0:1c358ea10753 664 goto done;
spastor 0:1c358ea10753 665
spastor 0:1c358ea10753 666 case connector_callback_continue:
spastor 0:1c358ea10753 667 result = connector_working;
spastor 0:1c358ea10753 668 break;
spastor 0:1c358ea10753 669
spastor 0:1c358ea10753 670 default:
spastor 0:1c358ea10753 671 sm_ptr->close.status = connector_close_status_abort;
spastor 0:1c358ea10753 672 break;
spastor 0:1c358ea10753 673 }
spastor 0:1c358ea10753 674
spastor 0:1c358ea10753 675 sm_ptr->network.handle = NULL;
spastor 0:1c358ea10753 676 }
spastor 0:1c358ea10753 677
spastor 0:1c358ea10753 678 if (sm_ptr->network.send_packet.data != NULL)
spastor 0:1c358ea10753 679 {
spastor 0:1c358ea10753 680 if (free_data_buffer(connector_ptr, named_buffer_id(sm_packet), sm_ptr->network.send_packet.data) == connector_abort)
spastor 0:1c358ea10753 681 sm_ptr->close.status = connector_close_status_abort;
spastor 0:1c358ea10753 682 sm_ptr->network.send_packet.data = NULL;
spastor 0:1c358ea10753 683 }
spastor 0:1c358ea10753 684
spastor 0:1c358ea10753 685 if (sm_ptr->close.callback_needed)
spastor 0:1c358ea10753 686 {
spastor 0:1c358ea10753 687 connector_transport_t const transport = sm_ptr->network.transport;
spastor 0:1c358ea10753 688 connector_status_t const stop_status = connector_stop_callback(connector_ptr, transport, sm_ptr->close.user_context);
spastor 0:1c358ea10753 689
spastor 0:1c358ea10753 690 switch (stop_status)
spastor 0:1c358ea10753 691 {
spastor 0:1c358ea10753 692 case connector_abort:
spastor 0:1c358ea10753 693 sm_ptr->close.status = connector_close_status_abort;
spastor 0:1c358ea10753 694 break;
spastor 0:1c358ea10753 695
spastor 0:1c358ea10753 696 case connector_pending:
spastor 0:1c358ea10753 697 result = connector_pending;
spastor 0:1c358ea10753 698 goto done;
spastor 0:1c358ea10753 699
spastor 0:1c358ea10753 700 default:
spastor 0:1c358ea10753 701 break;
spastor 0:1c358ea10753 702 }
spastor 0:1c358ea10753 703 }
spastor 0:1c358ea10753 704
spastor 0:1c358ea10753 705 switch (sm_ptr->close.status)
spastor 0:1c358ea10753 706 {
spastor 0:1c358ea10753 707 case connector_close_status_abort:
spastor 0:1c358ea10753 708 case connector_close_status_device_terminated:
spastor 0:1c358ea10753 709 sm_ptr->transport.state = connector_transport_terminate;
spastor 0:1c358ea10753 710 result = (sm_ptr->close.status == connector_close_status_device_terminated) ? connector_device_terminated : connector_abort;
spastor 0:1c358ea10753 711 break;
spastor 0:1c358ea10753 712
spastor 0:1c358ea10753 713 default:
spastor 0:1c358ea10753 714 sm_ptr->transport.state = connector_transport_idle;
spastor 0:1c358ea10753 715 sm_ptr->close.stop_condition = connector_stop_immediately;
spastor 0:1c358ea10753 716 sm_ptr->close.callback_needed = connector_true;
spastor 0:1c358ea10753 717 break;
spastor 0:1c358ea10753 718 }
spastor 0:1c358ea10753 719
spastor 0:1c358ea10753 720 done:
spastor 0:1c358ea10753 721 return result;
spastor 0:1c358ea10753 722 }
spastor 0:1c358ea10753 723
spastor 0:1c358ea10753 724 static connector_status_t sm_state_machine(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 725 {
spastor 0:1c358ea10753 726 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 727 size_t iterations = 2;
spastor 0:1c358ea10753 728
spastor 0:1c358ea10753 729 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 730
spastor 0:1c358ea10753 731 if (sm_ptr->transport.state == connector_transport_terminate)
spastor 0:1c358ea10753 732 {
spastor 0:1c358ea10753 733 result = connector_device_terminated;
spastor 0:1c358ea10753 734 goto done;
spastor 0:1c358ea10753 735 }
spastor 0:1c358ea10753 736 result = sm_process_pending_data(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 737 if (result != connector_idle && result != connector_pending)
spastor 0:1c358ea10753 738 goto done;
spastor 0:1c358ea10753 739
spastor 0:1c358ea10753 740 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 741 result = dp_process_request(connector_ptr, sm_ptr->network.transport);
spastor 0:1c358ea10753 742 if ((result != connector_idle) && (result != connector_working))
spastor 0:1c358ea10753 743 goto error;
spastor 0:1c358ea10753 744 #endif
spastor 0:1c358ea10753 745
spastor 0:1c358ea10753 746 while (iterations > 0)
spastor 0:1c358ea10753 747 {
spastor 0:1c358ea10753 748 switch (sm_ptr->transport.state)
spastor 0:1c358ea10753 749 {
spastor 0:1c358ea10753 750 case connector_transport_idle:
spastor 0:1c358ea10753 751 if ((sm_ptr->transport.connect_type == connector_connect_auto) && (sm_ptr->close.status == connector_close_status_device_error))
spastor 0:1c358ea10753 752 sm_ptr->transport.state = connector_transport_open;
spastor 0:1c358ea10753 753 goto done;
spastor 0:1c358ea10753 754
spastor 0:1c358ea10753 755 case connector_transport_open:
spastor 0:1c358ea10753 756 result = sm_open_transport(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 757 switch(result)
spastor 0:1c358ea10753 758 {
spastor 0:1c358ea10753 759 case connector_working:
spastor 0:1c358ea10753 760 sm_ptr->transport.state = connector_transport_receive;
spastor 0:1c358ea10753 761 break;
spastor 0:1c358ea10753 762 case connector_pending:
spastor 0:1c358ea10753 763 sm_ptr->transport.state = connector_transport_open;
spastor 0:1c358ea10753 764 break;
spastor 0:1c358ea10753 765 case connector_open_error:
spastor 0:1c358ea10753 766 {
spastor 0:1c358ea10753 767 sm_ptr->transport.connect_at = 0;
spastor 0:1c358ea10753 768 sm_ptr->transport.state = connector_transport_wait_for_reconnect;
spastor 0:1c358ea10753 769 break;
spastor 0:1c358ea10753 770 }
spastor 0:1c358ea10753 771 default:
spastor 0:1c358ea10753 772 sm_ptr->transport.state = connector_transport_idle;
spastor 0:1c358ea10753 773 break;
spastor 0:1c358ea10753 774 }
spastor 0:1c358ea10753 775 goto done;
spastor 0:1c358ea10753 776
spastor 0:1c358ea10753 777 case connector_transport_receive:
spastor 0:1c358ea10753 778 sm_ptr->transport.state = connector_transport_send;
spastor 0:1c358ea10753 779 if (sm_ptr->network.handle != NULL) /* Give a chance to dynamic reconfiguration of the network when provisioning message arrives */
spastor 0:1c358ea10753 780 result = sm_receive_data(connector_ptr, sm_ptr); /* NOTE: sm_receive_data has precedence over sm_process_recv_path just to keep the receive buffer ready */
spastor 0:1c358ea10753 781 if ((result != connector_idle) && (result != connector_pending))
spastor 0:1c358ea10753 782 goto done;
spastor 0:1c358ea10753 783 else
spastor 0:1c358ea10753 784 {
spastor 0:1c358ea10753 785 connector_sm_session_t * session = (sm_ptr->session.current == NULL) ? sm_ptr->session.head : sm_ptr->session.current;
spastor 0:1c358ea10753 786
spastor 0:1c358ea10753 787 if (session == NULL) goto done;
spastor 0:1c358ea10753 788
spastor 0:1c358ea10753 789 do
spastor 0:1c358ea10753 790 {
spastor 0:1c358ea10753 791 if (session->sm_state >= connector_sm_state_receive_data)
spastor 0:1c358ea10753 792 {
spastor 0:1c358ea10753 793 result = sm_process_recv_path(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 794 switch (result)
spastor 0:1c358ea10753 795 {
spastor 0:1c358ea10753 796 case connector_working:
spastor 0:1c358ea10753 797 case connector_pending:
spastor 0:1c358ea10753 798 sm_ptr->session.current = session->next;
spastor 0:1c358ea10753 799 goto done;
spastor 0:1c358ea10753 800
spastor 0:1c358ea10753 801 case connector_idle:
spastor 0:1c358ea10753 802 break;
spastor 0:1c358ea10753 803
spastor 0:1c358ea10753 804 default:
spastor 0:1c358ea10753 805 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 806 break;
spastor 0:1c358ea10753 807 }
spastor 0:1c358ea10753 808 }
spastor 0:1c358ea10753 809
spastor 0:1c358ea10753 810 session = session->next;
spastor 0:1c358ea10753 811 sm_ptr->session.current = session;
spastor 0:1c358ea10753 812
spastor 0:1c358ea10753 813 } while (session != NULL);
spastor 0:1c358ea10753 814 }
spastor 0:1c358ea10753 815
spastor 0:1c358ea10753 816 iterations--;
spastor 0:1c358ea10753 817 break;
spastor 0:1c358ea10753 818
spastor 0:1c358ea10753 819 case connector_transport_send:
spastor 0:1c358ea10753 820 {
spastor 0:1c358ea10753 821 connector_sm_session_t * session = (sm_ptr->session.current == NULL) ? sm_ptr->session.head : sm_ptr->session.current;
spastor 0:1c358ea10753 822
spastor 0:1c358ea10753 823 sm_ptr->transport.state = connector_transport_receive;
spastor 0:1c358ea10753 824 if (session == NULL) goto done;
spastor 0:1c358ea10753 825
spastor 0:1c358ea10753 826 do
spastor 0:1c358ea10753 827 {
spastor 0:1c358ea10753 828 if (session->sm_state <= connector_sm_state_send_data)
spastor 0:1c358ea10753 829 {
spastor 0:1c358ea10753 830 result = sm_process_send_path(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 831 switch (result)
spastor 0:1c358ea10753 832 {
spastor 0:1c358ea10753 833 case connector_working:
spastor 0:1c358ea10753 834 case connector_pending:
spastor 0:1c358ea10753 835 sm_ptr->session.current = session->next;
spastor 0:1c358ea10753 836 goto done;
spastor 0:1c358ea10753 837
spastor 0:1c358ea10753 838 case connector_idle:
spastor 0:1c358ea10753 839 break;
spastor 0:1c358ea10753 840
spastor 0:1c358ea10753 841 default:
spastor 0:1c358ea10753 842 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 843 break;
spastor 0:1c358ea10753 844 }
spastor 0:1c358ea10753 845 }
spastor 0:1c358ea10753 846
spastor 0:1c358ea10753 847 session = session->next;
spastor 0:1c358ea10753 848 sm_ptr->session.current = session;
spastor 0:1c358ea10753 849
spastor 0:1c358ea10753 850 } while (session != NULL);
spastor 0:1c358ea10753 851
spastor 0:1c358ea10753 852 iterations--;
spastor 0:1c358ea10753 853 break;
spastor 0:1c358ea10753 854 }
spastor 0:1c358ea10753 855
spastor 0:1c358ea10753 856 case connector_transport_close:
spastor 0:1c358ea10753 857 result = sm_close_transport(connector_ptr, sm_ptr);
spastor 0:1c358ea10753 858 goto done;
spastor 0:1c358ea10753 859
spastor 0:1c358ea10753 860 case connector_transport_terminate:
spastor 0:1c358ea10753 861 break;
spastor 0:1c358ea10753 862
spastor 0:1c358ea10753 863 case connector_transport_wait_for_reconnect:
spastor 0:1c358ea10753 864 {
spastor 0:1c358ea10753 865 if (sm_ptr->transport.connect_at == 0)
spastor 0:1c358ea10753 866 {
spastor 0:1c358ea10753 867 #if (defined CONNECTOR_TRANSPORT_UDP) && defined CONNECTOR_TRANSPORT_SMS
spastor 0:1c358ea10753 868 connector_debug_printf("Waiting %d second before reconnecting SM transport %s\n",
spastor 0:1c358ea10753 869 CONNECTOR_TRANSPORT_RECONNECT_AFTER, sm_ptr->network.transport == connector_transport_udp ? "UDP" : "SMS");
spastor 0:1c358ea10753 870 #elif defined CONNECTOR_TRANSPORT_UDP
spastor 0:1c358ea10753 871 connector_debug_printf("Waiting %d second before reconnecting SM transport UDP\n", CONNECTOR_TRANSPORT_RECONNECT_AFTER);
spastor 0:1c358ea10753 872 #else
spastor 0:1c358ea10753 873 connector_debug_printf("Waiting %d second before reconnecting SM transport SMS\n", CONNECTOR_TRANSPORT_RECONNECT_AFTER);
spastor 0:1c358ea10753 874 #endif
spastor 0:1c358ea10753 875 result = get_system_time(connector_ptr, &sm_ptr->transport.connect_at);
spastor 0:1c358ea10753 876 if (result != connector_working)
spastor 0:1c358ea10753 877 goto done;
spastor 0:1c358ea10753 878 sm_ptr->transport.connect_at += CONNECTOR_TRANSPORT_RECONNECT_AFTER;
spastor 0:1c358ea10753 879 } else {
spastor 0:1c358ea10753 880 unsigned long int uptime;
spastor 0:1c358ea10753 881
spastor 0:1c358ea10753 882 result = get_system_time(connector_ptr, &uptime);
spastor 0:1c358ea10753 883 if (result != connector_working)
spastor 0:1c358ea10753 884 goto done;
spastor 0:1c358ea10753 885 if (uptime >= sm_ptr->transport.connect_at)
spastor 0:1c358ea10753 886 sm_ptr->transport.state = connector_transport_open;
spastor 0:1c358ea10753 887 }
spastor 0:1c358ea10753 888 break;
spastor 0:1c358ea10753 889 }
spastor 0:1c358ea10753 890 default:
spastor 0:1c358ea10753 891 ASSERT_GOTO(connector_false, error);
spastor 0:1c358ea10753 892 break;
spastor 0:1c358ea10753 893 }
spastor 0:1c358ea10753 894 }
spastor 0:1c358ea10753 895
spastor 0:1c358ea10753 896 error:
spastor 0:1c358ea10753 897 done:
spastor 0:1c358ea10753 898 return result;
spastor 0:1c358ea10753 899 }
spastor 0:1c358ea10753 900
spastor 0:1c358ea10753 901 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 902 static connector_status_t connector_udp_step(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 903 {
spastor 0:1c358ea10753 904 return sm_state_machine(connector_ptr, &connector_ptr->sm_udp);
spastor 0:1c358ea10753 905 }
spastor 0:1c358ea10753 906 #endif
spastor 0:1c358ea10753 907
spastor 0:1c358ea10753 908 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 909 static connector_status_t connector_sms_step(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 910 {
spastor 0:1c358ea10753 911 return sm_state_machine(connector_ptr, &connector_ptr->sm_sms);
spastor 0:1c358ea10753 912 }
spastor 0:1c358ea10753 913 #endif
spastor 0:1c358ea10753 914