Everyone -- Thanks for the replies. I updated the killswitch patch. If you could test it, it should log messages about the device going down with nm_info("Killswitch activated"). As I said before, I cannot test it because I do not have a dell laptop. Dan: I left the mutexes in, just in case. Can't hurt, right (if it can, I will remove it)? -- Benjamin Kreuter
Index: src/NetworkManager.c =================================================================== --- src/NetworkManager.c (revision 2587) +++ src/NetworkManager.c (working copy) @@ -274,7 +274,38 @@ } +int killswitch_exists; +void nm_poll_killswitchs(gpointer); + /* + * nm_add_killswitch_device + * + * Adds a killswitch device to the list + * + */ +void nm_add_killswitch_device(NMData * data, char * udi) +{ + /* Attempt to acquire mutex for killswitch list addition. If acquire fails, + * just ignore the device addition entirely. + */ + if (nm_try_acquire_mutex (data->killswitch_list_mutex, __FUNCTION__)) + { + data->killswitch_list = g_slist_append (data->killswitch_list, udi); + nm_unlock_mutex (data->killswitch_list_mutex, __FUNCTION__); + + if(killswitch_exists == 0) + { + g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 5000, &nm_poll_killswitchs, nm_data, NULL); + killswitch_exists = -1; + } + } + else + { + nm_warning ("could not acquire killswitch list mutex." ); + } +} + +/* * nm_hal_device_new_capability * */ @@ -296,8 +327,45 @@ g_free (iface); } } + if(capability && (strcmp(capability, "killswitch") == 0)) + { + nm_add_killswitch_device(data, udi); + } } +void nm_poll_killswitchs(gpointer _data) +{ + NMData * data = (NMData *)_data; + DBusMessage * message; + DBusConnection * connection = data->dbus_connection; + DBusError error; + GSList * elt; + NMDevice * dev; + nm_lock_mutex (data->killswitch_list_mutex, __FUNCTION__); + for (elt = data->killswitch_list; elt; elt = g_slist_next (elt)) + { + int status; + message = dbus_message_new_method_call("org.freedesktop.Hal.Device.KillSwitch", elt->data, "org.freedesktop.Hal.Device.KillSwitch", "GetPower"); + message = dbus_connection_send_with_reply_and_block(connection, message, 500, &error); + if(dbus_error_is_set(&error)) + { + nm_warning("Could not poll killswitch: ", error.message); + dbus_error_free(&error); + } + else + { + dbus_message_get_args(message, &error, DBUS_TYPE_UINT32, &status, DBUS_TYPE_INVALID); + if(status > 0) + { + // Switch is on, deactivate device + nm_info("Killswitch activated"); + dev = nm_get_device_interface_from_hal(data->hal_ctx, elt->data); + nm_device_deactivate(dev); + } + } + } + nm_unlock_mutex (data->killswitch_list_mutex, __FUNCTION__); +} /* * nm_add_initial_devices @@ -309,8 +377,8 @@ { char ** net_devices; int num_net_devices; - int i; DBusError error; + int i; g_return_if_fail (data != NULL); @@ -340,7 +408,41 @@ libhal_free_string_array (net_devices); } +void nm_add_initial_killswitch_devices(NMData * data) +{ + char ** killswitchs; + int num_killswitch_devices; + int i; + DBusError error; + killswitch_exists = 0; + g_return_if_fail (data != NULL); + dbus_error_init (&error); + killswitchs = libhal_find_device_by_capability(data->hal_ctx, "killswitch", &num_killswitch_devices, &error); + if(dbus_error_is_set(&error)) + { + nm_warning("could not find killswitch devices: %s", error.message); + dbus_error_free(&error); + } + + if(killswitchs) + { + for(i = 0; i < num_killswitch_devices; i++) + { + char * dev; + if((dev = nm_get_device_interface_from_hal(data->hal_ctx, killswitchs[i]))) + { + if(strcmp(libhal_device_get_property_string(data->hal_ctx, killswitchs[i], "killswitch.type", NULL), "wlan") == 0) nm_add_killswitch_device(data, killswitchs[i]); + g_free(dev); + } + } +// polling_thread = g_thread_create(nm_poll_killswitchs, data, 0, NULL); + killswitch_exists = -1; + } + libhal_free_string_array (killswitchs); +} + + /* * nm_state_change_signal_broadcast * @@ -448,7 +550,8 @@ /* Initialize the device list mutex to protect additions/deletions to it. */ data->dev_list_mutex = g_mutex_new (); data->dialup_list_mutex = g_mutex_new (); - if (!data->dev_list_mutex || !data->dialup_list_mutex) + data->killswitch_list_mutex = g_mutex_new(); + if (!data->dev_list_mutex || !data->dialup_list_mutex || !data->killswitch_list_mutex) { nm_data_free (data); nm_warning ("could not initialize data structure locks."); @@ -456,6 +559,7 @@ } nm_register_mutex_desc (data->dev_list_mutex, "Device List Mutex"); nm_register_mutex_desc (data->dialup_list_mutex, "DialUp List Mutex"); + nm_register_mutex_desc (data->killswitch_list_mutex, "Killswitch List Mutex"); /* Initialize the access point lists */ data->allowed_ap_list = nm_ap_list_new (NETWORK_TYPE_ALLOWED); @@ -812,6 +916,12 @@ /* Get modems, ISDN, and so on's configuration from the system */ nm_data->dialup_list = nm_system_get_dialup_config (); + /* Initialize killswitchs */ + nm_add_initial_killswitch_devices(nm_data); + + /* Add killswitch poll if it is needed */ + if(killswitch_exists) g_timeout_add_full(G_PRIORITY_DEFAULT_IDLE, 5000, &nm_poll_killswitchs, nm_data, NULL); + /* Run the main loop */ nm_policy_schedule_device_change_check (nm_data); nm_schedule_state_change_signal_broadcast (nm_data); Index: src/NetworkManagerMain.h =================================================================== --- src/NetworkManagerMain.h (revision 2587) +++ src/NetworkManagerMain.h (working copy) @@ -90,6 +90,10 @@ GSList * dialup_list; GMutex * dialup_list_mutex; + /* Killswitch list */ + GSList * killswitch_list; + GMutex * killswitch_list_mutex; + struct NMAccessPointList *allowed_ap_list; struct NMAccessPointList *invalid_ap_list; } NMData;
Attachment:
pgpgdcFn7BdXJ.pgp
Description: PGP signature