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 session functions.
23 * @file wifi-direct-session.c
24 * @author Gibyoung Kim (lastkgb.kim@samsung.com)
34 #include <wifi-direct.h>
36 #include "wifi-direct-ipc.h"
37 #include "wifi-direct-manager.h"
38 #include "wifi-direct-oem.h"
39 #include "wifi-direct-peer.h"
40 #include "wifi-direct-group.h"
41 #include "wifi-direct-oem.h"
42 #include "wifi-direct-util.h"
43 #include "wifi-direct-session.h"
44 #include "wifi-direct-state.h"
45 #include "wifi-direct-error.h"
46 #include "wifi-direct-log.h"
47 #include "wifi-direct-dbus.h"
48 #include "wifi-direct-asp.h"
51 static gboolean _session_timeout_cb(gpointer *user_data)
53 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
54 wfd_manager_s *manager = wfd_get_manager();
55 wfd_session_s *session = (wfd_session_s*) manager->session;
56 unsigned char *peer_addr = NULL;
57 char peer_mac_address[MACSTR_LEN+1] = {0, };
60 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
63 session->connecting_120 = 0;
65 WDS_LOGD("Session timer expired");//LCOV_EXCL_LINE
67 peer_addr = wfd_session_get_peer_addr(session);
68 if (peer_addr != NULL)
69 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
71 g_snprintf(peer_mac_address, MACSTR_LEN, "%s", "");
73 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
75 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_TIME_OUT,
76 WFD_EVENT_CONNECTION_RSP,
79 if (wfd_asp_is_asp_session(session)) {
80 if (session->state < SESSION_STATE_GO_NEG)
81 wfd_asp_connect_status(session->session_mac,
83 ASP_CONNECT_STATUS_REQUEST_FAILED,
86 wfd_asp_connect_status(session->session_mac,
88 ASP_CONNECT_STATUS_GROUP_FORMATION_FAILED,
92 wfd_session_cancel(session, peer_addr);
94 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
96 wfd_group_s *group = (wfd_group_s*) manager->group;
97 if (group && wfd_util_is_remove_group_allowed()) {
98 wfd_oem_destroy_group(manager->oem_ops, group->ifname);
100 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
101 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
104 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
105 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
108 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
113 static void _wfd_notify_session_failed(wfd_manager_s *manager, unsigned char *peer_addr)
115 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
116 char peer_mac_address[MACSTR_LEN+1] = {0, };
118 snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(peer_addr));
119 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
121 g_variant_new("(iis)", WIFI_DIRECT_ERROR_CONNECTION_FAILED,
122 WFD_EVENT_CONNECTION_RSP,
127 wfd_session_s *session = manager->session;
128 if (wfd_asp_is_asp_session(session)) {
129 wfd_asp_connect_status(session->session_mac,
131 ASP_CONNECT_STATUS_GROUP_FORMATION_STARTED,
135 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
136 wfd_state_set(manager, WIFI_DIRECT_STATE_GROUP_OWNER);
137 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_GROUP_OWNER);
139 wfd_state_set(manager, WIFI_DIRECT_STATE_ACTIVATED);
140 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_ACTIVATED);
143 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
146 int wfd_session_timer(wfd_session_s *session, int start)
148 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
151 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
152 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
157 if (!session->connecting_120)
158 session->connecting_120 = 1;
160 if (session->timer > 0) {
161 WDS_LOGE("Session timer already started");//LCOV_EXCL_LINE
162 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
165 session->timer = g_timeout_add_seconds(session->timeout,
166 (GSourceFunc) _session_timeout_cb,
168 WDS_LOGD("Session timer started");//LCOV_EXCL_LINE
170 session->connecting_120 = 0;
171 if (session->timer > 0) {
172 g_source_remove(session->timer);
174 WDS_LOGD("Session timer stoped");//LCOV_EXCL_LINE
178 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
182 /* Check the session instance which has same peer address,
183 * before using this function */
184 wfd_session_s *wfd_create_session(void *data, unsigned char *peer_addr, int wps_mode, int direction)
186 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
187 wfd_manager_s *manager = (wfd_manager_s*) data;
188 wfd_session_s *session = NULL;
189 wfd_device_s *peer = NULL;
191 if (!data || !peer_addr) {
192 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
193 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
197 WDS_LOGD("create session for peer[" MACSTR "]", MAC2STR(peer_addr));
199 if (manager->session) {
200 WDS_LOGE("Session already exist");//LCOV_EXCL_LINE
204 session = (wfd_session_s*) g_try_malloc0(sizeof(wfd_session_s));
206 WDS_LOGE("Failed to allocate memory for session");//LCOV_EXCL_LINE
207 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
211 peer = wfd_peer_find_by_dev_addr(manager, peer_addr);
213 WDS_LOGE("Failed to find peer info[" MACSECSTR "]", MAC2SECSTR(peer_addr));
215 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
218 peer->state = WFD_PEER_STATE_CONNECTING;
220 session->peer = peer;
221 session->req_wps_mode = wps_mode;
222 if (wps_mode == WFD_WPS_MODE_DISPLAY)
223 session->wps_mode = WFD_WPS_MODE_KEYPAD;
224 else if (wps_mode == WFD_WPS_MODE_KEYPAD)
225 session->wps_mode = WFD_WPS_MODE_DISPLAY;
226 else if (wps_mode == WFD_WPS_MODE_P2PS)
227 session->wps_mode = WFD_WPS_MODE_P2PS;
229 session->wps_mode = wps_mode;
230 session->direction = direction;
231 session->state = SESSION_STATE_CREATED;
233 manager->session = session;
234 manager->local->wps_mode = session->wps_mode;
236 if (peer->dev_role == WFD_DEV_ROLE_GO &&
237 manager->local->wps_mode == WFD_WPS_MODE_DISPLAY) {
238 char *generated_pin = NULL;
239 session->wps_mode = WFD_WPS_MODE_DISPLAY;
240 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
242 if (wfd_oem_generate_pin(manager->oem_ops, &generated_pin) != 0) {
243 WDS_LOGE("Failed to generate pin");//LCOV_EXCL_LINE
245 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
249 #if defined(BUILD_GTESTS)
250 generated_pin = g_strndup("12345678", PINSTR_LEN + 1);
251 #endif /* BUILD_GTESTS */
252 g_strlcpy(session->wps_pin, generated_pin, PINSTR_LEN + 1);
253 g_free(generated_pin);
256 if (peer->dev_role == WFD_DEV_ROLE_GO && manager->local->dev_role != WFD_DEV_ROLE_GO)
257 manager->local->dev_role = WFD_DEV_ROLE_GC;
259 session->timeout = manager->connection_timeout;
260 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
264 int wfd_destroy_session(void *data)
266 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
267 wfd_manager_s *manager = (wfd_manager_s*) data;
268 wfd_session_s *session = NULL;
269 wfd_device_s *peer = NULL;
272 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
276 session = (wfd_session_s*) manager->session;
278 WDS_LOGE("Session not found");//LCOV_EXCL_LINE /* self prevent */
281 wfd_session_timer(session, 0);
282 peer = session->peer;
283 WDS_LOGD("peer :%p", peer);
286 if (session->state == SESSION_STATE_COMPLETED)
287 peer->state = WFD_PEER_STATE_CONNECTED;
289 peer->state = WFD_PEER_STATE_DISCOVERED;
291 WDS_LOGE("Peer not found");//LCOV_EXCL_LINE
295 manager->session = NULL;
296 manager->local->wps_mode = WFD_WPS_MODE_PBC;
297 manager->autoconnection = 0;
298 memset(manager->auto_pin, 0x0, PINSTR_LEN);
300 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
304 int wfd_session_start(wfd_session_s *session)
306 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
307 wfd_manager_s *manager = wfd_get_manager();
308 wfd_device_s *peer = NULL;
313 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
314 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
318 if (session->state > SESSION_STATE_STARTED) {
319 WDS_LOGE("Invalid session state(%d)", session->state);
323 /* Check: Invitation Received in Incomming case ->
324 * send prov_disc join
326 * Check: User select peer to connect with in Outgoing case ->
327 * send prov_disc wps_mode */
329 wfd_oem_stop_scan(manager->oem_ops);
331 session->state = SESSION_STATE_STARTED;
332 peer = session->peer;
333 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
335 res = wfd_oem_prov_disc_req(manager->oem_ops, peer->dev_addr,
336 session->req_wps_mode, join);
338 WDS_LOGD("Failed to send provision discovery request to peer [" MACSECSTR "]",
339 MAC2SECSTR(peer->dev_addr));
340 wfd_destroy_session(manager);
341 /* TODO: send notification to App */
342 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
346 wfd_session_timer(session, 1);
348 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
352 int wfd_session_asp_session_start(wfd_session_s *session, wfd_oem_asp_prov_s *params)
354 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
356 wfd_manager_s *manager = wfd_get_manager();
359 if (session == NULL || params == NULL) {
360 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
361 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
365 if (session->state > SESSION_STATE_STARTED) {
366 WDS_LOGE("Invalid session state(%d)", session->state);
367 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
371 res = wfd_oem_asp_prov_disc_req(manager->oem_ops, params);
373 WDS_LOGD("Failed to send ASP provision discovery request to peer");//LCOV_EXCL_LINE
374 wfd_destroy_session(manager);
375 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
379 session->state = SESSION_STATE_STARTED;
380 session->session_id = params->session_id;
381 memcpy(session->session_mac, params->session_mac, MACADDR_LEN);
382 memcpy(session->service_mac, params->service_mac, MACADDR_LEN);
383 wfd_session_timer(session, 1);
385 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
390 int wfd_session_stop(wfd_session_s *session)
392 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
393 wfd_manager_s *manager = wfd_get_manager();
394 wfd_device_s *peer = NULL;
398 WDS_LOGE("Invalid parameter");
399 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
403 if (session->state > SESSION_STATE_CREATED) {
404 peer = session->peer;
405 if (session->direction == SESSION_DIRECTION_INCOMING)
406 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
407 else if (session->direction == SESSION_DIRECTION_OUTGOING)
408 res = wfd_oem_cancel_connection(manager->oem_ops, peer->dev_addr);
411 WDS_LOGE("Failed to reject or cancel connection");
412 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
417 session->state = SESSION_STATE_STOPPED;
418 wfd_destroy_session(manager);
420 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
425 /* In case of incomming session, when user accept connection request, this function should be called.
426 * In case of outgoing session, when prov_disc response arrived, this function should be called.
427 * Even though peer is GO, we can use this function, which can decide using join itself.
429 int wfd_session_connect(wfd_session_s *session)
431 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
432 wfd_manager_s *manager = wfd_get_manager();
433 wfd_oem_conn_param_s param;
434 wfd_device_s *peer = NULL;
438 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
439 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
443 if (session->state > SESSION_STATE_GO_NEG) {
444 WDS_LOGE("Session already finished GO Negotiation");//LCOV_EXCL_LINE
448 session->state = SESSION_STATE_GO_NEG;
449 peer = session->peer;
451 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
452 param.wps_mode = session->wps_mode;
453 if (peer->dev_role == WFD_DEV_ROLE_GO || session->type == SESSION_TYPE_INVITE)
454 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
455 param.go_intent = session->go_intent;
456 if (peer->display.availability)
457 param.go_intent = manager->go_intent_per_type[manager->local->display.type];
458 param.freq = session->freq;
459 if (manager->local->group_flags & WFD_GROUP_FLAG_PERSISTENT)
460 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
462 if (session->wps_pin[0] != '\0')
463 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
465 /* To connect with windows phone,set go_intent value to 2.
466 * As windows phone does not connect when local device act as GO.
467 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_COMPUTER ==>1 (Assume Peer Device is Windows PC)
468 * WIFI_DIRECT_SECONDARY_DEVICE_TYPE_TELEPHONE_WINDOWS_MOBILE ==>1
469 * WIFI_DIRECT_PRIMARY_DEVICE_TYPE_TELEPHONE ==> 10
471 if ((peer->pri_dev_type == 1) ||
472 ((peer->pri_dev_type == 10) && (peer->sec_dev_type == 1))) {
474 WDS_LOGD("go_intent set to %d, Windows device", param.go_intent);
477 WDS_LOGD("connection go_intent: %d", param.go_intent);
478 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
480 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
481 wfd_destroy_session(manager);
482 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
486 wfd_session_timer(session, 1);
488 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
492 int wfd_session_cancel(wfd_session_s *session, unsigned char *peer_addr)
494 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
495 wfd_manager_s *manager = wfd_get_manager();
498 if (!session || !session->peer) {
499 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
500 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
501 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
504 if (memcmp(peer_addr, session->peer->dev_addr, MACADDR_LEN)) {
505 WDS_LOGE("Peer is not included in this session");//LCOV_EXCL_LINE
506 return WIFI_DIRECT_ERROR_NOT_PERMITTED;
509 if (manager->local->dev_role == WFD_DEV_ROLE_GO && session->state > SESSION_STATE_GO_NEG)
510 res = wfd_oem_wps_cancel(manager->oem_ops);
512 res = wfd_oem_cancel_connection(manager->oem_ops, peer_addr);
515 WDS_LOGE("Failed to cancel connection");//LCOV_EXCL_LINE
516 return WIFI_DIRECT_ERROR_OPERATION_FAILED;
519 wfd_destroy_session(manager);
521 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
525 int wfd_session_reject(wfd_session_s *session, unsigned char *peer_addr)
527 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
528 wfd_manager_s *manager = wfd_get_manager();
529 wfd_device_s *peer = NULL;
532 if (!session || !manager) {
533 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
534 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
538 /* Invite received case state is just created */
539 if (session->state < SESSION_STATE_CREATED ||
540 session->state >= SESSION_STATE_STOPPED) {
541 WDS_LOGE("Session state is Invalid [%d]", session->state);
542 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
547 * TODO: check session status and do proper work
548 * for example, reject prov_disc, reject nego, stop wps, etc.
552 peer = session->peer;
554 if (SESSION_TYPE_INVITE == session->type || SESSION_TYPE_JOIN == session->type)
555 res = wfd_oem_wps_cancel(manager->oem_ops);
557 res = wfd_oem_reject_connection(manager->oem_ops, peer->dev_addr);
559 WDS_LOGE("Failed to reject connection");//LCOV_EXCL_LINE
560 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
564 wfd_destroy_session(manager);
565 /* TODO: send notification to App */
567 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
571 int wfd_session_join(wfd_session_s *session)
573 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
574 wfd_manager_s *manager = wfd_get_manager();
575 wfd_oem_conn_param_s param;
576 wfd_device_s *peer = NULL;
580 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
581 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
585 session->state = SESSION_STATE_WPS;
586 peer = session->peer;
588 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
589 param.wps_mode = session->wps_mode;
590 if (peer->dev_role == WFD_DEV_ROLE_GO)
591 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
592 param.go_intent = session->go_intent;
593 param.freq = session->freq;
594 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
596 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
598 WDS_LOGD("Failed to join with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
599 wfd_destroy_session(manager);
600 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
604 wfd_session_timer(session, 1);
606 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
610 int wfd_session_invite(wfd_session_s *session)
612 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
613 wfd_manager_s *manager = wfd_get_manager();
614 wfd_oem_invite_param_s param;
615 wfd_device_s *peer = NULL;
616 wfd_group_s *group = NULL;
620 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
621 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
625 if (session->state > SESSION_STATE_CREATED) {
626 WDS_LOGE("Invalid session state(%d)", session->state);
630 peer = session->peer;
631 group = (wfd_group_s*) manager->group;
633 memset(¶m, 0x00, sizeof(wfd_oem_invite_param_s));
634 param.ifname = g_strdup(group->ifname);
635 memcpy(param.go_dev_addr, group->go_dev_addr, MACADDR_LEN);
637 WDS_LOGD("Invite: Peer[" MACSTR "], GO Addr[" MACSTR "]",
638 MAC2STR(peer->dev_addr), MAC2STR(param.go_dev_addr));
640 res = wfd_oem_invite(manager->oem_ops, peer->dev_addr, ¶m);
642 WDS_LOGE("Failed to invite with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
643 wfd_destroy_session(manager);
644 g_free(param.ifname);
645 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
649 wfd_session_timer(session, 1);
650 g_free(param.ifname);
652 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
656 int wfd_session_wps(wfd_session_s *session)
658 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
659 wfd_manager_s *manager = wfd_get_manager();
660 wfd_device_s *peer = NULL;
664 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
665 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
669 if (session->state > SESSION_STATE_WPS) {
670 WDS_LOGE("Session already starts WPS");//LCOV_EXCL_LINE
674 session->state = SESSION_STATE_WPS;
675 peer = session->peer;
677 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
678 WDS_LOGD("My device is GO, so WPS will be started. WPS mode[%d]", session->wps_mode);
679 res = wfd_oem_wps_start(manager->oem_ops, peer->dev_addr, session->wps_mode, session->wps_pin);
681 WDS_LOGD("My device is not GO, so Enrollee will be started. WPS mode[%d]", session->wps_mode);
682 wfd_oem_conn_param_s param;
683 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
684 param.wps_mode = session->wps_mode;
685 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
686 param.freq = session->freq; /* currently not used */
687 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
688 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
691 WDS_LOGE("Failed to start wps with peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
692 wfd_destroy_session(manager);
693 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
697 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
701 /* In case of incomming session, when user accept connection request, this function should be called.
702 * In case of outgoing session, when prov_disc response arrived, this function should be called.
703 * Even though peer is GO, we can use this function, which can decide using join itself.
705 int wfd_session_asp_connect(wfd_session_s *session, int role)
707 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
708 wfd_manager_s *manager = wfd_get_manager();
709 wfd_oem_conn_param_s param;
710 wfd_device_s *peer = NULL;
714 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
715 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
719 if (session->state >= SESSION_STATE_GO_NEG) {
720 WDS_LOGE("Session already starting GO Negotiation");//LCOV_EXCL_LINE
721 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
725 if (role == WFD_OEM_ASP_SESSION_ROLE_GO) {
726 session->state = SESSION_STATE_WPS;
729 session->state = SESSION_STATE_GO_NEG;
732 peer = session->peer;
734 memset(¶m, 0x00, sizeof(wfd_oem_conn_param_s));
735 param.wps_mode = session->wps_mode;
737 param.conn_flags |= WFD_OEM_CONN_TYPE_JOIN;
738 param.go_intent = session->go_intent;
739 param.freq = session->freq;
740 param.conn_flags |= WFD_OEM_CONN_TYPE_PERSISTENT;
742 if (session->wps_pin[0] != '\0')
743 g_strlcpy(param.wps_pin, session->wps_pin, OEM_PINSTR_LEN + 1);
745 res = wfd_oem_connect(manager->oem_ops, peer->dev_addr, ¶m);
747 WDS_LOGD("Failed to connect peer [" MACSECSTR "]", MAC2SECSTR(peer->dev_addr));
748 wfd_destroy_session(manager);
749 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
753 wfd_session_timer(session, 1);
755 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
759 /* In case of incomming session, when user accept connection request, this function should be called.
760 * In case of outgoing session, when prov_disc response arrived, this function should be called.
761 * Even though peer is GO, we can use this function, which can decide using join itself.
763 int wfd_session_asp_persistent_connect(wfd_session_s *session, int persist_group_id)
765 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
766 wfd_manager_s *manager = wfd_get_manager();
767 wfd_oem_group_param_s param;
771 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
772 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
776 if (session->state > SESSION_STATE_GO_NEG) {
777 WDS_LOGE("Session already finished GO Negotiation");//LCOV_EXCL_LINE
778 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
782 session->state = SESSION_STATE_WPS;
784 memset(¶m, 0x0, sizeof(param));
785 param.persistent = 2;
786 param.persistent_group_id = persist_group_id;
788 res = wfd_oem_create_group(manager->oem_ops, ¶m);
790 WDS_LOGD("Failed to create persistent group for ASP");//LCOV_EXCL_LINE
791 wfd_destroy_session(manager);
792 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
796 wfd_session_timer(session, 1);
798 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
802 wfd_device_s *wfd_session_get_peer(wfd_session_s *session)
804 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
805 wfd_device_s *peer = NULL;
808 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
812 peer = session->peer;
814 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
818 unsigned char *wfd_session_get_peer_addr(wfd_session_s *session)
820 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
821 wfd_device_s *peer = NULL;
823 if (!session || !session->peer) {
824 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
828 peer = session->peer;
830 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
831 return peer->dev_addr;
835 int wfd_session_get_wps_pin(wfd_session_s *session, unsigned char *pin)
837 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
839 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
843 int wfd_session_set_wps_pin(wfd_session_s *session, unsigned char *pin)
845 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
847 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
851 int wfd_session_set_freq(wfd_session_s *session, int freq)
853 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
855 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
859 int wfd_session_get_state(wfd_session_s *session)
861 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
863 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
867 int wfd_session_set_state(wfd_session_s *session, int state)
869 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
871 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
876 int wfd_session_process_event(wfd_manager_s *manager, wfd_oem_event_s *event)
878 __WDS_LOG_FUNC_ENTER__;//LCOV_EXCL_LINE
879 wfd_session_s *session = NULL;
882 if (!manager || !event) {
883 WDS_LOGE("Invalid parameter");//LCOV_EXCL_LINE
887 WDS_LOGD("event ID [%d]", event->event_id);
888 session = manager->session;
890 switch (event->event_id) {
891 case WFD_OEM_EVENT_PROV_DISC_REQ:
893 int req_wps_mode = WFD_WPS_MODE_NONE;
895 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
896 req_wps_mode = WFD_WPS_MODE_KEYPAD;
897 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
898 req_wps_mode = WFD_WPS_MODE_DISPLAY;
900 req_wps_mode = WFD_WPS_MODE_PBC;
902 /* Only peer initiated connection or invitation session can be allowed */
904 if (session->type != SESSION_TYPE_INVITE) {
905 WDS_LOGE("Unexpected event. Session is exist [peer: " MACSECSTR "]",
906 MAC2SECSTR(event->dev_addr));
909 WDS_LOGD("=====> session already exist. (invitation session)");//LCOV_EXCL_LINE
910 if (session->state > SESSION_STATE_WPS) {
911 WDS_LOGE("Session already starts WPS");//LCOV_EXCL_LINE
915 session->req_wps_mode = req_wps_mode;
916 session->wps_mode = event->wps_mode;
918 session = wfd_create_session(manager, event->dev_addr,
919 req_wps_mode, SESSION_DIRECTION_INCOMING);
921 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
922 MAC2SECSTR(event->dev_addr));
928 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
929 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
931 session->state = SESSION_STATE_STARTED;
932 if (session->type == SESSION_TYPE_INVITE)
933 WDS_LOGD("Invitation session");//LCOV_EXCL_LINE
934 else if (WFD_DEV_ROLE_GO == manager->local->dev_role)
935 session->type = SESSION_TYPE_JOIN;
937 session->type = SESSION_TYPE_NORMAL;
939 wfd_session_timer(session, 1);
941 /* Update local device */
942 manager->local->wps_mode = event->wps_mode;
944 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
945 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
947 if (session->type == SESSION_TYPE_INVITE) {
948 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
949 if (session->wps_mode != WFD_WPS_MODE_PBC) {
950 char peer_mac_address[MACSTR_LEN+1] = {0, };
952 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
953 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
955 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
956 WFD_EVENT_CONNECTION_WPS_REQ,
958 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
959 /* We have to wait until user type PIN using Keypad */
963 res = wfd_session_wps(session);
965 _wfd_notify_session_failed(manager, event->dev_addr);
967 char peer_mac_address[MACSTR_LEN+1] = {0, };
969 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
970 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
972 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
973 WFD_EVENT_CONNECTION_REQ,
978 case WFD_OEM_EVENT_PROV_DISC_RESP:
980 if (!session) { /* TODO: check validity of Event */
981 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
982 MAC2SECSTR(event->dev_addr));
986 if (session->state > SESSION_STATE_STARTED) {
987 WDS_LOGE("Unexpected event. Session is already started");//LCOV_EXCL_LINE
991 if (session->type == SESSION_TYPE_INVITE) {
992 WDS_LOGE("Session type is invite, ignore provision discovery response");//LCOV_EXCL_LINE
997 session->wps_mode = event->wps_mode;
998 if (event->wps_mode == WFD_WPS_MODE_DISPLAY) {
999 session->req_wps_mode = WFD_WPS_MODE_KEYPAD;
1000 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
1001 } else if (event->wps_mode == WFD_WPS_MODE_KEYPAD) {
1002 session->req_wps_mode = WFD_WPS_MODE_DISPLAY;
1004 session->req_wps_mode = WFD_WPS_MODE_PBC;
1007 session->state = SESSION_STATE_STARTED;
1008 wfd_session_timer(session, 1);
1010 /* Update local device */
1011 manager->local->wps_mode = event->wps_mode;
1012 WDS_LOGD("Local WPS mode is %d", session->wps_mode);
1014 if (session->wps_mode != WFD_WPS_MODE_PBC) {
1015 char peer_mac_address[MACSTR_LEN+1] = {0, };
1017 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1018 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1020 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1021 WFD_EVENT_CONNECTION_WPS_REQ,
1023 if (session->wps_mode == WFD_WPS_MODE_KEYPAD) {
1024 /* We have to wait until user type PIN using Keypad */
1029 if (manager->local->dev_role == WFD_DEV_ROLE_GO) {
1030 WDS_LOGD("Start WPS corresponding to OEM event [%d]", event->event_id);
1031 res = wfd_session_wps(session);
1032 } else if (session->peer->dev_role == WFD_DEV_ROLE_GO) {
1033 WDS_LOGD("Start WPS(join) corresponding to OEM event [%d]", event->event_id);
1034 res = wfd_session_join(session);
1036 WDS_LOGD("Start connection corresponding to OEM event [%d]", event->event_id);
1037 res = wfd_session_connect(session);
1041 _wfd_notify_session_failed(manager, event->dev_addr);
1044 case WFD_OEM_EVENT_GO_NEG_REQ:
1047 session = wfd_create_session(manager, event->dev_addr,
1048 event->wps_mode, SESSION_DIRECTION_INCOMING);
1050 WDS_LOGE("Failed to create session");//LCOV_EXCL_LINE
1051 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE
1055 session->type = SESSION_TYPE_NORMAL;
1056 session->state = SESSION_STATE_GO_NEG;
1057 wfd_session_timer(session, 1);
1058 wfd_state_set(manager, WIFI_DIRECT_STATE_CONNECTING);
1059 wfd_util_set_wifi_direct_state(WIFI_DIRECT_STATE_CONNECTING);
1061 if (manager->autoconnection == TRUE) {
1063 * TODO: Add autoconnection peer matching logic.
1066 * In autoconnection mode, connection request notification
1067 * should not be sent to library.
1069 res = wfd_session_connect(session);
1071 char peer_mac_address[MACSTR_LEN+1] = {0, };
1072 g_snprintf(peer_mac_address, MACSTR_LEN, MACSTR, MAC2STR(event->dev_addr));
1073 wfd_manager_dbus_emit_signal(WFD_MANAGER_MANAGE_INTERFACE,
1075 g_variant_new("(iis)", WIFI_DIRECT_ERROR_NONE,
1076 WFD_EVENT_CONNECTION_REQ,
1080 /* Sometimes, Provision Discovery response is not received.
1081 * At this time, connection should be triggered by GO Negotiation request event */
1082 if (session->direction == SESSION_DIRECTION_OUTGOING) {
1083 if (session->wps_mode == WFD_WPS_MODE_KEYPAD && session->wps_pin[0] == '\0')
1085 res = wfd_session_connect(session);
1088 * TODO: Add autoconnection peer matching logic.
1091 * In autoconnection mode, MT should not send GO Nego Req
1092 * before receiving the GO Nego Req from peer (MO).
1094 if (manager->autoconnection == TRUE)
1095 res = wfd_session_connect(session);
1098 _wfd_notify_session_failed(manager, event->dev_addr);
1102 case WFD_OEM_EVENT_GO_NEG_DONE:
1105 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1106 MAC2SECSTR(event->dev_addr));
1109 manager->local->dev_role = event->dev_role;
1110 session->state = SESSION_STATE_WPS;
1114 case WFD_OEM_EVENT_WPS_DONE:
1117 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1118 MAC2SECSTR(event->dev_addr));
1121 session->state = SESSION_STATE_KEY_NEG;
1125 case WFD_OEM_EVENT_STA_CONNECTED:
1128 WDS_LOGE("Unexpected event. Session is NULL [peer: " MACSECSTR "]",
1129 MAC2SECSTR(event->dev_addr));
1132 session->state = SESSION_STATE_COMPLETED;
1136 case WFD_OEM_EVENT_ASP_PROV_START:
1138 int req_wps_mode = WFD_WPS_MODE_NONE;
1140 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1141 req_wps_mode = WFD_WPS_MODE_KEYPAD;
1142 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
1143 req_wps_mode = WFD_WPS_MODE_DISPLAY;
1145 req_wps_mode = WFD_WPS_MODE_P2PS;
1147 session = wfd_create_session(manager, event->dev_addr,
1148 req_wps_mode, SESSION_DIRECTION_INCOMING);
1150 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
1151 MAC2SECSTR(event->dev_addr));
1155 /* Update session */
1156 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1157 g_strlcpy(session->wps_pin, event->wps_pin, PINSTR_LEN + 1);
1159 session->state = SESSION_STATE_STARTED;
1160 wfd_session_timer(session, 1);
1163 case WFD_OEM_EVENT_ASP_PROV_DONE:
1165 int req_wps_mode = WFD_WPS_MODE_NONE;
1167 if (event->wps_mode == WFD_WPS_MODE_DISPLAY)
1168 req_wps_mode = WFD_WPS_MODE_KEYPAD;
1169 else if (event->wps_mode == WFD_WPS_MODE_KEYPAD)
1170 req_wps_mode = WFD_WPS_MODE_DISPLAY;
1172 req_wps_mode = WFD_WPS_MODE_P2PS;
1174 session = (wfd_session_s*) manager->session;
1176 session = wfd_create_session(manager, event->dev_addr,
1177 req_wps_mode, SESSION_DIRECTION_INCOMING);
1179 WDS_LOGE("Failed to create session with peer [" MACSECSTR "]",
1180 MAC2SECSTR(event->dev_addr));
1183 session->state = SESSION_STATE_STARTED;
1184 wfd_session_timer(session, 1);
1191 __WDS_LOG_FUNC_EXIT__;//LCOV_EXCL_LINE