diff options
author | Andreas Ludviksen <andreas.e.ludviksen@stericsson.com> | 2011-06-03 15:05:04 +0200 |
---|---|---|
committer | Sverre Vegge <sverre.vegge@stericsson.com> | 2011-08-02 22:13:39 +0200 |
commit | 71048ccfd6b0839a6bbc6e7fcd8a9a483c5158de (patch) | |
tree | c2f7b670fbcd9b4151d084ddcb85463a4a299d7b | |
parent | 844cff457535424575aa4d796612e618ee8f4ea2 (diff) | |
download | u300-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.c | 37 | ||||
-rw-r--r-- | u300-ril-manager.c | 84 | ||||
-rw-r--r-- | u300-ril.c | 54 | ||||
-rw-r--r-- | u300-ril.h | 3 |
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 " @@ -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); @@ -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); |