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 /* This function searches for the next valid request_id and leaves it in connector_ptr->last_request_id */
spastor 0:1c358ea10753 13 static connector_status_t sm_get_request_id(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 14 {
spastor 0:1c358ea10753 15 connector_status_t result = connector_pending;
spastor 0:1c358ea10753 16 unsigned long const request_id = connector_ptr->last_request_id;
spastor 0:1c358ea10753 17
spastor 0:1c358ea10753 18 do
spastor 0:1c358ea10753 19 {
spastor 0:1c358ea10753 20 connector_sm_session_t * session = sm_ptr->session.head;
spastor 0:1c358ea10753 21
spastor 0:1c358ea10753 22 connector_ptr->last_request_id++;
spastor 0:1c358ea10753 23 connector_ptr->last_request_id &= SM_REQUEST_ID_MASK;
spastor 0:1c358ea10753 24
spastor 0:1c358ea10753 25 while (session != NULL)
spastor 0:1c358ea10753 26 {
spastor 0:1c358ea10753 27 /* already used? */
spastor 0:1c358ea10753 28 if (session->request_id == connector_ptr->last_request_id)
spastor 0:1c358ea10753 29 break;
spastor 0:1c358ea10753 30
spastor 0:1c358ea10753 31 session = session->next;
spastor 0:1c358ea10753 32 }
spastor 0:1c358ea10753 33
spastor 0:1c358ea10753 34 if (session == NULL)
spastor 0:1c358ea10753 35 break;
spastor 0:1c358ea10753 36
spastor 0:1c358ea10753 37 } while (request_id != connector_ptr->last_request_id);
spastor 0:1c358ea10753 38
spastor 0:1c358ea10753 39 ASSERT_GOTO(request_id != connector_ptr->last_request_id, error);
spastor 0:1c358ea10753 40 result = connector_working;
spastor 0:1c358ea10753 41
spastor 0:1c358ea10753 42 error:
spastor 0:1c358ea10753 43 return result;
spastor 0:1c358ea10753 44 }
spastor 0:1c358ea10753 45
spastor 0:1c358ea10753 46 static connector_sm_session_t * get_sm_session(connector_sm_data_t * const sm_ptr, uint32_t const transcation_id, connector_bool_t const client_originated)
spastor 0:1c358ea10753 47 {
spastor 0:1c358ea10753 48 connector_sm_session_t * session = sm_ptr->session.head;
spastor 0:1c358ea10753 49
spastor 0:1c358ea10753 50 while (session != NULL)
spastor 0:1c358ea10753 51 {
spastor 0:1c358ea10753 52 if ((session->request_id == transcation_id) && (SmIsClientOwned(session->flags) == client_originated))
spastor 0:1c358ea10753 53 break;
spastor 0:1c358ea10753 54
spastor 0:1c358ea10753 55 session = session->next;
spastor 0:1c358ea10753 56 }
spastor 0:1c358ea10753 57
spastor 0:1c358ea10753 58 return session;
spastor 0:1c358ea10753 59 }
spastor 0:1c358ea10753 60
spastor 0:1c358ea10753 61 static connector_sm_session_t * sm_create_session(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_bool_t const client_originated)
spastor 0:1c358ea10753 62 {
spastor 0:1c358ea10753 63 connector_sm_session_t * session = NULL;
spastor 0:1c358ea10753 64 void * ptr = NULL;
spastor 0:1c358ea10753 65 connector_status_t result;
spastor 0:1c358ea10753 66 size_t const active_sessions = client_originated ? sm_ptr->session.active_client_sessions : sm_ptr->session.active_cloud_sessions;
spastor 0:1c358ea10753 67 static connector_bool_t print_once = connector_true;
spastor 0:1c358ea10753 68
spastor 0:1c358ea10753 69 if (active_sessions >= sm_ptr->session.max_sessions)
spastor 0:1c358ea10753 70 {
spastor 0:1c358ea10753 71 if (print_once)
spastor 0:1c358ea10753 72 {
spastor 0:1c358ea10753 73 connector_debug_printf("Active %s sessions reached the limit %" PRIsize "\n", client_originated ? "client" : "cloud", active_sessions);
spastor 0:1c358ea10753 74 print_once = connector_false;
spastor 0:1c358ea10753 75 }
spastor 0:1c358ea10753 76
spastor 0:1c358ea10753 77 goto done;
spastor 0:1c358ea10753 78 }
spastor 0:1c358ea10753 79
spastor 0:1c358ea10753 80 print_once = connector_true;
spastor 0:1c358ea10753 81 result = malloc_data_buffer(connector_ptr, sizeof *session, named_buffer_id(sm_session), &ptr);
spastor 0:1c358ea10753 82 if (result != connector_working)
spastor 0:1c358ea10753 83 goto error;
spastor 0:1c358ea10753 84
spastor 0:1c358ea10753 85 session = ptr;
spastor 0:1c358ea10753 86 result = get_system_time(connector_ptr, &session->start_time);
spastor 0:1c358ea10753 87 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 88
spastor 0:1c358ea10753 89 session->flags = 0;
spastor 0:1c358ea10753 90 session->error = connector_sm_error_none;
spastor 0:1c358ea10753 91 session->in.data = NULL;
spastor 0:1c358ea10753 92 session->in.bytes = 0;
spastor 0:1c358ea10753 93 session->bytes_processed = 0;
spastor 0:1c358ea10753 94 session->user.header = NULL;
spastor 0:1c358ea10753 95 session->user.context = NULL;
spastor 0:1c358ea10753 96 session->segments.processed = 0;
spastor 0:1c358ea10753 97 session->segments.count = 0;
spastor 0:1c358ea10753 98
spastor 0:1c358ea10753 99 session->transport = sm_ptr->network.transport;
spastor 0:1c358ea10753 100 #if (defined CONNECTOR_TRANSPORT_SMS)
spastor 0:1c358ea10753 101 if (session->transport == connector_transport_sms)
spastor 0:1c358ea10753 102 SmSetEncoded(session->flags);
spastor 0:1c358ea10753 103 #endif
spastor 0:1c358ea10753 104
spastor 0:1c358ea10753 105 if (client_originated)
spastor 0:1c358ea10753 106 {
spastor 0:1c358ea10753 107 result = sm_copy_user_request(sm_ptr, session);
spastor 0:1c358ea10753 108 ASSERT_GOTO(result == connector_working, error);
spastor 0:1c358ea10753 109 SmSetClientOwned(session->flags);
spastor 0:1c358ea10753 110
spastor 0:1c358ea10753 111 session->request_id = sm_ptr->pending.request_id;
spastor 0:1c358ea10753 112 sm_ptr->session.active_client_sessions++;
spastor 0:1c358ea10753 113 }
spastor 0:1c358ea10753 114 else
spastor 0:1c358ea10753 115 {
spastor 0:1c358ea10753 116 session->sm_state = connector_sm_state_receive_data;
spastor 0:1c358ea10753 117 sm_ptr->session.active_cloud_sessions++;
spastor 0:1c358ea10753 118 }
spastor 0:1c358ea10753 119
spastor 0:1c358ea10753 120 add_list_node(&sm_ptr->session.head, &sm_ptr->session.tail, session);
spastor 0:1c358ea10753 121 goto done;
spastor 0:1c358ea10753 122
spastor 0:1c358ea10753 123 error:
spastor 0:1c358ea10753 124 if (session != NULL)
spastor 0:1c358ea10753 125 {
spastor 0:1c358ea10753 126 result = free_data_buffer(connector_ptr, named_buffer_id(sm_session), session);
spastor 0:1c358ea10753 127 ASSERT(result == connector_working);
spastor 0:1c358ea10753 128 session = NULL;
spastor 0:1c358ea10753 129 }
spastor 0:1c358ea10753 130
spastor 0:1c358ea10753 131 done:
spastor 0:1c358ea10753 132 return session;
spastor 0:1c358ea10753 133 }
spastor 0:1c358ea10753 134
spastor 0:1c358ea10753 135 static connector_status_t sm_delete_session(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session)
spastor 0:1c358ea10753 136 {
spastor 0:1c358ea10753 137 connector_status_t result = connector_working;
spastor 0:1c358ea10753 138
spastor 0:1c358ea10753 139 ASSERT_GOTO(sm_ptr != NULL, error);
spastor 0:1c358ea10753 140 ASSERT_GOTO(session != NULL, error);
spastor 0:1c358ea10753 141
spastor 0:1c358ea10753 142 if (SmIsClientOwned(session->flags))
spastor 0:1c358ea10753 143 {
spastor 0:1c358ea10753 144 ASSERT(sm_ptr->session.active_client_sessions > 0);
spastor 0:1c358ea10753 145 sm_ptr->session.active_client_sessions--;
spastor 0:1c358ea10753 146 }
spastor 0:1c358ea10753 147 else
spastor 0:1c358ea10753 148 {
spastor 0:1c358ea10753 149 ASSERT(sm_ptr->session.active_cloud_sessions > 0);
spastor 0:1c358ea10753 150 sm_ptr->session.active_cloud_sessions--;
spastor 0:1c358ea10753 151 }
spastor 0:1c358ea10753 152
spastor 0:1c358ea10753 153 if (session->in.data != NULL)
spastor 0:1c358ea10753 154 {
spastor 0:1c358ea10753 155 result = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->in.data);
spastor 0:1c358ea10753 156 session->in.data = NULL;
spastor 0:1c358ea10753 157 }
spastor 0:1c358ea10753 158
spastor 0:1c358ea10753 159 remove_list_node(&sm_ptr->session.head, &sm_ptr->session.tail, session);
spastor 0:1c358ea10753 160 if (sm_ptr->session.current == session)
spastor 0:1c358ea10753 161 sm_ptr->session.current = (session->next != NULL) ? session->next : sm_ptr->session.head;
spastor 0:1c358ea10753 162
spastor 0:1c358ea10753 163 {
spastor 0:1c358ea10753 164 connector_status_t const status = free_data_buffer(connector_ptr, named_buffer_id(sm_session), session);
spastor 0:1c358ea10753 165
spastor 0:1c358ea10753 166 if (status != connector_working)
spastor 0:1c358ea10753 167 result = connector_abort;
spastor 0:1c358ea10753 168 }
spastor 0:1c358ea10753 169
spastor 0:1c358ea10753 170 if (sm_ptr->close.stop_condition == connector_wait_sessions_complete)
spastor 0:1c358ea10753 171 {
spastor 0:1c358ea10753 172 if (sm_ptr->session.head == NULL)
spastor 0:1c358ea10753 173 sm_ptr->transport.state = connector_transport_close;
spastor 0:1c358ea10753 174 }
spastor 0:1c358ea10753 175
spastor 0:1c358ea10753 176 error:
spastor 0:1c358ea10753 177 return result;
spastor 0:1c358ea10753 178 }
spastor 0:1c358ea10753 179
spastor 0:1c358ea10753 180 /* If request_id == NULL cancel ALL sessions. Else cancel the SM session whose Request ID matches the one passed as a parameter. */
spastor 0:1c358ea10753 181 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 182 static connector_status_t sm_cancel_session(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, uint32_t const * const request_id)
spastor 0:1c358ea10753 183 {
spastor 0:1c358ea10753 184 connector_status_t result = connector_working;
spastor 0:1c358ea10753 185 connector_sm_session_t * session = sm_ptr->session.head;
spastor 0:1c358ea10753 186 connector_bool_t cancel_all = connector_bool(request_id == NULL);
spastor 0:1c358ea10753 187
spastor 0:1c358ea10753 188 while (session != NULL)
spastor 0:1c358ea10753 189 {
spastor 0:1c358ea10753 190 connector_sm_session_t * next_session = NULL;
spastor 0:1c358ea10753 191 uint32_t session_request_id = request_id != NULL ? *request_id : SM_INVALID_REQUEST_ID;
spastor 0:1c358ea10753 192
spastor 0:1c358ea10753 193 if (cancel_all || (session_request_id == *request_id))
spastor 0:1c358ea10753 194 {
spastor 0:1c358ea10753 195 session->error = connector_sm_error_cancel;
spastor 0:1c358ea10753 196 result = sm_inform_session_complete(connector_ptr, session);
spastor 0:1c358ea10753 197 if (result != connector_working)
spastor 0:1c358ea10753 198 break;
spastor 0:1c358ea10753 199 next_session = session->next;
spastor 0:1c358ea10753 200 result = sm_delete_session(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 201 if (result != connector_working)
spastor 0:1c358ea10753 202 break;
spastor 0:1c358ea10753 203
spastor 0:1c358ea10753 204 if (!cancel_all)
spastor 0:1c358ea10753 205 break;
spastor 0:1c358ea10753 206 }
spastor 0:1c358ea10753 207
spastor 0:1c358ea10753 208 session = next_session != NULL ? next_session : session->next;
spastor 0:1c358ea10753 209 }
spastor 0:1c358ea10753 210 #if (defined CONNECTOR_DATA_POINTS)
spastor 0:1c358ea10753 211 dp_cancel_session(connector_ptr, session, request_id);
spastor 0:1c358ea10753 212 #endif
spastor 0:1c358ea10753 213 return result;
spastor 0:1c358ea10753 214 }
spastor 0:1c358ea10753 215 #else
spastor 0:1c358ea10753 216 static connector_status_t sm_cancel_session(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, void const * const user_context)
spastor 0:1c358ea10753 217 {
spastor 0:1c358ea10753 218 connector_status_t result = connector_working;
spastor 0:1c358ea10753 219 connector_sm_session_t * session = sm_ptr->session.head;
spastor 0:1c358ea10753 220 connector_bool_t cancel_all = connector_bool(user_context == NULL);
spastor 0:1c358ea10753 221
spastor 0:1c358ea10753 222 while (session != NULL)
spastor 0:1c358ea10753 223 {
spastor 0:1c358ea10753 224 connector_status_t status;
spastor 0:1c358ea10753 225 connector_sm_session_t * next_session = NULL;
spastor 0:1c358ea10753 226
spastor 0:1c358ea10753 227 if (cancel_all || (session->user.context == user_context))
spastor 0:1c358ea10753 228 {
spastor 0:1c358ea10753 229 if (session->user.context != NULL)
spastor 0:1c358ea10753 230 {
spastor 0:1c358ea10753 231 session->error = connector_sm_error_cancel;
spastor 0:1c358ea10753 232 status = sm_inform_session_complete(connector_ptr, session);
spastor 0:1c358ea10753 233 if (status != connector_working)
spastor 0:1c358ea10753 234 result = connector_abort;
spastor 0:1c358ea10753 235 }
spastor 0:1c358ea10753 236
spastor 0:1c358ea10753 237 next_session = session->next;
spastor 0:1c358ea10753 238 status = sm_delete_session(connector_ptr, sm_ptr, session);
spastor 0:1c358ea10753 239 if (status != connector_working)
spastor 0:1c358ea10753 240 {
spastor 0:1c358ea10753 241 result = connector_abort;
spastor 0:1c358ea10753 242 break;
spastor 0:1c358ea10753 243 }
spastor 0:1c358ea10753 244 if (!cancel_all)
spastor 0:1c358ea10753 245 break;
spastor 0:1c358ea10753 246 }
spastor 0:1c358ea10753 247
spastor 0:1c358ea10753 248 session = next_session;
spastor 0:1c358ea10753 249 }
spastor 0:1c358ea10753 250
spastor 0:1c358ea10753 251 return result;
spastor 0:1c358ea10753 252 }
spastor 0:1c358ea10753 253 #endif
spastor 0:1c358ea10753 254 static connector_status_t sm_process_pending_data(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr)
spastor 0:1c358ea10753 255 {
spastor 0:1c358ea10753 256 connector_status_t result = connector_idle;
spastor 0:1c358ea10753 257
spastor 0:1c358ea10753 258 if (sm_ptr->pending.data == NULL)
spastor 0:1c358ea10753 259 goto done;
spastor 0:1c358ea10753 260
spastor 0:1c358ea10753 261 switch (sm_ptr->pending.request)
spastor 0:1c358ea10753 262 {
spastor 0:1c358ea10753 263 case connector_initiate_transport_start:
spastor 0:1c358ea10753 264 switch(sm_ptr->transport.state)
spastor 0:1c358ea10753 265 {
spastor 0:1c358ea10753 266 case connector_transport_idle:
spastor 0:1c358ea10753 267 sm_ptr->transport.state = connector_transport_open;
spastor 0:1c358ea10753 268 break;
spastor 0:1c358ea10753 269
spastor 0:1c358ea10753 270 case connector_transport_close:
spastor 0:1c358ea10753 271 /* wait for close to complete */
spastor 0:1c358ea10753 272 goto done;
spastor 0:1c358ea10753 273
spastor 0:1c358ea10753 274 case connector_transport_terminate:
spastor 0:1c358ea10753 275 result = connector_device_terminated;
spastor 0:1c358ea10753 276 break;
spastor 0:1c358ea10753 277
spastor 0:1c358ea10753 278 default:
spastor 0:1c358ea10753 279 break;
spastor 0:1c358ea10753 280 }
spastor 0:1c358ea10753 281 break;
spastor 0:1c358ea10753 282
spastor 0:1c358ea10753 283 case connector_initiate_transport_stop:
spastor 0:1c358ea10753 284 if ((sm_ptr->close.stop_condition == connector_wait_sessions_complete) && (sm_ptr->session.head != NULL))
spastor 0:1c358ea10753 285 goto done;
spastor 0:1c358ea10753 286 else
spastor 0:1c358ea10753 287 {
spastor 0:1c358ea10753 288 result = sm_cancel_session(connector_ptr, sm_ptr, NULL);
spastor 0:1c358ea10753 289 sm_ptr->transport.state = connector_transport_close;
spastor 0:1c358ea10753 290 }
spastor 0:1c358ea10753 291 break;
spastor 0:1c358ea10753 292
spastor 0:1c358ea10753 293 case connector_initiate_session_cancel:
spastor 0:1c358ea10753 294 {
spastor 0:1c358ea10753 295 connector_sm_cancel_request_t const * const request = sm_ptr->pending.data;
spastor 0:1c358ea10753 296 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 297 result = sm_cancel_session(connector_ptr, sm_ptr, &request->request_id);
spastor 0:1c358ea10753 298 #else
spastor 0:1c358ea10753 299 result = sm_cancel_session(connector_ptr, sm_ptr, request->user_context);
spastor 0:1c358ea10753 300 #endif
spastor 0:1c358ea10753 301 break;
spastor 0:1c358ea10753 302 }
spastor 0:1c358ea10753 303 #if (CONNECTOR_VERSION >= 0x02010000)
spastor 0:1c358ea10753 304 case connector_initiate_session_cancel_all:
spastor 0:1c358ea10753 305 {
spastor 0:1c358ea10753 306 result = sm_cancel_session(connector_ptr, sm_ptr, NULL);
spastor 0:1c358ea10753 307 break;
spastor 0:1c358ea10753 308 }
spastor 0:1c358ea10753 309 #endif
spastor 0:1c358ea10753 310 default:
spastor 0:1c358ea10753 311 {
spastor 0:1c358ea10753 312 connector_bool_t const client_originated = connector_true;
spastor 0:1c358ea10753 313 connector_sm_session_t * const session = sm_create_session(connector_ptr, sm_ptr, client_originated);
spastor 0:1c358ea10753 314
spastor 0:1c358ea10753 315 if (session == NULL)
spastor 0:1c358ea10753 316 {
spastor 0:1c358ea10753 317 result = connector_pending;
spastor 0:1c358ea10753 318 goto done;
spastor 0:1c358ea10753 319 }
spastor 0:1c358ea10753 320
spastor 0:1c358ea10753 321 result = connector_working;
spastor 0:1c358ea10753 322 break;
spastor 0:1c358ea10753 323 }
spastor 0:1c358ea10753 324 }
spastor 0:1c358ea10753 325
spastor 0:1c358ea10753 326 sm_ptr->pending.data = NULL;
spastor 0:1c358ea10753 327
spastor 0:1c358ea10753 328 done:
spastor 0:1c358ea10753 329 return result;
spastor 0:1c358ea10753 330 }
spastor 0:1c358ea10753 331
spastor 0:1c358ea10753 332
spastor 0:1c358ea10753 333