3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 #include <dbus/dbus.h>
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus-glib-lowlevel.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
28 #include "mobileap_agent.h"
29 #include "mobileap_common.h"
30 #include "mobileap_usb.h"
33 static void __handle_usb_disconnect_cb(keynode_t *key, void *data)
35 if (key == NULL || data == NULL) {
36 ERR("Parameter is NULL\n");
42 TetheringObject *obj = (TetheringObject *)data;
44 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
45 ERR("USB tethering is not enabled\n");
49 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
50 ERR("Invalid vconf key type\n");
54 vconf_name = vconf_keynode_get_name(key);
55 vconf_key = vconf_keynode_get_int(key);
56 DBG("key = %s, value = %d(int)\n", vconf_name, vconf_key);
58 if (!strcmp(vconf_name, VCONFKEY_SYSMAN_USB_STATUS) &&
59 vconf_key == VCONFKEY_SYSMAN_USB_DISCONNECTED)
60 DBG("USB is disconnected\n");
61 else if (!strcmp(vconf_name, VCONFKEY_SETAPPL_USB_MODE_INT) &&
62 vconf_key != SETTING_USB_TETHERING_MODE)
63 DBG("USB Mode is changed [%d]\n", vconf_key);
67 _disable_usb_tethering(obj);
68 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
69 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
72 static void __handle_usb_mode_change(keynode_t *key, void *data)
74 if (key == NULL || data == NULL) {
75 ERR("Parameter is NULL\n");
79 TetheringObject *obj = (TetheringObject *)data;
83 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
84 ERR("Invalid vconf key\n");
88 vconf_key = vconf_keynode_get_int(key);
89 DBG("key = %s, value = %d(int)\n",
90 vconf_keynode_get_name(key), vconf_key);
92 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
93 if (vconf_key != SETTING_USB_TETHERING_MODE) {
94 DBG("Is progressing for usb mode change\n");
98 DBG("USB tethering is enabled\n");
99 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
100 __handle_usb_mode_change);
101 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
102 dbus_g_method_return(obj->usb_context,
103 MOBILE_AP_ENABLE_USB_TETHERING_CFM,
104 MOBILE_AP_ERROR_NONE);
105 obj->usb_context = NULL;
107 /* USB Mode change is handled while USB tethering is enabled */
108 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
109 __handle_usb_disconnect_cb, (void *)obj);
110 ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &vconf_key);
112 ERR("vconf_get_int is failed. but ignored [%d]\n", ret);
115 if (vconf_key != SETTING_USB_TETHERING_MODE) {
116 ERR("USB Mode is changed suddenly\n");
117 _disable_usb_tethering(obj);
118 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
119 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
122 if (vconf_key == SETTING_USB_TETHERING_MODE) {
123 DBG("Is progressing for usb mode change\n");
127 DBG("USB tethering is disabled\n");
128 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
129 __handle_usb_mode_change);
130 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
131 dbus_g_method_return(obj->usb_context,
132 MOBILE_AP_DISABLE_USB_TETHERING_CFM,
133 MOBILE_AP_ERROR_NONE);
134 obj->usb_context = NULL;
138 mobile_ap_error_code_e _enable_usb_tethering(TetheringObject *obj,
139 DBusGMethodInvocation *context)
141 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
143 int usb_mode = SETTING_USB_NONE_MODE;
145 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
146 ERR("USB tethering is already enabled\n");
147 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
151 if (obj->usb_context) {
152 ERR("USB request is progressing\n");
153 ret = MOBILE_AP_ERROR_IN_PROGRESS;
157 vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
158 __handle_usb_disconnect_cb, obj);
159 vconf_ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &usb_mode);
160 if (vconf_ret != 0 || usb_mode == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
161 ERR("Error getting vconf\n");
162 ret = MOBILE_AP_ERROR_RESOURCE;
166 if (!_mobileap_set_state(MOBILE_AP_STATE_USB)) {
167 ret = MOBILE_AP_ERROR_RESOURCE;
171 if (!_init_tethering(obj)) {
172 ret = MOBILE_AP_ERROR_RESOURCE;
176 obj->usb_context = context;
177 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
178 __handle_usb_mode_change, (void *)obj);
180 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
181 if (vconf_ret != 0) {
182 ERR("Error getting vconf\n");
183 obj->usb_context = NULL;
184 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
185 __handle_usb_mode_change);
186 _deinit_tethering(obj);
187 ret = MOBILE_AP_ERROR_RESOURCE;
191 if (usb_mode == SETTING_USB_TETHERING_MODE) {
192 obj->usb_context = NULL;
193 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
194 __handle_usb_mode_change);
198 return MOBILE_AP_ERROR_NONE;
201 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
202 __handle_usb_disconnect_cb);
203 _mobileap_clear_state(MOBILE_AP_STATE_USB);
208 mobile_ap_error_code_e _disable_usb_tethering(TetheringObject *obj)
210 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
212 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
213 ERR("USB tethering has not been enabled\n");
214 ret = MOBILE_AP_ERROR_NOT_ENABLED;
218 _deinit_tethering(obj);
220 if (_remove_station_info_all(MOBILE_AP_TYPE_USB) != MOBILE_AP_ERROR_NONE) {
221 ERR("_remove_station_info_all is failed. Ignore it\n");
224 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
225 __handle_usb_disconnect_cb);
226 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
227 __handle_usb_disconnect_cb);
229 _mobileap_clear_state(MOBILE_AP_STATE_USB);
231 DBG("_disable_usb_tethering is done\n");
236 gboolean tethering_enable_usb_tethering(TetheringObject *obj,
237 DBusGMethodInvocation *context)
239 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
243 g_assert(obj != NULL);
244 g_assert(context != NULL);
247 ret = _enable_usb_tethering(obj, context);
248 if (ret != MOBILE_AP_ERROR_NONE) {
249 ERR("_enable_usb_tethering() is failed : %d\n", ret);
250 dbus_g_method_return(context,
251 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
253 } else if (obj->usb_context == NULL) {
254 DBG("Don't need to wait for usb-setting\n");
255 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
256 dbus_g_method_return(context,
257 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
259 DBG("dbus will be returned by vconf callback\n");
266 gboolean tethering_disable_usb_tethering(TetheringObject *obj,
267 DBusGMethodInvocation *context)
269 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
270 int usb_mode = SETTING_USB_NONE_MODE;
275 g_assert(obj != NULL);
276 g_assert(context != NULL);
278 if (obj->usb_context) {
279 ERR("USB request is progressing\n");
280 ret = MOBILE_AP_ERROR_IN_PROGRESS;
281 dbus_g_method_return(context,
282 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
286 ret = _disable_usb_tethering(obj);
287 if (ret != MOBILE_AP_ERROR_NONE) {
288 dbus_g_method_return(context,
289 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
293 obj->usb_context = context;
294 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
295 __handle_usb_mode_change, (void *)obj);
296 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
297 if (vconf_ret != 0) {
298 ERR("Error getting vconf : %d. This error is ignored\n", vconf_ret);
301 if (usb_mode != SETTING_USB_TETHERING_MODE) {
302 DBG("Don't need to wait for usb-setting\n");
310 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
311 __handle_usb_mode_change);
312 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
313 dbus_g_method_return(context,
314 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
318 static void __add_usb_station_info_to_array(GPtrArray *array, mobile_ap_station_info_t *node)
320 GValue value = {0, {{0}}};
322 g_value_init(&value, DBUS_STRUCT_STATION);
323 g_value_take_boxed(&value,
324 dbus_g_type_specialized_construct(DBUS_STRUCT_STATION));
325 dbus_g_type_struct_set(&value, 0, node->ip, 1, node->mac,
326 2, node->hostname, G_MAXUINT);
327 g_ptr_array_add(array, g_value_get_boxed(&value));
330 gboolean tethering_get_usb_station_info(TetheringObject *obj,
331 DBusGMethodInvocation *context)
333 g_assert(obj != NULL);
334 g_assert(context != NULL);
336 GPtrArray *array = g_ptr_array_new();
337 mobile_ap_station_info_t *node = NULL;
339 if (_get_station_info((gconstpointer)MOBILE_AP_TYPE_USB,
340 _slist_find_station_by_interface,
341 &node) != MOBILE_AP_ERROR_NONE) {
342 DBG("There is no USB station\n");
343 dbus_g_method_return(context, array);
344 g_ptr_array_free(array, TRUE);
348 __add_usb_station_info_to_array(array, node);
349 dbus_g_method_return(context, array);
350 g_ptr_array_free(array, TRUE);
355 gboolean tethering_get_usb_interface_info(TetheringObject *obj,
356 DBusGMethodInvocation *context)
358 g_assert(obj != NULL);
359 g_assert(context != NULL);
361 GPtrArray *array = g_ptr_array_new();
362 GValue value = {0, {{0}}};
365 addr.s_addr = htonl(IP_ADDRESS_USB);
367 g_value_init(&value, DBUS_STRUCT_INTERFACE);
368 g_value_take_boxed(&value,
369 dbus_g_type_specialized_construct(DBUS_STRUCT_INTERFACE));
370 dbus_g_type_struct_set(&value, 0, USB_IF, 1, inet_ntoa(addr),
371 2, inet_ntoa(addr), 3, IP_SUBNET_MASK, G_MAXUINT);
373 g_ptr_array_add(array, g_value_get_boxed(&value));
374 dbus_g_method_return(context, array);
375 g_ptr_array_free(array, TRUE);