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
spastor 0:1c358ea10753 13 /* This was moved here to correct a software engineering defect.
spastor 0:1c358ea10753 14 * These defines need to be private
spastor 0:1c358ea10753 15 */
spastor 0:1c358ea10753 16
spastor 0:1c358ea10753 17 #include <stddef.h>
spastor 0:1c358ea10753 18
spastor 0:1c358ea10753 19 #define CONNECTOR_CONST_PROTECTION
spastor 0:1c358ea10753 20
spastor 0:1c358ea10753 21 /* WARNING: connector_api.h must be the first connector_* header file
spastor 0:1c358ea10753 22 * to guarantee CONNECTOR_VERSION is properly applied to all files */
spastor 0:1c358ea10753 23
spastor 0:1c358ea10753 24 #include "connector_api.h"
spastor 0:1c358ea10753 25 #include "connector_debug.h"
spastor 0:1c358ea10753 26
spastor 0:1c358ea10753 27 #include "connector_info.h"
spastor 0:1c358ea10753 28 #include "connector_def.h"
spastor 0:1c358ea10753 29
spastor 0:1c358ea10753 30 #include "chk_config.h"
spastor 0:1c358ea10753 31 #include "bele.h"
spastor 0:1c358ea10753 32
spastor 0:1c358ea10753 33 static connector_status_t notify_error_status(connector_callback_t const callback, connector_class_id_t const class_number, connector_request_id_t const request_number, connector_status_t const status);
spastor 0:1c358ea10753 34 #include "os_intf.h"
spastor 0:1c358ea10753 35 #include "connector_global_config.h"
spastor 0:1c358ea10753 36
spastor 0:1c358ea10753 37 static connector_status_t connector_stop_callback(connector_data_t * const connector_ptr, connector_transport_t const transport, void * const user_context);
spastor 0:1c358ea10753 38 #if !(defined CONNECTOR_NETWORK_TCP_START) || (defined CONNECTOR_TRANSPORT_UDP) || defined (CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 39 static connector_status_t get_config_connect_status(connector_data_t * const connector_ptr, connector_request_id_config_t const request_id, connector_config_connect_type_t * const config_ptr);
spastor 0:1c358ea10753 40 #endif
spastor 0:1c358ea10753 41
spastor 0:1c358ea10753 42 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 43 #include "connector_data_point.h"
spastor 0:1c358ea10753 44 #endif
spastor 0:1c358ea10753 45
spastor 0:1c358ea10753 46 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 47 #include "connector_edp.h"
spastor 0:1c358ea10753 48 #endif
spastor 0:1c358ea10753 49
spastor 0:1c358ea10753 50 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 51 #include "connector_sm.h"
spastor 0:1c358ea10753 52 #endif
spastor 0:1c358ea10753 53
spastor 0:1c358ea10753 54 #ifdef CONNECTOR_NO_MALLOC
spastor 0:1c358ea10753 55 #include "connector_static_buffer.h"
spastor 0:1c358ea10753 56 #endif
spastor 0:1c358ea10753 57
spastor 0:1c358ea10753 58 #define DEVICE_ID_LENGTH 16
spastor 0:1c358ea10753 59
spastor 0:1c358ea10753 60
spastor 0:1c358ea10753 61 static char const connector_signature[] = CONNECTOR_SW_VERSION;
spastor 0:1c358ea10753 62
spastor 0:1c358ea10753 63 #if !(defined CONNECTOR_NETWORK_TCP_START) || (defined CONNECTOR_TRANSPORT_UDP) || defined (CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 64 static connector_status_t get_config_connect_status(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 65 connector_request_id_config_t const config_request_id,
spastor 0:1c358ea10753 66 connector_config_connect_type_t * const config_connect)
spastor 0:1c358ea10753 67 {
spastor 0:1c358ea10753 68 connector_status_t result = connector_working;
spastor 0:1c358ea10753 69
spastor 0:1c358ea10753 70 ASSERT(config_connect != NULL);
spastor 0:1c358ea10753 71 ASSERT((config_request_id == connector_request_id_config_network_tcp) ||
spastor 0:1c358ea10753 72 (config_request_id == connector_request_id_config_network_udp) ||
spastor 0:1c358ea10753 73 (config_request_id == connector_request_id_config_network_sms));
spastor 0:1c358ea10753 74
spastor 0:1c358ea10753 75 config_connect->type = connector_connect_auto;
spastor 0:1c358ea10753 76
spastor 0:1c358ea10753 77 {
spastor 0:1c358ea10753 78 connector_callback_status_t status;
spastor 0:1c358ea10753 79 connector_request_id_t request_id;
spastor 0:1c358ea10753 80
spastor 0:1c358ea10753 81 request_id.config_request = config_request_id;
spastor 0:1c358ea10753 82 status = connector_callback(connector_ptr->callback, connector_class_id_config, request_id, config_connect);
spastor 0:1c358ea10753 83
spastor 0:1c358ea10753 84 switch (status)
spastor 0:1c358ea10753 85 {
spastor 0:1c358ea10753 86 case connector_callback_continue:
spastor 0:1c358ea10753 87 switch (config_connect->type)
spastor 0:1c358ea10753 88 {
spastor 0:1c358ea10753 89 case connector_connect_auto:
spastor 0:1c358ea10753 90 case connector_connect_manual:
spastor 0:1c358ea10753 91 break;
spastor 0:1c358ea10753 92 default:
spastor 0:1c358ea10753 93 notify_error_status(connector_ptr->callback, connector_class_id_config, request_id, connector_invalid_data_range);
spastor 0:1c358ea10753 94 result = connector_abort;
spastor 0:1c358ea10753 95 break;
spastor 0:1c358ea10753 96 }
spastor 0:1c358ea10753 97 break;
spastor 0:1c358ea10753 98
spastor 0:1c358ea10753 99 case connector_callback_busy:
spastor 0:1c358ea10753 100 case connector_callback_abort:
spastor 0:1c358ea10753 101 case connector_callback_error:
spastor 0:1c358ea10753 102 result = connector_abort;
spastor 0:1c358ea10753 103 break;
spastor 0:1c358ea10753 104
spastor 0:1c358ea10753 105 case connector_callback_unrecognized:
spastor 0:1c358ea10753 106 break;
spastor 0:1c358ea10753 107 }
spastor 0:1c358ea10753 108 }
spastor 0:1c358ea10753 109 return result;
spastor 0:1c358ea10753 110 }
spastor 0:1c358ea10753 111 #endif
spastor 0:1c358ea10753 112
spastor 0:1c358ea10753 113 static connector_status_t get_wan_device_id(connector_data_t * const connector_ptr,
spastor 0:1c358ea10753 114 uint8_t * const device_id,
spastor 0:1c358ea10753 115 connector_request_id_config_t config_request)
spastor 0:1c358ea10753 116 {
spastor 0:1c358ea10753 117
spastor 0:1c358ea10753 118 enum {
spastor 0:1c358ea10753 119 imei_device_id_prefix = 1,
spastor 0:1c358ea10753 120 esn_hex_device_id_prefix,
spastor 0:1c358ea10753 121 esn_dec_device_id_prefix,
spastor 0:1c358ea10753 122 meid_hex_device_id_prefix,
spastor 0:1c358ea10753 123 meid_dec_device_id_prefix
spastor 0:1c358ea10753 124 };
spastor 0:1c358ea10753 125
spastor 0:1c358ea10753 126 connector_status_t result;
spastor 0:1c358ea10753 127
spastor 0:1c358ea10753 128 result = get_config_wan_id(connector_ptr, config_request);
spastor 0:1c358ea10753 129 if (result == connector_working)
spastor 0:1c358ea10753 130 {
spastor 0:1c358ea10753 131 uint8_t * dst = device_id + (DEVICE_ID_LENGTH - connector_ptr->wan_id_length);
spastor 0:1c358ea10753 132
spastor 0:1c358ea10753 133 #if (defined CONNECTOR_DEBUG)
spastor 0:1c358ea10753 134 {
spastor 0:1c358ea10753 135 char * wan_string = NULL;
spastor 0:1c358ea10753 136
spastor 0:1c358ea10753 137 switch (connector_ptr->wan_type)
spastor 0:1c358ea10753 138 {
spastor 0:1c358ea10753 139 case connector_wan_type_imei:
spastor 0:1c358ea10753 140 wan_string = "IMEI";
spastor 0:1c358ea10753 141 break;
spastor 0:1c358ea10753 142 case connector_wan_type_esn:
spastor 0:1c358ea10753 143 wan_string = "ESN";
spastor 0:1c358ea10753 144 break;
spastor 0:1c358ea10753 145 case connector_wan_type_meid:
spastor 0:1c358ea10753 146 wan_string = "MEID";
spastor 0:1c358ea10753 147 break;
spastor 0:1c358ea10753 148 }
spastor 0:1c358ea10753 149 connector_debug_hexvalue(wan_string, connector_ptr->wan_id, connector_ptr->wan_id_length);
spastor 0:1c358ea10753 150 }
spastor 0:1c358ea10753 151 #endif
spastor 0:1c358ea10753 152 memcpy(dst, connector_ptr->wan_id, connector_ptr->wan_id_length);
spastor 0:1c358ea10753 153
spastor 0:1c358ea10753 154 switch (connector_ptr->wan_type)
spastor 0:1c358ea10753 155 {
spastor 0:1c358ea10753 156 case connector_wan_type_imei:
spastor 0:1c358ea10753 157 device_id[1] = imei_device_id_prefix;
spastor 0:1c358ea10753 158 break;
spastor 0:1c358ea10753 159 case connector_wan_type_esn:
spastor 0:1c358ea10753 160 device_id[1] = esn_hex_device_id_prefix;
spastor 0:1c358ea10753 161 break;
spastor 0:1c358ea10753 162 case connector_wan_type_meid:
spastor 0:1c358ea10753 163 device_id[1] = meid_hex_device_id_prefix;
spastor 0:1c358ea10753 164 break;
spastor 0:1c358ea10753 165 }
spastor 0:1c358ea10753 166 }
spastor 0:1c358ea10753 167
spastor 0:1c358ea10753 168 return result;
spastor 0:1c358ea10753 169 }
spastor 0:1c358ea10753 170
spastor 0:1c358ea10753 171
spastor 0:1c358ea10753 172 static connector_status_t manage_device_id(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 173 {
spastor 0:1c358ea10753 174 connector_status_t result = connector_working;
spastor 0:1c358ea10753 175
spastor 0:1c358ea10753 176 connector_ptr->connector_got_device_id = connector_false;
spastor 0:1c358ea10753 177
spastor 0:1c358ea10753 178 result = get_config_device_id_method(connector_ptr);
spastor 0:1c358ea10753 179 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 180
spastor 0:1c358ea10753 181 switch (connector_ptr->device_id_method)
spastor 0:1c358ea10753 182 {
spastor 0:1c358ea10753 183 case connector_device_id_method_manual:
spastor 0:1c358ea10753 184 result = get_config_device_id(connector_ptr);
spastor 0:1c358ea10753 185 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 186 {
spastor 0:1c358ea10753 187 uint8_t const null_device_id[DEVICE_ID_LENGTH] = {0x00};
spastor 0:1c358ea10753 188 /* If the returned Device ID is zero, Cloud Connector will ask the Device Cloud for a Device ID. */
spastor 0:1c358ea10753 189 if (memcmp(connector_ptr->device_id, null_device_id, sizeof null_device_id) == 0)
spastor 0:1c358ea10753 190 connector_ptr->connector_got_device_id = connector_false;
spastor 0:1c358ea10753 191 else
spastor 0:1c358ea10753 192 connector_ptr->connector_got_device_id = connector_true;
spastor 0:1c358ea10753 193 }
spastor 0:1c358ea10753 194 break;
spastor 0:1c358ea10753 195
spastor 0:1c358ea10753 196 case connector_device_id_method_auto:
spastor 0:1c358ea10753 197 {
spastor 0:1c358ea10753 198 result = get_config_connection_type(connector_ptr);
spastor 0:1c358ea10753 199 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 200
spastor 0:1c358ea10753 201 switch (connector_ptr->connection_type)
spastor 0:1c358ea10753 202 {
spastor 0:1c358ea10753 203 case connector_connection_type_lan:
spastor 0:1c358ea10753 204 {
spastor 0:1c358ea10753 205 result = get_config_mac_addr(connector_ptr);
spastor 0:1c358ea10753 206 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 207
spastor 0:1c358ea10753 208 connector_ptr->device_id[8] = connector_ptr->mac_addr[0];
spastor 0:1c358ea10753 209 connector_ptr->device_id[9] = connector_ptr->mac_addr[1];
spastor 0:1c358ea10753 210 connector_ptr->device_id[10] = connector_ptr->mac_addr[2];
spastor 0:1c358ea10753 211 connector_ptr->device_id[11] = 0xFF;
spastor 0:1c358ea10753 212 connector_ptr->device_id[12] = 0xFF;
spastor 0:1c358ea10753 213 connector_ptr->device_id[13] = connector_ptr->mac_addr[3];
spastor 0:1c358ea10753 214 connector_ptr->device_id[14] = connector_ptr->mac_addr[4];
spastor 0:1c358ea10753 215 connector_ptr->device_id[15] = connector_ptr->mac_addr[5];
spastor 0:1c358ea10753 216 }
spastor 0:1c358ea10753 217 break;
spastor 0:1c358ea10753 218
spastor 0:1c358ea10753 219 case connector_connection_type_wan:
spastor 0:1c358ea10753 220 {
spastor 0:1c358ea10753 221 result = get_config_wan_type(connector_ptr);
spastor 0:1c358ea10753 222 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 223
spastor 0:1c358ea10753 224 switch (connector_ptr->wan_type)
spastor 0:1c358ea10753 225 {
spastor 0:1c358ea10753 226 case connector_wan_type_imei:
spastor 0:1c358ea10753 227 result = get_wan_device_id(connector_ptr, connector_ptr->device_id, connector_request_id_config_imei_number);
spastor 0:1c358ea10753 228 break;
spastor 0:1c358ea10753 229 case connector_wan_type_esn:
spastor 0:1c358ea10753 230 result = get_wan_device_id(connector_ptr, connector_ptr->device_id, connector_request_id_config_esn);
spastor 0:1c358ea10753 231 break;
spastor 0:1c358ea10753 232 case connector_wan_type_meid:
spastor 0:1c358ea10753 233 result = get_wan_device_id(connector_ptr, connector_ptr->device_id, connector_request_id_config_meid);
spastor 0:1c358ea10753 234 break;
spastor 0:1c358ea10753 235 }
spastor 0:1c358ea10753 236 break;
spastor 0:1c358ea10753 237 }
spastor 0:1c358ea10753 238 }
spastor 0:1c358ea10753 239 connector_ptr->connector_got_device_id = connector_true;
spastor 0:1c358ea10753 240 break;
spastor 0:1c358ea10753 241 }
spastor 0:1c358ea10753 242 }
spastor 0:1c358ea10753 243 COND_ELSE_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 244
spastor 0:1c358ea10753 245 error:
spastor 0:1c358ea10753 246 return result;
spastor 0:1c358ea10753 247 }
spastor 0:1c358ea10753 248
spastor 0:1c358ea10753 249 static connector_status_t connector_stop_callback(connector_data_t * const connector_ptr, connector_transport_t const transport, void * const user_context)
spastor 0:1c358ea10753 250 {
spastor 0:1c358ea10753 251 connector_status_t result = connector_working;
spastor 0:1c358ea10753 252
spastor 0:1c358ea10753 253 connector_initiate_stop_request_t stop_request;
spastor 0:1c358ea10753 254
spastor 0:1c358ea10753 255 connector_request_id_t request_id;
spastor 0:1c358ea10753 256 request_id.status_request = connector_request_id_status_stop_completed;
spastor 0:1c358ea10753 257
spastor 0:1c358ea10753 258 stop_request.transport = transport;
spastor 0:1c358ea10753 259 stop_request.user_context = user_context;
spastor 0:1c358ea10753 260
spastor 0:1c358ea10753 261 {
spastor 0:1c358ea10753 262 connector_callback_status_t const status = connector_callback(connector_ptr->callback, connector_class_id_status, request_id, &stop_request);
spastor 0:1c358ea10753 263
spastor 0:1c358ea10753 264 switch (status)
spastor 0:1c358ea10753 265 {
spastor 0:1c358ea10753 266 case connector_callback_continue:
spastor 0:1c358ea10753 267 case connector_callback_unrecognized:
spastor 0:1c358ea10753 268 break;
spastor 0:1c358ea10753 269 case connector_callback_busy:
spastor 0:1c358ea10753 270 result = connector_pending;
spastor 0:1c358ea10753 271 break;
spastor 0:1c358ea10753 272 default:
spastor 0:1c358ea10753 273 result = connector_abort;
spastor 0:1c358ea10753 274 break;
spastor 0:1c358ea10753 275 }
spastor 0:1c358ea10753 276 }
spastor 0:1c358ea10753 277
spastor 0:1c358ea10753 278 connector_debug_printf("connector_stop_callback: %s\n", transport_to_string(transport));
spastor 0:1c358ea10753 279 return result;
spastor 0:1c358ea10753 280 }
spastor 0:1c358ea10753 281
spastor 0:1c358ea10753 282
spastor 0:1c358ea10753 283 #define CONNECTOR_IS_STOP(state, value) ((state) == (value))
spastor 0:1c358ea10753 284
spastor 0:1c358ea10753 285 static connector_bool_t is_connector_stopped(connector_data_t * const connector_ptr, connector_close_status_t const close_status)
spastor 0:1c358ea10753 286 {
spastor 0:1c358ea10753 287 int count = 0;
spastor 0:1c358ea10753 288 connector_transport_state_t wait_state = (close_status == connector_close_status_device_stopped) ? connector_transport_idle : connector_transport_terminate;
spastor 0:1c358ea10753 289
spastor 0:1c358ea10753 290 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 291 if (!connector_bool(CONNECTOR_IS_STOP(connector_ptr->sm_udp.transport.state, wait_state))) count++;
spastor 0:1c358ea10753 292 #endif
spastor 0:1c358ea10753 293
spastor 0:1c358ea10753 294 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 295 if (!connector_bool(CONNECTOR_IS_STOP(connector_ptr->sm_sms.transport.state, wait_state))) count++;
spastor 0:1c358ea10753 296 #endif
spastor 0:1c358ea10753 297
spastor 0:1c358ea10753 298 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 299 if (!connector_bool(CONNECTOR_IS_STOP(edp_get_active_state(connector_ptr), wait_state))) count++;
spastor 0:1c358ea10753 300 #endif
spastor 0:1c358ea10753 301
spastor 0:1c358ea10753 302 return connector_bool(count == 0);
spastor 0:1c358ea10753 303 }
spastor 0:1c358ea10753 304
spastor 0:1c358ea10753 305 static void abort_connector(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 306 {
spastor 0:1c358ea10753 307 switch (connector_ptr->stop.state)
spastor 0:1c358ea10753 308 {
spastor 0:1c358ea10753 309 case connector_state_terminate_by_initiate_action:
spastor 0:1c358ea10753 310 case connector_state_abort_by_callback:
spastor 0:1c358ea10753 311 /* already shutting down - nothing to do here. */
spastor 0:1c358ea10753 312 break;
spastor 0:1c358ea10753 313
spastor 0:1c358ea10753 314 default:
spastor 0:1c358ea10753 315 {
spastor 0:1c358ea10753 316 connector_status_t status;
spastor 0:1c358ea10753 317
spastor 0:1c358ea10753 318 #if (defined CONNECTOR_TRANSPORT_UDP) ||(defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 319 status = sm_initiate_action(connector_ptr, connector_initiate_terminate, NULL);
spastor 0:1c358ea10753 320 if (status != connector_success)
spastor 0:1c358ea10753 321 connector_debug_printf("abort_connector: sm_initiate_action returns error %d\n", status);
spastor 0:1c358ea10753 322
spastor 0:1c358ea10753 323 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 324 connector_ptr->sm_udp.close.status = connector_close_status_abort;
spastor 0:1c358ea10753 325 #endif
spastor 0:1c358ea10753 326
spastor 0:1c358ea10753 327 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 328 connector_ptr->sm_sms.close.status = connector_close_status_abort;
spastor 0:1c358ea10753 329 #endif
spastor 0:1c358ea10753 330 #endif
spastor 0:1c358ea10753 331
spastor 0:1c358ea10753 332
spastor 0:1c358ea10753 333 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 334 status = edp_initiate_action(connector_ptr, connector_initiate_terminate, NULL);
spastor 0:1c358ea10753 335 if (status != connector_success)
spastor 0:1c358ea10753 336 connector_debug_printf("abort_connector: edp_initiate_action returns error %d\n", status);
spastor 0:1c358ea10753 337
spastor 0:1c358ea10753 338 edp_set_close_status(connector_ptr, connector_close_status_abort);
spastor 0:1c358ea10753 339 #endif
spastor 0:1c358ea10753 340
spastor 0:1c358ea10753 341 connector_ptr->stop.state = connector_state_abort_by_callback;
spastor 0:1c358ea10753 342 break;
spastor 0:1c358ea10753 343 }
spastor 0:1c358ea10753 344 }
spastor 0:1c358ea10753 345 }
spastor 0:1c358ea10753 346
spastor 0:1c358ea10753 347 connector_handle_t connector_init(connector_callback_t const callback)
spastor 0:1c358ea10753 348 {
spastor 0:1c358ea10753 349
spastor 0:1c358ea10753 350 connector_data_t * connector_handle = NULL;
spastor 0:1c358ea10753 351 connector_status_t status;
spastor 0:1c358ea10753 352
spastor 0:1c358ea10753 353 #if (defined CONNECTOR_SW_DESCRIPTION)
spastor 0:1c358ea10753 354 connector_debug_printf("Cloud Connector v%s %s\n", CONNECTOR_SW_VERSION, CONNECTOR_SW_DESCRIPTION);
spastor 0:1c358ea10753 355 #else
spastor 0:1c358ea10753 356 connector_debug_printf("Cloud Connector v%s\n", CONNECTOR_SW_VERSION);
spastor 0:1c358ea10753 357 #endif
spastor 0:1c358ea10753 358
spastor 0:1c358ea10753 359 {
spastor 0:1c358ea10753 360 void * handle;
spastor 0:1c358ea10753 361
spastor 0:1c358ea10753 362 #if (defined CONNECTOR_NO_MALLOC)
spastor 0:1c358ea10753 363 status = malloc_data_buffer(NULL, sizeof *connector_handle, named_buffer_id(connector_data), &handle);
spastor 0:1c358ea10753 364 #else
spastor 0:1c358ea10753 365 status = malloc_cb(callback, sizeof *connector_handle, &handle);
spastor 0:1c358ea10753 366 #endif
spastor 0:1c358ea10753 367
spastor 0:1c358ea10753 368 COND_ELSE_GOTO(status == connector_working, done);
spastor 0:1c358ea10753 369 memset(handle, 0x00, sizeof *connector_handle); /* Init structure, all pointers to NULL */
spastor 0:1c358ea10753 370 connector_handle = handle;
spastor 0:1c358ea10753 371 }
spastor 0:1c358ea10753 372
spastor 0:1c358ea10753 373 connector_handle->callback = callback;
spastor 0:1c358ea10753 374
spastor 0:1c358ea10753 375 status = manage_device_id(connector_handle);
spastor 0:1c358ea10753 376 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 377
spastor 0:1c358ea10753 378 /* make a copy of the cloud url */
spastor 0:1c358ea10753 379 #if (defined CONNECTOR_TRANSPORT_TCP) || (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 380 #if (defined CONNECTOR_CLOUD_URL)
spastor 0:1c358ea10753 381 {
spastor 0:1c358ea10753 382 static char const connector_device_cloud_url[]= CONNECTOR_CLOUD_URL;
spastor 0:1c358ea10753 383 connector_handle->device_cloud_url = (char *)connector_device_cloud_url;
spastor 0:1c358ea10753 384 connector_handle->device_cloud_url_length = sizeof connector_device_cloud_url -1;
spastor 0:1c358ea10753 385 }
spastor 0:1c358ea10753 386 #else
spastor 0:1c358ea10753 387 status = get_config_device_cloud_url(connector_handle);
spastor 0:1c358ea10753 388 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 389 #endif
spastor 0:1c358ea10753 390 #endif /* (defined CONNECTOR_TRANSPORT_TCP) || (defined CONNECTOR_TRANSPORT_UDP) */
spastor 0:1c358ea10753 391
spastor 0:1c358ea10753 392 /* make a copy of the cloud phone */
spastor 0:1c358ea10753 393 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 394 #if (defined CONNECTOR_CLOUD_PHONE)
spastor 0:1c358ea10753 395 {
spastor 0:1c358ea10753 396 static char const connector_device_cloud_phone[]= CONNECTOR_CLOUD_PHONE;
spastor 0:1c358ea10753 397 connector_handle->device_cloud_phone = (char *)connector_device_cloud_phone;
spastor 0:1c358ea10753 398 connector_handle->device_cloud_phone_length = sizeof connector_device_cloud_phone -1;
spastor 0:1c358ea10753 399 }
spastor 0:1c358ea10753 400 #else
spastor 0:1c358ea10753 401 status = get_config_device_cloud_phone(connector_handle);
spastor 0:1c358ea10753 402 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 403 #endif
spastor 0:1c358ea10753 404
spastor 0:1c358ea10753 405 #if (defined CONNECTOR_CLOUD_SERVICE_ID)
spastor 0:1c358ea10753 406 {
spastor 0:1c358ea10753 407 static char const connector_device_cloud_service_id[]= CONNECTOR_CLOUD_SERVICE_ID;
spastor 0:1c358ea10753 408 connector_handle->device_cloud_service_id = (char *)connector_device_cloud_service_id;
spastor 0:1c358ea10753 409 connector_handle->device_cloud_service_id_length = sizeof connector_device_cloud_service_id -1;
spastor 0:1c358ea10753 410 }
spastor 0:1c358ea10753 411 #else
spastor 0:1c358ea10753 412 status = get_config_device_cloud_service_id(connector_handle);
spastor 0:1c358ea10753 413 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 414 #endif
spastor 0:1c358ea10753 415 #endif /* (defined CONNECTOR_TRANSPORT_SMS) */
spastor 0:1c358ea10753 416
spastor 0:1c358ea10753 417 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 418 status = connector_edp_init(connector_handle);
spastor 0:1c358ea10753 419 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 420 #endif
spastor 0:1c358ea10753 421
spastor 0:1c358ea10753 422 #if (defined CONNECTOR_TRANSPORT_UDP) || (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 423 status = connector_sm_init(connector_handle);
spastor 0:1c358ea10753 424 COND_ELSE_GOTO(status == connector_working, error);
spastor 0:1c358ea10753 425 #endif
spastor 0:1c358ea10753 426
spastor 0:1c358ea10753 427 #if (defined CONNECTOR_TRANSPORT_COUNT > 1)
spastor 0:1c358ea10753 428 connector_handle->first_running_network = (connector_network_type_t) 0;
spastor 0:1c358ea10753 429 #endif
spastor 0:1c358ea10753 430
spastor 0:1c358ea10753 431 connector_handle->signature = connector_signature;
spastor 0:1c358ea10753 432 goto done;
spastor 0:1c358ea10753 433
spastor 0:1c358ea10753 434 error:
spastor 0:1c358ea10753 435 free_data_buffer(connector_handle, named_buffer_id(connector_data), connector_handle);
spastor 0:1c358ea10753 436 connector_handle = NULL;
spastor 0:1c358ea10753 437
spastor 0:1c358ea10753 438 done:
spastor 0:1c358ea10753 439 return connector_handle;
spastor 0:1c358ea10753 440 }
spastor 0:1c358ea10753 441
spastor 0:1c358ea10753 442
spastor 0:1c358ea10753 443 connector_status_t connector_step(connector_handle_t const handle)
spastor 0:1c358ea10753 444 {
spastor 0:1c358ea10753 445 connector_status_t result = connector_init_error;
spastor 0:1c358ea10753 446 connector_data_t * const connector_ptr = handle;
spastor 0:1c358ea10753 447
spastor 0:1c358ea10753 448 ASSERT_GOTO(handle != NULL, done);
spastor 0:1c358ea10753 449
spastor 0:1c358ea10753 450 if (connector_ptr->signature != connector_signature) goto done;
spastor 0:1c358ea10753 451
spastor 0:1c358ea10753 452 switch (connector_ptr->stop.state)
spastor 0:1c358ea10753 453 {
spastor 0:1c358ea10753 454 case connector_state_running:
spastor 0:1c358ea10753 455 break;
spastor 0:1c358ea10753 456 case connector_state_stop_by_initiate_action:
spastor 0:1c358ea10753 457 if (is_connector_stopped(connector_ptr, connector_close_status_device_stopped))
spastor 0:1c358ea10753 458 {
spastor 0:1c358ea10753 459 result = connector_stop_callback(connector_ptr, connector_transport_all, connector_ptr->stop.user_context);
spastor 0:1c358ea10753 460 if (result == connector_abort)
spastor 0:1c358ea10753 461 {
spastor 0:1c358ea10753 462 goto error;
spastor 0:1c358ea10753 463 }
spastor 0:1c358ea10753 464 else if (result == connector_working)
spastor 0:1c358ea10753 465 {
spastor 0:1c358ea10753 466 connector_ptr->stop.state = connector_state_running;
spastor 0:1c358ea10753 467 }
spastor 0:1c358ea10753 468 }
spastor 0:1c358ea10753 469 break;
spastor 0:1c358ea10753 470 case connector_state_abort_by_callback:
spastor 0:1c358ea10753 471 case connector_state_terminate_by_initiate_action:
spastor 0:1c358ea10753 472 if (is_connector_stopped(connector_ptr, connector_close_status_device_terminated))
spastor 0:1c358ea10753 473 {
spastor 0:1c358ea10753 474 connector_ptr->connector_got_device_id = connector_false; /* TODO, Probably this should not be done with provisioning! */
spastor 0:1c358ea10753 475 connector_ptr->signature = NULL;
spastor 0:1c358ea10753 476 free_data_buffer(connector_ptr, named_buffer_id(connector_data), connector_ptr);
spastor 0:1c358ea10753 477 connector_debug_printf("connector_step: free Cloud Connector\n");
spastor 0:1c358ea10753 478
spastor 0:1c358ea10753 479 result = (connector_ptr->stop.state == connector_state_terminate_by_initiate_action) ? connector_device_terminated : connector_abort;
spastor 0:1c358ea10753 480 goto done;
spastor 0:1c358ea10753 481 }
spastor 0:1c358ea10753 482 break;
spastor 0:1c358ea10753 483 default:
spastor 0:1c358ea10753 484 break;
spastor 0:1c358ea10753 485 }
spastor 0:1c358ea10753 486
spastor 0:1c358ea10753 487 #if (CONNECTOR_TRANSPORT_COUNT == 1)
spastor 0:1c358ea10753 488 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 489 result = connector_edp_step(connector_ptr);
spastor 0:1c358ea10753 490 #endif
spastor 0:1c358ea10753 491 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 492 result = connector_udp_step(connector_ptr);
spastor 0:1c358ea10753 493 #endif
spastor 0:1c358ea10753 494 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 495 result = connector_sms_step(connector_ptr);
spastor 0:1c358ea10753 496 #endif
spastor 0:1c358ea10753 497
spastor 0:1c358ea10753 498 #else
spastor 0:1c358ea10753 499 {
spastor 0:1c358ea10753 500 #define next_network(current_network) (((current_network) == last_network_index) ? first_network_index : (connector_network_type_t) ((current_network) + 1))
spastor 0:1c358ea10753 501
spastor 0:1c358ea10753 502 connector_network_type_t const first_network_index = (connector_network_type_t) 0;
spastor 0:1c358ea10753 503 connector_network_type_t const last_network_index = (connector_network_type_t) (connector_network_count - 1);
spastor 0:1c358ea10753 504 connector_network_type_t const first_network_checked = connector_ptr->first_running_network;
spastor 0:1c358ea10753 505 connector_network_type_t current_network = first_network_checked;
spastor 0:1c358ea10753 506
spastor 0:1c358ea10753 507 do
spastor 0:1c358ea10753 508 {
spastor 0:1c358ea10753 509 connector_status_t (*step_func)(connector_data_t * const connector_ptr);
spastor 0:1c358ea10753 510
spastor 0:1c358ea10753 511 switch (current_network)
spastor 0:1c358ea10753 512 {
spastor 0:1c358ea10753 513 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 514 case connector_network_tcp: step_func = connector_edp_step; break;
spastor 0:1c358ea10753 515 #endif
spastor 0:1c358ea10753 516 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 517 case connector_network_udp: step_func = connector_udp_step; break;
spastor 0:1c358ea10753 518 #endif
spastor 0:1c358ea10753 519 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 520 case connector_network_sms: step_func = connector_sms_step; break;
spastor 0:1c358ea10753 521 #endif
spastor 0:1c358ea10753 522 default:
spastor 0:1c358ea10753 523 ASSERT(connector_false);
spastor 0:1c358ea10753 524 result = connector_abort;
spastor 0:1c358ea10753 525 goto error; break;
spastor 0:1c358ea10753 526 }
spastor 0:1c358ea10753 527
spastor 0:1c358ea10753 528 result = step_func(connector_ptr);
spastor 0:1c358ea10753 529
spastor 0:1c358ea10753 530 current_network = next_network(current_network);
spastor 0:1c358ea10753 531 } while ((current_network != first_network_checked) && (result == connector_idle));
spastor 0:1c358ea10753 532
spastor 0:1c358ea10753 533 connector_ptr->first_running_network = (result == connector_idle) ? next_network(first_network_checked): current_network;
spastor 0:1c358ea10753 534
spastor 0:1c358ea10753 535 #undef next_network
spastor 0:1c358ea10753 536 }
spastor 0:1c358ea10753 537 #endif
spastor 0:1c358ea10753 538
spastor 0:1c358ea10753 539 error:
spastor 0:1c358ea10753 540 switch (result)
spastor 0:1c358ea10753 541 {
spastor 0:1c358ea10753 542 case connector_abort:
spastor 0:1c358ea10753 543 abort_connector(connector_ptr);
spastor 0:1c358ea10753 544 /* no break; */
spastor 0:1c358ea10753 545 case connector_device_terminated:
spastor 0:1c358ea10753 546 result = connector_working;
spastor 0:1c358ea10753 547 break;
spastor 0:1c358ea10753 548 default:
spastor 0:1c358ea10753 549 break;
spastor 0:1c358ea10753 550 }
spastor 0:1c358ea10753 551
spastor 0:1c358ea10753 552 done:
spastor 0:1c358ea10753 553 return result;
spastor 0:1c358ea10753 554 }
spastor 0:1c358ea10753 555
spastor 0:1c358ea10753 556 connector_status_t connector_run(connector_handle_t const handle)
spastor 0:1c358ea10753 557 {
spastor 0:1c358ea10753 558 connector_status_t rc;
spastor 0:1c358ea10753 559
spastor 0:1c358ea10753 560 do {
spastor 0:1c358ea10753 561 rc = connector_step(handle);
spastor 0:1c358ea10753 562
spastor 0:1c358ea10753 563 if (rc == connector_idle || rc == connector_working || rc == connector_pending || rc == connector_active || rc == connector_success)
spastor 0:1c358ea10753 564 {
spastor 0:1c358ea10753 565 if (yield_process(handle, rc) != connector_working)
spastor 0:1c358ea10753 566 {
spastor 0:1c358ea10753 567 abort_connector(handle);
spastor 0:1c358ea10753 568 rc = connector_success;
spastor 0:1c358ea10753 569 }
spastor 0:1c358ea10753 570 }
spastor 0:1c358ea10753 571
spastor 0:1c358ea10753 572 } while (rc == connector_idle || rc == connector_working || rc == connector_pending || rc == connector_active || rc == connector_success);
spastor 0:1c358ea10753 573
spastor 0:1c358ea10753 574 return rc;
spastor 0:1c358ea10753 575 }
spastor 0:1c358ea10753 576
spastor 0:1c358ea10753 577 connector_status_t connector_initiate_action(connector_handle_t const handle, connector_initiate_request_t const request, void const * const request_data)
spastor 0:1c358ea10753 578 {
spastor 0:1c358ea10753 579 connector_status_t result = connector_init_error;
spastor 0:1c358ea10753 580 connector_data_t * connector_ptr = (connector_data_t *)handle;
spastor 0:1c358ea10753 581
spastor 0:1c358ea10753 582 ASSERT_GOTO(handle != NULL, done);
spastor 0:1c358ea10753 583
spastor 0:1c358ea10753 584 if (connector_ptr->signature != connector_signature) goto done;
spastor 0:1c358ea10753 585
spastor 0:1c358ea10753 586 switch (request)
spastor 0:1c358ea10753 587 {
spastor 0:1c358ea10753 588 case connector_initiate_terminate:
spastor 0:1c358ea10753 589
spastor 0:1c358ea10753 590 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 591 result = edp_initiate_action(connector_ptr, request, request_data);
spastor 0:1c358ea10753 592 COND_ELSE_GOTO(result == connector_success, done);
spastor 0:1c358ea10753 593 #endif
spastor 0:1c358ea10753 594
spastor 0:1c358ea10753 595 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 596 result = sm_initiate_action(connector_ptr, request, request_data);
spastor 0:1c358ea10753 597 COND_ELSE_GOTO(result == connector_success, done);
spastor 0:1c358ea10753 598 #endif
spastor 0:1c358ea10753 599
spastor 0:1c358ea10753 600 connector_ptr->stop.state = connector_state_terminate_by_initiate_action;
spastor 0:1c358ea10753 601 result = connector_success;
spastor 0:1c358ea10753 602 break;
spastor 0:1c358ea10753 603
spastor 0:1c358ea10753 604 default:
spastor 0:1c358ea10753 605 if (connector_ptr->stop.state == connector_state_terminate_by_initiate_action)
spastor 0:1c358ea10753 606 {
spastor 0:1c358ea10753 607 result = connector_device_terminated;
spastor 0:1c358ea10753 608 goto done;
spastor 0:1c358ea10753 609 }
spastor 0:1c358ea10753 610
spastor 0:1c358ea10753 611 {
spastor 0:1c358ea10753 612 connector_transport_t const * const transport = request_data;
spastor 0:1c358ea10753 613
spastor 0:1c358ea10753 614 result = connector_unavailable;
spastor 0:1c358ea10753 615
spastor 0:1c358ea10753 616 if (transport == NULL)
spastor 0:1c358ea10753 617 {
spastor 0:1c358ea10753 618 result = connector_invalid_data;
spastor 0:1c358ea10753 619 goto done;
spastor 0:1c358ea10753 620 }
spastor 0:1c358ea10753 621
spastor 0:1c358ea10753 622 switch (*transport)
spastor 0:1c358ea10753 623 {
spastor 0:1c358ea10753 624 case connector_transport_all:
spastor 0:1c358ea10753 625 if (request != connector_initiate_transport_stop)
spastor 0:1c358ea10753 626 {
spastor 0:1c358ea10753 627 result = connector_invalid_data;
spastor 0:1c358ea10753 628 goto done;
spastor 0:1c358ea10753 629 }
spastor 0:1c358ea10753 630
spastor 0:1c358ea10753 631 if (connector_ptr->stop.state != connector_state_running)
spastor 0:1c358ea10753 632 {
spastor 0:1c358ea10753 633 /* already in close state */
spastor 0:1c358ea10753 634 result = (connector_ptr->stop.state == connector_state_terminate_by_initiate_action) ? connector_device_terminated: connector_service_busy;
spastor 0:1c358ea10753 635 goto done;
spastor 0:1c358ea10753 636 }
spastor 0:1c358ea10753 637
spastor 0:1c358ea10753 638 /* no break */
spastor 0:1c358ea10753 639
spastor 0:1c358ea10753 640 #if (defined CONNECTOR_SHORT_MESSAGE)
spastor 0:1c358ea10753 641 #if (defined CONNECTOR_TRANSPORT_UDP)
spastor 0:1c358ea10753 642 case connector_transport_udp:
spastor 0:1c358ea10753 643 #endif
spastor 0:1c358ea10753 644 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 645 case connector_transport_sms:
spastor 0:1c358ea10753 646 #endif
spastor 0:1c358ea10753 647 result = sm_initiate_action(connector_ptr, request, request_data);
spastor 0:1c358ea10753 648
spastor 0:1c358ea10753 649 if (*transport != connector_transport_all) break;
spastor 0:1c358ea10753 650 else if (result != connector_success) break;
spastor 0:1c358ea10753 651 else if (request != connector_initiate_transport_stop) break;
spastor 0:1c358ea10753 652 /* no break; */
spastor 0:1c358ea10753 653 #endif
spastor 0:1c358ea10753 654
spastor 0:1c358ea10753 655 #if (defined CONNECTOR_TRANSPORT_TCP)
spastor 0:1c358ea10753 656 case connector_transport_tcp:
spastor 0:1c358ea10753 657 result = edp_initiate_action(connector_ptr, request, request_data);
spastor 0:1c358ea10753 658
spastor 0:1c358ea10753 659 if (*transport != connector_transport_all) break;
spastor 0:1c358ea10753 660 else if (result != connector_success) break;
spastor 0:1c358ea10753 661 else if (request != connector_initiate_transport_stop) break;
spastor 0:1c358ea10753 662 #endif
spastor 0:1c358ea10753 663 {
spastor 0:1c358ea10753 664 connector_initiate_stop_request_t const * const stop_request = request_data;
spastor 0:1c358ea10753 665 connector_ptr->stop.condition = stop_request->condition;
spastor 0:1c358ea10753 666 connector_ptr->stop.user_context = stop_request->user_context;
spastor 0:1c358ea10753 667 connector_ptr->stop.state = connector_state_stop_by_initiate_action;
spastor 0:1c358ea10753 668 result = connector_success;
spastor 0:1c358ea10753 669 }
spastor 0:1c358ea10753 670 break;
spastor 0:1c358ea10753 671
spastor 0:1c358ea10753 672 default:
spastor 0:1c358ea10753 673 result = connector_invalid_data;
spastor 0:1c358ea10753 674 goto done;
spastor 0:1c358ea10753 675 }
spastor 0:1c358ea10753 676 }
spastor 0:1c358ea10753 677 }
spastor 0:1c358ea10753 678 done:
spastor 0:1c358ea10753 679 return result;
spastor 0:1c358ea10753 680 }