C++程序  |  191行  |  4.48 KB

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