2005-01-18 Dan Williams <dcbw@redhat.com>

* dhcpcd/client.c
		- Remove some debug messages
		- Wrap others in #ifdef DEBUG/#endif

	* src/NetworkManager.c
		- Remove some debug messages
		- Clarify some debug messages
		- Remove code related to old single-thread wireless scanning

	* src/NetworkManagerAP.[ch]
		- New AP property "last_seen" to track how recently an AP was
			found in a scan
		- Start using 'const' more in function arguments

	* src/NetworkManagerAPList.[ch]
		- (nm_ap_list_merge_scanned_ap): new, selectively update attributes
			of an AP found in an AP list from a source AP, or if not found
			in the list add the source AP
		- (nm_ap_list_combine): remove, no longer needed

	* src/NetworkManagerDevice.c
		- Each device now has a "worker" thread from start to end of its life.
			Scanning for wireless devices now happens in that thread,
			not in a single "wireless scanning thread" for all devices as
			previously.  Activation consists of adding an idle handler to the
			thread's main loop/context, which gets run at the next available
			opportunity.
		- Wireless scanning is also simplified, there is now only one list of
			access points per wireless device, and APs older than 60s are
			removed from the list.  Previously, we kept results for the last
			3 scans and merged whole lists, which was complicated.
		- Cleaned up activation debug messages.
		- Wireless activation and access-point search routines now use Open System
			authentication before trying Shared Key.
		- Removed some code in nm_device_update_best_ap() that could cause cards
			to loose their link to the access point.
		- Scanning now uses a backoff algorithm, where the inverval becomes
			progressively longer between scans when the list of scanned access
			points doesn't change.  A change will revert to the shortest scan
			interval (20s).

	* src/NetworkManagerWireless.[ch]
		- Remove code related to old single-thread wireless scanning


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@382 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2005-01-18 22:08:22 +00:00
parent 39851ae123
commit c9b41bb448
14 changed files with 522 additions and 525 deletions

View File

@@ -1,3 +1,49 @@
2005-01-18 Dan Williams <dcbw@redhat.com>
* dhcpcd/client.c
- Remove some debug messages
- Wrap others in #ifdef DEBUG/#endif
* src/NetworkManager.c
- Remove some debug messages
- Clarify some debug messages
- Remove code related to old single-thread wireless scanning
* src/NetworkManagerAP.[ch]
- New AP property "last_seen" to track how recently an AP was
found in a scan
- Start using 'const' more in function arguments
* src/NetworkManagerAPList.[ch]
- (nm_ap_list_merge_scanned_ap): new, selectively update attributes
of an AP found in an AP list from a source AP, or if not found
in the list add the source AP
- (nm_ap_list_combine): remove, no longer needed
* src/NetworkManagerDevice.c
- Each device now has a "worker" thread from start to end of its life.
Scanning for wireless devices now happens in that thread,
not in a single "wireless scanning thread" for all devices as
previously. Activation consists of adding an idle handler to the
thread's main loop/context, which gets run at the next available
opportunity.
- Wireless scanning is also simplified, there is now only one list of
access points per wireless device, and APs older than 60s are
removed from the list. Previously, we kept results for the last
3 scans and merged whole lists, which was complicated.
- Cleaned up activation debug messages.
- Wireless activation and access-point search routines now use Open System
authentication before trying Shared Key.
- Removed some code in nm_device_update_best_ap() that could cause cards
to loose their link to the access point.
- Scanning now uses a backoff algorithm, where the inverval becomes
progressively longer between scans when the list of scanned access
points doesn't change. A change will revert to the shortest scan
interval (20s).
* src/NetworkManagerWireless.[ch]
- Remove code related to old single-thread wireless scanning
2005-01-18 Colin Walters <walters@redhat.com>
* src/NetworkManagerDHCP.c (set_nameservers): Free and clear list

View File

@@ -422,12 +422,12 @@ int peekfd (dhcp_interface *iface, int sk, int min_data, struct timeval *end_tim
* to stop with iface->cease and check our end time.
*/
gettimeofday (&now, NULL);
syslog (LOG_INFO, "DHCP waiting for data, overall end_time = {%ds, %dus}\n", (int)end_time->tv_sec, (int)end_time->tv_usec);
/* syslog (LOG_INFO, "DHCP waiting for data, overall end_time = {%ds, %dus}\n", (int)end_time->tv_sec, (int)end_time->tv_usec);*/
while ((timeval_subtract (&diff, end_time, &now) == 0) && !iface->cease && (recv_data_len < min_data))
{
fd_set fs;
struct timeval wait = {1, 0};
syslog (LOG_INFO, "DHCP waiting for data of minimum size %d, remaining timeout = {%ds, %dus}\n", min_data, (int)diff.tv_sec, (int)diff.tv_usec);
/* syslog (LOG_INFO, "DHCP waiting for data of minimum size %d, remaining timeout = {%ds, %dus}\n", min_data, (int)diff.tv_sec, (int)diff.tv_usec);*/
FD_ZERO (&fs);
FD_SET (sk, &fs);
@@ -487,7 +487,9 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
/* Send the request, then wait for the reply for a certain period of time
* that increases with each failed request. Quit when we reach our end time though.
*/
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Starting request loop");
#endif
do
{
udpipMessage *udp_msg_recv = NULL;
@@ -506,7 +508,9 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
goto out;
/* Send the DHCP request */
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Sending request packet...");
#endif
do
{
int udp_send_len = 0;
@@ -524,7 +528,9 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
err = sendto (iface->sk, udp_send, udp_send_len, MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof (struct sockaddr));
if (iface->cease || ((err == -1) && (errno != EAGAIN)))
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: error sending, cease = %d, err = %d, errno = %d", iface->cease, err, errno);
#endif
err = iface->cease ? RET_DHCP_CEASED : RET_DHCP_ERROR;
goto out;
}
@@ -534,11 +540,15 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
if (timeval_subtract (&diff, &overall_end, &current) != 0)
{
err = RET_DHCP_TIMEOUT;
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Send timeout");
#endif
goto out;
}
} while ((err == -1) && (errno == EAGAIN));
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Sent request packet.");
#endif
/* Set up the future time at which point to stop waiting for data
* on our socket and try the request again. If that future point is
@@ -563,56 +573,71 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
char ethPacket[ETH_FRAME_LEN];
/* Wait for some kind of data to appear on the socket */
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Waiting for reply...");
#endif
if ((err = peekfd (iface, recv_sk, min_data_len, &recv_end)) != RET_DHCP_SUCCESS)
{
if (err == RET_DHCP_TIMEOUT)
break;
goto out;
}
syslog (LOG_INFO, "DHCP: Got some data to check for reply packet.");
gettimeofday (&current, NULL);
/* Ok, we allegedly have the data we need, so grab it from the queue */
o = sizeof (struct sockaddr_ll);
len = recvfrom (recv_sk, pkt_recv, ETH_FRAME_LEN, 0, (struct sockaddr *)&server_hw_addr, &o);
syslog (LOG_INFO, "DHCP: actual data length was %d", len);
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Got some data of length %d.", len);
#endif
if (len < (sizeof (struct iphdr) + sizeof (struct udphdr)))
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Data length failed minimum length check (should be %d, got %d)", (sizeof (struct iphdr) + sizeof (struct udphdr)), len);
#endif
continue;
}
ip_hdr = (struct iphdr *) pkt_recv;
if (!verify_checksum (NULL, 0, ip_hdr, sizeof (struct iphdr)))
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message had bad IP checksum, won't use it.");
#endif
continue;
}
if (ntohs (ip_hdr->tot_len) > len)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message had mismatch in length (IP header said %d, packet was really %d), won't use it.", ntohs (ip_hdr->tot_len), len);
#endif
continue;
}
len = ntohs (ip_hdr->tot_len);
if (ip_hdr->protocol != IPPROTO_UDP)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message was not not UDP (ip_hdr->protocol = %d, IPPROTO_UDP = %d), won't use it.", ip_hdr->protocol, IPPROTO_UDP);
#endif
continue;
}
udp_hdr = (struct udphdr *) (pkt_recv + sizeof (struct iphdr));
if (ntohs (udp_hdr->source) != DHCP_SERVER_PORT)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message's source port was not the DHCP server port number, won't use it.");
#endif
continue;
}
if (ntohs (udp_hdr->dest) != DHCP_CLIENT_PORT)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message's destination port was not the DHCP client port number, won't use it.");
#endif
continue;
}
@@ -624,22 +649,28 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
if (dhcp_msg_recv->xid != iface->xid)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message's XID does not match expected XID (message %d, expected %d), won't use it.", dhcp_msg_recv->xid, iface->xid);
#endif
free (dhcp_msg_recv);
continue;
}
if (dhcp_msg_recv->htype != ARPHRD_ETHER)
{
#ifdef DEBUG
if (DebugFlag)
syslog (LOG_DEBUG, "DHCP: Reply message's header type was not ARPHRD_ETHER (messgae %d, expected %d), won't use it.", dhcp_msg_recv->htype, ARPHRD_ETHER);
#endif
free (dhcp_msg_recv);
continue;
}
if (dhcp_msg_recv->op != DHCP_BOOTREPLY)
{
#ifdef DEBUG
syslog (LOG_INFO, "DHCP: Reply message was not a bootp/DHCP reply, won't use it.");
#endif
free (dhcp_msg_recv);
continue;
}
@@ -668,10 +699,12 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
if (reply_type == DHCP_NAK)
{
#ifdef DEBUG
if (iface->dhcp_options.val[dhcpMsg])
syslog (LOG_ERR, "DHCP: DHCP_NAK response received: %s.", (char *)iface->dhcp_options.val[dhcpMsg]);
else
syslog (LOG_ERR, "DHCP: DHCP_NAK response received.");
#endif
err = RET_DHCP_NAK;
goto out;
}
@@ -714,8 +747,8 @@ int dhcp_init (dhcp_interface *iface)
release_dhcp_options (iface);
#ifdef DEBUG
syslog (LOG_DEBUG, "ClassID = \"%s\"\n"
"ClientID = \"%u.%u.%u.%02X.%02X.%02X.%02X.%02X.%02X\"\n", iface->cls_id,
syslog (LOG_DEBUG, "ClassID = \"%s\"", iface->cls_id);
syslog (LOG_DEBUG, "ClientID = \"%u.%u.%u.%02X.%02X.%02X.%02X.%02X.%02X\"\n",
iface->cli_id[0], iface->cli_id[1], iface->cli_id[2],
iface->cli_id[3], iface->cli_id[4], iface->cli_id[5],
iface->cli_id[6], iface->cli_id[7], iface->cli_id[8]);

View File

@@ -124,7 +124,7 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
*/
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
{
syslog (LOG_INFO, "nm_create_device_and_add_to_list(): adding device '%s' (%s)",
syslog (LOG_INFO, "Adding device '%s' (%s) to our list.",
nm_device_get_iface (dev), nm_device_is_wireless (dev) ? "wireless" : "wired");
data->dev_list = g_slist_append (data->dev_list, dev);
@@ -202,7 +202,6 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
g_slist_free (element);
nm_data_mark_state_changed (data);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
break;
}
element = g_slist_next (element);
@@ -238,7 +237,7 @@ static void nm_hal_device_added (LibHalContext *ctx, const char *udi)
g_return_if_fail (data != NULL);
syslog( LOG_DEBUG, "nm_hal_device_added() called with udi = %s", udi );
syslog( LOG_DEBUG, "New device added (hal udi is '%s').", udi );
/* Sometimes the device's properties (like net.interface) are not set up yet,
* so this call will fail, and it will actually be added when hal sets the device's
@@ -262,7 +261,7 @@ static void nm_hal_device_removed (LibHalContext *ctx, const char *udi)
g_return_if_fail (data != NULL);
syslog( LOG_DEBUG, "nm_hal_device_removed() called with udi = %s", udi );
syslog( LOG_DEBUG, "Device removed (hal udi is '%s').", udi );
nm_remove_device_from_list (data, udi);
}
@@ -278,7 +277,7 @@ static void nm_hal_device_new_capability (LibHalContext *ctx, const char *udi, c
g_return_if_fail (data != NULL);
syslog( LOG_DEBUG, "nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );
/*syslog( LOG_DEBUG, "nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0)))
{
@@ -800,9 +799,7 @@ int main( int argc, char *argv[] )
/* Bring up the loopback interface. */
nm_system_enable_loopback ();
/* Create a watch function that monitors cards for link status (hal doesn't do
* this for wireless cards yet).
*/
/* Create a watch function that monitors cards for link status. */
link_source = g_timeout_source_new (5000);
g_source_set_callback (link_source, nm_link_state_monitor, nm_data, NULL);
link_source_id = g_source_attach (link_source, nm_data->main_context);
@@ -810,7 +807,7 @@ int main( int argc, char *argv[] )
if (become_daemon && daemon (0, 0) < 0)
{
syslog (LOG_ERR, "NetworkManager could not daemonize. errno = %d", errno);
exit (1);
exit (EXIT_FAILURE);
}
if (!nm_named_manager_start (nm_data->named, &error))
@@ -819,31 +816,15 @@ int main( int argc, char *argv[] )
exit (EXIT_FAILURE);
}
/* Start the wireless scanning thread and timeout */
if (!g_thread_create (nm_wireless_scan_worker, nm_data, FALSE, &error))
{
syslog (LOG_CRIT, "Could not start wireless scan worker thread. Exiting. (error: %s)", error ? error->message : "unknown");
if (error)
g_error_free (error);
exit (1);
}
/* Wheeee!!! */
syslog (LOG_NOTICE, "running mainloop...");
g_main_loop_run (nm_data->main_loop);
syslog (LOG_NOTICE, "exiting...");
/* Kill the watch functions */
g_source_remove (link_source_id);
/* Quit and wait for the scan thread */
g_main_loop_quit (nm_data->wscan_loop);
while (nm_data->wscan_thread_done == FALSE)
g_usleep (100);
/* Cleanup */
if (hal_shutdown (nm_data->hal_ctx) != 0)
syslog (LOG_NOTICE, "libhal shutdown failed");
syslog (LOG_NOTICE, "Error: libhal shutdown failed");
nm_data_free (nm_data);

View File

@@ -37,20 +37,22 @@ struct NMAccessPoint
double freq;
guint16 rate;
gboolean encrypted;
/* Non-scanned attributes */
gboolean invalid;
gboolean matched; /* used in ap list diffing */
gboolean trusted;
gboolean artificial; /* Whether or not the AP is from a scan */
gboolean user_created; /* Whether or not the AP was created by the user with "Create network..." */
GTimeVal last_seen; /* Last time the AP was seen in a scan */
/* Things from user prefs */
/* Things from user prefs/NetworkManagerInfo */
gboolean trusted;
char *enc_key;
NMEncKeyType enc_method;
GTimeVal timestamp;
GSList *user_addresses;
};
/*
* nm_ap_new
*
@@ -153,7 +155,7 @@ void nm_ap_unref (NMAccessPoint *ap)
* Get/set functions for timestamp
*
*/
const GTimeVal *nm_ap_get_timestamp (NMAccessPoint *ap)
const GTimeVal *nm_ap_get_timestamp (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, 0);
@@ -172,7 +174,7 @@ void nm_ap_set_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp)
* Get/set functions for essid
*
*/
char * nm_ap_get_essid (NMAccessPoint *ap)
char * nm_ap_get_essid (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NULL);
@@ -198,7 +200,7 @@ void nm_ap_set_essid (NMAccessPoint *ap, const char * essid)
* Get/set functions for encryption key
*
*/
char * nm_ap_get_enc_key_source (NMAccessPoint *ap)
char * nm_ap_get_enc_key_source (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NULL);
@@ -216,7 +218,7 @@ void nm_ap_set_enc_key_source (NMAccessPoint *ap, const char * key, NMEncKeyType
ap->enc_method = method;
}
char *nm_ap_get_enc_key_hashed (NMAccessPoint *ap)
char *nm_ap_get_enc_key_hashed (const NMAccessPoint *ap)
{
char *hashed = NULL;
char *source_key;
@@ -256,7 +258,7 @@ char *nm_ap_get_enc_key_hashed (NMAccessPoint *ap)
* Get/set functions for encrypted flag
*
*/
gboolean nm_ap_get_encrypted (NMAccessPoint *ap)
gboolean nm_ap_get_encrypted (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
@@ -275,7 +277,7 @@ void nm_ap_set_encrypted (NMAccessPoint *ap, gboolean encrypted)
* Get/set functions for address
*
*/
struct ether_addr * nm_ap_get_address (NMAccessPoint *ap)
struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NULL);
@@ -303,7 +305,7 @@ void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr)
* Get/set functions for mode (ie Ad-Hoc, Infrastructure, etc)
*
*/
NMNetworkMode nm_ap_get_mode (NMAccessPoint *ap)
NMNetworkMode nm_ap_get_mode (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, NETWORK_MODE_UNKNOWN);
@@ -322,7 +324,7 @@ void nm_ap_set_mode (NMAccessPoint *ap, const NMNetworkMode mode)
* Get/set functions for strength
*
*/
gint8 nm_ap_get_strength (NMAccessPoint *ap)
gint8 nm_ap_get_strength (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, 0);
@@ -341,7 +343,7 @@ void nm_ap_set_strength (NMAccessPoint *ap, const gint8 strength)
* Get/set functions for frequency
*
*/
double nm_ap_get_freq (NMAccessPoint *ap)
double nm_ap_get_freq (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, 0);
@@ -360,7 +362,7 @@ void nm_ap_set_freq (NMAccessPoint *ap, const double freq)
* Get/set functions for rate
*
*/
guint16 nm_ap_get_rate (NMAccessPoint *ap)
guint16 nm_ap_get_rate (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, 0);
@@ -381,7 +383,7 @@ void nm_ap_set_rate (NMAccessPoint *ap, guint16 rate)
* (by cancelling requests for WEP key, for example)
*
*/
gboolean nm_ap_get_invalid (NMAccessPoint *ap)
gboolean nm_ap_get_invalid (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, TRUE);
@@ -401,7 +403,7 @@ void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid)
* the ap list diffing functions to speed up the diff
*
*/
gboolean nm_ap_get_matched (NMAccessPoint *ap)
gboolean nm_ap_get_matched (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, TRUE);
@@ -421,7 +423,7 @@ void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched)
* 'trusted'
*
*/
gboolean nm_ap_get_trusted (NMAccessPoint *ap)
gboolean nm_ap_get_trusted (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
@@ -442,7 +444,7 @@ void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted)
* by the card or not
*
*/
gboolean nm_ap_get_artificial (NMAccessPoint *ap)
gboolean nm_ap_get_artificial (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
@@ -457,6 +459,26 @@ void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial)
}
/*
* Get/Set functions for how long ago the AP was last seen in a scan.
* APs older than a certain date are dropped from the list.
*
*/
const GTimeVal *nm_ap_get_last_seen (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
return (&ap->last_seen);
}
void nm_ap_set_last_seen (NMAccessPoint *ap, const GTimeVal *last_seen)
{
g_return_if_fail (ap != NULL);
ap->last_seen = *last_seen;
}
/*
* Get/Set functions to indicate that an access point is
* user-created, ie whether or not its a network filled with
@@ -464,7 +486,7 @@ void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial)
* wireless network.
*
*/
gboolean nm_ap_get_user_created (NMAccessPoint *ap)
gboolean nm_ap_get_user_created (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
@@ -483,7 +505,7 @@ void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created)
* Return the encryption method the user specified for this access point.
*
*/
const NMEncKeyType nm_ap_get_enc_method (NMAccessPoint *ap)
const NMEncKeyType nm_ap_get_enc_method (const NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, TRUE);
@@ -500,7 +522,7 @@ const NMEncKeyType nm_ap_get_enc_method (NMAccessPoint *ap)
* ap's actual list.
*
*/
GSList *nm_ap_get_user_addresses (NMAccessPoint *ap)
GSList *nm_ap_get_user_addresses (const NMAccessPoint *ap)
{
GSList *new = NULL;
GSList *elem = NULL;

View File

@@ -34,52 +34,55 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap);
void nm_ap_unref (NMAccessPoint *ap);
void nm_ap_ref (NMAccessPoint *ap);
const GTimeVal * nm_ap_get_timestamp (NMAccessPoint *ap);
const GTimeVal * nm_ap_get_timestamp (const NMAccessPoint *ap);
void nm_ap_set_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp);
char * nm_ap_get_essid (NMAccessPoint *ap);
char * nm_ap_get_essid (const NMAccessPoint *ap);
void nm_ap_set_essid (NMAccessPoint *ap, const char *essid);
char * nm_ap_get_enc_key_source (NMAccessPoint *ap);
char * nm_ap_get_enc_key_hashed (NMAccessPoint *ap);
char * nm_ap_get_enc_key_source (const NMAccessPoint *ap);
char * nm_ap_get_enc_key_hashed (const NMAccessPoint *ap);
void nm_ap_set_enc_key_source (NMAccessPoint *ap, const char *key, NMEncKeyType type);
gboolean nm_ap_get_encrypted (NMAccessPoint *ap);
gboolean nm_ap_get_encrypted (const NMAccessPoint *ap);
void nm_ap_set_encrypted (NMAccessPoint *ap, gboolean encrypted);
struct ether_addr * nm_ap_get_address (NMAccessPoint *ap);
struct ether_addr * nm_ap_get_address (const NMAccessPoint *ap);
void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr *addr);
NMNetworkMode nm_ap_get_mode (NMAccessPoint *ap);
NMNetworkMode nm_ap_get_mode (const NMAccessPoint *ap);
void nm_ap_set_mode (NMAccessPoint *ap, const NMNetworkMode mode);
gint8 nm_ap_get_strength (NMAccessPoint *ap);
gint8 nm_ap_get_strength (const NMAccessPoint *ap);
void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength);
double nm_ap_get_freq (NMAccessPoint *ap);
double nm_ap_get_freq (const NMAccessPoint *ap);
void nm_ap_set_freq (NMAccessPoint *ap, double freq);
guint16 nm_ap_get_rate (NMAccessPoint *ap);
guint16 nm_ap_get_rate (const NMAccessPoint *ap);
void nm_ap_set_rate (NMAccessPoint *ap, guint16 rate);
gboolean nm_ap_get_invalid (NMAccessPoint *ap);
gboolean nm_ap_get_invalid (const NMAccessPoint *ap);
void nm_ap_set_invalid (NMAccessPoint *ap, gboolean invalid);
gboolean nm_ap_get_matched (NMAccessPoint *ap);
gboolean nm_ap_get_matched (const NMAccessPoint *ap);
void nm_ap_set_matched (NMAccessPoint *ap, gboolean matched);
gboolean nm_ap_get_trusted (NMAccessPoint *ap);
gboolean nm_ap_get_trusted (const NMAccessPoint *ap);
void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted);
gboolean nm_ap_get_artificial (NMAccessPoint *ap);
gboolean nm_ap_get_artificial (const NMAccessPoint *ap);
void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial);
gboolean nm_ap_get_user_created (NMAccessPoint *ap);
const GTimeVal * nm_ap_get_last_seen (const NMAccessPoint *ap);
void nm_ap_set_last_seen (NMAccessPoint *ap, const GTimeVal *last_seen);
gboolean nm_ap_get_user_created (const NMAccessPoint *ap);
void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created);
const NMEncKeyType nm_ap_get_enc_method (NMAccessPoint *ap);
const NMEncKeyType nm_ap_get_enc_method (const NMAccessPoint *ap);
GSList * nm_ap_get_user_addresses (NMAccessPoint *ap);
GSList * nm_ap_get_user_addresses (const NMAccessPoint *ap);
void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
#endif

View File

@@ -291,12 +291,12 @@ NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const stru
/*
* nm_ap_list_update_network
* nm_ap_list_update_network_from_nmi
*
* Given a network ID, get its information from NetworkManagerInfo
*
*/
void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NMData *data)
void nm_ap_list_update_network_from_nmi (NMAccessPointList *list, const char *network, NMData *data)
{
NMAccessPoint *ap = NULL;
NMAccessPoint *list_ap = NULL;
@@ -332,12 +332,12 @@ void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NM
/*
* nm_ap_list_populate
* nm_ap_list_populate_from_nmi
*
* Populate an initial list of allowed access points
*
*/
void nm_ap_list_populate (NMAccessPointList *list, NMData *data)
void nm_ap_list_populate_from_nmi (NMAccessPointList *list, NMData *data)
{
char **networks;
int num_networks;
@@ -353,7 +353,7 @@ void nm_ap_list_populate (NMAccessPointList *list, NMData *data)
for (i = 0; i < num_networks; i++)
{
if (networks[i] && (strlen (networks[i]) > 0))
nm_ap_list_update_network (list, networks[i], data);
nm_ap_list_update_network_from_nmi (list, networks[i], data);
}
dbus_free_string_array (networks);
@@ -362,63 +362,41 @@ void nm_ap_list_populate (NMAccessPointList *list, NMData *data)
/*
* nm_ap_list_combine
* nm_ap_list_merge_scanned_ap
*
* Combine two access point lists into one. This is a simple OR operation, where each
* unique access point in either list is present in the final, combined list.
* Given an AP list and an access point, merge the access point into the list.
* If the AP is already in the list, merge just the /attributes/ together for that
* AP, if its not already in the list then just add it. This doesn't merge all
* attributes, just ones that are likely to be new from the scan.
*
* Returns: FALSE if the AP was not new and was merged
* TRUE if the ap was completely new
*
* NOTE: locks NMAccessPointList arguments
*/
NMAccessPointList * nm_ap_list_combine (NMAccessPointList *list1, NMAccessPointList *list2)
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap)
{
NMAccessPointList *final_list = NULL;
NMAPListIter *iter;
NMAccessPoint *ap;
NMAccessPoint *list_ap;
gboolean new = FALSE;
final_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
if (!final_list)
return (NULL);
g_return_val_if_fail (merge_ap != NULL, FALSE);
/* Add all APs in the first list */
if (list1 && (iter = nm_ap_list_iter_new (list1)))
if (!(list_ap = nm_ap_list_get_ap_by_address (list, nm_ap_get_address (merge_ap))))
list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap));
if (list_ap)
{
while ((ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *new_ap = nm_ap_new_from_ap (ap);
if (new_ap)
{
nm_ap_list_append_ap (final_list, new_ap);
nm_ap_unref (new_ap);
/* Merge some properties on the AP that are new from scan to scan. */
nm_ap_set_encrypted (list_ap, nm_ap_get_encrypted (merge_ap));
nm_ap_set_last_seen (list_ap, nm_ap_get_last_seen (merge_ap));
}
}
nm_ap_list_iter_free (iter);
else
{
/* Add the whole AP, list takes ownership. */
nm_ap_list_append_ap (list, merge_ap);
new = TRUE;
}
/* Add all APs in the second list not already added from the first */
if (list2 && (iter = nm_ap_list_iter_new (list2)))
{
while ((ap = nm_ap_list_iter_next (iter)))
{
if (!nm_ap_list_get_ap_by_essid (final_list, nm_ap_get_essid (ap)))
{
NMAccessPoint *new_ap = nm_ap_new_from_ap (ap);
if (new_ap)
{
nm_ap_list_append_ap (final_list, new_ap);
nm_ap_unref (new_ap);
}
}
}
nm_ap_list_iter_free (iter);
}
if (nm_ap_list_is_empty (final_list))
{
nm_ap_list_unref (final_list);
final_list = NULL;
}
return (final_list);
return new;
}

View File

@@ -42,14 +42,15 @@ void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap);
NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network);
NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr);
void nm_ap_list_update_network (NMAccessPointList *list, const char *network, NMData *data);
void nm_ap_list_update_network_from_nmi (NMAccessPointList *list, const char *network, NMData *data);
void nm_ap_list_populate (NMAccessPointList *list, NMData *data);
void nm_ap_list_populate_from_nmi (NMAccessPointList *list, NMData *data);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
NMAccessPointList * nm_ap_list_combine (NMAccessPointList *list1, NMAccessPointList *list2);
void nm_ap_list_diff (NMData *data, NMDevice *dev, NMAccessPointList *old, NMAccessPointList *new);
gboolean nm_ap_list_merge_scanned_ap (NMAccessPointList *list, NMAccessPoint *merge_ap);
gboolean nm_ap_list_lock (NMAccessPointList *list);
void nm_ap_list_unlock (NMAccessPointList *list);

View File

@@ -1060,8 +1060,8 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &network, DBUS_TYPE_INVALID))
return (DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
syslog (LOG_DEBUG, "NetowrkManagerInfo triggered update of wireless network '%s'", network);
nm_ap_list_update_network (data->allowed_ap_list, network, data);
syslog (LOG_DEBUG, "NetworkManagerInfo triggered update of wireless network '%s'", network);
nm_ap_list_update_network_from_nmi (data->allowed_ap_list, network, data);
dbus_free (network);
handled = TRUE;
}

View File

@@ -41,8 +41,16 @@
/* Local static prototypes */
static gboolean mii_get_link (NMDevice *dev);
static gpointer nm_device_activation_worker (gpointer user_data);
static gpointer nm_device_worker (gpointer user_data);
static gboolean nm_device_activate (gpointer user_data);
static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_only_autoip);
static gboolean nm_device_wireless_scan (gpointer user_data);
typedef struct
{
NMDevice *dev;
struct wireless_scan_head scan_head;
} NMWirelessScanResults;
/******************************************************/
@@ -197,6 +205,7 @@ NMDevice *nm_get_device_by_iface (NMData *data, const char *iface)
NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev, NMDeviceType test_dev_type, NMData *app_data)
{
NMDevice *dev;
GError *error = NULL;
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (strlen (iface) > 0, NULL);
@@ -223,7 +232,7 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
return (NULL);
}
dev->refcount = 1;
dev->refcount = 2; /* 1 for starters, and another 1 for the worker thread */
dev->app_data = app_data;
dev->iface = g_strdup (iface);
dev->test_device = test_dev;
@@ -247,6 +256,8 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
iwrange range;
int sk;
dev->options.wireless.scan_interval = 20;
if (!(dev->options.wireless.scan_mutex = g_mutex_new ()))
{
g_free (dev->iface);
@@ -294,6 +305,20 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
nm_system_device_update_config_info (dev);
}
if (!g_thread_create (nm_device_worker, dev, FALSE, &error))
{
syslog (LOG_CRIT, "nm_device_new (): could not create device worker thread. (glib said: '%s')", error->message);
g_error_free (error);
/* When we get here, we've got a refcount of 2, one because the
* device starts off with a refcount of 1, and a second ref because
* so that it sticks around for the worker thread. So we have to unref twice.
*/
nm_device_unref (dev);
nm_device_unref (dev);
dev = NULL;
}
return (dev);
}
@@ -328,6 +353,8 @@ gboolean nm_device_unref (NMDevice *dev)
{
if (dev->loop)
g_main_loop_quit (dev->loop);
while (dev->worker_done == FALSE)
g_usleep (300);
if (nm_device_is_wireless (dev))
{
@@ -337,12 +364,7 @@ gboolean nm_device_unref (NMDevice *dev)
g_mutex_free (dev->options.wireless.scan_mutex);
if (dev->options.wireless.ap_list)
nm_ap_list_unref (dev->options.wireless.ap_list);
if (dev->options.wireless.cached_ap_list1)
nm_ap_list_unref (dev->options.wireless.cached_ap_list1);
if (dev->options.wireless.cached_ap_list2)
nm_ap_list_unref (dev->options.wireless.cached_ap_list2);
if (dev->options.wireless.cached_ap_list3)
nm_ap_list_unref (dev->options.wireless.cached_ap_list3);
if (dev->options.wireless.best_ap)
nm_ap_unref (dev->options.wireless.best_ap);
g_mutex_free (dev->options.wireless.best_ap_mutex);
}
@@ -359,6 +381,57 @@ gboolean nm_device_unref (NMDevice *dev)
}
/*
* nm_device_worker
*
* Main thread of the device.
*
*/
static gpointer nm_device_worker (gpointer user_data)
{
NMDevice *dev = (NMDevice *)user_data;
g_return_val_if_fail (dev != NULL, NULL);
dev->context = g_main_context_new ();
dev->loop = g_main_loop_new (dev->context, FALSE);
/* Do an initial wireless scan */
if (nm_device_is_wireless (dev))
{
GSource *source = g_idle_source_new ();
guint source_id = 0;
g_source_set_callback (source, nm_device_wireless_scan, dev, NULL);
source_id = g_source_attach (source, dev->context);
g_source_unref (source);
}
g_main_loop_run (dev->loop);
if (nm_device_config_get_use_dhcp (dev))
{
if (dev->renew_timeout > 0)
g_source_remove (dev->renew_timeout);
if (dev->rebind_timeout > 0)
g_source_remove (dev->rebind_timeout);
}
g_main_loop_unref (dev->loop);
g_main_context_unref (dev->context);
dev->loop = NULL;
dev->context = NULL;
dev->renew_timeout = 0;
dev->rebind_timeout = 0;
dev->worker_done = TRUE;
nm_device_unref (dev);
return NULL;
}
/*
* nm_device_get_app_data
*
@@ -829,6 +902,10 @@ void nm_device_set_frequency (NMDevice *dev, const double freq)
int sk;
int err;
/* HACK FOR NOW */
if (freq <= 0)
return;
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
@@ -883,9 +960,6 @@ void nm_device_set_frequency (NMDevice *dev, const double freq)
if (iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWFREQ, &wrq) != -1)
success = TRUE;
}
if (!success && (errno != EOPNOTSUPP) && (errno != EINVAL) && (errno != EIO)) /* prism54 cards return EIO sometimes */
syslog (LOG_ERR, "nm_device_set_frequency(): error setting frequency %f for device %s. errno = %d", freq, nm_device_get_iface (dev), errno);
}
close (sk);
@@ -1568,18 +1642,20 @@ void nm_device_activation_schedule_finish (NMDevice *dev, gboolean success)
/*
* nm_device_activation_begin
* nm_device_activation_schedule_start
*
* Spawn a new thread to handle device activation.
* Tell the device thread to begin activation.
*
* Returns: TRUE on success activation beginning
* FALSE on error beginning activation (bad params, couldn't create thread)
*
*/
gboolean nm_device_activation_begin (NMDevice *dev)
gboolean nm_device_activation_schedule_start (NMDevice *dev)
{
GError *error = NULL;
NMData *data = (NMData *)dev->app_data;
GSource *source = NULL;
guint source_id = 0;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (!dev->activating, TRUE); /* Return if activation has already begun */
@@ -1614,16 +1690,10 @@ gboolean nm_device_activation_begin (NMDevice *dev)
return (TRUE);
}
/* Ref the device so it doesn't go away while worker function is active */
nm_device_ref (dev);
if (!g_thread_create (nm_device_activation_worker, dev, FALSE, &error))
{
syslog (LOG_CRIT, "nm_device_activation_begin(): could not create activation worker thread.");
dev->activating = FALSE;
nm_device_unref (dev);
return (FALSE);
}
source = g_idle_source_new ();
g_source_set_callback (source, nm_device_activate, dev, NULL);
g_source_attach (source, dev->context);
g_source_unref (source);
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_ACTIVATING);
@@ -1873,19 +1943,23 @@ static gboolean AP_NEED_KEY (NMAccessPoint *ap)
{
char *s;
int len = 0;
char *essid;
g_return_val_if_fail (ap != NULL, FALSE);
essid = nm_ap_get_essid (ap);
if ((s = nm_ap_get_enc_key_source (ap)))
len = strlen (s);
if (!nm_ap_get_encrypted (ap))
syslog (LOG_NOTICE, "AP_NEED_KEY: access point is unencrypted, no key needed.");
syslog (LOG_NOTICE, "AP_NEED_KEY: access point '%s' is unencrypted, no key needed.", essid ? essid : "(null)");
else
{
if (!!nm_ap_get_enc_key_source (ap) && len)
syslog (LOG_NOTICE, "AP_NEED_KEY: access point is encrypted, and a key exists. No new key needed.");
syslog (LOG_NOTICE, "AP_NEED_KEY: access point '%s' is encrypted, and a key exists. No new key needed.", essid ? essid : "(null)");
else
syslog (LOG_NOTICE, "AP_NEED_KEY: access point is encrypted, but NO valid key exists. New key needed.");
syslog (LOG_NOTICE, "AP_NEED_KEY: access point '%s' is encrypted, but NO valid key exists. New key needed.", essid ? essid : "(null)");
}
if (nm_ap_get_encrypted (ap) && (!nm_ap_get_enc_key_source (ap) || !len))
return (TRUE);
@@ -1893,15 +1967,6 @@ static gboolean AP_NEED_KEY (NMAccessPoint *ap)
return (FALSE);
}
static gboolean HAVE_LINK (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
syslog (LOG_NOTICE, "HAVELINK: card appears %s a link to the access point.", nm_device_get_link_active (dev) ? "to have" : "NOT to have");
return (nm_device_get_link_active (dev));
}
/*
* nm_device_activate_wireless
@@ -1942,13 +2007,14 @@ get_ap:
while (!(best_ap = nm_device_get_best_ap (dev)))
{
dev->options.wireless.now_scanning = TRUE;
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): waiting for an access point.", nm_device_get_iface (dev));
syslog (LOG_DEBUG, "Activation (%s/wireless): waiting for an access point.", nm_device_get_iface (dev));
g_usleep (G_USEC_PER_SEC * 2);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_handle_cancel (dev))
{
/* Wierd as it may seem, we lock here to balance the unlock in out: */
dev->options.wireless.now_scanning = FALSE;
g_mutex_lock (dev->options.wireless.scan_mutex);
goto out;
}
@@ -1976,7 +2042,7 @@ get_ap:
}
else
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no link to '%s', or couldn't get configure interface for IP. Trying another access point.",
syslog (LOG_DEBUG, "Activation (%s/wireless): no link to '%s', or couldn't get configure interface for IP. Trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
@@ -1991,7 +2057,7 @@ get_ap:
}
else
{
NMDeviceAuthMethod auth = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
NMDeviceAuthMethod auth = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
gboolean need_key = AP_NEED_KEY (best_ap);
need_key:
@@ -2012,32 +2078,23 @@ get_ap:
need_key = FALSE;
/* Wait for the key to come back */
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): asking for user key.", nm_device_get_iface (dev));
syslog (LOG_DEBUG, "Activation (%s/wireless): asking for user key.", nm_device_get_iface (dev));
while (!dev->options.wireless.user_key_received && !dev->quit_activation)
g_usleep (G_USEC_PER_SEC / 2);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev));
syslog (LOG_DEBUG, "Activation (%s/wireless): user key received.", nm_device_get_iface (dev));
/* Done waiting, grab lock again */
g_mutex_lock (dev->options.wireless.scan_mutex);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_handle_cancel (dev))
{
/* User may have cancelled the key request, so we need to update our best AP again. */
nm_ap_unref (best_ap);
goto out;
}
/* User may have cancelled the key request, so we need to update our best AP again.
* However, if they didn't, since there will now be a key, we won't get back here for
* the same access point until the key is deemed incorrect below.
*/
nm_ap_unref (best_ap);
goto get_ap;
}
try_connect:
while (auth > NM_DEVICE_AUTH_METHOD_NONE)
while (auth != NM_DEVICE_AUTH_METHOD_NONE)
{
int ip_success = FALSE;
@@ -2063,19 +2120,19 @@ get_ap:
link = nm_device_wireless_wait_for_link (dev, nm_ap_get_essid (best_ap));
if (!link && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
if (!link && (auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM))
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Shared Key mode, trying Open System.",
syslog (LOG_DEBUG, "Activation (%s/wireless): no hardware link to '%s' in Open System mode, trying Shared Key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
/* Back down to Open System mode */
auth--;
/* Back down to Shared Key mode */
auth = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
continue;
}
else if (!link)
{
/* Must be in Open System mode and it still didn't work, so
* we'll invalidate the current "best" ap and get another one */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Open System mode, trying another access point.",
syslog (LOG_DEBUG, "Activation (%s/wireless): no hardware link to '%s' in Shared Key mode, trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
@@ -2083,18 +2140,18 @@ get_ap:
nm_device_update_best_ap (dev);
goto get_ap;
} ip_success = nm_device_activation_configure_ip (dev, FALSE);
if (!ip_success && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
if (!ip_success && (auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM))
{
/* Back down to Open System mode */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Shared Key mode, trying Open System.",
/* Back down to Shared Key mode */
syslog (LOG_DEBUG, "Activation (%s/wireless): could not get IP configuration info for '%s' in Open System mode, trying Shared Key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
auth--;
auth = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
continue;
}
else if (!ip_success)
{
/* Open System mode failed, we must have bad WEP key */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Open System mode, asking for new key.",
syslog (LOG_DEBUG, "Activation (%s/wireless): could not get IP configuration info for '%s' in Shared Key mode, asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
need_key = TRUE;
goto need_key;
@@ -2109,7 +2166,7 @@ get_ap:
if (success)
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): Success! Connected to access point '%s' and got an IP address.",
syslog (LOG_DEBUG, "Activation (%s/wireless): Success! Connected to access point '%s' and got an IP address.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_unref (best_ap);
}
@@ -2178,22 +2235,21 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_on
/*
* nm_device_activation_worker
* nm_device_activate
*
* Activate a device, done from the device's worker thread.
*
* Thread worker function to actually activate a device. We have to do it in another
* thread because things like dhclient block our main thread's event loop, and thus we
* wouldn't respond to dbus messages.
*/
static gpointer nm_device_activation_worker (gpointer user_data)
static gboolean nm_device_activate (gpointer user_data)
{
NMDevice *dev = (NMDevice *)user_data;
gboolean success = FALSE;
GMainContext *context = NULL;
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (dev->app_data != NULL, NULL);
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
syslog (LOG_DEBUG, "nm_device_activation_worker (%s) started...", nm_device_get_iface (dev));
syslog (LOG_DEBUG, "Activation (%s) started...", nm_device_get_iface (dev));
/* Bring the device up */
if (!nm_device_is_up (dev));
@@ -2221,23 +2277,22 @@ static gpointer nm_device_activation_worker (gpointer user_data)
}
else if (nm_device_is_wired (dev))
success = nm_device_activation_configure_ip (dev, FALSE);
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP returned = %d\n", nm_device_get_iface (dev), success);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_handle_cancel (dev))
goto out;
if (!success)
{
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP unsuccessful! Ending activation...\n", nm_device_get_iface (dev));
dev->activating = FALSE;
dev->quit_activation = FALSE;
goto out;
}
dev->activating = FALSE;
dev->quit_activation = FALSE;
if (success)
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP successful!\n", nm_device_get_iface (dev));
else
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP unsuccessful! Ending activation...\n", nm_device_get_iface (dev));
/* Setup DHCP timeouts if we need to renew/rebind at any point */
if (nm_device_config_get_use_dhcp (dev) && dev->dhcp_iface)
nm_device_dhcp_setup_timeouts (dev);
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_handle_cancel (dev))
@@ -2245,37 +2300,15 @@ static gpointer nm_device_activation_worker (gpointer user_data)
nm_device_activation_schedule_finish (dev, success);
syslog (LOG_INFO, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
/* Don't need to stick around for devices that use Static IP */
if (!nm_device_config_get_use_dhcp (dev) || !dev->dhcp_iface)
goto out;
/* We stick around if we need to renew the address with DHCP or something. */
dev->context = g_main_context_new ();
dev->loop = g_main_loop_new (context, FALSE);
nm_device_dhcp_setup_timeouts (dev);
g_main_loop_run (dev->loop);
g_source_remove (dev->renew_timeout);
g_source_remove (dev->rebind_timeout);
g_main_loop_unref (dev->loop);
g_main_context_unref (dev->context);
out:
dev->context = NULL;
dev->loop = NULL;
if (dev->dhcp_iface)
{
dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL;
}
nm_device_unref (dev);
syslog (LOG_DEBUG, "Activation (%s) ending thread.\n", nm_device_get_iface (dev));
return (NULL);
syslog (LOG_DEBUG, "Activation (%s) ended.\n", nm_device_get_iface (dev));
return FALSE;
}
@@ -2356,9 +2389,6 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
nm_device_activation_cancel (dev);
if (dev->loop)
g_main_loop_quit (dev->loop);
if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)
return (TRUE);
@@ -2376,6 +2406,7 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
nm_device_set_essid (dev, "");
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
dev->options.wireless.scan_interval = 20;
}
return (TRUE);
@@ -2784,13 +2815,6 @@ void nm_device_update_best_ap (NMDevice *dev)
/* If the best ap is NULL, bring device down and clear out its essid and AP */
nm_device_set_best_ap (dev, best_ap);
if (!best_ap)
{
nm_device_set_frequency (dev, 0);
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
nm_device_set_essid (dev, "");
nm_device_bring_up (dev);
}
}
@@ -2812,7 +2836,7 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
gboolean temp_enc = FALSE;
struct ether_addr addr;
NMAccessPoint *ap = NULL;
NMDeviceAuthMethod auths[3] = { NM_DEVICE_AUTH_METHOD_SHARED_KEY, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM, NM_DEVICE_AUTH_METHOD_NONE };
NMDeviceAuthMethod auths[3] = { NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM, NM_DEVICE_AUTH_METHOD_SHARED_KEY, NM_DEVICE_AUTH_METHOD_NONE };
int i;
NMNetworkMode mode = NETWORK_MODE_INFRA;
@@ -2840,8 +2864,8 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
if (!nm_ap_get_encrypted (ap))
{
auths[0] = NM_DEVICE_AUTH_METHOD_NONE;
auths[1] = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
auths[2] = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
auths[1] = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
auths[2] = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
}
}
@@ -2873,17 +2897,17 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
char *hashed_key = NULL;
switch (key_type)
{
case (NM_ENC_TYPE_128_BIT_PASSPHRASE):
case NM_ENC_TYPE_128_BIT_PASSPHRASE:
hashed_key = nm_wireless_128bit_key_from_passphrase (key);
break;
case (NM_ENC_TYPE_ASCII_KEY):
case NM_ENC_TYPE_ASCII_KEY:
if (strlen (key) <= 5)
hashed_key = nm_wireless_64bit_ascii_to_hex (key);
else
hashed_key = nm_wireless_128bit_ascii_to_hex (key);
break;
case (NM_ENC_TYPE_HEX_KEY):
case (NM_ENC_TYPE_UNKNOWN):
case NM_ENC_TYPE_HEX_KEY:
case NM_ENC_TYPE_UNKNOWN:
hashed_key = g_strdup (key);
break;
default:
@@ -2893,7 +2917,10 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
g_free (hashed_key);
}
else
{
/* We must have some encryption key to use, so fake something */
nm_device_set_enc_key (dev, "11111111111111111111111111", auths[i]);
}
break;
}
case NM_DEVICE_AUTH_METHOD_NONE:
@@ -3168,31 +3195,55 @@ static void nm_device_fake_ap_list (NMDevice *dev)
/*
* nm_device_process_scan_results
* nm_device_wireless_schedule_scan
*
* Process results of an iwscan() into our own AP lists
* Schedule a wireless scan in the /device's/ thread.
*
*/
void nm_device_process_scan_results (NMDevice *dev, wireless_scan_head *results)
static void nm_device_wireless_schedule_scan (NMDevice *dev)
{
wireless_scan *tmp_ap;
NMAccessPointList *old_ap_list = NULL;
NMAccessPointList *new_scan_list = NULL;
NMAccessPointList *earliest_scan = NULL;
gboolean have_blank_essids = FALSE;
NMAPListIter *iter;
NMAccessPoint *artificial_ap;
GSource *wscan_source;
guint wscan_source_id;
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
if (!results)
return;
wscan_source = g_timeout_source_new (dev->options.wireless.scan_interval * 1000);
g_source_set_callback (wscan_source, nm_device_wireless_scan, dev, NULL);
wscan_source_id = g_source_attach (wscan_source, dev->context);
g_source_unref (wscan_source);
}
/*
* nm_device_wireless_process_scan_results
*
* Process results of an iwscan() into our own AP lists. We're an idle function,
* but we never reschedule ourselves.
*
*/
static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
{
NMWirelessScanResults *results = (NMWirelessScanResults *)user_data;
NMDevice *dev;
wireless_scan *tmp_ap;
gboolean have_blank_essids = FALSE;
NMAPListIter *iter;
GTimeVal cur_time;
gboolean list_changed = FALSE;
g_return_val_if_fail (results != NULL, FALSE);
dev = results->dev;
if (!dev || !results->scan_head.result)
return FALSE;
/* Test devices get their info faked */
if (dev->test_device)
{
nm_device_fake_ap_list (dev);
return;
return FALSE;
}
/* Devices that don't support scanning have their pseudo-scanning done in
@@ -3201,17 +3252,11 @@ void nm_device_process_scan_results (NMDevice *dev, wireless_scan_head *results)
if (!nm_device_supports_wireless_scan (dev))
{
nm_device_do_pseudo_scan (dev);
return;
return FALSE;
}
/* Shift all previous cached scan results and dispose of the oldest one. */
earliest_scan = dev->options.wireless.cached_ap_list3;
dev->options.wireless.cached_ap_list3 = dev->options.wireless.cached_ap_list2;
dev->options.wireless.cached_ap_list2 = dev->options.wireless.cached_ap_list1;
dev->options.wireless.cached_ap_list1 = nm_ap_list_new (NETWORK_TYPE_DEVICE);
/* Iterate over scan results and pick a "most" preferred access point. */
tmp_ap = results->result;
/* Translate iwlib scan results to NM access point list */
tmp_ap = results->scan_head.result;
while (tmp_ap)
{
/* We need at least an ESSID or a MAC address for each access point */
@@ -3267,90 +3312,104 @@ void nm_device_process_scan_results (NMDevice *dev, wireless_scan_head *results)
if (tmp_ap->b.has_freq)
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
g_get_current_time (&cur_time);
nm_ap_set_last_seen (nm_ap, &cur_time);
/* Add the AP to the device's AP list */
nm_ap_list_append_ap (dev->options.wireless.cached_ap_list1, nm_ap);
if (nm_ap_list_merge_scanned_ap (nm_device_ap_list_get (dev), nm_ap))
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap, FALSE);
list_changed = TRUE;
}
nm_ap_unref (nm_ap);
}
tmp_ap = tmp_ap->next;
}
/* Compose the current access point list for the card based on the past two scans. This
* is to achieve some stability in the list, since cards don't necessarily return the same
* access point list each scan even if you are standing in the same place.
*/
old_ap_list = nm_device_ap_list_get (dev);
dev->options.wireless.ap_list = nm_ap_list_combine (dev->options.wireless.cached_ap_list1, dev->options.wireless.cached_ap_list2);
/* If any blank ESSID networks were detected in the current scan, try to match their
* AP MAC address with existing ones in previous scans, and if we get a match, copy the
* ESSID over to the newest scan list. This enures that we keep the known ESSID for that
* base station around as long as possible, which allows nm_device_update_best_ap() to do
* its job when the user wanted us to connect to a non-broadcasting network.
/* If we detected any blank-ESSID access points (ie don't broadcast their ESSID), then try to
* merge in ESSIDs that we have addresses for from user preferences/NetworkManagerInfo.
*/
if (have_blank_essids)
{
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), old_ap_list);
nm_ap_list_copy_essids_by_address (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
}
/* Once we have the list, copy in any relevant information from our Allowed list. */
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
/* Furthermore, if we have any "artificial" access points, ie ones that exist but don't show up in
* the scan for some reason, copy those over if we are associated with that access point right now.
* Some Cisco cards don't report non-ESSID-broadcasting access points in their scans even though
* the card associates with that AP just fine.
*/
if (old_ap_list && (iter = nm_ap_list_iter_new (old_ap_list)))
/* Walk the access point list and remove any access points older than 60s */
g_get_current_time (&cur_time);
if (nm_device_ap_list_get (dev) && (iter = nm_ap_list_iter_new (nm_device_ap_list_get (dev))))
{
NMAccessPoint *outdated_ap;
GSList *outdated_list = NULL;
GSList *elem;
char *essid = nm_device_get_essid (dev);
while (essid && (artificial_ap = nm_ap_list_iter_next (iter)))
while ((outdated_ap = nm_ap_list_iter_next (iter)))
{
/* Copy over the artificial AP from the old list to the new one if
* its the AP the card is currently associated with.
const GTimeVal *ap_time = nm_ap_get_last_seen (outdated_ap);
gboolean keep_around = FALSE;
/* We don't add an "artifical" APs to the outdated list if it is the
* one the card is currently associated with.
* Some Cisco cards don't report non-ESSID-broadcasting access points
* in their scans even though the card associates with that AP just fine.
*/
if ( nm_ap_get_essid (artificial_ap)
&& !strcmp (essid, nm_ap_get_essid (artificial_ap))
&& nm_ap_get_artificial (artificial_ap))
nm_ap_list_append_ap (nm_device_ap_list_get (dev), artificial_ap);
if ( nm_ap_get_essid (outdated_ap)
&& !strcmp (essid, nm_ap_get_essid (outdated_ap))
&& nm_ap_get_artificial (outdated_ap))
keep_around = TRUE;
/* Eh, we don't care about sub-second time resolution. */
if ((ap_time->tv_sec + 60 < cur_time.tv_sec) && !keep_around)
outdated_list = g_slist_append (outdated_list, outdated_ap);
}
nm_ap_list_iter_free (iter);
}
if (old_ap_list)
nm_ap_list_unref (old_ap_list);
/* Generate the "old" list from the 3rd and 4th oldest scans we've done */
old_ap_list = nm_ap_list_combine (dev->options.wireless.cached_ap_list3, earliest_scan);
/* Don't need the 4th scan around any more */
if (earliest_scan)
nm_ap_list_unref (earliest_scan);
/* Now do a diff of the old and new networks that we can see, and
* signal any changes over dbus.
/* Ok, now remove outdated ones. We have to do it after the lock
* because nm_ap_list_remove_ap() locks the list too.
*/
nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
if (old_ap_list)
nm_ap_list_unref (old_ap_list);
elem = outdated_list;
while (elem)
{
if ((outdated_ap = (NMAccessPoint *)(elem->data)))
{
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, outdated_ap, TRUE);
nm_ap_list_remove_ap (nm_device_ap_list_get (dev), outdated_ap);
list_changed = TRUE;
}
elem = g_slist_next (elem);
}
g_slist_free (outdated_list);
}
/* If the list changed, decrease our wireless scanning interval */
if (list_changed)
dev->options.wireless.scan_interval = 20;
else
dev->options.wireless.scan_interval = MIN (60, dev->options.wireless.scan_interval + 10);
return FALSE;
}
/*
* nm_device_do_wireless_scan
* nm_device_wireless_scan
*
* Get a list of access points this device can see.
*
*/
void nm_device_do_wireless_scan (NMDevice *dev, wireless_scan_head *results)
static gboolean nm_device_wireless_scan (gpointer user_data)
{
NMDevice *dev = (NMDevice *)(user_data);
int sk;
NMWirelessScanResults *scan_results = NULL;
g_return_if_fail (dev != NULL);
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
/* We don't really scan on test devices or devices that don't have scanning support */
if (dev->test_device || !nm_device_supports_wireless_scan (dev))
return;
return FALSE;
/* Grab the scan mutex */
if (nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__))
@@ -3366,12 +3425,14 @@ void nm_device_do_wireless_scan (NMDevice *dev, wireless_scan_head *results)
int err;
NMNetworkMode orig_mode = NETWORK_MODE_INFRA;
double orig_freq = 0;
int orig_rate;
int orig_rate = 0;
orig_mode = nm_device_get_mode (dev);
if (orig_mode == NETWORK_MODE_ADHOC)
{
orig_freq = nm_device_get_frequency (dev);
orig_rate = nm_device_get_bitrate (dev);
}
/* Must be in infrastructure mode during scan, otherwise we don't get a full
* list of scan results. Scanning doesn't work well in Ad-Hoc mode :(
@@ -3379,29 +3440,54 @@ void nm_device_do_wireless_scan (NMDevice *dev, wireless_scan_head *results)
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
nm_device_set_frequency (dev, 0);
err = iw_scan (sk, (char *)nm_device_get_iface (dev), WIRELESS_EXT, results);
scan_results = g_malloc0 (sizeof (NMWirelessScanResults));
err = iw_scan (sk, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &(scan_results->scan_head));
if ((err == -1) && (errno == ENODATA))
{
/* Card hasn't had time yet to compile full access point list.
* Give it some more time and scan again. If that doesn't work
* give up. Cards that need to scan more channels (Atheros 5212
* based cards, for example) need more time here.
* give up.
*/
g_usleep ((G_USEC_PER_SEC * nm_device_get_association_pause_value (dev)) / 2);
err = iw_scan (sk, (char *)nm_device_get_iface (dev), WIRELESS_EXT, results);
err = iw_scan (sk, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &(scan_results->scan_head));
if (err == -1)
results->result = NULL;
scan_results->scan_head.result = NULL;
}
else if ((err == -1) && (errno == ETIME))
syslog (LOG_ERR, "Warning: the wireless card (%s) requires too much time for scans. It needs to be fixed.\n", nm_device_get_iface (dev));
nm_device_set_mode (dev, orig_mode);
/* Only set frequency if ad-hoc mode */
if (orig_mode == NETWORK_MODE_ADHOC)
{
nm_device_set_frequency (dev, orig_freq);
nm_device_set_bitrate (dev, orig_rate);
}
close (sk);
}
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
}
/* We run the scan processing function from the main thread, since it must deliver
* messages over DBUS. Plus, that way the main thread is the only thread that has
* to modify the device's access point list.
*/
if ((scan_results != NULL) && (scan_results->scan_head.result != NULL))
{
guint scan_process_source_id = 0;
GSource *scan_process_source = g_idle_source_new ();
scan_results->dev = dev;
g_source_set_callback (scan_process_source, nm_device_wireless_process_scan_results, scan_results, NULL);
scan_process_source_id = g_source_attach (scan_process_source, dev->app_data->main_context);
g_source_unref (scan_process_source);
}
/* Make sure we reschedule ourselves so we keep scanning */
nm_device_wireless_schedule_scan (dev);
return FALSE;
}

View File

@@ -80,8 +80,6 @@ void nm_device_update_hw_address (NMDevice *dev);
void nm_device_get_ip6_address (NMDevice *dev);
gboolean nm_device_get_supports_wireless_scan (NMDevice *dev);
void nm_device_process_scan_results (NMDevice *dev, struct wireless_scan_head *results);
void nm_device_do_wireless_scan (NMDevice *dev, struct wireless_scan_head *results);
gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network, const char *key, NMEncKeyType key_type,
struct ether_addr *addr, gboolean *encrypted);
@@ -107,7 +105,7 @@ char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);
/* There is no function to get the WEP key since that's a slight security risk */
void nm_device_set_enc_key (NMDevice *dev, const char *key, NMDeviceAuthMethod auth_method);
gboolean nm_device_activation_begin (NMDevice *dev);
gboolean nm_device_activation_schedule_start(NMDevice *dev);
void nm_device_activation_cancel (NMDevice *dev);
gboolean nm_device_activation_should_cancel (NMDevice *dev);
gboolean nm_device_is_activating (NMDevice *dev);

View File

@@ -45,16 +45,8 @@ typedef struct NMDeviceWirelessOptions
struct iw_range range_info;
GMutex *scan_mutex;
/* We keep a couple lists around since wireless cards
* are a bit flakey and don't report the same access
* points every time. The lists get merged and diffed
* to figure out the "real" list, but the latest_ap_list
* is always the most-current scan.
*/
NMAccessPointList *ap_list;
NMAccessPointList *cached_ap_list1;
NMAccessPointList *cached_ap_list2;
NMAccessPointList *cached_ap_list3;
guint8 scan_interval; /* seconds */
NMAccessPoint *best_ap;
GMutex *best_ap_mutex;
@@ -110,6 +102,7 @@ struct NMDevice
GMainContext *context;
GMainLoop *loop;
gboolean worker_done;
guint renew_timeout;
guint rebind_timeout;

View File

@@ -130,8 +130,10 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data)
element = g_slist_next (element);
}
#if 0
syslog (LOG_NOTICE, "AUTO: Best wired device = %s, best wireless device = %s (%s)", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)",
best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)", best_wireless_dev ? nm_device_get_essid (best_wireless_dev) : "null" );
#endif
if (best_wireless_dev || best_wired_dev)
{
@@ -258,7 +260,7 @@ gboolean nm_policy_activation_finish (gpointer user_data)
nm_device_get_ap_address (dev, &addr);
nm_dbus_add_network_address (data->dbus_connection, NETWORK_TYPE_ALLOWED, nm_device_get_essid (dev), &addr);
}
syslog (LOG_INFO, "nm_state_modification_monitor() activated device %s", nm_device_get_iface (data->active_device));
syslog (LOG_INFO, "Activation (%s) successful, device activated.", nm_device_get_iface (data->active_device));
}
else
{
@@ -277,16 +279,16 @@ gboolean nm_policy_activation_finish (gpointer user_data)
/* Unref because nm_device_get_best_ap() refs it before returning. */
nm_ap_unref (ap);
}
syslog (LOG_INFO, "nm_state_modification_monitor() failed to activate device %s (%s)", nm_device_get_iface (dev), ap ? nm_ap_get_essid (ap) : "(none)");
syslog (LOG_INFO, "Activation (%s) failed for access point (%s)", nm_device_get_iface (dev), ap ? nm_ap_get_essid (ap) : "(none)");
}
else
syslog (LOG_INFO, "nm_state_modification_monitor() failed to activate device %s", nm_device_get_iface (dev));
syslog (LOG_INFO, "Activation (%s) failed.", nm_device_get_iface (dev));
nm_data_mark_state_changed (data);
}
out:
g_free (result);
nm_device_unref (dev);
g_free (result);
return FALSE;
}
@@ -317,7 +319,7 @@ gboolean nm_state_modification_monitor (gpointer user_data)
nm_ap_list_unref (data->allowed_ap_list);
data->allowed_ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED);
if (data->allowed_ap_list)
nm_ap_list_populate (data->allowed_ap_list, data);
nm_ap_list_populate_from_nmi (data->allowed_ap_list, data);
data->update_ap_lists = FALSE;
}
@@ -364,10 +366,9 @@ gboolean nm_state_modification_monitor (gpointer user_data)
if (best_dev)
{
/* Begin activation on the new device */
syslog (LOG_INFO, "nm_state_modification_monitor(): beginning activation for device '%s'", nm_device_get_iface (best_dev));
nm_device_ref (best_dev);
data->active_device = best_dev;
nm_device_activation_begin (data->active_device);
nm_device_activation_schedule_start (data->active_device);
/* nm_policy_get_best_device() signals us that the user forced
* a device upon us and that we should lock the active device.

View File

@@ -191,139 +191,3 @@ int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual)
return (percent);
}
/*
* nm_wireless_process_scan_results
*
* Run from main thread to hand scan results off to each device
* for processing.
*
*/
static gboolean nm_wireless_process_scan_results (gpointer user_data)
{
GSList *results = (GSList *)user_data;
GSList *elem = NULL;
if (!results)
return FALSE;
elem = results;
while (elem)
{
NMWirelessScanResults *res = (NMWirelessScanResults *)(elem->data);
nm_device_process_scan_results (res->dev, &(res->results));
/* Release the scan results */
nm_dispose_scan_results (res->results.result);
nm_device_unref (res->dev);
g_free (res);
elem->data = NULL;
elem = g_slist_next (elem);
}
g_slist_free (results);
return FALSE;
}
/*
* nm_wireless_scan_monitor
*
* Called every 10s to get a list of access points from the hardware. When its got
* the list, it schedules an idle handler in the main thread's event loop to actually
* integrate the scan results into the NMDevice's access point list.
*
*/
static gboolean nm_wireless_scan_monitor (gpointer user_data)
{
NMData *data = (NMData *)user_data;
GSList *element;
NMDevice *dev;
GSList *scan_results = NULL;
g_return_val_if_fail (data != NULL, TRUE);
/* We don't want to lock the device list for the entire duration of the scanning process
* for all cards. Scanning can take quite a while. Therefore, we grab a list of the devices
* and ref each one, then release the device list lock, perform scanning, and pass that list
* to the idle handler in the main thread, along iwth the scanning results.
*/
if (!nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
{
syslog (LOG_ERR, "nm_wireless_scan_monitor() could not acquire device list mutex." );
return (TRUE);
}
element = data->dev_list;
while (element)
{
if ((dev = (NMDevice *)(element->data)) && nm_device_is_wireless (dev))
{
NMWirelessScanResults *scan_res = g_malloc0 (sizeof (NMWirelessScanResults));
nm_device_ref (dev);
scan_res->dev = dev;
scan_results = g_slist_append (scan_results, scan_res);
}
element = g_slist_next (element);
}
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
/* Okay, do the actual scanning now. */
element = scan_results;
while (element)
{
NMWirelessScanResults *res = (NMWirelessScanResults *)(element->data);
nm_device_do_wireless_scan (res->dev, &(res->results));
element = g_slist_next (element);
}
/* Schedule an idle handler in the main thread to process the scan results */
if (scan_results)
{
guint scan_process_source_id = 0;
GSource *scan_process_source = g_idle_source_new ();
g_source_set_callback (scan_process_source, nm_wireless_process_scan_results, scan_results, NULL);
scan_process_source_id = g_source_attach (scan_process_source, data->main_context);
g_source_unref (scan_process_source);
}
return (TRUE);
}
/*
* nm_wireless_scan_worker
*
* Worker thread main function to handle wireless scanning.
*
*/
gpointer nm_wireless_scan_worker (gpointer user_data)
{
NMData *data = (NMData *)user_data;
guint wscan_source_id = 0;
GSource *wscan_source = NULL;
if (!data)
return NULL;
wscan_source = g_timeout_source_new (20000);
g_source_set_callback (wscan_source, nm_wireless_scan_monitor, data, NULL);
wscan_source_id = g_source_attach (wscan_source, data->wscan_ctx);
g_source_unref (wscan_source);
/* Do an initial scan */
nm_wireless_scan_monitor (user_data);
g_main_loop_run (data->wscan_loop);
g_source_remove (wscan_source_id);
data->wscan_thread_done = TRUE;
return NULL;
}

View File

@@ -28,19 +28,10 @@
#include "NetworkManagerAPList.h"
typedef struct
{
NMDevice *dev;
struct wireless_scan_head results;
} NMWirelessScanResults;
char * nm_wireless_64bit_ascii_to_hex (const unsigned char *ascii);
char * nm_wireless_128bit_ascii_to_hex (const unsigned char *ascii);
char * nm_wireless_128bit_key_from_passphrase (const char *passphrase);
int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual);
gpointer nm_wireless_scan_worker (gpointer user_data);
#endif