Skip to content

Commit

Permalink
Merge branch 'next'
Browse files Browse the repository at this point in the history
  • Loading branch information
Pekka Lundstrom committed Mar 12, 2014
2 parents d2f5672 + e041c8b commit 7691073
Show file tree
Hide file tree
Showing 13 changed files with 417 additions and 28 deletions.
18 changes: 17 additions & 1 deletion configure.ac
@@ -1,5 +1,5 @@
# Package name and version
AC_INIT(dsme, 0.64.8)
AC_INIT(dsme, 0.65.0)

AM_INIT_AUTOMAKE

Expand Down Expand Up @@ -156,6 +156,19 @@ AS_IF([test "x$enable_bootreason_logger" != xno],
[AC_DEFINE([DSME_BOOTREASON_LOGGER], [1])])
AM_CONDITIONAL([WANT_BOOTREASON_LOGGER], [test x$enable_bootreason_logger != xno])

#
# Shutdown feedback
#
AC_ARG_ENABLE([shutdown-feedback],
[AS_HELP_STRING([--disable-shutdown-feedback],
[disable bootreason logger (libshutdownfeedback)])],
[],
[enable_shutdown_feedback=yes])

AS_IF([test "x$enable_shutdown_feedback" != xno],
[AC_DEFINE([DSME_SHUTDOWN_FEEDBACK], [1])])
AM_CONDITIONAL([WANT_SHUTDOWN_FEEDBACK], [test x$enable_shutdown_feedback != xno])

#
# Compiler and linker flags
#
Expand Down Expand Up @@ -198,6 +211,9 @@ AM_PROG_CC_C_O()
PKG_CHECK_MODULES(GLIB, glib-2.0)
PKG_CHECK_MODULES(DBUS, dbus-1)
PKG_CHECK_MODULES(DBUSGLIB, dbus-glib-1)
if test "x$enable_shutdown_feedback" != xno; then
PKG_CHECK_MODULES(LIBNGF, libngf0)
fi

# Check libs (that are not yet checked)
# Whitespaces in 'action-if-found' fields in order to not (auto)update LIBS variable
Expand Down
12 changes: 11 additions & 1 deletion modules/Makefile.am
Expand Up @@ -75,6 +75,10 @@ if WANT_BOOTREASON_LOGGER
pkglib_LTLIBRARIES += bootreasonlogger.la
endif

if WANT_SHUTDOWN_FEEDBACK
pkglib_LTLIBRARIES += shutdownfeedback.la
endif

startup_la_SOURCES = startup.c

# TODO: remove this
Expand Down Expand Up @@ -154,7 +158,7 @@ if WANT_HW_THERMAL_MGMT
thermalobject_hw_la_SOURCES = thermalobject_hw.c \
thermalsensor_hw.c \
thermalsensor_hw.h
thermalobject_hw_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS)
thermalobject_hw_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS)
thermalobject_hw_la_LIBADD = $(GLIB_LIBS)
endif

Expand Down Expand Up @@ -199,3 +203,9 @@ bootreasonlogger_la_SOURCES = bootreasonlogger.c
bootreasonlogger_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) -D_GNU_SOURCE
bootreasonlogger_la_LIBADD = $(GLIB_LIBS)
endif

if WANT_SHUTDOWN_FEEDBACK
shutdownfeedback_la_SOURCES = shutdownfeedback.c
shutdownfeedback_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBNGF_CFLAGS) -D_GNU_SOURCE
shutdownfeedback_la_LIBADD = $(GLIB_LIBS) $(LIBNGF_LIBS)
endif
59 changes: 56 additions & 3 deletions modules/batterytracker.c
Expand Up @@ -47,6 +47,14 @@
#define CHARGING_INFO_PATH "/run/state/namespaces/Battery/IsCharging"
#define BATTERY_LEVEL_CONFIG_FILE "/etc/dsme/battery_levels.conf"

/**
* Timer value for alarm shutdown timer. This is how long we wait before reporting
* empty battery when phone woke up for alarm and battery is empty.
* Note that actually user has little bit more because battery level is not checked
* during first wakeup minute.
*/
#define ALARM_DELAYED_TIMEOUT 60

typedef enum {
BATTERY_STATUS_FULL,
BATTERY_STATUS_NORMAL,
Expand Down Expand Up @@ -91,6 +99,10 @@ typedef struct battery_state_t {
static battery_state_t battery_state;
static dsme_state_t dsme_state = DSME_STATE_NOT_SET;
static bool battery_temp_normal = true;
static bool alarm_active = false;
static dsme_timer_t alarm_delayed_empty_timer = 0;

static int delayed_empty_fn(void* unused);

static void read_config_file(void)
{
Expand Down Expand Up @@ -124,10 +136,10 @@ static void read_config_file(void)
new_levels[i].wakeup = (wakeup != 0);

/* Do some sanity checking for values
* Battery level values should be between 2-99, and in descending order.
* Battery level values should be between 1-99, and in descending order.
* Polling times should also make sense 10-1000s
*/
if (((i < BATTERY_STATUS_EMPTY) && (new_levels[i].min_level < 2)) ||
if (((i < BATTERY_STATUS_EMPTY) && (new_levels[i].min_level < 1)) ||
(new_levels[i].min_level > 99 ) ||
((i>0) && (new_levels[i].min_level >= new_levels[i-1].min_level)) ||
(new_levels[i].polling_time < 10 ) ||
Expand Down Expand Up @@ -271,12 +283,25 @@ static void send_empty_if_needed()
if (!battery_state.is_charging) {
/* Charging is not goig on. Request shutdown */
request_shutdown = true;

/* Except when phone woke up and alarm is active.
* In that case we wait couple of minutes extra before we report empty
*/
if ((dsme_state == DSME_STATE_ACTDEAD) && alarm_active) {
if (! alarm_delayed_empty_timer) {
alarm_delayed_empty_timer = dsme_create_timer(ALARM_DELAYED_TIMEOUT,
delayed_empty_fn, NULL);
dsme_log(LOG_INFO, "batterytracker: Battery empty but shutdown delayed because of active alarm");
}
if (alarm_delayed_empty_timer)
request_shutdown = false;
}
} else if (dsme_state != DSME_STATE_ACTDEAD) {
/* If charging in USER state, make sure level won't drop more and always keep min 1% */
if ((battery_state.percentance < battery_level_when_empty_seen) ||
(battery_state.percentance < 1)) {
request_shutdown = true;
dsme_log(LOG_DEBUG, "batterytracker: Battery level keeps dropping. Must shutdown");
dsme_log(LOG_INFO, "batterytracker: Battery level keeps dropping. Must shutdown");
} else {
dsme_log(LOG_DEBUG, "batterytracker: Charging is going on. We don't shutdown");
}
Expand Down Expand Up @@ -379,6 +404,24 @@ DSME_HANDLER(DSM_MSGTYPE_STATE_CHANGE_IND, server, msg)
dsme_state = msg->state;
}

DSME_HANDLER(DSM_MSGTYPE_SET_ALARM_STATE, conn, msg)
{
dsme_log(LOG_DEBUG,
"batterytracker: alarm %s state received",
msg->alarm_set ? "set" : "not set");
alarm_active = msg->alarm_set;

/* When alarm was active, we might have postponed shutdown.
* Check current status now and stop possible timer
*/
if ((!alarm_active) && alarm_delayed_empty_timer) {
dsme_destroy_timer(alarm_delayed_empty_timer);
alarm_delayed_empty_timer = 0;
dsme_log(LOG_INFO, "batterytracker: Empty state was earlier delayed due alarm. Now alarm is off");
send_empty_if_needed();
}
}

DSME_HANDLER(DSM_MSGTYPE_WAKEUP, client, msg)
{
dsme_log(LOG_DEBUG, "batterytracker: WAKEUP");
Expand All @@ -390,9 +433,19 @@ module_fn_info_t message_handlers[] = {
DSME_HANDLER_BINDING(DSM_MSGTYPE_WAKEUP),
DSME_HANDLER_BINDING(DSM_MSGTYPE_STATE_CHANGE_IND),
DSME_HANDLER_BINDING(DSM_MSGTYPE_SET_THERMAL_STATUS),
DSME_HANDLER_BINDING(DSM_MSGTYPE_SET_ALARM_STATE),
{ 0 }
};

static int delayed_empty_fn(void* unused)
{
alarm_delayed_empty_timer = 0;
alarm_active = false;
dsme_log(LOG_INFO, "batterytracker: Alarm hold off timeout is over");
send_empty_if_needed();
return 0; /* stop the interval */
}


static void query_current_state(void)
{
Expand Down
26 changes: 16 additions & 10 deletions modules/bootreasonlogger.c
Expand Up @@ -44,6 +44,7 @@
typedef enum {
SD_REASON_UNKNOWN,
SD_SW_REBOOT,
SD_DBUS_FAILED_REBOOT,
SD_SW_SHUTDOWN,
SD_DEVICE_OVERHEAT,
SD_BATTERY_EMPTY,
Expand All @@ -55,6 +56,7 @@ typedef enum {
static const char* const shutdown_reason_string[SD_REASON_COUNT] = {
"Reason Unknown",
"SW reboot request",
"Dbus failed, reboot",
"SW shutdown request",
"Device overheated",
"Battery empty",
Expand Down Expand Up @@ -102,20 +104,20 @@ static const char* state_name(dsme_state_t state)

static bool sw_update_running(void)
{
if (access("/tmp/os-update-running", F_OK) == 0)
return TRUE;
else
return FALSE;
return (access("/tmp/os-update-running", F_OK) == 0);
}

static bool system_still_booting(void)
{
/* Once system boot is over, init-done flag is set */
/* If file is not there, we are still booting */
if (access("/run/systemd/boot-status/init-done", F_OK) != 0)
return TRUE;
else
return FALSE;
return (access("/run/systemd/boot-status/init-done", F_OK) != 0);
}

static bool dbus_has_failed(void)
{
/* If dbus fails, dsme dbus has noticed it, marked and requested reboot */
return (access("/run/systemd/boot-status/dbus-failed", F_OK) == 0);
}

static const char * get_timestamp(void)
Expand Down Expand Up @@ -280,8 +282,12 @@ DSME_HANDLER(DSM_MSGTYPE_REBOOT_REQ, conn, msg)
char* sender = endpoint_name(conn);

write_log("Received: reboot request from", sender ? sender : "(unknown)");
if (saved_shutdown_reason == SD_REASON_UNKNOWN)
saved_shutdown_reason = SD_SW_REBOOT;
if (saved_shutdown_reason == SD_REASON_UNKNOWN) {
if (dbus_has_failed())
saved_shutdown_reason = SD_DBUS_FAILED_REBOOT;
else
saved_shutdown_reason = SD_SW_REBOOT;
}
free(sender);
}

Expand Down
12 changes: 9 additions & 3 deletions modules/dsme_dbus.c
Expand Up @@ -31,6 +31,7 @@
#include "dsme/logging.h"
#include "dsme/modules.h"
#include "dsme/modulebase.h"
#include "dsme/state.h"

#include <glib.h>
#include <dbus/dbus.h>
Expand Down Expand Up @@ -82,13 +83,18 @@ static bool dsme_dbus_check_arg_type(DBusMessageIter* iter, int want_type)
return false;
}


static DBusHandlerResult
dsme_dbus_filter(DBusConnection *con, DBusMessage *msg, void *aptr)
{
FILE* f;

if( dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, "Disconnected") ) {
dsme_log(LOG_CRIT, "Disconnected from system bus; terminating");
dsme_exit(EXIT_FAILURE);
dsme_log(LOG_CRIT, "Disconnected from system bus; rebooting");
/* mark failure and request reboot */
if ((f = fopen(DBUS_FAILED_FILE, "w+")) != NULL)
fclose(f);
DSM_MSGTYPE_REBOOT_REQ req = DSME_MSG_INIT(DSM_MSGTYPE_REBOOT_REQ);
broadcast_internally(&req);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
Expand Down
3 changes: 3 additions & 0 deletions modules/dsme_dbus.h
Expand Up @@ -28,6 +28,9 @@
#include <stdbool.h>
#include <dbus/dbus.h>


#define DBUS_FAILED_FILE "/run/systemd/boot-status/dbus-failed"

typedef struct DsmeDbusMessage DsmeDbusMessage;

typedef void DsmeDbusMethod(const DsmeDbusMessage* request,
Expand Down
21 changes: 19 additions & 2 deletions modules/runlevel.c
Expand Up @@ -80,6 +80,8 @@ static bool change_runlevel(dsme_runlevel_t runlevel)
*/
static void shutdown(dsme_runlevel_t runlevel)
{
char command[64];

if ((runlevel != DSME_RUNLEVEL_REBOOT) &&
(runlevel != DSME_RUNLEVEL_SHUTDOWN) &&
(runlevel != DSME_RUNLEVEL_MALF))
Expand All @@ -92,10 +94,25 @@ static void shutdown(dsme_runlevel_t runlevel)
runlevel == DSME_RUNLEVEL_REBOOT ? "Reboot" :
"Malf");

/* If we have systemd, use systemctl commands */
if (access("/bin/systemctl", X_OK) == 0) {
if (runlevel == DSME_RUNLEVEL_SHUTDOWN) {
snprintf(command, sizeof(command), "/bin/systemctl --no-block poweroff");
} else if (runlevel == DSME_RUNLEVEL_REBOOT) {
snprintf(command, sizeof(command), "/bin/systemctl --no-block reboot");
} else {
dsme_log(LOG_WARNING, "MALF not supported by our systemd implementation");
goto fail_and_exit;
}
dsme_log(LOG_NOTICE, "Issuing %s", command);
if (system(command) != 0) {
dsme_log(LOG_WARNING, "command %s failed: %m", command);
/* We ignore error. No retry or anything else */
}
}
/* If runlevel change fails, handle the shutdown/reboot by DSME */
if (!change_runlevel(runlevel))
else if (!change_runlevel(runlevel))
{
char command[32];
dsme_log(LOG_CRIT, "Doing forced shutdown/reboot");
sync();

Expand Down

0 comments on commit 7691073

Please sign in to comment.