1 /* This file is part of LED Pattern Editor.
3 * Copyright (C) 2010 Philipp Zabel
5 * LED Pattern Editor is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * LED Pattern Editor is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with LED Pattern Editor. If not, see <http://www.gnu.org/licenses/>.
19 bool sysfs_write (string filename, string contents) {
20 var f = FileStream.open (filename, "w");
22 stderr.printf ("failed to open '%s' for writing\n", filename);
25 f.printf ("%s", contents);
29 public bool test_pattern (string pattern, bool apply) {
30 string[] key_value = pattern.split ("=");
32 if (key_value.length != 2) {
33 stderr.printf ("pattern does not contain '=': %s\n", pattern);
37 string[] p = key_value[1].split (";");
39 stderr.printf ("pattern does not contain 6 components: %d\n", p.length);
43 if (p[0].has_prefix ("Pattern")) {
44 stderr.printf ("pattern name doesn't start with 'Pattern': '%s'\n", p[0]);
48 // priority = p[0].to_int ();
49 // screen_on = p[1].to_int ();
50 // timeout = p[2].to_int ();
67 if ((led_map1 & led_map2) != 0) {
68 stderr.printf ("pattern assigns a led to both channels: '%s'\n", p[3]);
73 if (0x001 in led_map1)
75 if (0x001 in led_map2)
77 if (0x010 in led_map1)
79 if (0x010 in led_map2)
81 if (0x100 in led_map1)
83 if (0x100 in led_map2)
86 if (led_map != p[3]) {
87 stderr.printf ("pattern contains invalid led map: '%s\n", p[3]);
91 string[] led_currents = { "2", "2", "2" };
92 switch (led_map1 | led_map2) {
94 led_currents = { "8", "0", "2" };
97 led_currents = { "2", "2", "2" };
100 led_currents = { "2", "2", "2" };
103 led_currents = { "20", "2", "0" };
106 // TODO: led_currents?
109 // TODO: led_currents?
112 led_currents = { "8", "2", "2" };
116 if (p[4].length > 16*4 || p[5].length > 16*4) {
117 stderr.printf ("engine1 pattern too long!\n");
121 if (!(p[4].has_prefix ("9d80"))) {
122 stderr.printf ("engine1 pattern doesn't start with reset mux command\n");
126 if (!(p[4].has_suffix ("0000")) && !(p[4].has_suffix ("c000"))) {
127 stderr.printf ("engine1 pattern doesn't end with repeat or stop command\n");
131 if (p[5].length > 16*4 || p[5].length > 16*4) {
132 stderr.printf ("engine2 pattern too long!\n");
136 if (!(p[5].has_prefix ("9d80"))) {
137 stderr.printf ("engine2 pattern doesn't start with reset mux command\n");
141 if (!(p[5].has_suffix ("0000")) && !(p[5].has_suffix ("c000"))) {
142 stderr.printf ("engine2 pattern doesn't end with repeat or stop command\n");
149 string mux1 = "0000%03x00\n".printf (led_map1);
150 string mux2 = "0000%03x00\n".printf (led_map2);
151 string pattern1 = p[4];
152 string pattern2 = p[5];
154 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "disabled");
155 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "disabled");
156 sysfs_write ("/sys/class/leds/lp5523:r/brightness", "0");
157 sysfs_write ("/sys/class/leds/lp5523:g/brightness", "0");
158 sysfs_write ("/sys/class/leds/lp5523:b/brightness", "0");
160 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "load");
161 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_leds", mux1);
162 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_load", pattern1);
163 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "load");
164 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_leds", mux2);
165 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_load", pattern2);
166 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine2_mode", "run");
167 sysfs_write ("/sys/class/i2c-adapter/i2c-2/2-0032/engine1_mode", "run");
169 sysfs_write ("/sys/class/leds/lp5523:r/led_current", led_currents[0]);
170 sysfs_write ("/sys/class/leds/lp5523:g/led_current", led_currents[1]);
171 sysfs_write ("/sys/class/leds/lp5523:b/led_current", led_currents[2]);
176 bool mce_ini_check (string new_mce_ini) {
177 var f = FileStream.open ("/etc/mce/mce.ini", "r");
178 var g = FileStream.open (new_mce_ini, "r");
180 if (f == null || g == null) {
181 stderr.printf ("failed to open /etc/mce/mce.ini and %s\n", new_mce_ini);
185 var line1 = f.read_line ();
186 var line2 = g.read_line ();
187 while (line1 != null && line2 != null) {
188 if (line1 == line2) {
189 line1 = f.read_line ();
190 line2 = g.read_line ();
194 string[] key_value1 = line1.split ("=");
195 string[] key_value2 = line2.split ("=");
197 if (key_value1.length != 2 || key_value2.length != 2 || !line1.has_prefix ("Pattern")) {
198 stderr.printf ("not allowed to change anything but led patterns:\n-%s\n+%s\n",
203 if (key_value1[0] != key_value2[0]) {
204 stderr.printf ("not allowed to change pattern names\n-%s\n+%s\n",
209 if (!test_pattern (line2, false))
212 line1 = f.read_line ();
213 line2 = g.read_line ();
216 if (line1 != line2) {
217 stderr.printf ("different number of lines\n");
224 int mce_copy (string source, string destination) {
225 var f = FileStream.open (source, "r");
226 var g = FileStream.open (destination, "w");
228 if (f == null || g == null) {
232 var line = f.read_line ();
233 while (line != null) {
234 g.printf ("%s\n", line);
235 line = f.read_line ();
241 public static int main (string[] args) {
242 string usage = "usage: led-pattern-helper test <Pattern>\n";
244 if (args.length != 3) {
245 stderr.printf (usage);
249 if (args[1] == "test") {
250 if (!test_pattern (args[2], true))
256 if (args[1] == "save") {
257 if (!FileUtils.test (args[2], FileTest.IS_REGULAR)) {
258 stderr.printf ("not a regular file: %s\n", args[2]);
262 if (!mce_ini_check (args[2]))
265 // Ok, we're good to go
266 int result = mce_copy ("/etc/mce/mce.ini", "/etc/mce/mce.ini.led-pattern-old");
268 stderr.printf ("failed to copy old mce.ini to mce.ini.led-pattern-old\n");
271 result = mce_copy (args[2], "/etc/mce/mce.ini.led-pattern-new");
273 stderr.printf ("failed to copy new mce.ini to mce.ini.led-pattern-new\n");
276 result = FileUtils.rename ("/etc/mce/mce.ini.led-pattern-new", "/etc/mce/mce.ini");
278 stderr.printf ("failed to replace MCE configuration: %d\n", result);
282 // Moment of truth, restart MCE
286 var command = "initctl stop mce";
287 Process.spawn_command_line_sync (command, null, out error, out exit_status);
288 if (exit_status != 0) {
289 stderr.printf ("stopping mce failed: %d\n%s", exit_status, error);
293 Process.spawn_command_line_sync (command, null, out error, out exit_status);
294 command = "initctl start mce";
295 Process.spawn_command_line_sync (command, null, out error, out exit_status);
296 if (exit_status != 0) {
297 stderr.printf ("starting mce failed: %d\n%s", exit_status, error);
300 } catch (SpawnError e) {
301 stderr.printf ("restarting mce failed: %s", e.message);
308 stderr.printf (usage);