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