198a23840SMatthew Barth #include "globalhandler.h" 2*37af7331SPatrick Williams #include "host-ipmid/ipmid-api.h" 398a23840SMatthew Barth #include <stdio.h> 498a23840SMatthew Barth #include <string.h> 598a23840SMatthew Barth #include <stdint.h> 698a23840SMatthew Barth 798a23840SMatthew Barth const char *control_object_name = "/org/openbmc/control/bmc0"; 898a23840SMatthew Barth const char *control_intf_name = "org.openbmc.control.Bmc"; 998a23840SMatthew Barth 1098a23840SMatthew Barth const char *objectmapper_service_name = "org.openbmc.ObjectMapper"; 1198a23840SMatthew Barth const char *objectmapper_object_name = "/org/openbmc/ObjectMapper"; 1298a23840SMatthew Barth const char *objectmapper_intf_name = "org.openbmc.ObjectMapper"; 1398a23840SMatthew Barth 1498a23840SMatthew Barth void register_netfn_global_functions() __attribute__((constructor)); 1598a23840SMatthew Barth 1698a23840SMatthew Barth int obj_mapper_get_connection(char** buf, const char* obj_path) 1798a23840SMatthew Barth { 1898a23840SMatthew Barth sd_bus_error error = SD_BUS_ERROR_NULL; 1998a23840SMatthew Barth sd_bus_message *m = NULL; 2098a23840SMatthew Barth sd_bus *bus = NULL; 2198a23840SMatthew Barth char *temp_buf = NULL, *intf = NULL; 2298a23840SMatthew Barth size_t buf_size = 0; 2398a23840SMatthew Barth int r; 2498a23840SMatthew Barth 2598a23840SMatthew Barth //Get the system bus where most system services are provided. 2698a23840SMatthew Barth bus = ipmid_get_sd_bus_connection(); 2798a23840SMatthew Barth 2898a23840SMatthew Barth /* 2998a23840SMatthew Barth * Bus, service, object path, interface and method are provided to call 3098a23840SMatthew Barth * the method. 3198a23840SMatthew Barth * Signatures and input arguments are provided by the arguments at the 3298a23840SMatthew Barth * end. 3398a23840SMatthew Barth */ 3498a23840SMatthew Barth r = sd_bus_call_method(bus, 3598a23840SMatthew Barth objectmapper_service_name, /* service to contact */ 3698a23840SMatthew Barth objectmapper_object_name, /* object path */ 3798a23840SMatthew Barth objectmapper_intf_name, /* interface name */ 3898a23840SMatthew Barth "GetObject", /* method name */ 3998a23840SMatthew Barth &error, /* object to return error in */ 4098a23840SMatthew Barth &m, /* return message on success */ 4198a23840SMatthew Barth "s", /* input signature */ 4298a23840SMatthew Barth obj_path /* first argument */ 4398a23840SMatthew Barth ); 4498a23840SMatthew Barth 4598a23840SMatthew Barth if (r < 0) { 4698a23840SMatthew Barth fprintf(stderr, "Failed to issue method call: %s\n", error.message); 4798a23840SMatthew Barth goto finish; 4898a23840SMatthew Barth } 4998a23840SMatthew Barth 5098a23840SMatthew Barth // Get the key, aka, the connection name 5198a23840SMatthew Barth sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf); 5298a23840SMatthew Barth 5398a23840SMatthew Barth /* 5498a23840SMatthew Barth * TODO: check the return code. Currently for no reason the message 5598a23840SMatthew Barth * parsing of object mapper is always complaining about 5698a23840SMatthew Barth * "Device or resource busy", but the result seems OK for now. Need 5798a23840SMatthew Barth * further checks. 5898a23840SMatthew Barth */ 5998a23840SMatthew Barth 6098a23840SMatthew Barth buf_size = strlen(temp_buf) + 1; 6198a23840SMatthew Barth printf("IPMID connection name: %s\n", temp_buf); 6298a23840SMatthew Barth *buf = (char*)malloc(buf_size); 6398a23840SMatthew Barth 6498a23840SMatthew Barth if (*buf == NULL) { 6598a23840SMatthew Barth fprintf(stderr, "Malloc failed for warm reset"); 6698a23840SMatthew Barth r = -1; 6798a23840SMatthew Barth goto finish; 6898a23840SMatthew Barth } 6998a23840SMatthew Barth 7098a23840SMatthew Barth memcpy(*buf, temp_buf, buf_size); 7198a23840SMatthew Barth 7298a23840SMatthew Barth finish: 7398a23840SMatthew Barth sd_bus_error_free(&error); 7498a23840SMatthew Barth sd_bus_message_unref(m); 7598a23840SMatthew Barth 7698a23840SMatthew Barth return r; 7798a23840SMatthew Barth } 7898a23840SMatthew Barth 7998a23840SMatthew Barth int dbus_warm_reset() 8098a23840SMatthew Barth { 8198a23840SMatthew Barth sd_bus_error error = SD_BUS_ERROR_NULL; 8298a23840SMatthew Barth sd_bus_message *m = NULL; 8398a23840SMatthew Barth sd_bus *bus = NULL; 8498a23840SMatthew Barth char* temp_buf = NULL; 8598a23840SMatthew Barth uint8_t* get_value = NULL; 8698a23840SMatthew Barth char* connection = NULL; 8798a23840SMatthew Barth int r, i; 8898a23840SMatthew Barth 8998a23840SMatthew Barth r = obj_mapper_get_connection(&connection, control_object_name); 9098a23840SMatthew Barth if (r < 0) { 9198a23840SMatthew Barth fprintf(stderr, "Failed to get connection, return value: %d.\n", r); 9298a23840SMatthew Barth goto finish; 9398a23840SMatthew Barth } 9498a23840SMatthew Barth 9598a23840SMatthew Barth printf("connection: %s\n", connection); 9698a23840SMatthew Barth 9798a23840SMatthew Barth // Open the system bus where most system services are provided. 9898a23840SMatthew Barth bus = ipmid_get_sd_bus_connection(); 9998a23840SMatthew Barth 10098a23840SMatthew Barth /* 10198a23840SMatthew Barth * Bus, service, object path, interface and method are provided to call 10298a23840SMatthew Barth * the method. 10398a23840SMatthew Barth * Signatures and input arguments are provided by the arguments at the 10498a23840SMatthew Barth * end. 10598a23840SMatthew Barth */ 10698a23840SMatthew Barth r = sd_bus_call_method(bus, 10798a23840SMatthew Barth connection, /* service to contact */ 10898a23840SMatthew Barth control_object_name, /* object path */ 10998a23840SMatthew Barth control_intf_name, /* interface name */ 11098a23840SMatthew Barth "warmReset", /* method name */ 11198a23840SMatthew Barth &error, /* object to return error in */ 11298a23840SMatthew Barth &m, /* return message on success */ 11398a23840SMatthew Barth NULL, 11498a23840SMatthew Barth NULL 11598a23840SMatthew Barth ); 11698a23840SMatthew Barth 11798a23840SMatthew Barth if (r < 0) { 11898a23840SMatthew Barth fprintf(stderr, "Failed to issue method call: %s\n", error.message); 11998a23840SMatthew Barth goto finish; 12098a23840SMatthew Barth } 12198a23840SMatthew Barth 12298a23840SMatthew Barth finish: 12398a23840SMatthew Barth sd_bus_error_free(&error); 12498a23840SMatthew Barth sd_bus_message_unref(m); 12598a23840SMatthew Barth free(connection); 12698a23840SMatthew Barth 12798a23840SMatthew Barth return r; 12898a23840SMatthew Barth } 12998a23840SMatthew Barth 13098a23840SMatthew Barth ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 13198a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 13298a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 13398a23840SMatthew Barth { 13498a23840SMatthew Barth printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); 13598a23840SMatthew Barth 13698a23840SMatthew Barth // TODO: call the correct dbus method for warmReset. 13798a23840SMatthew Barth dbus_warm_reset(); 13898a23840SMatthew Barth 13998a23840SMatthew Barth // Status code. 14098a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 14198a23840SMatthew Barth *data_len = 0; 14298a23840SMatthew Barth return rc; 14398a23840SMatthew Barth } 14498a23840SMatthew Barth 14598a23840SMatthew Barth 14698a23840SMatthew Barth void register_netfn_global_functions() 14798a23840SMatthew Barth { 14898a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); 14998a23840SMatthew Barth ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); 15098a23840SMatthew Barth 15198a23840SMatthew Barth return; 15298a23840SMatthew Barth } 153