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_edp.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 00013 #include <stddef.h> 00014 00015 #include "connector_edp_util.h" 00016 00017 #include "connector_tcp_config.h" 00018 #include "connector_tcp_send.h" 00019 #include "connector_tcp_recv.h" 00020 #include "connector_tcp_open.h" 00021 #include "connector_tcp_close.h" 00022 00023 #include "connector_cc.h" 00024 00025 #if (defined CONNECTOR_DATA_SERVICE) || (defined CONNECTOR_FILE_SYSTEM) || (defined CONNECTOR_RCI_SERVICE) 00026 #include "connector_msg.h" 00027 #endif 00028 #if (defined CONNECTOR_DATA_SERVICE) 00029 #include "connector_data_service.h" 00030 #endif 00031 #if (defined CONNECTOR_FILE_SYSTEM) 00032 #include "connector_file_system.h" 00033 #endif 00034 00035 #if (defined CONNECTOR_FIRMWARE_SERVICE) 00036 #include "connector_firmware.h" 00037 #endif 00038 00039 #include "layer.h" 00040 00041 00042 static connector_status_t edp_config_init(connector_data_t * const connector_ptr) 00043 { 00044 connector_status_t result = connector_working; 00045 00046 if (connector_ptr->device_id_method == connector_device_id_method_manual) 00047 { 00048 /* then we have to obtain connection type from the callback */ 00049 result = get_config_connection_type(connector_ptr); 00050 COND_ELSE_GOTO(result == connector_working, done); 00051 } 00052 00053 switch (connector_ptr->connection_type) 00054 { 00055 case connector_connection_type_lan: 00056 break; 00057 case connector_connection_type_wan: 00058 #if (!defined CONNECTOR_WAN_LINK_SPEED_IN_BITS_PER_SECOND) 00059 result = get_config_link_speed(connector_ptr); 00060 COND_ELSE_GOTO(result == connector_working, done); 00061 #endif 00062 00063 #if (!defined CONNECTOR_WAN_PHONE_NUMBER_DIALED) 00064 result = get_config_phone_number(connector_ptr); 00065 COND_ELSE_GOTO(result == connector_working, done); 00066 #endif 00067 00068 break; 00069 } 00070 00071 #if !(defined CONNECTOR_VENDOR_ID) 00072 result = get_config_vendor_id(connector_ptr); 00073 COND_ELSE_GOTO(result == connector_working, done); 00074 #endif 00075 00076 #if !(defined CONNECTOR_DEVICE_TYPE) 00077 result = get_config_device_type(connector_ptr); 00078 COND_ELSE_GOTO(result == connector_working, done); 00079 #endif 00080 00081 #if !(defined CONNECTOR_TX_KEEPALIVE_IN_SECONDS) 00082 result = get_config_keepalive(connector_ptr, connector_request_id_config_tx_keepalive); 00083 COND_ELSE_GOTO(result == connector_working, done); 00084 #endif 00085 00086 #if !(defined CONNECTOR_RX_KEEPALIVE_IN_SECONDS) 00087 result = get_config_keepalive(connector_ptr, connector_request_id_config_rx_keepalive); 00088 COND_ELSE_GOTO(result == connector_working, done); 00089 #endif 00090 00091 #if !(defined CONNECTOR_WAIT_COUNT) 00092 result = get_config_wait_count(connector_ptr); 00093 COND_ELSE_GOTO(result == connector_working, done); 00094 #endif 00095 00096 #if !(defined CONNECTOR_NETWORK_TCP_START) 00097 { 00098 connector_config_connect_type_t config_connect; 00099 00100 result = get_config_connect_status(connector_ptr, connector_request_id_config_network_tcp, &config_connect); 00101 COND_ELSE_GOTO(result == connector_working, done); 00102 00103 connector_ptr->edp_data.connect_type = config_connect.type; 00104 connector_ptr->edp_data.stop.auto_connect = connector_bool(config_connect.type == connector_connect_auto); 00105 } 00106 #else 00107 ASSERT((CONNECTOR_NETWORK_TCP_START == connector_connect_auto) || (CONNECTOR_NETWORK_TCP_START == connector_connect_manual)); 00108 if (CONNECTOR_NETWORK_TCP_START == connector_connect_auto) 00109 { 00110 edp_set_active_state(connector_ptr, connector_transport_open); 00111 } 00112 connector_ptr->edp_data.stop.auto_connect = connector_bool(CONNECTOR_NETWORK_TCP_START == connector_connect_auto); 00113 #endif 00114 00115 00116 #if !(defined CONNECTOR_IDENTITY_VERIFICATION) 00117 result = get_config_identity_verification(connector_ptr); 00118 COND_ELSE_GOTO(result == connector_working, done); 00119 { 00120 connector_identity_verification_t const identity_verification = connector_ptr->edp_data.config.identity_verification; 00121 #else 00122 { 00123 ASSERT((CONNECTOR_IDENTITY_VERIFICATION == connector_identity_verification_simple) || (CONNECTOR_IDENTITY_VERIFICATION == connector_identity_verification_password)); 00124 connector_identity_verification_t const identity_verification = CONNECTOR_IDENTITY_VERIFICATION; 00125 #endif 00126 00127 if (identity_verification == connector_identity_verification_password) 00128 { 00129 /* get password for password identity verification */ 00130 result = get_config_password(connector_ptr); 00131 COND_ELSE_GOTO(result == connector_working, done); 00132 } 00133 } 00134 00135 00136 done: 00137 return result; 00138 } 00139 00140 00141 connector_status_t connector_edp_init(connector_data_t * const connector_ptr) 00142 { 00143 00144 connector_status_t result = connector_working; 00145 00146 edp_reset_initial_data(connector_ptr); 00147 connector_ptr->edp_data.facilities.list = NULL; 00148 connector_ptr->edp_data.facilities.supported_mask = 0; 00149 00150 edp_set_active_state(connector_ptr, connector_transport_idle); 00151 edp_set_initiate_state(connector_ptr, connector_transport_idle); 00152 00153 result = edp_config_init(connector_ptr); 00154 if (result != connector_working) 00155 { 00156 goto done; 00157 } 00158 00159 result = edp_layer_get_supported_facilities(connector_ptr); 00160 if (result != connector_working) 00161 { 00162 goto done; 00163 } 00164 00165 result = edp_layer_initialize_facilities(connector_ptr); 00166 if (result != connector_working) 00167 { 00168 goto done; 00169 } 00170 00171 edp_get_device_cloud(connector_ptr); 00172 00173 done: 00174 return result; 00175 } 00176 00177 00178 connector_status_t connector_edp_step(connector_data_t * const connector_ptr) 00179 { 00180 connector_status_t result = connector_idle; 00181 connector_transport_state_t init_active_state = edp_get_active_state(connector_ptr); 00182 00183 while (result == connector_idle) 00184 { 00185 switch (edp_get_active_state(connector_ptr)) 00186 { 00187 case connector_transport_idle: 00188 if (connector_ptr->edp_data.stop.auto_connect) 00189 { 00190 edp_set_active_state(connector_ptr, connector_transport_open); 00191 } 00192 00193 goto check_state; 00194 00195 case connector_transport_open: 00196 result = edp_tcp_open_process(connector_ptr); 00197 break; 00198 00199 case connector_transport_send: 00200 case connector_transport_receive: 00201 00202 switch (edp_get_active_state(connector_ptr)) 00203 { 00204 case connector_transport_send: 00205 result = edp_tcp_send_process(connector_ptr); 00206 00207 if (edp_get_active_state(connector_ptr) == connector_transport_send) 00208 { 00209 edp_set_active_state(connector_ptr, connector_transport_receive); 00210 } 00211 break; 00212 case connector_transport_receive: 00213 result = edp_tcp_receive_process(connector_ptr); 00214 00215 if (edp_get_active_state(connector_ptr) == connector_transport_receive) 00216 { 00217 edp_set_active_state(connector_ptr, connector_transport_send); 00218 } 00219 break; 00220 default: 00221 break; 00222 } 00223 00224 break; 00225 case connector_transport_close: 00226 case connector_transport_terminate: 00227 result = edp_close_process(connector_ptr); 00228 break; 00229 00230 case connector_transport_redirect: 00231 result = edp_redirect_process(connector_ptr); 00232 break; 00233 00234 case connector_transport_wait_for_reconnect: 00235 { 00236 if (connector_ptr->edp_data.connect_at == 0) 00237 { 00238 connector_debug_printf("Waiting %d second before reconnecting TCP transport\n", CONNECTOR_TRANSPORT_RECONNECT_AFTER); 00239 result = get_system_time(connector_ptr, &connector_ptr->edp_data.connect_at); 00240 if (result != connector_working) 00241 goto done; 00242 connector_ptr->edp_data.connect_at += CONNECTOR_TRANSPORT_RECONNECT_AFTER; 00243 } else { 00244 unsigned long int uptime; 00245 00246 result = get_system_time(connector_ptr, &uptime); 00247 if (result != connector_working) 00248 goto done; 00249 if (uptime >= connector_ptr->edp_data.connect_at) 00250 edp_set_active_state(connector_ptr, connector_transport_open); 00251 } 00252 break; 00253 } 00254 } 00255 00256 if (result == connector_device_terminated 00257 || result == connector_abort 00258 00259 ) 00260 { 00261 connector_debug_printf("connector_edp_step: done with status = %d\n", result); 00262 goto done; 00263 } 00264 00265 00266 /* done all cases */ 00267 if (edp_get_active_state(connector_ptr) == init_active_state) break; 00268 } 00269 00270 check_state: 00271 switch (edp_get_initiate_state(connector_ptr)) 00272 { 00273 case connector_transport_close: 00274 switch (edp_get_active_state(connector_ptr)) 00275 { 00276 case connector_transport_idle: 00277 connector_ptr->edp_data.stop.auto_connect = connector_false; 00278 edp_set_initiate_state(connector_ptr, connector_transport_idle); 00279 00280 if (edp_is_stop_request(connector_ptr)) 00281 { 00282 result = connector_stop_callback(connector_ptr, connector_transport_tcp, connector_ptr->edp_data.stop.user_context); 00283 00284 if (result == connector_pending) 00285 { 00286 /* restore the initiate state */ 00287 edp_set_initiate_state(connector_ptr, connector_transport_close); 00288 } 00289 else if (result == connector_working) 00290 { 00291 edp_clear_stop_request(connector_ptr); 00292 } 00293 } 00294 /* exit edp so let connector_step does next step */ 00295 goto done; 00296 00297 case connector_transport_close: 00298 connector_ptr->edp_data.stop.auto_connect = connector_false; 00299 /* no break */ 00300 case connector_transport_terminate: 00301 break; 00302 00303 default: 00304 if (!tcp_is_send_active(connector_ptr) && result == connector_idle) 00305 { 00306 edp_set_stop_condition(connector_ptr, connector_stop_immediately); 00307 } 00308 if (edp_is_stop_immediately(connector_ptr)) 00309 { 00310 connector_ptr->edp_data.stop.auto_connect = connector_false; 00311 edp_set_close_status(connector_ptr, connector_close_status_device_stopped); 00312 edp_set_active_state(connector_ptr, connector_transport_close); 00313 } 00314 break; 00315 } 00316 break; 00317 case connector_transport_open: 00318 switch (edp_get_active_state(connector_ptr)) 00319 { 00320 case connector_transport_terminate: 00321 break; 00322 case connector_transport_close: 00323 case connector_transport_idle: 00324 if (result != connector_open_error) 00325 edp_set_active_state(connector_ptr, connector_transport_open); 00326 else 00327 edp_set_initiate_state(connector_ptr, connector_transport_idle); 00328 break; 00329 default: 00330 edp_set_initiate_state(connector_ptr, connector_transport_idle); 00331 break; 00332 } 00333 break; 00334 00335 case connector_transport_terminate: 00336 edp_set_close_status(connector_ptr, connector_close_status_device_terminated); 00337 edp_set_active_state(connector_ptr, connector_transport_close); 00338 break; 00339 default: 00340 break; 00341 } 00342 00343 done: 00344 return result; 00345 } 00346 00347 connector_status_t edp_initiate_action(connector_data_t * const connector_ptr, connector_initiate_request_t const request, void const * const request_data) 00348 { 00349 connector_status_t result = connector_init_error; 00350 00351 switch (request) 00352 { 00353 case connector_initiate_terminate: 00354 UNUSED_PARAMETER(request_data); 00355 edp_set_initiate_state(connector_ptr, connector_transport_terminate); 00356 result = connector_success; 00357 break; 00358 00359 #if (defined CONNECTOR_DATA_SERVICE) 00360 case connector_initiate_send_data: 00361 if (edp_get_edp_state(connector_ptr) == edp_communication_connect_to_cloud) goto done; 00362 00363 switch (edp_get_active_state(connector_ptr)) 00364 { 00365 case connector_transport_idle: 00366 result = connector_unavailable; 00367 goto done; 00368 00369 case connector_transport_close: 00370 if (edp_get_initiate_state(connector_ptr) == connector_transport_open) 00371 { 00372 break; 00373 } 00374 /* no break to return error */ 00375 case connector_transport_redirect: 00376 result = connector_unavailable; 00377 goto done; 00378 00379 case connector_transport_wait_for_reconnect: 00380 case connector_transport_terminate: 00381 goto done; 00382 00383 case connector_transport_open: 00384 case connector_transport_send: 00385 case connector_transport_receive: 00386 switch (edp_get_initiate_state(connector_ptr)) 00387 { 00388 case connector_transport_close: 00389 result = connector_unavailable; 00390 goto done; 00391 default: 00392 break; 00393 } 00394 break; 00395 } 00396 result = data_service_initiate(connector_ptr, request_data); 00397 break; 00398 #endif 00399 #if (defined CONNECTOR_DATA_POINTS) 00400 case connector_initiate_data_point_single: 00401 case connector_initiate_data_point_binary: 00402 if (edp_get_edp_state(connector_ptr) == edp_communication_connect_to_cloud) goto done; 00403 00404 switch (edp_get_active_state(connector_ptr)) 00405 { 00406 case connector_transport_idle: 00407 result = connector_unavailable; 00408 goto done; 00409 00410 case connector_transport_close: 00411 if (edp_get_initiate_state(connector_ptr) == connector_transport_open) 00412 { 00413 break; 00414 } 00415 /* no break to return error */ 00416 case connector_transport_redirect: 00417 result = connector_unavailable; 00418 goto done; 00419 00420 case connector_transport_wait_for_reconnect: 00421 case connector_transport_terminate: 00422 goto done; 00423 00424 case connector_transport_open: 00425 case connector_transport_send: 00426 case connector_transport_receive: 00427 switch (edp_get_initiate_state(connector_ptr)) 00428 { 00429 case connector_transport_close: 00430 result = connector_unavailable; 00431 goto done; 00432 default: 00433 break; 00434 } 00435 break; 00436 } 00437 switch (request) 00438 { 00439 case connector_initiate_data_point_single: 00440 result = dp_initiate_data_point_single(request_data); 00441 break; 00442 case connector_initiate_data_point_binary: 00443 result = dp_initiate_data_point_binary(request_data); 00444 break; 00445 /* default: */ 00446 case connector_initiate_transport_start: 00447 case connector_initiate_transport_stop: 00448 #if (defined CONNECTOR_DATA_SERVICE) 00449 case connector_initiate_send_data: 00450 #endif 00451 #if (defined CONNECTOR_SHORT_MESSAGE) 00452 case connector_initiate_ping_request: 00453 case connector_initiate_session_cancel: 00454 #if (CONNECTOR_VERSION >= 0x02010000) 00455 case connector_initiate_session_cancel_all: 00456 #endif 00457 #endif 00458 case connector_initiate_terminate: 00459 break; 00460 } 00461 break; 00462 #endif 00463 00464 case connector_initiate_transport_stop: 00465 switch (edp_get_active_state(connector_ptr)) 00466 { 00467 case connector_transport_open: 00468 case connector_transport_send: 00469 case connector_transport_receive: 00470 case connector_transport_redirect: 00471 break; 00472 00473 case connector_transport_idle: 00474 case connector_transport_close: 00475 /* Return busy if start initiate action was called and cannot stop now */ 00476 if (edp_get_initiate_state(connector_ptr) == connector_transport_open) 00477 { 00478 result = connector_service_busy; 00479 goto done; 00480 } 00481 break; 00482 00483 default: 00484 goto done; 00485 } 00486 00487 if (edp_get_initiate_state(connector_ptr) == connector_transport_close && 00488 edp_is_stop_request(connector_ptr)) 00489 { 00490 /* already requesting stop before */ 00491 result = connector_service_busy; 00492 } 00493 else 00494 { 00495 connector_initiate_stop_request_t const * const stop_request = request_data; 00496 00497 edp_set_stop_condition(connector_ptr, stop_request->condition); 00498 00499 if (stop_request->transport == connector_transport_tcp) 00500 { 00501 edp_set_stop_request(connector_ptr, stop_request->user_context); 00502 } 00503 00504 edp_set_initiate_state(connector_ptr, connector_transport_close); 00505 result = connector_success; 00506 } 00507 break; 00508 00509 case connector_initiate_transport_start: 00510 if (request_data == NULL) 00511 { 00512 result = connector_invalid_data; 00513 goto done; 00514 } 00515 switch (edp_get_active_state(connector_ptr)) 00516 { 00517 case connector_transport_open: 00518 case connector_transport_send: 00519 case connector_transport_receive: 00520 case connector_transport_redirect: 00521 /* Return busy if stop initiate action was called and cannot start now */ 00522 result = (edp_get_initiate_state(connector_ptr) == connector_transport_close) ? connector_service_busy : connector_success; 00523 break; 00524 00525 case connector_transport_idle: 00526 case connector_transport_close: 00527 if (edp_get_initiate_state(connector_ptr) == connector_transport_close) 00528 { 00529 result = connector_service_busy; 00530 } 00531 else 00532 { 00533 edp_set_initiate_state(connector_ptr, connector_transport_open); 00534 edp_get_device_cloud(connector_ptr); 00535 result = connector_success; 00536 } 00537 break; 00538 00539 case connector_transport_wait_for_reconnect: 00540 case connector_transport_terminate: 00541 goto done; 00542 } 00543 00544 break; 00545 00546 default: 00547 ASSERT(connector_false); 00548 result = connector_abort; 00549 break; 00550 } 00551 00552 done: 00553 00554 return result; 00555 } 00556
Generated on Tue Jul 12 2022 19:18:38 by
1.7.2