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