Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4eb8cf8f authored by Yuchen He's avatar Yuchen He Committed by Hao Chen
Browse files

Read GNSS measurement from device file when available

Test: atest CtsLocationGnssTestCases GtsLocationTestCases on CF
Bug: 190757198
Change-Id: Ic03d56a5df6b99f7b20c5840e7091ead138316b1
Merged-In: Ic03d56a5df6b99f7b20c5840e7091ead138316b1
parent 6ceb09d6
Loading
Loading
Loading
Loading
+11 −7
Original line number Diff line number Diff line
@@ -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);
+4 −3
Original line number Diff line number Diff line
@@ -38,12 +38,13 @@ cc_library_static {
        "v2_1/GnssDebug.cpp",
        "v2_1/GnssMeasurement.cpp",
        "v2_1/GnssMeasurementCorrections.cpp",
        "DeviceFileReader.cpp",
        "GnssRawMeasurementParser.cpp",
        "GnssReplayUtils.cpp",
        "MockLocation.cpp",
        "Utils.cpp",
        "NmeaFixInfo.cpp",
        "GnssReplayUtils.cpp",
        "ParseUtils.cpp",
        "GnssRawMeasurementParser.cpp",
        "Utils.cpp",
    ],
    export_include_dirs: ["include"],
    shared_libs: [
+97 −0
Original line number Diff line number Diff line
/*
 * 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
+2 −39
Original line number Diff line number Diff line
@@ -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
+53 −0
Original line number Diff line number Diff line

/*
 * 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_
 No newline at end of file
Loading