diff --git a/LICENSE b/LICENSE index 6ea2861..e2aa83d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,20 @@ The MIT License (MIT) -Apple System Management Control (SMC) Tool -Copyright (C) 2006 devnull + Copyright (c) 2017 Sebastian Hildebrandt -Copyright (c) 2017 Sebastian Hildebrandt + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: -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 3 of the License, or -(at your option) any later version. + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. -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, see . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 77620a3..f946cb9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ OSX Temperature Sensor library for [node.js][nodejs-url] [![NPM Downloads][downloads-image]][downloads-url] [![Git Issues][issues-img]][issues-url] [![deps status][daviddm-img]][daviddm-url] - [![GPL license][license-img]][license-url] + [![MIT license][license-img]][license-url] ## Quick Start @@ -34,6 +34,7 @@ console.log(temperature); ### Latest Activity +- Version 1.0.6: reverted license to MIT - Version 1.0.5: changed license to GPL - Version 1.0.4: Add compatibility for Node 12 and fix deprecation warnings - Version 1.0.3: updated issue template @@ -94,27 +95,28 @@ All other trademarks are the property of their respective owners. ## License [![MIT license][license-img]][license-url] ->The [`GPL`][license-url] License (GPL) +>The [`MIT`][license-url] License (MIT) > >Copyright © 2017 Sebastian Hildebrandt, [+innovations](http://www.plus-innovations.com). > ->for Apple System Management Control (SMC) Tool ->Copyright © 2006 devnull -> - ->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 3 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, see . +>Permission is hereby granted, free of charge, to any person obtaining a copy +>of this software and associated documentation files (the "Software"), to deal +>in the Software without restriction, including without limitation the rights +>to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +>copies of the Software, and to permit persons to whom the Software is +>furnished to do so, subject to the following conditions: +> +>The above copyright notice and this permission notice shall be included in +>all copies or substantial portions of the Software. > +>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +>IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +>FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +>AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +>LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +>OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +>THE SOFTWARE. + >Further details see [LICENSE](LICENSE) file. @@ -124,7 +126,7 @@ All other trademarks are the property of their respective owners. [downloads-url]: https://npmjs.org/package/osx-temperature-sensor [license-url]: https://github.com/sebhildebrandt/osx-temperature-sensor/blob/master/LICENSE -[license-img]: https://img.shields.io/badge/license-GPL-blue.svg?style=flat-square +[license-img]: https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square [npmjs-license]: https://img.shields.io/npm/l/osx-temperature-sensor.svg?style=flat-square [changelog-url]: https://github.com/sebhildebrandt/osx-temperature-sensor/blob/master/CHANGELOG.md @@ -140,5 +142,5 @@ All other trademarks are the property of their respective owners. [systeminformation-npm-url]: https://npmjs.org/package/systeminformation [systeminformation-github-url]: https://github.com/sebhildebrandt/systeminformation -[smc-code-url]: https://github.com/mmarcon/node-smc +[smc-code-url]: https://github.com/pcafstockf/osx-temperature-sensor [osx-cpu-temp-url]: https://github.com/lavoiesl/osx-cpu-temp diff --git a/binding.gyp b/binding.gyp index ed12c73..584e75e 100644 --- a/binding.gyp +++ b/binding.gyp @@ -10,7 +10,7 @@ 'targets': [ { "target_name": "smc", - "sources": [ "lib/OSX/smc.h", "lib/OSX/smc.cc" ], + "sources": [ "lib/OSX/smc-read.h", "lib/OSX/smc-read.cc" ], "link_settings": { 'libraries': [ 'IOKit.framework' diff --git a/lib/OSX/smc-read.cc b/lib/OSX/smc-read.cc new file mode 100755 index 0000000..07acc6d --- /dev/null +++ b/lib/OSX/smc-read.cc @@ -0,0 +1,274 @@ +/* +Portions of this code Copyright (c) 2020 Frank Stock under the MIT License. +For details see the original code in the GitHub repo at https://github.com/pcafstockf/smc-reader +*/ + +#ifndef BUILDING_NODE_EXTENSION + #define BUILDING_NODE_EXTENSION +#endif +#include +#include + +#include "smc-read.h" +#include +#include +#include + +/** + * Most documentation on SMC keys are described in string format, even though the SMC itself considers keys to be 32 bit unsigned integers. + * This function translates from a null terminated "C" string to a 32 bit unsigned integer that the SMC will recognize. + */ +uint32_t stringToKey(const char* str) { + uint32_t tmp[2]; + strncpy((char*)&tmp, str, 4); // This is necessary because a char* may not be 4 byte aligned. + return ntohl(tmp[0]); +} + +/** + * Convert a SMC key to a human readable string. + * @see stringToKey + */ +void keyToString(uint32_t key, char* str) { + *((uint32_t*) str) = htonl(key); + str[4] = 0; +} + +// See header for documentation +IOReturn AppleSMCOpen(io_connect_t* conn) { + if (conn == NULL) + return kIOReturnInvalid; + io_iterator_t existing; + *conn = 0; + // Create a matching dictionary that specifies an IOService class match. + CFMutableDictionaryRef matching = IOServiceMatching("AppleSMC"); + // Look up registered IOService objects that match a matching dictionary. + IOReturn result = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &existing); + if (result != kIOReturnSuccess) + return result; + // Returns the next object in an iteration. + io_object_t service = IOIteratorNext(existing); + // Releases an object handle previously returned by IOKitLib. + IOObjectRelease(existing); + if (service == 0) + return kIOReturnNotFound; + // A request to create a connection to an IOService. + result = IOServiceOpen(service, mach_task_self(), 0, conn); + // Releases an object handle previously returned by IOKitLib. + IOObjectRelease(service); + return result; +} + +// See header for documentation +IOReturn AppleSMCClose(io_connect_t conn) { + // Close a connection to an IOService and destroy the connect handle. + return IOServiceClose(conn); +} + +// See header for documentation +IOReturn AppleSMCReadBuffer(io_connect_t conn, const char* key, uint32_t* dataType, SMCBytes_t buff, uint8_t* buffLen) { + SMCKeyData inputStructure; + SMCKeyData outputStructure; + + // We *probably* don't care that there is stale data on our stack, but I've found that the SMC_CMD_READ_KEYINFO command is looking at more than just 'key' and 'data8'. + memset(&inputStructure, 0, sizeof(SMCKeyData)); + memset(&outputStructure, 0, sizeof(SMCKeyData)); + + // Send a command to retrieve information about the key (specifically it's dataType and size). + inputStructure.key = stringToKey(key); + inputStructure.data8 = SMC_CMD_READ_KEYINFO; + size_t structureOutputSize = sizeof(SMCKeyData); + IOReturn result = IOConnectCallStructMethod(conn, KERNEL_INDEX_SMC, &inputStructure, sizeof(SMCKeyData), &outputStructure, &structureOutputSize); + if (result != kIOReturnSuccess) + return result; + if (dataType != NULL) + *dataType = outputStructure.keyInfo.dataType; + if (buffLen != NULL) + *buffLen = outputStructure.keyInfo.dataSize; + + // Send another command to retrieve the actual key value. + inputStructure.keyInfo.dataSize = outputStructure.keyInfo.dataSize; + inputStructure.data8 = SMC_CMD_READ_BYTES; + result = IOConnectCallStructMethod(conn, KERNEL_INDEX_SMC, &inputStructure, sizeof(SMCKeyData), &outputStructure, &structureOutputSize); + if (result != kIOReturnSuccess) + return result; + + // Copy the key value into the buffer supplied by our caller. + memcpy(buff, outputStructure.bytes, sizeof(outputStructure.bytes)); + + return kIOReturnSuccess; +} + +// See header for documentation +float ToSMCFloat(uint32_t dataType, uint16_t value) { + float result = value; + switch (dataType) { + case DATATYPE_FP1F_KEY: + result /= 32768.0f; + break; + case DATATYPE_FP4C_KEY: + result /= 4096.0f; + break; + case DATATYPE_FP5B_KEY: + result /= 2048.0f; + break; + case DATATYPE_FP6A_KEY: + result /= 1024.0f; + break; + case DATATYPE_FP79_KEY: + result /= 512.0f; + break; + case DATATYPE_FP88_KEY: + result /= 256.0f; + break; + case DATATYPE_FPA6_KEY: + result /= 64.0f; + break; + case DATATYPE_FPC4_KEY: + result /= 16.0f; + break; + case DATATYPE_FPE2_KEY: + result /= 4.0f; + break; + + case DATATYPE_SP1E_KEY: + result /= 16384.0f; + break; + case DATATYPE_SP3C_KEY: + result /= 4096.0f; + break; + case DATATYPE_SP4B_KEY: + result /= 2048.0f; + break; + case DATATYPE_SP5A_KEY: + result /= 1024.0f; + break; + case DATATYPE_SP69_KEY: + result /= 512.0f; + break; + case DATATYPE_SP78_KEY: + result /= 256.0f; + break; + case DATATYPE_SP87_KEY: + result /= 128.0f; + break; + case DATATYPE_SP96_KEY: + result /= 64.0f; + break; + case DATATYPE_SPB4_KEY: + result /= 16.0f; + break; + case DATATYPE_SPF0_KEY: + // is / 1.0; + break; + + case DATATYPE_PWM_KEY: + result /= 655.36f; + break; + + default: + // Oops! + result = NAN; + } + return result; +} + +// See header for documentation +double ToSMCNumber(uint32_t dataType, const SMCBytes_t buf, uint8_t bufLen) { + switch (dataType) { + case DATATYPE_HEX_KEY: + // Hex keys vary in length, but 1,2,4,8 are just numbers. + switch (bufLen) { + case 1: + return *((uint8_t*) buf); + case 2: + return ntohs(*((uint16_t*) buf)); + case 4: + return ntohl(*((uint32_t*) buf)); + default: + return NAN; + } + case DATATYPE_UINT8_KEY: + case DATATYPE_FLAG_KEY: + if (bufLen != 1) + return NAN; + return *((uint8_t*) buf); + case DATATYPE_SI8_KEY: + if (bufLen != 1) + return NAN; + return *((int8_t*) buf); + case DATATYPE_UINT16_KEY: + if (bufLen != 2) + return NAN; + return ntohs(*((uint16_t*) buf)); + case DATATYPE_SI16_KEY: + if (bufLen != 2) + return NAN; + return ntohs(*((int16_t*) buf)); + case DATATYPE_UINT32_KEY: + if (bufLen != 4) + return NAN; + return ntohl(*((uint32_t*) buf)); + default: + return ToSMCFloat(dataType, ntohs(*((uint16_t*) buf))); + } +} + +// See header for documentation +IOReturn AppleSMCReadNumber(io_connect_t conn, const char* key, double* value) { + SMCBytes_t buf; + uint8_t bufLen; + uint32_t dataType; + // Read the key into a buffer + IOReturn result = AppleSMCReadBuffer(conn, key, &dataType, buf, &bufLen); + if (result != kIOReturnSuccess) + return result; + if (value != NULL) + *value = ToSMCNumber(dataType, buf, bufLen); + return kIOReturnSuccess; +} + +using namespace v8; + +void Get(const FunctionCallbackInfo& args) { + Isolate* isolate = Isolate::GetCurrent(); + Local context = isolate->GetCurrentContext(); + HandleScope scope(isolate); + io_connect_t conn; + + if (args.Length() < 1) { + args.GetReturnValue().Set(Undefined(isolate)); + return; + } + if (!args[0]->IsString()) { + isolate->ThrowException(Exception::TypeError( + String::NewFromUtf8(isolate, "Expected string", NewStringType::kNormal) + .ToLocalChecked()) + ); + return; + } + v8::String::Utf8Value k(isolate, args[0]->ToString(context).ToLocalChecked()); + char *key = *k; + + IOReturn ioResult = AppleSMCOpen(&conn); + if (ioResult != kIOReturnSuccess) { + isolate->ThrowException(Exception::Error( + String::NewFromUtf8(isolate, "Unavailable", NewStringType::kNormal) + .ToLocalChecked()) + ); + return; + } + + double value; + ioResult = AppleSMCReadNumber(conn, key, &value); + if (ioResult != kIOReturnSuccess) + value = 0.0; + AppleSMCClose(conn); + + args.GetReturnValue().Set(Number::New(isolate, value)); +} + +void Init(v8::Local exports) { + NODE_SET_METHOD(exports, "get", Get); +} + +NODE_MODULE(smc, Init) diff --git a/lib/OSX/smc-read.h b/lib/OSX/smc-read.h new file mode 100755 index 0000000..5d5694f --- /dev/null +++ b/lib/OSX/smc-read.h @@ -0,0 +1,135 @@ +#pragma once +/* +Portions of this code Copyright (c) 2020 Frank Stock under the MIT License. +For details see the original code in the GitHub repo at https://github.com/pcafstockf/smc-reader +*/ + +#ifndef SMC_READER_H +#define SMC_READER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// SMC data types are described in human readable string format, even though the SMC itself considers types to be 32 bit unsigned integers. +// Comparing two numbers is a *lot* faster than converting to a string and doing calling strcmp, so this library works with integers. +#define DATATYPE_FP1F_KEY 0x66703166 // "fp1f" +#define DATATYPE_FP4C_KEY 0x66703463 // "fp4c" +#define DATATYPE_FP5B_KEY 0x66703562 // "fp5b" +#define DATATYPE_FP6A_KEY 0x66703661 // "fp6a" +#define DATATYPE_FP79_KEY 0x66703739 // "fp79" +#define DATATYPE_FP88_KEY 0x66703838 // "fp88" +#define DATATYPE_FPA6_KEY 0x66706136 // "fpa6" +#define DATATYPE_FPC4_KEY 0x66706334 // "fpc4" +#define DATATYPE_FPE2_KEY 0x66706532 // "fpe2" + +#define DATATYPE_SP1E_KEY 0x73703165 // "sp1e" +#define DATATYPE_SP3C_KEY 0x73703363 // "sp3c" +#define DATATYPE_SP4B_KEY 0x73703462 // "sp4b" +#define DATATYPE_SP5A_KEY 0x73703561 // "sp5a" +#define DATATYPE_SP69_KEY 0x73703639 // "sp69" +#define DATATYPE_SP78_KEY 0x73703738 // "sp78" +#define DATATYPE_SP87_KEY 0x73703837 // "sp87" +#define DATATYPE_SP96_KEY 0x73703936 // "sp96" +#define DATATYPE_SPB4_KEY 0x73706234 // "spb4" +#define DATATYPE_SPF0_KEY 0x73706630 // "spf0" + +#define DATATYPE_UINT8_KEY 0x75693820 // "ui8 " +#define DATATYPE_UINT16_KEY 0x75693136 // "ui16" +#define DATATYPE_UINT32_KEY 0x75693332 // "ui32" + +#define DATATYPE_SI8_KEY 0x73693820 // "si8 " +#define DATATYPE_SI16_KEY 0x73693136 // "si16" + +#define DATATYPE_PWM_KEY 0x7B70776D // "{pwm" +#define DATATYPE_FLAG_KEY 0x666C6167 // "flag" +#define DATATYPE_HEX_KEY 0x6865785F // "hex_" + +uint32_t stringToKey(const char* str); + +void keyToString(uint32_t key, char* str); + +// Some useful constants for talking to the SMC +#define KERNEL_INDEX_SMC 2 +#define SMC_CMD_READ_BYTES 5 +#define SMC_CMD_READ_INDEX 8 +#define SMC_CMD_READ_KEYINFO 9 + +// For purposes of this library, we have a 32 byte buffer for exchanging command specific data with the SMC. +typedef uint8_t SMCBytes_t[32]; + +// Declare the memory layout of data exchanged with the SMC +typedef struct { + uint8_t major; + uint8_t minor; + uint8_t build; + uint8_t reserved[1]; + uint16_t release; +} SMCKeyDataVers; + +typedef struct { + uint16_t version; + uint16_t length; + uint32_t cpuPLimit; + uint32_t gpuPLimit; + uint32_t memPLimit; +} SMCKeyDataLimits; + +// This declares the meta info about a key. +typedef struct { + uint32_t dataSize; + uint32_t dataType; + uint8_t dataAttributes; +} SMCKeyMetaData; + +typedef struct { + uint32_t key; + SMCKeyDataVers vers; + SMCKeyDataLimits limitData; + SMCKeyMetaData keyInfo; + uint8_t result; + uint8_t status; + uint8_t data8; + uint32_t data32; + SMCBytes_t bytes; +} SMCKeyData; + +/** + * Code using I/O Kit usually follows the same pattern: + * Find the service (usually via IOServiceGetMatchingServices) + * Open a connection to the service with IOServiceOpen + * Send some message to the service and get the result using one of the IOConnectCall*** functions. + * Close the service with IOServiceClose + * This function performs the first two steps and if successful initializes the connection reference. + * + * @param conn Reference to a connection handle used to communicate with the SMC. This value is undefined if the connection was not opened successfully. + * @return kIOReturnSuccess if the connection was opened successfully, some other error if not. + */ +IOReturn AppleSMCOpen(io_connect_t* conn); + +/** + * Read the numeric value of a key from the SMC. + * + * @param conn Reference to the connection handle obtained from @see AppleSMCOpen + * @param key A human readable string describing the key (such as "PC0C" for CPU Core power in watts). + * @param value The current value of 'key'. This value is undefined if the function returns does not return kIOReturnSuccess. + * @return kIOReturnSuccess if the value was read successfully, some other error if not. + */ +IOReturn AppleSMCReadNumber(io_connect_t conn, const char* key, double* value); + +/** + * Closes the connection handle obtained previously from @see AppleSMCOpen + * + * @param conn Reference to the connection handle obtained from @see AppleSMCOpen + * @return kIOReturnSuccess if the connection was closed successfully, some other error if not. + */ +IOReturn AppleSMCClose(io_connect_t conn); + +#ifdef __cplusplus +} +#endif + + +#endif //SMC_READER_H diff --git a/lib/OSX/smc.cc b/lib/OSX/smc.cc deleted file mode 100755 index 25fe35e..0000000 --- a/lib/OSX/smc.cc +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Apple System Management Control (SMC) Tool - * Copyright (C) 2006 devnull - * - * 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. - */ - -#ifndef BUILDING_NODE_EXTENSION - #define BUILDING_NODE_EXTENSION -#endif - -#include -#include -#include -#include -#include - -#include "smc.h" - -using namespace v8; - -static io_connect_t conn; - -UInt32 _strtoul(char *str, int size, int base) { - UInt32 total = 0; - int i; - - for (i = 0; i < size; i++) { - if (base == 16) - total += str[i] << (size - 1 - i) * 8; - else - total += (unsigned char) (str[i] << (size - 1 - i) * 8); - } - return total; -} - -float _strtof(char *str, int size, int e) { - float total = 0; - int i; - - for (i = 0; i < size; i++) { - if (i == (size - 1)) - total += (str[i] & 0xff) >> e; - else - total += str[i] << (size - 1 - i) * (8 - e); - } - - return total; -} - -void _ultostr(char *str, UInt32 val) { - str[0] = '\0'; - sprintf(str, "%c%c%c%c", - (unsigned int) val >> 24, - (unsigned int) val >> 16, - (unsigned int) val >> 8, - (unsigned int) val); -} - -kern_return_t SMCOpen(void) { - kern_return_t result; - io_iterator_t iterator; - io_object_t device; - - CFMutableDictionaryRef matchingDictionary = IOServiceMatching("AppleSMC"); - result = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDictionary, &iterator); - if (result != kIOReturnSuccess) { - printf("Error: IOServiceGetMatchingServices() = %08x\n", result); - return 1; - } - - device = IOIteratorNext(iterator); - IOObjectRelease(iterator); - if (device == 0) { - printf("Error: no SMC found\n"); - return 1; - } - - result = IOServiceOpen(device, mach_task_self(), 0, &conn); - IOObjectRelease(device); - if (result != kIOReturnSuccess) { - printf("Error: IOServiceOpen() = %08x\n", result); - return 1; - } - - return kIOReturnSuccess; -} - -kern_return_t SMCClose() { - return IOServiceClose(conn); -} - - -kern_return_t SMCCall(int index, SMCKeyData_t *inputStructure, SMCKeyData_t *outputStructure) { - size_t structureInputSize; - size_t structureOutputSize; - - structureInputSize = sizeof(SMCKeyData_t); - structureOutputSize = sizeof(SMCKeyData_t); - - #if MAC_OS_X_VERSION_10_5 - return IOConnectCallStructMethod( conn, index, - // inputStructure - inputStructure, structureInputSize, - // ouputStructure - outputStructure, &structureOutputSize ); - #else - return IOConnectMethodStructureIStructureO( conn, index, - structureInputSize, /* structureInputSize */ - &structureOutputSize, /* structureOutputSize */ - inputStructure, /* inputStructure */ - outputStructure); /* ouputStructure */ - #endif - -} - -kern_return_t SMCReadKey(UInt32Char_t key, SMCVal_t *val) { - kern_return_t result; - SMCKeyData_t inputStructure; - SMCKeyData_t outputStructure; - - memset(&inputStructure, 0, sizeof(SMCKeyData_t)); - memset(&outputStructure, 0, sizeof(SMCKeyData_t)); - memset(val, 0, sizeof(SMCVal_t)); - - inputStructure.key = _strtoul(key, 4, 16); - inputStructure.data8 = SMC_CMD_READ_KEYINFO; - - result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); - if (result != kIOReturnSuccess) - return result; - - val->dataSize = outputStructure.keyInfo.dataSize; - _ultostr(val->dataType, outputStructure.keyInfo.dataType); - inputStructure.keyInfo.dataSize = val->dataSize; - inputStructure.data8 = SMC_CMD_READ_BYTES; - - result = SMCCall(KERNEL_INDEX_SMC, &inputStructure, &outputStructure); - if (result != kIOReturnSuccess) - return result; - - memcpy(val->bytes, outputStructure.bytes, sizeof(outputStructure.bytes)); - - return kIOReturnSuccess; -} - -double SMCGet(UInt32Char_t key) { - SMCVal_t val; - kern_return_t result; - - result = SMCReadKey((char*) key, &val); - if (result == kIOReturnSuccess) { - // read succeeded - check returned value - if (val.dataSize > 0) { - if (strcmp(val.dataType, DATATYPE_SP78) == 0) { - // convert sp78 value to temperature - int intValue = val.bytes[0] * 256 + (unsigned char)val.bytes[1]; - return intValue / 256.0; - } - if (strcmp(val.dataType, DATATYPE_UINT8) == 0) { - int intValue = _strtoul((char *)val.bytes, val.dataSize, 10); - return intValue; - } - if (strcmp(val.dataType, DATATYPE_FPE2) == 0) { - int intValue = _strtof(val.bytes, val.dataSize, 2); - return intValue; - } - } - } - // read failed - return 0.0; -} - -void Get(const FunctionCallbackInfo& args) { - Isolate* isolate = Isolate::GetCurrent(); - Local context = isolate->GetCurrentContext(); - HandleScope scope(isolate); - SMCOpen(); - if (args.Length() < 1) { - args.GetReturnValue().Set(Undefined(isolate)); - return; - } - if (!args[0]->IsString()) { - isolate->ThrowException(Exception::TypeError( - String::NewFromUtf8(isolate, "Expected string", NewStringType::kNormal) - .ToLocalChecked())); - return; - } - v8::String::Utf8Value k( - isolate, args[0]->ToString(context).ToLocalChecked()); - char *key = *k; - double value = SMCGet(key); - SMCClose(); - args.GetReturnValue().Set(Number::New(isolate, value)); -} - -void Init(v8::Local exports) { - NODE_SET_METHOD(exports, "get", Get); -} - -NODE_MODULE(smc, Init) diff --git a/lib/OSX/smc.h b/lib/OSX/smc.h deleted file mode 100755 index 21d2fcf..0000000 --- a/lib/OSX/smc.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Apple System Management Control (SMC) Tool - * Copyright (C) 2006 devnull - * - * 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. - */ - -#ifndef __SMC_H__ -#define __SMC_H__ -#endif - -#define VERSION "0.02" - -#define KERNEL_INDEX_SMC 2 - -#define SMC_CMD_READ_BYTES 5 -#define SMC_CMD_WRITE_BYTES 6 -#define SMC_CMD_READ_INDEX 8 -#define SMC_CMD_READ_KEYINFO 9 -#define SMC_CMD_READ_PLIMIT 11 -#define SMC_CMD_READ_VERS 12 - -#define DATATYPE_FPE2 "fpe2" -#define DATATYPE_UINT8 "ui8 " -#define DATATYPE_UINT16 "ui16" -#define DATATYPE_UINT32 "ui32" -#define DATATYPE_SP78 "sp78" - -typedef struct { - char major; - char minor; - char build; - char reserved[1]; - UInt16 release; -} SMCKeyData_vers_t; - -typedef struct { - UInt16 version; - UInt16 length; - UInt32 cpuPLimit; - UInt32 gpuPLimit; - UInt32 memPLimit; -} SMCKeyData_pLimitData_t; - -typedef struct { - UInt32 dataSize; - UInt32 dataType; - char dataAttributes; -} SMCKeyData_keyInfo_t; - -typedef char SMCBytes_t[32]; - -typedef struct { - UInt32 key; - SMCKeyData_vers_t vers; - SMCKeyData_pLimitData_t pLimitData; - SMCKeyData_keyInfo_t keyInfo; - char result; - char status; - char data8; - UInt32 data32; - SMCBytes_t bytes; -} SMCKeyData_t; - -typedef char UInt32Char_t[5]; - -typedef struct { - UInt32Char_t key; - UInt32 dataSize; - UInt32Char_t dataType; - SMCBytes_t bytes; -} SMCVal_t; diff --git a/package.json b/package.json index 5dcdd13..5700f07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "osx-temperature-sensor", - "version": "1.0.5", + "version": "1.0.6", "description": "OSX temperature sensor", "license": "MIT", "main": "./lib/index.js",