[PATCH v3 2/5] mbimmodem: add support for MBIM extensions With MBIMEx 3.0, arguments for activating GPRS changed. Update as needed.
Muhammad Asif <[email protected]> Sat, 3 May 2025 00:03:15 +0500
| Newsgroups | dev.linux.lists.ofono |
|---|---|
| Message-ID | <[email protected]> |
From: Muhammad <[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