--- /dev/null
+/*
+ * acpi-events.c
+ *
+ * Register for and monitor acpi events and communicate relevant
+ * events to ioemu by triggering xenstore events.
+ *
+ * Copyright (c) 2008 Kamala Narasimhan
+ * Copyright (c) 2008 Citrix Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <xs.h>
+
+#define AC_ADAPTER_STATE_FILE_PATH "/proc/acpi/ac_adapter/AC/state"
+#define LID_STATE_FILE_PATH "/proc/acpi/button/lid/LID/state"
+#define ACPID_SOCKET_PATH "/var/run/acpid.socket"
+
+#define XS_AC_ADAPTER_STATE_PATH "/pm/ac_adapter"
+#define XS_LID_STATE_PATH "/pm/lid_state"
+
+#define XS_AC_ADAPTER_EVENT_PATH "/pm/events/acadapterstatechanged"
+#define XS_LID_EVENT_PATH "/pm/events/lidstatechanged"
+#define XS_PBTN_EVENT_PATH "/pm/events/powerbuttonpressed"
+
+static int socket_fd;
+static pthread_t acpi_thread;
+extern struct xs_handle *xs;
+
+void write_state_info_in_xenstore(char *file_path, char *xenstore_path,
+ char *search_str, char *default_value, char *alternate_value)
+{
+ FILE *file;
+ char file_data[1024];
+
+ xs_write(xs, XBT_NULL, xenstore_path, default_value, strlen(default_value));
+ file = fopen(file_path, "r");
+ if ( file == NULL )
+ return;
+
+ memset(file_data, 0, 1024);
+ fgets(file_data, 1024, file);
+ if ( strstr(file_data, search_str) )
+ xs_write(xs, XBT_NULL, xenstore_path, alternate_value,
+ strlen(alternate_value));
+ fclose(file);
+}
+
+void initialize_system_state_info(void)
+{
+ write_state_info_in_xenstore(AC_ADAPTER_STATE_FILE_PATH,
+ XS_AC_ADAPTER_STATE_PATH, "off-line", "1", "0");
+ write_state_info_in_xenstore(LID_STATE_FILE_PATH, XS_LID_STATE_PATH,
+ "closed", "1", "0");
+}
+
+void handle_ac_adapter_state_change(void)
+{
+ write_state_info_in_xenstore(AC_ADAPTER_STATE_FILE_PATH,
+ XS_AC_ADAPTER_STATE_PATH, "off-line", "1", "0");
+ xs_write(xs, XBT_NULL, XS_AC_ADAPTER_EVENT_PATH, "1", 1);
+}
+
+void handle_lid_state_change(void)
+{
+ write_state_info_in_xenstore(LID_STATE_FILE_PATH, XS_LID_STATE_PATH,
+ "closed", "1", "0");
+ xs_write(xs, XBT_NULL, XS_LID_EVENT_PATH, "1", 1);
+}
+
+void handle_pbtn_pressed_event(void)
+{
+ xs_write(xs, XBT_NULL, XS_PBTN_EVENT_PATH, "1", 1);
+}
+
+void process_acpi_message(char *acpi_buffer)
+{
+ if ( strstr(acpi_buffer, "ac_adapter") )
+ {
+ handle_ac_adapter_state_change();
+ return;
+ }
+
+ if ( strstr(acpi_buffer, "LID") )
+ {
+ handle_lid_state_change();
+ return;
+ }
+
+ if ( strstr(acpi_buffer, "PBTN") )
+ handle_pbtn_pressed_event();
+}
+
+static void *acpi_events_thread(void *arg)
+{
+ int ret;
+ struct sockaddr_un addr;
+ char acpi_buffer[1024];
+
+ socket_fd = socket(PF_UNIX, SOCK_STREAM, 0);
+ if ( socket_fd == -1)
+ return (void *)socket_fd;
+
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, ACPID_SOCKET_PATH, strlen(ACPID_SOCKET_PATH));
+ addr.sun_path[strlen(ACPID_SOCKET_PATH)] = '\0';
+ ret = connect(socket_fd, (struct sockaddr *)&addr, sizeof(addr));
+ if ( ret == -1 )
+ return (void *)ret;
+
+ while( 1 )
+ {
+ memset(acpi_buffer, 0, sizeof(acpi_buffer));
+ ret = recv(socket_fd, acpi_buffer, sizeof(acpi_buffer), 0);
+ if ( ret == 0 )
+ continue;
+
+ process_acpi_message(acpi_buffer);
+ }
+
+ return (void *)1;
+}
+
+void monitor_acpi_events(void)
+{
+ pthread_create(&acpi_thread, NULL, &acpi_events_thread, NULL);
+}
+
+void acpi_events_cleanup(void)
+{
+ if ( socket_fd != -1 )
+ close(socket_fd);
+
+ pthread_cancel(acpi_thread);
+}
+
unsigned long present_voltage;
};
-static struct xs_handle *xs;
+struct xs_handle *xs;
+extern void initialize_system_state_info(void);
+extern void monitor_acpi_events(void);
+extern void acpi_events_cleanup(void);
#ifdef RUN_IN_SIMULATE_MODE
#define BATTERY_DIR_PATH "/tmp/battery"
void print_battery_info(struct battery_info *info)
{
printf("present: %d\n", info->present);
- printf("design capacity: %d\n", info->design_capacity);
- printf("last full capacity: %d\n", info->last_full_capacity);
+ printf("design capacity: %d\n", (int) info->design_capacity);
+ printf("last full capacity: %d\n", (int) info->last_full_capacity);
printf("battery technology: %d\n", info->battery_technology);
- printf("design voltage: %d\n", info->design_voltage);
- printf("design capacity warning:%d\n", info->design_capacity_warning);
- printf("design capacity low: %d\n", info->design_capacity_low);
- printf("capacity granularity 1: %d\n", info->capacity_granularity_1);
- printf("capacity granularity 2: %d\n", info->capacity_granularity_2);
+ printf("design voltage: %d\n", (int) info->design_voltage);
+ printf("design capacity warning:%d\n", (int) info->design_capacity_warning);
+ printf("design capacity low: %d\n", (int) info->design_capacity_low);
+ printf("capacity granularity 1: %d\n", (int) info->capacity_granularity_1);
+ printf("capacity granularity 2: %d\n", (int) info->capacity_granularity_2);
printf("model number: %s\n", info->model_number);
printf("serial number: %s\n", info->serial_number);
printf("battery type: %s\n", info->battery_type);
void print_battery_status(struct battery_status *status)
{
printf("present: %d\n", status->present);
- printf("Battery state %d\n", status->state);
- printf("Battery present rate %d\n", status->present_rate);
- printf("Battery remining capacity %d\n", status->remaining_capacity);
- printf("Battery present voltage %d\n", status->present_voltage);
+ printf("Battery state %d\n", (int) status->state);
+ printf("Battery present rate %d\n", (int) status->present_rate);
+ printf("Battery remining capacity %d\n",
+ (int) status->remaining_capacity);
+ printf("Battery present voltage %d\n", (int) status->present_voltage);
}
#endif /*RUN_STANDALONE*/
return ret;
}
+#ifndef RUN_STANDALONE
/* Borrowed daemonize from xenstored - Initially written by Stevens. */
static void daemonize(void)
{
umask(0);
}
+#endif /* RUN_STANDALONE */
int main(int argc, char *argv[])
{
if ( xs == NULL )
return -1;
+ initialize_system_state_info();
+ monitor_acpi_events();
if ( write_one_time_battery_info() == 0 )
{
xs_daemon_close(xs);
}
wait_for_and_update_battery_status_request();
+ acpi_events_cleanup();
xs_daemon_close(xs);
return 0;
}