diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-28 13:02:32 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2015-01-28 20:25:06 +0100 |
commit | f962c45e43acba116e70074805c40bca73b29076 (patch) | |
tree | a2898d7298551ee4deb881b992f2687597155129 | |
parent | e02abb054bc8be9e93efde055191a7451ba9f8f5 (diff) | |
download | external_libqmi-f962c45e43acba116e70074805c40bca73b29076.zip external_libqmi-f962c45e43acba116e70074805c40bca73b29076.tar.gz external_libqmi-f962c45e43acba116e70074805c40bca73b29076.tar.bz2 |
libqmi-glib,device: new property and getter to load the WWAN interface name
Each QMI control port has one and only one associated WWAN net port. This new
"device-wwan-iface" property and the qmi_device_get_wwan_iface() getter allow
to load the WWAN net port name by looking directly at sysfs.
-rw-r--r-- | docs/reference/libqmi-glib/libqmi-glib-common.sections | 2 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-device.c | 108 | ||||
-rw-r--r-- | src/libqmi-glib/qmi-device.h | 2 |
3 files changed, 112 insertions, 0 deletions
diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections index ca964b7..37b8a2c 100644 --- a/docs/reference/libqmi-glib/libqmi-glib-common.sections +++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections @@ -44,6 +44,7 @@ qmi_client_get_type QMI_DEVICE_FILE QMI_DEVICE_NO_FILE_CHECK QMI_DEVICE_PROXY_PATH +QMI_DEVICE_WWAN_IFACE QMI_DEVICE_SIGNAL_INDICATION QmiDevice QmiDeviceOpenFlags @@ -55,6 +56,7 @@ qmi_device_get_file qmi_device_peek_file qmi_device_get_path qmi_device_get_path_display +qmi_device_get_wwan_iface qmi_device_is_open qmi_device_open qmi_device_open_finish diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c index d50c5b9..8694e98 100644 --- a/src/libqmi-glib/qmi-device.c +++ b/src/libqmi-glib/qmi-device.c @@ -71,6 +71,7 @@ enum { PROP_FILE, PROP_NO_FILE_CHECK, PROP_PROXY_PATH, + PROP_WWAN_IFACE, PROP_LAST }; @@ -90,6 +91,10 @@ struct _QmiDevicePrivate { gboolean no_file_check; gchar *proxy_path; + /* WWAN interface */ + gboolean no_wwan_check; + gchar *wwan_iface; + /* Implicit CTL client */ QmiClientCtl *client_ctl; guint sync_indication_id; @@ -596,6 +601,96 @@ qmi_device_is_open (QmiDevice *self) } /*****************************************************************************/ +/* WWAN iface name + * Always reload from scratch, to handle possible net interface renames */ + +static void +reload_wwan_iface_name (QmiDevice *self) +{ + const gchar *cdc_wdm_device_name; + static const gchar *driver_names[] = { "usbmisc", "usb" }; + guint i; + + /* Early cleanup */ + g_free (self->priv->wwan_iface); + self->priv->wwan_iface = NULL; + + cdc_wdm_device_name = strrchr (self->priv->path, '/'); + if (!cdc_wdm_device_name) { + g_warning ("[%s] invalid path for cdc-wdm control port", self->priv->path_display); + return; + } + cdc_wdm_device_name++; + + for (i = 0; i < G_N_ELEMENTS (driver_names) && !self->priv->wwan_iface; i++) { + gchar *sysfs_path; + GFile *sysfs_file; + GFileEnumerator *enumerator; + GError *error = NULL; + + sysfs_path = g_strdup_printf ("/sys/class/%s/%s/device/net/", driver_names[i], cdc_wdm_device_name); + sysfs_file = g_file_new_for_path (sysfs_path); + enumerator = g_file_enumerate_children (sysfs_file, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + &error); + if (!enumerator) { + g_debug ("[%s] cannot enumerate files at path '%s': %s", + self->priv->path_display, + sysfs_path, + error->message); + g_error_free (error); + } else { + GFileInfo *file_info; + + /* Ignore errors when enumerating */ + while ((file_info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { + const gchar *name; + + name = g_file_info_get_name (file_info); + if (name) { + /* We only expect ONE file in the sysfs directory corresponding + * to this control port, if more found for any reason, warn about it */ + if (self->priv->wwan_iface) + g_warning ("[%s] invalid additional wwan iface found: %s", + self->priv->path_display, name); + else + self->priv->wwan_iface = g_strdup (name); + } + g_object_unref (file_info); + } + + g_object_unref (enumerator); + } + + g_free (sysfs_path); + g_object_unref (sysfs_file); + } + + if (!self->priv->wwan_iface) + g_warning ("[%s] wwan iface not found", self->priv->path_display); +} + +/** + * qmi_device_get_wwan_iface: + * @self: a #QmiDevice. + * + * Get the WWAN interface name associated with this /dev/cdc-wdm control port. + * This value will be loaded the first time it's asked for it. + * + * Returns: UTF-8 encoded network interface name, or %NULL if not available. + */ +const gchar * +qmi_device_get_wwan_iface (QmiDevice *self) +{ + g_return_val_if_fail (QMI_IS_DEVICE (self), NULL); + + reload_wwan_iface_name (self); + return self->priv->wwan_iface; +} + +/*****************************************************************************/ /* Register/Unregister clients that want to receive indications */ static gpointer @@ -2492,6 +2587,10 @@ get_property (GObject *object, case PROP_FILE: g_value_set_object (value, self->priv->file); break; + case PROP_WWAN_IFACE: + reload_wwan_iface_name (self); + g_value_set_string (value, self->priv->wwan_iface); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2574,6 +2673,7 @@ finalize (GObject *object) g_free (self->priv->path); g_free (self->priv->path_display); g_free (self->priv->proxy_path); + g_free (self->priv->wwan_iface); if (self->priv->input_source) { g_source_destroy (self->priv->input_source); @@ -2638,6 +2738,14 @@ qmi_device_class_init (QmiDeviceClass *klass) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_PROXY_PATH, properties[PROP_PROXY_PATH]); + properties[PROP_WWAN_IFACE] = + g_param_spec_string (QMI_DEVICE_WWAN_IFACE, + "WWAN iface", + "Name of the WWAN network interface associated with the control port.", + NULL, + G_PARAM_READABLE); + g_object_class_install_property (object_class, PROP_WWAN_IFACE, properties[PROP_WWAN_IFACE]); + /** * QmiClientDms::event-report: * @object: A #QmiClientDms. diff --git a/src/libqmi-glib/qmi-device.h b/src/libqmi-glib/qmi-device.h index cef7c50..8224099 100644 --- a/src/libqmi-glib/qmi-device.h +++ b/src/libqmi-glib/qmi-device.h @@ -50,6 +50,7 @@ typedef struct _QmiDevicePrivate QmiDevicePrivate; #define QMI_DEVICE_FILE "device-file" #define QMI_DEVICE_NO_FILE_CHECK "device-no-file-check" #define QMI_DEVICE_PROXY_PATH "device-proxy-path" +#define QMI_DEVICE_WWAN_IFACE "device-wwan-iface" #define QMI_DEVICE_SIGNAL_INDICATION "indication" @@ -83,6 +84,7 @@ GFile *qmi_device_get_file (QmiDevice *self); GFile *qmi_device_peek_file (QmiDevice *self); const gchar *qmi_device_get_path (QmiDevice *self); const gchar *qmi_device_get_path_display (QmiDevice *self); +const gchar *qmi_device_get_wwan_iface (QmiDevice *self); gboolean qmi_device_is_open (QmiDevice *self); /** |