Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
private/connector_sm_cmd.h@1:908afea5a49d, 2013-12-03 (annotated)
- 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?
| User | Revision | Line number | New 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 | static connector_status_t sm_copy_user_request(connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 13 | { |
| spastor | 0:1c358ea10753 | 14 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 15 | connector_bool_t response_needed; |
| spastor | 0:1c358ea10753 | 16 | |
| spastor | 0:1c358ea10753 | 17 | ASSERT_GOTO(sm_ptr->pending.data != NULL, error); |
| spastor | 0:1c358ea10753 | 18 | session->bytes_processed = 0; |
| spastor | 0:1c358ea10753 | 19 | |
| spastor | 0:1c358ea10753 | 20 | switch (sm_ptr->pending.request) |
| spastor | 0:1c358ea10753 | 21 | { |
| spastor | 0:1c358ea10753 | 22 | case connector_initiate_ping_request: |
| spastor | 0:1c358ea10753 | 23 | { |
| spastor | 0:1c358ea10753 | 24 | connector_sm_send_ping_request_t const * const request = sm_ptr->pending.data; |
| spastor | 0:1c358ea10753 | 25 | |
| spastor | 0:1c358ea10753 | 26 | session->user.context = request->user_context; |
| spastor | 0:1c358ea10753 | 27 | session->user.header = NULL; |
| spastor | 0:1c358ea10753 | 28 | session->command = connector_sm_cmd_ping; |
| spastor | 0:1c358ea10753 | 29 | response_needed = request->response_required; |
| spastor | 0:1c358ea10753 | 30 | session->sm_state = connector_sm_state_prepare_segment; |
| spastor | 0:1c358ea10753 | 31 | break; |
| spastor | 0:1c358ea10753 | 32 | } |
| spastor | 0:1c358ea10753 | 33 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 34 | case connector_initiate_send_data: |
| spastor | 0:1c358ea10753 | 35 | { |
| spastor | 0:1c358ea10753 | 36 | connector_request_data_service_send_t const * const request = sm_ptr->pending.data; |
| spastor | 0:1c358ea10753 | 37 | |
| spastor | 0:1c358ea10753 | 38 | session->user.context = request->user_context; |
| spastor | 0:1c358ea10753 | 39 | session->user.header = request->path; |
| spastor | 0:1c358ea10753 | 40 | session->command = (request->path != NULL) ? connector_sm_cmd_data : connector_sm_cmd_no_path_data; |
| spastor | 0:1c358ea10753 | 41 | response_needed = request->response_required; |
| spastor | 0:1c358ea10753 | 42 | session->sm_state = connector_sm_state_get_total_length; |
| spastor | 0:1c358ea10753 | 43 | #if (defined CONNECTOR_DATA_POINTS) |
| spastor | 0:1c358ea10753 | 44 | if (request->path != NULL) |
| spastor | 0:1c358ea10753 | 45 | { |
| spastor | 0:1c358ea10753 | 46 | char const dp_prefix[] = "DataPoint/"; |
| spastor | 0:1c358ea10753 | 47 | size_t const dp_prefix_bytes = sizeof dp_prefix - 1; |
| spastor | 0:1c358ea10753 | 48 | |
| spastor | 0:1c358ea10753 | 49 | if (!strncmp(request->path, dp_prefix, dp_prefix_bytes)) |
| spastor | 0:1c358ea10753 | 50 | SmSetDatapoint(session->flags); |
| spastor | 0:1c358ea10753 | 51 | } |
| spastor | 0:1c358ea10753 | 52 | #endif |
| spastor | 0:1c358ea10753 | 53 | break; |
| spastor | 0:1c358ea10753 | 54 | } |
| spastor | 0:1c358ea10753 | 55 | #endif |
| spastor | 0:1c358ea10753 | 56 | default: |
| spastor | 0:1c358ea10753 | 57 | ASSERT_GOTO(connector_false, error); |
| spastor | 0:1c358ea10753 | 58 | break; |
| spastor | 0:1c358ea10753 | 59 | } |
| spastor | 0:1c358ea10753 | 60 | |
| spastor | 0:1c358ea10753 | 61 | if (response_needed) SmSetResponseNeeded(session->flags); |
| spastor | 0:1c358ea10753 | 62 | |
| spastor | 0:1c358ea10753 | 63 | result = connector_working; |
| spastor | 0:1c358ea10753 | 64 | |
| spastor | 0:1c358ea10753 | 65 | error: |
| spastor | 0:1c358ea10753 | 66 | return result; |
| spastor | 0:1c358ea10753 | 67 | } |
| spastor | 0:1c358ea10753 | 68 | |
| spastor | 0:1c358ea10753 | 69 | static void sm_verify_result(connector_sm_data_t * const sm_ptr, connector_status_t * const result) |
| spastor | 0:1c358ea10753 | 70 | { |
| spastor | 0:1c358ea10753 | 71 | switch (*result) |
| spastor | 0:1c358ea10753 | 72 | { |
| spastor | 0:1c358ea10753 | 73 | case connector_pending: |
| spastor | 0:1c358ea10753 | 74 | case connector_working: |
| spastor | 0:1c358ea10753 | 75 | case connector_idle: |
| spastor | 0:1c358ea10753 | 76 | goto done; |
| spastor | 0:1c358ea10753 | 77 | |
| spastor | 0:1c358ea10753 | 78 | case connector_invalid_data_size: |
| spastor | 0:1c358ea10753 | 79 | connector_debug_printf("WARNING: received a 'connector_invalid_data_size'\n"); |
| spastor | 0:1c358ea10753 | 80 | break; |
| spastor | 0:1c358ea10753 | 81 | case connector_abort: |
| spastor | 0:1c358ea10753 | 82 | case connector_invalid_response: |
| spastor | 0:1c358ea10753 | 83 | sm_ptr->close.status = connector_close_status_abort; |
| spastor | 0:1c358ea10753 | 84 | break; |
| spastor | 0:1c358ea10753 | 85 | |
| spastor | 0:1c358ea10753 | 86 | default: |
| spastor | 0:1c358ea10753 | 87 | sm_ptr->close.status = connector_close_status_device_error; |
| spastor | 0:1c358ea10753 | 88 | break; |
| spastor | 0:1c358ea10753 | 89 | } |
| spastor | 0:1c358ea10753 | 90 | |
| spastor | 0:1c358ea10753 | 91 | *result = connector_working; |
| spastor | 0:1c358ea10753 | 92 | switch(sm_ptr->transport.state) |
| spastor | 0:1c358ea10753 | 93 | { |
| spastor | 0:1c358ea10753 | 94 | case connector_transport_idle: |
| spastor | 0:1c358ea10753 | 95 | case connector_transport_close: |
| spastor | 0:1c358ea10753 | 96 | case connector_transport_terminate: |
| spastor | 0:1c358ea10753 | 97 | break; |
| spastor | 0:1c358ea10753 | 98 | |
| spastor | 0:1c358ea10753 | 99 | default: |
| spastor | 0:1c358ea10753 | 100 | sm_ptr->transport.state = connector_transport_close; |
| spastor | 0:1c358ea10753 | 101 | break; |
| spastor | 0:1c358ea10753 | 102 | } |
| spastor | 0:1c358ea10753 | 103 | |
| spastor | 0:1c358ea10753 | 104 | done: |
| spastor | 0:1c358ea10753 | 105 | return; |
| spastor | 0:1c358ea10753 | 106 | } |
| spastor | 0:1c358ea10753 | 107 | |
| spastor | 0:1c358ea10753 | 108 | #if (defined CONNECTOR_COMPRESSION) || (defined CONNECTOR_SM_MULTIPART) |
| spastor | 0:1c358ea10753 | 109 | static size_t sm_get_max_payload_bytes(connector_sm_data_t * const sm_ptr) |
| spastor | 0:1c358ea10753 | 110 | { |
| spastor | 0:1c358ea10753 | 111 | size_t const sm_header_size = 5; |
| spastor | 0:1c358ea10753 | 112 | |
| spastor | 0:1c358ea10753 | 113 | /* This is used for Rx path... */ |
| spastor | 0:1c358ea10753 | 114 | size_t const max_payload_bytes = sm_ptr->transport.sm_mtu_rx - sm_header_size; |
| spastor | 0:1c358ea10753 | 115 | |
| spastor | 0:1c358ea10753 | 116 | return max_payload_bytes; |
| spastor | 0:1c358ea10753 | 117 | } |
| spastor | 0:1c358ea10753 | 118 | #endif |
| spastor | 0:1c358ea10753 | 119 | |
| spastor | 0:1c358ea10753 | 120 | static connector_status_t sm_allocate_user_buffer(connector_data_t * const connector_ptr, sm_data_block_t * const dblock) |
| spastor | 0:1c358ea10753 | 121 | { |
| spastor | 0:1c358ea10753 | 122 | void * ptr = NULL; |
| spastor | 0:1c358ea10753 | 123 | connector_status_t result = connector_working; |
| spastor | 0:1c358ea10753 | 124 | |
| spastor | 0:1c358ea10753 | 125 | if (dblock->bytes > 0) |
| spastor | 0:1c358ea10753 | 126 | { |
| spastor | 0:1c358ea10753 | 127 | ASSERT(dblock->data == NULL); |
| spastor | 0:1c358ea10753 | 128 | result = malloc_data_buffer(connector_ptr, dblock->bytes, named_buffer_id(sm_data_block), &ptr); |
| spastor | 0:1c358ea10753 | 129 | } |
| spastor | 0:1c358ea10753 | 130 | |
| spastor | 0:1c358ea10753 | 131 | dblock->data = ptr; |
| spastor | 0:1c358ea10753 | 132 | |
| spastor | 0:1c358ea10753 | 133 | return result; |
| spastor | 0:1c358ea10753 | 134 | } |
| spastor | 0:1c358ea10753 | 135 | |
| spastor | 0:1c358ea10753 | 136 | static connector_status_t sm_map_callback_status_to_connector_status(connector_callback_status_t const callback_status) |
| spastor | 0:1c358ea10753 | 137 | { |
| spastor | 0:1c358ea10753 | 138 | connector_status_t result; |
| spastor | 0:1c358ea10753 | 139 | |
| spastor | 0:1c358ea10753 | 140 | switch (callback_status) |
| spastor | 0:1c358ea10753 | 141 | { |
| spastor | 0:1c358ea10753 | 142 | case connector_callback_continue: |
| spastor | 0:1c358ea10753 | 143 | result = connector_working; |
| spastor | 0:1c358ea10753 | 144 | break; |
| spastor | 0:1c358ea10753 | 145 | |
| spastor | 0:1c358ea10753 | 146 | case connector_callback_busy: |
| spastor | 0:1c358ea10753 | 147 | result = connector_pending; |
| spastor | 0:1c358ea10753 | 148 | break; |
| spastor | 0:1c358ea10753 | 149 | |
| spastor | 0:1c358ea10753 | 150 | case connector_callback_error: |
| spastor | 0:1c358ea10753 | 151 | result = connector_device_error; |
| spastor | 0:1c358ea10753 | 152 | break; |
| spastor | 0:1c358ea10753 | 153 | |
| spastor | 0:1c358ea10753 | 154 | default: |
| spastor | 0:1c358ea10753 | 155 | result = connector_abort; |
| spastor | 0:1c358ea10753 | 156 | break; |
| spastor | 0:1c358ea10753 | 157 | } |
| spastor | 0:1c358ea10753 | 158 | |
| spastor | 0:1c358ea10753 | 159 | return result; |
| spastor | 0:1c358ea10753 | 160 | } |
| spastor | 0:1c358ea10753 | 161 | |
| spastor | 0:1c358ea10753 | 162 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 163 | static connector_callback_status_t sm_inform_data_complete(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 164 | { |
| spastor | 0:1c358ea10753 | 165 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 166 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 167 | connector_data_service_status_t status_info; |
| spastor | 0:1c358ea10753 | 168 | |
| spastor | 0:1c358ea10753 | 169 | status_info.transport = session->transport; |
| spastor | 0:1c358ea10753 | 170 | status_info.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 171 | status_info.session_error = connector_session_error_none; |
| spastor | 0:1c358ea10753 | 172 | switch (session->error) |
| spastor | 0:1c358ea10753 | 173 | { |
| spastor | 0:1c358ea10753 | 174 | case connector_sm_error_cancel: |
| spastor | 0:1c358ea10753 | 175 | status_info.status = connector_data_service_status_cancel; |
| spastor | 0:1c358ea10753 | 176 | break; |
| spastor | 0:1c358ea10753 | 177 | |
| spastor | 0:1c358ea10753 | 178 | case connector_sm_error_timeout: |
| spastor | 0:1c358ea10753 | 179 | status_info.status = connector_data_service_status_timeout; |
| spastor | 0:1c358ea10753 | 180 | break; |
| spastor | 0:1c358ea10753 | 181 | |
| spastor | 0:1c358ea10753 | 182 | case connector_sm_error_complete: |
| spastor | 0:1c358ea10753 | 183 | status_info.status = connector_data_service_status_complete; |
| spastor | 0:1c358ea10753 | 184 | break; |
| spastor | 0:1c358ea10753 | 185 | |
| spastor | 0:1c358ea10753 | 186 | case connector_sm_error_no_resource: |
| spastor | 0:1c358ea10753 | 187 | status_info.session_error = connector_session_error_memory; |
| spastor | 0:1c358ea10753 | 188 | /* no break */ |
| spastor | 0:1c358ea10753 | 189 | default: |
| spastor | 0:1c358ea10753 | 190 | status_info.status = connector_data_service_status_session_error; |
| spastor | 0:1c358ea10753 | 191 | break; |
| spastor | 0:1c358ea10753 | 192 | } |
| spastor | 0:1c358ea10753 | 193 | |
| spastor | 0:1c358ea10753 | 194 | #if (defined CONNECTOR_DATA_POINTS) |
| spastor | 0:1c358ea10753 | 195 | if (SmIsDatapoint(session->flags)) |
| spastor | 0:1c358ea10753 | 196 | { |
| spastor | 0:1c358ea10753 | 197 | callback_status = dp_handle_callback(connector_ptr, connector_request_id_data_service_send_status, &status_info); |
| spastor | 0:1c358ea10753 | 198 | } |
| spastor | 0:1c358ea10753 | 199 | else |
| spastor | 0:1c358ea10753 | 200 | #endif |
| spastor | 0:1c358ea10753 | 201 | { |
| spastor | 0:1c358ea10753 | 202 | request_id.data_service_request = SmIsClientOwned(session->flags) ? connector_request_id_data_service_send_status : connector_request_id_data_service_receive_status; |
| spastor | 0:1c358ea10753 | 203 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_service, request_id, &status_info); |
| spastor | 0:1c358ea10753 | 204 | } |
| spastor | 0:1c358ea10753 | 205 | |
| spastor | 0:1c358ea10753 | 206 | return callback_status; |
| spastor | 0:1c358ea10753 | 207 | } |
| spastor | 0:1c358ea10753 | 208 | #endif |
| spastor | 0:1c358ea10753 | 209 | |
| spastor | 0:1c358ea10753 | 210 | #if (defined CONNECTOR_SM_CLI) |
| spastor | 0:1c358ea10753 | 211 | static connector_callback_status_t sm_inform_cli_complete(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 212 | { |
| spastor | 0:1c358ea10753 | 213 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 214 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 215 | connector_sm_cli_status_t cb_data; |
| spastor | 0:1c358ea10753 | 216 | |
| spastor | 0:1c358ea10753 | 217 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 218 | cb_data.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 219 | cb_data.status = (session->error == connector_sm_error_cancel) ? connector_sm_cli_status_cancel : connector_sm_cli_status_error; |
| spastor | 0:1c358ea10753 | 220 | request_id.sm_request = connector_request_id_sm_cli_status; |
| spastor | 0:1c358ea10753 | 221 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 222 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 223 | callback_status = connector_callback_error; |
| spastor | 0:1c358ea10753 | 224 | |
| spastor | 0:1c358ea10753 | 225 | return callback_status; |
| spastor | 0:1c358ea10753 | 226 | } |
| spastor | 0:1c358ea10753 | 227 | #endif |
| spastor | 0:1c358ea10753 | 228 | |
| spastor | 0:1c358ea10753 | 229 | static connector_callback_status_t sm_inform_ping_complete(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 230 | { |
| spastor | 0:1c358ea10753 | 231 | connector_callback_status_t callback_status = connector_callback_continue; |
| spastor | 0:1c358ea10753 | 232 | |
| spastor | 0:1c358ea10753 | 233 | if (SmIsClientOwned(session->flags)) |
| spastor | 0:1c358ea10753 | 234 | { |
| spastor | 0:1c358ea10753 | 235 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 236 | connector_sm_ping_response_t cb_data; |
| spastor | 0:1c358ea10753 | 237 | |
| spastor | 0:1c358ea10753 | 238 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 239 | cb_data.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 240 | switch (session->error) |
| spastor | 0:1c358ea10753 | 241 | { |
| spastor | 0:1c358ea10753 | 242 | case connector_sm_error_none: |
| spastor | 0:1c358ea10753 | 243 | cb_data.status = connector_sm_ping_status_success; |
| spastor | 0:1c358ea10753 | 244 | break; |
| spastor | 0:1c358ea10753 | 245 | |
| spastor | 0:1c358ea10753 | 246 | case connector_sm_error_cancel: |
| spastor | 0:1c358ea10753 | 247 | cb_data.status = connector_sm_ping_status_cancel; |
| spastor | 0:1c358ea10753 | 248 | break; |
| spastor | 0:1c358ea10753 | 249 | |
| spastor | 0:1c358ea10753 | 250 | case connector_sm_error_timeout: |
| spastor | 0:1c358ea10753 | 251 | cb_data.status = connector_sm_ping_status_timeout; |
| spastor | 0:1c358ea10753 | 252 | break; |
| spastor | 0:1c358ea10753 | 253 | |
| spastor | 0:1c358ea10753 | 254 | case connector_sm_error_complete: |
| spastor | 0:1c358ea10753 | 255 | cb_data.status = connector_sm_ping_status_complete; |
| spastor | 0:1c358ea10753 | 256 | break; |
| spastor | 0:1c358ea10753 | 257 | |
| spastor | 0:1c358ea10753 | 258 | default: |
| spastor | 0:1c358ea10753 | 259 | cb_data.status = connector_sm_ping_status_error; |
| spastor | 0:1c358ea10753 | 260 | break; |
| spastor | 0:1c358ea10753 | 261 | } |
| spastor | 0:1c358ea10753 | 262 | |
| spastor | 0:1c358ea10753 | 263 | request_id.sm_request = connector_request_id_sm_ping_response; |
| spastor | 0:1c358ea10753 | 264 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 265 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 266 | callback_status = connector_callback_continue; |
| spastor | 0:1c358ea10753 | 267 | } |
| spastor | 0:1c358ea10753 | 268 | |
| spastor | 0:1c358ea10753 | 269 | return callback_status; |
| spastor | 0:1c358ea10753 | 270 | } |
| spastor | 0:1c358ea10753 | 271 | |
| spastor | 0:1c358ea10753 | 272 | static connector_status_t sm_inform_session_complete(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 273 | { |
| spastor | 0:1c358ea10753 | 274 | connector_status_t result; |
| spastor | 0:1c358ea10753 | 275 | connector_callback_status_t callback_status = connector_callback_continue; |
| spastor | 0:1c358ea10753 | 276 | |
| spastor | 0:1c358ea10753 | 277 | if (session->sm_state == connector_sm_state_complete) goto done; |
| spastor | 0:1c358ea10753 | 278 | |
| spastor | 0:1c358ea10753 | 279 | switch (session->command) |
| spastor | 0:1c358ea10753 | 280 | { |
| spastor | 0:1c358ea10753 | 281 | case connector_sm_cmd_data: |
| spastor | 0:1c358ea10753 | 282 | case connector_sm_cmd_no_path_data: |
| spastor | 0:1c358ea10753 | 283 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 284 | callback_status = sm_inform_data_complete(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 285 | #endif |
| spastor | 0:1c358ea10753 | 286 | break; |
| spastor | 0:1c358ea10753 | 287 | |
| spastor | 0:1c358ea10753 | 288 | #if (defined CONNECTOR_SM_CLI) |
| spastor | 0:1c358ea10753 | 289 | case connector_sm_cmd_cli: |
| spastor | 0:1c358ea10753 | 290 | callback_status = sm_inform_cli_complete(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 291 | break; |
| spastor | 0:1c358ea10753 | 292 | #endif |
| spastor | 0:1c358ea10753 | 293 | |
| spastor | 0:1c358ea10753 | 294 | case connector_sm_cmd_ping: |
| spastor | 0:1c358ea10753 | 295 | callback_status = sm_inform_ping_complete(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 296 | break; |
| spastor | 0:1c358ea10753 | 297 | |
| spastor | 0:1c358ea10753 | 298 | default: |
| spastor | 0:1c358ea10753 | 299 | connector_debug_printf("sm_inform_session_complete: cancelling the session cmd [%d]\n", session->command); |
| spastor | 0:1c358ea10753 | 300 | callback_status = connector_callback_continue; |
| spastor | 0:1c358ea10753 | 301 | break; |
| spastor | 0:1c358ea10753 | 302 | } |
| spastor | 0:1c358ea10753 | 303 | |
| spastor | 0:1c358ea10753 | 304 | done: |
| spastor | 0:1c358ea10753 | 305 | result = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 306 | |
| spastor | 0:1c358ea10753 | 307 | if (session->in.data != NULL) |
| spastor | 0:1c358ea10753 | 308 | { |
| spastor | 0:1c358ea10753 | 309 | if (free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->in.data) != connector_working) |
| spastor | 0:1c358ea10753 | 310 | result = connector_abort; |
| spastor | 0:1c358ea10753 | 311 | |
| spastor | 0:1c358ea10753 | 312 | session->in.bytes = 0; |
| spastor | 0:1c358ea10753 | 313 | session->in.data = NULL; |
| spastor | 0:1c358ea10753 | 314 | } |
| spastor | 0:1c358ea10753 | 315 | |
| spastor | 0:1c358ea10753 | 316 | return result; |
| spastor | 0:1c358ea10753 | 317 | } |
| spastor | 0:1c358ea10753 | 318 | |
| spastor | 0:1c358ea10753 | 319 | static connector_status_t sm_switch_path(connector_data_t * const connector_ptr, connector_sm_session_t * const session, connector_sm_state_t const next_state) |
| spastor | 0:1c358ea10753 | 320 | { |
| spastor | 0:1c358ea10753 | 321 | connector_status_t result = connector_working; |
| spastor | 0:1c358ea10753 | 322 | |
| spastor | 0:1c358ea10753 | 323 | if (session->in.data != NULL) |
| spastor | 0:1c358ea10753 | 324 | { |
| spastor | 0:1c358ea10753 | 325 | result = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->in.data); |
| spastor | 0:1c358ea10753 | 326 | if (result != connector_working) goto error; |
| spastor | 0:1c358ea10753 | 327 | |
| spastor | 0:1c358ea10753 | 328 | session->in.bytes = 0; |
| spastor | 0:1c358ea10753 | 329 | session->in.data = NULL; |
| spastor | 0:1c358ea10753 | 330 | } |
| spastor | 0:1c358ea10753 | 331 | |
| spastor | 0:1c358ea10753 | 332 | if (SmIsResponseNeeded(session->flags)) |
| spastor | 0:1c358ea10753 | 333 | { |
| spastor | 0:1c358ea10753 | 334 | session->sm_state = next_state; |
| spastor | 0:1c358ea10753 | 335 | SmClearCompressed(session->flags); |
| spastor | 0:1c358ea10753 | 336 | SmClearMultiPart(session->flags); |
| spastor | 0:1c358ea10753 | 337 | SmSetResponse(session->flags); |
| spastor | 0:1c358ea10753 | 338 | session->segments.processed = 0; |
| spastor | 0:1c358ea10753 | 339 | if (session->command == connector_sm_cmd_data || session->command == connector_sm_cmd_no_path_data) |
| spastor | 0:1c358ea10753 | 340 | SmClearResponseNeeded(session->flags); /* After the response is sent, inform the user that the session is completed */ |
| spastor | 0:1c358ea10753 | 341 | } |
| spastor | 0:1c358ea10753 | 342 | else |
| spastor | 0:1c358ea10753 | 343 | { |
| spastor | 0:1c358ea10753 | 344 | if (SmIsClientOwned(session->flags) && !SmIsError(session->flags)) /* If it is an error, it has already been called by sm_handle_error() */ |
| spastor | 0:1c358ea10753 | 345 | { |
| spastor | 0:1c358ea10753 | 346 | session->error = connector_sm_error_complete; |
| spastor | 0:1c358ea10753 | 347 | result = sm_inform_session_complete(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 348 | } |
| spastor | 0:1c358ea10753 | 349 | |
| spastor | 0:1c358ea10753 | 350 | session->sm_state = connector_sm_state_complete; |
| spastor | 0:1c358ea10753 | 351 | } |
| spastor | 0:1c358ea10753 | 352 | |
| spastor | 0:1c358ea10753 | 353 | error: |
| spastor | 0:1c358ea10753 | 354 | return result; |
| spastor | 0:1c358ea10753 | 355 | } |
| spastor | 0:1c358ea10753 | 356 | |
| spastor | 0:1c358ea10753 | 357 | static void sm_set_payload_process(connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 358 | { |
| spastor | 0:1c358ea10753 | 359 | size_t const zlib_header_bytes = 2; |
| spastor | 0:1c358ea10753 | 360 | |
| spastor | 0:1c358ea10753 | 361 | session->in.bytes = session->bytes_processed; |
| spastor | 0:1c358ea10753 | 362 | session->sm_state = connector_sm_state_prepare_segment; |
| spastor | 0:1c358ea10753 | 363 | session->bytes_processed = SmIsCompressed(session->flags) ? zlib_header_bytes : 0; |
| spastor | 0:1c358ea10753 | 364 | } |
| spastor | 0:1c358ea10753 | 365 | |
| spastor | 0:1c358ea10753 | 366 | static void sm_set_payload_complete(connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 367 | { |
| spastor | 0:1c358ea10753 | 368 | ASSERT(session->bytes_processed <= session->in.bytes); |
| spastor | 0:1c358ea10753 | 369 | |
| spastor | 0:1c358ea10753 | 370 | #if (defined CONNECTOR_COMPRESSION) |
| spastor | 0:1c358ea10753 | 371 | session->sm_state = connector_sm_state_compress; |
| spastor | 0:1c358ea10753 | 372 | #else |
| spastor | 0:1c358ea10753 | 373 | sm_set_payload_process(session); |
| spastor | 0:1c358ea10753 | 374 | #endif |
| spastor | 0:1c358ea10753 | 375 | } |
| spastor | 0:1c358ea10753 | 376 | |
| spastor | 0:1c358ea10753 | 377 | static void sm_set_header_complete(connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 378 | { |
| spastor | 0:1c358ea10753 | 379 | if (session->bytes_processed < session->in.bytes) |
| spastor | 0:1c358ea10753 | 380 | session->sm_state = connector_sm_state_more_data; |
| spastor | 0:1c358ea10753 | 381 | else |
| spastor | 0:1c358ea10753 | 382 | sm_set_payload_complete(session); |
| spastor | 0:1c358ea10753 | 383 | } |
| spastor | 0:1c358ea10753 | 384 | |
| spastor | 0:1c358ea10753 | 385 | static connector_status_t sm_prepare_data_request(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 386 | { |
| spastor | 0:1c358ea10753 | 387 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 388 | size_t const path_length_field_bytes = 1; |
| spastor | 0:1c358ea10753 | 389 | char const * path = NULL; |
| spastor | 0:1c358ea10753 | 390 | size_t path_len = 0; |
| spastor | 0:1c358ea10753 | 391 | |
| spastor | 0:1c358ea10753 | 392 | if (session->command == connector_sm_cmd_data) |
| spastor | 0:1c358ea10753 | 393 | { |
| spastor | 0:1c358ea10753 | 394 | size_t const five_bits_max_len = (1 << 5); |
| spastor | 0:1c358ea10753 | 395 | |
| spastor | 0:1c358ea10753 | 396 | path = session->user.header; |
| spastor | 0:1c358ea10753 | 397 | ASSERT_GOTO(path != NULL, error); |
| spastor | 0:1c358ea10753 | 398 | path_len = strlen(path); |
| spastor | 0:1c358ea10753 | 399 | ASSERT_GOTO(path_len < five_bits_max_len, error); |
| spastor | 0:1c358ea10753 | 400 | session->in.bytes += (path_length_field_bytes + path_len); |
| spastor | 0:1c358ea10753 | 401 | } |
| spastor | 0:1c358ea10753 | 402 | |
| spastor | 0:1c358ea10753 | 403 | session->bytes_processed = 0; |
| spastor | 0:1c358ea10753 | 404 | result = sm_allocate_user_buffer(connector_ptr, &session->in); |
| spastor | 0:1c358ea10753 | 405 | if (result != connector_working) |
| spastor | 0:1c358ea10753 | 406 | { |
| spastor | 0:1c358ea10753 | 407 | session->error = connector_sm_error_no_resource; |
| spastor | 0:1c358ea10753 | 408 | goto error; |
| spastor | 0:1c358ea10753 | 409 | } |
| spastor | 0:1c358ea10753 | 410 | |
| spastor | 0:1c358ea10753 | 411 | if (path != NULL) |
| spastor | 0:1c358ea10753 | 412 | { |
| spastor | 0:1c358ea10753 | 413 | uint8_t * header = session->in.data; |
| spastor | 0:1c358ea10753 | 414 | |
| spastor | 0:1c358ea10753 | 415 | *header++ = path_len; |
| spastor | 0:1c358ea10753 | 416 | memcpy(header, path, path_len); |
| spastor | 0:1c358ea10753 | 417 | session->bytes_processed = path_length_field_bytes + path_len; |
| spastor | 0:1c358ea10753 | 418 | } |
| spastor | 0:1c358ea10753 | 419 | |
| spastor | 0:1c358ea10753 | 420 | sm_set_header_complete(session); |
| spastor | 0:1c358ea10753 | 421 | |
| spastor | 0:1c358ea10753 | 422 | error: |
| spastor | 0:1c358ea10753 | 423 | return result; |
| spastor | 0:1c358ea10753 | 424 | } |
| spastor | 0:1c358ea10753 | 425 | |
| spastor | 0:1c358ea10753 | 426 | static connector_status_t sm_prepare_data_response(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 427 | { |
| spastor | 0:1c358ea10753 | 428 | connector_status_t const result = sm_allocate_user_buffer(connector_ptr, &session->in); |
| spastor | 0:1c358ea10753 | 429 | |
| spastor | 0:1c358ea10753 | 430 | if (result == connector_working) |
| spastor | 0:1c358ea10753 | 431 | { |
| spastor | 0:1c358ea10753 | 432 | session->bytes_processed = 0; |
| spastor | 0:1c358ea10753 | 433 | sm_set_header_complete(session); |
| spastor | 0:1c358ea10753 | 434 | } |
| spastor | 0:1c358ea10753 | 435 | else |
| spastor | 0:1c358ea10753 | 436 | session->error = connector_sm_error_no_resource; |
| spastor | 0:1c358ea10753 | 437 | |
| spastor | 0:1c358ea10753 | 438 | return result; |
| spastor | 0:1c358ea10753 | 439 | } |
| spastor | 0:1c358ea10753 | 440 | |
| spastor | 0:1c358ea10753 | 441 | #if (defined CONNECTOR_SM_CLI) |
| spastor | 0:1c358ea10753 | 442 | static connector_status_t sm_process_cli_request(connector_data_t * const connector_ptr, connector_sm_session_t * const session, void * const payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 443 | { |
| spastor | 0:1c358ea10753 | 444 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 445 | char * const cli_command = payload; |
| spastor | 0:1c358ea10753 | 446 | size_t cli_bytes; |
| spastor | 0:1c358ea10753 | 447 | connector_sm_data_t * sm_ptr = NULL; |
| spastor | 0:1c358ea10753 | 448 | |
| spastor | 0:1c358ea10753 | 449 | if (SmIsLastData(session->flags)) |
| spastor | 0:1c358ea10753 | 450 | { |
| spastor | 0:1c358ea10753 | 451 | cli_bytes = strlen(cli_command) + 1; /* +1 for nul-terminate */ |
| spastor | 0:1c358ea10753 | 452 | } |
| spastor | 0:1c358ea10753 | 453 | else |
| spastor | 0:1c358ea10753 | 454 | { |
| spastor | 0:1c358ea10753 | 455 | cli_bytes = bytes; |
| spastor | 0:1c358ea10753 | 456 | } |
| spastor | 0:1c358ea10753 | 457 | |
| spastor | 0:1c358ea10753 | 458 | switch (session->transport) |
| spastor | 0:1c358ea10753 | 459 | { |
| spastor | 0:1c358ea10753 | 460 | #if (defined CONNECTOR_TRANSPORT_UDP) |
| spastor | 0:1c358ea10753 | 461 | case connector_transport_udp: |
| spastor | 0:1c358ea10753 | 462 | sm_ptr = &connector_ptr->sm_udp; |
| spastor | 0:1c358ea10753 | 463 | break; |
| spastor | 0:1c358ea10753 | 464 | #endif |
| spastor | 0:1c358ea10753 | 465 | |
| spastor | 0:1c358ea10753 | 466 | #if (defined CONNECTOR_TRANSPORT_SMS) |
| spastor | 0:1c358ea10753 | 467 | case connector_transport_sms: |
| spastor | 0:1c358ea10753 | 468 | sm_ptr = &connector_ptr->sm_sms; |
| spastor | 0:1c358ea10753 | 469 | break; |
| spastor | 0:1c358ea10753 | 470 | #endif |
| spastor | 0:1c358ea10753 | 471 | |
| spastor | 0:1c358ea10753 | 472 | default: |
| spastor | 0:1c358ea10753 | 473 | ASSERT(connector_false); |
| spastor | 0:1c358ea10753 | 474 | break; |
| spastor | 0:1c358ea10753 | 475 | } |
| spastor | 0:1c358ea10753 | 476 | |
| spastor | 0:1c358ea10753 | 477 | if (bytes > cli_bytes) |
| spastor | 0:1c358ea10753 | 478 | { |
| spastor | 0:1c358ea10753 | 479 | size_t const max_response_packets = LoadBE16(cli_command + cli_bytes); |
| spastor | 0:1c358ea10753 | 480 | size_t max_response_bytes = 0; |
| spastor | 0:1c358ea10753 | 481 | |
| spastor | 0:1c358ea10753 | 482 | size_t const max_payload = sm_ptr->transport.sm_mtu_tx - record_end(segment); |
| spastor | 0:1c358ea10753 | 483 | |
| spastor | 0:1c358ea10753 | 484 | if (max_response_packets == 0) |
| spastor | 0:1c358ea10753 | 485 | max_response_bytes = 0; |
| spastor | 0:1c358ea10753 | 486 | else if (max_response_packets == 1) |
| spastor | 0:1c358ea10753 | 487 | max_response_bytes = max_payload; |
| spastor | 0:1c358ea10753 | 488 | else |
| spastor | 0:1c358ea10753 | 489 | { |
| spastor | 0:1c358ea10753 | 490 | size_t const segment0_overhead_bytes = record_end(segment0) - record_end(segmentn); |
| spastor | 0:1c358ea10753 | 491 | max_response_bytes = max_response_packets * max_payload - segment0_overhead_bytes; |
| spastor | 0:1c358ea10753 | 492 | } |
| spastor | 0:1c358ea10753 | 493 | |
| spastor | 0:1c358ea10753 | 494 | session->user.header = (void *)max_response_bytes; |
| spastor | 0:1c358ea10753 | 495 | } |
| spastor | 0:1c358ea10753 | 496 | else |
| spastor | 0:1c358ea10753 | 497 | { |
| spastor | 0:1c358ea10753 | 498 | session->user.header = (void *)SIZE_MAX; |
| spastor | 0:1c358ea10753 | 499 | } |
| spastor | 0:1c358ea10753 | 500 | |
| spastor | 0:1c358ea10753 | 501 | { |
| spastor | 0:1c358ea10753 | 502 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 503 | connector_sm_cli_request_t cli_request; |
| spastor | 0:1c358ea10753 | 504 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 505 | |
| spastor | 0:1c358ea10753 | 506 | cli_request.transport = session->transport; |
| spastor | 0:1c358ea10753 | 507 | cli_request.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 508 | cli_request.buffer = cli_command; |
| spastor | 0:1c358ea10753 | 509 | cli_request.bytes_used = cli_bytes; |
| spastor | 0:1c358ea10753 | 510 | cli_request.response_required = SmIsResponseNeeded(session->flags); |
| spastor | 0:1c358ea10753 | 511 | #if (CONNECTOR_VERSION >= 0x02010000) |
| spastor | 0:1c358ea10753 | 512 | cli_request.more_data = SmIsNotLastData(session->flags); |
| spastor | 0:1c358ea10753 | 513 | #endif |
| spastor | 0:1c358ea10753 | 514 | |
| spastor | 0:1c358ea10753 | 515 | request_id.sm_request = connector_request_id_sm_cli_request; |
| spastor | 0:1c358ea10753 | 516 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cli_request); |
| spastor | 0:1c358ea10753 | 517 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 518 | callback_status = connector_callback_error; |
| spastor | 0:1c358ea10753 | 519 | result = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 520 | if (callback_status == connector_callback_continue) |
| spastor | 0:1c358ea10753 | 521 | session->user.context = cli_request.user_context; |
| spastor | 0:1c358ea10753 | 522 | } |
| spastor | 0:1c358ea10753 | 523 | |
| spastor | 0:1c358ea10753 | 524 | return result; |
| spastor | 0:1c358ea10753 | 525 | } |
| spastor | 0:1c358ea10753 | 526 | |
| spastor | 0:1c358ea10753 | 527 | static connector_status_t sm_prepare_cli_response(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 528 | { |
| spastor | 0:1c358ea10753 | 529 | connector_status_t result; |
| spastor | 0:1c358ea10753 | 530 | connector_sm_cli_response_t cli_response; |
| spastor | 0:1c358ea10753 | 531 | size_t const allowed_bytes = (size_t)session->user.header; |
| spastor | 0:1c358ea10753 | 532 | |
| spastor | 0:1c358ea10753 | 533 | if (session->in.data == NULL) |
| spastor | 0:1c358ea10753 | 534 | { |
| spastor | 0:1c358ea10753 | 535 | if (session->in.bytes > allowed_bytes) |
| spastor | 0:1c358ea10753 | 536 | session->in.bytes = allowed_bytes; |
| spastor | 0:1c358ea10753 | 537 | |
| spastor | 0:1c358ea10753 | 538 | session->bytes_processed = 0; |
| spastor | 0:1c358ea10753 | 539 | result = sm_allocate_user_buffer(connector_ptr, &session->in); |
| spastor | 0:1c358ea10753 | 540 | if (result != connector_working) |
| spastor | 0:1c358ea10753 | 541 | goto error; |
| spastor | 0:1c358ea10753 | 542 | } |
| spastor | 0:1c358ea10753 | 543 | |
| spastor | 0:1c358ea10753 | 544 | cli_response.transport = session->transport; |
| spastor | 0:1c358ea10753 | 545 | cli_response.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 546 | ASSERT(session->in.bytes >= session->bytes_processed); |
| spastor | 0:1c358ea10753 | 547 | cli_response.bytes_available = (session->in.bytes - session->bytes_processed); |
| spastor | 0:1c358ea10753 | 548 | cli_response.buffer = ((char *)session->in.data) + session->bytes_processed; |
| spastor | 0:1c358ea10753 | 549 | cli_response.bytes_used = 0; |
| spastor | 0:1c358ea10753 | 550 | cli_response.more_data = connector_false; |
| spastor | 0:1c358ea10753 | 551 | |
| spastor | 0:1c358ea10753 | 552 | { |
| spastor | 0:1c358ea10753 | 553 | connector_callback_status_t status; |
| spastor | 0:1c358ea10753 | 554 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 555 | |
| spastor | 0:1c358ea10753 | 556 | request_id.sm_request = connector_request_id_sm_cli_response; |
| spastor | 0:1c358ea10753 | 557 | status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cli_response); |
| spastor | 0:1c358ea10753 | 558 | if (status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 559 | status = connector_callback_error; |
| spastor | 0:1c358ea10753 | 560 | ASSERT(cli_response.bytes_available >= cli_response.bytes_used); |
| spastor | 0:1c358ea10753 | 561 | result = sm_map_callback_status_to_connector_status(status); |
| spastor | 0:1c358ea10753 | 562 | } |
| spastor | 0:1c358ea10753 | 563 | |
| spastor | 0:1c358ea10753 | 564 | switch (result) |
| spastor | 0:1c358ea10753 | 565 | { |
| spastor | 0:1c358ea10753 | 566 | case connector_working: |
| spastor | 0:1c358ea10753 | 567 | session->bytes_processed += cli_response.bytes_used; |
| spastor | 0:1c358ea10753 | 568 | if ((!cli_response.more_data) || (session->bytes_processed >= session->in.bytes)) |
| spastor | 0:1c358ea10753 | 569 | sm_set_payload_complete(session); |
| spastor | 0:1c358ea10753 | 570 | break; |
| spastor | 0:1c358ea10753 | 571 | |
| spastor | 0:1c358ea10753 | 572 | case connector_device_error: |
| spastor | 0:1c358ea10753 | 573 | session->error = connector_sm_error_cancel; |
| spastor | 0:1c358ea10753 | 574 | result = connector_working; |
| spastor | 0:1c358ea10753 | 575 | break; |
| spastor | 0:1c358ea10753 | 576 | |
| spastor | 0:1c358ea10753 | 577 | default: |
| spastor | 0:1c358ea10753 | 578 | break; |
| spastor | 0:1c358ea10753 | 579 | } |
| spastor | 0:1c358ea10753 | 580 | |
| spastor | 0:1c358ea10753 | 581 | error: |
| spastor | 0:1c358ea10753 | 582 | return result; |
| spastor | 0:1c358ea10753 | 583 | } |
| spastor | 0:1c358ea10753 | 584 | #endif |
| spastor | 0:1c358ea10753 | 585 | |
| spastor | 0:1c358ea10753 | 586 | #if (defined CONNECTOR_TRANSPORT_SMS) |
| spastor | 0:1c358ea10753 | 587 | static connector_status_t sm_process_config_request(connector_data_t * const connector_ptr, connector_sm_session_t * const session, void * const payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 588 | { |
| spastor | 0:1c358ea10753 | 589 | connector_status_t result = connector_success; |
| spastor | 0:1c358ea10753 | 590 | connector_sm_receive_config_request_t config_request; |
| spastor | 0:1c358ea10753 | 591 | |
| spastor | 0:1c358ea10753 | 592 | ASSERT(SmIsLastData(session->flags)); |
| spastor | 0:1c358ea10753 | 593 | config_request.phone_number = payload; |
| spastor | 0:1c358ea10753 | 594 | |
| spastor | 0:1c358ea10753 | 595 | { |
| spastor | 0:1c358ea10753 | 596 | size_t const phone_bytes = strlen(config_request.phone_number) + 1; |
| spastor | 0:1c358ea10753 | 597 | config_request.service_id = (phone_bytes < bytes) ? config_request.phone_number + phone_bytes : NULL; |
| spastor | 0:1c358ea10753 | 598 | } |
| spastor | 0:1c358ea10753 | 599 | |
| spastor | 0:1c358ea10753 | 600 | /* Callback sms transport close/open so new phone makes effect */ |
| spastor | 0:1c358ea10753 | 601 | { |
| spastor | 0:1c358ea10753 | 602 | connector_sm_data_t * const sm_ptr = &connector_ptr->sm_sms; /* Assume it's SMS transport */ |
| spastor | 0:1c358ea10753 | 603 | ASSERT(sm_ptr->network.class_id == connector_class_id_network_sms); |
| spastor | 0:1c358ea10753 | 604 | |
| spastor | 0:1c358ea10753 | 605 | if (sm_ptr->network.handle != NULL) |
| spastor | 0:1c358ea10753 | 606 | { |
| spastor | 0:1c358ea10753 | 607 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 608 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 609 | connector_network_close_t close_data; |
| spastor | 0:1c358ea10753 | 610 | |
| spastor | 0:1c358ea10753 | 611 | /* Close */ |
| spastor | 0:1c358ea10753 | 612 | close_data.handle = sm_ptr->network.handle; |
| spastor | 0:1c358ea10753 | 613 | close_data.status = connector_close_status_device_stopped; |
| spastor | 0:1c358ea10753 | 614 | |
| spastor | 0:1c358ea10753 | 615 | request_id.network_request = connector_request_id_network_close; |
| spastor | 0:1c358ea10753 | 616 | callback_status = connector_callback(connector_ptr->callback, sm_ptr->network.class_id, request_id, &close_data); |
| spastor | 0:1c358ea10753 | 617 | ASSERT(callback_status != connector_callback_unrecognized); |
| spastor | 0:1c358ea10753 | 618 | switch (callback_status) |
| spastor | 0:1c358ea10753 | 619 | { |
| spastor | 0:1c358ea10753 | 620 | case connector_callback_busy: |
| spastor | 0:1c358ea10753 | 621 | result = connector_pending; |
| spastor | 0:1c358ea10753 | 622 | sm_ptr->transport.state = connector_transport_receive; /* Keep on receive state to complete reconfiguration operation */ |
| spastor | 0:1c358ea10753 | 623 | goto error; |
| spastor | 0:1c358ea10753 | 624 | |
| spastor | 0:1c358ea10753 | 625 | case connector_callback_continue: |
| spastor | 0:1c358ea10753 | 626 | sm_ptr->network.handle = NULL; |
| spastor | 0:1c358ea10753 | 627 | result = connector_working; |
| spastor | 0:1c358ea10753 | 628 | break; |
| spastor | 0:1c358ea10753 | 629 | |
| spastor | 0:1c358ea10753 | 630 | default: |
| spastor | 0:1c358ea10753 | 631 | sm_ptr->close.status = connector_close_status_abort; |
| spastor | 0:1c358ea10753 | 632 | break; |
| spastor | 0:1c358ea10753 | 633 | } |
| spastor | 0:1c358ea10753 | 634 | } |
| spastor | 0:1c358ea10753 | 635 | |
| spastor | 0:1c358ea10753 | 636 | if (sm_ptr->network.handle == NULL) |
| spastor | 0:1c358ea10753 | 637 | { |
| spastor | 0:1c358ea10753 | 638 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 639 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 640 | connector_network_open_t open_data; |
| spastor | 0:1c358ea10753 | 641 | |
| spastor | 0:1c358ea10753 | 642 | /* Open */ |
| spastor | 0:1c358ea10753 | 643 | open_data.device_cloud_url = config_request.phone_number; |
| spastor | 0:1c358ea10753 | 644 | open_data.handle = NULL; |
| spastor | 0:1c358ea10753 | 645 | |
| spastor | 0:1c358ea10753 | 646 | request_id.network_request = connector_request_id_network_open; |
| spastor | 0:1c358ea10753 | 647 | callback_status = connector_callback(connector_ptr->callback, sm_ptr->network.class_id, request_id, &open_data); |
| spastor | 0:1c358ea10753 | 648 | ASSERT(callback_status != connector_callback_unrecognized); |
| spastor | 0:1c358ea10753 | 649 | switch (callback_status) |
| spastor | 0:1c358ea10753 | 650 | { |
| spastor | 0:1c358ea10753 | 651 | case connector_callback_continue: |
| spastor | 0:1c358ea10753 | 652 | result = connector_working; |
| spastor | 0:1c358ea10753 | 653 | sm_ptr->network.handle = open_data.handle; |
| spastor | 0:1c358ea10753 | 654 | break; |
| spastor | 0:1c358ea10753 | 655 | |
| spastor | 0:1c358ea10753 | 656 | case connector_callback_abort: |
| spastor | 0:1c358ea10753 | 657 | result = connector_abort; |
| spastor | 0:1c358ea10753 | 658 | goto error; |
| spastor | 0:1c358ea10753 | 659 | |
| spastor | 0:1c358ea10753 | 660 | case connector_callback_unrecognized: |
| spastor | 0:1c358ea10753 | 661 | result = connector_unavailable; |
| spastor | 0:1c358ea10753 | 662 | goto error; |
| spastor | 0:1c358ea10753 | 663 | |
| spastor | 0:1c358ea10753 | 664 | case connector_callback_error: |
| spastor | 0:1c358ea10753 | 665 | result = connector_open_error; |
| spastor | 0:1c358ea10753 | 666 | goto error; |
| spastor | 0:1c358ea10753 | 667 | |
| spastor | 0:1c358ea10753 | 668 | case connector_callback_busy: |
| spastor | 0:1c358ea10753 | 669 | result = connector_pending; |
| spastor | 0:1c358ea10753 | 670 | sm_ptr->transport.state = connector_transport_receive; /* Keep on receive state to complete reconfiguration operation */ |
| spastor | 0:1c358ea10753 | 671 | goto error; |
| spastor | 0:1c358ea10753 | 672 | } |
| spastor | 0:1c358ea10753 | 673 | } |
| spastor | 0:1c358ea10753 | 674 | } |
| spastor | 0:1c358ea10753 | 675 | |
| spastor | 0:1c358ea10753 | 676 | /* Callback to config.c so user can save the new phone to persistent storage */ |
| spastor | 0:1c358ea10753 | 677 | #if !(defined CONNECTOR_CLOUD_PHONE) |
| spastor | 0:1c358ea10753 | 678 | result = set_config_device_cloud_phone(connector_ptr, config_request.phone_number); |
| spastor | 0:1c358ea10753 | 679 | #endif |
| spastor | 0:1c358ea10753 | 680 | |
| spastor | 0:1c358ea10753 | 681 | /* Callback to user */ |
| spastor | 0:1c358ea10753 | 682 | { |
| spastor | 0:1c358ea10753 | 683 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 684 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 685 | config_request.transport = session->transport; |
| spastor | 0:1c358ea10753 | 686 | config_request.response_required = SmIsResponseNeeded(session->flags); |
| spastor | 0:1c358ea10753 | 687 | |
| spastor | 0:1c358ea10753 | 688 | request_id.sm_request = connector_request_id_sm_config_request; |
| spastor | 0:1c358ea10753 | 689 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &config_request); |
| spastor | 0:1c358ea10753 | 690 | result = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 691 | } |
| spastor | 0:1c358ea10753 | 692 | error: |
| spastor | 0:1c358ea10753 | 693 | return result; |
| spastor | 0:1c358ea10753 | 694 | } |
| spastor | 0:1c358ea10753 | 695 | #endif |
| spastor | 0:1c358ea10753 | 696 | |
| spastor | 0:1c358ea10753 | 697 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 698 | static connector_status_t sm_pass_target_info(connector_data_t * const connector_ptr, connector_sm_session_t * const session, uint8_t * const target_ptr, size_t target_bytes) |
| spastor | 0:1c358ea10753 | 699 | { |
| spastor | 0:1c358ea10753 | 700 | #define SM_TARGET_MAX_LENGTH 32 |
| spastor | 0:1c358ea10753 | 701 | connector_status_t result = connector_working; |
| spastor | 0:1c358ea10753 | 702 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 703 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 704 | connector_data_service_receive_target_t cb_data; |
| spastor | 0:1c358ea10753 | 705 | char target_name[SM_TARGET_MAX_LENGTH]; |
| spastor | 0:1c358ea10753 | 706 | |
| spastor | 0:1c358ea10753 | 707 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 708 | cb_data.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 709 | if (target_bytes > 0) |
| spastor | 0:1c358ea10753 | 710 | memcpy(target_name, target_ptr, target_bytes); |
| spastor | 0:1c358ea10753 | 711 | target_name[target_bytes] = '\0'; |
| spastor | 0:1c358ea10753 | 712 | cb_data.target = target_name; |
| spastor | 0:1c358ea10753 | 713 | cb_data.response_required = SmIsResponseNeeded(session->flags); |
| spastor | 0:1c358ea10753 | 714 | |
| spastor | 0:1c358ea10753 | 715 | request_id.data_service_request = connector_request_id_data_service_receive_target; |
| spastor | 0:1c358ea10753 | 716 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_service, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 717 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 718 | callback_status = connector_callback_error; |
| spastor | 0:1c358ea10753 | 719 | result = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 720 | session->user.context = cb_data.user_context; |
| spastor | 0:1c358ea10753 | 721 | |
| spastor | 0:1c358ea10753 | 722 | return result; |
| spastor | 0:1c358ea10753 | 723 | } |
| spastor | 0:1c358ea10753 | 724 | |
| spastor | 0:1c358ea10753 | 725 | static connector_status_t sm_process_data_request(connector_data_t * const connector_ptr, connector_sm_session_t * const session, void * const payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 726 | { |
| spastor | 0:1c358ea10753 | 727 | uint8_t * data_ptr = payload; |
| spastor | 0:1c358ea10753 | 728 | connector_status_t status = connector_working; |
| spastor | 0:1c358ea10753 | 729 | |
| spastor | 0:1c358ea10753 | 730 | if (session->error == connector_sm_error_complete) |
| spastor | 0:1c358ea10753 | 731 | goto done; |
| spastor | 0:1c358ea10753 | 732 | |
| spastor | 0:1c358ea10753 | 733 | if (session->bytes_processed == 0) |
| spastor | 0:1c358ea10753 | 734 | { |
| spastor | 0:1c358ea10753 | 735 | size_t target_length = 0; |
| spastor | 0:1c358ea10753 | 736 | |
| spastor | 0:1c358ea10753 | 737 | if (session->command == connector_sm_cmd_data) |
| spastor | 0:1c358ea10753 | 738 | target_length = 0x1F & *data_ptr; |
| spastor | 0:1c358ea10753 | 739 | |
| spastor | 0:1c358ea10753 | 740 | status = sm_pass_target_info(connector_ptr, session, data_ptr + 1, target_length); |
| spastor | 0:1c358ea10753 | 741 | if (status != connector_working) |
| spastor | 0:1c358ea10753 | 742 | goto error; |
| spastor | 0:1c358ea10753 | 743 | |
| spastor | 0:1c358ea10753 | 744 | /* Increase target_length: |
| spastor | 0:1c358ea10753 | 745 | * It's required for connector_sm_cmd_data to point correctly to actual data, |
| spastor | 0:1c358ea10753 | 746 | * and will be used for connector_sm_cmd_no_path_data to signal that sm_pass_target_info |
| spastor | 0:1c358ea10753 | 747 | * has already been called */ |
| spastor | 0:1c358ea10753 | 748 | target_length++; |
| spastor | 0:1c358ea10753 | 749 | |
| spastor | 0:1c358ea10753 | 750 | /* Set pre-processed bytes for segment 0 */ |
| spastor | 0:1c358ea10753 | 751 | session->bytes_processed = target_length; |
| spastor | 0:1c358ea10753 | 752 | |
| spastor | 0:1c358ea10753 | 753 | /* Return pending so bytes_processed and session->segments.processed are not incremented */ |
| spastor | 0:1c358ea10753 | 754 | status = connector_pending; |
| spastor | 0:1c358ea10753 | 755 | SmSetTargetInPayload(session->flags); |
| spastor | 0:1c358ea10753 | 756 | goto done; |
| spastor | 0:1c358ea10753 | 757 | } |
| spastor | 0:1c358ea10753 | 758 | |
| spastor | 0:1c358ea10753 | 759 | { |
| spastor | 0:1c358ea10753 | 760 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 761 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 762 | connector_data_service_receive_data_t cb_data; |
| spastor | 0:1c358ea10753 | 763 | size_t bytes_pre_processed = 0; |
| spastor | 0:1c358ea10753 | 764 | |
| spastor | 0:1c358ea10753 | 765 | /* Compute pre-processed bytes for segment 0 */ |
| spastor | 0:1c358ea10753 | 766 | if (SmIsTargetInPayload(session->flags) && (session->command == connector_sm_cmd_data)) |
| spastor | 0:1c358ea10753 | 767 | bytes_pre_processed = session->bytes_processed; |
| spastor | 0:1c358ea10753 | 768 | |
| spastor | 0:1c358ea10753 | 769 | data_ptr += bytes_pre_processed; |
| spastor | 0:1c358ea10753 | 770 | |
| spastor | 0:1c358ea10753 | 771 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 772 | cb_data.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 773 | cb_data.buffer = data_ptr; |
| spastor | 0:1c358ea10753 | 774 | cb_data.bytes_used = bytes - bytes_pre_processed; |
| spastor | 0:1c358ea10753 | 775 | cb_data.more_data = SmIsNotLastData(session->flags); |
| spastor | 0:1c358ea10753 | 776 | request_id.data_service_request = connector_request_id_data_service_receive_data; |
| spastor | 0:1c358ea10753 | 777 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_service, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 778 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 779 | callback_status = connector_callback_error; |
| spastor | 0:1c358ea10753 | 780 | if (callback_status != connector_callback_busy) |
| spastor | 0:1c358ea10753 | 781 | SmClearTargetInPayload(session->flags); |
| spastor | 0:1c358ea10753 | 782 | status = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 783 | session->user.context = cb_data.user_context; |
| spastor | 0:1c358ea10753 | 784 | } |
| spastor | 0:1c358ea10753 | 785 | |
| spastor | 0:1c358ea10753 | 786 | error: |
| spastor | 0:1c358ea10753 | 787 | switch (status) |
| spastor | 0:1c358ea10753 | 788 | { |
| spastor | 0:1c358ea10753 | 789 | case connector_device_error: |
| spastor | 0:1c358ea10753 | 790 | session->error = connector_sm_error_complete; |
| spastor | 0:1c358ea10753 | 791 | session->bytes_processed = bytes; |
| spastor | 0:1c358ea10753 | 792 | status = connector_working; |
| spastor | 0:1c358ea10753 | 793 | break; |
| spastor | 0:1c358ea10753 | 794 | |
| spastor | 0:1c358ea10753 | 795 | case connector_working: |
| spastor | 0:1c358ea10753 | 796 | /* Restore pre-processed bytes for segment 0 */ |
| spastor | 0:1c358ea10753 | 797 | if (session->segments.processed == 0) |
| spastor | 0:1c358ea10753 | 798 | session->bytes_processed = 0; |
| spastor | 0:1c358ea10753 | 799 | break; |
| spastor | 0:1c358ea10753 | 800 | |
| spastor | 0:1c358ea10753 | 801 | default: |
| spastor | 0:1c358ea10753 | 802 | break; |
| spastor | 0:1c358ea10753 | 803 | } |
| spastor | 0:1c358ea10753 | 804 | |
| spastor | 0:1c358ea10753 | 805 | done: |
| spastor | 0:1c358ea10753 | 806 | return status; |
| spastor | 0:1c358ea10753 | 807 | } |
| spastor | 0:1c358ea10753 | 808 | |
| spastor | 0:1c358ea10753 | 809 | static connector_status_t sm_process_data_response(connector_data_t * const connector_ptr, connector_sm_session_t * const session, void * const payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 810 | { |
| spastor | 0:1c358ea10753 | 811 | connector_status_t status = connector_working; |
| spastor | 0:1c358ea10753 | 812 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 813 | connector_data_service_send_response_t cb_data; |
| spastor | 0:1c358ea10753 | 814 | char * const text = payload; |
| spastor | 0:1c358ea10753 | 815 | |
| spastor | 0:1c358ea10753 | 816 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 817 | cb_data.user_context = session->user.context; |
| spastor | 0:1c358ea10753 | 818 | if (SmIsError(session->flags)) |
| spastor | 0:1c358ea10753 | 819 | { |
| spastor | 0:1c358ea10753 | 820 | switch (session->error) |
| spastor | 0:1c358ea10753 | 821 | { |
| spastor | 0:1c358ea10753 | 822 | case connector_sm_error_in_request: |
| spastor | 0:1c358ea10753 | 823 | cb_data.response = connector_data_service_send_response_bad_request; |
| spastor | 0:1c358ea10753 | 824 | break; |
| spastor | 0:1c358ea10753 | 825 | |
| spastor | 0:1c358ea10753 | 826 | case connector_sm_error_unavailable: |
| spastor | 0:1c358ea10753 | 827 | cb_data.response = connector_data_service_send_response_unavailable; |
| spastor | 0:1c358ea10753 | 828 | break; |
| spastor | 0:1c358ea10753 | 829 | |
| spastor | 0:1c358ea10753 | 830 | default: |
| spastor | 0:1c358ea10753 | 831 | cb_data.response = connector_data_service_send_response_cloud_error; |
| spastor | 0:1c358ea10753 | 832 | break; |
| spastor | 0:1c358ea10753 | 833 | } |
| spastor | 0:1c358ea10753 | 834 | } |
| spastor | 0:1c358ea10753 | 835 | else |
| spastor | 0:1c358ea10753 | 836 | cb_data.response = connector_data_service_send_response_success; |
| spastor | 0:1c358ea10753 | 837 | |
| spastor | 0:1c358ea10753 | 838 | cb_data.hint = (bytes > 0) ? text : NULL; |
| spastor | 0:1c358ea10753 | 839 | |
| spastor | 0:1c358ea10753 | 840 | #if (defined CONNECTOR_DATA_POINTS) |
| spastor | 0:1c358ea10753 | 841 | if (SmIsDatapoint(session->flags)) |
| spastor | 0:1c358ea10753 | 842 | { |
| spastor | 0:1c358ea10753 | 843 | callback_status = dp_handle_callback(connector_ptr, connector_request_id_data_service_send_response, &cb_data); |
| spastor | 0:1c358ea10753 | 844 | } |
| spastor | 0:1c358ea10753 | 845 | else |
| spastor | 0:1c358ea10753 | 846 | #endif |
| spastor | 0:1c358ea10753 | 847 | { |
| spastor | 0:1c358ea10753 | 848 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 849 | |
| spastor | 0:1c358ea10753 | 850 | request_id.data_service_request = connector_request_id_data_service_send_response; |
| spastor | 0:1c358ea10753 | 851 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_data_service, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 852 | } |
| spastor | 0:1c358ea10753 | 853 | |
| spastor | 0:1c358ea10753 | 854 | status = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 855 | if (SmIsError(session->flags) && (status != connector_pending)) |
| spastor | 0:1c358ea10753 | 856 | { |
| spastor | 0:1c358ea10753 | 857 | session->error = connector_sm_error_none; |
| spastor | 0:1c358ea10753 | 858 | SmClearError(session->flags); |
| spastor | 0:1c358ea10753 | 859 | } |
| spastor | 0:1c358ea10753 | 860 | |
| spastor | 0:1c358ea10753 | 861 | return status; |
| spastor | 0:1c358ea10753 | 862 | } |
| spastor | 0:1c358ea10753 | 863 | #endif |
| spastor | 0:1c358ea10753 | 864 | |
| spastor | 0:1c358ea10753 | 865 | static connector_status_t sm_process_reboot(connector_data_t * const connector_ptr) |
| spastor | 0:1c358ea10753 | 866 | { |
| spastor | 0:1c358ea10753 | 867 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 868 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 869 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 870 | |
| spastor | 0:1c358ea10753 | 871 | request_id.os_request = connector_request_id_os_reboot; |
| spastor | 0:1c358ea10753 | 872 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_operating_system, request_id, NULL); |
| spastor | 0:1c358ea10753 | 873 | /* JIRA IC4C-119 */ |
| spastor | 0:1c358ea10753 | 874 | /* ASSERT(callback_status != connector_callback_unrecognized); */ |
| spastor | 0:1c358ea10753 | 875 | |
| spastor | 0:1c358ea10753 | 876 | result = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 877 | |
| spastor | 0:1c358ea10753 | 878 | return result; |
| spastor | 0:1c358ea10753 | 879 | } |
| spastor | 0:1c358ea10753 | 880 | |
| spastor | 0:1c358ea10753 | 881 | static connector_status_t sm_process_ping_response(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 882 | { |
| spastor | 0:1c358ea10753 | 883 | connector_status_t status; |
| spastor | 0:1c358ea10753 | 884 | connector_callback_status_t const callback_status = sm_inform_ping_complete(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 885 | |
| spastor | 0:1c358ea10753 | 886 | status = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 887 | if (SmIsError(session->flags) && (status != connector_pending)) |
| spastor | 0:1c358ea10753 | 888 | { |
| spastor | 0:1c358ea10753 | 889 | session->error = connector_sm_error_none; |
| spastor | 0:1c358ea10753 | 890 | SmClearError(session->flags); |
| spastor | 0:1c358ea10753 | 891 | } |
| spastor | 0:1c358ea10753 | 892 | return status; |
| spastor | 0:1c358ea10753 | 893 | } |
| spastor | 0:1c358ea10753 | 894 | |
| spastor | 0:1c358ea10753 | 895 | static connector_status_t sm_process_ping_request(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 896 | { |
| spastor | 0:1c358ea10753 | 897 | connector_status_t status; |
| spastor | 0:1c358ea10753 | 898 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 899 | connector_sm_receive_ping_request_t cb_data; |
| spastor | 0:1c358ea10753 | 900 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 901 | |
| spastor | 0:1c358ea10753 | 902 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 903 | cb_data.response_required = SmIsResponseNeeded(session->flags); |
| spastor | 0:1c358ea10753 | 904 | |
| spastor | 0:1c358ea10753 | 905 | request_id.sm_request = connector_request_id_sm_ping_request; |
| spastor | 0:1c358ea10753 | 906 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 907 | if (callback_status == connector_callback_unrecognized) |
| spastor | 0:1c358ea10753 | 908 | callback_status = connector_callback_continue; |
| spastor | 0:1c358ea10753 | 909 | status = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 910 | |
| spastor | 0:1c358ea10753 | 911 | return status; |
| spastor | 0:1c358ea10753 | 912 | } |
| spastor | 0:1c358ea10753 | 913 | |
| spastor | 0:1c358ea10753 | 914 | static connector_status_t sm_process_opaque_response(connector_data_t * const connector_ptr, connector_sm_session_t * const session, void * payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 915 | { |
| spastor | 0:1c358ea10753 | 916 | connector_status_t status; |
| spastor | 0:1c358ea10753 | 917 | connector_request_id_t request_id; |
| spastor | 0:1c358ea10753 | 918 | connector_sm_opaque_response_t cb_data; |
| spastor | 0:1c358ea10753 | 919 | connector_callback_status_t callback_status; |
| spastor | 0:1c358ea10753 | 920 | |
| spastor | 0:1c358ea10753 | 921 | cb_data.transport = session->transport; |
| spastor | 0:1c358ea10753 | 922 | cb_data.id = session->request_id; |
| spastor | 0:1c358ea10753 | 923 | cb_data.data = payload; |
| spastor | 0:1c358ea10753 | 924 | cb_data.bytes_used = bytes; |
| spastor | 0:1c358ea10753 | 925 | cb_data.error = SmIsError(session->flags); |
| spastor | 0:1c358ea10753 | 926 | |
| spastor | 0:1c358ea10753 | 927 | request_id.sm_request = connector_request_id_sm_opaque_response; |
| spastor | 0:1c358ea10753 | 928 | callback_status = connector_callback(connector_ptr->callback, connector_class_id_short_message, request_id, &cb_data); |
| spastor | 0:1c358ea10753 | 929 | status = sm_map_callback_status_to_connector_status(callback_status); |
| spastor | 0:1c358ea10753 | 930 | |
| spastor | 0:1c358ea10753 | 931 | return status; |
| spastor | 0:1c358ea10753 | 932 | } |
| spastor | 0:1c358ea10753 | 933 | |
| spastor | 0:1c358ea10753 | 934 | static connector_status_t sm_prepare_payload(connector_data_t * const connector_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 935 | { |
| spastor | 0:1c358ea10753 | 936 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 937 | connector_status_t (* prepare_fn) (connector_data_t * const connector_ptr, connector_sm_session_t * const session) = NULL; |
| spastor | 0:1c358ea10753 | 938 | |
| spastor | 0:1c358ea10753 | 939 | ASSERT_GOTO(session != NULL, error); |
| spastor | 0:1c358ea10753 | 940 | switch (session->command) |
| spastor | 0:1c358ea10753 | 941 | { |
| spastor | 0:1c358ea10753 | 942 | case connector_sm_cmd_data: |
| spastor | 0:1c358ea10753 | 943 | case connector_sm_cmd_no_path_data: |
| spastor | 0:1c358ea10753 | 944 | prepare_fn = SmIsClientOwned(session->flags) ? sm_prepare_data_request : sm_prepare_data_response; |
| spastor | 0:1c358ea10753 | 945 | break; |
| spastor | 0:1c358ea10753 | 946 | |
| spastor | 0:1c358ea10753 | 947 | #if (defined CONNECTOR_SM_CLI) |
| spastor | 0:1c358ea10753 | 948 | case connector_sm_cmd_cli: |
| spastor | 0:1c358ea10753 | 949 | ASSERT_GOTO(SmIsCloudOwned(session->flags), error); |
| spastor | 0:1c358ea10753 | 950 | prepare_fn = sm_prepare_cli_response; |
| spastor | 0:1c358ea10753 | 951 | break; |
| spastor | 0:1c358ea10753 | 952 | #endif |
| spastor | 0:1c358ea10753 | 953 | |
| spastor | 0:1c358ea10753 | 954 | default: |
| spastor | 0:1c358ea10753 | 955 | result = connector_unavailable; |
| spastor | 0:1c358ea10753 | 956 | goto unexpected; |
| spastor | 0:1c358ea10753 | 957 | } |
| spastor | 0:1c358ea10753 | 958 | |
| spastor | 0:1c358ea10753 | 959 | result = prepare_fn(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 960 | |
| spastor | 0:1c358ea10753 | 961 | unexpected: |
| spastor | 0:1c358ea10753 | 962 | if ((result == connector_working) && (session->error != connector_sm_error_none) && (session->error != connector_sm_error_complete)) |
| spastor | 0:1c358ea10753 | 963 | { |
| spastor | 0:1c358ea10753 | 964 | session->sm_state = connector_sm_state_error; |
| spastor | 0:1c358ea10753 | 965 | SmSetError(session->flags); |
| spastor | 0:1c358ea10753 | 966 | } |
| spastor | 0:1c358ea10753 | 967 | |
| spastor | 0:1c358ea10753 | 968 | error: |
| spastor | 0:1c358ea10753 | 969 | return result; |
| spastor | 0:1c358ea10753 | 970 | } |
| spastor | 0:1c358ea10753 | 971 | |
| spastor | 0:1c358ea10753 | 972 | static connector_status_t sm_pass_user_data(connector_data_t * const connector_ptr, connector_sm_session_t * const session, uint8_t * payload, size_t const bytes) |
| spastor | 0:1c358ea10753 | 973 | { |
| spastor | 0:1c358ea10753 | 974 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 975 | connector_sm_state_t next_state = connector_sm_state_send_data; |
| spastor | 0:1c358ea10753 | 976 | |
| spastor | 0:1c358ea10753 | 977 | switch (session->command) |
| spastor | 0:1c358ea10753 | 978 | { |
| spastor | 0:1c358ea10753 | 979 | case connector_sm_cmd_data: |
| spastor | 0:1c358ea10753 | 980 | case connector_sm_cmd_no_path_data: |
| spastor | 0:1c358ea10753 | 981 | if (SmIsCloudOwned(session->flags)) |
| spastor | 0:1c358ea10753 | 982 | { |
| spastor | 0:1c358ea10753 | 983 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 984 | result = sm_process_data_request(connector_ptr, session, payload, bytes); |
| spastor | 0:1c358ea10753 | 985 | #endif |
| spastor | 0:1c358ea10753 | 986 | next_state = connector_sm_state_get_total_length; |
| spastor | 0:1c358ea10753 | 987 | } |
| spastor | 0:1c358ea10753 | 988 | else |
| spastor | 0:1c358ea10753 | 989 | { |
| spastor | 0:1c358ea10753 | 990 | #if (defined CONNECTOR_DATA_SERVICE) |
| spastor | 0:1c358ea10753 | 991 | result = sm_process_data_response(connector_ptr, session, payload, bytes); |
| spastor | 0:1c358ea10753 | 992 | #endif |
| spastor | 0:1c358ea10753 | 993 | next_state = connector_sm_state_complete; |
| spastor | 0:1c358ea10753 | 994 | } |
| spastor | 0:1c358ea10753 | 995 | break; |
| spastor | 0:1c358ea10753 | 996 | |
| spastor | 0:1c358ea10753 | 997 | #if (defined CONNECTOR_SM_CLI) |
| spastor | 0:1c358ea10753 | 998 | case connector_sm_cmd_cli: |
| spastor | 0:1c358ea10753 | 999 | result = sm_process_cli_request(connector_ptr, session, payload, bytes); |
| spastor | 0:1c358ea10753 | 1000 | next_state = connector_sm_state_get_total_length; |
| spastor | 0:1c358ea10753 | 1001 | break; |
| spastor | 0:1c358ea10753 | 1002 | #endif |
| spastor | 0:1c358ea10753 | 1003 | |
| spastor | 0:1c358ea10753 | 1004 | #if (defined CONNECTOR_TRANSPORT_SMS) |
| spastor | 0:1c358ea10753 | 1005 | case connector_sm_cmd_config: |
| spastor | 0:1c358ea10753 | 1006 | if (SmIsCloudOwned(session->flags)) |
| spastor | 0:1c358ea10753 | 1007 | { |
| spastor | 0:1c358ea10753 | 1008 | result = sm_process_config_request(connector_ptr, session, payload, bytes); |
| spastor | 0:1c358ea10753 | 1009 | } |
| spastor | 0:1c358ea10753 | 1010 | break; |
| spastor | 0:1c358ea10753 | 1011 | #endif |
| spastor | 0:1c358ea10753 | 1012 | |
| spastor | 0:1c358ea10753 | 1013 | case connector_sm_cmd_connect: |
| spastor | 0:1c358ea10753 | 1014 | #if (defined CONNECTOR_TRANSPORT_TCP) |
| spastor | 0:1c358ea10753 | 1015 | if (edp_get_active_state(connector_ptr) == connector_transport_idle) |
| spastor | 0:1c358ea10753 | 1016 | edp_set_active_state(connector_ptr, connector_transport_open); |
| spastor | 0:1c358ea10753 | 1017 | result = connector_working; |
| spastor | 0:1c358ea10753 | 1018 | #else |
| spastor | 0:1c358ea10753 | 1019 | connector_debug_printf("WARNING: received a 'request connect' but TCP transport is not available\n"); |
| spastor | 0:1c358ea10753 | 1020 | result = connector_device_error; |
| spastor | 0:1c358ea10753 | 1021 | #endif |
| spastor | 0:1c358ea10753 | 1022 | break; |
| spastor | 0:1c358ea10753 | 1023 | |
| spastor | 0:1c358ea10753 | 1024 | case connector_sm_cmd_ping: |
| spastor | 0:1c358ea10753 | 1025 | if (SmIsCloudOwned(session->flags)) |
| spastor | 0:1c358ea10753 | 1026 | { |
| spastor | 0:1c358ea10753 | 1027 | result = sm_process_ping_request(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 1028 | } |
| spastor | 0:1c358ea10753 | 1029 | else |
| spastor | 0:1c358ea10753 | 1030 | { |
| spastor | 0:1c358ea10753 | 1031 | result = sm_process_ping_response(connector_ptr, session); |
| spastor | 0:1c358ea10753 | 1032 | next_state = connector_sm_state_complete; |
| spastor | 0:1c358ea10753 | 1033 | } |
| spastor | 0:1c358ea10753 | 1034 | break; |
| spastor | 0:1c358ea10753 | 1035 | |
| spastor | 0:1c358ea10753 | 1036 | case connector_sm_cmd_reboot: |
| spastor | 0:1c358ea10753 | 1037 | SmSetReboot(session->flags); |
| spastor | 0:1c358ea10753 | 1038 | result = connector_working; |
| spastor | 0:1c358ea10753 | 1039 | break; |
| spastor | 0:1c358ea10753 | 1040 | |
| spastor | 0:1c358ea10753 | 1041 | case connector_sm_cmd_opaque_response: |
| spastor | 0:1c358ea10753 | 1042 | result = sm_process_opaque_response(connector_ptr, session, payload, bytes); |
| spastor | 0:1c358ea10753 | 1043 | break; |
| spastor | 0:1c358ea10753 | 1044 | |
| spastor | 0:1c358ea10753 | 1045 | default: |
| spastor | 0:1c358ea10753 | 1046 | result = connector_unavailable; |
| spastor | 0:1c358ea10753 | 1047 | break; |
| spastor | 0:1c358ea10753 | 1048 | } |
| spastor | 0:1c358ea10753 | 1049 | |
| spastor | 0:1c358ea10753 | 1050 | switch (result) |
| spastor | 0:1c358ea10753 | 1051 | { |
| spastor | 0:1c358ea10753 | 1052 | case connector_working: |
| spastor | 0:1c358ea10753 | 1053 | session->bytes_processed += bytes; |
| spastor | 0:1c358ea10753 | 1054 | switch (session->error) |
| spastor | 0:1c358ea10753 | 1055 | { |
| spastor | 0:1c358ea10753 | 1056 | case connector_sm_error_none: |
| spastor | 0:1c358ea10753 | 1057 | case connector_sm_error_complete: |
| spastor | 0:1c358ea10753 | 1058 | if (SmIsLastData(session->flags)) |
| spastor | 0:1c358ea10753 | 1059 | sm_switch_path(connector_ptr, session, next_state); |
| spastor | 0:1c358ea10753 | 1060 | break; |
| spastor | 0:1c358ea10753 | 1061 | |
| spastor | 0:1c358ea10753 | 1062 | default: |
| spastor | 0:1c358ea10753 | 1063 | session->sm_state = connector_sm_state_error; |
| spastor | 0:1c358ea10753 | 1064 | SmSetError(session->flags); |
| spastor | 0:1c358ea10753 | 1065 | break; |
| spastor | 0:1c358ea10753 | 1066 | } |
| spastor | 0:1c358ea10753 | 1067 | break; |
| spastor | 0:1c358ea10753 | 1068 | |
| spastor | 0:1c358ea10753 | 1069 | case connector_pending: |
| spastor | 0:1c358ea10753 | 1070 | break; |
| spastor | 0:1c358ea10753 | 1071 | |
| spastor | 0:1c358ea10753 | 1072 | case connector_device_error: |
| spastor | 0:1c358ea10753 | 1073 | session->error = connector_sm_error_cancel; |
| spastor | 0:1c358ea10753 | 1074 | session->sm_state = connector_sm_state_error; |
| spastor | 0:1c358ea10753 | 1075 | SmSetError(session->flags); |
| spastor | 0:1c358ea10753 | 1076 | result = connector_working; |
| spastor | 0:1c358ea10753 | 1077 | break; |
| spastor | 0:1c358ea10753 | 1078 | |
| spastor | 0:1c358ea10753 | 1079 | default: |
| spastor | 0:1c358ea10753 | 1080 | session->sm_state = connector_sm_state_error; |
| spastor | 0:1c358ea10753 | 1081 | SmSetError(session->flags); |
| spastor | 0:1c358ea10753 | 1082 | break; |
| spastor | 0:1c358ea10753 | 1083 | } |
| spastor | 0:1c358ea10753 | 1084 | |
| spastor | 0:1c358ea10753 | 1085 | return result; |
| spastor | 0:1c358ea10753 | 1086 | } |
| spastor | 0:1c358ea10753 | 1087 | |
| spastor | 0:1c358ea10753 | 1088 | static connector_status_t sm_process_payload(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr, connector_sm_session_t * const session) |
| spastor | 0:1c358ea10753 | 1089 | { |
| spastor | 0:1c358ea10753 | 1090 | connector_status_t result = connector_abort; |
| spastor | 0:1c358ea10753 | 1091 | uint8_t * data_ptr; |
| spastor | 0:1c358ea10753 | 1092 | size_t bytes; |
| spastor | 0:1c358ea10753 | 1093 | |
| spastor | 0:1c358ea10753 | 1094 | #if (defined CONNECTOR_SM_MULTIPART) |
| spastor | 0:1c358ea10753 | 1095 | if (SmIsMultiPart(session->flags)) |
| spastor | 0:1c358ea10753 | 1096 | { |
| spastor | 0:1c358ea10753 | 1097 | size_t const max_payload_bytes = sm_get_max_payload_bytes(sm_ptr); |
| spastor | 0:1c358ea10753 | 1098 | size_t const data_index = session->segments.processed * max_payload_bytes; |
| spastor | 0:1c358ea10753 | 1099 | |
| spastor | 0:1c358ea10753 | 1100 | ASSERT_GOTO(session->in.data != NULL, error); |
| spastor | 0:1c358ea10753 | 1101 | ASSERT_GOTO(session->segments.processed < session->segments.count, error); |
| spastor | 0:1c358ea10753 | 1102 | if (session->segments.processed == (session->segments.count - 1)) |
| spastor | 0:1c358ea10753 | 1103 | SmSetLastData(session->flags); |
| spastor | 0:1c358ea10753 | 1104 | |
| spastor | 0:1c358ea10753 | 1105 | data_ptr = &session->in.data[data_index]; |
| spastor | 0:1c358ea10753 | 1106 | bytes = session->segments.size_array[session->segments.processed]; |
| spastor | 0:1c358ea10753 | 1107 | } |
| spastor | 0:1c358ea10753 | 1108 | else |
| spastor | 0:1c358ea10753 | 1109 | #endif |
| spastor | 0:1c358ea10753 | 1110 | { |
| spastor | 0:1c358ea10753 | 1111 | UNUSED_PARAMETER(sm_ptr); |
| spastor | 0:1c358ea10753 | 1112 | ASSERT_GOTO(SmIsNotMultiPart(session->flags), error); |
| spastor | 0:1c358ea10753 | 1113 | SmSetLastData(session->flags); |
| spastor | 0:1c358ea10753 | 1114 | data_ptr = session->in.data; |
| spastor | 0:1c358ea10753 | 1115 | bytes = session->in.bytes; |
| spastor | 0:1c358ea10753 | 1116 | } |
| spastor | 0:1c358ea10753 | 1117 | |
| spastor | 0:1c358ea10753 | 1118 | result = sm_pass_user_data(connector_ptr, session, data_ptr, bytes); |
| spastor | 0:1c358ea10753 | 1119 | if ((result == connector_working) && (SmIsNotLastData(session->flags))) |
| spastor | 0:1c358ea10753 | 1120 | session->segments.processed++; |
| spastor | 0:1c358ea10753 | 1121 | |
| spastor | 0:1c358ea10753 | 1122 | error: |
| spastor | 0:1c358ea10753 | 1123 | return result; |
| spastor | 0:1c358ea10753 | 1124 | } |
| spastor | 0:1c358ea10753 | 1125 |