openc3 7.3.0 → 7.4.1
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 +139 -0
- data/bin/pipuninstall +0 -0
- data/bin/uvinstall +10 -3
- 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 +0 -0
- data/data/config/microservice.yaml +5 -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 +0 -0
- 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 +0 -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 +0 -0
- data/data/config/unknown.yaml +0 -0
- data/data/config/widgets.yaml +6 -0
- data/data/xtce_schemas/SpaceSystem_20180204.xsd +0 -0
- data/data/xtce_schemas/xml.xsd +0 -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 +0 -0
- 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 +0 -0
- 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 +0 -0
- data/lib/openc3/api/limits_api.rb +0 -0
- 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 +0 -0
- 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 +19 -14
- 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 +0 -0
- 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 +12 -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 +24 -3
- data/lib/openc3/io/json_drb.rb +20 -4
- data/lib/openc3/io/json_drb_object.rb +3 -2
- data/lib/openc3/io/json_drb_rack.rb +0 -0
- data/lib/openc3/io/json_rpc.rb +0 -0
- 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 +0 -0
- 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 +5 -0
- 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 +72 -25
- 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 +11 -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 +0 -0
- 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 +12 -9
- 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 +178 -19
- 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 +9 -22
- 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 +9 -2
- 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 +4 -4
- data/lib/openc3/models/queue_model.rb +0 -0
- data/lib/openc3/models/reaction_model.rb +6 -3
- 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 +51 -26
- 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 +548 -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 +30 -25
- 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 +1 -0
- 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 +64 -22
- 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 +0 -0
- data/lib/openc3/packets/json_packet.rb +0 -0
- data/lib/openc3/packets/limits.rb +0 -0
- data/lib/openc3/packets/limits_response.rb +0 -0
- data/lib/openc3/packets/packet.rb +4 -0
- data/lib/openc3/packets/packet_config.rb +36 -1
- 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 +0 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +0 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +8 -1
- data/lib/openc3/packets/structure.rb +7 -1
- data/lib/openc3/packets/structure_item.rb +0 -0
- data/lib/openc3/packets/telemetry.rb +0 -0
- 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 +0 -0
- data/lib/openc3/script/critical_cmd.rb +0 -0
- data/lib/openc3/script/exceptions.rb +0 -0
- data/lib/openc3/script/extract.rb +0 -0
- 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 +5 -1
- data/lib/openc3/script/telemetry.rb +9 -3
- data/lib/openc3/script/web_socket_api.rb +218 -145
- 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 +0 -0
- 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 +0 -0
- 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 +2 -2
- 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 +0 -0
- 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 +32 -6
- 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 +29 -46
- 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 +0 -0
- data/lib/openc3/utilities/rubygems_url.rb +39 -0
- data/lib/openc3/utilities/running_script.rb +24 -55
- data/lib/openc3/utilities/s3_autoload.rb +5 -5
- data/lib/openc3/utilities/script.rb +12 -8
- 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 +0 -0
- 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 +56 -9
|
@@ -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
|
|
File without changes
|
|
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]
|
|
@@ -311,6 +311,11 @@ module OpenC3
|
|
|
311
311
|
extra = JSON.parse(extra, allow_nan: true, create_additions: true) if String === extra
|
|
312
312
|
length += OPENC3_EXTRA_LENGTH_FIXED_SIZE
|
|
313
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
|
|
314
319
|
extra_encoded = extra.as_json.to_cbor
|
|
315
320
|
else
|
|
316
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
|
|
@@ -221,7 +221,12 @@ module OpenC3
|
|
|
221
221
|
next 'SUCCESS'
|
|
222
222
|
end
|
|
223
223
|
if msg_hash.key?('interface_details')
|
|
224
|
-
|
|
224
|
+
begin
|
|
225
|
+
next @interface.details.as_json.to_json(allow_nan: true)
|
|
226
|
+
rescue => e
|
|
227
|
+
@logger.error "#{@interface.name}: interface_details: #{e.formatted}"
|
|
228
|
+
next e.message
|
|
229
|
+
end
|
|
225
230
|
end
|
|
226
231
|
end
|
|
227
232
|
|
|
@@ -508,7 +513,12 @@ module OpenC3
|
|
|
508
513
|
next 'SUCCESS'
|
|
509
514
|
end
|
|
510
515
|
if msg_hash.key?('router_details')
|
|
511
|
-
|
|
516
|
+
begin
|
|
517
|
+
next @router.details.as_json.to_json(allow_nan: true)
|
|
518
|
+
rescue => e
|
|
519
|
+
@logger.error "#{@router.name}: router_details: #{e.formatted}"
|
|
520
|
+
next e.message
|
|
521
|
+
end
|
|
512
522
|
end
|
|
513
523
|
next 'SUCCESS'
|
|
514
524
|
end
|
|
@@ -610,7 +620,26 @@ module OpenC3
|
|
|
610
620
|
# Called to connect the interface/router. It takes optional parameters to
|
|
611
621
|
# rebuilt the interface/router. Once we set the state to 'ATTEMPTING' the
|
|
612
622
|
# run method handles the actual connection.
|
|
623
|
+
# Connecting an interface/router which is already CONNECTED is a no-op.
|
|
624
|
+
# Without this the existing (working) connection would be torn down and
|
|
625
|
+
# rebuilt which can take up to the read_timeout to detect. Callers who want
|
|
626
|
+
# to force a reconnect should disconnect first or pass new parameters.
|
|
613
627
|
def attempting(*params)
|
|
628
|
+
if params.empty? and @interface.state == 'CONNECTED' and @interface.connected?
|
|
629
|
+
@logger.info "#{@interface.name}: Connect ignored, already connected"
|
|
630
|
+
return @interface
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
attempt_connection(*params)
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
# Sets the state to 'ATTEMPTING', first rebuilding the interface/router if
|
|
637
|
+
# parameters are given, so the run method performs the actual connection.
|
|
638
|
+
# Unlike attempting() this always transitions. The reconnect path in
|
|
639
|
+
# disconnect() requires that, since @interface.disconnect may have raised or
|
|
640
|
+
# left connected? true, which would make attempting() ignore the request and
|
|
641
|
+
# leave the interface stuck in 'CONNECTED' with no way back to a connection.
|
|
642
|
+
def attempt_connection(*params)
|
|
614
643
|
unless params.empty?
|
|
615
644
|
@interface.disconnect()
|
|
616
645
|
# Build New Interface, this can fail if passed bad parameters
|
|
@@ -828,6 +857,13 @@ module OpenC3
|
|
|
828
857
|
|
|
829
858
|
def connect
|
|
830
859
|
@logger.info "#{@interface.name}: Connect #{@interface.connection_string}"
|
|
860
|
+
# Interface connect implementations typically overwrite their stream / socket
|
|
861
|
+
# so cleanly close any existing connection rather than leaking it
|
|
862
|
+
begin
|
|
863
|
+
@interface.disconnect if @interface.connected?
|
|
864
|
+
rescue => e
|
|
865
|
+
@logger.error "Disconnect: #{@interface.name}: #{e.formatted}"
|
|
866
|
+
end
|
|
831
867
|
begin
|
|
832
868
|
@interface.connect
|
|
833
869
|
@interface.post_connect
|
|
@@ -849,38 +885,49 @@ module OpenC3
|
|
|
849
885
|
end
|
|
850
886
|
|
|
851
887
|
def disconnect(allow_reconnect = true)
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
#
|
|
855
|
-
#
|
|
856
|
-
#
|
|
888
|
+
reconnect = false
|
|
889
|
+
|
|
890
|
+
# Two threads reach here for a single connection loss: the cmd handler
|
|
891
|
+
# thread servicing a disconnect directive, and the run thread coming back
|
|
892
|
+
# out of read (or out of the connection maintenance sleep). The redundant
|
|
893
|
+
# check below and the state change that records the disconnect must be in
|
|
894
|
+
# the same critical section, otherwise the second thread reads the state
|
|
895
|
+
# before the first has updated it and disconnects the interface twice.
|
|
857
896
|
@mutex.synchronize do
|
|
897
|
+
# A disconnect has already been performed so there is nothing left to do
|
|
898
|
+
return if @interface.state == 'DISCONNECTED' && !@interface.connected?
|
|
899
|
+
|
|
900
|
+
# Call disconnect without consulting connected? so any resources the
|
|
901
|
+
# interface is still holding are cleaned up. It takes an unknown amount
|
|
902
|
+
# of time which is the other reason for the mutex.
|
|
858
903
|
begin
|
|
859
|
-
@interface.disconnect
|
|
904
|
+
@interface.disconnect
|
|
860
905
|
rescue => e
|
|
861
906
|
@logger.error "Disconnect: #{@interface.name}: #{e.formatted}"
|
|
862
907
|
end
|
|
863
|
-
end
|
|
864
908
|
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
@
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
else
|
|
880
|
-
RouterStatusModel.set(@interface.as_json(), queued: true, scope: @scope)
|
|
909
|
+
# If the interface is set to auto_reconnect then delay so the thread
|
|
910
|
+
# can come back around and allow the interface a chance to reconnect.
|
|
911
|
+
# Skip reconnect if stop() has been called to avoid re-creating the status model
|
|
912
|
+
reconnect = allow_reconnect && @interface.auto_reconnect && @interface.state != 'DISCONNECTED' && !@cancel_thread
|
|
913
|
+
if reconnect
|
|
914
|
+
attempt_connection()
|
|
915
|
+
else
|
|
916
|
+
@interface.state = 'DISCONNECTED'
|
|
917
|
+
unless @cancel_thread
|
|
918
|
+
if @interface_or_router == 'INTERFACE'
|
|
919
|
+
InterfaceStatusModel.set(@interface.as_json(), queued: true, scope: @scope)
|
|
920
|
+
else
|
|
921
|
+
RouterStatusModel.set(@interface.as_json(), queued: true, scope: @scope)
|
|
922
|
+
end
|
|
881
923
|
end
|
|
882
924
|
end
|
|
883
925
|
end
|
|
926
|
+
|
|
927
|
+
# Sleep outside the mutex so stop() and connect() are not blocked for the
|
|
928
|
+
# whole reconnect delay
|
|
929
|
+
# @logger.debug "reconnect delay: #{@interface.reconnect_delay}"
|
|
930
|
+
@interface_thread_sleeper.sleep(@interface.reconnect_delay) if reconnect && !@cancel_thread
|
|
884
931
|
end
|
|
885
932
|
|
|
886
933
|
# Disconnect from the interface and stop the thread
|
|
File without changes
|
|
@@ -43,7 +43,7 @@ module OpenC3
|
|
|
43
43
|
attr_accessor :secrets
|
|
44
44
|
|
|
45
45
|
def self.run(name = nil)
|
|
46
|
-
name = ENV
|
|
46
|
+
name = ENV.fetch('OPENC3_MICROSERVICE_NAME', nil) unless name
|
|
47
47
|
microservice = self.new(name)
|
|
48
48
|
thread = Thread.new do
|
|
49
49
|
begin
|
|
@@ -150,7 +150,7 @@ module OpenC3
|
|
|
150
150
|
cmd_array = @config["cmd"]
|
|
151
151
|
|
|
152
152
|
# Get Microservice files from bucket storage
|
|
153
|
-
bucket = ENV
|
|
153
|
+
bucket = ENV.fetch('OPENC3_CONFIG_BUCKET') { raise 'OPENC3_CONFIG_BUCKET environment variable is required' }
|
|
154
154
|
client = Bucket.getClient()
|
|
155
155
|
|
|
156
156
|
prefix = "#{@scope}/microservices/#{@name}/"
|
|
@@ -160,7 +160,7 @@ module OpenC3
|
|
|
160
160
|
# unreachable while many microservices start at once. Rather than crash
|
|
161
161
|
# and CrashLoopBackOff (which can outlast deploy timeouts), retry for a
|
|
162
162
|
# bounded time before giving up.
|
|
163
|
-
startup_timeout = (ENV
|
|
163
|
+
startup_timeout = (ENV.fetch('OPENC3_MICROSERVICE_STARTUP_BUCKET_TIMEOUT', 60)).to_f
|
|
164
164
|
startup_deadline = Time.now + startup_timeout
|
|
165
165
|
begin
|
|
166
166
|
file_count = 0
|
|
@@ -46,8 +46,8 @@ module OpenC3
|
|
|
46
46
|
NewsModel.news_error("Error contacting OpenC3 news feed (status: #{response.status})")
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
|
-
rescue
|
|
50
|
-
NewsModel.news_error("Error contacting OpenC3 news feed. #{e.message}
|
|
49
|
+
rescue StandardError => e
|
|
50
|
+
NewsModel.news_error("Error contacting OpenC3 news feed. #{e.message}")
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def run
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Copyright 2026 OpenC3, Inc.
|
|
2
|
+
# All Rights Reserved.
|
|
3
|
+
#
|
|
4
|
+
# This program is distributed in the hope that it will be useful,
|
|
5
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
6
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
7
|
+
# See LICENSE.md for more details.
|
|
8
|
+
|
|
9
|
+
# This file may also be used under the terms of a commercial license
|
|
10
|
+
# if purchased from OpenC3, Inc.
|
|
11
|
+
|
|
12
|
+
require 'openc3/utilities/migration'
|
|
13
|
+
require 'openc3/models/scope_model'
|
|
14
|
+
require 'openc3/models/microservice_model'
|
|
15
|
+
require 'openc3/models/bridge_model'
|
|
16
|
+
|
|
17
|
+
module OpenC3
|
|
18
|
+
# Ensure every existing scope has a DEFAULT bridge_microservice (the Iroh hub
|
|
19
|
+
# that lets openc3-app run COSMOS interfaces on the host). New scopes get one
|
|
20
|
+
# via ScopeModel#deploy; this backfills any scope created before that.
|
|
21
|
+
class DefaultBridge < Migration
|
|
22
|
+
def self.run
|
|
23
|
+
ScopeModel.get_all_models(scope: nil).each do |scope, scope_model|
|
|
24
|
+
name = "#{scope}__BRIDGE__DEFAULT"
|
|
25
|
+
next if MicroserviceModel.get_model(name: name, scope: scope)
|
|
26
|
+
|
|
27
|
+
microservice = BridgeModel.build_microservice(bridge_name: "DEFAULT", scope: scope, shard: scope_model.shard)
|
|
28
|
+
microservice.create
|
|
29
|
+
microservice.deploy
|
|
30
|
+
Logger.info("Added DEFAULT bridge_microservice to scope #{scope}")
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
unless ENV['OPENC3_NO_MIGRATE']
|
|
37
|
+
OpenC3::DefaultBridge.run
|
|
38
|
+
end
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
# Copyright 2026 OpenC3, Inc.
|
|
2
|
+
# All Rights Reserved.
|
|
3
|
+
#
|
|
4
|
+
# This program is distributed in the hope that it will be useful,
|
|
5
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
6
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
7
|
+
# See LICENSE.md for more details.
|
|
8
|
+
#
|
|
9
|
+
# This file may also be used under the terms of a commercial license
|
|
10
|
+
# if purchased from OpenC3, Inc.
|
|
11
|
+
|
|
1
12
|
require 'json'
|
|
2
13
|
require 'openc3/utilities/local_mode'
|
|
3
14
|
require 'openc3/utilities/migration'
|
|
File without changes
|
|
@@ -27,7 +27,7 @@ module OpenC3
|
|
|
27
27
|
PRIMARY_KEY = 'OPENC3__TOKEN' # for argon2 password hash
|
|
28
28
|
SESSIONS_KEY = 'OPENC3__SESSIONS' # for hash containing session tokens
|
|
29
29
|
|
|
30
|
-
# The length of time in
|
|
30
|
+
# The length of time in seconds to keep redis values in memory
|
|
31
31
|
PW_HASH_CACHE_TIMEOUT = 5
|
|
32
32
|
SESSION_CACHE_TIMEOUT = 5
|
|
33
33
|
|
|
@@ -44,6 +44,21 @@ module OpenC3
|
|
|
44
44
|
SESSION_PREFIX = "ses_"
|
|
45
45
|
OTP_PREFIX = "otp_"
|
|
46
46
|
|
|
47
|
+
# A session token is SESSION_PREFIX followed by the unpadded urlsafe base64
|
|
48
|
+
# encoding of 16 random bytes, i.e. exactly 22 characters of [A-Za-z0-9_-].
|
|
49
|
+
# Keep this in sync with generate_session.
|
|
50
|
+
SESSION_TOKEN_REGEX = /\A#{SESSION_PREFIX}[A-Za-z0-9_-]{22}\z/
|
|
51
|
+
|
|
52
|
+
# Whether the given value could have been produced by generate_session.
|
|
53
|
+
# Callers handling a token from an unauthenticated request use this to
|
|
54
|
+
# reject garbage before doing any Redis work. Checking only the prefix is
|
|
55
|
+
# not enough: something like "ses_AAA" would pass and still cost us a read.
|
|
56
|
+
# @param token [String] the value to check
|
|
57
|
+
# @return [Boolean] whether the value is shaped like a session token
|
|
58
|
+
def self.session_token?(token)
|
|
59
|
+
SESSION_TOKEN_REGEX.match?(token.to_s)
|
|
60
|
+
end
|
|
61
|
+
|
|
47
62
|
def self.set?(key = PRIMARY_KEY)
|
|
48
63
|
Store.exists(key) == 1
|
|
49
64
|
end
|
|
@@ -56,7 +71,7 @@ module OpenC3
|
|
|
56
71
|
def self.verify(token, no_password: true, service_only: false)
|
|
57
72
|
# Handle a service password - Generally only used by ScriptRunner
|
|
58
73
|
# TODO: Replace this with temporary service tokens
|
|
59
|
-
service_password = ENV
|
|
74
|
+
service_password = ENV.fetch('OPENC3_SERVICE_PASSWORD', nil)
|
|
60
75
|
return true if service_password and service_password == token
|
|
61
76
|
|
|
62
77
|
return false if service_only
|
|
@@ -78,15 +93,28 @@ module OpenC3
|
|
|
78
93
|
# Check cached session tokens and password hash
|
|
79
94
|
time = Time.now
|
|
80
95
|
unless mode == :password
|
|
81
|
-
|
|
96
|
+
# Drop the whole cache once it ages out rather than tracking per token
|
|
97
|
+
# times. This bounds how long a terminated token keeps working to
|
|
98
|
+
# SESSION_CACHE_TIMEOUT, same as before.
|
|
99
|
+
if @@session_cache.nil? or (time - @@session_cache_time) >= SESSION_CACHE_TIMEOUT
|
|
100
|
+
@@session_cache = {}
|
|
101
|
+
@@session_cache_time = time
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
if @@session_cache[token]
|
|
82
105
|
terminate_otp(token)
|
|
83
106
|
return true
|
|
84
107
|
end
|
|
85
108
|
|
|
86
|
-
# Check stored session tokens
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
109
|
+
# Check the stored session tokens for just this token. Deliberately not
|
|
110
|
+
# HGETALL: verify_token is unauthenticated, so reading the entire
|
|
111
|
+
# session hash here lets any caller make us pull every session ever
|
|
112
|
+
# created on every request, and that hash only grows. HGET is O(1) and
|
|
113
|
+
# can't be amplified. The cache then fills with the tokens actually in
|
|
114
|
+
# use instead of all of them.
|
|
115
|
+
stored = Store.hget(SESSIONS_KEY, token)
|
|
116
|
+
if stored
|
|
117
|
+
@@session_cache[token] = stored
|
|
90
118
|
terminate_otp(token)
|
|
91
119
|
return true
|
|
92
120
|
end
|