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 *sig_name, const char *peer_mac)
57 GVariantBuilder *builder;
59 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
60 g_variant_builder_add(builder, "{sv}", "peermac", g_variant_new_string(peer_mac));
62 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
63 g_variant_builder_unref(builder);
65 netconfig_dbus_emit_signal(NULL,
67 NETCONFIG_WIFI_INTERFACE,
71 INFO("Sent signal (%s) Peer Mac (%s)", sig_name, peer_mac);
74 void __netconfig_wifi_notify_tdls_discover_event(const char *peer_mac, int discover_type)
76 GVariantBuilder *builder;
78 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
80 g_variant_builder_add(builder, "{sv}", "peermac", g_variant_new_string(peer_mac));
81 g_variant_builder_add(builder, "{sv}", "discover_type", g_variant_new_int32(discover_type));
83 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
84 g_variant_builder_unref(builder);
86 netconfig_dbus_emit_signal(NULL,
88 NETCONFIG_WIFI_INTERFACE,
92 INFO("Sent signal (%s) Peer Mac (%s)", "TDLSPeerFound", peer_mac);
95 static gboolean _tdls_timer_discover_event(gpointer user_data)
98 if (tdls_timer_id == 0)
101 INFO("[TDLS Discover Timer Expired");
102 __netconfig_wifi_notify_tdls_discover_event("00:00:00:00:00:00", is_discover_broadcast);
103 is_discover_broadcast = 0;
105 is_timer_expired = 1;
110 static GVariant * __netconfig_wifi_tdls_send_dbus_str(const char* method, const char *str)
112 GVariant *message = NULL;
113 char *if_path = NULL;
114 GVariant *params = NULL;
116 if_path = netconfig_wifi_get_supplicant_interface();
117 if (if_path == NULL) {
118 ERR("Fail to get wpa_supplicant DBus path");
122 params = g_variant_new("(s)", str);
123 INFO("[TizenMW-->WPAS]Sent Dbus Method :[%s],value[%s]", method, str);
124 message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
125 if_path, SUPPLICANT_INTERFACE ".Interface", method, params);
128 INFO("TDLS Returned from Blocking method for Send DBUS Command");
132 static unsigned char _netconfig_freq_to_channel(int freq)
134 if (freq < 2412 || freq > 5825 ||
135 (freq > 2484 && freq < 5180)) {
136 ERR("Invalid Frequence Range");
140 return 36 + (freq - 5180)/5;
141 else if (freq <= 2472)
142 return 1 + (freq - 2412)/5;
143 else if (freq == 2484)
149 static unsigned char _netconfig_get_operating_class(int freq)
151 unsigned char channel = 0;
152 unsigned char oper_class = 0;
154 channel = _netconfig_freq_to_channel(freq);
157 /* Operating class 81 - 2.4 GHz band channels 1..13 */
158 if (channel >= 1 && channel <= 13)
160 /* Operating class 115 - 5 GHz, channels 36-48 */
161 else if (channel >= 36 && channel <= 48)
163 /* Operating class 124 - 5 GHz, channels 149,153,157,161 */
167 INFO("TDLS: Operating Class is [%d]", oper_class);
173 gboolean handle_tdls_connect(Wifi *wifi, GDBusMethodInvocation *context,
174 gchar *peer_mac_Addr)
176 DBG("[TizenMW-->WPAS]: TDLS Setup Request: [%s]", peer_mac_Addr);
179 ERR(" Already TDLS Connection !!!");
181 GVariant *message = NULL;
182 message = __netconfig_wifi_tdls_send_dbus_str("TDLSSetup", (const char*)peer_mac_Addr);
184 if (message == NULL) {
185 ERR(" TDLS : failed to connect !!!");
186 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsConnect");
190 DBG("[TizenMW<--WPAS] TDLS DBUS Command sent successfully");
191 g_variant_unref(message);
195 wifi_complete_tdls_connect(wifi, context, 1);
199 gboolean handle_tdls_discover(Wifi *wifi, GDBusMethodInvocation *context,
200 gchar *peer_mac_Addr)
202 DBG("TDLS Discover Request: [%s]", peer_mac_Addr);
203 int discover_timeout = 0;
205 GVariant *message = NULL;
207 if (tdls_timer_id > 0) {
208 DBG(" TDLS Discover is already progress !!!");
209 wifi_complete_tdls_discover(wifi, context, NETCONFIG_ERROR_TDLS_ALREADY_DONE);
213 message = __netconfig_wifi_tdls_send_dbus_str("TDLSDiscover", (const char*)peer_mac_Addr);
215 if (message == NULL) {
216 ERR(" TDLS : failed to discover !!!");
217 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsDiscover");
218 wifi_complete_tdls_discover(wifi, context, NETCONFIG_ERROR_TDLS_FAIL_DISCOVER);
222 DBG(" TDLS DBUS Command sent successfully");
223 g_variant_unref(message);
225 if (NULL != strstr(peer_mac_Addr, "ff:ff:ff:ff:ff:ff")) {
226 DBG("TDLS: Broadcast Discovery");
227 is_discover_broadcast = 1;
228 discover_timeout = TDLS_DISCOVER_BROADCAST_TIMOUT;
230 is_discover_broadcast = 0;
231 discover_timeout = TDLS_DISCOVER_TIMOUT;
234 is_timer_expired = 0;
235 tdls_timer_id = g_timeout_add_seconds(discover_timeout,
236 _tdls_timer_discover_event, NULL);
238 wifi_complete_tdls_discover(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
242 gboolean handle_tdls_disconnect(Wifi *wifi, GDBusMethodInvocation *context,
243 gchar *peer_mac_Addr)
245 DBG("[TizenMW-->WPAS]: TDLS Teardown Request: [%s]", peer_mac_Addr);
248 ERR(" Already TDLS disconnection !!!");
249 wifi_complete_tdls_disconnect(wifi, context, NETCONFIG_ERROR_TDLS_ALREADY_DONE);
251 GVariant *message = NULL;
252 message = __netconfig_wifi_tdls_send_dbus_str("TDLSTeardown", (const char*)peer_mac_Addr);
254 if (message == NULL) {
255 ERR(" TDLS : failed to disconnect !!!");
256 netconfig_error_dbus_method_return(context, NETCONFIG_ERROR_INTERNAL, "FailTdlsDisconnect");
260 DBG("[TizenMW<--WPAS] TDLS DBUS Command sent successfully");
261 g_variant_unref(message);
265 wifi_complete_tdls_disconnect(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
269 gboolean handle_tdls_connected_peer(Wifi *wifi, GDBusMethodInvocation *context)
271 DBG("[TizenMW-->WPAS]: TDLS Connected Peer Request: ");
273 GVariant *message = NULL;
274 const gchar* reply_str = NULL;
276 if (peer_mac == NULL) {
277 INFO("TDLS: No Active Connection");
278 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
281 message = __netconfig_wifi_tdls_send_dbus_str("TDLSStatus", (const char*)peer_mac);
282 if (message == NULL) {
283 ERR(" TDLS : No active TDLS Link Setup !!!");
284 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
288 g_variant_get(message, "(&s)", &reply_str);
289 INFO("TDLS reply: [%s]", reply_str);
290 INFO("TDLS :peer_mac [%s]", peer_mac);
292 if (g_strcmp0("connected", reply_str) != 0) {
293 ERR("[TizenMW<--WPAS] TDLS Connection not available");
294 wifi_complete_tdls_connected_peer(wifi, context, "00.00.00.00.00.00");
295 g_variant_unref(message);
299 INFO("TDLS Connection available, Peer Mac address %s", peer_mac);
300 wifi_complete_tdls_connected_peer(wifi, context, peer_mac);
302 g_variant_unref(message);
306 gboolean handle_tdls_channel_switch(Wifi *wifi, GDBusMethodInvocation *context,
307 gchar *peer_mac_Addr, int freq)
309 GVariant *message = NULL;
310 GVariantBuilder *builder;
312 char *if_path = NULL;
313 unsigned char oper_class = 0;
315 if (peer_mac_Addr == NULL) {
316 ERR("TDLS: Invalid Parameter");
317 wifi_complete_tdls_channel_switch(wifi, context,
318 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
322 oper_class = _netconfig_get_operating_class(freq);
325 ERR("TDLS: Invalid Parameter");
326 wifi_complete_tdls_channel_switch(wifi, context,
327 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
331 builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
333 g_variant_builder_add(builder, "{sv}", "PeerAddress", g_variant_new_string(peer_mac_Addr));
334 g_variant_builder_add(builder, "{sv}", "Frequency", g_variant_new_uint32(freq));
335 g_variant_builder_add(builder, "{sv}", "OperClass", g_variant_new_byte(oper_class));
336 params = g_variant_new("(@a{sv})", g_variant_builder_end(builder));
337 g_variant_builder_unref(builder);
339 if_path = netconfig_wifi_get_supplicant_interface();
341 if (if_path == NULL) {
342 ERR("Fail to get wpa_supplicant DBus path");
343 wifi_complete_tdls_channel_switch(wifi, context,
344 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
348 message = netconfig_invoke_dbus_method(SUPPLICANT_SERVICE,
349 if_path, SUPPLICANT_INTERFACE ".Interface", "TDLSChannelSwitch", params);
352 if (message == NULL) {
353 ERR(" TDLS : Fail to Process TDLS Channel Switch Request !!!");
354 wifi_complete_tdls_channel_switch(wifi, context,
355 NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
359 INFO("TDLS Channel Change Request: Success");
360 wifi_complete_tdls_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
362 g_variant_unref(message);
367 gboolean handle_tdls_cancel_channel_switch(Wifi *wifi, GDBusMethodInvocation *context,
368 gchar *peer_mac_Addr)
370 GVariant *message = NULL;
372 if (peer_mac_Addr == NULL) {
373 INFO("TDLS: Invalid Parameter");
374 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
377 message = __netconfig_wifi_tdls_send_dbus_str("TDLSCancelChannelSwitch", (const char*)peer_mac_Addr);
378 if (message == NULL) {
379 ERR(" TDLS : Fail to TDLS Cancel Channel Swicth Request !!!");
380 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_FAIL_CHANNEL_SWITCH);
384 INFO("TDLS Cancel Channel Swicth Request : Success");
385 wifi_complete_tdls_cancel_channel_switch(wifi, context, NETCONFIG_ERROR_TDLS_NO_ERROR);
387 g_variant_unref(message);
391 void netconfig_wifi_tdls_connected_event(GVariant *message)
394 DBG("WiFi TDLS Connected EVENT");
395 if (is_connected == 1) {
396 INFO("TDLS Peer already connected");
400 g_variant_get(message, "(s)", &peer_mac);
401 INFO("Peer Mac Address: [%s]", peer_mac);
404 __netconfig_wifi_notify_tdls_event("TDLSConnect", peer_mac);
407 void netconfig_wifi_tdls_disconnected_event(GVariant *message)
409 DBG("WiFi TDLS Disconnected EVENT");
410 const gchar *peer_mac_addr = NULL;
412 g_variant_get(message, "(&s)", &peer_mac_addr);
413 if (g_strcmp0(peer_mac, peer_mac_addr) == 0) {
414 INFO("TDLS Peer Disconnected Mac Address: [%s]", peer_mac);
416 __netconfig_wifi_notify_tdls_event("TDLSDisconnect", peer_mac);
418 INFO("TDLS Peer Disconnected peer_mac(%s) != peer_mac_address(%s)", peer_mac, peer_mac_addr);
422 void netconfig_wifi_tdls_peer_found_event(GVariant *message)
424 DBG("WiFi TDLS Discovery EVENT Received !!");
425 const gchar *peer_mac_addr = NULL;
427 if (!is_timer_expired) {
429 g_variant_get(message, "(s)", &peer_mac_addr);
430 INFO("Discover Peer Mac Address: [%s]", peer_mac_addr);
432 if (is_discover_broadcast == 0)
435 __netconfig_wifi_notify_tdls_discover_event(peer_mac_addr, is_discover_broadcast);
437 DBG("Timer expired: Do not process the TDLS Discovery Event");