2
* This file is a part of the Cairo-Dock project
4
* Copyright : (C) see the 'copyright' file.
5
* E-mail : see the 'copyright' file.
7
* This program is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU General Public License
9
* as published by the Free Software Foundation; either version 3
10
* of the License, or (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
25
#include "applet-struct.h"
26
#include "applet-connections.h"
27
#include "applet-menu.h"
29
static GList *cd_NetworkMonitor_get_connections_for_access_point (const gchar *cAccessPoint, const gchar *cDevice, const gchar *cSsid, const gchar *cHwAddress, int iMode, int iWirelessCapabilities, GPtrArray *paConnections, GPtrArray *paSettings)
31
g_return_val_if_fail (paConnections != NULL, NULL);
32
GList *pConnList = NULL;
34
GHashTable *pSettings, *pSubSettings;
37
for (i = 0; i < paConnections->len; i++)
39
cConnection = (gchar *)g_ptr_array_index(paConnections, i);
40
cd_debug (" Connection path : %s", cConnection);
42
pSettings = g_ptr_array_index (paSettings, i);
44
pSubSettings = g_hash_table_lookup (pSettings, "connection");
45
if (pSubSettings == NULL)
48
const gchar *cType = NULL;
49
v = g_hash_table_lookup (pSubSettings, "type");
50
if (v && G_VALUE_HOLDS_STRING (v))
52
cType = g_value_get_string (v);
53
cd_debug (" type : %s", cType);
55
if (cType == NULL || strcmp (cType, "802-11-wireless") != 0) // on veut du wifi.
58
const gchar *cID = NULL;
59
v = g_hash_table_lookup (pSubSettings, "id");
60
if (v && G_VALUE_HOLDS_STRING (v))
62
cID = g_value_get_string (v);
63
cd_debug (" id : %s", cID);
66
pSubSettings = g_hash_table_lookup (pSettings, "802-11-wireless");
67
if (pSubSettings == NULL)
69
const gchar *cMode = NULL;
70
v = g_hash_table_lookup (pSubSettings, "mode");
71
if (v && G_VALUE_HOLDS_STRING (v))
73
cMode = g_value_get_string (v);
74
cd_debug (" mode : %s", cMode);
78
if (iMode == 1 && strcmp (cMode, "ad-hoc") != 0)
80
if (iMode == 2 && strcmp (cMode, "infrastructure") != 0)
84
gchar *cAPSsid = NULL;
85
v = g_hash_table_lookup (pSubSettings, "ssid");
86
if (v && G_VALUE_HOLDS_BOXED (v))
88
GByteArray *a = g_value_get_boxed (v);
89
cAPSsid = g_strndup ((gchar *) a->data, a->len);
90
cd_debug (" ssid : %s", cSsid);
92
if (cSsid == NULL || (cAPSsid != NULL && strcmp (cAPSsid, cSsid) != 0)) // le SSID est necessaire.
95
const gchar *cMacAddress = NULL;
96
v = g_hash_table_lookup (pSubSettings, "mac-address");
97
if (v && G_VALUE_HOLDS_STRING (v))
99
cMacAddress = g_value_get_string (v);
100
cd_debug (" mac address : %s", cMacAddress);
102
if (cHwAddress != NULL && cMacAddress != NULL && strcmp (cMacAddress, cHwAddress) != 0)
105
pSubSettings = g_hash_table_lookup (pSettings, "802-11-wireless-security");
108
/// on verra plus tard ...
112
pConnList = g_list_prepend (pConnList, GINT_TO_POINTER (i));
119
static GList *cd_NetworkMonitor_get_connections_for_wired_device (const gchar *cDevice, const gchar *cHwAddress, GPtrArray *paConnections)
121
GList *pConnList = NULL;
122
//\_____________ On cherche une connection qui ait le meme type (wifi ou filaire), et soit le meme SSID, soit la meme interface.
125
for (i = 0; i < paConnections->len; i++)
127
cConnection = (gchar *)g_ptr_array_index(paConnections, i);
128
cd_debug (" Connection path : %s", cConnection);
136
static void _on_select_access_point (GtkMenuItem *menu_item, CDMenuItemData *pItemData)
138
if (pItemData == NULL || pItemData->cConnection == NULL)
140
/// il faut creer une connection ...
141
cd_debug ("aucune des connexions existantes ne convient pour ce point d'acces\n");
143
GHashTable *pSettings = g_hash_table_new_full (g_str_hash,
146
(GDestroyNotify) g_hash_table_destroy); // a table of tables.
147
GHashTable *pSubSettings;
149
// connection: type, id, uuid
150
pSubSettings = g_hash_table_new_full (g_str_hash,
154
g_hash_table_insert (pSettings, g_strdup ("connection"), pSubSettings);
155
g_hash_table_insert (pSubSettings, g_strdup ("type"), g_strdup ("802-11-wireless"));
156
g_hash_table_insert (pSubSettings, g_strdup ("id"), g_strdup_printf ("CD - %s", pItemData->cSsid));
158
// 802-11-wireless: ssid, mode, seen-bssids
159
pSubSettings = g_hash_table_new_full (g_str_hash,
163
g_hash_table_insert (pSettings, g_strdup ("802-11-wireless"), pSubSettings);
164
g_hash_table_insert (pSubSettings, g_strdup ("ssid"), g_strdup (pItemData->cSsid));
165
g_hash_table_insert (pSubSettings, g_strdup ("mode"), g_strdup ("infrastructure"));
168
DBusGProxy *dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
170
"/org/freedesktop/NetworkManagerSettings",
171
"org.freedesktop.NetworkManagerSettings");
173
GError *erreur = NULL;
174
dbus_g_proxy_call (dbus_proxy_Settings, "AddConnection", &erreur,
175
CD_DBUS_TYPE_HASH_TABLE_OF_HASH_TABLE, pSettings,
180
cd_warning (erreur->message);
181
g_error_free (erreur);
185
/// on attend le signal NewConnection ...
189
/// on active la connexion...
196
cd_debug ("on a choisit (%s; %s; %s)", pItemData->cAccessPoint, pItemData->cDevice, pItemData->cConnection);
198
//ActivateConnection ( s: service_name, o: connection, o: device, o: specific_object )o
199
GError *erreur = NULL;
200
GValue active_connection_path = G_VALUE_INIT;
201
g_value_init (&active_connection_path, DBUS_TYPE_G_OBJECT_PATH);
203
gchar *cNewActiveConnectionPath = NULL;
204
dbus_g_proxy_call (myData.dbus_proxy_NM, "ActivateConnection", &erreur,
205
G_TYPE_STRING, myData.cServiceName,
206
DBUS_TYPE_G_OBJECT_PATH, pItemData->cConnection,
207
DBUS_TYPE_G_OBJECT_PATH, pItemData->cDevice,
208
DBUS_TYPE_G_OBJECT_PATH, pItemData->cAccessPoint,
210
DBUS_TYPE_G_OBJECT_PATH, &cNewActiveConnectionPath,
214
cd_warning (erreur->message);
215
g_error_free (erreur);
218
cd_debug (" => new active connection path : %s", cNewActiveConnectionPath);
222
GtkWidget * cd_NetworkMonitor_build_menu_with_access_points (void)
224
//\_____________ On recupere les connections existantes, ainsi que leur settings.
225
DBusGProxy *dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
227
"/org/freedesktop/NetworkManagerSettings",
228
"org.freedesktop.NetworkManagerSettings");
229
GPtrArray *paConnections = cairo_dock_dbus_get_array (dbus_proxy_Settings, "ListConnections");
230
cd_debug ("%d connection(s)", paConnections ? paConnections->len : 0);
231
g_object_unref (dbus_proxy_Settings);
233
GPtrArray *paSettings = NULL;
235
if (paConnections != NULL && paConnections->len > 0)
237
paSettings = g_ptr_array_sized_new (paConnections->len);
238
g_ptr_array_set_size (paSettings, paConnections->len);
239
DBusGProxy *dbus_proxy_ConnectionSettings;
240
GError *erreur = NULL;
241
GHashTable *pSettingsTable;
243
for (i = 0; i < paConnections->len; i++)
245
cConnection = (gchar *)g_ptr_array_index(paConnections, i);
246
cd_debug (" Connection path : %s", cConnection);
248
dbus_proxy_ConnectionSettings = cairo_dock_create_new_system_proxy (
249
"org.freedesktop.NetworkManagerUserSettings",
251
"org.freedesktop.NetworkManagerSettings.Connection");
253
pSettingsTable = NULL;
254
dbus_g_proxy_call (dbus_proxy_ConnectionSettings, "GetSettings", &erreur,
256
CD_DBUS_TYPE_HASH_TABLE_OF_HASH_TABLE, &pSettingsTable,
260
cd_warning (erreur->message);
261
g_error_free (erreur);
264
paSettings->pdata[i] = pSettingsTable;
266
g_object_unref (dbus_proxy_ConnectionSettings);
270
//\_____________ On recupere la liste des devices.
271
GPtrArray *paDevices = cairo_dock_dbus_get_array (myData.dbus_proxy_NM, "GetDevices");
272
g_return_val_if_fail (paDevices != NULL, FALSE);
273
cd_debug ("%d device(s)", paDevices->len);
275
GtkWidget *pMenu = gldi_menu_new (myIcon);
277
//\_____________ On parcourt tous les devices.
278
GHashTable *pSsidTable = g_hash_table_new_full (g_str_hash,
283
DBusGProxy *dbus_proxy_Device_prop;
285
DBusGProxy *dbus_proxy_WirelessDevice;
286
DBusGProxy *dbus_proxy_AccessPoint_prop;
287
gchar *cAccessPointPath;
288
GHashTable *hProperties;
292
const gchar *cHwAddress;
293
CDMenuItemData *pItemData;
295
for (i = 0; i < paDevices->len; i++)
297
// on recupere le device.
298
cDevice = (gchar *)g_ptr_array_index(paDevices, i);
299
dbus_proxy_Device_prop = cairo_dock_create_new_system_proxy (
300
"org.freedesktop.NetworkManager",
302
"org.freedesktop.DBus.Properties");
303
if (!DBUS_IS_G_PROXY (dbus_proxy_Device_prop))
305
cd_debug (" device %s", cDevice);
307
// on regarde son type.
308
iDeviceType = cairo_dock_dbus_get_property_as_uint (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "DeviceType"); // 1 : ethernet, 2 : wifi
309
cd_debug (" device type : %d", iDeviceType);
310
if (iDeviceType != 1 && iDeviceType != 2) // ne nous insteresse pas.
312
cd_debug (" useless device type\n");
313
g_object_unref (dbus_proxy_Device_prop);
317
if (iDeviceType == 2)
319
// On recupere ses proprietes.
320
hProperties = cairo_dock_dbus_get_all_properties (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device.Wireless");
322
/*v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
323
if (v && G_VALUE_HOLDS_STRING (v))
325
cAccessPointHwAdress = g_value_get_string (v);
329
v = (GValue *)g_hash_table_lookup (hProperties, "Mode");
330
if (v && G_VALUE_HOLDS_UINT (v))
332
iMode = g_value_get_uint (v);
335
int iWirelessCapabilities = 0;
336
v = (GValue *)g_hash_table_lookup (hProperties, "WirelessCapabilities");
337
if (v && G_VALUE_HOLDS_UINT (v))
339
iWirelessCapabilities = g_value_get_uint (v);
342
// On recupere la liste des points d'acces.
343
dbus_proxy_WirelessDevice = cairo_dock_create_new_system_proxy (
344
"org.freedesktop.NetworkManager",
346
"org.freedesktop.NetworkManager.Device.Wireless");
347
GError *erreur = NULL;
348
GPtrArray *pAccessPoints = NULL;
349
dbus_g_proxy_call (dbus_proxy_WirelessDevice, "GetAccessPoints", &erreur,
351
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &pAccessPoints,
353
g_object_unref (dbus_proxy_WirelessDevice);
356
cd_warning (erreur->message);
357
g_error_free (erreur);
359
g_object_unref (dbus_proxy_Device_prop);
362
if (!pAccessPoints || pAccessPoints->len == 0)
364
cd_debug (" aucun point d'acces\n");
365
g_object_unref (dbus_proxy_Device_prop);
366
/// ajouter une entree pour dire si le wifi est desactive ...
371
// on insere chaque point d'acces dans le menu.
372
for (j = 0; j < pAccessPoints->len; j ++)
374
// on recupere le point d'acces.
375
cAccessPointPath = (gchar *)g_ptr_array_index (pAccessPoints, j);
376
dbus_proxy_AccessPoint_prop = cairo_dock_create_new_system_proxy (
377
"org.freedesktop.NetworkManager",
379
"org.freedesktop.DBus.Properties");
381
// on recupere ses proprietes.
382
hProperties = cairo_dock_dbus_get_all_properties (dbus_proxy_AccessPoint_prop, "org.freedesktop.NetworkManager.AccessPoint");
383
if (hProperties == NULL)
385
g_object_unref (dbus_proxy_AccessPoint_prop);
390
v = (GValue *)g_hash_table_lookup (hProperties, "Strength");
391
if (v != NULL && G_VALUE_HOLDS_UCHAR (v))
393
iPercent = g_value_get_uchar (v);
396
v = (GValue *)g_hash_table_lookup (hProperties, "Ssid");
397
if (v != NULL && G_VALUE_HOLDS_BOXED (v))
399
GByteArray *a = g_value_get_boxed (v);
400
cSsid = g_strndup ((gchar *) a->data, a->len);
403
// on empeche les doublons.
404
pItemData = (cSsid ? g_hash_table_lookup (pSsidTable, cSsid) : NULL);
405
if (pItemData != NULL)
407
if (pItemData->iPercent > iPercent)
410
g_object_unref (dbus_proxy_AccessPoint_prop);
414
g_free (pItemData->cAccessPoint);
415
pItemData->cAccessPoint = g_strdup (cAccessPointPath);
421
v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
422
if (v != NULL && G_VALUE_HOLDS_STRING (v))
424
cHwAddress = g_value_get_string (v);
428
v = (GValue *)g_hash_table_lookup (hProperties, "Mode");
429
if (v != NULL && G_VALUE_HOLDS_UINT (v))
431
iMode = g_value_get_uint (v);
434
iWirelessCapabilities = 0;
435
v = (GValue *)g_hash_table_lookup (hProperties, "WpaFlags");
436
if (v != NULL && G_VALUE_HOLDS_UINT (v))
438
iWirelessCapabilities = g_value_get_uint (v);
441
cd_debug ("%d) %s : %s (%s, %d%%)", j, cSsid, cAccessPointPath, cHwAddress, iPercent);
443
const gchar *cImage = NULL;
445
cImage = MY_APPLET_SHARE_DATA_DIR"/link-5.svg";
446
else if (iPercent > 60)
447
cImage = MY_APPLET_SHARE_DATA_DIR"/link-4.svg";
448
else if (iPercent > 40)
449
cImage = MY_APPLET_SHARE_DATA_DIR"/link-3.svg";
450
else if (iPercent > 20)
451
cImage = MY_APPLET_SHARE_DATA_DIR"/link-2.svg";
452
else if (iPercent > 0)
453
cImage = MY_APPLET_SHARE_DATA_DIR"/link-1.svg";
455
cImage = MY_APPLET_SHARE_DATA_DIR"/link-0.svg";
457
/// recuperer les flags, wpa flags, et rsn flags -> encrypted.
458
/// et le mode -> ad_hoc
459
/// et mettre une icone asociee dans une hbox...
461
// on cherche une connection qui convienne.
462
GList *pConnList = cd_NetworkMonitor_get_connections_for_access_point (cAccessPointPath, cDevice, cSsid, cHwAddress, iMode, iWirelessCapabilities, paConnections, paSettings);
464
cd_debug ("%d connexion(s) satisfont a ce point d'acces", g_list_length (pConnList));
466
if (pConnList == NULL || pConnList->next == NULL)
468
if (pItemData == NULL)
470
pItemData = g_new0 (CDMenuItemData, 1);
471
g_hash_table_insert (pSsidTable, g_strdup (cSsid), pItemData);
475
g_free (pItemData->cAccessPoint);
477
pItemData->cDevice = g_strdup (cDevice);
478
pItemData->iPercent = iPercent;
479
pItemData->cAccessPoint = g_strdup (cAccessPointPath);
480
pItemData->cSsid = g_strdup (cSsid);
483
int n = GPOINTER_TO_INT (pConnList->data);
484
pItemData->cConnection = g_strdup (g_ptr_array_index (paConnections, n));
486
cairo_dock_add_in_menu_with_stock_and_data (cSsid, cImage, G_CALLBACK (_on_select_access_point), pMenu, pItemData);
490
GtkWidget *pSubMenu = cairo_dock_create_sub_menu (cSsid, pMenu, cImage);
492
for (c = pConnList; c != NULL; c = c->next)
494
int n = GPOINTER_TO_INT (c->data);
495
GHashTable *h = g_ptr_array_index (paSettings, n);
498
GHashTable *hh = g_hash_table_lookup (h, "connection");
501
v = g_hash_table_lookup (hh, "id");
502
if (v && G_VALUE_HOLDS_STRING (v))
504
const gchar *cID = g_value_get_string (v);
506
pItemData = g_new0 (CDMenuItemData, 1);
507
pItemData->cConnection = g_strdup (g_ptr_array_index (paConnections, n));
508
pItemData->cDevice = g_strdup (cDevice);
509
pItemData->cAccessPoint = g_strdup (cAccessPointPath);
511
cairo_dock_add_in_menu_with_stock_and_data (cID, NULL, G_CALLBACK (_on_select_access_point), pSubMenu, GINT_TO_POINTER (n));
515
g_list_free (pConnList);
517
g_object_unref (dbus_proxy_AccessPoint_prop);
519
g_ptr_array_free (pAccessPoints, TRUE);
523
/// si non connecte : ajouter une entree grisee.
525
/// sinon ajouter une entree pour (des)activer ce device.
529
g_ptr_array_free (paDevices, TRUE);
530
g_ptr_array_free (paConnections, TRUE);
531
g_hash_table_destroy (pSsidTable);