blob: 11bd53e0c49dcf0639c7d2e97e731cf5edb332cb [file] [log] [blame]
vishwabmcba0bd5f2015-09-30 16:50:23 +05301#include <stdio.h>
2#include <dlfcn.h>
3#include <iostream>
4#include <unistd.h>
5#include <assert.h>
6#include <dirent.h>
Chris Austen0ba649e2015-10-13 12:28:13 -05007#include <systemd/sd-bus.h>
vishwabmcba0bd5f2015-09-30 16:50:23 +05308#include <string.h>
9#include <stdlib.h>
10#include <map>
11#include "ipmid.H"
Chris Austen0ba649e2015-10-13 12:28:13 -050012#include <sys/time.h>
13#include <errno.h>
Chris Austen0012e9b2015-10-22 01:37:46 -050014#include "sensorhandler.h"
Chris Austen0ba649e2015-10-13 12:28:13 -050015
16
17sd_bus *bus = NULL;
Chris Austen41a4b312015-10-25 03:45:42 -050018FILE *ipmiio, *ipmidbus, *ipmicmddetails;
vishwabmcba0bd5f2015-09-30 16:50:23 +053019
20// Channel that is used for OpenBMC Barreleye
21const char * DBUS_NAME = "org.openbmc.HostIpmi";
22const char * OBJ_NAME = "/org/openbmc/HostIpmi/1";
23
Chris Austen0ba649e2015-10-13 12:28:13 -050024const char * FILTER = "type='signal',sender='org.openbmc.HostIpmi',member='ReceivedMessage'";
25
26
vishwabmcba0bd5f2015-09-30 16:50:23 +053027typedef std::pair<ipmi_netfn_t, ipmi_cmd_t> ipmi_fn_cmd_t;
28typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;
29
30// Global data structure that contains the IPMI command handler's registrations.
31std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;
32
Chris Austen0ba649e2015-10-13 12:28:13 -050033
34
35#ifndef HEXDUMP_COLS
36#define HEXDUMP_COLS 16
37#endif
38
39void hexdump(void *mem, size_t len)
40{
41 unsigned int i, j;
Chris Austen120f7322015-10-14 23:27:31 -050042
Chris Austen0ba649e2015-10-13 12:28:13 -050043 for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++)
44 {
45 /* print offset */
46 if(i % HEXDUMP_COLS == 0)
47 {
48 printf("0x%06x: ", i);
49 }
Chris Austen120f7322015-10-14 23:27:31 -050050
Chris Austen0ba649e2015-10-13 12:28:13 -050051 /* print hex data */
52 if(i < len)
53 {
54 printf("%02x ", 0xFF & ((char*)mem)[i]);
55 }
56 else /* end of block, just aligning for ASCII dump */
57 {
58 printf(" ");
59 }
Chris Austen120f7322015-10-14 23:27:31 -050060
Chris Austen0ba649e2015-10-13 12:28:13 -050061 /* print ASCII dump */
62 if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
63 {
64 for(j = i - (HEXDUMP_COLS - 1); j <= i; j++)
65 {
66 if(j >= len) /* end of block, not really printing */
67 {
68 putchar(' ');
69 }
70 else if(isprint(((char*)mem)[j])) /* printable char */
71 {
Chris Austen120f7322015-10-14 23:27:31 -050072 putchar(0xFF & ((char*)mem)[j]);
Chris Austen0ba649e2015-10-13 12:28:13 -050073 }
74 else /* other char */
75 {
76 putchar('.');
77 }
78 }
79 putchar('\n');
80 }
81 }
82}
83
84
vishwabmcba0bd5f2015-09-30 16:50:23 +053085// Method that gets called by shared libraries to get their command handlers registered
86void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
87 ipmi_context_t context, ipmid_callback_t handler)
88{
89 // Pack NetFn and Command in one.
90 auto netfn_and_cmd = std::make_pair(netfn, cmd);
91
92 // Pack Function handler and Data in another.
93 auto handler_and_context = std::make_pair(handler, context);
94
95 // Check if the registration has already been made..
96 auto iter = g_ipmid_router_map.find(netfn_and_cmd);
97 if(iter != g_ipmid_router_map.end())
98 {
99 fprintf(stderr,"ERROR : Duplicate registration for NetFn [0x%X], Cmd:[0x%X]\n",netfn, cmd);
100 }
101 else
102 {
103 // This is a fresh registration.. Add it to the map.
104 g_ipmid_router_map.emplace(netfn_and_cmd, handler_and_context);
105 }
106
107 return;
108}
109
110// Looks at the map and calls corresponding handler functions.
111ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
112 ipmi_response_t response, ipmi_data_len_t data_len)
113{
114 // return from the Command handlers.
115 ipmi_ret_t rc = IPMI_CC_INVALID;
116
117 // Walk the map that has the registered handlers and invoke the approprite
118 // handlers for matching commands.
119 auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd));
120 if(iter == g_ipmid_router_map.end())
121 {
122 printf("No registered handlers for NetFn:[0x%X], Cmd:[0x%X]"
123 " trying Wilcard implementation \n",netfn, cmd);
124
125 // Now that we did not find any specific [NetFn,Cmd], tuple, check for
126 // NetFn, WildCard command present.
127 iter = g_ipmid_router_map.find(std::make_pair(netfn, IPMI_CMD_WILDCARD));
128 if(iter == g_ipmid_router_map.end())
129 {
130 printf("No Registered handlers for NetFn:[0x%X],Cmd:[0x%X]\n",netfn, IPMI_CMD_WILDCARD);
131
132 // Respond with a 0xC1
133 memcpy(response, &rc, IPMI_CC_LEN);
134 *data_len = IPMI_CC_LEN;
135 return rc;
136 }
137 }
138
139#ifdef __IPMI_DEBUG__
140 // We have either a perfect match -OR- a wild card atleast,
141 printf("Calling Net function:[0x%X], Command:[0x%X]\n", netfn, cmd);
142#endif
143
144 // Extract the map data onto appropriate containers
145 auto handler_and_context = iter->second;
146
147 // Creating a pointer type casted to char* to make sure we advance 1 byte
148 // when we advance pointer to next's address. advancing void * would not
149 // make sense.
150 char *respo = &((char *)response)[IPMI_CC_LEN];
151
152 // Response message from the plugin goes into a byte post the base response
153 rc = (handler_and_context.first) (netfn, cmd, request, respo,
154 data_len, handler_and_context.second);
Chris Austen120f7322015-10-14 23:27:31 -0500155
vishwabmcba0bd5f2015-09-30 16:50:23 +0530156 // Now copy the return code that we got from handler and pack it in first
157 // byte.
158 memcpy(response, &rc, IPMI_CC_LEN);
Chris Austen120f7322015-10-14 23:27:31 -0500159
vishwabmcba0bd5f2015-09-30 16:50:23 +0530160 // Data length is now actual data + completion code.
161 *data_len = *data_len + IPMI_CC_LEN;
162
163 return rc;
164}
165
vishwabmcba0bd5f2015-09-30 16:50:23 +0530166
vishwabmcba0bd5f2015-09-30 16:50:23 +0530167
vishwabmcba0bd5f2015-09-30 16:50:23 +0530168
Chris Austen0ba649e2015-10-13 12:28:13 -0500169static int send_ipmi_message(unsigned char seq, unsigned char netfn, unsigned char cmd, unsigned char *buf, unsigned char len) {
vishwabmcba0bd5f2015-09-30 16:50:23 +0530170
Chris Austen0ba649e2015-10-13 12:28:13 -0500171 sd_bus_error error = SD_BUS_ERROR_NULL;
172 sd_bus_message *reply = NULL, *m=NULL;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530173
vishwabmcba0bd5f2015-09-30 16:50:23 +0530174
Chris Austen0ba649e2015-10-13 12:28:13 -0500175 const char *path;
176 int r, pty;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530177
vishwabmcba0bd5f2015-09-30 16:50:23 +0530178
Chris Austen0ba649e2015-10-13 12:28:13 -0500179 r = sd_bus_message_new_method_call(bus,&m,DBUS_NAME,OBJ_NAME,DBUS_NAME,"sendMessage");
180 if (r < 0) {
181 fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
182 return -1;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530183 }
184
vishwabmcba0bd5f2015-09-30 16:50:23 +0530185
Chris Austenabfb5e82015-10-13 12:29:24 -0500186 // Responses in IPMI require a bit set. So there ya go...
187 netfn |= 0x04;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530188
Chris Austen0ba649e2015-10-13 12:28:13 -0500189
190 // Add the bytes needed for the methods to be called
191 r = sd_bus_message_append(m, "yyy", seq, netfn, cmd);
192 if (r < 0) {
193 fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
194 return -1;
195 }
Chris Austen120f7322015-10-14 23:27:31 -0500196
Chris Austen0ba649e2015-10-13 12:28:13 -0500197 r = sd_bus_message_append_array(m, 'y', buf, len);
198 if (r < 0) {
199 fprintf(stderr, "Failed to add the string of response bytes: %s\n", strerror(-r));
200 return -1;
201 }
202
203
204
205 // Call the IPMI responder on the bus so the message can be sent to the CEC
206 r = sd_bus_call(bus, m, 0, &error, &reply);
207 if (r < 0) {
208 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
209 return -1;
210 }
211
212 r = sd_bus_message_read(reply, "x", &pty);
213#ifdef __IPMI_DEBUG__
214 printf("RC from the ipmi dbus method :%d \n", pty);
Chris Austen120f7322015-10-14 23:27:31 -0500215#endif
Chris Austen0ba649e2015-10-13 12:28:13 -0500216 if (r < 0) {
217 fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
218
219 }
220
221
222 sd_bus_error_free(&error);
223 sd_bus_message_unref(m);
224
225
226#ifdef __IPMI_DEBUG__
227 printf("%d : %s\n", __LINE__, __PRETTY_FUNCTION__ );
Chris Austen120f7322015-10-14 23:27:31 -0500228#endif
Chris Austen0ba649e2015-10-13 12:28:13 -0500229 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
230
231}
232
233static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
234 *ret_error) {
235 int r = 0;
236 const char *msg = NULL;
237 char sequence, netfn, cmd;
238 const void *request;
239 size_t sz;
240 size_t resplen =MAX_IPMI_BUFFER;
241 unsigned char response[MAX_IPMI_BUFFER];
242
243 printf(" *** Received Signal: ");
244
245 memset(response, 0, MAX_IPMI_BUFFER);
246
247 r = sd_bus_message_read(m, "yyy", &sequence, &netfn, &cmd);
248 if (r < 0) {
249 fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
250 return -1;
251 }
252
253 r = sd_bus_message_read_array(m, 'y', &request, &sz );
254 if (r < 0) {
255 fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
256 return -1;
257 }
258
259
260 printf("Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n", sequence, netfn, cmd);
261 hexdump((void*)request, sz);
262
Chris Austen120f7322015-10-14 23:27:31 -0500263 // Allow the length field to be used for both input and output of the
Chris Austen0ba649e2015-10-13 12:28:13 -0500264 // ipmi call
265 resplen = sz;
266
Chris Austen120f7322015-10-14 23:27:31 -0500267 // Now that we have parsed the entire byte array from the caller
vishwabmcba0bd5f2015-09-30 16:50:23 +0530268 // we can call the ipmi router to do the work...
Chris Austen0ba649e2015-10-13 12:28:13 -0500269 r = ipmi_netfn_router(netfn, cmd, (void *)request, (void *)response, &resplen);
270 if(r != 0)
vishwabmcba0bd5f2015-09-30 16:50:23 +0530271 {
Chris Austen0ba649e2015-10-13 12:28:13 -0500272 fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",r, netfn, cmd);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530273 }
274
Chris Austen0ba649e2015-10-13 12:28:13 -0500275 printf("Response...\n");
276 hexdump((void*)response, resplen);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530277
Chris Austen0ba649e2015-10-13 12:28:13 -0500278 // Send the response buffer from the ipmi command
279 r = send_ipmi_message(sequence, netfn, cmd, response, resplen);
280 if (r < 0) {
281 fprintf(stderr, "Failed to send the response message\n");
282 return -1;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530283 }
284
vishwabmcba0bd5f2015-09-30 16:50:23 +0530285
Chris Austen0ba649e2015-10-13 12:28:13 -0500286 return 0;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530287}
288
Chris Austen0ba649e2015-10-13 12:28:13 -0500289
vishwabmcba0bd5f2015-09-30 16:50:23 +0530290//----------------------------------------------------------------------
291// handler_select
292// Select all the files ending with with .so. in the given diretcory
293// @d: dirent structure containing the file name
294//----------------------------------------------------------------------
295int handler_select(const struct dirent *entry)
296{
297 // To hold ".so" from entry->d_name;
298 char dname_copy[4] = {0};
299
300 // We want to avoid checking for everything and isolate to the ones having
301 // .so in them.
302 if(strstr(entry->d_name, IPMI_PLUGIN_EXTN))
303 {
304 // It is possible that .so could be anywhere in the string but unlikely
Chris Austen120f7322015-10-14 23:27:31 -0500305 // But being careful here. Get the base address of the string, move
vishwabmcba0bd5f2015-09-30 16:50:23 +0530306 // until end and come back 3 steps and that gets what we need.
307 strcpy(dname_copy, (entry->d_name + strlen(entry->d_name)-strlen(IPMI_PLUGIN_EXTN)));
308 if(strcmp(dname_copy, IPMI_PLUGIN_EXTN) == 0)
309 {
310 return 1;
311 }
312 }
313 return 0;
314}
315
316// This will do a dlopen of every .so in ipmi_lib_path and will dlopen everything so that they will
Chris Austen120f7322015-10-14 23:27:31 -0500317// register a callback handler
vishwabmcba0bd5f2015-09-30 16:50:23 +0530318void ipmi_register_callback_handlers(const char* ipmi_lib_path)
319{
320 // For walking the ipmi_lib_path
321 struct dirent **handler_list;
322 int num_handlers = 0;
323
324 // This is used to check and abort if someone tries to register a bad one.
325 void *lib_handler = NULL;
326
327 if(ipmi_lib_path == NULL)
328 {
329 fprintf(stderr,"ERROR; No handlers to be registered for ipmi.. Aborting\n");
330 assert(0);
331 }
332 else
333 {
334 // 1: Open ipmi_lib_path. Its usually "/usr/lib/phosphor-host-ipmid"
335 // 2: Scan the directory for the files that end with .so
Chris Austen120f7322015-10-14 23:27:31 -0500336 // 3: For each one of them, just do a 'dlopen' so that they register
vishwabmcba0bd5f2015-09-30 16:50:23 +0530337 // the handlers for callback routines.
338
339 std::string handler_fqdn = ipmi_lib_path;
Chris Austen120f7322015-10-14 23:27:31 -0500340
vishwabmcba0bd5f2015-09-30 16:50:23 +0530341 // Append a "/" since we need to add the name of the .so. If there is
342 // already a .so, adding one more is not any harm.
343 handler_fqdn += "/";
344
345 num_handlers = scandir(ipmi_lib_path, &handler_list, handler_select, alphasort);
346 while(num_handlers--)
347 {
Chris Austen54030262015-10-13 12:30:46 -0500348 handler_fqdn = ipmi_lib_path;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530349 handler_fqdn += handler_list[num_handlers]->d_name;
Chris Austen54030262015-10-13 12:30:46 -0500350 printf("Registering handler:[%s]\n",handler_fqdn.c_str());
351
vishwabmcba0bd5f2015-09-30 16:50:23 +0530352 lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);
353 if(lib_handler == NULL)
354 {
Chris Austen120f7322015-10-14 23:27:31 -0500355 fprintf(stderr,"ERROR opening [%s]: %s\n",
356 handler_fqdn.c_str(), dlerror());
vishwabmcba0bd5f2015-09-30 16:50:23 +0530357 }
358 // Wipe the memory allocated for this particular entry.
359 free(handler_list[num_handlers]);
360 }
361 // Done with all registration.
362 free(handler_list);
363 }
364
365 // TODO : What to be done on the memory that is given by dlopen ?.
366 return;
367}
368
369int main(int argc, char *argv[])
370{
Chris Austen0ba649e2015-10-13 12:28:13 -0500371 sd_bus_slot *slot = NULL;
372 int r;
373 char *mode = NULL;
374
375
vishwabmcba0bd5f2015-09-30 16:50:23 +0530376 // Register all the handlers that provider implementation to IPMI commands.
377 ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);
378
379#ifdef __IPMI_DEBUG__
380 printf("Registered Function handlers:\n");
381
382 // Print the registered handlers and their arguments.
383 for(auto& iter : g_ipmid_router_map)
384 {
385 ipmi_fn_cmd_t fn_and_cmd = iter.first;
Chris Austen120f7322015-10-14 23:27:31 -0500386 printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530387 }
388#endif
vishwabmcba0bd5f2015-09-30 16:50:23 +0530389
vishwabmcba0bd5f2015-09-30 16:50:23 +0530390
Chris Austen0ba649e2015-10-13 12:28:13 -0500391 /* Connect to system bus */
392 r = sd_bus_open_system(&bus);
393 if (r < 0) {
394 fprintf(stderr, "Failed to connect to system bus: %s\n",
395 strerror(-r));
396 goto finish;
397 }
vishwabmcba0bd5f2015-09-30 16:50:23 +0530398
Chris Austen0ba649e2015-10-13 12:28:13 -0500399 r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL);
400 if (r < 0) {
401 fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);
402 goto finish;
403 }
vishwabmcba0bd5f2015-09-30 16:50:23 +0530404
vishwabmcba0bd5f2015-09-30 16:50:23 +0530405
Chris Austen0ba649e2015-10-13 12:28:13 -0500406 for (;;) {
407 /* Process requests */
408
409 r = sd_bus_process(bus, NULL);
410 if (r < 0) {
411 fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
412 goto finish;
413 }
414 if (r > 0) {
415 continue;
416 }
417
418 r = sd_bus_wait(bus, (uint64_t) - 1);
419 if (r < 0) {
420 fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
421 goto finish;
422 }
423 }
424
425finish:
426 sd_bus_slot_unref(slot);
427 sd_bus_unref(bus);
428 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
429
vishwabmcba0bd5f2015-09-30 16:50:23 +0530430}
Chris Austenb071c702015-10-15 00:00:09 -0500431
Chris Austen0012e9b2015-10-22 01:37:46 -0500432// Use a lookup table to find the interface name of a specific sensor
433// This will be used until an alternative is found. this is the first
434// step for mapping IPMI
435int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) {
Chris Austenb071c702015-10-15 00:00:09 -0500436
Chris Austen0012e9b2015-10-22 01:37:46 -0500437 char *str1, *str2, *str3;
438 sd_bus_error error = SD_BUS_ERROR_NULL;
439 sd_bus_message *reply = NULL, *m=NULL;
Chris Austenb071c702015-10-15 00:00:09 -0500440
441
Chris Austen0012e9b2015-10-22 01:37:46 -0500442 int r;
443
Chris Austen0012e9b2015-10-22 01:37:46 -0500444 r = sd_bus_message_new_method_call(bus,&m,interface->bus,interface->path,"org.freedesktop.DBus.Properties","Get");
445 if (r < 0) {
446 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
447 fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
448 interface->bus, interface->path, interface->interface);
449 }
450
451 r = sd_bus_message_append(m, "ss", "org.openbmc.InventoryItem", property_name);
452 if (r < 0) {
453 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
454 fprintf(stderr,"Bus: %s Path: %s Interface: %s \n",
455 interface->bus, interface->path, interface->interface);
456 }
457
458 r = sd_bus_call(bus, m, 0, &error, &reply);
459 if (r < 0) {
460 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
461 goto final;
462 }
463
464 r = sd_bus_message_read(reply, "v", "s", &str1) ;
465 if (r < 0) {
466 fprintf(stderr, "Failed to get a response: %s", strerror(-r));
467 goto final;
468 }
469
470 strcpy(property_value, str1);
471
472final:
473
474 sd_bus_error_free(&error);
475 sd_bus_message_unref(m);
476
477 return r;
478}
Chris Austenb071c702015-10-15 00:00:09 -0500479
Chris Austen41a4b312015-10-25 03:45:42 -0500480
Chris Austenb071c702015-10-15 00:00:09 -0500481// Use a lookup table to find the interface name of a specific sensor
482// This will be used until an alternative is found. this is the first
483// step for mapping IPMI
484int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) {
485
486 const char *busname = "org.openbmc.managers.System";
487 const char *objname = "/org/openbmc/managers/System";
488
489 char *str1, *str2, *str3;
490 sd_bus_error error = SD_BUS_ERROR_NULL;
491 sd_bus_message *reply = NULL, *m=NULL;
492
493
494 int r;
495
496 r = sd_bus_message_new_method_call(bus,&m,busname,objname,busname,"getObjectFromByteId");
497 if (r < 0) {
498 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
499 }
500
501 r = sd_bus_message_append(m, "sy", type, num);
502 if (r < 0) {
503 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
504 }
505
506 // Call the IPMI responder on the bus so the message can be sent to the CEC
507 r = sd_bus_call(bus, m, 0, &error, &reply);
508 if (r < 0) {
509 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
510 goto final;
511 }
512
513
514 r = sd_bus_message_read(reply, "(sss)", &str1, &str2, &str3);
515 if (r < 0) {
516 fprintf(stderr, "Failed to get a response: %s", strerror(-r));
517 goto final;
518 }
519
520 strncpy(interface->bus, str1, MAX_DBUS_PATH);
521 strncpy(interface->path, str2, MAX_DBUS_PATH);
522 strncpy(interface->interface, str3, MAX_DBUS_PATH);
523
524 interface->sensornumber = num;
525
Chris Austenb071c702015-10-15 00:00:09 -0500526final:
527
528 sd_bus_error_free(&error);
529 sd_bus_message_unref(m);
530
531 return r;
532}
533
534
535/////////////////////////////////////////////////////////////////////
536//
537// Routines used by ipmi commands wanting to interact on the dbus
538//
539/////////////////////////////////////////////////////////////////////
540
541
542// Simple set routine because some methods are standard.
543int set_sensor_dbus_state(uint8_t number, const char *method, const char *value) {
544
545
546 dbus_interface_t a;
547 int r;
548 sd_bus_error error = SD_BUS_ERROR_NULL;
549 sd_bus_message *reply = NULL, *m=NULL;
550
551 printf("Attempting to set a dbus Sensor 0x%02x via %s with a value of %s\n",
552 number, method, value);
553
554 r = find_openbmc_path("SENSOR", number, &a);
555
Chris Austenb071c702015-10-15 00:00:09 -0500556 r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
557 if (r < 0) {
558 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
559 }
560
561 r = sd_bus_message_append(m, "s", value);
562 if (r < 0) {
563 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
564 }
565
Chris Austenb071c702015-10-15 00:00:09 -0500566 r = sd_bus_call(bus, m, 0, &error, &reply);
567 if (r < 0) {
568 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
569 }
570
Chris Austenb071c702015-10-15 00:00:09 -0500571 sd_bus_error_free(&error);
572 sd_bus_message_unref(m);
573
574 return 0;
Chris Austenb071c702015-10-15 00:00:09 -0500575}
Chris Austen0130d6e2015-10-15 22:32:36 -0500576
577int set_sensor_dbus_state_v(uint8_t number, const char *method, char *value) {
578
579
580 dbus_interface_t a;
581 int r;
582 sd_bus_error error = SD_BUS_ERROR_NULL;
583 sd_bus_message *reply = NULL, *m=NULL;
584
585 printf("Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of %s\n",
586 number, method, value);
587
588 r = find_openbmc_path("SENSOR", number, &a);
589
Chris Austen0130d6e2015-10-15 22:32:36 -0500590 r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
591 if (r < 0) {
592 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
593 }
594
595 r = sd_bus_message_append(m, "v", "s", value);
596 if (r < 0) {
597 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
598 }
599
600
Chris Austen0130d6e2015-10-15 22:32:36 -0500601 r = sd_bus_call(bus, m, 0, &error, NULL);
602 if (r < 0) {
603 fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
604 }
605
606
Chris Austen0130d6e2015-10-15 22:32:36 -0500607 sd_bus_error_free(&error);
608 sd_bus_message_unref(m);
609
610 return 0;
611}