mbim-proxy support
authorBjørn Mork <bjorn@mork.no>
Fri, 15 Feb 2019 13:24:57 +0000 (14:24 +0100)
committerPetr Štetiar <ynezz@true.cz>
Wed, 10 Apr 2019 14:05:27 +0000 (16:05 +0200)
This adds support for the libmbim-glib "mbim-proxy", allowing umbim to access
a device under ModemManager control. The feature is mostly useful for debugging
and development purposes, and is therefore disabled by default.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
CMakeLists.txt
cli.c
data/mbim-service-proxy-control.h
mbim-dev.c
mbim-dev.h

index c210d6f828fb4ee0c4db893d529851759cc371a8..bc18c1f6d0d7f6419af29265dfb55186df061160 100644 (file)
@@ -1,6 +1,9 @@
 cmake_minimum_required(VERSION 2.6)
 
 PROJECT(umbim C)
+
+OPTION(PROXY OFF)
+
 ADD_DEFINITIONS(-Os -ggdb -Wall -Werror --std=gnu99 -Wmissing-declarations)
 
 SET(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
@@ -13,6 +16,10 @@ IF(DEBUG)
   ADD_DEFINITIONS(-DDEBUG -g3)
 ENDIF()
 
+IF(PROXY)
+  ADD_DEFINITIONS(-DLIBQMI_MBIM_PROXY)
+ENDIF()
+
 ADD_EXECUTABLE(umbim ${SOURCES})
 
 TARGET_LINK_LIBRARIES(umbim ${LIBS})
diff --git a/cli.c b/cli.c
index e00b6d4911c6c84a5ff4930ae0840dfa1af0bd81..3089d16a5a5beee05fbaaab7ba02069c1bd2782c 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -493,6 +493,9 @@ usage(void)
 {
        fprintf(stderr, "Usage: umbim <caps|pinstate|unlock|registration|subscriber|attach|detach|connect|disconnect|config|radio> [options]\n"
                "Options:\n"
+#ifdef LIBQMI_MBIM_PROXY
+               "    -p                 use mbim-proxy\n"
+#endif
                "    -d <device>        the device (/dev/cdc-wdmX)\n"
                "    -t <transaction>   the transaction id\n"
                "    -n                 no close\n\n"
@@ -505,8 +508,11 @@ main(int argc, char **argv)
 {
        char *cmd, *device = NULL;
        int no_open = 0, ch, i;
+#ifdef LIBQMI_MBIM_PROXY
+       int proxy = 0;
+#endif
 
-       while ((ch = getopt(argc, argv, "nvd:t:")) != -1) {
+       while ((ch = getopt(argc, argv, "pnvd:t:")) != -1) {
                switch (ch) {
                case 'v':
                        verbose = 1;
@@ -521,6 +527,11 @@ main(int argc, char **argv)
                        no_open = 1;
                        transaction_id = atoi(optarg);
                        break;
+#ifdef LIBQMI_MBIM_PROXY
+               case 'p':
+                       proxy = 1;
+                       break;
+#endif
                default:
                        return usage();
                }
@@ -544,6 +555,11 @@ main(int argc, char **argv)
 
        uloop_init();
 
+#ifdef LIBQMI_MBIM_PROXY
+       if (proxy)
+               mbim_proxy_open(device);
+       else
+#endif
        mbim_open(device);
        if (!no_open)
                mbim_send_open_msg();
index 7d81e7d2daf6f5bd18a4a2737c3450bd599556b9..227b6253a5120a4aa9e89e40564e247df1a2ddd7 100644 (file)
@@ -5,3 +5,8 @@
 
 #define MBIM_CMD_PROXY_CONTROL_CONFIGURATION   1
 
+struct mbim_proxy_control_configuration_s {
+       struct mbim_string devicepath;
+       uint32_t timeout;
+} __attribute__((packed));
+
index dd1110daeb5245da1884e3c9937c771aaaffc10c..170de2dde19800c49bb32116c93bc37666678327 100644 (file)
 
 #include "mbim.h"
 
+
+#ifdef LIBQMI_MBIM_PROXY
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "data/mbim-service-proxy-control.h"
+
+uint8_t proxy_control[16] = { 0x83, 0x8c, 0xf7, 0xfb, 0x8d, 0x0d, 0x4d, 0x7f, 0x87, 0x1e, 0xd7, 0x1d, 0xbe, 0xfb, 0xb3, 0x9b };
+#endif
+
 size_t mbim_bufsize = 0;
 uint8_t *mbim_buffer = NULL;
 static struct uloop_fd mbim_fd;
@@ -114,6 +123,10 @@ mbim_recv(struct uloop_fd *u, unsigned int events)
                }
                if (msg->status_code && !msg->buffer_length)
                        return_code = -le32toh(msg->status_code);
+#ifdef LIBQMI_MBIM_PROXY
+               else if (le32toh(msg->command_id) == MBIM_CMD_PROXY_CONTROL_CONFIGURATION && !memcmp(msg->service_id, proxy_control, 16))
+                       break;
+#endif
                else
                        return_code = current_handler->response(msg->buffer, le32toh(msg->buffer_length));
                if (return_code < 0)
@@ -152,6 +165,42 @@ mbim_open(const char *path)
        uloop_fd_add(&mbim_fd, ULOOP_READ);
 }
 
+#ifdef LIBQMI_MBIM_PROXY
+static int
+mbim_send_proxy_msg(const char *path)
+{
+       struct mbim_proxy_control_configuration_s *p =
+               (struct mbim_proxy_control_configuration_s *) mbim_setup_command_msg(proxy_control,
+                       MBIM_MESSAGE_COMMAND_TYPE_SET, MBIM_CMD_PROXY_CONTROL_CONFIGURATION,
+                       sizeof(struct mbim_proxy_control_configuration_s));
+       mbim_encode_string(&p->devicepath, (char *)path);
+       p->timeout = htole32(30); // FIXME: hard coded timeout
+       return mbim_send_command_msg();
+}
+
+void
+mbim_proxy_open(const char *path)
+{
+       struct sockaddr_un addr = { .sun_family = AF_UNIX, .sun_path = "\0mbim-proxy" };
+
+       mbim_fd.cb = mbim_recv;
+       mbim_fd.fd = socket(PF_UNIX, SOCK_STREAM, 0);
+       if (mbim_fd.fd < 1) {
+               perror("socket failed: ");
+               exit(-1);
+       }
+       if (connect(mbim_fd.fd, (struct sockaddr *)&addr, 13)) {
+               perror("failed to connect to mbim-proxy: ");
+               exit(-1);
+       }
+       mbim_bufsize = 512; // FIXME
+       mbim_buffer = malloc(mbim_bufsize);
+       uloop_fd_add(&mbim_fd, ULOOP_READ);
+       no_close = 1;
+       mbim_send_proxy_msg(path);
+}
+#endif
+
 void
 mbim_end(void)
 {
index b7a253ca0befe5ec007824a673b3003b87dbb6d3..501bbf2b32d7fc8acee80e0bb10ed7f289ce04ea 100644 (file)
@@ -21,6 +21,9 @@ extern int no_close;
 
 int mbim_send(void);
 void mbim_open(const char *path);
+#ifdef LIBQMI_MBIM_PROXY
+void mbim_proxy_open(const char *path);
+#endif
 void mbim_end(void);
 
 #endif