1 /*
2 * Copyright (C) 2012 Invensense, Inc.
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 <MPLSupport.h>
18 #include <dirent.h>
19 #include <string.h>
20 #include <stdio.h>
21 #include "log.h"
22 #include "SensorBase.h"
23 #include <fcntl.h>
24
25 #include "ml_sysfs_helper.h"
26 #include "ml_load_dmp.h"
27
inv_read_data(char * fname,long * data)28 int inv_read_data(char *fname, long *data)
29 {
30 VFUNC_LOG;
31
32 char buf[sizeof(long) * 4];
33 int count, fd;
34
35 fd = open(fname, O_RDONLY);
36 if(fd < 0) {
37 LOGE("HAL:Error opening %s", fname);
38 return -1;
39 }
40 memset(buf, 0, sizeof(buf));
41 count = read_attribute_sensor(fd, buf, sizeof(buf));
42 if(count < 1) {
43 close(fd);
44 return -1;
45 } else {
46 count = sscanf(buf, "%ld", data);
47 if(count)
48 LOGV_IF(EXTRA_VERBOSE, "HAL:Data= %ld", *data);
49 }
50 close(fd);
51
52 return 0;
53 }
54
55 /* This one DOES NOT close FDs for you */
read_attribute_sensor(int fd,char * data,unsigned int size)56 int read_attribute_sensor(int fd, char* data, unsigned int size)
57 {
58 VFUNC_LOG;
59
60 int count = 0;
61 if (fd > 0) {
62 count = pread(fd, data, size, 0);
63 if(count < 1) {
64 LOGE("HAL:read fails with error code=%d", count);
65 }
66 }
67 return count;
68 }
69
70 /**
71 * @brief Enable a sensor through the sysfs file descriptor
72 * provided.
73 * @note this function one closes FD after the write
74 * @param fd
75 * the file descriptor to write into
76 * @param en
77 * the value to write, typically 1 or 0
78 * @return the errno whenever applicable.
79 */
enable_sysfs_sensor(int fd,int en)80 int enable_sysfs_sensor(int fd, int en)
81 {
82 VFUNC_LOG;
83
84 int nb;
85 int err = 0;
86
87 char c = en ? '1' : '0';
88 nb = write(fd, &c, 1);
89
90 if (nb <= 0) {
91 err = errno;
92 LOGE("HAL:enable_sysfs_sensor - write %c returned %d (%s / %d)",
93 c, nb, strerror(err), err);
94 }
95 close(fd);
96
97
98 return -err;
99 }
100
101 /* This one closes FDs for you */
write_attribute_sensor(int fd,long data)102 int write_attribute_sensor(int fd, long data)
103 {
104 VFUNC_LOG;
105
106 int num_b = 0;
107
108 if (fd >= 0) {
109 char buf[80];
110 sprintf(buf, "%ld", data);
111 num_b = write(fd, buf, strlen(buf) + 1);
112 if (num_b <= 0) {
113 int err = errno;
114 LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err);
115 } else {
116 LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data);
117 }
118 close(fd);
119 }
120
121 return num_b;
122 }
123
124 /* This one DOES NOT close FDs for you */
write_attribute_sensor_continuous(int fd,long data)125 int write_attribute_sensor_continuous(int fd, long data)
126 {
127 VFUNC_LOG;
128
129 int num_b = 0;
130
131 if (fd >= 0) {
132 char buf[80];
133 sprintf(buf, "%ld", data);
134 num_b = write(fd, buf, strlen(buf) + 1);
135 if (num_b <= 0) {
136 int err = errno;
137 LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err);
138 } else {
139 LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data);
140 }
141 }
142
143 return num_b;
144 }
145
read_sysfs_int(char * filename,int * var)146 int read_sysfs_int(char *filename, int *var)
147 {
148 int res=0;
149 FILE *sysfsfp;
150
151 sysfsfp = fopen(filename, "r");
152 if (sysfsfp != NULL) {
153 if (fscanf(sysfsfp, "%d\n", var) < 0 || fclose(sysfsfp) < 0) {
154 res = errno;
155 LOGE("HAL:ERR open file %s to read with error %d", filename, res);
156 }
157 }
158 return -res;
159 }
160
read_sysfs_int64(char * filename,int64_t * var)161 int read_sysfs_int64(char *filename, int64_t *var)
162 {
163 int res=0;
164 FILE *sysfsfp;
165
166 sysfsfp = fopen(filename, "r");
167 if (sysfsfp != NULL) {
168 if (fscanf(sysfsfp, "%lld\n", var) < 0 || fclose(sysfsfp) < 0) {
169 res = errno;
170 LOGE("HAL:ERR open file %s to read with error %d", filename, res);
171 }
172 }
173 return -res;
174 }
175
convert_long_to_hex_char(long * quat,unsigned char * hex,int numElement)176 void convert_long_to_hex_char(long* quat, unsigned char* hex, int numElement)
177 {
178 int bytePosition = 0;
179 for (int index = 0; index < numElement; index++) {
180 for (int i = 0; i < 4; i++) {
181 hex[bytePosition] = (int) ((quat[index] >> (4-1-i) * 8) & 0xFF);
182 //LOGI("e%d quat[%d]: %x", index, bytePosition, hex[bytePosition]);
183 bytePosition++;
184 }
185 }
186 return;
187 }
188
write_sysfs_int(char * filename,int var)189 int write_sysfs_int(char *filename, int var)
190 {
191 int res=0;
192 FILE *sysfsfp;
193
194 sysfsfp = fopen(filename, "w");
195 if (sysfsfp != NULL) {
196 if (fprintf(sysfsfp, "%d\n", var) < 0 || fclose(sysfsfp) < 0) {
197 res = errno;
198 LOGE("HAL:ERR open file %s to write with error %d", filename, res);
199 }
200 }
201 return -res;
202 }
203
write_sysfs_longlong(char * filename,int64_t var)204 int write_sysfs_longlong(char *filename, int64_t var)
205 {
206 int res=0;
207 FILE *sysfsfp;
208
209 sysfsfp = fopen(filename, "w");
210 if (sysfsfp != NULL) {
211 if (fprintf(sysfsfp, "%lld\n", var) < 0 || fclose(sysfsfp) < 0) {
212 res = errno;
213 LOGE("HAL:ERR open file %s to write with error %d", filename, res);
214 }
215 }
216 return -res;
217 }
218
fill_dev_full_name_by_prefix(const char * dev_prefix,char * dev_full_name,int len)219 int fill_dev_full_name_by_prefix(const char* dev_prefix,
220 char *dev_full_name, int len)
221 {
222 char cand_name[20];
223 int prefix_len = strlen(dev_prefix);
224 strncpy(cand_name, dev_prefix, sizeof(cand_name) / sizeof(cand_name[0]));
225
226 // try adding a number, 0-9
227 for(int cand_postfix = 0; cand_postfix < 10; cand_postfix++) {
228 snprintf(&cand_name[prefix_len],
229 sizeof(cand_name) / sizeof(cand_name[0]),
230 "%d", cand_postfix);
231 int dev_num = find_type_by_name(cand_name, "iio:device");
232 if (dev_num != -ENODEV) {
233 strncpy(dev_full_name, cand_name, len);
234 return 0;
235 }
236 }
237 // try adding a small letter, a-z
238 for(char cand_postfix = 'a'; cand_postfix <= 'z'; cand_postfix++) {
239 snprintf(&cand_name[prefix_len],
240 sizeof(cand_name) / sizeof(cand_name[0]),
241 "%c", cand_postfix);
242 int dev_num = find_type_by_name(cand_name, "iio:device");
243 if (dev_num != -ENODEV) {
244 strncpy(dev_full_name, cand_name, len);
245 return 0;
246 }
247 }
248 // try adding a capital letter, A-Z
249 for(char cand_postfix = 'A'; cand_postfix <= 'Z'; cand_postfix++) {
250 snprintf(&cand_name[prefix_len],
251 sizeof(cand_name) / sizeof(cand_name[0]),
252 "%c", cand_postfix);
253 int dev_num = find_type_by_name(cand_name, "iio:device");
254 if (dev_num != -ENODEV) {
255 strncpy(dev_full_name, cand_name, len);
256 return 0;
257 }
258 }
259 return 1;
260 }
261
dump_dmp_img(const char * outFile)262 void dump_dmp_img(const char *outFile)
263 {
264 char sysfs_path[MAX_SYSFS_NAME_LEN];
265 char dmp_path[MAX_SYSFS_NAME_LEN];
266
267 inv_get_sysfs_path(sysfs_path);
268 sprintf(dmp_path, "%s%s", sysfs_path, "/dmp_firmware");
269
270 LOGI("HAL DEBUG:dump DMP image");
271 LOGI("HAL DEBUG:open %s\n", dmp_path);
272 LOGI("HAL DEBUG:write to %s", outFile);
273
274 read_dmp_img(dmp_path, (char *)outFile);
275 }
276
read_sysfs_dir(bool fileMode,char * sysfs_path)277 int read_sysfs_dir(bool fileMode, char *sysfs_path)
278 {
279 VFUNC_LOG;
280
281 int res = 0;
282 char full_path[MAX_SYSFS_NAME_LEN];
283 int fd;
284 char buf[sizeof(long) *4];
285 long data;
286
287 DIR *dp;
288 struct dirent *ep;
289
290 dp = opendir (sysfs_path);
291
292 if (dp != NULL)
293 {
294 LOGI("******************** System Sysfs Dump ***************************");
295 LOGV_IF(0,"HAL DEBUG: opened directory %s", sysfs_path);
296 while ((ep = readdir (dp))) {
297 if(ep != NULL) {
298 LOGV_IF(0,"file name %s", ep->d_name);
299 if(!strcmp(ep->d_name, ".") || !strcmp(ep->d_name, "..") ||
300 !strcmp(ep->d_name, "uevent") || !strcmp(ep->d_name, "dev") ||
301 !strcmp(ep->d_name, "self_test"))
302 continue;
303 sprintf(full_path, "%s%s%s", sysfs_path, "/", ep->d_name);
304 LOGV_IF(0,"HAL DEBUG: reading %s", full_path);
305 fd = open(full_path, O_RDONLY);
306 if (fd > -1) {
307 memset(buf, 0, sizeof(buf));
308 res = read_attribute_sensor(fd, buf, sizeof(buf));
309 close(fd);
310 if (res > 0) {
311 res = sscanf(buf, "%ld", &data);
312 if (res)
313 LOGI("HAL DEBUG:sysfs:cat %s = %ld", full_path, data);
314 } else {
315 LOGV_IF(0,"HAL DEBUG: error reading %s", full_path);
316 }
317 } else {
318 LOGV_IF(0,"HAL DEBUG: error opening %s", full_path);
319 }
320 close(fd);
321 }
322 }
323 closedir(dp);
324 } else{
325 LOGI("HAL DEBUG: could not open directory %s", sysfs_path);
326 }
327
328 return res;
329 }
330