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 30 int64_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 38 int64_t timevalToNano(timeval const& t) { 39 return t.tv_sec * 1000000000LL + t.tv_usec * 1000; 40 } 41 42 int 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 */ 70 int 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 */ 94 int 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 */ 116 int 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 138 int 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 157 int 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