198a23840SMatthew Barth #include "globalhandler.h"
237af7331SPatrick Williams #include "host-ipmid/ipmid-api.h"
398a23840SMatthew Barth #include <stdio.h>
498a23840SMatthew Barth #include <string.h>
598a23840SMatthew Barth #include <stdint.h>
630be0f70SBrad Bishop #include <mapper.h>
798a23840SMatthew Barth 
898a23840SMatthew Barth const char  *control_object_name  =  "/org/openbmc/control/bmc0";
998a23840SMatthew Barth const char  *control_intf_name    =  "org.openbmc.control.Bmc";
1098a23840SMatthew Barth 
1198a23840SMatthew Barth void register_netfn_global_functions() __attribute__((constructor));
1298a23840SMatthew Barth 
13bc759884SNan Li int dbus_reset(const char *method)
1498a23840SMatthew Barth {
1598a23840SMatthew Barth     sd_bus_error error = SD_BUS_ERROR_NULL;
1698a23840SMatthew Barth     sd_bus_message *m = NULL;
1798a23840SMatthew Barth     sd_bus *bus = NULL;
1898a23840SMatthew Barth     char* connection = NULL;
198b470052SMatthew Barth     int r;
2098a23840SMatthew Barth 
2130be0f70SBrad Bishop     bus = ipmid_get_sd_bus_connection();
2230be0f70SBrad Bishop     r = mapper_get_service(bus, control_object_name, &connection);
2398a23840SMatthew Barth     if (r < 0) {
2430be0f70SBrad Bishop         fprintf(stderr, "Failed to get connection for %s: %s\n",
2530be0f70SBrad Bishop                 control_object_name, strerror(-r));
2698a23840SMatthew Barth         goto finish;
2798a23840SMatthew Barth     }
2898a23840SMatthew Barth 
2998a23840SMatthew Barth     printf("connection: %s\n", connection);
3098a23840SMatthew Barth 
3198a23840SMatthew Barth     // Open the system bus where most system services are provided.
3298a23840SMatthew Barth     bus = ipmid_get_sd_bus_connection();
3398a23840SMatthew Barth 
3498a23840SMatthew Barth     /*
3598a23840SMatthew Barth      * Bus, service, object path, interface and method are provided to call
3698a23840SMatthew Barth      * the method.
3798a23840SMatthew Barth      * Signatures and input arguments are provided by the arguments at the
3898a23840SMatthew Barth      * end.
3998a23840SMatthew Barth      */
4098a23840SMatthew Barth     r = sd_bus_call_method(bus,
4198a23840SMatthew Barth             connection,                                /* service to contact */
4298a23840SMatthew Barth             control_object_name,                       /* object path */
4398a23840SMatthew Barth             control_intf_name,                         /* interface name */
44bc759884SNan Li             method,                               /* method name */
4598a23840SMatthew Barth             &error,                                    /* object to return error in */
4698a23840SMatthew Barth             &m,                                        /* return message on success */
4798a23840SMatthew Barth             NULL,
4898a23840SMatthew Barth             NULL
4998a23840SMatthew Barth             );
5098a23840SMatthew Barth 
5198a23840SMatthew Barth     if (r < 0) {
5298a23840SMatthew Barth         fprintf(stderr, "Failed to issue method call: %s\n", error.message);
5398a23840SMatthew Barth         goto finish;
5498a23840SMatthew Barth     }
5598a23840SMatthew Barth 
5698a23840SMatthew Barth finish:
5798a23840SMatthew Barth     sd_bus_error_free(&error);
5898a23840SMatthew Barth     sd_bus_message_unref(m);
5998a23840SMatthew Barth     free(connection);
6098a23840SMatthew Barth 
6198a23840SMatthew Barth     return r;
6298a23840SMatthew Barth }
6398a23840SMatthew Barth 
6498a23840SMatthew Barth ipmi_ret_t ipmi_global_warm_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
6598a23840SMatthew Barth                               ipmi_request_t request, ipmi_response_t response,
6698a23840SMatthew Barth                               ipmi_data_len_t data_len, ipmi_context_t context)
6798a23840SMatthew Barth {
6898a23840SMatthew Barth     printf("Handling GLOBAL warmReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
6998a23840SMatthew Barth 
7098a23840SMatthew Barth     // TODO: call the correct dbus method for warmReset.
71bc759884SNan Li     dbus_reset("warmReset");
7298a23840SMatthew Barth 
7398a23840SMatthew Barth     // Status code.
7498a23840SMatthew Barth     ipmi_ret_t rc = IPMI_CC_OK;
7598a23840SMatthew Barth     *data_len = 0;
7698a23840SMatthew Barth     return rc;
7798a23840SMatthew Barth }
7898a23840SMatthew Barth 
79bc759884SNan Li ipmi_ret_t ipmi_global_cold_reset(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
80bc759884SNan Li                               ipmi_request_t request, ipmi_response_t response,
81bc759884SNan Li                               ipmi_data_len_t data_len, ipmi_context_t context)
82bc759884SNan Li {
83bc759884SNan Li     printf("Handling GLOBAL coldReset Netfn:[0x%X], Cmd:[0x%X]\n",netfn, cmd);
84bc759884SNan Li 
85bc759884SNan Li     // TODO: call the correct dbus method for coldReset.
86bc759884SNan Li     dbus_reset("coldReset");
87bc759884SNan Li 
88bc759884SNan Li     // Status code.
89bc759884SNan Li     ipmi_ret_t rc = IPMI_CC_OK;
90bc759884SNan Li     *data_len = 0;
91bc759884SNan Li     return rc;
92bc759884SNan Li }
9398a23840SMatthew Barth 
9498a23840SMatthew Barth void register_netfn_global_functions()
9598a23840SMatthew Barth {
96*0573237fSTom     // Cold Reset
97bc759884SNan Li     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_COLD_RESET);
98*0573237fSTom     ipmi_register_callback(NETFUN_APP, IPMI_CMD_COLD_RESET, NULL, ipmi_global_cold_reset,
99*0573237fSTom                            PRIVILEGE_ADMIN);
100bc759884SNan Li 
101*0573237fSTom     // <Warm Reset>
10298a23840SMatthew Barth     printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_APP, IPMI_CMD_WARM_RESET);
103*0573237fSTom     ipmi_register_callback(NETFUN_APP, IPMI_CMD_WARM_RESET, NULL, ipmi_global_warm_reset,
104*0573237fSTom                            PRIVILEGE_ADMIN);
10598a23840SMatthew Barth 
10698a23840SMatthew Barth     return;
10798a23840SMatthew Barth }
108