William | cb8ac88 | 2015-12-31 19:15:17 +0800 | [diff] [blame^] | 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/objectmapper"; |
| 12 | const char *objectmapper_intf_name = "org.openbmc.objectmapper.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 | ipmi_ret_t ipmi_global_wildcard_handler(ipmi_netfn_t netfn, ipmi_cmd_t cmd, |
| 146 | ipmi_request_t request, ipmi_response_t response, |
| 147 | ipmi_data_len_t data_len, ipmi_context_t context) |
| 148 | { |
| 149 | printf("Handling WILDCARD Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd); |
| 150 | |
| 151 | // Status code. |
| 152 | ipmi_ret_t rc = IPMI_CC_OK; |
| 153 | |
| 154 | *data_len = strlen("THIS IS WILDCARD"); |
| 155 | |
| 156 | // Now pack actual response |
| 157 | memcpy(response, "THIS IS WILDCARD", *data_len); |
| 158 | |
| 159 | return rc; |
| 160 | } |
| 161 | |
| 162 | void register_netfn_global_functions() |
| 163 | { |
| 164 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET); |
| 165 | ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset); |
| 166 | |
| 167 | printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WILDCARD); |
| 168 | ipmi_register_callback(NETFUN_APP, IPMI_CMD_WILDCARD, NULL, ipmi_global_wildcard_handler); |
| 169 | |
| 170 | return; |
| 171 | } |