aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Ludviksen <andreas.e.ludviksen@stericsson.com>2011-06-03 15:05:04 +0200
committerSverre Vegge <sverre.vegge@stericsson.com>2011-08-02 22:13:39 +0200
commit71048ccfd6b0839a6bbc6e7fcd8a9a483c5158de (patch)
treec2f7b670fbcd9b4151d084ddcb85463a4a299d7b
parent844cff457535424575aa4d796612e618ee8f4ea2 (diff)
downloadu300-71048ccfd6b0839a6bbc6e7fcd8a9a483c5158de.tar.gz
SHUTDOWN: Hold POWER_REQUEST response until 'off' is received from MID
Check if android property 'sys.shutdown.requested' is set when receiving RIL_REQUEST_RADIO_POWER (0), and wait for 'off' signal before returning to Android. Signed-off-by: Sverre Vegge <sverre.vegge@stericsson.com>
-rw-r--r--u300-ril-information.c37
-rw-r--r--u300-ril-manager.c84
-rw-r--r--u300-ril.c54
-rw-r--r--u300-ril.h3
4 files changed, 115 insertions, 63 deletions
diff --git a/u300-ril-information.c b/u300-ril-information.c
index a98a909..b1e2ed2 100644
--- a/u300-ril-information.c
+++ b/u300-ril-information.c
@@ -25,7 +25,6 @@
#include <pthread.h>
#include <string.h>
#include <assert.h>
-#include <cutils/properties.h>
#include "u300-ril-information.h"
#include "u300-ril-network.h"
@@ -202,9 +201,6 @@ void requestRadioPower(void *data, size_t datalen, RIL_Token t)
int onOff;
int err;
ATResponse *atresponse = NULL;
- const char *property = "sys.shutdown.requested";
- char systemShutdown[PROPERTY_VALUE_MAX + 1];
- int getRet = -1;
if(datalen < sizeof(int))
goto error;
@@ -212,37 +208,8 @@ void requestRadioPower(void *data, size_t datalen, RIL_Token t)
onOff = ((int *) data)[0];
if (onOff == 0 && getCurrentState() != RADIO_STATE_OFF) {
-
- /*
- * Check Android system property if system is shutting down.
- * Note: If property is set a shutdown is taking place, regardless
- * of value.
- */
- getRet = property_get(property, systemShutdown, NULL);
-
- if (getRet > 0) {
- /* Modem shutdown */
- LOGI("Android shutdown received. Shutting down modem.");
- err = at_send_command("AT+CFUN=100", &atresponse);
- if (err < 0 || atresponse->success == 0)
- LOGE("Failed to perform modem shutdown");
-
-#ifndef EXTERNAL_MODEM_CONTROL_MODULE_DISABLED
- /* loop until MID reports that modem is shut down */
- while (g_shutdownCompleted == false) {
- usleep(100*1000);
- }
-#else
- /* No indication on Dbus available. Allow 2 sec for other parts
- * of the system to have a chance to prepare for shutdown.
- */
- usleep(2000*1000);
-#endif /* EXTERNAL_MODEM_CONTROL_MODULE_DISABLED */
- } else {
- /* Turn radio off */
- err = at_send_command("AT+CFUN=4", &atresponse);
- }
-
+ /* Turn radio off */
+ err = at_send_command("AT+CFUN=4", &atresponse);
if (err < 0 || atresponse->success == 0)
goto error;
setRadioState(RADIO_STATE_OFF);
diff --git a/u300-ril-manager.c b/u300-ril-manager.c
index 1a959aa..bf4fe43 100644
--- a/u300-ril-manager.c
+++ b/u300-ril-manager.c
@@ -32,6 +32,7 @@
#include <assert.h>
#ifndef CAIF_SOCKET_SUPPORT_DISABLED
#include <linux/caif/if_caif.h>
+#include <cutils/properties.h>
#include "u300-ril-netif.h"
#endif
@@ -71,34 +72,6 @@ static void haltCommandThreads(void)
pthread_mutex_unlock(&ril_manager_queue_startup_mutex);
}
-/******************************************************************************
- * Start section that includes DBUS communication with MID module *
- ******************************************************************************/
-#ifndef EXTERNAL_MODEM_CONTROL_MODULE_DISABLED
-#include <dbus/dbus.h>
-#include <poll.h>
-
-#define BUF_MID_RESPONSE_SIZE 32
-#define DBUS_MAX_WATCHERS 2 /* 1 for reading, 1 for writing. */
-#define DBUS_CONNECTION_NAME "com.stericsson.mid"
-#define DBUS_OBJECT_PATH "/com/stericsson/mid"
-#define DBUS_OBJECT_INTERFACE "com.stericsson.mid.Modem"
-#define DBUS_CONNECT_DELAY 2 /* Retry timeout waiting for Dbus and MID */
-
-static DBusWatch *used_watches[DBUS_MAX_WATCHERS];
-static DBusWatch *unused_watches[DBUS_MAX_WATCHERS];
-
-static int dbus_used_fds = 0;
-static int dbus_not_used_fds = 0;
-
-static struct pollfd dbus_used_pollfds_tab[DBUS_MAX_WATCHERS];
-static struct pollfd dbus_not_used_pollfds_tab[DBUS_MAX_WATCHERS];
-
-static pthread_mutex_t s_dbus_watch_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-pthread_t s_tid_dbusRunner;
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
#ifndef CAIF_SOCKET_SUPPORT_DISABLED
static bool createNetworkInterface(const char *ifname, int connection_id)
{
@@ -136,6 +109,52 @@ static bool createNetworkInterface(const char *ifname, int connection_id)
}
#endif
+/******************************************************************************
+ * Start section that includes DBUS communication with MID module *
+ ******************************************************************************/
+#ifndef EXTERNAL_MODEM_CONTROL_MODULE_DISABLED
+#include <dbus/dbus.h>
+#include <poll.h>
+
+#define BUF_MID_RESPONSE_SIZE 32
+#define DBUS_MAX_WATCHERS 2 /* 1 for reading, 1 for writing. */
+#define DBUS_CONNECTION_NAME "com.stericsson.mid"
+#define DBUS_OBJECT_PATH "/com/stericsson/mid"
+#define DBUS_OBJECT_INTERFACE "com.stericsson.mid.Modem"
+#define DBUS_CONNECT_DELAY 2 /* Retry timeout waiting for Dbus and MID */
+
+static DBusWatch *used_watches[DBUS_MAX_WATCHERS];
+static DBusWatch *unused_watches[DBUS_MAX_WATCHERS];
+
+static int dbus_used_fds = 0;
+static int dbus_not_used_fds = 0;
+
+static struct pollfd dbus_used_pollfds_tab[DBUS_MAX_WATCHERS];
+static struct pollfd dbus_not_used_pollfds_tab[DBUS_MAX_WATCHERS];
+
+static pthread_mutex_t s_dbus_watch_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+pthread_t s_tid_dbusRunner;
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+static void signalShutdown(void)
+{
+ int err;
+
+ if ((err = pthread_mutex_lock(&ril_system_shutdown_mutex)) != 0) {
+ LOGE("%s() failed to take shutdown mutex: %s", __func__, strerror(err));
+ assert(0);
+ }
+ g_offSignalReceived = true;
+ if ((err = pthread_cond_signal(&ril_system_shutdown_cond)) != 0) {
+ LOGE("%s() failed to signal shutdown cond: %s",__func__, strerror(err));
+ }
+ if ((err = pthread_mutex_unlock(&ril_system_shutdown_mutex)) != 0) {
+ LOGE("%s() failed to release shutdown mutex: %s!",
+ __func__, strerror(err));
+ }
+}
+
/* MID signal message handler */
static DBusHandlerResult midSignalHandler(DBusConnection *dbcon, DBusMessage
*msg, void *data)
@@ -145,6 +164,10 @@ static DBusHandlerResult midSignalHandler(DBusConnection *dbcon, DBusMessage
DBusMessage *dbmsg;
UNUSED(data);
char *signame = NULL;
+ const char *property = "sys.shutdown.requested";
+ char systemShutdown[PROPERTY_VALUE_MAX + 1];
+ int getRet = -1;
+ int err;
/*
* g_managerRelease is here used a state indication of QueueRunners.
@@ -184,6 +207,11 @@ static DBusHandlerResult midSignalHandler(DBusConnection *dbcon, DBusMessage
"for \"on\"...", __func__);
}
} else if (strncmp(signame, "off", 3) == 0) {
+ /* Check if Android property is set, and signal for shutdown. */
+ getRet = property_get(property, systemShutdown, NULL);
+ if (getRet > 0) {
+ signalShutdown();
+ }
g_shutdownCompleted = true;
if (g_managerRelease) {
LOGD("%s(): Signal queueRunner threads and prepare to go "
diff --git a/u300-ril.c b/u300-ril.c
index f688518..7534be5 100644
--- a/u300-ril.c
+++ b/u300-ril.c
@@ -94,6 +94,11 @@ static pthread_mutex_t s_state_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Mutex used to synchronize screen state variable changes */
static pthread_mutex_t s_screen_state_mutex = PTHREAD_MUTEX_INITIALIZER;
+/* Mutex used to synchronize system shutdown with Dbus 'OFF' message */
+bool g_offSignalReceived = false;
+pthread_mutex_t ril_system_shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t ril_system_shutdown_cond = PTHREAD_COND_INITIALIZER;
+
/*** Declarations ***/
static void onRequest(int request, void *data, size_t datalen,
RIL_Token t);
@@ -296,6 +301,37 @@ static void resetModemState(int resetState)
onResetModemStateStk(resetState);
}
+static void shutdownSystem(RIL_Token t)
+{
+ int err;
+ if ((err = pthread_mutex_lock(&ril_system_shutdown_mutex)) != 0) {
+ LOGE("%s() failed to take system shutdown mutex: %s!", __func__,
+ strerror(err));
+ assert(0);
+ }
+
+ /**
+ * If Dbus is disabled, there will be no indication when the modem
+ * is shut down and thus no signal to the condition.
+ * To allow system maximum time to shut down the modem, the request
+ * will wait here until the timeout in Android expires.
+ */
+ while (!g_offSignalReceived) {
+ if ((err = pthread_cond_wait(&ril_system_shutdown_cond,
+ &ril_system_shutdown_mutex)) != 0) {
+ LOGE("%s(): pthread_cond_wait Failed. err: %s", __func__,
+ strerror(err));
+ }
+ }
+
+ if ((err = pthread_mutex_unlock(&ril_system_shutdown_mutex)) != 0) {
+ LOGE("%s() failed to release system shutdown mutex: %s!", __func__,
+ strerror(err));
+ }
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+}
+
void enqueueRILEventOnList(RequestQueue* q, RILEvent* e)
{
int err;
@@ -1080,6 +1116,24 @@ static void onRequest(int request, void *data, size_t datalen, RIL_Token t)
RequestQueue *q = &s_requestQueueDefault;
int err;
+ const char *property = "sys.shutdown.requested";
+ char systemShutdown[PROPERTY_VALUE_MAX + 1];
+ int getRet = -1;
+
+ /*
+ * Check if this is a 'RADIO_POWER' request, and if Android system
+ * property for shutdown is set.
+ * Note: If property is set a shutdown is taking place, regardless
+ * of value.
+ */
+ if (request == RIL_REQUEST_RADIO_POWER && ((int *) data)[0] == 0) {
+ getRet = property_get(property, systemShutdown, NULL);
+ if (getRet > 0) {
+ shutdownSystem(t);
+ goto finally;
+ }
+ }
+
/* In radio state unavailable no requests are to enter the queues */
if (s_state == RADIO_STATE_UNAVAILABLE) {
(void)requestStateFilter(request, data, datalen, t);
diff --git a/u300-ril.h b/u300-ril.h
index d95a6a7..948fe86 100644
--- a/u300-ril.h
+++ b/u300-ril.h
@@ -56,6 +56,9 @@ extern pthread_mutex_t ril_manager_queue_startup_mutex;
extern pthread_cond_t ril_manager_queue_startup_cond;
extern pthread_mutex_t ril_manager_queue_exit_mutex;
extern pthread_cond_t ril_manager_queue_exit_cond;
+extern bool g_offSignalReceived;
+extern pthread_mutex_t ril_system_shutdown_mutex;
+extern pthread_cond_t ril_system_shutdown_cond;
int getRestrictedState(void);
void initializeStateVariables(void);