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 14:10:48 2013 +0000
Revision:
1:908afea5a49d
Parent:
0:1c358ea10753
Use internal Thread.h instead of Threads.h

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
spastor 0:1c358ea10753 14 #define MANDATORY_FACILITY (connector_request_id_config_t)-1
spastor 0:1c358ea10753 15
spastor 0:1c358ea10753 16 #define SET_FACILITY_SUPPORT(i) (UINT32_C(0x01) << (i))
spastor 0:1c358ea10753 17 #define IS_FACILITY_SUPPORTED(connector_ptr, table_index) (connector_ptr->edp_data.facilities.supported_mask & SET_FACILITY_SUPPORT(table_index))
spastor 0:1c358ea10753 18
spastor 0:1c358ea10753 19 typedef connector_status_t (* connector_facility_service_init_cb_t)(struct connector_data * const connector_ptr, unsigned int const facility_index);
spastor 0:1c358ea10753 20 typedef connector_status_t (* connector_facility_service_delete_cb_t)(struct connector_data * const connector_ptr);
spastor 0:1c358ea10753 21 typedef connector_status_t (* connector_facility_service_process_cb_t )(struct connector_data * const connector_ptr,
spastor 0:1c358ea10753 22 void * const facility_data,
spastor 0:1c358ea10753 23 uint8_t * const packet,
spastor 0:1c358ea10753 24 unsigned int * const receive_timeout);
spastor 0:1c358ea10753 25
spastor 0:1c358ea10753 26 typedef struct {
spastor 0:1c358ea10753 27 connector_request_id_t request_id;
spastor 0:1c358ea10753 28 connector_facility_service_init_cb_t init_cb;
spastor 0:1c358ea10753 29 connector_facility_service_delete_cb_t delete_cb;
spastor 0:1c358ea10753 30 connector_facility_service_delete_cb_t cleanup_cb;
spastor 0:1c358ea10753 31 connector_facility_service_process_cb_t discovery_cb;
spastor 0:1c358ea10753 32 connector_facility_service_process_cb_t process_cb;
spastor 0:1c358ea10753 33 } connector_facility_service_t;
spastor 0:1c358ea10753 34
spastor 0:1c358ea10753 35 /* Table of all supported facilities.
spastor 0:1c358ea10753 36 *
spastor 0:1c358ea10753 37 * The connector will call the callback to see whether it supports each optional facility.
spastor 0:1c358ea10753 38 * It will call init_cb to initialize the facility and delete_cb to remove the facility.
spastor 0:1c358ea10753 39 * The init_cb must call add_facility_data() to add the facility into the facility list.
spastor 0:1c358ea10753 40 * The delete_cb is called to delete the facility from the facility list when user terminates the connector.
spastor 0:1c358ea10753 41 */
spastor 0:1c358ea10753 42 static connector_facility_service_t const connector_supported_service_table[] = {
spastor 0:1c358ea10753 43 /* mandatory facilities */
spastor 0:1c358ea10753 44 {{MANDATORY_FACILITY}, connector_facility_cc_init, connector_facility_cc_delete, connector_facility_cc_cleanup, cc_discovery, cc_process},
spastor 0:1c358ea10753 45
spastor 0:1c358ea10753 46 /* list of optional facilities */
spastor 0:1c358ea10753 47 #if (defined CONNECTOR_FIRMWARE_SERVICE) || (defined CONNECTOR_RCI_SERVICE)
spastor 0:1c358ea10753 48 #if (defined CONNECTOR_FIRMWARE_SUPPORT) || (defined CONNECTOR_RCI_SERVICE)
spastor 0:1c358ea10753 49 {{MANDATORY_FACILITY}, connector_facility_firmware_init, connector_facility_firmware_delete, NULL, fw_discovery, fw_process},
spastor 0:1c358ea10753 50 #else
spastor 0:1c358ea10753 51 {{connector_request_id_config_firmware_facility}, connector_facility_firmware_init, connector_facility_firmware_delete, NULL, fw_discovery, fw_process},
spastor 0:1c358ea10753 52 #endif
spastor 0:1c358ea10753 53 #endif
spastor 0:1c358ea10753 54 #if (defined CONNECTOR_DATA_SERVICE)
spastor 0:1c358ea10753 55 #if (defined CONNECTOR_DATA_SERVICE_SUPPORT)
spastor 0:1c358ea10753 56 {{MANDATORY_FACILITY}, connector_facility_data_service_init, connector_facility_data_service_delete, connector_facility_data_service_cleanup, msg_discovery, msg_process},
spastor 0:1c358ea10753 57 #else
spastor 0:1c358ea10753 58 {{connector_request_id_config_data_service}, connector_facility_data_service_init, connector_facility_data_service_delete, connector_facility_data_service_cleanup, msg_discovery, msg_process},
spastor 0:1c358ea10753 59 #endif
spastor 0:1c358ea10753 60 #endif
spastor 0:1c358ea10753 61 #if (defined CONNECTOR_FILE_SYSTEM)
spastor 0:1c358ea10753 62 #if (defined CONNECTOR_FILE_SYSTEM_SUPPORT)
spastor 0:1c358ea10753 63 {{MANDATORY_FACILITY}, connector_facility_file_system_init, connector_facility_file_system_delete, connector_facility_file_system_cleanup, msg_discovery, msg_process},
spastor 0:1c358ea10753 64 #else
spastor 0:1c358ea10753 65 {{connector_request_id_config_file_system}, connector_facility_file_system_init, connector_facility_file_system_delete, connector_facility_file_system_cleanup, msg_discovery, msg_process},
spastor 0:1c358ea10753 66 #endif
spastor 0:1c358ea10753 67 #endif
spastor 0:1c358ea10753 68
spastor 0:1c358ea10753 69 #if (defined CONNECTOR_RCI_SERVICE)
spastor 0:1c358ea10753 70 #if (defined CONNECTOR_REMOTE_CONFIGURATION_SUPPORT)
spastor 0:1c358ea10753 71 {{MANDATORY_FACILITY}, connector_facility_rci_service_init, connector_facility_rci_service_delete, connector_facility_rci_service_cleanup, msg_discovery, msg_process}
spastor 0:1c358ea10753 72 #else
spastor 0:1c358ea10753 73 {{connector_request_id_config_remote_configuration}, connector_facility_rci_service_init, connector_facility_rci_service_delete, connector_facility_rci_service_cleanup, msg_discovery, msg_process}
spastor 0:1c358ea10753 74 #endif
spastor 0:1c358ea10753 75 #endif
spastor 0:1c358ea10753 76 };
spastor 0:1c358ea10753 77
spastor 0:1c358ea10753 78 static size_t const connector_facility_count = asizeof(connector_supported_service_table);
spastor 0:1c358ea10753 79
spastor 0:1c358ea10753 80
spastor 0:1c358ea10753 81 static connector_status_t layer_remove_facilities(connector_data_t * const connector_ptr, connector_supported_facility_cb_index_t cb_index)
spastor 0:1c358ea10753 82 {
spastor 0:1c358ea10753 83 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 84 size_t i;
spastor 0:1c358ea10753 85
spastor 0:1c358ea10753 86 for (i=0; (i < connector_facility_count) && ((result == connector_idle) || (result == connector_working)); i++)
spastor 0:1c358ea10753 87 {
spastor 0:1c358ea10753 88 if (IS_FACILITY_SUPPORTED(connector_ptr,i))
spastor 0:1c358ea10753 89 {
spastor 0:1c358ea10753 90 switch (cb_index)
spastor 0:1c358ea10753 91 {
spastor 0:1c358ea10753 92 case facility_callback_delete:
spastor 0:1c358ea10753 93 if (connector_supported_service_table[i].delete_cb != NULL)
spastor 0:1c358ea10753 94 {
spastor 0:1c358ea10753 95 result = connector_supported_service_table[i].delete_cb(connector_ptr);
spastor 0:1c358ea10753 96 }
spastor 0:1c358ea10753 97 break;
spastor 0:1c358ea10753 98 case facility_callback_cleanup:
spastor 0:1c358ea10753 99 if (connector_supported_service_table[i].cleanup_cb != NULL)
spastor 0:1c358ea10753 100 {
spastor 0:1c358ea10753 101 result = connector_supported_service_table[i].cleanup_cb(connector_ptr);
spastor 0:1c358ea10753 102 }
spastor 0:1c358ea10753 103 break;
spastor 0:1c358ea10753 104 }
spastor 0:1c358ea10753 105 ASSERT(result != connector_pending);
spastor 0:1c358ea10753 106 }
spastor 0:1c358ea10753 107 }
spastor 0:1c358ea10753 108 return result;
spastor 0:1c358ea10753 109 }
spastor 0:1c358ea10753 110
spastor 0:1c358ea10753 111
spastor 0:1c358ea10753 112
spastor 0:1c358ea10753 113 static connector_status_t layer_discovery_facility(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 114 {
spastor 0:1c358ea10753 115 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 116 connector_facility_t * fac_ptr;
spastor 0:1c358ea10753 117
spastor 0:1c358ea10753 118 /* invoke any facility that needs to send any message to Device Cloud
spastor 0:1c358ea10753 119 * during initialization phase at discovery layer.
spastor 0:1c358ea10753 120 */
spastor 0:1c358ea10753 121 fac_ptr = (connector_ptr->edp_data.facilities.current == NULL)? connector_ptr->edp_data.facilities.list: connector_ptr->edp_data.facilities.current;
spastor 0:1c358ea10753 122
spastor 0:1c358ea10753 123 for (;fac_ptr != NULL && result == connector_idle; fac_ptr = fac_ptr->next)
spastor 0:1c358ea10753 124 {
spastor 0:1c358ea10753 125 unsigned int const i = fac_ptr->service_index;
spastor 0:1c358ea10753 126
spastor 0:1c358ea10753 127 if (connector_supported_service_table[i].discovery_cb != NULL)
spastor 0:1c358ea10753 128 { /* function to send facility discovery */
spastor 0:1c358ea10753 129 result = connector_supported_service_table[i].discovery_cb(connector_ptr, fac_ptr->facility_data,
spastor 0:1c358ea10753 130 NULL, &connector_ptr->edp_data.receive_packet.timeout);
spastor 0:1c358ea10753 131 connector_ptr->edp_data.facilities.current = (result == connector_pending) ? fac_ptr : fac_ptr->next;
spastor 0:1c358ea10753 132 }
spastor 0:1c358ea10753 133 }
spastor 0:1c358ea10753 134
spastor 0:1c358ea10753 135 if (result == connector_working || result == connector_idle)
spastor 0:1c358ea10753 136 {
spastor 0:1c358ea10753 137 if (connector_ptr->edp_data.facilities.current == NULL)
spastor 0:1c358ea10753 138 {
spastor 0:1c358ea10753 139 /* done all facilities */
spastor 0:1c358ea10753 140 result = connector_working;
spastor 0:1c358ea10753 141 }
spastor 0:1c358ea10753 142 else if (result == connector_working)
spastor 0:1c358ea10753 143 {
spastor 0:1c358ea10753 144 /* continue next facility */
spastor 0:1c358ea10753 145 result = connector_idle;
spastor 0:1c358ea10753 146 }
spastor 0:1c358ea10753 147 }
spastor 0:1c358ea10753 148 return result;
spastor 0:1c358ea10753 149 }
spastor 0:1c358ea10753 150
spastor 0:1c358ea10753 151
spastor 0:1c358ea10753 152 static connector_status_t edp_layer_get_supported_facilities(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 153 {
spastor 0:1c358ea10753 154 #define NUMBER_FACILITY_PER_BYTE CHAR_BIT
spastor 0:1c358ea10753 155 connector_status_t result = connector_working;
spastor 0:1c358ea10753 156 unsigned int i;
spastor 0:1c358ea10753 157
spastor 0:1c358ea10753 158 connector_ptr->edp_data.facilities.supported_mask = 0;
spastor 0:1c358ea10753 159
spastor 0:1c358ea10753 160 ASSERT(CHAR_BIT == 8);
spastor 0:1c358ea10753 161 ASSERT(connector_facility_count <= (sizeof connector_ptr->edp_data.facilities.supported_mask * NUMBER_FACILITY_PER_BYTE));
spastor 0:1c358ea10753 162
spastor 0:1c358ea10753 163 /* connector_supported_service_table[] table includes a list of supported facilities.
spastor 0:1c358ea10753 164 * Call callback to see which facility is supported.
spastor 0:1c358ea10753 165 */
spastor 0:1c358ea10753 166
spastor 0:1c358ea10753 167 for (i=0; i < connector_facility_count; i++)
spastor 0:1c358ea10753 168 {
spastor 0:1c358ea10753 169 connector_request_id_t const request_id = connector_supported_service_table[i].request_id;
spastor 0:1c358ea10753 170 connector_config_supported_t config_status;
spastor 0:1c358ea10753 171
spastor 0:1c358ea10753 172 config_status.supported = connector_bool(request_id.config_request == MANDATORY_FACILITY);
spastor 0:1c358ea10753 173
spastor 0:1c358ea10753 174 if (request_id.config_request != MANDATORY_FACILITY)
spastor 0:1c358ea10753 175 { /* this is optional facility so ask application whether it supports this facility */
spastor 0:1c358ea10753 176 connector_callback_status_t status;
spastor 0:1c358ea10753 177
spastor 0:1c358ea10753 178 status = connector_callback(connector_ptr->callback, connector_class_id_config, request_id, &config_status);
spastor 0:1c358ea10753 179 switch (status)
spastor 0:1c358ea10753 180 {
spastor 0:1c358ea10753 181 case connector_callback_busy:
spastor 0:1c358ea10753 182 /* not allowed to returned busy */
spastor 0:1c358ea10753 183 connector_debug_printf("edp_layer_get_supported_facilities: callback returns connector_callback_busy which is not allowed\n");
spastor 0:1c358ea10753 184 result = connector_abort;
spastor 0:1c358ea10753 185 goto error;
spastor 0:1c358ea10753 186 case connector_callback_abort:
spastor 0:1c358ea10753 187 case connector_callback_error:
spastor 0:1c358ea10753 188 result = connector_abort;
spastor 0:1c358ea10753 189 goto done;
spastor 0:1c358ea10753 190 case connector_callback_unrecognized:
spastor 0:1c358ea10753 191 config_status.supported = connector_false;
spastor 0:1c358ea10753 192 break;
spastor 0:1c358ea10753 193 case connector_callback_continue:
spastor 0:1c358ea10753 194 break;
spastor 0:1c358ea10753 195 }
spastor 0:1c358ea10753 196 }
spastor 0:1c358ea10753 197
spastor 0:1c358ea10753 198 switch (config_status.supported)
spastor 0:1c358ea10753 199 {
spastor 0:1c358ea10753 200 case connector_true:
spastor 0:1c358ea10753 201 connector_ptr->edp_data.facilities.supported_mask |= (uint16_t)SET_FACILITY_SUPPORT(i);
spastor 0:1c358ea10753 202 break;
spastor 0:1c358ea10753 203 case connector_false:
spastor 0:1c358ea10753 204 break;
spastor 0:1c358ea10753 205 default:
spastor 0:1c358ea10753 206 result = connector_invalid_data_range;
spastor 0:1c358ea10753 207 goto error;
spastor 0:1c358ea10753 208 }
spastor 0:1c358ea10753 209
spastor 0:1c358ea10753 210 }
spastor 0:1c358ea10753 211
spastor 0:1c358ea10753 212 error:
spastor 0:1c358ea10753 213 if (result != connector_working)
spastor 0:1c358ea10753 214 {
spastor 0:1c358ea10753 215 connector_request_id_t const request_id = connector_supported_service_table[i].request_id;
spastor 0:1c358ea10753 216 if (notify_error_status(connector_ptr->callback, connector_class_id_config, request_id, result) != connector_working)
spastor 0:1c358ea10753 217 result = connector_abort;
spastor 0:1c358ea10753 218 }
spastor 0:1c358ea10753 219
spastor 0:1c358ea10753 220 done:
spastor 0:1c358ea10753 221 return result;
spastor 0:1c358ea10753 222 }
spastor 0:1c358ea10753 223
spastor 0:1c358ea10753 224 static connector_status_t edp_layer_initialize_facilities(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 225 {
spastor 0:1c358ea10753 226 connector_status_t result = connector_working;
spastor 0:1c358ea10753 227 size_t i;
spastor 0:1c358ea10753 228
spastor 0:1c358ea10753 229 for (i=0; i < connector_facility_count; i++)
spastor 0:1c358ea10753 230 {
spastor 0:1c358ea10753 231 if (IS_FACILITY_SUPPORTED(connector_ptr,i) &&
spastor 0:1c358ea10753 232 connector_supported_service_table[i].init_cb != NULL)
spastor 0:1c358ea10753 233 {
spastor 0:1c358ea10753 234 result = connector_supported_service_table[i].init_cb(connector_ptr, i);
spastor 0:1c358ea10753 235 if ( result != connector_working) goto done;
spastor 0:1c358ea10753 236 }
spastor 0:1c358ea10753 237 }
spastor 0:1c358ea10753 238
spastor 0:1c358ea10753 239 {
spastor 0:1c358ea10753 240 connector_facility_t * fac_ptr;
spastor 0:1c358ea10753 241 /* initialize packet pointer for each facility */
spastor 0:1c358ea10753 242 for (fac_ptr = connector_ptr->edp_data.facilities.list; fac_ptr != NULL; fac_ptr = fac_ptr->next)
spastor 0:1c358ea10753 243 {
spastor 0:1c358ea10753 244 fac_ptr->packet_buffer = NULL;
spastor 0:1c358ea10753 245 }
spastor 0:1c358ea10753 246 }
spastor 0:1c358ea10753 247
spastor 0:1c358ea10753 248 done:
spastor 0:1c358ea10753 249 return result;
spastor 0:1c358ea10753 250 }
spastor 0:1c358ea10753 251
spastor 0:1c358ea10753 252 static connector_status_t layer_facility_process(connector_data_t * const connector_ptr)
spastor 0:1c358ea10753 253 {
spastor 0:1c358ea10753 254 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 255 connector_facility_t * fac_ptr;
spastor 0:1c358ea10753 256
spastor 0:1c358ea10753 257
spastor 0:1c358ea10753 258 /* Invoke facility process.
spastor 0:1c358ea10753 259 *
spastor 0:1c358ea10753 260 * Run all facilities. But each starting facility
spastor 0:1c358ea10753 261 * will be alternated.
spastor 0:1c358ea10753 262 */
spastor 0:1c358ea10753 263 fac_ptr = (connector_ptr->edp_data.facilities.current != NULL) ? connector_ptr->edp_data.facilities.current : connector_ptr->edp_data.facilities.list;
spastor 0:1c358ea10753 264 connector_ptr->edp_data.facilities.current = fac_ptr;
spastor 0:1c358ea10753 265 do
spastor 0:1c358ea10753 266 {
spastor 0:1c358ea10753 267 /* We want to run all facilities processes */
spastor 0:1c358ea10753 268 unsigned int const i = fac_ptr->service_index;
spastor 0:1c358ea10753 269
spastor 0:1c358ea10753 270 if (connector_supported_service_table[i].process_cb)
spastor 0:1c358ea10753 271 {
spastor 0:1c358ea10753 272 uint8_t * const packet = (fac_ptr->packet_buffer != NULL) ? fac_ptr->packet_buffer->buffer: NULL;
spastor 0:1c358ea10753 273
spastor 0:1c358ea10753 274 result = connector_supported_service_table[i].process_cb(connector_ptr, fac_ptr->facility_data,
spastor 0:1c358ea10753 275 packet, &connector_ptr->edp_data.receive_packet.timeout);
spastor 0:1c358ea10753 276
spastor 0:1c358ea10753 277 if (result != connector_pending && result != connector_active && fac_ptr->packet_buffer != NULL)
spastor 0:1c358ea10753 278 { /* release the packet when it's done */
spastor 0:1c358ea10753 279 tcp_release_receive_packet(connector_ptr, fac_ptr->packet_buffer);
spastor 0:1c358ea10753 280 fac_ptr->packet_buffer = NULL;
spastor 0:1c358ea10753 281 }
spastor 0:1c358ea10753 282 fac_ptr = (fac_ptr->next != NULL) ? fac_ptr->next : connector_ptr->edp_data.facilities.list;
spastor 0:1c358ea10753 283 }
spastor 0:1c358ea10753 284
spastor 0:1c358ea10753 285 } while (result == connector_idle && fac_ptr != connector_ptr->edp_data.facilities.current);
spastor 0:1c358ea10753 286
spastor 0:1c358ea10753 287 /* setup next starting facility process */
spastor 0:1c358ea10753 288 connector_ptr->edp_data.facilities.current = (connector_ptr->edp_data.facilities.current != NULL) ? connector_ptr->edp_data.facilities.current->next : connector_ptr->edp_data.facilities.list;
spastor 0:1c358ea10753 289
spastor 0:1c358ea10753 290 if (result == connector_abort) edp_set_close_status(connector_ptr, connector_close_status_abort);
spastor 0:1c358ea10753 291
spastor 0:1c358ea10753 292 return result;
spastor 0:1c358ea10753 293 }
spastor 0:1c358ea10753 294