guint32 nm_device_bt_get_capabilities (NMDeviceBt *self) { g_return_val_if_fail (self != NULL, NM_BT_CAPABILITY_NONE); g_return_val_if_fail (NM_IS_DEVICE_BT (self), NM_BT_CAPABILITY_NONE); return NM_DEVICE_BT_GET_PRIVATE (self)->capabilities; }
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); switch (prop_id) { case PROP_HW_ADDRESS: /* Construct only */ priv->bdaddr = g_ascii_strup (g_value_get_string (value), -1); if (!nm_utils_hwaddr_aton (priv->bdaddr, ARPHRD_ETHER, &priv->hw_addr)) nm_log_err (LOGD_HW, "Failed to convert BT address '%s'", priv->bdaddr); break; case PROP_BT_NAME: /* Construct only */ priv->name = g_value_dup_string (value); break; case PROP_BT_CAPABILITIES: /* Construct only */ priv->capabilities = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
/** * nm_device_bt_get_name: * @device: a #NMDeviceBt * * Gets the name of the #NMDeviceBt. * * Returns: the name of the device **/ const char * nm_device_bt_get_name (NMDeviceBt *device) { g_return_val_if_fail (NM_IS_DEVICE_BT (device), NULL); _nm_object_ensure_inited (NM_OBJECT (device)); return NM_DEVICE_BT_GET_PRIVATE (device)->name; }
/** * nm_device_bt_get_capabilities: * @device: a #NMDeviceBt * * Returns the Bluetooth device's usable capabilities. * * Returns: a combination of #NMBluetoothCapabilities **/ NMBluetoothCapabilities nm_device_bt_get_capabilities (NMDeviceBt *device) { g_return_val_if_fail (NM_IS_DEVICE_BT (device), NM_BT_CAPABILITY_NONE); _nm_object_ensure_inited (NM_OBJECT (device)); return NM_DEVICE_BT_GET_PRIVATE (device)->bt_capabilities; }
static const guint8 * get_hw_address (NMDevice *device, guint *out_len) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); *out_len = sizeof (priv->hw_addr); return priv->hw_addr; }
static void bluez_property_changed (DBusGProxy *proxy, const char *property, GValue *value, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); NMDeviceBt *self = NM_DEVICE_BT (user_data); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); gboolean connected; NMDeviceState state; const char *prop_str = "(unknown)"; if (G_VALUE_HOLDS_STRING (value)) prop_str = g_value_get_string (value); else if (G_VALUE_HOLDS_BOOLEAN (value)) prop_str = g_value_get_boolean (value) ? "true" : "false"; nm_log_dbg (LOGD_BT, "(%s): bluez property '%s' changed to '%s'", nm_device_get_iface (device), property, prop_str); if (strcmp (property, "Connected")) return; state = nm_device_get_state (device); connected = g_value_get_boolean (value); if (connected) { if (state == NM_DEVICE_STATE_CONFIG) { nm_log_dbg (LOGD_BT, "(%s): connected to the device", nm_device_get_iface (device)); priv->connected = TRUE; check_connect_continue (self); } } else { gboolean fail = FALSE; /* Bluez says we're disconnected from the device. Suck. */ if (nm_device_is_activating (device)) { nm_log_info (LOGD_BT, "Activation (%s/bluetooth): bluetooth link disconnected.", nm_device_get_iface (device)); fail = TRUE; } else if (state == NM_DEVICE_STATE_ACTIVATED) { nm_log_info (LOGD_BT, "(%s): bluetooth link disconnected.", nm_device_get_iface (device)); fail = TRUE; } if (fail) { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CARRIER); priv->connected = FALSE; } } }
static NMActStageReturn act_stage3_ip6_config_start (NMDevice *device, NMIP6Config **out_config, NMDeviceStateReason *reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMActStageReturn ret; if (priv->bt_type == NM_BT_CAPABILITY_DUN) { ret = nm_modem_stage3_ip6_config_start (NM_DEVICE_BT_GET_PRIVATE (device)->modem, device, NM_DEVICE_CLASS (nm_device_bt_parent_class), reason); } else ret = NM_DEVICE_CLASS (nm_device_bt_parent_class)->act_stage3_ip6_config_start (device, out_config, reason); return ret; }
static void dispose (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); g_clear_object (&priv->proxy); G_OBJECT_CLASS (nm_device_bt_parent_class)->dispose (object); }
static void finalize (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); g_free (priv->hw_address); g_free (priv->name); G_OBJECT_CLASS (nm_device_bt_parent_class)->finalize (object); }
static void constructed (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); priv->proxy = _nm_object_new_proxy (NM_OBJECT (object), NULL, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); register_properties (NM_DEVICE_BT (object)); }
static gboolean real_check_connection_compatible (NMDevice *device, NMConnection *connection, GError **error) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMSettingConnection *s_con; NMSettingBluetooth *s_bt; const GByteArray *array; char *str; int addr_match = FALSE; guint32 bt_type; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME)) { g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_CONNECTION_NOT_BT, "The connection was not a Bluetooth connection."); return FALSE; } s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH)); if (!s_bt) { g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INVALID, "The connection was not a valid Bluetooth connection."); return FALSE; } array = nm_setting_bluetooth_get_bdaddr (s_bt); if (!array || (array->len != ETH_ALEN)) { g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INVALID, "The connection did not contain a valid Bluetooth address."); return FALSE; } bt_type = get_connection_bt_type (connection); if (!(bt_type & priv->capabilities)) { g_set_error (error, NM_BT_ERROR, NM_BT_ERROR_CONNECTION_INCOMPATIBLE, "The connection was not compatible with the device's capabilities."); return FALSE; } str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", array->data[0], array->data[1], array->data[2], array->data[3], array->data[4], array->data[5]); addr_match = !strcmp (priv->bdaddr, str); g_free (str); return addr_match; }
static void device_state_changed (NMDevice *device, NMDeviceState new_state, NMDeviceState old_state, NMDeviceStateReason reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); if (priv->modem) nm_modem_device_state_changed (priv->modem, new_state, old_state, reason); }
static gboolean modem_find_timeout (gpointer user_data) { NMDeviceBt *self = NM_DEVICE_BT (user_data); NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0; nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_MODEM_NOT_FOUND); return FALSE; }
static gboolean is_available (NMDevice *dev) { NMDeviceBt *self = NM_DEVICE_BT (dev); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); /* PAN doesn't need ModemManager, so devices that support it are always available */ if (priv->capabilities & NM_BT_CAPABILITY_NAP) return TRUE; /* DUN requires ModemManager */ return priv->mm_running; }
static gboolean bt_connect_timeout (gpointer user_data) { NMDeviceBt *self = NM_DEVICE_BT (user_data); nm_log_dbg (LOGD_BT, "(%s): initial connection timed out", nm_device_get_iface (NM_DEVICE (self))); NM_DEVICE_BT_GET_PRIVATE (self)->timeout_id = 0; nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); return FALSE; }
static void constructed (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); G_OBJECT_CLASS (nm_device_bt_parent_class)->constructed (object); priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (NM_OBJECT (object)), NM_DBUS_SERVICE, nm_object_get_path (NM_OBJECT (object)), NM_DBUS_INTERFACE_DEVICE_BLUETOOTH); register_properties (NM_DEVICE_BT (object)); }
static void register_properties (NMDeviceBt *device) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); const NMPropertiesInfo property_info[] = { { NM_DEVICE_BT_HW_ADDRESS, &priv->hw_address }, { NM_DEVICE_BT_NAME, &priv->name }, { NM_DEVICE_BT_CAPABILITIES, &priv->bt_capabilities }, { NULL }, }; _nm_object_register_properties (NM_OBJECT (device), priv->proxy, property_info); }
static gboolean check_connection_available (NMDevice *device, NMConnection *connection) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); guint32 bt_type; bt_type = get_connection_bt_type (connection); if (!(bt_type & priv->capabilities)) return FALSE; /* DUN connections aren't available without ModemManager */ if (bt_type == NM_BT_CAPABILITY_DUN && priv->mm_running == FALSE) return FALSE; return TRUE; }
static void bluez_connect_cb (DBusGProxy *proxy, DBusGProxyCall *call_id, void *user_data) { NMDeviceBt *self = NM_DEVICE_BT (user_data); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); GError *error = NULL; char *device; if (dbus_g_proxy_end_call (proxy, call_id, &error, G_TYPE_STRING, &device, G_TYPE_INVALID) == FALSE) { nm_log_warn (LOGD_BT, "Error connecting with bluez: %s", error && error->message ? error->message : "(unknown)"); g_clear_error (&error); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); return; } if (!device || !strlen (device)) { nm_log_warn (LOGD_BT, "Invalid network device returned by bluez"); nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED); } if (priv->bt_type == NM_BT_CAPABILITY_DUN) { g_free (priv->rfcomm_iface); priv->rfcomm_iface = device; } else if (priv->bt_type == NM_BT_CAPABILITY_NAP) { nm_device_set_ip_iface (NM_DEVICE (self), device); g_free (device); } nm_log_dbg (LOGD_BT, "(%s): connect request successful", nm_device_get_iface (NM_DEVICE (self))); /* Stage 3 gets scheduled when Bluez says we're connected */ priv->have_iface = TRUE; check_connect_continue (self); }
static void init_dbus (NMObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); const NMPropertiesInfo property_info[] = { { NM_DEVICE_BT_HW_ADDRESS, &priv->hw_address }, { NM_DEVICE_BT_NAME, &priv->name }, { NM_DEVICE_BT_CAPABILITIES, &priv->bt_capabilities }, { NULL }, }; NM_OBJECT_CLASS (nm_device_bt_parent_class)->init_dbus (object); _nm_object_register_properties (object, NM_DBUS_INTERFACE_DEVICE_BLUETOOTH, property_info); }
static void modem_auth_result (NMModem *modem, GError *error, gpointer user_data) { NMDevice *device = NM_DEVICE (user_data); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; if (error) { nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_NO_SECRETS); } else { /* Otherwise, on success for GSM/CDMA secrets we need to schedule modem stage1 again */ g_return_if_fail (nm_device_get_state (device) == NM_DEVICE_STATE_NEED_AUTH); if (!modem_stage1 (NM_DEVICE_BT (device), priv->modem, &reason)) nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, reason); } }
static void nm_device_bt_init (NMDeviceBt *self) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); gboolean mm_running; priv->dbus_mgr = nm_dbus_manager_get (); priv->mm_watch_id = g_signal_connect (priv->dbus_mgr, NM_DBUS_MANAGER_NAME_OWNER_CHANGED, G_CALLBACK (mm_name_owner_changed), self); /* Initial check to see if ModemManager is running */ mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_OLD_DBUS_SERVICE); #if WITH_MODEM_MANAGER_1 if (!mm_running) mm_running = nm_dbus_manager_name_has_owner (priv->dbus_mgr, MM_NEW_DBUS_SERVICE); #endif set_mm_running (self, mm_running); }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); switch (prop_id) { case PROP_HW_ADDRESS: g_value_set_string (value, priv->bdaddr); break; case PROP_BT_NAME: g_value_set_string (value, priv->name); break; case PROP_BT_CAPABILITIES: g_value_set_uint (value, priv->capabilities); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void dispose (GObject *object) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); if (priv->timeout_id) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } if (priv->dbus_mgr && priv->mm_watch_id) { g_signal_handler_disconnect (priv->dbus_mgr, priv->mm_watch_id); priv->mm_watch_id = 0; } g_clear_object (&priv->dbus_mgr); g_clear_object (&priv->type_proxy); g_clear_object (&priv->dev_proxy); g_clear_object (&priv->modem); G_OBJECT_CLASS (nm_device_bt_parent_class)->dispose (object); }
static void set_mm_running (NMDeviceBt *self, gboolean running) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); gboolean old_available; if (priv->mm_running == running) return; nm_log_dbg (LOGD_BT, "(%s): ModemManager now %s", nm_device_get_iface (NM_DEVICE (self)), running ? "available" : "unavailable"); old_available = nm_device_is_available (NM_DEVICE (self)); priv->mm_running = running; handle_availability_change (self, old_available, NM_DEVICE_STATE_REASON_MODEM_MANAGER_UNAVAILABLE); /* Need to recheck available connections whenever MM appears or disappears, * since the device could be both DUN and NAP capable and thus may not * change state (which rechecks available connections) when MM comes and goes. */ if (priv->capabilities & NM_BT_CAPABILITY_DUN) nm_device_recheck_available_connections (NM_DEVICE (self)); }
static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (object); switch (prop_id) { case PROP_HW_ADDRESS: /* Construct only */ priv->bdaddr = g_ascii_strup (g_value_get_string (value), -1); break; case PROP_BT_NAME: /* Construct only */ priv->name = g_value_dup_string (value); break; case PROP_BT_CAPABILITIES: /* Construct only */ priv->capabilities = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static void check_connect_continue (NMDeviceBt *self) { NMDevice *device = NM_DEVICE (self); NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (self); gboolean pan = (priv->bt_type == NM_BT_CAPABILITY_NAP); gboolean dun = (priv->bt_type == NM_BT_CAPABILITY_DUN); if (!priv->connected || !priv->have_iface) return; nm_log_info (LOGD_BT, "Activation (%s %s/bluetooth) Stage 2 of 5 (Device Configure) " "successful. Will connect via %s.", nm_device_get_iface (device), nm_device_get_ip_iface (device), dun ? "DUN" : (pan ? "PAN" : "unknown")); /* Kill the connect timeout since we're connected now */ if (priv->timeout_id) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } if (pan) { /* Bluez says we're connected now. Start IP config. */ nm_device_activate_schedule_stage3_ip_config_start (device); } else if (dun) { /* Wait for ModemManager to find the modem */ priv->timeout_id = g_timeout_add_seconds (30, modem_find_timeout, self); nm_log_info (LOGD_BT | LOGD_MB, "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) " "waiting for modem to appear.", nm_device_get_iface (device)); } else g_assert_not_reached (); }
gboolean nm_device_bt_modem_added (NMDeviceBt *self, NMModem *modem, const char *driver) { NMDeviceBtPrivate *priv; const char *modem_iface; char *base; NMDeviceState state; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_DEVICE_BT (self), FALSE); g_return_val_if_fail (modem != NULL, FALSE); g_return_val_if_fail (NM_IS_MODEM (modem), FALSE); priv = NM_DEVICE_BT_GET_PRIVATE (self); modem_iface = nm_modem_get_iface (modem); g_return_val_if_fail (modem_iface != NULL, FALSE); if (!priv->rfcomm_iface) return FALSE; base = g_path_get_basename (priv->rfcomm_iface); if (strcmp (base, modem_iface)) { g_free (base); return FALSE; } g_free (base); /* Got the modem */ if (priv->timeout_id) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } /* Can only accept the modem in stage2, but since the interface matched * what we were expecting, don't let anything else claim the modem either. */ state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (self)); if (state != NM_DEVICE_STATE_CONFIG) { nm_log_warn (LOGD_BT | LOGD_MB, "(%s): modem found but device not in correct state (%d)", nm_device_get_iface (NM_DEVICE (self)), nm_device_get_state (NM_DEVICE (self))); return TRUE; } nm_log_info (LOGD_BT | LOGD_MB, "Activation (%s/bluetooth) Stage 2 of 5 (Device Configure) modem found.", nm_device_get_iface (NM_DEVICE (self))); if (priv->modem) { g_warn_if_reached (); g_object_unref (priv->modem); } priv->modem = g_object_ref (modem); g_signal_connect (modem, NM_MODEM_PPP_STATS, G_CALLBACK (ppp_stats), self); g_signal_connect (modem, NM_MODEM_PPP_FAILED, G_CALLBACK (ppp_failed), self); g_signal_connect (modem, NM_MODEM_PREPARE_RESULT, G_CALLBACK (modem_prepare_result), self); g_signal_connect (modem, NM_MODEM_IP4_CONFIG_RESULT, G_CALLBACK (modem_ip4_config_result), self); g_signal_connect (modem, NM_MODEM_NEED_AUTH, G_CALLBACK (modem_need_auth), self); /* Kick off the modem connection */ if (!modem_stage1 (self, modem, &reason)) nm_device_state_changed (NM_DEVICE (self), NM_DEVICE_STATE_FAILED, reason); return TRUE; }
static NMActStageReturn real_act_stage2_config (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); NMActRequest *req; NMDBusManager *dbus_mgr; DBusGConnection *g_connection; gboolean dun = FALSE; req = nm_device_get_act_request (device); g_assert (req); priv->bt_type = get_connection_bt_type (nm_act_request_get_connection (req)); if (priv->bt_type == NM_BT_CAPABILITY_NONE) { // FIXME: set a reason code return NM_ACT_STAGE_RETURN_FAILURE; } dbus_mgr = nm_dbus_manager_get (); g_connection = nm_dbus_manager_get_connection (dbus_mgr); g_object_unref (dbus_mgr); if (priv->bt_type == NM_BT_CAPABILITY_DUN) dun = TRUE; else if (priv->bt_type == NM_BT_CAPABILITY_NAP) dun = FALSE; else g_assert_not_reached (); priv->dev_proxy = dbus_g_proxy_new_for_name (g_connection, BLUEZ_SERVICE, nm_device_get_udi (device), BLUEZ_DEVICE_INTERFACE); if (!priv->dev_proxy) { // FIXME: set a reason code return NM_ACT_STAGE_RETURN_FAILURE; } /* Watch for BT device property changes */ dbus_g_object_register_marshaller (_nm_marshal_VOID__STRING_BOXED, G_TYPE_NONE, G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); dbus_g_proxy_add_signal (priv->dev_proxy, "PropertyChanged", G_TYPE_STRING, G_TYPE_VALUE, G_TYPE_INVALID); dbus_g_proxy_connect_signal (priv->dev_proxy, "PropertyChanged", G_CALLBACK (bluez_property_changed), device, NULL); priv->type_proxy = dbus_g_proxy_new_for_name (g_connection, BLUEZ_SERVICE, nm_device_get_udi (device), dun ? BLUEZ_SERIAL_INTERFACE : BLUEZ_NETWORK_INTERFACE); if (!priv->type_proxy) { // FIXME: set a reason code return NM_ACT_STAGE_RETURN_FAILURE; } nm_log_dbg (LOGD_BT, "(%s): requesting connection to the device", nm_device_get_iface (device)); /* Connect to the BT device */ dbus_g_proxy_begin_call_with_timeout (priv->type_proxy, "Connect", bluez_connect_cb, device, NULL, 20000, G_TYPE_STRING, dun ? BLUETOOTH_DUN_UUID : BLUETOOTH_NAP_UUID, G_TYPE_INVALID); if (priv->timeout_id) g_source_remove (priv->timeout_id); priv->timeout_id = g_timeout_add_seconds (30, bt_connect_timeout, device); return NM_ACT_STAGE_RETURN_POSTPONE; }
static void real_deactivate_quickly (NMDevice *device) { NMDeviceBtPrivate *priv = NM_DEVICE_BT_GET_PRIVATE (device); priv->have_iface = FALSE; priv->connected = FALSE; if (priv->bt_type == NM_BT_CAPABILITY_DUN) { if (priv->modem) { nm_modem_deactivate_quickly (priv->modem, device); /* Since we're killing the Modem object before it'll get the * state change signal, simulate the state change here. */ nm_modem_device_state_changed (priv->modem, NM_DEVICE_STATE_DISCONNECTED, NM_DEVICE_STATE_ACTIVATED, NM_DEVICE_STATE_REASON_USER_REQUESTED); g_object_unref (priv->modem); priv->modem = NULL; } if (priv->type_proxy) { /* Don't ever pass NULL through dbus; rfcomm_iface * might happen to be NULL for some reason. */ if (priv->rfcomm_iface) { dbus_g_proxy_call_no_reply (priv->type_proxy, "Disconnect", G_TYPE_STRING, priv->rfcomm_iface, G_TYPE_INVALID); } g_object_unref (priv->type_proxy); priv->type_proxy = NULL; } } else if (priv->bt_type == NM_BT_CAPABILITY_NAP) { if (priv->type_proxy) { dbus_g_proxy_call_no_reply (priv->type_proxy, "Disconnect", G_TYPE_INVALID); g_object_unref (priv->type_proxy); priv->type_proxy = NULL; } } if (priv->dev_proxy) { g_object_unref (priv->dev_proxy); priv->dev_proxy = NULL; } if (priv->timeout_id) { g_source_remove (priv->timeout_id); priv->timeout_id = 0; } priv->bt_type = NM_BT_CAPABILITY_NONE; g_free (priv->rfcomm_iface); priv->rfcomm_iface = NULL; if (NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate_quickly) NM_DEVICE_CLASS (nm_device_bt_parent_class)->deactivate_quickly (device); }