1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
|
From 4f31ba72de77ea5e6462ba7f71825de2c46d9348 Mon Sep 17 00:00:00 2001
From: Muhammad <thevancedgamer@mentallysanemainliners.org>
Date: Sat, 19 Apr 2025 18:22:13 +0500
Subject: [PATCH 1/4] mbimmodem: add support for MBIM extensions * With MBIMEx
3.0, arguments for activating GPRS changed. Update as needed.
---
drivers/mbimmodem/gprs-context.c | 59 ++++++++++++++++++++++++--------
drivers/mbimmodem/mbim.c | 53 ++++++++++++++++++++++++++++
drivers/mbimmodem/mbim.h | 6 ++++
3 files changed, 104 insertions(+), 14 deletions(-)
--- a/drivers/mbimmodem/gprs-context.c
+++ b/drivers/mbimmodem/gprs-context.c
@@ -102,9 +102,16 @@
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 @@
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 @@
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)
--- a/drivers/mbimmodem/mbim.c
+++ b/drivers/mbimmodem/mbim.c
@@ -107,6 +107,11 @@
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 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;
};
@@ -879,6 +889,22 @@
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;
@@ -1039,6 +1065,33 @@
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,
--- a/drivers/mbimmodem/mbim.h
+++ b/drivers/mbimmodem/mbim.h
@@ -31,6 +31,8 @@
#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_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,9 @@
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,
|