4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <ITapiModem.h>
22 #include <tapi_event.h>
23 #include <tapi_common.h>
29 #include <device-node.h>
30 #include "dd-deviced.h"
32 #include "core/common.h"
33 #include "core/devices.h"
34 #include "core/edbus-handler.h"
35 #include "display/core.h"
36 #include "power/power-handler.h"
38 #define PREDEF_FLIGHT_MODE "flightmode"
39 #define PREDEF_ENTERSLEEP "entersleep"
40 #define PREDEF_LEAVESLEEP "leavesleep"
42 #define POWER_RESTART 5
44 static TapiHandle *tapi_handle = NULL;
45 static Ecore_Timer *poweroff_timer_id = NULL;
46 static int reboot_opt;
48 static Eina_Bool telephony_powerdown_ap_internal(void *data)
53 static void telephony_powerdown_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
55 telephony_powerdown_ap_internal(data);
58 static void telephony_restart_ap(TapiHandle *handle, const char *noti_id, void *data, void *user_data)
60 restart_ap((void *)reboot_opt);
63 static Eina_Bool telephony_restart_ap_by_force(void *data)
65 if (poweroff_timer_id) {
66 ecore_timer_del(poweroff_timer_id);
67 poweroff_timer_id = NULL;
73 static void powerdown_res_cb(TapiHandle *handle, int result, void *data, void *user_data)
75 _D("poweroff command request : %d",result);
78 static Eina_Bool telephony_powerdown_ap_by_force(void *data)
80 if (poweroff_timer_id) {
81 ecore_timer_del(poweroff_timer_id);
82 poweroff_timer_id = NULL;
88 static int telephony_start(enum device_flags flags)
93 _I("already initialized");
96 if (vconf_get_bool(VCONFKEY_TELEPHONY_READY,&ready) != 0 || ready != 1) {
97 _E("fail to get %s(%d)", VCONFKEY_TELEPHONY_READY, ready);
100 tapi_handle = tel_init(NULL);
101 if (tapi_handle == NULL) {
102 _E("tapi init error");
108 static int telephony_stop(enum device_flags flags)
112 ret = tel_deregister_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER);
113 if (ret != TAPI_API_SUCCESS)
114 _E("tel_deregister_noti_event is not subscribed. error %d", ret);
116 ret = tel_deinit(tapi_handle);
118 _E("fail to deinit");
125 static void telephony_exit(void *data)
134 if (!strncmp(data, POWER_POWEROFF, POWER_POWEROFF_LEN)) {
136 ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
137 telephony_powerdown_ap, NULL);
138 if (ret != TAPI_API_SUCCESS) {
139 _E("tel_register_event is not subscribed. error %d", ret);
140 telephony_powerdown_ap_by_force(NULL);
143 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF,
144 powerdown_res_cb, NULL);
145 if (ret != TAPI_API_SUCCESS) {
146 _E("tel_process_power_command() error %d\n", ret);
147 telephony_powerdown_ap_by_force(NULL);
150 poweroff_timer_id = ecore_timer_add(15,
151 telephony_powerdown_ap_internal, NULL);
155 if (strncmp(data, POWER_REBOOT, POWER_REBOOT_LEN) &&
156 strncmp(data, POWER_RECOVERY, POWER_RECOVERY_LEN) &&
157 strncmp(data, POWER_FOTA, POWER_FOTA_LEN)) {
162 _I("Option: %s", data);
163 if (!strncmp(data, POWER_RECOVERY, POWER_RECOVERY_LEN))
164 reboot_opt = SYSTEMD_STOP_POWER_RESTART_RECOVERY;
165 else if (!strncmp(data, POWER_REBOOT, POWER_REBOOT_LEN))
166 reboot_opt = SYSTEMD_STOP_POWER_RESTART;
167 else if (!strncmp(data, POWER_FOTA, POWER_FOTA_LEN))
168 reboot_opt = SYSTEMD_STOP_POWER_RESTART_FOTA;
170 ret = tel_register_noti_event(tapi_handle, TAPI_NOTI_MODEM_POWER,
171 telephony_restart_ap, NULL);
172 if (ret != TAPI_API_SUCCESS) {
173 _E("tel_register_event is not subscribed. error %d", ret);
174 telephony_restart_ap_by_force((void *)POWER_RESTART);
177 ret = tel_process_power_command(tapi_handle, TAPI_PHONE_POWER_OFF,
178 powerdown_res_cb, NULL);
179 if (ret != TAPI_API_SUCCESS) {
180 _E("tel_process_power_command() error %d", ret);
181 telephony_restart_ap_by_force((void *)reboot_opt);
184 poweroff_timer_id = ecore_timer_add(15,telephony_restart_ap_by_force,
188 static void telephony_flight_mode_on(TapiHandle *handle, int result, void *data, void *user_data)
191 int bCurFlightMode = 0;
193 if (result != TAPI_POWER_FLIGHT_MODE_ENTER) {
194 _E("flight mode enter failed %d", result);
197 _D("enter flight mode result : %d", result);
198 ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &bCurFlightMode);
200 _D("Flight Mode is %d", bCurFlightMode);
202 _E("failed to get vconf key");
205 static void telephony_flight_mode_off(TapiHandle *handle, int result, void *data, void *user_data)
208 int bCurFlightMode = 0;
210 if (result != TAPI_POWER_FLIGHT_MODE_LEAVE) {
211 _E("flight mode leave failed %d", result);
214 _D("leave flight mode result : %d", result);
215 ret = vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &bCurFlightMode);
217 _D("Flight Mode is %d", bCurFlightMode);
219 _E("failed to get vconf key");
222 static int telephony_execute(void *data)
225 int mode = *(int *)(data);
226 int err = TAPI_API_SUCCESS;
228 if (tapi_handle == NULL) {
229 ret = telephony_start(NORMAL_MODE);
231 _E("fail to get tapi handle");
237 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE,
238 telephony_flight_mode_off, NULL);
239 } else if (mode == 0) {
240 err = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER,
241 telephony_flight_mode_on, NULL);
243 if (err != TAPI_API_SUCCESS)
244 _E("FlightMode tel api action failed %d",err);
249 static int telephony_flight_mode(int argc, char **argv)
253 if (argc != 1 || argv[0] == NULL) {
254 _E("FlightMode Set predefine action failed");
257 mode = atoi(argv[0]);
258 telephony_execute(&mode);
262 static int telephony_enter_sleep(int argc, char **argv)
266 pm_change_internal(getpid(), LCD_NORMAL);
270 * TODO - add check, cb, etc...
271 * should be checked wirh telephony part */
272 ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_ENTER,
273 telephony_flight_mode_on, NULL);
274 _I("request for changing into flight mode : %d", ret);
276 launch_evenif_exist("/etc/rc.d/rc.entersleep", "");
277 pm_change_internal(getpid(), POWER_OFF);
282 static int telephony_leave_sleep(int argc, char **argv)
286 pm_change_internal(getpid(), LCD_NORMAL);
290 * TODO - add check, cb, etc...
291 * should be checked wirh telephony part */
292 ret = tel_set_flight_mode(tapi_handle, TAPI_POWER_FLIGHT_MODE_LEAVE,
293 telephony_flight_mode_off, NULL);
294 _I("request for changing into flight mode : %d", ret);
299 static DBusMessage *flight_mode_handler(E_DBus_Object *obj, DBusMessage *msg)
302 DBusMessageIter iter;
310 dbus_error_init(&err);
312 if (!dbus_message_get_args(msg, &err,
313 DBUS_TYPE_STRING, &type_str,
314 DBUS_TYPE_INT32, &argc,
315 DBUS_TYPE_STRING, &argv, DBUS_TYPE_INVALID)) {
316 _E("there is no message");
322 _E("message is invalid!");
327 pid = get_edbus_sender_pid(msg);
328 if (kill(pid, 0) == -1) {
329 _E("%d process does not exist, dbus ignored!", pid);
334 telephony_flight_mode(argc, (char **)&argv);
337 reply = dbus_message_new_method_return(msg);
338 dbus_message_iter_init_append(reply, &iter);
339 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
344 static DBusMessage *telephony_handler(E_DBus_Object *obj, DBusMessage *msg)
347 DBusMessageIter iter;
354 dbus_error_init(&err);
356 if (!dbus_message_get_args(msg, &err,
357 DBUS_TYPE_STRING, &type_str,
358 DBUS_TYPE_INT32, &argc, DBUS_TYPE_INVALID)) {
359 _E("there is no message");
365 _E("message is invalid!");
370 pid = get_edbus_sender_pid(msg);
371 if (kill(pid, 0) == -1) {
372 _E("%d process does not exist, dbus ignored!", pid);
377 if (tapi_handle == NULL) {
378 if (telephony_start(NORMAL_MODE) != 0)
379 _E("fail to get tapi handle");
382 if (!strncmp(type_str, PREDEF_ENTERSLEEP, strlen(PREDEF_ENTERSLEEP)))
383 ret = telephony_enter_sleep(0, NULL);
384 else if (!strncmp(type_str, PREDEF_LEAVESLEEP, strlen(PREDEF_LEAVESLEEP)))
385 ret = telephony_leave_sleep(0, NULL);
388 reply = dbus_message_new_method_return(msg);
389 dbus_message_iter_init_append(reply, &iter);
390 dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &ret);
395 static const struct edbus_method edbus_methods[] = {
396 { PREDEF_FLIGHT_MODE, "sis", "i", flight_mode_handler },
397 { PREDEF_ENTERSLEEP, "si", "i", telephony_handler },
398 { PREDEF_LEAVESLEEP, "si", "i", telephony_handler },
399 /* Add methods here */
402 static void telephony_init(void *data)
406 /* init dbus interface */
407 ret = register_edbus_method(DEVICED_PATH_POWER, edbus_methods,
408 ARRAY_SIZE(edbus_methods));
410 _E("fail to init edbus method(%d)", ret);
413 static const struct device_ops tel_device_ops = {
414 .priority = DEVICE_PRIORITY_NORMAL,
416 .init = telephony_init,
417 .start = telephony_start,
418 .stop = telephony_stop,
419 .exit = telephony_exit,
420 .execute = telephony_execute,
423 DEVICE_OPS_REGISTER(&tel_device_ops)