#include <string.h>
#include <glib.h>
+#include <stdlib.h>
#include <tcore.h>
#include <server.h>
#include <manager.h>
#include "tfeature.h"
#include <vconf.h>
+#include <system_info.h>
+#include <device/power-internal.h>
/*
* Timeout of 1 second for normal cases, we may have to consider 4 sec for Verizon.
#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)
+
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)
co_call = co_call_other;
plugin_subs = plugin_subs_other;
}
- } else{
+ } else {
priv_data->is_end_all_initiated = FALSE;
}
tcore_user_request_set_command(new_ur, TREQ_CALL_END);
tcore_user_request_set_data(new_ur, sizeof(struct treq_call_end), &req);
if (TCORE_RETURN_SUCCESS != tcore_server_dispatch_request(server, new_ur)) {
- err("END_ALL request failed!!r");
+ err("END_ALL request failed!!");
tcore_user_request_free(new_ur);
} else {
info("queueing flight mode request");
}
return TCORE_MANAGER_RETURN_CONTINUE;
-
}
+
enum tcore_manager_return manager_modem_process_request(Server *server,
UserRequest *ur)
{
}
+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_handler(device_power_state_e prev_state, device_power_state_e next_state,
+ uint64_t wait_callback_id, device_power_transition_reason_e reason, void *user_data)
+{
+ ModemPrivateInfo *modem_info = user_data;
+ TcorePlugin *modem_plugin = NULL;
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info))
+ return;
+
+ modem_info->poweroff_id = wait_callback_id;
+
+ 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 mamager_modem_register_poweroff_handler(ModemPrivateInfo *modem_info)
+{
+ int ret;
+ char *profile = NULL;
+
+ dbg("enter");
+
+ if (G_UNLIKELY(!modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ /* Poweroff signal support should be executed only mobile and wearable profile.
+ In case of TV or IoT profile etc... (dongle modem support case),
+ dongle modem can be power off with udev_remove event. */
+ ret = system_info_get_platform_string("tizen.org/feature/profile", &profile);
+ if (ret != SYSTEM_INFO_ERROR_NONE) {
+ err("system_info_get_platform_string() failed!!! (%d,%s)", ret, get_error_message(ret));
+ return;
+ }
+
+ dbg("profile: %s", profile);
+ if (g_strcmp0(profile, "mobile") && g_strcmp0(profile, "wearable")) {
+ dbg("No need to subscribe poweroff signal handling to deviced");
+ free(profile);
+ return;
+ }
+ if (profile)
+ free(profile);
+
+ device_power_add_state_wait_callback(DEVICE_POWER_STATE_POWEROFF | DEVICE_POWER_STATE_REBOOT, manager_modem_poweroff_handler, modem_info);
+
+ dbg("done");
+}
+
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;
+ /* 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("manager_modem_register_poweroff_handler() for modem index (%d)", mb->index);
+ mamager_modem_register_poweroff_handler(mb->modem_info);
+ }
+
dbg("Initialized modem private info");
return TRUE;
}
+
+void manager_modem_clear_private_info(ModemBoard *mb)
+{
+
+ dbg("enter");
+
+ if (G_UNLIKELY(!mb || !mb->modem_info)) {
+ err("Invalid data");
+ return;
+ }
+
+ if (mb->index == MANAGER_MODEM_BOARD_INDEX_0) {
+ dbg("device_power_remove_state_wait_callback() for modem index (%d)", mb->index);
+ device_power_remove_state_wait_callback(DEVICE_POWER_STATE_POWEROFF | DEVICE_POWER_STATE_REBOOT);
+ }
+
+ g_free(mb->modem_info);
+ mb->modem_info = NULL;
+
+ dbg("done");
+}
+
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;
}
const struct tnoti_modem_power *modem_power = data;
switch (modem_power->state) {
- case MODEM_STATE_ERROR:
+ case MODEM_STATE_ERROR: {
dbg("Modem RESET happened");
+
manager_network_process_modem_error(source);
manager_call_process_modem_error(source);
+ manager_sim_process_modem_error(source);
+
priv_data->fm_processing_state = MANAGER_FLIGHT_PROCESSING_NONE;
+ }
break;
case MODEM_STATE_ONLINE: {
dbg("Write MODEM_STATE to /sys/class/sec/bsp/boot_stat");
manager_util_write_to_proc_file(msg, strlen(msg));
g_free(msg);
+
}
- break;
+ 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->poweroff_id > 0) {
+ device_power_confirm_wait_callback(mb->modem_info->poweroff_id);
+ mb->modem_info->poweroff_id = 0;
+ }
+ }
+ }
+ break;
default:
break;
set_nw_dds_ds_on_boot(manager);
#endif
}
- break;
+ break;
default:
break;