2 * Network Configuration Module
4 * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
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.
21 * This file implements wifi direct manager functions.
23 * @file wifi-direct-manager.c
24 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
31 #include <sys/utsname.h>
36 #include <glib-object.h>
37 #include <wifi-direct.h>
39 #include "wifi-direct-ipc.h"
40 #include "wifi-direct-manager.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-session.h"
43 #include "wifi-direct-group.h"
44 #include "wifi-direct-peer.h"
45 #include "wifi-direct-state.h"
46 #include "wifi-direct-client.h"
47 #include "wifi-direct-event.h"
48 #include "wifi-direct-util.h"
50 wfd_manager_s *g_manager;
52 wfd_manager_s *wfd_get_manager()
57 static gboolean _wfd_exit_timeout_cb(void *user_data)
59 __WDS_LOG_FUNC_ENTER__;
60 wfd_manager_s *manager = (wfd_manager_s*) user_data;
63 WDS_LOGE("Invalid parameter");
67 if (manager->client_count > 0) {
68 WDS_LOGD("Client count [%d]", manager->client_count);
72 if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
73 WDS_LOGD("Terminate Wi-Fi Direct Manager");
74 g_main_quit(manager->main_loop);
76 manager->exit_timer = 0;
77 WDS_LOGD( "Stop exit timer. State [%d]", manager->state);
79 __WDS_LOG_FUNC_EXIT__;
83 static int _wfd_local_init_device(wfd_manager_s *manager)
85 __WDS_LOG_FUNC_ENTER__;
86 wfd_device_s *local = NULL;
90 WDS_LOGE("Invalid parameter");
95 local = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
97 WDS_LOGE("Failed to allocate memory for local device [%s]", strerror(errno));
101 res = wfd_util_get_phone_name(local->dev_name);
103 WDS_LOGE("Failed to get phone name of local device. Use default device name");
104 g_strlcpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN + 1);
106 WDS_LOGD("Local Device name [%s]", local->dev_name);
107 wfd_util_set_dev_name_notification();
109 res = wfd_util_get_local_dev_mac(local->dev_addr);
111 WDS_LOGE("Failed to get local device MAC address");
114 memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
115 local->intf_addr[4] ^= 0x80;
116 WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
117 MAC2SECSTR(local->intf_addr));
119 local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
120 local->wps_mode = WFD_WPS_MODE_PBC;
121 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
122 local->services = NULL;
123 local->service_count = 0;
124 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
125 // TODO: initialize other local device datas
126 manager->local = local;
128 __WDS_LOG_FUNC_EXIT__;
132 static int _wfd_local_deinit_device(wfd_manager_s *manager)
134 __WDS_LOG_FUNC_ENTER__;
137 WDS_LOGE("Invalid parameter");
141 wfd_util_unset_dev_name_notification();
143 // TODO: free member of local device
144 g_free(manager->local);
146 __WDS_LOG_FUNC_EXIT__;
150 int wfd_local_reset_data(wfd_manager_s *manager)
152 __WDS_LOG_FUNC_ENTER__;
153 wfd_device_s *local = NULL;
156 WDS_LOGE("Invalid parameter");
160 local = manager->local;
161 /* init local device data */
162 local->dev_role = WFD_DEV_ROLE_NONE;
163 local->wps_mode = WFD_WPS_MODE_PBC;
164 memset(local->go_dev_addr, 0x0, MACADDR_LEN);
165 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
166 memset(&(local->display), 0x0, sizeof(wfd_display_s));
167 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
168 memset(local->ip_addr, 0x0, IPADDR_LEN);
170 __WDS_LOG_FUNC_EXIT__;
174 int wfd_local_get_dev_name(char *dev_name)
176 __WDS_LOG_FUNC_ENTER__;
177 wfd_device_s *local = g_manager->local;
180 WDS_LOGE("Invalid parameter");
181 __WDS_LOG_FUNC_EXIT__;
185 g_strlcpy(dev_name, local->dev_name, DEV_NAME_LEN + 1);
186 WDS_LOGD("Local device name [%s]", dev_name);
188 __WDS_LOG_FUNC_EXIT__;
192 int wfd_local_set_dev_name(char *dev_name)
194 __WDS_LOG_FUNC_ENTER__;
195 wfd_device_s *local = g_manager->local;
198 WDS_LOGE("Invalid parameter");
199 __WDS_LOG_FUNC_EXIT__;
203 g_strlcpy(local->dev_name, dev_name, DEV_NAME_LEN + 1);
205 if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
206 wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
207 WDS_LOGD("Device name changed.");
210 WDS_LOGE("Device name can't changed: state is %d",g_manager->state);
213 __WDS_LOG_FUNC_EXIT__;
217 int wfd_local_get_dev_mac(char *dev_mac)
219 __WDS_LOG_FUNC_ENTER__;
220 wfd_device_s *local = g_manager->local;
223 WDS_LOGE("Invalid parameter");
224 __WDS_LOG_FUNC_EXIT__;
228 g_snprintf(dev_mac, MACSTR_LEN, MACSTR, MAC2STR(local->dev_addr));
229 WDS_SECLOGD("Local device MAC address [%s]", dev_mac);
231 __WDS_LOG_FUNC_EXIT__;
236 int wfd_local_get_intf_mac(unsigned char *intf_mac)
238 __WDS_LOG_FUNC_ENTER__;
239 wfd_device_s *local = g_manager->local;
242 WDS_LOGE("Invalid parameter");
243 __WDS_LOG_FUNC_EXIT__;
247 g_snprintf(intf_mac, MACSTR_LEN, MACSTR, MAC2STR(local->intf_addr));
248 WDS_SECLOGD("Local interface MAC address [%s]", intf_mac);
250 __WDS_LOG_FUNC_EXIT__;
255 int wfd_local_get_ip_addr(char *ip_str)
257 __WDS_LOG_FUNC_ENTER__;
258 wfd_device_s *local = g_manager->local;
261 WDS_LOGE("Invalid parameter");
262 __WDS_LOG_FUNC_EXIT__;
266 snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
267 WDS_SECLOGD("Local IP address [" IPSECSTR "]", IP2SECSTR(local->ip_addr));
269 __WDS_LOG_FUNC_EXIT__;
273 int wfd_local_get_supported_wps_mode(int *config_methods)
275 __WDS_LOG_FUNC_ENTER__;
276 wfd_device_s *local = g_manager->local;
278 if (!config_methods) {
279 WDS_LOGE("Invalid parameter");
280 __WDS_LOG_FUNC_EXIT__;
284 *config_methods = local->config_methods;
285 WDS_LOGD("Local config method [0x%x]", *config_methods);
287 __WDS_LOG_FUNC_EXIT__;
291 int wfd_local_get_wps_mode(int *wps_mode)
293 __WDS_LOG_FUNC_ENTER__;
294 wfd_device_s *local = g_manager->local;
297 WDS_LOGE("Invalid parameter");
298 __WDS_LOG_FUNC_EXIT__;
302 *wps_mode = local->wps_mode;
303 WDS_LOGD("Local wps mode [0x%x]", *wps_mode);
305 __WDS_LOG_FUNC_EXIT__;
310 int wfd_local_set_wps_mode(int wps_mode)
312 __WDS_LOG_FUNC_ENTER__;
313 wfd_device_s *local = g_manager->local;
316 WDS_LOGE("Invalid parameter");
317 __WDS_LOG_FUNC_EXIT__;
321 local->wps_mode = wps_mode;
322 WDS_LOGD("Local wps mode [0x%x]", wps_mode);
324 __WDS_LOG_FUNC_EXIT__;
329 int wfd_manager_get_go_intent(int *go_intent)
331 __WDS_LOG_FUNC_ENTER__;
333 WDS_LOGE("Invalid parameter");
334 __WDS_LOG_FUNC_EXIT__;
338 *go_intent = g_manager->go_intent;
339 WDS_LOGD("Local GO intent [%d]", *go_intent);
341 __WDS_LOG_FUNC_EXIT__;
345 int wfd_manager_set_go_intent(int go_intent)
347 __WDS_LOG_FUNC_ENTER__;
349 if (go_intent < 0 || go_intent > 15) {
350 WDS_LOGE("Invalid parameter");
351 __WDS_LOG_FUNC_EXIT__;
355 g_manager->go_intent = go_intent;
356 if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED)
357 wfd_oem_set_go_intent(g_manager->oem_ops, go_intent);
359 __WDS_LOG_FUNC_EXIT__;
363 int wfd_manager_get_max_station(int *max_station)
365 __WDS_LOG_FUNC_ENTER__;
368 WDS_LOGE("Invalid parameter");
369 __WDS_LOG_FUNC_EXIT__;
373 *max_station = g_manager->max_station;
374 WDS_LOGD("Local max station[%d]", *max_station);
376 __WDS_LOG_FUNC_EXIT__;
380 int wfd_manager_set_max_station(int max_station)
382 __WDS_LOG_FUNC_ENTER__;
384 if (max_station < 1) {
385 WDS_LOGE("Invalid parameter");
386 __WDS_LOG_FUNC_EXIT__;
390 g_manager->max_station = max_station;
392 __WDS_LOG_FUNC_EXIT__;
396 int wfd_manager_get_autoconnection(int *autoconnection)
398 __WDS_LOG_FUNC_ENTER__;
399 if (!autoconnection) {
400 WDS_LOGE("Invalid parameter");
401 __WDS_LOG_FUNC_EXIT__;
405 *autoconnection = g_manager->autoconnection;
406 WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE":"FALSE");
408 __WDS_LOG_FUNC_EXIT__;
412 int wfd_manager_set_autoconnection(int autoconnection)
414 __WDS_LOG_FUNC_ENTER__;
415 if (autoconnection < 0) {
416 WDS_LOGE("Invalid parameter");
417 __WDS_LOG_FUNC_EXIT__;
421 g_manager->autoconnection = autoconnection;
423 __WDS_LOG_FUNC_EXIT__;
427 int wfd_manager_get_req_wps_mode(int *req_wps_mode)
429 __WDS_LOG_FUNC_ENTER__;
432 WDS_LOGE("Invalid parameter");
433 __WDS_LOG_FUNC_EXIT__;
437 *req_wps_mode = g_manager->req_wps_mode;
438 WDS_LOGD("Requested wps mode [0x%x]", *req_wps_mode);
440 __WDS_LOG_FUNC_EXIT__;
444 int wfd_manager_set_req_wps_mode(int req_wps_mode)
446 __WDS_LOG_FUNC_ENTER__;
447 wfd_device_s *local = g_manager->local;
449 if (req_wps_mode != WIFI_DIRECT_WPS_TYPE_PBC &&
450 req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY &&
451 req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
452 WDS_LOGE("Invalid parameter");
453 __WDS_LOG_FUNC_EXIT__;
457 g_manager->req_wps_mode = req_wps_mode;
458 WDS_LOGD("Requested wps mode [0x%x]", req_wps_mode);
459 if (req_wps_mode == WFD_WPS_MODE_DISPLAY)
460 local->wps_mode = WFD_WPS_MODE_KEYPAD;
461 else if (req_wps_mode == WFD_WPS_MODE_KEYPAD)
462 local->wps_mode = WFD_WPS_MODE_DISPLAY;
464 local->wps_mode = req_wps_mode;
466 __WDS_LOG_FUNC_EXIT__;
470 int wfd_manager_local_config_set(wfd_manager_s *manager)
472 __WDS_LOG_FUNC_ENTER__;
473 wfd_device_s *local = NULL;
477 WDS_LOGE("Invalid parameter");
478 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
481 local = manager->local;
483 local->wps_mode = WFD_WPS_MODE_PBC;
484 WDS_LOGD("Device name set as %s", local->dev_name);
485 res = wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
487 WDS_LOGE("Failed to set device name");
488 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
491 res = wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
493 WDS_LOGE("Failed to set device type");
494 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
497 res = wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
499 WDS_LOGE("Failed to set go intent");
500 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
503 return WIFI_DIRECT_ERROR_NONE;
506 int wfd_manager_activate(wfd_manager_s *manager)
508 __WDS_LOG_FUNC_ENTER__;
514 WDS_LOGE("Invalid parameter");
515 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
518 if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
519 WDS_LOGE("Already activated");
523 wfd_state_get(manager, &prev_state);
524 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
526 #if 0 /* No need to check wifi state. Net-config will check and proceed driver loading */
527 concurrent = wfd_util_check_wifi_state();
528 if (concurrent < 0) {
529 WDS_LOGE("Failed to get wifi state");
534 res = wfd_oem_activate(manager->oem_ops, concurrent);
536 WDS_LOGE("Failed to activate");
537 wfd_state_set(manager, prev_state);
538 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
540 WDS_LOGE("Succeeded to activate");
542 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
543 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
545 wfd_manager_local_config_set(manager);
546 wfd_util_set_country();
548 wfd_util_start_wifi_direct_popup();
550 res = wfd_util_get_local_dev_mac(manager->local->dev_addr);
552 WDS_LOGE("Failed to get local device MAC address");
555 memcpy(manager->local->intf_addr, manager->local->dev_addr, MACADDR_LEN);
556 manager->local->intf_addr[4] ^= 0x80;
557 WDS_LOGD("Local Interface MAC address [" MACSECSTR "]",
558 MAC2SECSTR(manager->local->intf_addr));
560 __WDS_LOG_FUNC_EXIT__;
561 return WIFI_DIRECT_ERROR_NONE;
564 int wfd_manager_deactivate(wfd_manager_s *manager)
566 __WDS_LOG_FUNC_ENTER__;
572 WDS_LOGE("Invalid parameter");
573 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
576 if (manager->state < WIFI_DIRECT_STATE_ACTIVATING) {
577 WDS_LOGE("Already deactivated");
578 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
581 wfd_state_get(manager, &prev_state);
582 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
584 concurrent = wfd_util_check_wifi_state();
585 if (concurrent < 0) {
586 WDS_LOGE("Failed to get wifi state");
590 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
591 res = wfd_oem_miracast_init(manager->oem_ops, false);
593 WDS_LOGE("Failed to initialize miracast");
594 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
596 res = wfd_oem_destroy_group(manager->oem_ops, "p2p-wlan0-0");
598 WDS_LOGE("Failed to destroy group before deactivation");
600 res = wfd_oem_deactivate(manager->oem_ops, concurrent);
602 WDS_LOGE("Failed to deactivate");
603 wfd_state_set(manager, prev_state);
604 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
606 WDS_LOGE("Succeeded to deactivate");
608 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
609 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
611 manager->req_wps_mode = WFD_WPS_MODE_PBC;
613 wfd_destroy_group(manager, GROUP_IFNAME);
614 wfd_destroy_session(manager);
615 wfd_peer_clear_all(manager);
616 wfd_local_reset_data(manager);
618 __WDS_LOG_FUNC_EXIT__;
619 return WIFI_DIRECT_ERROR_NONE;
622 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
624 __WDS_LOG_FUNC_ENTER__;
625 wfd_session_s *session = NULL;
628 if (!manager || !peer_addr) {
629 WDS_LOGE("Invalid parameter");
630 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
633 session = (wfd_session_s*) manager->session;
634 if (session && session->type != SESSION_TYPE_INVITE) {
635 WDS_LOGE("Session already exist and it's not an invitation session");
636 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
640 session = wfd_create_session(manager, peer_addr,
641 manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
643 WDS_LOGE("Failed to create new session");
644 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
648 if (manager->local->dev_role == WFD_DEV_ROLE_GO &&
649 session->type != SESSION_TYPE_INVITE) {
650 session->type = SESSION_TYPE_INVITE;
651 res = wfd_session_invite(session);
653 res = wfd_session_start(session);
656 WDS_LOGE("Failed to start session");
657 wfd_destroy_session(manager);
658 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
660 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
662 __WDS_LOG_FUNC_EXIT__;
663 return WIFI_DIRECT_ERROR_NONE;
666 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
668 __WDS_LOG_FUNC_ENTER__;
669 wfd_session_s *session = NULL;
670 wfd_device_s *peer = NULL;
673 if (!manager || !peer_addr) {
674 WDS_LOGE("Invalid parameter");
675 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
678 session = (wfd_session_s*) manager->session;
680 WDS_LOGE("Session not found");
681 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
684 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
686 WDS_LOGE("Peer is NULL");
687 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
690 // TODO: check peer_addr with session's peer_addr
692 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
693 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
694 res = wfd_session_wps(session);
695 } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
696 WDS_LOGD("Peer device is GO, so Prov_Disc or Join will be started");
697 if (session->type == SESSION_TYPE_INVITE) {
698 if (session->state == SESSION_STATE_CREATED) {
699 WDS_LOGD("Invitation session. PD will be started");
700 res = wfd_session_start(session);
702 WDS_LOGD("Invitation session. Join will be started");
703 res = wfd_session_join(session);
706 if (manager->autoconnection && (manager->auto_pin[0] != 0))
707 g_strlcpy(session->wps_pin, manager->auto_pin, PINSTR_LEN + 1);
709 WDS_LOGD("Peer device is GO, so WPS will be started");
710 res = wfd_session_connect(session);
713 /* We should wait GO_NEGO_REQ from peer(MO) in autoconnection mode. */
714 /* Otherwise, GO Nego is sometimes failed. */
715 if (manager->autoconnection == FALSE) {
716 WDS_LOGD("My device is Device, so Negotiation will be started");
717 res = wfd_session_connect(session);
721 WDS_LOGE("Failed to start session");
722 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
723 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
724 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
726 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
727 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
729 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
731 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
733 __WDS_LOG_FUNC_EXIT__;
734 return WIFI_DIRECT_ERROR_NONE;
738 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
740 __WDS_LOG_FUNC_ENTER__;
741 wfd_group_s *group = NULL;
744 if (!manager || !peer_addr) {
745 WDS_LOGE("Invalid parameter");
746 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
749 res = wfd_session_cancel(manager->session, peer_addr);
751 WDS_LOGE("Failed to cancel session");
752 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
755 if (manager->local->dev_role != WFD_DEV_ROLE_GO)
756 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
758 group = (wfd_group_s*) manager->group;
760 wfd_group_remove_member(group, peer_addr);
761 if (!group->member_count) {
762 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
763 wfd_destroy_group(manager, group->ifname);
765 wfd_oem_disconnect(manager->oem_ops, peer_addr);
769 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
770 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
771 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
773 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
774 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
777 __WDS_LOG_FUNC_EXIT__;
778 return WIFI_DIRECT_ERROR_NONE;
782 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
784 __WDS_LOG_FUNC_ENTER__;
785 wfd_session_s *session = NULL;
788 if (!manager || !peer_addr) {
789 WDS_LOGE("Invalid parameter");
790 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
793 session = (wfd_session_s*) manager->session;
795 WDS_LOGE("Session not found");
796 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
799 res = wfd_session_reject(session, peer_addr);
801 WDS_LOGE("Failed to reject connection");
802 // TODO: check whether set state and break
804 wfd_destroy_session(manager);
806 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
807 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
808 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
810 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
811 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
814 __WDS_LOG_FUNC_EXIT__;
815 return WIFI_DIRECT_ERROR_NONE;
819 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
821 __WDS_LOG_FUNC_ENTER__;
822 wfd_group_s *group = NULL;
823 wfd_device_s *peer = NULL;
827 WDS_LOGE("Invalid parameter");
828 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
832 WDS_LOGE("Invalid parameter");
833 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
836 group = (wfd_group_s*) manager->group;
838 WDS_LOGE("Group not found");
839 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
842 peer = wfd_group_find_member_by_addr(group, peer_addr);
844 WDS_LOGE("Connected peer not found");
845 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
848 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
850 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
851 #ifdef CTRL_IFACE_DBUS
852 /* dbus using device address to identify the peer */
853 res = wfd_oem_disconnect(manager->oem_ops, peer->dev_addr);
854 #else /* CTRL_IFACE_DBUS */
855 res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr);
856 #endif /* CTRL_IFACE_DBUS */
858 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
861 WDS_LOGE("Failed to disconnect peer");
862 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
865 WDS_LOGE("Succeeded to disconnect peer");
867 wfd_group_remove_member(group, peer_addr);
868 if (!group->member_count) {
869 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
870 wfd_destroy_group(manager, group->ifname);
873 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
874 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
875 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
877 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
878 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
881 __WDS_LOG_FUNC_EXIT__;
882 return WIFI_DIRECT_ERROR_NONE;
885 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
886 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
887 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
889 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
890 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
893 __WDS_LOG_FUNC_EXIT__;
897 int wfd_manager_disconnect_all(wfd_manager_s *manager)
899 __WDS_LOG_FUNC_ENTER__;
900 wfd_group_s *group = NULL;
904 WDS_LOGE("Invalid parameter");
905 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
908 group = (wfd_group_s*) manager->group;
910 WDS_LOGE("Group not found");
911 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
914 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
916 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
918 WDS_LOGE("Failed to destroy group");
919 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
922 WDS_LOGE("Succeeded to disconnect all peer");
924 wfd_destroy_group(manager, group->ifname);
926 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
927 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
929 __WDS_LOG_FUNC_EXIT__;
930 return WIFI_DIRECT_ERROR_NONE;
933 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
934 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
935 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
937 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
938 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
941 __WDS_LOG_FUNC_EXIT__;
945 int wfd_manager_get_peer_info(wfd_manager_s *manager, unsigned char *addr, wfd_discovery_entry_s **peer)
947 __WDS_LOG_FUNC_ENTER__;
948 wfd_device_s *peer_dev = NULL;
949 wfd_discovery_entry_s *peer_info;
950 wfd_oem_device_s *oem_dev = NULL;
953 if (!manager || !addr) {
954 WDS_LOGE("Invalid parameter");
958 unsigned long time = 0;
959 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
960 wfd_util_get_current_time(&time);
963 gettimeofday(&tval, NULL);
966 WDS_LOGI("Current time [%ld]", time);
968 res = wfd_oem_get_peer_info(manager->oem_ops, addr, &oem_dev);
969 if (res < 0 || !oem_dev) {
970 WDS_LOGE("Failed to get peer information");
974 peer_dev = wfd_peer_find_by_addr(manager, addr);
976 peer_dev = (wfd_device_s*) g_try_malloc0(sizeof(wfd_device_s));
978 WDS_LOGE("Failed to allocate memory for peer device. [%s]", strerror(errno));
982 memcpy(peer_dev->dev_addr, addr, MACADDR_LEN);
983 manager->peers = g_list_prepend(manager->peers, peer_dev);
984 manager->peer_count++;
985 peer_dev->time = time;
986 WDS_LOGD("peer_count[%d]", manager->peer_count);
988 if (oem_dev->age > 30 && peer_dev->state == WFD_PEER_STATE_DISCOVERED) {
989 WDS_LOGE("Too old age to update peer");
995 g_strlcpy(peer_dev->dev_name, oem_dev->dev_name, DEV_NAME_LEN + 1);
996 memcpy(peer_dev->intf_addr, oem_dev->intf_addr, MACADDR_LEN);
997 memcpy(peer_dev->go_dev_addr, oem_dev->go_dev_addr, MACADDR_LEN);
998 peer_dev->dev_role = oem_dev->dev_role;
999 peer_dev->config_methods = oem_dev->config_methods;
1000 peer_dev->pri_dev_type = oem_dev->pri_dev_type;
1001 peer_dev->sec_dev_type = oem_dev->sec_dev_type;
1002 peer_dev->dev_flags = oem_dev->dev_flags;
1003 peer_dev->group_flags = oem_dev->group_flags;
1004 peer_dev->wps_mode = oem_dev->wps_mode;
1006 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1007 memcpy(&(peer_dev->display), &(oem_dev->display), sizeof(wfd_display_s));
1008 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1010 peer_dev->time = time;
1011 peer_dev->channel = oem_dev->channel;
1015 peer_info = (wfd_discovery_entry_s*) g_try_malloc0(sizeof(wfd_discovery_entry_s));
1017 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1021 g_strlcpy(peer_info->device_name, peer_dev->dev_name, DEV_NAME_LEN + 1);
1022 memcpy(peer_info->mac_address, peer_dev->dev_addr, MACADDR_LEN);
1023 memcpy(peer_info->intf_address, peer_dev->intf_addr, MACADDR_LEN);
1024 peer_info->channel = peer_dev->channel;
1025 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1026 peer_info->services = 0;
1027 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1028 peer_info->is_group_owner = peer_dev->dev_role == WFD_DEV_ROLE_GO;
1029 peer_info->is_persistent_go = peer_dev->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1030 peer_info->is_connected = peer_dev->dev_role == WFD_DEV_ROLE_GC;
1031 peer_info->wps_device_pwd_id = 0;
1032 peer_info->wps_cfg_methods = peer_dev->config_methods;
1033 peer_info->category = peer_dev->pri_dev_type;
1034 peer_info->subcategory = peer_dev->sec_dev_type;
1036 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1037 if (peer_dev->display.availablity && peer_dev->display.port)
1038 peer_info->is_wfd_device = 1;
1039 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1043 __WDS_LOG_FUNC_EXIT__;
1048 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
1050 __WDS_LOG_FUNC_ENTER__;
1052 wfd_device_s *peer = NULL;
1053 wfd_discovery_entry_s *peers = NULL;
1058 if (!manager || !peers_data) {
1059 WDS_LOGE("Invalid parameter");
1063 unsigned long time = 0;
1064 #if !(__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
1065 wfd_util_get_current_time(&time);
1067 struct timeval tval;
1068 gettimeofday(&tval, NULL);
1071 WDS_LOGI("Current time [%ld]", time);
1073 peer_count = manager->peer_count;
1074 WDS_LOGI("peer count [%ld]", peer_count);
1077 else if (peer_count == 0)
1081 peers = (wfd_discovery_entry_s*) g_try_malloc0_n(peer_count, sizeof(wfd_discovery_entry_s));
1083 WDS_LOGE("Failed to allocate memory for peer data. [%s]", strerror(errno));
1087 temp = g_list_first(manager->peers);
1088 while (temp && count < peer_count) {
1092 if (peer->time + 8 < time) {
1093 WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
1094 res = wfd_update_peer(manager, peer);
1096 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
1097 temp = g_list_next(temp);
1098 manager->peers = g_list_remove(manager->peers, peer);
1099 manager->peer_count--;
1106 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1107 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1108 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1109 peers[count].channel = peer->channel;
1110 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1111 peers[count].services = 0;
1112 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1113 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1114 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1115 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1116 peers[count].wps_device_pwd_id = 0;
1117 peers[count].wps_cfg_methods = peer->config_methods;
1118 peers[count].category = peer->pri_dev_type;
1119 peers[count].subcategory = peer->sec_dev_type;
1121 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1122 if (peer->display.availablity && peer->display.port)
1123 peers[count].is_wfd_device = 1;
1124 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1126 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1128 temp = g_list_next(temp);
1131 WDS_LOGD("%d peers converted", count);
1132 WDS_LOGD("Final peer count is %d", manager->peer_count);
1134 *peers_data = peers;
1136 __WDS_LOG_FUNC_EXIT__;
1140 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1142 __WDS_LOG_FUNC_ENTER__;
1143 wfd_connected_peer_info_s *peers = NULL;
1144 wfd_group_s *group = NULL;
1145 wfd_device_s *peer = NULL;
1150 if (!manager || !peers_data) {
1151 WDS_LOGE("Invalid parameter");
1155 group = manager->group;
1157 WDS_LOGE("Group not exist");
1161 peer_count = group->member_count;
1162 if (peer_count == 0) {
1163 WDS_LOGD("Member not exist");
1168 peers = (wfd_connected_peer_info_s*) g_try_malloc0_n(peer_count, sizeof(wfd_connected_peer_info_s));
1170 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
1174 temp = g_list_first(group->members);
1175 while (temp && count < group->member_count) {
1178 g_strlcpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN + 1);
1179 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1180 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1181 memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1182 peers[count].category = peer->pri_dev_type;
1183 peers[count].subcategory = peer->sec_dev_type;
1184 peers[count].channel = peer->channel;
1185 peers[count].is_p2p = 1;
1186 #ifdef TIZEN_FEATURE_SERVICE_DISCOVERY
1187 peers[count].services = 0;
1188 #endif /* TIZEN_FEATURE_SERVICE_DISCOVERY */
1190 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1191 if (peer->display.availablity && peer->display.port)
1192 peers[count].is_wfd_device = 1;
1194 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1196 WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1199 temp = g_list_next(temp);
1202 WDS_LOGD("%d members converted", count);
1204 *peers_data = peers;
1206 __WDS_LOG_FUNC_EXIT__;
1211 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1213 __WDS_LOG_FUNC_ENTER__;
1214 wfd_device_s *peer = NULL;
1216 if (!manager || !peer_addr) {
1217 WDS_LOGE("Invalid parameter");
1221 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1223 __WDS_LOG_FUNC_EXIT__;
1228 int wfd_manager_get_goup_ifname(char **ifname)
1230 __WDS_LOG_FUNC_ENTER__;
1231 wfd_group_s *group = g_manager->group;
1234 WDS_LOGE("Invalid parameter");
1235 __WDS_LOG_FUNC_EXIT__;
1240 WDS_LOGE("Group not exist");
1244 *ifname = group->ifname;
1246 __WDS_LOG_FUNC_EXIT__;
1250 #ifdef TIZEN_FEATURE_WIFI_DISPLAY
1251 int wfd_manager_set_display_device(int type, int port, int hdcp)
1253 __WDS_LOG_FUNC_ENTER__;
1254 wfd_device_s * device = g_manager->local;
1255 wfd_oem_display_s display;
1259 WDS_LOGE("Invalid parameter");
1260 __WDS_LOG_FUNC_EXIT__;
1264 memset(&display, 0x0, sizeof(wfd_oem_display_s));
1266 display.type = type;
1267 display.port = port;
1268 display.hdcp_support = hdcp;
1270 display.availablity = device->display.availablity;
1271 display.max_tput = device->display.max_tput;
1273 res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1275 WDS_LOGE("Failed to set wifi display");
1279 device->display.type = type;
1280 device->display.port = port;
1281 device->display.hdcp_support = hdcp;
1283 __WDS_LOG_FUNC_EXIT__;
1287 int wfd_manager_set_session_availability(int availability)
1289 __WDS_LOG_FUNC_ENTER__;
1290 wfd_device_s * device = g_manager->local;
1291 wfd_oem_display_s display;
1295 WDS_LOGE("Invalid parameter");
1296 __WDS_LOG_FUNC_EXIT__;
1300 memset(&display, 0x0, sizeof(wfd_oem_display_s));
1302 display.availablity = availability;
1304 display.type = device->display.type;
1305 display.hdcp_support = device->display.hdcp_support;
1306 display.port = device->display.port;
1307 display.max_tput = device->display.max_tput;
1309 res = wfd_oem_set_display(g_manager->oem_ops, (wfd_oem_display_s*)&display);
1311 WDS_LOGE("Failed to set wifi display session availability");
1315 device->display.availablity = availability;
1317 __WDS_LOG_FUNC_EXIT__;
1321 #endif /* TIZEN_FEATURE_WIFI_DISPLAY */
1323 wfd_device_s *wfd_manager_get_peer_by_addr(wfd_manager_s *manager, unsigned char *peer_addr)
1325 __WDS_LOG_FUNC_ENTER__;
1326 wfd_device_s *peer = NULL;
1327 if(manager->group) {
1328 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1335 peer = wfd_peer_find_by_addr(manager, peer_addr);
1338 __WDS_LOG_FUNC_EXIT__;
1341 static wfd_manager_s *wfd_manager_init()
1343 __WDS_LOG_FUNC_ENTER__;
1344 wfd_manager_s *manager = NULL;
1347 manager = (wfd_manager_s*) g_try_malloc0(sizeof(wfd_manager_s));
1349 WDS_LOGE("Failed to allocate memory for wfd_manager structure");
1353 manager->go_intent = 7;
1354 manager->req_wps_mode = WFD_WPS_MODE_PBC;
1355 manager->max_station = 8;
1356 res = _wfd_local_init_device(manager);
1358 WDS_LOGE("Failed to initialize local device");
1360 return NULL; // really stop manager?
1362 WDS_LOGD("Succeeded to initialize local device");
1364 manager->exit_timer = g_timeout_add(120000,
1365 (GSourceFunc) _wfd_exit_timeout_cb, manager);
1366 WDS_LOGD("Exit timer started");
1368 __WDS_LOG_FUNC_EXIT__;
1372 int wfd_manager_deinit(wfd_manager_s *manager)
1374 __WDS_LOG_FUNC_ENTER__;
1377 WDS_LOGE("Invalid parameter");
1378 __WDS_LOG_FUNC_EXIT__;
1382 if (manager->exit_timer > 0)
1383 g_source_remove(manager->exit_timer);
1384 manager->exit_timer = 0;
1386 _wfd_local_deinit_device(manager);
1390 __WDS_LOG_FUNC_EXIT__;
1394 static void *wfd_plugin_init(wfd_manager_s *manager)
1396 __WDS_LOG_FUNC_ENTER__;
1398 struct utsname kernel_info;
1402 WDS_LOGE("Invalid parameter");
1403 __WDS_LOG_FUNC_EXIT__;
1407 res = uname(&kernel_info);
1409 WDS_LOGE("Failed to detect target type");
1410 __WDS_LOG_FUNC_EXIT__;
1413 WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1416 handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
1418 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1419 __WDS_LOG_FUNC_EXIT__;
1424 int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1425 plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
1427 WDS_LOGE( "Failed to load symbol. Error = [%s]", strerror(errno));
1429 __WDS_LOG_FUNC_EXIT__;
1433 wfd_oem_ops_s *temp_ops;
1434 (*plugin_load)(&temp_ops);
1435 manager->oem_ops = temp_ops;
1437 res = wfd_oem_init(temp_ops, (wfd_oem_event_cb) wfd_process_event, manager);
1439 WDS_LOGE("Failed to initialize OEM");
1441 __WDS_LOG_FUNC_EXIT__;
1444 WDS_LOGD("Succeeded to initialize OEM");
1446 __WDS_LOG_FUNC_EXIT__;
1450 static int wfd_plugin_deinit(wfd_manager_s *manager)
1452 __WDS_LOG_FUNC_ENTER__;
1454 if (!manager || !manager->plugin_handle) {
1455 WDS_LOGE("Invalid parameter");
1456 __WDS_LOG_FUNC_EXIT__;
1460 dlclose(manager->plugin_handle);
1461 manager->plugin_handle = NULL;
1463 __WDS_LOG_FUNC_EXIT__;
1467 int main(int argc, char *argv[])
1469 __WDS_LOG_FUNC_ENTER__;
1470 GMainLoop *main_loop = NULL;
1473 #if !GLIB_CHECK_VERSION(2,32,0)
1474 if (!g_thread_supported())
1475 g_thread_init(NULL);
1478 #if !GLIB_CHECK_VERSION(2,36,0)
1482 // TODO: Parsing argument
1483 /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1485 g_manager = wfd_manager_init();
1487 WDS_LOGE("Failed to initialize wifi-direct manager");
1488 __WDS_LOG_FUNC_EXIT__;
1491 WDS_LOGD("Succeeded to initialize manager");
1493 g_manager->plugin_handle = wfd_plugin_init(g_manager);
1494 if (!g_manager->plugin_handle) {
1495 WDS_LOGE("Failed to initialize plugin");
1496 wfd_manager_deinit(g_manager);
1497 __WDS_LOG_FUNC_EXIT__;
1500 WDS_LOGD("Succeeded to load plugin");
1502 res = wfd_client_handler_init(g_manager);
1504 WDS_LOGE("Failed to initialize client handler");
1505 wfd_plugin_deinit(g_manager);
1506 wfd_manager_deinit(g_manager);
1507 __WDS_LOG_FUNC_EXIT__;
1510 WDS_LOGD("Succeeded to initialize client handler");
1512 main_loop = g_main_loop_new(NULL, FALSE);
1513 if (main_loop == NULL) {
1514 WDS_LOGE("Failed to create GMainLoop structure");
1515 __WDS_LOG_FUNC_EXIT__;
1518 g_manager->main_loop = main_loop;
1520 g_main_loop_run(main_loop);
1522 wfd_client_handler_deinit(g_manager);
1523 wfd_plugin_deinit(g_manager);
1524 wfd_manager_deinit(g_manager);
1526 __WDS_LOG_FUNC_EXIT__;