You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1184 lines
37 KiB
1184 lines
37 KiB
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cassert>
|
|
#include <csignal>
|
|
#include <unistd.h>
|
|
#include <semaphore.h>
|
|
#include <time.h>
|
|
|
|
#include <pthread.h>
|
|
#include <capnp/serialize.h>
|
|
|
|
#include "cereal/gen/cpp/log.capnp.h"
|
|
|
|
#include "messaging.hpp"
|
|
#include "common/timing.h"
|
|
#include "common/util.h"
|
|
#include "common/swaglog.h"
|
|
|
|
#include "libdiag.h"
|
|
|
|
#define NV_GNSS_OEM_FEATURE_MASK 7165
|
|
# define NV_GNSS_OEM_FEATURE_MASK_OEMDRE 1
|
|
#define NV_CGPS_DPO_CONTROL 5596
|
|
|
|
#define DIAG_NV_READ_F 38
|
|
#define DIAG_NV_WRITE_F 39
|
|
|
|
#define DIAG_SUBSYS_CMD 75
|
|
#define DIAG_SUBSYS_CMD_VER_2 128
|
|
|
|
#define DIAG_SUBSYS_GPS 13
|
|
#define DIAG_SUBSYS_FS 19
|
|
|
|
#define CGPS_DIAG_PDAPI_CMD 100
|
|
#define CGPS_OEM_CONTROL 202
|
|
|
|
#define GPSDIAG_OEMFEATURE_DRE 1
|
|
#define GPSDIAG_OEM_DRE_ON 1
|
|
|
|
#define FEATURE_OEMDRE_NOT_SUPPORTED 1
|
|
#define FEATURE_OEMDRE_ON 2
|
|
#define FEATURE_OEMDRE_ALREADY_ON 4
|
|
|
|
#define TM_DIAG_NAV_CONFIG_CMD 0x6E
|
|
|
|
#define EFS2_DIAG_SYNC_NO_WAIT 48
|
|
|
|
struct __attribute__((packed)) NvPacket {
|
|
uint8_t cmd_code;
|
|
uint16_t nv_id;
|
|
uint8_t data[128];
|
|
uint16_t status;
|
|
};
|
|
|
|
enum NvStatus {
|
|
NV_DONE,
|
|
NV_BUSY,
|
|
NV_FULL,
|
|
NV_FAIL,
|
|
NV_NOTACTIVE,
|
|
NV_BADPARAM,
|
|
NV_READONLY,
|
|
NV_BADRG,
|
|
NV_NOMEM,
|
|
NV_NOTALLOC,
|
|
};
|
|
|
|
struct __attribute__((packed)) Efs2DiagSyncReq {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint16_t sequence_num;
|
|
char path[8];
|
|
};
|
|
|
|
|
|
struct __attribute__((packed)) Efs2DiagSyncResp {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint16_t sequence_num;
|
|
uint32_t sync_token;
|
|
int32_t diag_errno;
|
|
};
|
|
|
|
|
|
|
|
struct __attribute__((packed)) GpsOemControlReq {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint8_t gps_cmd_code;
|
|
uint8_t version;
|
|
|
|
uint32_t oem_feature;
|
|
uint32_t oem_command;
|
|
uint32_t reserved[2];
|
|
};
|
|
|
|
|
|
struct __attribute__((packed)) GpsOemControlResp {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint8_t gps_cmd_code;
|
|
uint8_t version;
|
|
|
|
uint32_t oem_feature;
|
|
uint32_t oem_command;
|
|
uint32_t resp_result;
|
|
uint32_t reserved[2];
|
|
};
|
|
|
|
struct __attribute__((packed)) GpsNavConfigReq {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint32_t subsys_status;
|
|
uint16_t subsys_delayed_resp_id;
|
|
uint16_t subsys_rsp_cnt;
|
|
|
|
uint8_t desired_config;
|
|
};
|
|
|
|
struct __attribute__((packed)) GpsNavConfigResp {
|
|
uint8_t cmd_code;
|
|
uint8_t subsys_id;
|
|
uint16_t subsys_cmd_code;
|
|
uint32_t subsys_status;
|
|
uint16_t subsys_delayed_resp_id;
|
|
uint16_t subsys_rsp_cnt;
|
|
|
|
uint8_t supported_config;
|
|
uint8_t actual_config;
|
|
};
|
|
|
|
|
|
#define LOG_GNSS_POSITION_REPORT 0x1476
|
|
#define LOG_GNSS_GPS_MEASUREMENT_REPORT 0x1477
|
|
#define LOG_GNSS_CLOCK_REPORT 0x1478
|
|
#define LOG_GNSS_GLONASS_MEASUREMENT_REPORT 0x1480
|
|
#define LOG_GNSS_BDS_MEASUREMENT_REPORT 0x1756
|
|
#define LOG_GNSS_GAL_MEASUREMENT_REPORT 0x1886
|
|
|
|
#define LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT 0x14DE
|
|
#define LOG_GNSS_OEMDRE_SVPOLY_REPORT 0x14E1
|
|
|
|
#define LOG_GNSS_ME_DPO_STATUS 0x1838
|
|
#define LOG_GNSS_CD_DB_REPORT 0x147B
|
|
#define LOG_GNSS_PRX_RF_HW_STATUS_REPORT 0x147E
|
|
#define LOG_CGPS_SLOW_CLOCK_CLIB_REPORT 0x1488
|
|
#define LOG_GNSS_CONFIGURATION_STATE 0x1516
|
|
|
|
struct __attribute__((packed)) log_header_type {
|
|
uint16_t len;
|
|
uint16_t code;
|
|
uint64_t ts;
|
|
};
|
|
|
|
|
|
|
|
enum SVObservationStates {
|
|
SV_IDLE,
|
|
SV_SEARCH,
|
|
SV_SEACH_VERIFY,
|
|
SV_BIT_EDGE,
|
|
SV_TRACK_VERIFY,
|
|
SV_TRACK,
|
|
SV_RESTART,
|
|
SV_DPO,
|
|
SV_GLO_10ms_BE,
|
|
SV_GLO_10ms_AT,
|
|
};
|
|
|
|
struct __attribute__((packed)) GNSSGpsMeasurementReportv0_SV{
|
|
uint8_t sv_id;
|
|
uint8_t observation_state; // SVObservationStates
|
|
uint8_t observations;
|
|
uint8_t good_observations;
|
|
uint16_t parity_error_count;
|
|
uint8_t filter_stages;
|
|
uint16_t carrier_noise;
|
|
int16_t latency;
|
|
uint8_t predetect_interval;
|
|
uint16_t postdetections;
|
|
uint32_t unfiltered_measurement_integral;
|
|
float unfiltered_measurement_fraction;
|
|
float unfiltered_time_uncertainty;
|
|
float unfiltered_speed;
|
|
float unfiltered_speed_uncertainty;
|
|
uint32_t measurement_status;
|
|
uint8_t misc_status;
|
|
uint32_t multipath_estimate;
|
|
float azimuth;
|
|
float elevation;
|
|
int32_t carrier_phase_cycles_integral;
|
|
uint16_t carrier_phase_cycles_fraction;
|
|
float fine_speed;
|
|
float fine_speed_uncertainty;
|
|
uint8_t cycle_slip_count;
|
|
uint32_t pad;
|
|
};
|
|
|
|
_Static_assert(sizeof(GNSSGpsMeasurementReportv0_SV) == 70, "error");
|
|
|
|
struct __attribute__((packed)) GNSSGpsMeasurementReportv0{
|
|
log_header_type header;
|
|
uint8_t version;
|
|
uint32_t f_count;
|
|
uint16_t week;
|
|
uint32_t milliseconds;
|
|
float time_bias;
|
|
float clock_time_uncertainty;
|
|
float clock_frequency_bias;
|
|
float clock_frequency_uncertainty;
|
|
uint8_t sv_count;
|
|
GNSSGpsMeasurementReportv0_SV sv[];
|
|
};
|
|
|
|
|
|
|
|
struct __attribute__((packed)) GNSSGlonassMeasurementReportv0_SV {
|
|
uint8_t sv_id;
|
|
int8_t frequency_index;
|
|
uint8_t observation_state; // SVObservationStates
|
|
uint8_t observations;
|
|
uint8_t good_observations;
|
|
uint8_t hemming_error_count;
|
|
uint8_t filter_stages;
|
|
uint16_t carrier_noise;
|
|
int16_t latency;
|
|
uint8_t predetect_interval;
|
|
uint16_t postdetections;
|
|
uint32_t unfiltered_measurement_integral;
|
|
float unfiltered_measurement_fraction;
|
|
float unfiltered_time_uncertainty;
|
|
float unfiltered_speed;
|
|
float unfiltered_speed_uncertainty;
|
|
uint32_t measurement_status;
|
|
uint8_t misc_status;
|
|
uint32_t multipath_estimate;
|
|
float azimuth;
|
|
float elevation;
|
|
int32_t carrier_phase_cycles_integral;
|
|
uint16_t carrier_phase_cycles_fraction;
|
|
float fine_speed;
|
|
float fine_speed_uncertainty;
|
|
uint8_t cycle_slip_count;
|
|
uint32_t pad;
|
|
};
|
|
|
|
_Static_assert(sizeof(GNSSGlonassMeasurementReportv0_SV) == 70, "error");
|
|
|
|
struct __attribute__((packed)) GNSSGlonassMeasurementReportv0 {
|
|
log_header_type header;
|
|
uint8_t version;
|
|
uint32_t f_count;
|
|
uint8_t glonass_cycle_number;
|
|
uint16_t glonass_number_of_days;
|
|
uint32_t milliseconds;
|
|
float time_bias;
|
|
float clock_time_uncertainty;
|
|
float clock_frequency_bias;
|
|
float clock_frequency_uncertainty;
|
|
uint8_t sv_count;
|
|
GNSSGlonassMeasurementReportv0_SV sv[];
|
|
};
|
|
|
|
|
|
struct __attribute__((packed)) GNSSClockReportv2 {
|
|
log_header_type header;
|
|
uint8_t version;
|
|
uint16_t valid_flags;
|
|
|
|
uint32_t f_count;
|
|
|
|
uint16_t gps_week;
|
|
uint32_t gps_milliseconds;
|
|
float gps_time_bias;
|
|
float gps_clock_time_uncertainty;
|
|
uint8_t gps_clock_source;
|
|
|
|
uint8_t glonass_year;
|
|
uint16_t glonass_day;
|
|
uint32_t glonass_milliseconds;
|
|
float glonass_time_bias;
|
|
float glonass_clock_time_uncertainty;
|
|
uint8_t glonass_clock_source;
|
|
|
|
uint16_t bds_week;
|
|
uint32_t bds_milliseconds;
|
|
float bds_time_bias;
|
|
float bds_clock_time_uncertainty;
|
|
uint8_t bds_clock_source;
|
|
|
|
uint16_t gal_week;
|
|
uint32_t gal_milliseconds;
|
|
float gal_time_bias;
|
|
float gal_clock_time_uncertainty;
|
|
uint8_t gal_clock_source;
|
|
|
|
float clock_frequency_bias;
|
|
float clock_frequency_uncertainty;
|
|
uint8_t frequency_source;
|
|
uint8_t gps_leap_seconds;
|
|
uint8_t gps_leap_seconds_uncertainty;
|
|
uint8_t gps_leap_seconds_source;
|
|
|
|
float gps_to_glonass_time_bias_milliseconds;
|
|
float gps_to_glonass_time_bias_milliseconds_uncertainty;
|
|
float gps_to_bds_time_bias_milliseconds;
|
|
float gps_to_bds_time_bias_milliseconds_uncertainty;
|
|
float bds_to_glo_time_bias_milliseconds;
|
|
float bds_to_glo_time_bias_milliseconds_uncertainty;
|
|
float gps_to_gal_time_bias_milliseconds;
|
|
float gps_to_gal_time_bias_milliseconds_uncertainty;
|
|
float gal_to_glo_time_bias_milliseconds;
|
|
float gal_to_glo_time_bias_milliseconds_uncertainty;
|
|
float gal_to_bds_time_bias_milliseconds;
|
|
float gal_to_bds_time_bias_milliseconds_uncertainty;
|
|
|
|
uint32_t system_rtc_time;
|
|
uint32_t f_count_offset;
|
|
uint32_t lpm_rtc_count;
|
|
uint32_t clock_resets;
|
|
|
|
uint32_t reserved[3];
|
|
|
|
};
|
|
|
|
|
|
enum GNSSMeasurementSource {
|
|
SOURCE_GPS,
|
|
SOURCE_GLONASS,
|
|
SOURCE_BEIDOU,
|
|
};
|
|
|
|
struct __attribute__((packed)) GNSSOemdreMeasurement {
|
|
uint8_t sv_id;
|
|
uint8_t unkn;
|
|
int8_t glonass_frequency_index;
|
|
uint32_t observation_state;
|
|
uint8_t observations;
|
|
uint8_t good_observations;
|
|
uint8_t filter_stages;
|
|
uint8_t predetect_interval;
|
|
uint8_t cycle_slip_count;
|
|
uint16_t postdetections;
|
|
|
|
uint32_t measurement_status;
|
|
uint32_t measurement_status2;
|
|
|
|
uint16_t carrier_noise;
|
|
uint16_t rf_loss;
|
|
int16_t latency;
|
|
|
|
float filtered_measurement_fraction;
|
|
uint32_t filtered_measurement_integral;
|
|
float filtered_time_uncertainty;
|
|
float filtered_speed;
|
|
float filtered_speed_uncertainty;
|
|
|
|
float unfiltered_measurement_fraction;
|
|
uint32_t unfiltered_measurement_integral;
|
|
float unfiltered_time_uncertainty;
|
|
float unfiltered_speed;
|
|
float unfiltered_speed_uncertainty;
|
|
|
|
uint8_t multipath_estimate_valid;
|
|
uint32_t multipath_estimate;
|
|
uint8_t direction_valid;
|
|
float azimuth;
|
|
float elevation;
|
|
float doppler_acceleration;
|
|
float fine_speed;
|
|
float fine_speed_uncertainty;
|
|
|
|
uint64_t carrier_phase;
|
|
uint32_t f_count;
|
|
|
|
uint16_t parity_error_count;
|
|
uint8_t good_parity;
|
|
|
|
};
|
|
|
|
_Static_assert(sizeof(GNSSOemdreMeasurement) == 109, "error");
|
|
|
|
struct __attribute__((packed)) GNSSOemdreMeasurementReportv2 {
|
|
log_header_type header;
|
|
uint8_t version;
|
|
uint8_t reason;
|
|
uint8_t sv_count;
|
|
uint8_t seq_num;
|
|
uint8_t seq_max;
|
|
uint16_t rf_loss;
|
|
|
|
uint8_t system_rtc_valid;
|
|
uint32_t f_count;
|
|
uint32_t clock_resets;
|
|
uint64_t system_rtc_time;
|
|
|
|
uint8_t gps_leap_seconds;
|
|
uint8_t gps_leap_seconds_uncertainty;
|
|
float gps_to_glonass_time_bias_milliseconds;
|
|
float gps_to_glonass_time_bias_milliseconds_uncertainty;
|
|
|
|
uint16_t gps_week;
|
|
uint32_t gps_milliseconds;
|
|
uint32_t gps_time_bias;
|
|
uint32_t gps_clock_time_uncertainty;
|
|
uint8_t gps_clock_source;
|
|
|
|
uint8_t glonass_clock_source;
|
|
uint8_t glonass_year;
|
|
uint16_t glonass_day;
|
|
uint32_t glonass_milliseconds;
|
|
float glonass_time_bias;
|
|
float glonass_clock_time_uncertainty;
|
|
|
|
float clock_frequency_bias;
|
|
float clock_frequency_uncertainty;
|
|
uint8_t frequency_source;
|
|
|
|
uint32_t cdma_clock_info[5];
|
|
|
|
uint8_t source;
|
|
|
|
GNSSOemdreMeasurement measurements[16];
|
|
|
|
};
|
|
|
|
_Static_assert(sizeof(GNSSOemdreMeasurementReportv2) == 1851, "error");
|
|
|
|
|
|
struct __attribute__((packed)) GNSSOemdreSVPolyReportv2 {
|
|
log_header_type header;
|
|
uint8_t version;
|
|
uint16_t sv_id;
|
|
int8_t frequency_index;
|
|
uint8_t flags;
|
|
uint16_t iode;
|
|
double t0;
|
|
double xyz0[3];
|
|
double xyzN[9];
|
|
float other[4];
|
|
float position_uncertainty;
|
|
float iono_delay;
|
|
float iono_dot;
|
|
float sbas_iono_delay;
|
|
float sbas_iono_dot;
|
|
float tropo_delay;
|
|
float elevation;
|
|
float elevation_dot;
|
|
float elevation_uncertainty;
|
|
double velocity_coeff[12];
|
|
};
|
|
|
|
_Static_assert(sizeof(GNSSOemdreSVPolyReportv2) == 271, "error");
|
|
|
|
|
|
static Context *rawgps_context;
|
|
static PubSocket *rawgps_publisher;
|
|
static int client_id = 0;
|
|
|
|
static void hexdump(uint8_t* d, size_t len) {
|
|
for (int i=0; i<len; i++) {
|
|
printf("%02x ", d[i]);
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
static void parse_measurement_status_common(uint32_t measurement_status,
|
|
cereal::QcomGnss::MeasurementStatus::Builder status) {
|
|
status.setSubMillisecondIsValid(measurement_status & (1 << 0));
|
|
status.setSubBitTimeIsKnown(measurement_status & (1 << 1));
|
|
status.setSatelliteTimeIsKnown(measurement_status & (1 << 2));
|
|
status.setBitEdgeConfirmedFromSignal(measurement_status & (1 << 3));
|
|
status.setMeasuredVelocity(measurement_status & (1 << 4));
|
|
status.setFineOrCoarseVelocity(measurement_status & (1 << 5));
|
|
status.setLockPointValid(measurement_status & (1 << 6));
|
|
status.setLockPointPositive(measurement_status & (1 << 7));
|
|
|
|
status.setLastUpdateFromDifference(measurement_status & (1 << 9));
|
|
status.setLastUpdateFromVelocityDifference(measurement_status & (1 << 10));
|
|
status.setStrongIndicationOfCrossCorelation(measurement_status & (1 << 11));
|
|
status.setTentativeMeasurement(measurement_status & (1 << 12));
|
|
status.setMeasurementNotUsable(measurement_status & (1 << 13));
|
|
status.setSirCheckIsNeeded(measurement_status & (1 << 14));
|
|
status.setProbationMode(measurement_status & (1 << 15));
|
|
|
|
status.setMultipathIndicator(measurement_status & (1 << 24));
|
|
status.setImdJammingIndicator(measurement_status & (1 << 25));
|
|
status.setLteB13TxJammingIndicator(measurement_status & (1 << 26));
|
|
status.setFreshMeasurementIndicator(measurement_status & (1 << 27));
|
|
}
|
|
|
|
static void handle_log(uint8_t *ptr, int len) {
|
|
assert(len >= sizeof(log_header_type)+1);
|
|
log_header_type* log_header = (log_header_type*)ptr;
|
|
uint8_t* log_data = ptr + sizeof(log_header_type);
|
|
|
|
#ifdef RAWGPS_TEST
|
|
printf("%04x\n", log_header->code);
|
|
#endif
|
|
|
|
capnp::MallocMessageBuilder msg;
|
|
cereal::Event::Builder event = msg.initRoot<cereal::Event>();
|
|
event.setLogMonoTime(nanos_since_boot());
|
|
auto qcomGnss = event.initQcomGnss();
|
|
qcomGnss.setLogTs(log_header->ts);
|
|
|
|
switch (log_header->code) {
|
|
|
|
case LOG_GNSS_CLOCK_REPORT: {
|
|
uint8_t version = log_data[0];
|
|
assert(version == 2);
|
|
|
|
assert(len >= sizeof(GNSSClockReportv2));
|
|
const GNSSClockReportv2* report = (const GNSSClockReportv2*)ptr;
|
|
|
|
auto lreport = qcomGnss.initClockReport();
|
|
lreport.setHasFCount(report->valid_flags & (1 << 0));
|
|
lreport.setFCount(report->f_count);
|
|
|
|
lreport.setHasGpsWeek(report->valid_flags & (1 << 2));
|
|
lreport.setGpsWeek(report->gps_week);
|
|
lreport.setHasGpsMilliseconds(report->valid_flags & (1 << 1));
|
|
lreport.setGpsMilliseconds(report->gps_milliseconds);
|
|
lreport.setGpsTimeBias(report->gps_time_bias);
|
|
lreport.setGpsClockTimeUncertainty(report->gps_clock_time_uncertainty);
|
|
lreport.setGpsClockSource(report->gps_clock_source);
|
|
|
|
lreport.setHasGlonassYear(report->valid_flags & (1 << 6));
|
|
lreport.setGlonassYear(report->glonass_year);
|
|
lreport.setHasGlonassDay(report->valid_flags & (1 << 5));
|
|
lreport.setGlonassDay(report->glonass_day);
|
|
lreport.setHasGlonassMilliseconds(report->valid_flags & (1 << 4));
|
|
lreport.setGlonassMilliseconds(report->glonass_milliseconds);
|
|
lreport.setGlonassTimeBias(report->glonass_time_bias);
|
|
lreport.setGlonassClockTimeUncertainty(report->glonass_clock_time_uncertainty);
|
|
lreport.setGlonassClockSource(report->glonass_clock_source);
|
|
|
|
lreport.setBdsWeek(report->bds_week);
|
|
lreport.setBdsMilliseconds(report->bds_milliseconds);
|
|
lreport.setBdsTimeBias(report->bds_time_bias);
|
|
lreport.setBdsClockTimeUncertainty(report->bds_clock_time_uncertainty);
|
|
lreport.setBdsClockSource(report->bds_clock_source);
|
|
|
|
lreport.setGalWeek(report->gal_week);
|
|
lreport.setGalMilliseconds(report->gal_milliseconds);
|
|
lreport.setGalTimeBias(report->gal_time_bias);
|
|
lreport.setGalClockTimeUncertainty(report->gal_clock_time_uncertainty);
|
|
lreport.setGalClockSource(report->gal_clock_source);
|
|
|
|
lreport.setClockFrequencyBias(report->clock_frequency_bias);
|
|
lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty);
|
|
lreport.setFrequencySource(report->frequency_source);
|
|
lreport.setGpsLeapSeconds(report->gps_leap_seconds);
|
|
lreport.setGpsLeapSecondsUncertainty(report->gps_leap_seconds_uncertainty);
|
|
lreport.setGpsLeapSecondsSource(report->gps_leap_seconds_source);
|
|
|
|
lreport.setGpsToGlonassTimeBiasMilliseconds(report->gps_to_glonass_time_bias_milliseconds);
|
|
lreport.setGpsToGlonassTimeBiasMillisecondsUncertainty(report->gps_to_glonass_time_bias_milliseconds_uncertainty);
|
|
lreport.setGpsToBdsTimeBiasMilliseconds(report->gps_to_bds_time_bias_milliseconds);
|
|
lreport.setGpsToBdsTimeBiasMillisecondsUncertainty(report->gps_to_bds_time_bias_milliseconds_uncertainty);
|
|
lreport.setBdsToGloTimeBiasMilliseconds(report->bds_to_glo_time_bias_milliseconds);
|
|
lreport.setBdsToGloTimeBiasMillisecondsUncertainty(report->bds_to_glo_time_bias_milliseconds_uncertainty);
|
|
lreport.setGpsToGalTimeBiasMilliseconds(report->gps_to_gal_time_bias_milliseconds);
|
|
lreport.setGpsToGalTimeBiasMillisecondsUncertainty(report->gps_to_gal_time_bias_milliseconds_uncertainty);
|
|
lreport.setGalToGloTimeBiasMilliseconds(report->gal_to_glo_time_bias_milliseconds);
|
|
lreport.setGalToGloTimeBiasMillisecondsUncertainty(report->gal_to_glo_time_bias_milliseconds_uncertainty);
|
|
lreport.setGalToBdsTimeBiasMilliseconds(report->gal_to_bds_time_bias_milliseconds);
|
|
lreport.setGalToBdsTimeBiasMillisecondsUncertainty(report->gal_to_bds_time_bias_milliseconds_uncertainty);
|
|
|
|
lreport.setHasRtcTime(report->valid_flags & (1 << 3));
|
|
lreport.setSystemRtcTime(report->system_rtc_time);
|
|
lreport.setFCountOffset(report->f_count_offset);
|
|
lreport.setLpmRtcCount(report->lpm_rtc_count);
|
|
lreport.setClockResets(report->clock_resets);
|
|
|
|
break;
|
|
}
|
|
case LOG_GNSS_GPS_MEASUREMENT_REPORT: {
|
|
uint8_t version = log_data[0];
|
|
assert(version == 0);
|
|
|
|
assert(len >= sizeof(GNSSGpsMeasurementReportv0));
|
|
const GNSSGpsMeasurementReportv0* report = (const GNSSGpsMeasurementReportv0*)ptr;
|
|
assert(len >= sizeof(sizeof(GNSSGpsMeasurementReportv0))+sizeof(GNSSGpsMeasurementReportv0_SV) * report->sv_count);
|
|
|
|
auto lreport = qcomGnss.initMeasurementReport();
|
|
lreport.setSource(cereal::QcomGnss::MeasurementSource::GPS);
|
|
lreport.setFCount(report->f_count);
|
|
lreport.setGpsWeek(report->week);
|
|
lreport.setMilliseconds(report->milliseconds);
|
|
lreport.setTimeBias(report->time_bias);
|
|
lreport.setClockTimeUncertainty(report->clock_time_uncertainty);
|
|
lreport.setClockFrequencyBias(report->clock_frequency_bias);
|
|
lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty);
|
|
|
|
auto lsvs = lreport.initSv(report->sv_count);
|
|
for (int i=0; i<report->sv_count; i++) {
|
|
auto lsv = lsvs[i];
|
|
const GNSSGpsMeasurementReportv0_SV *sv = &report->sv[i];
|
|
|
|
lsv.setSvId(sv->sv_id);
|
|
lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state));
|
|
lsv.setObservations(sv->observations);
|
|
lsv.setGoodObservations(sv->good_observations);
|
|
lsv.setGpsParityErrorCount(sv->parity_error_count);
|
|
lsv.setFilterStages(sv->filter_stages);
|
|
lsv.setCarrierNoise(sv->carrier_noise);
|
|
lsv.setLatency(sv->latency);
|
|
lsv.setPredetectInterval(sv->predetect_interval);
|
|
lsv.setPostdetections(sv->postdetections);
|
|
lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral);
|
|
lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction);
|
|
lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty);
|
|
lsv.setUnfilteredSpeed(sv->unfiltered_speed);
|
|
lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty);
|
|
|
|
lsv.setMultipathEstimate(sv->multipath_estimate);
|
|
lsv.setAzimuth(sv->azimuth);
|
|
lsv.setElevation(sv->elevation);
|
|
lsv.setCarrierPhaseCyclesIntegral(sv->carrier_phase_cycles_integral);
|
|
lsv.setCarrierPhaseCyclesFraction(sv->carrier_phase_cycles_fraction);
|
|
lsv.setFineSpeed(sv->fine_speed);
|
|
lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty);
|
|
lsv.setCycleSlipCount(sv->cycle_slip_count);
|
|
|
|
auto status = lsv.initMeasurementStatus();
|
|
parse_measurement_status_common(sv->measurement_status, status);
|
|
|
|
status.setGpsRoundRobinRxDiversity(sv->measurement_status & (1 << 18));
|
|
status.setGpsRxDiversity(sv->measurement_status & (1 << 19));
|
|
status.setGpsLowBandwidthRxDiversityCombined(sv->measurement_status & (1 << 20));
|
|
status.setGpsHighBandwidthNu4(sv->measurement_status & (1 << 21));
|
|
status.setGpsHighBandwidthNu8(sv->measurement_status & (1 << 22));
|
|
status.setGpsHighBandwidthUniform(sv->measurement_status & (1 << 23));
|
|
|
|
status.setMultipathEstimateIsValid(sv->misc_status & (1 << 0));
|
|
status.setDirectionIsValid(sv->misc_status & (1 << 1));
|
|
|
|
#ifdef RAWGPS_TEST
|
|
// if (sv->measurement_status & (1 << 27)) printf("%d\n", sv->unfiltered_measurement_integral);
|
|
printf("GPS %03d %d %d 0x%08X o: %02x go: %02x fs: %02x cn: %02x pd: %02x cs: %02x po: %02x ms: %08x ms2: %08x me: %08x az: %08x el: %08x fc: %08x\n",
|
|
sv->sv_id,
|
|
!!(sv->measurement_status & (1 << 27)),
|
|
sv->unfiltered_measurement_integral, sv->unfiltered_measurement_integral,
|
|
sv->observations,
|
|
sv->good_observations,
|
|
sv->filter_stages,
|
|
sv->carrier_noise,
|
|
sv->predetect_interval,
|
|
sv->cycle_slip_count,
|
|
sv->postdetections,
|
|
sv->measurement_status,
|
|
sv->misc_status,
|
|
sv->multipath_estimate,
|
|
*(uint32_t*)&sv->azimuth,
|
|
*(uint32_t*)&sv->elevation,
|
|
report->f_count
|
|
);
|
|
#endif
|
|
|
|
}
|
|
|
|
break;
|
|
}
|
|
case LOG_GNSS_GLONASS_MEASUREMENT_REPORT: {
|
|
uint8_t version = log_data[0];
|
|
assert(version == 0);
|
|
|
|
assert(len >= sizeof(GNSSGlonassMeasurementReportv0));
|
|
const GNSSGlonassMeasurementReportv0* report = (const GNSSGlonassMeasurementReportv0*)ptr;
|
|
|
|
auto lreport = qcomGnss.initMeasurementReport();
|
|
lreport.setSource(cereal::QcomGnss::MeasurementSource::GLONASS);
|
|
lreport.setFCount(report->f_count);
|
|
lreport.setGlonassCycleNumber(report->glonass_cycle_number);
|
|
lreport.setGlonassNumberOfDays(report->glonass_number_of_days);
|
|
lreport.setMilliseconds(report->milliseconds);
|
|
lreport.setTimeBias(report->time_bias);
|
|
lreport.setClockTimeUncertainty(report->clock_time_uncertainty);
|
|
lreport.setClockFrequencyBias(report->clock_frequency_bias);
|
|
lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty);
|
|
|
|
auto lsvs = lreport.initSv(report->sv_count);
|
|
for (int i=0; i<report->sv_count; i++) {
|
|
auto lsv = lsvs[i];
|
|
const GNSSGlonassMeasurementReportv0_SV *sv = &report->sv[i];
|
|
|
|
lsv.setSvId(sv->sv_id);
|
|
lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state));
|
|
lsv.setObservations(sv->observations);
|
|
lsv.setGoodObservations(sv->good_observations);
|
|
lsv.setGlonassFrequencyIndex(sv->frequency_index);
|
|
lsv.setGlonassHemmingErrorCount(sv->hemming_error_count);
|
|
lsv.setFilterStages(sv->filter_stages);
|
|
lsv.setCarrierNoise(sv->carrier_noise);
|
|
lsv.setLatency(sv->latency);
|
|
lsv.setPredetectInterval(sv->predetect_interval);
|
|
lsv.setPostdetections(sv->postdetections);
|
|
lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral);
|
|
lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction);
|
|
lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty);
|
|
lsv.setUnfilteredSpeed(sv->unfiltered_speed);
|
|
lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty);
|
|
|
|
lsv.setMultipathEstimate(sv->multipath_estimate);
|
|
lsv.setAzimuth(sv->azimuth);
|
|
lsv.setElevation(sv->elevation);
|
|
lsv.setCarrierPhaseCyclesIntegral(sv->carrier_phase_cycles_integral);
|
|
lsv.setCarrierPhaseCyclesFraction(sv->carrier_phase_cycles_fraction);
|
|
lsv.setFineSpeed(sv->fine_speed);
|
|
lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty);
|
|
lsv.setCycleSlipCount(sv->cycle_slip_count);
|
|
|
|
auto status = lsv.initMeasurementStatus();
|
|
parse_measurement_status_common(sv->measurement_status, status);
|
|
|
|
status.setGlonassMeanderBitEdgeValid(sv->measurement_status & (1 << 16));
|
|
status.setGlonassTimeMarkValid(sv->measurement_status & (1 << 17));
|
|
|
|
status.setMultipathEstimateIsValid(sv->misc_status & (1 << 0));
|
|
status.setDirectionIsValid(sv->misc_status & (1 << 1));
|
|
|
|
|
|
#ifdef RAWGPS_TEST
|
|
// if (sv->measurement_status & (1 << 27)) printf("%d\n", sv->unfiltered_measurement_integral);
|
|
printf("GLO %03d %02x %d %d 0x%08X o: %02x go: %02x fs: %02x cn: %02x pd: %02x cs: %02x po: %02x ms: %08x ms2: %08x me: %08x az: %08x el: %08x fc: %08x\n",
|
|
sv->sv_id, sv->frequency_index & 0xff,
|
|
!!(sv->measurement_status & (1 << 27)),
|
|
sv->unfiltered_measurement_integral, sv->unfiltered_measurement_integral,
|
|
sv->observations,
|
|
sv->good_observations,
|
|
sv->filter_stages,
|
|
sv->carrier_noise,
|
|
sv->predetect_interval,
|
|
sv->cycle_slip_count,
|
|
sv->postdetections,
|
|
sv->measurement_status,
|
|
sv->misc_status,
|
|
sv->multipath_estimate,
|
|
*(uint32_t*)&sv->azimuth,
|
|
*(uint32_t*)&sv->elevation,
|
|
report->f_count
|
|
);
|
|
#endif
|
|
|
|
}
|
|
break;
|
|
}
|
|
case LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT: {
|
|
// hexdump(ptr, len);
|
|
|
|
uint8_t version = log_data[0];
|
|
assert(version == 2);
|
|
|
|
assert(len >= sizeof(GNSSOemdreMeasurementReportv2));
|
|
const GNSSOemdreMeasurementReportv2* report = (const GNSSOemdreMeasurementReportv2*)ptr;
|
|
|
|
|
|
auto lreport = qcomGnss.initDrMeasurementReport();
|
|
|
|
lreport.setReason(report->reason);
|
|
lreport.setSeqNum(report->seq_num);
|
|
lreport.setSeqMax(report->seq_max);
|
|
lreport.setRfLoss(report->rf_loss);
|
|
lreport.setSystemRtcValid(report->system_rtc_valid);
|
|
lreport.setFCount(report->f_count);
|
|
lreport.setClockResets(report->clock_resets);
|
|
lreport.setSystemRtcTime(report->system_rtc_time);
|
|
|
|
lreport.setGpsLeapSeconds(report->gps_leap_seconds);
|
|
lreport.setGpsLeapSecondsUncertainty(report->gps_leap_seconds_uncertainty);
|
|
lreport.setGpsToGlonassTimeBiasMilliseconds(report->gps_to_glonass_time_bias_milliseconds);
|
|
lreport.setGpsToGlonassTimeBiasMillisecondsUncertainty(report->gps_to_glonass_time_bias_milliseconds_uncertainty);
|
|
|
|
lreport.setGpsWeek(report->gps_week);
|
|
lreport.setGpsMilliseconds(report->gps_milliseconds);
|
|
lreport.setGpsTimeBiasMs(report->gps_time_bias);
|
|
lreport.setGpsClockTimeUncertaintyMs(report->gps_clock_time_uncertainty);
|
|
lreport.setGpsClockSource(report->gps_clock_source);
|
|
|
|
lreport.setGlonassClockSource(report->glonass_clock_source);
|
|
lreport.setGlonassYear(report->glonass_year);
|
|
lreport.setGlonassDay(report->glonass_day);
|
|
lreport.setGlonassMilliseconds(report->glonass_milliseconds);
|
|
lreport.setGlonassTimeBias(report->glonass_time_bias);
|
|
lreport.setGlonassClockTimeUncertainty(report->glonass_clock_time_uncertainty);
|
|
|
|
lreport.setClockFrequencyBias(report->clock_frequency_bias);
|
|
lreport.setClockFrequencyUncertainty(report->clock_frequency_uncertainty);
|
|
lreport.setFrequencySource(report->frequency_source);
|
|
|
|
lreport.setSource(cereal::QcomGnss::MeasurementSource(report->source));
|
|
|
|
auto lsvs = lreport.initSv(report->sv_count);
|
|
|
|
// for (int i=0; i<report->sv_count; i++) {
|
|
// GNSSOemdreMeasurement *sv = &report->gps[i];
|
|
// if (!(sv->measurement_status & (1 << 27))) continue;
|
|
// printf("oemdre %03d %d %f\n", sv->sv_id, sv->unfiltered_measurement_integral, sv->unfiltered_measurement_fraction);
|
|
// }
|
|
for (int i=0; i<report->sv_count; i++) {
|
|
auto lsv = lsvs[i];
|
|
const GNSSOemdreMeasurement *sv = &report->measurements[i];
|
|
|
|
lsv.setSvId(sv->sv_id);
|
|
lsv.setGlonassFrequencyIndex(sv->glonass_frequency_index);
|
|
lsv.setObservationState(cereal::QcomGnss::SVObservationState(sv->observation_state));
|
|
lsv.setObservations(sv->observations);
|
|
lsv.setGoodObservations(sv->good_observations);
|
|
lsv.setFilterStages(sv->filter_stages);
|
|
lsv.setPredetectInterval(sv->predetect_interval);
|
|
lsv.setCycleSlipCount(sv->cycle_slip_count);
|
|
lsv.setPostdetections(sv->postdetections);
|
|
|
|
auto status = lsv.initMeasurementStatus();
|
|
parse_measurement_status_common(sv->measurement_status, status);
|
|
|
|
status.setMultipathEstimateIsValid(sv->multipath_estimate_valid);
|
|
status.setDirectionIsValid(sv->direction_valid);
|
|
|
|
lsv.setCarrierNoise(sv->carrier_noise);
|
|
lsv.setRfLoss(sv->rf_loss);
|
|
lsv.setLatency(sv->latency);
|
|
|
|
lsv.setFilteredMeasurementFraction(sv->filtered_measurement_fraction);
|
|
lsv.setFilteredMeasurementIntegral(sv->filtered_measurement_integral);
|
|
lsv.setFilteredTimeUncertainty(sv->filtered_time_uncertainty);
|
|
lsv.setFilteredSpeed(sv->filtered_speed);
|
|
lsv.setFilteredSpeedUncertainty(sv->filtered_speed_uncertainty);
|
|
|
|
lsv.setUnfilteredMeasurementFraction(sv->unfiltered_measurement_fraction);
|
|
lsv.setUnfilteredMeasurementIntegral(sv->unfiltered_measurement_integral);
|
|
lsv.setUnfilteredTimeUncertainty(sv->unfiltered_time_uncertainty);
|
|
lsv.setUnfilteredSpeed(sv->unfiltered_speed);
|
|
lsv.setUnfilteredSpeedUncertainty(sv->unfiltered_speed_uncertainty);
|
|
|
|
lsv.setMultipathEstimate(sv->multipath_estimate);
|
|
lsv.setAzimuth(sv->azimuth);
|
|
lsv.setElevation(sv->elevation);
|
|
lsv.setDopplerAcceleration(sv->doppler_acceleration);
|
|
lsv.setFineSpeed(sv->fine_speed);
|
|
lsv.setFineSpeedUncertainty(sv->fine_speed_uncertainty);
|
|
|
|
lsv.setCarrierPhase(sv->carrier_phase);
|
|
lsv.setFCount(sv->f_count);
|
|
|
|
lsv.setParityErrorCount(sv->parity_error_count);
|
|
lsv.setGoodParity(sv->good_parity);
|
|
|
|
}
|
|
break;
|
|
}
|
|
case LOG_GNSS_OEMDRE_SVPOLY_REPORT: {
|
|
uint8_t version = log_data[0];
|
|
assert(version == 2);
|
|
|
|
assert(len >= sizeof(GNSSOemdreSVPolyReportv2));
|
|
const GNSSOemdreSVPolyReportv2* report = (const GNSSOemdreSVPolyReportv2*)ptr;
|
|
|
|
auto lreport = qcomGnss.initDrSvPoly();
|
|
|
|
lreport.setSvId(report->sv_id);
|
|
lreport.setFrequencyIndex(report->frequency_index);
|
|
|
|
lreport.setHasPosition(report->flags & 1);
|
|
lreport.setHasIono(report->flags & 2);
|
|
lreport.setHasTropo(report->flags & 4);
|
|
lreport.setHasElevation(report->flags & 8);
|
|
lreport.setPolyFromXtra(report->flags & 16);
|
|
lreport.setHasSbasIono(report->flags & 32);
|
|
|
|
lreport.setIode(report->iode);
|
|
lreport.setT0(report->t0);
|
|
|
|
kj::ArrayPtr<const double> xyz0(report->xyz0, 3);
|
|
lreport.setXyz0(xyz0);
|
|
|
|
kj::ArrayPtr<const double> xyzN(report->xyzN, 9);
|
|
lreport.setXyzN(xyzN);
|
|
|
|
kj::ArrayPtr<const float> other(report->other, 4);
|
|
lreport.setOther(other);
|
|
|
|
lreport.setPositionUncertainty(report->position_uncertainty);
|
|
lreport.setIonoDelay(report->iono_delay);
|
|
lreport.setIonoDot(report->iono_dot);
|
|
lreport.setSbasIonoDelay(report->sbas_iono_delay);
|
|
lreport.setSbasIonoDot(report->sbas_iono_dot);
|
|
lreport.setTropoDelay(report->tropo_delay);
|
|
lreport.setElevation(report->elevation);
|
|
lreport.setElevationDot(report->elevation_dot);
|
|
lreport.setElevationUncertainty(report->elevation_uncertainty);
|
|
|
|
kj::ArrayPtr<const double> velocity_coeff(report->velocity_coeff, 12);
|
|
lreport.setVelocityCoeff(velocity_coeff);
|
|
|
|
break;
|
|
}
|
|
default:
|
|
// printf("%04x\n", log_header->code);
|
|
// hexdump(ptr, len);
|
|
|
|
qcomGnss.setRawLog(kj::arrayPtr(ptr, len));
|
|
|
|
break;
|
|
}
|
|
|
|
auto words = capnp::messageToFlatArray(msg);
|
|
auto bytes = words.asBytes();
|
|
rawgps_publisher->send((char*)bytes.begin(), bytes.size());
|
|
}
|
|
|
|
static void handle_event(unsigned char *ptr, int len) {
|
|
// printf("EVENT\n");
|
|
}
|
|
|
|
static uint16_t log_codes[] = {
|
|
LOG_GNSS_CLOCK_REPORT,
|
|
LOG_GNSS_GPS_MEASUREMENT_REPORT,
|
|
LOG_GNSS_GLONASS_MEASUREMENT_REPORT,
|
|
LOG_GNSS_OEMDRE_MEASUREMENMT_REPORT,
|
|
LOG_GNSS_OEMDRE_SVPOLY_REPORT,
|
|
|
|
// unparsed:
|
|
LOG_GNSS_POSITION_REPORT,
|
|
|
|
LOG_GNSS_BDS_MEASUREMENT_REPORT, // these are missing by might as well try to catch them anyway
|
|
LOG_GNSS_GAL_MEASUREMENT_REPORT,
|
|
|
|
LOG_GNSS_ME_DPO_STATUS,
|
|
LOG_GNSS_CD_DB_REPORT,
|
|
LOG_GNSS_PRX_RF_HW_STATUS_REPORT,
|
|
LOG_CGPS_SLOW_CLOCK_CLIB_REPORT,
|
|
LOG_GNSS_CONFIGURATION_STATE,
|
|
};
|
|
|
|
|
|
struct SendDiagSyncState {
|
|
sem_t sem;
|
|
int len;
|
|
};
|
|
|
|
static void diag_send_sync_cb(unsigned char *ptr, int len, void *data_ptr) {
|
|
SendDiagSyncState *s = (SendDiagSyncState*)data_ptr;
|
|
s->len = len;
|
|
sem_post(&s->sem);
|
|
}
|
|
|
|
static int diag_send_sync(int client_id, unsigned char* req_pkt, size_t pkt_len,
|
|
unsigned char* res_pkt, size_t res_pkt_size) {
|
|
|
|
SendDiagSyncState s = {0};
|
|
sem_init(&s.sem, 0, 0);
|
|
|
|
int err = diag_send_dci_async_req(client_id, req_pkt, pkt_len, res_pkt, res_pkt_size,
|
|
diag_send_sync_cb, &s);
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
|
|
sem_wait(&s.sem);
|
|
return s.len;
|
|
}
|
|
|
|
static int oemdre_on(int client_id) {
|
|
// enable OEM DR
|
|
unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ];
|
|
|
|
GpsOemControlReq req_pkt = {
|
|
.cmd_code = DIAG_SUBSYS_CMD,
|
|
.subsys_id = DIAG_SUBSYS_GPS,
|
|
.subsys_cmd_code = CGPS_DIAG_PDAPI_CMD,
|
|
.gps_cmd_code = CGPS_OEM_CONTROL,
|
|
.version = 1,
|
|
|
|
.oem_feature = GPSDIAG_OEMFEATURE_DRE,
|
|
.oem_command = GPSDIAG_OEM_DRE_ON,
|
|
};
|
|
|
|
int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt),
|
|
res_pkt, sizeof(res_pkt));
|
|
GpsOemControlResp *resp = (GpsOemControlResp*)res_pkt;
|
|
|
|
if (res_len != sizeof(GpsOemControlResp)
|
|
|| resp->cmd_code != DIAG_SUBSYS_CMD
|
|
|| resp->subsys_id != DIAG_SUBSYS_GPS
|
|
|| resp->subsys_cmd_code != CGPS_DIAG_PDAPI_CMD
|
|
|| resp->gps_cmd_code != CGPS_OEM_CONTROL
|
|
|| resp->oem_feature != GPSDIAG_OEMFEATURE_DRE
|
|
|| resp->oem_command != GPSDIAG_OEM_DRE_ON) {
|
|
LOGW("oemdre_on: bad response!");
|
|
return -1;
|
|
}
|
|
|
|
return resp->resp_result;
|
|
}
|
|
|
|
static void efs_sync(int client_id) {
|
|
unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ];
|
|
|
|
Efs2DiagSyncReq req_pkt = {
|
|
.cmd_code = DIAG_SUBSYS_CMD,
|
|
.subsys_id = DIAG_SUBSYS_FS,
|
|
.subsys_cmd_code = EFS2_DIAG_SYNC_NO_WAIT,
|
|
.sequence_num = (uint16_t)(rand() % 100),
|
|
};
|
|
req_pkt.path[0] = '/';
|
|
req_pkt.path[1] = 0;
|
|
|
|
int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt),
|
|
res_pkt, sizeof(res_pkt));
|
|
Efs2DiagSyncResp *resp = (Efs2DiagSyncResp*)res_pkt;
|
|
|
|
if (res_len != sizeof(Efs2DiagSyncResp)
|
|
|| resp->cmd_code != DIAG_SUBSYS_CMD
|
|
|| resp->subsys_id != DIAG_SUBSYS_FS
|
|
|| resp->subsys_cmd_code != EFS2_DIAG_SYNC_NO_WAIT) {
|
|
LOGW("efs_sync: bad response!");
|
|
return;
|
|
}
|
|
if (resp->diag_errno != 0) {
|
|
LOGW("efs_sync: error %d", resp->diag_errno);
|
|
}
|
|
}
|
|
|
|
static uint32_t nv_read_u32(int client_id, uint16_t nv_id) {
|
|
NvPacket req = {
|
|
.cmd_code = DIAG_NV_READ_F,
|
|
.nv_id = nv_id,
|
|
};
|
|
NvPacket resp = {0};
|
|
|
|
int res_len = diag_send_sync(client_id, (unsigned char*)&req, sizeof(req),
|
|
(unsigned char*)&resp, sizeof(resp));
|
|
|
|
// hexdump((uint8_t*)&resp, res_len);
|
|
|
|
if (resp.cmd_code != DIAG_NV_READ_F
|
|
|| resp.nv_id != nv_id) {
|
|
LOGW("nv_read_u32: diag command failed");
|
|
return 0;
|
|
}
|
|
|
|
if (resp.status != NV_DONE) {
|
|
LOGW("nv_read_u32: read failed: %d", resp.status);
|
|
return 0;
|
|
}
|
|
return *(uint32_t*)resp.data;
|
|
}
|
|
|
|
static bool nv_write_u32(int client_id, uint16_t nv_id, uint32_t val) {
|
|
NvPacket req = {
|
|
.cmd_code = DIAG_NV_WRITE_F,
|
|
.nv_id = nv_id,
|
|
};
|
|
*(uint32_t*)req.data = val;
|
|
|
|
NvPacket resp = {0};
|
|
int res_len = diag_send_sync(client_id, (unsigned char*)&req, sizeof(req),
|
|
(unsigned char*)&resp, sizeof(resp));
|
|
|
|
// hexdump((uint8_t*)&resp, res_len);
|
|
|
|
if (resp.cmd_code != DIAG_NV_WRITE_F
|
|
|| resp.nv_id != nv_id) {
|
|
LOGW("nv_write_u32: diag command failed");
|
|
return false;
|
|
}
|
|
|
|
if (resp.status != NV_DONE) {
|
|
LOGW("nv_write_u32: write failed: %d", resp.status);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void nav_config(int client_id, uint8_t config) {
|
|
unsigned char res_pkt[DIAG_MAX_RX_PKT_SIZ];
|
|
|
|
GpsNavConfigReq req_pkt = {
|
|
.cmd_code = DIAG_SUBSYS_CMD_VER_2,
|
|
.subsys_id = DIAG_SUBSYS_GPS,
|
|
.subsys_cmd_code = TM_DIAG_NAV_CONFIG_CMD,
|
|
.desired_config = config,
|
|
};
|
|
|
|
int res_len = diag_send_sync(client_id, (unsigned char*)&req_pkt, sizeof(req_pkt),
|
|
res_pkt, sizeof(res_pkt));
|
|
GpsNavConfigResp *resp = (GpsNavConfigResp*)res_pkt;
|
|
|
|
if (res_len != sizeof(GpsNavConfigResp)
|
|
|| resp->cmd_code != DIAG_SUBSYS_CMD_VER_2
|
|
|| resp->subsys_id != DIAG_SUBSYS_GPS
|
|
|| resp->subsys_cmd_code != TM_DIAG_NAV_CONFIG_CMD) {
|
|
LOGW("nav_config: bad response!");
|
|
return;
|
|
}
|
|
LOG("nav config: %04x %04x", resp->supported_config, resp->actual_config);
|
|
}
|
|
|
|
void rawgps_init() {
|
|
int err;
|
|
|
|
rawgps_context = Context::create();
|
|
rawgps_publisher = PubSocket::create(rawgps_context, "qcomGnss");
|
|
assert(rawgps_publisher != NULL);
|
|
|
|
bool init_success = Diag_LSM_Init(NULL);
|
|
assert(init_success);
|
|
|
|
uint16_t list = DIAG_CON_APSS | DIAG_CON_MPSS;
|
|
int signal_type = SIGCONT;
|
|
err = diag_register_dci_client(&client_id, &list, 0, &signal_type);
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
|
|
{
|
|
uint32_t oem_features = nv_read_u32(client_id, NV_GNSS_OEM_FEATURE_MASK);
|
|
LOG("oem features: %08x", oem_features);
|
|
|
|
if (!(oem_features & NV_GNSS_OEM_FEATURE_MASK_OEMDRE)) {
|
|
LOG("OEMDRE feature disabled, enabling...");
|
|
nv_write_u32(client_id, NV_GNSS_OEM_FEATURE_MASK, NV_GNSS_OEM_FEATURE_MASK_OEMDRE);
|
|
efs_sync(client_id);
|
|
}
|
|
|
|
int oemdre_status = oemdre_on(client_id);
|
|
LOG("oemdre status: %d", oemdre_status);
|
|
}
|
|
|
|
{
|
|
// make sure GNSS duty cycling is off
|
|
uint32_t dpo = nv_read_u32(client_id, NV_CGPS_DPO_CONTROL);
|
|
LOG("dpo: %d", dpo);
|
|
if (dpo != 0) {
|
|
nv_write_u32(client_id, NV_CGPS_DPO_CONTROL, 0);
|
|
efs_sync(client_id);
|
|
}
|
|
}
|
|
|
|
// enable beidou
|
|
// nav_config(client_id, 0x13); // 0b10011
|
|
|
|
err = diag_register_dci_stream(handle_log, handle_event);
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
|
|
err = diag_log_stream_config(client_id, true, log_codes, ARRAYSIZE(log_codes));
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
}
|
|
|
|
void rawgps_destroy() {
|
|
|
|
int err;
|
|
|
|
err = diag_log_stream_config(client_id, false, log_codes, ARRAYSIZE(log_codes));
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
|
|
err = diag_release_dci_client(&client_id);
|
|
assert(err == DIAG_DCI_NO_ERROR);
|
|
|
|
Diag_LSM_DeInit();
|
|
|
|
delete rawgps_publisher;
|
|
delete rawgps_context;
|
|
}
|
|
|
|
|
|
#ifdef RAWGPS_TEST
|
|
int main() {
|
|
int err = 0;
|
|
rawgps_init();
|
|
|
|
while(1) {
|
|
usleep(100000);
|
|
}
|
|
|
|
rawgps_destroy();
|
|
return 0;
|
|
}
|
|
#endif
|
|
|