Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ura-override #27

Merged
merged 2 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Added options to use the SLP address instead of providing `--host`.
- `--slp-host-imsi` to use the IMSI to generate the SLP address.
- `--slp-host-cell` to use the cell information to generate the SLP address.
- Fixed a bug where the default `ura-override` value was initialized to 0 causing the SPARTN generator to always include it as "unknown".

## [3.4.9] 2024-05-03
- Added a few options to controll how SPARTN messages are generated:
Expand Down
9 changes: 9 additions & 0 deletions examples/lpp/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,19 @@ static std::vector<std::string> split(std::string const& str, char delimiter) {
}

void ControlParser::parse(std::unique_ptr<interface::Interface>& interface) {
if(!interface->is_open()) {
interface->open();
}

if(!interface->is_open()) {
return;
}

while (interface->can_read()) {
char buffer[128];
size_t length = interface->read(buffer, sizeof(buffer));
if (length <= 0) {
interface->close();
break;
}

Expand Down
58 changes: 36 additions & 22 deletions examples/lpp/ssr_example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ using NReceiver = receiver::nmea::ThreadedReceiver;
static CellID gCell;
static ssr_example::Format gFormat;
static int gUraOverride;
static int gUraDefault;
static bool gUBloxClockCorrection;
static bool gForceIodeContinuity;
static bool gAverageZenithDelay;
Expand Down Expand Up @@ -58,14 +59,15 @@ static std::unique_ptr<NReceiver> gNmeaReceiver;
static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*, void*);

[[noreturn]] void execute(Options options, ssr_example::Format format, int ura_override,
bool ublox_clock_correction, bool force_continuity,
int ura_default, bool ublox_clock_correction, bool force_continuity,
bool average_zenith_delay, bool enable_iode_shift, int sf055_override,
int sf055_default, int sf042_override, int sf042_default,
bool increasing_siou, bool filter_by_ocb, bool ignore_l2l,
bool print_rtcm) {
gOptions = std::move(options);
gFormat = format;
gUraOverride = ura_override;
gUraDefault = ura_default;
gUBloxClockCorrection = ublox_clock_correction;
gForceIodeContinuity = force_continuity;
gAverageZenithDelay = average_zenith_delay;
Expand Down Expand Up @@ -150,6 +152,7 @@ static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*

#ifdef INCLUDE_GENERATOR_SPARTN
gSpartnGeneratorNew.set_ura_override(gUraOverride);
gSpartnGeneratorNew.set_ura_default(gUraDefault);
gSpartnGeneratorNew.set_ublox_clock_correction(gUBloxClockCorrection);
if (gForceIodeContinuity) {
gSpartnGeneratorNew.set_continuity_indicator(320.0);
Expand All @@ -174,9 +177,9 @@ static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*
#endif

LPP_Client::AD_Request request;
LPP_Client client{false /* experimental segmentation support */};
bool client_initialized = false;
bool client_got_identity = false;
LPP_Client client{false /* experimental segmentation support */};
bool client_initialized = false;
bool client_got_identity = false;

if (!identity_options.use_supl_identity_fix) {
client.use_incorrect_supl_identity();
Expand All @@ -188,7 +191,7 @@ static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*
control_options.interface->print_info();

gControlParser.on_cid = [&](CellID cell) {
if(!client_initialized) return;
if (!client_initialized) return;
if (gCell != cell) {
printf("[control] cell: %ld:%ld:%ld:%llu\n", cell.mcc, cell.mnc, cell.tac,
cell.cell);
Expand All @@ -202,22 +205,22 @@ static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*

gControlParser.on_identity_imsi = [&](unsigned long long imsi) {
printf("[control] identity: imsi: %llu\n", imsi);
if(client_got_identity) return;
if (client_got_identity) return;
client.set_identity_imsi(imsi);
client_got_identity = true;
};
}

if(identity_options.wait_for_identity) {
if(!control_options.interface) {
if (identity_options.wait_for_identity) {
if (!control_options.interface) {
throw std::runtime_error("No control interface provided");
}

printf(" waiting for identity\n");
if(identity_options.imsi || identity_options.msisdn || identity_options.ipv4) {
if (identity_options.imsi || identity_options.msisdn || identity_options.ipv4) {
printf(" (imsi, msisdn, or ipv4 identity ignored)\n");
}
while(!client_got_identity) {
while (!client_got_identity) {
struct timespec timeout;
timeout.tv_sec = 0;
timeout.tv_nsec = 1000000 * 100; // 100 ms
Expand Down Expand Up @@ -286,15 +289,15 @@ static void assistance_data_callback(LPP_Client*, LPP_Transaction*, LPP_Message*
timeout.tv_nsec = 1000000 * 100; // 100 ms
nanosleep(&timeout, nullptr);

if (control_options.interface) {
gControlParser.parse(control_options.interface);
}

// client.process() MUST be called at least once every second, otherwise
// ProvideLocationInformation messages will not be send to the server.
if (!client.process()) {
throw std::runtime_error("Unable to process LPP client (probably disconnected)");
}

if (control_options.interface) {
gControlParser.parse(control_options.interface);
}
}
}

Expand Down Expand Up @@ -440,6 +443,7 @@ void SsrCommand::parse(args::Subparser& parser) {
// NOTE: parse may be called multiple times
delete mFormatArg;
delete mUraOverrideArg;
delete mUraDefaultArg;
delete mUbloxClockCorrectionArg;
delete mForceContinuityArg;
delete mAverageZenithDelayArg;
Expand Down Expand Up @@ -471,11 +475,15 @@ void SsrCommand::parse(args::Subparser& parser) {
});

mUraOverrideArg = new args::ValueFlag<int>(
parser, "ura",
"A hacky fix to set a nominal value for the URA if the LPP message does not include it"
", value will be clamped between 0-7.",
parser, "ura-override",
"Override the URA (SF024) value, value will be clamped between 0-7. "
"Where 0 indicates that the value is unknown.",
{"ura-override"}, args::Options::Single);
mUraOverrideArg->HelpDefault("0");
mUraDefaultArg = new args::ValueFlag<int>(
parser, "ura-default",
"Set the default URA (SF024) value, value will be clamped between 0-7. "
"Where 0 indicates that the value is unknown.",
{"ura-default"}, args::Options::Single);

mUbloxClockCorrectionArg =
new args::Flag(parser, "ublox-clock-correction", "Change the sign of the clock correction",
Expand Down Expand Up @@ -552,11 +560,16 @@ void SsrCommand::execute(Options options) {
}
}

auto ura_override = 0;
auto ura_override = -1;
if (*mUraOverrideArg) {
ura_override = mUraOverrideArg->Get();
}

auto ura_default = -1;
if (*mUraDefaultArg) {
ura_default = mUraDefaultArg->Get();
}

auto ublox_clock_correction = false;
if (*mUbloxClockCorrectionArg) {
ublox_clock_correction = mUbloxClockCorrectionArg->Get();
Expand Down Expand Up @@ -625,9 +638,10 @@ void SsrCommand::execute(Options options) {
print_rtcm = true;
}

::execute(std::move(options), format, ura_override, ublox_clock_correction, force_continuity,
average_zenith_delay, iode_shift, sf055_override, sf055_default, sf042_override,
sf042_default, increasing_siou, filter_by_ocb, ignore_l2l, print_rtcm);
::execute(std::move(options), format, ura_override, ura_default, ublox_clock_correction,
force_continuity, average_zenith_delay, iode_shift, sf055_override, sf055_default,
sf042_override, sf042_default, increasing_siou, filter_by_ocb, ignore_l2l,
print_rtcm);
}

} // namespace ssr_example
13 changes: 8 additions & 5 deletions examples/lpp/ssr_example.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ class SsrCommand final : public Command {
public:
SsrCommand()
: Command("ssr", "Request State-space Representation (SSR) data from the location server"),
mFormatArg(nullptr), mUraOverrideArg(nullptr), mUbloxClockCorrectionArg(nullptr),
mForceContinuityArg(nullptr), mAverageZenithDelayArg(nullptr), mEnableIodeShift(nullptr),
mSf055Override(nullptr), mSf055Default(nullptr), mSf042Override(nullptr),
mSf042Default(nullptr), mIncreasingSiou(nullptr), mFilterByOcb(nullptr),
mIgnoreL2L(nullptr), mPrintRTCMArg(nullptr) {}
mFormatArg(nullptr), mUraOverrideArg(nullptr), mUraDefaultArg(nullptr),
mUbloxClockCorrectionArg(nullptr), mForceContinuityArg(nullptr),
mAverageZenithDelayArg(nullptr), mEnableIodeShift(nullptr), mSf055Override(nullptr),
mSf055Default(nullptr), mSf042Override(nullptr), mSf042Default(nullptr),
mIncreasingSiou(nullptr), mFilterByOcb(nullptr), mIgnoreL2L(nullptr),
mPrintRTCMArg(nullptr) {}

~SsrCommand() override {
delete mFormatArg;
delete mUraOverrideArg;
delete mUraDefaultArg;
delete mUbloxClockCorrectionArg;
delete mForceContinuityArg;
delete mAverageZenithDelayArg;
Expand All @@ -50,6 +52,7 @@ class SsrCommand final : public Command {
private:
args::ValueFlag<std::string>* mFormatArg;
args::ValueFlag<int>* mUraOverrideArg;
args::ValueFlag<int>* mUraDefaultArg;
args::Flag* mUbloxClockCorrectionArg;
args::Flag* mForceContinuityArg;
args::Flag* mAverageZenithDelayArg;
Expand Down
21 changes: 14 additions & 7 deletions examples/modem_ctrl/main.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "options.hpp"

#include <inttypes.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <inttypes.h>

#include <interface/interface.hpp>
#include <modem/modem.hpp>
Expand Down Expand Up @@ -70,24 +70,28 @@ static int start_server(int port) {
auto length = snprintf(buffer, sizeof(buffer), "%s\r\n", command);
auto result = ::send(client, buffer, static_cast<size_t>(length), MSG_NOSIGNAL);
if (result < 0) {
printf("write failed\n");
exit(1);
return false;
}

return true;
};

for (;;) {
printf("-----------------------------------------------------\n");
auto client = ::accept(socket, nullptr, nullptr);
if (client < 0) {
printf("accept failed\n");
exit(1);
continue;
}

device.get_cgmi();
auto cimi = device.get_cimi();
char send_buffer[1024];
snprintf(send_buffer, sizeof(send_buffer), "/IDENTITY,IMSI,%" PRIu64, cimi.imsi);
send_command(client, send_buffer);
if (!send_command(client, send_buffer)) {
::close(client);
continue;
}

auto connected = true;
while (connected) {
Expand All @@ -113,9 +117,12 @@ static int start_server(int port) {
snprintf(send_buffer, sizeof(send_buffer), "/CID,L,%d,%d,%d,%d", cops.mcc,
cops.mnc, reg.lac, reg.ci);
}
send_command(client, send_buffer);
if (!send_command(client, send_buffer)) {
::close(client);
continue;
}
}

sleep(config.update_interval);
}

Expand Down
3 changes: 2 additions & 1 deletion generator/spartn2/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ namespace generator {
namespace spartn {

Generator::Generator()
: mGenerationIndex(0), mNextAreaId(0), mUraOverride(-1), mContinuityIndicator(-1),
: mGenerationIndex(0), mNextAreaId(0), mUraOverride(-1),
mUraDefault(0 /* SF024(0) = unknown */), mContinuityIndicator(-1),
mUBloxClockCorrection(false), mSf055Override(-1), mSf055Default(0 /* SF055(0) = invalid */),
mSf042Override(-1), mSf042Default(7 /* SF042(7) = >0.320m */),
mComputeAverageZenithDelay(false), mGroupByEpochTime(false), mIodeShift(true),
Expand Down
19 changes: 17 additions & 2 deletions generator/spartn2/hpac.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,17 @@ static double compute_average_zentith_delay(GNSS_SSR_GriddedCorrection_r16 const

static void troposphere_data_block(MessageBuilder& builder,
GNSS_SSR_GriddedCorrection_r16 const& data, int sf042_override,
int sf042_default, bool use_average_zenith_delay, bool calculate_sf051) {
int sf042_default, bool use_average_zenith_delay,
bool calculate_sf051) {
// NOTE(ewasjon): Use a polynomial of degree 0, as we don't have a polynomial in 3GPP
// LPP. This will result in a constant value for the troposphere correction.
builder.sf041(0 /* T_00 */);

if (sf042_override >= 0) {
uint8_t value = sf042_override > 7 ? 7 : static_cast<uint8_t>(sf042_override);
#ifdef SPARTN_DEBUG_PRINT
printf(" sf042: %d [override]\n", value);
#endif
builder.sf042_raw(value);
} else if (data.troposphericDelayQualityIndicator_r16) {
// TODO(ewasjon): Refactor as function in decode namespace
Expand All @@ -280,8 +284,16 @@ static void troposphere_data_block(MessageBuilder& builder
auto val = quality.buf[0] & 0x7;
auto q = pow(3, cls) * (1 + static_cast<double>(val) / 4.0) - 1;
auto q_meter = q / 1000.0;
#ifdef SPARTN_DEBUG_PRINT
printf(" sf042: %f\n", q_meter);
#endif
builder.sf042(q_meter);
} else {
#ifdef SPARTN_DEBUG_PRINT
printf(" sf042: %d [default]\n", sf042_default);
#endif
uint8_t value =
sf042_default < 0 ? 0 : (sf042_default > 7 ? 7 : static_cast<uint8_t>(sf042_default));
builder.sf042_raw(sf042_default);
}

Expand Down Expand Up @@ -457,7 +469,10 @@ static void ionosphere_data_block_1(MessageBuilder& builder, HpacSatellite const
#ifdef SPARTN_DEBUG_PRINT
printf(" sf055: %d [default]\n", sf055_default);
#endif
builder.sf055_raw(sf055_default);
uint8_t value = sf055_default < 0 ?
0 :
(sf055_default > 15 ? 15 : static_cast<uint8_t>(sf055_default));
builder.sf055_raw(value);
} else {
#ifdef SPARTN_DEBUG_PRINT
printf(" sf055: %f\n", q.value);
Expand Down
4 changes: 3 additions & 1 deletion generator/spartn2/include/generator/spartn2/generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Generator {
~Generator();

void set_ura_override(int ura_override) { mUraOverride = ura_override; }
void set_ura_default(int ura_default) { mUraDefault = ura_default; }

void set_continuity_indicator(double continuity_indicator) {
mContinuityIndicator = continuity_indicator;
Expand Down Expand Up @@ -106,7 +107,8 @@ class Generator {
std::unique_ptr<CorrectionData> mCorrectionData;
std::vector<Message> mMessages;

int mUraOverride; // <0 = no override
int mUraOverride; // <0 = no override
int mUraDefault;
double mContinuityIndicator; // <0 = no override
bool mUBloxClockCorrection;

Expand Down
12 changes: 11 additions & 1 deletion generator/spartn2/ocb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,12 +718,22 @@ void Generator::generate_ocb(uint16_t iod) {
if (mUraOverride >= 0) {
uint8_t ura_value = mUraOverride > 7 ? 7 : static_cast<uint8_t>(mUraOverride);
builder.sf024_raw(ura_value);
#ifdef SPARTN_DEBUG_PRINT
printf(" sf024: %u [override]\n", ura_value);
#endif
} else if (satellite.ura) {
auto& ura = *satellite.ura;
auto value = decode::ssr_URA_r16(ura.ssr_URA_r16);
#ifdef SPARTN_DEBUG_PRINT
printf(" sf024: %f\n", value);
#endif
builder.sf024(value);
} else {
builder.sf024_raw(0);
#ifdef SPARTN_DEBUG_PRINT
printf(" sf024: %u [default]\n", mUraDefault);
#endif
uint8_t ura_value = mUraDefault < 0 ? 0 : (mUraDefault > 7 ? 7 : mUraDefault);
builder.sf024_raw(ura_value);
}
}

Expand Down
5 changes: 5 additions & 0 deletions interface/file_descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ bool FileDescriptor::can_write() IF_NOEXCEPT {
return select(false, true, false, &tv);
}

bool FileDescriptor::can_except() IF_NOEXCEPT {
struct timeval tv = {0, 0};
return select(false, false, true, &tv);
}

bool FileDescriptor::wait_for_read() IF_NOEXCEPT {
return select(true, false, false, nullptr);
}
Expand Down
Loading