From 9b8a6c1e2ced2acf43331d762ce1da4b220dd57a Mon Sep 17 00:00:00 2001 From: Andy Taylor Date: Tue, 17 Mar 2026 15:02:38 +0000 Subject: [PATCH] Always emit source_info and reflector fields in JSON output Several JSON message builders conditionally omit fields when their values are empty or null: - DMRSlot, P25Control, NXDNControl: source_info omitted when the callsign/ID lookup returns an empty string - DStarControl: reflector omitted in RF start messages and when the reflector pointer is null in network start messages - YSFControl: reflector omitted in RF start messages Downstream consumers (such as Display-Driver) that access these fields via nlohmann::json const operator[] crash with an assertion failure when the key is absent. Always emit these fields with an empty string default so that the JSON schema is consistent regardless of lookup results or message source. --- DMRSlot.cpp | 3 +-- DStarControl.cpp | 7 +++++-- NXDNControl.cpp | 3 +-- P25Control.cpp | 3 +-- YSFControl.cpp | 7 ++++--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 7e4dbf2..eb0976c 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -2519,8 +2519,7 @@ void CDMRSlot::writeJSON(nlohmann::json& json, const char* source, const char* a json["destination_id"] = int(dstId); json["destination_type"] = grp ? "group" : "individual"; - if (!srcInfo.empty()) - json["source_info"] = srcInfo; + json["source_info"] = srcInfo; } #endif diff --git a/DStarControl.cpp b/DStarControl.cpp index 9498ca5..277cbf1 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -1499,8 +1499,9 @@ void CDStarControl::writeJSONRF(const char* action, const unsigned char* my1, co json["source_ext"] = convertBuffer(my2, DSTAR_SHORT_CALLSIGN_LENGTH); json["destination_cs"] = convertBuffer(your, DSTAR_LONG_CALLSIGN_LENGTH); - json["source"] = "rf"; - json["action"] = action; + json["source"] = "rf"; + json["action"] = action; + json["reflector"] = ""; WriteJSON("D-Star", json); } @@ -1554,6 +1555,8 @@ void CDStarControl::writeJSONNet(const char* action, const unsigned char* my1, c if (reflector != nullptr) json["reflector"] = convertBuffer(reflector, DSTAR_LONG_CALLSIGN_LENGTH); + else + json["reflector"] = ""; WriteJSON("D-Star", json); } diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 981a42e..85b3027 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -1284,8 +1284,7 @@ void CNXDNControl::writeJSON(nlohmann::json& json, const char* source, const cha json["destination_id"] = int(dstId); json["destination_type"] = grp ? "group" : "individual"; - if (!srcInfo.empty()) - json["source_info"] = srcInfo; + json["source_info"] = srcInfo; } #endif diff --git a/P25Control.cpp b/P25Control.cpp index 27f2493..d713bd0 100644 --- a/P25Control.cpp +++ b/P25Control.cpp @@ -1383,8 +1383,7 @@ void CP25Control::writeJSON(nlohmann::json& json, const char* source, const char json["destination_id"] = int(dstId); json["destination_type"] = grp ? "group" : "individual"; - if (!srcInfo.empty()) - json["source_info"] = srcInfo; + json["source_info"] = srcInfo; } #endif diff --git a/YSFControl.cpp b/YSFControl.cpp index 52020c4..4b1c718 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -1343,9 +1343,10 @@ void CYSFControl::writeJSONRF(nlohmann::json& json, const char* action, const un json["source_cs"] = convertBuffer(source); - json["source"] = "rf"; - json["action"] = action; - json["dg-id"] = int(dgid); + json["source"] = "rf"; + json["action"] = action; + json["dg-id"] = int(dgid); + json["reflector"] = ""; } void CYSFControl::writeJSONNet(nlohmann::json& json, const char* action)