summaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorSean E. Russell <ser@ser1.net>2020-02-27 18:51:28 -0600
committerSean E. Russell <ser@ser1.net>2020-02-28 07:06:51 -0600
commit7a89225d729d4c54c5bc95b21979f48f9cd046b1 (patch)
tree10bf143324cf553765d7002d0eb82abc21c72bb1 /widgets
parent4fce1654c5c263797205997e7635c7d06c393a85 (diff)
Abstracts CPU & mem devices.
Finishes device refactoring: temps Refactoring to allow updating maps. Simpler, and optimizable.
Diffstat (limited to 'widgets')
-rw-r--r--widgets/cpu.go110
-rw-r--r--widgets/include/smc.c700
-rw-r--r--widgets/include/smc.h254
-rw-r--r--widgets/mem.go105
-rw-r--r--widgets/mem_freebsd.go67
-rw-r--r--widgets/mem_other.go25
-rw-r--r--widgets/temp.go13
-rw-r--r--widgets/temp_darwin.go74
-rw-r--r--widgets/temp_freebsd.go124
-rw-r--r--widgets/temp_linux.go32
-rw-r--r--widgets/temp_openbsd.go74
-rw-r--r--widgets/temp_windows.go29
12 files changed, 96 insertions, 1511 deletions
diff --git a/widgets/cpu.go b/widgets/cpu.go
index c0f25bc..e56cd3d 100644
--- a/widgets/cpu.go
+++ b/widgets/cpu.go
@@ -1,14 +1,12 @@
package widgets
import (
- "context"
"fmt"
"log"
"sync"
"time"
"github.com/prometheus/client_golang/prometheus"
- psCpu "github.com/shirou/gopsutil/cpu"
"github.com/xxxserxxx/gotop/devices"
ui "github.com/xxxserxxx/gotop/termui"
@@ -20,27 +18,19 @@ type CpuWidget struct {
ShowAverageLoad bool
ShowPerCpuLoad bool
updateInterval time.Duration
- formatString string
updateLock sync.Mutex
- metric []prometheus.Gauge
+ metric map[string]prometheus.Gauge
}
+var cpuLabels []string
+
func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverageLoad bool, showPerCpuLoad bool) *CpuWidget {
- cpuCount, err := devices.Counts(false)
- if err != nil {
- log.Printf("failed to get CPU count: %v", err)
- }
- formatString := "CPU%1d"
- if cpuCount > 10 {
- formatString = "CPU%02d"
- }
self := &CpuWidget{
LineGraph: ui.NewLineGraph(),
- CpuCount: cpuCount,
+ CpuCount: len(cpuLabels),
updateInterval: updateInterval,
ShowAverageLoad: showAverageLoad,
ShowPerCpuLoad: showPerCpuLoad,
- formatString: formatString,
}
self.Title = " CPU Usage "
self.HorizontalScale = horizontalScale
@@ -58,9 +48,10 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
}
if self.ShowPerCpuLoad {
- for i := 0; i < int(self.CpuCount); i++ {
- key := fmt.Sprintf(formatString, i)
- self.Data[key] = []float64{0}
+ cpus := make(map[string]float64)
+ devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
+ for k, v := range cpus {
+ self.Data[k] = []float64{v}
}
}
@@ -77,29 +68,24 @@ func NewCpuWidget(updateInterval time.Duration, horizontalScale int, showAverage
func (self *CpuWidget) EnableMetric() {
if self.ShowAverageLoad {
- self.metric = make([]prometheus.Gauge, 1)
- self.metric[0] = prometheus.NewGauge(prometheus.GaugeOpts{
+ self.metric = make(map[string]prometheus.Gauge)
+ self.metric["AVRG"] = prometheus.NewGauge(prometheus.GaugeOpts{
Subsystem: "cpu",
Name: "avg",
})
} else {
- ctx, ccl := context.WithTimeout(context.Background(), time.Second*5)
- defer ccl()
- percents, err := psCpu.PercentWithContext(ctx, self.updateInterval, true)
- if err != nil {
- log.Printf("error setting up metrics: %v", err)
- return
- }
- self.metric = make([]prometheus.Gauge, self.CpuCount)
- for i, perc := range percents {
+ cpus := make(map[string]float64)
+ devices.UpdateCPU(cpus, self.updateInterval, self.ShowPerCpuLoad)
+ self.metric = make(map[string]prometheus.Gauge)
+ for key, perc := range cpus {
gauge := prometheus.NewGauge(prometheus.GaugeOpts{
Namespace: "gotop",
Subsystem: "cpu",
- Name: fmt.Sprintf("%d", i),
+ Name: key,
})
gauge.Set(perc)
prometheus.MustRegister(gauge)
- self.metric[i] = gauge
+ self.metric[key] = gauge
}
}
}
@@ -111,47 +97,41 @@ func (b *CpuWidget) Scale(i int) {
func (self *CpuWidget) update() {
if self.ShowAverageLoad {
go func() {
- percent, err := devices.Percent(self.updateInterval, false)
- if err != nil {
- log.Printf("failed to get average CPU usage percent: %v. self.updateInterval: %v. percpu: %v", err, self.updateInterval, false)
- } else {
- self.Lock()
- defer self.Unlock()
- self.updateLock.Lock()
- defer self.updateLock.Unlock()
- self.Data["AVRG"] = append(self.Data["AVRG"], percent[0])
- self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", percent[0])
- if self.metric != nil {
- self.metric[0].Set(percent[0])
- }
+ cpus := make(map[string]float64)
+ devices.UpdateCPU(cpus, self.updateInterval, false)
+ self.Lock()
+ defer self.Unlock()
+ self.updateLock.Lock()
+ defer self.updateLock.Unlock()
+ var val float64
+ for _, v := range cpus {
+ val = v
+ break
+ }
+ self.Data["AVRG"] = append(self.Data["AVRG"], val)
+ self.Labels["AVRG"] = fmt.Sprintf("%3.0f%%", val)
+ if self.metric != nil {
+ self.metric["AVRG"].Set(val)
}
}()
}
if self.ShowPerCpuLoad {
go func() {
- percents, err := devices.Percent(self.updateInterval, true)
- if err != nil {
- log.Printf("failed to get CPU usage percents: %v. self.updateInterval: %v. percpu: %v", err, self.updateInterval, true)
- } else {
- if len(percents) != int(self.CpuCount) {
- log.Printf("error: number of CPU usage percents doesn't match CPU count. percents: %v. self.Count: %v", percents, self.CpuCount)
- } else {
- self.Lock()
- defer self.Unlock()
- self.updateLock.Lock()
- defer self.updateLock.Unlock()
- for i, percent := range percents {
- key := fmt.Sprintf(self.formatString, i)
- self.Data[key] = append(self.Data[key], percent)
- self.Labels[key] = fmt.Sprintf("%3.0f%%", percent)
- if self.metric != nil {
- if self.metric[i] == nil {
- log.Printf("ERROR: not enough metrics %d", i)
- } else {
- self.metric[i].Set(percent)
- }
- }
+ cpus := make(map[string]float64)
+ devices.UpdateCPU(cpus, self.updateInterval, true)
+ self.Lock()
+ defer self.Unlock()
+ self.updateLock.Lock()
+ defer self.updateLock.Unlock()
+ for key, percent := range cpus {
+ self.Data[key] = append(self.Data[key], percent)
+ self.Labels[key] = fmt.Sprintf("%3.0f%%", percent)
+ if self.metric != nil {
+ if self.metric[key] == nil {
+ log.Printf("no metrics for %s", key)
+ } else {
+ self.metric[key].Set(percent)
}
}
}
diff --git a/widgets/include/smc.c b/widgets/include/smc.c
deleted file mode 100644
index 0c200d6..0000000
--- a/widgets/include/smc.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * Apple System Management Controller (SMC) API from user space for Intel based
- * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver
- * for the SMC.
- *
- * smc.c
- * libsmc
- *
- * Copyright (C) 2014 beltex <https://github.com/beltex>
- *
- * Based off of fork from:
- * osx-cpu-temp <https://github.com/lavoiesl/osx-cpu-temp>
- *
- * With credits to:
- *
- * Copyright (C) 2006 devnull
- * Apple System Management Control (SMC) Tool
- *
- * Copyright (C) 2006 Hendrik Holtmann
- * smcFanControl <https://github.com/hholtmann/smcFanControl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "smc.h"
-
-
-//------------------------------------------------------------------------------
-// MARK: MACROS
-//------------------------------------------------------------------------------
-
-
-/**
-Name of the SMC IOService as seen in the IORegistry. You can view it either via
-command line with ioreg or through the IORegistryExplorer app (found on Apple's
-developer site - Hardware IO Tools for Xcode)
-*/
-#define IOSERVICE_SMC "AppleSMC"
-
-
-/**
-IOService for getting machine model name
-*/
-#define IOSERVICE_MODEL "IOPlatformExpertDevice"
-
-
-/**
-SMC data types - 4 byte multi-character constants
-
-Sources: See TMP SMC keys in smc.h
-
-http://stackoverflow.com/questions/22160746/fpe2-and-sp78-data-types
-*/
-#define DATA_TYPE_UINT8 "ui8 "
-#define DATA_TYPE_UINT16 "ui16"
-#define DATA_TYPE_UINT32 "ui32"
-#define DATA_TYPE_FLAG "flag"
-#define DATA_TYPE_FPE2 "fpe2"
-#define DATA_TYPE_SFDS "{fds"
-#define DATA_TYPE_SP78 "sp78"
-
-
-//------------------------------------------------------------------------------
-// MARK: GLOBAL VARS
-//------------------------------------------------------------------------------
-
-
-/**
-Our connection to the SMC
-*/
-static io_connect_t conn;
-
-
-/**
-Number of characters in an SMC key
-*/
-static const int SMC_KEY_SIZE = 4;
-
-
-/**
-Number of characters in a data type "key" returned from the SMC. See data type
-macros.
-*/
-static const int DATA_TYPE_SIZE = 4;
-
-
-//------------------------------------------------------------------------------
-// MARK: ENUMS
-//------------------------------------------------------------------------------
-
-
-/**
-Defined by AppleSMC.kext. See SMCParamStruct.
-
-These are SMC specific return codes
-*/
-typedef enum {
- kSMCSuccess = 0,
- kSMCError = 1,
- kSMCKeyNotFound = 0x84
-} kSMC_t;
-
-
-/**
-Defined by AppleSMC.kext. See SMCParamStruct.
-
-Function selectors. Used to tell the SMC which function inside it to call.
-*/
-typedef enum {
- kSMCUserClientOpen = 0,
- kSMCUserClientClose = 1,
- kSMCHandleYPCEvent = 2,
- kSMCReadKey = 5,
- kSMCWriteKey = 6,
- kSMCGetKeyCount = 7,
- kSMCGetKeyFromIndex = 8,
- kSMCGetKeyInfo = 9
-} selector_t;
-
-
-//------------------------------------------------------------------------------
-// MARK: STRUCTS
-//------------------------------------------------------------------------------
-
-
-/**
-Defined by AppleSMC.kext. See SMCParamStruct.
-*/
-typedef struct {
- unsigned char major;
- unsigned char minor;
- unsigned char build;
- unsigned char reserved;
- unsigned short release;
-} SMCVersion;
-
-
-/**
-Defined by AppleSMC.kext. See SMCParamStruct.
-*/
-typedef struct {
- uint16_t version;
- uint16_t length;
- uint32_t cpuPLimit;
- uint32_t gpuPLimit;
- uint32_t memPLimit;
-} SMCPLimitData;
-
-
-/**
-Defined by AppleSMC.kext. See SMCParamStruct.
-
-- dataSize : How many values written to SMCParamStruct.bytes
-- dataType : Type of data written to SMCParamStruct.bytes. This lets us know how
- to interpret it (translate it to human readable)
-*/
-typedef struct {
- IOByteCount dataSize;
- uint32_t dataType;
- uint8_t dataColors;
-} SMCKeyInfoData;
-
-
-/**
-Defined by AppleSMC.kext.
-
-This is the predefined struct that must be passed to communicate with the
-AppleSMC driver. While the driver is closed source, the definition of this
-struct happened to appear in the Apple PowerManagement project at around
-version 211, and soon after disappeared. It can be seen in the PrivateLib.c
-file under pmconfigd.
-
-https://www.opensource.apple.com/source/PowerManagement/PowerManagement-211/
-*/
-typedef struct {
- uint32_t key;
- SMCVersion vers;
- SMCPLimitData pLimitData;
- SMCKeyInfoData keyInfo;
- uint8_t result;
- uint8_t status;
- uint8_t data8;
- uint32_t data32;
- uint8_t bytes[32];
-} SMCParamStruct;
-
-
-/**
-Used for returning data from the SMC.
-*/
-typedef struct {
- uint8_t data[32];
- uint32_t dataType;
- uint32_t dataSize;
- kSMC_t kSMC;
-} smc_return_t;
-
-
-//------------------------------------------------------------------------------
-// MARK: HELPERS - TYPE CONVERSION
-//------------------------------------------------------------------------------
-
-
-/**
-Convert data from SMC of fpe2 type to human readable.
-
-:param: data Data from the SMC to be converted. Assumed data size of 2.
-:returns: Converted data
-*/
-static unsigned int from_fpe2(uint8_t data[32])
-{
- unsigned int ans = 0;
-
- // Data type for fan calls - fpe2
- // This is assumend to mean floating point, with 2 exponent bits
- // http://stackoverflow.com/questions/22160746/fpe2-and-sp78-data-types
- ans += data[0] << 6;
- ans += data[1] << 2;
-
- return ans;
-}
-
-
-/**
-Convert to fpe2 data type to be passed to SMC.
-
-:param: val Value to convert
-:param: data Pointer to data array to place result
-*/
-static void to_fpe2(unsigned int val, uint8_t *data)
-{
- data[0] = val >> 6;
- data[1] = (val << 2) ^ (data[0] << 8);
-}
-
-
-/**
-Convert SMC key to uint32_t. This must be done to pass it to the SMC.
-
-:param: key The SMC key to convert
-:returns: uint32_t translation.
- Returns zero if key is not 4 characters in length.
-*/
-static uint32_t to_uint32_t(char *key)
-{
- uint32_t ans = 0;
- uint32_t shift = 24;
-
- // SMC key is expected to be 4 bytes - thus 4 chars
- if (strlen(key) != SMC_KEY_SIZE) {
- return 0;
- }
-
- for (int i = 0; i < SMC_KEY_SIZE; i++) {
- ans += key[i] << shift;
- shift -= 8;
- }
-
- return ans;
-}
-
-
-/**
-For converting the dataType return from the SMC to human readable 4 byte
-multi-character constant.
-*/
-static void to_string(uint32_t val, char *dataType)
-{
- int shift = 24;
-
- for (int i = 0; i < DATA_TYPE_SIZE; i++) {
- // To get each char, we shift it into the lower 8 bits, and then & by
- // 255 to insolate it
- dataType[i] = (val >> shift) & 0xff;
- shift -= 8;
- }
-}
-
-
-//------------------------------------------------------------------------------
-// MARK: HELPERS - TMP CONVERSION
-//------------------------------------------------------------------------------
-
-
-/**
-Celsius to Fahrenheit
-*/
-static double to_fahrenheit(double tmp)
-{
- // http://en.wikipedia.org/wiki/Fahrenheit#Definition_and_conversions
- return (tmp * 1.8) + 32;
-}
-
-
-/**
-Celsius to Kelvin
-*/
-static double to_kelvin(double tmp)
-{
- // http://en.wikipedia.org/wiki/Kelvin
- return tmp + 273.15;
-}
-
-
-//------------------------------------------------------------------------------
-// MARK: "PRIVATE" FUNCTIONS
-//------------------------------------------------------------------------------
-
-
-/**
-Make a call to the SMC
-
-:param: inputStruct Struct that holds data telling the SMC what you want
-:param: outputStruct Struct holding the SMC's response
-:returns: I/O Kit return code
-*/
-static kern_return_t call_smc(SMCParamStruct *inputStruct,
- SMCParamStruct *outputStruct)
-{
- kern_return_t result;
- size_t inputStructCnt = sizeof(SMCParamStruct);
- size_t outputStructCnt = sizeof(SMCParamStruct);
-
- result = IOConnectCallStructMethod(conn, kSMCHandleYPCEvent,
- inputStruct,
- inputStructCnt,
- outputStruct,
- &outputStructCnt);
-
- if (result != kIOReturnSuccess) {
- // IOReturn error code lookup. See "Accessing Hardware From Applications
- // -> Handling Errors" Apple doc
- result = err_get_code(result);
- }
-
- return result;
-}
-
-
-/**
-Read data from the SMC
-
-:param: key The SMC key
-*/
-static kern_return_t read_smc(char *key, smc_return_t *result_smc)
-{
- kern_return_t result;
- SMCParamStruct inputStruct;
- SMCParamStruct outputStruct;
-
- memset(&inputStruct, 0, sizeof(SMCParamStruct));
- memset(&outputStruct, 0, sizeof(SMCParamStruct));
- memset(result_smc, 0, sizeof(smc_return_t));
-
- // First call to AppleSMC - get key info
- inputStruct.key = to_uint32_t(key);
- inputStruct.data8 = kSMCGetKeyInfo;
-
- result = call_smc(&inputStruct, &outputStruct);
- result_smc->kSMC = outputStruct.result;
-
- if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) {
- return result;
- }
-
- // Store data for return
- result_smc->dataSize = outputStruct.keyInfo.dataSize;
- result_smc->dataType = outputStruct.keyInfo.dataType;
-
-
- // Second call to AppleSMC - now we can get the data
- inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize;
- inputStruct.data8 = kSMCReadKey;
-
- result = call_smc(&inputStruct, &outputStruct);
- result_smc->kSMC = outputStruct.result;
-
- if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) {
- return result;
- }
-
- memcpy(result_smc->data, outputStruct.bytes, sizeof(outputStruct.bytes));
-
- return result;
-}
-
-
-/**
-Write data to the SMC.
-
-:returns: IOReturn IOKit return code
-*/
-static kern_return_t write_smc(char *key, smc_return_t *result_smc)
-{
- kern_return_t result;
- SMCParamStruct inputStruct;
- SMCParamStruct outputStruct;
-
- memset(&inputStruct, 0, sizeof(SMCParamStruct));
- memset(&outputStruct, 0, sizeof(SMCParamStruct));
-
- // First call to AppleSMC - get key info
- inputStruct.key = to_uint32_t(key);
- inputStruct.data8 = kSMCGetKeyInfo;
-
- result = call_smc(&inputStruct, &outputStruct);
- result_smc->kSMC = outputStruct.result;
-
- if (result != kIOReturnSuccess || outputStruct.result != kSMCSuccess) {
- return result;
- }
-
- // Check data is correct
- if (result_smc->dataSize != outputStruct.keyInfo.dataSize ||
- result_smc->dataType != outputStruct.keyInfo.dataType) {
- return kIOReturnBadArgument;
- }
-
- // Second call to AppleSMC - now we can write the data
- inputStruct.data8 = kSMCWriteKey;
- inputStruct.keyInfo.dataSize = outputStruct.keyInfo.dataSize;
-
- // Set data to write
- memcpy(inputStruct.bytes, result_smc->data, sizeof(result_smc->data));
-
- result = call_smc(&inputStruct, &outputStruct);
- result_smc->kSMC = outputStruct.result;
-
- return result;
-}
-
-
-/**
-Get the model name of the machine.
-*/
-static kern_return_t get_machine_model(io_name_t model)
-{
- io_service_t service;
- kern_return_t result;
-
- service = IOServiceGetMatchingService(kIOMasterPortDefault,
- IOServiceMatching(IOSERVICE_MODEL));
-
- if (service == 0) {
- printf("ERROR: %s NOT FOUND\n", IOSERVICE_MODEL);
- return kIOReturnError;
- }
-
- // Get the model name
- result = IORegistryEntryGetName(service, model);
- IOObjectRelease(service);
-
- return result;
-}
-
-
-//------------------------------------------------------------------------------
-// MARK: "PUBLIC" FUNCTIONS
-//------------------------------------------------------------------------------
-
-
-kern_return_t open_smc(void)
-{
- kern_return_t result;
- io_service_t service;
-
- service = IOServiceGetMatchingService(kIOMasterPortDefault,
- IOServiceMatching(IOSERVICE_SMC));
-
- if (service == 0) {
- // NOTE: IOServiceMatching documents 0 on failure
- printf("ERROR: %s NOT FOUND\n", IOSERVICE_SMC);
- return kIOReturnError;
- }
-
- result = IOServiceOpen(service, mach_task_self(), 0, &conn);
- IOObjectRelease(service);
-
- return result;
-}
-
-
-kern_return_t close_smc(void)
-{
- return IOServiceClose(conn);
-}
-
-
-bool is_key_valid(char *key)
-{
- bool ans = false;
- kern_return_t result;
- smc_return_t result_smc;
-
- if (strlen(key) != SMC_KEY_SIZE) {
- printf("ERROR: Invalid key size - must be 4 chars\n");
- return ans;
- }
-
- // Try a read and see if it succeeds
- result = read_smc(key, &result_smc);
-
- if (result == kIOReturnSuccess && result_smc.kSMC == kSMCSuccess) {
- ans = true;
- }
-
- return ans;
-}
-
-
-double get_tmp(char *key, tmp_unit_t unit)
-{
- kern_return_t result;
- smc_return_t result_smc;
-
- result = read_smc(key, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 2 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_SP78))) {
- // Error
- return 0.0;
- }
-
- // TODO: Create from_sp78() convert function
- double tmp = result_smc.data[0];
-
- switch (unit) {
- case CELSIUS:
- break;
- case FAHRENHEIT:
- tmp = to_fahrenheit(tmp);
- break;
- case KELVIN:
- tmp = to_kelvin(tmp);
- break;
- }
-
- return tmp;
-}
-
-
-bool is_battery_powered(void)
-{
- kern_return_t result;
- smc_return_t result_smc;
-
- result = read_smc(BATT_PWR, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 1 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_FLAG))) {
- // Error
- return false;
- }
-
- return result_smc.data[0];
-}
-
-
-bool is_optical_disk_drive_full(void)
-{
- kern_return_t result;
- smc_return_t result_smc;
-
- result = read_smc(ODD_FULL, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 1 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_FLAG))) {
- // Error
- return false;
- }
-
- return result_smc.data[0];
-}
-
-
-//------------------------------------------------------------------------------
-// MARK: FAN FUNCTIONS
-//------------------------------------------------------------------------------
-
-
-bool get_fan_name(unsigned int fan_num, fan_name_t name)
-{
- char key[5];
- kern_return_t result;
- smc_return_t result_smc;
-
- sprintf(key, "F%dID", fan_num);
- result = read_smc(key, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 16 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_SFDS))) {
- return false;
- }
-
-
- /*
- We know the data size is 16 bytes and the type is "{fds", a custom
- struct defined by the AppleSMC.kext. See TMP enum sources for the
- struct.
-
- The last 12 bytes contain the name of the fan, an array of chars, hence
- the loop range.
- */
- int index = 0;
- for (int i = 4; i < 16; i++) {
- // Check if at the end (name may not be full 12 bytes)
- // Could check for 0 (null), but instead we check for 32 (space). This
- // is a hack to remove whitespace. :)
- if (result_smc.data[i] == 32) {
- break;
- }
-
- name[index] = result_smc.data[i];
- index++;
- }
-
- return true;
-}
-
-
-int get_num_fans(void)
-{
- kern_return_t result;
- smc_return_t result_smc;
-
- result = read_smc(NUM_FANS, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 1 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_UINT8))) {
- // Error
- return -1;
- }
-
- return result_smc.data[0];
-}
-
-
-unsigned int get_fan_rpm(unsigned int fan_num)
-{
- char key[5];
- kern_return_t result;
- smc_return_t result_smc;
-
- sprintf(key, "F%dAc", fan_num);
- result = read_smc(key, &result_smc);
-
- if (!(result == kIOReturnSuccess &&
- result_smc.dataSize == 2 &&
- result_smc.dataType == to_uint32_t(DATA_TYPE_FPE2))) {
- // Error
- return 0;
- }
-
- return from_fpe2(result_smc.data);
-}
-
-
-bool set_fan_min_rpm(unsigned int fan_num, unsigned int rpm, bool auth)
-{
- // TODO: Add rpm val safety check
- char key[5];
- bool ans = false;
- kern_return_t result;
- smc_return_t result_smc;
-
- memset(&result_smc, 0, sizeof(smc_return_t));
-
- // TODO: Don't use magic number
- result_smc.dataSize = 2;
- result_smc.dataType = to_uint32_t(DATA_TYPE_FPE2);
- to_fpe2(rpm, result_smc.data);
-
- sprintf(key, "F%dMn", fan_num);
- result = write_smc(key, &result_smc);
-
- if (result == kIOReturnSuccess && result_smc.kSMC == kSMCSuccess) {
- ans = true;
- }
-
- return ans;
-}
diff --git a/widgets/include/smc.h b/widgets/include/smc.h
deleted file mode 100644
index d837e11..0000000
--- a/widgets/include/smc.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Apple System Management Controller (SMC) API from user space for Intel based
- * Macs. Works by talking to the AppleSMC.kext (kernel extension), the driver
- * for the SMC.
- *
- * smc.h
- * libsmc
- *
- * Copyright (C) 2014 beltex <https://github.com/beltex>
- *
- * Based off of fork from:
- * osx-cpu-temp <https://github.com/lavoiesl/osx-cpu-temp>
- *
- * With credits to:
- *
- * Copyright (C) 2006 devnull
- * Apple System Management Control (SMC) Tool
- *
- * Copyright (C) 2006 Hendrik Holtmann
- * smcFanControl <https://github.com/hholtmann/smcFanControl>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <IOKit/IOKitLib.h>
-
-
-//------------------------------------------------------------------------------
-// MARK: MACROS
-//------------------------------------------------------------------------------
-
-
-/**
-SMC keys for temperature sensors - 4 byte multi-character constants
-
-Not applicable to all Mac's of course. In adition, the definition of the codes
-may not be 100% accurate necessarily. Finally, list is incomplete.
-
-Presumed letter translations:
-
-- T = Temperature (if first char)
-- C = CPU
-- G = GPU
-- P = Proximity
-- D = Diode
-- H = Heatsink
-
-Sources:
-
-- https://www.apple.com/downloads/dashboard/status/istatpro.html
-- https://github.com/hholtmann/smcFanControl
-- https://github.com/jedda/OSX-Monitoring-Tools
-- http://www.parhelia.ch/blog/statics/k3_keys.html
-*/
-#define AMBIENT_AIR_0 "TA0P"
-#define AMBIENT_AIR_1 "TA1P"
-#define CPU_0_DIODE "TC0D"
-#define CPU_0_HEATSINK "TC0H"
-#define CPU_0_PROXIMITY "TC0P"
-#define ENCLOSURE_BASE_0 "TB0T"
-#define ENCLOSURE_BASE_1 "TB1T"
-#define ENCLOSURE_BASE_2 "TB2T"
-#define ENCLOSURE_BASE_3 "TB3T"
-#define GPU_0_DIODE "TG0D"
-#define GPU_0_HEATSINK "TG0H"
-#define GPU_0_PROXIMITY "TG0P"
-#define HARD_DRIVE_BAY "TH0P"
-#define MEMORY_SLOT_0 "TM0S"
-#define MEMORY_SLOTS_PROXIMITY "TM0P"
-#define NORTHBRIDGE "TN0H"
-#define NORTHBRIDGE_DIODE "TN0D"
-#define NORTHBRIDGE_PROXIMITY "TN0P"
-#define THUNDERBOLT_0 "TI0P"
-#define THUNDERBOLT_1 "TI1P"
-#define WIRELESS_MODULE "TW0P"
-
-
-/**
-SMC keys for fans - 4 byte multi-character constants
-
-Number of fans on Macs vary of course, thus not all keys will be applicable.
-
-Presumed letter translations:
-
-- F = Fan
-- Ac = Acutal
-- Mn = Min
-- Mx = Max
-- Sf = Safe
-- Tg = Target
-
-Sources: See TMP SMC keys
-*/
-#define FAN_0 "F0Ac"
-#define FAN_0_MIN_RPM "F0Mn"
-#define FAN_0_MAX_RPM "F0Mx"
-#define FAN_0_SAFE_RPM "F0Sf"
-#define FAN_0_TARGET_RPM "F0Tg"
-#define FAN_1 "F1Ac"
-#define FAN_1_MIN_RPM "F1Mn"
-#define FAN_1_MAX_RPM "F1Mx"
-#define FAN_1_SAFE_RPM "F1Sf"
-#define FAN_1_TARGET_RPM "F1Tg"
-#define FAN_2 "F2Ac"
-#define FAN_2_MIN_RPM "F2Mn"
-#define FAN_2_MAX_RPM "F2Mx"
-#define FAN_2_SAFE_RPM "F2Sf"
-#define FAN_2_TARGET_RPM "F2Tg"
-#define NUM_FANS "FNum"
-#define FORCE_BITS "FS! "
-
-
-/**
-Misc SMC keys - 4 byte multi-character constants
-
-Sources: See TMP SMC keys
-*/
-#define BATT_PWR "BATP"
-#define NUM_KEYS "#KEY"
-#define ODD_FULL "MSDI"
-
-
-//------------------------------------------------------------------------------
-// MARK: TYPES
-//------------------------------------------------------------------------------
-
-
-typedef char fan_name_t[13];
-
-
-//------------------------------------------------------------------------------
-// MARK: ENUMS
-//------------------------------------------------------------------------------
-
-
-typedef enum {
- CELSIUS,
- FAHRENHEIT,
- KELVIN
-} tmp_unit_t;
-
-
-//------------------------------------------------------------------------------
-// MARK: PROTOTYPES
-//------------------------------------------------------------------------------
-
-
-/**
-Open a connection to the SMC
-
-:returns: kIOReturnSuccess on successful connection to the SMC.
-*/
-kern_return_t open_smc(void);
-
-
-/**
-Close connection to the SMC
-
-:returns: kIOReturnSuccess on successful close of connection to the SMC.
-*/
-kern_return_t close_smc(void);
-
-
-/**
-Check if an SMC key is valid. Useful for determining if a certain machine has
-particular sensor or fan for example.
-
-:param: key The SMC key to check. 4 byte multi-character constant. Must be 4
- characters in length.
-:returns: True if the key is found, false otherwise
-*/
-bool is_key_valid(char *key);
-
-
-/**
-Get the current temperature from a sensor
-
-:param: key The temperature sensor to read