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.
connector_sm_session.h
00001 /* 00002 * Copyright (c) 2013 Digi International Inc., 00003 * All rights not expressly granted are reserved. 00004 * 00005 * This Source Code Form is subject to the terms of the Mozilla Public 00006 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 00007 * You can obtain one at http://mozilla.org/MPL/2.0/. 00008 * 00009 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343 00010 * ======================================================================= 00011 */ 00012 /* This function searches for the next valid request_id and leaves it in connector_ptr->last_request_id */ 00013 static connector_status_t sm_get_request_id(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr) 00014 { 00015 connector_status_t result = connector_pending; 00016 unsigned long const request_id = connector_ptr->last_request_id; 00017 00018 do 00019 { 00020 connector_sm_session_t * session = sm_ptr->session.head; 00021 00022 connector_ptr->last_request_id++; 00023 connector_ptr->last_request_id &= SM_REQUEST_ID_MASK; 00024 00025 while (session != NULL) 00026 { 00027 /* already used? */ 00028 if (session->request_id == connector_ptr->last_request_id) 00029 break; 00030 00031 session = session->next; 00032 } 00033 00034 if (session == NULL) 00035 break; 00036 00037 } while (request_id != connector_ptr->last_request_id); 00038 00039 ASSERT_GOTO(request_id != connector_ptr->last_request_id, error); 00040 result = connector_working; 00041 00042 error: 00043 return result; 00044 } 00045 00046 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) 00047 { 00048 connector_sm_session_t * session = sm_ptr->session.head; 00049 00050 while (session != NULL) 00051 { 00052 if ((session->request_id == transcation_id) && (SmIsClientOwned(session->flags) == client_originated)) 00053 break; 00054 00055 session = session->next; 00056 } 00057 00058 return session; 00059 } 00060 00061 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) 00062 { 00063 connector_sm_session_t * session = NULL; 00064 void * ptr = NULL; 00065 connector_status_t result; 00066 size_t const active_sessions = client_originated ? sm_ptr->session.active_client_sessions : sm_ptr->session.active_cloud_sessions; 00067 static connector_bool_t print_once = connector_true; 00068 00069 if (active_sessions >= sm_ptr->session.max_sessions) 00070 { 00071 if (print_once) 00072 { 00073 connector_debug_printf("Active %s sessions reached the limit %" PRIsize "\n", client_originated ? "client" : "cloud", active_sessions); 00074 print_once = connector_false; 00075 } 00076 00077 goto done; 00078 } 00079 00080 print_once = connector_true; 00081 result = malloc_data_buffer(connector_ptr, sizeof *session, named_buffer_id(sm_session), &ptr); 00082 if (result != connector_working) 00083 goto error; 00084 00085 session = ptr; 00086 result = get_system_time(connector_ptr, &session->start_time); 00087 ASSERT_GOTO(result == connector_working, error); 00088 00089 session->flags = 0; 00090 session->error = connector_sm_error_none; 00091 session->in.data = NULL; 00092 session->in.bytes = 0; 00093 session->bytes_processed = 0; 00094 session->user.header = NULL; 00095 session->user.context = NULL; 00096 session->segments.processed = 0; 00097 session->segments.count = 0; 00098 00099 session->transport = sm_ptr->network.transport; 00100 #if (defined CONNECTOR_TRANSPORT_SMS) 00101 if (session->transport == connector_transport_sms) 00102 SmSetEncoded(session->flags); 00103 #endif 00104 00105 if (client_originated) 00106 { 00107 result = sm_copy_user_request(sm_ptr, session); 00108 ASSERT_GOTO(result == connector_working, error); 00109 SmSetClientOwned(session->flags); 00110 00111 session->request_id = sm_ptr->pending.request_id; 00112 sm_ptr->session.active_client_sessions++; 00113 } 00114 else 00115 { 00116 session->sm_state = connector_sm_state_receive_data; 00117 sm_ptr->session.active_cloud_sessions++; 00118 } 00119 00120 add_list_node(&sm_ptr->session.head, &sm_ptr->session.tail, session); 00121 goto done; 00122 00123 error: 00124 if (session != NULL) 00125 { 00126 result = free_data_buffer(connector_ptr, named_buffer_id(sm_session), session); 00127 ASSERT(result == connector_working); 00128 session = NULL; 00129 } 00130 00131 done: 00132 return session; 00133 } 00134 00135 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) 00136 { 00137 connector_status_t result = connector_working; 00138 00139 ASSERT_GOTO(sm_ptr != NULL, error); 00140 ASSERT_GOTO(session != NULL, error); 00141 00142 if (SmIsClientOwned(session->flags)) 00143 { 00144 ASSERT(sm_ptr->session.active_client_sessions > 0); 00145 sm_ptr->session.active_client_sessions--; 00146 } 00147 else 00148 { 00149 ASSERT(sm_ptr->session.active_cloud_sessions > 0); 00150 sm_ptr->session.active_cloud_sessions--; 00151 } 00152 00153 if (session->in.data != NULL) 00154 { 00155 result = free_data_buffer(connector_ptr, named_buffer_id(sm_data_block), session->in.data); 00156 session->in.data = NULL; 00157 } 00158 00159 remove_list_node(&sm_ptr->session.head, &sm_ptr->session.tail, session); 00160 if (sm_ptr->session.current == session) 00161 sm_ptr->session.current = (session->next != NULL) ? session->next : sm_ptr->session.head; 00162 00163 { 00164 connector_status_t const status = free_data_buffer(connector_ptr, named_buffer_id(sm_session), session); 00165 00166 if (status != connector_working) 00167 result = connector_abort; 00168 } 00169 00170 if (sm_ptr->close.stop_condition == connector_wait_sessions_complete) 00171 { 00172 if (sm_ptr->session.head == NULL) 00173 sm_ptr->transport.state = connector_transport_close; 00174 } 00175 00176 error: 00177 return result; 00178 } 00179 00180 /* If request_id == NULL cancel ALL sessions. Else cancel the SM session whose Request ID matches the one passed as a parameter. */ 00181 #if (CONNECTOR_VERSION >= 0x02010000) 00182 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) 00183 { 00184 connector_status_t result = connector_working; 00185 connector_sm_session_t * session = sm_ptr->session.head; 00186 connector_bool_t cancel_all = connector_bool(request_id == NULL); 00187 00188 while (session != NULL) 00189 { 00190 connector_sm_session_t * next_session = NULL; 00191 uint32_t session_request_id = request_id != NULL ? *request_id : SM_INVALID_REQUEST_ID; 00192 00193 if (cancel_all || (session_request_id == *request_id)) 00194 { 00195 session->error = connector_sm_error_cancel; 00196 result = sm_inform_session_complete(connector_ptr, session); 00197 if (result != connector_working) 00198 break; 00199 next_session = session->next; 00200 result = sm_delete_session(connector_ptr, sm_ptr, session); 00201 if (result != connector_working) 00202 break; 00203 00204 if (!cancel_all) 00205 break; 00206 } 00207 00208 session = next_session != NULL ? next_session : session->next; 00209 } 00210 #if (defined CONNECTOR_DATA_POINTS) 00211 dp_cancel_session(connector_ptr, session, request_id); 00212 #endif 00213 return result; 00214 } 00215 #else 00216 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) 00217 { 00218 connector_status_t result = connector_working; 00219 connector_sm_session_t * session = sm_ptr->session.head; 00220 connector_bool_t cancel_all = connector_bool(user_context == NULL); 00221 00222 while (session != NULL) 00223 { 00224 connector_status_t status; 00225 connector_sm_session_t * next_session = NULL; 00226 00227 if (cancel_all || (session->user.context == user_context)) 00228 { 00229 if (session->user.context != NULL) 00230 { 00231 session->error = connector_sm_error_cancel; 00232 status = sm_inform_session_complete(connector_ptr, session); 00233 if (status != connector_working) 00234 result = connector_abort; 00235 } 00236 00237 next_session = session->next; 00238 status = sm_delete_session(connector_ptr, sm_ptr, session); 00239 if (status != connector_working) 00240 { 00241 result = connector_abort; 00242 break; 00243 } 00244 if (!cancel_all) 00245 break; 00246 } 00247 00248 session = next_session; 00249 } 00250 00251 return result; 00252 } 00253 #endif 00254 static connector_status_t sm_process_pending_data(connector_data_t * const connector_ptr, connector_sm_data_t * const sm_ptr) 00255 { 00256 connector_status_t result = connector_idle; 00257 00258 if (sm_ptr->pending.data == NULL) 00259 goto done; 00260 00261 switch (sm_ptr->pending.request) 00262 { 00263 case connector_initiate_transport_start: 00264 switch(sm_ptr->transport.state) 00265 { 00266 case connector_transport_idle: 00267 sm_ptr->transport.state = connector_transport_open; 00268 break; 00269 00270 case connector_transport_close: 00271 /* wait for close to complete */ 00272 goto done; 00273 00274 case connector_transport_terminate: 00275 result = connector_device_terminated; 00276 break; 00277 00278 default: 00279 break; 00280 } 00281 break; 00282 00283 case connector_initiate_transport_stop: 00284 if ((sm_ptr->close.stop_condition == connector_wait_sessions_complete) && (sm_ptr->session.head != NULL)) 00285 goto done; 00286 else 00287 { 00288 result = sm_cancel_session(connector_ptr, sm_ptr, NULL); 00289 sm_ptr->transport.state = connector_transport_close; 00290 } 00291 break; 00292 00293 case connector_initiate_session_cancel: 00294 { 00295 connector_sm_cancel_request_t const * const request = sm_ptr->pending.data; 00296 #if (CONNECTOR_VERSION >= 0x02010000) 00297 result = sm_cancel_session(connector_ptr, sm_ptr, &request->request_id); 00298 #else 00299 result = sm_cancel_session(connector_ptr, sm_ptr, request->user_context); 00300 #endif 00301 break; 00302 } 00303 #if (CONNECTOR_VERSION >= 0x02010000) 00304 case connector_initiate_session_cancel_all: 00305 { 00306 result = sm_cancel_session(connector_ptr, sm_ptr, NULL); 00307 break; 00308 } 00309 #endif 00310 default: 00311 { 00312 connector_bool_t const client_originated = connector_true; 00313 connector_sm_session_t * const session = sm_create_session(connector_ptr, sm_ptr, client_originated); 00314 00315 if (session == NULL) 00316 { 00317 result = connector_pending; 00318 goto done; 00319 } 00320 00321 result = connector_working; 00322 break; 00323 } 00324 } 00325 00326 sm_ptr->pending.data = NULL; 00327 00328 done: 00329 return result; 00330 } 00331 00332 00333
Generated on Tue Jul 12 2022 19:18:38 by
 1.7.2
 1.7.2