blob: 91e75eb460302c4c3e589e584e385cde182f28f1 [file] [log] [blame]
Yuchen He3cbf5f32021-08-30 22:20:30 +00001/*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "DeviceFileReader.h"
17
18namespace android {
19namespace hardware {
20namespace gnss {
21namespace common {
22
23void DeviceFileReader::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
24 char inputBuffer[INPUT_BUFFER_SIZE];
Yuchen He090f16c2022-01-20 22:57:09 +000025 std::string deviceFilePath = "";
26 if (command == CMD_GET_LOCATION) {
27 deviceFilePath = ReplayUtils::getFixedLocationPath();
28 } else if (command == CMD_GET_RAWMEASUREMENT) {
29 deviceFilePath = ReplayUtils::getGnssPath();
30 } else {
31 // Invalid command
32 return;
33 }
34
Yuchen He6dddd6f2023-03-02 00:02:13 +000035 int gnss_fd, epoll_fd;
36 if ((gnss_fd = open(deviceFilePath.c_str(), O_RDWR | O_NONBLOCK)) == -1) {
37 return;
38 }
39 if (write(gnss_fd, command.c_str(), command.size()) <= 0) {
40 close(gnss_fd);
Yuchen He3cbf5f32021-08-30 22:20:30 +000041 return;
42 }
43
Yuchen He6dddd6f2023-03-02 00:02:13 +000044 // Create an epoll instance.
45 if ((epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
46 close(gnss_fd);
Yuchen He3cbf5f32021-08-30 22:20:30 +000047 return;
48 }
49
Yuchen He6dddd6f2023-03-02 00:02:13 +000050 // Add file descriptor to epoll instance.
Yuchen He3cbf5f32021-08-30 22:20:30 +000051 struct epoll_event ev, events[1];
Yuchen He6dddd6f2023-03-02 00:02:13 +000052 memset(&ev, 0, sizeof(ev));
53 ev.data.fd = gnss_fd;
Yuchen He3cbf5f32021-08-30 22:20:30 +000054 ev.events = EPOLLIN;
Yuchen He6dddd6f2023-03-02 00:02:13 +000055 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, gnss_fd, &ev) == -1) {
56 close(gnss_fd);
57 close(epoll_fd);
58 return;
59 }
60
61 // Wait for device file event.
62 if (epoll_wait(epoll_fd, events, 1, mMinIntervalMs) == -1) {
63 close(gnss_fd);
64 close(epoll_fd);
65 return;
66 }
67
68 // Handle event and write data to string buffer.
Yuchen He3cbf5f32021-08-30 22:20:30 +000069 int bytes_read = -1;
70 std::string inputStr = "";
Yuchen He3cbf5f32021-08-30 22:20:30 +000071 while (true) {
72 memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
Yuchen He6dddd6f2023-03-02 00:02:13 +000073 bytes_read = read(gnss_fd, &inputBuffer, INPUT_BUFFER_SIZE);
Yuchen He3cbf5f32021-08-30 22:20:30 +000074 if (bytes_read <= 0) {
75 break;
76 }
77 s_buffer_ += std::string(inputBuffer, bytes_read);
78 }
Yuchen He6dddd6f2023-03-02 00:02:13 +000079 close(gnss_fd);
80 close(epoll_fd);
Yuchen He3cbf5f32021-08-30 22:20:30 +000081
82 // Trim end of file mark(\n\n\n\n).
83 auto pos = s_buffer_.find("\n\n\n\n");
84 if (pos != std::string::npos) {
85 inputStr = s_buffer_.substr(0, pos);
86 s_buffer_ = s_buffer_.substr(pos + 4);
87 } else {
88 return;
89 }
90
91 // Cache the injected data.
Yuchen He090f16c2022-01-20 22:57:09 +000092 if (command == CMD_GET_LOCATION) {
93 // TODO validate data
Yuchen He3cbf5f32021-08-30 22:20:30 +000094 data_[CMD_GET_LOCATION] = inputStr;
Yuchen He090f16c2022-01-20 22:57:09 +000095 } else if (command == CMD_GET_RAWMEASUREMENT) {
96 if (ReplayUtils::isGnssRawMeasurement(inputStr)) {
97 data_[CMD_GET_RAWMEASUREMENT] = inputStr;
98 }
Yuchen He3cbf5f32021-08-30 22:20:30 +000099 }
100}
101
102std::string DeviceFileReader::getLocationData() {
103 std::unique_lock<std::mutex> lock(mMutex);
104 getDataFromDeviceFile(CMD_GET_LOCATION, 20);
105 return data_[CMD_GET_LOCATION];
106}
107
108std::string DeviceFileReader::getGnssRawMeasurementData() {
109 std::unique_lock<std::mutex> lock(mMutex);
110 getDataFromDeviceFile(CMD_GET_RAWMEASUREMENT, 20);
111 return data_[CMD_GET_RAWMEASUREMENT];
112}
113
114DeviceFileReader::DeviceFileReader() {}
115
116DeviceFileReader::~DeviceFileReader() {}
117
118} // namespace common
119} // namespace gnss
120} // namespace hardware
121} // namespace android