openc3 7.2.1 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Guardfile +0 -0
- data/LICENSE.md +0 -0
- data/README.md +0 -0
- data/Rakefile +0 -0
- data/bin/openc3cli +235 -6
- data/bin/pipinstall +5 -4
- data/bin/pipuninstall +5 -1
- data/bin/uvinstall +156 -0
- data/data/config/_array_params.yaml +0 -0
- data/data/config/_canvas_values.yaml +0 -0
- data/data/config/_graph_params.yaml +0 -0
- data/data/config/_id_items.yaml +0 -0
- data/data/config/_id_params.yaml +0 -0
- data/data/config/_interfaces.yaml +0 -0
- data/data/config/_items.yaml +0 -0
- data/data/config/_params.yaml +0 -0
- data/data/config/command.yaml +0 -0
- data/data/config/command_modifiers.yaml +2 -0
- data/data/config/command_telemetry.yaml +0 -0
- data/data/config/conversions.yaml +0 -0
- data/data/config/graph_settings.yaml +0 -0
- data/data/config/interface_modifiers.yaml +103 -1
- data/data/config/item_modifiers.yaml +2 -1
- data/data/config/microservice.yaml +9 -2
- data/data/config/param_item_modifiers.yaml +0 -0
- data/data/config/parameter_modifiers.yaml +0 -0
- data/data/config/plugins.yaml +0 -0
- data/data/config/processors.yaml +0 -0
- data/data/config/protocols.yaml +0 -0
- data/data/config/screen.yaml +2 -1
- data/data/config/settings.yaml +0 -0
- data/data/config/table_manager.yaml +0 -0
- data/data/config/table_parameter_modifiers.yaml +0 -0
- data/data/config/target.yaml +21 -0
- data/data/config/target_config.yaml +0 -0
- data/data/config/telemetry.yaml +0 -0
- data/data/config/telemetry_modifiers.yaml +2 -0
- data/data/config/tool.yaml +3 -1
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +22 -3
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +5918 -0
- data/data/xtce_schemas/xml.xsd +116 -0
- data/ext/openc3/ext/array/array.c +0 -0
- data/ext/openc3/ext/array/extconf.rb +0 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
- data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
- data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
- data/ext/openc3/ext/config_parser/config_parser.c +0 -0
- data/ext/openc3/ext/config_parser/extconf.rb +0 -0
- data/ext/openc3/ext/crc/crc.c +0 -0
- data/ext/openc3/ext/crc/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
- data/ext/openc3/ext/packet/extconf.rb +0 -0
- data/ext/openc3/ext/packet/packet.c +0 -0
- data/ext/openc3/ext/platform/extconf.rb +0 -0
- data/ext/openc3/ext/platform/platform.c +4 -1
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
- data/ext/openc3/ext/string/extconf.rb +0 -0
- data/ext/openc3/ext/string/string.c +0 -0
- data/ext/openc3/ext/structure/structure.c +49 -17
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
- data/ext/openc3/ext/telemetry/extconf.rb +0 -0
- data/ext/openc3/ext/telemetry/telemetry.c +1 -1
- data/lib/cosmos.rb +0 -0
- data/lib/cosmosc2.rb +0 -0
- data/lib/openc3/accessors/accessor.rb +0 -0
- data/lib/openc3/accessors/binary_accessor.rb +63 -9
- data/lib/openc3/accessors/cbor_accessor.rb +0 -0
- data/lib/openc3/accessors/form_accessor.rb +0 -0
- data/lib/openc3/accessors/html_accessor.rb +0 -0
- data/lib/openc3/accessors/http_accessor.rb +0 -0
- data/lib/openc3/accessors/json_accessor.rb +0 -0
- data/lib/openc3/accessors/template_accessor.rb +2 -2
- data/lib/openc3/accessors/xml_accessor.rb +0 -0
- data/lib/openc3/accessors.rb +0 -0
- data/lib/openc3/api/README.md +0 -0
- data/lib/openc3/api/api.rb +0 -0
- data/lib/openc3/api/authorized_api.rb +0 -0
- data/lib/openc3/api/calendar_api.rb +0 -0
- data/lib/openc3/api/cmd_api.rb +1 -1
- data/lib/openc3/api/config_api.rb +0 -0
- data/lib/openc3/api/interface_api.rb +2 -2
- data/lib/openc3/api/limits_api.rb +27 -13
- data/lib/openc3/api/metrics_api.rb +1 -1
- data/lib/openc3/api/offline_access_api.rb +1 -1
- data/lib/openc3/api/router_api.rb +3 -3
- data/lib/openc3/api/settings_api.rb +22 -18
- data/lib/openc3/api/stash_api.rb +1 -1
- data/lib/openc3/api/target_api.rb +0 -0
- data/lib/openc3/api/tlm_api.rb +5 -4
- data/lib/openc3/bridge/bridge.rb +0 -0
- data/lib/openc3/bridge/bridge_config.rb +0 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
- data/lib/openc3/config/config_parser.rb +78 -17
- data/lib/openc3/config/meta_config_parser.rb +0 -0
- data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
- data/lib/openc3/conversions/conversion.rb +0 -0
- data/lib/openc3/conversions/generic_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
- data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
- data/lib/openc3/conversions/object_read_conversion.rb +0 -0
- data/lib/openc3/conversions/object_write_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/processor_conversion.rb +0 -0
- data/lib/openc3/conversions/received_count_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
- data/lib/openc3/conversions.rb +0 -0
- data/lib/openc3/core_ext/array.rb +0 -0
- data/lib/openc3/core_ext/binding.rb +0 -0
- data/lib/openc3/core_ext/class.rb +0 -0
- data/lib/openc3/core_ext/exception.rb +0 -0
- data/lib/openc3/core_ext/faraday.rb +0 -0
- data/lib/openc3/core_ext/file.rb +0 -0
- data/lib/openc3/core_ext/io.rb +0 -0
- data/lib/openc3/core_ext/kernel.rb +0 -0
- data/lib/openc3/core_ext/math.rb +0 -0
- data/lib/openc3/core_ext/matrix.rb +0 -0
- data/lib/openc3/core_ext/objectspace.rb +0 -0
- data/lib/openc3/core_ext/openc3_io.rb +0 -0
- data/lib/openc3/core_ext/range.rb +0 -0
- data/lib/openc3/core_ext/socket.rb +0 -0
- data/lib/openc3/core_ext/string.rb +0 -0
- data/lib/openc3/core_ext/stringio.rb +0 -0
- data/lib/openc3/core_ext/tempfile.rb +0 -0
- data/lib/openc3/core_ext/time.rb +0 -0
- data/lib/openc3/core_ext.rb +0 -0
- data/lib/openc3/ext/.keep +0 -0
- data/lib/openc3/interfaces/file_interface.rb +0 -0
- data/lib/openc3/interfaces/http_client_interface.rb +1 -1
- data/lib/openc3/interfaces/http_server_interface.rb +0 -0
- data/lib/openc3/interfaces/interface.rb +5 -4
- data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
- data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
- data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +4 -4
- data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
- data/lib/openc3/interfaces/serial_interface.rb +2 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
- data/lib/openc3/interfaces/stream_interface.rb +0 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
- data/lib/openc3/interfaces/udp_interface.rb +16 -5
- data/lib/openc3/interfaces.rb +0 -0
- data/lib/openc3/io/buffered_file.rb +0 -0
- data/lib/openc3/io/io_multiplexer.rb +0 -0
- data/lib/openc3/io/json_api.rb +3 -2
- data/lib/openc3/io/json_api_object.rb +0 -0
- data/lib/openc3/io/json_drb.rb +44 -12
- data/lib/openc3/io/json_drb_object.rb +0 -0
- data/lib/openc3/io/json_drb_rack.rb +0 -0
- data/lib/openc3/io/json_rpc.rb +0 -2
- data/lib/openc3/io/posix_serial_driver.rb +0 -0
- data/lib/openc3/io/serial_driver.rb +0 -0
- data/lib/openc3/io/stderr.rb +0 -0
- data/lib/openc3/io/stdout.rb +0 -0
- data/lib/openc3/io/udp_sockets.rb +38 -8
- data/lib/openc3/io/win32_serial_driver.rb +1 -0
- data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
- data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
- data/lib/openc3/logs/log_writer.rb +43 -7
- data/lib/openc3/logs/packet_log_constants.rb +0 -0
- data/lib/openc3/logs/packet_log_reader.rb +23 -2
- data/lib/openc3/logs/packet_log_writer.rb +6 -2
- data/lib/openc3/logs/stream_log.rb +1 -1
- data/lib/openc3/logs/stream_log_pair.rb +0 -0
- data/lib/openc3/logs/text_log_writer.rb +0 -0
- data/lib/openc3/logs.rb +0 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/decom_common.rb +0 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -0
- data/lib/openc3/microservices/interface_decom_common.rb +2 -1
- data/lib/openc3/microservices/interface_microservice.rb +73 -26
- data/lib/openc3/microservices/log_microservice.rb +0 -0
- data/lib/openc3/microservices/microservice.rb +3 -3
- data/lib/openc3/microservices/multi_microservice.rb +1 -1
- data/lib/openc3/microservices/periodic_microservice.rb +2 -2
- data/lib/openc3/microservices/plugin_microservice.rb +0 -0
- data/lib/openc3/microservices/queue_microservice.rb +0 -0
- data/lib/openc3/microservices/router_microservice.rb +0 -0
- data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
- data/lib/openc3/microservices/text_log_microservice.rb +0 -0
- data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
- data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
- data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
- data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
- data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
- data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
- data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
- data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
- data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
- data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
- data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
- data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
- data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
- data/lib/openc3/migrations/20260731000000_system_health_json.rb +52 -0
- data/lib/openc3/models/activity_model.rb +0 -0
- data/lib/openc3/models/auth_model.rb +35 -7
- data/lib/openc3/models/bridge_model.rb +133 -0
- data/lib/openc3/models/config_keyword_model.rb +63 -0
- data/lib/openc3/models/cvt_model.rb +5 -5
- data/lib/openc3/models/db_sharded_model.rb +0 -0
- data/lib/openc3/models/environment_model.rb +0 -0
- data/lib/openc3/models/gem_model.rb +13 -10
- data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
- data/lib/openc3/models/info_model.rb +0 -0
- data/lib/openc3/models/interface_model.rb +179 -20
- data/lib/openc3/models/interface_status_model.rb +0 -0
- data/lib/openc3/models/metadata_model.rb +0 -0
- data/lib/openc3/models/metric_model.rb +0 -0
- data/lib/openc3/models/microservice_model.rb +26 -18
- data/lib/openc3/models/microservice_status_model.rb +0 -0
- data/lib/openc3/models/migration_model.rb +0 -0
- data/lib/openc3/models/model.rb +0 -0
- data/lib/openc3/models/news_model.rb +0 -0
- data/lib/openc3/models/note_model.rb +0 -0
- data/lib/openc3/models/offline_access_model.rb +0 -0
- data/lib/openc3/models/ping_model.rb +0 -0
- data/lib/openc3/models/plugin_model.rb +211 -50
- data/lib/openc3/models/plugin_store_model.rb +0 -0
- data/lib/openc3/models/process_status_model.rb +0 -0
- data/lib/openc3/models/python_package_model.rb +211 -15
- data/lib/openc3/models/queue_model.rb +0 -0
- data/lib/openc3/models/reaction_model.rb +0 -0
- data/lib/openc3/models/reingest_job_model.rb +0 -0
- data/lib/openc3/models/router_model.rb +0 -0
- data/lib/openc3/models/router_status_model.rb +0 -0
- data/lib/openc3/models/scope_model.rb +85 -56
- data/lib/openc3/models/script_engine_model.rb +0 -0
- data/lib/openc3/models/script_status_model.rb +0 -0
- data/lib/openc3/models/secret_model.rb +0 -0
- data/lib/openc3/models/setting_model.rb +546 -3
- data/lib/openc3/models/sorted_model.rb +0 -0
- data/lib/openc3/models/stash_model.rb +0 -0
- data/lib/openc3/models/target_model.rb +210 -31
- data/lib/openc3/models/timeline_model.rb +0 -0
- data/lib/openc3/models/tool_config_model.rb +0 -0
- data/lib/openc3/models/tool_model.rb +34 -20
- data/lib/openc3/models/trigger_group_model.rb +0 -0
- data/lib/openc3/models/trigger_model.rb +20 -0
- data/lib/openc3/models/widget_model.rb +0 -0
- data/lib/openc3/operators/microservice_operator.rb +79 -8
- data/lib/openc3/operators/operator.rb +4 -4
- data/lib/openc3/packets/binary_accessor.rb +0 -0
- data/lib/openc3/packets/command_validator.rb +0 -0
- data/lib/openc3/packets/commands.rb +4 -4
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +15 -7
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +5 -1
- data/lib/openc3/packets/packet_config.rb +0 -0
- data/lib/openc3/packets/packet_item.rb +0 -0
- data/lib/openc3/packets/packet_item_limits.rb +0 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
- data/lib/openc3/packets/parsers/state_parser.rb +1 -1
- data/lib/openc3/packets/parsers/xtce_converter.rb +183 -103
- data/lib/openc3/packets/parsers/xtce_parser.rb +71 -23
- data/lib/openc3/packets/structure.rb +9 -3
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +3 -3
- data/lib/openc3/processors/processor.rb +2 -0
- data/lib/openc3/processors/statistics_processor.rb +0 -0
- data/lib/openc3/processors/watermark_processor.rb +0 -0
- data/lib/openc3/processors.rb +0 -0
- data/lib/openc3/script/api_shared.rb +0 -0
- data/lib/openc3/script/autonomic.rb +12 -12
- data/lib/openc3/script/calendar.rb +0 -0
- data/lib/openc3/script/commands.rb +1 -1
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +20 -25
- data/lib/openc3/script/limits.rb +0 -0
- data/lib/openc3/script/metadata.rb +0 -0
- data/lib/openc3/script/packages.rb +0 -0
- data/lib/openc3/script/plugins.rb +0 -0
- data/lib/openc3/script/queue.rb +0 -0
- data/lib/openc3/script/screen.rb +0 -0
- data/lib/openc3/script/script.rb +2 -2
- data/lib/openc3/script/script_runner.rb +0 -0
- data/lib/openc3/script/storage.rb +4 -4
- data/lib/openc3/script/suite.rb +0 -0
- data/lib/openc3/script/suite_results.rb +0 -0
- data/lib/openc3/script/suite_runner.rb +26 -0
- data/lib/openc3/script/tables.rb +0 -0
- data/lib/openc3/script/telemetry.rb +9 -3
- data/lib/openc3/script/web_socket_api.rb +247 -134
- data/lib/openc3/script.rb +0 -0
- data/lib/openc3/script_engines/script_engine.rb +0 -0
- data/lib/openc3/streams/mqtt_stream.rb +0 -0
- data/lib/openc3/streams/serial_stream.rb +0 -0
- data/lib/openc3/streams/stream.rb +0 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
- data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
- data/lib/openc3/system/system.rb +0 -0
- data/lib/openc3/system/target.rb +0 -0
- data/lib/openc3/system.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
- data/lib/openc3/tools/table_manager/table.rb +0 -0
- data/lib/openc3/tools/table_manager/table_config.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item.rb +0 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
- data/lib/openc3/tools/test_runner/test.rb +0 -0
- data/lib/openc3/top_level.rb +1 -1
- data/lib/openc3/topics/autonomic_topic.rb +0 -0
- data/lib/openc3/topics/calendar_topic.rb +0 -0
- data/lib/openc3/topics/command_decom_topic.rb +16 -1
- data/lib/openc3/topics/command_topic.rb +0 -0
- data/lib/openc3/topics/config_topic.rb +0 -0
- data/lib/openc3/topics/decom_interface_topic.rb +2 -1
- data/lib/openc3/topics/interface_topic.rb +8 -2
- data/lib/openc3/topics/limits_event_topic.rb +1 -1
- data/lib/openc3/topics/notebook_topic.rb +0 -0
- data/lib/openc3/topics/queue_topic.rb +0 -0
- data/lib/openc3/topics/router_topic.rb +6 -1
- data/lib/openc3/topics/system_events_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
- data/lib/openc3/topics/telemetry_topic.rb +0 -0
- data/lib/openc3/topics/timeline_topic.rb +0 -0
- data/lib/openc3/topics/topic.rb +0 -0
- data/lib/openc3/utilities/authentication.rb +4 -4
- data/lib/openc3/utilities/authorization.rb +0 -0
- data/lib/openc3/utilities/aws_bucket.rb +12 -4
- data/lib/openc3/utilities/bucket.rb +1 -1
- data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
- data/lib/openc3/utilities/bucket_require.rb +0 -0
- data/lib/openc3/utilities/bucket_utilities.rb +3 -4
- data/lib/openc3/utilities/cli_generator.rb +0 -0
- data/lib/openc3/utilities/cmd_log.rb +0 -0
- data/lib/openc3/utilities/config_overlay.rb +75 -0
- data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
- data/lib/openc3/utilities/crc.rb +59 -32
- data/lib/openc3/utilities/csv.rb +5 -5
- data/lib/openc3/utilities/ctrf.rb +0 -0
- data/lib/openc3/utilities/env_helper.rb +0 -0
- data/lib/openc3/utilities/local_bucket.rb +0 -0
- data/lib/openc3/utilities/local_mode.rb +36 -7
- data/lib/openc3/utilities/logger.rb +30 -8
- data/lib/openc3/utilities/message_log.rb +0 -0
- data/lib/openc3/utilities/metric.rb +0 -0
- data/lib/openc3/utilities/migration.rb +0 -0
- data/lib/openc3/utilities/open_telemetry.rb +0 -0
- data/lib/openc3/utilities/process_manager.rb +0 -0
- data/lib/openc3/utilities/pypi_url.rb +0 -0
- data/lib/openc3/utilities/python_proxy.rb +0 -0
- data/lib/openc3/utilities/python_venv.rb +135 -0
- data/lib/openc3/utilities/quaternion.rb +0 -0
- data/lib/openc3/utilities/questdb_client.rb +0 -0
- data/lib/openc3/utilities/redis_secrets.rb +0 -0
- data/lib/openc3/utilities/reingest_job.rb +0 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +5 -1
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +119 -95
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +52 -12
- data/lib/openc3/utilities/secrets.rb +48 -3
- data/lib/openc3/utilities/simulated_target.rb +0 -0
- data/lib/openc3/utilities/sleeper.rb +0 -0
- data/lib/openc3/utilities/store.rb +0 -0
- data/lib/openc3/utilities/store_autoload.rb +2 -2
- data/lib/openc3/utilities/store_queued.rb +0 -0
- data/lib/openc3/utilities/target_file.rb +18 -1
- data/lib/openc3/utilities/thread_manager.rb +0 -0
- data/lib/openc3/utilities/throttle.rb +0 -0
- data/lib/openc3/utilities/zip.rb +0 -0
- data/lib/openc3/utilities.rb +0 -0
- data/lib/openc3/version.rb +6 -6
- data/lib/openc3/win32/excel.rb +0 -0
- data/lib/openc3/win32/win32.rb +0 -0
- data/lib/openc3/win32/win32_main.rb +0 -0
- data/lib/openc3.rb +2 -2
- data/tasks/gemfile_stats.rake +0 -0
- data/tasks/spec.rake +0 -0
- data/templates/command_validator/command_validator.py +0 -0
- data/templates/command_validator/command_validator.rb +0 -0
- data/templates/conversion/conversion.py +0 -0
- data/templates/conversion/conversion.rb +0 -0
- data/templates/limits_response/response.py +0 -0
- data/templates/limits_response/response.rb +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
- data/templates/plugin/.gitignore +0 -0
- data/templates/plugin/LICENSE.md +0 -0
- data/templates/plugin/README.md +0 -0
- data/templates/plugin/Rakefile +0 -0
- data/templates/plugin/plugin.gemspec +1 -1
- data/templates/plugin/plugin.txt +0 -0
- data/templates/processor/processor.py +1 -1
- data/templates/processor/processor.rb +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- data/templates/target/targets/TARGET/lib/target.py +0 -0
- data/templates/target/targets/TARGET/lib/target.rb +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
- data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
- data/templates/target/targets/TARGET/public/README.txt +0 -0
- data/templates/target/targets/TARGET/screens/status.txt +0 -0
- data/templates/target/targets/TARGET/target.txt +0 -0
- data/templates/tool_angular/.editorconfig +0 -0
- data/templates/tool_angular/.gitignore +0 -0
- data/templates/tool_angular/.vscode/extensions.json +0 -0
- data/templates/tool_angular/.vscode/launch.json +0 -0
- data/templates/tool_angular/.vscode/tasks.json +0 -0
- data/templates/tool_angular/angular.json +0 -0
- data/templates/tool_angular/extra-webpack.config.js +0 -0
- data/templates/tool_angular/package.json +2 -2
- data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
- data/templates/tool_angular/src/app/app.component.html +0 -0
- data/templates/tool_angular/src/app/app.component.scss +0 -0
- data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
- data/templates/tool_angular/src/app/app.component.ts +0 -0
- data/templates/tool_angular/src/app/app.module.ts +0 -0
- data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
- data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
- data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
- data/templates/tool_angular/src/assets/.gitkeep +0 -0
- data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
- data/templates/tool_angular/src/environments/environment.ts +0 -0
- data/templates/tool_angular/src/favicon.ico +0 -0
- data/templates/tool_angular/src/index.html +0 -0
- data/templates/tool_angular/src/main.single-spa.ts +0 -0
- data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
- data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
- data/templates/tool_angular/src/styles.scss +0 -0
- data/templates/tool_angular/tsconfig.app.json +0 -0
- data/templates/tool_angular/tsconfig.json +0 -0
- data/templates/tool_angular/tsconfig.spec.json +0 -0
- data/templates/tool_react/.eslintrc +0 -0
- data/templates/tool_react/.gitignore +0 -0
- data/templates/tool_react/.prettierignore +0 -0
- data/templates/tool_react/babel.config.json +0 -0
- data/templates/tool_react/jest.config.js +0 -0
- data/templates/tool_react/package.json +1 -1
- data/templates/tool_react/src/openc3-tool_name.js +0 -0
- data/templates/tool_react/src/root.component.js +0 -0
- data/templates/tool_react/src/root.component.test.js +0 -0
- data/templates/tool_react/webpack.config.js +0 -0
- data/templates/tool_svelte/.gitignore +0 -0
- data/templates/tool_svelte/.prettierignore +0 -0
- data/templates/tool_svelte/.prettierrc.js +0 -0
- data/templates/tool_svelte/babel.config.js +0 -0
- data/templates/tool_svelte/build/smui.css +0 -0
- data/templates/tool_svelte/jest.config.js +0 -0
- data/templates/tool_svelte/package.json +1 -1
- data/templates/tool_svelte/rollup.config.js +0 -0
- data/templates/tool_svelte/src/App.svelte +0 -0
- data/templates/tool_svelte/src/App.test.js +0 -0
- data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
- data/templates/tool_svelte/src/tool_name.js +0 -0
- data/templates/tool_vue/.env.standalone +0 -0
- data/templates/tool_vue/.gitignore +0 -0
- data/templates/tool_vue/.prettierrc.cjs +0 -0
- data/templates/tool_vue/eslint.config.mjs +0 -0
- data/templates/tool_vue/jsconfig.json +0 -0
- data/templates/tool_vue/package.json +3 -3
- data/templates/tool_vue/src/App.vue +0 -0
- data/templates/tool_vue/src/main.js +0 -0
- data/templates/tool_vue/src/router.js +0 -0
- data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
- data/templates/tool_vue/vite.config.js +1 -1
- data/templates/widget/.prettierrc.cjs +0 -0
- data/templates/widget/LICENSE.md +0 -0
- data/templates/widget/Rakefile +0 -0
- data/templates/widget/package.json +2 -2
- data/templates/widget/src/Widget.vue +0 -0
- data/templates/widget/vite.config.js +0 -0
- metadata +40 -11
- data/templates/tool_vue/.nycrc +0 -3
- data/templates/widget/.nycrc +0 -3
|
@@ -106,6 +106,13 @@ module OpenC3
|
|
|
106
106
|
when 4
|
|
107
107
|
string_length = string_length.unpack('N')[0] # UINT32
|
|
108
108
|
raise "Length value received larger than max_length: #{string_length} > #{@max_length}" if @max_length and string_length > @max_length
|
|
109
|
+
|
|
110
|
+
# Reject up front rather than buffering the declared number of bytes first
|
|
111
|
+
if string_length > @max_buffer_size
|
|
112
|
+
reset() # Drop the partial frame rather than holding it until disconnect
|
|
113
|
+
raise "Length value received of #{string_length} bytes exceeds maximum buffer size of #{@max_buffer_size} bytes. " \
|
|
114
|
+
"Increase OPENC3_PROTOCOL_MAX_BUFFER_SIZE."
|
|
115
|
+
end
|
|
109
116
|
else
|
|
110
117
|
raise "Unsupported length given to read_length_field_followed_by_string: #{length_num_bytes}"
|
|
111
118
|
end
|
|
@@ -131,13 +131,13 @@ module OpenC3
|
|
|
131
131
|
def write_details
|
|
132
132
|
result = {'name' => self.class.name.to_s.split("::")[-1]}
|
|
133
133
|
if @write_data_input_time
|
|
134
|
-
result['write_data_input_time'] = @write_data_input_time.iso8601
|
|
134
|
+
result['write_data_input_time'] = @write_data_input_time.getutc.iso8601(6)
|
|
135
135
|
else
|
|
136
136
|
result['write_data_input_time'] = nil
|
|
137
137
|
end
|
|
138
138
|
result['write_data_input'] = @write_data_input
|
|
139
139
|
if @write_data_output_time
|
|
140
|
-
result['write_data_output_time'] = @write_data_output_time.iso8601
|
|
140
|
+
result['write_data_output_time'] = @write_data_output_time.getutc.iso8601(6)
|
|
141
141
|
else
|
|
142
142
|
result['write_data_output_time'] = nil
|
|
143
143
|
end
|
|
@@ -148,13 +148,13 @@ module OpenC3
|
|
|
148
148
|
def read_details
|
|
149
149
|
result = {'name' => self.class.name.to_s.split("::")[-1]}
|
|
150
150
|
if @read_data_input_time
|
|
151
|
-
result['read_data_input_time'] = @read_data_input_time.iso8601
|
|
151
|
+
result['read_data_input_time'] = @read_data_input_time.getutc.iso8601(6)
|
|
152
152
|
else
|
|
153
153
|
result['read_data_input_time'] = nil
|
|
154
154
|
end
|
|
155
155
|
result['read_data_input'] = @read_data_input
|
|
156
156
|
if @read_data_output_time
|
|
157
|
-
result['read_data_output_time'] = @read_data_output_time.iso8601
|
|
157
|
+
result['read_data_output_time'] = @read_data_output_time.getutc.iso8601(6)
|
|
158
158
|
else
|
|
159
159
|
result['read_data_output_time'] = nil
|
|
160
160
|
end
|
|
File without changes
|
|
@@ -266,7 +266,7 @@ module OpenC3
|
|
|
266
266
|
result['response_timeout'] = @response_timeout
|
|
267
267
|
result['response_polling_period'] = @response_polling_period
|
|
268
268
|
if @connect_complete_time
|
|
269
|
-
result['connect_complete_time'] = @connect_complete_time.iso8601
|
|
269
|
+
result['connect_complete_time'] = @connect_complete_time.getutc.iso8601(6)
|
|
270
270
|
else
|
|
271
271
|
result['connect_complete_time'] = nil
|
|
272
272
|
end
|
|
@@ -285,7 +285,7 @@ module OpenC3
|
|
|
285
285
|
result['response_timeout'] = @response_timeout
|
|
286
286
|
result['response_polling_period'] = @response_polling_period
|
|
287
287
|
if @connect_complete_time
|
|
288
|
-
result['connect_complete_time'] = @connect_complete_time.iso8601
|
|
288
|
+
result['connect_complete_time'] = @connect_complete_time.getutc.iso8601(6)
|
|
289
289
|
else
|
|
290
290
|
result['connect_complete_time'] = nil
|
|
291
291
|
end
|
|
File without changes
|
|
@@ -77,6 +77,8 @@ module OpenC3
|
|
|
77
77
|
|
|
78
78
|
# Creates a new {SerialStream} using the parameters passed in the constructor
|
|
79
79
|
def connect
|
|
80
|
+
# Cleanly close any existing stream rather than leaving it open
|
|
81
|
+
@stream.disconnect if @stream
|
|
80
82
|
@stream = SerialStream.new(
|
|
81
83
|
@write_port_name,
|
|
82
84
|
@read_port_name,
|
|
File without changes
|
|
File without changes
|
|
@@ -76,6 +76,8 @@ module OpenC3
|
|
|
76
76
|
# Connects the {TcpipClientStream} by passing the
|
|
77
77
|
# initialization parameters to the {TcpipClientStream}.
|
|
78
78
|
def connect
|
|
79
|
+
# Cleanly close any existing stream rather than leaving it open
|
|
80
|
+
@stream.disconnect if @stream
|
|
79
81
|
@stream = TcpipClientStream.new(
|
|
80
82
|
@hostname,
|
|
81
83
|
@write_port,
|
|
File without changes
|
|
@@ -23,6 +23,7 @@ module OpenC3
|
|
|
23
23
|
# Base class for interfaces that send and receive messages over UDP
|
|
24
24
|
class UdpInterface < Interface
|
|
25
25
|
HOST_127_0_0_1 = '127.0.0.1'
|
|
26
|
+
HOST_0_0_0_0 = '0.0.0.0'
|
|
26
27
|
|
|
27
28
|
# @param hostname [String] Machine to connect to
|
|
28
29
|
# @param write_dest_port [Integer] Port to write commands to
|
|
@@ -77,8 +78,11 @@ module OpenC3
|
|
|
77
78
|
@read_timeout = ConfigParser.handle_nil(read_timeout)
|
|
78
79
|
@read_timeout = @read_timeout.to_f if @read_timeout
|
|
79
80
|
@bind_address = ConfigParser.handle_nil(bind_address)
|
|
80
|
-
if @bind_address
|
|
81
|
-
@bind_address = HOST_127_0_0_1
|
|
81
|
+
if @bind_address
|
|
82
|
+
@bind_address = HOST_127_0_0_1 if @bind_address.casecmp('LOCALHOST').zero?
|
|
83
|
+
else
|
|
84
|
+
# nil means all local addresses which is what 0.0.0.0 means
|
|
85
|
+
@bind_address = HOST_0_0_0_0
|
|
82
86
|
end
|
|
83
87
|
@write_socket = nil
|
|
84
88
|
@read_socket = nil
|
|
@@ -91,9 +95,9 @@ module OpenC3
|
|
|
91
95
|
result = ''
|
|
92
96
|
result += " #{@hostname}:#{@write_dest_port} (write dest port)" if @write_dest_port
|
|
93
97
|
result += " #{@write_src_port} (write src port)" if @write_src_port
|
|
94
|
-
result += " #{@
|
|
98
|
+
result += " #{@bind_address}:#{@read_port} (read)" if @read_port
|
|
95
99
|
result += " #{@interface_address} (interface addr)" if @interface_address
|
|
96
|
-
result += " #{@bind_address} (bind addr)" if @bind_address !=
|
|
100
|
+
result += " #{@bind_address} (bind addr)" if @bind_address != HOST_0_0_0_0
|
|
97
101
|
return result.strip
|
|
98
102
|
end
|
|
99
103
|
|
|
@@ -102,13 +106,20 @@ module OpenC3
|
|
|
102
106
|
# the constructor.
|
|
103
107
|
def connect
|
|
104
108
|
if @read_port and @write_dest_port and @write_src_port and (@read_port == @write_src_port)
|
|
109
|
+
# read_multicast is false because this socket is not connected and thus
|
|
110
|
+
# doesn't filter by peer address. Joining the multicast group we write to
|
|
111
|
+
# would deliver our own commands back to us as telemetry (multicast
|
|
112
|
+
# loopback is enabled by default).
|
|
105
113
|
@read_socket = UdpReadWriteSocket.new(
|
|
106
114
|
@read_port,
|
|
107
115
|
@bind_address,
|
|
108
116
|
@write_dest_port,
|
|
109
117
|
@hostname,
|
|
110
118
|
@interface_address,
|
|
111
|
-
@ttl
|
|
119
|
+
@ttl,
|
|
120
|
+
false, # read_multicast
|
|
121
|
+
true, # write_multicast
|
|
122
|
+
false # connect_socket
|
|
112
123
|
)
|
|
113
124
|
@write_socket = @read_socket
|
|
114
125
|
else
|
data/lib/openc3/interfaces.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/io/json_api.rb
CHANGED
|
@@ -35,8 +35,9 @@ module OpenC3
|
|
|
35
35
|
# pull openc3-cosmos-script-runner-api url from environment variables
|
|
36
36
|
def _generate_url(microservice_name:, prefix:, schema: 'http', hostname: nil, port:, scope: $openc3_scope)
|
|
37
37
|
prefix = '/' + prefix unless prefix[0] == '/'
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
operator_hostname = ENV.fetch('OPENC3_OPERATOR_HOSTNAME', nil)
|
|
39
|
+
if operator_hostname
|
|
40
|
+
hostname = operator_hostname unless hostname
|
|
40
41
|
return "#{schema}://#{hostname}:#{port.to_i}#{prefix}"
|
|
41
42
|
else
|
|
42
43
|
if ENV['KUBERNETES_SERVICE_HOST']
|
|
File without changes
|
data/lib/openc3/io/json_drb.rb
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
require 'socket'
|
|
19
19
|
require 'json'
|
|
20
|
+
require 'set'
|
|
20
21
|
# require 'drb/acl'
|
|
21
22
|
require 'drb/drb'
|
|
22
23
|
require 'openc3/io/json_rpc'
|
|
@@ -47,8 +48,9 @@ module OpenC3
|
|
|
47
48
|
# JsonDRb implements the JSON-RPC 2.0 Specification to provide an interface
|
|
48
49
|
# for both internal and external tools to access the OpenC3 server. It
|
|
49
50
|
# provides methods to install an access control list to control access to the
|
|
50
|
-
# API.
|
|
51
|
-
#
|
|
51
|
+
# API. Access is controlled by a required method_whitelist which names every
|
|
52
|
+
# method that may be invoked. There is no permissive fallback: any method not
|
|
53
|
+
# explicitly listed is rejected.
|
|
52
54
|
class JsonDRb
|
|
53
55
|
# Minimum amount of time in seconds to receive the JSON request,
|
|
54
56
|
# process it, and send the response. Requests for less than this amount
|
|
@@ -62,18 +64,21 @@ module OpenC3
|
|
|
62
64
|
|
|
63
65
|
# @return [Integer] The number of JSON-RPC requests processed
|
|
64
66
|
attr_accessor :request_count
|
|
65
|
-
# @return [
|
|
66
|
-
|
|
67
|
+
# @return [Set<String>] Set of downcased method names which may be called
|
|
68
|
+
attr_reader :method_whitelist
|
|
67
69
|
# @return [ACL] The access control list
|
|
68
70
|
# attr_accessor :acl
|
|
69
71
|
|
|
70
72
|
attr_accessor :object
|
|
71
73
|
|
|
72
|
-
|
|
74
|
+
# @param method_whitelist [Enumerable<String>] Every method name which may
|
|
75
|
+
# be called over JSON-RPC. Required and must not be empty since there is
|
|
76
|
+
# no permissive fallback.
|
|
77
|
+
def initialize(method_whitelist:)
|
|
78
|
+
self.method_whitelist = method_whitelist
|
|
73
79
|
@thread = nil
|
|
74
80
|
# @acl = nil
|
|
75
81
|
@object = nil
|
|
76
|
-
@method_whitelist = nil
|
|
77
82
|
@request_count = 0
|
|
78
83
|
@request_times = []
|
|
79
84
|
@request_times_index = 0
|
|
@@ -82,6 +87,18 @@ module OpenC3
|
|
|
82
87
|
@server_mutex = Mutex.new
|
|
83
88
|
end
|
|
84
89
|
|
|
90
|
+
# Replaces the set of methods which may be called over JSON-RPC. Names are
|
|
91
|
+
# downcased to match the dispatch in {#process_request}.
|
|
92
|
+
#
|
|
93
|
+
# @param whitelist [Enumerable<String>] Every method name which may be called
|
|
94
|
+
def method_whitelist=(whitelist)
|
|
95
|
+
if whitelist.nil? or whitelist.to_a.empty?
|
|
96
|
+
raise ArgumentError, "method_whitelist is required and must not be empty"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@method_whitelist = whitelist.map { |name| name.to_s.downcase }.to_set
|
|
100
|
+
end
|
|
101
|
+
|
|
85
102
|
# Returns the number of connected clients
|
|
86
103
|
# @return [Integer] The number of connected clients
|
|
87
104
|
def num_clients
|
|
@@ -254,8 +271,7 @@ module OpenC3
|
|
|
254
271
|
error_code = nil
|
|
255
272
|
response_data = nil
|
|
256
273
|
|
|
257
|
-
if
|
|
258
|
-
(!@method_whitelist and !JsonRpcRequest::DANGEROUS_METHODS.include?(request.method.downcase()))
|
|
274
|
+
if @method_whitelist.include?(request.method.downcase())
|
|
259
275
|
begin
|
|
260
276
|
if request.keyword_params
|
|
261
277
|
result = @object.public_send(request.method.downcase().intern, *request.params, **request.keyword_params)
|
|
@@ -266,10 +282,26 @@ module OpenC3
|
|
|
266
282
|
response = JsonRpcSuccessResponse.new(result, request.id)
|
|
267
283
|
end
|
|
268
284
|
rescue Exception => e
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
285
|
+
error_name = e.class.name.split('::')[-1]
|
|
286
|
+
method_name = request.method.downcase()
|
|
287
|
+
case e
|
|
288
|
+
when AuthError, ForbiddenError
|
|
289
|
+
# Auth failures are expected (e.g. browser requests before login or with an
|
|
290
|
+
# expired session token) so log a single line without the stack trace
|
|
291
|
+
Logger.warn "#{error_name} : #{e.message} calling #{method_name}"
|
|
292
|
+
when HazardousError, CriticalCmdError
|
|
293
|
+
# Not errors at all: these are the signal that the UI should raise an
|
|
294
|
+
# operator confirmation dialog, and the user retries with the hazardous
|
|
295
|
+
# or critical flag set. A stack trace per prompt is pure noise, and
|
|
296
|
+
# HazardousError#to_s embeds the formatted command with a newline,
|
|
297
|
+
# so log just the error name and the method that raised it.
|
|
298
|
+
Logger.info "#{error_name} calling #{method_name}"
|
|
299
|
+
else
|
|
300
|
+
# Filter out the framework stack trace (rails, rack, puma etc)
|
|
301
|
+
lines = e.formatted.split("\n")
|
|
302
|
+
i = lines.find_index { |row| row.include?('actionpack') || row.include?('activesupport') }
|
|
303
|
+
Logger.error lines[0...(i || lines.length)].join("\n")
|
|
304
|
+
end
|
|
273
305
|
|
|
274
306
|
if request.id
|
|
275
307
|
if NoMethodError === e
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/io/json_rpc.rb
CHANGED
|
@@ -227,8 +227,6 @@ module OpenC3
|
|
|
227
227
|
|
|
228
228
|
# Represents a JSON Remote Procedure Call Request
|
|
229
229
|
class JsonRpcRequest < JsonRpc
|
|
230
|
-
DANGEROUS_METHODS = Set['__send__', 'send', 'instance_eval', 'instance_exec']
|
|
231
|
-
|
|
232
230
|
# @param method_name [String] The name of the method to call
|
|
233
231
|
# @param method_params [Array<String>] Array of strings which represent the
|
|
234
232
|
# parameters to send to the method
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/io/stderr.rb
CHANGED
|
File without changes
|
data/lib/openc3/io/stdout.rb
CHANGED
|
File without changes
|
|
@@ -27,6 +27,9 @@ module OpenC3
|
|
|
27
27
|
class UdpReadWriteSocket
|
|
28
28
|
HOST_0_0_0_0 = '0.0.0.0'
|
|
29
29
|
|
|
30
|
+
# MSG_DONTWAIT is not defined on Windows where sends are left blocking
|
|
31
|
+
WRITE_FLAGS = Socket.const_defined?('MSG_DONTWAIT') ? Socket::MSG_DONTWAIT : 0
|
|
32
|
+
|
|
30
33
|
# @param bind_port [Integer[ Port to write data out from and receive data on (0 = randomly assigned)
|
|
31
34
|
# @param bind_address [String] Local address to bind to (0.0.0.0 = All local addresses)
|
|
32
35
|
# @param external_port [Integer] External port to write to
|
|
@@ -35,6 +38,8 @@ module OpenC3
|
|
|
35
38
|
# @param ttl [Integer] Time To Live for outgoing multicast packets
|
|
36
39
|
# @param read_multicast [Boolean] Whether or not to try to read from the external address as multicast
|
|
37
40
|
# @param write_multicast [Boolean] Whether or not to write to the external address as multicast
|
|
41
|
+
# @param connect_socket [Boolean] Whether to connect the socket to the external address. If false,
|
|
42
|
+
# writes explicitly address each datagram so reads can accept datagrams from any source.
|
|
38
43
|
def initialize(
|
|
39
44
|
bind_port = 0,
|
|
40
45
|
bind_address = HOST_0_0_0_0,
|
|
@@ -43,10 +48,23 @@ module OpenC3
|
|
|
43
48
|
multicast_interface_address = nil,
|
|
44
49
|
ttl = 1,
|
|
45
50
|
read_multicast = true,
|
|
46
|
-
write_multicast = true
|
|
51
|
+
write_multicast = true,
|
|
52
|
+
connect_socket = true
|
|
47
53
|
)
|
|
48
54
|
|
|
49
55
|
@socket = UDPSocket.new
|
|
56
|
+
@external_address = external_address
|
|
57
|
+
@external_port = external_port
|
|
58
|
+
@connect_socket = connect_socket
|
|
59
|
+
# Resolve the destination once at creation time so writes don't pay for a
|
|
60
|
+
# (potentially blocking) name lookup on every datagram
|
|
61
|
+
@external_sockaddr = nil
|
|
62
|
+
if !connect_socket and external_address and external_port
|
|
63
|
+
# Explicitly resolve IPv4 because UDPSocket is an AF_INET socket and
|
|
64
|
+
# sockaddr_in would otherwise hand back an IPv6 address for names like localhost
|
|
65
|
+
ip_address = Socket.getaddrinfo(external_address, nil, Socket::AF_INET, Socket::SOCK_DGRAM)[0][3]
|
|
66
|
+
@external_sockaddr = Socket.sockaddr_in(external_port, ip_address)
|
|
67
|
+
end
|
|
50
68
|
|
|
51
69
|
# Basic setup to reuse address
|
|
52
70
|
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
|
|
@@ -55,10 +73,10 @@ module OpenC3
|
|
|
55
73
|
@socket.bind(bind_address, bind_port) if bind_address and bind_port
|
|
56
74
|
|
|
57
75
|
# Default send to the specified address and port
|
|
58
|
-
@socket.connect(external_address, external_port) if external_address and external_port
|
|
76
|
+
@socket.connect(external_address, external_port) if connect_socket and external_address and external_port
|
|
59
77
|
|
|
60
78
|
# Handle multicast
|
|
61
|
-
if UdpReadWriteSocket.multicast?(external_address
|
|
79
|
+
if UdpReadWriteSocket.multicast?(external_address)
|
|
62
80
|
if write_multicast
|
|
63
81
|
# Basic setup set time to live
|
|
64
82
|
@socket.setsockopt(Socket::IPPROTO_IP, Socket::IP_MULTICAST_TTL, ttl.to_i)
|
|
@@ -90,7 +108,13 @@ module OpenC3
|
|
|
90
108
|
|
|
91
109
|
loop do
|
|
92
110
|
begin
|
|
93
|
-
|
|
111
|
+
if @external_sockaddr
|
|
112
|
+
# send is used rather than sendmsg_nonblock because sendmsg is not
|
|
113
|
+
# implemented on Windows
|
|
114
|
+
bytes_sent = @socket.send(data_to_send, WRITE_FLAGS, @external_sockaddr)
|
|
115
|
+
else
|
|
116
|
+
bytes_sent = @socket.write_nonblock(data_to_send)
|
|
117
|
+
end
|
|
94
118
|
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
|
95
119
|
result = IO.fast_select(nil, [@socket], nil, write_timeout)
|
|
96
120
|
if result
|
|
@@ -129,12 +153,18 @@ module OpenC3
|
|
|
129
153
|
end
|
|
130
154
|
|
|
131
155
|
# @param host [String] Machine name or IP address
|
|
132
|
-
# @param port [String] Port
|
|
156
|
+
# @param port [String] Port (unused, kept for backwards compatibility)
|
|
133
157
|
# @return [Boolean] Whether the hostname is multicast
|
|
134
|
-
def self.multicast?(host, port)
|
|
135
|
-
return false if host.nil?
|
|
158
|
+
def self.multicast?(host, port = nil)
|
|
159
|
+
return false if host.nil?
|
|
136
160
|
|
|
137
|
-
|
|
161
|
+
begin
|
|
162
|
+
Addrinfo.udp(host, 0).ipv4_multicast?
|
|
163
|
+
rescue SocketError, ArgumentError
|
|
164
|
+
# Hostname isn't resolvable so it can't be a multicast address we handle.
|
|
165
|
+
# Reads don't need the hostname at all so don't fail creating the socket.
|
|
166
|
+
false
|
|
167
|
+
end
|
|
138
168
|
end
|
|
139
169
|
end
|
|
140
170
|
|
|
File without changes
|
|
File without changes
|
|
@@ -113,6 +113,7 @@ module OpenC3
|
|
|
113
113
|
@cycle_minute = Integer(@cycle_minute) if @cycle_minute
|
|
114
114
|
@enforce_time_order = ConfigParser.handle_true_false(enforce_time_order)
|
|
115
115
|
@out_of_order = false
|
|
116
|
+
@bad_time = false
|
|
116
117
|
@mutex = Mutex.new
|
|
117
118
|
@file = nil
|
|
118
119
|
@file_size = 0
|
|
@@ -125,6 +126,13 @@ module OpenC3
|
|
|
125
126
|
@cleanup_offsets = []
|
|
126
127
|
@cleanup_times = []
|
|
127
128
|
@previous_time_nsec_since_epoch = nil
|
|
129
|
+
# Stored packets older than 20 years are treated as invalid (e.g. 1970 before
|
|
130
|
+
# clock/GPS sync). They never drive file segmentation nor become the ordering
|
|
131
|
+
# baseline, so a late-syncing clock doesn't thrash log files.
|
|
132
|
+
@min_valid_time_nsec = (@start_time - (20 * 365 * 24 * 60 * 60)).to_nsec_from_epoch
|
|
133
|
+
# Validity (valid/invalid time) of the packets in the currently open file. Used to
|
|
134
|
+
# segregate invalid-time (1970) packets into their own file. nil = no packets yet.
|
|
135
|
+
@current_file_valid = nil
|
|
128
136
|
@tmp_dir = Dir.mktmpdir
|
|
129
137
|
@wait_threads = []
|
|
130
138
|
|
|
@@ -280,6 +288,7 @@ module OpenC3
|
|
|
280
288
|
@first_time = nil
|
|
281
289
|
@last_time = nil
|
|
282
290
|
@previous_time_nsec_since_epoch = nil
|
|
291
|
+
@current_file_valid = nil
|
|
283
292
|
Logger.debug "Log File Opened : #{@filename}"
|
|
284
293
|
rescue => e
|
|
285
294
|
Logger.error "Error starting new log file: #{e.formatted}"
|
|
@@ -289,7 +298,14 @@ module OpenC3
|
|
|
289
298
|
|
|
290
299
|
# @enforce_time_order requires the timestamps on each write to be greater than the previous
|
|
291
300
|
# process_out_of_order ignores the timestamps for the current entry (used to ignore timestamps on metadata entries, vs actual packets)
|
|
292
|
-
|
|
301
|
+
# stored: stored packets roll a new file when GOOD times move backward (a new /
|
|
302
|
+
# overlapping replay run). Packets with an invalid time (e.g. 1970 before clock/GPS
|
|
303
|
+
# sync) - realtime or stored - are segregated into their own file: the first valid
|
|
304
|
+
# packet after a run of 1970s rolls a fresh, properly-named file (and vice-versa).
|
|
305
|
+
def prepare_write(time_nsec_since_epoch, data_length, redis_topic = nil, redis_offset = nil, allow_new_file: true, process_out_of_order: true, stored: false)
|
|
306
|
+
# An invalid time is a packet from before the clock/GPS synced (e.g. 1970). This
|
|
307
|
+
# applies to both realtime and stored packets so neither taints a file's filename.
|
|
308
|
+
packet_valid = !(process_out_of_order and time_nsec_since_epoch < @min_valid_time_nsec)
|
|
293
309
|
# This check includes logging_enabled again because it might have changed since we acquired the mutex
|
|
294
310
|
# Ensures new files based on size, and ensures always increasing time order in files
|
|
295
311
|
if @logging_enabled
|
|
@@ -299,17 +315,37 @@ module OpenC3
|
|
|
299
315
|
elsif @cycle_size and ((@file_size + data_length) > @cycle_size)
|
|
300
316
|
Logger.debug("Log writer start new file due to cycle size #{@cycle_size}")
|
|
301
317
|
start_new_file() if allow_new_file
|
|
318
|
+
elsif process_out_of_order and !@current_file_valid.nil? and packet_valid != @current_file_valid and allow_new_file
|
|
319
|
+
# Time validity changed (1970 <-> valid): segregate invalid-time packets into
|
|
320
|
+
# their own file so valid files keep a clean, correctly-timed filename.
|
|
321
|
+
Logger.debug("Log writer start new file due to time validity change")
|
|
322
|
+
start_new_file()
|
|
302
323
|
elsif process_out_of_order and @enforce_time_order and @previous_time_nsec_since_epoch and (@previous_time_nsec_since_epoch > time_nsec_since_epoch)
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
Logger.
|
|
307
|
-
|
|
324
|
+
if stored and packet_valid and allow_new_file
|
|
325
|
+
# Good stored time went backward => new/overlapping replay run. Roll a new
|
|
326
|
+
# file so each stored file stays monotonic (start_new_file resets @previous_time).
|
|
327
|
+
Logger.debug("Log writer start new file due to out of order stored time")
|
|
328
|
+
start_new_file()
|
|
329
|
+
elsif !stored
|
|
330
|
+
# Warning: Creating new files here can cause lots of files to be created if packets make it through out of order
|
|
331
|
+
# Changed to just a warning to prevent file thrashing
|
|
332
|
+
unless @out_of_order
|
|
333
|
+
Logger.warn("Log writer out of order time detected (increase buffer depth?): #{Time.from_nsec_from_epoch(@previous_time_nsec_since_epoch)} #{Time.from_nsec_from_epoch(time_nsec_since_epoch)}")
|
|
334
|
+
@out_of_order = true
|
|
335
|
+
end
|
|
308
336
|
end
|
|
309
337
|
end
|
|
310
338
|
end
|
|
311
339
|
@last_offsets[redis_topic] = redis_offset if redis_topic and redis_offset # This is needed for the redis offset marker entry at the end of the log file
|
|
312
|
-
|
|
340
|
+
if process_out_of_order
|
|
341
|
+
@current_file_valid = packet_valid
|
|
342
|
+
if packet_valid
|
|
343
|
+
@previous_time_nsec_since_epoch = time_nsec_since_epoch
|
|
344
|
+
elsif !@bad_time
|
|
345
|
+
Logger.warn("Log writer segregating invalid packet time (before clock sync?): #{Time.from_nsec_from_epoch(time_nsec_since_epoch)}")
|
|
346
|
+
@bad_time = true
|
|
347
|
+
end
|
|
348
|
+
end
|
|
313
349
|
end
|
|
314
350
|
|
|
315
351
|
# Closing a log file isn't critical so we just log an error. NOTE: This also trims the Redis stream
|
|
File without changes
|
|
@@ -142,7 +142,7 @@ module OpenC3
|
|
|
142
142
|
end
|
|
143
143
|
elsif flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_RAW_PACKET_ENTRY_TYPE_MASK
|
|
144
144
|
packet_index, time_nsec_since_epoch = entry[2..11].unpack('nQ>')
|
|
145
|
-
received_time_nsec_since_epoch,
|
|
145
|
+
received_time_nsec_since_epoch, extra, packet_data = handle_received_time_extra_and_data(entry, time_nsec_since_epoch, includes_received_time, includes_extra, cbor)
|
|
146
146
|
lookup_cmd_or_tlm, target_name, packet_name, _id = @packets[packet_index]
|
|
147
147
|
if cmd_or_tlm != lookup_cmd_or_tlm
|
|
148
148
|
raise "Packet type mismatch, packet:#{cmd_or_tlm}, lookup:#{lookup_cmd_or_tlm}"
|
|
@@ -159,6 +159,10 @@ module OpenC3
|
|
|
159
159
|
packet.set_received_time_fast(received_time)
|
|
160
160
|
packet.cmd_or_tlm = cmd_or_tlm
|
|
161
161
|
packet.stored = stored
|
|
162
|
+
# Assigned unconditionally because identify_and_define_packet_data
|
|
163
|
+
# returns the shared System packet, so a nil extra here must clear
|
|
164
|
+
# the extra left over from a previous read of the same packet
|
|
165
|
+
packet.extra = extra
|
|
162
166
|
packet.received_count += 1
|
|
163
167
|
return packet
|
|
164
168
|
elsif flags & OPENC3_ENTRY_TYPE_MASK == OPENC3_TARGET_DECLARATION_ENTRY_TYPE_MASK
|
|
@@ -304,7 +308,24 @@ module OpenC3
|
|
|
304
308
|
if cbor
|
|
305
309
|
extra = CBOR.decode(extra_encoded)
|
|
306
310
|
else
|
|
307
|
-
|
|
311
|
+
begin
|
|
312
|
+
extra = JSON.parse(extra_encoded, allow_nan: true, create_additions: true)
|
|
313
|
+
rescue JSON::ParserError => e
|
|
314
|
+
# PacketLogWriter up to version 7.3.0 CBOR encoded the extra on
|
|
315
|
+
# RAW_PACKET entries without setting OPENC3_CBOR_FLAG_MASK, so the
|
|
316
|
+
# flag claims JSON while the bytes are CBOR. Retry as CBOR so those
|
|
317
|
+
# existing files can still be read. extra is always a Hash, so a
|
|
318
|
+
# decode to anything else means these bytes aren't the legacy
|
|
319
|
+
# encoding either and the original JSON error is the useful one.
|
|
320
|
+
decoded = begin
|
|
321
|
+
CBOR.decode(extra_encoded)
|
|
322
|
+
rescue StandardError
|
|
323
|
+
raise e
|
|
324
|
+
end
|
|
325
|
+
raise e unless Hash === decoded
|
|
326
|
+
|
|
327
|
+
extra = decoded
|
|
328
|
+
end
|
|
308
329
|
end
|
|
309
330
|
end
|
|
310
331
|
data = entry[next_offset..-1]
|
|
@@ -96,13 +96,12 @@ module OpenC3
|
|
|
96
96
|
@mutex.lock if take_mutex
|
|
97
97
|
begin
|
|
98
98
|
if entry_type == :RAW_PACKET or entry_type == :JSON_PACKET
|
|
99
|
-
# Only care about the timestamps on the real packets being in order
|
|
100
99
|
process_out_of_order = true
|
|
101
100
|
else
|
|
102
101
|
# Metadata timestamps don't matter
|
|
103
102
|
process_out_of_order = false
|
|
104
103
|
end
|
|
105
|
-
prepare_write(time_nsec_since_epoch, data.length, redis_topic, redis_offset, allow_new_file: allow_new_file, process_out_of_order: process_out_of_order)
|
|
104
|
+
prepare_write(time_nsec_since_epoch, data.length, redis_topic, redis_offset, allow_new_file: allow_new_file, process_out_of_order: process_out_of_order, stored: stored)
|
|
106
105
|
write_entry(entry_type, cmd_or_tlm, target_name, packet_name, time_nsec_since_epoch, stored, data, id, received_time_nsec_since_epoch: received_time_nsec_since_epoch, extra: extra) if @file
|
|
107
106
|
ensure
|
|
108
107
|
@mutex.unlock if take_mutex
|
|
@@ -312,6 +311,11 @@ module OpenC3
|
|
|
312
311
|
extra = JSON.parse(extra, allow_nan: true, create_additions: true) if String === extra
|
|
313
312
|
length += OPENC3_EXTRA_LENGTH_FIXED_SIZE
|
|
314
313
|
if @data_format == :CBOR
|
|
314
|
+
# The reader uses this same flag to pick the extra decoder, so it
|
|
315
|
+
# must be set here as well as in the JSON_PACKET data branch above.
|
|
316
|
+
# RAW_PACKET entries never reach that branch and would otherwise
|
|
317
|
+
# write CBOR extra that the reader tries to JSON.parse.
|
|
318
|
+
flags |= OPENC3_CBOR_FLAG_MASK
|
|
315
319
|
extra_encoded = extra.as_json.to_cbor
|
|
316
320
|
else
|
|
317
321
|
extra_encoded = JSON.generate(extra.as_json, allow_nan: true)
|
|
@@ -47,7 +47,7 @@ module OpenC3
|
|
|
47
47
|
raise "log_type must be :READ or :WRITE" unless LOG_TYPES.include? log_type
|
|
48
48
|
|
|
49
49
|
super(
|
|
50
|
-
"#{ENV
|
|
50
|
+
"#{ENV.fetch('OPENC3_SCOPE', 'DEFAULT')}/stream_logs/",
|
|
51
51
|
true, # Start with logging enabled
|
|
52
52
|
cycle_time,
|
|
53
53
|
cycle_size,
|
|
File without changes
|
|
File without changes
|
data/lib/openc3/logs.rb
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -33,7 +33,8 @@ module OpenC3
|
|
|
33
33
|
end
|
|
34
34
|
stored = inject_tlm_hash.fetch('stored', false)
|
|
35
35
|
packet.stored = stored.to_s.downcase == 'true'
|
|
36
|
-
|
|
36
|
+
received_time = inject_tlm_hash['received_time']
|
|
37
|
+
packet.received_time = received_time.nil? ? Time.now.sys : Time.from_nsec_from_epoch(received_time).sys
|
|
37
38
|
packet.received_count = TargetModel.increment_telemetry_count(packet.target_name, packet.packet_name, 1, scope: @scope)
|
|
38
39
|
TelemetryTopic.write_packet(packet, scope: @scope)
|
|
39
40
|
end
|