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