/*
* 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;
}