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

« Back to documentation index

Show/hide line numbers rci_binary.h Source File

rci_binary.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 "rci_binary_support.h"
00014 #include "rci_binary_debug.h"
00015 #include "rci_binary_util.h"
00016 #include "rci_binary_buffer.h"
00017 #include "rci_binary_string.h"
00018 #include "rci_binary_group.h"
00019 #include "rci_binary_element.h"
00020 #include "rci_binary_callback.h"
00021 #include "rci_binary_output.h"
00022 #include "rci_binary_input.h"
00023 #include "rci_binary_traverse.h"
00024 #include "rci_binary_error.h"
00025 
00026 static connector_bool_t rci_action_session_start(rci_t * const rci, rci_service_data_t * service_data)
00027 {
00028     ASSERT(rci->service_data == NULL);
00029     rci->service_data = service_data;
00030     ASSERT(rci->service_data != NULL);
00031 
00032     rci_set_buffer(&rci->buffer.input, &rci->service_data->input);
00033     rci_set_buffer(&rci->buffer.output, &rci->service_data->output);
00034 #if defined RCI_DEBUG
00035     memset(rci->service_data->output.data, 0, rci->service_data->output.bytes);
00036 #endif
00037 
00038     rci->input.destination = rci_buffer_position(&rci->buffer.input);
00039     reset_input_content(rci);
00040 
00041     invalidate_group_id(rci);
00042     invalidate_group_index(rci);
00043     invalidate_element_id(rci);
00044 
00045     rci->shared.callback_data.response.element_value = &rci->shared.value;
00046 
00047     rci->status = rci_status_busy;
00048     rci->error.command_error = connector_false;
00049     rci->input.flag = 0;
00050 
00051     trigger_rci_callback(rci, connector_request_id_remote_config_session_start);
00052     set_rci_input_state(rci, rci_input_state_command_id);
00053     state_call(rci, rci_parser_state_input);
00054 
00055     set_rci_error_state(rci, rci_error_state_id);
00056 
00057     return connector_true;
00058 }
00059 
00060 static connector_bool_t rci_action_session_active(rci_t * const rci)
00061 {
00062     connector_bool_t success = connector_true;
00063 
00064     switch (rci->status)
00065     {
00066         case rci_status_error:
00067         case rci_status_complete:
00068         {
00069             rci->status = rci_status_internal_error;
00070             /* no break; */
00071         }
00072 
00073         case rci_status_internal_error:
00074         {
00075             success = connector_false;
00076             break;
00077         }
00078 
00079         case rci_status_busy:
00080         {
00081             break;
00082         }
00083 
00084         case rci_status_more_input:
00085         {
00086             connector_debug_hexvalue("rci_binary more request", rci->service_data->input.data, rci->service_data->input.bytes);
00087             rci_set_buffer(&rci->buffer.input, &rci->service_data->input);
00088             if (!destination_in_storage(rci))
00089             {
00090                 rci->input.destination = rci_buffer_position(&rci->buffer.input);
00091             }
00092             rci->status = rci_status_busy;
00093             break;
00094         }
00095 
00096         case rci_status_flush_output:
00097         {
00098             rci_set_buffer(&rci->buffer.output, &rci->service_data->output);
00099 #if defined RCI_DEBUG
00100             memset(rci->service_data->output.data, 0, rci->service_data->output.bytes);
00101 #endif
00102             rci->status = rci_status_busy;
00103             break;
00104         }
00105     }
00106 
00107     return success;
00108 }
00109 
00110 static connector_bool_t rci_action_session_lost(rci_t * const rci)
00111 {
00112     trigger_rci_callback(rci, connector_request_id_remote_config_session_cancel);
00113     {
00114         connector_bool_t const success = rci_callback(rci);
00115         ASSERT(success); UNUSED_VARIABLE(success);
00116     }
00117 
00118     rci->status = rci_status_complete;
00119 
00120     return connector_false;
00121 }
00122 
00123 
00124 static rci_status_t rci_binary(rci_session_t const action, ...)
00125 {
00126     static rci_t rci;
00127 
00128     {
00129         connector_bool_t success;
00130         va_list ap;
00131 
00132         switch (action)
00133         {
00134         case rci_session_start:
00135             va_start(ap, action);
00136             success = rci_action_session_start(&rci, va_arg(ap, rci_service_data_t *));
00137             va_end(ap);
00138             break;
00139 
00140         case rci_session_active:
00141             success = rci_action_session_active(&rci);
00142             break;
00143 
00144         case rci_session_lost:
00145             success = rci_action_session_lost(&rci);
00146             break;
00147 
00148         default:
00149             success = connector_false;
00150             break;
00151         }
00152 
00153         if (!success) goto done;
00154     }
00155 
00156     if (pending_rci_callback(&rci))
00157     {
00158         connector_remote_config_t * const remote_config = &rci.shared.callback_data;
00159 
00160         if (!rci_callback(&rci))
00161             goto done;
00162 
00163         if (remote_config->error_id != connector_success)
00164         {
00165             rci_group_error(&rci, remote_config->error_id, remote_config->response.error_hint);
00166             goto done;
00167         }
00168     }
00169 
00170     switch (rci.parser.state)
00171     {
00172     case rci_parser_state_input:
00173         rci_parse_input(&rci);
00174         break;
00175 
00176     case rci_parser_state_output:
00177         rci_generate_output(&rci);
00178         break;
00179 
00180     case rci_parser_state_traverse:
00181         rci_traverse_data(&rci);
00182         break;
00183 
00184     case rci_parser_state_error:
00185         rci_generate_error(&rci);
00186         break;
00187     }
00188 
00189 done:
00190 
00191     switch (rci.status)
00192     {
00193     case rci_status_busy:
00194         break;
00195     case rci_status_more_input:
00196         rci_debug_printf("Need more input\n");
00197         break;
00198     case rci_status_flush_output:
00199         rci.service_data->output.bytes = rci_buffer_used(&rci.buffer.output);
00200         break;
00201     case rci_status_complete:
00202         rci.service_data->output.bytes = rci_buffer_used(&rci.buffer.output);
00203         /* no break; */
00204     case rci_status_internal_error:
00205     case rci_status_error:
00206         rci.service_data = NULL;
00207         break;
00208     }
00209 
00210     return rci.status;
00211 }
00212 
00213