#include "globalhandler.h" #include "ipmid-api.h" #include #include #include const char *control_object_name = "/org/openbmc/control/bmc0"; const char *control_intf_name = "org.openbmc.control.Bmc"; const char *objectmapper_service_name = "org.openbmc.ObjectMapper"; const char *objectmapper_object_name = "/org/openbmc/ObjectMapper"; const char *objectmapper_intf_name = "org.openbmc.ObjectMapper"; void register_netfn_global_functions() __attribute__((constructor)); int obj_mapper_get_connection(char** buf, const char* obj_path) { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL; sd_bus *bus = NULL; char *temp_buf = NULL, *intf = NULL; size_t buf_size = 0; int r; //Get the system bus where most system services are provided. bus = ipmid_get_sd_bus_connection(); /* * Bus, service, object path, interface and method are provided to call * the method. * Signatures and input arguments are provided by the arguments at the * end. */ r = sd_bus_call_method(bus, objectmapper_service_name, /* service to contact */ objectmapper_object_name, /* object path */ objectmapper_intf_name, /* interface name */ "GetObject", /* method name */ &error, /* object to return error in */ &m, /* return message on success */ "s", /* input signature */ obj_path /* first argument */ ); if (r < 0) { fprintf(stderr, "Failed to issue method call: %s\n", error.message); goto finish; } // Get the key, aka, the connection name sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf); /* * TODO: check the return code. Currently for no reason the message * parsing of object mapper is always complaining about * "Device or resource busy", but the result seems OK for now. Need * further checks. */ buf_size = strlen(temp_buf) + 1; printf("IPMID connection name: %s\n", temp_buf); *buf = (char*)malloc(buf_size); if (*buf == NULL) { fprintf(stderr, "Malloc failed for warm reset"); r = -1; goto finish; } memcpy(*buf, temp_buf, buf_size); finish: sd_bus_error_free(&error); sd_bus_message_unref(m); return r; } int dbus_warm_reset() { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL; sd_bus *bus = NULL; char* temp_buf = NULL; uint8_t* get_value = NULL; char* connection = NULL; int r, i; r = obj_mapper_get_connection(&connection, control_object_name); if (r < 0) { fprintf(stderr, "Failed to get connection, return value: %d.\n", r); goto finish; } printf("connection: %s\n", connection); // Open the system bus where most system services are provided. bus = ipmid_get_sd_bus_connection(); /* * Bus, service, object path, interface and method are provided to call * the method. * Signatures and input arguments are provided by the arguments at the * end. */ r = sd_bus_call_method(bus, connection, /* service to contact */ control_object_name, /* object path */ control_intf_name, /* interface name */ "warmReset", /* method name */ &error, /* object to return error in */ &m, /* return message on success */ NULL, NULL ); if (r < 0) { fprintf(stderr, "Failed to issue method call: %s\n", error.message); goto finish; } finish: sd_bus_error_free(&error); sd_bus_message_unref(m); free(connection); return r; } ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) { printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); // TODO: call the correct dbus method for warmReset. dbus_warm_reset(); // Status code. ipmi_ret_t rc = IPMI_CC_OK; *data_len = 0; return rc; } void register_netfn_global_functions() { printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); return; }