| 5964 | } |
| 5965 | |
| 5966 | QJsonObject RadioModel::troubleshootingSnapshot() const |
| 5967 | { |
| 5968 | QJsonObject snapshot; |
| 5969 | snapshot["schema_version"] = 1; |
| 5970 | snapshot["captured_at"] = QDateTime::currentDateTime().toString(Qt::ISODate); |
| 5971 | snapshot["captured_from"] = "AetherSDR in-memory application state"; |
| 5972 | snapshot["note"] = |
| 5973 | "This snapshot is built from the app's cached radio, panadapter, slice, " |
| 5974 | "and meter models. It does not query the radio directly."; |
| 5975 | snapshot["privacy"] = |
| 5976 | "Sensitive identifiers are omitted by design, including radio name, " |
| 5977 | "nickname, callsign, serial numbers, MAC/IP addresses, GPS data, and " |
| 5978 | "client station names."; |
| 5979 | |
| 5980 | QJsonObject app; |
| 5981 | app["name"] = QCoreApplication::applicationName(); |
| 5982 | app["version"] = QCoreApplication::applicationVersion(); |
| 5983 | app["qt_version"] = qVersion(); |
| 5984 | app["os"] = QSysInfo::prettyProductName(); |
| 5985 | app["cpu_arch"] = QSysInfo::currentCpuArchitecture(); |
| 5986 | snapshot["app"] = app; |
| 5987 | |
| 5988 | QJsonObject radio; |
| 5989 | radio["connected"] = isConnected(); |
| 5990 | radio["transport"] = isWan() ? "WAN" : "LAN"; |
| 5991 | radio["model"] = m_model; |
| 5992 | radio["software_version"] = m_version; |
| 5993 | radio["protocol_version"] = m_protocolVersion; |
| 5994 | radio["region"] = m_region; |
| 5995 | radio["radio_options"] = m_radioOptions; |
| 5996 | radio["max_slices"] = m_maxSlices; |
| 5997 | radio["full_duplex_enabled"] = m_fullDuplex; |
| 5998 | radio["binaural_rx"] = m_binauralRx; |
| 5999 | radio["mute_local_audio_when_remote"] = m_muteLocalWhenRemote; |
| 6000 | radio["low_latency_digital_modes"] = m_lowLatencyDigital; |
| 6001 | radio["enforce_private_ip_connections"] = m_enforcePrivateIp; |
| 6002 | radio["remote_on_enabled"] = m_remoteOnEnabled; |
| 6003 | radio["mf_enable"] = m_multiFlexEnabled; |
| 6004 | radio["rtty_mark_default"] = m_rttyMarkDefault; |
| 6005 | radio["antenna_list"] = toJsonArray(m_antList); |
| 6006 | radio["owned_slice_ids"] = toJsonArray(m_ownedSliceIds); |
| 6007 | radio["global_profile_count"] = m_globalProfiles.size(); |
| 6008 | radio["active_global_profile_set"] = !m_activeGlobalProfile.trimmed().isEmpty(); |
| 6009 | |
| 6010 | QJsonObject oscillator; |
| 6011 | oscillator["setting"] = m_oscSetting; |
| 6012 | oscillator["locked"] = m_oscLocked; |
| 6013 | oscillator["ext_present"] = m_extPresent; |
| 6014 | oscillator["tcxo_present"] = m_tcxoPresent; |
| 6015 | radio["oscillator"] = oscillator; |
| 6016 | |
| 6017 | QJsonObject audioOutputs; |
| 6018 | audioOutputs["lineout_gain"] = m_lineoutGain; |
| 6019 | audioOutputs["lineout_mute"] = m_lineoutMute; |
| 6020 | audioOutputs["headphone_gain"] = m_headphoneGain; |
| 6021 | audioOutputs["headphone_mute"] = m_headphoneMute; |
| 6022 | audioOutputs["front_speaker_mute"] = m_frontSpeakerMute; |
| 6023 | radio["audio_outputs"] = audioOutputs; |
no test coverage detected