153 lines
4.3 KiB
C
153 lines
4.3 KiB
C
/*
|
|
* Copyright (c) 2017 Digi International Inc.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
* PERFORMANCE OF THIS SOFTWARE.
|
|
*
|
|
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
|
|
* =======================================================================
|
|
*/
|
|
|
|
#include <aws_iot_log.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#include "device_control.h"
|
|
|
|
/*------------------------------------------------------------------------------
|
|
D E F I N I T I O N S
|
|
------------------------------------------------------------------------------*/
|
|
#define MAX_LENGTH 256
|
|
|
|
#define FILE_CPU_TEMP "/sys/class/thermal/thermal_zone0/temp"
|
|
#define FILE_CPU_LOAD "/proc/stat"
|
|
|
|
/*------------------------------------------------------------------------------
|
|
F U N C T I O N D E C L A R A T I O N S
|
|
------------------------------------------------------------------------------*/
|
|
static long read_file(const char * path, char *buffer, long bytes_to_read);
|
|
|
|
/*------------------------------------------------------------------------------
|
|
F U N C T I O N D E F I N I T I O N S
|
|
------------------------------------------------------------------------------*/
|
|
/*
|
|
* get_cpu_load() - Get the CPU load of the system
|
|
*
|
|
* Return: The CPU load in %, -1 if the value is not available.
|
|
*/
|
|
double get_cpu_load(void)
|
|
{
|
|
static unsigned long long last_work = 0, last_total = 0;
|
|
char data[MAX_LENGTH] = {0};
|
|
unsigned long long int fields[10];
|
|
unsigned long long work = 0, total = 0;
|
|
double usage = -1;
|
|
int i, result;
|
|
|
|
if (read_file(FILE_CPU_LOAD, data, MAX_LENGTH) <= 0) {
|
|
IOT_ERROR("Error reading cpu load file");
|
|
return usage;
|
|
}
|
|
|
|
result = sscanf(data, "cpu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu",
|
|
&fields[0], &fields[1], &fields[2], &fields[3], &fields[4],
|
|
&fields[5], &fields[6], &fields[7], &fields[8], &fields[9]);
|
|
|
|
if (result < 4) {
|
|
IOT_ERROR("CPU load not enough fields error");
|
|
return usage;
|
|
}
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
work += fields[i];
|
|
}
|
|
for (i = 0; i < result; i++) {
|
|
total += fields[i];
|
|
}
|
|
|
|
if (last_work == 0 && last_total == 0) {
|
|
/* The first time report 0%. */
|
|
usage = 0;
|
|
} else {
|
|
unsigned long long diff_work = work - last_work;
|
|
unsigned long long diff_total = total - last_total;
|
|
|
|
usage = diff_work * 100.0 / diff_total;
|
|
}
|
|
|
|
last_total = total;
|
|
last_work = work;
|
|
|
|
return usage;
|
|
}
|
|
|
|
/*
|
|
* get_cpu_temp() - Get the CPU temperature of the system
|
|
*
|
|
* Return: The CPU temperature in C, -1 if error.
|
|
*/
|
|
double get_cpu_temp(void)
|
|
{
|
|
char file_data[MAX_LENGTH] = {0};
|
|
double temperature ;
|
|
int result;
|
|
|
|
if (read_file(FILE_CPU_TEMP, file_data, MAX_LENGTH) <= 0) {
|
|
IOT_ERROR("Error reading CPU temperature file");
|
|
return -1;
|
|
}
|
|
|
|
result = sscanf(file_data, "%lf", &temperature);
|
|
if (result < 1) {
|
|
IOT_ERROR("Error getting CPU temperature: not enough fields");
|
|
return -1;
|
|
}
|
|
return temperature / 1000;
|
|
}
|
|
|
|
/**
|
|
* read_file() - Read the given file and returns its contents
|
|
*
|
|
* @path: Absolute path of the file to read.
|
|
* @buffer: Buffer to store the contents of the file.
|
|
* @bytes_to_read: The number of bytes to read (including the terminating
|
|
* null byte).
|
|
*
|
|
* Return: The number of read bytes (including the terminating null byte), -1 on
|
|
* error.
|
|
*/
|
|
static long read_file(const char * path, char *buffer, long bytes_to_read)
|
|
{
|
|
FILE *fd = NULL;
|
|
long read_size = 0;
|
|
|
|
if (access(path, R_OK) != 0) {
|
|
IOT_DEBUG("File cannot be read: %s", path);
|
|
return -1;
|
|
}
|
|
|
|
if ((fd = fopen(path, "rb")) == NULL) {
|
|
IOT_DEBUG("fopen error: %s", path);
|
|
return -1;
|
|
}
|
|
|
|
if (fgets(buffer, bytes_to_read, fd) == NULL) {
|
|
IOT_DEBUG("fgets error: %s", path);
|
|
read_size = -1;
|
|
} else {
|
|
read_size = strlen(buffer) + 1;
|
|
}
|
|
fclose(fd);
|
|
|
|
return read_size;
|
|
}
|