Sebastián Pastor / EtheriosCloudConnector
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers connector_edp.h Source File

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