[PATCH v4 2/6] mbimmodem: add support for MBIM extensions * With MBIMEx 3.0, arguments for activating GPRS changed. Update as needed.
Muhammad Asif <[email protected]> Mon, 5 May 2025 00:19:27 +0500
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <[email protected]> |
---
drivers/mbimmodem/gprs-context.c | 59 ++++++++++++++++++++++++--------
drivers/mbimmodem/mbim.c | 55 +++++++++++++++++++++++++++++
drivers/mbimmodem/mbim.h | 7 ++++
3 files changed, 107 insertions(+), 14 deletions(-)
diff --git a/drivers/mbimmodem/gprs-context.c b/drivers/mbimmodem/gprs-context.c
index c420e300..e912b6a5 100644
--- a/drivers/mbimmodem/gprs-context.c
+++ b/drivers/mbimmodem/gprs-context.c
@@ -102,9 +102,16 @@ static void mbim_gprs_deactivate_primary(struct ofono_gprs_context *gc,
message = mbim_message_new(mbim_uuid_basic_connect,
MBIM_CID_CONNECT,
MBIM_COMMAND_TYPE_SET);
- mbim_message_set_arguments(message, "uusssuuu16y",
- cid, 0, NULL, NULL, NULL, 0, 0, 0,
- mbim_context_type_internet);
+
+ if (mbim_device_check_mbimex_version(gcd->device, 3, 0)) {
+ mbim_message_set_arguments(message, "uuuuu16yussss",
+ cid, 0, 0, 0, 0, mbim_context_type_internet,
+ 0, NULL, NULL, NULL, NULL);
+ } else {
+ mbim_message_set_arguments(message, "uusssuuu16y",
+ cid, 0, NULL, NULL, NULL, 0, 0, 0,
+ mbim_context_type_internet);
+ }
if (mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
mbim_deactivate_cb, gc, NULL) > 0)
@@ -288,10 +295,18 @@ error:
message = mbim_message_new(mbim_uuid_basic_connect,
MBIM_CID_CONNECT,
MBIM_COMMAND_TYPE_SET);
- mbim_message_set_arguments(message, "uusssuuu16y",
+
+ if (mbim_device_check_mbimex_version(gcd->device, 3, 0)) {
+ mbim_message_set_arguments(message, "uuuuu16yussss",
+ gcd->active_context, 0, 0, 0, 0,
+ mbim_context_type_internet, 0, NULL,
+ NULL, NULL, NULL);
+ } else {
+ mbim_message_set_arguments(message, "uusssuuu16y",
gcd->active_context, 0,
NULL, NULL, NULL, 0, 0, 0,
mbim_context_type_internet);
+ }
if (!mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
NULL, NULL, NULL))
@@ -352,16 +367,32 @@ static void mbim_gprs_activate_primary(struct ofono_gprs_context *gc,
message = mbim_message_new(mbim_uuid_basic_connect,
MBIM_CID_CONNECT,
MBIM_COMMAND_TYPE_SET);
- mbim_message_set_arguments(message, "uusssuuu16y",
- ctx->cid,
- 1, /* MBIMActivationCommandActivate */
- ctx->apn,
- username,
- password,
- 0, /*MBIMCompressionNone */
- auth_method_to_auth_protocol(ctx->auth_method),
- proto_to_context_ip_type(ctx->proto),
- mbim_context_type_internet);
+
+ if (mbim_device_check_mbimex_version(gcd->device, 3, 0)) {
+ mbim_message_set_arguments(message, "uuuuu16yussss",
+ ctx->cid,
+ 1, // Activate
+ 0, // Compression
+ auth_method_to_auth_protocol(ctx->auth_method),
+ proto_to_context_ip_type(ctx->proto),
+ mbim_context_type_internet,
+ 0, // MbimMediaTypeNone
+ ctx->apn,
+ username,
+ password,
+ NULL);
+ } else {
+ mbim_message_set_arguments(message, "uusssuuu16y",
+ ctx->cid,
+ 1, // Activate
+ ctx->apn,
+ username,
+ password,
+ 0, // compression
+ auth_method_to_auth_protocol(ctx->auth_method),
+ proto_to_context_ip_type(ctx->proto),
+ mbim_context_type_internet);
+ }
if (mbim_device_send(gcd->device, GPRS_CONTEXT_GROUP, message,
mbim_activate_cb, gc, NULL) > 0)
diff --git a/drivers/mbimmodem/mbim.c b/drivers/mbimmodem/mbim.c
index 43ff9704..be4df986 100644
--- a/drivers/mbimmodem/mbim.c
+++ b/drivers/mbimmodem/mbim.c
@@ -107,6 +107,11 @@ const uint8_t mbim_context_type_local[] = {
0x03, 0x3C, 0x39, 0xF6, 0x0D, 0xB9,
};
+const uint8_t mbim_ms_basic_connect_extensions[] = {
+ 0x3D, 0x01, 0xDC, 0xC5, 0xFE, 0xF5, 0x4D, 0x05, 0x0D, 0x3A,
+ 0xBE, 0xF7, 0x05, 0x8E, 0x9A, 0xAF,
+};
+
struct message_assembly_node {
struct mbim_message_header msg_hdr;
struct mbim_fragment_header frag_hdr;
@@ -253,6 +258,11 @@ struct mbim_device {
struct message_assembly *assembly;
struct l_idle *close_io;
+ uint8_t mbim_version_major;
+ uint8_t mbim_version_minor;
+ uint8_t mbimex_version_major;
+ uint8_t mbimex_version_minor;
+
bool is_ready : 1;
bool in_notify : 1;
};
@@ -875,6 +885,22 @@ static bool close_read_handler(struct l_io *io, void *user_data)
return true;
}
+static void parse_mbim_version(struct mbim_message *message, void *user_data)
+{
+ struct mbim_device *device = user_data;
+ uint16_t mbim_version = 0, mbimex_version = 0;
+
+ if (mbim_message_get_error(message) != 0)
+ return;
+
+ mbim_message_get_arguments(message, "qq", &mbim_version, &mbimex_version);
+
+ device->mbim_version_major = mbim_version >> 8;
+ device->mbim_version_minor = mbim_version & 0xFF;
+ device->mbimex_version_major = mbimex_version >> 8;
+ device->mbimex_version_minor = mbimex_version & 0xFF;
+}
+
struct mbim_device *mbim_device_new(int fd, uint32_t max_segment_size)
{
struct mbim_device *device;
@@ -1035,6 +1061,35 @@ bool mbim_device_set_ready_handler(struct mbim_device *device,
return true;
}
+void mbim_device_get_version(struct mbim_device *device)
+{
+ // Version is formatted as (major version) << 8 | (minor version)
+ const int mbim_version = 1 << 8 | 0;
+
+ // Always open with MBIMEx 3, devices not supporting it will fallback to MBIMEx 2
+ const int mbimex_version = 3 << 8 | 0;
+
+ struct mbim_message *message = mbim_message_new(mbim_ms_basic_connect_extensions,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION,
+ MBIM_COMMAND_TYPE_QUERY);
+
+ mbim_message_set_arguments(message, "qq",
+ mbim_version,
+ mbimex_version);
+
+ // For some reason, sending a message will return an error code, even if valid
+ mbim_device_send(device, 0, message,
+ parse_mbim_version, device, NULL);
+}
+
+bool mbim_device_check_mbimex_version(struct mbim_device *device,
+ int version_major, int version_minor)
+{
+ return (device->mbimex_version_major > version_major) ||
+ ((device->mbimex_version_major == version_major) &&
+ (device->mbimex_version_minor >= version_minor));
+}
+
uint32_t mbim_device_send(struct mbim_device *device, uint32_t gid,
struct mbim_message *message,
mbim_device_reply_func_t function,
diff --git a/drivers/mbimmodem/mbim.h b/drivers/mbimmodem/mbim.h
index 5f15d0a2..4a6c8f47 100644
--- a/drivers/mbimmodem/mbim.h
+++ b/drivers/mbimmodem/mbim.h
@@ -31,6 +31,8 @@ struct mbim_message;
#define MBIM_CID_IP_PACKET_FILTERS 23
#define MBIM_CID_MULTICARRIER_PROVIDERS 24
+#define MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION 15
+
#define MBIM_CID_SMS_CONFIGURATION 1
#define MBIM_CID_SMS_READ 2
#define MBIM_CID_SMS_SEND 3
@@ -87,6 +89,7 @@ extern const uint8_t mbim_uuid_phonebook[];
extern const uint8_t mbim_uuid_stk[];
extern const uint8_t mbim_uuid_auth[];
extern const uint8_t mbim_uuid_dss[];
+extern const uint8_t mbim_ms_basic_connect_extensions[];
extern const uint8_t mbim_context_type_none[];
extern const uint8_t mbim_context_type_internet[];
@@ -118,6 +121,10 @@ bool mbim_device_set_ready_handler(struct mbim_device *device,
void *user_data,
mbim_device_destroy_func_t destroy);
+void mbim_device_get_version(struct mbim_device *device);
+bool mbim_device_check_mbimex_version(struct mbim_device *device,
+ int version_major, int version_minor);
+
uint32_t mbim_device_send(struct mbim_device *device, uint32_t gid,
struct mbim_message *message,
mbim_device_reply_func_t function,
--
2.49.0