if (!session) {
WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSTR "]",
MAC2STR(event->dev_addr));
- return -1;
+ wfd_oem_destroy_group(manager->oem_ops, GROUP_IFNAME);
+ wfd_destroy_group(manager, GROUP_IFNAME);
+ wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
+ wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+ break;
}
- // TODO: check whether here is complete location. How about Group Created event
- session->state = SESSION_STATE_COMPLETED;
+
+ wfd_device_s *peer = wfd_session_get_peer(session);
+ if (!peer) {
+ WDS_LOGE("Peer not found");
+ break;
+ }
wfd_group_s *group = (wfd_group_s*) manager->group;
if (!group) {
group = wfd_create_pending_group(manager, event->intf_addr);
if (!group) {
WDS_LOGE("Failed to create pending group");
- return -1;
+ break;
}
manager->group = group;
}
+ wfd_group_add_member(group, peer->dev_addr);
- wfd_device_s *peer = session->peer;
- if (!peer) {
- WDS_LOGE("Peer not found");
- // TODO: remove pending group
- return -1;
- }
- memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
session->state = SESSION_STATE_COMPLETED;
+ memcpy(peer->intf_addr, event->intf_addr, MACADDR_LEN);
peer->state = WFD_PEER_STATE_CONNECTED;
- group->members = g_list_prepend(group->members, peer);
- group->member_count++;
-
- manager->peers = g_list_remove(manager->peers, peer);
- manager->peer_count--;
if (event->event_id == WFD_OEM_EVENT_STA_CONNECTED) { // GO
wifi_direct_client_noti_s noti;
case WFD_OEM_EVENT_DISCONNECTED:
case WFD_OEM_EVENT_STA_DISCONNECTED:
{
- wfd_group_s *group = NULL;
+ wfd_group_s *group = (wfd_group_s*) manager->group;
+ wfd_session_s *session = (wfd_session_s*) manager->session;
wfd_device_s *peer = NULL;
- group = (wfd_group_s*) manager->group;
- if (!group) {
- WDS_LOGE("Group not found");
- break;
- }
+ unsigned char peer_addr[MACADDR_LEN] = {0, };
+ wifi_direct_client_noti_s noti;
+ memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
- peer = wfd_group_find_peer_by_intf_addr(group, event->intf_addr);
+ peer = wfd_group_find_member_by_addr(group, event->intf_addr);
if (!peer) {
- WDS_LOGE("Failed to find peer by interface address");
- break;
+ WDS_LOGE("Failed to find connected peer");
+ peer = wfd_session_get_peer(session);
+ if (!peer) {
+ WDS_LOGE("Failed to find connecting peer");
+ break;
+ }
}
+ memcpy(peer_addr, peer->dev_addr, MACADDR_LEN);
- group->members = g_list_remove(group->members, peer);
- group->member_count--;
-
- wifi_direct_client_noti_s noti;
- memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
/* If state is not DISCONNECTING, connection is finished by peer */
if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
+ wfd_group_remove_member(group, peer_addr);
if (group->member_count)
noti.event = WIFI_DIRECT_CLI_EVENT_DISASSOCIATION_IND;
else
noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_IND;
noti.error = WIFI_DIRECT_ERROR_NONE;
- snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
- wfd_client_send_event(manager, ¬i);
+ snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+ /* If there is no member, GO should be destroyed */
+ if (!group->member_count) {
+ wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+ wfd_destroy_group(manager, group->ifname);
+ }
} else if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
noti.error = WIFI_DIRECT_ERROR_NONE;
- snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer->dev_addr));
- wfd_client_send_event(manager, ¬i);
+ snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+ } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING &&
+ /* Some devices(GO) send disconnection message before connection completed.
+ * This message should be ignored when device is not GO */
+ manager->local->dev_role == WFD_DEV_ROLE_GO) {
+ noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+ noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+ snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+ } else {
+ WDS_LOGE("Unexpected event. Ignore it");
+ break;
}
+ wfd_client_send_event(manager, ¬i);
- if (group->role == WFD_DEV_ROLE_GO) {
+ if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
} else {
wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
}
-
- if (!group->member_count && group->role == WFD_DEV_ROLE_GO)
- wfd_oem_destroy_group(manager->oem_ops, group->ifname);
-
- if (peer)
- free(peer);
+ wfd_destroy_session(manager);
}
break;
case WFD_OEM_EVENT_GROUP_CREATED:
{
- wfd_oem_group_data_s *edata = NULL;
- edata = event->edata;
+ wfd_oem_group_data_s *edata = event->edata;
+ wfd_group_s *group = (wfd_group_s*) manager->group;
- wfd_group_s *group = NULL;
- group = (wfd_group_s*) manager->group;
if (!group) {
- group = wfd_create_group(manager, event->ifname, event->dev_role, edata->go_dev_addr /* event->intf_addr */);
+ if (!manager->session) {
+ WDS_LOGE("Unexpected Event. Group should be removed(Client)");
+ wfd_oem_destroy_group(manager->oem_ops, event->ifname);
+ break;
+ }
+
+ group = wfd_create_group(manager, event->ifname, event->dev_role, edata->go_dev_addr);
if (!group) {
WDS_LOGE("Failed to create group");
break;
}
} else {
+ if (!manager->session && !(group->flags & WFD_GROUP_FLAG_AUTONOMOUS)) {
+ WDS_LOGE("Unexpected Event. Group should be removed(Owner)");
+ wfd_oem_destroy_group(manager->oem_ops, group->ifname);
+ break;
+ }
+
if (group->pending) {
wfd_group_complete(manager, event->ifname, event->dev_role, edata->go_dev_addr);
} else {
- // TODO: ignore it
WDS_LOGE("Unexpected event. Group already exist");
break;
}
wifi_direct_client_noti_s noti;
memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
if (group->role == WFD_DEV_ROLE_GC) {
- if (!manager->session) {
- WDS_LOGE("Unexpected Event. Group should be removed(Client)");
- wfd_oem_destroy_group(manager->oem_ops, group->ifname);
- break;
- }
- wfd_peer_clear_all(manager);
- wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTED);
- wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTED);
wfd_destroy_session(manager);
- manager->local->dev_role = WFD_DEV_ROLE_GC;
+ wfd_peer_clear_all(manager);
} else {
if (group->flags & WFD_GROUP_FLAG_AUTONOMOUS) {
noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_CREATE_RSP;
wfd_client_send_event(manager, ¬i);
- } else if (!manager->session) {
- WDS_LOGE("Unexpected Event. Group should be removed(Owner)");
- wfd_oem_destroy_group(manager->oem_ops, group->ifname);
- break;
+ wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
+ wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
}
- wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
- wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
- manager->local->dev_role = WFD_DEV_ROLE_GO;
}
}
break;
case WFD_OEM_EVENT_GROUP_DESTROYED:
{
- wfd_group_s *group = (wfd_group_s*) manager->group;
- if (!group) {
- WDS_LOGE("Unexpected event. Group not found. But set state");
- wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
- wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
- break;
- }
-
- if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING &&
- group->role == WFD_DEV_ROLE_GO) {
- wifi_direct_client_noti_s noti;
- memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
+ wifi_direct_client_noti_s noti;
+ memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
+ if (manager->state == WIFI_DIRECT_STATE_DISCONNECTING) {
noti.event = WIFI_DIRECT_CLI_EVENT_DISCONNECTION_RSP;
noti.error = WIFI_DIRECT_ERROR_NONE;
- wfd_client_send_event(manager, ¬i);
- } else {
- wifi_direct_client_noti_s noti;
- memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
+ } else if (manager->state == WIFI_DIRECT_STATE_CONNECTING && manager->session){
+ noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+ noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+ unsigned char *peer_addr = wfd_session_get_peer_addr(manager->session);
+ snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+ } else if (manager->state >= WIFI_DIRECT_STATE_CONNECTED) {
noti.event = WIFI_DIRECT_CLI_EVENT_GROUP_DESTROY_RSP;
noti.error = WIFI_DIRECT_ERROR_NONE;
- wfd_client_send_event(manager, ¬i);
- }
-
- res = wfd_destroy_group(manager, event->ifname);
- if (res < 0) {
- WDS_LOGE("Failed to destroy group");
+ } else {
+ WDS_LOGD("Unexpected event(GROUP_DESTROYED). Ignore it");
break;
}
+ wfd_client_send_event(manager, ¬i);
- wfd_destroy_session(manager);
- manager->local->dev_role = WFD_DEV_ROLE_NONE;
- memset(manager->local->ip_addr, 0x0, IPADDR_LEN);
wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
+ wfd_destroy_group(manager, event->ifname);
+ wfd_destroy_session(manager);
+ manager->local->dev_role = WFD_DEV_ROLE_NONE;
}
break;
case WFD_OEM_EVENT_PROV_DISC_FAIL:
break;
}
- wfd_destroy_session(manager);
+ wifi_direct_client_noti_s noti;
+ memset(¬i, 0x0, sizeof(wifi_direct_client_noti_s));
+ noti.event = WIFI_DIRECT_CLI_EVENT_CONNECTION_RSP;
+ noti.error = WIFI_DIRECT_ERROR_CONNECTION_FAILED;
+ snprintf(noti.param1, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
+ wfd_client_send_event(manager, ¬i);
+
if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
}
+ wfd_destroy_session(manager);
+
/* After connection failed, scan again */
wfd_oem_scan_param_s param;
memset(¶m, 0x0, sizeof(wfd_oem_scan_param_s));
#include "wifi-direct-group.h"
#include "wifi-direct-util.h"
#include "wifi-direct-session.h"
-#include "wifi-direct-event.h"
+#include "wifi-direct-client.h"
// Check the group instance which has same interface name, before using this function
wfd_group_s *wfd_create_group(void *data, char *ifname, int role, unsigned char *go_dev_addr)
temp = g_list_first(group->members);
while(temp && count < group->member_count) {
member = temp->data;
- //member->my_group = 0;
WDS_LOGD("%dth member[%s] freed", count, member->dev_name);
if (member) // Temporary. Sometimes manager crashed
free(member);
return 0;
}
-int wfd_group_get_channel(void *data, unsigned char *bssid)
+int wfd_group_get_channel(wfd_group_s *group)
{
__WDS_LOG_FUNC_ENTER__;
- wfd_group_s *group = NULL;
- wfd_manager_s *manager = (wfd_manager_s*) data;
- if (!data || !bssid) {
- WDS_LOGE("Invalid parameter");
- __WDS_LOG_FUNC_EXIT__;
- return -1;
- }
-
- group = manager->group;
if (!group) {
- WDS_LOGE("Group not found [bssid: " MACSTR "]", MAC2STR(bssid));
+ WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
return -1;
}
return group->freq;
}
-int wfd_group_is_autonomous(void *data)
+int wfd_group_is_autonomous(wfd_group_s *group)
{
__WDS_LOG_FUNC_ENTER__;
- wfd_group_s *group = NULL;
- wfd_manager_s *manager = (wfd_manager_s*) data;
- if (!data) {
- WDS_LOGE("Invalid parameter");
- __WDS_LOG_FUNC_EXIT__;
- return -1;
- }
-
- group = manager->group;
if (!group) {
- WDS_LOGE("Group not found");
+ WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
return -1;
}
return 0;
}
-int wfd_group_get_flags(void *data, unsigned char *bssid)
+int wfd_group_get_flags(wfd_group_s *group)
{
__WDS_LOG_FUNC_ENTER__;
- wfd_group_s *group = NULL;
- wfd_manager_s *manager = (wfd_manager_s*) data;
- if (!data || !bssid) {
- WDS_LOGE("Invalid parameter");
- __WDS_LOG_FUNC_EXIT__;
- return -1;
- }
-
- group = manager->group;
if (!group) {
- WDS_LOGE("Group not found [bssid: " MACSTR "]", MAC2STR(bssid));
+ WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
return -1;
}
return group->flags;
}
-wfd_device_s *wfd_group_find_peer_by_dev_addr(wfd_group_s *group, unsigned char *dev_addr)
+wfd_device_s *wfd_group_find_member_by_addr(wfd_group_s *group, unsigned char *addr)
{
__WDS_LOG_FUNC_ENTER__;
GList *temp = NULL;
wfd_device_s *member = NULL;
- if (!group || !dev_addr) {
+ if (!group || !addr) {
WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
return NULL;
}
- if (group->member_count == 0) {
+ if (!group->member_count) {
WDS_LOGE("There is no members");
__WDS_LOG_FUNC_EXIT__;
return NULL;
temp = g_list_first(group->members);
while (temp) {
member = temp->data;
- if (!memcmp(member->dev_addr, dev_addr, MACADDR_LEN)) {
+ if (!memcmp(member->intf_addr, addr, MACADDR_LEN) ||
+ !memcmp(member->dev_addr, addr, MACADDR_LEN)) {
WDS_LOGD("Member found");
break;
}
+next:
temp = g_list_next(temp);
member = NULL;
}
return member;
}
-wfd_device_s *wfd_group_find_peer_by_intf_addr(wfd_group_s *group, unsigned char *intf_addr)
+int wfd_group_add_member(wfd_group_s *group, unsigned char *addr)
{
__WDS_LOG_FUNC_ENTER__;
- GList *temp = NULL;
wfd_device_s *member = NULL;
+ wfd_manager_s *manager = wfd_get_manager();
- if (!group || !intf_addr) {
+ if (!group || !addr) {
WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
- return NULL;
- }
-
- if (group->member_count == 0) {
- WDS_LOGE("There is no members");
- __WDS_LOG_FUNC_EXIT__;
- return NULL;
- }
-
- temp = g_list_first(group->members);
- while (temp) {
- member = temp->data;
- if (!memcmp(member->intf_addr, intf_addr, MACADDR_LEN)) {
- WDS_LOGD("Member found");
- break;
- }
- temp = g_list_next(temp);
- member = NULL;
+ return -1;
}
- __WDS_LOG_FUNC_EXIT__;
- return member;
-}
-
-int wfd_group_add_member(void *data, unsigned char *bssid, unsigned char *peer)
-{
- __WDS_LOG_FUNC_ENTER__;
- wfd_group_s *group = NULL;
- wfd_manager_s *manager = (wfd_manager_s*) data;
- unsigned char *member = NULL;
-
- if (!data || !bssid || !peer) {
- WDS_LOGE("Invalid parameter");
- __WDS_LOG_FUNC_EXIT__;
+ member = wfd_group_find_member_by_addr(group, addr);
+ if (member) {
+ WDS_LOGE("Member already exist");
return -1;
}
- group = manager->group;
- if (!group) {
- WDS_LOGE("Group not found [bssid: " MACSTR "]", MAC2STR(bssid));
- __WDS_LOG_FUNC_EXIT__;
- return -1;
+ member = wfd_peer_find_by_addr(manager, addr);
+ if (!member) {
+ WDS_LOGE("Peer not found");
}
- member = (unsigned char*) calloc(1, MACADDR_LEN);
group->members = g_list_prepend(group->members, member);
group->member_count++;
+ manager->peers = g_list_remove(manager->peers, member);
+ manager->peer_count--;
+
__WDS_LOG_FUNC_EXIT__;
return 0;
}
-int wfd_group_remove_member(void *data, unsigned char *bssid, unsigned char *peer)
+int wfd_group_remove_member(wfd_group_s *group, unsigned char *addr)
{
__WDS_LOG_FUNC_ENTER__;
- wfd_group_s *group = NULL;
- wfd_manager_s *manager = (wfd_manager_s*) data;
- GList *temp = NULL;
- unsigned char *member = NULL;
+ wfd_device_s *member = NULL;
- if (!data || !bssid || !peer) {
+ if (!group || !addr) {
WDS_LOGE("Invalid parameter");
__WDS_LOG_FUNC_EXIT__;
return -1;
}
- group = manager->group;
- if (!group) {
- WDS_LOGE("Group not found [bssid: " MACSTR "]", MAC2STR(bssid));
- __WDS_LOG_FUNC_EXIT__;
- return -1;
- }
-
if (group->member_count == 0) {
WDS_LOGE("There is no members");
__WDS_LOG_FUNC_EXIT__;
return -1;
}
- temp = g_list_first(group->members);
- while (temp) {
- member = temp->data;
- if (!memcmp(member, peer, MACADDR_LEN)) {
- WDS_LOGD("Member found [MAC: " MACSTR "]", peer);
- break;
- }
- temp = g_list_next(temp);
- member = NULL;
- }
-
+ member = wfd_group_find_member_by_addr(group, addr);
if (!member) {
- WDS_LOGE("Member not found [MAC: " MACSTR "]", peer);
+ WDS_LOGE("Member not found [MAC: " MACSTR "]", addr);
__WDS_LOG_FUNC_EXIT__;
return -1;
}