4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Hocheol Seo <hocheol.seo@samsung.com>,
7 * Injun Yang <injun.yang@samsung.com>,
8 * Seungyoun Ju <sy39.ju@samsung.com>
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
25 #include <dbus/dbus.h>
26 #include <dbus/dbus-glib.h>
27 #include <dbus/dbus-glib-lowlevel.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
34 #include "mobileap_agent.h"
35 #include "mobileap_common.h"
36 #include "mobileap_usb.h"
39 static void __handle_usb_disconnect_cb(keynode_t *key, void *data)
41 if (key == NULL || data == NULL) {
42 ERR("Parameter is NULL\n");
48 MobileAPObject *obj = (MobileAPObject *)data;
50 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
51 ERR("USB tethering is not enabled\n");
55 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
56 ERR("Invalid vconf key type\n");
60 vconf_name = vconf_keynode_get_name(key);
61 vconf_key = vconf_keynode_get_int(key);
62 DBG("key = %s, value = %d(int)\n", vconf_name, vconf_key);
64 if (!strcmp(vconf_name, VCONFKEY_SYSMAN_USB_STATUS) &&
65 vconf_key == VCONFKEY_SYSMAN_USB_DISCONNECTED)
66 DBG("USB is disconnected\n");
67 else if (!strcmp(vconf_name, VCONFKEY_SETAPPL_USB_MODE_INT) &&
68 vconf_key != SETTING_USB_TETHERING_MODE)
69 DBG("USB Mode is changed [%d]\n", vconf_key);
73 _disable_usb_tethering(obj);
74 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
75 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
78 static void __handle_usb_mode_change(keynode_t *key, void *data)
80 if (key == NULL || data == NULL) {
81 ERR("Parameter is NULL\n");
85 MobileAPObject *obj = (MobileAPObject *)data;
89 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
90 ERR("Invalid vconf key\n");
94 vconf_key = vconf_keynode_get_int(key);
95 DBG("key = %s, value = %d(int)\n",
96 vconf_keynode_get_name(key), vconf_key);
98 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
99 if (vconf_key != SETTING_USB_TETHERING_MODE) {
100 DBG("Is progressing for usb mode change\n");
104 DBG("USB tethering is enabled\n");
105 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
106 __handle_usb_mode_change);
107 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
108 dbus_g_method_return(obj->usb_context,
109 MOBILE_AP_ENABLE_USB_TETHERING_CFM,
110 MOBILE_AP_ERROR_NONE);
111 obj->usb_context = NULL;
113 /* USB Mode change is handled while USB tethering is enabled */
114 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
115 __handle_usb_disconnect_cb, (void *)obj);
116 ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &vconf_key);
118 ERR("vconf_get_int is failed. but ignored [%d]\n", ret);
121 if (vconf_key != SETTING_USB_TETHERING_MODE) {
122 ERR("USB Mode is changed suddenly\n");
123 _disable_usb_tethering(obj);
124 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
125 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
128 if (vconf_key == SETTING_USB_TETHERING_MODE) {
129 DBG("Is progressing for usb mode change\n");
133 DBG("USB tethering is disabled\n");
134 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
135 __handle_usb_mode_change);
136 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
137 dbus_g_method_return(obj->usb_context,
138 MOBILE_AP_DISABLE_USB_TETHERING_CFM,
139 MOBILE_AP_ERROR_NONE);
140 obj->usb_context = NULL;
144 mobile_ap_error_code_e _disable_usb_tethering(MobileAPObject *obj)
146 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
148 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
149 ERR("USB tethering has not been enabled\n");
150 ret = MOBILE_AP_ERROR_NOT_ENABLED;
154 _deinit_tethering(obj);
156 if (_remove_station_info_all(MOBILE_AP_TYPE_USB) != MOBILE_AP_ERROR_NONE) {
157 ERR("_remove_station_info_all is failed. Ignore it\n");
160 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
161 __handle_usb_disconnect_cb);
162 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
163 __handle_usb_disconnect_cb);
165 _mobileap_clear_state(MOBILE_AP_STATE_USB);
167 DBG("_disable_usb_tethering is done\n");
172 gboolean mobileap_enable_usb_tethering(MobileAPObject *obj,
173 DBusGMethodInvocation *context)
176 int usb_mode = SETTING_USB_NONE_MODE;
177 int ret = MOBILE_AP_ERROR_NONE;
181 g_assert(obj != NULL);
182 g_assert(context != NULL);
185 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
186 ERR("USB tethering is already enabled\n");
187 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
188 dbus_g_method_return(context,
189 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
193 if (obj->usb_context) {
194 ERR("USB request is progressing\n");
195 ret = MOBILE_AP_ERROR_IN_PROGRESS;
196 dbus_g_method_return(context,
197 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
201 vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
202 __handle_usb_disconnect_cb, obj);
203 vconf_ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &usb_mode);
204 if (vconf_ret != 0 || usb_mode == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
205 ERR("Error getting vconf\n");
206 ret = MOBILE_AP_ERROR_RESOURCE;
210 if (!_mobileap_set_state(MOBILE_AP_STATE_USB)) {
211 ret = MOBILE_AP_ERROR_RESOURCE;
215 if (!_init_tethering(obj)) {
216 ret = MOBILE_AP_ERROR_RESOURCE;
220 obj->usb_context = context;
221 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
222 __handle_usb_mode_change, (void *)obj);
224 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
225 if (vconf_ret != 0) {
226 ERR("Error getting vconf\n");
227 obj->usb_context = NULL;
228 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
229 __handle_usb_mode_change);
230 _deinit_tethering(obj);
231 ret = MOBILE_AP_ERROR_RESOURCE;
235 if (usb_mode == SETTING_USB_TETHERING_MODE) {
236 DBG("Don't need to wait for usb-setting\n");
237 obj->usb_context = NULL;
238 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
239 __handle_usb_mode_change);
240 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
241 dbus_g_method_return(context,
242 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
250 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
251 __handle_usb_disconnect_cb);
252 _mobileap_clear_state(MOBILE_AP_STATE_USB);
253 dbus_g_method_return(context,
254 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
258 gboolean mobileap_disable_usb_tethering(MobileAPObject *obj,
259 DBusGMethodInvocation *context)
261 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
262 int usb_mode = SETTING_USB_NONE_MODE;
267 g_assert(obj != NULL);
268 g_assert(context != NULL);
270 if (obj->usb_context) {
271 ERR("USB request is progressing\n");
272 ret = MOBILE_AP_ERROR_IN_PROGRESS;
273 dbus_g_method_return(context,
274 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
278 ret = _disable_usb_tethering(obj);
279 if (ret != MOBILE_AP_ERROR_NONE) {
280 dbus_g_method_return(context,
281 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
285 obj->usb_context = context;
286 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
287 __handle_usb_mode_change, (void *)obj);
288 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
289 if (vconf_ret != 0) {
290 ERR("Error getting vconf : %d. This error is ignored\n", vconf_ret);
293 if (usb_mode != SETTING_USB_TETHERING_MODE) {
294 DBG("Don't need to wait for usb-setting\n");
302 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
303 __handle_usb_mode_change);
304 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
305 dbus_g_method_return(context,
306 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
310 static void __add_usb_station_info_to_array(GPtrArray *array, mobile_ap_station_info_t *node)
312 GValue value = {0, {{0}}};
314 g_value_init(&value, DBUS_STRUCT_STATION);
315 g_value_take_boxed(&value,
316 dbus_g_type_specialized_construct(DBUS_STRUCT_STATION));
317 dbus_g_type_struct_set(&value, 0, node->ip, 1, node->mac,
318 2, node->hostname, G_MAXUINT);
319 g_ptr_array_add(array, g_value_get_boxed(&value));
322 gboolean mobileap_get_usb_station_info(MobileAPObject *obj,
323 DBusGMethodInvocation *context)
325 g_assert(obj != NULL);
326 g_assert(context != NULL);
328 GPtrArray *array = g_ptr_array_new();
329 mobile_ap_station_info_t *node = NULL;
331 if (_get_station_info((gconstpointer)MOBILE_AP_TYPE_USB,
332 _slist_find_station_by_interface,
333 &node) != MOBILE_AP_ERROR_NONE) {
334 DBG("There is no USB station\n");
335 dbus_g_method_return(context, array);
336 g_ptr_array_free(array, TRUE);
340 __add_usb_station_info_to_array(array, node);
341 dbus_g_method_return(context, array);
342 g_ptr_array_free(array, TRUE);
347 gboolean mobileap_get_usb_interface_info(MobileAPObject *obj,
348 DBusGMethodInvocation *context)
350 g_assert(obj != NULL);
351 g_assert(context != NULL);
353 GPtrArray *array = g_ptr_array_new();
354 GValue value = {0, {{0}}};
357 addr.s_addr = htonl(IP_ADDRESS_USB);
359 g_value_init(&value, DBUS_STRUCT_INTERFACE);
360 g_value_take_boxed(&value,
361 dbus_g_type_specialized_construct(DBUS_STRUCT_INTERFACE));
362 dbus_g_type_struct_set(&value, 0, USB_IF, 1, inet_ntoa(addr),
363 2, inet_ntoa(addr), 3, IP_SUBNET_MASK, G_MAXUINT);
365 g_ptr_array_add(array, g_value_get_boxed(&value));
366 dbus_g_method_return(context, array);
367 g_ptr_array_free(array, TRUE);