From ff8d35615153086f4b89443e511907f10ff059de Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bj=C3=B8rn=20Mork?= Date: Fri, 15 Feb 2019 14:24:57 +0100 Subject: [PATCH] mbim-proxy support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- CMakeLists.txt | 7 +++++ cli.c | 18 +++++++++++- data/mbim-service-proxy-control.h | 5 ++++ mbim-dev.c | 49 +++++++++++++++++++++++++++++++ mbim-dev.h | 3 ++ 5 files changed, 81 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c210d6f..bc18c1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 e00b6d4..3089d16 100644 --- a/cli.c +++ b/cli.c @@ -493,6 +493,9 @@ usage(void) { fprintf(stderr, "Usage: umbim [options]\n" "Options:\n" +#ifdef LIBQMI_MBIM_PROXY + " -p use mbim-proxy\n" +#endif " -d the device (/dev/cdc-wdmX)\n" " -t 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(); diff --git a/data/mbim-service-proxy-control.h b/data/mbim-service-proxy-control.h index 7d81e7d..227b625 100644 --- a/data/mbim-service-proxy-control.h +++ b/data/mbim-service-proxy-control.h @@ -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)); + diff --git a/mbim-dev.c b/mbim-dev.c index dd1110d..170de2d 100644 --- a/mbim-dev.c +++ b/mbim-dev.c @@ -27,6 +27,15 @@ #include "mbim.h" + +#ifdef LIBQMI_MBIM_PROXY +#include +#include +#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) { diff --git a/mbim-dev.h b/mbim-dev.h index b7a253c..501bbf2 100644 --- a/mbim-dev.h +++ b/mbim-dev.h @@ -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 -- 2.25.1