Merge remote-tracking branch 'cros/upstream' into 'cros/master'
Contains the following commits:
0bbe65c libmbim-glib,proxy: plug memleak (Aleksander Morgado)
4064021 libmbim-glib,proxy: always use realpath in the MbimDevice (Aleksander Morgado)
b0ede0c libmbim-glib,device: use realpath basename to look for descriptors file (Aleksander Morgado)
4932766 libmbim-glib,utils: new helpers to work with symlinks (Aleksander Morgado)
2999e9a mbimcli: add --query-provisioned-contexts flag (Eric Caruso)
Change-Id: I5986dd430acdfc70a53435de9da01fb04b735879
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index 113fd36..6d38a39 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -862,8 +862,9 @@
GUdevDevice *device = NULL;
GUdevDevice *parent_device = NULL;
GUdevDevice *grandparent_device = NULL;
- gchar *descriptors_path = NULL;
- gchar *device_basename = NULL;
+ gchar *descriptors_path = NULL;
+ gchar *device_basename = NULL;
+ GError *error = NULL;
client = g_udev_client_new (NULL);
if (!G_UDEV_IS_CLIENT (client)) {
@@ -884,7 +885,14 @@
* Which is the one with the descriptors file.
*/
- device_basename = g_path_get_basename (self->priv->path);
+ device_basename = __mbim_utils_get_devname (self->priv->path, &error);
+ if (!device_basename) {
+ g_warning ("[%s] Invalid path for cdc-wdm control port: %s",
+ self->priv->path_display, error->message);
+ g_clear_error (&error);
+ goto out;
+ }
+
device = g_udev_client_query_by_subsystem_and_name (client, "usb", device_basename);
if (!device) {
device = g_udev_client_query_by_subsystem_and_name (client, "usbmisc", device_basename);
diff --git a/src/libmbim-glib/mbim-proxy.c b/src/libmbim-glib/mbim-proxy.c
index 508e935..912e1f0 100644
--- a/src/libmbim-glib/mbim-proxy.c
+++ b/src/libmbim-glib/mbim-proxy.c
@@ -744,10 +744,12 @@
Client *client,
MbimMessage *message)
{
- Request *request;
+ Request *request;
MbimDevice *device;
- gchar *path;
- GFile *file;
+ gchar *incoming_path;
+ gchar *path;
+ GFile *file;
+ GError *error = NULL;
/* create request holder */
request = request_new (self, client, message);
@@ -767,13 +769,27 @@
}
/* Retrieve path from request */
- path = _mbim_message_read_string (message, 0, 0);
- if (!path) {
+ incoming_path = _mbim_message_read_string (message, 0, 0);
+ if (!incoming_path) {
request->response = build_proxy_control_command_done (message, MBIM_STATUS_ERROR_INVALID_PARAMETERS);
request_complete_and_free (request);
return TRUE;
}
+ /* The incoming path may be a symlink. In the proxy, we always use the real path of the
+ * device, so that clients using different symlinks for the same file don't collide with
+ * each other. */
+ path = __mbim_utils_get_devpath (incoming_path, &error);
+ if (!path) {
+ g_warning ("Error looking up real device path: %s", error->message);
+ g_error_free (error);
+ request->response = build_proxy_control_command_done (message, MBIM_STATUS_ERROR_INVALID_PARAMETERS);
+ request_complete_and_free (request);
+ g_free (incoming_path);
+ return TRUE;
+ }
+ g_free (incoming_path);
+
/* Only allow subsequent requests with the same path */
if (client->device) {
if (g_str_equal (path, mbim_device_get_path (client->device)))
diff --git a/src/libmbim-glib/mbim-utils.c b/src/libmbim-glib/mbim-utils.c
index f360542..f168e6d 100644
--- a/src/libmbim-glib/mbim-utils.c
+++ b/src/libmbim-glib/mbim-utils.c
@@ -18,13 +18,16 @@
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
- * Copyright (C) 2013 - 2014 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2013 - 2019 Aleksander Morgado <aleksander@aleksander.es>
*/
#include <config.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <errno.h>
#include <pwd.h>
#include "mbim-utils.h"
@@ -79,6 +82,45 @@
/*****************************************************************************/
+gchar *
+__mbim_utils_get_devpath (const gchar *cdc_wdm_path,
+ GError **error)
+{
+ gchar *aux;
+
+ if (!g_file_test (cdc_wdm_path, G_FILE_TEST_IS_SYMLINK))
+ return g_strdup (cdc_wdm_path);
+
+ aux = realpath (cdc_wdm_path, NULL);
+ if (!aux) {
+ int saved_errno = errno;
+
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Couldn't get realpath: %s", g_strerror (saved_errno));
+ return NULL;
+ }
+
+ return aux;
+}
+
+gchar *
+__mbim_utils_get_devname (const gchar *cdc_wdm_path,
+ GError **error)
+{
+ gchar *aux;
+ gchar *devname = NULL;
+
+ aux = __mbim_utils_get_devpath (cdc_wdm_path, error);
+ if (aux) {
+ devname = g_path_get_basename (aux);
+ g_free (aux);
+ }
+
+ return devname;
+}
+
+/*****************************************************************************/
+
static volatile gint __traces_enabled = FALSE;
/**
diff --git a/src/libmbim-glib/mbim-utils.h b/src/libmbim-glib/mbim-utils.h
index 77ed4ca..858ae17 100644
--- a/src/libmbim-glib/mbim-utils.h
+++ b/src/libmbim-glib/mbim-utils.h
@@ -39,8 +39,12 @@
/* Other private methods */
#if defined (LIBMBIM_GLIB_COMPILATION)
-gboolean __mbim_user_allowed (uid_t uid,
- GError **error);
+gboolean __mbim_user_allowed (uid_t uid,
+ GError **error);
+gchar *__mbim_utils_get_devpath (const gchar *cdc_wdm_path,
+ GError **error);
+gchar *__mbim_utils_get_devname (const gchar *cdc_wdm_path,
+ GError **error);
#endif
G_END_DECLS
diff --git a/src/mbimcli/mbimcli-basic-connect.c b/src/mbimcli/mbimcli-basic-connect.c
index b3dc408..ff84f0d 100644
--- a/src/mbimcli/mbimcli-basic-connect.c
+++ b/src/mbimcli/mbimcli-basic-connect.c
@@ -70,6 +70,7 @@
static gchar *set_connect_deactivate_str;
static gboolean query_packet_statistics_flag;
static gchar *query_ip_packet_filters_str;
+static gboolean query_provisioned_contexts_flag;
static gboolean query_connection_state_arg_parse (const char *option_name,
const char *value,
@@ -200,6 +201,10 @@
"Query IP packet filters (SessionID is optional, defaults to 0)",
"[SessionID]"
},
+ { "query-provisioned-contexts", 0, 0, G_OPTION_ARG_NONE, &query_provisioned_contexts_flag,
+ "Query provisioned contexts",
+ NULL
+ },
{ NULL }
};
@@ -293,7 +298,8 @@
!!query_ip_configuration_str +
!!set_connect_deactivate_str +
query_packet_statistics_flag +
- !!query_ip_packet_filters_str);
+ !!query_ip_packet_filters_str +
+ query_provisioned_contexts_flag);
if (n_actions > 1) {
g_printerr ("error: too many Basic Connect actions requested\n");
@@ -1765,6 +1771,68 @@
shutdown (TRUE);
}
+static void
+provisioned_contexts_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ MbimMessage *response;
+ MbimProvisionedContextElement **provisioned_contexts;
+ guint32 provisioned_contexts_count;
+ int i;
+ GError *error = NULL;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ g_error_free (error);
+ if (response)
+ mbim_message_unref (response);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!mbim_message_provisioned_contexts_response_parse (
+ response,
+ &provisioned_contexts_count,
+ &provisioned_contexts,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ g_error_free (error);
+ mbim_message_unref (response);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Provisioned contexts (%u):\n",
+ mbim_device_get_path_display (device),
+ provisioned_contexts_count);
+
+ for (i = 0; i < provisioned_contexts_count; i++) {
+ g_print ("\tContext ID %u:\n"
+ "\t Context type: '%s'\n"
+ "\t Access string: '%s'\n"
+ "\t Username: '%s'\n"
+ "\t Password: '%s'\n"
+ "\t Compression: '%s'\n"
+ "\t Auth protocol: '%s'\n",
+ provisioned_contexts[i]->context_id,
+ VALIDATE_UNKNOWN (mbim_context_type_get_string (
+ mbim_uuid_to_context_type (&provisioned_contexts[i]->context_type))),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->access_string),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->user_name),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->password),
+ VALIDATE_UNKNOWN (mbim_compression_get_string (
+ provisioned_contexts[i]->compression)),
+ VALIDATE_UNKNOWN (mbim_auth_protocol_get_string (
+ provisioned_contexts[i]->auth_protocol)));
+ }
+
+ mbim_provisioned_context_element_array_free (provisioned_contexts);
+
+ mbim_message_unref (response);
+ shutdown (TRUE);
+}
+
void
mbimcli_basic_connect_run (MbimDevice *device,
GCancellable *cancellable)
@@ -2321,5 +2389,20 @@
return;
}
+ /* Provisioned contexts? */
+ if (query_provisioned_contexts_flag) {
+ MbimMessage *request;
+
+ request = mbim_message_provisioned_contexts_query_new (NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)provisioned_contexts_ready,
+ NULL);
+ mbim_message_unref (request);
+ return;
+ }
+
g_warn_if_reached ();
}