1 /*
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
18 namespace android {
19 namespace hardware {
20 namespace gnss {
21 namespace common {
22
getDataFromDeviceFile(const std::string & command,int mMinIntervalMs)23 void DeviceFileReader::getDataFromDeviceFile(const std::string& command, int mMinIntervalMs) {
24 char inputBuffer[INPUT_BUFFER_SIZE];
25 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
35 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);
41 return;
42 }
43
44 // Create an epoll instance.
45 if ((epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
46 close(gnss_fd);
47 return;
48 }
49
50 // Add file descriptor to epoll instance.
51 struct epoll_event ev, events[1];
52 memset(&ev, 0, sizeof(ev));
53 ev.data.fd = gnss_fd;
54 ev.events = EPOLLIN;
55 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.
69 int bytes_read = -1;
70 std::string inputStr = "";
71 while (true) {
72 memset(inputBuffer, 0, INPUT_BUFFER_SIZE);
73 bytes_read = read(gnss_fd, &inputBuffer, INPUT_BUFFER_SIZE);
74 if (bytes_read <= 0) {
75 break;
76 }
77 s_buffer_ += std::string(inputBuffer, bytes_read);
78 }
79 close(gnss_fd);
80 close(epoll_fd);
81
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.
92 if (command == CMD_GET_LOCATION) {
93 // TODO validate data
94 data_[CMD_GET_LOCATION] = inputStr;
95 } else if (command == CMD_GET_RAWMEASUREMENT) {
96 if (ReplayUtils::isGnssRawMeasurement(inputStr)) {
97 data_[CMD_GET_RAWMEASUREMENT] = inputStr;
98 }
99 }
100 }
101
getLocationData()102 std::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
getGnssRawMeasurementData()108 std::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
DeviceFileReader()114 DeviceFileReader::DeviceFileReader() {}
115
~DeviceFileReader()116 DeviceFileReader::~DeviceFileReader() {}
117
118 } // namespace common
119 } // namespace gnss
120 } // namespace hardware
121 } // namespace android
122