2 * Network Configuration Module
4 * Copyright (c) 2012-2013 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.
28 #include "netsupplicant.h"
29 #include "network-state.h"
31 #include <vconf-keys.h>
32 #include <arpa/inet.h>
36 #include "wifi-tdls.h"
39 char *peer_mac = NULL;
41 static gint tdls_timer_id = 0;
42 int is_discover_broadcast = 0;
43 int is_timer_expired = 0;
45 #define TDLS_DISCOVER_TIMOUT 4 /*TDLS Unicast Discovery Timeout*/
46 #define TDLS_DISCOVER_BROADCAST_TIMOUT 8 /*TDLS Broadcast Discovery Timeout*/
47 static void stop_tdls_timer()
49 if (tdls_timer_id > 0) {
50 g_source_remove(tdls_timer_id);
55 void __netconfig_wifi_notify_tdls_event(const char *interface_name,
56 const char *sig_name, const char *peer_mac)
58 GVariantBuilder *builder;
61 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
62 g_variant_builder_add(builder, "{sv}", "peermac", g_variant_new_string(peer_mac));
63 params = g_variant_new("(s@a{sv})", interface_name, g_variant_builder_end(builder));
64 g_variant_builder_unref(builder);
66 netconfig_dbus_emit_signal(NULL,
68 NETCONFIG_WIFI_INTERFACE,
72 INFO("Sent signal (%s) Peer Mac (%s)", sig_name, peer_mac);
75 void __netconfig_wifi_notify_tdls_discover_event(const char *interface_name,
76 const char *peer_mac, int discover_type)
78 GVariantBuilder *builder;
81 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
83 g_variant_builder_add(builder, "{sv}", "peermac", g_variant_new_string(peer_mac));
84 g_variant_builder_add(builder, "{sv}", "discover_type", g_variant_new_int32(discover_type));
85 params = g_variant_new("(s@a{sv})", interface_name, g_variant_builder_end(builder));
86 g_variant_builder_unref(builder);
88 netconfig_dbus_emit_signal(NULL,
90 NETCONFIG_WIFI_INTERFACE,
94 INFO("Sent signal (%s) Peer Mac (%s)", "TDLSPeerFound", peer_mac);
97 static gboolean _tdls_timer_discover_event(gpointer user_data)
99 char *interface_name = user_data;
101 if (tdls_timer_id == 0) {
102 g_free(interface_name);
106 INFO("[TDLS Discover Timer Expired");
107 __netconfig_wifi_notify_tdls_discover_event(interface_name,
108 "00:00:00:00:00:00", is_discover_broadcast);
109 is_discover_broadcast = 0;
111 is_timer_expired = 1;
113 g_free(interface_name);
117 static GVariant * __netconfig_wifi_tdls_send_dbus_str(const char *interface_name,
118 const char *method, const char *str)
120 GVariant *message = NULL;
121 char *if_path = NULL;
122 GVariant *params = NULL;
124 if_path = netconfig_wifi_get_supplicant_interface_path(interface_name);
125 if (if_path == NULL) {
126 ERR("Fail to get wpa_supplicant DBus path");
130 params = g_variant_new("(s)", str);
131 INFO("[TizenMW-->WPAS]Sent Dbus Method :[%s],value[%s]", method, str);
132 message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
133 if_path, SUPPLICANT_INTERFACE ".Interface", method, params);
136 INFO("TDLS Returned from Blocking method for Send DBUS Command");
140 gboolean handle_tdls_connect(Wifi *wifi, GDBusMethodInvocation *context,
141 const gchar *ifname, gchar *peer_mac_Addr)
143 DBG("[TizenMW-->WPAS]: TDLS Setup Request: [%s]", peer_mac_Addr);
146 ERR(" Already TDLS Connection !!!");
148 GVariant *message = NULL;
149 message = __netconfig_wifi_tdls_send_dbus_str(ifname, "TDLSSetup", (const char*)peer_mac_Addr);
151 if (message == NULL) {
152 ERR(" TDLS : failed to connect !!!");
153 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsConnect");
157 DBG("[TizenMW<--WPAS] TDLS DBUS Command sent successfully");
158 g_variant_unref(message);
162 wifi_complete_tdls_connect(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
166 gboolean handle_tdls_discover(Wifi *wifi, GDBusMethodInvocation *context,
167 const gchar *ifname, gchar *peer_mac_Addr)
169 DBG("TDLS Discover Request: [%s]", peer_mac_Addr);
170 int discover_timeout = 0;
172 GVariant *message = NULL;
174 if (tdls_timer_id > 0) {
175 DBG(" TDLS Discover is already progress !!!");
176 wifi_complete_tdls_discover(wifi, context, NETCONFIG_ERROR_TDLS_ALREADY_DONE);
180 message = __netconfig_wifi_tdls_send_dbus_str(ifname, "TDLSDiscover", (const char*)peer_mac_Addr);
182 if (message == NULL) {
183 ERR(" TDLS : failed to discover !!!");
184 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsDiscover");
188 DBG(" TDLS DBUS Command sent successfully");
189 g_variant_unref(message);
191 if (NULL != strstr(peer_mac_Addr, "ff:ff:ff:ff:ff:ff")) {
192 DBG("TDLS: Broadcast Discovery");
193 is_discover_broadcast = 1;
194 discover_timeout = TDLS_DISCOVER_BROADCAST_TIMOUT;
196 is_discover_broadcast = 0;
197 discover_timeout = TDLS_DISCOVER_TIMOUT;
200 is_timer_expired = 0;
201 tdls_timer_id = g_timeout_add_seconds(discover_timeout,
202 _tdls_timer_discover_event, g_strdup(ifname));
204 wifi_complete_tdls_discover(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
208 gboolean handle_tdls_disconnect(Wifi *wifi, GDBusMethodInvocation *context,
209 const gchar *ifname, gchar *peer_mac_Addr)
211 DBG("[TizenMW-->WPAS]: TDLS Teardown Request: [%s]", peer_mac_Addr);
214 ERR(" Already TDLS disconnection !!!");
215 wifi_complete_tdls_disconnect(wifi, context, NETCONFIG_ERROR_TDLS_ALREADY_DONE);
217 GVariant *message = NULL;
218 message = __netconfig_wifi_tdls_send_dbus_str(ifname, "TDLSTeardown", (const char*)peer_mac_Addr);
220 if (message == NULL) {
221 ERR(" TDLS : failed to disconnect !!!");
222 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsDisconnect");
226 DBG("[TizenMW<--WPAS] TDLS DBUS Command sent successfully");
227 g_variant_unref(message);
231 wifi_complete_tdls_disconnect(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
235 gboolean handle_tdls_connected_peer(Wifi *wifi, GDBusMethodInvocation *context,
238 DBG("[TizenMW-->WPAS]: TDLS Connected Peer Request: ");
240 GVariant *message = NULL;
241 const gchar* reply_str = NULL;
243 if (peer_mac == NULL) {
244 INFO("TDLS: No Active Connection");
245 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
248 message = __netconfig_wifi_tdls_send_dbus_str(ifname, "TDLSStatus", (const char*)peer_mac);
249 if (message == NULL) {
250 ERR(" TDLS : No active TDLS Link Setup !!!");
251 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
255 g_variant_get(message, "(&s)", &reply_str);
256 INFO("TDLS reply: [%s]", reply_str);
257 INFO("TDLS :peer_mac [%s]", peer_mac);
259 if (g_strcmp0("connected", reply_str) != 0) {
260 ERR("[TizenMW<--WPAS] TDLS Connection not available");
261 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
262 g_variant_unref(message);
266 INFO("TDLS Connection available, Peer Mac address %s", peer_mac);
267 wifi_complete_tdls_connected_peer(wifi, context, peer_mac);
269 g_variant_unref(message);
273 gboolean handle_tdls_channel_switch(Wifi *wifi, GDBusMethodInvocation *context,
274 const gchar *ifname, gchar *peer_mac_Addr, int freq)
276 GVariant *message = NULL;
277 GVariantBuilder *builder;
279 char *if_path = NULL;
280 unsigned char oper_class = 0;
282 if (peer_mac_Addr == NULL) {
283 ERR("TDLS: Invalid Parameter");
284 wifi_complete_tdls_channel_switch(wifi, context,
285 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
289 oper_class = (unsigned char)netconfig_get_operating_class(freq);
292 ERR("TDLS: Invalid Parameter");
293 wifi_complete_tdls_channel_switch(wifi, context,
294 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
298 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
300 g_variant_builder_add(builder, "{sv}", "PeerAddress", g_variant_new_string(peer_mac_Addr));
301 g_variant_builder_add(builder, "{sv}", "Frequency", g_variant_new_uint32(freq));
302 g_variant_builder_add(builder, "{sv}", "OperClass", g_variant_new_byte(oper_class));
303 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
304 g_variant_builder_unref(builder);
306 if_path = netconfig_wifi_get_supplicant_interface_path(ifname);
308 if (if_path == NULL) {
309 ERR("Fail to get wpa_supplicant DBus path");
310 wifi_complete_tdls_channel_switch(wifi, context,
311 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
315 message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
316 if_path, SUPPLICANT_INTERFACE ".Interface",
317 "TDLSChannelSwitch", params);
320 if (message == NULL) {
321 ERR(" TDLS : Fail to Process TDLS Channel Switch Request !!!");
322 wifi_complete_tdls_channel_switch(wifi, context,
323 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
327 INFO("TDLS Channel Change Request: Success");
328 wifi_complete_tdls_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
330 g_variant_unref(message);
335 gboolean handle_tdls_cancel_channel_switch(Wifi *wifi, GDBusMethodInvocation *context,
336 const gchar *ifname, gchar *peer_mac_Addr)
338 GVariant *message = NULL;
340 if (peer_mac_Addr == NULL) {
341 INFO("TDLS: Invalid Parameter");
342 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
345 message = __netconfig_wifi_tdls_send_dbus_str(ifname,
346 "TDLSCancelChannelSwitch", (const char*)peer_mac_Addr);
347 if (message == NULL) {
348 ERR(" TDLS : Fail to TDLS Cancel Channel Swicth Request !!!");
349 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
353 INFO("TDLS Cancel Channel Swicth Request : Success");
354 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
356 g_variant_unref(message);
360 void netconfig_wifi_tdls_connected_event(const char *interface_name, GVariant *message)
363 DBG("WiFi TDLS Connected EVENT");
364 if (is_connected == 1) {
365 INFO("TDLS Peer already connected");
369 g_variant_get(message, "(s)", &peer_mac);
370 INFO("Peer Mac Address: [%s]", peer_mac);
373 __netconfig_wifi_notify_tdls_event(interface_name, "TDLSConnect", peer_mac);
376 void netconfig_wifi_tdls_disconnected_event(const char *interface_name, GVariant *message)
378 DBG("WiFi TDLS Disconnected EVENT");
379 const gchar *peer_mac_addr = NULL;
381 g_variant_get(message, "(&s)", &peer_mac_addr);
382 if (g_strcmp0(peer_mac, peer_mac_addr) == 0) {
383 INFO("TDLS Peer Disconnected Mac Address: [%s]", peer_mac);
385 __netconfig_wifi_notify_tdls_event(interface_name, "TDLSDisconnect", peer_mac);
387 INFO("TDLS Peer Disconnected peer_mac(%s) != peer_mac_address(%s)", peer_mac, peer_mac_addr);
391 void netconfig_wifi_tdls_peer_found_event(const char *interface_name, GVariant *message)
393 DBG("WiFi TDLS Discovery EVENT Received !!");
394 const gchar *peer_mac_addr = NULL;
396 if (!is_timer_expired) {
398 g_variant_get(message, "(s)", &peer_mac_addr);
399 INFO("Discover Peer Mac Address: [%s]", peer_mac_addr);
401 if (is_discover_broadcast == 0)
404 __netconfig_wifi_notify_tdls_discover_event(interface_name, peer_mac_addr, is_discover_broadcast);
406 DBG("Timer expired: Do not process the TDLS Discovery Event");