Fixed strict prototype warnings passed by gcc -Wmissing-prototypes -Wstrict-prototypes
[olsrd.git] / src / linux / apm.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2003 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: apm.c,v 1.8 2004/10/09 22:32:47 kattemat Exp $
23  *
24  */
25
26 /*
27  * Much of the ACPI code is taken from Florian Schaefers
28  * Acpi-Power Enlightenment epplet
29  */
30
31 #include "../apm.h"
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35
36 #warning ACPI code not tested!!!!
37
38 /* APM related stuff */
39
40 #define APM_PROC "/proc/apm"
41
42 struct linux_apm_info
43 {
44   char driver_version[10];
45   int apm_version_major;
46   int apm_version_minor;
47   int apm_flags;
48   int ac_line_status;
49   int battery_status;
50   int battery_flags;
51   int battery_percentage;
52   int battery_time;
53   int using_minutes;
54 };
55
56
57 /* ACPI related stuff */
58
59 #define ACPI_PROC "/proc/acpi/info"
60
61 const static char * acpi_info[] = 
62   {
63     "/proc/acpi/battery/0/info",
64     "/proc/acpi/battery/1/info",
65     "/proc/acpi/battery/BATA/info",
66     "/proc/acpi/battery/BAT0/info",
67     "/proc/acpi/battery/BAT1/info" 
68   };
69
70 const static char * acpi_state[] =
71   {    
72     "/proc/acpi/battery/0/status",
73     "/proc/acpi/battery/1/status",
74     "/proc/acpi/battery/BATA/state",
75     "/proc/acpi/battery/BAT0/state",
76     "/proc/acpi/battery/BAT1/state" 
77   };
78
79
80 #define ACPI_BT_CNT  (sizeof(acpi_state) / sizeof(char *))
81
82
83 const static char * acpi_ac[] = 
84   {    
85     "/proc/acpi/ac_adapter/0/status",
86     "/proc/acpi/ac_adapter/AC/state",
87     "/proc/acpi/ac_adapter/ACAD/state" 
88   };
89
90 #define ACPI_AC_CNT  (sizeof(acpi_ac) / sizeof(char *))
91
92
93 #define USE_APM    1
94 #define USE_ACPI   2
95
96 static int method, fd_index;
97
98 /* Prototypes */
99
100 extern int
101 olsr_printf(int, char *, ...);
102
103 static int
104 apm_read_apm(struct olsr_apm_info *);
105
106 static int
107 apm_read_acpi(struct olsr_apm_info *);
108
109 static int
110 acpi_probe(void);
111
112
113 int 
114 apm_init()
115 {
116   struct olsr_apm_info ainfo;
117
118   method = -1;
119   olsr_printf(3, "Initializing APM\n");
120
121   if(((fd_index = acpi_probe()) >= 0) && apm_read_acpi(&ainfo))
122     method = USE_ACPI;
123   else if(apm_read_apm(&ainfo))
124     method = USE_APM;
125   
126   if(method)
127     apm_printinfo(&ainfo);
128
129   return method;
130 }
131
132 void
133 apm_printinfo(struct olsr_apm_info *ainfo)
134 {
135   olsr_printf(5, "APM info:\n\tAC status %d\n\tBattery percentage %d%%\n\n",
136               ainfo->ac_line_status,
137               ainfo->battery_percentage);
138
139   return;
140 }
141
142
143
144 int
145 apm_read(struct olsr_apm_info *ainfo)
146 {
147
148   switch(method)
149     {
150     case(USE_APM):
151       return apm_read_apm(ainfo);
152       break;
153     case(USE_ACPI):
154       return apm_read_acpi(ainfo);
155       break;
156     default:
157       return 0;
158       break;
159     }
160
161   return 1;
162 }
163
164
165
166
167
168 static int
169 apm_read_apm(struct olsr_apm_info *ainfo)
170 {
171   char buffer[100];
172   char units[10];
173   FILE *apm_procfile;
174   struct linux_apm_info lainfo;
175
176   /* Open procfile */
177   if((apm_procfile = fopen(APM_PROC, "r")) == NULL)
178     return 0;
179
180
181   fgets(buffer, sizeof(buffer) - 1, apm_procfile);
182   if(buffer == NULL)
183     {
184       /* Try re-opening the file */
185       if((apm_procfile = fopen(APM_PROC, "r")) < 0)
186         return 0;
187       fgets(buffer, sizeof(buffer) - 1, apm_procfile);
188       if(buffer == NULL)
189         {
190           /* Giving up */
191           fprintf(stderr, "OLSRD: Could not read APM info - setting willingness to default");
192           fclose(apm_procfile);
193           return 0;
194         }
195     }
196
197   buffer[sizeof(buffer) - 1] = '\0';
198
199   //printf("READ: %s\n", buffer);
200
201   /* Get the info */
202   sscanf(buffer, "%s %d.%d %x %x %x %x %d%% %d %s\n",
203          lainfo.driver_version,
204          &lainfo.apm_version_major,
205          &lainfo.apm_version_minor,
206          &lainfo.apm_flags,
207          &lainfo.ac_line_status,
208          &lainfo.battery_status,
209          &lainfo.battery_flags,
210          &lainfo.battery_percentage,
211          &lainfo.battery_time,
212          units);
213
214   lainfo.using_minutes = !strncmp(units, "min", 3) ? 1 : 0;
215
216   /*
217    * Should take care of old APM type info here
218    */
219
220   /*
221    * Fix possible percentage error
222    */
223   if(lainfo.battery_percentage > 100)
224     lainfo.battery_percentage = -1;
225
226   /* Fill the provided struct */
227
228   if(lainfo.ac_line_status)
229     ainfo->ac_line_status = OLSR_AC_POWERED;
230   else
231     ainfo->ac_line_status = OLSR_BATTERY_POWERED;
232   
233   ainfo->battery_percentage = lainfo.battery_percentage;
234   
235   fclose(apm_procfile);
236
237   return 1;
238 }
239
240
241
242 static int
243 apm_read_acpi(struct olsr_apm_info *ainfo)
244 {
245   FILE *fd;
246   char s1[32], s2[32], s3[32], s4[32], inbuff[127];
247   int bat_max = 5000; /* Find some sane value */
248   int bat_val = 0;
249   
250   printf("READING ACPI\n");
251
252
253   if(fd_index < 0)
254     {
255       /* No battery was found or AC power was detected */
256       ainfo->ac_line_status = OLSR_AC_POWERED;
257       ainfo->battery_percentage = 100;
258       return 1;
259     }
260
261
262   /* Get maxvalue */
263   if((fd = fopen(acpi_info[fd_index], "r")) == NULL) 
264     return 0;
265
266   fgets(inbuff, 127, fd);
267   while(!feof(fd)) 
268     {
269       sscanf(inbuff, "%s %s %s %s", s1, s2, s3, s4);
270         
271       if (!strcasecmp(s2, "full")) 
272         {
273           bat_max = atoi(s4);
274         }
275
276       fgets(inbuff, 127, fd);
277     }
278   fclose(fd);
279
280
281   if((fd = fopen(acpi_state[fd_index], "r")) == NULL) 
282     return 0;
283
284   /* Extract battery status */
285   fgets(inbuff, 127, fd);
286   while(!feof(fd)) 
287     {
288       sscanf(inbuff, "%s %s %s %s", s1, s2, s3, s4);
289
290       /* find remaining juice */
291       if(!strcasecmp(s1, "Remaining")) 
292         {
293           bat_val = atoi(s3);
294         }
295
296       fgets(inbuff, 127, fd);
297     }
298
299   fclose(fd);
300
301
302   ainfo->ac_line_status = OLSR_BATTERY_POWERED;
303   ainfo->battery_percentage = bat_val * 100 / bat_max;
304
305   return 1;
306 }
307
308
309
310 static int
311 acpi_probe()
312 {
313   char s1[32], s2[32];
314   FILE *fd;
315   int i;
316   
317
318   /* First check for AC power */
319
320   for(i = 0; i < ACPI_AC_CNT; i++)
321     {
322       /* Try opening the info file */
323       if((fd = fopen(acpi_ac[i], "r")) == NULL)
324         continue;
325       
326       /* Extract info */
327       if(fscanf(fd, "%s %s", s1, s2) < 2)
328         {
329           fclose(fd);
330           continue;
331         }
332       
333       /* Close info entry */
334       fclose(fd);
335
336       /* Running on AC power */
337       if(!strcasecmp(s2, "on-line"))
338         return -1;
339
340     }
341
342   /* Only checking the first found batery entry... */
343   for(i = 0; i < ACPI_BT_CNT; i ++)
344     {
345
346       /* Try opening the info file */
347       if((fd = fopen(acpi_info[i], "r")) == NULL)
348         continue;
349
350       /* Extract info */
351       if(fscanf(fd, "%s %s", s1, s2) < 2)
352         {
353           fclose(fd);
354           continue;
355         }
356
357       /* Close info entry */
358       fclose(fd);
359
360       /* Check if battery is present */
361       if((!strcasecmp(s1, "present:")) && (!strcasecmp(s2, "no"))) 
362         continue;
363
364       /* Open the corresponding state file */
365       if((fd = fopen(acpi_state[i], "r")) == NULL)
366         continue;
367
368       fclose(fd);
369
370       return i;
371     }
372
373   /* No battery found */
374   return -1;
375 }
376