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>
38 #include <wifi-direct.h>
39 #include <wifi-direct-internal.h>
41 #include "wifi-direct-manager.h"
42 #include "wifi-direct-oem.h"
43 #include "wifi-direct-session.h"
44 #include "wifi-direct-group.h"
45 #include "wifi-direct-peer.h"
46 #include "wifi-direct-state.h"
47 #include "wifi-direct-client.h"
48 #include "wifi-direct-event.h"
49 #include "wifi-direct-util.h"
51 wfd_manager_s *g_manager;
53 wfd_manager_s *wfd_get_manager()
58 static gboolean _wfd_exit_timeout_cb(void *user_data)
60 __WDS_LOG_FUNC_ENTER__;
61 wfd_manager_s *manager = (wfd_manager_s*) user_data;
64 WDS_LOGE("Invalid parameter");
68 if (manager->client_count > 0) {
69 WDS_LOGD("Client count [%d]", manager->client_count);
73 if (manager->state == WIFI_DIRECT_STATE_DEACTIVATED) {
74 WDS_LOGD("Terminate Wi-Fi Direct Manager");
75 g_main_quit(manager->main_loop);
77 manager->exit_timer = 0;
78 WDS_LOGD( "Stop exit timer. State [%d]", manager->state);
80 __WDS_LOG_FUNC_EXIT__;
84 static int _wfd_local_init_device(wfd_manager_s *manager)
86 __WDS_LOG_FUNC_ENTER__;
87 wfd_device_s *local = NULL;
91 WDS_LOGE("Invalid parameter");
96 local = (wfd_device_s*) calloc(1, sizeof(wfd_device_s));
98 WDS_LOGE("Failed to allocate memory for local device [%s]", strerror(errno));
102 res = wfd_util_get_phone_name(local->dev_name);
104 WDS_LOGE("Failed to get phone name of local device. Use default device name");
105 strncpy(local->dev_name, DEFAULT_DEVICE_NAME, DEV_NAME_LEN);
106 local->dev_name[DEV_NAME_LEN] = '\0';
108 WDS_LOGD("Local Device name [%s]", local->dev_name);
109 wfd_util_set_dev_name_notification();
111 res = wfd_util_get_local_dev_mac(local->dev_addr);
113 WDS_LOGE("Failed to get local device MAC address");
116 memcpy(local->intf_addr, local->dev_addr, MACADDR_LEN);
117 local->intf_addr[4] ^= 0x80;
118 WDS_LOGD("Local Interface MAC address [" MACSTR "]", MAC2STR(local->intf_addr));
120 local->config_methods = WFD_WPS_MODE_PBC | WFD_WPS_MODE_DISPLAY | WFD_WPS_MODE_KEYPAD;
121 local->wps_mode = WFD_WPS_MODE_PBC;
122 // TODO: initialize other local device datas
123 manager->local = local;
125 __WDS_LOG_FUNC_EXIT__;
129 static int _wfd_local_deinit_device(wfd_manager_s *manager)
131 __WDS_LOG_FUNC_ENTER__;
134 WDS_LOGE("Invalid parameter");
138 wfd_util_unset_dev_name_notification();
141 free(manager->local);
143 __WDS_LOG_FUNC_EXIT__;
147 int wfd_local_reset_data(wfd_manager_s *manager)
149 __WDS_LOG_FUNC_ENTER__;
150 wfd_device_s *local = manager->local;
152 /* init local device data */
153 local->dev_role = WFD_DEV_ROLE_NONE;
154 local->wps_mode = WFD_WPS_MODE_PBC;
155 memset(local->go_dev_addr, 0x0, MACADDR_LEN);
156 memset(local->ip_addr, 0x0, IPADDR_LEN);
158 __WDS_LOG_FUNC_EXIT__;
162 int wfd_local_get_dev_name(char *dev_name)
164 __WDS_LOG_FUNC_ENTER__;
165 wfd_device_s *local = g_manager->local;
168 WDS_LOGE("Invalid parameter");
169 __WDS_LOG_FUNC_EXIT__;
173 strncpy(dev_name, local->dev_name, DEV_NAME_LEN);
174 dev_name[DEV_NAME_LEN-1] = '\0';
175 WDS_LOGD("Local device name [%s]", dev_name);
177 __WDS_LOG_FUNC_EXIT__;
181 int wfd_local_set_dev_name(char *dev_name)
183 __WDS_LOG_FUNC_ENTER__;
184 wfd_device_s *local = g_manager->local;
187 WDS_LOGE("Invalid parameter");
188 __WDS_LOG_FUNC_EXIT__;
192 strncpy(local->dev_name, dev_name, DEV_NAME_LEN);
193 local->dev_name[DEV_NAME_LEN-1] = '\0';
195 if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED) {
196 wfd_oem_set_dev_name(g_manager->oem_ops, dev_name);
198 wfd_oem_scan_param_s param;
199 param.scan_mode = WFD_OEM_SCAN_MODE_ACTIVE;
200 param.scan_type = WFD_OEM_SCAN_TYPE_FULL;
202 param.refresh = TRUE;
203 wfd_oem_start_scan(g_manager->oem_ops, ¶m);
204 g_manager->scan_mode = WFD_SCAN_MODE_ACTIVE;
205 WDS_LOGD("Device name changed. Active scan started");
208 __WDS_LOG_FUNC_EXIT__;
212 int wfd_local_get_dev_mac(unsigned char *dev_mac)
214 __WDS_LOG_FUNC_ENTER__;
215 wfd_device_s *local = g_manager->local;
218 WDS_LOGE("Invalid parameter");
219 __WDS_LOG_FUNC_EXIT__;
223 memcpy(dev_mac, local->dev_addr, MACADDR_LEN);
224 WDS_LOGD("Local device MAC address [" MACSTR "]", MAC2STR(dev_mac));
226 __WDS_LOG_FUNC_EXIT__;
230 int wfd_local_get_intf_mac(unsigned char *intf_mac)
232 __WDS_LOG_FUNC_ENTER__;
233 wfd_device_s *local = g_manager->local;
236 WDS_LOGE("Invalid parameter");
237 __WDS_LOG_FUNC_EXIT__;
241 memcpy(intf_mac, local->intf_addr, MACADDR_LEN);
242 WDS_LOGD("Local interface MAC address [" MACSTR "]", MAC2STR(intf_mac));
244 __WDS_LOG_FUNC_EXIT__;
248 int wfd_local_get_ip_addr(char *ip_str)
250 __WDS_LOG_FUNC_ENTER__;
251 wfd_device_s *local = g_manager->local;
254 WDS_LOGE("Invalid parameter");
255 __WDS_LOG_FUNC_EXIT__;
259 snprintf(ip_str, IPSTR_LEN, IPSTR, IP2STR(local->ip_addr));
260 WDS_LOGD("Local IP address [" IPSTR "]", IP2STR(local->ip_addr));
262 __WDS_LOG_FUNC_EXIT__;
266 int wfd_local_get_supported_wps_mode(int *config_methods)
268 __WDS_LOG_FUNC_ENTER__;
269 wfd_device_s *local = g_manager->local;
271 if (!config_methods) {
272 WDS_LOGE("Invalid parameter");
273 __WDS_LOG_FUNC_EXIT__;
277 *config_methods = local->config_methods;
278 WDS_LOGD("Local config method [0x%x]", *config_methods);
280 __WDS_LOG_FUNC_EXIT__;
284 int wfd_local_get_wps_mode(int *wps_mode)
286 __WDS_LOG_FUNC_ENTER__;
287 wfd_device_s *local = g_manager->local;
290 WDS_LOGE("Invalid parameter");
291 __WDS_LOG_FUNC_EXIT__;
295 *wps_mode = local->wps_mode;
296 WDS_LOGD("Local wps mode [0x%x]", *wps_mode);
298 __WDS_LOG_FUNC_EXIT__;
302 int wfd_local_set_wps_mode(int wps_mode)
304 __WDS_LOG_FUNC_ENTER__;
305 wfd_device_s *local = g_manager->local;
308 WDS_LOGE("Invalid parameter");
309 __WDS_LOG_FUNC_EXIT__;
313 local->wps_mode = wps_mode;
314 WDS_LOGD("Local wps mode [0x%x]", wps_mode);
316 __WDS_LOG_FUNC_EXIT__;
320 int wfd_manager_get_go_intent(int *go_intent)
322 __WDS_LOG_FUNC_ENTER__;
324 WDS_LOGE("Invalid parameter");
325 __WDS_LOG_FUNC_EXIT__;
329 *go_intent = g_manager->go_intent;
330 WDS_LOGD("Local GO intent [%d]", *go_intent);
332 __WDS_LOG_FUNC_EXIT__;
336 int wfd_manager_set_go_intent(int go_intent)
338 __WDS_LOG_FUNC_ENTER__;
340 if (go_intent < 0 || go_intent > 15) {
341 WDS_LOGE("Invalid parameter");
342 __WDS_LOG_FUNC_EXIT__;
346 g_manager->go_intent = go_intent;
347 if (g_manager->state >= WIFI_DIRECT_STATE_ACTIVATED)
348 wfd_oem_set_go_intent(g_manager->oem_ops, go_intent);
350 __WDS_LOG_FUNC_EXIT__;
354 int wfd_manager_get_max_station(int *max_station)
356 __WDS_LOG_FUNC_ENTER__;
359 WDS_LOGE("Invalid parameter");
360 __WDS_LOG_FUNC_EXIT__;
364 *max_station = g_manager->max_station;
365 WDS_LOGD("Local max station[%d]", *max_station);
367 __WDS_LOG_FUNC_EXIT__;
371 int wfd_manager_set_max_station(int max_station)
373 __WDS_LOG_FUNC_ENTER__;
375 if (max_station < 1) {
376 WDS_LOGE("Invalid parameter");
377 __WDS_LOG_FUNC_EXIT__;
381 g_manager->max_station = max_station;
383 __WDS_LOG_FUNC_EXIT__;
387 int wfd_manager_get_autoconnection(int *autoconnection)
389 __WDS_LOG_FUNC_ENTER__;
390 if (!autoconnection) {
391 WDS_LOGE("Invalid parameter");
392 __WDS_LOG_FUNC_EXIT__;
396 *autoconnection = g_manager->autoconnection;
397 WDS_LOGD("Local autoconnection [%s]", *autoconnection ? "TRUE":"FALSE");
399 __WDS_LOG_FUNC_EXIT__;
403 int wfd_manager_set_autoconnection(int autoconnection)
405 __WDS_LOG_FUNC_ENTER__;
406 if (autoconnection < 0) {
407 WDS_LOGE("Invalid parameter");
408 __WDS_LOG_FUNC_EXIT__;
412 g_manager->autoconnection = autoconnection;
414 __WDS_LOG_FUNC_EXIT__;
418 int wfd_manager_get_req_wps_mode(int *req_wps_mode)
420 __WDS_LOG_FUNC_ENTER__;
423 WDS_LOGE("Invalid parameter");
424 __WDS_LOG_FUNC_EXIT__;
428 *req_wps_mode = g_manager->req_wps_mode;
429 WDS_LOGD("Requested wps mode [0x%x]", *req_wps_mode);
431 __WDS_LOG_FUNC_EXIT__;
435 int wfd_manager_set_req_wps_mode(int req_wps_mode)
437 __WDS_LOG_FUNC_ENTER__;
438 wfd_device_s *local = g_manager->local;
440 if (req_wps_mode != WIFI_DIRECT_WPS_TYPE_PBC &&
441 req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_DISPLAY &&
442 req_wps_mode != WIFI_DIRECT_WPS_TYPE_PIN_KEYPAD) {
443 WDS_LOGE("Invalid parameter");
444 __WDS_LOG_FUNC_EXIT__;
448 g_manager->req_wps_mode = req_wps_mode;
449 WDS_LOGD("Requested wps mode [0x%x]", req_wps_mode);
450 if (req_wps_mode == WFD_WPS_MODE_DISPLAY)
451 local->wps_mode = WFD_WPS_MODE_KEYPAD;
452 else if (req_wps_mode == WFD_WPS_MODE_KEYPAD)
453 local->wps_mode = WFD_WPS_MODE_DISPLAY;
455 local->wps_mode = req_wps_mode;
457 __WDS_LOG_FUNC_EXIT__;
461 int wfd_manager_local_config_set(wfd_manager_s *manager)
463 __WDS_LOG_FUNC_ENTER__;
464 wfd_device_s *local = NULL;
468 WDS_LOGE("Invalid parameter");
469 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
472 local = manager->local;
474 local->wps_mode = WFD_WPS_MODE_PBC;
475 WDS_LOGD("Device name set as %s", local->dev_name);
476 wfd_oem_set_dev_type(manager->oem_ops, local->pri_dev_type, local->sec_dev_type);
477 wfd_oem_set_go_intent(manager->oem_ops, manager->go_intent);
478 wfd_oem_set_dev_name(manager->oem_ops, local->dev_name);
480 return WIFI_DIRECT_ERROR_NONE;
483 int wfd_local_get_display_port(int *port)
485 __WDS_LOG_FUNC_ENTER__;
486 wfd_device_s *local = g_manager->local;
489 WDS_LOGE("Invalid parameter");
490 __WDS_LOG_FUNC_EXIT__;
494 if (!local->wifi_display) {
495 WDS_LOGE("wifi display is not registered");
496 __WDS_LOG_FUNC_EXIT__;
500 *port = local->wifi_display->ctrl_port;
501 WDS_LOGD("Local display port [%d]", *port);
503 __WDS_LOG_FUNC_EXIT__;
507 int wfd_local_get_display_type(wifi_direct_display_type_e *type)
509 __WDS_LOG_FUNC_ENTER__;
510 wfd_device_s *local = g_manager->local;
513 WDS_LOGE("Invalid parameter");
514 __WDS_LOG_FUNC_EXIT__;
518 if (!local->wifi_display) {
519 WDS_LOGE("wifi display is not registered");
520 __WDS_LOG_FUNC_EXIT__;
524 *type = local->wifi_display->type;
525 WDS_LOGD("Local display type [%d]", *type);
527 __WDS_LOG_FUNC_EXIT__;
531 int wfd_manager_activate(wfd_manager_s *manager)
533 __WDS_LOG_FUNC_ENTER__;
537 WDS_LOGE("Invalid parameter");
538 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
541 if (manager->state > WIFI_DIRECT_STATE_ACTIVATING) {
542 WDS_LOGE("Already activated");
546 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATING);
548 res = wfd_oem_activate(manager->oem_ops);
550 WDS_LOGE("Failed to activate");
551 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
552 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
554 WDS_LOGE("Succeeded to activate");
556 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
557 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
559 __WDS_LOG_FUNC_EXIT__;
560 return WIFI_DIRECT_ERROR_NONE;
563 int wfd_manager_deactivate(wfd_manager_s *manager)
565 __WDS_LOG_FUNC_ENTER__;
569 WDS_LOGE("Invalid parameter");
570 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
573 if (manager->state < WIFI_DIRECT_STATE_ACTIVATING) {
574 WDS_LOGE("Already deactivated");
575 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
578 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATING);
580 res = wfd_oem_deactivate(manager->oem_ops);
582 WDS_LOGE("Failed to deactivate");
583 // TODO: check state setting is correct
584 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
585 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
587 WDS_LOGE("Succeeded to deactivate");
589 wfd_state_set(manager, WIFI_DIRECT_STATE_DEACTIVATED);
590 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_DEACTIVATED);
592 manager->req_wps_mode = WFD_WPS_MODE_PBC;
594 __WDS_LOG_FUNC_EXIT__;
595 return WIFI_DIRECT_ERROR_NONE;
598 int wfd_manager_connect(wfd_manager_s *manager, unsigned char *peer_addr)
600 __WDS_LOG_FUNC_ENTER__;
601 wfd_session_s *session = NULL;
604 if (!manager || !peer_addr) {
605 WDS_LOGE("Invalid parameter");
606 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
609 session = (wfd_session_s*) manager->session;
610 if (session && session->type != SESSION_TYPE_INVITE) {
611 WDS_LOGE("Session already exist or not an invitaion session");
612 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
616 session = wfd_create_session(manager, peer_addr,
617 manager->req_wps_mode, SESSION_DIRECTION_OUTGOING);
619 WDS_LOGE("Failed to create new session");
620 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
624 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->type != SESSION_TYPE_INVITE) {
625 session->type = SESSION_TYPE_INVITE;
626 res = wfd_session_invite(session);
628 /* joining to group or starting connection with PD */
629 /* In case of invitation session PD should be started
630 * peer->dev_role == WFD_DEV_ROLE_GO
631 * session->direction == SESSION_DIRECTION_INCOMING
632 * session->invitation == TRUE;
634 res = wfd_session_start(session);
637 WDS_LOGE("Failed to start session");
638 wfd_destroy_session(manager);
639 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
641 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
643 __WDS_LOG_FUNC_EXIT__;
644 return WIFI_DIRECT_ERROR_NONE;
647 int wfd_manager_accept_connection(wfd_manager_s *manager, unsigned char *peer_addr)
649 __WDS_LOG_FUNC_ENTER__;
650 wfd_session_s *session = NULL;
651 wfd_device_s *peer = NULL;
654 if (!manager || !peer_addr) {
655 WDS_LOGE("Invalid parameter");
656 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
659 session = (wfd_session_s*) manager->session;
661 WDS_LOGE("Session not found");
662 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
665 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
667 WDS_LOGE("Peer is NULL");
668 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
671 // TODO: check peer_addr with session's peer_addr
673 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
674 /* Peer want to join my group(Peer sent PD) */
675 WDS_LOGD("My device is GO and peer want to join my group, so WPS will be started");
676 res = wfd_session_wps(session);
677 } else if (peer->dev_role == WFD_DEV_ROLE_GO) {
678 /* FIX ME: When Enter PIN or Display event comes up from supplicant
679 * manager send Connection WPS Req event to client.
680 * So, application use accept_connection API.
681 * This is odd situation. We need new client event such as WPS_KEYPAD/WPS_DISPLAY for application.
682 * We can correct alien code below with new client event */
683 if (session->direction == SESSION_DIRECTION_OUTGOING) {
684 WDS_LOGD("Peer device is GO, WPS_Enrollee will be started");
685 wfd_session_wps(manager->session);
687 WDS_LOGD("Peer device is GO, so Prov_Disc will be started");
688 wfd_session_start(session);
691 /* Prov_disc_req received. GO Negotiation will be started */
692 WDS_LOGD("My device is Device, so Negotiation will be started");
693 res = wfd_session_connect(session);
696 WDS_LOGE("Failed to start session");
697 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
699 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
701 __WDS_LOG_FUNC_EXIT__;
702 return WIFI_DIRECT_ERROR_NONE;
706 int wfd_manager_cancel_connection(wfd_manager_s *manager, unsigned char *peer_addr)
708 __WDS_LOG_FUNC_ENTER__;
709 wfd_session_s *session = NULL;
710 wfd_group_s *group = NULL;
713 if (!manager || !peer_addr) {
714 WDS_LOGE("Invalid parameter");
715 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
718 res = wfd_session_cancel(manager->session, peer_addr);
720 WDS_LOGE("Failed to cancel session");
721 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
724 if (manager->local->dev_role != WFD_DEV_ROLE_GO)
725 wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
727 group = (wfd_group_s*) manager->group;
729 wfd_group_remove_member(group, peer_addr);
730 if (!group->member_count) {
731 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
732 wfd_destroy_group(manager, group->ifname);
734 wfd_oem_disconnect(manager->oem_ops, peer_addr);
738 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
739 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
740 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
742 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
743 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
746 __WDS_LOG_FUNC_EXIT__;
747 return WIFI_DIRECT_ERROR_NONE;
751 int wfd_manager_reject_connection(wfd_manager_s *manager, unsigned char *peer_addr)
753 __WDS_LOG_FUNC_ENTER__;
754 wfd_session_s *session = NULL;
757 if (!manager || !peer_addr) {
758 WDS_LOGE("Invalid parameter");
759 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
762 session = (wfd_session_s*) manager->session;
764 WDS_LOGE("Session not found");
765 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
768 if (manager->local->dev_role == WFD_DEV_ROLE_NONE) {
769 res = wfd_oem_reject_connection(manager->oem_ops, peer_addr);
771 WDS_LOGE("Failed to reject connection");
772 // TODO: check whether set state and break
775 wfd_destroy_session(manager);
777 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
778 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
779 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
781 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
782 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
785 __WDS_LOG_FUNC_EXIT__;
786 return WIFI_DIRECT_ERROR_NONE;
790 int wfd_manager_disconnect(wfd_manager_s *manager, unsigned char *peer_addr)
792 __WDS_LOG_FUNC_ENTER__;
793 wfd_group_s *group = NULL;
794 wfd_device_s *peer = NULL;
798 WDS_LOGE("Invalid parameter");
799 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
803 WDS_LOGE("Invalid parameter");
804 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
807 group = (wfd_group_s*) manager->group;
809 WDS_LOGE("Group not found");
810 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
813 peer = wfd_group_find_member_by_addr(group, peer_addr);
815 WDS_LOGE("Connected peer not found");
816 return WIFI_DIRECT_ERROR_INVALID_PARAMETER;
819 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
821 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
822 res = wfd_oem_disconnect(manager->oem_ops, peer->intf_addr);
824 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
827 WDS_LOGE("Failed to disconnect peer");
828 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
831 WDS_LOGE("Succeeded to disconnect peer");
833 wfd_group_remove_member(group, peer_addr);
834 if (!group->member_count) {
835 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
836 wfd_destroy_group(manager, group->ifname);
839 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
840 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
841 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
843 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
844 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
847 __WDS_LOG_FUNC_EXIT__;
848 return WIFI_DIRECT_ERROR_NONE;
851 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
852 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
853 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
855 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
856 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
859 __WDS_LOG_FUNC_EXIT__;
863 int wfd_manager_disconnect_all(wfd_manager_s *manager)
865 __WDS_LOG_FUNC_ENTER__;
866 wfd_group_s *group = NULL;
870 WDS_LOGE("Invalid parameter");
871 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
874 group = (wfd_group_s*) manager->group;
876 WDS_LOGE("Group not found");
877 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
880 wfd_state_set(manager, WIFI_DIRECT_STATE_DISCONNECTING);
882 res = wfd_oem_destroy_group(manager->oem_ops, group->ifname);
884 WDS_LOGE("Failed to destroy group");
885 res = WIFI_DIRECT_ERROR_OPERATION_FAILED;
888 WDS_LOGE("Succeeded to disconnect all peer");
890 wfd_destroy_group(manager, group->ifname);
892 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
893 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
895 __WDS_LOG_FUNC_EXIT__;
896 return WIFI_DIRECT_ERROR_NONE;
899 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
900 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
901 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
903 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
904 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
907 __WDS_LOG_FUNC_EXIT__;
911 static int _wfd_manager_service_copy(char* dst, GList* services, int dst_length)
913 __WDS_LOG_FUNC_ENTER__;
914 wfd_service_s *service = NULL;
917 int length = dst_length;
920 temp = g_list_first(services);
923 service = temp->data;
924 if(length < service->service_str_length + 4)
926 WDS_LOGD("There is not enough space to reserve service list");
930 memcpy(ptr, service->service_string, service->service_str_length);
931 ptr+=service->service_str_length;
932 strncpy(ptr," ,\n",3);
934 length = length - service->service_str_length - 3;
936 temp = g_list_next(temp);
939 __WDS_LOG_FUNC_EXIT__;
943 int wfd_manager_get_peers(wfd_manager_s *manager, wfd_discovery_entry_s **peers_data)
945 __WDS_LOG_FUNC_ENTER__;
947 wfd_device_s *peer = NULL;
948 wfd_discovery_entry_s *peers = NULL;
953 if (!manager || !peers_data) {
954 WDS_LOGE("Invalid parameter");
958 unsigned long time = 0;
960 gettimeofday(&tval, NULL);
962 WDS_LOGI("Current time [%ld]", time);
964 peer_count = manager->peer_count;
967 else if (peer_count == 0)
971 peers = (wfd_discovery_entry_s*) calloc(peer_count, sizeof(wfd_discovery_entry_s));
973 WDS_LOGF("Failed to allocate memory for peer data. [%s]", strerror(errno));
977 temp = g_list_first(manager->peers);
978 while (temp && count < peer_count) {
982 if (peer->time + 4 < time) {
983 WDS_LOGD("Device data is too old to report to application [%s]", peer->dev_name);
984 res = wfd_update_peer(manager, peer);
986 WDS_LOGE("This device is disappeared [%s]", peer->dev_name);
987 temp = g_list_next(temp);
988 manager->peers = g_list_remove(manager->peers, peer);
989 manager->peer_count--;
990 wfd_manager_init_service(peer);
991 if(peer->wifi_display)
992 free(peer->wifi_display);
999 strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
1000 peers[count].device_name[DEV_NAME_LEN] = '\0';
1001 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1002 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1003 peers[count].channel = peer->channel;
1004 peers[count].is_group_owner = peer->dev_role == WFD_DEV_ROLE_GO;
1005 peers[count].is_persistent_go = peer->group_flags & WFD_OEM_GROUP_FLAG_PERSISTENT_GROUP;
1006 peers[count].is_connected = peer->dev_role == WFD_DEV_ROLE_GC;
1007 peers[count].wps_device_pwd_id = 0;
1008 peers[count].wps_cfg_methods = peer->config_methods;
1009 peers[count].category = peer->pri_dev_type;
1010 peers[count].subcategory = peer->sec_dev_type;
1011 _wfd_manager_service_copy(peers[count].services, peer->services, 1024);
1012 if(peer->wifi_display)
1013 peers[count].is_wfd_device = peer->wifi_display->availability;
1016 WDS_LOGD("%dth peer [%s]", count, peer->dev_name);
1018 temp = g_list_next(temp);
1021 WDS_LOGD("%d peers converted", count);
1022 WDS_LOGD("Final peer count is %d", manager->peer_count);
1024 *peers_data = peers;
1026 __WDS_LOG_FUNC_EXIT__;
1030 int wfd_manager_get_connected_peers(wfd_manager_s *manager, wfd_connected_peer_info_s **peers_data)
1032 __WDS_LOG_FUNC_ENTER__;
1033 wfd_connected_peer_info_s *peers = NULL;
1034 wfd_group_s *group = NULL;
1035 wfd_device_s *peer = NULL;
1040 if (!manager || !peers_data) {
1041 WDS_LOGE("Invalid parameter");
1045 group = manager->group;
1047 WDS_LOGE("Group not exist");
1051 peer_count = group->member_count;
1052 if (peer_count == 0) {
1053 WDS_LOGD("Member not exist");
1058 peers = (wfd_connected_peer_info_s*) calloc(peer_count, sizeof(wfd_connected_peer_info_s));
1060 WDS_LOGE("Failed to allocate memory for connected peer data. [%s]", strerror(errno));
1064 temp = g_list_first(group->members);
1065 while (temp && count < group->member_count) {
1068 strncpy(peers[count].device_name, peer->dev_name, DEV_NAME_LEN);
1069 peers[count].device_name[DEV_NAME_LEN] = '\0';
1070 memcpy(peers[count].mac_address, peer->dev_addr, MACADDR_LEN);
1071 memcpy(peers[count].intf_address, peer->intf_addr, MACADDR_LEN);
1072 memcpy(peers[count].ip_address, peer->ip_addr, IPADDR_LEN);
1073 peers[count].category = peer->pri_dev_type;
1074 peers[count].subcategory = peer->sec_dev_type;
1075 peers[count].channel = peer->channel;
1076 peers[count].is_p2p = 1;
1077 _wfd_manager_service_copy(peers[count].services, peer->services, 1024);
1078 WDS_LOGD("%dth member converted[%s]", count, peers[count].device_name);
1081 temp = g_list_next(temp);
1084 WDS_LOGD("%d members converted", count);
1086 *peers_data = peers;
1088 __WDS_LOG_FUNC_EXIT__;
1092 wfd_device_s *wfd_manager_find_connected_peer(wfd_manager_s *manager, unsigned char *peer_addr)
1094 __WDS_LOG_FUNC_ENTER__;
1095 wfd_device_s *peer = NULL;
1097 if (!manager || !peer_addr) {
1098 WDS_LOGE("Invalid parameter");
1102 peer = wfd_group_find_member_by_addr(manager->group, peer_addr);
1104 __WDS_LOG_FUNC_EXIT__;
1108 wfd_device_s *wfd_manager_get_current_peer(wfd_manager_s *manager)
1110 __WDS_LOG_FUNC_ENTER__;
1111 wfd_session_s *session = NULL;
1114 WDS_LOGE("Invalid parameter");
1115 __WDS_LOG_FUNC_EXIT__;
1119 session = manager->session;
1120 if (session && session->peer) {
1121 __WDS_LOG_FUNC_EXIT__;
1122 return session->peer;
1125 __WDS_LOG_FUNC_EXIT__;
1129 int wfd_manager_get_goup_ifname(char **ifname)
1131 __WDS_LOG_FUNC_ENTER__;
1132 wfd_group_s *group = g_manager->group;
1135 WDS_LOGE("Invalid parameter");
1136 __WDS_LOG_FUNC_EXIT__;
1141 WDS_LOGE("Group not exist");
1145 *ifname = group->ifname;
1147 __WDS_LOG_FUNC_EXIT__;
1151 static wfd_service_s *_wfd_service_find(wfd_device_s *device, wifi_direct_service_type_e type, char *data)
1153 __WDS_LOG_FUNC_ENTER__;
1154 wfd_service_s *result = NULL;
1158 temp = g_list_first(device->services);
1160 result = temp->data;
1162 if(result->service_type == WIFI_DIRECT_SERVICE_BONJOUR)
1163 cmp_result = strncmp(data, result->service_string, strlen(data));
1165 cmp_result = strcmp(data, result->service_string);
1167 if(type == result->service_type && !cmp_result)
1169 WDS_LOGD("Service found");
1172 temp = g_list_next(temp);
1175 __WDS_LOG_FUNC_EXIT__;
1179 static wfd_query_s *_wfd_query_find(wfd_manager_s *manager, unsigned char* mac_addr, wifi_direct_service_type_e type, char *data)
1181 __WDS_LOG_FUNC_ENTER__;
1182 wfd_query_s *query = NULL;
1187 data_len = strlen(data);
1189 temp = g_list_first(manager->query_handles);
1193 if(!memcmp(query->mac_addr, mac_addr, MACADDR_LEN) &&
1194 type == query->service_type)
1198 if(!strcmp(data, query->query_string))
1200 WDS_LOGD("Query found");
1204 WDS_LOGD("Query found");
1208 temp = g_list_next(temp);
1211 __WDS_LOG_FUNC_EXIT__;
1215 int wfd_manager_service_add(wfd_manager_s *manager, wifi_direct_service_type_e type, char *data)
1217 __WDS_LOG_FUNC_ENTER__;
1218 wfd_device_s * device = manager->local;
1219 wfd_service_s * service;
1222 if (!device || !data) {
1223 WDS_LOGE("Invalid parameter");
1227 service = _wfd_service_find(device, type, data);
1229 WDS_LOGE("service already exist");
1230 service->ref_counter++;
1231 __WDS_LOG_FUNC_EXIT__;
1235 res = wfd_oem_service_add(manager->oem_ops, type, data);
1237 WDS_LOGE("Failed to add service");
1238 __WDS_LOG_FUNC_EXIT__;
1242 service = (wfd_service_s*) calloc(1, sizeof(wfd_service_s));
1243 service->service_string = strndup(data, strlen(data));
1244 service->service_str_length = strlen(data);
1245 service->service_type = type;
1246 service->ref_counter=1;
1247 device->services = g_list_prepend(device->services, service);
1248 __WDS_LOG_FUNC_EXIT__;
1252 int wfd_manager_service_del(wfd_manager_s *manager, wifi_direct_service_type_e type, char *data)
1254 __WDS_LOG_FUNC_ENTER__;
1255 wfd_device_s * device = manager->local;
1256 wfd_service_s* service;
1259 if (!device || !data) {
1260 WDS_LOGE("Invalid parameter");
1263 service = _wfd_service_find(device, type, data);
1265 WDS_LOGE("Failed to find service");
1268 }else if(service->ref_counter ==1)
1270 res = wfd_oem_service_del(manager->oem_ops, type, data);
1272 WDS_LOGE("Failed to delete service");
1273 __WDS_LOG_FUNC_EXIT__;
1276 device->services = g_list_remove(device->services, service);
1277 free(service->service_string);
1281 service->ref_counter--;
1283 __WDS_LOG_FUNC_EXIT__;
1287 int wfd_manager_serv_disc_req(wfd_manager_s *manager, unsigned char* mad_addr, wifi_direct_service_type_e type, char *data)
1289 __WDS_LOG_FUNC_ENTER__;
1294 WDS_LOGE("Invalid parameter");
1297 query = _wfd_query_find(manager, mad_addr, type, data);
1299 WDS_LOGE("Query already exist");
1300 query->ref_counter++;
1301 __WDS_LOG_FUNC_EXIT__;
1305 res = wfd_oem_serv_disc_req(manager->oem_ops, mad_addr, type, data);
1307 WDS_LOGE("Failed to request service discovery");
1310 query = (wfd_query_s*) calloc(1, sizeof(wfd_query_s));
1311 query->handle = res;
1312 query->ref_counter=1;
1313 memcpy(query->mac_addr, mad_addr, MACADDR_LEN);
1315 if(data && strlen(data))
1316 query->query_string = strndup(data, strlen(data));
1317 query->service_type = type;
1318 manager->query_handles = g_list_prepend(manager->query_handles, query);
1319 __WDS_LOG_FUNC_EXIT__;
1323 int wfd_manager_serv_disc_cancel(wfd_manager_s *manager, int handle)
1325 __WDS_LOG_FUNC_ENTER__;
1326 wfd_query_s *query = NULL;
1330 temp = g_list_first(manager->query_handles);
1334 //TODO : compare the services
1335 if(query->handle == handle)
1337 WDS_LOGD("Query handle found");
1340 temp = g_list_next(temp);
1345 WDS_LOGE("handle does not exist");
1347 }else if(query->ref_counter ==1) {
1349 res = wfd_oem_serv_disc_cancel(manager->oem_ops, query->handle);
1351 WDS_LOGE("Failed to cancel service discovery or already canceled");
1353 manager->query_handles = g_list_remove(manager->query_handles, query);
1354 if(query->query_string)
1355 free(query->query_string);
1358 query->ref_counter--;
1360 __WDS_LOG_FUNC_EXIT__;
1364 int wfd_manager_init_service(wfd_device_s *device)
1366 __WDS_LOG_FUNC_ENTER__;
1367 wfd_service_s* service = NULL;
1372 WDS_LOGE("Invalid parameter");
1376 if(device->services)
1378 temp = g_list_first(device->services);
1380 service = temp->data;
1381 free(service->service_string);
1383 temp = g_list_next(temp);
1385 g_list_free(device->services);
1387 __WDS_LOG_FUNC_EXIT__;
1391 int wfd_manager_init_query(wfd_manager_s *manager)
1393 __WDS_LOG_FUNC_ENTER__;
1394 wfd_query_s *query = NULL;
1399 WDS_LOGE("Invalid parameter");
1403 if(manager->query_handles)
1405 temp = g_list_first(manager->query_handles);
1409 free(query->query_string);
1411 temp = g_list_next(temp);
1413 g_list_free(manager->query_handles);
1416 __WDS_LOG_FUNC_EXIT__;
1420 int wfd_manager_init_wifi_display(wifi_direct_display_type_e type, int port, int hdcp)
1422 __WDS_LOG_FUNC_ENTER__;
1423 wfd_device_s * device = g_manager->local;
1424 wfd_display_info_s * display;
1427 if (type < 0 || port < 0 || hdcp < 0) {
1428 WDS_LOGE("Invalid parameter");
1429 __WDS_LOG_FUNC_EXIT__;
1433 res = wfd_oem_init_wifi_display(g_manager->oem_ops, type, port, hdcp);
1435 WDS_LOGE("Failed to initialize wifi display");
1439 if(!device->wifi_display)
1440 device->wifi_display = calloc(1, sizeof(wfd_display_info_s));
1442 device->wifi_display->type = type;
1443 device->wifi_display->hdcp_support = hdcp;
1444 device->wifi_display->ctrl_port = port;
1446 __WDS_LOG_FUNC_EXIT__;
1450 int wfd_manager_deinit_wifi_display()
1452 __WDS_LOG_FUNC_ENTER__;
1453 wfd_device_s * device = g_manager->local;
1454 wfd_display_info_s * display;
1457 res = wfd_oem_deinit_wifi_display(g_manager->oem_ops);
1459 WDS_LOGE("Failed to deinitialize wifi display");
1463 if(device->wifi_display)
1465 free(device->wifi_display);
1466 device->wifi_display = NULL;
1468 __WDS_LOG_FUNC_EXIT__;
1472 static wfd_manager_s *wfd_manager_init()
1474 __WDS_LOG_FUNC_ENTER__;
1475 wfd_manager_s *manager = NULL;
1478 manager = (wfd_manager_s*) calloc(1, sizeof(wfd_manager_s));
1480 WDS_LOGE("Failed to allocate memory for wfd_manager structure");
1484 manager->go_intent = 7;
1485 manager->req_wps_mode = WFD_WPS_MODE_PBC;
1486 manager->max_station = 8;
1488 res = _wfd_local_init_device(manager);
1490 WDS_LOGE("Failed to initialize local device");
1492 return NULL; // really stop manager?
1494 WDS_LOGD("Succeeded to initialize local device");
1496 manager->exit_timer = g_timeout_add(120000,
1497 (GSourceFunc) _wfd_exit_timeout_cb, manager);
1498 WDS_LOGD("Exit timer started");
1500 __WDS_LOG_FUNC_EXIT__;
1504 int wfd_manager_deinit(wfd_manager_s *manager)
1506 __WDS_LOG_FUNC_ENTER__;
1509 WDS_LOGE("Invalid parameter");
1510 __WDS_LOG_FUNC_EXIT__;
1514 if (manager->exit_timer > 0)
1515 g_source_remove(manager->exit_timer);
1516 manager->exit_timer = 0;
1518 _wfd_local_deinit_device(manager);
1523 __WDS_LOG_FUNC_EXIT__;
1527 static void *wfd_plugin_init(wfd_manager_s *manager)
1529 __WDS_LOG_FUNC_ENTER__;
1531 struct utsname kernel_info;
1535 WDS_LOGE("Invalid parameter");
1536 __WDS_LOG_FUNC_EXIT__;
1540 res = uname(&kernel_info);
1542 WDS_LOGE("Failed to detect target type");
1543 __WDS_LOG_FUNC_EXIT__;
1546 WDS_LOGD("Node name [%s], HW ID [%s]", kernel_info.nodename, kernel_info.machine);
1549 handle = dlopen(SUPPL_PLUGIN_PATH, RTLD_NOW);
1551 WDS_LOGE("Failed to open shared object. [%s]", dlerror());
1552 __WDS_LOG_FUNC_EXIT__;
1557 int (*plugin_load)(wfd_oem_ops_s **ops) = NULL;
1558 plugin_load = (int (*)(wfd_oem_ops_s **ops)) dlsym(handle, "wfd_plugin_load");
1560 WDS_LOGE( "Failed to load symbol. Error = [%s]", strerror(errno));
1562 __WDS_LOG_FUNC_EXIT__;
1566 wfd_oem_ops_s *temp_ops;
1567 (*plugin_load)(&temp_ops);
1568 manager->oem_ops = temp_ops;
1570 res = wfd_oem_init(temp_ops, (wfd_oem_event_cb) wfd_process_event, manager);
1572 WDS_LOGE("Failed to initialize OEM");
1574 __WDS_LOG_FUNC_EXIT__;
1577 WDS_LOGD("Succeeded to initialize OEM");
1579 __WDS_LOG_FUNC_EXIT__;
1583 static int wfd_plugin_deinit(wfd_manager_s *manager)
1585 __WDS_LOG_FUNC_ENTER__;
1587 if (!manager || !manager->plugin_handle) {
1588 WDS_LOGE("Invalid parameter");
1589 __WDS_LOG_FUNC_EXIT__;
1593 dlclose(manager->plugin_handle);
1594 manager->plugin_handle = NULL;
1596 __WDS_LOG_FUNC_EXIT__;
1600 int main(int argc, char *argv[])
1602 __WDS_LOG_FUNC_ENTER__;
1603 GMainLoop *main_loop = NULL;
1606 if (!g_thread_supported())
1607 g_thread_init(NULL);
1611 // TODO: Parsing argument
1612 /* Wi-Fi direct connection for S-Beam can be optimized using argument */
1614 g_manager = wfd_manager_init();
1616 WDS_LOGE("Failed to initialize wifi-direct manager");
1617 __WDS_LOG_FUNC_EXIT__;
1620 WDS_LOGD("Succeeded to initialize manager");
1622 g_manager->plugin_handle = wfd_plugin_init(g_manager);
1623 if (!g_manager->plugin_handle) {
1624 WDS_LOGE("Failed to initialize plugin");
1625 wfd_manager_deinit(g_manager);
1626 __WDS_LOG_FUNC_EXIT__;
1629 WDS_LOGD("Succeeded to load plugin");
1631 res = wfd_client_handler_init(g_manager);
1633 WDS_LOGE("Failed to initialize client handler");
1634 wfd_plugin_deinit(g_manager);
1635 wfd_manager_deinit(g_manager);
1636 __WDS_LOG_FUNC_EXIT__;
1639 WDS_LOGD("Succeeded to initialize client handler");
1641 main_loop = g_main_loop_new(NULL, FALSE);
1642 if (main_loop == NULL) {
1643 WDS_LOGE("Failed to create GMainLoop structure");
1644 __WDS_LOG_FUNC_EXIT__;
1647 g_manager->main_loop = main_loop;
1649 g_main_loop_run(main_loop);
1651 wfd_client_handler_deinit(g_manager);
1652 wfd_plugin_deinit(g_manager);
1653 wfd_manager_deinit(g_manager);
1655 __WDS_LOG_FUNC_EXIT__;