OSDN Git Service

Merge branch 'lineage-16.0' of https://github.com/me176c-dev/android_hardware_iio...
[android-x86/hardware-intel-libsensors.git] / utils.c
1 /*
2 // Copyright (c) 2015 Intel Corporation
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
17 #include <stdlib.h>
18 #include <fcntl.h>
19 #include <sys/ioctl.h>
20 #include <utils/Log.h>
21 #include <hardware/sensors.h>
22 #include <utils/Atomic.h>
23
24 #include "common.h"
25 #include "utils.h"
26
27 #include <errno.h>
28
29 /* Note:
30  *
31  * Some of these calls are going to fail, because not all sensors expose all
32  * possible sysfs attributes. As an optimization we may want to cache which
33  * ones are valid and immediately return in error for inexistent entries.
34  */
35 int sysfs_read(const char path[PATH_MAX], void *buf, int buf_len)
36 {
37         int fd, len;
38
39         if (!path[0] || !buf || buf_len < 1)
40                 return -1;
41
42         fd = open(path, O_RDONLY);
43
44         if (fd == -1) {
45                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
46                 return -1;
47         }
48
49         len = read(fd, buf, buf_len);
50
51         close(fd);
52
53         if (len == -1)
54                 ALOGW("Cannot read from %s (%s)\n", path, strerror(errno));
55         else
56                 ALOGV("Read %d bytes from %s\n", len, path);
57
58         return len;
59 }
60
61
62 int sysfs_write(const char path[PATH_MAX], const void *buf, const int buf_len)
63 {
64         int fd, len;
65
66         if (!path[0] || !buf || buf_len < 1)
67                 return -1;
68
69         fd = open(path, O_WRONLY);
70
71         if (fd == -1) {
72                 ALOGV("Cannot open %s (%s)\n", path, strerror(errno));
73                 return -1;
74         }
75
76         len = write(fd, buf, buf_len);
77
78         close(fd);
79
80         if (len == -1)
81                 ALOGW("Cannot write to %s (%s)\n", path, strerror(errno));
82         else if (len != buf_len)
83                 ALOGW("Cannot write %d bytes to %s (%d)\n", buf_len, path, len);
84         else
85                 ALOGV("Wrote %d bytes to %s\n", buf_len, path);
86
87         return len;
88 }
89
90
91 static void str2int(const char* buf, void *v)
92 {
93         *(int*)v = atoi(buf);
94 }
95
96
97 static void str2float(const char* buf, void *v)
98 {
99         *(float*)v = strtof(buf, NULL);
100 }
101
102
103 static void str2uint64(const char* buf, void *v)
104 {
105         *(uint64_t*)v = atoll(buf);
106 }
107
108
109 int sysfs_read_num(const char path[PATH_MAX], void *v,
110                 void (*str2num)(const char* buf, void *v))
111 {
112         char buf[20];
113         int len = sysfs_read_str(path, buf, sizeof(buf));
114
115         if (len <= 0) {
116                 ALOGW("Cannot read number from %s (%s)\n", path,
117                       strerror(errno));
118                 return -1;
119         }
120
121         str2num(buf, v);
122         return 0;
123 }
124
125
126 int sysfs_read_int(const char path[PATH_MAX], int *value)
127 {
128         return sysfs_read_num(path, value, str2int);
129 }
130
131
132 int sysfs_read_float(const char path[PATH_MAX], float *value)
133 {
134         return sysfs_read_num(path, value, str2float);
135 }
136
137
138 int sysfs_read_uint64(const char path[PATH_MAX], uint64_t *value)
139 {
140         return sysfs_read_num(path, value, str2uint64);
141 }
142
143
144 int sysfs_write_int(const char path[PATH_MAX], int value)
145 {
146         char buf[20];
147         int len = snprintf(buf, sizeof(buf), "%d", value);
148
149         if (len <= 0) {
150                 ALOGE("Unexpected condition in sysfs_write_int\n");
151                 return -1;
152         }
153
154         return sysfs_write(path, buf, len);
155 }
156
157 int sysfs_write_float(const char path[PATH_MAX], float value)
158 {
159         char buf[20];
160         int len = snprintf(buf, sizeof(buf), "%g", value);
161
162         if (len <= 0) {
163                 ALOGE("Unexpected condition in sysfs_write_float\n");
164                 return -1;
165         }
166
167         return sysfs_write(path, buf, len);
168 }
169
170
171 int sysfs_write_str(const char path[PATH_MAX], const char *str)
172 {
173         if (!str || !str[0])
174                 return -1;
175
176         return sysfs_write(path, str, strlen(str));
177 }
178
179
180 int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len)
181 {
182         int len;
183
184         if (!buf || buf_len < 1)
185                 return -1;
186
187         len = sysfs_read(path, buf, buf_len);
188
189         if (len == -1) {
190                 ALOGW("Cannot read string from %s (%s)\n", path,
191                       strerror(errno));
192                 return -1;
193         }
194
195         buf[len == 0 ? 0 : len - 1] = '\0';
196
197         ALOGV("Read %s from %s\n", buf, path);
198
199         return len;
200 }
201
202
203 int64_t get_timestamp (clockid_t clock_id)
204 {
205         struct timespec ts = {0, 0};
206
207         if (!clock_gettime(clock_id, &ts))
208                 return 1000000000LL * ts.tv_sec + ts.tv_nsec;
209         else    /* in this case errno is set appropriately */
210                 return -1;
211 }
212
213 int64_t get_timestamp_realtime (void)
214 {
215         return get_timestamp(CLOCK_REALTIME);
216 }
217
218 int64_t get_timestamp_boot (void)
219 {
220         return get_timestamp(CLOCK_BOOTTIME);
221 }
222
223 int64_t get_timestamp_thread (void)
224 {
225         return get_timestamp(CLOCK_THREAD_CPUTIME_ID);
226 }
227
228 int64_t get_timestamp_monotonic (void)
229 {
230         return get_timestamp(CLOCK_MONOTONIC);
231 }
232
233 void set_timestamp (struct timespec *out, int64_t target_ns)
234 {
235         out->tv_sec  = target_ns / 1000000000LL;
236         out->tv_nsec = target_ns % 1000000000LL;
237 }
238