1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
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.
11 *
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/>.
18 */
19 // http://projects.gnome.org/NetworkManager/developers/spec-08.html
20 
21 #define _BSD_SOURCE
22 
23 #include <unistd.h>
24 #include <string.h>
25 
26 #include "applet-struct.h"
27 #include "applet-notifications.h"
28 #include "applet-draw.h"
29 #include "applet-dbus-callbacks.h"
30 #include "applet-connections.h"
31 
32 #define _reset_proxy(p) if (p) {\
33 	g_object_unref (p);\
34 	p = NULL; }
35 
g_cclosure_marshal_VOID__GHashTable_GHashTable(GClosure * c,GValue * r,guint n,const GValue * p,gpointer i,gpointer d)36 static void g_cclosure_marshal_VOID__GHashTable_GHashTable (GClosure *c, GValue *r, guint n, const GValue *p, gpointer i, gpointer d)
37 {
38 
39 }
40 
cd_NetworkMonitor_connect_to_bus(void)41 gboolean cd_NetworkMonitor_connect_to_bus (void)
42 {
43 	cd_debug ("%s ()", __func__);
44 	//\_____________ On verifie la presence de NM sur le bus.
45 	if (! cairo_dock_dbus_detect_system_application("org.freedesktop.NetworkManager"))
46 		return FALSE;
47 	dbus_g_object_register_marshaller(g_cclosure_marshal_VOID__GHashTable_GHashTable,
48 		G_TYPE_NONE, CD_DBUS_TYPE_HASH_TABLE_OF_HASH_TABLE, G_TYPE_INVALID);  // pour la methode GetSettings (il faut le faire avant de recuperer tout proxy, sinon les signaux ne passent plus !)
49 
50 	//\_____________ On recupere l'objet principal de NM.
51 	myData.dbus_proxy_NM = cairo_dock_create_new_system_proxy (
52 		"org.freedesktop.NetworkManager",
53 		"/org/freedesktop/NetworkManager",
54 		"org.freedesktop.NetworkManager");
55 	g_return_val_if_fail (DBUS_IS_G_PROXY (myData.dbus_proxy_NM), FALSE);
56 	myData.dbus_proxy_NM_prop = cairo_dock_create_new_system_proxy (
57 		"org.freedesktop.NetworkManager",
58 		"/org/freedesktop/NetworkManager",
59 		"org.freedesktop.DBus.Properties");
60 	g_return_val_if_fail (DBUS_IS_G_PROXY (myData.dbus_proxy_NM_prop), FALSE);
61 
62 	//\_____________ On se connecte aux signaux de base : wifi active (WirelessEnabled && WirelessHardwareEnabled ), etat de NM (State).
63 	dbus_g_object_register_marshaller(g_cclosure_marshal_VOID__BOXED,
64 		G_TYPE_NONE, G_TYPE_HASH_TABLE ,G_TYPE_INVALID);  // enregistrement d'un marshaller specifique au signal (sinon impossible de le recuperer ni de le voir
65 
66 	dbus_g_proxy_add_signal(myData.dbus_proxy_NM, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
67 	dbus_g_proxy_connect_signal(myData.dbus_proxy_NM, "PropertiesChanged",
68 		G_CALLBACK(onChangeNMProperties), NULL, NULL);
69 
70 	//\_____________ On recupere l'objet des connections.
71 	myData.cServiceName = g_strdup ("org.freedesktop.NetworkManagerUserSettings");
72 
73 	myData.dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
74 		myData.cServiceName,
75 		"/org/freedesktop/NetworkManagerSettings",
76 		"org.freedesktop.NetworkManagerSettings");
77 	dbus_g_proxy_add_signal(myData.dbus_proxy_Settings, "NewConnection", DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID);
78 	dbus_g_proxy_connect_signal(myData.dbus_proxy_Settings, "NewConnection",
79 		G_CALLBACK(onNewConnection), NULL, NULL);
80 
81 	return TRUE;
82 }
83 
cd_NetworkMonitor_get_device(void)84 gboolean cd_NetworkMonitor_get_device (void)
85 {
86 	cd_debug ("%s ()", __func__);
87 	//\_____________ On recupere la liste des devices.
88 	GPtrArray *paDevices = cairo_dock_dbus_get_array (myData.dbus_proxy_NM, "GetDevices");
89 	g_return_val_if_fail (paDevices != NULL, FALSE);
90 
91 	//\_____________ On choisit celui defini en conf, ou un par defaut (wifi de preference).
92 	cd_debug ("%d devices", paDevices->len);
93 	DBusGProxy *dbus_proxy_Device_prop;
94 	gchar *cDevice;
95 	uint i;
96 	for (i = 0; i < paDevices->len; i++)
97 	{
98 		// on recupere le device.
99 		cDevice = (gchar *)g_ptr_array_index(paDevices, i);
100 		dbus_proxy_Device_prop = cairo_dock_create_new_system_proxy (
101 			"org.freedesktop.NetworkManager",
102 			cDevice,
103 			"org.freedesktop.DBus.Properties");
104 		if (!DBUS_IS_G_PROXY (dbus_proxy_Device_prop))
105 			continue;
106 		cd_debug (" device %s", cDevice);
107 
108 		// on regarde son type.
109 		guint iDeviceType = cairo_dock_dbus_get_property_as_uint (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "DeviceType");  // 1 : ethernet, 2 : wifi
110 		cd_debug (" device type : %d", iDeviceType);
111 		if (iDeviceType != 1 && iDeviceType != 2)  // ne nous insteresse pas.
112 		{
113 			cd_debug (" useless device type\n");
114 			g_object_unref (dbus_proxy_Device_prop);
115 			continue;
116 		}
117 
118 		// on recupere son interface.
119 		gchar *cInterface = cairo_dock_dbus_get_property_as_string (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "Interface");
120 		cd_debug (" interface :%s", cInterface);
121 
122 		// on regarde si on doit le selectionner ou pas.
123 		if (myData.cDevice != NULL)  // on a deja trouve un device, on regarde si celui-ci convient mieux.
124 		{
125 			if (myConfig.cInterface && cInterface && strcmp (cInterface, myConfig.cInterface) == 0)  // c'est celui qu'on veut.
126 			{
127 				g_free (myData.cDevice);
128 				myData.cDevice = NULL;
129 				g_free (myData.cInterface);
130 				myData.cInterface = NULL;
131 				g_object_unref (myData.dbus_proxy_Device_prop);
132 				myData.dbus_proxy_Device_prop = NULL;
133 			}
134 			else if (iDeviceType == 2 && myData.bWiredExt)  // c'est un wifi alors que celui qu'on a deja est un ethernet, on le prend a sa place.
135 			{
136 				g_free (myData.cDevice);
137 				myData.cDevice = NULL;
138 				g_free (myData.cInterface);
139 				myData.cInterface = NULL;
140 				g_object_unref (myData.dbus_proxy_Device_prop);
141 				myData.dbus_proxy_Device_prop = NULL;
142 			}
143 		}
144 		if (myData.cDevice == NULL)  // aucun autre device, on selectionne celui-la.
145 		{
146 			cd_debug (" on selectionne ce device\n");
147 			myData.dbus_proxy_Device_prop = dbus_proxy_Device_prop;
148 			myData.cInterface = cInterface;
149 			myData.cDevice = g_strdup (cDevice);
150 			myData.bWiredExt = (iDeviceType == 1);
151 			myData.bWirelessExt = (iDeviceType == 2);
152 			if (myConfig.cInterface && cInterface && strcmp (cInterface, myConfig.cInterface) == 0)
153 			{
154 				cd_debug ("  c'est l'interface qu'on veut\n");
155 				break;
156 			}
157 		}
158 		else
159 		{
160 			g_free (cInterface);
161 			g_object_unref (dbus_proxy_Device_prop);
162 		}
163 	}
164 	g_ptr_array_free (paDevices, TRUE);  // on suppose qu'une GDestroyFunc a ete assignee au tableau.
165 	g_return_val_if_fail (myData.cDevice != NULL, FALSE);
166 
167 	//\_____________ On complete le device.
168 	myData.dbus_proxy_Device = cairo_dock_create_new_system_proxy (
169 		"org.freedesktop.NetworkManager",
170 		myData.cDevice,
171 		"org.freedesktop.NetworkManager.Device");
172 	/// se conecter au changement de propriete State ?...
173 
174 	if (myData.bWirelessExt)
175 	{
176 		// on se connecte au changement de la propriete ActiveAccessPoint.
177 		myData.dbus_proxy_WirelessDevice = cairo_dock_create_new_system_proxy (
178 			"org.freedesktop.NetworkManager",
179 			myData.cDevice,
180 			"org.freedesktop.NetworkManager.Device.Wireless");
181 		dbus_g_proxy_add_signal(myData.dbus_proxy_WirelessDevice, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
182 		dbus_g_proxy_connect_signal(myData.dbus_proxy_WirelessDevice, "PropertiesChanged",
183 			G_CALLBACK(onChangeWirelessDeviceProperties), NULL, NULL);
184 
185 		cd_NetworkMonitor_get_wireless_connection_infos ();
186 	}
187 	else
188 	{
189 		// on se connecte au changement de la propriete Carrier.
190 		myData.dbus_proxy_WiredDevice = cairo_dock_create_new_system_proxy (
191 			"org.freedesktop.NetworkManager",
192 			myData.cDevice,
193 			"org.freedesktop.NetworkManager.Device.Wired");
194 		dbus_g_proxy_add_signal(myData.dbus_proxy_WiredDevice, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
195 		dbus_g_proxy_connect_signal(myData.dbus_proxy_WiredDevice, "PropertiesChanged",
196 			G_CALLBACK(onChangeWiredDeviceProperties), NULL, NULL);
197 
198 		cd_NetworkMonitor_get_wired_connection_infos ();
199 	}
200 
201 	return TRUE;
202 }
203 
cd_NetworkMonitor_get_connection(void)204 gboolean cd_NetworkMonitor_get_connection (void)
205 {
206 	cd_debug ("%s ()", __func__);
207 
208 	myData.cServiceName = g_strdup ("org.freedesktop.NetworkManagerUserSettings");
209 
210 	//\_____________ On recupere la liste des connexions disponibles (ce sont les configs tout-en-un de NM).
211 	DBusGProxy *dbus_proxy_Settings = cairo_dock_create_new_system_proxy (
212 		myData.cServiceName,
213 		"/org/freedesktop/NetworkManagerSettings",
214 		"org.freedesktop.NetworkManagerSettings");
215 	GPtrArray *paConnections = cairo_dock_dbus_get_array (dbus_proxy_Settings, "ListConnections");
216 	cd_debug ("%d connections", paConnections->len);
217 
218 	//\_____________ On en choisit une.
219 	gchar *cConnection;
220 	uint i;
221 	for (i = 0; i < paConnections->len; i++)
222 	{
223 		cConnection = (gchar *)g_ptr_array_index(paConnections, i);
224 		cd_debug (" Connection path : %s", cConnection);
225 
226 		myData.cConnection = g_strdup (cConnection);
227 	}
228 
229 	g_ptr_array_free (paConnections, TRUE);
230 	g_object_unref (dbus_proxy_Settings);
231 
232 	return (myData.cConnection != NULL);
233 }
234 
cd_NetworkMonitor_get_active_connection_info(void)235 gboolean cd_NetworkMonitor_get_active_connection_info (void)
236 {
237 	cd_debug ("%s ()", __func__);
238 	//\_____________ on reset tout.
239 	myData.bWiredExt = myData.bWirelessExt = FALSE;
240 	g_free (myData.cDevice);
241 	myData.cDevice = NULL;
242 	g_free (myData.cInterface);
243 	myData.cInterface = NULL;
244 	g_free (myData.cAccessPoint);
245 	myData.cAccessPoint = NULL;
246 	_reset_proxy (myData.dbus_proxy_ActiveConnection);
247 	_reset_proxy (myData.dbus_proxy_ActiveConnection_prop);
248 	_reset_proxy (myData.dbus_proxy_Device);
249 	_reset_proxy (myData.dbus_proxy_Device_prop);
250 	_reset_proxy (myData.dbus_proxy_ActiveAccessPoint);
251 	_reset_proxy (myData.dbus_proxy_ActiveAccessPoint_prop);
252 	_reset_proxy (myData.dbus_proxy_WirelessDevice);
253 	_reset_proxy (myData.dbus_proxy_WiredDevice);
254 
255 	DBusGProxy *dbus_proxy_ActiveConnection_prop = NULL;
256 	DBusGProxy *dbus_proxy_Device_prop = NULL;
257 
258 	uint j,k;
259 	GPtrArray *paActiveConnections = NULL;
260 	gchar *cActiveConnection, *cDevice, *cAccessPointPath, *cConnection;
261 	const gchar *cServiceName;
262 
263 	//\_____________ On recupere la liste des connexions actives (ce sont les configs tout-en-un de NM qui sont actuellement utilisees).
264 	paActiveConnections = (GPtrArray*) cairo_dock_dbus_get_property_as_boxed (myData.dbus_proxy_NM_prop, "org.freedesktop.NetworkManager", "ActiveConnections");
265 	cd_debug ("%d connections", paActiveConnections->len);
266 	for (j=0; j < paActiveConnections->len; j++)
267 	{
268 		cActiveConnection = (gchar *)g_ptr_array_index(paActiveConnections,j);
269 		cd_debug ("Network-Monitor : Active Connection path : %s", cActiveConnection);
270 
271 		// on recupere les proprietes de la connexion.
272 		dbus_proxy_ActiveConnection_prop = cairo_dock_create_new_system_proxy (
273 			"org.freedesktop.NetworkManager",
274 			cActiveConnection,
275 			"org.freedesktop.DBus.Properties");
276 		GHashTable *props = cairo_dock_dbus_get_all_properties (dbus_proxy_ActiveConnection_prop, "org.freedesktop.NetworkManager.Connection.Active");
277 		if (props == NULL)
278 		{
279 			g_object_unref (dbus_proxy_ActiveConnection_prop);
280 			continue;
281 		}
282 
283 		// on regarde si c'est la connexion par defaut.
284 		GValue *v = g_hash_table_lookup (props, "Default");
285 		if (!v || !G_VALUE_HOLDS_BOOLEAN (v) || ! g_value_get_boolean (v))
286 		{
287 			g_hash_table_unref (props);
288 			g_object_unref (dbus_proxy_ActiveConnection_prop);
289 			continue;
290 		}
291 		cd_debug (" c'est la connexion par defaut\n");
292 		myData.cActiveConnection = g_strdup (cActiveConnection);
293 
294 		// on recupere le SpecificObject qui contient le point d'acces courant.
295 		cAccessPointPath=NULL;
296 		v = g_hash_table_lookup (props, "SpecificObject");
297 		if (v && G_VALUE_HOLDS_BOXED (v))
298 		{
299 			cAccessPointPath = g_value_get_boxed (v);
300 			cd_debug (" cAccessPointPath : %s", cAccessPointPath);
301 		}
302 
303 		// on recupere le nom du service qui fournit cette connexion.
304 		cServiceName=NULL;
305 		v = g_hash_table_lookup (props, "ServiceName");
306 		if (v && G_VALUE_HOLDS_STRING (v))
307 		{
308 			cServiceName = g_value_get_string (v);
309 			cd_debug (" cServiceName : %s", cServiceName);
310 		}
311 
312 		// on recupere le chemin de la connection.
313 		cConnection=NULL;
314 		v = g_hash_table_lookup (props, "Connection");
315 		if (v && G_VALUE_HOLDS (v, DBUS_TYPE_G_OBJECT_PATH))
316 		{
317 			cConnection = g_value_get_boxed (v);
318 			cd_debug (" cConnectionPath : %s", cConnection);
319 		}
320 
321 		// on parcourt la liste des devices associes.
322 		v = g_hash_table_lookup (props, "Devices");
323 		if (v && G_VALUE_HOLDS_BOXED (v))
324 		{
325 			GPtrArray *paDevices = g_value_get_boxed (v);
326 			cd_debug (" %d devices", paDevices->len);
327 			for (k=0;  k < paDevices->len; k++)
328 			{
329 				// on recupere le device.
330 				cDevice = (gchar *)g_ptr_array_index(paDevices,k);
331 				cd_debug (" device path : %s", cDevice);
332 				dbus_proxy_Device_prop = cairo_dock_create_new_system_proxy (
333 					"org.freedesktop.NetworkManager",
334 					cDevice,
335 					"org.freedesktop.DBus.Properties");
336 
337 				// on regarde son type.
338 				guint iDeviceType = cairo_dock_dbus_get_property_as_uint (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "DeviceType");  // 1 : ethernet, 2 : wifi
339 				cd_debug (" device type : %d", iDeviceType);
340 				if (iDeviceType != 1 && iDeviceType != 2)  // ne nous insteresse pas.
341 				{
342 					g_object_unref (dbus_proxy_Device_prop);
343 					continue;
344 				}
345 
346 				// on recupere son interface.
347 				gchar *cInterface = cairo_dock_dbus_get_property_as_string (dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device", "Interface");
348 				cd_debug (" interface :%s", cInterface);
349 
350 				// on garde toutes les infos en memoire.
351 				myData.cInterface = cInterface;
352 				myData.cDevice = g_strdup(cDevice);
353 				myData.cServiceName = g_strdup (cServiceName);
354 				myData.cConnection = g_strdup (cConnection);
355 				myData.dbus_proxy_ActiveConnection_prop = dbus_proxy_ActiveConnection_prop;
356 				myData.dbus_proxy_ActiveConnection =  cairo_dock_create_new_system_proxy (
357 					"org.freedesktop.NetworkManager",
358 					myData.cActiveConnection,
359 					"org.freedesktop.NetworkManager.Connection.Active");
360 				dbus_g_proxy_add_signal(myData.dbus_proxy_ActiveConnection, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
361 				dbus_g_proxy_connect_signal(myData.dbus_proxy_ActiveConnection, "PropertiesChanged",
362 					G_CALLBACK(onChangeActiveConnectionProperties), NULL, NULL);
363 
364 				myData.dbus_proxy_Device_prop = dbus_proxy_Device_prop;
365 				myData.dbus_proxy_Device = cairo_dock_create_new_system_proxy (
366 					"org.freedesktop.NetworkManager",
367 					cDevice,
368 					"org.freedesktop.NetworkManager.Device");
369 
370 				if (cAccessPointPath && strncmp (cAccessPointPath, "/org/freedesktop/NetworkManager/AccessPoint/", 44) == 0)
371 				{
372 					myData.cAccessPoint = g_strdup (cAccessPointPath);
373 					myData.dbus_proxy_ActiveAccessPoint_prop = cairo_dock_create_new_system_proxy (
374 						"org.freedesktop.NetworkManager",
375 						cAccessPointPath,
376 						"org.freedesktop.DBus.Properties");
377 					myData.dbus_proxy_ActiveAccessPoint = cairo_dock_create_new_system_proxy (
378 						"org.freedesktop.NetworkManager",
379 						cAccessPointPath,
380 						"org.freedesktop.NetworkManager.AccessPoint");
381 					dbus_g_proxy_add_signal(myData.dbus_proxy_ActiveAccessPoint, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
382 					dbus_g_proxy_connect_signal(myData.dbus_proxy_ActiveAccessPoint, "PropertiesChanged",
383 						G_CALLBACK(onChangeAccessPointProperties), NULL, NULL);
384 				}
385 
386 				if (iDeviceType == 1)
387 				{
388 					cd_debug (" => Network-Monitor : Connexion filaire\n");
389 					myData.bWiredExt = TRUE;
390 
391 					// on se connecte au changement de la propriete Carrier.
392 					myData.dbus_proxy_WiredDevice = cairo_dock_create_new_system_proxy (
393 						"org.freedesktop.NetworkManager",
394 						myData.cDevice,
395 						"org.freedesktop.NetworkManager.Device.Wired");
396 					dbus_g_proxy_add_signal(myData.dbus_proxy_WiredDevice, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
397 					dbus_g_proxy_connect_signal(myData.dbus_proxy_WiredDevice, "PropertiesChanged",
398 						G_CALLBACK(onChangeWiredDeviceProperties), NULL, NULL);
399 
400 					// on recupere les proprietes de la carte reseau, et de son etat connecte ou non.
401 					cd_NetworkMonitor_get_wired_connection_infos();
402 				}
403 				else
404 				{
405 					cd_debug (" => Network-Monitor : Connexion sans fil\n");
406 					myData.bWirelessExt = TRUE;
407 
408 					// on se connecte au changement de la propriete ActiveAccessPoint.
409 					myData.dbus_proxy_WirelessDevice = cairo_dock_create_new_system_proxy (
410 						"org.freedesktop.NetworkManager",
411 						myData.cDevice,
412 						"org.freedesktop.NetworkManager.Device.Wireless");
413 					dbus_g_proxy_add_signal(myData.dbus_proxy_WirelessDevice, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
414 					dbus_g_proxy_connect_signal(myData.dbus_proxy_WirelessDevice, "PropertiesChanged",
415 						G_CALLBACK(onChangeWirelessDeviceProperties), NULL, NULL);
416 
417 					// Recuperation de l'AP active.
418 					cd_NetworkMonitor_get_wireless_connection_infos();
419 
420 					// Calcul de la qualite du signal
421 					cd_NetworkMonitor_quality();
422 				}
423 
424 				cd_NetworkMonitor_draw_icon ();
425 
426 				break ;
427 			}  // fin de la liste des devices.
428 		}
429 
430 		g_hash_table_unref (props);
431 		break;  // on prend la premierr connexion.
432 	}
433 
434 	g_ptr_array_free(paActiveConnections,TRUE);
435 	return (myData.bWiredExt || myData.bWirelessExt);
436 }
437 
438 
cd_NetworkMonitor_get_wireless_connection_infos(void)439 void cd_NetworkMonitor_get_wireless_connection_infos (void)
440 {
441 	cd_debug ("%s ()", __func__);
442 	GHashTable *hProperties;
443 	GValue *v;
444 
445 	g_free (myData.cAccessPointHwAdress);
446 	myData.cAccessPointHwAdress = NULL;
447 	myData.iSpeed = 0;
448 
449 	//\_____________ On recupere les proprietes du device "wireless".
450 	hProperties = cairo_dock_dbus_get_all_properties (myData.dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device.Wireless");
451 	g_return_if_fail (hProperties != NULL);
452 
453 	v = (GValue *)g_hash_table_lookup (hProperties, "Bitrate");
454 	if (v && G_VALUE_HOLDS_UINT (v))
455 	{
456 		myData.iSpeed = g_value_get_uint (v);
457 		cd_debug ("  Bitrate : %d\n",myData.iSpeed);
458 	}
459 
460 	v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
461 	if (v && G_VALUE_HOLDS_STRING (v))
462 	{
463 		myData.cAccessPointHwAdress = g_strdup(g_value_get_string (v));
464 		cd_debug ("  Adresse physique : %s\n",myData.cAccessPointHwAdress);
465 	}
466 
467 	v = (GValue *)g_hash_table_lookup (hProperties, "ActiveAccessPoint");
468 	if (v && G_VALUE_HOLDS (v, DBUS_TYPE_G_OBJECT_PATH))
469 	{
470 		gchar *cAccessPoint = g_value_get_boxed (v);
471 		cd_debug ("  Access point : %s", cAccessPoint);
472 		if (cAccessPoint && strncmp (cAccessPoint, "/org/freedesktop/NetworkManager/AccessPoint/", 44) == 0)
473 		{
474 			g_free (myData.cAccessPoint);
475 			myData.cAccessPoint = g_strdup (cAccessPoint);
476 		}
477 	}
478 
479 	g_hash_table_unref (hProperties);
480 
481 	//\_____________ On recupere le point d'acces courant sur le bus.
482 	myData.iQuality = WIFI_QUALITY_NO_SIGNAL;
483 	if (myData.cAccessPoint != NULL)
484 	{
485 		cd_NetworkMonitor_get_new_access_point ();
486 	}
487 }
488 
cd_NetworkMonitor_get_wired_connection_infos(void)489 void cd_NetworkMonitor_get_wired_connection_infos (void)
490 {
491 	cd_debug ("%s ()", __func__);
492 	GHashTable *hProperties;
493 	GValue *v;
494 
495 	//\_____________ On recupere les proprietes du device "wired"
496 	hProperties = cairo_dock_dbus_get_all_properties (myData.dbus_proxy_Device_prop, "org.freedesktop.NetworkManager.Device.Wired");
497 	g_return_if_fail (hProperties != NULL);
498 
499 	v = (GValue *)g_hash_table_lookup (hProperties, "Speed");
500 	if (v != NULL && G_VALUE_HOLDS_UINT (v))
501 	{
502 		myData.iSpeed = g_value_get_uint (v);
503 		cd_debug("  Vitesse de connexion : %d",myData.iSpeed);
504 	}
505 
506 	v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
507 	if (v != NULL && G_VALUE_HOLDS_STRING (v))
508 	{
509 		myData.cAccessPointHwAdress = g_strdup(g_value_get_string (v));
510 		cd_debug("  Adresse physique : %s",myData.cAccessPointHwAdress);
511 	}
512 
513 	myData.iQuality = WIRED_NO_CONNECTION;
514 	v = (GValue *)g_hash_table_lookup (hProperties, "Carrier");
515 	if (v != NULL && G_VALUE_HOLDS_BOOLEAN (v))
516 	{
517 		if (g_value_get_boolean (v))
518 			myData.iQuality = WIRED_CONNECTION;
519 		cd_debug("  cable branche : %d", g_value_get_boolean (v));
520 	}
521 
522 	g_hash_table_unref (hProperties);
523 }
524 
525 
526   //////////////////
527  // ACCESS POINT //
528 //////////////////
529 
cd_NetworkMonitor_quality(void)530 void cd_NetworkMonitor_quality (void)
531 {
532 	if (myData.bWirelessExt)
533 	{
534 		if (myData.iPercent <= 0)
535 			myData.iQuality = WIFI_QUALITY_NO_SIGNAL;
536 		else if (myData.iPercent < 20)
537 			myData.iQuality = WIFI_QUALITY_VERY_LOW;
538 		else if (myData.iPercent < 40)
539 			myData.iQuality = WIFI_QUALITY_LOW;
540 		else if (myData.iPercent < 60)
541 			myData.iQuality = WIFI_QUALITY_MIDDLE;
542 		else if (myData.iPercent < 80)
543 			myData.iQuality = WIFI_QUALITY_GOOD;
544 		else
545 			myData.iQuality = WIFI_QUALITY_EXCELLENT;
546 	}
547 	else if (myData.bWiredExt)
548 		myData.iQuality = WIRED_CONNECTION;
549 }
550 
551 // les proprietes d'un AccessPoint sont :
552 // Flags - u - (read)  (NM_802_11_AP_FLAGS)
553 //     Flags describing the capabilities of the access point.
554 // WpaFlags - u - (read) (NM_802_11_AP_SEC)
555 //     Flags describing the access point's capabilities according to WPA (Wifi Protected Access).
556 // RsnFlags - u - (read) (NM_802_11_AP_SEC)
557 //     Flags describing the access point's capabilities according to the RSN (Robust Secure Network) protocol.
558 // Ssid - ay - (read)
559 //     The Service Set Identifier identifying the access point.
560 // Frequency - u - (read)
561 //     The radio channel frequency in use by the access point, in MHz.
562 // HwAddress - s - (read)
563 //     The hardware address (BSSID) of the access point.
564 // Mode - u - (read) (NM_802_11_MODE)
565 //     Describes the operating mode of the access point.
566 // MaxBitrate - u - (read)
567 //     The maximum bitrate this access point is capable of, in kilobits/second (Kb/s).
568 // Strength - y - (read)
569 //     The current signal quality of the access point, in percent.
cd_NetworkMonitor_fetch_access_point_properties(GHashTable * hProperties)570 void cd_NetworkMonitor_fetch_access_point_properties (GHashTable *hProperties)
571 {
572 	GValue *v;
573 	v = (GValue *)g_hash_table_lookup (hProperties, "Strength");
574 	if (v != NULL && G_VALUE_HOLDS_UCHAR (v))
575 	{
576 		myData.iPercent = MIN (100, (gint) g_value_get_uchar (v));  // pas clair si c'est deja des % ou s'il faut convertir par 100/255, des fois on se chope des 255 ...
577 		cd_debug ("Network-Monitor : Force du signal : %d %%", myData.iPercent);
578 		cd_NetworkMonitor_quality ();
579 		cd_NetworkMonitor_draw_icon ();
580 	}
581 
582 	v = (GValue *)g_hash_table_lookup (hProperties, "HwAddress");
583 	if (v != NULL && G_VALUE_HOLDS_STRING (v))
584 	{
585 		myData.cAccessPointHwAdress = g_strdup(g_value_get_string (v));
586 		cd_debug ("Network-Monitor : Adresse physique de l'AP active : %s", myData.cAccessPointHwAdress);
587 	}
588 
589 	v = (GValue *)g_hash_table_lookup (hProperties, "Ssid");
590 	if (v != NULL && G_VALUE_HOLDS_BOXED (v))
591 	{
592 		GByteArray *a = g_value_get_boxed (v);
593 		myData.cESSID = g_new0 (gchar, a->len+1);
594 		for (uint i = 0; i < a->len; i ++)
595 		{
596 			myData.cESSID[i] = a->data[i];
597 		}
598 		cd_debug ("Network-Monitor : SSID : %s", myData.cESSID);
599 	}
600 
601 	v = (GValue *)g_hash_table_lookup (hProperties, "MaxBitrate");  // in kilobits/second (Kb/s).
602 	if (v != NULL && G_VALUE_HOLDS_UINT (v))
603 	{
604 		myData.iSpeed = (gint) g_value_get_uint (v) / 8;  // Ko/s
605 		cd_debug("Network-Monitor : Max Bitrate au demarrage : %d",myData.iSpeed);
606 	}
607 }
608 
cd_NetworkMonitor_get_access_point_properties(void)609 void cd_NetworkMonitor_get_access_point_properties (void)
610 {
611 	//\_____________ On recupere les proprietes associees.
612 	GHashTable *hProperties = cairo_dock_dbus_get_all_properties (myData.dbus_proxy_ActiveAccessPoint_prop, "org.freedesktop.NetworkManager.AccessPoint");
613 	g_return_if_fail (hProperties != NULL);
614 
615 	myData.iQuality = WIFI_QUALITY_NO_SIGNAL;
616 	cd_NetworkMonitor_fetch_access_point_properties (hProperties);
617 
618 	g_hash_table_unref (hProperties);
619 }
620 
cd_NetworkMonitor_get_new_access_point(void)621 void cd_NetworkMonitor_get_new_access_point (void)
622 {
623 	myData.iQuality = WIFI_QUALITY_NO_SIGNAL;
624 	if (myData.cAccessPoint != NULL)
625 	{
626 		cd_debug (" on recupere le nouveau point d'acces...\n");
627 		if (myData.dbus_proxy_ActiveAccessPoint)
628 		{
629 			dbus_g_proxy_disconnect_signal(myData.dbus_proxy_ActiveAccessPoint, "PropertiesChanged",
630 				G_CALLBACK(onChangeAccessPointProperties), NULL);
631 			g_object_unref (myData.dbus_proxy_ActiveAccessPoint);
632 		}
633 		if (myData.dbus_proxy_ActiveAccessPoint_prop)
634 		{
635 			g_object_unref (myData.dbus_proxy_ActiveAccessPoint_prop);
636 		}
637 
638 		myData.dbus_proxy_ActiveAccessPoint_prop = cairo_dock_create_new_system_proxy (
639 			"org.freedesktop.NetworkManager",
640 			myData.cAccessPoint,
641 			"org.freedesktop.DBus.Properties");
642 		myData.dbus_proxy_ActiveAccessPoint = cairo_dock_create_new_system_proxy (
643 			"org.freedesktop.NetworkManager",
644 			myData.cAccessPoint,
645 			"org.freedesktop.NetworkManager.AccessPoint");
646 		dbus_g_proxy_add_signal(myData.dbus_proxy_ActiveAccessPoint, "PropertiesChanged", CD_DBUS_TYPE_HASH_TABLE, G_TYPE_INVALID);
647 		dbus_g_proxy_connect_signal(myData.dbus_proxy_ActiveAccessPoint, "PropertiesChanged",
648 			G_CALLBACK(onChangeAccessPointProperties), NULL, NULL);
649 
650 		cd_NetworkMonitor_get_access_point_properties ();
651 	}
652 }
653 
654 /*
655 #!/usr/bin/env python
656 # The url the program will try to open hoping to be redirected to the portal
657 URL = 'http://perdu.com/'
658 
659 import sys
660 import gobject
661 import dbus
662 import dbus.mainloop.glib
663 import urllib2, urllib
664 from BeautifulSoup import BeautifulSoup
665 import re
666 import ConfigParser
667 import os
668 import pynotify
669 
670 def properties_changed_signal_handler(props):
671     if not props.has_key('ActiveConnections'):
672         return
673     for device_path in props['ActiveConnections']:
674         device = bus.get_object('org.freedesktop.NetworkManager', device_path)
675         device_props = device.GetAll("org.freedesktop.NetworkManager.Connection.Active", dbus_interface="org.freedesktop.DBus.Properties")
676         if device_props['Default']:
677             return
678         ap_path = device_props['SpecificObject']
679         if ap_path.startswith('/org/freedesktop/NetworkManager/AccessPoint/'):
680             ap = bus.get_object('org.freedesktop.NetworkManager', ap_path)
681             ssid = ap.Get("org.freedesktop.NetworkManager.AccessPoint", "Ssid", dbus_interface="org.freedesktop.DBus.Properties")
682             ssid = ''.join([chr(c) for c in ssid])
683             if ssid not in config.sections():
684                 return
685             print ssid
686             device.connect_to_signal("PropertiesChanged", device_properties_changed_signal_handler(ssid), dbus_interface="org.freedesktop.NetworkManager.Connection.Active")
687 
688 def device_properties_changed_signal_handler(ssid):
689     def handler(props):
690         if not props.has_key('State'):
691             return
692         if props['State'] != 2:
693             return
694         print ssid
695         section = dict(config.items(ssid))
696 
697         if login(section):
698             txt = "Successfully logged on " + ssid
699         else:
700             txt = "Failled to log on " + ssid
701         n = pynotify.Notification("Open Wifi Auto Connect", txt, "dialog-warning")
702         n.set_urgency(pynotify.URGENCY_NORMAL)
703         n.set_timeout(10)
704         #n.add_action("clicked","Button text", callback_function, None)
705         n.show()
706     return handler
707 
708 
709 def login(values):
710     # build an http fetcher that support cookies
711     opener = urllib2.build_opener( urllib2.HTTPCookieProcessor() )
712     urllib2.install_opener(opener)
713 
714     # try to open the portal page
715     f = opener.open(URL)
716     data = f.read()
717     redirect_url = f.geturl().split('?')[0]
718     f.close()
719     if redirect_url == URL:
720         return # Our request wasn't hijacked by the portal (maybe the wifi network isn't the default connection)
721 
722     # parse the portal page
723     soup = BeautifulSoup(data)
724     form = soup.find('form')
725     if not form:
726         return # There's no form on this page
727 
728     # creating the post values
729     login_post = {}
730     for input in form.findAll('input'):
731         if input.has_key('name'):
732             default = ''
733             if input.has_key('type') and input['type'] == 'checkbox':
734                 default = 'on'
735             login_post[input['name']] = input.has_key('value') and input['value'] or default
736 
737     login_post.update(values)
738 
739     # guessing the post url
740     if not form.has_key('action'):
741         url = redirect_url
742     elif not form['action'].startswith('/'):
743         url = '/'.join(redirect_url.split('/')[:-1]) + '/' + form['action']
744     else:
745         url = '/'.join(redirect_url.split('/')[:3]) + form['action']
746 
747     # GET ou POST ?
748     postBody = None
749     if form.has_key('method') and form['method'].lower() == 'post':
750         postBody = urllib.urlencode(login_post)
751     else:
752         url += '?' + urllib.urlencode(login_post).replace(' ', '+')
753 
754     # submit the form
755     f = opener.open(url, postBody)
756     data = f.read()
757     f.close()
758 
759     # Test if the login was a success
760     f = opener.open(URL)
761     data = f.read()
762     status = f.geturl() == URL
763     f.close()
764     return status
765 
766 if __name__ == '__main__':
767     config = ConfigParser.RawConfigParser()
768     config.read(os.path.expanduser('~/.OpenWifiAutoConnect'))
769 
770     pynotify.init( "Open Wifi Auto Connect" )
771 
772     dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
773 
774     bus = dbus.SystemBus()
775     nm = bus.get_object("org.freedesktop.NetworkManager", "/org/freedesktop/NetworkManager")
776     nm.connect_to_signal("PropertiesChanged", properties_changed_signal_handler, dbus_interface="org.freedesktop.NetworkManager")
777 
778     loop = gobject.MainLoop()
779     loop.run()
780 */
781