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 "usb-client.h"
21 #include "core/device-handler.h"
22 #include "core/edbus-handler.h"
24 #define USB_POPUP_NAME "usb-syspopup"
26 #ifndef VCONFKEY_USB_CONFIGURATION_ENABLED
27 #define VCONFKEY_USB_CONFIGURATION_ENABLED "memory/private/usb/conf_enabled"
41 static bool client_mode = false;
42 static char *driver_version = NULL;
43 static bool wait_configured = false;
45 void launch_syspopup(char *str)
47 struct popup_data params;
48 static const struct device_ops *apps = NULL;
51 apps = find_device("apps");
56 params.name = USB_POPUP_NAME;
57 params.key = POPUP_KEY_CONTENT;
64 bool get_wait_configured(void)
66 return wait_configured;
69 int get_debug_mode(void)
72 if (vconf_get_bool(VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL, &debug) != 0)
73 return 1; /* 0 means debug mode is on */
78 int get_default_mode(void)
80 if (get_debug_mode() == 0)
81 return SET_USB_DEFAULT;
86 int update_usb_state(int state)
88 return vconf_set_int(VCONFKEY_SYSMAN_USB_STATUS, state);
91 int update_current_usb_mode(int mode)
93 /*************************************************/
94 /* TODO: This legacy vconf key should be removed */
95 /* The legacy vconf key is used by mtp and OSP */
101 case SET_USB_SDB_DIAG:
102 legacy = SETTING_USB_SAMSUNG_KIES;
105 case SET_USB_RNDIS_DIAG:
106 case SET_USB_RNDIS_SDB:
107 legacy = SETTING_USB_DEBUG_MODE;
109 case SET_USB_RNDIS_TETHERING:
110 legacy = SETTING_USB_TETHERING_MODE;
114 legacy = SETTING_USB_NONE_MODE;
118 if (vconf_set_int(VCONFKEY_SETAPPL_USB_MODE_INT, legacy) != 0)
119 _E("Failed to set legacy vconf key for current usb mode");
120 /****************************************************/
122 return vconf_set_int(VCONFKEY_USB_CUR_MODE, mode);
125 int check_current_usb_state(void)
130 ret = device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state);
137 int get_current_usb_mode(void)
142 ret = vconf_get_int(VCONFKEY_USB_CUR_MODE, &mode);
149 int get_selected_usb_mode(void)
154 ret = vconf_get_int(VCONFKEY_USB_SEL_MODE, &mode);
161 int change_selected_usb_mode(int mode)
163 if (mode <= SET_USB_NONE)
165 return vconf_set_int(VCONFKEY_USB_SEL_MODE, mode);
168 static int notify_vconf_keys(void)
172 ret = vconf_notify_key_changed(
173 VCONFKEY_USB_SEL_MODE,
174 client_mode_changed, NULL);
176 _E("FAIL: vconf_notify_key_changed()");
180 ret = vconf_notify_key_changed(
181 VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL,
182 debug_mode_changed, NULL);
184 _E("FAIL: vconf_notify_key_changed()");
186 ret = vconf_notify_key_changed(
187 VCONFKEY_MOBILE_HOTSPOT_MODE,
188 tethering_status_changed, NULL);
190 _E("FAIL: vconf_notify_key_changed()");
195 static int ignore_vconf_keys(void)
199 ret = vconf_ignore_key_changed(
200 VCONFKEY_USB_SEL_MODE,
201 client_mode_changed);
203 _E("FAIL: vconf_ignore_key_changed()");
207 ret = vconf_ignore_key_changed(
208 VCONFKEY_SETAPPL_USB_DEBUG_MODE_BOOL,
211 _E("FAIL: vconf_ignore_key_changed()");
213 ret = vconf_ignore_key_changed(
214 VCONFKEY_MOBILE_HOTSPOT_MODE,
215 tethering_status_changed);
217 _E("FAIL: vconf_ignore_key_changed()");
223 static int register_client_handlers(void)
227 ret = notify_vconf_keys();
231 /* TODO: register other handler (ex. dbus, ... ) */
236 static int unregister_client_handlers(void)
240 ret = ignore_vconf_keys();
244 /* TODO: unregister other handler (ex. dbus, ... ) */
249 static int init_client_values(void)
253 ret = make_empty_configuration_list();
255 _E("Failed to get information of usb configurations");
257 ret = make_supported_confs_list();
259 _E("Failed to get information of usb configuration files");
264 static void deinit_client_values(void)
268 sel_mode = get_selected_usb_mode();
270 case SET_USB_RNDIS_TETHERING:
271 case SET_USB_RNDIS_DIAG:
272 if (change_selected_usb_mode(get_default_mode()) != 0)
273 _E("Failed to set selected usb mode");
279 release_supported_confs_list();
280 release_configuration_list();
283 static int init_client(void)
289 ret = register_client_handlers();
293 ret = init_client_values();
300 static int deinit_client(void)
306 ret = unregister_client_handlers();
308 _E("FAIL: unregister_client_handlers()");
310 deinit_client_values();
316 void act_usb_connected(void)
318 wait_configured = false;
320 if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
321 _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
323 if (init_client() < 0)
324 _E("FAIL: init_client()");
326 change_client_setting(SET_CONFIGURATION | SET_OPERATION | SET_NOTIFICATION);
328 pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
331 void act_usb_connected(void)
333 wait_configured = true;
335 if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_ENABLED) != 0)
336 _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
338 if (init_client() < 0)
339 _E("FAIL: init_client()");
341 change_client_setting(SET_CONFIGURATION);
343 pm_lock_internal(getpid(), LCD_OFF, STAY_CUR_STATE, 0);
347 static void act_usb_disconnected(void)
351 wait_configured = false;
353 if (vconf_set_int(VCONFKEY_USB_CONFIGURATION_ENABLED, USB_CONF_DISABLED) != 0)
354 _E("Failed to set vconf key (%s)", VCONFKEY_USB_CONFIGURATION_ENABLED);
356 pm_unlock_internal(getpid(), LCD_OFF, STAY_CUR_STATE);
358 cur_mode = get_current_usb_mode();
359 if (cur_mode > SET_USB_NONE)
360 unset_client_mode(cur_mode, false);
362 if (deinit_client() < 0)
363 _E("FAIL: deinit_client()");
365 if (update_usb_state(VCONFKEY_SYSMAN_USB_DISCONNECTED) < 0)
366 _E("FAIL: update_usb_state(%d)", VCONFKEY_SYSMAN_USB_DISCONNECTED);
369 static void subsystem_switch_changed (struct udev_device *dev)
371 const char *name = NULL;
372 const char *state = NULL;
376 name = udev_device_get_property_value(dev, UDEV_PROP_KEY_SWITCH_NAME);
380 if (strncmp(name, UDEV_PROP_VALUE_USB_CABLE, strlen(UDEV_PROP_VALUE_USB_CABLE)))
383 state = udev_device_get_property_value(dev, UDEV_PROP_KEY_SWITCH_STATE);
387 /* USB cable disconnected */
388 if (!strncmp(state, UDEV_PROP_VALUE_DISCON, strlen(UDEV_PROP_VALUE_DISCON))) {
389 _I("USB cable is disconnected");
390 act_usb_disconnected();
394 /* USB cable connected */
395 if (!strncmp(state, UDEV_PROP_VALUE_CON, strlen(UDEV_PROP_VALUE_CON))) {
396 _I("USB cable is connected");
402 static void subsystem_platform_changed (struct udev_device *dev)
404 const char *chgdet = NULL;
408 chgdet = udev_device_get_property_value(dev, UDEV_PROP_KEY_CHGDET);
412 if (strncmp(chgdet, UDEV_PROP_VALUE_USB, strlen(UDEV_PROP_VALUE_USB)))
415 if (device_get_property(DEVICE_TYPE_EXTCON, PROP_EXTCON_USB_ONLINE, &state) != 0
416 || (state != 0 && state != 1)) {
417 _E("cannot get the usb cable connection status");
418 state = get_usb_state_direct();
421 /* USB cable disconnected */
423 _I("USB cable is disconnected");
424 act_usb_disconnected();
428 /* USB cable connected */
430 _I("USB cable is connected");
435 _E("USB state is unknown(%d)", state);
438 static void subsystem_usbmode_changed (struct udev_device *dev)
440 const char *state = NULL;
442 if (!wait_configured)
445 wait_configured = false;
447 state = udev_device_get_property_value(dev, UDEV_PROP_KEY_USB_STATE);
451 if (strncmp(state, UDEV_PROP_VALUE_CONFIGURED, strlen(state)))
454 _I("Real USB cable is connected");
455 change_client_setting(SET_OPERATION | SET_NOTIFICATION);
458 const static struct uevent_handler uhs[] = {
459 { SWITCH_SUBSYSTEM , subsystem_switch_changed , NULL },
460 { USBMODE_SUBSYSTEM , subsystem_usbmode_changed , NULL },
461 { PLATFORM_SUBSYSTEM , subsystem_platform_changed , NULL },
464 void usbclient_init_booting_done(void)
468 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
469 ret = register_kernel_uevent_control(&uhs[i]);
471 _E("FAIL: reg_uevent_control()");
474 if (register_usb_client_change_request() < 0)
475 _E("Failed to register the request to change usb mode");
478 static void usbclient_init(void *data)
480 wait_until_booting_done();
483 static void usbclient_exit(void *data)
487 for (i = 0 ; i < ARRAY_SIZE(uhs) ; i++) {
488 unregister_kernel_uevent_control(&uhs[i]);
492 static const struct device_ops usbclient_device_ops = {
493 .priority = DEVICE_PRIORITY_NORMAL,
495 .init = usbclient_init,
496 .exit = usbclient_exit,
497 .start = control_start,
498 .stop = control_stop,
499 .status = control_status,
502 DEVICE_OPS_REGISTER(&usbclient_device_ops)