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