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

« Back to documentation index

Show/hide line numbers rci_binary_error.h Source File

rci_binary_error.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 rci_output_error_id(rci_t * const rci)
00014 {
00015 
00016     connector_remote_config_t const * const response = &rci->shared.callback_data;
00017     uint32_t value;
00018 
00019     if (rci->error.command_error)
00020     {
00021         #define BINARY_RCI_COMMAND_LOWER_ERROR_ID_MASK  UINT32_C(0x7FF)
00022         #define BINARY_RCI_COMMAND_UPPER_ERROR_ID_MASK   (~UINT32_C(0x1FFF))
00023         /* Command Error ID is [:13][10:0] */
00024         value = (response->error_id & BINARY_RCI_COMMAND_LOWER_ERROR_ID_MASK);
00025         value |= ((response->error_id << UINT32_C(2)) & BINARY_RCI_COMMAND_UPPER_ERROR_ID_MASK);
00026     }
00027     else
00028     {
00029         /* Error Id is [:13][10:7][5:0] */
00030         #define BINARY_RCI_LOWER_ERROR_ID_MASK UINT32_C(0x3F)
00031         #define BINARY_RCI_MIDDLE_ERROR_ID_MASK UINT32_C(0x780)
00032         #define BINARY_RCI_UPPER_ERROR_ID_MASK  ()~UINT32_C(0x1FFF))
00033 
00034         value = response->error_id & BINARY_RCI_LOWER_ERROR_ID_MASK;
00035         value |= (response->error_id << 1) & BINARY_RCI_MIDDLE_ERROR_ID_MASK;
00036         value |= (response->error_id << 3) & BINARY_RCI_MIDDLE_ERROR_ID_MASK;
00037 
00038     }
00039 
00040     value |= BINARY_RCI_ERROR_INDICATOR_BIT;
00041 
00042     {
00043         connector_bool_t const overflow = rci_output_uint32(rci, value);
00044 
00045         if (!overflow)
00046             set_rci_error_state(rci, rci_error_state_description);
00047     }
00048 }
00049 
00050 static void rci_output_error_description(rci_t * const rci)
00051 {
00052 #if defined RCI_PARSER_USES_ERROR_DESCRIPTIONS
00053     char const * const description = rci->error.description+1;
00054     size_t const length = (size_t)*rci->error.description;
00055 #else
00056     char * description = NULL;
00057     size_t const length = 0;
00058 #endif
00059 
00060     connector_bool_t const overflow = rci_output_string(rci, description,  length);
00061 
00062     if (!overflow)
00063         set_rci_error_state(rci, rci_error_state_hint);
00064 }
00065 
00066 static void rci_output_error_hint(rci_t * const rci)
00067 {
00068     connector_remote_config_t const * const remote_config_ = &rci->shared.callback_data;
00069     size_t const description_length = (remote_config_->response.error_hint == NULL) ? 0 : strlen(remote_config_->response.error_hint);
00070     connector_bool_t const overflow = rci_output_string(rci, remote_config_->response.error_hint,  description_length);
00071 
00072     if (!overflow)
00073     {
00074         set_rci_error_state(rci, rci_error_state_callback);
00075     }
00076 }
00077 
00078 
00079 static void rci_generate_error(rci_t * const rci)
00080 {
00081     rci_buffer_t * const output = &rci->buffer.output;
00082 
00083     if (pending_rci_callback(rci))
00084     {
00085         if (!rci_callback(rci))
00086             goto done;
00087     }
00088 
00089     if (rci_buffer_remaining(output) != 0)
00090     {
00091         switch (rci->error.state)
00092         {
00093             case rci_error_state_id:
00094                 rci_output_error_id(rci);
00095                 break;
00096 
00097             case rci_error_state_description:
00098                 rci_output_error_description(rci);
00099                 break;
00100 
00101             case rci_error_state_hint:
00102                 rci_output_error_hint(rci);
00103                 break;
00104 
00105             case rci_error_state_callback:
00106             {
00107                 connector_request_id_remote_config_t const remote_config_request = rci->callback.request.remote_config_request;
00108 
00109                 switch (remote_config_request)
00110                 {
00111                     case connector_request_id_remote_config_action_start:
00112                     case connector_request_id_remote_config_group_end:
00113                         trigger_rci_callback(rci, connector_request_id_remote_config_action_end);
00114                         break;
00115                     case connector_request_id_remote_config_session_start:
00116                         trigger_rci_callback(rci, connector_request_id_remote_config_session_end);
00117                         break;
00118                     case connector_request_id_remote_config_action_end:
00119                         {
00120                             connector_bool_t const overflow = rci_output_terminator(rci);
00121                             if (overflow) goto done;
00122                         }
00123                         trigger_rci_callback(rci, connector_request_id_remote_config_session_end);
00124                         break;
00125 
00126                     case connector_request_id_remote_config_group_process:
00127                     case connector_request_id_remote_config_group_start:
00128                         {
00129                             connector_bool_t const overflow = rci_output_terminator(rci);
00130                             if (overflow) goto done;
00131                         }
00132                         trigger_rci_callback(rci, connector_request_id_remote_config_group_end);
00133                         break;
00134 
00135                     case connector_request_id_remote_config_session_cancel:
00136                         ASSERT(connector_false);
00137                         break;
00138 
00139                     case connector_request_id_remote_config_session_end:
00140                         rci->status = rci_status_complete;
00141                         break;
00142                 }
00143                 break;
00144             }
00145         }
00146     }
00147 
00148 #if defined RCI_DEBUG
00149     {
00150         size_t const bytes = rci_buffer_used(&rci->buffer.output);
00151         if (bytes > 0)
00152         {
00153             connector_debug_hexvalue("Response", rci->buffer.output.start, bytes);
00154         }
00155     }
00156 #endif
00157 
00158 done:
00159     return;
00160 }
00161 
00162 
00163