3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of olsr.org, olsrd nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
34 * Visit http://www.olsr.org for more information.
36 * If you find this software useful feel free to make a donation
37 * to the project. For more information see the website or contact
38 * the copyright holders.
43 * Much of the ACPI code is taken from Florian Schaefers
44 * Acpi-Power Enlightenment epplet
53 /* APM related stuff */
55 #define APM_PROC "/proc/apm"
57 struct linux_apm_info {
58 char driver_version[10];
59 int apm_version_major;
60 int apm_version_minor;
65 int battery_percentage;
70 /* ACPI related stuff */
71 static const char *const acpi_info[] = {
72 "/proc/acpi/battery/0/info",
73 "/proc/acpi/battery/1/info",
74 "/proc/acpi/battery/BATA/info",
75 "/proc/acpi/battery/BAT0/info",
76 "/proc/acpi/battery/BAT1/info"
79 static const char *const acpi_state[] = {
80 "/proc/acpi/battery/0/status",
81 "/proc/acpi/battery/1/status",
82 "/proc/acpi/battery/BATA/state",
83 "/proc/acpi/battery/BAT0/state",
84 "/proc/acpi/battery/BAT1/state"
87 #define ACPI_BT_CNT ARRAYSIZE(acpi_state)
89 static const char *const acpi_ac[] = {
90 "/proc/acpi/ac_adapter/0/status",
91 "/proc/acpi/ac_adapter/AC/state",
92 "/proc/acpi/ac_adapter/ACAD/state"
95 #define ACPI_AC_CNT ARRAYSIZE(acpi_ac)
104 static int ac_power_on;
108 static int apm_read_apm(struct olsr_apm_info *);
110 static int apm_read_acpi(struct olsr_apm_info *);
112 static int acpi_probe(void);
117 struct olsr_apm_info ainfo;
120 OLSR_PRINTF(3, "Initializing APM\n");
122 if ((((fd_index = acpi_probe()) >= 0) || ac_power_on) && apm_read_acpi(&ainfo))
124 else if (apm_read_apm(&ainfo))
128 apm_printinfo(&ainfo);
134 apm_printinfo(struct olsr_apm_info *ainfo)
136 OLSR_PRINTF(5, "APM info:\n\tAC status %d\n\tBattery percentage %d%%\n\tBattery time left %d mins\n\n", ainfo->ac_line_status,
137 ainfo->battery_percentage, ainfo->battery_time_left);
139 ainfo = NULL; /* squelch compiler warnings */
143 apm_read(struct olsr_apm_info *ainfo)
147 return apm_read_apm(ainfo);
149 return apm_read_acpi(ainfo);
157 apm_read_apm(struct olsr_apm_info *ainfo)
162 struct linux_apm_info lainfo;
165 if ((apm_procfile = fopen(APM_PROC, "r")) == NULL)
168 if (fgets(buffer, sizeof(buffer), apm_procfile) == NULL) {
169 fclose(apm_procfile);
170 /* Try re-opening the file */
171 if ((apm_procfile = fopen(APM_PROC, "r")) == NULL)
174 if (fgets(buffer, sizeof(buffer), apm_procfile) == NULL) {
176 fprintf(stderr, "OLSRD: Could not read APM info - setting willingness to default");
177 fclose(apm_procfile);
181 fclose(apm_procfile);
183 //printf("READ: %s\n", buffer);
186 sscanf(buffer, "%10s %d.%d %x %x %x %x %d%% %d %10s\n", lainfo.driver_version, &lainfo.apm_version_major, &lainfo.apm_version_minor,
187 &lainfo.apm_flags, &lainfo.ac_line_status, &lainfo.battery_status, &lainfo.battery_flags, &lainfo.battery_percentage,
188 &lainfo.battery_time, units);
190 lainfo.using_minutes = strncmp(units, "min", 3) ? 0 : 1;
193 * Should take care of old APM type info here
197 * Fix possible percentage error
199 if (lainfo.battery_percentage > 100)
200 lainfo.battery_percentage = -1;
202 /* Fill the provided struct */
204 if (lainfo.ac_line_status)
205 ainfo->ac_line_status = OLSR_AC_POWERED;
207 ainfo->ac_line_status = OLSR_BATTERY_POWERED;
209 ainfo->battery_percentage = lainfo.battery_percentage;
210 ainfo->battery_time_left = lainfo.battery_time;
216 apm_read_acpi(struct olsr_apm_info *ainfo)
219 int bat_max = 5000; /* Find some sane value */
223 /* reporbe in case ac status changed */
224 fd_index = acpi_probe();
226 /* No battery was found */
230 ainfo->ac_line_status = OLSR_AC_POWERED;
232 ainfo->battery_percentage = -1;
237 /* not enough info */
242 if ((fd = fopen(acpi_info[fd_index], "r")) == NULL)
246 char s1[32], s2[32], s3[32], s4[32], inbuff[127];
247 if (fgets(inbuff, sizeof(inbuff), fd) == NULL)
250 sscanf(inbuff, "%32s %32s %32s %32s", s1, s2, s3, s4);
251 if (!strcasecmp(s2, "full"))
256 if ((fd = fopen(acpi_state[fd_index], "r")) == NULL)
259 /* Extract battery status */
261 char s1[32], s2[32], s3[32], s4[32], inbuff[127];
262 if (fgets(inbuff, sizeof(inbuff), fd) == NULL)
264 sscanf(inbuff, "%32s %32s %32s %32s", s1, s2, s3, s4);
266 /* find remaining juice */
267 if (!strcasecmp(s1, "Remaining"))
272 ainfo->ac_line_status = ac_power_on ? OLSR_AC_POWERED : OLSR_BATTERY_POWERED;
275 /* protection against stupid acpi data */
276 ainfo->battery_percentage = 0;
279 result = bat_val * 100 / bat_max;
281 ainfo->battery_percentage = result > 100 ? 100 : result;
292 /* First check for AC power */
295 for (i = 0; i < ACPI_AC_CNT; i++) {
298 FILE *fd = fopen(acpi_ac[i], "r");
300 /* Try opening the info file */
305 rc = fscanf(fd, "%32s %32s", s1, s2);
307 /* Close info entry */
313 /* Running on AC power */
314 if (!strcasecmp(s2, "on-line")) {
316 /* ac power enabled */
323 /* Only checking the first found battery entry... */
324 for (i = 0; i < ACPI_BT_CNT; i++) {
327 FILE *fd = fopen(acpi_info[i], "r");
329 /* Try opening the info file */
334 rc = fscanf(fd, "%32s %32s", s1, s2);
336 /* Close info entry */
342 /* Check if battery is present */
343 if ((!strcasecmp(s1, "present:")) && (!strcasecmp(s2, "no")))
346 /* Open the corresponding state file */
347 if ((fd = fopen(acpi_state[i], "r")) == NULL)
354 /* No battery found */
361 * indent-tabs-mode: nil