blob: 06b15546e4b06776a1055f866dbf5a41472e32f9 [file] [log] [blame]
Brad Bishop77390492016-04-13 10:47:19 -04001#include "interfaces/openbmc_intf.h"
2#include <stdio.h>
3#include <fcntl.h>
4#include "openbmc.h"
5#include "gpio.h"
6#include "object_mapper.h"
7
8/* ------------------------------------------------------------------------- */
9static const gchar* dbus_object_path = "/org/openbmc/sensors";
10static const gchar* dbus_name = "org.openbmc.sensors.hwmon";
11
12static GDBusObjectManagerServer *manager = NULL;
13
14typedef struct {
15 const gchar* filename;
16 const gchar* name;
17 int poll_interval;
18 const gchar* units;
19 int scale;
20 int fd;
21} HWMON;
22
23#define NUM_HWMONS 7
24
25// TODO: Don't hardcode
26//Hardcoded for barreleye
27HWMON hwmons[NUM_HWMONS] = {
28 (HWMON){"/sys/class/hwmon/hwmon0/temp1_input","temperature/ambient",3000,"C",1000},
29 (HWMON){"/sys/class/hwmon/hwmon1/pwm1","speed/fan0",30000,"",1},
30 (HWMON){"/sys/class/hwmon/hwmon1/pwm2","speed/fan1",30000,"",1},
31 (HWMON){"/sys/class/hwmon/hwmon1/pwm3","speed/fan2",30000,"",1},
32 (HWMON){"/sys/class/hwmon/hwmon2/pwm1","speed/fan3",30000,"",1},
33 (HWMON){"/sys/class/hwmon/hwmon2/pwm2","speed/fan4",30000,"",1},
34 (HWMON){"/sys/class/hwmon/hwmon2/pwm3","speed/fan5",30000,"",1},
35};
36
37bool
38is_hwmon_valid(HWMON* hwmon)
39{
40 int fd = open(hwmon->filename, O_RDONLY);
41 if(fd == -1)
42 {
43 g_print("ERROR hwmon is not valid: %s\n",hwmon->filename);
44 return false;
45 }
46 close(fd);
47 return true;
48}
49
50static gboolean
51poll_hwmon(gpointer user_data)
52{
53 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
54 SensorValue *sensor = object_get_sensor_value((Object*)user_data);
55 const gchar* filename = hwmon_get_sysfs_path(hwmon);
56
57 int fd = open(filename, O_RDONLY);
58 if(fd != -1)
59 {
60 char buf[255];
61 if(read(fd,&buf,255) == -1)
62 {
63 g_print("ERROR: Unable to read value: %s\n",filename);
64 } else {
65 guint32 scale = hwmon_get_scale(hwmon);
66 if(scale == 0)
67 {
68 g_print("ERROR: Invalid scale value of 0\n");
69 scale = 1;
70
71 }
72 guint32 value = atoi(buf)/scale;
73 GVariant* v = NEW_VARIANT_U(value);
74 GVariant* old_value = sensor_value_get_value(sensor);
75 bool do_set = false;
76 if(old_value == NULL)
77 {
78 do_set = true;
79 }
80 else
81 {
82 if(GET_VARIANT_U(old_value) != value) { do_set = true; }
83 }
84 if(do_set)
85 {
86 g_print("Sensor changed: %s,%d\n",filename,value);
87 GVariant* v = NEW_VARIANT_U(value);
88 const gchar* units = sensor_value_get_units(sensor);
89 sensor_value_set_value(sensor,v);
90 sensor_value_emit_changed(sensor,v,units);
91 }
92 }
93 close(fd);
94 } else {
95 g_print("ERROR - hwmons: File %s doesn't exist\n",filename);
96 }
97
98 return TRUE;
99}
100
101static gboolean
102on_set_value(SensorValue *sensor,
103 GDBusMethodInvocation *invocation,
104 GVariant* v_value,
105 gpointer user_data)
106{
107 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
108 const gchar* filename = hwmon_get_sysfs_path(hwmon);
109
110 int fd = open(filename, O_WRONLY);
111 if(fd != -1)
112 {
113 char buf[255];
114 guint32 value = GET_VARIANT_U(v_value);
115 sprintf(buf,"%d",value);
116 if(write(fd, buf, 255) == -1)
117 {
118 g_print("ERROR: Unable to read value: %s\n",filename);
119 }
120 close(fd);
121 }
122 sensor_value_complete_set_value(sensor,invocation);
123 return TRUE;
124}
125
126static void
127on_bus_acquired(GDBusConnection *connection,
128 const gchar *name,
129 gpointer user_data)
130{
131 ObjectSkeleton *object;
132
133 cmdline *cmd = user_data;
134
135 manager = g_dbus_object_manager_server_new(dbus_object_path);
136 int i = 0;
137 for(i=0;i<NUM_HWMONS;i++)
138 {
139 if(!is_hwmon_valid(&hwmons[i])) { continue; }
140 gchar *s;
141 s = g_strdup_printf("%s/%s",dbus_object_path,hwmons[i].name);
142 object = object_skeleton_new(s);
143 g_free(s);
144
145 Hwmon *hwmon = hwmon_skeleton_new();
146 object_skeleton_set_hwmon(object, hwmon);
147 g_object_unref(hwmon);
148
149 SensorValue *sensor = sensor_value_skeleton_new();
150 object_skeleton_set_sensor_value(object, sensor);
151 g_object_unref(sensor);
152
153 ObjectMapper* mapper = object_mapper_skeleton_new();
154 object_skeleton_set_object_mapper(object, mapper);
155 g_object_unref(mapper);
156
157 hwmon_set_sysfs_path(hwmon,hwmons[i].filename);
158 hwmon_set_scale(hwmon,hwmons[i].scale);
159 sensor_value_set_units(sensor,hwmons[i].units);
160
161 //define method callbacks here
162 g_signal_connect(sensor,
163 "handle-set-value",
164 G_CALLBACK(on_set_value),
165 object); /* user_data */
166
167
168 if(hwmons[i].poll_interval > 0) {
169 g_timeout_add(hwmons[i].poll_interval, poll_hwmon, object);
170 }
171 /* Export the object (@manager takes its own reference to @object) */
172 g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
173 g_object_unref(object);
174 }
175 /* Export all objects */
176 g_dbus_object_manager_server_set_connection(manager, connection);
177 emit_object_added((GDBusObjectManager*)manager);
178}
179
180static void
181on_name_acquired(GDBusConnection *connection,
182 const gchar *name,
183 gpointer user_data)
184{
185}
186
187static void
188on_name_lost(GDBusConnection *connection,
189 const gchar *name,
190 gpointer user_data)
191{
192}
193
194gint
195main(gint argc, gchar *argv[])
196{
197 GMainLoop *loop;
198 cmdline cmd;
199 cmd.argc = argc;
200 cmd.argv = argv;
201
202 guint id;
203 loop = g_main_loop_new(NULL, FALSE);
204
205 id = g_bus_own_name(DBUS_TYPE,
206 dbus_name,
207 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
208 G_BUS_NAME_OWNER_FLAGS_REPLACE,
209 on_bus_acquired,
210 on_name_acquired,
211 on_name_lost,
212 &cmd,
213 NULL);
214
215 g_main_loop_run(loop);
216
217 g_bus_unown_name(id);
218 g_main_loop_unref(loop);
219 return 0;
220}