William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 1 | #include "globalhandler.h" |
Patrick Williams | 37af733 | 2016-09-02 21:21:42 -0500 | [diff] [blame] | 2 | #include "host-ipmid/ipmid-api.h" |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 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 | |
Brad Bishop | fa97b0c | 2016-06-14 20:34:44 -0400 | [diff] [blame] | 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"; |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 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; |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 84 | char* connection = NULL; |
Matthew Barth | 8b47005 | 2016-09-21 10:02:57 -0500 | [diff] [blame] | 85 | int r; |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 86 | |
| 87 | r = obj_mapper_get_connection(&connection, control_object_name); |
| 88 | if (r < 0) { |
| 89 | fprintf(stderr, "Failed to get connection, return value: %d.\n", r); |
| 90 | goto finish; |
| 91 | } |
| 92 | |
| 93 | printf("connection: %s\n", connection); |
| 94 | |
| 95 | // Open the system bus where most system services are provided. |
| 96 | bus = ipmid_get_sd_bus_connection(); |
| 97 | |
| 98 | /* |
| 99 | * Bus, service, object path, interface and method are provided to call |
| 100 | * the method. |
| 101 | * Signatures and input arguments are provided by the arguments at the |
| 102 | * end. |
| 103 | */ |
| 104 | r = sd_bus_call_method(bus, |
| 105 | connection, /* service to contact */ |
| 106 | control_object_name, /* object path */ |
| 107 | control_intf_name, /* interface name */ |
| 108 | "warmReset", /* method name */ |
| 109 | &error, /* object to return error in */ |
| 110 | &m, /* return message on success */ |
| 111 | NULL, |
| 112 | NULL |
| 113 | ); |
| 114 | |
| 115 | if (r < 0) { |
| 116 | fprintf(stderr, "Failed to issue method call: %s\n", error.message); |
| 117 | goto finish; |
| 118 | } |
| 119 | |
| 120 | finish: |
| 121 | sd_bus_error_free(&error); |
| 122 | sd_bus_message_unref(m); |
| 123 | free(connection); |
| 124 | |
| 125 | return r; |
| 126 | } |
| 127 | |
| 128 | ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd, |
| 129 | ipmi_request_t request, ipmi_response_t response, |
| 130 | ipmi_data_len_t data_len, ipmi_context_t context) |
| 131 | { |
| 132 | printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); |
| 133 | |
| 134 | // TODO: call the correct dbus method for warmReset. |
| 135 | dbus_warm_reset(); |
| 136 | |
| 137 | // Status code. |
| 138 | ipmi_ret_t rc = IPMI_CC_OK; |
| 139 | *data_len = 0; |
| 140 | return rc; |
| 141 | } |
| 142 | |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 143 | |
| 144 | void register_netfn_global_functions() |
| 145 | { |
| 146 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); |
| 147 | ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); |
| 148 | |
Ratan Gupta | eedf4f5 | 2016-02-25 18:53:52 +0530 | [diff] [blame] | 149 | return; |
William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame] | 150 | } |