198a23840SMatthew Barth #include "globalhandler.h" 237af7331SPatrick 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 79*bc759884SNan Li 80*bc759884SNan Li int dbus_reset(const char *method) 8198a23840SMatthew Barth { 8298a23840SMatthew Barth sd_bus_error error = SD_BUS_ERROR_NULL; 8398a23840SMatthew Barth sd_bus_message *m = NULL; 8498a23840SMatthew Barth sd_bus *bus = NULL; 8598a23840SMatthew Barth char* connection = NULL; 868b470052SMatthew Barth int r; 8798a23840SMatthew Barth 8898a23840SMatthew Barth r = obj_mapper_get_connection(&connection, control_object_name); 8998a23840SMatthew Barth if (r < 0) { 9098a23840SMatthew Barth fprintf(stderr, "Failed to get connection, return value: %d.\n", r); 9198a23840SMatthew Barth goto finish; 9298a23840SMatthew Barth } 9398a23840SMatthew Barth 9498a23840SMatthew Barth printf("connection: %s\n", connection); 9598a23840SMatthew Barth 9698a23840SMatthew Barth // Open the system bus where most system services are provided. 9798a23840SMatthew Barth bus = ipmid_get_sd_bus_connection(); 9898a23840SMatthew Barth 9998a23840SMatthew Barth /* 10098a23840SMatthew Barth * Bus, service, object path, interface and method are provided to call 10198a23840SMatthew Barth * the method. 10298a23840SMatthew Barth * Signatures and input arguments are provided by the arguments at the 10398a23840SMatthew Barth * end. 10498a23840SMatthew Barth */ 10598a23840SMatthew Barth r = sd_bus_call_method(bus, 10698a23840SMatthew Barth connection, /* service to contact */ 10798a23840SMatthew Barth control_object_name, /* object path */ 10898a23840SMatthew Barth control_intf_name, /* interface name */ 109*bc759884SNan Li method, /* method name */ 11098a23840SMatthew Barth &error, /* object to return error in */ 11198a23840SMatthew Barth &m, /* return message on success */ 11298a23840SMatthew Barth NULL, 11398a23840SMatthew Barth NULL 11498a23840SMatthew Barth ); 11598a23840SMatthew Barth 11698a23840SMatthew Barth if (r < 0) { 11798a23840SMatthew Barth fprintf(stderr, "Failed to issue method call: %s\n", error.message); 11898a23840SMatthew Barth goto finish; 11998a23840SMatthew Barth } 12098a23840SMatthew Barth 12198a23840SMatthew Barth finish: 12298a23840SMatthew Barth sd_bus_error_free(&error); 12398a23840SMatthew Barth sd_bus_message_unref(m); 12498a23840SMatthew Barth free(connection); 12598a23840SMatthew Barth 12698a23840SMatthew Barth return r; 12798a23840SMatthew Barth } 12898a23840SMatthew Barth 12998a23840SMatthew Barth ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 13098a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 13198a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 13298a23840SMatthew Barth { 13398a23840SMatthew Barth printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); 13498a23840SMatthew Barth 13598a23840SMatthew Barth // TODO: call the correct dbus method for warmReset. 136*bc759884SNan Li dbus_reset("warmReset"); 13798a23840SMatthew Barth 13898a23840SMatthew Barth // Status code. 13998a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 14098a23840SMatthew Barth *data_len = 0; 14198a23840SMatthew Barth return rc; 14298a23840SMatthew Barth } 14398a23840SMatthew Barth 144*bc759884SNan Li ipmi_ret_t ipmi_global_cold_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 145*bc759884SNan Li ipmi_request_t request, ipmi_response_t response, 146*bc759884SNan Li ipmi_data_len_t data_len, ipmi_context_t context) 147*bc759884SNan Li { 148*bc759884SNan Li printf("Handling GLOBAL coldReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); 149*bc759884SNan Li 150*bc759884SNan Li // TODO: call the correct dbus method for coldReset. 151*bc759884SNan Li dbus_reset("coldReset"); 152*bc759884SNan Li 153*bc759884SNan Li // Status code. 154*bc759884SNan Li ipmi_ret_t rc = IPMI_CC_OK; 155*bc759884SNan Li *data_len = 0; 156*bc759884SNan Li return rc; 157*bc759884SNan Li } 15898a23840SMatthew Barth 15998a23840SMatthew Barth void register_netfn_global_functions() 16098a23840SMatthew Barth { 161*bc759884SNan Li printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_COLD_RESET); 162*bc759884SNan Li ipmi_register_callback(NETFUN_APP, IPMI_CMD_COLD_RESET, NULL, ipmi_global_cold_reset); 163*bc759884SNan Li 16498a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); 16598a23840SMatthew Barth ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); 16698a23840SMatthew Barth 16798a23840SMatthew Barth return; 16898a23840SMatthew Barth } 169