diff options
-rw-r--r-- | gnss/aidl/default/GnssMeasurementInterface.cpp | 21 | ||||
-rw-r--r-- | gnss/common/utils/default/Android.bp | 1 | ||||
-rw-r--r-- | gnss/common/utils/default/GnssReplayUtils.cpp | 88 | ||||
-rw-r--r-- | gnss/common/utils/default/include/Constants.h | 12 | ||||
-rw-r--r-- | gnss/common/utils/default/include/GnssReplayUtils.h | 54 | ||||
-rw-r--r-- | gnss/common/utils/default/include/NmeaFixInfo.h | 7 | ||||
-rw-r--r-- | gnss/common/utils/default/include/v2_1/GnssTemplate.h | 42 |
7 files changed, 178 insertions, 47 deletions
diff --git a/gnss/aidl/default/GnssMeasurementInterface.cpp b/gnss/aidl/default/GnssMeasurementInterface.cpp index fcc1f986cc..0e489c59e4 100644 --- a/gnss/aidl/default/GnssMeasurementInterface.cpp +++ b/gnss/aidl/default/GnssMeasurementInterface.cpp @@ -19,11 +19,13 @@ #include "GnssMeasurementInterface.h" #include <aidl/android/hardware/gnss/BnGnss.h> #include <log/log.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; std::shared_ptr<IGnssMeasurementCallback> GnssMeasurementInterface::sCallback = nullptr; @@ -63,9 +65,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 = ReplayUtils::getDataFromDeviceFile( + std::string( + ::android::hardware::gnss::common::CMD_GET_RAWMEASUREMENT), + mMinIntervalMillis))) { + // TODO: implement rawMeasurementStr parser and report measurement. + ALOGD("rawMeasurementStr(size: %zu) from device file: %s", rawMeasurementStr.size(), + rawMeasurementStr.c_str()); + auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs); + this->reportMeasurement(measurement); + } else { + auto measurement = Utils::getMockMeasurement(enableCorrVecOutputs); + this->reportMeasurement(measurement); + } std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMillis)); } }); diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp index a1d3123500..ac94cc1bc0 100644 --- a/gnss/common/utils/default/Android.bp +++ b/gnss/common/utils/default/Android.bp @@ -41,6 +41,7 @@ cc_library_static { "MockLocation.cpp", "Utils.cpp", "NmeaFixInfo.cpp", + "GnssReplayUtils.cpp", ], export_include_dirs: ["include"], shared_libs: [ diff --git a/gnss/common/utils/default/GnssReplayUtils.cpp b/gnss/common/utils/default/GnssReplayUtils.cpp new file mode 100644 index 0000000000..6dcf6ea252 --- /dev/null +++ b/gnss/common/utils/default/GnssReplayUtils.cpp @@ -0,0 +1,88 @@ +/* + * 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" + +namespace android { +namespace hardware { +namespace gnss { +namespace common { + +const char* ReplayUtils::getGnssPath() { + 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; + } + return gnss_dev_path; +} + +bool ReplayUtils::hasGnssDeviceFile() { + struct stat sb; + return stat(getGnssPath(), &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.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(), 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; +} + +} // namespace common +} // namespace gnss +} // namespace hardware +} // namespace android diff --git a/gnss/common/utils/default/include/Constants.h b/gnss/common/utils/default/include/Constants.h index 22afee1ad1..f205ba603c 100644 --- a/gnss/common/utils/default/include/Constants.h +++ b/gnss/common/utils/default/include/Constants.h @@ -34,6 +34,18 @@ 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 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 diff --git a/gnss/common/utils/default/include/GnssReplayUtils.h b/gnss/common/utils/default/include/GnssReplayUtils.h new file mode 100644 index 0000000000..d7530f741a --- /dev/null +++ b/gnss/common/utils/default/include/GnssReplayUtils.h @@ -0,0 +1,54 @@ +/* + * 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 const char* getGnssPath(); + + static std::string getDataFromDeviceFile(const std::string& command, int mMinIntervalMs); + + static bool hasGnssDeviceFile(); + + 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_ diff --git a/gnss/common/utils/default/include/NmeaFixInfo.h b/gnss/common/utils/default/include/NmeaFixInfo.h index c96eecea00..5c27045316 100644 --- a/gnss/common/utils/default/include/NmeaFixInfo.h +++ b/gnss/common/utils/default/include/NmeaFixInfo.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: diff --git a/gnss/common/utils/default/include/v2_1/GnssTemplate.h b/gnss/common/utils/default/include/v2_1/GnssTemplate.h index 48cab99a10..75bcd33766 100644 --- a/gnss/common/utils/default/include/v2_1/GnssTemplate.h +++ b/gnss/common/utils/default/include/v2_1/GnssTemplate.h @@ -35,6 +35,7 @@ #include "GnssDebug.h" #include "GnssMeasurement.h" #include "GnssMeasurementCorrections.h" +#include "GnssReplayUtils.h" #include "MockLocation.h" #include "NmeaFixInfo.h" #include "Utils.h" @@ -159,15 +160,9 @@ 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); - } + // default using /dev/gnss0 + const char* gnss_dev_path = ReplayUtils::getGnssPath(); mGnssFd = open(gnss_dev_path, O_RDWR | O_NONBLOCK); if (mGnssFd == -1) { @@ -176,35 +171,8 @@ std::unique_ptr<V2_0::GnssLocation> GnssTemplate<T_IGnss>::getLocationFromHW() { mHardwareModeChecked = true; } - if (mGnssFd == -1) { - 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); - } + std::string inputStr = ::android::hardware::gnss::common::ReplayUtils::getDataFromDeviceFile( + CMD_GET_LOCATION, mMinIntervalMs); return NmeaFixInfo::getLocationFromInputStr(inputStr); } |