// Copyright 2020 Infostellar, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. syntax = "proto3"; import "google/protobuf/timestamp.proto"; import "google/protobuf/wrappers.proto"; import "stellarstation/api/v1/orbit/orbit.proto"; import "stellarstation/api/v1/radio/radio.proto"; import "stellarstation/api/v1/transport.proto"; package stellarstation.api.v1; option go_package = "github.com/infostellarinc/go-stellarstation/api/v1"; option java_multiple_files = true; option java_outer_classname = "StellarstationProto"; option java_package = "com.stellarstation.api.v1"; // The public API service of StellarStation, a system supporting communication between satellites // and ground stations. This API is for use by an operator of a satellite - it is invalid to specify // satellites that the operator does not own or plans they have not reserved. // Only using IDs shown on the StellarStation Console or returned in API responses will ensure all // inputs are valid. // // A pass is a time range where an ground station and satellite can communicate with each other, i.e., // the period between Acquisition of Signal (AOS) and Loss of Signal (LOS) of the ground station and // satellite pair. // // A plan is a scheduled pass that will be executed to send and receive data between the ground // station and satellite during the time range. service StellarStationService { // Lists the plans for a particular satellite. // // The request will be closed with an `INVALID_ARGUMENT` status if `satellite_id`, // `aos_after`, or `aos_before` are missing, or the duration between the two times is longer than // 31 days. rpc ListPlans (ListPlansRequest) returns (ListPlansResponse); // Cancel a previously reserved upcoming plan. Cancelling the plan will cause it to not be // executed. This action cannot be undone, but it is still possible to reserve the corresponding // pass again by calling `ListUpcomingAvailablePasses` and `ReservePass` as usual - this will // cause a new plan to be reserved. The plan cannot be cancelled less than ten minutes before // AOS. // // Canceling a plan may incur a charge based on the time left to AOS. See our cancellation policy // for details. // // If the plan is not found, the request will return a `NOT_FOUND` error. // // If the plan has already been canceled or is less than ten minutes away from its AOS, the // request will return a `FAILED_PRECONDITION` error. // // If the plan is ongoing or has already finished executing, the request will return a // `OUT_OF_RANGE` error. rpc CancelPlan (CancelPlanRequest) returns (CancelPlanResponse); // Lists upcoming passes for a satellite. Passes that can be scheduled for the satellite with an // Acquisition of Signal (AOS) within 14 days from now will be returned. This method does not // reserve passes in any way - it is possible for a pass that is returned by this method to be // unschedulable when actually trying to schedule because a conflict appeared during that time. // // If the satellite is not found or the client is not authorized for it, the request will return // a `NOT_FOUND` error. rpc ListUpcomingAvailablePasses (ListUpcomingAvailablePassesRequest) returns (ListUpcomingAvailablePassesResponse); // Open a stream to a satellite. The returned stream is bi-directional - it can be used by the // client to send commands to the satellite and data received from the satellite will be returned // as it is made available. All telemetry received from the satellite on reserved passes along // with associated events from this point on will be returned as soon as this method is called. If // `SatelliteStreamRequest.stream_id` is specified, any messages that have been buffered for the // stream will be returned as well. If `SatelliteStreamRequest.plan_id` is provided, only messages // for the specified plan will be returned. // // The first `SatelliteStreamRequest` sent on the stream is used for configuring the stream. // Unless otherwise specified, all configuration is taken from the first request and configuration // values in subsequent requests will be ignored. // // The stream can be left open for any amount of time and telemetry will be received as available // and returned. When the client is done with the stream, it should close it successfully. If the // stream is cancelled with an unexpected error at any point, telemetry received before the next // call to `OpenSatelliteStream` to resume the stream will be buffered up to 1 minute, and if no // call to `OpenSatelliteStream` is made with `stream_id` specified to resume the stream, it will // expire in 10 minutes and a call to `OpenSatelliteStream` with that `stream_id` will be closed // with a `ABORTED` error. // // If the satellite is not found or the client is not authorized for it, the stream will be closed // with a `NOT_FOUND` error. rpc OpenSatelliteStream (stream SatelliteStreamRequest) returns (stream SatelliteStreamResponse); // Reserves a pass for later execution as a plan. The pass must be specified by a // `reservation_token` returned in another method like `ListUpcomingAvailablePasses` and its // `aos_time` must be at least one hour in the future. // // If the `reservation_token` is invalid, the request will return an `INVALID_ARGUMENT` error. // // If the requested pass cannot be scheduled due to a conflict with existing plans or other // scheduling constraints, the request will return a `FAILED_PRECONDITION` error. This includes // if the pass `aos_time` is less than one hour in the future. // // Note that the reservation_token may have become unreservable since it was fetched. If that's // the case, the call to `ReservePass` will fail with a 'FAILED_PRECONDITION' error and // `ListUpcomingAvailablePasses` should be called again to get a fresh list of reservable passes. // The pass must be scheduled at least one hour in advance of `aos_time` or it will be rejected. rpc ReservePass (ReservePassRequest) returns (ReservePassResponse); // Adds TLE for a satellite. // // The TLE will be used for satellite orbit calculation until it is superseded by a newly // added TLE. Adding TLE using this API will automatically change the satellite's TLE source to // `MANUAL` if it was previously set to `NORAD` to allow for immediate use. // // An 'INVALID_ARGUMENT' error will be returned in the following conditions: // - the TLE cannot be parsed // - the TLE norad ID does not correspond to the requested satellite. // // If the satellite is not found or the client is not authorized for it, the request will return // a `NOT_FOUND` error. rpc AddTle (AddTleRequest) returns (AddTleResponse); // Gets the TLE for a satellite. // // The returned TLE will be the one that has most recently been added to StellarStation and matches // the satellite's TLE source. This TLE is used when calculating satellite orbits. // // If the satellite is not found or the client is not authorized for it, the request will return // a `NOT_FOUND` error. rpc GetTle (GetTleRequest) returns (GetTleResponse); // Sets the TLE source for a satellite. // // The selected source will be used for all upcoming pass calculations for the satellite. If TLE // does not exist for a specific source, no passes will be generated. // // An 'INVALID_ARGUMENT' error will be returned in the following condition: // - no satellite_id is provided. // - the source provided is invalid. // // If the satellite is not found or the client is not authorized for it, the request will return // a `NOT_FOUND` error. rpc SetTleSource(SetTleSourceRequest) returns (SetTleSourceResponse); // Sets the metadata for a plan. // // Metadata added to a plan is available via ListPlans RPCs for both satellite and ground station // APIs. Because of this, it is important not to store sensitive information that the plan's // satellite operator and ground station operator should not have access to. // // Any metadata set with this method will overwrite existing metadata. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. rpc SetPlanMetadata(SetPlanMetadataRequest) returns (SetPlanMetadataResponse); } //---------------------------------------------------------------------------------------------- // Streaming APIs. //---------------------------------------------------------------------------------------------- // Request for the `OpenSatelliteStream` method. // // Next ID: 12 message SatelliteStreamRequest { // The ID of the satellite to open a stream with. The ID of a satellite can be found on the // StellarStation Console page for the satellite. string satellite_id = 1; // The ID of the plan to open a stream for. If `plan_id` is set, only messages for the provided // plan ID will be returned on this stream. A valid `plan_id` can be found in the response for // the `ListPlans` method or on the StellarStation Console page for the satellite. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. string plan_id = 11; // Optional. The ID of the ground station to open a stream with. `satellite_id` must also be set when // specifying `ground_station_id`. Only messages for the provided `ground_station_id` from the provided // `satellite_id` will be returned on this stream. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. string ground_station_id = 12; // The `SatelliteStreamResponse.stream_id` from a previously opened stream to resume. If the // specified stream has already expired or been closed, the stream is closed with a `ABORTED` // error. string stream_id = 2; // Whether monitoring events should be returned by the stream in // `SatelliteStreamResponse.stream_event`. If set in the first request of the stream, events of // type `StreamEvent` will be returned throughout the lifetime of the stream. bool enable_events = 5; // A unique ID identifying this request. If `enable_events` is true and this is filled, events // returned in `SatelliteStreamResponse.stream_event` that correspond to this request will have // this value copied into `StreamEvent.request_id` for correlation. The API will treat this as an // opaque identifier which can be set to any value, e.g., to the same value as the request ID or // command number in a downstream system. For simple cases, it is often simplest to set this to a // standard UUID. string request_id = 6; // A request to send on the satellite stream. Currently only command sending to the satellite is // supported. The request does not need to be filled on the first request to // `OpenSatelliteStream`. oneof Request { // A request to send commands to the satellite. SendSatelliteCommandsRequest send_satellite_commands_request = 3; // A request to modify a configuration of a ground station. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. GroundStationConfigurationRequest ground_station_configuration_request = 7; // An ack message to respond to each ReceiveTelemetryResponse when `enable_flow_control` is true. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. ReceiveTelemetryAck telemetry_received_ack = 9; } // The `Framing` types to accept, for satellites that have been configured for multiple framings // (e.g., IQ + AX25). If empty, all framings produced by the satellite will be returned. repeated Framing accepted_framing = 4; // Optional. The `ReceiveTelemetryResponse.message_ack_id` of the most recently received telemetry. // This may be specified in attempt to resume streaming after a connection or application error. If // specified, the server will attempt to resume transfer assuming the provided value is that of the // most recent Telemetry received & processed by the client. If not specified (or if provided value // is invalid), server will resume streaming from the most recent telemetry message sent by the server // which may or may not have been received by the client. // // This feature is only available if enable_flow_control is true. // This feature may not be available for Out-of-order-allowed-satellites. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. string resume_stream_message_ack_id = 8; // Whether flow control is enabled on the client side. If set to true, client must respond to each // ReceiveTelemetryResponse received with a corresponding ReceiveTelemetryAck message. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. bool enable_flow_control = 10; } // A request to send commands to a satellite. // // Next ID: 4 message SendSatelliteCommandsRequest { // The command frames to send to the satellite. All commands will be transmitted in sequence // immediately, during which time telemetry will not be received. After all commands have been // transmitted, telemetry receive will be immediately re-enabled. The maximum size of each command // is 2MB. If a command larger than 2MB is received, the stream will be closed with a // `RESOURCE_EXHAUSTED` error. repeated bytes command = 2; // The ID of the channel set to be used when sending the command. Required if two uplink-capable // plans are simultaneously executing. If not provided and only one plan is executing, the // channel set will be automatically determined. // // If a channel set without an uplink component is provided or two uplink-capable plans are // simultaneously executing and no ID is provided, the command will be ignored. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. string channel_set_id = 3; } // A request to modify configuration of ground station hardware. // // Next ID: 3 // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. message GroundStationConfigurationRequest { // A request to modify transmitter configuration at a ground station. TransmitterConfigurationRequest transmitter_configuration_request = 1; // A request to modify receiver configuration at a ground station. ReceiverConfigurationRequest receiver_configuration_request = 2; } // An ack message for client to notify server of sucessful receive of a ReceiveTelemetryResponse message. // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. message ReceiveTelemetryAck { // The `ReceiveTelemetryResponse.message_ack_id` value of the telemetry message received string message_ack_id = 1; // Optional. The local timestamp of message reception, used for statistics collection. google.protobuf.Timestamp received_timestamp = 2; } // A request to configure a transmitter at a ground station. Default state of these parameters // depends on hardware configuration at each ground station. Please check TransmitterConfiguration // and TransmitterState in monitoring message. // // Not all configuration requests are supported by some transmitters. If a field isn't set, // the configuration will not be changed. // // Next ID: 7 message TransmitterConfigurationRequest { // Enable carrier transmission. google.protobuf.BoolValue enable_carrier = 1; // Enable IF modulation. google.protobuf.BoolValue enable_if_modulation = 2; // Enable idle pattern transmission. google.protobuf.BoolValue enable_idle_pattern = 3; // Enable IF sweep. google.protobuf.BoolValue enable_if_sweep = 4; // Bitrate of the transmitter google.protobuf.FloatValue bitrate = 5; // Modulation of the transmitter. Note that the default modulation is DISABLED and // will be ignored. There is no way to disable modulation using this method. radio.Modulation modulation = 6; } // A request to configure a receiver at a ground station. Default state of these parameters // depends on hardware configuration at each ground station. Please check ReceiverConfiguration // and ReceiverState in monitoring message. // // Not all configuration requests are supported by some receivers. If a field isn't set, // the configuration will not be changed. // // Next ID: 3 message ReceiverConfigurationRequest { // Bitrate of the receiver. google.protobuf.FloatValue bitrate = 1; // Modulation of the receiver. Note that the default modulation is DISABLED and // will be ignored. There is no way to disable modulation using this method. radio.Modulation modulation = 2; } // A response from the `OpenSatelliteStream` method. message SatelliteStreamResponse { // The ID of this stream, which can be used in a subsequent call to `OpenSatelliteStream` to // resume this stream on interruption (e.g., if a network failure causes the connection to be // closed mid-stream). Telemetry received on a previously opened stream with no current listener // will be buffered for a maximum of 1 minute, and the stream itself will be cancelled and no more // buffering will occur if no client resumes the stream with `OpenSatelliteStream` within 10 // minutes. string stream_id = 1; // A response on the stream. Currently the only types of response are telemetry received from the // satellite and stream events. oneof Response { // A response from a satellite containing telemetry. ReceiveTelemetryResponse receive_telemetry_response = 2; // An event that occurred while processing the stream. Often used for monitoring the stream. // Never returned if `SatelliteStreamRequest.enable_events` is false in the first // `SatelliteStreamRequest` of the stream. StreamEvent stream_event = 3; } } // A response from a satellite containing telemetry. message ReceiveTelemetryResponse { // The telemetry received. repeated Telemetry telemetry = 1; // The ID of the plan the telemetry was received for. string plan_id = 2; // The ID of the satellite. string satellite_id = 4; // The ID of the ground station. string ground_station_id = 5; // The ID to be used to when creating a `ReceiveTelemetryAck.message_ack_id` response // // This value may not be available for Out-of-order-allowed-satellites // // Status: ALPHA This API is under development and may not work correctly or be changed in backwards // incompatible ways in the future. string message_ack_id = 3; } //---------------------------------------------------------------------------------------------- // Scheduling APIs. //---------------------------------------------------------------------------------------------- // Request for the `CancelPlan` method. message CancelPlanRequest { // The id of the plan to cancel, i.e., the value of `Plan.id`. string plan_id = 1; } // Response for the `CancelPlan` method. message CancelPlanResponse { // Currently no payload in the response. } // Request for the `ListUpcomingAvailablePasses` method. message ListUpcomingAvailablePassesRequest { // The ID of the satellite to list passes for. The ID of a satellite can be found on the // StellarStation Console page for the satellite. string satellite_id = 1; } // Response for the `ListUpcomingAvailablePasses` method. message ListUpcomingAvailablePassesResponse { // The upcoming, schedulable passes for the satellite. repeated Pass pass = 1; } // The priority level of a plan. enum Priority { LOW = 0; MEDIUM = 1; HIGH = 2; } // Request for the `ReservePass` method. message ReservePassRequest { // The token that specifies the pass, as returned in `Pass.reservation_token` or one of the // `Pass.channel_set_token.reservation_token` values. string reservation_token = 1; Priority priority = 2; } // Response for the `ReservePass` method. message ReservePassResponse { // The reserved plan. Plan plan = 1; } // Request for the `ListPlans` method. message ListPlansRequest { // The ID of the satellite to list plans for. The ID can be found on the StellarStation // Console page for the satellite. string satellite_id = 1; // The start time of the range of plans to list (inclusive). Only plans with an Acquisition of // Signal (AOS) at or after this time will be returned. It is an error for the duration between // `aos_after` and `aos_before` to be longer than 31 days. google.protobuf.Timestamp aos_after = 2; // The end time of the range of plans to list (exclusive). Only plans with an Acquisition of // Signal (AOS) before this time will be returned. It is an error for the duration between // `aos_after` and `aos_before` to be longer than 31 days. google.protobuf.Timestamp aos_before = 3; } // A response from the `ListPlans` method. message ListPlansResponse { // The requested list of plans for the satellite. repeated Plan plan = 1; } // A channel set defines one or both of the uplink and downlink `RadioDeviceConfiguration`s to be // used when executing a pass. A channel set is unique to a specific satellite, and a satellite may // have one or more channel sets. // // A common example is to have a channel set for TT&C with both uplink and downlink configurations, // and a second channel set only for mission downlink. In this case it is necessary to select the // configuration that will be used during plan execution. message ChannelSet { // The unique ID of the channel set. string id = 1; // The name used to identify the channel set (for example, TT&C UHF). string name = 2; // The radio device configuration used for uplinking. // // Optional if downlink is set. stellarstation.api.v1.radio.RadioDeviceConfiguration uplink = 3; // The radio device configuration used for downlinking. // // Optional if uplink is set. stellarstation.api.v1.radio.RadioDeviceConfiguration downlink = 4; } // A pass during which a satellite can be communicated with from a given ground station. // // Next ID: 14 message Pass { // The time of Acquisition of Signal (AOS) between the ground station and satellite in this pass. google.protobuf.Timestamp aos_time = 2; // The time of Loss of Signal (LOS) between the ground station and satellite in this pass. google.protobuf.Timestamp los_time = 3; // The latitude, in degrees, of the ground station's location. double ground_station_latitude = 4; // The longitude, in degrees, of the ground station's location. double ground_station_longitude = 5; // The organization name of the ground station. string ground_station_organization_name = 12; // The ID of the ground station. string ground_station_id = 13; // The ISO 3166-1 alpha-2 2-letter country code for the ground station's location. // See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 string ground_station_country_code = 6; // The max elevation during the pass, in degrees. double max_elevation_degrees = 7; // The time of the max elevation during the pass. google.protobuf.Timestamp max_elevation_time = 8; // A mapping of channel set to its unique reservation token. message ChannelSetToken { // A channel set that can be reserved. ChannelSet channel_set = 1; // A unique token for this pass, specific to this channel set, that can // be used for scheduling it by copying to ReservePassRequest.reservation_token. string reservation_token = 2; // The price per minute (USD) for this pass and channel set combination. double unit_price = 3; } // List of channel set and corresponding reservation token groupings. Only channel sets that are // compatible with this pass's ground station will be present. repeated ChannelSetToken channel_set_token = 11; } // Metadata for telemetry downlinked during a pass. message TelemetryMetadata { // URL of the data. This URL is valid for one hour after being returned. string url = 1; // The type of data available at the above URL. enum DataType { // Raw IQ data. RAW = 0; // Demodulated IQ data. DEMODULATED = 1; // Decoded data. DECODED = 2; } // The type of data received during downlinking. DataType data_type = 2; } // A plan, specifying a time range within which a satellite will be communicated with. // // Next ID: 22 message Plan { // The unique ID of the plan. string id = 1; // The id of the satellite to be tracked in the plan. string satellite_id = 2; // The organization name of the satellite to be tracked in the plan. string satellite_organization_name = 17; // A description of the status of a plan. enum Status { // The plan is reserved for execution in the future at `aos_time`. RESERVED = 0; // The plan is currently executing and will end in the future at `los_time`. EXECUTING = 1; // The plan already finished executing successfully. SUCCEEDED = 2; // The plan failed to execute correctly. FAILED = 3; // The plan was canceled. This can be explicitly by calling `CancelPlan` or implicit due to // cancellation by the ground station in the plan (e.g., due to bad weather). CANCELED = 4; // The plan completed execution and telemetry data is being processed. PROCESSING = 5; } // The status of this plan. Status status = 3; // The start of the time window reserved for the plan. This value does not change over time. google.protobuf.Timestamp start_time = 14; // The end of the time window reserved for the plan. This value does not change over time. google.protobuf.Timestamp end_time = 15; // The time of Acquisition of Signal (AOS) between the ground station and satellite in this plan. // // This value is never before 'start_time'. It may change over time (for example, if updated // TLE becomes available). google.protobuf.Timestamp aos_time = 4; // The time of Loss of Signal (LOS) between the ground station and satellite in this plan. // // This value is never after 'end_time'. It may change over time (for example, if updated // TLE becomes available). google.protobuf.Timestamp los_time = 5; // The latitude, in degrees, of the ground station's location. double ground_station_latitude = 6; // The longitude, in degrees, of the ground station's location. double ground_station_longitude = 7; // The ISO 3166-1 alpha-2 2-letter country code for the ground station's location. // See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 string ground_station_country_code = 8; // The organization name of the ground station. string ground_station_organization_name = 18; // The ID of the ground station. string ground_station_id = 20; // The max elevation during the plan, in degrees. double max_elevation_degrees = 9; // The time of the max elevation during the plan. google.protobuf.Timestamp max_elevation_time = 10; // Metadata for telemetry received during the pass. Only populated when the pass has completed // successfully and data processing is complete. repeated TelemetryMetadata telemetry_metadata = 13; // The channel set used to reserve this plan. ChannelSet channel_set = 16; // The price per minute (USD) for this plan set by the ground station owner at the time of reservation. double unit_price = 19; // The priority of the plan. Priority priority = 21; } // Request for the 'AddTle' method. message AddTleRequest { // The ID of the satellite to add TLE for. The ID can be found on the StellarStation // Console page for the satellite. string satellite_id = 1; // The TLE to be added. orbit.Tle tle = 2; } // Response for the `AddTle` method. message AddTleResponse { // Currently no payload in the response. } // Request for the 'GetTle' method. message GetTleRequest { // The ID of the satellite for which to fetch TLE. The ID can be found on the StellarStation // Console page for the satellite. string satellite_id = 1; } // Response for the 'GetTle' method. message GetTleResponse { // The TLE for the given satellite. orbit.Tle tle = 1; } // Request for the `SetTleSource` method. message SetTleSourceRequest { // The ID of the satellite to set the TLE for. // // Required. string satellite_id = 1; // The source of the TLE. enum Source { // This is not allowed and will cause an error. UNKNOWN = 0; // Provided by NORAD. NORAD = 1; // Manually provided by the owner of the satellite. MANUAL = 2; } // The source of the TLE the satellite will use for pass calculations. // // Required. Source source = 2; } // Response for the `SetTleSource` method. message SetTleSourceResponse { // Currently no payload in the response. } // Message to be nested inside of a SetPlanMetadataRequest message in order to // get around the limitation of protobuf maps not allowing repeated values. message PlanMetadata { message Metadata { repeated string data = 1; } map metadata = 2; } // Request for the `SetPlanMetadata` method. message SetPlanMetadataRequest { // The ID of the plan to set the metadata for. // // Required. string plan_id = 1; // The metadata to set. PlanMetadata metadata = 2; } // Response for the `SetPlanMetadata` method. message SetPlanMetadataResponse { // Currently no payload in the response. }