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 public bool test_pattern (string pattern, bool apply) {
20 string[] key_value = pattern.split ("=");
22 if (key_value.length != 2) {
23 stderr.printf ("pattern does not contain '=': %s\n", pattern);
27 string[] p = key_value[1].split (";");
29 stderr.printf ("pattern does not contain 6 components: %d\n", p.length);
33 if (p[0].has_prefix ("Pattern")) {
34 stderr.printf ("pattern name doesn't start with 'Pattern': '%s'\n", p[0]);
38 // priority = p[0].to_int ();
39 // screen_on = p[1].to_int ();
40 // timeout = p[2].to_int ();
42 int[] led_currents = { 2, 2, 2 };
43 string led_map1 = "000";
47 led_currents = { 8, 0, 2 };
51 led_currents = { 2, 2, 2 };
55 led_currents = { 2, 2, 2 };
59 led_currents = { 20, 2, 0 };
63 // TODO: led_currents?
67 // TODO: led_currents?
71 led_currents = { 8, 2, 2 };
74 stderr.printf ("only single-engine patterns supported for now\n");
78 if (p[4].length > 16*4 || p[5].length > 16*4) {
79 stderr.printf ("pattern too long!\n");
83 if (!(p[4].has_prefix ("9d80"))) {
84 stderr.printf ("engine1 pattern doesn't start with reset mux command\n");
88 if (!(p[4].has_suffix ("0000")) && !(p[4].has_suffix ("c000"))) {
89 stderr.printf ("engine1 pattern doesn't end with repeat or stop command\n");
93 if (p[5] != "9d800000") {
95 stderr.printf ("only single-engine patterns supported for now\n");
102 string i2c_dev = "/sys/bus/i2c/devices/2-0032";
104 var f = FileStream.open ("/sys/class/leds/lp5523:r/led_current", "w");
106 stderr.printf ("failed to set red led current\n");
109 f.printf ("%d\n", led_currents[0]);
111 f = FileStream.open ("/sys/class/leds/lp5523:g/led_current", "w");
113 stderr.printf ("failed to set green led current\n");
116 f.printf ("%d\n", led_currents[1]);
118 f = FileStream.open ("/sys/class/leds/lp5523:b/led_current", "w");
120 stderr.printf ("failed to set blue led current\n");
123 f.printf ("%d\n", led_currents[2]);
125 f = FileStream.open (Path.build_filename (i2c_dev, "engine1_mode"), "w");
127 stderr.printf ("failed to set engine1 to load mode\n");
133 for (int i = 0; i < retries; i++) {
134 f = FileStream.open (Path.build_filename (i2c_dev, "engine1_leds"), "w");
139 stderr.printf ("failed to set engine1 mux\n");
142 f.printf ("0000%s00\n", led_map1);
144 f = FileStream.open (Path.build_filename (i2c_dev, "engine1_load"), "w");
146 stderr.printf ("failed to load engine1 pattern\n");
149 f.printf ("%s\n", p[4]);
151 f = FileStream.open (Path.build_filename (i2c_dev, "engine1_mode"), "w");
153 stderr.printf ("failed to set engine1 to run mode\n");
161 bool mce_ini_check (string new_mce_ini) {
162 var f = FileStream.open ("/etc/mce/mce.ini", "r");
163 var g = FileStream.open (new_mce_ini, "r");
165 if (f == null || g == null) {
166 stderr.printf ("failed to open /etc/mce/mce.ini and %s\n", new_mce_ini);
170 var line1 = f.read_line ();
171 var line2 = g.read_line ();
172 while (line1 != null && line2 != null) {
173 if (line1 == line2) {
174 line1 = f.read_line ();
175 line2 = g.read_line ();
179 string[] key_value1 = line1.split ("=");
180 string[] key_value2 = line2.split ("=");
182 if (key_value1.length != 2 || key_value2.length != 2 || !line1.has_prefix ("Pattern")) {
183 stderr.printf ("not allowed to change anything but led patterns:\n-%s\n+%s\n",
188 if (key_value1[0] != key_value2[0]) {
189 stderr.printf ("not allowed to change pattern names\n-%s\n+%s\n",
194 if (!test_pattern (line2, false))
197 line1 = f.read_line ();
198 line2 = g.read_line ();
201 if (line1 != line2) {
202 stderr.printf ("different number of lines\n");
209 int mce_copy (string source, string destination) {
210 var f = FileStream.open (source, "r");
211 var g = FileStream.open (destination, "w");
213 if (f == null || g == null) {
217 var line = f.read_line ();
218 while (line != null) {
219 g.printf ("%s\n", line);
220 line = f.read_line ();
226 public static int main (string[] args) {
227 string usage = "usage: led-pattern-helper test <Pattern>\n";
229 if (args.length != 3) {
230 stderr.printf (usage);
234 if (args[1] == "test") {
235 if (!test_pattern (args[2], true))
241 if (args[1] == "save") {
242 if (!FileUtils.test (args[2], FileTest.IS_REGULAR)) {
243 stderr.printf ("not a regular file: %s\n", args[2]);
247 if (!mce_ini_check (args[2]))
250 // Ok, we're good to go
251 int result = mce_copy ("/etc/mce/mce.ini", "/etc/mce/mce.ini.led-pattern-old");
253 stderr.printf ("failed to copy old mce.ini to mce.ini.led-pattern-old\n");
256 result = mce_copy (args[2], "/etc/mce/mce.ini.led-pattern-new");
258 stderr.printf ("failed to copy new mce.ini to mce.ini.led-pattern-new\n");
261 result = FileUtils.rename ("/etc/mce/mce.ini.led-pattern-new", "/etc/mce/mce.ini");
263 stderr.printf ("failed to replace MCE configuration: %d\n", result);
267 // Moment of truth, restart MCE
271 var command = "initctl stop mce";
272 Process.spawn_command_line_sync (command, null, out error, out exit_status);
273 if (exit_status != 0) {
274 stderr.printf ("stopping mce failed: %d\n%s", exit_status, error);
278 Process.spawn_command_line_sync (command, null, out error, out exit_status);
279 command = "initctl start mce";
280 Process.spawn_command_line_sync (command, null, out error, out exit_status);
281 if (exit_status != 0) {
282 stderr.printf ("starting mce failed: %d\n%s", exit_status, error);
285 } catch (SpawnError e) {
286 stderr.printf ("restarting mce failed: %s", e.message);
293 stderr.printf (usage);