X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=utils.c;h=6ec6f64e11b22b08ffd8612f67f2b9e0931b6366;hb=cda77fa4f1de5197c40d1845a382f9abaa4818a4;hp=9e4fb2735f51767f4c2a08737a4848c998fc4494;hpb=259d5cfe043792f3549e8e765b97da1f486c3bc8;p=android-x86%2Fhardware-intel-libsensors.git diff --git a/utils.c b/utils.c index 9e4fb27..6ec6f64 100644 --- a/utils.c +++ b/utils.c @@ -1,14 +1,31 @@ /* - * Copyright (C) 2014 Intel Corporation. - */ +// Copyright (c) 2015 Intel Corporation +// +// 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. +*/ #include #include +#include #include #include +#include +#include + #include "common.h" #include "utils.h" +#include /* Note: * @@ -16,215 +33,207 @@ * possible sysfs attributes. As an optimization we may want to cache which * ones are valid and immediately return in error for inexistent entries. */ - -int sysfs_write_int(const char path[PATH_MAX], int value) +int sysfs_read(const char path[PATH_MAX], void *buf, int buf_len) { - int ret; - int fd; - int len; - char buf[20]; + int fd, len; - if (!path[0]) { + if (!path[0] || !buf || buf_len < 1) return -1; - } - fd = open(path, O_WRONLY); + fd = open(path, O_RDONLY); if (fd == -1) { ALOGV("Cannot open %s (%s)\n", path, strerror(errno)); return -1; } - len = sprintf(buf, "%d", value) + 1; - - ret = write(fd, buf, len); - - if (ret != len) { - ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", buf, len, path, - strerror(errno)); - } + len = read(fd, buf, buf_len); close(fd); - return ret; + if (len == -1) + ALOGW("Cannot read from %s (%s)\n", path, strerror(errno)); + else + ALOGV("Read %d bytes from %s\n", len, path); + + return len; } -int sysfs_read_int(const char path[PATH_MAX], int *value) +int sysfs_write(const char path[PATH_MAX], const void *buf, const int buf_len) { - int fd; - int len; - char buf[20] = {0}; + int fd, len; - if (!path[0] || !value) { + if (!path[0] || !buf || buf_len < 1) return -1; - } - fd = open(path, O_RDONLY); + fd = open(path, O_WRONLY); if (fd == -1) { ALOGV("Cannot open %s (%s)\n", path, strerror(errno)); return -1; } - len = read(fd, buf, sizeof(buf)); + len = write(fd, buf, buf_len); close(fd); - if (len <= 0) { - ALOGW("Cannot read integer from %s (%s)\n", path, - strerror(errno)); - return -1; - } + if (len == -1) + ALOGW("Cannot write to %s (%s)\n", path, strerror(errno)); + else if (len != buf_len) + ALOGW("Cannot write %d bytes to %s (%d)\n", buf_len, path, len); + else + ALOGV("Wrote %d bytes to %s\n", buf_len, path); - *value = atoi(buf); + return len; +} - ALOGV("Read %d from %s\n", *value, path); - return 0; +static void str2int(const char* buf, void *v) +{ + *(int*)v = atoi(buf); } -int sysfs_write_str(const char path[PATH_MAX], const char *str) +static void str2float(const char* buf, void *v) { - int ret; - int fd; - int len; + *(float*)v = strtof(buf, NULL); +} - if (!path[0] || !str || !str[0]) { - return -1; - } - fd = open(path, O_WRONLY); +static void str2uint64(const char* buf, void *v) +{ + *(uint64_t*)v = atoll(buf); +} - if (fd == -1) { - ALOGV("Cannot open %s (%s)\n", path, strerror(errno)); + +int sysfs_read_num(const char path[PATH_MAX], void *v, + void (*str2num)(const char* buf, void *v)) +{ + char buf[20]; + int len = sysfs_read_str(path, buf, sizeof(buf)); + + if (len <= 0) { + ALOGW("Cannot read number from %s (%s)\n", path, + strerror(errno)); return -1; } - len = strlen(str); + str2num(buf, v); + return 0; +} - ret = write(fd, str, len); - if (ret != len) { - ALOGW("Cannot write %s (%d bytes) to %s (%s)\n", str, len, path, - strerror(errno)); - } - else - ALOGV("Wrote %s to %s\n", str, path); +int sysfs_read_int(const char path[PATH_MAX], int *value) +{ + return sysfs_read_num(path, value, str2int); +} - close(fd); - return ret; +int sysfs_read_float(const char path[PATH_MAX], float *value) +{ + return sysfs_read_num(path, value, str2float); } -int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len) +int sysfs_read_uint64(const char path[PATH_MAX], uint64_t *value) { - int fd; - int len; + return sysfs_read_num(path, value, str2uint64); +} - if (!path[0] || !buf || buf_len < 1) - return -1; - fd = open(path, O_RDONLY); +int sysfs_write_int(const char path[PATH_MAX], int value) +{ + char buf[20]; + int len = snprintf(buf, sizeof(buf), "%d", value); - if (fd == -1) { - ALOGV("Cannot open %s (%s)\n", path, strerror(errno)); + if (len <= 0) { + ALOGE("Unexpected condition in sysfs_write_int\n"); return -1; } - len = read(fd, buf, buf_len); + return sysfs_write(path, buf, len); +} - close(fd); +int sysfs_write_float(const char path[PATH_MAX], float value) +{ + char buf[20]; + int len = snprintf(buf, sizeof(buf), "%g", value); - if (len == -1) { - ALOGW("Cannot read string from %s (%s)\n", path, - strerror(errno)); + if (len <= 0) { + ALOGE("Unexpected condition in sysfs_write_float\n"); return -1; } - buf[len == 0 ? 0 : len-1] = '\0'; + return sysfs_write(path, buf, len); +} - ALOGV("Read %s from %s\n", buf, path); - return len; +int sysfs_write_str(const char path[PATH_MAX], const char *str) +{ + if (!str || !str[0]) + return -1; + + return sysfs_write(path, str, strlen(str)); } -int sysfs_read_float(const char path[PATH_MAX], float *value) +int sysfs_read_str(const char path[PATH_MAX], char *buf, int buf_len) { - int fd; int len; - char buf[20] = {0}; - - if (!path[0] || !value) { - return -1; - } - - fd = open(path, O_RDONLY); - if (fd == -1) { - ALOGV("Cannot open %s (%s)\n", path, strerror(errno)); + if (!buf || buf_len < 1) return -1; - } - len = read(fd, buf, sizeof(buf)); + len = sysfs_read(path, buf, buf_len); - close(fd); - - if (len <= 0) { - ALOGW("Cannot read float from %s (%s)\n", path, + if (len == -1) { + ALOGW("Cannot read string from %s (%s)\n", path, strerror(errno)); return -1; } - *value = (float) strtod(buf, NULL); + buf[len == 0 ? 0 : len - 1] = '\0'; - ALOGV("Read %f from %s\n", *value, path); + ALOGV("Read %s from %s\n", buf, path); - return 0; + return len; } -int decode_type_spec( const char type_buf[MAX_TYPE_SPEC_LEN], - struct datum_info_t *type_info) +int64_t get_timestamp (clockid_t clock_id) { - /* Return size in bytes for this type specification, or -1 in error */ - char sign; - char endianness; - unsigned int realbits, storagebits, shift; - int tokens; - - /* Valid specs: "le:u10/16>>0", "le:s16/32>>0" or "le:s32/32>>0" */ - - tokens = sscanf(type_buf, "%ce:%c%u/%u>>%u", - &endianness, &sign, &realbits, &storagebits, &shift); - - if (tokens != 5 || - (endianness != 'b' && endianness != 'l') || - (sign != 'u' && sign != 's') || - realbits > storagebits || - (storagebits != 16 && storagebits != 32 && storagebits != 64)) { - ALOGE("Invalid iio channel type spec: %s\n", type_buf); - return -1; - } + struct timespec ts = {0}; - type_info->endianness = endianness; - type_info->sign = sign; - type_info->realbits = (short) realbits; - type_info->storagebits = (short) storagebits; - type_info->shift = (short) shift; + if (!clock_gettime(clock_id, &ts)) + return 1000000000LL * ts.tv_sec + ts.tv_nsec; + else /* in this case errno is set appropriately */ + return -1; +} - return storagebits / 8; +int64_t get_timestamp_realtime (void) +{ + return get_timestamp(CLOCK_REALTIME); } +int64_t get_timestamp_boot (void) +{ + return get_timestamp(CLOCK_BOOTTIME); +} -int64_t get_timestamp(void) +int64_t get_timestamp_thread (void) { - struct timespec ts = {0}; + return get_timestamp(CLOCK_THREAD_CPUTIME_ID); +} - clock_gettime(CLOCK_MONOTONIC, &ts); +int64_t get_timestamp_monotonic (void) +{ + return get_timestamp(CLOCK_MONOTONIC); +} - return 1000000000LL * ts.tv_sec + ts.tv_nsec; +void set_timestamp (struct timespec *out, int64_t target_ns) +{ + out->tv_sec = target_ns / 1000000000LL; + out->tv_nsec = target_ns % 1000000000LL; } +