blob: 07717cfb67a2f0f2fd86acc98778b5f96dda1674 [file] [log] [blame]
Brad Bishop77390492016-04-13 10:47:19 -04001#include "interfaces/openbmc_intf.h"
2#include <stdio.h>
Brad Bishop0c82c602016-04-13 13:36:49 -04003#include <stdlib.h>
Brad Bishop77390492016-04-13 10:47:19 -04004#include <fcntl.h>
5#include "openbmc.h"
6#include "gpio.h"
Brad Bishop77390492016-04-13 10:47:19 -04007
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;
Brad Bishop0c82c602016-04-13 13:36:49 -040073 NEW_VARIANT_U(value);
Brad Bishop77390492016-04-13 10:47:19 -040074 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
Brad Bishop77390492016-04-13 10:47:19 -0400133 manager = g_dbus_object_manager_server_new(dbus_object_path);
134 int i = 0;
135 for(i=0;i<NUM_HWMONS;i++)
136 {
137 if(!is_hwmon_valid(&hwmons[i])) { continue; }
138 gchar *s;
139 s = g_strdup_printf("%s/%s",dbus_object_path,hwmons[i].name);
140 object = object_skeleton_new(s);
141 g_free(s);
142
143 Hwmon *hwmon = hwmon_skeleton_new();
144 object_skeleton_set_hwmon(object, hwmon);
145 g_object_unref(hwmon);
146
147 SensorValue *sensor = sensor_value_skeleton_new();
148 object_skeleton_set_sensor_value(object, sensor);
149 g_object_unref(sensor);
150
Brad Bishop77390492016-04-13 10:47:19 -0400151 hwmon_set_sysfs_path(hwmon,hwmons[i].filename);
152 hwmon_set_scale(hwmon,hwmons[i].scale);
153 sensor_value_set_units(sensor,hwmons[i].units);
154
155 //define method callbacks here
156 g_signal_connect(sensor,
157 "handle-set-value",
158 G_CALLBACK(on_set_value),
159 object); /* user_data */
160
161
162 if(hwmons[i].poll_interval > 0) {
163 g_timeout_add(hwmons[i].poll_interval, poll_hwmon, object);
164 }
165 /* Export the object (@manager takes its own reference to @object) */
Brad Bishop58e694d2016-04-13 16:04:32 -0400166 g_dbus_object_manager_server_set_connection(manager, connection);
Brad Bishop77390492016-04-13 10:47:19 -0400167 g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
168 g_object_unref(object);
169 }
Brad Bishop77390492016-04-13 10:47:19 -0400170}
171
172static void
173on_name_acquired(GDBusConnection *connection,
174 const gchar *name,
175 gpointer user_data)
176{
177}
178
179static void
180on_name_lost(GDBusConnection *connection,
181 const gchar *name,
182 gpointer user_data)
183{
184}
185
186gint
187main(gint argc, gchar *argv[])
188{
189 GMainLoop *loop;
190 cmdline cmd;
191 cmd.argc = argc;
192 cmd.argv = argv;
193
194 guint id;
195 loop = g_main_loop_new(NULL, FALSE);
196
197 id = g_bus_own_name(DBUS_TYPE,
198 dbus_name,
199 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
200 G_BUS_NAME_OWNER_FLAGS_REPLACE,
201 on_bus_acquired,
202 on_name_acquired,
203 on_name_lost,
204 &cmd,
205 NULL);
206
207 g_main_loop_run(loop);
208
209 g_bus_unown_name(id);
210 g_main_loop_unref(loop);
211 return 0;
212}