NetworkManager/src/NetworkManagerWireless.c
Ray Strode 278e500f99 2005-03-14 Ray Strode <rstrode@redhat.com>
Fourth (probably working) cut at porting to
	dbus 0.30 api and new hal. This cut adds
	some new logging macros to make debugging
	easier.

	* dispatcher-daemon/NetworkManagerDispatcher.c:
	* info-daemon/NetworkmanagerInfo.c:
	* info-daemon/NetworkManagerInfoPassphraseDialog.c:
	* info-daemon/NetworkManagerInfoVPN.c:
	* src/NetworkManager.c:
	* src/NetworkManagerAP.c:
	* src/NetworkManagerAPList.c:
	* src/NetworkManagerDHCP.c:
	* src/NetworkManagerDbus.c:
	* src/NetworkManagerDevice.c:
	* src/NetworkManagerPolicy.c:
	* src/NetworkManagerSystem.c:
	* src/NetworkManagerUtils.c:
	* src/NetworkManagerWireless.c:
	* src/autoip.c:
	* src/nm-dbus-nm.c:
	* src/backends/NetworkManagerDebian.c:
	* src/backends/NetworkManagerGentoo.c:
	* src/backends/NetworkManagerRedHat.c:
	* src/backends/NetworkManagerSlackware.c:
	use new logging macros.

	* dispatcher-daemon/NetworkManagerDispatcher.c:
	(nmd_dbus_filter): s/dbus_free/g_free/

	* info-daemon/Makefile.am: link in utils library.
	* info-daemon/NetworkmanagerInfo.c: use new logging
	macros.
	(nmi_dbus_get_network): don't assume enumerations
	are 32-bit.
	(nmi_dbus_nmi_message_handler): don't free what
	doesn't belong to us.

	* libnm_glib/libnm_glib.c:
	(libnm_glib_get_nm_status):
	(libnm_glib_init): don't free what doesn't
	belong to us.
	(libnm_glib_dbus): strdup result, so it doesn't get
	lost when message is unref'd.

	* panel-applet/NMWirelessAppletDbus.c:
	(nmwa_dbus_update_devices): s/dbus_free/g_free/

	* src/NetworkManager.c:
	(nm_monitor_wired_link_state): request initial status
	dump of all cards when we start up, instead of relying
	on /sys/.../carrier.
	(nm_info_handler), (nm_set_up_log_handlers):
	log handlers to specify what syslog priorites
	the logging macros default to.

	* src/NetworkManagerAPList.c:
	(nm_ap_list_populate_from_nmi):
	s/dbus_free_string_array/g_strfreev/

	* src/NetworkManagerDbus.c:
	(nm_dbus_get_network_object):
	validate d-bus message argument types.
	Advance message iterator after reading argument,
	prepend instead of append to GSList.

	* src/NetworkManagerDevice.c:
	(nm_device_probe_wired_link_status):
	remove redundant /sys in /sys path. remove wrong
	contents == NULL means has carrier assumption.

	* src/nm-netlink-monitor.c
	(nm_netlink_monitor_request_status): implement
	function to ask kernel to dump interface link
	status over netlink socket.

	* test/*.c: s/dbus_free/g_free/

	* utils/nm-utils.h:
	(nm_print_backtrace): new macro to print backtrace.
	(nm_get_timestamp): new macro to get sub-second precise
	unix timestamp.
	(nm_info), (nm_debug), (nm_warning), (nm_error):
	new logging functions. nm_info just prints,
	nm_debug includes timestamp and function,
	nm_warning includes function, nm_error includes
	backtrace and sigtrap.


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@497 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2005-03-15 05:30:15 +00:00

221 lines
7.2 KiB
C

/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <stdio.h>
#include <iwlib.h>
#include "config.h"
#ifdef HAVE_GCRYPT
#include <gcrypt.h>
#else
#include "gnome-keyring-md5.h"
#endif
#include "NetworkManager.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerWireless.h"
#include "NetworkManagerPolicy.h"
#include "NetworkManagerUtils.h"
/*
* nm_wireless_64bit_ascii_to_hex
*
* Convert an ASCII string into a suitable WEP key.
*
*/
char *nm_wireless_64bit_ascii_to_hex (const unsigned char *ascii)
{
static char hex_digits[] = "0123456789abcdef";
unsigned char *res;
int i;
res = g_malloc (33);
for (i = 0; i < 16; i++)
{
res[2*i] = hex_digits[(ascii[i] >> 4) & 0xf];
res[2*i+1] = hex_digits[ascii[i] & 0xf];
}
/* We chomp it at byte 10, since WEP keys only use 40 bits */
res[10] = 0;
return (res);
}
/*
* nm_wireless_128bit_ascii_to_hex
*
* Convert an ascii string into a suitable string for use
* as a WEP key.
*
* Code originally by Alex Larsson <alexl@redhat.com> and
* copyright Red Hat, Inc. under terms of the LGPL.
*
*/
char *nm_wireless_128bit_ascii_to_hex (const unsigned char *ascii)
{
static char hex_digits[] = "0123456789abcdef";
unsigned char *res;
int i;
res = g_malloc (33);
for (i = 0; i < 16; i++)
{
res[2*i] = hex_digits[(ascii[i] >> 4) & 0xf];
res[2*i+1] = hex_digits[ascii[i] & 0xf];
}
/* We chomp it at byte 26, since WEP keys only use 104 bits */
res[26] = 0;
return (res);
}
/*
* nm_wireless_128bit_key_from_passphrase
*
* From a passphrase, generate a standard 128-bit WEP key using
* MD5 algorithm.
*
*/
char *nm_wireless_128bit_key_from_passphrase (const char *passphrase)
{
char md5_data[65];
unsigned char digest[16];
int passphrase_len;
int i;
g_return_val_if_fail (passphrase != NULL, NULL);
passphrase_len = strlen (passphrase);
if (passphrase_len < 1)
return (NULL);
/* Get at least 64 bits */
for (i = 0; i < 64; i++)
md5_data [i] = passphrase [i % passphrase_len];
/* Null terminate md5 data-to-hash and hash it */
md5_data[64] = 0;
#ifdef HAVE_GCRYPT
gcry_md_hash_buffer (GCRY_MD_MD5, digest, md5_data, 64);
#else
gnome_keyring_md5_string (md5_data, digest);
#endif
return (nm_wireless_128bit_ascii_to_hex (digest));
}
/*
* nm_wireless_stats_to_percent
*
* Convert an iw_stats structure from a scan or the card into
* a magical signal strength percentage.
*
*/
int nm_wireless_qual_to_percent (const struct iw_quality *qual, const struct iw_quality *max_qual, const struct iw_quality *avg_qual)
{
int percent = -1;
int level_percent = -1;
g_return_val_if_fail (qual != NULL, -1);
g_return_val_if_fail (max_qual != NULL, -1);
g_return_val_if_fail (avg_qual != NULL, -1);
#if IW_QUAL_DEBUG
nm_debug ("QL: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X ** MAX: qual %d/%u/0x%X, level %d/%u/0x%X, noise %d/%u/0x%X",
(__s8)qual->qual, qual->qual, qual->qual, (__s8)qual->level, qual->level, qual->level, (__s8)qual->noise, qual->noise, qual->noise,
(__s8)max_qual->qual, max_qual->qual, max_qual->qual, (__s8)max_qual->level, max_qual->level, max_qual->level, (__s8)max_qual->noise, max_qual->noise, max_qual->noise);
#endif
/* Try using the card's idea of the signal quality first as long as it tells us what the max quality is.
* Drivers that fill in quality values MUST treat them as percentages, ie the "Link Quality" MUST be
* bounded by 0 and max_qual->qual, and MUST change in a linear fashion. Within those bounds, drivers
* are free to use whatever they want to calculate "Link Quality".
*/
if ((max_qual->qual != 0) && !(max_qual->updated & IW_QUAL_QUAL_INVALID) && !(qual->updated & IW_QUAL_QUAL_INVALID))
percent = (int)(100 * ((double)qual->qual / (double)max_qual->qual));
/* If the driver doesn't specify a complete and valid quality, we have two options:
*
* 1) dBm: driver must specify max_qual->level = 0, and have valid values for
* qual->level and (qual->noise OR max_qual->noise)
* 2) raw RSSI: driver must specify max_qual->level > 0, and have valid values for
* qual->level and max_qual->level
*
* This is the WEXT spec. If this interpretation is wrong, I'll fix it. Otherwise,
* If drivers don't conform to it, they are wrong and need to be fixed.
*/
if ( (max_qual->level == 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level == 0 */
&& !(qual->updated & IW_QUAL_LEVEL_INVALID) /* Must have valid qual->level */
&& ( ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID)) /* Must have valid max_qual->noise */
|| ((qual->noise > 0) && !(qual->updated & IW_QUAL_NOISE_INVALID))) /* OR valid qual->noise */
)
{
/* Absolute power values (dBm) */
/* Reasonable fallbacks for dumb drivers that don't specify either level. */
#define FALLBACK_NOISE_FLOOR_DBM -90
#define FALLBACK_SIGNAL_MAX_DBM -20
int max_level = FALLBACK_SIGNAL_MAX_DBM;
int noise = FALLBACK_NOISE_FLOOR_DBM;
int level = qual->level - 0x100;
level = CLAMP (level, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
if ((qual->noise > 0) && (!qual->updated & IW_QUAL_NOISE_INVALID))
noise = qual->noise - 0x100;
else if ((max_qual->noise > 0) && !(max_qual->updated & IW_QUAL_NOISE_INVALID))
noise = max_qual->noise - 0x100;
noise = CLAMP (noise, FALLBACK_NOISE_FLOOR_DBM, FALLBACK_SIGNAL_MAX_DBM);
/* A sort of signal-to-noise ratio calculation */
level_percent = (int)(100 - 70 *(
((double)max_level - (double)level) /
((double)max_level - (double)noise)));
#if IW_QUAL_DEBUG
nm_debug ("QL1: level_percent is %d. max_level %d, level %d, noise_floor %d.", level_percent, max_level, level, noise);
#endif
}
else if ((max_qual->level != 0) && !(max_qual->updated & IW_QUAL_LEVEL_INVALID) /* Valid max_qual->level as upper bound */
&& !(qual->updated & IW_QUAL_LEVEL_INVALID))
{
/* Relative power values (RSSI) */
int level = qual->level;
/* Signal level is relavtive (0 -> max_qual->level) */
level = CLAMP (level, 0, max_qual->level);
level_percent = (int)(100 * ((double)level / (double)max_qual->level));
#if IW_QUAL_DEBUG
nm_debug ("QL2: level_percent is %d. max_level %d, level %d.", level_percent, max_qual->level, level);
#endif
}
/* If the quality percent was 0 or doesn't exist, then try to use signal levels instead */
if ((percent < 1) && (level_percent >= 0))
percent = level_percent;
#if IW_QUAL_DEBUG
nm_debug ("QL: Final quality %% is %d (%d).", percent, CLAMP (percent, 0, 100));
#endif
return (CLAMP (percent, 0, 100));
}