Etherios Cloud Connector very first porting for mbed. Tested in an LPC1768

Etherios Cloud Connector for Embedded v2.1.0.3 library for mbed. Early porting.

This port is centered mainly in the platform code. So it should work properly with the provided examples of send_data, device_request, data_points, RCI and firmware_update (stub implementation, not a real one... yet ;-)). Filesystem is not implemented yet, and some examples might need changes.

To run, it needs the following libraries: - mbed - mbed-rtos - EthernetInterface

Find more information (and the source code!) about Etherios Cloud Connector for Embedded here: http://www.etherios.com/products/devicecloud/support/connector and in: http://www.etherios.com

Committer:
spastor
Date:
Tue Dec 03 14:10:48 2013 +0000
Revision:
1:908afea5a49d
Parent:
0:1c358ea10753
Use internal Thread.h instead of Threads.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
spastor 0:1c358ea10753 1 /*
spastor 0:1c358ea10753 2 * Copyright (c) 2013 Digi International Inc.,
spastor 0:1c358ea10753 3 * All rights not expressly granted are reserved.
spastor 0:1c358ea10753 4 *
spastor 0:1c358ea10753 5 * This Source Code Form is subject to the terms of the Mozilla Public
spastor 0:1c358ea10753 6 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
spastor 0:1c358ea10753 7 * You can obtain one at http://mozilla.org/MPL/2.0/.
spastor 0:1c358ea10753 8 *
spastor 0:1c358ea10753 9 * Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
spastor 0:1c358ea10753 10 * =======================================================================
spastor 0:1c358ea10753 11 */
spastor 0:1c358ea10753 12
spastor 0:1c358ea10753 13
spastor 0:1c358ea10753 14 #if defined RCI_PARSER_USES_ERROR_DESCRIPTIONS
spastor 0:1c358ea10753 15 static char const rci_set_empty_group_hint[] = "Empty group";
spastor 0:1c358ea10753 16 static char const rci_set_empty_element_hint[] = "empty element";
spastor 0:1c358ea10753 17 static char const rci_error_descriptor_mismatch_hint[] = "Mismatch configurations";
spastor 0:1c358ea10753 18 static char const rci_error_content_size_hint[] = "Maximum content size exceeded";
spastor 0:1c358ea10753 19 #else
spastor 0:1c358ea10753 20 #define rci_set_empty_group_hint RCI_NO_HINT
spastor 0:1c358ea10753 21 #define rci_set_empty_element_hint RCI_NO_HINT
spastor 0:1c358ea10753 22 #define rci_error_descriptor_mismatch_hint RCI_NO_HINT
spastor 0:1c358ea10753 23 #define rci_error_content_size_hint RCI_NO_HINT
spastor 0:1c358ea10753 24 #endif
spastor 0:1c358ea10753 25
spastor 0:1c358ea10753 26 static connector_bool_t destination_in_storage(rci_t const * const rci)
spastor 0:1c358ea10753 27 {
spastor 0:1c358ea10753 28 uint8_t const * const storage_begin = rci->input.storage;
spastor 0:1c358ea10753 29 uint8_t const * const storage_end = storage_begin + sizeof rci->input.storage;
spastor 0:1c358ea10753 30
spastor 0:1c358ea10753 31 return ptr_in_range(rci->input.destination, storage_begin, storage_end);
spastor 0:1c358ea10753 32 }
spastor 0:1c358ea10753 33
spastor 0:1c358ea10753 34 static size_t get_bytes_to_follow(uint8_t opcode)
spastor 0:1c358ea10753 35 {
spastor 0:1c358ea10753 36 size_t bytes_to_read = 0;
spastor 0:1c358ea10753 37
spastor 0:1c358ea10753 38 if (opcode & BINARY_RCI_SIZE_ALTERNATE_FLAG)
spastor 0:1c358ea10753 39 {
spastor 0:1c358ea10753 40 rci_size_modifier_t size_mask = BINARY_RCI_SIZE_MODIFIER(opcode);
spastor 0:1c358ea10753 41 switch (size_mask)
spastor 0:1c358ea10753 42 {
spastor 0:1c358ea10753 43 case binary_rci_one_follow_byte:
spastor 0:1c358ea10753 44 bytes_to_read = 1;
spastor 0:1c358ea10753 45 break;
spastor 0:1c358ea10753 46 case binary_rci_multi_follow_byte:
spastor 0:1c358ea10753 47 switch (BINARY_RCI_MULTI_FOLLOW_BYTES(opcode))
spastor 0:1c358ea10753 48 {
spastor 0:1c358ea10753 49 case binary_rci_two_follow_byte:
spastor 0:1c358ea10753 50 bytes_to_read = 2;
spastor 0:1c358ea10753 51 break;
spastor 0:1c358ea10753 52 case binary_rci_four_follow_byte:
spastor 0:1c358ea10753 53 bytes_to_read = 4;
spastor 0:1c358ea10753 54 break;
spastor 0:1c358ea10753 55 case binary_rci_eight_follow_byte:
spastor 0:1c358ea10753 56 bytes_to_read = 8;
spastor 0:1c358ea10753 57 break;
spastor 0:1c358ea10753 58 }
spastor 0:1c358ea10753 59 break;
spastor 0:1c358ea10753 60 case binary_rci_special_value:
spastor 0:1c358ea10753 61 bytes_to_read = 0;
spastor 0:1c358ea10753 62 break;
spastor 0:1c358ea10753 63 default:
spastor 0:1c358ea10753 64 ASSERT(connector_false);
spastor 0:1c358ea10753 65 }
spastor 0:1c358ea10753 66 }
spastor 0:1c358ea10753 67 return bytes_to_read;
spastor 0:1c358ea10753 68 }
spastor 0:1c358ea10753 69
spastor 0:1c358ea10753 70 static void reset_input_content(rci_t * const rci)
spastor 0:1c358ea10753 71 {
spastor 0:1c358ea10753 72 rci->shared.content.data = rci->input.destination;
spastor 0:1c358ea10753 73 rci->shared.content.length = 0;
spastor 0:1c358ea10753 74 }
spastor 0:1c358ea10753 75
spastor 0:1c358ea10753 76 #define BINARY_RCI_ONE_BYTE_LIMIT_MASK UINT32_C(0x7F)
spastor 0:1c358ea10753 77 #define BINARY_RCI_HI_BYTE_MASK UINT32_C(0x1F)
spastor 0:1c358ea10753 78
spastor 0:1c358ea10753 79 static size_t get_modifier_ber(rci_t * const rci, uint32_t * const value)
spastor 0:1c358ea10753 80 {
spastor 0:1c358ea10753 81
spastor 0:1c358ea10753 82 uint8_t * const rci_ber = rci->shared.content.data;
spastor 0:1c358ea10753 83 uint8_t const modifier_ber = message_load_u8(rci_ber, value);
spastor 0:1c358ea10753 84
spastor 0:1c358ea10753 85 size_t bytes_read = ++rci->shared.content.length;
spastor 0:1c358ea10753 86
spastor 0:1c358ea10753 87 {
spastor 0:1c358ea10753 88 /* we have modifier BEF */
spastor 0:1c358ea10753 89 size_t const bytes_to_follow = get_bytes_to_follow(modifier_ber) +1;
spastor 0:1c358ea10753 90
spastor 0:1c358ea10753 91 bytes_read = rci->shared.content.length;
spastor 0:1c358ea10753 92
spastor 0:1c358ea10753 93 if (bytes_read < bytes_to_follow)
spastor 0:1c358ea10753 94 {
spastor 0:1c358ea10753 95 bytes_read = 0;
spastor 0:1c358ea10753 96 goto done;
spastor 0:1c358ea10753 97 }
spastor 0:1c358ea10753 98
spastor 0:1c358ea10753 99 switch (bytes_to_follow)
spastor 0:1c358ea10753 100 {
spastor 0:1c358ea10753 101 case record_bytes(rci_ber):
spastor 0:1c358ea10753 102 *value = (modifier_ber & BINARY_RCI_SIZE_ALTERNATE_FLAG) ? modifier_ber : (modifier_ber & BINARY_RCI_ONE_BYTE_LIMIT_MASK);
spastor 0:1c358ea10753 103 break;
spastor 0:1c358ea10753 104 case record_bytes(rci_ber_u8):
spastor 0:1c358ea10753 105 {
spastor 0:1c358ea10753 106 uint8_t * const rci_ber_u8 = rci_ber;
spastor 0:1c358ea10753 107 /* mask of the 1st byte for data value */
spastor 0:1c358ea10753 108 *value = (modifier_ber & BINARY_RCI_HI_BYTE_MASK) << 8;
spastor 0:1c358ea10753 109 *value |= message_load_u8(rci_ber_u8, value);
spastor 0:1c358ea10753 110 break;
spastor 0:1c358ea10753 111 }
spastor 0:1c358ea10753 112 case record_bytes(rci_ber_u16):
spastor 0:1c358ea10753 113 {
spastor 0:1c358ea10753 114 uint8_t * const rci_ber_u16 = rci_ber;
spastor 0:1c358ea10753 115 *value = message_load_be16(rci_ber_u16, value);
spastor 0:1c358ea10753 116 break;
spastor 0:1c358ea10753 117 }
spastor 0:1c358ea10753 118 case record_bytes(rci_ber_u32):
spastor 0:1c358ea10753 119 {
spastor 0:1c358ea10753 120 uint8_t * const rci_ber_u32 = rci_ber;
spastor 0:1c358ea10753 121 *value = message_load_be32(rci_ber_u32, value);
spastor 0:1c358ea10753 122 break;
spastor 0:1c358ea10753 123 }
spastor 0:1c358ea10753 124 default:
spastor 0:1c358ea10753 125 ASSERT(bytes_to_follow == 1);
spastor 0:1c358ea10753 126 /* NONUM or TRM value */
spastor 0:1c358ea10753 127 *value = modifier_ber;
spastor 0:1c358ea10753 128 break;
spastor 0:1c358ea10753 129 }
spastor 0:1c358ea10753 130 bytes_read = bytes_to_follow;
spastor 0:1c358ea10753 131 }
spastor 0:1c358ea10753 132
spastor 0:1c358ea10753 133 done:
spastor 0:1c358ea10753 134 return bytes_read;
spastor 0:1c358ea10753 135 }
spastor 0:1c358ea10753 136
spastor 0:1c358ea10753 137 static connector_bool_t get_uint32(rci_t * const rci, uint32_t * const value)
spastor 0:1c358ea10753 138 {
spastor 0:1c358ea10753 139
spastor 0:1c358ea10753 140 size_t const bytes = get_modifier_ber(rci, value);
spastor 0:1c358ea10753 141
spastor 0:1c358ea10753 142 if (bytes > 0)
spastor 0:1c358ea10753 143 reset_input_content(rci);
spastor 0:1c358ea10753 144
spastor 0:1c358ea10753 145 return connector_bool(bytes > 0);
spastor 0:1c358ea10753 146 }
spastor 0:1c358ea10753 147
spastor 0:1c358ea10753 148 #if defined RCI_PARSER_USES_FLOAT
spastor 0:1c358ea10753 149 static connector_bool_t get_float(rci_t * const rci, float * const value)
spastor 0:1c358ea10753 150 {
spastor 0:1c358ea10753 151
spastor 0:1c358ea10753 152 connector_bool_t value_decoded = connector_false;
spastor 0:1c358ea10753 153 uint8_t * rci_ber_u32 = rci->shared.content.data;
spastor 0:1c358ea10753 154 uint8_t const opcode = message_load_u8(rci_ber_u32, opcode);
spastor 0:1c358ea10753 155
spastor 0:1c358ea10753 156 rci->shared.content.length++;
spastor 0:1c358ea10753 157 ASSERT(sizeof(uint32_t) == sizeof(float));
spastor 0:1c358ea10753 158
spastor 0:1c358ea10753 159 {
spastor 0:1c358ea10753 160 /* we have modifier BEF */
spastor 0:1c358ea10753 161 size_t const bytes_to_follow = get_bytes_to_follow(opcode);
spastor 0:1c358ea10753 162 size_t bytes_read = rci->shared.content.length;
spastor 0:1c358ea10753 163
spastor 0:1c358ea10753 164 if (bytes_read < (bytes_to_follow + 1))
spastor 0:1c358ea10753 165 {
spastor 0:1c358ea10753 166 goto error;
spastor 0:1c358ea10753 167 }
spastor 0:1c358ea10753 168
spastor 0:1c358ea10753 169 /* Current, we only support single precision float. */
spastor 0:1c358ea10753 170 ASSERT(bytes_read == record_bytes(rci_ber_u32));
spastor 0:1c358ea10753 171
spastor 0:1c358ea10753 172 {
spastor 0:1c358ea10753 173 uint32_t float_value = message_load_be32(rci_ber_u32, value);
spastor 0:1c358ea10753 174 memcpy(value, &float_value, sizeof *value);
spastor 0:1c358ea10753 175 }
spastor 0:1c358ea10753 176 }
spastor 0:1c358ea10753 177
spastor 0:1c358ea10753 178 value_decoded = connector_true;
spastor 0:1c358ea10753 179 reset_input_content(rci);
spastor 0:1c358ea10753 180
spastor 0:1c358ea10753 181 error:
spastor 0:1c358ea10753 182 return value_decoded;
spastor 0:1c358ea10753 183 }
spastor 0:1c358ea10753 184 #endif
spastor 0:1c358ea10753 185
spastor 0:1c358ea10753 186 static connector_bool_t get_string(rci_t * const rci, char const * * string, size_t * const length)
spastor 0:1c358ea10753 187 {
spastor 0:1c358ea10753 188 connector_bool_t got_string = connector_false;
spastor 0:1c358ea10753 189 uint32_t value;
spastor 0:1c358ea10753 190 size_t const ber_bytes = get_modifier_ber(rci, &value);
spastor 0:1c358ea10753 191
spastor 0:1c358ea10753 192 if (ber_bytes > 0)
spastor 0:1c358ea10753 193 {
spastor 0:1c358ea10753 194 size_t const bytes = rci->shared.content.length;
spastor 0:1c358ea10753 195 #if defined CONNECTOR_DEBUG
spastor 0:1c358ea10753 196 size_t const size_max = SIZE_MAX;
spastor 0:1c358ea10753 197
spastor 0:1c358ea10753 198 (void)size_max;
spastor 0:1c358ea10753 199 ASSERT(value <= size_max);
spastor 0:1c358ea10753 200 #endif
spastor 0:1c358ea10753 201 *length = value;
spastor 0:1c358ea10753 202 if (*length > CONNECTOR_RCI_MAXIMUM_CONTENT_LENGTH)
spastor 0:1c358ea10753 203 {
spastor 0:1c358ea10753 204 connector_debug_printf("Maximum content size exceeded while getting a string - wanted %u, had %u\n", *length, CONNECTOR_RCI_MAXIMUM_CONTENT_LENGTH);
spastor 0:1c358ea10753 205 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 206 goto done;
spastor 0:1c358ea10753 207 }
spastor 0:1c358ea10753 208
spastor 0:1c358ea10753 209 if (bytes == (ber_bytes + *length))
spastor 0:1c358ea10753 210 {
spastor 0:1c358ea10753 211 char * data = (char *)(rci->shared.content.data + ber_bytes);
spastor 0:1c358ea10753 212
spastor 0:1c358ea10753 213 if (!destination_in_storage(rci))
spastor 0:1c358ea10753 214 {
spastor 0:1c358ea10753 215 memcpy(rci->input.storage, data, *length);
spastor 0:1c358ea10753 216 data = (char *)rci->input.storage;
spastor 0:1c358ea10753 217 }
spastor 0:1c358ea10753 218
spastor 0:1c358ea10753 219 data[*length] = nul;
spastor 0:1c358ea10753 220 *string = data;
spastor 0:1c358ea10753 221
spastor 0:1c358ea10753 222 reset_input_content(rci);
spastor 0:1c358ea10753 223 got_string = connector_true;
spastor 0:1c358ea10753 224 }
spastor 0:1c358ea10753 225 }
spastor 0:1c358ea10753 226 done:
spastor 0:1c358ea10753 227 return got_string;
spastor 0:1c358ea10753 228 }
spastor 0:1c358ea10753 229
spastor 0:1c358ea10753 230 #if defined RCI_PARSER_USES_IPV4
spastor 0:1c358ea10753 231 static connector_bool_t get_ip_address(rci_t * const rci, uint32_t * const ip_addr, size_t const length)
spastor 0:1c358ea10753 232 {
spastor 0:1c358ea10753 233 connector_bool_t got_ip = connector_false;
spastor 0:1c358ea10753 234
spastor 0:1c358ea10753 235 uint8_t * rci_ber_u32 = rci->shared.content.data;
spastor 0:1c358ea10753 236 uint8_t const bytes_read = message_load_u8(rci_ber_u32, opcode);
spastor 0:1c358ea10753 237
spastor 0:1c358ea10753 238 UNUSED_PARAMETER(length);
spastor 0:1c358ea10753 239
spastor 0:1c358ea10753 240 rci->shared.content.length++;
spastor 0:1c358ea10753 241
spastor 0:1c358ea10753 242 if (rci->shared.content.length == (size_t)(bytes_read + 1))
spastor 0:1c358ea10753 243 {
spastor 0:1c358ea10753 244 /* Current, we only support ipv4. */
spastor 0:1c358ea10753 245 ASSERT(bytes_read == sizeof *ip_addr);
spastor 0:1c358ea10753 246 ASSERT(length == bytes_read);
spastor 0:1c358ea10753 247
spastor 0:1c358ea10753 248 *ip_addr = message_load_be32(rci_ber_u32, value);
spastor 0:1c358ea10753 249
spastor 0:1c358ea10753 250 got_ip = connector_true;
spastor 0:1c358ea10753 251 reset_input_content(rci);
spastor 0:1c358ea10753 252 }
spastor 0:1c358ea10753 253
spastor 0:1c358ea10753 254 return got_ip;
spastor 0:1c358ea10753 255 }
spastor 0:1c358ea10753 256 #endif
spastor 0:1c358ea10753 257
spastor 0:1c358ea10753 258 static connector_bool_t decode_attribute(rci_t * const rci, unsigned int * index)
spastor 0:1c358ea10753 259 {
spastor 0:1c358ea10753 260 #define BINARY_RCI_ATTRIBUTE_TYPE_MASK 0x60 /* attr type: [bit 6 and 5] */
spastor 0:1c358ea10753 261
spastor 0:1c358ea10753 262 #define BINARY_RCI_ATTRIBUTE_TYPE_NORMAL 0x00
spastor 0:1c358ea10753 263 #define BINARY_RCI_ATTRIBUTE_TYPE_INDEX 0x20
spastor 0:1c358ea10753 264 #define BINARY_RCI_ATTRIBUTE_TYPE_NAME 0x40
spastor 0:1c358ea10753 265
spastor 0:1c358ea10753 266 #define BINARY_RCI_ATTRIBUTE_INDEX_MASK 0x1F
spastor 0:1c358ea10753 267
spastor 0:1c358ea10753 268 connector_bool_t got_attribute = connector_false;
spastor 0:1c358ea10753 269 uint32_t attribute_value;
spastor 0:1c358ea10753 270
spastor 0:1c358ea10753 271 if (get_uint32(rci, &attribute_value))
spastor 0:1c358ea10753 272 {
spastor 0:1c358ea10753 273 unsigned int type = attribute_value & BINARY_RCI_ATTRIBUTE_TYPE_MASK;
spastor 0:1c358ea10753 274 switch (type)
spastor 0:1c358ea10753 275 {
spastor 0:1c358ea10753 276 case BINARY_RCI_ATTRIBUTE_TYPE_INDEX:
spastor 0:1c358ea10753 277 *index = attribute_value & BINARY_RCI_ATTRIBUTE_INDEX_MASK;
spastor 0:1c358ea10753 278 rci_debug_printf("decode_attribute: index = %d\n", *index);
spastor 0:1c358ea10753 279 got_attribute = connector_true;
spastor 0:1c358ea10753 280 break;
spastor 0:1c358ea10753 281 case BINARY_RCI_ATTRIBUTE_TYPE_NAME:
spastor 0:1c358ea10753 282 case BINARY_RCI_ATTRIBUTE_TYPE_NORMAL:
spastor 0:1c358ea10753 283 /* Tool doesn't support name and enum attribute */
spastor 0:1c358ea10753 284 connector_debug_printf("decode_attribute: unsupported attribute type\n");
spastor 0:1c358ea10753 285 rci->status = rci_status_internal_error;
spastor 0:1c358ea10753 286 ASSERT(connector_false);
spastor 0:1c358ea10753 287 break;
spastor 0:1c358ea10753 288 }
spastor 0:1c358ea10753 289 }
spastor 0:1c358ea10753 290
spastor 0:1c358ea10753 291 return got_attribute;
spastor 0:1c358ea10753 292 }
spastor 0:1c358ea10753 293
spastor 0:1c358ea10753 294 static connector_bool_t has_rci_atribute(unsigned int data)
spastor 0:1c358ea10753 295 {
spastor 0:1c358ea10753 296 return connector_bool((data & BINARY_RCI_ATTRIBUTE_BIT) == BINARY_RCI_ATTRIBUTE_BIT);
spastor 0:1c358ea10753 297 }
spastor 0:1c358ea10753 298
spastor 0:1c358ea10753 299 static connector_bool_t has_rci_error(rci_t * const rci, unsigned int data)
spastor 0:1c358ea10753 300 {
spastor 0:1c358ea10753 301
spastor 0:1c358ea10753 302 connector_bool_t const hasError = connector_bool((data & BINARY_RCI_ERROR_INDICATOR_BIT) == BINARY_RCI_ERROR_INDICATOR_BIT);
spastor 0:1c358ea10753 303
spastor 0:1c358ea10753 304 UNUSED_PARAMETER(rci);
spastor 0:1c358ea10753 305
spastor 0:1c358ea10753 306 if (hasError)
spastor 0:1c358ea10753 307 {
spastor 0:1c358ea10753 308 connector_debug_printf("has_rci_error: unexpected error set.\n");
spastor 0:1c358ea10753 309 }
spastor 0:1c358ea10753 310 return hasError;
spastor 0:1c358ea10753 311 }
spastor 0:1c358ea10753 312
spastor 0:1c358ea10753 313 static connector_bool_t has_rci_terminated(unsigned int data)
spastor 0:1c358ea10753 314 {
spastor 0:1c358ea10753 315 return connector_bool(data == BINARY_RCI_TERMINATOR);
spastor 0:1c358ea10753 316 }
spastor 0:1c358ea10753 317
spastor 0:1c358ea10753 318 static connector_bool_t has_rci_no_value(unsigned int data)
spastor 0:1c358ea10753 319 {
spastor 0:1c358ea10753 320 return connector_bool(data == BINARY_RCI_NO_VALUE);
spastor 0:1c358ea10753 321 }
spastor 0:1c358ea10753 322
spastor 0:1c358ea10753 323 static void process_rci_command(rci_t * const rci)
spastor 0:1c358ea10753 324 {
spastor 0:1c358ea10753 325 #define BINARY_RCI_COMMAND_MASK 0x3F
spastor 0:1c358ea10753 326
spastor 0:1c358ea10753 327 uint32_t command;
spastor 0:1c358ea10753 328
spastor 0:1c358ea10753 329 {
spastor 0:1c358ea10753 330 connector_remote_config_t const * const remote_config = &rci->shared.callback_data;
spastor 0:1c358ea10753 331
spastor 0:1c358ea10753 332 if (remote_config->error_id != connector_success)
spastor 0:1c358ea10753 333 {
spastor 0:1c358ea10753 334 set_rci_output_state(rci, rci_output_state_field_id);
spastor 0:1c358ea10753 335 state_call(rci, rci_parser_state_output);
spastor 0:1c358ea10753 336 goto done;
spastor 0:1c358ea10753 337 }
spastor 0:1c358ea10753 338 }
spastor 0:1c358ea10753 339
spastor 0:1c358ea10753 340 if (get_uint32(rci, &command))
spastor 0:1c358ea10753 341 {
spastor 0:1c358ea10753 342
spastor 0:1c358ea10753 343 connector_bool_t const has_attribute = has_rci_atribute(command);
spastor 0:1c358ea10753 344
spastor 0:1c358ea10753 345 ASSERT_GOTO(!has_rci_error(rci, command), done);
spastor 0:1c358ea10753 346
spastor 0:1c358ea10753 347 command &= BINARY_RCI_COMMAND_MASK;
spastor 0:1c358ea10753 348
spastor 0:1c358ea10753 349 switch (command)
spastor 0:1c358ea10753 350 {
spastor 0:1c358ea10753 351 case rci_command_set_setting:
spastor 0:1c358ea10753 352 case rci_command_query_setting:
spastor 0:1c358ea10753 353 rci->shared.callback_data.group.type = connector_remote_group_setting;
spastor 0:1c358ea10753 354 break;
spastor 0:1c358ea10753 355 case rci_command_set_state:
spastor 0:1c358ea10753 356 case rci_command_query_state:
spastor 0:1c358ea10753 357 rci->shared.callback_data.group.type = connector_remote_group_state;
spastor 0:1c358ea10753 358 break;
spastor 0:1c358ea10753 359 }
spastor 0:1c358ea10753 360
spastor 0:1c358ea10753 361 switch (command)
spastor 0:1c358ea10753 362 {
spastor 0:1c358ea10753 363 case rci_command_set_setting:
spastor 0:1c358ea10753 364 case rci_command_set_state:
spastor 0:1c358ea10753 365 rci->shared.callback_data.action = connector_remote_action_set;
spastor 0:1c358ea10753 366 break;
spastor 0:1c358ea10753 367 case rci_command_query_setting:
spastor 0:1c358ea10753 368 case rci_command_query_state:
spastor 0:1c358ea10753 369 rci->shared.callback_data.action = connector_remote_action_query;
spastor 0:1c358ea10753 370 break;
spastor 0:1c358ea10753 371 default:
spastor 0:1c358ea10753 372 /* unsupported command.
spastor 0:1c358ea10753 373 * Just go to error state for returning error message.
spastor 0:1c358ea10753 374 */
spastor 0:1c358ea10753 375 rci_global_error(rci, connector_rci_error_bad_command, RCI_NO_HINT);
spastor 0:1c358ea10753 376 set_rci_command_error(rci);
spastor 0:1c358ea10753 377 state_call(rci, rci_parser_state_error);
spastor 0:1c358ea10753 378 goto done;
spastor 0:1c358ea10753 379 }
spastor 0:1c358ea10753 380
spastor 0:1c358ea10753 381 if (has_attribute)
spastor 0:1c358ea10753 382 {
spastor 0:1c358ea10753 383 set_rci_input_state(rci, rci_input_state_command_attribute);
spastor 0:1c358ea10753 384 }
spastor 0:1c358ea10753 385 else
spastor 0:1c358ea10753 386 {
spastor 0:1c358ea10753 387 set_rci_input_state(rci, rci_input_state_group_id);
spastor 0:1c358ea10753 388
spastor 0:1c358ea10753 389 set_rci_traverse_state(rci, rci_traverse_state_command_id);
spastor 0:1c358ea10753 390 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 391 }
spastor 0:1c358ea10753 392
spastor 0:1c358ea10753 393 }
spastor 0:1c358ea10753 394 done:
spastor 0:1c358ea10753 395 return;
spastor 0:1c358ea10753 396 }
spastor 0:1c358ea10753 397
spastor 0:1c358ea10753 398 static void process_command_attribute(rci_t * const rci)
spastor 0:1c358ea10753 399 {
spastor 0:1c358ea10753 400 unsigned int index;
spastor 0:1c358ea10753 401
spastor 0:1c358ea10753 402 if (decode_attribute(rci, &index))
spastor 0:1c358ea10753 403 {
spastor 0:1c358ea10753 404 /* We don't support command attribute; so just ignore it. */
spastor 0:1c358ea10753 405 set_rci_input_state(rci, rci_input_state_group_id);
spastor 0:1c358ea10753 406
spastor 0:1c358ea10753 407 set_rci_traverse_state(rci, rci_traverse_state_command_id);
spastor 0:1c358ea10753 408 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 409 }
spastor 0:1c358ea10753 410
spastor 0:1c358ea10753 411 return;
spastor 0:1c358ea10753 412 }
spastor 0:1c358ea10753 413
spastor 0:1c358ea10753 414
spastor 0:1c358ea10753 415 static void process_group_id(rci_t * const rci)
spastor 0:1c358ea10753 416 {
spastor 0:1c358ea10753 417 uint32_t group_id;
spastor 0:1c358ea10753 418
spastor 0:1c358ea10753 419 if (!get_uint32(rci, &group_id))
spastor 0:1c358ea10753 420 {
spastor 0:1c358ea10753 421 goto done;
spastor 0:1c358ea10753 422 }
spastor 0:1c358ea10753 423
spastor 0:1c358ea10753 424 ASSERT_GOTO(!has_rci_error(rci, group_id), done);
spastor 0:1c358ea10753 425
spastor 0:1c358ea10753 426 if (has_rci_terminated(group_id))
spastor 0:1c358ea10753 427 {
spastor 0:1c358ea10753 428 if (have_group_id(rci))
spastor 0:1c358ea10753 429 {
spastor 0:1c358ea10753 430 /* not 1st group */
spastor 0:1c358ea10753 431 set_rci_input_state(rci, rci_input_state_command_id);
spastor 0:1c358ea10753 432
spastor 0:1c358ea10753 433 set_rci_traverse_state(rci, rci_traverse_state_group_end);
spastor 0:1c358ea10753 434 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 435 goto done;
spastor 0:1c358ea10753 436 }
spastor 0:1c358ea10753 437 else
spastor 0:1c358ea10753 438 {
spastor 0:1c358ea10753 439 /* Get all groups if no group has been requested before */
spastor 0:1c358ea10753 440 switch (rci->shared.callback_data.action)
spastor 0:1c358ea10753 441 {
spastor 0:1c358ea10753 442 case connector_remote_action_query:
spastor 0:1c358ea10753 443 set_rci_traverse_state(rci, rci_traverse_state_all_groups);
spastor 0:1c358ea10753 444 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 445 break;
spastor 0:1c358ea10753 446 case connector_remote_action_set:
spastor 0:1c358ea10753 447 connector_debug_printf("process_group_id: got set command with no group id specified\n");
spastor 0:1c358ea10753 448 rci_set_output_error(rci, connector_rci_error_bad_command, rci_set_empty_group_hint, rci_output_state_group_id);
spastor 0:1c358ea10753 449 break;
spastor 0:1c358ea10753 450 }
spastor 0:1c358ea10753 451 goto done;
spastor 0:1c358ea10753 452 }
spastor 0:1c358ea10753 453 }
spastor 0:1c358ea10753 454 else
spastor 0:1c358ea10753 455 {
spastor 0:1c358ea10753 456 set_group_id(rci, decode_group_id(group_id));
spastor 0:1c358ea10753 457
spastor 0:1c358ea10753 458 if (!have_group_id(rci))
spastor 0:1c358ea10753 459 {
spastor 0:1c358ea10753 460 connector_debug_printf("process_group_id: unrecognized group (mismatch of descriptors) group id = %d.\n", decode_group_id(group_id));
spastor 0:1c358ea10753 461 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_group_id);
spastor 0:1c358ea10753 462 ASSERT(connector_false);
spastor 0:1c358ea10753 463 goto done;
spastor 0:1c358ea10753 464 }
spastor 0:1c358ea10753 465
spastor 0:1c358ea10753 466 if (has_rci_atribute(group_id))
spastor 0:1c358ea10753 467 {
spastor 0:1c358ea10753 468 invalidate_group_index(rci);
spastor 0:1c358ea10753 469 set_rci_input_state(rci, rci_input_state_group_attribute);
spastor 0:1c358ea10753 470 goto done;
spastor 0:1c358ea10753 471 }
spastor 0:1c358ea10753 472
spastor 0:1c358ea10753 473 {
spastor 0:1c358ea10753 474 connector_group_t const * const group = get_current_group(rci);
spastor 0:1c358ea10753 475 if (group->instances > 1)
spastor 0:1c358ea10753 476 {
spastor 0:1c358ea10753 477 set_rci_input_flag(rci, RCI_FLAG_GET_ALL_INSTANCES);
spastor 0:1c358ea10753 478 }
spastor 0:1c358ea10753 479 }
spastor 0:1c358ea10753 480
spastor 0:1c358ea10753 481 set_rci_input_state(rci, rci_input_state_field_id);
spastor 0:1c358ea10753 482 }
spastor 0:1c358ea10753 483
spastor 0:1c358ea10753 484 set_group_index(rci, 1);
spastor 0:1c358ea10753 485 set_rci_traverse_state(rci, rci_traverse_state_group_id);
spastor 0:1c358ea10753 486 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 487 rci_debug_printf("process_group_id: group id = %d\n", get_group_id(rci));
spastor 0:1c358ea10753 488
spastor 0:1c358ea10753 489 done:
spastor 0:1c358ea10753 490 return;
spastor 0:1c358ea10753 491 }
spastor 0:1c358ea10753 492
spastor 0:1c358ea10753 493 static void process_group_attribute(rci_t * const rci)
spastor 0:1c358ea10753 494 {
spastor 0:1c358ea10753 495 if (decode_attribute(rci, &rci->shared.group.index))
spastor 0:1c358ea10753 496 {
spastor 0:1c358ea10753 497 set_rci_input_state(rci, rci_input_state_field_id);
spastor 0:1c358ea10753 498 set_rci_traverse_state(rci, rci_traverse_state_group_id);
spastor 0:1c358ea10753 499 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 500 }
spastor 0:1c358ea10753 501
spastor 0:1c358ea10753 502 return;
spastor 0:1c358ea10753 503 }
spastor 0:1c358ea10753 504
spastor 0:1c358ea10753 505 static void process_field_id(rci_t * const rci)
spastor 0:1c358ea10753 506 {
spastor 0:1c358ea10753 507 unsigned int id = INVALID_ID;
spastor 0:1c358ea10753 508 {
spastor 0:1c358ea10753 509 uint32_t value;
spastor 0:1c358ea10753 510
spastor 0:1c358ea10753 511 if (!get_uint32(rci, &value))
spastor 0:1c358ea10753 512 {
spastor 0:1c358ea10753 513 goto done;
spastor 0:1c358ea10753 514 }
spastor 0:1c358ea10753 515
spastor 0:1c358ea10753 516 /* Bit 6 - is Field type present indicator
spastor 0:1c358ea10753 517 * Bit 10 - is attributes present indicator
spastor 0:1c358ea10753 518 * Bit 12 - is Error indicator (Should not be set)
spastor 0:1c358ea10753 519 */
spastor 0:1c358ea10753 520 ASSERT_GOTO(!has_rci_error(rci, value), done);
spastor 0:1c358ea10753 521
spastor 0:1c358ea10753 522 if (has_rci_terminated(value))
spastor 0:1c358ea10753 523 {
spastor 0:1c358ea10753 524 if (!have_element_id(rci))
spastor 0:1c358ea10753 525 {
spastor 0:1c358ea10753 526 switch (rci->shared.callback_data.action)
spastor 0:1c358ea10753 527 {
spastor 0:1c358ea10753 528 case connector_remote_action_query:
spastor 0:1c358ea10753 529 /* all fields */
spastor 0:1c358ea10753 530 if (is_rci_input_flag(rci,RCI_FLAG_GET_ALL_INSTANCES))
spastor 0:1c358ea10753 531 set_rci_traverse_state(rci, rci_traverse_state_all_group_instances);
spastor 0:1c358ea10753 532 else
spastor 0:1c358ea10753 533 set_rci_traverse_state(rci, rci_traverse_state_all_elements);
spastor 0:1c358ea10753 534
spastor 0:1c358ea10753 535 set_rci_input_state(rci, rci_input_state_group_id);
spastor 0:1c358ea10753 536
spastor 0:1c358ea10753 537 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 538 break;
spastor 0:1c358ea10753 539 case connector_remote_action_set:
spastor 0:1c358ea10753 540 connector_debug_printf("process_field_id: got set command with no field id specified\n");
spastor 0:1c358ea10753 541 rci_set_output_error(rci, connector_rci_error_bad_command, rci_set_empty_element_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 542 break;
spastor 0:1c358ea10753 543 }
spastor 0:1c358ea10753 544 }
spastor 0:1c358ea10753 545 else
spastor 0:1c358ea10753 546 {
spastor 0:1c358ea10753 547 /* done with all fields */
spastor 0:1c358ea10753 548 invalidate_element_id(rci);
spastor 0:1c358ea10753 549 set_rci_input_state(rci, rci_input_state_group_id);
spastor 0:1c358ea10753 550
spastor 0:1c358ea10753 551 set_rci_traverse_state(rci, rci_traverse_state_element_end);
spastor 0:1c358ea10753 552 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 553 }
spastor 0:1c358ea10753 554 goto done;
spastor 0:1c358ea10753 555 }
spastor 0:1c358ea10753 556
spastor 0:1c358ea10753 557 if ((value & BINARY_RCI_FIELD_TYPE_INDICATOR_BIT) == BINARY_RCI_FIELD_TYPE_INDICATOR_BIT)
spastor 0:1c358ea10753 558 {
spastor 0:1c358ea10753 559 set_rci_input_state(rci, rci_input_state_field_type);
spastor 0:1c358ea10753 560 }
spastor 0:1c358ea10753 561 else
spastor 0:1c358ea10753 562 {
spastor 0:1c358ea10753 563 set_rci_input_state(rci, rci_input_state_field_no_value);
spastor 0:1c358ea10753 564 }
spastor 0:1c358ea10753 565
spastor 0:1c358ea10753 566
spastor 0:1c358ea10753 567 if ((value & BINARY_RCI_FIELD_ATTRIBUTE_BIT) == BINARY_RCI_FIELD_ATTRIBUTE_BIT)
spastor 0:1c358ea10753 568 {
spastor 0:1c358ea10753 569 connector_debug_printf("process_field_id: field attribute is not supported\n");
spastor 0:1c358ea10753 570 rci_set_output_error(rci, connector_rci_error_bad_descriptor, RCI_NO_HINT, rci_output_state_field_id);
spastor 0:1c358ea10753 571 goto done;
spastor 0:1c358ea10753 572 }
spastor 0:1c358ea10753 573
spastor 0:1c358ea10753 574 id = decode_element_id(value);
spastor 0:1c358ea10753 575
spastor 0:1c358ea10753 576 }
spastor 0:1c358ea10753 577
spastor 0:1c358ea10753 578
spastor 0:1c358ea10753 579 set_element_id(rci, id);
spastor 0:1c358ea10753 580
spastor 0:1c358ea10753 581 if (!have_element_id(rci))
spastor 0:1c358ea10753 582 {
spastor 0:1c358ea10753 583 connector_debug_printf("process_field_id: unrecognized field id (mismatch of descriptors). element id = %d\n", id);
spastor 0:1c358ea10753 584 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 585 }
spastor 0:1c358ea10753 586
spastor 0:1c358ea10753 587 done:
spastor 0:1c358ea10753 588 return;
spastor 0:1c358ea10753 589 }
spastor 0:1c358ea10753 590
spastor 0:1c358ea10753 591 static void process_field_type(rci_t * const rci)
spastor 0:1c358ea10753 592 {
spastor 0:1c358ea10753 593 connector_group_element_t const * const element = get_current_element(rci);
spastor 0:1c358ea10753 594 connector_bool_t error = connector_false;
spastor 0:1c358ea10753 595 uint32_t type;
spastor 0:1c358ea10753 596
spastor 0:1c358ea10753 597 if (get_uint32(rci, &type))
spastor 0:1c358ea10753 598 {
spastor 0:1c358ea10753 599 ASSERT_GOTO(!has_rci_error(rci, type), done);
spastor 0:1c358ea10753 600
spastor 0:1c358ea10753 601 switch (type)
spastor 0:1c358ea10753 602 {
spastor 0:1c358ea10753 603 case rci_field_type_none:
spastor 0:1c358ea10753 604 break;
spastor 0:1c358ea10753 605
spastor 0:1c358ea10753 606 default:
spastor 0:1c358ea10753 607 if (element->type != type)
spastor 0:1c358ea10753 608 {
spastor 0:1c358ea10753 609 connector_debug_printf("process_field_type: mismatch field type (type %d) != (actual %d)\n", type, element->type);
spastor 0:1c358ea10753 610 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 611 error = connector_true;
spastor 0:1c358ea10753 612 }
spastor 0:1c358ea10753 613 break;
spastor 0:1c358ea10753 614 }
spastor 0:1c358ea10753 615 }
spastor 0:1c358ea10753 616
spastor 0:1c358ea10753 617 if (!error)
spastor 0:1c358ea10753 618 {
spastor 0:1c358ea10753 619 set_rci_input_state(rci, rci_input_state_field_no_value);
spastor 0:1c358ea10753 620 }
spastor 0:1c358ea10753 621
spastor 0:1c358ea10753 622 done:
spastor 0:1c358ea10753 623 return;
spastor 0:1c358ea10753 624 }
spastor 0:1c358ea10753 625
spastor 0:1c358ea10753 626 static void process_field_value(rci_t * const rci)
spastor 0:1c358ea10753 627 {
spastor 0:1c358ea10753 628 connector_group_element_t const * const element = get_current_element(rci);
spastor 0:1c358ea10753 629 connector_element_value_type_t const type = element->type;
spastor 0:1c358ea10753 630
spastor 0:1c358ea10753 631 #if (defined RCI_PARSER_USES_ON_OFF) || (defined RCI_PARSER_USES_BOOLEAN)
spastor 0:1c358ea10753 632 connector_bool_t error = connector_false;
spastor 0:1c358ea10753 633 #endif
spastor 0:1c358ea10753 634
spastor 0:1c358ea10753 635 switch (type)
spastor 0:1c358ea10753 636 {
spastor 0:1c358ea10753 637 #if defined RCI_PARSER_USES_STRINGS
spastor 0:1c358ea10753 638
spastor 0:1c358ea10753 639 #if defined RCI_PARSER_USES_STRING
spastor 0:1c358ea10753 640 case connector_element_type_string:
spastor 0:1c358ea10753 641 #endif
spastor 0:1c358ea10753 642
spastor 0:1c358ea10753 643 #if defined RCI_PARSER_USES_MULTILINE_STRING
spastor 0:1c358ea10753 644 case connector_element_type_multiline_string:
spastor 0:1c358ea10753 645 #endif
spastor 0:1c358ea10753 646
spastor 0:1c358ea10753 647 #if defined RCI_PARSER_USES_PASSWORD
spastor 0:1c358ea10753 648 case connector_element_type_password:
spastor 0:1c358ea10753 649 #endif
spastor 0:1c358ea10753 650
spastor 0:1c358ea10753 651
spastor 0:1c358ea10753 652 #if defined RCI_PARSER_USES_FQDNV4
spastor 0:1c358ea10753 653 case connector_element_type_fqdnv4:
spastor 0:1c358ea10753 654 #endif
spastor 0:1c358ea10753 655
spastor 0:1c358ea10753 656 #if defined RCI_PARSER_USES_FQDNV6
spastor 0:1c358ea10753 657 case connector_element_type_fqdnv6:
spastor 0:1c358ea10753 658 #endif
spastor 0:1c358ea10753 659
spastor 0:1c358ea10753 660 #if defined RCI_PARSER_USES_DATETIME
spastor 0:1c358ea10753 661 case connector_element_type_datetime:
spastor 0:1c358ea10753 662 #endif
spastor 0:1c358ea10753 663 if (!get_string(rci, &rci->shared.value.string_value, &rci->shared.string_value_length))
spastor 0:1c358ea10753 664 {
spastor 0:1c358ea10753 665 goto done;
spastor 0:1c358ea10753 666 }
spastor 0:1c358ea10753 667 break;
spastor 0:1c358ea10753 668 #endif
spastor 0:1c358ea10753 669
spastor 0:1c358ea10753 670
spastor 0:1c358ea10753 671 #if defined RCI_PARSER_USES_INT32
spastor 0:1c358ea10753 672 case connector_element_type_int32:
spastor 0:1c358ea10753 673 {
spastor 0:1c358ea10753 674 int32_t value;
spastor 0:1c358ea10753 675
spastor 0:1c358ea10753 676 if (!get_uint32(rci, (uint32_t *)&value))
spastor 0:1c358ea10753 677 {
spastor 0:1c358ea10753 678 goto done;
spastor 0:1c358ea10753 679 }
spastor 0:1c358ea10753 680 rci->shared.value.signed_integer_value = value;
spastor 0:1c358ea10753 681 break;
spastor 0:1c358ea10753 682 }
spastor 0:1c358ea10753 683 #endif
spastor 0:1c358ea10753 684
spastor 0:1c358ea10753 685 #if defined RCI_PARSER_USES_IPV4
spastor 0:1c358ea10753 686 case connector_element_type_ipv4:
spastor 0:1c358ea10753 687 {
spastor 0:1c358ea10753 688 uint32_t ip_addr;
spastor 0:1c358ea10753 689
spastor 0:1c358ea10753 690 if (!get_ip_address(rci, &ip_addr, sizeof ip_addr))
spastor 0:1c358ea10753 691 {
spastor 0:1c358ea10753 692 goto done;
spastor 0:1c358ea10753 693 }
spastor 0:1c358ea10753 694
spastor 0:1c358ea10753 695 {
spastor 0:1c358ea10753 696 #define MAX_IPV4_VALUE "255.255.255.255"
spastor 0:1c358ea10753 697
spastor 0:1c358ea10753 698 char * const data = (char *)rci->input.storage;
spastor 0:1c358ea10753 699 size_t const size_avail = sizeof MAX_IPV4_VALUE;
spastor 0:1c358ea10753 700 int size_written;
spastor 0:1c358ea10753 701
spastor 0:1c358ea10753 702 uint8_t ip1 = BYTE32_3(ip_addr);
spastor 0:1c358ea10753 703 uint8_t ip2 = BYTE32_2(ip_addr);
spastor 0:1c358ea10753 704 uint8_t ip3 = BYTE32_1(ip_addr);
spastor 0:1c358ea10753 705 uint8_t ip4 = BYTE32_0(ip_addr);
spastor 0:1c358ea10753 706
spastor 0:1c358ea10753 707 ASSERT(size_avail <= sizeof rci->input.storage);
spastor 0:1c358ea10753 708
spastor 0:1c358ea10753 709 size_written = connector_snprintf(data, size_avail, "%d.%d.%d.%d", ip1, ip2, ip3, ip4);
spastor 0:1c358ea10753 710
spastor 0:1c358ea10753 711 ASSERT(size_written < (int)size_avail);
spastor 0:1c358ea10753 712 ASSERT_GOTO(size_written > 0, done);
spastor 0:1c358ea10753 713
spastor 0:1c358ea10753 714 rci->shared.value.string_value = data;
spastor 0:1c358ea10753 715
spastor 0:1c358ea10753 716 #undef MAX_IPV4_VALUE
spastor 0:1c358ea10753 717 }
spastor 0:1c358ea10753 718 break;
spastor 0:1c358ea10753 719 }
spastor 0:1c358ea10753 720 #endif
spastor 0:1c358ea10753 721
spastor 0:1c358ea10753 722 #if (defined RCI_PARSER_USES_UNSIGNED_INTEGER)
spastor 0:1c358ea10753 723
spastor 0:1c358ea10753 724
spastor 0:1c358ea10753 725 #if defined RCI_PARSER_USES_UINT32
spastor 0:1c358ea10753 726 case connector_element_type_uint32:
spastor 0:1c358ea10753 727 #endif
spastor 0:1c358ea10753 728
spastor 0:1c358ea10753 729 #if defined RCI_PARSER_USES_HEX32
spastor 0:1c358ea10753 730 case connector_element_type_hex32:
spastor 0:1c358ea10753 731 #endif
spastor 0:1c358ea10753 732
spastor 0:1c358ea10753 733 #if defined RCI_PARSER_USES_0X_HEX32
spastor 0:1c358ea10753 734 case connector_element_type_0x_hex32:
spastor 0:1c358ea10753 735 #endif
spastor 0:1c358ea10753 736 {
spastor 0:1c358ea10753 737 uint32_t value;
spastor 0:1c358ea10753 738
spastor 0:1c358ea10753 739 if (!get_uint32(rci, &value))
spastor 0:1c358ea10753 740 {
spastor 0:1c358ea10753 741 goto done;
spastor 0:1c358ea10753 742 }
spastor 0:1c358ea10753 743 rci->shared.value.unsigned_integer_value = value;
spastor 0:1c358ea10753 744 break;
spastor 0:1c358ea10753 745 }
spastor 0:1c358ea10753 746 #endif
spastor 0:1c358ea10753 747
spastor 0:1c358ea10753 748 #if defined RCI_PARSER_USES_FLOAT
spastor 0:1c358ea10753 749 case connector_element_type_float:
spastor 0:1c358ea10753 750 {
spastor 0:1c358ea10753 751 if (!get_float(rci, &rci->shared.value.float_value))
spastor 0:1c358ea10753 752 {
spastor 0:1c358ea10753 753 goto done;
spastor 0:1c358ea10753 754 }
spastor 0:1c358ea10753 755 break;
spastor 0:1c358ea10753 756 }
spastor 0:1c358ea10753 757 #endif
spastor 0:1c358ea10753 758
spastor 0:1c358ea10753 759 #if defined RCI_PARSER_USES_ENUM
spastor 0:1c358ea10753 760 case connector_element_type_enum:
spastor 0:1c358ea10753 761 {
spastor 0:1c358ea10753 762 uint32_t value;
spastor 0:1c358ea10753 763 if (!get_uint32(rci, &value))
spastor 0:1c358ea10753 764 {
spastor 0:1c358ea10753 765 goto done;
spastor 0:1c358ea10753 766 }
spastor 0:1c358ea10753 767 rci->shared.value.enum_value = value;
spastor 0:1c358ea10753 768 break;
spastor 0:1c358ea10753 769 }
spastor 0:1c358ea10753 770 #endif
spastor 0:1c358ea10753 771
spastor 0:1c358ea10753 772 #if defined RCI_PARSER_USES_ON_OFF
spastor 0:1c358ea10753 773 case connector_element_type_on_off:
spastor 0:1c358ea10753 774 {
spastor 0:1c358ea10753 775 uint32_t value;
spastor 0:1c358ea10753 776
spastor 0:1c358ea10753 777 if (!get_uint32(rci, &value))
spastor 0:1c358ea10753 778 {
spastor 0:1c358ea10753 779 goto done;
spastor 0:1c358ea10753 780 }
spastor 0:1c358ea10753 781 rci->shared.value.on_off_value = (value == 0)? connector_off : connector_on;
spastor 0:1c358ea10753 782 error = connector_bool((value != 0) && (value != 1));
spastor 0:1c358ea10753 783 break;
spastor 0:1c358ea10753 784 }
spastor 0:1c358ea10753 785 #endif
spastor 0:1c358ea10753 786
spastor 0:1c358ea10753 787 #if defined RCI_PARSER_USES_BOOLEAN
spastor 0:1c358ea10753 788 case connector_element_type_boolean:
spastor 0:1c358ea10753 789 {
spastor 0:1c358ea10753 790 uint32_t value;
spastor 0:1c358ea10753 791 if (!get_uint32(rci, &value))
spastor 0:1c358ea10753 792 {
spastor 0:1c358ea10753 793 goto done;
spastor 0:1c358ea10753 794 }
spastor 0:1c358ea10753 795 rci->shared.value.boolean_value = (value == 0)? connector_false : connector_true;
spastor 0:1c358ea10753 796 error = connector_bool((value != 0) && (value != 1));
spastor 0:1c358ea10753 797 break;
spastor 0:1c358ea10753 798 }
spastor 0:1c358ea10753 799 #endif
spastor 0:1c358ea10753 800 }
spastor 0:1c358ea10753 801
spastor 0:1c358ea10753 802 #if (defined RCI_PARSER_USES_ON_OFF) || (defined RCI_PARSER_USES_BOOLEAN)
spastor 0:1c358ea10753 803 if (error)
spastor 0:1c358ea10753 804 {
spastor 0:1c358ea10753 805 connector_debug_printf("process_field_value: range check error! Descriptor problem!");
spastor 0:1c358ea10753 806 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 807 }
spastor 0:1c358ea10753 808 else
spastor 0:1c358ea10753 809 #endif
spastor 0:1c358ea10753 810 {
spastor 0:1c358ea10753 811 set_rci_traverse_state(rci, rci_traverse_state_element_id);
spastor 0:1c358ea10753 812 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 813 }
spastor 0:1c358ea10753 814 set_rci_input_state(rci, rci_input_state_field_id);
spastor 0:1c358ea10753 815
spastor 0:1c358ea10753 816 done:
spastor 0:1c358ea10753 817 return;
spastor 0:1c358ea10753 818 }
spastor 0:1c358ea10753 819
spastor 0:1c358ea10753 820 static void process_field_no_value(rci_t * const rci)
spastor 0:1c358ea10753 821 {
spastor 0:1c358ea10753 822 uint8_t * const rci_ber = rci->shared.content.data;
spastor 0:1c358ea10753 823 uint8_t const modifier_ber = message_load_u8(rci_ber, value);
spastor 0:1c358ea10753 824
spastor 0:1c358ea10753 825 if (has_rci_no_value(modifier_ber))
spastor 0:1c358ea10753 826 {
spastor 0:1c358ea10753 827 /* this initializes element.value in case for set setting */
spastor 0:1c358ea10753 828 connector_group_element_t const * const element = get_current_element(rci);
spastor 0:1c358ea10753 829 connector_element_value_type_t const type = element->type;
spastor 0:1c358ea10753 830
spastor 0:1c358ea10753 831 switch (type)
spastor 0:1c358ea10753 832 {
spastor 0:1c358ea10753 833 #if defined RCI_PARSER_USES_STRINGS
spastor 0:1c358ea10753 834
spastor 0:1c358ea10753 835 #if defined RCI_PARSER_USES_STRING
spastor 0:1c358ea10753 836 case connector_element_type_string:
spastor 0:1c358ea10753 837 #endif
spastor 0:1c358ea10753 838
spastor 0:1c358ea10753 839 #if defined RCI_PARSER_USES_MULTILINE_STRING
spastor 0:1c358ea10753 840 case connector_element_type_multiline_string:
spastor 0:1c358ea10753 841 #endif
spastor 0:1c358ea10753 842
spastor 0:1c358ea10753 843 #if defined RCI_PARSER_USES_PASSWORD
spastor 0:1c358ea10753 844 case connector_element_type_password:
spastor 0:1c358ea10753 845 #endif
spastor 0:1c358ea10753 846
spastor 0:1c358ea10753 847
spastor 0:1c358ea10753 848 #if defined RCI_PARSER_USES_FQDNV4
spastor 0:1c358ea10753 849 case connector_element_type_fqdnv4:
spastor 0:1c358ea10753 850 #endif
spastor 0:1c358ea10753 851
spastor 0:1c358ea10753 852 #if defined RCI_PARSER_USES_FQDNV6
spastor 0:1c358ea10753 853 case connector_element_type_fqdnv6:
spastor 0:1c358ea10753 854 #endif
spastor 0:1c358ea10753 855
spastor 0:1c358ea10753 856 #if defined RCI_PARSER_USES_DATETIME
spastor 0:1c358ea10753 857 case connector_element_type_datetime:
spastor 0:1c358ea10753 858 #endif
spastor 0:1c358ea10753 859
spastor 0:1c358ea10753 860 #if defined RCI_PARSER_USES_IPV4
spastor 0:1c358ea10753 861 case connector_element_type_ipv4:
spastor 0:1c358ea10753 862 #endif
spastor 0:1c358ea10753 863 rci->shared.value.string_value = (char *)rci->input.storage;
spastor 0:1c358ea10753 864 rci->input.storage[0] = (uint8_t)nul;
spastor 0:1c358ea10753 865 break;
spastor 0:1c358ea10753 866 #endif
spastor 0:1c358ea10753 867
spastor 0:1c358ea10753 868 #if defined RCI_PARSER_USES_INT32
spastor 0:1c358ea10753 869 case connector_element_type_int32:
spastor 0:1c358ea10753 870 rci->shared.value.signed_integer_value = 0;
spastor 0:1c358ea10753 871 break;
spastor 0:1c358ea10753 872 #endif
spastor 0:1c358ea10753 873
spastor 0:1c358ea10753 874 #if (defined RCI_PARSER_USES_UNSIGNED_INTEGER)
spastor 0:1c358ea10753 875
spastor 0:1c358ea10753 876
spastor 0:1c358ea10753 877 #if defined RCI_PARSER_USES_UINT32
spastor 0:1c358ea10753 878 case connector_element_type_uint32:
spastor 0:1c358ea10753 879 #endif
spastor 0:1c358ea10753 880
spastor 0:1c358ea10753 881 #if defined RCI_PARSER_USES_HEX32
spastor 0:1c358ea10753 882 case connector_element_type_hex32:
spastor 0:1c358ea10753 883 #endif
spastor 0:1c358ea10753 884
spastor 0:1c358ea10753 885 #if defined RCI_PARSER_USES_0X_HEX32
spastor 0:1c358ea10753 886 case connector_element_type_0x_hex32:
spastor 0:1c358ea10753 887 #endif
spastor 0:1c358ea10753 888 rci->shared.value.unsigned_integer_value = 0;
spastor 0:1c358ea10753 889 break;
spastor 0:1c358ea10753 890 #endif
spastor 0:1c358ea10753 891
spastor 0:1c358ea10753 892 #if defined RCI_PARSER_USES_FLOAT
spastor 0:1c358ea10753 893 case connector_element_type_float:
spastor 0:1c358ea10753 894 rci->shared.value.float_value = 0;
spastor 0:1c358ea10753 895 break;
spastor 0:1c358ea10753 896 #endif
spastor 0:1c358ea10753 897
spastor 0:1c358ea10753 898 #if defined RCI_PARSER_USES_ENUM
spastor 0:1c358ea10753 899 case connector_element_type_enum:
spastor 0:1c358ea10753 900 rci->shared.value.enum_value = 0;
spastor 0:1c358ea10753 901 break;
spastor 0:1c358ea10753 902 #endif
spastor 0:1c358ea10753 903
spastor 0:1c358ea10753 904 #if defined RCI_PARSER_USES_ON_OFF
spastor 0:1c358ea10753 905 case connector_element_type_on_off:
spastor 0:1c358ea10753 906 rci->shared.value.on_off_value = connector_off;
spastor 0:1c358ea10753 907 break;
spastor 0:1c358ea10753 908 #endif
spastor 0:1c358ea10753 909
spastor 0:1c358ea10753 910 #if defined RCI_PARSER_USES_BOOLEAN
spastor 0:1c358ea10753 911 case connector_element_type_boolean:
spastor 0:1c358ea10753 912 rci->shared.value.boolean_value = connector_false;
spastor 0:1c358ea10753 913 break;
spastor 0:1c358ea10753 914 #endif
spastor 0:1c358ea10753 915 }
spastor 0:1c358ea10753 916
spastor 0:1c358ea10753 917 reset_input_content(rci);
spastor 0:1c358ea10753 918 set_rci_traverse_state(rci, rci_traverse_state_element_id);
spastor 0:1c358ea10753 919 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 920 set_rci_input_state(rci, rci_input_state_field_id);
spastor 0:1c358ea10753 921 }
spastor 0:1c358ea10753 922 else
spastor 0:1c358ea10753 923 {
spastor 0:1c358ea10753 924 set_rci_input_state(rci, rci_input_state_field_value);
spastor 0:1c358ea10753 925 process_field_value(rci);
spastor 0:1c358ea10753 926 }
spastor 0:1c358ea10753 927
spastor 0:1c358ea10753 928 }
spastor 0:1c358ea10753 929
spastor 0:1c358ea10753 930 static void rci_parse_input(rci_t * const rci)
spastor 0:1c358ea10753 931 {
spastor 0:1c358ea10753 932 rci_buffer_t * const input = &rci->buffer.input;
spastor 0:1c358ea10753 933
spastor 0:1c358ea10753 934 while ((rci->parser.state == rci_parser_state_input) && (rci_buffer_remaining(input) != 0))
spastor 0:1c358ea10753 935 {
spastor 0:1c358ea10753 936
spastor 0:1c358ea10753 937 if (rci->input.destination != rci_buffer_position(&rci->buffer.input))
spastor 0:1c358ea10753 938 {
spastor 0:1c358ea10753 939 *(rci->input.destination) = rci_buffer_read(input);
spastor 0:1c358ea10753 940 }
spastor 0:1c358ea10753 941 rci->input.destination++;
spastor 0:1c358ea10753 942
spastor 0:1c358ea10753 943 rci_debug_printf("input: %s\n", rci_input_state_t_as_string(rci->input.state));
spastor 0:1c358ea10753 944
spastor 0:1c358ea10753 945 switch (rci->input.state)
spastor 0:1c358ea10753 946 {
spastor 0:1c358ea10753 947 case rci_input_state_command_id:
spastor 0:1c358ea10753 948 process_rci_command(rci);
spastor 0:1c358ea10753 949 break;
spastor 0:1c358ea10753 950 case rci_input_state_command_attribute:
spastor 0:1c358ea10753 951 process_command_attribute(rci);
spastor 0:1c358ea10753 952 break;
spastor 0:1c358ea10753 953 case rci_input_state_group_id:
spastor 0:1c358ea10753 954 process_group_id(rci);
spastor 0:1c358ea10753 955 break;
spastor 0:1c358ea10753 956 case rci_input_state_group_attribute:
spastor 0:1c358ea10753 957 process_group_attribute(rci);
spastor 0:1c358ea10753 958 break;
spastor 0:1c358ea10753 959 case rci_input_state_field_id:
spastor 0:1c358ea10753 960 process_field_id(rci);
spastor 0:1c358ea10753 961 break;
spastor 0:1c358ea10753 962 case rci_input_state_field_type:
spastor 0:1c358ea10753 963 process_field_type(rci);
spastor 0:1c358ea10753 964 break;
spastor 0:1c358ea10753 965 case rci_input_state_field_no_value:
spastor 0:1c358ea10753 966 process_field_no_value(rci);
spastor 0:1c358ea10753 967 break;
spastor 0:1c358ea10753 968 case rci_input_state_field_value:
spastor 0:1c358ea10753 969 process_field_value(rci);
spastor 0:1c358ea10753 970 break;
spastor 0:1c358ea10753 971 case rci_input_state_done:
spastor 0:1c358ea10753 972 break;
spastor 0:1c358ea10753 973 }
spastor 0:1c358ea10753 974
spastor 0:1c358ea10753 975 {
spastor 0:1c358ea10753 976 size_t const storage_bytes = sizeof rci->input.storage;
spastor 0:1c358ea10753 977 uint8_t const * const storage_end = rci->input.storage + storage_bytes;
spastor 0:1c358ea10753 978
spastor 0:1c358ea10753 979 if (rci->input.destination == storage_end)
spastor 0:1c358ea10753 980 {
spastor 0:1c358ea10753 981 connector_debug_printf("Maximum content size exceeded while parsing - wanted %u, had %u\n", storage_bytes + 1, storage_bytes);
spastor 0:1c358ea10753 982 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 983 goto done;
spastor 0:1c358ea10753 984 }
spastor 0:1c358ea10753 985 }
spastor 0:1c358ea10753 986
spastor 0:1c358ea10753 987 rci_buffer_advance(input, 1);
spastor 0:1c358ea10753 988 }
spastor 0:1c358ea10753 989
spastor 0:1c358ea10753 990 if (rci_buffer_remaining(input) == 0)
spastor 0:1c358ea10753 991 {
spastor 0:1c358ea10753 992 if (MsgIsLastData(rci->service_data->input.flags))
spastor 0:1c358ea10753 993 {
spastor 0:1c358ea10753 994 set_rci_input_state(rci, rci_input_state_done);
spastor 0:1c358ea10753 995 state_call(rci, rci_parser_state_traverse);
spastor 0:1c358ea10753 996 }
spastor 0:1c358ea10753 997 else
spastor 0:1c358ea10753 998 {
spastor 0:1c358ea10753 999 uint8_t const * const old_base = rcistr_data(&rci->shared.content);
spastor 0:1c358ea10753 1000 uint8_t * const new_base = destination_in_storage(rci) ? rci->input.destination : rci->input.storage;
spastor 0:1c358ea10753 1001
spastor 0:1c358ea10753 1002 if (ptr_in_buffer(old_base, &rci->buffer.input))
spastor 0:1c358ea10753 1003 {
spastor 0:1c358ea10753 1004 size_t const storage_bytes = sizeof rci->input.storage;
spastor 0:1c358ea10753 1005 uint8_t const * const storage_end = rci->input.storage + storage_bytes;
spastor 0:1c358ea10753 1006 size_t const bytes_wanted = (size_t)(rci->buffer.input.end - old_base);
spastor 0:1c358ea10753 1007 size_t const bytes_have = (size_t)(storage_end - new_base);
spastor 0:1c358ea10753 1008
spastor 0:1c358ea10753 1009 if (bytes_wanted >= bytes_have)
spastor 0:1c358ea10753 1010 {
spastor 0:1c358ea10753 1011 connector_debug_printf("Maximum content size exceeded while storing - wanted %u, had %u\n", bytes_wanted, bytes_have);
spastor 0:1c358ea10753 1012 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id);
spastor 0:1c358ea10753 1013 goto done;
spastor 0:1c358ea10753 1014 }
spastor 0:1c358ea10753 1015
spastor 0:1c358ea10753 1016 memcpy(new_base, old_base, bytes_wanted);
spastor 0:1c358ea10753 1017
spastor 0:1c358ea10753 1018 adjust_rcistr(new_base, old_base, &rci->shared.content);
spastor 0:1c358ea10753 1019 rci->input.destination = new_base + bytes_wanted;
spastor 0:1c358ea10753 1020 }
spastor 0:1c358ea10753 1021
spastor 0:1c358ea10753 1022 rci->status = rci_status_more_input;
spastor 0:1c358ea10753 1023 }
spastor 0:1c358ea10753 1024 }
spastor 0:1c358ea10753 1025
spastor 0:1c358ea10753 1026 done:
spastor 0:1c358ea10753 1027 return;
spastor 0:1c358ea10753 1028 }
spastor 0:1c358ea10753 1029
spastor 0:1c358ea10753 1030