blob: c38a3c974396fd31289c3b0c1e866428a9a8dbe2 [file] [log] [blame]
Norman James47327082015-11-24 10:32:29 -06001#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 1
24
25// TODO: Don't hardcode
26//Hardcoded for palmetto
27HWMON hwmons[NUM_HWMONS] = {
28 (HWMON){"/sys/class/hwmon/hwmon0/temp1_input","temperature/ambient",3000,"C",1000},
29};
30bool is_hwmon_valid(HWMON* hwmon)
31{
32 int fd = open(hwmon->filename, O_RDONLY);
33 if (fd == -1)
34 {
35 g_print("ERROR hwmon is not valid: %s\n",hwmon->filename);
36 return false;
37 }
38 close(fd);
39 return true;
40}
41
42static gboolean poll_hwmon(gpointer user_data)
43{
44 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
45 SensorValue *sensor = object_get_sensor_value((Object*)user_data);
46 const gchar* filename = hwmon_get_sysfs_path(hwmon);
47
48 int fd = open(filename, O_RDONLY);
49 if (fd != -1)
50 {
51 char buf[255];
52 if (read(fd,&buf,255) == -1)
53 {
54 g_print("ERROR: Unable to read value: %s\n",filename);
55 } else {
56 guint32 scale = hwmon_get_scale(hwmon);
57 if (scale == 0)
58 {
59 g_print("ERROR: Invalid scale value of 0\n");
60 scale = 1;
61
62 }
63 guint32 value = atoi(buf)/scale;
64 GVariant* v = NEW_VARIANT_U(value);
65 GVariant* old_value = sensor_value_get_value(sensor);
66 bool do_set = false;
67 if (old_value == NULL)
68 {
69 do_set = true;
70 }
71 else
72 {
73 if (GET_VARIANT_U(old_value) != value) { do_set = true; }
74 }
75 if (do_set)
76 {
77 g_print("Sensor changed: %s,%d\n",filename,value);
78 GVariant* v = NEW_VARIANT_U(value);
79 const gchar* units = sensor_value_get_units(sensor);
80 sensor_value_set_value(sensor,v);
81 sensor_value_emit_changed(sensor,v,units);
82 }
83 }
84 close(fd);
85 } else {
86 g_print("ERROR - hwmons: File %s doesn't exist\n",filename);
87 }
88
89 return TRUE;
90}
91static gboolean
92on_set_value (SensorValue *sensor,
93 GDBusMethodInvocation *invocation,
94 GVariant* v_value,
95 gpointer user_data)
96{
97 Hwmon *hwmon = object_get_hwmon((Object*)user_data);
98 const gchar* filename = hwmon_get_sysfs_path(hwmon);
99
100 int fd = open(filename, O_WRONLY);
101 if (fd != -1)
102 {
103 char buf[255];
104 guint32 value = GET_VARIANT_U(v_value);
105 sprintf(buf,"%d",value);
106 if (write(fd, buf, 255) == -1)
107 {
108 g_print("ERROR: Unable to read value: %s\n",filename);
109 }
110 close(fd);
111 }
112 sensor_value_complete_set_value(sensor,invocation);
113 return TRUE;
114}
115
116
117
118static void
119on_bus_acquired (GDBusConnection *connection,
120 const gchar *name,
121 gpointer user_data)
122{
123 ObjectSkeleton *object;
124
125 cmdline *cmd = user_data;
126
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
146 ObjectMapper* mapper = object_mapper_skeleton_new ();
147 object_skeleton_set_object_mapper (object, mapper);
148 g_object_unref (mapper);
149
150 hwmon_set_sysfs_path(hwmon,hwmons[i].filename);
151 hwmon_set_scale(hwmon,hwmons[i].scale);
152 sensor_value_set_units(sensor,hwmons[i].units);
153
154 //define method callbacks here
155 g_signal_connect (sensor,
156 "handle-set-value",
157 G_CALLBACK (on_set_value),
158 object); /* user_data */
159
160
161 if (hwmons[i].poll_interval > 0) {
162 g_timeout_add(hwmons[i].poll_interval, poll_hwmon, object);
163 }
164 /* Export the object (@manager takes its own reference to @object) */
165 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
166 g_object_unref (object);
167 }
168 /* Export all objects */
169 g_dbus_object_manager_server_set_connection (manager, connection);
170 emit_object_added((GDBusObjectManager*)manager);
171}
172
173
174static void
175on_name_acquired (GDBusConnection *connection,
176 const gchar *name,
177 gpointer user_data)
178{
179}
180
181static void
182on_name_lost (GDBusConnection *connection,
183 const gchar *name,
184 gpointer user_data)
185{
186}
187
188
189gint
190main (gint argc, gchar *argv[])
191{
192 GMainLoop *loop;
193 cmdline cmd;
194 cmd.argc = argc;
195 cmd.argv = argv;
196
197 guint id;
198 loop = g_main_loop_new (NULL, FALSE);
199
200 id = g_bus_own_name (DBUS_TYPE,
201 dbus_name,
202 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
203 G_BUS_NAME_OWNER_FLAGS_REPLACE,
204 on_bus_acquired,
205 on_name_acquired,
206 on_name_lost,
207 &cmd,
208 NULL);
209
210 g_main_loop_run (loop);
211
212 g_bus_unown_name (id);
213 g_main_loop_unref (loop);
214 return 0;
215}