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 group functions.
23 * @file wifi-direct-group.c
24 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
34 #include <wifi-direct-internal.h>
36 #include "wifi-direct-manager.h"
37 #include "wifi-direct-peer.h"
38 #include "wifi-direct-oem.h"
39 #include "wifi-direct-group.h"
40 #include "wifi-direct-util.h"
41 #include "wifi-direct-session.h"
42 #include "wifi-direct-client.h"
44 // Check the group instance which has same interface name, before using this function
45 wfd_group_s *wfd_create_group(void *data, char *ifname, int role, unsigned char *go_dev_addr)
47 __WDS_LOG_FUNC_ENTER__;
48 wfd_group_s *group = NULL;
49 wfd_manager_s *manager = (wfd_manager_s*) data;
51 if (!manager || !ifname || !go_dev_addr) {
52 WDS_LOGE("Invalid parameter");
53 __WDS_LOG_FUNC_EXIT__;
57 group = manager->group;
59 WDS_LOGE("Group already exist");
60 __WDS_LOG_FUNC_EXIT__;
65 group = (wfd_group_s*) calloc(1, sizeof(wfd_group_s));
67 WDS_LOGE("Failed to allocate memory for group. [%s]", strerror(errno));
68 __WDS_LOG_FUNC_EXIT__;
72 memcpy(group->ifname, ifname, IFACE_NAME_LEN);
73 group->ifname[IFACE_NAME_LEN] = '\0';
75 memcpy(group->go_dev_addr, go_dev_addr, MACADDR_LEN);
78 wfd_util_dhcps_start();
79 WDS_LOGD("Role is Group Owner. DHCP Server started");
81 __WDS_LOG_FUNC_EXIT__;
85 // Used for CTRL-EVENT_CONNECTED event that comes before group created
86 wfd_group_s *wfd_create_pending_group(void *data, unsigned char * bssid)
88 __WDS_LOG_FUNC_ENTER__;
89 wfd_group_s *group = NULL;
90 wfd_manager_s *manager = (wfd_manager_s*) data;
92 if (!manager || !bssid) {
93 WDS_LOGE("Invalid parameter");
94 __WDS_LOG_FUNC_EXIT__;
98 group = manager->group;
100 WDS_LOGE("Group already exist");
101 __WDS_LOG_FUNC_EXIT__;
106 group = (wfd_group_s*) calloc(1, sizeof(wfd_group_s));
108 WDS_LOGE("Failed to allocate memory for group. [%s]", strerror(errno));
109 __WDS_LOG_FUNC_EXIT__;
113 memcpy(group->bssid, bssid, MACADDR_LEN);
116 __WDS_LOG_FUNC_EXIT__;
120 int wfd_group_complete(void *data, char *ifname, int role, unsigned char *go_dev_addr)
122 __WDS_LOG_FUNC_ENTER__;
123 wfd_manager_s *manager = (wfd_manager_s*) data;
124 wfd_group_s *group = NULL;
125 wfd_device_s *peer = NULL;
127 if (!manager || !ifname || !go_dev_addr) {
128 WDS_LOGE("Invalid parameter");
129 __WDS_LOG_FUNC_EXIT__;
133 group = manager->group;
135 WDS_LOGE("Group not found");
139 if (!group->pending) {
140 WDS_LOGE("This is not pending group");
141 __WDS_LOG_FUNC_EXIT__;
145 memcpy(group->ifname, ifname, IFACE_NAME_LEN);
146 group->ifname[IFACE_NAME_LEN] = '\0';
148 memcpy(group->go_dev_addr, go_dev_addr, MACADDR_LEN);
151 peer = wfd_session_get_peer(manager->session);
152 if (!peer && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
153 WDS_LOGE("Failed to find peer by device address[" MACSTR "]", go_dev_addr);
156 if (group->role == WFD_DEV_ROLE_GO) {
157 wfd_util_dhcps_start();
158 WDS_LOGD("Role is Group Owner. DHCP Server started");
160 wfd_util_dhcpc_start(peer);
163 __WDS_LOG_FUNC_EXIT__;
167 int wfd_destroy_group(void *data, char *ifname)
169 __WDS_LOG_FUNC_ENTER__;
170 wfd_group_s *group = NULL;
171 wfd_manager_s *manager = (wfd_manager_s*) data;
173 wfd_device_s *member = NULL;
176 if (!data || !ifname) {
177 WDS_LOGE("Invalid parameter");
178 __WDS_LOG_FUNC_EXIT__;
182 group = manager->group;
184 WDS_LOGE("Group not exist");
185 __WDS_LOG_FUNC_EXIT__;
188 manager->group = NULL;
190 if (group->role == WFD_DEV_ROLE_GO)
191 wfd_util_dhcps_stop();
193 wfd_util_dhcpc_stop();
195 temp = g_list_first(group->members);
196 while(temp && count < group->member_count) {
198 WDS_LOGD("%dth member[%s] freed", count, member->dev_name);
199 if (member) // Temporary. Sometimes manager crashed
201 wfd_manager_init_service(member);
204 temp = g_list_next(temp);
207 g_list_free(group->members);
211 manager->local->dev_role = WFD_DEV_ROLE_NONE;
212 __WDS_LOG_FUNC_EXIT__;
216 int wfd_group_get_channel(wfd_group_s *group)
218 __WDS_LOG_FUNC_ENTER__;
221 WDS_LOGE("Invalid parameter");
222 __WDS_LOG_FUNC_EXIT__;
226 __WDS_LOG_FUNC_EXIT__;
230 int wfd_group_is_autonomous(wfd_group_s *group)
232 __WDS_LOG_FUNC_ENTER__;
235 WDS_LOGE("Invalid parameter");
236 __WDS_LOG_FUNC_EXIT__;
240 __WDS_LOG_FUNC_EXIT__;
241 return group->flags & WFD_GROUP_FLAG_AUTONOMOUS;;
244 int wfd_group_get_members()
246 __WDS_LOG_FUNC_ENTER__;
248 __WDS_LOG_FUNC_EXIT__;
252 int wfd_group_make_persistent()
254 __WDS_LOG_FUNC_ENTER__;
256 __WDS_LOG_FUNC_EXIT__;
260 int wfd_group_get_flags(wfd_group_s *group)
262 __WDS_LOG_FUNC_ENTER__;
265 WDS_LOGE("Invalid parameter");
266 __WDS_LOG_FUNC_EXIT__;
270 __WDS_LOG_FUNC_EXIT__;
274 wfd_device_s *wfd_group_find_member_by_addr(wfd_group_s *group, unsigned char *addr)
276 __WDS_LOG_FUNC_ENTER__;
278 wfd_device_s *member = NULL;
280 if (!group || !addr) {
281 WDS_LOGE("Invalid parameter");
282 __WDS_LOG_FUNC_EXIT__;
286 if (!group->member_count) {
287 WDS_LOGE("There is no members");
288 __WDS_LOG_FUNC_EXIT__;
292 temp = g_list_first(group->members);
295 if (!memcmp(member->intf_addr, addr, MACADDR_LEN) ||
296 !memcmp(member->dev_addr, addr, MACADDR_LEN)) {
297 WDS_LOGD("Member found");
301 temp = g_list_next(temp);
305 __WDS_LOG_FUNC_EXIT__;
309 int wfd_group_add_member(wfd_group_s *group, unsigned char *addr)
311 __WDS_LOG_FUNC_ENTER__;
312 wfd_device_s *member = NULL;
313 wfd_manager_s *manager = wfd_get_manager();
315 if (!group || !addr) {
316 WDS_LOGE("Invalid parameter");
317 __WDS_LOG_FUNC_EXIT__;
321 member = wfd_group_find_member_by_addr(group, addr);
323 WDS_LOGE("Member already exist");
327 member = wfd_peer_find_by_addr(manager, addr);
329 WDS_LOGE("Peer not found");
332 group->members = g_list_prepend(group->members, member);
333 group->member_count++;
335 manager->peers = g_list_remove(manager->peers, member);
336 manager->peer_count--;
338 __WDS_LOG_FUNC_EXIT__;
342 int wfd_group_remove_member(wfd_group_s *group, unsigned char *addr)
344 __WDS_LOG_FUNC_ENTER__;
345 wfd_device_s *member = NULL;
347 if (!group || !addr) {
348 WDS_LOGE("Invalid parameter");
349 __WDS_LOG_FUNC_EXIT__;
353 if (group->member_count == 0) {
354 WDS_LOGE("There is no members");
355 __WDS_LOG_FUNC_EXIT__;
359 member = wfd_group_find_member_by_addr(group, addr);
361 WDS_LOGE("Member not found [MAC: " MACSTR "]", addr);
362 __WDS_LOG_FUNC_EXIT__;
366 group->members = g_list_remove(group->members, member);
368 group->member_count--;
370 __WDS_LOG_FUNC_EXIT__;