1*98a23840SMatthew Barth #include "globalhandler.h" 2*98a23840SMatthew Barth #include "ipmid-api.h" 3*98a23840SMatthew Barth #include <stdio.h> 4*98a23840SMatthew Barth #include <string.h> 5*98a23840SMatthew Barth #include <stdint.h> 6*98a23840SMatthew Barth 7*98a23840SMatthew Barth const char *control_object_name = "/org/openbmc/control/bmc0"; 8*98a23840SMatthew Barth const char *control_intf_name = "org.openbmc.control.Bmc"; 9*98a23840SMatthew Barth 10*98a23840SMatthew Barth const char *objectmapper_service_name = "org.openbmc.ObjectMapper"; 11*98a23840SMatthew Barth const char *objectmapper_object_name = "/org/openbmc/ObjectMapper"; 12*98a23840SMatthew Barth const char *objectmapper_intf_name = "org.openbmc.ObjectMapper"; 13*98a23840SMatthew Barth 14*98a23840SMatthew Barth void register_netfn_global_functions() __attribute__((constructor)); 15*98a23840SMatthew Barth 16*98a23840SMatthew Barth int obj_mapper_get_connection(char** buf, const char* obj_path) 17*98a23840SMatthew Barth { 18*98a23840SMatthew Barth sd_bus_error error = SD_BUS_ERROR_NULL; 19*98a23840SMatthew Barth sd_bus_message *m = NULL; 20*98a23840SMatthew Barth sd_bus *bus = NULL; 21*98a23840SMatthew Barth char *temp_buf = NULL, *intf = NULL; 22*98a23840SMatthew Barth size_t buf_size = 0; 23*98a23840SMatthew Barth int r; 24*98a23840SMatthew Barth 25*98a23840SMatthew Barth //Get the system bus where most system services are provided. 26*98a23840SMatthew Barth bus = ipmid_get_sd_bus_connection(); 27*98a23840SMatthew Barth 28*98a23840SMatthew Barth /* 29*98a23840SMatthew Barth * Bus, service, object path, interface and method are provided to call 30*98a23840SMatthew Barth * the method. 31*98a23840SMatthew Barth * Signatures and input arguments are provided by the arguments at the 32*98a23840SMatthew Barth * end. 33*98a23840SMatthew Barth */ 34*98a23840SMatthew Barth r = sd_bus_call_method(bus, 35*98a23840SMatthew Barth objectmapper_service_name, /* service to contact */ 36*98a23840SMatthew Barth objectmapper_object_name, /* object path */ 37*98a23840SMatthew Barth objectmapper_intf_name, /* interface name */ 38*98a23840SMatthew Barth "GetObject", /* method name */ 39*98a23840SMatthew Barth &error, /* object to return error in */ 40*98a23840SMatthew Barth &m, /* return message on success */ 41*98a23840SMatthew Barth "s", /* input signature */ 42*98a23840SMatthew Barth obj_path /* first argument */ 43*98a23840SMatthew Barth ); 44*98a23840SMatthew Barth 45*98a23840SMatthew Barth if (r < 0) { 46*98a23840SMatthew Barth fprintf(stderr, "Failed to issue method call: %s\n", error.message); 47*98a23840SMatthew Barth goto finish; 48*98a23840SMatthew Barth } 49*98a23840SMatthew Barth 50*98a23840SMatthew Barth // Get the key, aka, the connection name 51*98a23840SMatthew Barth sd_bus_message_read(m, "a{sas}", 1, &temp_buf, 1, &intf); 52*98a23840SMatthew Barth 53*98a23840SMatthew Barth /* 54*98a23840SMatthew Barth * TODO: check the return code. Currently for no reason the message 55*98a23840SMatthew Barth * parsing of object mapper is always complaining about 56*98a23840SMatthew Barth * "Device or resource busy", but the result seems OK for now. Need 57*98a23840SMatthew Barth * further checks. 58*98a23840SMatthew Barth */ 59*98a23840SMatthew Barth 60*98a23840SMatthew Barth buf_size = strlen(temp_buf) + 1; 61*98a23840SMatthew Barth printf("IPMID connection name: %s\n", temp_buf); 62*98a23840SMatthew Barth *buf = (char*)malloc(buf_size); 63*98a23840SMatthew Barth 64*98a23840SMatthew Barth if (*buf == NULL) { 65*98a23840SMatthew Barth fprintf(stderr, "Malloc failed for warm reset"); 66*98a23840SMatthew Barth r = -1; 67*98a23840SMatthew Barth goto finish; 68*98a23840SMatthew Barth } 69*98a23840SMatthew Barth 70*98a23840SMatthew Barth memcpy(*buf, temp_buf, buf_size); 71*98a23840SMatthew Barth 72*98a23840SMatthew Barth finish: 73*98a23840SMatthew Barth sd_bus_error_free(&error); 74*98a23840SMatthew Barth sd_bus_message_unref(m); 75*98a23840SMatthew Barth 76*98a23840SMatthew Barth return r; 77*98a23840SMatthew Barth } 78*98a23840SMatthew Barth 79*98a23840SMatthew Barth int dbus_warm_reset() 80*98a23840SMatthew Barth { 81*98a23840SMatthew Barth sd_bus_error error = SD_BUS_ERROR_NULL; 82*98a23840SMatthew Barth sd_bus_message *m = NULL; 83*98a23840SMatthew Barth sd_bus *bus = NULL; 84*98a23840SMatthew Barth char* temp_buf = NULL; 85*98a23840SMatthew Barth uint8_t* get_value = NULL; 86*98a23840SMatthew Barth char* connection = NULL; 87*98a23840SMatthew Barth int r, i; 88*98a23840SMatthew Barth 89*98a23840SMatthew Barth r = obj_mapper_get_connection(&connection, control_object_name); 90*98a23840SMatthew Barth if (r < 0) { 91*98a23840SMatthew Barth fprintf(stderr, "Failed to get connection, return value: %d.\n", r); 92*98a23840SMatthew Barth goto finish; 93*98a23840SMatthew Barth } 94*98a23840SMatthew Barth 95*98a23840SMatthew Barth printf("connection: %s\n", connection); 96*98a23840SMatthew Barth 97*98a23840SMatthew Barth // Open the system bus where most system services are provided. 98*98a23840SMatthew Barth bus = ipmid_get_sd_bus_connection(); 99*98a23840SMatthew Barth 100*98a23840SMatthew Barth /* 101*98a23840SMatthew Barth * Bus, service, object path, interface and method are provided to call 102*98a23840SMatthew Barth * the method. 103*98a23840SMatthew Barth * Signatures and input arguments are provided by the arguments at the 104*98a23840SMatthew Barth * end. 105*98a23840SMatthew Barth */ 106*98a23840SMatthew Barth r = sd_bus_call_method(bus, 107*98a23840SMatthew Barth connection, /* service to contact */ 108*98a23840SMatthew Barth control_object_name, /* object path */ 109*98a23840SMatthew Barth control_intf_name, /* interface name */ 110*98a23840SMatthew Barth "warmReset", /* method name */ 111*98a23840SMatthew Barth &error, /* object to return error in */ 112*98a23840SMatthew Barth &m, /* return message on success */ 113*98a23840SMatthew Barth NULL, 114*98a23840SMatthew Barth NULL 115*98a23840SMatthew Barth ); 116*98a23840SMatthew Barth 117*98a23840SMatthew Barth if (r < 0) { 118*98a23840SMatthew Barth fprintf(stderr, "Failed to issue method call: %s\n", error.message); 119*98a23840SMatthew Barth goto finish; 120*98a23840SMatthew Barth } 121*98a23840SMatthew Barth 122*98a23840SMatthew Barth finish: 123*98a23840SMatthew Barth sd_bus_error_free(&error); 124*98a23840SMatthew Barth sd_bus_message_unref(m); 125*98a23840SMatthew Barth free(connection); 126*98a23840SMatthew Barth 127*98a23840SMatthew Barth return r; 128*98a23840SMatthew Barth } 129*98a23840SMatthew Barth 130*98a23840SMatthew Barth ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, 131*98a23840SMatthew Barth ipmi_request_t request, ipmi_response_t response, 132*98a23840SMatthew Barth ipmi_data_len_t data_len, ipmi_context_t context) 133*98a23840SMatthew Barth { 134*98a23840SMatthew Barth printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); 135*98a23840SMatthew Barth 136*98a23840SMatthew Barth // TODO: call the correct dbus method for warmReset. 137*98a23840SMatthew Barth dbus_warm_reset(); 138*98a23840SMatthew Barth 139*98a23840SMatthew Barth // Status code. 140*98a23840SMatthew Barth ipmi_ret_t rc = IPMI_CC_OK; 141*98a23840SMatthew Barth *data_len = 0; 142*98a23840SMatthew Barth return rc; 143*98a23840SMatthew Barth } 144*98a23840SMatthew Barth 145*98a23840SMatthew Barth 146*98a23840SMatthew Barth void register_netfn_global_functions() 147*98a23840SMatthew Barth { 148*98a23840SMatthew Barth printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); 149*98a23840SMatthew Barth ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); 150*98a23840SMatthew Barth 151*98a23840SMatthew Barth return; 152*98a23840SMatthew Barth } 153