Fix a number of issues with the network-manager backend, including event loop recursion

pull/16/head
Timothy Pearson 12 years ago
parent 360d9e3c4a
commit 2277bfa0d6

@ -39,9 +39,12 @@
#define UPDATE_STRING_SETTING_IF_VALID(string, key, settingsMap) if (!string.isNull()) settingsMap[key] = convertDBUSDataToVariantData(TQT_DBusData::fromString(string)); \
else settingsMap.remove(key);
//#define NM_ASYNC_TIMEOUT_MS 1000
#define NM_ASYNC_TIMEOUT_MS 1000
// Give the user 5 minutes to authenticate to DBUS before timing out
#define NM_ASYNC_TIMEOUT_MS (5*60*1000)
#define NM_ASYNC_SECRETS_INTERACTION_TIMEOUT_MS (5*60*1000)
// #define WAIT_FOR_OPERATION_BEFORE_RETURNING 1
#define USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS 1
TQ_UINT32 reverseIPV4ByteOrder(TQ_UINT32 address) {
TQ_UINT32 ret;
@ -1341,6 +1344,17 @@ void TDENetworkConnectionManager_BackendNM_DBusSignalReceiver::dbusSignal(const
}
}
}
else if (interface == NM_DBUS_DEVICE_SERVICE) {
if (path == m_parent->m_dbusDeviceString) {
if (member == "StateChanged") {
// Demarshal data
TQ_UINT32 new_state = message[0].toUInt32();
TQ_UINT32 old_state = message[1].toUInt32();
TQ_UINT32 reason = message[2].toUInt32();
m_parent->internalProcessDeviceStateChanged(new_state, old_state, reason);
}
}
}
}
}
@ -1355,12 +1369,12 @@ TDENetworkConnectionManager_BackendNM::TDENetworkConnectionManager_BackendNM(TQS
d->m_vpnProxy = new DBus::VPNPluginProxy(NM_VPN_DBUS_PLUGIN_SERVICE, NM_VPN_DBUS_PLUGIN_PATH);
d->m_vpnProxy->setConnection(TQT_DBusConnection::systemBus());
TQString dbusDeviceString = deviceInterfaceString(macAddress);
if (dbusDeviceString != "") {
d->m_networkDeviceProxy = new DBus::DeviceProxy(NM_DBUS_SERVICE, dbusDeviceString);
d->m_dbusDeviceString = deviceInterfaceString(macAddress);
if (d->m_dbusDeviceString != "") {
d->m_networkDeviceProxy = new DBus::DeviceProxy(NM_DBUS_SERVICE, d->m_dbusDeviceString);
d->m_networkDeviceProxy->setConnection(TQT_DBusConnection::systemBus());
if (deviceType() == TDENetworkDeviceType::WiFi) {
d->m_wiFiDeviceProxy = new DBus::WiFiDeviceProxy(NM_DBUS_SERVICE, dbusDeviceString);
d->m_wiFiDeviceProxy = new DBus::WiFiDeviceProxy(NM_DBUS_SERVICE, d->m_dbusDeviceString);
d->m_wiFiDeviceProxy->setConnection(TQT_DBusConnection::systemBus());
}
}
@ -1428,7 +1442,16 @@ void TDENetworkConnectionManager_BackendNMPrivate::internalProcessVPNFailure(TQ_
void TDENetworkConnectionManager_BackendNMPrivate::internalProcessDeviceStateChanged(TQ_UINT32 newState, TQ_UINT32 oldState, TQ_UINT32 reason) {
Q_UNUSED(oldState)
Q_UNUSED(reason)
if (m_prevDeviceState == newState) return;
m_prevDeviceState = newState;
if (newState == NM_DEVICE_STATE_FAILED) {
// FIXME
// This should provide a plain-text interpretation of the NetworkManager-specific error code
m_parent->internalNetworkDeviceEvent(TDENetworkDeviceEventType::Failure, TQString("Connection attempt failed!<br>NetworkManager returned error %1.").arg(reason));
}
m_parent->internalNetworkDeviceStateChanged(nmDeviceStateToTDEDeviceState(newState), m_parent->m_macAddress);
}
@ -1475,7 +1498,7 @@ void TDENetworkConnectionManager_BackendNMPrivate::internalProcessWiFiProperties
}
}
else if (props.contains("Bitrate")) {
m_parent->internalNetworkDeviceEvent(TDENetworkDeviceEventType::BitRateChanged);
m_parent->internalNetworkDeviceEvent(TDENetworkDeviceEventType::BitRateChanged, TQString::null);
}
}
}
@ -1499,8 +1522,8 @@ TDENetworkDeviceType::TDENetworkDeviceType TDENetworkConnectionManager_BackendNM
else {
// Query NM for the device type
TQT_DBusError error;
TQString dbusDeviceString = deviceInterfaceString(m_macAddress);
DBus::DeviceProxy genericDevice(NM_DBUS_SERVICE, dbusDeviceString);
d->m_dbusDeviceString = deviceInterfaceString(m_macAddress);
DBus::DeviceProxy genericDevice(NM_DBUS_SERVICE, d->m_dbusDeviceString);
genericDevice.setConnection(TQT_DBusConnection::systemBus());
TDENetworkDeviceType::TDENetworkDeviceType ret = nmDeviceTypeToTDEDeviceType(genericDevice.getDeviceType(error));
if (error.isValid()) {
@ -1519,6 +1542,18 @@ TDENetworkConnectionType::TDENetworkConnectionType TDENetworkConnectionManager_B
TQ_UINT32 ret;
TQT_DBusError error;
#ifndef USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, dbusPath);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
TQT_DBusTQStringDataMap connectionSettingsMap;
ret = connectionSettings.GetSettings(connectionSettingsMap, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
if (ret) {
#else // USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, dbusPath);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
@ -1544,6 +1579,7 @@ TDENetworkConnectionType::TDENetworkConnectionType TDENetworkConnectionManager_B
TQT_DBusTQStringDataMap connectionSettingsMap = d->nmConnectionSettingsAsyncSettingsResponse[asyncCallID];
d->nmConnectionSettingsAsyncCallWaiting.remove(asyncCallID);
d->nmConnectionSettingsAsyncSettingsResponse.remove(asyncCallID);
#endif // USE_ASYNC_DBUS_CALLS
// Parse settings to find connection type
TQT_DBusTQStringDataMap::const_iterator it2;
@ -1766,6 +1802,18 @@ void TDENetworkConnectionManager_BackendNM::loadConnectionInformation() {
printf("[network-manager comm debug] %s\n\r", (*it).data()); fflush(stdout);
#endif // DEBUG_NETWORK_MANAGER_COMMUNICATIONS
#ifndef USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, (*it));
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
TQT_DBusTQStringDataMap connectionSettingsMap;
ret = connectionSettings.GetSettings(connectionSettingsMap, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
if (ret) {
#else // USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, (*it));
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
@ -1791,6 +1839,7 @@ void TDENetworkConnectionManager_BackendNM::loadConnectionInformation() {
TQT_DBusTQStringDataMap connectionSettingsMap = d->nmConnectionSettingsAsyncSettingsResponse[asyncCallID];
d->nmConnectionSettingsAsyncCallWaiting.remove(asyncCallID);
d->nmConnectionSettingsAsyncSettingsResponse.remove(asyncCallID);
#endif // USE_ASYNC_DBUS_CALLS
#ifdef DEBUG_NETWORK_MANAGER_COMMUNICATIONS
printf("[network-manager comm debug] received DBUS object structure map follows:\n\r"); fflush(stdout);
@ -2886,6 +2935,17 @@ bool TDENetworkConnectionManager_BackendNM::loadConnectionSecretsForGroup(TQStri
TQT_DBusTQStringDataMap connectionSecretsMap(TQT_DBusData::String);
ret = d->m_networkManagerSettings->GetConnectionByUuid(uuid, existingConnection, error);
if (ret) {
#ifndef USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, existingConnection);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
ret = connectionSettings.GetSecrets(group, connectionSecretsMap, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
if (ret) {
#else // USE_ASYNC_DBUS_CALLS
// Obtain connection secrets from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, existingConnection);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
@ -2900,7 +2960,7 @@ bool TDENetworkConnectionManager_BackendNM::loadConnectionSecretsForGroup(TQStri
// Wait for the asynchronous call to return...
d->nmConnectionSettingsAsyncCallWaiting[asyncCallID] = true;
TQTimer nmCallTimeoutTimer;
nmCallTimeoutTimer.start(NM_ASYNC_TIMEOUT_MS, TRUE);
nmCallTimeoutTimer.start(NM_ASYNC_SECRETS_INTERACTION_TIMEOUT_MS, TRUE);
while (d->nmConnectionSettingsAsyncCallWaiting[asyncCallID]) {
tqApp->processEvents();
if (!nmCallTimeoutTimer.isActive()) {
@ -2911,6 +2971,7 @@ bool TDENetworkConnectionManager_BackendNM::loadConnectionSecretsForGroup(TQStri
connectionSecretsMap = d->nmConnectionSettingsAsyncSettingsResponse[asyncCallID];
d->nmConnectionSettingsAsyncCallWaiting.remove(asyncCallID);
d->nmConnectionSettingsAsyncSettingsResponse.remove(asyncCallID);
#endif // USE_ASYNC_DBUS_CALLS
#ifdef DEBUG_NETWORK_MANAGER_COMMUNICATIONS
printf("[network-manager comm debug] received DBUS object structure map follows:\n\r"); fflush(stdout);
@ -3082,6 +3143,18 @@ bool TDENetworkConnectionManager_BackendNM::saveConnection(TDENetworkConnection*
existing = false;
ret = d->m_networkManagerSettings->GetConnectionByUuid(connection->UUID, existingConnection, error);
if (ret) {
#ifndef USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, existingConnection);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
connectionSettingsMap;
ret = connectionSettings.GetSettings(connectionSettingsMap, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
if (ret) {
#else // USE_ASYNC_DBUS_CALLS
// Obtain connection settings from the path specified
DBus::ConnectionSettingsInterface connectionSettings(NM_DBUS_SERVICE, existingConnection);
connectionSettings.setConnection(TQT_DBusConnection::systemBus());
@ -3105,9 +3178,10 @@ bool TDENetworkConnectionManager_BackendNM::saveConnection(TDENetworkConnection*
}
}
connectionSettingsMap = d->nmConnectionSettingsAsyncSettingsResponse[asyncCallID];
existing = true;
d->nmConnectionSettingsAsyncCallWaiting.remove(asyncCallID);
d->nmConnectionSettingsAsyncSettingsResponse.remove(asyncCallID);
#endif // USE_ASYNC_DBUS_CALLS
existing = true;
}
}
@ -4571,20 +4645,29 @@ TDENetworkConnectionStatus::TDENetworkConnectionStatus TDENetworkConnectionManag
if ((d->m_networkManagerSettings) && (d->m_networkManagerProxy)) {
ret = d->m_networkManagerSettings->GetConnectionByUuid(uuid, existingConnection, error);
if (ret) {
TQString dbusDeviceString;
if (m_macAddress == "") {
dbusDeviceString = "/";
d->m_dbusDeviceString = "/";
}
else {
dbusDeviceString = deviceInterfaceString(m_macAddress);
d->m_dbusDeviceString = deviceInterfaceString(m_macAddress);
}
#ifndef USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
TQT_DBusObjectPath active_connection;
ret = d->m_networkManagerProxy->ActivateConnection(existingConnection, TQT_DBusObjectPath(d->m_dbusDeviceString.ascii()), TQT_DBusObjectPath("/"), active_connection, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
return checkConnectionStatus(uuid);
#else // USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
connect(d->m_networkManagerProxy, SIGNAL(ActivateConnectionAsyncReply(int, const TQT_DBusObjectPath&)), d, SLOT(processAddConnectionAsyncReply(int, const TQT_DBusObjectPath&)));
int asyncCallID;
ret = d->m_networkManagerProxy->ActivateConnectionAsync(asyncCallID, existingConnection, TQT_DBusObjectPath(dbusDeviceString.ascii()), TQT_DBusObjectPath("/"), error);
ret = d->m_networkManagerProxy->ActivateConnectionAsync(asyncCallID, existingConnection, TQT_DBusObjectPath(d->m_dbusDeviceString.ascii()), TQT_DBusObjectPath("/"), error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
#ifdef WAIT_FOR_OPERATION_BEFORE_RETURNING
if (ret) {
// Wait for the asynchronous call to return...
d->nmConnectionSettingsAsyncCallWaiting[asyncCallID] = true;
@ -4606,6 +4689,10 @@ TDENetworkConnectionStatus::TDENetworkConnectionStatus TDENetworkConnectionManag
PRINT_ERROR(error.name())
return checkConnectionStatus(uuid);
}
#else
return checkConnectionStatus(uuid);
#endif
#endif // USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
}
else {
PRINT_WARNING(TQString("connection for provided uuid '%1' was not found").arg(uuid));
@ -4740,13 +4827,20 @@ TDENetworkConnectionStatus::TDENetworkConnectionStatus TDENetworkConnectionManag
if ((d->m_networkManagerSettings) && (d->m_networkManagerProxy)) {
existingConnection = getActiveConnectionPath(uuid);
if (existingConnection.isValid()) {
TQString dbusDeviceString;
if (m_macAddress == "") {
dbusDeviceString = "/";
d->m_dbusDeviceString = "/";
}
else {
dbusDeviceString = deviceInterfaceString(m_macAddress);
d->m_dbusDeviceString = deviceInterfaceString(m_macAddress);
}
#ifndef USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
ret = d->m_networkManagerProxy->DeactivateConnection(existingConnection, error);
if (ret && error.isValid()) {
ret = 0;
PRINT_ERROR(error.name())
}
return checkConnectionStatus(uuid);
#else // USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
connect(d->m_networkManagerProxy, SIGNAL(DeactivateConnectionAsyncReply(int)), d, SLOT(processConnectionSettingsUpdateAsyncReply(int)));
int asyncCallID;
ret = d->m_networkManagerProxy->DeactivateConnectionAsync(asyncCallID, existingConnection, error);
@ -4754,6 +4848,7 @@ TDENetworkConnectionStatus::TDENetworkConnectionStatus TDENetworkConnectionManag
ret = 0;
PRINT_ERROR(error.name())
}
#ifdef WAIT_FOR_OPERATION_BEFORE_RETURNING
if (ret) {
// Wait for the asynchronous call to return...
d->nmConnectionSettingsAsyncCallWaiting[asyncCallID] = true;
@ -4774,6 +4869,10 @@ TDENetworkConnectionStatus::TDENetworkConnectionStatus TDENetworkConnectionManag
PRINT_ERROR(error.name())
return checkConnectionStatus(uuid);
}
#else
return checkConnectionStatus(uuid);
#endif
#endif // USE_ASYNC_DBUS_CONNECTION_COMMAND_CALLS
}
else {
PRINT_WARNING(TQString("connection for provided uuid '%1' was not found").arg(uuid));
@ -5014,11 +5113,11 @@ TDENetworkHWNeighborList* TDENetworkConnectionManager_BackendNM::siteSurvey() {
bool ret;
TDENetworkDeviceType::TDENetworkDeviceType myDeviceType = deviceType();
TQString dbusDeviceString = deviceInterfaceString(m_macAddress);
d->m_dbusDeviceString = deviceInterfaceString(m_macAddress);
clearTDENetworkHWNeighborList();
if (myDeviceType == TDENetworkDeviceType::WiFi) {
DBus::WiFiDeviceProxy wiFiDevice(NM_DBUS_SERVICE, dbusDeviceString);
DBus::WiFiDeviceProxy wiFiDevice(NM_DBUS_SERVICE, d->m_dbusDeviceString);
wiFiDevice.setConnection(TQT_DBusConnection::systemBus());
// FIXME
// Should call wiFiDevice.RequestScanAsync first to rescan all access points
@ -5176,7 +5275,7 @@ TQStringList TDENetworkConnectionManager_BackendNM::defaultNetworkDevices() {
}
}
TDENetworkConnectionManager_BackendNMPrivate::TDENetworkConnectionManager_BackendNMPrivate(TDENetworkConnectionManager_BackendNM* parent) : m_networkManagerProxy(NULL), m_networkManagerSettings(NULL), m_networkDeviceProxy(NULL), m_wiFiDeviceProxy(NULL), m_vpnProxy(NULL), nonReentrantCallActive(false), m_parent(parent) {
TDENetworkConnectionManager_BackendNMPrivate::TDENetworkConnectionManager_BackendNMPrivate(TDENetworkConnectionManager_BackendNM* parent) : m_networkManagerProxy(NULL), m_networkManagerSettings(NULL), m_networkDeviceProxy(NULL), m_wiFiDeviceProxy(NULL), m_vpnProxy(NULL), nonReentrantCallActive(false), m_parent(parent), m_prevDeviceState(-1) {
// Set up global signal handler
m_dbusSignalConnection = new TQT_DBusConnection(TQT_DBusConnection::systemBus());
m_dbusSignalReceiver = new TDENetworkConnectionManager_BackendNM_DBusSignalReceiver(this);

@ -101,6 +101,7 @@ class TDENetworkConnectionManager_BackendNMPrivate : public TQObject
NMAsyncSettingsResponseMap nmConnectionSettingsAsyncSettingsResponse;
NMAddConnectionAsyncResponseMap nmAddConnectionAsyncResponse;
bool nonReentrantCallActive;
TQString m_dbusDeviceString;
public slots:
void processConnectionSettingsAsyncReply(int, const TQT_DBusDataMap<TQString>&);
@ -122,6 +123,7 @@ class TDENetworkConnectionManager_BackendNMPrivate : public TQObject
TQMap<TQString, DBus::AccessPointProxy*> m_accessPointProxyList;
TQT_DBusConnection *m_dbusSignalConnection;
TDENetworkConnectionManager_BackendNM_DBusSignalReceiver *m_dbusSignalReceiver;
int m_prevDeviceState;
friend class TDENetworkConnectionManager_BackendNM_DBusSignalReceiver;
};

@ -2724,7 +2724,7 @@ TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQStr
else if (query == "ThermalControl") {
ret = TDEGenericDeviceType::ThermalControl;
}
else if (query == "BlueTooth") {
else if (query == "Bluetooth") {
ret = TDEGenericDeviceType::BlueTooth;
}
else if (query == "Bridge") {
@ -3215,6 +3215,11 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
)) {
if (!device) device = new TDEStorageDevice(TDEGenericDeviceType::Disk);
}
else if (devicetype == "host") {
if (devicesubsystem == "bluetooth") {
if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
}
}
else if (devicetype.isNull()) {
if (devicesubsystem == "acpi") {
// If the ACPI device exposes a system path ending in /PNPxxxx:yy, the device type can be precisely determined
@ -3265,9 +3270,6 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::TextIO);
}
}
else if (devicesubsystem == "bluetooth") {
if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::BlueTooth);
}
else if (devicesubsystem == "usb-serial") {
if (!device) device = new TDEGenericDevice(TDEGenericDeviceType::Serial);
}
@ -5288,7 +5290,7 @@ TQString TDEHardwareDevices::getFriendlyDeviceTypeStringFromType(TDEGenericDevic
ret = i18n("Thermal Control");
}
else if (query == TDEGenericDeviceType::BlueTooth) {
ret = i18n("BlueTooth");
ret = i18n("Bluetooth");
}
else if (query == TDEGenericDeviceType::Bridge) {
ret = i18n("Bridge");

@ -844,8 +844,8 @@ void TDENetworkConnectionManager::internalAccessPointStatusChanged(TDEMACAddress
emit(accessPointStatusChanged(BSSID, event));
}
void TDENetworkConnectionManager::internalNetworkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event) {
emit(networkDeviceEvent(event));
void TDENetworkConnectionManager::internalNetworkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event, TQString message) {
emit(networkDeviceEvent(event, message));
}
void TDENetworkConnectionManager::internalVpnEvent(TDENetworkVPNEventType::TDENetworkVPNEventType event, TQString message) {

@ -213,6 +213,7 @@ namespace TDENetworkVPNEventType {
namespace TDENetworkDeviceEventType {
enum TDENetworkDeviceEventType {
BitRateChanged,
Failure,
Other,
Last = Other
};
@ -1186,8 +1187,9 @@ class TDECORE_EXPORT TDENetworkConnectionManager : public TQObject
/**
* Emitted whenever a network device event occurs
* The event type that caused the signal is available in @param event
* @param message contains additional information if available
*/
void networkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event);
void networkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event, TQString message);
/**
* Emitted whenever a VPN-related event occurs
@ -1295,7 +1297,7 @@ class TDECORE_EXPORT TDENetworkConnectionManager : public TQObject
* @internal This method must be called by the network backend whenever a device event occurs
* It emits the appropriate signals to notify client applications of the network device event
*/
void internalNetworkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event);
void internalNetworkDeviceEvent(TDENetworkDeviceEventType::TDENetworkDeviceEventType event, TQString message);
/**
* @internal This method must be called by the network backend whenever a VPN event occurs

Loading…
Cancel
Save