summaryrefslogtreecommitdiff
path: root/src/power_commands.c
blob: 40684fd0125bece97a18c69b6a2ba2bed6c1c81a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <stdio.h>
#include <string.h>

#include<sd_bus.h>
#include "power_commands.h"
#include "errno.h"

typedef struct
{   const char* first;
    const char* second;
}string_pair_t;

typedef struct
{   const char* first;
    const char* second;
    const char* third;
    const char* fourth;
}string_quadruple_t;

const string_quadruple_t chassis_dbus = {
    "xyz.openbmc_project.State.Chassis",
    "/xyz/openbmc_project/state/chassis0",
    "xyz.openbmc_project.State.Chassis",
    "RequestedPowerTransition"};

const string_quadruple_t host_dbus = {
    "xyz.openbmc_project.State.Host",
    "/xyz/openbmc_project/state/host0",
    "xyz.openbmc_project.State.Host",
    "RequestedHostTransition"};

typedef enum
{
    POWER_UNKNOWN=-1,
    POWER_ON_GRACEFUL=100,
    POWER_ON_FORCE,
    POWER_OFF_GRACEFUL,
    POWER_OFF_FORCE,
    POWER_RESET_GRACEFUL,
    POWER_RESET_FORCE
}power_command_t;

static power_command_t parse_power_command(const char* command)
{
    if(strcmp(command,"on-graceful")==0)
        return POWER_ON_GRACEFUL;
    if(strcmp(command,"on")==0)
        return POWER_ON_GRACEFUL;
    if(strcmp(command,"on-force")==0)
        return POWER_ON_FORCE;
    if(strcmp(command,"off-graceful")==0)
        return POWER_OFF_GRACEFUL;
    if(strcmp(command,"off")==0)
        return POWER_OFF_GRACEFUL;
    if(strcmp(command,"off-force")==0)
        return POWER_OFF_FORCE;
    if(strcmp(command,"reset-graceful")==0)
        return POWER_RESET_GRACEFUL;
    if(strcmp(command,"reset")==0)
        return POWER_RESET_GRACEFUL;
    if(strcmp(command,"reset-force")==0)
        return POWER_RESET_FORCE;
    return POWER_UNKNOWN;
}

const string_quadruple_t* get_dbus_power_interface(power_command_t cmd)
{
    switch(cmd)
    {
    case POWER_OFF_FORCE: return &chassis_dbus;break;

    case POWER_ON_GRACEFUL:
    case POWER_ON_FORCE:
    case POWER_OFF_GRACEFUL:
    case POWER_RESET_GRACEFUL:
    case POWER_RESET_FORCE:
        return &host_dbus;break;
    default: return NULL;
    }
}

const char* get_dbus_power_property_value(power_command_t cmd)
{
    switch(cmd)
    {
    case POWER_ON_GRACEFUL:
    case POWER_ON_FORCE:
        return "xyz.openbmc_project.State.Host.Transition.On";break;
    case POWER_OFF_GRACEFUL:
        return "xyz.openbmc_project.State.Host.Transition.Off";break;
    case POWER_OFF_FORCE:
        return "xyz.openbmc_project.State.Chassis.Transition.Off";break;
    case POWER_RESET_GRACEFUL:
        return "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";break;
    case POWER_RESET_FORCE:
        return "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";break;
    default: return NULL;
    }
}

int com_power( char *arg )
{
    power_command_t cmd = parse_power_command(arg);
    if(cmd==POWER_UNKNOWN) {
        fprintf(stderr, "Unknown command: %s\n", arg);
        return -EOPNOTSUPP;
    }
    const string_quadruple_t* dbus_power_interface = get_dbus_power_interface(cmd);
    if(!dbus_power_interface)
        return -EOPNOTSUPP;
    const char* property_val =  get_dbus_power_property_value(cmd);
    if(!property_val)
        return -EOPNOTSUPP;
    return dbus_set_property_string(dbus_power_interface->first,
                                    dbus_power_interface->second,
                                    dbus_power_interface->third,
                                    dbus_power_interface->fourth,
                                    property_val);
    return 0;
}