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

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

Refactor and reuse some read device file logic

Add skeleton on HAL for Gnss raw measurement injection

Bug: 190757198
Test: manual test
Merged-In: I9b58043d5ed321aa71ff4f23031df251ae89c407
Change-Id: I9b58043d5ed321aa71ff4f23031df251ae89c407
parent 8fc5a4fb
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -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) {
            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));
        }
    });
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ cc_library_static {
        "MockLocation.cpp",
        "Utils.cpp",
        "NmeaFixInfo.cpp",
        "GnssReplayUtils.cpp",
    ],
    export_include_dirs: ["include"],
    shared_libs: [
+88 −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 "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
+12 −0
Original line number Diff line number Diff line
@@ -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
+54 −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_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_
Loading