#define MANAGER_FLIGHT_MODE_REQUEST_TIMEOUT (1000) /* 1 seconds */
#define MANAGER_MODEM_POWER_OFF_REQUEST_TIMEOUT (1000) /* 1 seconds */
+/*
+ * Timeout for 5 seconds for poweroff wait timer set
+ */
+#define MANAGER_DEFAULT_TIMEOUT (5 * 1000)
+#define MANAGER_RETRY_TIMEOUT (1 * 1000)
+
+
+/*
+ * Dbus interface info for power off wait timer handling
+ */
+#define DEVICED_BUS_NAME "org.tizen.system.deviced"
+#define DEVICED_OBJECT_PATH "/Org/Tizen/System/DeviceD"
+#define DEVICED_INTERFACE_NAME DEVICED_BUS_NAME
+
+#define DEVICED_PATH_REBOOT DEVICED_OBJECT_PATH"/Reboot"
+#define DEVICED_PATH_POWEROFF DEVICED_OBJECT_PATH"/PowerOff"
+
+#define DEVICED_INTERFACE_REBOOT DEVICED_INTERFACE_NAME".reboot"
+#define DEVICED_INTERFACE_POWEROFF DEVICED_INTERFACE_NAME".PowerOff"
+
+#define DBUS_METHOD_ADD_POWEROFF_WAIT "AddPoweroffWait"
+#define DBUS_METHOD_REMOVE_POWEROFF_WAIT "RemovePoweroffWait"
+#define DBUS_SIGNAL_POWEROFF_STATE "ChangeState"
+
+static void __manager_modem_add_poweroff_wait(ModemPrivateInfo *modem_info);
+
static enum tcore_hook_return on_noti_hook_manager_call_status_idle(Server *server,
CoreObject *source, enum tcore_notification_command command,
unsigned int data_len, void *data, void *user_data)
}
+static void __on_resp_modem_poweroff(UserRequest *ur, enum tcore_response_command command,
+ unsigned int data_len, const void *data, void *user_data)
+{
+ struct tresp_modem_power_off *poweroff_status = (struct tresp_modem_power_off *)data;
+ TcorePlugin *modem_plugin = (TcorePlugin *)user_data;
+
+ dbg("enter");
+
+ if (!poweroff_status || !modem_plugin) {
+ err("NULL data : poweroff_status[%p], modem_plugin[%p]", poweroff_status, modem_plugin);
+ return;
+ }
+
+}
+
+static void __request_modem_poweroff(TcorePlugin *modem_plugin)
+{
+ struct treq_modem_power_off poweroff_cmd = {};
+ gboolean ret = FALSE;
+
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_plugin))
+ return;
+
+ ret = manager_util_send_request(modem_plugin, TREQ_MODEM_POWER_OFF,
+ sizeof(poweroff_cmd), &poweroff_cmd, __on_resp_modem_poweroff, modem_plugin);
+
+ if (!ret) {
+ err("Fail to request modem power off!!");
+ }
+
+ dbg("done");
+}
+
+static void __manager_modem_poweroff_signal_handler(GDBusConnection *connection,
+ const gchar *sender_name, const gchar *object_path,
+ const gchar *interface_name, const gchar *signal_name,
+ GVariant *parameters, gpointer user_data)
+{
+
+ ModemPrivateInfo *modem_info = user_data;
+ TcorePlugin *modem_plugin = NULL;
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info))
+ return;
+
+ if (g_strcmp0(signal_name, DBUS_SIGNAL_POWEROFF_STATE) == 0) {
+ modem_plugin = tcore_object_ref_plugin(modem_info->co_modem);
+ dbg("poweroff state changed is happened");
+ __request_modem_poweroff(modem_plugin);
+ }
+ dbg("done");
+
+}
+
+static void __manager_modem_poweroff_subscribe_signal(ModemPrivateInfo *modem_info)
+{
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ if (!modem_info->sys_power.conn) {
+ GError *error = NULL;
+
+ modem_info->sys_power.conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (modem_info->sys_power.conn == NULL) {
+ err("GDBusconnection is NULL: [%s]", error->message);
+ g_error_free(error);
+ return;
+ }
+ modem_info->sys_power.set_poweroff_wait = FALSE;
+ }
+
+ if (!modem_info->sys_power.ca) {
+ modem_info->sys_power.ca = g_cancellable_new();
+ }
+
+ if (modem_info->sys_power.subs_id_power_off) {
+ dbg("g_dbus_connection_signal_subscribe() for poweroff_state has been already done.");
+ return;
+ }
+
+ modem_info->sys_power.subs_id_power_off = g_dbus_connection_signal_subscribe(modem_info->sys_power.conn,
+ NULL,
+ DEVICED_INTERFACE_POWEROFF,
+ DBUS_SIGNAL_POWEROFF_STATE,
+ DEVICED_PATH_POWEROFF, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
+ __manager_modem_poweroff_signal_handler, modem_info, NULL);
+
+
+ if (modem_info->sys_power.subs_id_power_off == 0) {
+ err("g_dbus_connection_signal_subscribe() is failed.");
+ g_object_unref(modem_info->sys_power.conn);
+ }
+
+ dbg("done");
+
+}
+
+static void __manager_modem_poweroff_unsubscribe_signal(ModemPrivateInfo *modem_info)
+{
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ if (modem_info->sys_power.subs_id_power_off > 0) {
+ g_dbus_connection_signal_unsubscribe(modem_info->sys_power.conn, modem_info->sys_power.subs_id_power_off);
+ modem_info->sys_power.subs_id_power_off = 0;
+ }
+
+ if (modem_info->sys_power.ca) {
+ g_cancellable_cancel(modem_info->sys_power.ca);
+ g_object_unref(modem_info->sys_power.ca);
+ }
+
+ if (modem_info->sys_power.conn) {
+ g_object_unref(modem_info->sys_power.conn);
+ modem_info->sys_power.conn = NULL;
+ }
+
+ modem_info->sys_power.set_poweroff_wait = FALSE;
+
+ /* Remove Timer */
+ if (modem_info->sys_power.set_poweroff_timer > 0) {
+ g_source_remove(modem_info->sys_power.set_poweroff_timer);
+ modem_info->sys_power.set_poweroff_timer = -1;
+ }
+
+ dbg("done");
+
+}
+
+static gboolean __manager_modem_poweroff_wait_retry(gpointer user_data)
+{
+ ModemPrivateInfo *modem_info = user_data;
+
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return FALSE;
+ }
+
+ /* Remove Timer */
+ if (modem_info->sys_power.set_poweroff_timer > 0) {
+ g_source_remove(modem_info->sys_power.set_poweroff_timer);
+ modem_info->sys_power.set_poweroff_timer = -1;
+ }
+ __manager_modem_add_poweroff_wait(modem_info);
+
+ dbg("done");
+
+ return TRUE;
+}
+
+static void __manager_modem_add_poweroff_wait_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusConnection *conn = NULL;
+ int result = -1;
+ GVariant *dbus_result = NULL;
+ ModemPrivateInfo *modem_info = user_data;
+
+ dbg("enter");
+
+ conn = G_DBUS_CONNECTION(source_object);
+ dbus_result = g_dbus_connection_call_finish(conn, res, &error);
+ if (error) {
+ err("Failed: %s", error->message);
+ g_error_free(error);
+ modem_info->sys_power.set_poweroff_timer = g_timeout_add(MANAGER_RETRY_TIMEOUT, __manager_modem_poweroff_wait_retry, modem_info);
+ } else {
+ dbg("PoweroffWait Added Successufully");
+ modem_info->sys_power.set_poweroff_wait = TRUE;
+ }
+
+ if (dbus_result) {
+ g_variant_get(dbus_result, "(i)", &result);
+ g_variant_unref(dbus_result);
+ }
+
+ dbg("result : %d", result);
+}
+
+
+static void __manager_modem_add_poweroff_wait(ModemPrivateInfo *modem_info)
+{
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ if (modem_info->sys_power.set_poweroff_wait == TRUE) {
+ return;
+ }
+
+ if (modem_info->sys_power.conn) {
+ g_dbus_connection_call(modem_info->sys_power.conn, DEVICED_BUS_NAME,
+ DEVICED_PATH_REBOOT, DEVICED_INTERFACE_REBOOT, DBUS_METHOD_ADD_POWEROFF_WAIT,
+ NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
+ MANAGER_DEFAULT_TIMEOUT, modem_info->sys_power.ca,
+ __manager_modem_add_poweroff_wait_cb, modem_info);
+ }
+
+ dbg("done");
+
+ return;
+}
+
+static void __manager_modem_remove_poweroff_wait_cb(GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ GDBusConnection *conn = NULL;
+ int result = -1;
+ GVariant *dbus_result = NULL;
+ ModemPrivateInfo *modem_info = user_data;
+
+ dbg("enter");
+
+ conn = G_DBUS_CONNECTION(source_object);
+ dbus_result = g_dbus_connection_call_finish(conn, res, &error);
+ if (error) {
+ err("Failed: %s", error->message);
+ g_error_free(error);
+ } else {
+ dbg("PoweroffWait Removed Successufully");
+ modem_info->sys_power.set_poweroff_wait = FALSE;
+ }
+
+ if (dbus_result) {
+ g_variant_get(dbus_result, "(i)", &result);
+ g_variant_unref(dbus_result);
+ }
+
+ dbg("result : %d", result);
+}
+
+static void __manager_modem_remove_poweroff_wait(ModemPrivateInfo *modem_info)
+{
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ if (modem_info->sys_power.conn) {
+ g_dbus_connection_call(modem_info->sys_power.conn, DEVICED_BUS_NAME,
+ DEVICED_PATH_REBOOT, DEVICED_INTERFACE_REBOOT, DBUS_METHOD_REMOVE_POWEROFF_WAIT,
+ NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
+ MANAGER_DEFAULT_TIMEOUT, modem_info->sys_power.ca,
+ __manager_modem_remove_poweroff_wait_cb, NULL);
+
+ modem_info->sys_power.set_poweroff_wait = FALSE;
+ }
+
+ return;
+}
+
gboolean manager_modem_initialize_private_info(ModemBoard *mb)
{
- if (G_UNLIKELY(!mb))
+ dbg("enter");
+
+ if (G_UNLIKELY(!mb)) {
+ err("Invalid data");
return FALSE;
+ }
if (mb->modem_info)
mb->modem_info->modem_status = MODEM_STATE_UNKNOWN;
mb->modem_info->co_modem = tcore_plugin_ref_core_object(mb->modem_plugin, CORE_OBJECT_TYPE_MODEM);
mb->modem_info->modem_status = MODEM_STATE_UNKNOWN;
+
+ mb->modem_info->sys_power.set_poweroff_timer = -1;
+
+ if (mb->index == MANAGER_MODEM_BOARD_INDEX_0) {
+ dbg("__manager_power_subscribe_signal() for modem index (%d)", mb->index);
+ __manager_modem_poweroff_subscribe_signal(mb->modem_info);
+ }
+
dbg("Initialized modem private info");
return TRUE;
}
+
+gboolean manager_modem_clear_private_info(ModemBoard *mb)
+{
+
+ dbg("enter");
+
+ if (G_UNLIKELY(!mb || !mb->modem_info)) {
+ err("Invalid data");
+ return FALSE;
+ }
+
+ if (mb->index == MANAGER_MODEM_BOARD_INDEX_0) {
+ dbg("__manager_power_unsubscribe_signal() for modem index (%d)", mb->index);
+ __manager_modem_poweroff_unsubscribe_signal(mb->modem_info);
+ }
+
+ g_free(mb->modem_info);
+ mb->modem_info = NULL;
+
+ dbg("done");
+
+ return TRUE;
+}
+
enum tcore_manager_return manager_modem_process_notification(Manager *manager,
CoreObject *source, enum tcore_notification_command command,
unsigned int data_len, void *data)
TcorePlugin *manager_plugin = tcore_manager_get_plugin(manager);
PrivateData *priv_data = tcore_plugin_ref_user_data(manager_plugin);
- if (!data || !priv_data) {
+ ModemBoard *mb = manager_core_get_modem_board(manager, tcore_object_ref_plugin(source));
+
+ if (!data || !priv_data || !mb || !mb->modem_info) {
err("Invalid data");
return ret;
}
dbg("Write MODEM_STATE to /sys/class/sec/bsp/boot_stat");
manager_util_write_to_proc_file(msg, strlen(msg));
g_free(msg);
+
+ /* For executing CP detach process when Device Power off */
+ /* It should be subscribed power off waiting timer to deviced */
+ /* Poweroff timer should be added only one time, in case of modem index (0) */
+ if (mb->index == MANAGER_MODEM_BOARD_INDEX_0) {
+ dbg("Should add poweroff timer in case of modem index(0)");
+ if (!mb->modem_info->sys_power.set_poweroff_wait) {
+ //__manager_power_subscribe_signal(mb->modem_info);
+ __manager_modem_add_poweroff_wait(mb->modem_info);
+ }
+ }
+ }
+ break;
+
+ case MODEM_STATE_OFFLINE: {
+ dbg("MODEM_STATE has been changed to OFFLINE");
+
+ /* Once MODEM has been power off successufully, */
+ /* It should be removed power off waiting timer from deviced */
+ /* Poweroff timer should be removed only one time, in case of modem index (0) */
+ if (mb->index == MANAGER_MODEM_BOARD_INDEX_0) {
+ dbg("Should removed poweroff timer in case of modem index (0)");
+
+ if (mb->modem_info->sys_power.set_poweroff_wait == TRUE) {
+ __manager_modem_remove_poweroff_wait(mb->modem_info);
+ }
+ }
}
break;