From e7597bcae247905e836c93c56bc7c9c14d7d617e Mon Sep 17 00:00:00 2001 From: Denis Kenzior Date: Tue, 19 Sep 2017 21:20:38 -0500 Subject: [PATCH] mbim: Parse MBIM descriptors This is needed to find out the maximum fragment size that this device supports. The minimum length specified in the spec is 64, however 512 bytes is recommended. We also attempt to parse how many simultaneous commands can be outstanding at a given time. In theory MBIM supports multiple outstanding commands through the use of transaction-id matching, but it seems some devices only support a single outstanding command at a time. --- plugins/mbim.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/plugins/mbim.c b/plugins/mbim.c index 258b2da7..13948d0f 100644 --- a/plugins/mbim.c +++ b/plugins/mbim.c @@ -26,6 +26,10 @@ #define _GNU_SOURCE #include #include +#include +#include +#include +#include #include #include @@ -36,19 +40,66 @@ #include +#include #include struct mbim_data { struct mbim_device *device; + uint16_t max_segment; + uint8_t max_outstanding; }; +static int mbim_parse_descriptors(struct mbim_data *md, const char *file) +{ + void *data; + size_t len; + const struct mbim_desc *desc = NULL; + const struct mbim_extended_desc *ext_desc = NULL; + + data = l_file_get_contents(file, &len); + if (!data) + return -EIO; + + if (!mbim_find_descriptors(data, len, &desc, &ext_desc)) { + l_free(data); + return -ENOENT; + } + + if (desc) + md->max_segment = L_LE16_TO_CPU(desc->wMaxControlMessage); + + if (ext_desc) + md->max_outstanding = ext_desc->bMaxOutstandingCommandMessages; + + l_free(data); + return 0; +} + static int mbim_probe(struct ofono_modem *modem) { + const char *descriptors; struct mbim_data *data; + int err; DBG("%p", modem); + descriptors = ofono_modem_get_string(modem, "DescriptorFile"); + + if (!descriptors) + return -EINVAL; + data = l_new(struct mbim_data, 1); + data->max_outstanding = 1; + + err = mbim_parse_descriptors(data, descriptors); + if (err < 0) { + DBG("Warning, unable to load descriptors, setting defaults"); + data->max_segment = 512; + } + + DBG("MaxSegment: %d, MaxOutstanding: %d", + data->max_segment, data->max_outstanding); + ofono_modem_set_data(modem, data); return 0;