Read GNSS measurement from device file when available

Test: atest CtsLocationGnssTestCases GtsLocationTestCases on CF
Bug: 190757198
Change-Id: Ic03d56a5df6b99f7b20c5840e7091ead138316b1
Merged-In: Ic03d56a5df6b99f7b20c5840e7091ead138316b1
This commit is contained in:
Yuchen He
2021-08-30 22:20:30 +00:00
committed by Hao Chen
parent 31493d1dc4
commit 65569272ad
6 changed files with 173 additions and 64 deletions

View File

@@ -19,6 +19,8 @@
#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"
@@ -26,6 +28,8 @@ 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;
@@ -68,15 +72,15 @@ void GnssMeasurementInterface::start(const bool enableCorrVecOutputs) {
std::string rawMeasurementStr = "";
if (ReplayUtils::hasGnssDeviceFile() &&
ReplayUtils::isGnssRawMeasurement(
rawMeasurementStr = ReplayUtils::getDataFromDeviceFile(
std::string(
::android::hardware::gnss::common::CMD_GET_RAWMEASUREMENT),
mMinIntervalMillis))) {
// TODO: implement rawMeasurementStr parser and report measurement.
rawMeasurementStr =
DeviceFileReader::Instance().getGnssRawMeasurementData())) {
ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(),
rawMeasurementStr.c_str());
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
this->reportMeasurement(measurement);
auto measurement =
GnssRawMeasurementParser::getMeasurementFromStrs(rawMeasurementStr);
if (measurement != nullptr) {
this->reportMeasurement(*measurement);
}
} else {
auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs);
this->reportMeasurement(measurement);

View File

@@ -38,12 +38,13 @@ cc_library_static {
"v2_1/GnssDebug.cpp",
"v2_1/GnssMeasurement.cpp",
"v2_1/GnssMeasurementCorrections.cpp",
"MockLocation.cpp",
"Utils.cpp",
"NmeaFixInfo.cpp",
"GnssReplayUtils.cpp",
"ParseUtils.cpp",
"DeviceFileReader.cpp",
"GnssRawMeasurementParser.cpp",
"GnssReplayUtils.cpp",
"MockLocation.cpp",
"NmeaFixInfo.cpp",
"ParseUtils.cpp",
"Utils.cpp",
],
export_include_dirs: ["include"],
shared_libs: [

View File

@@ -0,0 +1,97 @@
/*
* 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];
int mGnssFd = open(ReplayUtils::getGnssPath().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 (ReplayUtils::isGnssRawMeasurement(inputStr)) {
data_[CMD_GET_RAWMEASUREMENT] = inputStr;
} else if (ReplayUtils::isNMEA(inputStr)) {
data_[CMD_GET_LOCATION] = 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

View File

@@ -40,45 +40,8 @@ bool ReplayUtils::isGnssRawMeasurement(const std::string& inputStr) {
}
bool ReplayUtils::isNMEA(const std::string& inputStr) {
return !inputStr.empty() &&
(inputStr.rfind("$GPRMC,", 0) == 0 || inputStr.rfind("$GPRMA,", 0) == 0);
}
std::string ReplayUtils::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
char inputBuffer[INPUT_BUFFER_SIZE];
int mGnssFd = open(getGnssPath().c_str(), O_RDWR | O_NONBLOCK);
if (mGnssFd == -1) {
return "";
}
int bytes_write = write(mGnssFd, command.c_str(), command.size());
if (bytes_write <= 0) {
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) {
return "";
}
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 inputStr;
return !inputStr.empty() && (inputStr.find("$GPRMC,", 0) != std::string::npos ||
inputStr.find("$GPRMA,", 0) != std::string::npos);
}
} // namespace common

View 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_

View File

@@ -30,6 +30,7 @@
#include <cutils/properties.h>
#include "DeviceFileReader.h"
#include "GnssAntennaInfo.h"
#include "GnssConfiguration.h"
#include "GnssDebug.h"
@@ -160,19 +161,9 @@ GnssTemplate<T_IGnss>::~GnssTemplate() {
template <class T_IGnss>
std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() {
if (!mHardwareModeChecked) {
// default using /dev/gnss0
std::string gnss_dev_path = ReplayUtils::getGnssPath();
mGnssFd = open(gnss_dev_path.c_str(), O_RDWR | O_NONBLOCK);
if (mGnssFd == -1) {
ALOGW("Failed to open %s errno: %d", gnss_dev_path.c_str(), errno);
}
mHardwareModeChecked = true;
}
std::string inputStr = ::android::hardware::gnss::common::ReplayUtils::getDataFromDeviceFile(
CMD_GET_LOCATION, mMinIntervalMs);
mHardwareModeChecked = true;
std::string inputStr =
::android::hardware::gnss::common::DeviceFileReader::Instance().getLocationData();
return NmeaFixInfo::getLocationFromInputStr(inputStr);
}