static void set_current_nsp (NMDeviceWimax *self, NMWimaxNsp *new_nsp) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMWimaxNsp *old_nsp; gboolean path_changed = FALSE; old_nsp = priv->current_nsp; priv->current_nsp = NULL; if (new_nsp) priv->current_nsp = g_object_ref (new_nsp); if (old_nsp && new_nsp) { path_changed = (g_strcmp0 (nm_wimax_nsp_get_dbus_path (old_nsp), nm_wimax_nsp_get_dbus_path (new_nsp)) != 0); } /* Only notify if it's really changed */ if (old_nsp != new_nsp || path_changed) g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); if (old_nsp) g_object_unref (old_nsp); }
static void set_current_nsp (NMDeviceWimax *self, NMWimaxNsp *new_nsp) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMWimaxNsp *old_nsp; char *old_path = NULL; old_nsp = priv->current_nsp; if (old_nsp) { old_path = g_strdup (nm_wimax_nsp_get_dbus_path (old_nsp)); priv->current_nsp = NULL; } if (new_nsp) priv->current_nsp = g_object_ref (new_nsp); if (old_nsp) g_object_unref (old_nsp); /* Only notify if it's really changed */ if ( (!old_path && new_nsp) || (old_path && !new_nsp) || (old_path && new_nsp && strcmp (old_path, nm_wimax_nsp_get_dbus_path (new_nsp)))) g_object_notify (G_OBJECT (self), NM_DEVICE_WIMAX_ACTIVE_NSP); g_free (old_path); }
static NMActStageReturn real_act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); NMActRequest *req; GSList *iter; const char *path; clear_link_timeout (NM_DEVICE_WIMAX (device)); req = nm_device_get_act_request (device); if (!req) goto err; path = nm_act_request_get_specific_object (req); if (!path) goto err; for (iter = priv->nsp_list; iter; iter = iter->next) { NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); if (!strcmp (path, nm_wimax_nsp_get_dbus_path (nsp))) { set_current_nsp (NM_DEVICE_WIMAX (device), nsp); return NM_ACT_STAGE_RETURN_SUCCESS; } } err: *reason = NM_DEVICE_STATE_REASON_NONE; return NM_ACT_STAGE_RETURN_FAILURE; }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDeviceWimax *self = NM_DEVICE_WIMAX (object); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); GPtrArray *array; GSList *iter; switch (prop_id) { case PROP_NSPS: array = g_ptr_array_sized_new (4); for (iter = priv->nsp_list; iter; iter = g_slist_next (iter)) g_ptr_array_add (array, g_strdup (nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))); g_value_take_boxed (value, array); break; case PROP_ACTIVE_NSP: if (priv->current_nsp) g_value_set_boxed (value, nm_wimax_nsp_get_dbus_path (priv->current_nsp)); else g_value_set_boxed (value, "/"); break; case PROP_CENTER_FREQ: g_value_set_uint (value, priv->center_freq); break; case PROP_RSSI: g_value_set_int (value, priv->rssi); break; case PROP_CINR: g_value_set_int (value, priv->cinr); break; case PROP_TX_POWER: g_value_set_int (value, priv->tx_power); break; case PROP_BSID: g_value_set_string (value, priv->bsid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean impl_device_get_nsp_list (NMDeviceWimax *self, GPtrArray **nsps, GError **error) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); GSList *iter; *nsps = g_ptr_array_sized_new (4); for (iter = priv->nsp_list; iter; iter = iter->next) g_ptr_array_add (*nsps, g_strdup (nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))); return TRUE; }
static NMActStageReturn act_stage1_prepare (NMDevice *device, NMDeviceStateReason *reason) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); NMActRequest *req; GSList *iter; const char *path; NMWimaxNsp *nsp = NULL; clear_link_timeout (NM_DEVICE_WIMAX (device)); *reason = NM_DEVICE_STATE_REASON_NONE; req = nm_device_get_act_request (device); if (!req) return NM_ACT_STAGE_RETURN_FAILURE; path = nm_active_connection_get_specific_object (NM_ACTIVE_CONNECTION (req)); if (!path) return NM_ACT_STAGE_RETURN_FAILURE; /* Find the NSP in the scan list */ for (iter = priv->nsp_list; iter; iter = iter->next) { NMWimaxNsp *candidate = NM_WIMAX_NSP (iter->data); if (!strcmp (path, nm_wimax_nsp_get_dbus_path (candidate))) { nsp = candidate; break; } } /* Couldn't find the NSP for some reason */ if (nsp == NULL) return NM_ACT_STAGE_RETURN_FAILURE; set_current_nsp (NM_DEVICE_WIMAX (device), nsp); priv->prepare_done = TRUE; /* If the device is scanning, it won't connect, so we have to wait until * it's not scanning to proceed to stage 2. */ if (priv->status == WIMAX_API_DEVICE_STATUS_Scanning) return NM_ACT_STAGE_RETURN_POSTPONE; return NM_ACT_STAGE_RETURN_SUCCESS; }
static NMWimaxNsp * get_nsp_by_path (NMDeviceWimax *self, const char *path) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); GSList *iter; g_return_val_if_fail (path, NULL); for (iter = priv->nsp_list; iter; iter = iter->next) { NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); if (!strcmp (nm_wimax_nsp_get_dbus_path (nsp), path)) return nsp; } return NULL; }
static NMConnection * real_get_best_auto_connection (NMDevice *device, GSList *connections, char **specific_object) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); GSList *iter; for (iter = connections; iter; iter = g_slist_next (iter)) { NMConnection *connection = NM_CONNECTION (iter->data); NMSettingConnection *s_con; NMSettingWimax *s_wimax; const char *connection_type; const GByteArray *mac; s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION); g_assert (s_con); if (!nm_setting_connection_get_autoconnect (s_con)) continue; connection_type = nm_setting_connection_get_connection_type (s_con); if (strcmp (connection_type, NM_SETTING_WIMAX_SETTING_NAME)) continue; s_wimax = (NMSettingWimax *) nm_connection_get_setting (connection, NM_TYPE_SETTING_WIMAX); if (!s_wimax) continue; mac = nm_setting_wimax_get_mac_address (s_wimax); if (mac && memcmp (mac->data, priv->hw_addr.ether_addr_octet, ETH_ALEN)) continue; for (iter = priv->nsp_list; iter; iter = iter->next) { NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); if (nm_wimax_nsp_check_compatible (nsp, connection)) { *specific_object = (char *) nm_wimax_nsp_get_dbus_path (nsp); return connection; } } } return NULL; }
static gboolean can_auto_connect (NMDevice *device, NMConnection *connection, char **specific_object) { NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (device); GSList *iter; if (!NM_DEVICE_CLASS (nm_device_wimax_parent_class)->can_auto_connect (device, connection, specific_object)) return FALSE; for (iter = priv->nsp_list; iter; iter = iter->next) { NMWimaxNsp *nsp = NM_WIMAX_NSP (iter->data); if (nm_wimax_nsp_check_compatible (nsp, connection)) { *specific_object = (char *) nm_wimax_nsp_get_dbus_path (nsp); return TRUE; } } return FALSE; }
static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMDeviceWimax *self = NM_DEVICE_WIMAX (object); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); struct ether_addr hw_addr; switch (prop_id) { case PROP_HW_ADDRESS: nm_device_wimax_get_hw_address (self, &hw_addr); g_value_take_string (value, nm_ether_ntop (&hw_addr)); break; case PROP_ACTIVE_NSP: if (priv->current_nsp) g_value_set_boxed (value, nm_wimax_nsp_get_dbus_path (priv->current_nsp)); else g_value_set_boxed (value, "/"); break; case PROP_CENTER_FREQ: g_value_set_uint (value, priv->center_freq); break; case PROP_RSSI: g_value_set_int (value, priv->rssi); break; case PROP_CINR: g_value_set_int (value, priv->cinr); break; case PROP_TX_POWER: g_value_set_int (value, priv->tx_power); break; case PROP_BSID: g_value_set_string (value, priv->bsid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } }
static gboolean complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, const GSList *existing_connections, GError **error) { NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMSettingWimax *s_wimax; const char *setting_mac; const char *hw_address; const char *nsp_name = NULL; NMWimaxNsp *nsp = NULL; GSList *iter; s_wimax = nm_connection_get_setting_wimax (connection); if (!specific_object) { /* If not given a specific object, we need at minimum an NSP name */ if (!s_wimax) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting is required if no NSP path was given."); return FALSE; } nsp_name = nm_setting_wimax_get_network_name (s_wimax); if (!nsp_name || !strlen (nsp_name)) { g_set_error_literal (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_INVALID_CONNECTION, "A 'wimax' setting with a valid network name is required if no NSP path was given."); return FALSE; } /* Find a compatible NSP in the list */ nsp = get_nsp_by_name (self, nsp_name); /* If we still don't have an NSP, then the WiMAX settings needs to be * fully specified by the client. Might not be able to find the NSP * if the scan didn't find the NSP yet. */ if (!nsp) { if (!nm_setting_verify (NM_SETTING (s_wimax), NULL, error)) return FALSE; } } else { /* Find a compatible NSP in the list */ for (iter = priv->nsp_list; iter; iter = g_slist_next (iter)) { if (!strcmp (specific_object, nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))) { nsp = NM_WIMAX_NSP (iter->data); break; } } if (!nsp) { g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_SPECIFIC_OBJECT_NOT_FOUND, "The NSP %s was not in the scan list.", specific_object); return FALSE; } nsp_name = nm_wimax_nsp_get_name (nsp); } /* Add a WiMAX setting if one doesn't exist */ if (!s_wimax) { s_wimax = (NMSettingWimax *) nm_setting_wimax_new (); nm_connection_add_setting (connection, NM_SETTING (s_wimax)); } g_assert (nsp_name); nm_utils_complete_generic (connection, NM_SETTING_WIMAX_SETTING_NAME, existing_connections, nsp_name, nsp_name, NULL, TRUE); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); setting_mac = nm_setting_wimax_get_mac_address (s_wimax); hw_address = nm_device_get_hw_address (device); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ if (!nm_utils_hwaddr_matches (setting_mac, -1, hw_address, -1)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("connection does not match device")); g_prefix_error (error, "%s.%s: ", NM_SETTING_WIMAX_SETTING_NAME, NM_SETTING_WIMAX_MAC_ADDRESS); return FALSE; } } else { /* Lock the connection to this device by default */ if (!nm_utils_hwaddr_matches (hw_address, -1, NULL, ETH_ALEN)) g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, hw_address, NULL); } return TRUE; }
static gboolean real_complete_connection (NMDevice *device, NMConnection *connection, const char *specific_object, const GSList *existing_connections, GError **error) { NMDeviceWimax *self = NM_DEVICE_WIMAX (device); NMDeviceWimaxPrivate *priv = NM_DEVICE_WIMAX_GET_PRIVATE (self); NMSettingWimax *s_wimax; const GByteArray *setting_mac; char *format; const char *nsp_name = NULL; NMWimaxNsp *nsp = NULL; GSList *iter; s_wimax = nm_connection_get_setting_wimax (connection); if (!specific_object) { /* If not given a specific object, we need at minimum an NSP name */ if (!s_wimax) { g_set_error_literal (error, NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INVALID, "A 'wimax' setting is required if no NSP path was given."); return FALSE; } nsp_name = nm_setting_wimax_get_network_name (s_wimax); if (!nsp_name || !strlen (nsp_name)) { g_set_error_literal (error, NM_WIMAX_ERROR, NM_WIMAX_ERROR_CONNECTION_INVALID, "A 'wimax' setting with a valid network name is required if no NSP path was given."); return FALSE; } /* Find a compatible NSP in the list */ nsp = get_nsp_by_name (self, nsp_name); /* If we still don't have an NSP, then the WiMAX settings needs to be * fully specified by the client. Might not be able to find the NSP * if the scan didn't find the NSP yet. */ if (!nsp) { if (!nm_setting_verify (NM_SETTING (s_wimax), NULL, error)) return FALSE; } } else { /* Find a compatible NSP in the list */ for (iter = priv->nsp_list; iter; iter = g_slist_next (iter)) { if (!strcmp (specific_object, nm_wimax_nsp_get_dbus_path (NM_WIMAX_NSP (iter->data)))) { nsp = NM_WIMAX_NSP (iter->data); break; } } if (!nsp) { g_set_error (error, NM_WIMAX_ERROR, NM_WIMAX_ERROR_NSP_NOT_FOUND, "The NSP %s was not in the scan list.", specific_object); return FALSE; } nsp_name = nm_wimax_nsp_get_name (nsp); } /* Add a WiMAX setting if one doesn't exist */ if (!s_wimax) { s_wimax = (NMSettingWimax *) nm_setting_wimax_new (); nm_connection_add_setting (connection, NM_SETTING (s_wimax)); } g_assert (nsp_name); format = g_strdup_printf ("%s %%d", nsp_name); nm_utils_complete_generic (connection, NM_SETTING_WIMAX_SETTING_NAME, existing_connections, format, nsp_name, TRUE); g_free (format); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_NETWORK_NAME, nsp_name, NULL); setting_mac = nm_setting_wimax_get_mac_address (s_wimax); if (setting_mac) { /* Make sure the setting MAC (if any) matches the device's permanent MAC */ if (memcmp (setting_mac->data, &priv->hw_addr.ether_addr_octet, ETH_ALEN)) { g_set_error (error, NM_SETTING_WIMAX_ERROR, NM_SETTING_WIMAX_ERROR_INVALID_PROPERTY, NM_SETTING_WIMAX_MAC_ADDRESS); return FALSE; } } else { GByteArray *mac; const guint8 null_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 }; /* Lock the connection to this device by default */ if (memcmp (&priv->hw_addr.ether_addr_octet, null_mac, ETH_ALEN)) { mac = g_byte_array_sized_new (ETH_ALEN); g_byte_array_append (mac, priv->hw_addr.ether_addr_octet, ETH_ALEN); g_object_set (G_OBJECT (s_wimax), NM_SETTING_WIMAX_MAC_ADDRESS, mac, NULL); g_byte_array_free (mac, TRUE); } } return TRUE; }