#pragma once // Requires: nlohmann/json (header-only), libcurl #include #include #include #include #include #include #include namespace sigtera { enum class DataType { iq, spectrogram }; inline std::string to_string(DataType v) { switch (v) { case DataType::iq: return "iq"; case DataType::spectrogram: return "spectrogram"; } return ""; } enum class Format { raw_float32, raw_float64, wav, sigmf, matlab, vita49 }; inline std::string to_string(Format v) { switch (v) { case Format::raw_float32: return "raw_float32"; case Format::raw_float64: return "raw_float64"; case Format::wav: return "wav"; case Format::sigmf: return "sigmf"; case Format::matlab: return "matlab"; case Format::vita49: return "vita49"; } return ""; } enum class SelfInterferenceCancelation { True, False }; inline std::string to_string(SelfInterferenceCancelation v) { switch (v) { case SelfInterferenceCancelation::True: return "True"; case SelfInterferenceCancelation::False: return "False"; } return ""; } enum class Signal { tone, psk, iridium, ook, ask, fsk, dpsk, qam, ofdm, gmsk, ais, dsss, pam, am, fm, chirp, lora, adsb, apsk, msk, gfsk, cpfsk, ble, aprs, fhss, wifi }; inline std::string to_string(Signal v) { switch (v) { case Signal::tone: return "tone"; case Signal::psk: return "psk"; case Signal::iridium: return "iridium"; case Signal::ook: return "ook"; case Signal::ask: return "ask"; case Signal::fsk: return "fsk"; case Signal::dpsk: return "dpsk"; case Signal::qam: return "qam"; case Signal::ofdm: return "ofdm"; case Signal::gmsk: return "gmsk"; case Signal::ais: return "ais"; case Signal::dsss: return "dsss"; case Signal::pam: return "pam"; case Signal::am: return "am"; case Signal::fm: return "fm"; case Signal::chirp: return "chirp"; case Signal::lora: return "lora"; case Signal::adsb: return "adsb"; case Signal::apsk: return "apsk"; case Signal::msk: return "msk"; case Signal::gfsk: return "gfsk"; case Signal::cpfsk: return "cpfsk"; case Signal::ble: return "ble"; case Signal::aprs: return "aprs"; case Signal::fhss: return "fhss"; case Signal::wifi: return "wifi"; } return ""; } enum class MessageType { msg1_position_report, msg2_assigned_position_report, msg3_special_position_report, msg4_base_station_report, msg9_sar_aircraft_position, msg14_safety_broadcast, msg18_position_report_class_b, msg21_aid_to_navigation, msg24_static_data, msg27_long_range_broadcast, msg28_aid_to_navigation_single_slot }; inline std::string to_string(MessageType v) { switch (v) { case MessageType::msg1_position_report: return "msg1_position_report"; case MessageType::msg2_assigned_position_report: return "msg2_assigned_position_report"; case MessageType::msg3_special_position_report: return "msg3_special_position_report"; case MessageType::msg4_base_station_report: return "msg4_base_station_report"; case MessageType::msg9_sar_aircraft_position: return "msg9_sar_aircraft_position"; case MessageType::msg14_safety_broadcast: return "msg14_safety_broadcast"; case MessageType::msg18_position_report_class_b: return "msg18_position_report_class_b"; case MessageType::msg21_aid_to_navigation: return "msg21_aid_to_navigation"; case MessageType::msg24_static_data: return "msg24_static_data"; case MessageType::msg27_long_range_broadcast: return "msg27_long_range_broadcast"; case MessageType::msg28_aid_to_navigation_single_slot: return "msg28_aid_to_navigation_single_slot"; } return ""; } enum class Mode { dsb, dsb_sc, usb, lsb }; inline std::string to_string(Mode v) { switch (v) { case Mode::dsb: return "dsb"; case Mode::dsb_sc: return "dsb_sc"; case Mode::usb: return "usb"; case Mode::lsb: return "lsb"; } return ""; } enum class Direction { up, down }; inline std::string to_string(Direction v) { switch (v) { case Direction::up: return "up"; case Direction::down: return "down"; } return ""; } enum class Format2 { extended, short_ }; inline std::string to_string(Format2 v) { switch (v) { case Format2::extended: return "extended"; case Format2::short_: return "short"; } return ""; } struct _ReceiverBase { virtual nlohmann::json to_json() const = 0; virtual ~_ReceiverBase() = default; }; struct NbTone { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double duration = 0.1; double phase = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "tone"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["duration"] = duration; j["phase"] = phase; j["count"] = count; return j; } }; struct NbPsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "psk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct NbIridium { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int slot_index = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double duration = 0.1; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "iridium"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["slot_index"] = slot_index; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["duration"] = duration; j["count"] = count; return j; } }; struct NbOok { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ook"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["baud"] = baud; j["count"] = count; return j; } }; struct NbAsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; int modulation_order = 2; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ask"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct NbFsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int modulation_order = 4; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 1000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["count"] = count; return j; } }; struct NbDpsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dpsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["baud"] = baud; j["count"] = count; return j; } }; struct NbQam { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "qam"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct NbOfdm { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int num_subcarriers = 64; int fft_size = 64; int cyclic_prefix_length = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ofdm"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["num_subcarriers"] = num_subcarriers; j["fft_size"] = fft_size; j["cyclic_prefix_length"] = cyclic_prefix_length; j["baud"] = baud; j["count"] = count; return j; } }; struct NbGmsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 9600; int samples_per_symbol = 8; double BT = 0.3; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gmsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["count"] = count; return j; } }; struct NbAis { double pre_padding = 0; double post_padding = 0; double power = -2; std::string center_frequency = "161975000, 162025000"; double baud = 9600; int samples_per_symbol = 8; double BT = 0.4; MessageType message_type = MessageType::msg1_position_report; int mmsi = 338000001; double lat = 37.7749; double lon = -122.4194; double speed = 0.0; double course = 0.0; int heading = 511; int status = 0; int alt = 1000; std::string text = "ALL CLEAR"; std::string name = "BUOY"; int aid_type = 1; int repeat = 0; int accuracy = 0; int to_bow = 0; int to_stern = 0; int to_port = 0; int to_starboard = 0; int epfd = 0; int second = 60; int off_position = 0; int reserved_1 = 0; int raim = 0; int virtual_aid = 0; int assigned = 0; std::string name_ext = ""; std::string shipname = "SIGTERA"; std::string callsign = "KXYZ"; int ship_type = 0; int station_type = 1; int restricted = 0; int iala_mrn = 0; int dimension = 0; int dimensions_a = 0; int dimensions_b = 0; int dimension_additional_data = 0; int charted_status = 0; int station_status = 0; int status_bits = 0; int auth = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ais"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["message_type"] = to_string(message_type); j["mmsi"] = mmsi; j["lat"] = lat; j["lon"] = lon; j["speed"] = speed; j["course"] = course; j["heading"] = heading; j["status"] = status; j["alt"] = alt; j["text"] = text; j["name"] = name; j["aid_type"] = aid_type; j["repeat"] = repeat; j["accuracy"] = accuracy; j["to_bow"] = to_bow; j["to_stern"] = to_stern; j["to_port"] = to_port; j["to_starboard"] = to_starboard; j["epfd"] = epfd; j["second"] = second; j["off_position"] = off_position; j["reserved_1"] = reserved_1; j["raim"] = raim; j["virtual_aid"] = virtual_aid; j["assigned"] = assigned; j["name_ext"] = name_ext; j["shipname"] = shipname; j["callsign"] = callsign; j["ship_type"] = ship_type; j["station_type"] = station_type; j["restricted"] = restricted; j["iala_mrn"] = iala_mrn; j["dimension"] = dimension; j["dimensions_a"] = dimensions_a; j["dimensions_b"] = dimensions_b; j["dimension_additional_data"] = dimension_additional_data; j["charted_status"] = charted_status; j["station_status"] = station_status; j["status_bits"] = status_bits; j["auth"] = auth; j["count"] = count; return j; } }; struct NbDsss { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 9600; std::string sequence = "barker_13"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dsss"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["sequence"] = sequence; j["count"] = count; return j; } }; struct NbPam { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "pam"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct NbAm { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double duration = 0.1; Mode mode = Mode::dsb; double modulation_index = 0.5; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "am"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["duration"] = duration; j["mode"] = to_string(mode); j["modulation_index"] = modulation_index; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct NbFm { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double duration = 0.1; double deviation = 5000; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fm"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["duration"] = duration; j["deviation"] = deviation; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct NbChirp { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double duration = 0.001; double bandwidth = 10000; Direction direction = Direction::up; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "chirp"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["duration"] = duration; j["bandwidth"] = bandwidth; j["direction"] = to_string(direction); j["count"] = count; return j; } }; struct NbLora { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int spreading_factor = 7; double bandwidth = 125000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "lora"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["spreading_factor"] = spreading_factor; j["bandwidth"] = bandwidth; j["count"] = count; return j; } }; struct NbAdsb { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; Format2 format = Format2::extended; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "adsb"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["format"] = to_string(format); j["count"] = count; return j; } }; struct NbApsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "apsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct NbMsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 4800; int samples_per_symbol = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "msk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["count"] = count; return j; } }; struct NbGfsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 4800; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gfsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct NbCpfsk { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int modulation_order = 2; double baud = 4800; int samples_per_symbol = 8; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "cpfsk"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct NbBle { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 1000000; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; int payload_bytes = 16; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ble"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["payload_bytes"] = payload_bytes; j["count"] = count; return j; } }; struct NbAprs { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; std::string source = "N0CALL"; std::string info = ">SIGTERA TEST"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "aprs"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["source"] = source; j["info"] = info; j["count"] = count; return j; } }; struct NbFhss { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 2000; int num_channels = 8; double channel_spacing = 25000; double hop_rate = 100; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fhss"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["num_channels"] = num_channels; j["channel_spacing"] = channel_spacing; j["hop_rate"] = hop_rate; j["count"] = count; return j; } }; struct NbWifi { double pre_padding = 0; double post_padding = 0; double power = -2; double center_frequency = 0; int modulation_order = 4; int num_symbols = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "wifi"; j["pre-padding"] = pre_padding; j["post-padding"] = post_padding; j["power"] = power; j["center_frequency"] = center_frequency; j["modulation_order"] = modulation_order; j["num_symbols"] = num_symbols; j["count"] = count; return j; } }; struct WbTone { double power = -2; double center_frequency = 0; double signal_start_time = 0; double duration = 0.1; double phase = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "tone"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["duration"] = duration; j["phase"] = phase; j["count"] = count; return j; } }; struct WbPsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "psk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct WbIridium { double power = -2; double center_frequency = 0; int slot_index = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; double duration = 0.1; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "iridium"; j["power"] = power; j["center_frequency"] = center_frequency; j["slot_index"] = slot_index; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["duration"] = duration; j["count"] = count; return j; } }; struct WbOok { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ook"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["count"] = count; return j; } }; struct WbAsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; int modulation_order = 2; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ask"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct WbFsk { double power = -2; double center_frequency = 0; double signal_start_time = 0; int modulation_order = 4; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 1000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["count"] = count; return j; } }; struct WbDpsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dpsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["count"] = count; return j; } }; struct WbQam { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "qam"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct WbOfdm { double power = -2; double center_frequency = 0; double signal_start_time = 0; int num_subcarriers = 64; int fft_size = 64; int cyclic_prefix_length = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ofdm"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["num_subcarriers"] = num_subcarriers; j["fft_size"] = fft_size; j["cyclic_prefix_length"] = cyclic_prefix_length; j["baud"] = baud; j["count"] = count; return j; } }; struct WbGmsk { double power = -2; double center_frequency = 0; double signal_start_time = 0; double baud = 9600; int samples_per_symbol = 8; double BT = 0.3; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gmsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["count"] = count; return j; } }; struct WbAis { double power = -2; std::string center_frequency = "161975000, 162025000"; double baud = 9600; int samples_per_symbol = 8; double BT = 0.4; double signal_start_time = 0; MessageType message_type = MessageType::msg1_position_report; int mmsi = 338000001; double lat = 37.7749; double lon = -122.4194; double speed = 0.0; double course = 0.0; int heading = 511; int status = 0; int alt = 1000; std::string text = "ALL CLEAR"; std::string name = "BUOY"; int aid_type = 1; int repeat = 0; int accuracy = 0; int to_bow = 0; int to_stern = 0; int to_port = 0; int to_starboard = 0; int epfd = 0; int second = 60; int off_position = 0; int reserved_1 = 0; int raim = 0; int virtual_aid = 0; int assigned = 0; std::string name_ext = ""; std::string shipname = "SIGTERA"; std::string callsign = "KXYZ"; int ship_type = 0; int station_type = 1; int restricted = 0; int iala_mrn = 0; int dimension = 0; int dimensions_a = 0; int dimensions_b = 0; int dimension_additional_data = 0; int charted_status = 0; int station_status = 0; int status_bits = 0; int auth = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ais"; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["signal_start_time"] = signal_start_time; j["message_type"] = to_string(message_type); j["mmsi"] = mmsi; j["lat"] = lat; j["lon"] = lon; j["speed"] = speed; j["course"] = course; j["heading"] = heading; j["status"] = status; j["alt"] = alt; j["text"] = text; j["name"] = name; j["aid_type"] = aid_type; j["repeat"] = repeat; j["accuracy"] = accuracy; j["to_bow"] = to_bow; j["to_stern"] = to_stern; j["to_port"] = to_port; j["to_starboard"] = to_starboard; j["epfd"] = epfd; j["second"] = second; j["off_position"] = off_position; j["reserved_1"] = reserved_1; j["raim"] = raim; j["virtual_aid"] = virtual_aid; j["assigned"] = assigned; j["name_ext"] = name_ext; j["shipname"] = shipname; j["callsign"] = callsign; j["ship_type"] = ship_type; j["station_type"] = station_type; j["restricted"] = restricted; j["iala_mrn"] = iala_mrn; j["dimension"] = dimension; j["dimensions_a"] = dimensions_a; j["dimensions_b"] = dimensions_b; j["dimension_additional_data"] = dimension_additional_data; j["charted_status"] = charted_status; j["station_status"] = station_status; j["status_bits"] = status_bits; j["auth"] = auth; j["count"] = count; return j; } }; struct WbDsss { double power = -2; double center_frequency = 0; double signal_start_time = 0; double baud = 9600; std::string sequence = "barker_13"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dsss"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["sequence"] = sequence; j["count"] = count; return j; } }; struct WbPam { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "pam"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct WbAm { double power = -2; double center_frequency = 0; double signal_start_time = 0; double duration = 0.1; Mode mode = Mode::dsb; double modulation_index = 0.5; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "am"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["duration"] = duration; j["mode"] = to_string(mode); j["modulation_index"] = modulation_index; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct WbFm { double power = -2; double center_frequency = 0; double signal_start_time = 0; double duration = 0.1; double deviation = 5000; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fm"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["duration"] = duration; j["deviation"] = deviation; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct WbChirp { double power = -2; double center_frequency = 0; double signal_start_time = 0; double duration = 0.001; double bandwidth = 10000; Direction direction = Direction::up; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "chirp"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["duration"] = duration; j["bandwidth"] = bandwidth; j["direction"] = to_string(direction); j["count"] = count; return j; } }; struct WbLora { double power = -2; double center_frequency = 0; double signal_start_time = 0; int spreading_factor = 7; double bandwidth = 125000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "lora"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["spreading_factor"] = spreading_factor; j["bandwidth"] = bandwidth; j["count"] = count; return j; } }; struct WbAdsb { double power = -2; double center_frequency = 0; double signal_start_time = 0; Format2 format = Format2::extended; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "adsb"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["format"] = to_string(format); j["count"] = count; return j; } }; struct WbApsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double signal_start_time = 0; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "apsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct WbMsk { double power = -2; double center_frequency = 0; double signal_start_time = 0; double baud = 4800; int samples_per_symbol = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "msk"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["count"] = count; return j; } }; struct WbGfsk { double power = -2; double center_frequency = 0; double signal_start_time = 0; double baud = 4800; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gfsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct WbCpfsk { double power = -2; double center_frequency = 0; double signal_start_time = 0; int modulation_order = 2; double baud = 4800; int samples_per_symbol = 8; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "cpfsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct WbBle { double power = -2; double center_frequency = 0; double baud = 1000000; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; double signal_start_time = 0; int payload_bytes = 16; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ble"; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["signal_start_time"] = signal_start_time; j["payload_bytes"] = payload_bytes; j["count"] = count; return j; } }; struct WbAprs { double power = -2; double center_frequency = 0; double signal_start_time = 0; std::string source = "N0CALL"; std::string info = ">SIGTERA TEST"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "aprs"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["source"] = source; j["info"] = info; j["count"] = count; return j; } }; struct WbFhss { double power = -2; double center_frequency = 0; double signal_start_time = 0; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 2000; int num_channels = 8; double channel_spacing = 25000; double hop_rate = 100; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fhss"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["num_channels"] = num_channels; j["channel_spacing"] = channel_spacing; j["hop_rate"] = hop_rate; j["count"] = count; return j; } }; struct WbWifi { double power = -2; double center_frequency = 0; double signal_start_time = 0; int modulation_order = 4; int num_symbols = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "wifi"; j["power"] = power; j["center_frequency"] = center_frequency; j["signal_start_time"] = signal_start_time; j["modulation_order"] = modulation_order; j["num_symbols"] = num_symbols; j["count"] = count; return j; } }; class _Narrowband : public _ReceiverBase { public: DataType data_type = DataType::iq; Format format = Format::raw_float32; int noise = -10; double sample_rate = 100000; _Narrowband& Tone(NbTone p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Psk(NbPsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Iridium(NbIridium p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Ook(NbOok p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Ask(NbAsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Fsk(NbFsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Dpsk(NbDpsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Qam(NbQam p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Ofdm(NbOfdm p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Gmsk(NbGmsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Ais(NbAis p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Dsss(NbDsss p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Pam(NbPam p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Am(NbAm p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Fm(NbFm p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Chirp(NbChirp p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Lora(NbLora p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Adsb(NbAdsb p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Apsk(NbApsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Msk(NbMsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Gfsk(NbGfsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Cpfsk(NbCpfsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Ble(NbBle p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Aprs(NbAprs p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Fhss(NbFhss p = {}) { signals_.push_back(p.to_json()); return *this; } _Narrowband& Wifi(NbWifi p = {}) { signals_.push_back(p.to_json()); return *this; } nlohmann::json to_json() const override { nlohmann::json j, sigs = nlohmann::json::array(); j["mode"] = "dataset_generation"; j["segmentation"] = "narrowband"; j["data_type"] = to_string(data_type); j["format"] = to_string(format); j["noise"] = noise; j["sample_rate"] = sample_rate; for (auto& s : signals_) sigs.push_back(s); j["signal"] = sigs; return j; } private: std::vector signals_; }; class _Wideband : public _ReceiverBase { public: DataType data_type = DataType::iq; Format format = Format::raw_float32; int noise = -10; double length = 10; double sample_rate = 100000; _Wideband& Tone(WbTone p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Psk(WbPsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Iridium(WbIridium p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Ook(WbOok p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Ask(WbAsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Fsk(WbFsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Dpsk(WbDpsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Qam(WbQam p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Ofdm(WbOfdm p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Gmsk(WbGmsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Ais(WbAis p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Dsss(WbDsss p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Pam(WbPam p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Am(WbAm p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Fm(WbFm p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Chirp(WbChirp p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Lora(WbLora p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Adsb(WbAdsb p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Apsk(WbApsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Msk(WbMsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Gfsk(WbGfsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Cpfsk(WbCpfsk p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Ble(WbBle p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Aprs(WbAprs p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Fhss(WbFhss p = {}) { signals_.push_back(p.to_json()); return *this; } _Wideband& Wifi(WbWifi p = {}) { signals_.push_back(p.to_json()); return *this; } nlohmann::json to_json() const override { nlohmann::json j, sigs = nlohmann::json::array(); j["mode"] = "dataset_generation"; j["segmentation"] = "wideband"; j["data_type"] = to_string(data_type); j["format"] = to_string(format); j["noise"] = noise; j["length"] = length; j["sample_rate"] = sample_rate; for (auto& s : signals_) sigs.push_back(s); j["signal"] = sigs; return j; } private: std::vector signals_; }; struct EnvTxTone { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double duration = 0.1; double phase = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "tone"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["duration"] = duration; j["phase"] = phase; j["count"] = count; return j; } }; struct EnvTxPsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "psk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxIridium { double power = -2; double center_frequency = 0; int slot_index = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; double duration = 0.1; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "iridium"; j["power"] = power; j["center_frequency"] = center_frequency; j["slot_index"] = slot_index; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["duration"] = duration; j["count"] = count; return j; } }; struct EnvTxOok { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ook"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxAsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; int modulation_order = 2; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ask"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxFsk { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; int modulation_order = 4; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 1000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["count"] = count; return j; } }; struct EnvTxDpsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dpsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxQam { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "qam"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxOfdm { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; int num_subcarriers = 64; int fft_size = 64; int cyclic_prefix_length = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ofdm"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["num_subcarriers"] = num_subcarriers; j["fft_size"] = fft_size; j["cyclic_prefix_length"] = cyclic_prefix_length; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxGmsk { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double baud = 9600; int samples_per_symbol = 8; double BT = 0.3; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gmsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["count"] = count; return j; } }; struct EnvTxAis { double power = -2; std::string center_frequency = "161975000, 162025000"; double baud = 9600; int samples_per_symbol = 8; double BT = 0.4; double transmitter_start_time = 0; MessageType message_type = MessageType::msg1_position_report; int mmsi = 338000001; double lat = 37.7749; double lon = -122.4194; double speed = 0.0; double course = 0.0; int heading = 511; int status = 0; int alt = 1000; std::string text = "ALL CLEAR"; std::string name = "BUOY"; int aid_type = 1; int repeat = 0; int accuracy = 0; int to_bow = 0; int to_stern = 0; int to_port = 0; int to_starboard = 0; int epfd = 0; int second = 60; int off_position = 0; int reserved_1 = 0; int raim = 0; int virtual_aid = 0; int assigned = 0; std::string name_ext = ""; std::string shipname = "SIGTERA"; std::string callsign = "KXYZ"; int ship_type = 0; int station_type = 1; int restricted = 0; int iala_mrn = 0; int dimension = 0; int dimensions_a = 0; int dimensions_b = 0; int dimension_additional_data = 0; int charted_status = 0; int station_status = 0; int status_bits = 0; int auth = 0; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ais"; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["transmitter_start_time"] = transmitter_start_time; j["message_type"] = to_string(message_type); j["mmsi"] = mmsi; j["lat"] = lat; j["lon"] = lon; j["speed"] = speed; j["course"] = course; j["heading"] = heading; j["status"] = status; j["alt"] = alt; j["text"] = text; j["name"] = name; j["aid_type"] = aid_type; j["repeat"] = repeat; j["accuracy"] = accuracy; j["to_bow"] = to_bow; j["to_stern"] = to_stern; j["to_port"] = to_port; j["to_starboard"] = to_starboard; j["epfd"] = epfd; j["second"] = second; j["off_position"] = off_position; j["reserved_1"] = reserved_1; j["raim"] = raim; j["virtual_aid"] = virtual_aid; j["assigned"] = assigned; j["name_ext"] = name_ext; j["shipname"] = shipname; j["callsign"] = callsign; j["ship_type"] = ship_type; j["station_type"] = station_type; j["restricted"] = restricted; j["iala_mrn"] = iala_mrn; j["dimension"] = dimension; j["dimensions_a"] = dimensions_a; j["dimensions_b"] = dimensions_b; j["dimension_additional_data"] = dimension_additional_data; j["charted_status"] = charted_status; j["station_status"] = station_status; j["status_bits"] = status_bits; j["auth"] = auth; j["count"] = count; return j; } }; struct EnvTxDsss { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double baud = 9600; std::string sequence = "barker_13"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "dsss"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["sequence"] = sequence; j["count"] = count; return j; } }; struct EnvTxPam { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; int modulation_order = 4; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "pam"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxAm { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double duration = 0.1; Mode mode = Mode::dsb; double modulation_index = 0.5; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "am"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["duration"] = duration; j["mode"] = to_string(mode); j["modulation_index"] = modulation_index; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct EnvTxFm { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double duration = 0.1; double deviation = 5000; double message_bandwidth = 3000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fm"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["duration"] = duration; j["deviation"] = deviation; j["message_bandwidth"] = message_bandwidth; j["count"] = count; return j; } }; struct EnvTxChirp { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double duration = 0.001; double bandwidth = 10000; Direction direction = Direction::up; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "chirp"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["duration"] = duration; j["bandwidth"] = bandwidth; j["direction"] = to_string(direction); j["count"] = count; return j; } }; struct EnvTxLora { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; int spreading_factor = 7; double bandwidth = 125000; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "lora"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["spreading_factor"] = spreading_factor; j["bandwidth"] = bandwidth; j["count"] = count; return j; } }; struct EnvTxAdsb { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; Format2 format = Format2::extended; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "adsb"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["format"] = to_string(format); j["count"] = count; return j; } }; struct EnvTxApsk { double power = -2; double center_frequency = 0; int samples_per_symbol = 8; std::string pulse_shape = "rectangle"; int pulse_shape_span = 6; double pulse_shape_rolloff = 0.35; double transmitter_start_time = 0; int modulation_order = 16; double baud = 4800; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "apsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["samples_per_symbol"] = samples_per_symbol; j["pulse_shape"] = pulse_shape; j["pulse_shape_span"] = pulse_shape_span; j["pulse_shape_rolloff"] = pulse_shape_rolloff; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["count"] = count; return j; } }; struct EnvTxMsk { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double baud = 4800; int samples_per_symbol = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "msk"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["count"] = count; return j; } }; struct EnvTxGfsk { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double baud = 4800; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "gfsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct EnvTxCpfsk { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; int modulation_order = 2; double baud = 4800; int samples_per_symbol = 8; double modulation_index = 0.5; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "cpfsk"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["modulation_index"] = modulation_index; j["count"] = count; return j; } }; struct EnvTxBle { double power = -2; double center_frequency = 0; double baud = 1000000; int samples_per_symbol = 8; double BT = 0.5; double modulation_index = 0.5; double transmitter_start_time = 0; int payload_bytes = 16; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "ble"; j["power"] = power; j["center_frequency"] = center_frequency; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["BT"] = BT; j["modulation_index"] = modulation_index; j["transmitter_start_time"] = transmitter_start_time; j["payload_bytes"] = payload_bytes; j["count"] = count; return j; } }; struct EnvTxAprs { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; std::string source = "N0CALL"; std::string info = ">SIGTERA TEST"; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "aprs"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["source"] = source; j["info"] = info; j["count"] = count; return j; } }; struct EnvTxFhss { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; double baud = 4800; int samples_per_symbol = 8; double freq_sep = 2000; int num_channels = 8; double channel_spacing = 25000; double hop_rate = 100; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "fhss"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["baud"] = baud; j["samples_per_symbol"] = samples_per_symbol; j["freq_sep"] = freq_sep; j["num_channels"] = num_channels; j["channel_spacing"] = channel_spacing; j["hop_rate"] = hop_rate; j["count"] = count; return j; } }; struct EnvTxWifi { double power = -2; double center_frequency = 0; double transmitter_start_time = 0; int modulation_order = 4; int num_symbols = 8; int count = 1; nlohmann::json to_json() const { nlohmann::json j; j["signal"] = "wifi"; j["power"] = power; j["center_frequency"] = center_frequency; j["transmitter_start_time"] = transmitter_start_time; j["modulation_order"] = modulation_order; j["num_symbols"] = num_symbols; j["count"] = count; return j; } }; struct _EnvReceiver { DataType data_type = DataType::iq; Format format = Format::raw_float32; int noise = -10; double sample_rate = 100000; nlohmann::json to_json() const { nlohmann::json j; j["element"] = "receiver"; j["data_type"] = to_string(data_type); j["format"] = to_string(format); j["noise"] = noise; j["sample_rate"] = sample_rate; return j; } }; class _EnvTransmitter { public: _EnvTransmitter& Tone(EnvTxTone p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Psk(EnvTxPsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Iridium(EnvTxIridium p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Ook(EnvTxOok p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Ask(EnvTxAsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Fsk(EnvTxFsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Dpsk(EnvTxDpsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Qam(EnvTxQam p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Ofdm(EnvTxOfdm p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Gmsk(EnvTxGmsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Ais(EnvTxAis p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Dsss(EnvTxDsss p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Pam(EnvTxPam p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Am(EnvTxAm p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Fm(EnvTxFm p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Chirp(EnvTxChirp p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Lora(EnvTxLora p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Adsb(EnvTxAdsb p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Apsk(EnvTxApsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Msk(EnvTxMsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Gfsk(EnvTxGfsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Cpfsk(EnvTxCpfsk p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Ble(EnvTxBle p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Aprs(EnvTxAprs p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Fhss(EnvTxFhss p = {}) { sig_ = p.to_json(); return *this; } _EnvTransmitter& Wifi(EnvTxWifi p = {}) { sig_ = p.to_json(); return *this; } nlohmann::json to_json() const { nlohmann::json j; j["element"] = "transmitter"; if (!sig_.is_null()) { for (auto& [k, v] : sig_.items()) j[k] = v; } return j; } private: nlohmann::json sig_; }; class _EnvPlatform { public: double latitude = 0; double longitude = 0; double altitude = 0; SelfInterferenceCancelation self_interference_cancelation = SelfInterferenceCancelation::True; _EnvPlatform& Receiver(_EnvReceiver p = {}) { elements_.push_back(p.to_json()); return *this; } _EnvPlatform& Transmitter(_EnvTransmitter p = {}) { elements_.push_back(p.to_json()); return *this; } nlohmann::json to_json() const { nlohmann::json j, elems = nlohmann::json::array(); j["platform"] = "platform"; j["latitude"] = latitude; j["longitude"] = longitude; j["altitude"] = altitude; j["self_interference_cancelation"] = to_string(self_interference_cancelation); for (auto& e : elements_) elems.push_back(e); j["element"] = elems; return j; } private: std::vector elements_; }; class _Environment : public _ReceiverBase { public: double length = 10; double speed_of_propagation = 300000000.0; double path_loss_exponent = 2; _Environment& Platform(_EnvPlatform p = {}) { platforms_.push_back(p.to_json()); return *this; } nlohmann::json to_json() const override { nlohmann::json j, plats = nlohmann::json::array(); j["mode"] = "environment_simulation"; j["length"] = length; j["speed_of_propagation"] = speed_of_propagation; j["path_loss_exponent"] = path_loss_exponent; for (auto& p : platforms_) plats.push_back(p); j["platform"] = plats; return j; } private: std::vector platforms_; }; struct Frame { nlohmann::json params; std::vector data; }; class Client { public: explicit Client(std::string url = "https://api.sigtera.com") : url_(std::move(url)) {} _Narrowband& narrowband() { auto p = std::make_unique<_Narrowband>(); auto& ref = *p; requests_.push_back(std::move(p)); return ref; } _Wideband& wideband() { auto p = std::make_unique<_Wideband>(); auto& ref = *p; requests_.push_back(std::move(p)); return ref; } _Environment& environment() { auto p = std::make_unique<_Environment>(); auto& ref = *p; requests_.push_back(std::move(p)); return ref; } std::vector simulate() { std::vector out; for (auto& req : requests_) { auto frames = _send(req->to_json()); out.insert(out.end(), frames.begin(), frames.end()); } return out; } private: std::string url_; std::vector> requests_; static size_t _write_cb(char* ptr, size_t size, size_t n, void* ud) { auto* buf = static_cast*>(ud); buf->insert(buf->end(), ptr, ptr + size * n); return size * n; } std::vector _send(const nlohmann::json& body) { std::string payload = body.dump(); std::vector raw; CURL* curl = curl_easy_init(); if (!curl) throw std::runtime_error("curl_easy_init failed"); std::string endpoint = url_ + "/api"; struct curl_slist* hdrs = curl_slist_append(nullptr, "Content-Type: application/json"); curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str()); curl_easy_setopt(curl, CURLOPT_POST, 1L); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload.c_str()); curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)payload.size()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrs); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, _write_cb); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &raw); CURLcode res = curl_easy_perform(curl); curl_slist_free_all(hdrs); curl_easy_cleanup(curl); if (res != CURLE_OK) throw std::runtime_error(curl_easy_strerror(res)); return _parse(raw); } std::vector _parse(const std::vector& raw) { std::vector frames; size_t pos = 0; auto read_u32 = [&]() -> uint32_t { if (pos + 4 > raw.size()) return 0; uint32_t n = (uint32_t(raw[pos]) << 24) | (uint32_t(raw[pos+1]) << 16) | (uint32_t(raw[pos+2]) << 8) | uint32_t(raw[pos+3]); pos += 4; return n; }; while (pos < raw.size()) { uint32_t jlen = read_u32(); if (pos + jlen > raw.size()) break; auto params = nlohmann::json::parse(raw.begin() + pos, raw.begin() + pos + jlen); pos += jlen; std::vector data; for (;;) { uint32_t blen = read_u32(); if (blen == 0) break; if (pos + blen > raw.size()) break; data.insert(data.end(), raw.begin() + pos, raw.begin() + pos + blen); pos += blen; } frames.push_back({std::move(params), std::move(data)}); } return frames; } }; } // namespace sigtera