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

« Back to documentation index

Show/hide line numbers rci_binary_traverse.h Source File

rci_binary_traverse.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 static void traverse_rci_command(rci_t * const rci)
00014 {
00015     trigger_rci_callback(rci, connector_request_id_remote_config_action_start);
00016 
00017     set_rci_output_state(rci, rci_output_state_command_id);
00018     state_call(rci, rci_parser_state_output);
00019 
00020 }
00021 static void traverse_group_id(rci_t * const rci)
00022 {
00023     trigger_rci_callback(rci, connector_request_id_remote_config_group_start);
00024 
00025     set_rci_output_state(rci, rci_output_state_group_id);
00026     state_call(rci, rci_parser_state_output);
00027 }
00028 
00029 static void traverse_element_id(rci_t * const rci)
00030 {
00031 
00032     connector_group_element_t const * const element = get_current_element(rci);
00033 
00034     if ((rci->shared.callback_data.action == connector_remote_action_query) &&
00035         (element->access == connector_element_access_write_only))
00036     {
00037         goto done;
00038     }
00039 
00040     trigger_rci_callback(rci, connector_request_id_remote_config_group_process);
00041     set_rci_output_state(rci, rci_output_state_field_id);
00042     state_call(rci, rci_parser_state_output);
00043 
00044 done:
00045     return;
00046 }
00047 
00048 static void traverse_element_end(rci_t * const rci)
00049 {
00050     trigger_rci_callback(rci, connector_request_id_remote_config_group_end);
00051 
00052     set_rci_output_state(rci, rci_output_state_field_terminator);
00053     state_call(rci, rci_parser_state_output);
00054 }
00055 
00056 static void traverse_group_end(rci_t * const rci)
00057 {
00058     trigger_rci_callback(rci, connector_request_id_remote_config_action_end);
00059     set_rci_output_state(rci, rci_output_state_group_terminator);
00060     state_call(rci, rci_parser_state_output);
00061 
00062 }
00063 
00064 static connector_bool_t traverse_all_elements(rci_t * const rci)
00065 {
00066     connector_bool_t done = connector_false;
00067 
00068     if (!have_element_id(rci))
00069     {
00070         /* all fields */
00071         set_element_id(rci, 0);
00072         traverse_element_id(rci);
00073     }
00074     else
00075     {
00076         connector_group_t const * const group =  get_current_group(rci);
00077         unsigned int const id = get_element_id(rci) + 1;
00078 
00079         if (id < group->elements.count)
00080         {
00081             set_element_id(rci, id);
00082             traverse_element_id(rci);
00083         }
00084         else
00085         {
00086             traverse_element_end(rci);
00087             done = connector_true;
00088         }
00089     }
00090     return done;
00091 }
00092 
00093 static connector_bool_t traverse_all_group_instances(rci_t * const rci)
00094 {
00095     connector_bool_t done = connector_false;
00096 
00097     switch (rci->traverse.process_state)
00098     {
00099         case rci_traverse_process_group:
00100         case rci_traverse_process_element:
00101             if (traverse_all_elements(rci))
00102                 rci->traverse.process_state = rci_traverse_process_next_instance;
00103             break;
00104         case rci_traverse_process_next_instance:
00105             {
00106                 connector_group_t const * const group =  get_current_group(rci);
00107                 if (group->instances > 1 && group->instances > get_group_index(rci))
00108                 {
00109                     /* next instances */
00110                     increment_group_index(rci);
00111                     traverse_group_id(rci);
00112                     rci->traverse.process_state = rci_traverse_process_element;
00113                 }
00114                 else
00115                 {
00116                     /* no more instances */
00117                     done = connector_true;
00118                 }
00119             }
00120             break;
00121     }
00122 
00123     return done;
00124 }
00125 
00126 static connector_bool_t traverse_all_groups(rci_t * const rci)
00127 {
00128     connector_bool_t done = connector_false;
00129 
00130     switch (rci->traverse.process_state)
00131     {
00132         case rci_traverse_process_group:
00133         {
00134             connector_remote_group_table_t const * const table = (connector_rci_config_data.group_table + rci->shared.callback_data.group.type);
00135 
00136             if (table->count == 0)
00137             {
00138                 traverse_group_end(rci);
00139             }
00140             else if (!have_group_id(rci))
00141             {
00142                 set_group_id(rci, 0);
00143                 set_group_index(rci, 1);
00144                 traverse_group_id(rci);
00145                 rci->traverse.process_state = rci_traverse_process_element;
00146             }
00147             else
00148             {
00149 
00150                 size_t const id = get_group_id(rci) + 1;
00151 
00152                 if (id == table->count)
00153                 {
00154                     /* done all groups */
00155                     traverse_group_end(rci);
00156                     done = connector_true;
00157                 }
00158                 else
00159                 {
00160                     connector_group_t const * const group =  get_current_group(rci);
00161                     if (group->instances > 1 && group->instances > get_group_index(rci))
00162                     {
00163                         /* next instances */
00164                         increment_group_index(rci);
00165                     }
00166                     else
00167                     {
00168                         /* next group */
00169                         increment_group_id(rci);
00170                         set_group_index(rci, 1);
00171                     }
00172                     traverse_group_id(rci);
00173                     rci->traverse.process_state = rci_traverse_process_element;
00174                 }
00175             }
00176             break;
00177         }
00178         case rci_traverse_process_element:
00179             if (traverse_all_elements(rci))
00180                 rci->traverse.process_state = rci_traverse_process_group;
00181             break;
00182 
00183         case rci_traverse_process_next_instance:
00184             break;
00185     }
00186 
00187     return done;
00188 }
00189 
00190 static void rci_traverse_data(rci_t * const rci)
00191 {
00192     connector_bool_t done_state = connector_true;
00193 
00194     rci_debug_printf("traverse: %s\n", rci_traverse_state_t_as_string(rci->traverse.state));
00195 
00196     switch (rci->traverse.state)
00197     {
00198         case rci_traverse_state_none:
00199             if (get_rci_input_state(rci) == rci_input_state_done)
00200                 state_call(rci, rci_parser_state_output);
00201             else
00202                 state_call(rci, rci_parser_state_input);
00203             break;
00204 
00205         case rci_traverse_state_command_id:
00206             traverse_rci_command(rci);
00207             break;
00208 
00209         case rci_traverse_state_all_groups:
00210             done_state = traverse_all_groups(rci);
00211             break;
00212 
00213         case rci_traverse_state_group_id:
00214             traverse_group_id(rci);
00215             break;
00216 
00217         case rci_traverse_state_all_group_instances:
00218             done_state = traverse_all_group_instances(rci);
00219             break;
00220 
00221         case rci_traverse_state_element_id:
00222             traverse_element_id(rci);
00223             break;
00224 
00225         case rci_traverse_state_all_elements:
00226             done_state = traverse_all_elements(rci);
00227             break;
00228 
00229         case rci_traverse_state_element_end:
00230             traverse_element_end(rci);
00231             break;
00232 
00233         case rci_traverse_state_group_end:
00234             traverse_group_end(rci);
00235             break;
00236     }
00237 
00238     if (done_state)
00239     {
00240         rci->traverse.process_state = rci_traverse_process_group;
00241         set_rci_traverse_state(rci, rci_traverse_state_none);
00242     }
00243 
00244     return;
00245 }
00246 
00247