Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
rci_binary_input.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 00014 #if defined RCI_PARSER_USES_ERROR_DESCRIPTIONS 00015 static char const rci_set_empty_group_hint[] = "Empty group"; 00016 static char const rci_set_empty_element_hint[] = "empty element"; 00017 static char const rci_error_descriptor_mismatch_hint[] = "Mismatch configurations"; 00018 static char const rci_error_content_size_hint[] = "Maximum content size exceeded"; 00019 #else 00020 #define rci_set_empty_group_hint RCI_NO_HINT 00021 #define rci_set_empty_element_hint RCI_NO_HINT 00022 #define rci_error_descriptor_mismatch_hint RCI_NO_HINT 00023 #define rci_error_content_size_hint RCI_NO_HINT 00024 #endif 00025 00026 static connector_bool_t destination_in_storage(rci_t const * const rci) 00027 { 00028 uint8_t const * const storage_begin = rci->input.storage; 00029 uint8_t const * const storage_end = storage_begin + sizeof rci->input.storage; 00030 00031 return ptr_in_range(rci->input.destination, storage_begin, storage_end); 00032 } 00033 00034 static size_t get_bytes_to_follow(uint8_t opcode) 00035 { 00036 size_t bytes_to_read = 0; 00037 00038 if (opcode & BINARY_RCI_SIZE_ALTERNATE_FLAG) 00039 { 00040 rci_size_modifier_t size_mask = BINARY_RCI_SIZE_MODIFIER(opcode); 00041 switch (size_mask) 00042 { 00043 case binary_rci_one_follow_byte: 00044 bytes_to_read = 1; 00045 break; 00046 case binary_rci_multi_follow_byte: 00047 switch (BINARY_RCI_MULTI_FOLLOW_BYTES(opcode)) 00048 { 00049 case binary_rci_two_follow_byte: 00050 bytes_to_read = 2; 00051 break; 00052 case binary_rci_four_follow_byte: 00053 bytes_to_read = 4; 00054 break; 00055 case binary_rci_eight_follow_byte: 00056 bytes_to_read = 8; 00057 break; 00058 } 00059 break; 00060 case binary_rci_special_value: 00061 bytes_to_read = 0; 00062 break; 00063 default: 00064 ASSERT(connector_false); 00065 } 00066 } 00067 return bytes_to_read; 00068 } 00069 00070 static void reset_input_content(rci_t * const rci) 00071 { 00072 rci->shared.content.data = rci->input.destination; 00073 rci->shared.content.length = 0; 00074 } 00075 00076 #define BINARY_RCI_ONE_BYTE_LIMIT_MASK UINT32_C(0x7F) 00077 #define BINARY_RCI_HI_BYTE_MASK UINT32_C(0x1F) 00078 00079 static size_t get_modifier_ber(rci_t * const rci, uint32_t * const value) 00080 { 00081 00082 uint8_t * const rci_ber = rci->shared.content.data; 00083 uint8_t const modifier_ber = message_load_u8(rci_ber, value); 00084 00085 size_t bytes_read = ++rci->shared.content.length; 00086 00087 { 00088 /* we have modifier BEF */ 00089 size_t const bytes_to_follow = get_bytes_to_follow(modifier_ber) +1; 00090 00091 bytes_read = rci->shared.content.length; 00092 00093 if (bytes_read < bytes_to_follow) 00094 { 00095 bytes_read = 0; 00096 goto done; 00097 } 00098 00099 switch (bytes_to_follow) 00100 { 00101 case record_bytes(rci_ber): 00102 *value = (modifier_ber & BINARY_RCI_SIZE_ALTERNATE_FLAG) ? modifier_ber : (modifier_ber & BINARY_RCI_ONE_BYTE_LIMIT_MASK); 00103 break; 00104 case record_bytes(rci_ber_u8): 00105 { 00106 uint8_t * const rci_ber_u8 = rci_ber; 00107 /* mask of the 1st byte for data value */ 00108 *value = (modifier_ber & BINARY_RCI_HI_BYTE_MASK) << 8; 00109 *value |= message_load_u8(rci_ber_u8, value); 00110 break; 00111 } 00112 case record_bytes(rci_ber_u16): 00113 { 00114 uint8_t * const rci_ber_u16 = rci_ber; 00115 *value = message_load_be16(rci_ber_u16, value); 00116 break; 00117 } 00118 case record_bytes(rci_ber_u32): 00119 { 00120 uint8_t * const rci_ber_u32 = rci_ber; 00121 *value = message_load_be32(rci_ber_u32, value); 00122 break; 00123 } 00124 default: 00125 ASSERT(bytes_to_follow == 1); 00126 /* NONUM or TRM value */ 00127 *value = modifier_ber; 00128 break; 00129 } 00130 bytes_read = bytes_to_follow; 00131 } 00132 00133 done: 00134 return bytes_read; 00135 } 00136 00137 static connector_bool_t get_uint32(rci_t * const rci, uint32_t * const value) 00138 { 00139 00140 size_t const bytes = get_modifier_ber(rci, value); 00141 00142 if (bytes > 0) 00143 reset_input_content(rci); 00144 00145 return connector_bool(bytes > 0); 00146 } 00147 00148 #if defined RCI_PARSER_USES_FLOAT 00149 static connector_bool_t get_float(rci_t * const rci, float * const value) 00150 { 00151 00152 connector_bool_t value_decoded = connector_false; 00153 uint8_t * rci_ber_u32 = rci->shared.content.data; 00154 uint8_t const opcode = message_load_u8(rci_ber_u32, opcode); 00155 00156 rci->shared.content.length++; 00157 ASSERT(sizeof(uint32_t) == sizeof(float)); 00158 00159 { 00160 /* we have modifier BEF */ 00161 size_t const bytes_to_follow = get_bytes_to_follow(opcode); 00162 size_t bytes_read = rci->shared.content.length; 00163 00164 if (bytes_read < (bytes_to_follow + 1)) 00165 { 00166 goto error; 00167 } 00168 00169 /* Current, we only support single precision float. */ 00170 ASSERT(bytes_read == record_bytes(rci_ber_u32)); 00171 00172 { 00173 uint32_t float_value = message_load_be32(rci_ber_u32, value); 00174 memcpy(value, &float_value, sizeof *value); 00175 } 00176 } 00177 00178 value_decoded = connector_true; 00179 reset_input_content(rci); 00180 00181 error: 00182 return value_decoded; 00183 } 00184 #endif 00185 00186 static connector_bool_t get_string(rci_t * const rci, char const * * string, size_t * const length) 00187 { 00188 connector_bool_t got_string = connector_false; 00189 uint32_t value; 00190 size_t const ber_bytes = get_modifier_ber(rci, &value); 00191 00192 if (ber_bytes > 0) 00193 { 00194 size_t const bytes = rci->shared.content.length; 00195 #if defined CONNECTOR_DEBUG 00196 size_t const size_max = SIZE_MAX; 00197 00198 (void)size_max; 00199 ASSERT(value <= size_max); 00200 #endif 00201 *length = value; 00202 if (*length > CONNECTOR_RCI_MAXIMUM_CONTENT_LENGTH) 00203 { 00204 connector_debug_printf("Maximum content size exceeded while getting a string - wanted %u, had %u\n", *length, CONNECTOR_RCI_MAXIMUM_CONTENT_LENGTH); 00205 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id); 00206 goto done; 00207 } 00208 00209 if (bytes == (ber_bytes + *length)) 00210 { 00211 char * data = (char *)(rci->shared.content.data + ber_bytes); 00212 00213 if (!destination_in_storage(rci)) 00214 { 00215 memcpy(rci->input.storage, data, *length); 00216 data = (char *)rci->input.storage; 00217 } 00218 00219 data[*length] = nul; 00220 *string = data; 00221 00222 reset_input_content(rci); 00223 got_string = connector_true; 00224 } 00225 } 00226 done: 00227 return got_string; 00228 } 00229 00230 #if defined RCI_PARSER_USES_IPV4 00231 static connector_bool_t get_ip_address(rci_t * const rci, uint32_t * const ip_addr, size_t const length) 00232 { 00233 connector_bool_t got_ip = connector_false; 00234 00235 uint8_t * rci_ber_u32 = rci->shared.content.data; 00236 uint8_t const bytes_read = message_load_u8(rci_ber_u32, opcode); 00237 00238 UNUSED_PARAMETER(length); 00239 00240 rci->shared.content.length++; 00241 00242 if (rci->shared.content.length == (size_t)(bytes_read + 1)) 00243 { 00244 /* Current, we only support ipv4. */ 00245 ASSERT(bytes_read == sizeof *ip_addr); 00246 ASSERT(length == bytes_read); 00247 00248 *ip_addr = message_load_be32(rci_ber_u32, value); 00249 00250 got_ip = connector_true; 00251 reset_input_content(rci); 00252 } 00253 00254 return got_ip; 00255 } 00256 #endif 00257 00258 static connector_bool_t decode_attribute(rci_t * const rci, unsigned int * index) 00259 { 00260 #define BINARY_RCI_ATTRIBUTE_TYPE_MASK 0x60 /* attr type: [bit 6 and 5] */ 00261 00262 #define BINARY_RCI_ATTRIBUTE_TYPE_NORMAL 0x00 00263 #define BINARY_RCI_ATTRIBUTE_TYPE_INDEX 0x20 00264 #define BINARY_RCI_ATTRIBUTE_TYPE_NAME 0x40 00265 00266 #define BINARY_RCI_ATTRIBUTE_INDEX_MASK 0x1F 00267 00268 connector_bool_t got_attribute = connector_false; 00269 uint32_t attribute_value; 00270 00271 if (get_uint32(rci, &attribute_value)) 00272 { 00273 unsigned int type = attribute_value & BINARY_RCI_ATTRIBUTE_TYPE_MASK; 00274 switch (type) 00275 { 00276 case BINARY_RCI_ATTRIBUTE_TYPE_INDEX: 00277 *index = attribute_value & BINARY_RCI_ATTRIBUTE_INDEX_MASK; 00278 rci_debug_printf("decode_attribute: index = %d\n", *index); 00279 got_attribute = connector_true; 00280 break; 00281 case BINARY_RCI_ATTRIBUTE_TYPE_NAME: 00282 case BINARY_RCI_ATTRIBUTE_TYPE_NORMAL: 00283 /* Tool doesn't support name and enum attribute */ 00284 connector_debug_printf("decode_attribute: unsupported attribute type\n"); 00285 rci->status = rci_status_internal_error; 00286 ASSERT(connector_false); 00287 break; 00288 } 00289 } 00290 00291 return got_attribute; 00292 } 00293 00294 static connector_bool_t has_rci_atribute(unsigned int data) 00295 { 00296 return connector_bool((data & BINARY_RCI_ATTRIBUTE_BIT) == BINARY_RCI_ATTRIBUTE_BIT); 00297 } 00298 00299 static connector_bool_t has_rci_error(rci_t * const rci, unsigned int data) 00300 { 00301 00302 connector_bool_t const hasError = connector_bool((data & BINARY_RCI_ERROR_INDICATOR_BIT) == BINARY_RCI_ERROR_INDICATOR_BIT); 00303 00304 UNUSED_PARAMETER(rci); 00305 00306 if (hasError) 00307 { 00308 connector_debug_printf("has_rci_error: unexpected error set.\n"); 00309 } 00310 return hasError; 00311 } 00312 00313 static connector_bool_t has_rci_terminated(unsigned int data) 00314 { 00315 return connector_bool(data == BINARY_RCI_TERMINATOR); 00316 } 00317 00318 static connector_bool_t has_rci_no_value(unsigned int data) 00319 { 00320 return connector_bool(data == BINARY_RCI_NO_VALUE); 00321 } 00322 00323 static void process_rci_command(rci_t * const rci) 00324 { 00325 #define BINARY_RCI_COMMAND_MASK 0x3F 00326 00327 uint32_t command; 00328 00329 { 00330 connector_remote_config_t const * const remote_config = &rci->shared.callback_data; 00331 00332 if (remote_config->error_id != connector_success) 00333 { 00334 set_rci_output_state(rci, rci_output_state_field_id); 00335 state_call(rci, rci_parser_state_output); 00336 goto done; 00337 } 00338 } 00339 00340 if (get_uint32(rci, &command)) 00341 { 00342 00343 connector_bool_t const has_attribute = has_rci_atribute(command); 00344 00345 ASSERT_GOTO(!has_rci_error(rci, command), done); 00346 00347 command &= BINARY_RCI_COMMAND_MASK; 00348 00349 switch (command) 00350 { 00351 case rci_command_set_setting: 00352 case rci_command_query_setting: 00353 rci->shared.callback_data.group.type = connector_remote_group_setting; 00354 break; 00355 case rci_command_set_state: 00356 case rci_command_query_state: 00357 rci->shared.callback_data.group.type = connector_remote_group_state; 00358 break; 00359 } 00360 00361 switch (command) 00362 { 00363 case rci_command_set_setting: 00364 case rci_command_set_state: 00365 rci->shared.callback_data.action = connector_remote_action_set; 00366 break; 00367 case rci_command_query_setting: 00368 case rci_command_query_state: 00369 rci->shared.callback_data.action = connector_remote_action_query; 00370 break; 00371 default: 00372 /* unsupported command. 00373 * Just go to error state for returning error message. 00374 */ 00375 rci_global_error(rci, connector_rci_error_bad_command, RCI_NO_HINT); 00376 set_rci_command_error(rci); 00377 state_call(rci, rci_parser_state_error); 00378 goto done; 00379 } 00380 00381 if (has_attribute) 00382 { 00383 set_rci_input_state(rci, rci_input_state_command_attribute); 00384 } 00385 else 00386 { 00387 set_rci_input_state(rci, rci_input_state_group_id); 00388 00389 set_rci_traverse_state(rci, rci_traverse_state_command_id); 00390 state_call(rci, rci_parser_state_traverse); 00391 } 00392 00393 } 00394 done: 00395 return; 00396 } 00397 00398 static void process_command_attribute(rci_t * const rci) 00399 { 00400 unsigned int index; 00401 00402 if (decode_attribute(rci, &index)) 00403 { 00404 /* We don't support command attribute; so just ignore it. */ 00405 set_rci_input_state(rci, rci_input_state_group_id); 00406 00407 set_rci_traverse_state(rci, rci_traverse_state_command_id); 00408 state_call(rci, rci_parser_state_traverse); 00409 } 00410 00411 return; 00412 } 00413 00414 00415 static void process_group_id(rci_t * const rci) 00416 { 00417 uint32_t group_id; 00418 00419 if (!get_uint32(rci, &group_id)) 00420 { 00421 goto done; 00422 } 00423 00424 ASSERT_GOTO(!has_rci_error(rci, group_id), done); 00425 00426 if (has_rci_terminated(group_id)) 00427 { 00428 if (have_group_id(rci)) 00429 { 00430 /* not 1st group */ 00431 set_rci_input_state(rci, rci_input_state_command_id); 00432 00433 set_rci_traverse_state(rci, rci_traverse_state_group_end); 00434 state_call(rci, rci_parser_state_traverse); 00435 goto done; 00436 } 00437 else 00438 { 00439 /* Get all groups if no group has been requested before */ 00440 switch (rci->shared.callback_data.action) 00441 { 00442 case connector_remote_action_query: 00443 set_rci_traverse_state(rci, rci_traverse_state_all_groups); 00444 state_call(rci, rci_parser_state_traverse); 00445 break; 00446 case connector_remote_action_set: 00447 connector_debug_printf("process_group_id: got set command with no group id specified\n"); 00448 rci_set_output_error(rci, connector_rci_error_bad_command, rci_set_empty_group_hint, rci_output_state_group_id); 00449 break; 00450 } 00451 goto done; 00452 } 00453 } 00454 else 00455 { 00456 set_group_id(rci, decode_group_id(group_id)); 00457 00458 if (!have_group_id(rci)) 00459 { 00460 connector_debug_printf("process_group_id: unrecognized group (mismatch of descriptors) group id = %d.\n", decode_group_id(group_id)); 00461 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_group_id); 00462 ASSERT(connector_false); 00463 goto done; 00464 } 00465 00466 if (has_rci_atribute(group_id)) 00467 { 00468 invalidate_group_index(rci); 00469 set_rci_input_state(rci, rci_input_state_group_attribute); 00470 goto done; 00471 } 00472 00473 { 00474 connector_group_t const * const group = get_current_group(rci); 00475 if (group->instances > 1) 00476 { 00477 set_rci_input_flag(rci, RCI_FLAG_GET_ALL_INSTANCES); 00478 } 00479 } 00480 00481 set_rci_input_state(rci, rci_input_state_field_id); 00482 } 00483 00484 set_group_index(rci, 1); 00485 set_rci_traverse_state(rci, rci_traverse_state_group_id); 00486 state_call(rci, rci_parser_state_traverse); 00487 rci_debug_printf("process_group_id: group id = %d\n", get_group_id(rci)); 00488 00489 done: 00490 return; 00491 } 00492 00493 static void process_group_attribute(rci_t * const rci) 00494 { 00495 if (decode_attribute(rci, &rci->shared.group.index)) 00496 { 00497 set_rci_input_state(rci, rci_input_state_field_id); 00498 set_rci_traverse_state(rci, rci_traverse_state_group_id); 00499 state_call(rci, rci_parser_state_traverse); 00500 } 00501 00502 return; 00503 } 00504 00505 static void process_field_id(rci_t * const rci) 00506 { 00507 unsigned int id = INVALID_ID; 00508 { 00509 uint32_t value; 00510 00511 if (!get_uint32(rci, &value)) 00512 { 00513 goto done; 00514 } 00515 00516 /* Bit 6 - is Field type present indicator 00517 * Bit 10 - is attributes present indicator 00518 * Bit 12 - is Error indicator (Should not be set) 00519 */ 00520 ASSERT_GOTO(!has_rci_error(rci, value), done); 00521 00522 if (has_rci_terminated(value)) 00523 { 00524 if (!have_element_id(rci)) 00525 { 00526 switch (rci->shared.callback_data.action) 00527 { 00528 case connector_remote_action_query: 00529 /* all fields */ 00530 if (is_rci_input_flag(rci,RCI_FLAG_GET_ALL_INSTANCES)) 00531 set_rci_traverse_state(rci, rci_traverse_state_all_group_instances); 00532 else 00533 set_rci_traverse_state(rci, rci_traverse_state_all_elements); 00534 00535 set_rci_input_state(rci, rci_input_state_group_id); 00536 00537 state_call(rci, rci_parser_state_traverse); 00538 break; 00539 case connector_remote_action_set: 00540 connector_debug_printf("process_field_id: got set command with no field id specified\n"); 00541 rci_set_output_error(rci, connector_rci_error_bad_command, rci_set_empty_element_hint, rci_output_state_field_id); 00542 break; 00543 } 00544 } 00545 else 00546 { 00547 /* done with all fields */ 00548 invalidate_element_id(rci); 00549 set_rci_input_state(rci, rci_input_state_group_id); 00550 00551 set_rci_traverse_state(rci, rci_traverse_state_element_end); 00552 state_call(rci, rci_parser_state_traverse); 00553 } 00554 goto done; 00555 } 00556 00557 if ((value & BINARY_RCI_FIELD_TYPE_INDICATOR_BIT) == BINARY_RCI_FIELD_TYPE_INDICATOR_BIT) 00558 { 00559 set_rci_input_state(rci, rci_input_state_field_type); 00560 } 00561 else 00562 { 00563 set_rci_input_state(rci, rci_input_state_field_no_value); 00564 } 00565 00566 00567 if ((value & BINARY_RCI_FIELD_ATTRIBUTE_BIT) == BINARY_RCI_FIELD_ATTRIBUTE_BIT) 00568 { 00569 connector_debug_printf("process_field_id: field attribute is not supported\n"); 00570 rci_set_output_error(rci, connector_rci_error_bad_descriptor, RCI_NO_HINT, rci_output_state_field_id); 00571 goto done; 00572 } 00573 00574 id = decode_element_id(value); 00575 00576 } 00577 00578 00579 set_element_id(rci, id); 00580 00581 if (!have_element_id(rci)) 00582 { 00583 connector_debug_printf("process_field_id: unrecognized field id (mismatch of descriptors). element id = %d\n", id); 00584 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id); 00585 } 00586 00587 done: 00588 return; 00589 } 00590 00591 static void process_field_type(rci_t * const rci) 00592 { 00593 connector_group_element_t const * const element = get_current_element(rci); 00594 connector_bool_t error = connector_false; 00595 uint32_t type; 00596 00597 if (get_uint32(rci, &type)) 00598 { 00599 ASSERT_GOTO(!has_rci_error(rci, type), done); 00600 00601 switch (type) 00602 { 00603 case rci_field_type_none: 00604 break; 00605 00606 default: 00607 if (element->type != type) 00608 { 00609 connector_debug_printf("process_field_type: mismatch field type (type %d) != (actual %d)\n", type, element->type); 00610 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id); 00611 error = connector_true; 00612 } 00613 break; 00614 } 00615 } 00616 00617 if (!error) 00618 { 00619 set_rci_input_state(rci, rci_input_state_field_no_value); 00620 } 00621 00622 done: 00623 return; 00624 } 00625 00626 static void process_field_value(rci_t * const rci) 00627 { 00628 connector_group_element_t const * const element = get_current_element(rci); 00629 connector_element_value_type_t const type = element->type; 00630 00631 #if (defined RCI_PARSER_USES_ON_OFF) || (defined RCI_PARSER_USES_BOOLEAN) 00632 connector_bool_t error = connector_false; 00633 #endif 00634 00635 switch (type) 00636 { 00637 #if defined RCI_PARSER_USES_STRINGS 00638 00639 #if defined RCI_PARSER_USES_STRING 00640 case connector_element_type_string: 00641 #endif 00642 00643 #if defined RCI_PARSER_USES_MULTILINE_STRING 00644 case connector_element_type_multiline_string: 00645 #endif 00646 00647 #if defined RCI_PARSER_USES_PASSWORD 00648 case connector_element_type_password: 00649 #endif 00650 00651 00652 #if defined RCI_PARSER_USES_FQDNV4 00653 case connector_element_type_fqdnv4: 00654 #endif 00655 00656 #if defined RCI_PARSER_USES_FQDNV6 00657 case connector_element_type_fqdnv6: 00658 #endif 00659 00660 #if defined RCI_PARSER_USES_DATETIME 00661 case connector_element_type_datetime: 00662 #endif 00663 if (!get_string(rci, &rci->shared.value.string_value, &rci->shared.string_value_length)) 00664 { 00665 goto done; 00666 } 00667 break; 00668 #endif 00669 00670 00671 #if defined RCI_PARSER_USES_INT32 00672 case connector_element_type_int32: 00673 { 00674 int32_t value; 00675 00676 if (!get_uint32(rci, (uint32_t *)&value)) 00677 { 00678 goto done; 00679 } 00680 rci->shared.value.signed_integer_value = value; 00681 break; 00682 } 00683 #endif 00684 00685 #if defined RCI_PARSER_USES_IPV4 00686 case connector_element_type_ipv4: 00687 { 00688 uint32_t ip_addr; 00689 00690 if (!get_ip_address(rci, &ip_addr, sizeof ip_addr)) 00691 { 00692 goto done; 00693 } 00694 00695 { 00696 #define MAX_IPV4_VALUE "255.255.255.255" 00697 00698 char * const data = (char *)rci->input.storage; 00699 size_t const size_avail = sizeof MAX_IPV4_VALUE; 00700 int size_written; 00701 00702 uint8_t ip1 = BYTE32_3(ip_addr); 00703 uint8_t ip2 = BYTE32_2(ip_addr); 00704 uint8_t ip3 = BYTE32_1(ip_addr); 00705 uint8_t ip4 = BYTE32_0(ip_addr); 00706 00707 ASSERT(size_avail <= sizeof rci->input.storage); 00708 00709 size_written = connector_snprintf(data, size_avail, "%d.%d.%d.%d", ip1, ip2, ip3, ip4); 00710 00711 ASSERT(size_written < (int)size_avail); 00712 ASSERT_GOTO(size_written > 0, done); 00713 00714 rci->shared.value.string_value = data; 00715 00716 #undef MAX_IPV4_VALUE 00717 } 00718 break; 00719 } 00720 #endif 00721 00722 #if (defined RCI_PARSER_USES_UNSIGNED_INTEGER) 00723 00724 00725 #if defined RCI_PARSER_USES_UINT32 00726 case connector_element_type_uint32: 00727 #endif 00728 00729 #if defined RCI_PARSER_USES_HEX32 00730 case connector_element_type_hex32: 00731 #endif 00732 00733 #if defined RCI_PARSER_USES_0X_HEX32 00734 case connector_element_type_0x_hex32: 00735 #endif 00736 { 00737 uint32_t value; 00738 00739 if (!get_uint32(rci, &value)) 00740 { 00741 goto done; 00742 } 00743 rci->shared.value.unsigned_integer_value = value; 00744 break; 00745 } 00746 #endif 00747 00748 #if defined RCI_PARSER_USES_FLOAT 00749 case connector_element_type_float: 00750 { 00751 if (!get_float(rci, &rci->shared.value.float_value)) 00752 { 00753 goto done; 00754 } 00755 break; 00756 } 00757 #endif 00758 00759 #if defined RCI_PARSER_USES_ENUM 00760 case connector_element_type_enum: 00761 { 00762 uint32_t value; 00763 if (!get_uint32(rci, &value)) 00764 { 00765 goto done; 00766 } 00767 rci->shared.value.enum_value = value; 00768 break; 00769 } 00770 #endif 00771 00772 #if defined RCI_PARSER_USES_ON_OFF 00773 case connector_element_type_on_off: 00774 { 00775 uint32_t value; 00776 00777 if (!get_uint32(rci, &value)) 00778 { 00779 goto done; 00780 } 00781 rci->shared.value.on_off_value = (value == 0)? connector_off : connector_on; 00782 error = connector_bool((value != 0) && (value != 1)); 00783 break; 00784 } 00785 #endif 00786 00787 #if defined RCI_PARSER_USES_BOOLEAN 00788 case connector_element_type_boolean: 00789 { 00790 uint32_t value; 00791 if (!get_uint32(rci, &value)) 00792 { 00793 goto done; 00794 } 00795 rci->shared.value.boolean_value = (value == 0)? connector_false : connector_true; 00796 error = connector_bool((value != 0) && (value != 1)); 00797 break; 00798 } 00799 #endif 00800 } 00801 00802 #if (defined RCI_PARSER_USES_ON_OFF) || (defined RCI_PARSER_USES_BOOLEAN) 00803 if (error) 00804 { 00805 connector_debug_printf("process_field_value: range check error! Descriptor problem!"); 00806 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_descriptor_mismatch_hint, rci_output_state_field_id); 00807 } 00808 else 00809 #endif 00810 { 00811 set_rci_traverse_state(rci, rci_traverse_state_element_id); 00812 state_call(rci, rci_parser_state_traverse); 00813 } 00814 set_rci_input_state(rci, rci_input_state_field_id); 00815 00816 done: 00817 return; 00818 } 00819 00820 static void process_field_no_value(rci_t * const rci) 00821 { 00822 uint8_t * const rci_ber = rci->shared.content.data; 00823 uint8_t const modifier_ber = message_load_u8(rci_ber, value); 00824 00825 if (has_rci_no_value(modifier_ber)) 00826 { 00827 /* this initializes element.value in case for set setting */ 00828 connector_group_element_t const * const element = get_current_element(rci); 00829 connector_element_value_type_t const type = element->type; 00830 00831 switch (type) 00832 { 00833 #if defined RCI_PARSER_USES_STRINGS 00834 00835 #if defined RCI_PARSER_USES_STRING 00836 case connector_element_type_string: 00837 #endif 00838 00839 #if defined RCI_PARSER_USES_MULTILINE_STRING 00840 case connector_element_type_multiline_string: 00841 #endif 00842 00843 #if defined RCI_PARSER_USES_PASSWORD 00844 case connector_element_type_password: 00845 #endif 00846 00847 00848 #if defined RCI_PARSER_USES_FQDNV4 00849 case connector_element_type_fqdnv4: 00850 #endif 00851 00852 #if defined RCI_PARSER_USES_FQDNV6 00853 case connector_element_type_fqdnv6: 00854 #endif 00855 00856 #if defined RCI_PARSER_USES_DATETIME 00857 case connector_element_type_datetime: 00858 #endif 00859 00860 #if defined RCI_PARSER_USES_IPV4 00861 case connector_element_type_ipv4: 00862 #endif 00863 rci->shared.value.string_value = (char *)rci->input.storage; 00864 rci->input.storage[0] = (uint8_t)nul; 00865 break; 00866 #endif 00867 00868 #if defined RCI_PARSER_USES_INT32 00869 case connector_element_type_int32: 00870 rci->shared.value.signed_integer_value = 0; 00871 break; 00872 #endif 00873 00874 #if (defined RCI_PARSER_USES_UNSIGNED_INTEGER) 00875 00876 00877 #if defined RCI_PARSER_USES_UINT32 00878 case connector_element_type_uint32: 00879 #endif 00880 00881 #if defined RCI_PARSER_USES_HEX32 00882 case connector_element_type_hex32: 00883 #endif 00884 00885 #if defined RCI_PARSER_USES_0X_HEX32 00886 case connector_element_type_0x_hex32: 00887 #endif 00888 rci->shared.value.unsigned_integer_value = 0; 00889 break; 00890 #endif 00891 00892 #if defined RCI_PARSER_USES_FLOAT 00893 case connector_element_type_float: 00894 rci->shared.value.float_value = 0; 00895 break; 00896 #endif 00897 00898 #if defined RCI_PARSER_USES_ENUM 00899 case connector_element_type_enum: 00900 rci->shared.value.enum_value = 0; 00901 break; 00902 #endif 00903 00904 #if defined RCI_PARSER_USES_ON_OFF 00905 case connector_element_type_on_off: 00906 rci->shared.value.on_off_value = connector_off; 00907 break; 00908 #endif 00909 00910 #if defined RCI_PARSER_USES_BOOLEAN 00911 case connector_element_type_boolean: 00912 rci->shared.value.boolean_value = connector_false; 00913 break; 00914 #endif 00915 } 00916 00917 reset_input_content(rci); 00918 set_rci_traverse_state(rci, rci_traverse_state_element_id); 00919 state_call(rci, rci_parser_state_traverse); 00920 set_rci_input_state(rci, rci_input_state_field_id); 00921 } 00922 else 00923 { 00924 set_rci_input_state(rci, rci_input_state_field_value); 00925 process_field_value(rci); 00926 } 00927 00928 } 00929 00930 static void rci_parse_input(rci_t * const rci) 00931 { 00932 rci_buffer_t * const input = &rci->buffer.input; 00933 00934 while ((rci->parser.state == rci_parser_state_input) && (rci_buffer_remaining(input) != 0)) 00935 { 00936 00937 if (rci->input.destination != rci_buffer_position(&rci->buffer.input)) 00938 { 00939 *(rci->input.destination) = rci_buffer_read(input); 00940 } 00941 rci->input.destination++; 00942 00943 rci_debug_printf("input: %s\n", rci_input_state_t_as_string(rci->input.state)); 00944 00945 switch (rci->input.state) 00946 { 00947 case rci_input_state_command_id: 00948 process_rci_command(rci); 00949 break; 00950 case rci_input_state_command_attribute: 00951 process_command_attribute(rci); 00952 break; 00953 case rci_input_state_group_id: 00954 process_group_id(rci); 00955 break; 00956 case rci_input_state_group_attribute: 00957 process_group_attribute(rci); 00958 break; 00959 case rci_input_state_field_id: 00960 process_field_id(rci); 00961 break; 00962 case rci_input_state_field_type: 00963 process_field_type(rci); 00964 break; 00965 case rci_input_state_field_no_value: 00966 process_field_no_value(rci); 00967 break; 00968 case rci_input_state_field_value: 00969 process_field_value(rci); 00970 break; 00971 case rci_input_state_done: 00972 break; 00973 } 00974 00975 { 00976 size_t const storage_bytes = sizeof rci->input.storage; 00977 uint8_t const * const storage_end = rci->input.storage + storage_bytes; 00978 00979 if (rci->input.destination == storage_end) 00980 { 00981 connector_debug_printf("Maximum content size exceeded while parsing - wanted %u, had %u\n", storage_bytes + 1, storage_bytes); 00982 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id); 00983 goto done; 00984 } 00985 } 00986 00987 rci_buffer_advance(input, 1); 00988 } 00989 00990 if (rci_buffer_remaining(input) == 0) 00991 { 00992 if (MsgIsLastData(rci->service_data->input.flags)) 00993 { 00994 set_rci_input_state(rci, rci_input_state_done); 00995 state_call(rci, rci_parser_state_traverse); 00996 } 00997 else 00998 { 00999 uint8_t const * const old_base = rcistr_data(&rci->shared.content); 01000 uint8_t * const new_base = destination_in_storage(rci) ? rci->input.destination : rci->input.storage; 01001 01002 if (ptr_in_buffer(old_base, &rci->buffer.input)) 01003 { 01004 size_t const storage_bytes = sizeof rci->input.storage; 01005 uint8_t const * const storage_end = rci->input.storage + storage_bytes; 01006 size_t const bytes_wanted = (size_t)(rci->buffer.input.end - old_base); 01007 size_t const bytes_have = (size_t)(storage_end - new_base); 01008 01009 if (bytes_wanted >= bytes_have) 01010 { 01011 connector_debug_printf("Maximum content size exceeded while storing - wanted %u, had %u\n", bytes_wanted, bytes_have); 01012 rci_set_output_error(rci, connector_rci_error_bad_descriptor, rci_error_content_size_hint, rci_output_state_field_id); 01013 goto done; 01014 } 01015 01016 memcpy(new_base, old_base, bytes_wanted); 01017 01018 adjust_rcistr(new_base, old_base, &rci->shared.content); 01019 rci->input.destination = new_base + bytes_wanted; 01020 } 01021 01022 rci->status = rci_status_more_input; 01023 } 01024 } 01025 01026 done: 01027 return; 01028 } 01029 01030
Generated on Tue Jul 12 2022 19:18:38 by
1.7.2