blob: 6514849e161d370a64509fd5090622bf2a9f8d21 [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;
vishwabmcba0bd5f2015-09-30 16:50:23 +053018
19// Channel that is used for OpenBMC Barreleye
20const char * DBUS_NAME = "org.openbmc.HostIpmi";
21const char * OBJ_NAME = "/org/openbmc/HostIpmi/1";
22
Chris Austen0ba649e2015-10-13 12:28:13 -050023const char * FILTER = "type='signal',sender='org.openbmc.HostIpmi',member='ReceivedMessage'";
24
25
vishwabmcba0bd5f2015-09-30 16:50:23 +053026typedef std::pair<ipmi_netfn_t, ipmi_cmd_t> ipmi_fn_cmd_t;
27typedef std::pair<ipmid_callback_t, ipmi_context_t> ipmi_fn_context_t;
28
29// Global data structure that contains the IPMI command handler's registrations.
30std::map<ipmi_fn_cmd_t, ipmi_fn_context_t> g_ipmid_router_map;
31
Chris Austen0ba649e2015-10-13 12:28:13 -050032
33
34#ifndef HEXDUMP_COLS
35#define HEXDUMP_COLS 16
36#endif
37
38void hexdump(void *mem, size_t len)
39{
40 unsigned int i, j;
Chris Austen120f7322015-10-14 23:27:31 -050041
Chris Austen0ba649e2015-10-13 12:28:13 -050042 for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++)
43 {
44 /* print offset */
45 if(i % HEXDUMP_COLS == 0)
46 {
47 printf("0x%06x: ", i);
48 }
Chris Austen120f7322015-10-14 23:27:31 -050049
Chris Austen0ba649e2015-10-13 12:28:13 -050050 /* print hex data */
51 if(i < len)
52 {
53 printf("%02x ", 0xFF & ((char*)mem)[i]);
54 }
55 else /* end of block, just aligning for ASCII dump */
56 {
57 printf(" ");
58 }
Chris Austen120f7322015-10-14 23:27:31 -050059
Chris Austen0ba649e2015-10-13 12:28:13 -050060 /* print ASCII dump */
61 if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1))
62 {
63 for(j = i - (HEXDUMP_COLS - 1); j <= i; j++)
64 {
65 if(j >= len) /* end of block, not really printing */
66 {
67 putchar(' ');
68 }
69 else if(isprint(((char*)mem)[j])) /* printable char */
70 {
Chris Austen120f7322015-10-14 23:27:31 -050071 putchar(0xFF & ((char*)mem)[j]);
Chris Austen0ba649e2015-10-13 12:28:13 -050072 }
73 else /* other char */
74 {
75 putchar('.');
76 }
77 }
78 putchar('\n');
79 }
80 }
81}
82
83
vishwabmcba0bd5f2015-09-30 16:50:23 +053084// Method that gets called by shared libraries to get their command handlers registered
85void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
86 ipmi_context_t context, ipmid_callback_t handler)
87{
88 // Pack NetFn and Command in one.
89 auto netfn_and_cmd = std::make_pair(netfn, cmd);
90
91 // Pack Function handler and Data in another.
92 auto handler_and_context = std::make_pair(handler, context);
93
94 // Check if the registration has already been made..
95 auto iter = g_ipmid_router_map.find(netfn_and_cmd);
96 if(iter != g_ipmid_router_map.end())
97 {
98 fprintf(stderr,"ERROR : Duplicate registration for NetFn [0x%X], Cmd:[0x%X]\n",netfn, cmd);
99 }
100 else
101 {
102 // This is a fresh registration.. Add it to the map.
103 g_ipmid_router_map.emplace(netfn_and_cmd, handler_and_context);
104 }
105
106 return;
107}
108
109// Looks at the map and calls corresponding handler functions.
110ipmi_ret_t ipmi_netfn_router(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
111 ipmi_response_t response, ipmi_data_len_t data_len)
112{
113 // return from the Command handlers.
114 ipmi_ret_t rc = IPMI_CC_INVALID;
115
116 // Walk the map that has the registered handlers and invoke the approprite
117 // handlers for matching commands.
118 auto iter = g_ipmid_router_map.find(std::make_pair(netfn, cmd));
119 if(iter == g_ipmid_router_map.end())
120 {
121 printf("No registered handlers for NetFn:[0x%X], Cmd:[0x%X]"
122 " trying Wilcard implementation \n",netfn, cmd);
123
124 // Now that we did not find any specific [NetFn,Cmd], tuple, check for
125 // NetFn, WildCard command present.
126 iter = g_ipmid_router_map.find(std::make_pair(netfn, IPMI_CMD_WILDCARD));
127 if(iter == g_ipmid_router_map.end())
128 {
129 printf("No Registered handlers for NetFn:[0x%X],Cmd:[0x%X]\n",netfn, IPMI_CMD_WILDCARD);
130
131 // Respond with a 0xC1
132 memcpy(response, &rc, IPMI_CC_LEN);
133 *data_len = IPMI_CC_LEN;
134 return rc;
135 }
136 }
137
138#ifdef __IPMI_DEBUG__
139 // We have either a perfect match -OR- a wild card atleast,
140 printf("Calling Net function:[0x%X], Command:[0x%X]\n", netfn, cmd);
141#endif
142
143 // Extract the map data onto appropriate containers
144 auto handler_and_context = iter->second;
145
146 // Creating a pointer type casted to char* to make sure we advance 1 byte
147 // when we advance pointer to next's address. advancing void * would not
148 // make sense.
149 char *respo = &((char *)response)[IPMI_CC_LEN];
150
151 // Response message from the plugin goes into a byte post the base response
152 rc = (handler_and_context.first) (netfn, cmd, request, respo,
153 data_len, handler_and_context.second);
Chris Austen120f7322015-10-14 23:27:31 -0500154
vishwabmcba0bd5f2015-09-30 16:50:23 +0530155 // Now copy the return code that we got from handler and pack it in first
156 // byte.
157 memcpy(response, &rc, IPMI_CC_LEN);
Chris Austen120f7322015-10-14 23:27:31 -0500158
vishwabmcba0bd5f2015-09-30 16:50:23 +0530159 // Data length is now actual data + completion code.
160 *data_len = *data_len + IPMI_CC_LEN;
161
162 return rc;
163}
164
vishwabmcba0bd5f2015-09-30 16:50:23 +0530165
vishwabmcba0bd5f2015-09-30 16:50:23 +0530166
vishwabmcba0bd5f2015-09-30 16:50:23 +0530167
Chris Austen0ba649e2015-10-13 12:28:13 -0500168static 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 +0530169
Chris Austen0ba649e2015-10-13 12:28:13 -0500170 sd_bus_error error = SD_BUS_ERROR_NULL;
171 sd_bus_message *reply = NULL, *m=NULL;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530172
vishwabmcba0bd5f2015-09-30 16:50:23 +0530173
Chris Austen0ba649e2015-10-13 12:28:13 -0500174 const char *path;
175 int r, pty;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530176
vishwabmcba0bd5f2015-09-30 16:50:23 +0530177
Chris Austen0ba649e2015-10-13 12:28:13 -0500178 r = sd_bus_message_new_method_call(bus,&m,DBUS_NAME,OBJ_NAME,DBUS_NAME,"sendMessage");
179 if (r < 0) {
180 fprintf(stderr, "Failed to add the method object: %s\n", strerror(-r));
181 return -1;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530182 }
183
vishwabmcba0bd5f2015-09-30 16:50:23 +0530184
Chris Austenabfb5e82015-10-13 12:29:24 -0500185 // Responses in IPMI require a bit set. So there ya go...
186 netfn |= 0x04;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530187
Chris Austen0ba649e2015-10-13 12:28:13 -0500188
189 // Add the bytes needed for the methods to be called
190 r = sd_bus_message_append(m, "yyy", seq, netfn, cmd);
191 if (r < 0) {
192 fprintf(stderr, "Failed add the netfn and others : %s\n", strerror(-r));
193 return -1;
194 }
Chris Austen120f7322015-10-14 23:27:31 -0500195
Chris Austen0ba649e2015-10-13 12:28:13 -0500196 r = sd_bus_message_append_array(m, 'y', buf, len);
197 if (r < 0) {
198 fprintf(stderr, "Failed to add the string of response bytes: %s\n", strerror(-r));
199 return -1;
200 }
201
202
203
204 // Call the IPMI responder on the bus so the message can be sent to the CEC
205 r = sd_bus_call(bus, m, 0, &error, &reply);
206 if (r < 0) {
207 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
208 return -1;
209 }
210
211 r = sd_bus_message_read(reply, "x", &pty);
212#ifdef __IPMI_DEBUG__
213 printf("RC from the ipmi dbus method :%d \n", pty);
Chris Austen120f7322015-10-14 23:27:31 -0500214#endif
Chris Austen0ba649e2015-10-13 12:28:13 -0500215 if (r < 0) {
216 fprintf(stderr, "Failed to get a rc from the method: %s\n", strerror(-r));
217
218 }
219
220
221 sd_bus_error_free(&error);
222 sd_bus_message_unref(m);
223
224
225#ifdef __IPMI_DEBUG__
226 printf("%d : %s\n", __LINE__, __PRETTY_FUNCTION__ );
Chris Austen120f7322015-10-14 23:27:31 -0500227#endif
Chris Austen0ba649e2015-10-13 12:28:13 -0500228 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
229
230}
231
232static int handle_ipmi_command(sd_bus_message *m, void *user_data, sd_bus_error
233 *ret_error) {
234 int r = 0;
235 const char *msg = NULL;
236 char sequence, netfn, cmd;
237 const void *request;
238 size_t sz;
239 size_t resplen =MAX_IPMI_BUFFER;
240 unsigned char response[MAX_IPMI_BUFFER];
241
242 printf(" *** Received Signal: ");
243
244 memset(response, 0, MAX_IPMI_BUFFER);
245
246 r = sd_bus_message_read(m, "yyy", &sequence, &netfn, &cmd);
247 if (r < 0) {
248 fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
249 return -1;
250 }
251
252 r = sd_bus_message_read_array(m, 'y', &request, &sz );
253 if (r < 0) {
254 fprintf(stderr, "Failed to parse signal message: %s\n", strerror(-r));
255 return -1;
256 }
257
258
259 printf("Seq 0x%02x, NetFn 0x%02x, CMD: 0x%02x \n", sequence, netfn, cmd);
260 hexdump((void*)request, sz);
261
Chris Austen120f7322015-10-14 23:27:31 -0500262 // Allow the length field to be used for both input and output of the
Chris Austen0ba649e2015-10-13 12:28:13 -0500263 // ipmi call
264 resplen = sz;
265
Chris Austen120f7322015-10-14 23:27:31 -0500266 // Now that we have parsed the entire byte array from the caller
vishwabmcba0bd5f2015-09-30 16:50:23 +0530267 // we can call the ipmi router to do the work...
Chris Austen0ba649e2015-10-13 12:28:13 -0500268 r = ipmi_netfn_router(netfn, cmd, (void *)request, (void *)response, &resplen);
269 if(r != 0)
vishwabmcba0bd5f2015-09-30 16:50:23 +0530270 {
Chris Austen0ba649e2015-10-13 12:28:13 -0500271 fprintf(stderr,"ERROR:[0x%X] handling NetFn:[0x%X], Cmd:[0x%X]\n",r, netfn, cmd);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530272 }
273
Chris Austen0ba649e2015-10-13 12:28:13 -0500274 printf("Response...\n");
275 hexdump((void*)response, resplen);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530276
Chris Austen0ba649e2015-10-13 12:28:13 -0500277 // Send the response buffer from the ipmi command
278 r = send_ipmi_message(sequence, netfn, cmd, response, resplen);
279 if (r < 0) {
280 fprintf(stderr, "Failed to send the response message\n");
281 return -1;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530282 }
283
vishwabmcba0bd5f2015-09-30 16:50:23 +0530284
Chris Austen0ba649e2015-10-13 12:28:13 -0500285 return 0;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530286}
287
Chris Austen0ba649e2015-10-13 12:28:13 -0500288
vishwabmcba0bd5f2015-09-30 16:50:23 +0530289//----------------------------------------------------------------------
290// handler_select
291// Select all the files ending with with .so. in the given diretcory
292// @d: dirent structure containing the file name
293//----------------------------------------------------------------------
294int handler_select(const struct dirent *entry)
295{
296 // To hold ".so" from entry->d_name;
297 char dname_copy[4] = {0};
298
299 // We want to avoid checking for everything and isolate to the ones having
300 // .so in them.
301 if(strstr(entry->d_name, IPMI_PLUGIN_EXTN))
302 {
303 // It is possible that .so could be anywhere in the string but unlikely
Chris Austen120f7322015-10-14 23:27:31 -0500304 // But being careful here. Get the base address of the string, move
vishwabmcba0bd5f2015-09-30 16:50:23 +0530305 // until end and come back 3 steps and that gets what we need.
306 strcpy(dname_copy, (entry->d_name + strlen(entry->d_name)-strlen(IPMI_PLUGIN_EXTN)));
307 if(strcmp(dname_copy, IPMI_PLUGIN_EXTN) == 0)
308 {
309 return 1;
310 }
311 }
312 return 0;
313}
314
315// 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 -0500316// register a callback handler
vishwabmcba0bd5f2015-09-30 16:50:23 +0530317void ipmi_register_callback_handlers(const char* ipmi_lib_path)
318{
319 // For walking the ipmi_lib_path
320 struct dirent **handler_list;
321 int num_handlers = 0;
322
323 // This is used to check and abort if someone tries to register a bad one.
324 void *lib_handler = NULL;
325
326 if(ipmi_lib_path == NULL)
327 {
328 fprintf(stderr,"ERROR; No handlers to be registered for ipmi.. Aborting\n");
329 assert(0);
330 }
331 else
332 {
333 // 1: Open ipmi_lib_path. Its usually "/usr/lib/phosphor-host-ipmid"
334 // 2: Scan the directory for the files that end with .so
Chris Austen120f7322015-10-14 23:27:31 -0500335 // 3: For each one of them, just do a 'dlopen' so that they register
vishwabmcba0bd5f2015-09-30 16:50:23 +0530336 // the handlers for callback routines.
337
338 std::string handler_fqdn = ipmi_lib_path;
Chris Austen120f7322015-10-14 23:27:31 -0500339
vishwabmcba0bd5f2015-09-30 16:50:23 +0530340 // Append a "/" since we need to add the name of the .so. If there is
341 // already a .so, adding one more is not any harm.
342 handler_fqdn += "/";
343
344 num_handlers = scandir(ipmi_lib_path, &handler_list, handler_select, alphasort);
345 while(num_handlers--)
346 {
Chris Austen54030262015-10-13 12:30:46 -0500347 handler_fqdn = ipmi_lib_path;
vishwabmcba0bd5f2015-09-30 16:50:23 +0530348 handler_fqdn += handler_list[num_handlers]->d_name;
Chris Austen54030262015-10-13 12:30:46 -0500349 printf("Registering handler:[%s]\n",handler_fqdn.c_str());
350
vishwabmcba0bd5f2015-09-30 16:50:23 +0530351 lib_handler = dlopen(handler_fqdn.c_str(), RTLD_NOW);
352 if(lib_handler == NULL)
353 {
Chris Austen120f7322015-10-14 23:27:31 -0500354 fprintf(stderr,"ERROR opening [%s]: %s\n",
355 handler_fqdn.c_str(), dlerror());
vishwabmcba0bd5f2015-09-30 16:50:23 +0530356 }
357 // Wipe the memory allocated for this particular entry.
358 free(handler_list[num_handlers]);
359 }
360 // Done with all registration.
361 free(handler_list);
362 }
363
364 // TODO : What to be done on the memory that is given by dlopen ?.
365 return;
366}
367
368int main(int argc, char *argv[])
369{
Chris Austen0ba649e2015-10-13 12:28:13 -0500370 sd_bus_slot *slot = NULL;
371 int r;
372 char *mode = NULL;
373
374
vishwabmcba0bd5f2015-09-30 16:50:23 +0530375 // Register all the handlers that provider implementation to IPMI commands.
376 ipmi_register_callback_handlers(HOST_IPMI_LIB_PATH);
377
378#ifdef __IPMI_DEBUG__
379 printf("Registered Function handlers:\n");
380
381 // Print the registered handlers and their arguments.
382 for(auto& iter : g_ipmid_router_map)
383 {
384 ipmi_fn_cmd_t fn_and_cmd = iter.first;
Chris Austen120f7322015-10-14 23:27:31 -0500385 printf("NETFN:[0x%X], cmd[0x%X]\n", fn_and_cmd.first, fn_and_cmd.second);
vishwabmcba0bd5f2015-09-30 16:50:23 +0530386 }
387#endif
vishwabmcba0bd5f2015-09-30 16:50:23 +0530388
vishwabmcba0bd5f2015-09-30 16:50:23 +0530389
Chris Austen0ba649e2015-10-13 12:28:13 -0500390 /* Connect to system bus */
391 r = sd_bus_open_system(&bus);
392 if (r < 0) {
393 fprintf(stderr, "Failed to connect to system bus: %s\n",
394 strerror(-r));
395 goto finish;
396 }
vishwabmcba0bd5f2015-09-30 16:50:23 +0530397
Chris Austen0ba649e2015-10-13 12:28:13 -0500398 r = sd_bus_add_match(bus, &slot, FILTER, handle_ipmi_command, NULL);
399 if (r < 0) {
400 fprintf(stderr, "Failed: sd_bus_add_match: %s : %s\n", strerror(-r), FILTER);
401 goto finish;
402 }
vishwabmcba0bd5f2015-09-30 16:50:23 +0530403
vishwabmcba0bd5f2015-09-30 16:50:23 +0530404
Chris Austen0ba649e2015-10-13 12:28:13 -0500405 for (;;) {
406 /* Process requests */
407
408 r = sd_bus_process(bus, NULL);
409 if (r < 0) {
410 fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
411 goto finish;
412 }
413 if (r > 0) {
414 continue;
415 }
416
417 r = sd_bus_wait(bus, (uint64_t) - 1);
418 if (r < 0) {
419 fprintf(stderr, "Failed to wait on bus: %s\n", strerror(-r));
420 goto finish;
421 }
422 }
423
424finish:
425 sd_bus_slot_unref(slot);
426 sd_bus_unref(bus);
427 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
428
vishwabmcba0bd5f2015-09-30 16:50:23 +0530429}
Chris Austenb071c702015-10-15 00:00:09 -0500430
Chris Austen0012e9b2015-10-22 01:37:46 -0500431// Use a lookup table to find the interface name of a specific sensor
432// This will be used until an alternative is found. this is the first
433// step for mapping IPMI
434int find_interface_property_fru_type(dbus_interface_t *interface, const char *property_name, char *property_value) {
Chris Austenb071c702015-10-15 00:00:09 -0500435
Chris Austen0012e9b2015-10-22 01:37:46 -0500436 char *str1, *str2, *str3;
437 sd_bus_error error = SD_BUS_ERROR_NULL;
438 sd_bus_message *reply = NULL, *m=NULL;
Chris Austenb071c702015-10-15 00:00:09 -0500439
440
Chris Austen0012e9b2015-10-22 01:37:46 -0500441 int r;
442
443
444 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
480// Use a lookup table to find the interface name of a specific sensor
481// This will be used until an alternative is found. this is the first
482// step for mapping IPMI
483int find_openbmc_path(const char *type, const uint8_t num, dbus_interface_t *interface) {
484
485 const char *busname = "org.openbmc.managers.System";
486 const char *objname = "/org/openbmc/managers/System";
487
488 char *str1, *str2, *str3;
489 sd_bus_error error = SD_BUS_ERROR_NULL;
490 sd_bus_message *reply = NULL, *m=NULL;
491
492
493 int r;
494
495 r = sd_bus_message_new_method_call(bus,&m,busname,objname,busname,"getObjectFromByteId");
496 if (r < 0) {
497 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
498 }
499
500 r = sd_bus_message_append(m, "sy", type, num);
501 if (r < 0) {
502 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
503 }
504
505 // Call the IPMI responder on the bus so the message can be sent to the CEC
506 r = sd_bus_call(bus, m, 0, &error, &reply);
507 if (r < 0) {
508 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
509 goto final;
510 }
511
512
513 r = sd_bus_message_read(reply, "(sss)", &str1, &str2, &str3);
514 if (r < 0) {
515 fprintf(stderr, "Failed to get a response: %s", strerror(-r));
516 goto final;
517 }
518
519 strncpy(interface->bus, str1, MAX_DBUS_PATH);
520 strncpy(interface->path, str2, MAX_DBUS_PATH);
521 strncpy(interface->interface, str3, MAX_DBUS_PATH);
522
523 interface->sensornumber = num;
524
Chris Austen0012e9b2015-10-22 01:37:46 -0500525 printf("%s\n", str2);
526
Chris Austenb071c702015-10-15 00:00:09 -0500527
528final:
529
530 sd_bus_error_free(&error);
531 sd_bus_message_unref(m);
532
533 return r;
534}
535
536
537/////////////////////////////////////////////////////////////////////
538//
539// Routines used by ipmi commands wanting to interact on the dbus
540//
541/////////////////////////////////////////////////////////////////////
542
543
544// Simple set routine because some methods are standard.
545int set_sensor_dbus_state(uint8_t number, const char *method, const char *value) {
546
547
548 dbus_interface_t a;
549 int r;
550 sd_bus_error error = SD_BUS_ERROR_NULL;
551 sd_bus_message *reply = NULL, *m=NULL;
552
553 printf("Attempting to set a dbus Sensor 0x%02x via %s with a value of %s\n",
554 number, method, value);
555
556 r = find_openbmc_path("SENSOR", number, &a);
557
Chris Austenb071c702015-10-15 00:00:09 -0500558 r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
559 if (r < 0) {
560 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
561 }
562
563 r = sd_bus_message_append(m, "s", value);
564 if (r < 0) {
565 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
566 }
567
Chris Austenb071c702015-10-15 00:00:09 -0500568 r = sd_bus_call(bus, m, 0, &error, &reply);
569 if (r < 0) {
570 fprintf(stderr, "Failed to call the method: %s", strerror(-r));
571 }
572
Chris Austenb071c702015-10-15 00:00:09 -0500573 sd_bus_error_free(&error);
574 sd_bus_message_unref(m);
575
576 return 0;
Chris Austenb071c702015-10-15 00:00:09 -0500577}
Chris Austen0130d6e2015-10-15 22:32:36 -0500578
579int set_sensor_dbus_state_v(uint8_t number, const char *method, char *value) {
580
581
582 dbus_interface_t a;
583 int r;
584 sd_bus_error error = SD_BUS_ERROR_NULL;
585 sd_bus_message *reply = NULL, *m=NULL;
586
587 printf("Attempting to set a dbus Variant Sensor 0x%02x via %s with a value of %s\n",
588 number, method, value);
589
590 r = find_openbmc_path("SENSOR", number, &a);
591
Chris Austen0130d6e2015-10-15 22:32:36 -0500592 r = sd_bus_message_new_method_call(bus,&m,a.bus,a.path,a.interface,method);
593 if (r < 0) {
594 fprintf(stderr, "Failed to create a method call: %s", strerror(-r));
595 }
596
597 r = sd_bus_message_append(m, "v", "s", value);
598 if (r < 0) {
599 fprintf(stderr, "Failed to create a input parameter: %s", strerror(-r));
600 }
601
602
Chris Austen0130d6e2015-10-15 22:32:36 -0500603 r = sd_bus_call(bus, m, 0, &error, NULL);
604 if (r < 0) {
605 fprintf(stderr, "12 Failed to call the method: %s", strerror(-r));
606 }
607
608
Chris Austen0130d6e2015-10-15 22:32:36 -0500609 sd_bus_error_free(&error);
610 sd_bus_message_unref(m);
611
612 return 0;
613}