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.
21 #include <dbus/dbus.h>
26 #include <dd-display.h>
28 #include <net_connection.h>
29 #include <appcore-common.h>
33 #include "mobileap_softap.h"
34 #include "mobileap_handler.h"
35 #include "mobileap_common.h"
36 #include "mobileap_bluetooth.h"
37 #include "mobileap_wifi.h"
38 #include "mobileap_usb.h"
39 #include "mobileap_network.h"
40 #include "mobileap_notification.h"
41 #include "mobileap_iptables.h"
43 GMainLoop *mainloop = NULL;
44 int mobileap_state = MOBILE_AP_STATE_NONE;
46 GDBusObjectManagerServer *manager_server = NULL;
48 GDBusConnection *teth_gdbus_conn = NULL;
49 Tethering *tethering_obj = NULL;
50 static int init_count = 0;
51 guint conn_sig_id = 0;
52 guint deleted_sig_id = 0;
53 gboolean tethering_disable(Tethering *obj, GDBusMethodInvocation *context);
54 gboolean tethering_get_station_info(Tethering *obj,
55 GDBusMethodInvocation *context);
56 gboolean tethering_get_data_packet_usage(Tethering *obj,
57 GDBusMethodInvocation *context);
59 Tethering *_get_tethering_obj(void)
64 gboolean _mobileap_set_state(int state)
68 mobileap_state |= state;
70 vconf_ret = vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_MODE, mobileap_state);
72 ERR("vconf_set_int is failed : %d\n", vconf_ret);
79 gboolean _mobileap_is_disabled(void)
81 return mobileap_state ? FALSE : TRUE;
84 gboolean _mobileap_is_enabled(int state)
86 return (mobileap_state & state) ? TRUE : FALSE;
89 gboolean _mobileap_is_enabled_by_type(mobile_ap_type_e type)
92 case MOBILE_AP_TYPE_WIFI:
93 if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
97 case MOBILE_AP_TYPE_BT:
98 if (_mobileap_is_enabled(MOBILE_AP_STATE_BT))
102 case MOBILE_AP_TYPE_USB:
103 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB))
107 case MOBILE_AP_TYPE_WIFI_AP:
108 if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
113 ERR("Unknow type : %d\n", type);
120 gboolean _mobileap_clear_state(int state)
124 mobileap_state &= (~state);
126 vconf_ret = vconf_set_int(VCONFKEY_MOBILE_HOTSPOT_MODE, mobileap_state);
127 if (vconf_ret != 0) {
128 ERR("vconf_set_int is failed : %d\n", vconf_ret);
135 gboolean _terminate_mobileap_agent(gpointer user_data)
137 if (mainloop == NULL) {
141 if (!_mobileap_is_disabled()) {
142 DBG("Tethering is enabled\n");
146 if (_is_trying_network_operation()) {
147 DBG("Network operation is going on\n");
151 if (_is_trying_wifi_operation()) {
152 DBG("Wi-Fi operation is going on\n");
156 if (_is_trying_bt_operation()) {
157 DBG("BT operation is going on\n");
161 if (_is_trying_usb_operation()) {
162 DBG("USB operation is going on\n");
166 DBG("All tethering / AP's are turned off\n");
167 g_main_loop_quit(mainloop);
173 void _block_device_sleep(void)
177 ret = display_lock_state(LCD_OFF, STAY_CUR_STATE, 0);
179 ERR("PM control [ERROR] result = %d\n", ret);
181 DBG("PM control [SUCCESS]\n");
184 void _unblock_device_sleep(void)
188 ret = display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN);
190 ERR("PM control [ERROR] result = %d\n", ret);
192 DBG("PM control [SUCCESS]\n");
195 int _init_tethering(void)
197 int ret = MOBILE_AP_ERROR_NONE;
199 DBG("init_count: %d\n", init_count);
201 if (init_count > 0) {
203 return MOBILE_AP_ERROR_NONE;
206 if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
207 ret = _open_network();
209 _mh_core_execute_dhcp_server();
216 gboolean _deinit_tethering(void)
218 DBG("obj->init_count: %d\n", init_count);
222 if (init_count > 1) {
225 } else if (init_count <= 0) {
226 ERR("Already deinitialized\n");
233 _mh_core_terminate_dhcp_server();
235 if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
239 idle_id = g_idle_add(_terminate_mobileap_agent, NULL);
241 ERR("g_idle_add is failed\n");
247 gboolean tethering_disable(Tethering *obj, GDBusMethodInvocation *context)
249 int ret = MOBILE_AP_ERROR_NONE;
252 g_assert(obj != NULL);
253 g_assert(context != NULL);
255 if (_mobileap_is_disabled()) {
256 ERR("Mobile hotspot has not been enabled\n");
257 ret = MOBILE_AP_ERROR_NOT_ENABLED;
258 tethering_complete_disable(obj, context, MOBILE_AP_DISABLE_CFM, ret);
262 _disable_wifi_tethering(obj);
263 _disable_bt_tethering(obj);
264 _disable_usb_tethering(obj);
266 tethering_complete_disable(obj, context, MOBILE_AP_DISABLE_CFM, ret);
271 gboolean tethering_get_station_info(Tethering *obj,
272 GDBusMethodInvocation *context)
276 GVariant *var = NULL;
278 g_assert(obj != NULL);
279 g_assert(context != NULL);
281 var = _station_info_foreach();
283 g_dbus_method_invocation_return_value(context, var);
284 g_variant_unref(var);
290 gboolean tethering_get_data_packet_usage(Tethering *obj,
291 GDBusMethodInvocation *context)
293 char *if_name = NULL;
294 unsigned long long wifi_tx_bytes = 0;
295 unsigned long long wifi_rx_bytes = 0;
296 unsigned long long bt_tx_bytes = 0;
297 unsigned long long bt_rx_bytes = 0;
298 unsigned long long usb_tx_bytes = 0;
299 unsigned long long usb_rx_bytes = 0;
300 unsigned long long tx_bytes = 0;
301 unsigned long long rx_bytes = 0;
303 if (_get_network_interface_name(&if_name) == FALSE) {
304 tethering_complete_get_data_packet_usage(obj, context,
305 MOBILE_AP_GET_DATA_PACKET_USAGE_CFM,
310 if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
311 _get_data_usage(WIFI_IF, if_name,
312 &wifi_tx_bytes, &wifi_rx_bytes);
314 if (_mobileap_is_enabled(MOBILE_AP_STATE_BT))
315 _get_data_usage(BT_IF_ALL, if_name,
316 &bt_tx_bytes, &bt_rx_bytes);
318 if (_mobileap_is_enabled(MOBILE_AP_STATE_USB))
319 _get_data_usage(USB_IF, if_name,
320 &usb_tx_bytes, &usb_rx_bytes);
323 tx_bytes = wifi_tx_bytes + bt_tx_bytes + usb_tx_bytes;
324 rx_bytes = wifi_rx_bytes + bt_rx_bytes + usb_rx_bytes;
326 tethering_complete_get_data_packet_usage(obj, context, MOBILE_AP_GET_DATA_PACKET_USAGE_CFM,
332 void static __handle_dnsmasq_dhcp_status_changed_cb(GDBusConnection *connection,
333 const gchar *sender_name, const gchar *object_path,
334 const gchar *interface_name, const gchar *signal_name,
335 GVariant *parameters, gpointer user_data)
338 char *ip_addr = NULL;
341 char *bt_remote_device_name = NULL;
342 mobile_ap_type_e type = MOBILE_AP_TYPE_MAX;
343 mobile_ap_station_info_t *info = NULL;
347 if (signal_name == NULL) {
348 ERR("singal name is NULL\n");
351 g_variant_get(parameters, "(sss)", &ip_addr, &mac, &name);
352 if (!g_strcmp0(signal_name, "DhcpConnected")) {
353 SDBG("DhcpConnected signal : %s %s %s\n", ip_addr, mac, name);
355 * DHCP ACK received, destroy timeout if exists
357 if (ip_addr == NULL || mac == NULL) {
360 _destroy_dhcp_ack_timer(mac);
362 if (_get_tethering_type_from_ip(ip_addr, &type) != MOBILE_AP_ERROR_NONE)
365 if (_mobileap_is_enabled_by_type(type) == FALSE) {
369 info = (mobile_ap_station_info_t *)g_malloc(sizeof(mobile_ap_station_info_t));
371 ERR("malloc failed\n");
375 info->interface = type;
376 g_strlcpy(info->ip, ip_addr, sizeof(info->ip));
377 g_strlcpy(info->mac, mac, sizeof(info->mac));
378 if (type == MOBILE_AP_TYPE_WIFI || type == MOBILE_AP_TYPE_USB ||
379 type == MOBILE_AP_TYPE_WIFI_AP) {
381 info->hostname = g_strdup(MOBILE_AP_NAME_UNKNOWN);
383 info->hostname = g_strdup(name);
384 } else if (type == MOBILE_AP_TYPE_BT) {
385 _bt_get_remote_device_name(mac, &bt_remote_device_name);
386 if (bt_remote_device_name == NULL)
387 info->hostname = g_strdup(MOBILE_AP_NAME_UNKNOWN);
389 info->hostname = bt_remote_device_name;
393 if (_add_station_info(info) != MOBILE_AP_ERROR_NONE) {
394 ERR("_add_station_info is failed\n");
395 g_free(info->hostname);
400 _get_station_count((gconstpointer)type,
401 _slist_find_station_by_interface, &n_station);
403 _stop_timeout_cb(type);
405 _send_dbus_station_info("DhcpConnected", info);
406 } else if (!g_strcmp0(signal_name, "DhcpLeaseDeleted")) {
407 SDBG("DhcpLeaseDeleted signal : %s %s %s\n", ip_addr, mac, name);
408 _remove_station_info(ip_addr, _slist_find_station_by_ip_addr);
410 SDBG("UNKNOWN member signal\n");
419 static void on_bus_acquired_cb (GDBusConnection *connection, const gchar *name,
423 GDBusInterfaceSkeleton *intf = NULL;
424 teth_gdbus_conn = connection;
426 manager_server = g_dbus_object_manager_server_new(TETHERING_SERVICE_OBJECT_PATH);
427 if(manager_server == NULL) {
428 DBG("Manager server not created.");
431 tethering_obj = tethering_skeleton_new();
432 intf = G_DBUS_INTERFACE_SKELETON(tethering_obj);
433 if (!g_dbus_interface_skeleton_export(intf, connection,
434 TETHERING_SERVICE_OBJECT_PATH, NULL)) {
435 ERR("Export with path failed");
437 DBG("Export sucessss");
440 g_signal_connect(tethering_obj, "handle-enable-wifi-tethering",
441 G_CALLBACK(tethering_enable_wifi_tethering), NULL);
442 g_signal_connect(tethering_obj, "handle-enable-bt-tethering",
443 G_CALLBACK(tethering_enable_bt_tethering), NULL);
444 g_signal_connect(tethering_obj, "handle-enable-usb-tethering",
445 G_CALLBACK(tethering_enable_usb_tethering), NULL);
446 g_signal_connect(tethering_obj, "handle-disable-wifi-tethering",
447 G_CALLBACK(tethering_disable_wifi_tethering), NULL);
448 g_signal_connect(tethering_obj, "handle-disable-bt-tethering",
449 G_CALLBACK(tethering_disable_bt_tethering), NULL);
450 g_signal_connect(tethering_obj, "handle-disable-usb-tethering",
451 G_CALLBACK(tethering_disable_usb_tethering), NULL);
452 g_signal_connect(tethering_obj, "handle-enable-wifi-ap",
453 G_CALLBACK(tethering_enable_wifi_ap), NULL);
455 g_signal_connect(tethering_obj, "handle-disable-wifi-ap",
456 G_CALLBACK(tethering_disable_wifi_ap), NULL);
457 g_signal_connect(tethering_obj, "handle-reload-wifi-settings",
458 G_CALLBACK(tethering_reload_wifi_settings), NULL);
459 g_signal_connect(tethering_obj, "handle-reload-wifi-ap-settings",
460 G_CALLBACK(tethering_reload_wifi_ap_settings), NULL);
461 g_signal_connect(tethering_obj, "handle-get-station-info",
462 G_CALLBACK(tethering_get_station_info), NULL);
463 g_signal_connect(tethering_obj, "handle-get-data-packet-usage",
464 G_CALLBACK(tethering_get_data_packet_usage), NULL);
466 _init_network((void *)tethering_obj);
467 _register_vconf_cb((void *)tethering_obj);
469 conn_sig_id = g_dbus_connection_signal_subscribe(connection, NULL, DNSMASQ_DBUS_INTERFACE,
470 "DhcpConnected", NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
471 __handle_dnsmasq_dhcp_status_changed_cb, NULL, NULL);
472 deleted_sig_id = g_dbus_connection_signal_subscribe(connection, NULL, DNSMASQ_DBUS_INTERFACE,
473 "DhcpLeaseDeleted", NULL, NULL, G_DBUS_SIGNAL_FLAGS_NONE,
474 __handle_dnsmasq_dhcp_status_changed_cb, NULL, NULL);
476 g_dbus_object_manager_server_set_connection(manager_server, connection);
480 static void on_name_acquired_cb(GDBusConnection *connection, const gchar *name,
488 static void on_name_lost_db(GDBusConnection *conn, const gchar *name,
492 /* May service name is already in use */
493 ERR("Service name is already in use");
495 /* The result of DBus name request is only permitted,
496 * such as DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER.
503 static int __tethering_setup_gdbus(void)
507 owner_id = g_bus_own_name(DBUS_BUS_SYSTEM, TETHERING_SERVICE_NAME,
508 G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired_cb,
509 on_name_acquired_cb, on_name_lost_db, NULL, NULL);
512 ERR("g_bus_own_name is failed\n");
517 int main(int argc, char **argv)
523 #if !GLIB_CHECK_VERSION(2,36,0)
527 mainloop = g_main_loop_new(NULL, FALSE);
528 if (mainloop == NULL) {
529 ERR("Couldn't create GMainLoop\n");
533 ret = __tethering_setup_gdbus();
535 ERR("tethering_setup_gdbus is failed\n");
538 /* Platform modules */
539 if (appcore_set_i18n(MOBILEAP_LOCALE_COMMON_PKG, MOBILEAP_LOCALE_COMMON_RES) < 0) {
540 ERR("appcore_set_i18n is failed\n");
543 if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &mobileap_state) < 0) {
544 ERR("vconf_get_int is failed\n");
545 mobileap_state = MOBILE_AP_STATE_NONE;
548 _register_wifi_station_handler();
550 ret = wifi_initialize();
551 if (ret != WIFI_ERROR_NONE) {
552 ERR("wifi_initialize() is failed : %d\n", ret);
555 ret = alarmmgr_init(APPNAME);
556 if (ret != ALARMMGR_RESULT_SUCCESS) {
557 ERR("alarmmgr_init(%s) is failed : %d\n", APPNAME, ret);
559 ret = alarmmgr_set_cb(_sp_timeout_handler, NULL);
560 if (ret != ALARMMGR_RESULT_SUCCESS) {
561 ERR("alarmmgr_set_cb is failed : %d\n", ret);
565 g_main_loop_run(mainloop);
569 ret = wifi_deinitialize();
570 if (ret != WIFI_ERROR_NONE) {
571 ERR("wifi_deinitialize() is failed : %d\n", ret);
574 _unregister_vconf_cb();
575 _unregister_wifi_station_handler();
578 g_dbus_connection_signal_unsubscribe(teth_gdbus_conn, conn_sig_id);
579 g_dbus_connection_signal_unsubscribe(teth_gdbus_conn, deleted_sig_id);
581 g_object_unref(tethering_obj);
582 g_bus_unown_name(owner_id);
583 g_object_unref(manager_server);