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#define LOG_NDEBUG 0 18 19#include <MPLSupport.h> 20#include <string.h> 21#include <stdio.h> 22#include <fcntl.h> 23 24#include "log.h" 25#include "SensorBase.h" 26 27#include "ml_sysfs_helper.h" 28#include "local_log_def.h" 29 30int64_t getTimestamp() 31{ 32 struct timespec t; 33 t.tv_sec = t.tv_nsec = 0; 34 clock_gettime(CLOCK_MONOTONIC, &t); 35 return int64_t(t.tv_sec) * 1000000000LL + t.tv_nsec; 36} 37 38int64_t timevalToNano(timeval const& t) { 39 return t.tv_sec * 1000000000LL + t.tv_usec * 1000; 40} 41 42int inv_read_data(char *fname, long *data) 43{ 44 VFUNC_LOG; 45 46 char buf[sizeof(long) * 4]; 47 int count, fd; 48 49 fd = open(fname, O_RDONLY); 50 if(fd < 0) { 51 LOGE("HAL:Error opening %s", fname); 52 return -1; 53 } 54 memset(buf, 0, sizeof(buf)); 55 count = read_attribute_sensor(fd, buf, sizeof(buf)); 56 if(count < 1) { 57 close(fd); 58 return -1; 59 } else { 60 count = sscanf(buf, "%ld", data); 61 if(count) 62 LOGV_IF(EXTRA_VERBOSE, "HAL:Data= %ld", *data); 63 } 64 close(fd); 65 66 return 0; 67} 68 69/* This one DOES NOT close FDs for you */ 70int read_attribute_sensor(int fd, char* data, unsigned int size) 71{ 72 VFUNC_LOG; 73 74 int count = 0; 75 if (fd > 0) { 76 count = pread(fd, data, size, 0); 77 if(count < 1) { 78 LOGE("HAL:read fails with error code=%d", count); 79 } 80 } 81 return count; 82} 83 84/** 85 * @brief Enable a sensor through the sysfs file descriptor 86 * provided. 87 * @note this function one closes FD after the write 88 * @param fd 89 * the file descriptor to write into 90 * @param en 91 * the value to write, typically 1 or 0 92 * @return the errno whenever applicable. 93 */ 94int enable_sysfs_sensor(int fd, int en) 95{ 96 VFUNC_LOG; 97 98 int nb; 99 int err = 0; 100 101 char c = en ? '1' : '0'; 102 nb = write(fd, &c, 1); 103 104 if (nb <= 0) { 105 err = errno; 106 LOGE("HAL:enable_sysfs_sensor - write %c returned %d (%s / %d)", 107 c, nb, strerror(err), err); 108 } 109 close(fd); 110 111 112 return err; 113} 114 115/* This one closes FDs for you */ 116int write_attribute_sensor(int fd, long data) 117{ 118 VFUNC_LOG; 119 120 int num_b = 0; 121 122 if (fd >= 0) { 123 char buf[80]; 124 sprintf(buf, "%ld", data); 125 num_b = write(fd, buf, strlen(buf) + 1); 126 if (num_b <= 0) { 127 int err = errno; 128 LOGE("HAL:write fd %d returned '%s' (%d)", fd, strerror(err), err); 129 } else { 130 LOGV_IF(EXTRA_VERBOSE, "HAL:fd=%d write attribute to %ld", fd, data); 131 } 132 close(fd); 133 } 134 135 return num_b; 136} 137 138int read_sysfs_int(char *filename, int *var) 139{ 140 int res=0; 141 FILE *sysfsfp; 142 143 sysfsfp = fopen(filename, "r"); 144 if (sysfsfp != NULL) { 145 if (fscanf(sysfsfp, "%d\n", var) < 1) { 146 LOGE("HAL:ERR failed to read an int from %s.", filename); 147 res = -EINVAL; 148 } 149 fclose(sysfsfp); 150 } else { 151 res = -errno; 152 LOGE("HAL:ERR open file %s to read with error %d", filename, res); 153 } 154 return res; 155} 156 157int write_sysfs_int(char *filename, int var) 158{ 159 int res = 0; 160 FILE *sysfsfp; 161 162 LOGV_IF(SYSFS_VERBOSE, "HAL:sysfs:echo %d > %s (%lld)", 163 var, filename, getTimestamp()); 164 sysfsfp = fopen(filename, "w"); 165 if (sysfsfp == NULL) { 166 res = -errno; 167 LOGE("HAL:ERR open file %s to write with error %d", filename, res); 168 return res; 169 } 170 int fpres, fcres = 0; 171 fpres = fprintf(sysfsfp, "%d\n", var); 172 /* fprintf() can succeed because it never actually writes to the 173 * underlying sysfs node. 174 */ 175 if (fpres < 0) { 176 res = -errno; 177 fclose(sysfsfp); 178 } else { 179 fcres = fclose(sysfsfp); 180 /* Check for errors from: fflush(), write(), and close() */ 181 if (fcres < 0) { 182 res = -errno; 183 } 184 } 185 if (fpres < 0 || fcres < 0) { 186 LOGE("HAL:ERR failed to write %d to %s (err=%d) print/close=%d/%d", 187 var, filename, res, fpres, fcres); 188 } 189 return res; 190} 191