summaryrefslogtreecommitdiffstats
path: root/src/fan/cmpiLinux_FanProvider.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fan/cmpiLinux_FanProvider.c')
-rw-r--r--src/fan/cmpiLinux_FanProvider.c498
1 files changed, 498 insertions, 0 deletions
diff --git a/src/fan/cmpiLinux_FanProvider.c b/src/fan/cmpiLinux_FanProvider.c
new file mode 100644
index 0000000..67a1a82
--- /dev/null
+++ b/src/fan/cmpiLinux_FanProvider.c
@@ -0,0 +1,498 @@
+/* This file is part of cmpiLinux_FanProvider.
+ *
+ * cmpiLinux_FanProvider 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.
+ *
+ * cmpiLinux_FanProvider 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 cmpiLinux_FanProvider. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <strings.h>
+#include <errno.h>
+
+#include <cmpi/cmpidt.h>
+#include <cmpi/cmpift.h>
+#include <cmpi/cmpimacs.h>
+#include <sblim/OSBase_Common.h>
+#include <sblim/cmpiOSBase_Common.h>
+
+#include "cmpiLinux_Fan.h"
+
+#define UNUSED(x) ((void) (x))
+static const CMPIBroker * _broker;
+
+#ifdef CMPI_VER_100
+ #define Linux_FanProviderSetInstance Linux_FanProviderModifyInstance
+#endif
+
+// utilities ******************************************************************
+static bool data_2_uint64_t(CMPIData const * data, uint64_t *res) {
+ if (data->state != CMPI_goodValue) return false;
+ switch (data->type) {
+ case CMPI_string:
+ errno = 0;
+ *res = strtoull(CMGetCharPtr(data->value.string), NULL, 10);
+ if (errno) return false;
+ break;
+ case CMPI_sint32: *res = (uint64_t) data->value.sint32; break;
+ case CMPI_uint32: *res = (uint64_t) data->value.uint32; break;
+ case CMPI_sint64: *res = (uint64_t) data->value.sint64; break;
+ default: return false;
+ }
+ return true;
+}
+
+/* ---------------------------------------------------------------------------*/
+/* Instance Provider Interface */
+/* ---------------------------------------------------------------------------*/
+
+
+CMPIStatus Linux_FanProviderCleanup( CMPIInstanceMI * mi,
+ const CMPIContext * ctx, CMPIBoolean terminate) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(terminate);
+
+ _OSBASE_TRACE(1,("--- %s CMPI Cleanup() called",_ClassName));
+ cleanup_linux_fan_module();
+ _OSBASE_TRACE(1,("--- %s CMPI Cleanup() exited",_ClassName));
+ CMReturn(CMPI_RC_OK);
+}
+
+CMPIStatus Linux_FanProviderEnumInstanceNames( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * ref) {
+ UNUSED(mi);
+
+ CMPIObjectPath * op = NULL;
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+ struct fanlist * lptr = NULL;
+ struct fanlist * rm = NULL;
+
+ _OSBASE_TRACE(1,("--- %s CMPI EnumInstanceNames() called",_ClassName));
+
+ if (enum_all_fans(&lptr) != 0 ) {
+ CMSetStatusWithChars( _broker, &rc,
+ CMPI_RC_ERR_FAILED, "Could not list get fan list." );
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstanceNames() failed : %s",
+ _ClassName,CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ // iterate fan list
+ for (rm = lptr; lptr && rc.rc == CMPI_RC_OK ; lptr = lptr->next) {
+ // method call to create the CMPIInstance object
+ op = _makePath_Fan(_broker, ctx, ref, lptr->f, &rc);
+ if (op == NULL || rc.rc != CMPI_RC_OK) {
+ if (rc.msg != NULL) {
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstanceNames() failed"
+ ": %s", _ClassName, CMGetCharPtr(rc.msg)));
+ }
+ CMSetStatusWithChars(_broker, &rc, CMPI_RC_ERR_FAILED,
+ "Transformation from internal structure to CIM"
+ " ObjectPath failed.");
+ if (rm) free_fanlist(rm);
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstanceNames() failed"
+ ": %s", _ClassName, CMGetCharPtr(rc.msg)));
+ return rc;
+ }else {
+ CMReturnObjectPath(rslt, op);
+ }
+ }
+ if (rm) free_fanlist(rm);
+
+ CMReturnDone(rslt);
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstanceNames() exited", _ClassName));
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderEnumInstances( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * ref,
+ const char ** properties) {
+ UNUSED(mi);
+
+ CMPIInstance * ci = NULL;
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+ struct fanlist * lptr = NULL;
+ struct fanlist * rm = NULL;
+
+ _OSBASE_TRACE(1,("--- %s CMPI EnumInstances() called",_ClassName));
+
+ if (enum_all_fans(&lptr)) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, "Could not list fans.");
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstances() failed : %s",
+ _ClassName,CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ // iterate fan list
+ for (rm=lptr; lptr && rc.rc == CMPI_RC_OK; lptr = lptr->next) {
+ // method call to create the CMPIInstance object
+ ci = _makeInst_Fan(_broker, ctx, ref, properties, lptr->f, &rc);
+ if (ci == NULL || rc.rc != CMPI_RC_OK ) {
+ if (rc.msg != NULL ) {
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstances() failed :"
+ " %s",_ClassName,CMGetCharPtr(rc.msg)));
+ }
+ CMSetStatusWithChars( _broker, &rc,
+ CMPI_RC_ERR_FAILED, "Transformation from internal"
+ " structure to CIM Instance failed.");
+ if (rm) free_fanlist(rm);
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstances() failed :"
+ " %s", _ClassName,CMGetCharPtr(rc.msg)));
+ return rc;
+ }else {
+ CMReturnInstance(rslt, ci);
+ }
+ }
+ if (rm) free_fanlist(rm);
+
+ CMReturnDone(rslt);
+ _OSBASE_TRACE(1, ("--- %s CMPI EnumInstances() exited", _ClassName));
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderGetInstance( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * cop,
+ const char **properties) {
+ UNUSED(mi);
+
+ CMPIInstance * ci = NULL;
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+ struct cim_fan * sptr = NULL;
+ CMPIData data;
+ CMPIArray * other_identifying_info = NULL;
+ CMPIString * sys_path = NULL;
+ CMPIString * fan_name = NULL;
+ CMPIString * device_id = NULL;
+ cim_fan_error_t cmdrc;
+
+ _OSBASE_TRACE(1,("--- %s CMPI GetInstance() called",_ClassName));
+
+ _check_system_key_value_pairs(_broker, cop, "SystemCreationClassName",
+ "SystemName", &rc);
+ if (rc.rc != CMPI_RC_OK) {
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ data = CMGetKey(cop, "OtherIdentifyingInfo", &rc);
+ if ( !rc.rc
+ && data.type == CMPI_stringA
+ && (other_identifying_info = data.value.array)
+ && !rc.rc
+ && (CMGetArrayCount(other_identifying_info, &rc) > 1)
+ && !rc.rc)
+ {
+ data = CMGetArrayElementAt(other_identifying_info, 0, &rc);
+ if (!rc.rc) sys_path = data.value.string;
+ data = CMGetArrayElementAt(other_identifying_info, 1, &rc);
+ if (!rc.rc) fan_name = data.value.string;
+ }
+ device_id = CMGetKey(cop, "DeviceID", &rc).value.string;
+ if ((sys_path == NULL || fan_name == NULL) && (device_id == NULL)) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, "Could not get fan ID." );
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ if (sys_path && fan_name) {
+ cmdrc = get_fan_data(CMGetCharPtr(sys_path), CMGetCharPtr(fan_name),
+ &sptr);
+ }
+ if ((cmdrc || !sptr) && device_id) {
+ cmdrc = get_fan_data_by_id(CMGetCharPtr(device_id), &sptr);
+ }
+ if (cmdrc || !sptr) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_NOT_FOUND, cim_fan_strerror(cmdrc));
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() exited : %s",
+ _ClassName,CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ ci = _makeInst_Fan(_broker, ctx, cop, properties, sptr, &rc);
+ if (sptr) free_fan(sptr);
+
+ if (ci == NULL) {
+ if (rc.msg != NULL) {
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ }else {
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() failed", _ClassName));
+ }
+ return rc;
+ }
+
+ CMReturnInstance(rslt, ci);
+ CMReturnDone(rslt);
+ _OSBASE_TRACE(1, ("--- %s CMPI GetInstance() exited", _ClassName));
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderCreateInstance( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * cop,
+ const CMPIInstance * ci) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(rslt); UNUSED(cop); UNUSED(ci);
+
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+
+ _OSBASE_TRACE(1, ("--- %s CMPI CreateInstance() called", _ClassName));
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED");
+ _OSBASE_TRACE(1, ("--- %s CMPI CreateInstance() exited", _ClassName));
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderSetInstance( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * cop,
+ const CMPIInstance * ci,
+ const char ** properties) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(rslt); UNUSED(properties);
+
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+ CMPIData data;
+ char const * device_id = NULL;
+ struct cim_fan * sptr;
+ cim_fan_prop_value_t cfpv;
+ cim_fan_error_t cmdrc;
+ char const * tmp = NULL;
+ char buf[200];
+
+ _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() called", _ClassName));
+
+ _check_system_key_value_pairs(_broker, cop, "SystemCreationClassName",
+ "SystemName", &rc);
+ if (rc.rc != CMPI_RC_OK) {
+ _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ data = CMGetKey(cop, "DeviceID", &rc);
+ if (data.value.string == NULL) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, "Could not get fan ID." );
+ _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ }
+ device_id = CMGetCharPtr(data.value.string);
+ if (device_id) {
+ cmdrc = get_fan_data_by_id(device_id, &sptr);
+ }
+ if (cmdrc || !sptr) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_NOT_FOUND, cim_fan_strerror(cmdrc));
+ _OSBASE_TRACE(1, ("--- %s CMPI SetInstance() exited : %s",
+ _ClassName,CMGetCharPtr(rc.msg)));
+ return rc;
+ }
+
+ data = CMGetProperty(ci, "MinSpeed", &rc);
+ if (!rc.rc && data.value.uint64 != (uint64_t) sptr->min_speed) {
+ tmp = "MinSpeed";
+ cfpv.min_speed = data.value.uint64;
+ cmdrc = set_fan_prop_by_id(device_id, CIM_FAN_MIN_SPEED, &cfpv);
+ }
+ data = CMGetProperty(ci , "MaxSpeed", &rc);
+ if (!cmdrc && !rc.rc && data.value.uint64 != (uint64_t) sptr->max_speed) {
+ tmp = "MaxSpeed";
+ cfpv.max_speed = data.value.uint64;
+ set_fan_prop_by_id(device_id, CIM_FAN_MAX_SPEED, &cfpv);
+ }
+ data = CMGetProperty(ci, "Divisor", &rc);
+ if (!cmdrc && !rc.rc && data.value.uint32 != sptr->divisor) {
+ tmp = "Divisor";
+ cfpv.divisor = data.value.uint32;
+ set_fan_prop_by_id(device_id, CIM_FAN_DIV, &cfpv);
+ }
+ data = CMGetProperty(ci, "Pulses", &rc);
+ if (!cmdrc && !rc.rc && data.value.uint32 != sptr->pulses) {
+ tmp = "Pulses";
+ cfpv.pulses = data.value.uint32;
+ set_fan_prop_by_id(device_id, CIM_FAN_PULSES, &cfpv);
+ }
+ data = CMGetProperty(ci, "Beep", &rc);
+ if (!cmdrc && !rc.rc && data.value.boolean != sptr->beep) {
+ tmp = "Beep";
+ cfpv.beep = data.value.uint32;
+ set_fan_prop_by_id(device_id, CIM_FAN_BEEP, &cfpv);
+ }
+
+ if (cmdrc) {
+ if (tmp && cmdrc == CIM_FAN_SEN_NO_ENTRY) {
+ snprintf(buf, 200,
+ "System interface for fan(name=\"%s\", chip=\"%s\") does not"
+ " provide a way to set \"%s\".", sptr->name, sptr->chip_name,
+ tmp);
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, buf);
+ }else {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, cim_fan_strerror(cmdrc))
+ }
+ _OSBASE_TRACE(2, ("--- %s CMPI SetInstance() exited : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ }else {
+ rc.rc = CMPI_RC_OK;
+ rc.msg = NULL;
+ }
+
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderDeleteInstance( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * cop) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(rslt); UNUSED(cop);
+
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+
+ _OSBASE_TRACE(1,("--- %s CMPI DeleteInstance() called",_ClassName));
+ CMSetStatusWithChars( _broker, &rc,
+ CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED" );
+ _OSBASE_TRACE(1,("--- %s CMPI DeleteInstance() exited",_ClassName));
+ return rc;
+}
+
+CMPIStatus Linux_FanProviderExecQuery( CMPIInstanceMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * ref,
+ const char * lang,
+ const char * query) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(rslt); UNUSED(ref); UNUSED(lang);
+ UNUSED(query);
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+
+ _OSBASE_TRACE(1,("--- %s CMPI ExecQuery() called",_ClassName));
+
+ CMSetStatusWithChars( _broker, &rc,
+ CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED" );
+
+ _OSBASE_TRACE(1,("--- %s CMPI ExecQuery() exited",_ClassName));
+ return rc;
+}
+
+
+/* ---------------------------------------------------------------------------*/
+/* Method Provider Interface */
+/* ---------------------------------------------------------------------------*/
+
+
+CMPIStatus Linux_FanProviderMethodCleanup( CMPIMethodMI * mi,
+ const CMPIContext * ctx, CMPIBoolean terminate) {
+ UNUSED(mi); UNUSED(ctx), UNUSED(terminate);
+ _OSBASE_TRACE(1,("--- %s CMPI MethodCleanup() called",_ClassName));
+ _OSBASE_TRACE(1,("--- %s CMPI MethodCleanup() exited",_ClassName));
+ CMReturn(CMPI_RC_OK);
+}
+
+CMPIStatus Linux_FanProviderInvokeMethod( CMPIMethodMI * mi,
+ const CMPIContext * ctx,
+ const CMPIResult * rslt,
+ const CMPIObjectPath * ref,
+ const char * methodName,
+ const CMPIArgs * in,
+ CMPIArgs * out) {
+ UNUSED(mi); UNUSED(ctx); UNUSED(in); UNUSED(out);
+
+ struct cim_fan * sptr = NULL;
+ CMPIString * device_id = NULL;
+ CMPIValue valrc;
+ CMPIData data;
+ CMPIString * class = NULL;
+ CMPIStatus rc = {CMPI_RC_OK, NULL};
+ uint64_t desired_speed;
+
+ _OSBASE_TRACE(1, ("--- %s CMPI InvokeMethod() called", _ClassName));
+
+ class = CMGetClassName(ref, &rc);
+
+ if ( strcasecmp(CMGetCharPtr(class), _ClassName) == 0
+ && strcasecmp(methodName, "setspeed") == 0 ) {
+ if (!(device_id = CMGetKey(ref, "DeviceID", &rc).value.string)) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, "Could not get fan ID." );
+ _OSBASE_TRACE(1, ("--- %s CMPI InvokeMethod() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ }else if (get_fan_data_by_id(CMGetCharPtr(device_id), &sptr) || !sptr) {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_NOT_FOUND, "No such Fan found.");
+ _OSBASE_TRACE(1, ("--- %s CMPI InvokeMethod() failed : %s",
+ _ClassName, CMGetCharPtr(rc.msg)));
+ }else {
+ char errbuf[100];
+ char const * errdscr;
+ data = CMGetArg(in, "DesiredSpeed", &rc);
+ if (data.state != CMPI_goodValue) {
+ switch (data.state) {
+ case CMPI_nullValue: errdscr = "null value"; break;
+ case CMPI_badValue: errdscr = "bad value"; break;
+ case CMPI_notFound: errdscr = "not found"; break;
+ default: errdscr = "unknown error";
+ }
+ snprintf(errbuf, 100, "Argument error: DesiredSpeed - %s", errdscr);
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_FAILED, errbuf);
+ }else if (!data_2_uint64_t(&data, &desired_speed)) {
+ CMSetStatusWithChars(_broker, &rc, CMPI_RC_ERR_FAILED,
+ "Argument error: DesiredSpeed must be of type uint64");
+ }else {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_NOT_SUPPORTED, "CIM_ERR_NOT_SUPPORTED");
+ }
+ }
+ }else {
+ CMSetStatusWithChars(_broker, &rc,
+ CMPI_RC_ERR_METHOD_NOT_AVAILABLE, methodName);
+ }
+
+ _OSBASE_TRACE(1, ("--- %s CMPI InvokeMethod() exited", _ClassName));
+ return rc;
+}
+
+/* ---------------------------------------------------------------------------*/
+/* Provider Factory */
+/* ---------------------------------------------------------------------------*/
+
+CMInstanceMIStub( Linux_FanProvider,
+ Linux_FanProvider,
+ _broker,
+ init_linux_fan_module());
+
+CMMethodMIStub( Linux_FanProvider,
+ Linux_FanProvider,
+ _broker,
+ init_linux_fan_module());
+
+/* ---------------------------------------------------------------------------*/
+/* end of cmpiLinux_FanProvider */
+/* ---------------------------------------------------------------------------*/
+