4 * Copyright 2012-2013 Samsung Electronics Co., Ltd
6 * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license
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.
21 #include <dbus/dbus.h>
22 #include <dbus/dbus-glib.h>
23 #include <dbus/dbus-glib-lowlevel.h>
26 #include <sys/socket.h>
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
30 #include "mobileap_agent.h"
31 #include "mobileap_common.h"
32 #include "mobileap_usb.h"
35 static void __handle_usb_disconnect_cb(keynode_t *key, void *data)
37 if (key == NULL || data == NULL) {
38 ERR("Parameter is NULL\n");
44 TetheringObject *obj = (TetheringObject *)data;
46 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
47 ERR("USB tethering is not enabled\n");
51 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
52 ERR("Invalid vconf key type\n");
56 vconf_name = vconf_keynode_get_name(key);
57 vconf_key = vconf_keynode_get_int(key);
58 DBG("key = %s, value = %d(int)\n", vconf_name, vconf_key);
60 if (!strcmp(vconf_name, VCONFKEY_SYSMAN_USB_STATUS) &&
61 vconf_key == VCONFKEY_SYSMAN_USB_DISCONNECTED)
62 DBG("USB is disconnected\n");
63 else if (!strcmp(vconf_name, VCONFKEY_SETAPPL_USB_MODE_INT) &&
64 vconf_key != SETTING_USB_TETHERING_MODE)
65 DBG("USB Mode is changed [%d]\n", vconf_key);
69 _disable_usb_tethering(obj);
70 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
71 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
74 static void __handle_usb_mode_change(keynode_t *key, void *data)
76 if (key == NULL || data == NULL) {
77 ERR("Parameter is NULL\n");
81 TetheringObject *obj = (TetheringObject *)data;
85 if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
86 ERR("Invalid vconf key\n");
90 vconf_key = vconf_keynode_get_int(key);
91 DBG("key = %s, value = %d(int)\n",
92 vconf_keynode_get_name(key), vconf_key);
94 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
95 if (vconf_key != SETTING_USB_TETHERING_MODE) {
96 DBG("Is progressing for usb mode change\n");
100 DBG("USB tethering is enabled\n");
101 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
102 __handle_usb_mode_change);
103 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
104 dbus_g_method_return(obj->usb_context,
105 MOBILE_AP_ENABLE_USB_TETHERING_CFM,
106 MOBILE_AP_ERROR_NONE);
107 obj->usb_context = NULL;
109 /* USB Mode change is handled while USB tethering is enabled */
110 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
111 __handle_usb_disconnect_cb, (void *)obj);
112 ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &vconf_key);
114 ERR("vconf_get_int is failed. but ignored [%d]\n", ret);
117 if (vconf_key != SETTING_USB_TETHERING_MODE) {
118 ERR("USB Mode is changed suddenly\n");
119 _disable_usb_tethering(obj);
120 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF,
121 SIGNAL_MSG_NOT_AVAIL_INTERFACE);
124 if (vconf_key == SETTING_USB_TETHERING_MODE) {
125 DBG("Is progressing for usb mode change\n");
129 DBG("USB tethering is disabled\n");
130 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
131 __handle_usb_mode_change);
132 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
133 dbus_g_method_return(obj->usb_context,
134 MOBILE_AP_DISABLE_USB_TETHERING_CFM,
135 MOBILE_AP_ERROR_NONE);
136 obj->usb_context = NULL;
140 mobile_ap_error_code_e _enable_usb_tethering(TetheringObject *obj,
141 DBusGMethodInvocation *context)
143 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
145 int usb_mode = SETTING_USB_NONE_MODE;
147 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
148 ERR("USB tethering is already enabled\n");
149 ret = MOBILE_AP_ERROR_ALREADY_ENABLED;
153 if (obj->usb_context) {
154 ERR("USB request is progressing\n");
155 ret = MOBILE_AP_ERROR_IN_PROGRESS;
159 vconf_notify_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
160 __handle_usb_disconnect_cb, obj);
161 vconf_ret = vconf_get_int(VCONFKEY_SYSMAN_USB_STATUS, &usb_mode);
162 if (vconf_ret != 0 || usb_mode == VCONFKEY_SYSMAN_USB_DISCONNECTED) {
163 ERR("Error getting vconf\n");
164 ret = MOBILE_AP_ERROR_RESOURCE;
168 if (!_mobileap_set_state(MOBILE_AP_STATE_USB)) {
169 ret = MOBILE_AP_ERROR_RESOURCE;
173 if (!_init_tethering(obj)) {
174 ret = MOBILE_AP_ERROR_RESOURCE;
178 obj->usb_context = context;
179 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
180 __handle_usb_mode_change, (void *)obj);
182 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
183 if (vconf_ret != 0) {
184 ERR("Error getting vconf\n");
185 obj->usb_context = NULL;
186 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
187 __handle_usb_mode_change);
188 _deinit_tethering(obj);
189 ret = MOBILE_AP_ERROR_RESOURCE;
193 if (usb_mode == SETTING_USB_TETHERING_MODE) {
194 obj->usb_context = NULL;
195 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
196 __handle_usb_mode_change);
200 return MOBILE_AP_ERROR_NONE;
203 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
204 __handle_usb_disconnect_cb);
205 _mobileap_clear_state(MOBILE_AP_STATE_USB);
210 mobile_ap_error_code_e _disable_usb_tethering(TetheringObject *obj)
212 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
214 if (!_mobileap_is_enabled(MOBILE_AP_STATE_USB)) {
215 ERR("USB tethering has not been enabled\n");
216 ret = MOBILE_AP_ERROR_NOT_ENABLED;
220 _deinit_tethering(obj);
222 if (_remove_station_info_all(MOBILE_AP_TYPE_USB) != MOBILE_AP_ERROR_NONE) {
223 ERR("_remove_station_info_all is failed. Ignore it\n");
226 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
227 __handle_usb_disconnect_cb);
228 vconf_ignore_key_changed(VCONFKEY_SYSMAN_USB_STATUS,
229 __handle_usb_disconnect_cb);
231 _mobileap_clear_state(MOBILE_AP_STATE_USB);
233 DBG("_disable_usb_tethering is done\n");
238 gboolean tethering_enable_usb_tethering(TetheringObject *obj,
239 DBusGMethodInvocation *context)
241 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
245 g_assert(obj != NULL);
246 g_assert(context != NULL);
249 ret = _enable_usb_tethering(obj, context);
250 if (ret != MOBILE_AP_ERROR_NONE) {
251 ERR("_enable_usb_tethering() is failed : %d\n", ret);
252 dbus_g_method_return(context,
253 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
255 } else if (obj->usb_context == NULL) {
256 DBG("Don't need to wait for usb-setting\n");
257 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_ON, NULL);
258 dbus_g_method_return(context,
259 MOBILE_AP_ENABLE_USB_TETHERING_CFM, ret);
261 DBG("dbus will be returned by vconf callback\n");
268 gboolean tethering_disable_usb_tethering(TetheringObject *obj,
269 DBusGMethodInvocation *context)
271 mobile_ap_error_code_e ret = MOBILE_AP_ERROR_NONE;
272 int usb_mode = SETTING_USB_NONE_MODE;
277 g_assert(obj != NULL);
278 g_assert(context != NULL);
280 if (obj->usb_context) {
281 ERR("USB request is progressing\n");
282 ret = MOBILE_AP_ERROR_IN_PROGRESS;
283 dbus_g_method_return(context,
284 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
288 ret = _disable_usb_tethering(obj);
289 if (ret != MOBILE_AP_ERROR_NONE) {
290 dbus_g_method_return(context,
291 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
295 obj->usb_context = context;
296 vconf_notify_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
297 __handle_usb_mode_change, (void *)obj);
298 vconf_ret = vconf_get_int(VCONFKEY_SETAPPL_USB_MODE_INT, &usb_mode);
299 if (vconf_ret != 0) {
300 ERR("Error getting vconf : %d. This error is ignored\n", vconf_ret);
303 if (usb_mode != SETTING_USB_TETHERING_MODE) {
304 DBG("Don't need to wait for usb-setting\n");
312 vconf_ignore_key_changed(VCONFKEY_SETAPPL_USB_MODE_INT,
313 __handle_usb_mode_change);
314 _emit_mobileap_dbus_signal(obj, E_SIGNAL_USB_TETHER_OFF, NULL);
315 dbus_g_method_return(context,
316 MOBILE_AP_DISABLE_USB_TETHERING_CFM, ret);
320 static void __add_usb_station_info_to_array(GPtrArray *array, mobile_ap_station_info_t *node)
322 GValue value = {0, {{0}}};
324 g_value_init(&value, DBUS_STRUCT_STATION);
325 g_value_take_boxed(&value,
326 dbus_g_type_specialized_construct(DBUS_STRUCT_STATION));
327 dbus_g_type_struct_set(&value, 0, node->ip, 1, node->mac,
328 2, node->hostname, G_MAXUINT);
329 g_ptr_array_add(array, g_value_get_boxed(&value));
332 gboolean tethering_get_usb_station_info(TetheringObject *obj,
333 DBusGMethodInvocation *context)
335 g_assert(obj != NULL);
336 g_assert(context != NULL);
338 GPtrArray *array = g_ptr_array_new();
339 mobile_ap_station_info_t *node = NULL;
341 if (_get_station_info((gconstpointer)MOBILE_AP_TYPE_USB,
342 _slist_find_station_by_interface,
343 &node) != MOBILE_AP_ERROR_NONE) {
344 DBG("There is no USB station\n");
345 dbus_g_method_return(context, array);
346 g_ptr_array_free(array, TRUE);
350 __add_usb_station_info_to_array(array, node);
351 dbus_g_method_return(context, array);
352 g_ptr_array_free(array, TRUE);
357 gboolean tethering_get_usb_interface_info(TetheringObject *obj,
358 DBusGMethodInvocation *context)
360 g_assert(obj != NULL);
361 g_assert(context != NULL);
363 GPtrArray *array = g_ptr_array_new();
364 GValue value = {0, {{0}}};
367 addr.s_addr = htonl(IP_ADDRESS_USB);
369 g_value_init(&value, DBUS_STRUCT_INTERFACE);
370 g_value_take_boxed(&value,
371 dbus_g_type_specialized_construct(DBUS_STRUCT_INTERFACE));
372 dbus_g_type_struct_set(&value, 0, USB_IF, 1, inet_ntoa(addr),
373 2, inet_ntoa(addr), 3, IP_SUBNET_MASK, G_MAXUINT);
375 g_ptr_array_add(array, g_value_get_boxed(&value));
376 dbus_g_method_return(context, array);
377 g_ptr_array_free(array, TRUE);