mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 16:50:18 +00:00
Merge Android 12 QPR 3
Bug: 236045730 Merged-In: I8564456248d0b01eb521d575ef540689c8035d3d Change-Id: I56da73431668a2a7dc5f23dfbcdf90622c222770
This commit is contained in:
@@ -19,11 +19,17 @@
|
||||
#include "GnssMeasurementInterface.h"
|
||||
#include <aidl/android/hardware/gnss/BnGnss.h>
|
||||
#include <log/log.h>
|
||||
#include "DeviceFileReader.h"
|
||||
#include "GnssRawMeasurementParser.h"
|
||||
#include "GnssReplayUtils.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace aidl::android::hardware::gnss {
|
||||
|
||||
using Utils = ::android::hardware::gnss::common::Utils;
|
||||
using ReplayUtils = ::android::hardware::gnss::common::ReplayUtils;
|
||||
using GnssRawMeasurementParser = ::android::hardware::gnss::common::GnssRawMeasurementParser;
|
||||
using DeviceFileReader = ::android::hardware::gnss::common::DeviceFileReader;
|
||||
|
||||
std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr;
|
||||
|
||||
@@ -63,9 +69,22 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
|
||||
mIsActive = true;
|
||||
mThread = std::thread([this, enableCorrVecOutputs]() {
|
||||
while (mIsActive == true) {
|
||||
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
|
||||
this->reportMeasurement(measurement);
|
||||
|
||||
std::string rawMeasurementStr = "";
|
||||
if (ReplayUtils::hasGnssDeviceFile() &&
|
||||
ReplayUtils::isGnssRawMeasurement(
|
||||
rawMeasurementStr =
|
||||
DeviceFileReader::Instance().getGnssRawMeasurementData())) {
|
||||
ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(),
|
||||
rawMeasurementStr.c_str());
|
||||
auto measurement =
|
||||
GnssRawMeasurementParser::getMeasurementFromStrs(rawMeasurementStr);
|
||||
if (measurement != nullptr) {
|
||||
this->reportMeasurement(*measurement);
|
||||
}
|
||||
} else {
|
||||
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
|
||||
this->reportMeasurement(measurement);
|
||||
}
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -38,9 +38,14 @@ cc_library_static {
|
||||
"v2_1/GnssDebug.cpp",
|
||||
"v2_1/GnssMeasurement.cpp",
|
||||
"v2_1/GnssMeasurementCorrections.cpp",
|
||||
"DeviceFileReader.cpp",
|
||||
"FixLocationParser.cpp",
|
||||
"GnssRawMeasurementParser.cpp",
|
||||
"GnssReplayUtils.cpp",
|
||||
"MockLocation.cpp",
|
||||
"Utils.cpp",
|
||||
"NmeaFixInfo.cpp",
|
||||
"ParseUtils.cpp",
|
||||
"Utils.cpp",
|
||||
],
|
||||
export_include_dirs: ["include"],
|
||||
shared_libs: [
|
||||
|
||||
109
gnss/common/utils/default/DeviceFileReader.cpp
Normal file
109
gnss/common/utils/default/DeviceFileReader.cpp
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "DeviceFileReader.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
void DeviceFileReader::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
|
||||
char inputBuffer[INPUT_BUFFER_SIZE];
|
||||
std::string deviceFilePath = "";
|
||||
if (command == CMD_GET_LOCATION) {
|
||||
deviceFilePath = ReplayUtils::getFixedLocationPath();
|
||||
} else if (command == CMD_GET_RAWMEASUREMENT) {
|
||||
deviceFilePath = ReplayUtils::getGnssPath();
|
||||
} else {
|
||||
// Invalid command
|
||||
return;
|
||||
}
|
||||
|
||||
int mGnssFd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK);
|
||||
|
||||
if (mGnssFd == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
int bytes_write = write(mGnssFd, command.c_str(), command.size());
|
||||
if (bytes_write <= 0) {
|
||||
close(mGnssFd);
|
||||
return;
|
||||
}
|
||||
|
||||
struct epoll_event ev, events[1];
|
||||
ev.data.fd = mGnssFd;
|
||||
ev.events = EPOLLIN;
|
||||
int epoll_fd = epoll_create1(0);
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
|
||||
int bytes_read = -1;
|
||||
std::string inputStr = "";
|
||||
int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
|
||||
|
||||
if (epoll_ret == -1) {
|
||||
close(mGnssFd);
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
|
||||
bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
|
||||
if (bytes_read <= 0) {
|
||||
break;
|
||||
}
|
||||
s_buffer_ += std::string(inputBuffer, bytes_read);
|
||||
}
|
||||
close(mGnssFd);
|
||||
|
||||
// Trim end of file mark(\n\n\n\n).
|
||||
auto pos = s_buffer_.find("\n\n\n\n");
|
||||
if (pos != std::string::npos) {
|
||||
inputStr = s_buffer_.substr(0, pos);
|
||||
s_buffer_ = s_buffer_.substr(pos + 4);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache the injected data.
|
||||
if (command == CMD_GET_LOCATION) {
|
||||
// TODO validate data
|
||||
data_[CMD_GET_LOCATION] = inputStr;
|
||||
} else if (command == CMD_GET_RAWMEASUREMENT) {
|
||||
if (ReplayUtils::isGnssRawMeasurement(inputStr)) {
|
||||
data_[CMD_GET_RAWMEASUREMENT] = inputStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string DeviceFileReader::getLocationData() {
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
getDataFromDeviceFile(CMD_GET_LOCATION, 20);
|
||||
return data_[CMD_GET_LOCATION];
|
||||
}
|
||||
|
||||
std::string DeviceFileReader::getGnssRawMeasurementData() {
|
||||
std::unique_lock<std::mutex> lock(mMutex);
|
||||
getDataFromDeviceFile(CMD_GET_RAWMEASUREMENT, 20);
|
||||
return data_[CMD_GET_RAWMEASUREMENT];
|
||||
}
|
||||
|
||||
DeviceFileReader::DeviceFileReader() {}
|
||||
|
||||
DeviceFileReader::~DeviceFileReader() {}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
76
gnss/common/utils/default/FixLocationParser.cpp
Normal file
76
gnss/common/utils/default/FixLocationParser.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "FixLocationParser.h"
|
||||
|
||||
#include <android/hardware/gnss/1.0/IGnss.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
std::unique_ptr<V2_0::GnssLocation> FixLocationParser::getLocationFromInputStr(
|
||||
const std::string& locationStr) {
|
||||
/*
|
||||
* Fix,Provider,LatitudeDegrees,LongitudeDegrees,AltitudeMeters,SpeedMps,
|
||||
* AccuracyMeters,BearingDegrees,UnixTimeMillis,SpeedAccuracyMps,BearingAccuracyDegrees,
|
||||
* elapsedRealtimeNanos
|
||||
*/
|
||||
if (locationStr.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<std::string> locationStrRecords;
|
||||
ParseUtils::splitStr(locationStr, LINE_SEPARATOR, locationStrRecords);
|
||||
if (locationStrRecords.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::string> locationValues;
|
||||
ParseUtils::splitStr(locationStrRecords[0], COMMA_SEPARATOR, locationValues);
|
||||
if (locationValues.size() < 12) {
|
||||
return nullptr;
|
||||
}
|
||||
V2_0::ElapsedRealtime elapsedRealtime = {
|
||||
.flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
|
||||
V2_0::ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS,
|
||||
.timestampNs = static_cast<uint64_t>(::android::elapsedRealtimeNano()),
|
||||
// This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
|
||||
// In an actual implementation provide an estimate of the synchronization uncertainty
|
||||
// or don't set the field.
|
||||
.timeUncertaintyNs = 1020400};
|
||||
|
||||
V1_0::GnssLocation locationV1 = {
|
||||
.gnssLocationFlags = 0xFF,
|
||||
.latitudeDegrees = ParseUtils::tryParseDouble(locationValues[2], 0),
|
||||
.longitudeDegrees = ParseUtils::tryParseDouble(locationValues[3], 0),
|
||||
.altitudeMeters = ParseUtils::tryParseDouble(locationValues[4], 0),
|
||||
.speedMetersPerSec = ParseUtils::tryParsefloat(locationValues[5], 0),
|
||||
.bearingDegrees = ParseUtils::tryParsefloat(locationValues[7], 0),
|
||||
.horizontalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
|
||||
.verticalAccuracyMeters = ParseUtils::tryParsefloat(locationValues[6], 0),
|
||||
.speedAccuracyMetersPerSecond = ParseUtils::tryParsefloat(locationValues[9], 0),
|
||||
.bearingAccuracyDegrees = ParseUtils::tryParsefloat(locationValues[10], 0),
|
||||
.timestamp = ParseUtils::tryParseLongLong(locationValues[8], 0)};
|
||||
|
||||
V2_0::GnssLocation locationV2 = {.v1_0 = locationV1, .elapsedRealtime = elapsedRealtime};
|
||||
return std::make_unique<V2_0::GnssLocation>(locationV2);
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
305
gnss/common/utils/default/GnssRawMeasurementParser.cpp
Normal file
305
gnss/common/utils/default/GnssRawMeasurementParser.cpp
Normal file
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "GnssRawMeasurementParser.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
using aidl::android::hardware::gnss::ElapsedRealtime;
|
||||
using aidl::android::hardware::gnss::GnssClock;
|
||||
using aidl::android::hardware::gnss::GnssConstellationType;
|
||||
using aidl::android::hardware::gnss::GnssData;
|
||||
using aidl::android::hardware::gnss::GnssMeasurement;
|
||||
using aidl::android::hardware::gnss::GnssMultipathIndicator;
|
||||
using aidl::android::hardware::gnss::GnssSignalType;
|
||||
|
||||
using ParseUtils = ::android::hardware::gnss::common::ParseUtils;
|
||||
|
||||
std::unordered_map<std::string, int> GnssRawMeasurementParser::getColumnIdNameMappingFromHeader(
|
||||
const std::string& header) {
|
||||
std::vector<std::string> columnNames;
|
||||
std::unordered_map<std::string, int> columnNameIdMapping;
|
||||
std::string s = header;
|
||||
// Trim left spaces
|
||||
s.erase(s.begin(),
|
||||
std::find_if(s.begin(), s.end(), [](unsigned char ch) { return !std::isspace(ch); }));
|
||||
// Trim right spaces
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { return !std::isspace(ch); })
|
||||
.base(),
|
||||
s.end());
|
||||
// Remove comment symbol, start from `Raw`.
|
||||
s = s.substr(s.find("Raw"));
|
||||
|
||||
ParseUtils::splitStr(s, COMMA_SEPARATOR, columnNames);
|
||||
int columnId = 0;
|
||||
for (auto& name : columnNames) {
|
||||
columnNameIdMapping[name] = columnId++;
|
||||
}
|
||||
|
||||
return columnNameIdMapping;
|
||||
}
|
||||
|
||||
int GnssRawMeasurementParser::getClockFlags(
|
||||
const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping) {
|
||||
int clockFlags = 0;
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("LeapSecond")].empty()) {
|
||||
clockFlags |= GnssClock::HAS_LEAP_SECOND;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullBiasNanos")].empty()) {
|
||||
clockFlags |= GnssClock::HAS_FULL_BIAS;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasNanos")].empty()) {
|
||||
clockFlags |= GnssClock::HAS_BIAS;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")].empty()) {
|
||||
clockFlags |= GnssClock::HAS_BIAS_UNCERTAINTY;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")].empty()) {
|
||||
clockFlags |= GnssClock::HAS_DRIFT;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("DriftUncertaintyNanosPerSecond")]
|
||||
.empty()) {
|
||||
clockFlags |= GnssClock::HAS_DRIFT_UNCERTAINTY;
|
||||
}
|
||||
return clockFlags;
|
||||
}
|
||||
|
||||
int GnssRawMeasurementParser::getElapsedRealtimeFlags(
|
||||
const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping) {
|
||||
int elapsedRealtimeFlags = ElapsedRealtime::HAS_TIMESTAMP_NS;
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")].empty()) {
|
||||
elapsedRealtimeFlags |= ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS;
|
||||
}
|
||||
return elapsedRealtimeFlags;
|
||||
}
|
||||
|
||||
int GnssRawMeasurementParser::getRawMeasurementFlags(
|
||||
const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping) {
|
||||
int rawMeasurementFlags = 0;
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("SnrInDb")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_SNR;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierFrequencyHz")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_FREQUENCY;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierCycles")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_CYCLES;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhase")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("CarrierPhaseUncertainty")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_CARRIER_PHASE_UNCERTAINTY;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("AgcDb")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_AUTOMATIC_GAIN_CONTROL;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasNanos")].empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("FullInterSignalBiasUncertaintyNanos")]
|
||||
.empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_FULL_ISB_UNCERTAINTY;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at("SatelliteInterSignalBiasNanos")]
|
||||
.empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB;
|
||||
}
|
||||
if (!rawMeasurementRecordValues[columnNameIdMapping.at(
|
||||
"SatelliteInterSignalBiasUncertaintyNanos")]
|
||||
.empty()) {
|
||||
rawMeasurementFlags |= GnssMeasurement::HAS_SATELLITE_ISB_UNCERTAINTY;
|
||||
}
|
||||
// HAS_SATELLITE_PVT and HAS_CORRELATION_VECTOR fields currently not in rawmeasurement
|
||||
// output, need add them later.
|
||||
return rawMeasurementFlags;
|
||||
}
|
||||
|
||||
GnssConstellationType GnssRawMeasurementParser::getGnssConstellationType(int constellationType) {
|
||||
GnssConstellationType gnssConstellationType =
|
||||
aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
|
||||
|
||||
switch (constellationType) {
|
||||
case 1:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GPS;
|
||||
break;
|
||||
case 2:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::SBAS;
|
||||
break;
|
||||
case 3:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GLONASS;
|
||||
break;
|
||||
case 4:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::QZSS;
|
||||
break;
|
||||
case 5:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::BEIDOU;
|
||||
break;
|
||||
case 6:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::GALILEO;
|
||||
break;
|
||||
default:
|
||||
gnssConstellationType = aidl::android::hardware::gnss::GnssConstellationType::UNKNOWN;
|
||||
}
|
||||
|
||||
return gnssConstellationType;
|
||||
}
|
||||
|
||||
std::unique_ptr<GnssData> GnssRawMeasurementParser::getMeasurementFromStrs(
|
||||
std::string& rawMeasurementStr) {
|
||||
/*
|
||||
* Raw,utcTimeMillis,TimeNanos,LeapSecond,TimeUncertaintyNanos,FullBiasNanos,BiasNanos,
|
||||
* BiasUncertaintyNanos,DriftNanosPerSecond,DriftUncertaintyNanosPerSecond,
|
||||
* HardwareClockDiscontinuityCount,Svid,TimeOffsetNanos,State,ReceivedSvTimeNanos,
|
||||
* ReceivedSvTimeUncertaintyNanos,Cn0DbHz,PseudorangeRateMetersPerSecond,
|
||||
* PseudorangeRateUncertaintyMetersPerSecond,AccumulatedDeltaRangeState,
|
||||
* AccumulatedDeltaRangeMeters,AccumulatedDeltaRangeUncertaintyMeters,CarrierFrequencyHz,
|
||||
* CarrierCycles,CarrierPhase,CarrierPhaseUncertainty,MultipathIndicator,SnrInDb,
|
||||
* ConstellationType,AgcDb,BasebandCn0DbHz,FullInterSignalBiasNanos,
|
||||
* FullInterSignalBiasUncertaintyNanos,SatelliteInterSignalBiasNanos,
|
||||
* SatelliteInterSignalBiasUncertaintyNanos,CodeType,ChipsetElapsedRealtimeNanos
|
||||
*/
|
||||
ALOGD("Parsing %zu bytes rawMeasurementStr.", rawMeasurementStr.size());
|
||||
if (rawMeasurementStr.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
std::vector<std::string> rawMeasurementStrRecords;
|
||||
ParseUtils::splitStr(rawMeasurementStr, LINE_SEPARATOR, rawMeasurementStrRecords);
|
||||
if (rawMeasurementStrRecords.size() <= 1) {
|
||||
ALOGE("Raw GNSS Measurements parser failed. (No records) ");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Get the column name mapping from the header.
|
||||
std::unordered_map<std::string, int> columnNameIdMapping =
|
||||
getColumnIdNameMappingFromHeader(rawMeasurementStrRecords[0]);
|
||||
|
||||
if (columnNameIdMapping.size() < 37 || !ParseUtils::isValidHeader(columnNameIdMapping)) {
|
||||
ALOGE("Raw GNSS Measurements parser failed. (No header or missing columns.) ");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Set GnssClock from 1st record.
|
||||
std::size_t pointer = 1;
|
||||
std::vector<std::string> firstRecordValues;
|
||||
ParseUtils::splitStr(rawMeasurementStrRecords[pointer], COMMA_SEPARATOR, firstRecordValues);
|
||||
GnssClock clock = {
|
||||
.gnssClockFlags = getClockFlags(firstRecordValues, columnNameIdMapping),
|
||||
.timeNs = ParseUtils::tryParseLongLong(
|
||||
firstRecordValues[columnNameIdMapping.at("TimeNanos")], 0),
|
||||
.fullBiasNs = ParseUtils::tryParseLongLong(
|
||||
firstRecordValues[columnNameIdMapping.at("FullBiasNanos")], 0),
|
||||
.biasNs = ParseUtils::tryParseDouble(
|
||||
firstRecordValues[columnNameIdMapping.at("BiasNanos")], 0),
|
||||
.biasUncertaintyNs = ParseUtils::tryParseDouble(
|
||||
firstRecordValues[columnNameIdMapping.at("BiasUncertaintyNanos")], 0),
|
||||
.driftNsps = ParseUtils::tryParseDouble(
|
||||
firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
|
||||
.driftUncertaintyNsps = ParseUtils::tryParseDouble(
|
||||
firstRecordValues[columnNameIdMapping.at("DriftNanosPerSecond")], 0),
|
||||
.hwClockDiscontinuityCount = ParseUtils::tryParseInt(
|
||||
firstRecordValues[columnNameIdMapping.at("HardwareClockDiscontinuityCount")],
|
||||
0)};
|
||||
|
||||
ElapsedRealtime timestamp = {
|
||||
.flags = getElapsedRealtimeFlags(firstRecordValues, columnNameIdMapping),
|
||||
.timestampNs = ParseUtils::tryParseLongLong(
|
||||
firstRecordValues[columnNameIdMapping.at("ChipsetElapsedRealtimeNanos")]),
|
||||
.timeUncertaintyNs = ParseUtils::tryParseDouble(
|
||||
firstRecordValues[columnNameIdMapping.at("TimeUncertaintyNanos")], 0)};
|
||||
|
||||
std::vector<GnssMeasurement> measurementsVec;
|
||||
for (pointer = 1; pointer < rawMeasurementStrRecords.size(); pointer++) {
|
||||
std::vector<std::string> rawMeasurementValues;
|
||||
std::string line = rawMeasurementStrRecords[pointer];
|
||||
ParseUtils::splitStr(line, COMMA_SEPARATOR, rawMeasurementValues);
|
||||
GnssSignalType signalType = {
|
||||
.constellation = getGnssConstellationType(ParseUtils::tryParseInt(
|
||||
rawMeasurementValues[columnNameIdMapping.at("ConstellationType")], 0)),
|
||||
.carrierFrequencyHz = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("CarrierFrequencyHz")], 0),
|
||||
.codeType = rawMeasurementValues[columnNameIdMapping.at("CodeType")],
|
||||
};
|
||||
GnssMeasurement measurement = {
|
||||
.flags = getRawMeasurementFlags(rawMeasurementValues, columnNameIdMapping),
|
||||
.svid = ParseUtils::tryParseInt(
|
||||
rawMeasurementValues[columnNameIdMapping.at("Svid")], 0),
|
||||
.signalType = signalType,
|
||||
.receivedSvTimeInNs = ParseUtils::tryParseLongLong(
|
||||
rawMeasurementValues[columnNameIdMapping.at("ReceivedSvTimeNanos")], 0),
|
||||
.receivedSvTimeUncertaintyInNs =
|
||||
ParseUtils::tryParseLongLong(rawMeasurementValues[columnNameIdMapping.at(
|
||||
"ReceivedSvTimeUncertaintyNanos")],
|
||||
0),
|
||||
.antennaCN0DbHz = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("Cn0DbHz")], 0),
|
||||
.basebandCN0DbHz = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("BasebandCn0DbHz")], 0),
|
||||
.agcLevelDb = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("AgcDb")], 0),
|
||||
.pseudorangeRateMps =
|
||||
ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
|
||||
"PseudorangeRateMetersPerSecond")],
|
||||
0),
|
||||
.pseudorangeRateUncertaintyMps = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at(
|
||||
"PseudorangeRateUncertaintyMetersPerSecond")],
|
||||
0),
|
||||
.accumulatedDeltaRangeState = ParseUtils::tryParseInt(
|
||||
rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeState")],
|
||||
0),
|
||||
.accumulatedDeltaRangeM = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("AccumulatedDeltaRangeMeters")],
|
||||
0),
|
||||
.accumulatedDeltaRangeUncertaintyM = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at(
|
||||
"AccumulatedDeltaRangeUncertaintyMeters")],
|
||||
0),
|
||||
.multipathIndicator = GnssMultipathIndicator::UNKNOWN, // Not in GnssLogger yet.
|
||||
.state = ParseUtils::tryParseInt(
|
||||
rawMeasurementValues[columnNameIdMapping.at("State")], 0),
|
||||
.fullInterSignalBiasNs = ParseUtils::tryParseDouble(rawMeasurementValues[31], 0),
|
||||
.fullInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at("FullInterSignalBiasNanos")],
|
||||
0),
|
||||
.satelliteInterSignalBiasNs =
|
||||
ParseUtils::tryParseDouble(rawMeasurementValues[columnNameIdMapping.at(
|
||||
"SatelliteInterSignalBiasNanos")],
|
||||
0),
|
||||
.satelliteInterSignalBiasUncertaintyNs = ParseUtils::tryParseDouble(
|
||||
rawMeasurementValues[columnNameIdMapping.at(
|
||||
"SatelliteInterSignalBiasUncertaintyNanos")],
|
||||
0),
|
||||
.satellitePvt = {},
|
||||
.correlationVectors = {}};
|
||||
measurementsVec.push_back(measurement);
|
||||
}
|
||||
|
||||
GnssData gnssData = {
|
||||
.measurements = measurementsVec, .clock = clock, .elapsedRealtime = timestamp};
|
||||
return std::make_unique<GnssData>(gnssData);
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
81
gnss/common/utils/default/GnssReplayUtils.cpp
Normal file
81
gnss/common/utils/default/GnssReplayUtils.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "GnssReplayUtils.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
std::string ReplayUtils::getGnssPath() {
|
||||
std::array<char, PROPERTY_VALUE_MAX> devname_value;
|
||||
|
||||
devname_value.fill(0);
|
||||
if (property_get("debug.location.gnss.devname", devname_value.begin(), NULL) > 0) {
|
||||
return devname_value.begin();
|
||||
}
|
||||
|
||||
devname_value.fill(0);
|
||||
if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
|
||||
return devname_value.begin();
|
||||
}
|
||||
|
||||
return GNSS_PATH;
|
||||
}
|
||||
|
||||
std::string ReplayUtils::getFixedLocationPath() {
|
||||
std::array<char, PROPERTY_VALUE_MAX> devname_value;
|
||||
|
||||
devname_value.fill(0);
|
||||
if (property_get("debug.location.fixedlocation.devname", devname_value.begin(), NULL) > 0) {
|
||||
return devname_value.begin();
|
||||
}
|
||||
|
||||
devname_value.fill(0);
|
||||
if (property_get("vendor.ser.gnss-uart", devname_value.begin(), NULL) > 0) {
|
||||
return devname_value.begin();
|
||||
}
|
||||
|
||||
return FIXED_LOCATION_PATH;
|
||||
}
|
||||
|
||||
bool ReplayUtils::hasGnssDeviceFile() {
|
||||
struct stat sb;
|
||||
return stat(getGnssPath().c_str(), &sb) != -1;
|
||||
}
|
||||
|
||||
bool ReplayUtils::hasFixedLocationDeviceFile() {
|
||||
struct stat sb;
|
||||
return stat(getFixedLocationPath().c_str(), &sb) != -1;
|
||||
}
|
||||
|
||||
bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) {
|
||||
// TODO: add more logic check to by pass invalid data.
|
||||
return !inputStr.empty() && (inputStr.find("Raw") != std::string::npos);
|
||||
}
|
||||
|
||||
bool ReplayUtils::isNMEA(const std::string& inputStr) {
|
||||
return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
|
||||
inputStr.find("$GPRMA,", 0) != std::string::npos);
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
127
gnss/common/utils/default/ParseUtils.cpp
Normal file
127
gnss/common/utils/default/ParseUtils.cpp
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ParseUtils.h>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
int ParseUtils::tryParseInt(const std::string& s, int defaultVal) {
|
||||
if (s.empty()) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return std::stoi(s);
|
||||
}
|
||||
}
|
||||
|
||||
float ParseUtils::tryParsefloat(const std::string& s, float defaultVal) {
|
||||
if (s.empty()) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return std::stof(s);
|
||||
}
|
||||
}
|
||||
|
||||
double ParseUtils::tryParseDouble(const std::string& s, double defaultVal) {
|
||||
if (s.empty()) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return std::stod(s);
|
||||
}
|
||||
}
|
||||
|
||||
long ParseUtils::tryParseLong(const std::string& s, long defaultVal) {
|
||||
if (s.empty()) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return std::stol(s);
|
||||
}
|
||||
}
|
||||
|
||||
long long ParseUtils::tryParseLongLong(const std::string& s, long long defaultVal) {
|
||||
if (s.empty()) {
|
||||
return defaultVal;
|
||||
} else {
|
||||
return std::stoll(s);
|
||||
}
|
||||
}
|
||||
|
||||
void ParseUtils::splitStr(const std::string& line, const char& delimiter,
|
||||
std::vector<std::string>& out) {
|
||||
std::istringstream iss(line);
|
||||
std::string item;
|
||||
while (std::getline(iss, item, delimiter)) {
|
||||
out.push_back(item);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParseUtils::isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping) {
|
||||
std::vector<std::string> requiredHeaderColumns = {"Raw",
|
||||
"utcTimeMillis",
|
||||
"TimeNanos",
|
||||
"LeapSecond",
|
||||
"TimeUncertaintyNanos",
|
||||
"FullBiasNanos",
|
||||
"BiasNanos",
|
||||
"BiasUncertaintyNanos",
|
||||
"DriftNanosPerSecond",
|
||||
"DriftUncertaintyNanosPerSecond",
|
||||
"HardwareClockDiscontinuityCount",
|
||||
"Svid",
|
||||
"TimeOffsetNanos",
|
||||
"State",
|
||||
"ReceivedSvTimeNanos",
|
||||
"ReceivedSvTimeUncertaintyNanos",
|
||||
"Cn0DbHz",
|
||||
"PseudorangeRateMetersPerSecond",
|
||||
"PseudorangeRateUncertaintyMetersPerSecond",
|
||||
"AccumulatedDeltaRangeState",
|
||||
"AccumulatedDeltaRangeMeters",
|
||||
"AccumulatedDeltaRangeUncertaintyMeters",
|
||||
"CarrierFrequencyHz",
|
||||
"CarrierCycles",
|
||||
"CarrierPhase",
|
||||
"CarrierPhaseUncertainty",
|
||||
"MultipathIndicator",
|
||||
"SnrInDb",
|
||||
"ConstellationType",
|
||||
"AgcDb",
|
||||
"BasebandCn0DbHz",
|
||||
"FullInterSignalBiasNanos",
|
||||
"FullInterSignalBiasUncertaintyNanos",
|
||||
"SatelliteInterSignalBiasNanos",
|
||||
"SatelliteInterSignalBiasUncertaintyNanos",
|
||||
"CodeType",
|
||||
"ChipsetElapsedRealtimeNanos"};
|
||||
|
||||
for (const auto& columnName : requiredHeaderColumns) {
|
||||
if (columnNameIdMapping.find(columnName) == columnNameIdMapping.end()) {
|
||||
ALOGE("Missing column %s in header.", columnName.c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
@@ -34,6 +34,19 @@ const float kGpsL5FreqHz = 1176.45 * 1e6;
|
||||
const float kGloG1FreqHz = 1602.0 * 1e6;
|
||||
const float kIrnssL5FreqHz = 1176.45 * 1e6;
|
||||
|
||||
// Location replay constants
|
||||
constexpr char GNSS_PATH[] = "/dev/gnss0";
|
||||
constexpr char FIXED_LOCATION_PATH[] = "/dev/gnss1";
|
||||
constexpr int INPUT_BUFFER_SIZE = 256;
|
||||
constexpr char CMD_GET_LOCATION[] = "CMD_GET_LOCATION";
|
||||
constexpr char CMD_GET_RAWMEASUREMENT[] = "CMD_GET_RAWMEASUREMENT";
|
||||
constexpr char LINE_SEPARATOR = '\n';
|
||||
constexpr char COMMA_SEPARATOR = ',';
|
||||
constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
|
||||
constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
|
||||
constexpr double TIMESTAMP_EPSILON = 0.001;
|
||||
constexpr int MIN_COL_NUM = 13;
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
|
||||
53
gnss/common/utils/default/include/DeviceFileReader.h
Normal file
53
gnss/common/utils/default/include/DeviceFileReader.h
Normal file
@@ -0,0 +1,53 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef android_hardware_gnss_common_default_DeviceFileReader_H_
|
||||
#define android_hardware_gnss_common_default_DeviceFileReader_H_
|
||||
|
||||
#include <log/log.h>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include "Constants.h"
|
||||
#include "GnssReplayUtils.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
class DeviceFileReader {
|
||||
public:
|
||||
static DeviceFileReader& Instance() {
|
||||
static DeviceFileReader reader;
|
||||
return reader;
|
||||
}
|
||||
std::string getLocationData();
|
||||
std::string getGnssRawMeasurementData();
|
||||
void getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
|
||||
|
||||
private:
|
||||
DeviceFileReader();
|
||||
~DeviceFileReader();
|
||||
std::unordered_map<std::string, std::string> data_;
|
||||
std::string s_buffer_;
|
||||
std::mutex mMutex;
|
||||
};
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_gnss_common_default_DeviceFileReader_H_
|
||||
47
gnss/common/utils/default/include/FixLocationParser.h
Normal file
47
gnss/common/utils/default/include/FixLocationParser.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef android_hardware_gnss_common_default_FixLocationParser_H_
|
||||
#define android_hardware_gnss_common_default_FixLocationParser_H_
|
||||
|
||||
#include <android/hardware/gnss/2.0/IGnss.h>
|
||||
|
||||
#include <utils/SystemClock.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <Constants.h>
|
||||
#include <Utils.h>
|
||||
#include <log/log.h>
|
||||
#include "Constants.h"
|
||||
#include "ParseUtils.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
struct FixLocationParser {
|
||||
public:
|
||||
static std::unique_ptr<V2_0::GnssLocation> getLocationFromInputStr(const std::string& inputStr);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_gnss_common_default_FixLocationParser_H_
|
||||
56
gnss/common/utils/default/include/GnssRawMeasurementParser.h
Normal file
56
gnss/common/utils/default/include/GnssRawMeasurementParser.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
|
||||
#define android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
|
||||
|
||||
#include <aidl/android/hardware/gnss/BnGnss.h>
|
||||
#include <log/log.h>
|
||||
#include <utils/SystemClock.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Constants.h"
|
||||
#include "ParseUtils.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
struct GnssRawMeasurementParser {
|
||||
static std::unique_ptr<aidl::android::hardware::gnss::GnssData> getMeasurementFromStrs(
|
||||
std::string& rawMeasurementStr);
|
||||
static int getClockFlags(const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping);
|
||||
static int getElapsedRealtimeFlags(
|
||||
const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping);
|
||||
static int getRawMeasurementFlags(
|
||||
const std::vector<std::string>& rawMeasurementRecordValues,
|
||||
const std::unordered_map<std::string, int>& columnNameIdMapping);
|
||||
static std::unordered_map<std::string, int> getColumnIdNameMappingFromHeader(
|
||||
const std::string& header);
|
||||
static aidl::android::hardware::gnss::GnssConstellationType getGnssConstellationType(
|
||||
int constellationType);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_gnss_common_default_GnssRawMeasurementParser_H_
|
||||
58
gnss/common/utils/default/include/GnssReplayUtils.h
Normal file
58
gnss/common/utils/default/include/GnssReplayUtils.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef android_hardware_gnss_common_GnssReplayUtils_H_
|
||||
#define android_hardware_gnss_common_GnssReplayUtils_H_
|
||||
|
||||
#include <cutils/properties.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <log/log.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <chrono>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include "Constants.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
struct ReplayUtils {
|
||||
static std::string getGnssPath();
|
||||
|
||||
static std::string getFixedLocationPath();
|
||||
|
||||
static std::string getDataFromDeviceFile(const std::string& command, int mMinIntervalMs);
|
||||
|
||||
static bool hasGnssDeviceFile();
|
||||
|
||||
static bool hasFixedLocationDeviceFile();
|
||||
|
||||
static bool isGnssRawMeasurement(const std::string& inputStr);
|
||||
|
||||
static bool isNMEA(const std::string& inputStr);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_gnss_common_GnssReplayUtils_H_
|
||||
@@ -27,13 +27,6 @@ namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
constexpr char GPGA_RECORD_TAG[] = "$GPGGA";
|
||||
constexpr char GPRMC_RECORD_TAG[] = "$GPRMC";
|
||||
constexpr char LINE_SEPARATOR = '\n';
|
||||
constexpr char COMMA_SEPARATOR = ',';
|
||||
constexpr double TIMESTAMP_EPSILON = 0.001;
|
||||
constexpr int MIN_COL_NUM = 13;
|
||||
|
||||
/** Helper class to parse and store the GNSS fix details information. */
|
||||
class NmeaFixInfo {
|
||||
private:
|
||||
|
||||
46
gnss/common/utils/default/include/ParseUtils.h
Normal file
46
gnss/common/utils/default/include/ParseUtils.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef android_hardware_gnss_common_default_ParseUtils_H_
|
||||
#define android_hardware_gnss_common_default_ParseUtils_H_
|
||||
|
||||
#include <log/log.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace gnss {
|
||||
namespace common {
|
||||
|
||||
struct ParseUtils {
|
||||
static int tryParseInt(const std::string& s, int defaultVal = 0);
|
||||
static float tryParsefloat(const std::string& s, float defaultVal = 0.0);
|
||||
static double tryParseDouble(const std::string& s, double defaultVal = 0.0);
|
||||
static long tryParseLong(const std::string& s, long defaultVal = 0);
|
||||
static long long tryParseLongLong(const std::string& s, long long defaultVal = 0);
|
||||
static void splitStr(const std::string& line, const char& delimiter,
|
||||
std::vector<std::string>& out);
|
||||
static bool isValidHeader(const std::unordered_map<std::string, int>& columnNameIdMapping);
|
||||
};
|
||||
|
||||
} // namespace common
|
||||
} // namespace gnss
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_gnss_common_default_ParseUtils_H_
|
||||
@@ -30,13 +30,15 @@
|
||||
|
||||
#include <cutils/properties.h>
|
||||
|
||||
#include "DeviceFileReader.h"
|
||||
#include "FixLocationParser.h"
|
||||
#include "GnssAntennaInfo.h"
|
||||
#include "GnssConfiguration.h"
|
||||
#include "GnssDebug.h"
|
||||
#include "GnssMeasurement.h"
|
||||
#include "GnssMeasurementCorrections.h"
|
||||
#include "GnssReplayUtils.h"
|
||||
#include "MockLocation.h"
|
||||
#include "NmeaFixInfo.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace android::hardware::gnss::common::implementation {
|
||||
@@ -159,53 +161,13 @@ GnssTemplate<T_IGnss>::~GnssTemplate() {
|
||||
|
||||
template <class T_IGnss>
|
||||
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
|
||||
char inputBuffer[INPUT_BUFFER_SIZE];
|
||||
if (!mHardwareModeChecked) {
|
||||
// default using gnss0
|
||||
const char * gnss_dev_path = GNSS_PATH;
|
||||
char devname_value[PROPERTY_VALUE_MAX] = "";
|
||||
if (property_get("debug.location.gnss.devname", devname_value, NULL) > 0) {
|
||||
gnss_dev_path = devname_value;
|
||||
ALOGD("using %s instead of the default %s", gnss_dev_path, GNSS_PATH);
|
||||
}
|
||||
|
||||
mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK);
|
||||
if (mGnssFd == -1) {
|
||||
ALOGW("Failed to open %s errno: %d", gnss_dev_path, errno);
|
||||
}
|
||||
mHardwareModeChecked = true;
|
||||
}
|
||||
|
||||
if (mGnssFd == -1) {
|
||||
mHardwareModeChecked = true;
|
||||
if (!ReplayUtils::hasFixedLocationDeviceFile()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int bytes_write = write(mGnssFd, CMD_GET_LOCATION, strlen(CMD_GET_LOCATION));
|
||||
if (bytes_write <= 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct epoll_event ev, events[1];
|
||||
ev.data.fd = mGnssFd;
|
||||
ev.events = EPOLLIN;
|
||||
int epoll_fd = epoll_create1(0);
|
||||
epoll_ctl(epoll_fd, EPOLL_CTL_ADD, mGnssFd, &ev);
|
||||
int bytes_read = -1;
|
||||
std::string inputStr = "";
|
||||
int epoll_ret = epoll_wait(epoll_fd, events, 1, mMinIntervalMs);
|
||||
|
||||
if (epoll_ret == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
while (true) {
|
||||
memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
|
||||
bytes_read = read(mGnssFd, &inputBuffer, INPUT_BUFFER_SIZE);
|
||||
if (bytes_read <= 0) {
|
||||
break;
|
||||
}
|
||||
inputStr += std::string(inputBuffer, bytes_read);
|
||||
}
|
||||
return NmeaFixInfo::getLocationFromInputStr(inputStr);
|
||||
std::string inputStr =
|
||||
::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
|
||||
return FixLocationParser::getLocationFromInputStr(inputStr);
|
||||
}
|
||||
|
||||
template <class T_IGnss>
|
||||
|
||||
Reference in New Issue
Block a user