[PATCH 1/3] libqmi-glib, device: new getter/setter for the expected data format in the kernel

Dan Williams dcbw at redhat.com
Wed Jan 6 09:04:59 PST 2016


On Tue, 2015-12-29 at 17:39 +0100, Aleksander Morgado wrote:
> Userspace is in charge of defining the data format to be used in the WWAN net
> interface, both in the device itself (e.g. through CTL or WDA requests) and also
> in the kernel (e.g. through /sys/class/net//qmi/raw_ip sysfs files).
> 
> These new API methods allow to query and modify the data format expected by the
> kernel.
> ---
>  .../libqmi-glib/libqmi-glib-common.sections        |   7 +
>  src/libqmi-glib/qmi-device.c                       | 179 ++++++++++++++++++++-
>  src/libqmi-glib/qmi-device.h                       |  19 +++
>  3 files changed, 204 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/reference/libqmi-glib/libqmi-glib-common.sections b/docs/reference/libqmi-glib/libqmi-glib-common.sections
> index f5d5619..2893851 100644
> --- a/docs/reference/libqmi-glib/libqmi-glib-common.sections
> +++ b/docs/reference/libqmi-glib/libqmi-glib-common.sections
> @@ -50,6 +50,7 @@ QmiDevice
>  QmiDeviceOpenFlags
>  QmiDeviceReleaseClientFlags
>  QmiDeviceServiceVersionInfo
> +QmiDeviceExpectedDataFormat
>  qmi_device_new
>  qmi_device_new_finish
>  qmi_device_get_file
> @@ -57,6 +58,8 @@ qmi_device_peek_file
>  qmi_device_get_path
>  qmi_device_get_path_display
>  qmi_device_get_wwan_iface
> +qmi_device_get_expected_data_format
> +qmi_device_set_expected_data_format
>  qmi_device_is_open
>  qmi_device_open
>  qmi_device_open_finish
> @@ -73,6 +76,7 @@ qmi_device_get_service_version_info
>  qmi_device_get_service_version_info_finish
>  qmi_device_open_flags_build_string_from_mask
>  qmi_device_release_client_flags_build_string_from_mask
> +qmi_device_expected_data_format_get_string
>  
>  QmiDeviceClass
>  QMI_DEVICE
> @@ -83,13 +87,16 @@ QMI_IS_DEVICE_CLASS
>  QMI_TYPE_DEVICE
>  QMI_TYPE_DEVICE_OPEN_FLAGS
>  QMI_TYPE_DEVICE_RELEASE_CLIENT_FLAGS
> +QMI_TYPE_DEVICE_EXPECTED_DATA_FORMAT
>  QmiDevicePrivate
>  qmi_device_get_type
>  qmi_device_open_flags_get_type
>  qmi_device_release_client_flags_get_type
> +qmi_device_expected_data_format_get_type
>  
>  qmi_device_open_flags_get_string
>  qmi_device_release_client_flags_get_string
> +qmi_device_expected_data_format_build_string_from_mask
>  
>  
>  
> diff --git a/src/libqmi-glib/qmi-device.c b/src/libqmi-glib/qmi-device.c
> index c9d05c0..198db60 100644
> --- a/src/libqmi-glib/qmi-device.c
> +++ b/src/libqmi-glib/qmi-device.c
> @@ -21,6 +21,7 @@
>   * Copyright (C) 2012-2015 Aleksander Morgado <aleksander at aleksander.es>
>   */
>  
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -678,7 +679,7 @@ reload_wwan_iface_name (QmiDevice *self)
>   * @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.
> + * This value will be loaded every time it's asked for it.
>   *
>   * Returns: UTF-8 encoded network interface name, or %NULL if not available.
>   */
> @@ -692,6 +693,182 @@ qmi_device_get_wwan_iface (QmiDevice *self)
>  }
>  
>  /*****************************************************************************/
> +/* Expected data format */
> +
> +static gboolean
> +get_expected_data_format (QmiDevice *self,
> +                          const gchar *sysfs_path,
> +                          GError **error)
> +{
> +    QmiDeviceExpectedDataFormat expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN;
> +    gchar value = '\0';
> +    FILE *f;
> +
> +    g_debug ("[%s] Reading expected data format from: %s",
> +             self->priv->path_display,
> +             sysfs_path);
> +
> +    if (!(f = fopen (sysfs_path, "r"))) {
> +        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
> +                     "Failed to open file '%s': %s",
> +                     sysfs_path, g_strerror (errno));
> +        goto out;
> +    }
> +
> +    if (fread (&value, 1, 1, f) != 1) {
> +        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
> +                     "Failed to read from file '%s': %s",
> +                     sysfs_path, g_strerror (errno));
> +        goto out;
> +    }

Would just g_file_get_contents() work here?  Or is that too heavy? 
Otherwise looks fine.

Dan

> +    if (value == 'Y')
> +        expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP;
> +    else if (value == 'N')
> +        expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3;
> +    else
> +        g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED,
> +                     "Unexpected sysfs file contents");
> +
> + out:
> +    g_prefix_error (error, "Expected data format not retrieved properly: ");
> +    if (f)
> +        fclose (f);
> +    return expected;
> +}
> +
> +static gboolean
> +set_expected_data_format (QmiDevice *self,
> +                          const gchar *sysfs_path,
> +                          QmiDeviceExpectedDataFormat requested,
> +                          GError **error)
> +{
> +    gboolean status = FALSE;
> +    gchar value;
> +    FILE *f;
> +
> +    g_debug ("[%s] Writing expected data format to: %s",
> +             self->priv->path_display,
> +             sysfs_path);
> +
> +    if (requested == QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP)
> +        value = 'Y';
> +    else if (requested == QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3)
> +        value = 'N';
> +    else
> +        g_assert_not_reached ();
> +
> +    if (!(f = fopen (sysfs_path, "w"))) {
> +        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
> +                     "Failed to open file '%s' for R/W: %s",
> +                     sysfs_path, g_strerror (errno));
> +        goto out;
> +    }
> +
> +    if (fwrite (&value, 1, 1, f) != 1) {
> +        g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
> +                     "Failed to write to file '%s': %s",
> +                     sysfs_path, g_strerror (errno));
> +        goto out;
> +    }
> +
> +    status = TRUE;
> +
> + out:
> +    g_prefix_error (error, "Expected data format not updated properly: ");
> +    if (f)
> +        fclose (f);
> +    return status;
> +}
> +
> +static QmiDeviceExpectedDataFormat
> +common_get_set_expected_data_format (QmiDevice *self,
> +                                     QmiDeviceExpectedDataFormat requested,
> +                                     GError **error)
> +{
> +    gchar *sysfs_path = NULL;
> +    QmiDeviceExpectedDataFormat expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN;
> +    gboolean readonly;
> +
> +    readonly = (requested == QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN);
> +
> +    /* Make sure we load the WWAN iface name */
> +    reload_wwan_iface_name (self);
> +    if (!self->priv->wwan_iface) {
> +        g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED,
> +                     "Unknown wwan iface");
> +        goto out;
> +    }
> +
> +    /* Build sysfs file path and open it */
> +    sysfs_path = g_strdup_printf ("/sys/class/net/%s/qmi/raw_ip", self->priv->wwan_iface);
> +
> +    /* Set operation? */
> +    if (!readonly && !set_expected_data_format (self, sysfs_path, requested, error))
> +        goto out;
> +
> +    /* Get/Set operations */
> +    if ((expected = get_expected_data_format (self, sysfs_path, error)) == QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN)
> +        goto out;
> +
> +    /* If we requested an update but we didn't read that value, report an error */
> +    if (!readonly && (requested != expected)) {
> +        g_set_error (error, QMI_CORE_ERROR, QMI_CORE_ERROR_FAILED,
> +                     "Expected data format not updated properly to '%s': got '%s' instead",
> +                     qmi_device_expected_data_format_get_string (requested),
> +                     qmi_device_expected_data_format_get_string (expected));
> +        expected = QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN;
> +    }
> +
> + out:
> +    g_free (sysfs_path);
> +    return expected;
> +}
> +
> +/**
> + * qmi_device_get_expected_data_format:
> + * @self: a #QmiDevice.
> + * @error: Return location for error or %NULL.
> + *
> + * Retrieves the data format currently expected by the kernel in the network
> + * interface.
> + *
> + * If @QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN is returned, the user should assume
> + * that 802.3 is the expected format.
> + *
> + * Returns: a valid #QmiDeviceExpectedDataFormat, or @QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN if @error is set.
> + */
> +QmiDeviceExpectedDataFormat
> +qmi_device_get_expected_data_format (QmiDevice  *self,
> +                                     GError    **error)
> +{
> +    g_return_val_if_fail (QMI_IS_DEVICE (self), QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN);
> +
> +    return common_get_set_expected_data_format (self, QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN, error);
> +}
> +
> +/**
> + * qmi_device_set_expected_data_format:
> + * @self: a #QmiDevice.
> + * @format: a known #QmiDeviceExpectedDataFormat.
> + * @error: Return location for error or %NULL.
> + *
> + * Configures the data format currently expected by the kernel in the network
> + * interface.
> + *
> + * Returns: %TRUE if successful, or #NULL if @error is set.
> + */
> +gboolean
> +qmi_device_set_expected_data_format (QmiDevice *self,
> +                                     QmiDeviceExpectedDataFormat format,
> +                                     GError **error)
> +{
> +    g_return_val_if_fail (QMI_IS_DEVICE (self), FALSE);
> +
> +    return (common_get_set_expected_data_format (self, format, error) != QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN);
> +}
> +
> +/*****************************************************************************/
>  /* Register/Unregister clients that want to receive indications */
>  
>  static gpointer
> diff --git a/src/libqmi-glib/qmi-device.h b/src/libqmi-glib/qmi-device.h
> index 09a0766..58651e1 100644
> --- a/src/libqmi-glib/qmi-device.h
> +++ b/src/libqmi-glib/qmi-device.h
> @@ -201,6 +201,25 @@ void    qmi_device_get_service_version_info        (QmiDevice *self,
>  GArray *qmi_device_get_service_version_info_finish (QmiDevice *self,
>                                                      GAsyncResult *res,
>                                                      GError **error);
> +/**
> + * QmiDeviceExpectedDataFormat:
> + * @QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN: Unknown.
> + * @QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3: 802.3.
> + * @QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP: Raw IP.
> + *
> + * Data format expected by the kernel.
> + */
> +typedef enum {
> +    QMI_DEVICE_EXPECTED_DATA_FORMAT_UNKNOWN,
> +    QMI_DEVICE_EXPECTED_DATA_FORMAT_802_3,
> +    QMI_DEVICE_EXPECTED_DATA_FORMAT_RAW_IP,
> +} QmiDeviceExpectedDataFormat;
> +
> +QmiDeviceExpectedDataFormat qmi_device_get_expected_data_format (QmiDevice *self,
> +                                                                 GError **error);
> +gboolean                    qmi_device_set_expected_data_format (QmiDevice *self,
> +                                                                 QmiDeviceExpectedDataFormat format,
> +                                                                 GError **error);
>  
>  G_END_DECLS
>  


More information about the libqmi-devel mailing list