| /* |
| * Copyright (C) 2012 Invensense, Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #define LOG_NDEBUG 0 |
| |
| #include <MPLSupport.h> |
| #include <string.h> |
| #include <stdio.h> |
| #include <fcntl.h> |
| |
| #include "log.h" |
| #include "SensorBase.h" |
| |
| #include "ml_sysfs_helper.h" |
| #include "local_log_def.h" |
| |
| int64_t getTimestamp() |
| { |
| struct timespec t; |
| t.tv_sec = t.tv_nsec = 0; |
| clock_gettime(CLOCK_MONOTONIC, &t); |
| return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec; |
| } |
| |
| int64_t timevalToNano(timeval const& t) { |
| return t.tv_sec * 1000000000LL + t.tv_usec * 1000; |
| } |
| |
| int inv_read_data(char *fname, long *data) |
| { |
| VFUNC_LOG; |
| |
| char buf[sizeof(long) * 4]; |
| int count, fd; |
| |
| fd = open(fname, O_RDONLY); |
| if(fd < 0) { |
| LOGE("HAL:Error opening %s", fname); |
| return -1; |
| } |
| memset(buf, 0, sizeof(buf)); |
| count = read_attribute_sensor(fd, buf, sizeof(buf)); |
| if(count < 1) { |
| close(fd); |
| return -1; |
| } else { |
| count = sscanf(buf, "%ld", data); |
| if(count) |
| LOGV_IF(EXTRA_VERBOSE, "HAL:Data= %ld", *data); |
| } |
| close(fd); |
| |
| return 0; |
| } |
| |
| /* This one DOES NOT close FDs for you */ |
| int read_attribute_sensor(int fd, char* data, unsigned int size) |
| { |
| VFUNC_LOG; |
| |
| int count = 0; |
| if (fd > 0) { |
| count = pread(fd, data, size, 0); |
| if(count < 1) { |
| LOGE("HAL:read fails with error code=%d", count); |
| } |
| } |
| return count; |
| } |
| |
| /** |
| * @brief Enable a sensor through the sysfs file descriptor |
| * provided. |
| * @note this function one closes FD after the write |
| * @param fd |
| * the file descriptor to write into |
| * @param en |
| * the value to write, typically 1 or 0 |
| * @return the errno whenever applicable. |
| */ |
| int enable_sysfs_sensor(int fd, int en) |
| { |
| VFUNC_LOG; |
| |
| int nb; |
| int err = 0; |
| |
| char c = en ? '1' : '0'; |
| nb = write(fd, &c, 1); |
| |
| if (nb <= 0) { |
| err = errno; |
| LOGE("HAL:enable_sysfs_sensor - write %c returned %d (%s / %d)", |
| c, nb, strerror(err), err); |
| } |
| close(fd); |
| |
| |
| return err; |
| } |
| |
| /* This one closes FDs for you */ |
| int write_attribute_sensor(int fd, long data) |
| { |
| VFUNC_LOG; |
| |
| int num_b = 0; |
| |
| if (fd >= 0) { |
| char buf[80]; |
| sprintf(buf, "%ld", data); |
| num_b = write(fd, buf, strlen(buf) + 1); |
| if (num_b <= 0) { |
| int err = errno; |
| LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err); |
| } else { |
| LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data); |
| } |
| close(fd); |
| } |
| |
| return num_b; |
| } |
| |
| int read_sysfs_int(char *filename, int *var) |
| { |
| int res=0; |
| FILE *sysfsfp; |
| |
| sysfsfp = fopen(filename, "r"); |
| if (sysfsfp != NULL) { |
| if (fscanf(sysfsfp, "%d\n", var) < 1) { |
| LOGE("HAL:ERR failed to read an int from %s.", filename); |
| res = -EINVAL; |
| } |
| fclose(sysfsfp); |
| } else { |
| res = -errno; |
| LOGE("HAL:ERR open file %s to read with error %d", filename, res); |
| } |
| return res; |
| } |
| |
| int write_sysfs_int(char *filename, int var) |
| { |
| int res = 0; |
| FILE *sysfsfp; |
| |
| LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", |
| var, filename, getTimestamp()); |
| sysfsfp = fopen(filename, "w"); |
| if (sysfsfp == NULL) { |
| res = -errno; |
| LOGE("HAL:ERR open file %s to write with error %d", filename, res); |
| return res; |
| } |
| int fpres, fcres = 0; |
| fpres = fprintf(sysfsfp, "%d\n", var); |
| /* fprintf() can succeed because it never actually writes to the |
| * underlying sysfs node. |
| */ |
| if (fpres < 0) { |
| res = -errno; |
| fclose(sysfsfp); |
| } else { |
| fcres = fclose(sysfsfp); |
| /* Check for errors from: fflush(), write(), and close() */ |
| if (fcres < 0) { |
| res = -errno; |
| } |
| } |
| if (fpres < 0 || fcres < 0) { |
| LOGE("HAL:ERR failed to write %d to %s (err=%d) print/close=%d/%d", |
| var, filename, res, fpres, fcres); |
| } |
| return res; |
| } |