Added preliminary ACPI support - NOT TESTED
authorAndreas Tonnesen <andreto@olsr.org>
Sat, 2 Oct 2004 12:02:06 +0000 (12:02 +0000)
committerAndreas Tonnesen <andreto@olsr.org>
Sat, 2 Oct 2004 12:02:06 +0000 (12:02 +0000)
src/linux/apm.c

index 6d3ca9e..d35ac62 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  * 
  * 
- * $Id: apm.c,v 1.5 2004/09/21 19:08:58 kattemat Exp $
+ * $Id: apm.c,v 1.6 2004/10/02 12:02:06 kattemat Exp $
  *
  */
 
+/*
+ * Much of the ACPI code is taken from Florian Schaefers
+ * Acpi-Power Enlightenment epplet
+ */
+
 #include "../apm.h"
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
+
+#warning ACPI code not tested!!!!
+
+/* APM related stuff */
 
 #define APM_PROC "/proc/apm"
 
@@ -44,21 +54,79 @@ struct linux_apm_info
 };
 
 
+/* ACPI related stuff */
+
+#define ACPI_PROC "/proc/acpi/info"
+
+const static char * acpi_info[] = 
+  {
+    "/proc/acpi/battery/0/info",
+    "/proc/acpi/battery/1/info",
+    "/proc/acpi/battery/BATA/info",
+    "/proc/acpi/battery/BAT0/info",
+    "/proc/acpi/battery/BAT1/info" 
+  };
+
+const static char * acpi_state[] =
+  {    
+    "/proc/acpi/battery/0/status",
+    "/proc/acpi/battery/1/status",
+    "/proc/acpi/battery/BATA/state",
+    "/proc/acpi/battery/BAT0/state",
+    "/proc/acpi/battery/BAT1/state" 
+  };
+
+
+#define ACPI_BT_CNT  (sizeof(acpi_state) / sizeof(char *))
+
+
+const static char * acpi_ac[] = 
+  {    
+    "/proc/acpi/ac_adapter/0/status",
+    "/proc/acpi/ac_adapter/AC/state",
+    "/proc/acpi/ac_adapter/ACAD/state" 
+  };
+
+#define ACPI_AC_CNT  (sizeof(acpi_ac) / sizeof(char *))
+
+
+#define USE_APM    1
+#define USE_ACPI   2
+
+static int method;
+
+/* Prototypes */
+
 extern int
 olsr_printf(int, char *, ...);
 
+static int
+apm_read_apm(struct olsr_apm_info *);
+
+static int
+apm_read_acpi(struct olsr_apm_info *);
+
+static int
+acpi_probe();
+
 
 int 
 apm_init()
 {
   struct olsr_apm_info ainfo;
 
+  method = -1;
   olsr_printf(3, "Initializing APM\n");
 
-  if(apm_read(&ainfo))
+  if(apm_read_apm(&ainfo))
+    method = USE_APM;
+  if(apm_read_acpi(&ainfo))
+    method = USE_ACPI;
+
+  if(method)
     apm_printinfo(&ainfo);
 
-  return 1;
+  return method;
 }
 
 void
@@ -72,8 +140,33 @@ apm_printinfo(struct olsr_apm_info *ainfo)
 }
 
 
+
 int
 apm_read(struct olsr_apm_info *ainfo)
+{
+
+  switch(method)
+    {
+    case(USE_APM):
+      return apm_read_apm(ainfo);
+      break;
+    case(USE_ACPI):
+      return apm_read_acpi(ainfo);
+      break;
+    default:
+      return 0;
+      break;
+    }
+
+  return 1;
+}
+
+
+
+
+
+static int
+apm_read_apm(struct olsr_apm_info *ainfo)
 {
   char buffer[100];
   char units[10];
@@ -143,3 +236,148 @@ apm_read(struct olsr_apm_info *ainfo)
 
   return 1;
 }
+
+
+
+static int
+apm_read_acpi(struct olsr_apm_info *ainfo)
+{
+  FILE *fd;
+  char s1[32], s2[32], s3[32], s4[32], inbuff[127];
+  int fd_index;
+  int bat_max = 5000; /* Find some sane value */
+  int bat_val = 0;
+
+  /* Check for ACPI support */
+  if((fd = fopen(ACPI_PROC, "r")) == NULL) 
+    return 0;
+
+  fclose(fd);
+  
+  printf("READING ACPI\n");
+
+
+  if((fd_index = acpi_probe()) < 0)
+    {
+      /* No battery was found or AC power was detected */
+      ainfo->ac_line_status = OLSR_AC_POWERED;
+      ainfo->battery_percentage = 100;
+      return 1;
+    }
+
+
+  /* Get maxvalue */
+  if((fd = fopen(acpi_info[fd_index], "r")) == NULL) 
+    return 0;
+
+  fgets(inbuff, 127, fd);
+  while(!feof(fd)) 
+    {
+      sscanf(inbuff, "%s %s %s %s", s1, s2, s3, s4);
+       
+      if (!strcasecmp(s2, "full")) 
+       {
+         bat_max = atoi(s4);
+       }
+
+      fgets(inbuff, 127, fd);
+    }
+  fclose(fd);
+
+
+  if((fd = fopen(acpi_state[fd_index], "r")) == NULL) 
+    return 0;
+
+  /* Extract battery status */
+  fgets(inbuff, 127, fd);
+  while(!feof(fd)) 
+    {
+      sscanf(inbuff, "%s %s %s %s", s1, s2, s3, s4);
+
+      /* find remaining juice */
+      if(!strcasecmp(s1, "Remaining")) 
+       {
+         bat_val = atoi(s3);
+       }
+
+      fgets(inbuff, 127, fd);
+    }
+
+  fclose(fd);
+
+
+  ainfo->ac_line_status = OLSR_BATTERY_POWERED;
+  ainfo->battery_percentage = bat_val * 100 / bat_max;
+
+  return 1;
+}
+
+
+
+static int
+acpi_probe()
+{
+  char s1[32], s2[32];
+  FILE *fd;
+  int i;
+  
+
+  /* First check for AC power */
+
+  for(i = 0; i < ACPI_AC_CNT; i++)
+    {
+      /* Try opening the info file */
+      if((fd = fopen(acpi_ac[i], "r")) == NULL)
+       continue;
+      
+      /* Extract info */
+      if(fscanf(fd, "%s %s", s1, s2) < 2)
+       {
+         fclose(fd);
+         continue;
+       }
+      
+      /* Close info entry */
+      fclose(fd);
+
+      /* Running on AC power */
+      if(!strcasecmp(s2, "on-line"))
+       return -1;
+
+    }
+
+  /* Only checking the first found batery entry... */
+  for(i = 0; i < ACPI_BT_CNT; i ++)
+    {
+
+      /* Try opening the info file */
+      if((fd = fopen(acpi_info[i], "r")) == NULL)
+       continue;
+
+      /* Extract info */
+      if(fscanf(fd, "%s %s", s1, s2) < 2)
+       {
+         fclose(fd);
+         continue;
+       }
+
+      /* Close info entry */
+      fclose(fd);
+
+      /* Check if battery is present */
+      if((!strcasecmp(s1, "present:")) && (!strcasecmp(s2, "no"))) 
+       continue;
+
+      /* Open the corresponding state file */
+      if((fd = fopen(acpi_state[i], "r")) == NULL)
+       continue;
+
+      fclose(fd);
+
+      return i;
+    }
+
+  /* No battery found */
+  return -1;
+}
+