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