Merge cros/upstream to cros/master
Contains the following commits:
0a119a7 libmbim-glib,device: ensure CLOSED state always in mbim_device_close() (Aleksander Morgado)
ce8b4da libmbim-glib,device: don't allow close() if opening (Aleksander Morgado)
411287f mbim-codegen: add support to r/w 16bit unsigned integers (Som_SP)
9f9da41 libmbim-glib,ms-basic-connect-extensions: adding cid 'version' (Som_SP)
f58ba1c libmbim-glib,ms-basic-connect-extensions: adding cid 'location-info-status' (Som_SP)
5a8672e mbimcli,ms-basic-connect-extensions: remove redundant comments (Aleksander Morgado)
8af3bbd mbimcli,ms-basic-connect-extensions: minor comment style issues (Aleksander Morgado)
87413ab mbimcli,ms-basic-connect-extensions: improve --ms-query-version command help (Aleksander Morgado)
a596ba4 mbimcli,ms-basic-connect-extensions: switch 16 bit reader to bcd reader (Aleksander Morgado)
a64d93a build: use python3 everywhere (goapunk)
f5a06ff build: Use the newer python module (Iñigo Martínez)
28dc349 build: Make use of the summary function (Iñigo Martínez)
2e6edfc build: Create a variable for the project name (Iñigo Martínez)
69c72d3 build: Use / instead of join_paths (Iñigo Martínez)
38deb2f build: Removed duplicated variable (Iñigo Martínez)
6b4a303 build: Make use of features build option for introspection (Iñigo Martínez)
9607e04 build: Make use of dictionaries (Iñigo Martínez)
28674e6 build: Use the if_found feature (Iñigo Martínez)
02b027b build: Use strings for include_directories (Iñigo Martínez)
35abb03 build: Use the install_mode option (Iñigo Martínez)
86a5dc7 build: Use install_dir instead of subdir (Iñigo Martínez)
531374d build: Add version script linker flag when available (Iñigo Martínez)
433108b build: Remove unnecessary MALLOC_PERTURB_ variable set (Iñigo Martínez)
231ade7 build: Add explicit content files to documentation (Iñigo Martínez)
5da217a libmbim-glib,mbimcli: remove execution bit from mode in source files (Aleksander Morgado)
d356118 build: cleanup gitignore after meson port (Aleksander Morgado)
9e0a74d ci: add tests without introspection support (Aleksander Morgado)
73137ab ci: add uninstall check in the release task (Aleksander Morgado)
8fe6a3d libmbim-glib,device: new 'MS_MBIMEX_V2' open flag (Aleksander Morgado)
547de0c libmbim-glib,device: new methods to manage the MBIMEx version (Aleksander Morgado)
418f289 libmbim-glib,enums: define 5G NSA/SA data classes (Aleksander Morgado)
18c5e77 mbim-codegen: no need to redefine service inside each command (Aleksander Morgado)
ae83b73 ms-basic-connect-v2: new 'MS Basic Connect V2" service and 'Register State' message (Aleksander Morgado)
edb1d92 libmbim-glib,message: new method to get printable string with mbimex support (Aleksander Morgado)
2842748 mbimcli: allow requesting MBIMEx v2.0 support on device open (Aleksander Morgado)
63cf334 mbimcli,basic-connect: support MBIMEx v2.0 'Register State' (Aleksander Morgado)
39abda6 libmbim-glib,proxy: monitor MBIMEx version exchange and track per device (Aleksander Morgado)
d94fb7a libmbim-glib,proxy: notify to all clients updates in the MBIMEx version (Aleksander Morgado)
baa6641 libmbim,device: receive from proxy MBIMEx version updates (Aleksander Morgado)
67f895a libmbim-glib,proxy: notify to new clients the current MBIMEx version (Aleksander Morgado)
d21bcb6 ms-basic-connect-v2: implement 'Packet Service' (Som_SP)
af6f897 mbimcli,basic-connect: support MBIMEx v2.0 'Packet Service' (Aleksander Morgado)
718e6ce mbim-codegen: report UNSUPPORTED error when printing unknown CID (Aleksander Morgado)
1d0415b libmbim-glib,message: fallback to printing v1 format if message undefined in v2 (Aleksander Morgado)
9538b9f build-aux,codegen: add missing annotations in the input 'ref-struct-array' types (Aleksander Morgado)
de75176 build-aux,codegen: separate methods to process different struct array types (Aleksander Morgado)
8dde6bb build-aux,codegen: fix error messages when 'struct-type' field missing (Aleksander Morgado)
cd3554c build-aux,codegen: define new 'ms-struct-array' type (Aleksander Morgado)
bd89b91 ms-basic-connect-v2: implement 'Signal State v2' (Aleksander Morgado)
54d738b sms: fix public format for SMS CDMA language (Aleksander Morgado)
fa06ce0 build-aux,codegen: document public format type in struct fields (Aleksander Morgado)
f73fba3 build-aux,codegen: include printable info for struct fields with public type (Aleksander Morgado)
54cec41 mbimcli,basic-connect: support MBIMEx v2.0 'Signal State' (Aleksander Morgado)
7ebff59 ms-basic-connect-extensions: implement 'provisioned-context-v2' (Som_SP)
d6d0114 ms-basic-connect-extensions: minor alignment fixes in JSON (Aleksander Morgado)
392e95a ms-basic-connect-extensions: rename enum types in 'Provisioned Contexts v2' (Aleksander Morgado)
caa3b47 docs: add missing references to 'Provisioned Contexts v2' enum types (Aleksander Morgado)
dd14741 mbimcli,ms-basic-connect-extensions: minor coding style updates (Aleksander Morgado)
19cd976 mbimcli: don't include possible enum values in the short command help (Aleksander Morgado)
b35422e mbimcli,basic-connect: overwrite duplicated key-value pairs (Aleksander Morgado)
d8cb4b0 mbimcli,ms-basic-connect-extensions: use key-value pairs for --ms-set-provisioned-contexts (Aleksander Morgado)
172c462 mbimcli,basic-connect: deprecate 'apn' key and prefer 'access-string' (Aleksander Morgado)
6c2d10e mbimcli,basic-connect: minor coding style updates (Aleksander Morgado)
e7654f8 mbimcli,basic-connect: auth, username and protocol validation only in legacy input format (Aleksander Morgado)
07ff953 mbimcli: setup common helper to get enum values from strings (Aleksander Morgado)
c896f5f mbimcli,ms-basic-connect-extensions: avoid custom string to enums parsers (Aleksander Morgado)
005f1e9 mbimcli,basic-connect: avoid custom string to enums parsers (Aleksander Morgado)
804f07c mbimcli,basic-connect: support 'compression' in --connect (Aleksander Morgado)
9808f46 mbimcli,basic-connect: support 'context-type' in --connect (Aleksander Morgado)
5b6a4ad mbimcli,ms-basic-connect-extensions: fix double message unref (Aleksander Morgado)
06312c0 mbimcli,sar: use 'all' to set antenna index as '0xFFFFFFFF' (Jack Song)
64f52fc mbimcli,sar: avoid custom string to enums parsers (Aleksander Morgado)
7fd0ac2 mbimcli,sar: use regex matching for the list of SAR config states (Aleksander Morgado)
c9672ae mbimcli,sar: minor changes in how SAR config response is printed (Aleksander Morgado)
6d2140a mbimcli,sar: print 'all' instead of '0xFFFFFFFF' in SAR config response (Aleksander Morgado)
80bcf58 mbimcli,sar: demote message to debug level (Aleksander Morgado)
d1d75f0 ci: bump image template to refresh CA certificates (Aleksander Morgado)
d9552bc MBIMEx 3.0: implement "registration-params" (Som_SP)
ef95079 ms-basic-connect-extensions: add comment about unnamed IEs in Register Params (Aleksander Morgado)
6bfe3e5 ms-basic-connect-extensions: rename 'Registration Params' to 'Registration Parameters' (Aleksander Morgado)
fa93547 libmbim-glib,cid: add missing entry for 'Registration Parameters' (Aleksander Morgado)
2ed143c build-aux,codegen: allow 'gboolean' as public output (Aleksander Morgado)
ae85b33 ms-basic-connect-extensions: rework enum fields in 'Registration Parameters' (Aleksander Morgado)
03335a2 mbimcli,ms-basic-connect-extensions: use key-value pairs for --ms-set-registration-parameters (Aleksander Morgado)
21b5c67 docs,reference: add 1.28 index reference (Aleksander Morgado)
881f9a3 docs,reference: add missing enum documentation (Aleksander Morgado)
3d44393 libmbim-glib,proxy: report MBIMEx to clients on proxy config (Aleksander Morgado)
6928485 ms-basic-connect-v3: implement "subscriber-ready-status" (Som_SP)
48d1a88 libmbim-glib,device: allow requesting MBIMEx v3.0 (Aleksander Morgado)
a81e655 libmbim-glib,ms-basic-connect-v3: add new service to build (Aleksander Morgado)
6eff8a7 libmbim-glib,ms-basic-connect-v3: fix ready status flags (Aleksander Morgado)
c9572ba docs,reference: add missing MbimSubscriberReadyStatusFlag flag docs (Aleksander Morgado)
7b6b249 mbimcli: allow requesting MBIMEx v3.0 (Aleksander Morgado)
a710f74 libmbim-glib,message: support printing basic connect v3 messages (Aleksander Morgado)
60f779c ms-basic-connect-extensions-v3: implement 'lte-attach-info' (Som_SP)
7a764b4 libmbim-glib,ms-basic-connect-extensions-v3: add new service to build (Aleksander Morgado)
7ef442b ms-basic-connect-extensions-v3: fix order of NwError field (Aleksander Morgado)
bb1d6da mbimcli,ms-basic-connect-extensions: print detailed network error info (Aleksander Morgado)
75f3b0b libmbim-glib,enums: rename MBIM_NW_ERROR_UNKNOWN to MBIM_NW_ERROR_NONE (Aleksander Morgado)
6378f61 build: version bump to indicate existence of new API (MBIM_NW_ERROR_NONE) (Aleksander Morgado)
0d31108 build-aux,codegen: always initialize output array size in ms-struct-array (Aleksander Morgado)
ff2930b build-aux,codegen: treat empty ms-struct-array as no array (Aleksander Morgado)
f200daf build-aux,codegen: new 'ms-struct' type (Aleksander Morgado)
75c5b76 build-aux,codegen: support 'gint32' fields in structs (Aleksander Morgado)
a8673ea libmbim-glib: implement 'Base Stations Info' (Aleksander Morgado)
426a135 build-aux,codegen: generate support for all versions of same service together (Aleksander Morgado)
45523ca ms-basic-connect-v2: don't reimplement commands if they didn't change (Aleksander Morgado)
91adfb1 ms-basic-connect-v3: don't reimplement commands if they didn't change (Aleksander Morgado)
c3c7277 ms-basic-connect-extensions-v3: don't reimplement commands if they didn't change (Aleksander Morgado)
0a5176f libmbim-glib: implement 'Base Stations Info v3' (Aleksander Morgado)
11ba859 MBIMEx 3.0: implement "packet service v3" for SA (Som_SP)
0ab3098 mbimcli,basic-connect: minor rework on how packet service status response is printed (Aleksander Morgado)
01b8115 ms-basic-connect-v3: fix MbimTai struct definition (Aleksander Morgado)
8c781c8 ms-basic-connect: implement connect for mbim version 3 (Som_SP)
56983e6 libmbim-glib: new MbimTlv generic type (Aleksander Morgado)
f20b157 libmbim-glib,test,message-builder: include printable output in traces (Aleksander Morgado)
2bb3cc6 libmbim-glib,test,message-parser: include printable output in traces (Aleksander Morgado)
9506fd8 ms-basic-connect-v3: switch 'Basic Connect' to use MbimTlvs (Aleksander Morgado)
b7432fc build-aux,codegen: remove 'string-tlv' from structs (Aleksander Morgado)
9f60c77 mbimcli,basic-connect: avoid updating connect positional arguments logic (Aleksander Morgado)
b72136e build-aux,mbim-codegen: report ms-struct and ms-struct-array as nullable (Aleksander Morgado)
421ead1 libmbim-glib,mbimcli: 'Version' command is part of MBIMEx v2.0 (Aleksander Morgado)
3ec0440 libmbim-glib,tlv: specify it's used since MBIMEx v3.0 (Aleksander Morgado)
2658b0b libmbim-glib,mbimcli: 'Registration Parameters' command is part of MBIMEx v3.0 (Aleksander Morgado)
31bcbea libmbim-glib,enums: add missing Since tags (Aleksander Morgado)
700d07a libmbim-glib,enums: add comment about MBimDataClass vs MbimDataClassV2 (Aleksander Morgado)
b292716 libmbim-glib: Adding esim no profile support in ready state (Som_SP)
ab20894 libmbim-glib,enums: update MBIM_SUBSCRIBER_READY_STATE_NO_ESIM_PROFILE doc (Aleksander Morgado)
8482cdc build: version bump to flag existence of new API (NO_ESIM_PROFILE) (Aleksander Morgado)
ab218de libmbim-glib,enums: minor fix in MBIM_FREQUENCY_RANGE_UNKNOWN (Aleksander Morgado)
a58bb37 libmbim-glib,proxy: fix wrong message unref in MBIMEx reporting logic (Aleksander Morgado)
b840b84 docs,reference: add missing entries for mbim_tlv_string_{new|get} (Aleksander Morgado)
32034e4 libmbim-glib,tlv: fix string reading in BE systems (Aleksander Morgado)
872259e libmbim-glib,message: remove obsolete read_string_tlv() method (Aleksander Morgado)
d69bab7 build-aux,codegen: fix attempting to unref a NULL MbimTlv (Aleksander Morgado)
6d09092 libmbim-glib,message: printable support for MBIMEx v2.0 extensions (Aleksander Morgado)
96d9140 libmbim-glib,enums: rename 'MbimDataClassV2' to 'MbimDataClassV3' (Aleksander Morgado)
a5fbc67 libmbim-glib,enums: update MbimCtrlCaps in MBIMEx v3.0 (Aleksander Morgado)
25b17dc build-aux,codegen: new 'tlv-guint16-array' field type (Aleksander Morgado)
88cc6b2 MBIMEx 3.0: implement 'device caps v3' (Som_SP)
5b20317 mbimcli: add support for MBIMEx v3.0 Device Caps (Aleksander Morgado)
9eb738c ms-basic-connect-extensions-v3: implement 'Modem Configuration' (Som_SP)
ee9eea6 ms-basic-connect-extensions: implement wake-reason (Som_SP)
e980523 libmbim-glib,tlv: parsers for wake command and wake packet types (Aleksander Morgado)
70ccf75 libmbim-glib,test: always enable message traces (Aleksander Morgado)
e335b17 libmbim-glib,test: add Device Caps v3 parser test (Aleksander Morgado)
7590e34 libmbim-glib,test: minor refactoring in method names (Aleksander Morgado)
f6fbc6c build: Fix double quotes in rules file (Iñigo Martínez)
792af73 meson.build: add an option to not build man pages. (Nicolas Cavallari)
b72257f basic-connect: implement ip-packet-filters (Som_SP)
489f40e mbimcli: implement --set-ip-packet-filters (Aleksander Morgado)
4ea5995 libmbim-glib,uuid: new context type definitions in Microsoft Extensions (Aleksander Morgado)
8c2eac7 libmbim-glib,uuid: set missing Since tag in MBIM_UUID_MS_UICC_LOW_LEVEL_ACCESS (Aleksander Morgado)
984fe27 libmbim-glib,enums: fix MbimAccessMediaType documentation (Aleksander Morgado)
b3cca0c libmbim-glib,api: rename 'network blacklist' to 'network denylist' (Aleksander Morgado)
523da17 libmbim-glib,device: rename 'dummy' with 'placeholder' (Aleksander Morgado)
0af01cf Revert "CHROMIUM: Disable help2man doc generation" (Madhav)
cc3350c Merge branch 'upstream' of https://chromium.googlesource.com/chromiumos/third_party/libmbim into merge-upstream (Madhav)
BUG=b:204815284
TEST=emerge-dedede libmbim && cros deploy && run tast
Cq-Depend: chromium:3290496
Change-Id: Idb5fdac277ea0a545565b54d723530c7b68fab52
diff --git a/.gitignore b/.gitignore
index bdc0a38..98af0c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,82 +1,3 @@
*~
-*.o
-*.lo
-*.la
*.bz2
*.pyc
-*.gir
-*.typelib
-
-Makefile
-Makefile.in
-.deps
-.libs
-
-/INSTALL
-/aclocal.m4
-/autom4te.cache
-/compile
-/config.*
-/configure
-/install-sh
-/libtool
-/ltmain.sh
-/m4
-/missing
-/stamp-h1
-/depcomp
-
-/data/pkg-config/mbim-glib.pc
-
-/docs/reference/libmbim-glib/version.xml
-/docs/reference/libmbim-glib/libmbim-glib.args
-/docs/reference/libmbim-glib/libmbim-glib.hierarchy
-/docs/reference/libmbim-glib/libmbim-glib.interfaces
-/docs/reference/libmbim-glib/libmbim-glib.prerequisites
-/docs/reference/libmbim-glib/libmbim-glib.signals
-/docs/reference/libmbim-glib/libmbim-glib.actions
-/docs/reference/libmbim-glib/libmbim-glib.types
-/docs/reference/libmbim-glib/*.mstamp
-/docs/reference/libmbim-glib/*.stamp
-/docs/reference/libmbim-glib/*.txt
-/docs/reference/libmbim-glib/*.bak
-/docs/reference/libmbim-glib/html
-/docs/reference/libmbim-glib/tmpl
-/docs/reference/libmbim-glib/xml
-/docs/reference/libmbim-glib/.libs
-
-/docs/man/mbimcli.1
-/docs/man/mbim-network.1
-
-/src/common/test/test-common
-
-/src/libmbim-glib/.deps
-/src/libmbim-glib/.libs
-/src/libmbim-glib/mbim-version.h
-
-/src/libmbim-glib/test/.deps
-/src/libmbim-glib/test/.libs
-/src/libmbim-glib/test/test-uuid
-/src/libmbim-glib/test/test-cid
-/src/libmbim-glib/test/test-message
-/src/libmbim-glib/test/test-fragment
-/src/libmbim-glib/test/test-message-parser
-/src/libmbim-glib/test/test-message-builder
-/src/libmbim-glib/test/test-proxy-helpers
-/src/libmbim-glib/test/*.log
-/src/libmbim-glib/test/*.trs
-
-/src/libmbim-glib/generated/.deps
-/src/libmbim-glib/generated/.libs
-/src/libmbim-glib/generated/*.c
-/src/libmbim-glib/generated/*.h
-/src/libmbim-glib/generated/*.sections
-
-/src/mbimcli/.deps
-/src/mbimcli/.libs
-/src/mbimcli/mbimcli
-
-/utils/mbim-network
-
-/src/mbim-proxy/mbim-proxy
-/src/mbim-proxy/76-mbim-proxy-device-ownership.rules
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 68cfbff..0374b49 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -11,8 +11,8 @@
.common_variables:
variables:
FDO_UPSTREAM_REPO: mobile-broadband/libmbim
- FDO_DISTRIBUTION_VERSION: '18.04'
- FDO_DISTRIBUTION_TAG: '2021-07-27.1'
+ FDO_DISTRIBUTION_VERSION: '20.04'
+ FDO_DISTRIBUTION_TAG: '2021-10-03.1'
FDO_DISTRIBUTION_PACKAGES: ca-certificates git gcc libgirepository1.0-dev
libglib2.0-dev gtk-doc-tools libglib2.0-doc
gobject-introspection bash-completion valac
@@ -30,7 +30,7 @@
- tags
- pushes
-build-meson-default:
+build-no-introspection:
stage: build
extends:
- .fdo.distribution-image@ubuntu
@@ -41,10 +41,38 @@
- tags
- schedules
script:
- - meson setup _debug_build --prefix=/usr -Dwerror=true
- - ninja -C _debug_build
- - ninja -C _debug_build install
- - meson setup _release_build --prefix=/usr --buildtype=release -Dwerror=true
- - ninja -C _release_build
- - ninja -C _release_build install
- - ninja -C _release_build dist
+ - meson setup build --prefix=/usr -Dwerror=true -Dintrospection=disabled
+ - ninja -C build
+ - ninja -C build install
+
+build-introspection:
+ stage: build
+ extends:
+ - .fdo.distribution-image@ubuntu
+ - .common_variables
+ only:
+ - master
+ - merge_requests
+ - tags
+ - schedules
+ script:
+ - meson setup build --prefix=/usr -Dwerror=true -Dintrospection=enabled
+ - ninja -C build
+ - ninja -C build install
+
+build-release:
+ stage: build
+ extends:
+ - .fdo.distribution-image@ubuntu
+ - .common_variables
+ only:
+ - master
+ - merge_requests
+ - tags
+ - schedules
+ script:
+ - meson setup build --buildtype=release --prefix=/usr -Dwerror=true -Dintrospection=enabled
+ - ninja -C build
+ - ninja -C build install
+ - ninja -C build dist
+ - ninja -C build uninstall
diff --git a/build-aux/mbim-codegen/Message.py b/build-aux/mbim-codegen/Message.py
index 0d10ca9..0e24cac 100644
--- a/build-aux/mbim-codegen/Message.py
+++ b/build-aux/mbim-codegen/Message.py
@@ -45,6 +45,8 @@
pass
elif field['format'] == 'uuid':
pass
+ elif field['format'] == 'guint16':
+ pass
elif field['format'] == 'guint32':
pass
elif field['format'] == 'guint32-array':
@@ -58,14 +60,20 @@
elif field['format'] == 'struct':
if 'struct-type' not in field:
raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ elif field['format'] == 'ms-struct':
+ if 'struct-type' not in field:
+ raise ValueError('Field type \'ms-struct\' requires \'struct-type\' field')
elif field['format'] == 'struct-array':
flag_always_read_field(fields, field['array-size-field'])
if 'struct-type' not in field:
- raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ raise ValueError('Field type \'struct-array\' requires \'struct-type\' field')
elif field['format'] == 'ref-struct-array':
flag_always_read_field(fields, field['array-size-field'])
if 'struct-type' not in field:
- raise ValueError('Field type \'struct\' requires \'struct-type\' field')
+ raise ValueError('Field type \'ref-struct-array\' requires \'struct-type\' field')
+ elif field['format'] == 'ms-struct-array':
+ if 'struct-type' not in field:
+ raise ValueError('Field type \'ms-struct-array\' requires \'struct-type\' field')
elif field['format'] == 'ipv4':
pass
elif field['format'] == 'ref-ipv4':
@@ -78,6 +86,14 @@
pass
elif field['format'] == 'ipv6-array':
flag_always_read_field(fields, field['array-size-field'])
+ elif field['format'] == 'tlv':
+ pass
+ elif field['format'] == 'tlv-string':
+ pass
+ elif field['format'] == 'tlv-guint16-array':
+ pass
+ elif field['format'] == 'tlv-list':
+ pass
else:
raise ValueError('Cannot handle field type \'%s\'' % field['format'])
@@ -90,9 +106,11 @@
"""
Constructor
"""
- def __init__(self, dictionary):
+ def __init__(self, service, mbimex_service, mbimex_version, dictionary):
# The message service, e.g. "Basic Connect"
- self.service = dictionary['service']
+ self.service = service
+ self.mbimex_service = mbimex_service
+ self.mbimex_version = mbimex_version
# The name of the specific message, e.g. "Something"
self.name = dictionary['name']
@@ -154,8 +172,18 @@
else:
self.fullname = 'MBIM Message ' + self.service + ' ' + self.name
+ # Build SERVICE enum
+ if self.mbimex_service:
+ self.service_enum_name = 'MBIM Service ' + self.mbimex_service
+ else:
+ self.service_enum_name = 'MBIM Service ' + self.service
+ self.service_enum_name = utils.build_underscore_name(self.service_enum_name).upper()
+
# Build CID enum
- self.cid_enum_name = 'MBIM CID ' + self.service
+ if self.mbimex_service:
+ self.cid_enum_name = 'MBIM CID ' + self.mbimex_service
+ else:
+ self.cid_enum_name = 'MBIM CID ' + self.service
if self.name != "":
self.cid_enum_name += (' ' + self.name)
self.cid_enum_name = utils.build_underscore_name(self.cid_enum_name).upper()
@@ -194,14 +222,14 @@
Emit message creator
"""
def _emit_message_creator(self, hfile, cfile, message_type, fields, since):
- translations = { 'message' : self.name,
- 'service' : self.service,
- 'since' : since,
- 'underscore' : utils.build_underscore_name (self.fullname),
- 'message_type' : message_type,
- 'message_type_upper' : message_type.upper(),
- 'service_underscore_upper' : utils.build_underscore_name (self.service).upper(),
- 'cid_enum_name' : self.cid_enum_name }
+ translations = { 'message' : self.name,
+ 'service' : self.service,
+ 'since' : since,
+ 'underscore' : utils.build_underscore_name (self.fullname),
+ 'message_type' : message_type,
+ 'message_type_upper' : message_type.upper(),
+ 'service_enum_name' : self.service_enum_name,
+ 'cid_enum_name' : self.cid_enum_name }
template = (
'\n'
@@ -226,6 +254,8 @@
' * @${field}: (in)(element-type guint8)(array length=${field}_size): the \'${name}\' field, given as an array of #guint8 values.\n')
elif field['format'] == 'uuid':
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #MbimUuid.\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #${public}.\n')
elif field['format'] == 'guint32':
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #${public}.\n')
elif field['format'] == 'guint64':
@@ -236,10 +266,14 @@
inner_template = (' * @${field}: (in)(type GStrv): the \'${name}\' field, given as an array of strings.\n')
elif field['format'] == 'struct':
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #${struct}.\n')
+ elif field['format'] == 'ms-struct':
+ raise ValueError('type \'ms-struct\' unsupported as input')
elif field['format'] == 'struct-array':
inner_template = (' * @${field}: (in)(array zero-terminated=1)(element-type ${struct}): the \'${name}\' field, given as an array of #${struct} items.\n')
elif field['format'] == 'ref-struct-array':
- inner_template = (' * @${field}: (in): the \'${name}\' field, given as an array of #${struct} items.\n')
+ inner_template = (' * @${field}: (in)(array zero-terminated=1)(element-type ${struct}): the \'${name}\' field, given as an array of #${struct} items.\n')
+ elif field['format'] == 'ms-struct-array':
+ raise ValueError('type \'ms-struct-array\' unsupported as input')
elif field['format'] == 'ipv4':
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #MbimIPv4.\n')
elif field['format'] == 'ref-ipv4':
@@ -252,6 +286,14 @@
inner_template = (' * @${field}: (in): the \'${name}\' field, given as a #MbimIPv6.\n')
elif field['format'] == 'ipv6-array':
inner_template = (' * @${field}: (in)(array zero-terminated=1)(element-type MbimIPv6): the \'${name}\' field, given as an array of #MbimIPv6 items.\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' * @${field}: (in)(transfer none): the \'${name}\' field, given as a #${struct} item.\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' * @${field}: (in): the \'${name}\' field, given as a string.\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' * @${field}: (in)(element-type MbimTlv)(transfer none): the \'${name}\' field, given as a list of #${struct} items.\n')
template += (string.Template(inner_template).substitute(translations))
@@ -282,6 +324,8 @@
' const guint8 *${field},\n')
elif field['format'] == 'uuid':
inner_template = (' const MbimUuid *${field},\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' ${public} ${field},\n')
elif field['format'] == 'guint32':
inner_template = (' ${public} ${field},\n')
elif field['format'] == 'guint64':
@@ -292,10 +336,14 @@
inner_template = (' const gchar *const *${field},\n')
elif field['format'] == 'struct':
inner_template = (' const ${struct} *${field},\n')
+ elif field['format'] == 'ms-struct':
+ raise ValueError('type \'ms-struct\' unsupported as input')
elif field['format'] == 'struct-array':
inner_template = (' const ${struct} *const *${field},\n')
elif field['format'] == 'ref-struct-array':
inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ms-struct-array':
+ raise ValueError('type \'ms-struct-array\' unsupported as input')
elif field['format'] == 'ipv4':
inner_template = (' const MbimIPv4 *${field},\n')
elif field['format'] == 'ref-ipv4':
@@ -308,6 +356,14 @@
inner_template = (' const MbimIPv6 *${field},\n')
elif field['format'] == 'ipv6-array':
inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' const MbimTlv *${field},\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' const GList *${field},\n')
template += (string.Template(inner_template).substitute(translations))
@@ -337,6 +393,8 @@
' const guint8 *${field},\n')
elif field['format'] == 'uuid':
inner_template = (' const MbimUuid *${field},\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' ${public} ${field},\n')
elif field['format'] == 'guint32':
inner_template = (' ${public} ${field},\n')
elif field['format'] == 'guint64':
@@ -347,10 +405,14 @@
inner_template = (' const gchar *const *${field},\n')
elif field['format'] == 'struct':
inner_template = (' const ${struct} *${field},\n')
+ elif field['format'] == 'ms-struct':
+ raise ValueError('type \'ms-struct\' unsupported as input')
elif field['format'] == 'struct-array':
inner_template = (' const ${struct} *const *${field},\n')
elif field['format'] == 'ref-struct-array':
inner_template = (' const ${struct} *const *${field},\n')
+ elif field['format'] == 'ms-struct-array':
+ raise ValueError('type \'ms-struct-array\' unsupported as input')
elif field['format'] == 'ipv4':
inner_template = (' const MbimIPv4 *${field},\n')
elif field['format'] == 'ref-ipv4':
@@ -363,6 +425,14 @@
inner_template = (' const MbimIPv6 *${field},\n')
elif field['format'] == 'ipv6-array':
inner_template = (' const MbimIPv6 *${field},\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' const MbimTlv *${field},\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' const gchar *${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' const GList *${field},\n')
template += (string.Template(inner_template).substitute(translations))
@@ -372,7 +442,7 @@
' MbimMessageCommandBuilder *builder;\n'
'\n'
' builder = _mbim_message_command_builder_new (0,\n'
- ' MBIM_SERVICE_${service_underscore_upper},\n'
+ ' ${service_enum_name},\n'
' ${cid_enum_name},\n'
' MBIM_MESSAGE_COMMAND_TYPE_${message_type_upper});\n')
@@ -407,6 +477,8 @@
inner_template += (' _mbim_message_command_builder_append_byte_array (builder, FALSE, TRUE, ${pad_array}, ${field}, ${field}_size, FALSE);\n')
elif field['format'] == 'uuid':
inner_template += (' _mbim_message_command_builder_append_uuid (builder, ${field});\n')
+ elif field['format'] == 'guint16':
+ inner_template += (' _mbim_message_command_builder_append_guint16 (builder, ${field});\n')
elif field['format'] == 'guint32':
inner_template += (' _mbim_message_command_builder_append_guint32 (builder, ${field});\n')
elif field['format'] == 'guint64':
@@ -417,10 +489,14 @@
inner_template += (' _mbim_message_command_builder_append_string_array (builder, ${field}, ${array_size_field});\n')
elif field['format'] == 'struct':
inner_template += (' _mbim_message_command_builder_append_${struct_underscore}_struct (builder, ${field});\n')
+ elif field['format'] == 'ms-struct':
+ raise ValueError('type \'ms-struct\' unsupported as input')
elif field['format'] == 'struct-array':
- inner_template += (' _mbim_message_command_builder_append_${struct_underscore}_struct_array (builder, ${field}, ${array_size_field}, FALSE);\n')
+ inner_template += (' _mbim_message_command_builder_append_${struct_underscore}_struct_array (builder, ${field}, ${array_size_field});\n')
elif field['format'] == 'ref-struct-array':
- inner_template += (' _mbim_message_command_builder_append_${struct_underscore}_struct_array (builder, ${field}, ${array_size_field}, TRUE);\n')
+ inner_template += (' _mbim_message_command_builder_append_${struct_underscore}_ref_struct_array (builder, ${field}, ${array_size_field});\n')
+ elif field['format'] == 'ms-struct-array':
+ raise ValueError('type \'ms-struct-array\' unsupported as input')
elif field['format'] == 'ipv4':
inner_template += (' _mbim_message_command_builder_append_ipv4 (builder, ${field}, FALSE);\n')
elif field['format'] == 'ref-ipv4':
@@ -433,6 +509,15 @@
inner_template += (' _mbim_message_command_builder_append_ipv6 (builder, ${field}, TRUE);\n')
elif field['format'] == 'ipv6-array':
inner_template += (' _mbim_message_command_builder_append_ipv6_array (builder, ${field}, ${array_size_field});\n')
+ elif field['format'] == 'tlv':
+ inner_template += (' _mbim_message_command_builder_append_tlv (builder, ${field});\n')
+ elif field['format'] == 'tlv-string':
+ inner_template += (' _mbim_message_command_builder_append_tlv_string (builder, ${field});\n')
+ elif field['format'] == 'tlv-guint16-array':
+ raise ValueError('type \'tlv-guint16-array\' unsupported as input')
+ elif field['format'] == 'tlv-list':
+ inner_template += (' _mbim_message_command_builder_append_tlv_list (builder, ${field});\n')
+
else:
raise ValueError('Cannot handle field type \'%s\'' % field['format'])
@@ -451,13 +536,12 @@
Emit message parser
"""
def _emit_message_parser(self, hfile, cfile, message_type, fields, since):
- translations = { 'message' : self.name,
- 'service' : self.service,
- 'since' : since,
- 'underscore' : utils.build_underscore_name (self.fullname),
- 'message_type' : message_type,
- 'message_type_upper' : message_type.upper(),
- 'service_underscore_upper' : utils.build_underscore_name (self.service).upper() }
+ translations = { 'message' : self.name,
+ 'service' : self.service,
+ 'since' : since,
+ 'underscore' : utils.build_underscore_name (self.fullname),
+ 'message_type' : message_type,
+ 'message_type_upper' : message_type.upper() }
template = (
'\n'
@@ -481,6 +565,8 @@
' * @out_${field}: (out)(optional)(transfer none)(element-type guint8)(array length=out_${field}_size): return location for an array of #guint8 values. Do not free the returned value, it is owned by @message.\n')
elif field['format'] == 'uuid':
inner_template = (' * @out_${field}: (out)(optional)(transfer none): return location for a #MbimUuid, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' * @out_${field}: (out)(optional)(transfer none): return location for a #${public}, or %NULL if the \'${name}\' field is not needed.\n')
elif field['format'] == 'guint32':
inner_template = (' * @out_${field}: (out)(optional)(transfer none): return location for a #${public}, or %NULL if the \'${name}\' field is not needed.\n')
elif field['format'] == 'guint64':
@@ -491,10 +577,15 @@
inner_template = (' * @out_${field}: (out)(optional)(transfer full)(type GStrv): return location for a newly allocated array of strings, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_strfreev().\n')
elif field['format'] == 'struct':
inner_template = (' * @out_${field}: (out)(optional)(transfer full): return location for a newly allocated #${struct}, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_free().\n')
+ elif field['format'] == 'ms-struct':
+ inner_template = (' * @out_${field}: (out)(optional)(nullable)(transfer full): return location for a newly allocated #${struct}, or %NULL if the \'${name}\' field is not needed. The availability of this field is not always guaranteed, and therefore %NULL may be given as a valid output. Free the returned value with ${struct_underscore}_free().\n')
elif field['format'] == 'struct-array':
inner_template = (' * @out_${field}: (out)(optional)(transfer full)(array zero-terminated=1)(element-type ${struct}): return location for a newly allocated array of #${struct} items, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_array_free().\n')
elif field['format'] == 'ref-struct-array':
inner_template = (' * @out_${field}: (out)(optional)(transfer full)(array zero-terminated=1)(element-type ${struct}): return location for a newly allocated array of #${struct} items, or %NULL if the \'${name}\' field is not needed. Free the returned value with ${struct_underscore}_array_free().\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template = (' * @out_${field}_count: (out)(optional)(transfer none): return location for a #guint32, or %NULL if the field is not needed.\n'
+ ' * @out_${field}: (out)(optional)(nullable)(transfer full)(array zero-terminated=1)(element-type ${struct}): return location for a newly allocated array of #${struct} items, or %NULL if the \'${name}\' field is not needed. The availability of this field is not always guaranteed, and therefore %NULL may be given as a valid output. Free the returned value with ${struct_underscore}_array_free().\n')
elif field['format'] == 'ipv4':
inner_template = (' * @out_${field}: (out)(optional)(transfer none): return location for a #MbimIPv4, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
elif field['format'] == 'ref-ipv4':
@@ -507,6 +598,15 @@
inner_template = (' * @out_${field}: (out)(optional)(transfer none): return location for a #MbimIPv6, or %NULL if the \'${name}\' field is not needed. Do not free the returned value, it is owned by @message.\n')
elif field['format'] == 'ipv6-array':
inner_template = (' * @out_${field}: (out)(optional)(transfer full)(array zero-terminated=1)(element-type MbimIPv6): return location for a newly allocated array of #MbimIPv6 items, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' * @out_${field}: (out)(optional)(transfer full): return location for a newly allocated #MbimTlv, or %NULL if the \'${name}\' field is not needed. Free the returned value with mbim_tlv_unref().\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' * @out_${field}: (out)(optional)(transfer full): return location for a newly allocated string, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_free().\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' * @out_${field}_count: (out)(optional)(transfer none): return location for a #guint32, or %NULL if the field is not needed.\n'
+ ' * @out_${field}: (out)(optional)(nullable)(transfer full): return location for a newly allocated array of #guint16 items, or %NULL if the \'${name}\' field is not needed. The availability of this field is not always guaranteed, and therefore %NULL may be given as a valid output. Free the returned value with g_free().\n')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' * @out_${field}: (out)(optional)(element-type MbimTlv)(transfer full): return location for a newly allocated list of #MbimTlv items, or %NULL if the \'${name}\' field is not needed. Free the returned value with g_list_free_full() using mbim_tlv_unref() as #GDestroyNotify.\n')
template += (string.Template(inner_template).substitute(translations))
@@ -535,6 +635,8 @@
' const guint8 **out_${field},\n')
elif field['format'] == 'uuid':
inner_template = (' const MbimUuid **out_${field},\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' ${public} *out_${field},\n')
elif field['format'] == 'guint32':
inner_template = (' ${public} *out_${field},\n')
elif field['format'] == 'guint64':
@@ -545,10 +647,15 @@
inner_template = (' gchar ***out_${field},\n')
elif field['format'] == 'struct':
inner_template = (' ${struct} **out_${field},\n')
+ elif field['format'] == 'ms-struct':
+ inner_template = (' ${struct} **out_${field},\n')
elif field['format'] == 'struct-array':
inner_template = (' ${struct}Array **out_${field},\n')
elif field['format'] == 'ref-struct-array':
inner_template = (' ${struct}Array **out_${field},\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' ${struct}Array **out_${field},\n')
elif field['format'] == 'ipv4':
inner_template = (' const MbimIPv4 **out_${field},\n')
elif field['format'] == 'ref-ipv4':
@@ -561,6 +668,15 @@
inner_template = (' const MbimIPv6 **out_${field},\n')
elif field['format'] == 'ipv6-array':
inner_template = (' MbimIPv6 **out_${field},\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' MbimTlv **out_${field},\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' gchar **out_${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' guint16 **out_${field},\n')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' GList **out_${field},\n')
else:
raise ValueError('Cannot handle field type \'%s\'' % field['format'])
@@ -589,6 +705,8 @@
' const guint8 **out_${field},\n')
elif field['format'] == 'uuid':
inner_template = (' const MbimUuid **out_${field},\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' ${public} *out_${field},\n')
elif field['format'] == 'guint32':
inner_template = (' ${public} *out_${field},\n')
elif field['format'] == 'guint64':
@@ -599,10 +717,15 @@
inner_template = (' gchar ***out_${field},\n')
elif field['format'] == 'struct':
inner_template = (' ${struct} **out_${field},\n')
+ elif field['format'] == 'ms-struct':
+ inner_template = (' ${struct} **out_${field},\n')
elif field['format'] == 'struct-array':
inner_template = (' ${struct}Array **out_${field},\n')
elif field['format'] == 'ref-struct-array':
inner_template = (' ${struct}Array **out_${field},\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' ${struct}Array **out_${field},\n')
elif field['format'] == 'ipv4':
inner_template = (' const MbimIPv4 **out_${field},\n')
elif field['format'] == 'ref-ipv4':
@@ -615,6 +738,15 @@
inner_template = (' const MbimIPv6 **out_${field},\n')
elif field['format'] == 'ipv6-array':
inner_template = (' MbimIPv6 **out_${field},\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' MbimTlv **out_${field},\n')
+ elif field['format'] == 'tlv-string':
+ inner_template = (' gchar **out_${field},\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template = (' guint32 *out_${field}_count,\n'
+ ' guint16 **out_${field},\n')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' GList **out_${field},\n')
template += (string.Template(inner_template).substitute(translations))
@@ -645,18 +777,36 @@
elif field['format'] == 'struct':
count_allocated_variables += 1
inner_template = (' ${struct} *_${field} = NULL;\n')
+ elif field['format'] == 'ms-struct':
+ count_allocated_variables += 1
+ inner_template = (' ${struct} *_${field} = NULL;\n')
elif field['format'] == 'struct-array':
count_allocated_variables += 1
inner_template = (' ${struct} **_${field} = NULL;\n')
elif field['format'] == 'ref-struct-array':
count_allocated_variables += 1
inner_template = (' ${struct} **_${field} = NULL;\n')
+ elif field['format'] == 'ms-struct-array':
+ count_allocated_variables += 1
+ inner_template = (' ${struct} **_${field} = NULL;\n')
elif field['format'] == 'ipv4-array':
count_allocated_variables += 1
inner_template = (' MbimIPv4 *_${field} = NULL;\n')
elif field['format'] == 'ipv6-array':
count_allocated_variables += 1
inner_template = (' MbimIPv6 *_${field} = NULL;\n')
+ elif field['format'] == 'tlv':
+ count_allocated_variables += 1
+ inner_template = (' MbimTlv *_${field} = NULL;\n')
+ elif field['format'] == 'tlv-string':
+ count_allocated_variables += 1
+ inner_template = (' gchar *_${field} = NULL;\n')
+ elif field['format'] == 'tlv-guint16-array':
+ count_allocated_variables += 1
+ inner_template = (' guint16 *_${field} = NULL;\n')
+ elif field['format'] == 'tlv-list':
+ count_allocated_variables += 1
+ inner_template = (' GList *_${field} = NULL;\n')
template += (string.Template(inner_template).substitute(translations))
if message_type == 'response':
@@ -738,6 +888,7 @@
elif field['format'] == 'string' or \
field['format'] == 'string-array' or \
field['format'] == 'struct' or \
+ field['format'] == 'ms-struct' or \
field['format'] == 'struct-array' or \
field['format'] == 'ref-struct-array' or \
field['format'] == 'ipv4' or \
@@ -749,6 +900,12 @@
inner_template += (
' if (out_${field} != NULL)\n'
' *out_${field} = NULL;\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template += (
+ ' if (out_${field}_count != NULL)\n'
+ ' *out_${field}_count = 0;\n'
+ ' if (out_${field} != NULL)\n'
+ ' *out_${field} = NULL;\n')
else:
raise ValueError('Field format \'%s\' unsupported as optional field' % field['format'])
@@ -815,6 +972,23 @@
' if ((out_${field} != NULL) && !_mbim_message_read_uuid (message, offset, out_${field}, error))\n'
' goto out;\n'
' offset += 16;\n')
+ elif field['format'] == 'guint16':
+ if 'public-format' in field:
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+ inner_template += (
+ ' if (out_${field} != NULL) {\n'
+ ' guint16 aux;\n'
+ '\n'
+ ' if (!_mbim_message_read_guint16 (message, offset, &aux, error))\n'
+ ' goto out;\n'
+ ' *out_${field} = (${public})aux;\n'
+ ' }\n')
+ else:
+ inner_template += (
+ ' if ((out_${field} != NULL) && !_mbim_message_read_guint16 (message, offset, out_${field}, error))\n'
+ ' goto out;\n')
+ inner_template += (
+ ' offset += 2;\n')
elif field['format'] == 'guint32':
if 'public-format' in field:
translations['public'] = field['public-format'] if 'public-format' in field else field['format']
@@ -872,16 +1046,32 @@
' else\n'
' _${struct_name}_free (tmp);\n'
' offset += bytes_read;\n')
+ elif field['format'] == 'ms-struct':
+ inner_template += (
+ ' ${struct_type} *tmp = NULL;\n'
+ '\n'
+ ' if (!_mbim_message_read_${struct_name}_ms_struct (message, offset, &tmp, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' _${struct_name}_free (tmp);\n'
+ ' offset += 8;\n')
elif field['format'] == 'struct-array':
inner_template += (
- ' if ((out_${field} != NULL) && !_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, FALSE, &_${field}, error))\n'
+ ' if ((out_${field} != NULL) && !_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, &_${field}, error))\n'
' goto out;\n'
' offset += 4;\n')
elif field['format'] == 'ref-struct-array':
inner_template += (
- ' if ((out_${field} != NULL) && !_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, TRUE, &_${field}, error))\n'
+ ' if ((out_${field} != NULL) && !_mbim_message_read_${struct_name}_ref_struct_array (message, _${array_size_field}, offset, &_${field}, error))\n'
' goto out;\n'
' offset += (8 * _${array_size_field});\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template += (
+ ' if ((out_${field} != NULL) && !_mbim_message_read_${struct_name}_ms_struct_array (message, offset, out_${field}_count, &_${field}, error))\n'
+ ' goto out;\n'
+ ' offset += 8;\n')
elif field['format'] == 'ipv4':
inner_template += (
' if ((out_${field} != NULL) && !_mbim_message_read_ipv4 (message, offset, FALSE, out_${field}, error))\n'
@@ -912,6 +1102,54 @@
' if ((out_${field} != NULL) && !_mbim_message_read_ipv6_array (message, _${array_size_field}, offset, &_${field}, error))\n'
' goto out;\n'
' offset += 4;\n')
+ elif field['format'] == 'tlv':
+ inner_template += (
+ ' MbimTlv *tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv (message, offset, &tmp, &bytes_read, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' mbim_tlv_unref (tmp);\n'
+ ' offset += bytes_read;\n')
+ elif field['format'] == 'tlv-string':
+ inner_template += (
+ ' gchar *tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv_string (message, offset, &tmp, &bytes_read, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' g_free (tmp);\n'
+ ' offset += bytes_read;\n')
+ elif field['format'] == 'tlv-guint16-array':
+ inner_template += (
+ ' guint16 *tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv_guint16_array (message, offset, out_${field}_count, &tmp, &bytes_read, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' g_free (tmp);\n'
+ ' offset += bytes_read;\n')
+ elif field['format'] == 'tlv-list':
+ inner_template += (
+ ' GList *tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv_list (message, offset, &tmp, &bytes_read, error))\n'
+ ' goto out;\n'
+ ' if (out_${field} != NULL)\n'
+ ' _${field} = tmp;\n'
+ ' else\n'
+ ' g_list_free_full (tmp, (GDestroyNotify)mbim_tlv_unref);\n'
+ ' offset += bytes_read;\n')
inner_template += (
' }\n')
@@ -938,10 +1176,16 @@
if field['format'] == 'string' or \
field['format'] == 'string-array' or \
field['format'] == 'struct' or \
+ field['format'] == 'ms-struct' or \
field['format'] == 'struct-array' or \
field['format'] == 'ref-struct-array' or \
+ field['format'] == 'ms-struct-array' or \
field['format'] == 'ipv4-array' or \
- field['format'] == 'ipv6-array':
+ field['format'] == 'ipv6-array' or \
+ field['format'] == 'tlv' or \
+ field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array' or \
+ field['format'] == 'tlv-list':
inner_template = (' if (out_${field} != NULL)\n'
' *out_${field} = _${field};\n')
template += (string.Template(inner_template).substitute(translations))
@@ -954,14 +1198,21 @@
inner_template = ''
if field['format'] == 'string' or \
field['format'] == 'ipv4-array' or \
- field['format'] == 'ipv6-array':
+ field['format'] == 'ipv6-array' or \
+ field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array':
inner_template = (' g_free (_${field});\n')
elif field['format'] == 'string-array':
inner_template = (' g_strfreev (_${field});\n')
- elif field['format'] == 'struct':
+ elif field['format'] == 'struct' or field['format'] == 'ms-struct':
inner_template = (' ${struct_underscore}_free (_${field});\n')
- elif field['format'] == 'struct-array' or field['format'] == 'ref-struct-array':
+ elif field['format'] == 'struct-array' or field['format'] == 'ref-struct-array' or field['format'] == 'ms-struct-array':
inner_template = (' ${struct_underscore}_array_free (_${field});\n')
+ elif field['format'] == 'tlv':
+ inner_template = (' if (_${field})\n'
+ ' mbim_tlv_unref (_${field});\n')
+ elif field['format'] == 'tlv-list':
+ inner_template = (' g_list_free_full (_${field}, (GDestroyNotify)mbim_tlv_unref);\n')
template += (string.Template(inner_template).substitute(translations))
template += (
' }\n')
@@ -983,13 +1234,12 @@
Emit message printable
"""
def _emit_message_printable(self, cfile, message_type, fields):
- translations = { 'message' : self.name,
- 'underscore' : utils.build_underscore_name(self.name),
- 'service' : self.service,
- 'underscore' : utils.build_underscore_name (self.fullname),
- 'message_type' : message_type,
- 'message_type_upper' : message_type.upper(),
- 'service_underscore_upper' : utils.build_underscore_name (self.service).upper() }
+ translations = { 'message' : self.name,
+ 'underscore' : utils.build_underscore_name(self.name),
+ 'service' : self.service,
+ 'underscore' : utils.build_underscore_name (self.fullname),
+ 'message_type' : message_type,
+ 'message_type_upper' : message_type.upper() }
template = (
'\n'
'static gchar *\n'
@@ -1026,8 +1276,6 @@
translations['field_format'] = field['format']
translations['field_format_underscore'] = utils.build_underscore_name_from_camelcase(field['format'])
translations['public'] = field['public-format'] if 'public-format' in field else field['format']
- translations['public_underscore'] = utils.build_underscore_name_from_camelcase(field['public-format']) if 'public-format' in field else ''
- translations['public_underscore_upper'] = utils.build_underscore_name_from_camelcase(field['public-format']).upper() if 'public-format' in field else ''
translations['field_name'] = field['name']
translations['array_size_field'] = utils.build_underscore_name_from_camelcase(field['array-size-field']) if 'array-size-field' in field else ''
translations['struct_name'] = utils.build_underscore_name_from_camelcase(field['struct-type']) if 'struct-type' in field else ''
@@ -1113,12 +1361,18 @@
' tmpstr = mbim_uuid_get_printable (tmp);\n'
' g_string_append_printf (str, "\'%s\'", tmpstr);\n')
- elif field['format'] == 'guint32' or \
+ elif field['format'] == 'guint16' or \
+ field['format'] == 'guint32' or \
field['format'] == 'guint64':
inner_template += (
' ${field_format} tmp;\n'
'\n')
- if field['format'] == 'guint32' :
+ if field['format'] == 'guint16' :
+ inner_template += (
+ ' if (!_mbim_message_read_guint16 (message, offset, &tmp, &inner_error))\n'
+ ' goto out;\n'
+ ' offset += 2;\n')
+ elif field['format'] == 'guint32' :
inner_template += (
' if (!_mbim_message_read_guint32 (message, offset, &tmp, &inner_error))\n'
' goto out;\n'
@@ -1130,20 +1384,31 @@
' offset += 8;\n')
if 'public-format' in field:
+ if field['public-format'] == 'gboolean':
+ inner_template += (
+ ' g_string_append_printf (str, "\'%s\'", tmp ? "true" : "false");\n'
+ '\n')
+ else:
+ translations['public_underscore'] = utils.build_underscore_name_from_camelcase(field['public-format'])
+ translations['public_underscore_upper'] = utils.build_underscore_name_from_camelcase(field['public-format']).upper()
+ inner_template += (
+ '#if defined __${public_underscore_upper}_IS_ENUM__\n'
+ ' g_string_append_printf (str, "\'%s\'", ${public_underscore}_get_string ((${public})tmp));\n'
+ '#elif defined __${public_underscore_upper}_IS_FLAGS__\n'
+ ' {\n'
+ ' g_autofree gchar *tmpstr = NULL;\n'
+ '\n'
+ ' tmpstr = ${public_underscore}_build_string_from_mask ((${public})tmp);\n'
+ ' g_string_append_printf (str, "\'%s\'", tmpstr);\n'
+ ' }\n'
+ '#else\n'
+ '# error neither enum nor flags\n'
+ '#endif\n'
+ '\n')
+
+ elif field['format'] == 'guint16':
inner_template += (
- '#if defined __${public_underscore_upper}_IS_ENUM__\n'
- ' g_string_append_printf (str, "\'%s\'", ${public_underscore}_get_string ((${public})tmp));\n'
- '#elif defined __${public_underscore_upper}_IS_FLAGS__\n'
- ' {\n'
- ' g_autofree gchar *tmpstr = NULL;\n'
- '\n'
- ' tmpstr = ${public_underscore}_build_string_from_mask ((${public})tmp);\n'
- ' g_string_append_printf (str, "\'%s\'", tmpstr);\n'
- ' }\n'
- '#else\n'
- '# error neither enum nor flags\n'
- '#endif\n'
- '\n')
+ ' g_string_append_printf (str, "\'%" G_GUINT16_FORMAT "\'", tmp);\n')
elif field['format'] == 'guint32':
inner_template += (
' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", tmp);\n')
@@ -1192,30 +1457,64 @@
' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n'
' struct_str = _mbim_message_print_${struct_name}_struct (tmp, new_line_prefix);\n'
' g_string_append (str, struct_str);\n'
- ' g_string_append_printf (str, "%s }\\n", line_prefix);\n')
+ ' g_string_append_printf (str, "%s }", line_prefix);\n')
- elif field['format'] == 'struct-array' or field['format'] == 'ref-struct-array':
+ elif field['format'] == 'ms-struct':
+ inner_template += (
+ ' g_autoptr(${struct_type}) tmp = NULL;\n'
+ ' g_autofree gchar *new_line_prefix = NULL;\n'
+ '\n'
+ ' if (!_mbim_message_read_${struct_name}_ms_struct (message, offset, &tmp, &inner_error))\n'
+ ' goto out;\n'
+ ' offset += 8;\n'
+ ' g_string_append (str, "{\\n");\n'
+ ' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n'
+ ' if (tmp) {\n'
+ ' g_autofree gchar *struct_str = NULL;\n'
+ ' struct_str = _mbim_message_print_${struct_name}_struct (tmp, new_line_prefix);\n'
+ ' g_string_append (str, struct_str);\n'
+ ' }\n'
+ ' g_string_append_printf (str, "%s }", line_prefix);\n')
+
+ elif field['format'] == 'struct-array' or field['format'] == 'ref-struct-array' or field['format'] == 'ms-struct-array':
inner_template += (
' g_autoptr(${struct_type}Array) tmp = NULL;\n'
' g_autofree gchar *new_line_prefix = NULL;\n'
- ' guint i;\n'
+ ' guint i;\n')
+ if field['format'] == 'ms-struct-array':
+ inner_template += (
+ ' guint32 tmp_count = 0;\n')
+ inner_template += (
'\n')
if field['format'] == 'struct-array':
inner_template += (
- ' if (!_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, FALSE, &tmp, &inner_error))\n'
+ ' if (!_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, &tmp, &inner_error))\n'
' goto out;\n'
' offset += 4;\n')
elif field['format'] == 'ref-struct-array':
inner_template += (
- ' if (!_mbim_message_read_${struct_name}_struct_array (message, _${array_size_field}, offset, TRUE, &tmp, &inner_error))\n'
+ ' if (!_mbim_message_read_${struct_name}_ref_struct_array (message, _${array_size_field}, offset, &tmp, &inner_error))\n'
' goto out;\n'
' offset += (8 * _${array_size_field});\n')
+ elif field['format'] == 'ms-struct-array':
+ inner_template += (
+ ' if (!_mbim_message_read_${struct_name}_ms_struct_array (message, offset, &tmp_count, &tmp, &inner_error))\n'
+ ' goto out;\n'
+ ' offset += 8;\n')
inner_template += (
' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n'
- ' g_string_append (str, "\'{\\n");\n'
- ' for (i = 0; i < _${array_size_field}; i++) {\n'
+ ' g_string_append (str, "\'{\\n");\n')
+
+ if field['format'] == 'ms-struct-array':
+ inner_template += (
+ ' for (i = 0; i < tmp_count; i++) {\n')
+ else:
+ inner_template += (
+ ' for (i = 0; i < _${array_size_field}; i++) {\n')
+
+ inner_template += (
' g_autofree gchar *struct_str = NULL;\n'
'\n'
' g_string_append_printf (str, "%s [%u] = {\\n", line_prefix, i);\n'
@@ -1316,6 +1615,45 @@
' }\n'
' g_string_append (str, "\'");\n')
+ elif field['format'] == 'tlv' or \
+ field['format'] == 'tlv-string' or \
+ field['format'] == 'tlv-guint16-array':
+ inner_template += (
+ ' g_autoptr(MbimTlv) tmp = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ ' g_autofree gchar *tlv_str = NULL;\n'
+ ' g_autofree gchar *new_line_prefix = NULL;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv (message, offset, &tmp, &bytes_read, &inner_error))\n'
+ ' goto out;\n'
+ ' offset += bytes_read;\n'
+ '\n'
+ ' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n'
+ ' tlv_str = _mbim_tlv_print (tmp, new_line_prefix);\n'
+ ' g_string_append_printf (str, "\'%s\'", tlv_str);\n')
+
+ elif field['format'] == 'tlv-list':
+ inner_template += (
+ ' GList *tmp = NULL;\n'
+ ' GList *walker = NULL;\n'
+ ' guint32 bytes_read = 0;\n'
+ ' g_autofree gchar *new_line_prefix = NULL;\n'
+ '\n'
+ ' if (!_mbim_message_read_tlv_list (message, offset, &tmp, &bytes_read, &inner_error))\n'
+ ' goto out;\n'
+ ' offset += bytes_read;\n'
+ '\n'
+ ' new_line_prefix = g_strdup_printf ("%s ", line_prefix);\n'
+ ' g_string_append (str, "\'[ ");\n'
+ ' for (walker = tmp; walker; walker = g_list_next (walker)) {\n'
+ ' g_autofree gchar *tlv_str = NULL;\n'
+ '\n'
+ ' tlv_str = _mbim_tlv_print ((MbimTlv *)walker->data, new_line_prefix);\n'
+ ' g_string_append_printf (str, "%s,", tlv_str);\n'
+ ' }\n'
+ ' g_string_append_printf (str, "\\n%s ]\'", line_prefix);\n'
+ ' g_list_free_full (tmp, (GDestroyNotify)mbim_tlv_unref);\n')
+
else:
raise ValueError('Field format \'%s\' not printable' % field['format'])
diff --git a/build-aux/mbim-codegen/ObjectList.py b/build-aux/mbim-codegen/ObjectList.py
index 3faf1ee..bb3d45a 100644
--- a/build-aux/mbim-codegen/ObjectList.py
+++ b/build-aux/mbim-codegen/ObjectList.py
@@ -19,11 +19,18 @@
if field['format'] == 'struct' and field['struct-type'] == struct.name:
struct.single_member = True
break
+ if field['format'] == 'ms-struct' and field['struct-type'] == struct.name:
+ struct.single_member = True
+ struct.ms_struct = True
+ break
if field['format'] == 'ref-struct-array' and field['struct-type'] == struct.name:
- struct.array_member = True
+ struct.ref_struct_array_member = True
break
if field['format'] == 'struct-array' and field['struct-type'] == struct.name:
- struct.array_member = True
+ struct.struct_array_member = True
+ break
+ if field['format'] == 'ms-struct-array' and field['struct-type'] == struct.name:
+ struct.ms_struct_array_member = True
break
@@ -39,20 +46,33 @@
def __init__(self, objects_dictionary):
self.command_list = []
self.struct_list = []
- self.service = ''
+ self.service_list = []
# Loop items in the list, creating Message objects for the messages
+ service_iter = ''
+ mbimex_service_iter = ''
+ mbimex_version_iter = ''
+
for object_dictionary in objects_dictionary:
if object_dictionary['type'] == 'Command':
- self.command_list.append(Message(object_dictionary))
+ if service_iter == '':
+ raise ValueError('Service name not specified before the first command')
+ self.command_list.append(Message(service_iter, mbimex_service_iter, mbimex_version_iter, object_dictionary))
elif object_dictionary['type'] == 'Struct':
self.struct_list.append(Struct(object_dictionary))
elif object_dictionary['type'] == 'Service':
- self.service = object_dictionary['name']
+ service_iter = object_dictionary['name']
+ self.service_list.append(service_iter)
+ if 'mbimex-service' in object_dictionary:
+ mbimex_service_iter = object_dictionary['mbimex-service']
+ mbimex_version_iter = object_dictionary['mbimex-version']
+ else:
+ mbimex_service_iter = ''
+ mbimex_version_iter = ''
else:
raise ValueError('Cannot handle object type \'%s\'' % object_dictionary['type'])
- if self.service == '':
+ if not self.service_list:
raise ValueError('Service name not specified')
# Populate struct usages
@@ -76,61 +96,47 @@
"""
- Emit support for printing messages in this service
+ Emit support for printing messages in a single service
"""
- def emit_printable(self, hfile, cfile):
- translations = { 'service_underscore' : utils.build_underscore_name(self.service),
- 'service' : self.service }
-
+ def emit_printable_service(self, hfile, cfile, service):
+ translations = { 'service_underscore' : utils.build_underscore_name(service),
+ 'service' : service }
template = (
'\n'
- '/*****************************************************************************/\n'
- '/* Service helper for printable fields */\n'
- '\n'
- '#if defined (LIBMBIM_GLIB_COMPILATION)\n'
- '\n'
'G_GNUC_INTERNAL\n'
'gchar *\n'
'__mbim_message_${service_underscore}_get_printable_fields (\n'
' const MbimMessage *message,\n'
' const gchar *line_prefix,\n'
- ' GError **error);\n'
- '\n'
- '#endif\n')
+ ' GError **error);\n')
hfile.write(string.Template(template).substitute(translations))
template = (
'\n'
- 'typedef struct {\n'
- ' gchar * (* query_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
- ' gchar * (* set_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
- ' gchar * (* response_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
- ' gchar * (* notification_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
- '} GetPrintableCallbacks;\n'
- '\n'
- 'static const GetPrintableCallbacks get_printable_callbacks[] = {\n')
+ 'static const GetPrintableCallbacks ${service_underscore}_get_printable_callbacks[] = {\n')
for item in self.command_list:
- translations['message'] = utils.build_underscore_name (item.fullname)
- translations['cid'] = item.cid_enum_name
- inner_template = (
- ' [${cid}] = {\n')
- if item.has_query:
+ if item.service == service:
+ translations['message'] = utils.build_underscore_name (item.fullname)
+ translations['cid'] = item.cid_enum_name
+ inner_template = (
+ ' [${cid}] = {\n')
+ if item.has_query:
+ inner_template += (
+ ' .query_cb = ${message}_query_get_printable,\n')
+ if item.has_set:
+ inner_template += (
+ ' .set_cb = ${message}_set_get_printable,\n')
+ if item.has_response:
+ inner_template += (
+ ' .response_cb = ${message}_response_get_printable,\n')
+ if item.has_notification:
+ inner_template += (
+ ' .notification_cb = ${message}_notification_get_printable,\n')
inner_template += (
- ' .query_cb = ${message}_query_get_printable,\n')
- if item.has_set:
- inner_template += (
- ' .set_cb = ${message}_set_get_printable,\n')
- if item.has_response:
- inner_template += (
- ' .response_cb = ${message}_response_get_printable,\n')
- if item.has_notification:
- inner_template += (
- ' .notification_cb = ${message}_notification_get_printable,\n')
- inner_template += (
- ' },\n')
- template += (string.Template(inner_template).substitute(translations))
+ ' },\n')
+ template += (string.Template(inner_template).substitute(translations))
template += (
'};\n'
@@ -146,15 +152,15 @@
' switch (mbim_message_get_message_type (message)) {\n'
' case MBIM_MESSAGE_TYPE_COMMAND: {\n'
' cid = mbim_message_command_get_cid (message);\n'
- ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
+ ' if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
' switch (mbim_message_command_get_command_type (message)) {\n'
' case MBIM_MESSAGE_COMMAND_TYPE_QUERY:\n'
- ' if (get_printable_callbacks[cid].query_cb)\n'
- ' return get_printable_callbacks[cid].query_cb (message, line_prefix, error);\n'
+ ' if (${service_underscore}_get_printable_callbacks[cid].query_cb)\n'
+ ' return ${service_underscore}_get_printable_callbacks[cid].query_cb (message, line_prefix, error);\n'
' break;\n'
' case MBIM_MESSAGE_COMMAND_TYPE_SET:\n'
- ' if (get_printable_callbacks[cid].set_cb)\n'
- ' return get_printable_callbacks[cid].set_cb (message, line_prefix, error);\n'
+ ' if (${service_underscore}_get_printable_callbacks[cid].set_cb)\n'
+ ' return ${service_underscore}_get_printable_callbacks[cid].set_cb (message, line_prefix, error);\n'
' break;\n'
' case MBIM_MESSAGE_COMMAND_TYPE_UNKNOWN:\n'
' default:\n'
@@ -170,17 +176,17 @@
'\n'
' case MBIM_MESSAGE_TYPE_COMMAND_DONE:\n'
' cid = mbim_message_command_done_get_cid (message);\n'
- ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
- ' if (get_printable_callbacks[cid].response_cb)\n'
- ' return get_printable_callbacks[cid].response_cb (message, line_prefix, error);\n'
+ ' if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
+ ' if (${service_underscore}_get_printable_callbacks[cid].response_cb)\n'
+ ' return ${service_underscore}_get_printable_callbacks[cid].response_cb (message, line_prefix, error);\n'
' }\n'
' break;\n'
'\n'
' case MBIM_MESSAGE_TYPE_INDICATE_STATUS:\n'
' cid = mbim_message_indicate_status_get_cid (message);\n'
- ' if (cid < G_N_ELEMENTS (get_printable_callbacks)) {\n'
- ' if (get_printable_callbacks[cid].notification_cb)\n'
- ' return get_printable_callbacks[cid].notification_cb (message, line_prefix, error);\n'
+ ' if (cid < G_N_ELEMENTS (${service_underscore}_get_printable_callbacks)) {\n'
+ ' if (${service_underscore}_get_printable_callbacks[cid].notification_cb)\n'
+ ' return ${service_underscore}_get_printable_callbacks[cid].notification_cb (message, line_prefix, error);\n'
' }\n'
' break;\n'
'\n'
@@ -201,20 +207,48 @@
'\n'
' g_set_error (error,\n'
' MBIM_CORE_ERROR,\n'
- ' MBIM_CORE_ERROR_INVALID_MESSAGE,\n'
- ' \"Unknown contents\");\n'
+ ' MBIM_CORE_ERROR_UNSUPPORTED,\n'
+ ' \"Unsupported message\");\n'
' return NULL;\n'
'}\n')
cfile.write(string.Template(template).substitute(translations))
+ def emit_printable(self, hfile, cfile):
+
+ template = (
+ '\n'
+ '/*****************************************************************************/\n'
+ '/* Service helpers for printable fields */\n'
+ '\n'
+ '#if defined (LIBMBIM_GLIB_COMPILATION)\n')
+ hfile.write(template)
+
+ template = (
+ '\n'
+ 'typedef struct {\n'
+ ' gchar * (* query_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
+ ' gchar * (* set_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
+ ' gchar * (* response_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
+ ' gchar * (* notification_cb) (const MbimMessage *message, const gchar *line_prefix, GError **error);\n'
+ '} GetPrintableCallbacks;\n')
+ cfile.write(template)
+
+ for service in self.service_list:
+ self.emit_printable_service(hfile, cfile, service)
+
+ template = (
+ '\n'
+ '#endif\n')
+ hfile.write(template)
+
"""
- Emit the sections
+ Emit the section for a single service
"""
- def emit_sections(self, sfile):
- translations = { 'service_dashed' : utils.build_dashed_name(self.service),
- 'service' : self.service }
+ def emit_sections_service(self, sfile, service):
+ translations = { 'service_dashed' : utils.build_dashed_name(service),
+ 'service' : service }
# Emit section header
template = (
@@ -234,3 +268,7 @@
sfile.write(
'</SECTION>\n')
+
+ def emit_sections(self, sfile):
+ for service in self.service_list:
+ self.emit_sections_service(sfile, service)
diff --git a/build-aux/mbim-codegen/Struct.py b/build-aux/mbim-codegen/Struct.py
index 445e175..02037a5 100644
--- a/build-aux/mbim-codegen/Struct.py
+++ b/build-aux/mbim-codegen/Struct.py
@@ -26,12 +26,19 @@
# Whether the struct is used as a single field, or as an array of
# fields. Will be updated after having created the object.
self.single_member = False
- self.array_member = False
+ self.ms_struct = False
+ self.ref_struct_array_member = False
+ self.struct_array_member = False
+ self.ms_struct_array_member = False
# Check whether the struct is composed of fixed-sized fields
self.size = 0
for field in self.contents:
- if field['format'] == 'guint32':
+ if field['format'] == 'guint16':
+ self.size += 2
+ elif field['format'] == 'guint32':
+ self.size += 4
+ elif field['format'] == 'gint32':
self.size += 4
elif field['format'] == 'guint64':
self.size += 8
@@ -68,15 +75,36 @@
if 'array-size-field' not in field:
inner_template += (' * @${field_name_underscore}_size: size of the ${field_name_underscore} array.\n')
inner_template += (' * @${field_name_underscore}: an array of #guint8 values.\n')
+ elif field['format'] == 'guint16':
+ if 'public-format' in field:
+ translations['public'] = field['public-format']
+ inner_template = (
+ ' * @${field_name_underscore}: a ${public} given as a #guint16.\n')
+ else:
+ inner_template = (
+ ' * @${field_name_underscore}: a #guint16.\n')
elif field['format'] == 'guint32':
+ if 'public-format' in field:
+ translations['public'] = field['public-format']
+ inner_template = (
+ ' * @${field_name_underscore}: a ${public} given as a #guint32.\n')
+ else:
+ inner_template = (
+ ' * @${field_name_underscore}: a #guint32.\n')
+ elif field['format'] == 'gint32':
inner_template = (
- ' * @${field_name_underscore}: a #guint32.\n')
+ ' * @${field_name_underscore}: a #gint32.\n')
elif field['format'] == 'guint32-array':
inner_template = (
' * @${field_name_underscore}: an array of #guint32 values.\n')
elif field['format'] == 'guint64':
- inner_template = (
- ' * @${field_name_underscore}: a #guint64.\n')
+ if 'public-format' in field:
+ translations['public'] = field['public-format']
+ inner_template = (
+ ' * @${field_name_underscore}: a ${public} given as a #guint64.\n')
+ else:
+ inner_template = (
+ ' * @${field_name_underscore}: a #guint64.\n')
elif field['format'] == 'string':
inner_template = (
' * @${field_name_underscore}: a string.\n')
@@ -120,9 +148,15 @@
' guint32 ${field_name_underscore}_size;\n')
inner_template += (
' guint8 *${field_name_underscore};\n')
+ elif field['format'] == 'guint16':
+ inner_template = (
+ ' guint16 ${field_name_underscore};\n')
elif field['format'] == 'guint32':
inner_template = (
' guint32 ${field_name_underscore};\n')
+ elif field['format'] == 'gint32':
+ inner_template = (
+ ' gint32 ${field_name_underscore};\n')
elif field['format'] == 'guint32-array':
inner_template = (
' guint32 *${field_name_underscore};\n')
@@ -197,8 +231,12 @@
elif field['format'] in ['unsized-byte-array', 'ref-byte-array', 'ref-byte-array-no-offset']:
inner_template += (
' g_free (var->${field_name_underscore});\n')
+ elif field['format'] == 'guint16':
+ pass
elif field['format'] == 'guint32':
pass
+ elif field['format'] == 'gint32':
+ pass
elif field['format'] == 'guint32-array':
inner_template += (
' g_free (var->${field_name_underscore});\n')
@@ -237,7 +275,7 @@
'}\n')
cfile.write(string.Template(template).substitute(translations))
- if self.array_member:
+ if self.struct_array_member == True or self.ref_struct_array_member == True or self.ms_struct_array_member == True:
# TypeArray was introduced in 1.24
translations['array_since'] = self.since if utils.version_compare('1.24', self.since) > 0 else '1.24'
template = (
@@ -299,8 +337,11 @@
'\n')
for field in self.contents:
- translations['field_name'] = field['name']
- translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['field_name'] = field['name']
+ translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name'])
+ translations['public'] = field['public-format'] if 'public-format' in field else field['format']
+ translations['public_underscore'] = utils.build_underscore_name_from_camelcase(field['public-format']) if 'public-format' in field else ''
+ translations['public_underscore_upper'] = utils.build_underscore_name_from_camelcase(field['public-format']).upper() if 'public-format' in field else ''
inner_template = (
' g_string_append_printf (str, "%s ${field_name} = ", line_prefix);\n'
@@ -338,14 +379,34 @@
' g_string_append_printf (str, "%02x%s", self->${field_name_underscore}[i], (i == (array_size - 1)) ? "" : ":" );\n'
' g_string_append (str, "\'");\n')
- elif field['format'] == 'guint32':
- inner_template += (
- ' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", self->${field_name_underscore});\n')
-
- elif field['format'] == 'guint64':
- inner_template += (
- ' g_string_append_printf (str, "\'%" G_GUINT64_FORMAT "\'", self->${field_name_underscore});\n')
-
+ elif field['format'] in ['guint16', 'guint32', 'guint64']:
+ if 'public-format' in field:
+ inner_template += (
+ '#if defined __${public_underscore_upper}_IS_ENUM__\n'
+ ' g_string_append_printf (str, "\'%s\'", ${public_underscore}_get_string ((${public})self->${field_name_underscore}));\n'
+ '#elif defined __${public_underscore_upper}_IS_FLAGS__\n'
+ ' {\n'
+ ' g_autofree gchar *tmpstr = NULL;\n'
+ '\n'
+ ' tmpstr = ${public_underscore}_build_string_from_mask ((${public})self->${field_name_underscore});\n'
+ ' g_string_append_printf (str, "\'%s\'", tmpstr);\n'
+ ' }\n'
+ '#else\n'
+ '# error neither enum nor flags\n'
+ '#endif\n'
+ '\n')
+ elif field['format'] == 'guint16':
+ inner_template += (
+ ' g_string_append_printf (str, "\'%" G_GUINT16_FORMAT "\'", self->${field_name_underscore});\n')
+ elif field['format'] == 'guint32':
+ inner_template += (
+ ' g_string_append_printf (str, "\'%" G_GUINT32_FORMAT "\'", self->${field_name_underscore});\n')
+ elif field['format'] == 'guint64':
+ inner_template += (
+ ' g_string_append_printf (str, "\'%" G_GUINT64_FORMAT "\'", self->${field_name_underscore});\n')
+ elif field['format'] == 'gint32':
+ inner_template += (
+ ' g_string_append_printf (str, "\'%" G_GINT32_FORMAT "\'", self->${field_name_underscore});\n')
elif field['format'] == 'guint32-array':
translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field'])
inner_template += (
@@ -428,7 +489,9 @@
'\n'
' g_assert (self != NULL);\n'
'\n'
- ' out = g_new0 (${name}, 1);\n')
+ ' out = g_new0 (${name}, 1);\n'
+ '\n')
+
for field in self.contents:
translations['field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['name'])
@@ -496,12 +559,24 @@
' memcpy (out->${field_name_underscore}, tmp, ${array_size});\n'
' offset += ${array_size};\n'
' }\n')
+ elif field['format'] == 'guint16':
+ inner_template += (
+ '\n'
+ ' if (!_mbim_message_read_guint16 (self, offset, &out->${field_name_underscore}, error))\n'
+ ' goto out;\n'
+ ' offset += 2;\n')
elif field['format'] == 'guint32':
inner_template += (
'\n'
' if (!_mbim_message_read_guint32 (self, offset, &out->${field_name_underscore}, error))\n'
' goto out;\n'
' offset += 4;\n')
+ elif field['format'] == 'gint32':
+ inner_template += (
+ '\n'
+ ' if (!_mbim_message_read_gint32 (self, offset, &out->${field_name_underscore}, error))\n'
+ ' goto out;\n'
+ ' offset += 4;\n')
elif field['format'] == 'guint32-array':
translations['array_size_field_name_underscore'] = utils.build_underscore_name_from_camelcase(field['array-size-field'])
inner_template += (
@@ -604,7 +679,44 @@
'}\n')
cfile.write(string.Template(template).substitute(translations))
- if self.array_member:
+ if self.ms_struct == True:
+ template = (
+ '\n'
+ 'static gboolean\n'
+ '_mbim_message_read_${name_underscore}_ms_struct (\n'
+ ' const MbimMessage *self,\n'
+ ' guint32 relative_offset,\n'
+ ' ${name} **out_struct,\n'
+ ' GError **error)\n'
+ '{\n'
+ ' ${name} *out;\n'
+ ' guint32 offset;\n'
+ ' guint32 size;\n'
+ '\n'
+ ' g_assert (self != NULL);\n'
+ '\n'
+ ' if (!_mbim_message_read_guint32 (self, relative_offset, &offset, error))\n'
+ ' return FALSE;\n'
+ ' relative_offset += 4;\n'
+ '\n'
+ ' if (!_mbim_message_read_guint32 (self, relative_offset, &size, error))\n'
+ ' return FALSE;\n'
+ ' relative_offset += 4;\n'
+ '\n'
+ ' if (!offset) {\n'
+ ' *out_struct = NULL;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' out = _mbim_message_read_${name_underscore}_struct (self, offset, NULL, error);\n'
+ ' if (!out)\n'
+ ' return FALSE;\n'
+ ' *out_struct = out;\n'
+ ' return TRUE;\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ if self.struct_array_member == True:
template = (
'\n'
'static gboolean\n'
@@ -612,7 +724,6 @@
' const MbimMessage *self,\n'
' guint32 array_size,\n'
' guint32 relative_offset_array_start,\n'
- ' gboolean refs,\n'
' ${name}Array **out_array,\n'
' GError **error)\n'
'{\n'
@@ -628,18 +739,50 @@
'\n'
' out = g_new0 (${name} *, array_size + 1);\n'
'\n'
- ' if (!refs) {\n'
- ' _mbim_message_read_guint32 (self, relative_offset_array_start, &offset, &inner_error);\n'
- ' for (i = 0; !inner_error && (i < array_size); i++, offset += ${struct_size})\n'
- ' out[i] = _mbim_message_read_${name_underscore}_struct (self, offset, NULL, &inner_error);\n'
- ' } else {\n'
- ' offset = relative_offset_array_start;\n'
- ' for (i = 0; !inner_error && (i < array_size); i++, offset += 8) {\n'
- ' guint32 tmp_offset;\n'
+ ' _mbim_message_read_guint32 (self, relative_offset_array_start, &offset, &inner_error);\n'
+ ' for (i = 0; !inner_error && (i < array_size); i++, offset += ${struct_size})\n'
+ ' out[i] = _mbim_message_read_${name_underscore}_struct (self, offset, NULL, &inner_error);\n'
'\n'
- ' if (_mbim_message_read_guint32 (self, offset, &tmp_offset, &inner_error))\n'
- ' out[i] = _mbim_message_read_${name_underscore}_struct (self, tmp_offset, NULL, &inner_error);\n'
- ' }\n'
+ ' if (!inner_error) {\n'
+ ' *out_array = out;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' ${name_underscore}_array_free (out);\n'
+ ' g_propagate_error (error, inner_error);\n'
+ ' return FALSE;\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ if self.ref_struct_array_member == True:
+ template = (
+ '\n'
+ 'static gboolean\n'
+ '_mbim_message_read_${name_underscore}_ref_struct_array (\n'
+ ' const MbimMessage *self,\n'
+ ' guint32 array_size,\n'
+ ' guint32 relative_offset_array_start,\n'
+ ' ${name}Array **out_array,\n'
+ ' GError **error)\n'
+ '{\n'
+ ' GError *inner_error = NULL;\n'
+ ' ${name}Array *out;\n'
+ ' guint32 i;\n'
+ ' guint32 offset;\n'
+ '\n'
+ ' if (!array_size) {\n'
+ ' *out_array = NULL;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' out = g_new0 (${name} *, array_size + 1);\n'
+ '\n'
+ ' offset = relative_offset_array_start;\n'
+ ' for (i = 0; !inner_error && (i < array_size); i++, offset += 8) {\n'
+ ' guint32 tmp_offset;\n'
+ '\n'
+ ' if (_mbim_message_read_guint32 (self, offset, &tmp_offset, &inner_error))\n'
+ ' out[i] = _mbim_message_read_${name_underscore}_struct (self, tmp_offset, NULL, &inner_error);\n'
' }\n'
'\n'
' if (!inner_error) {\n'
@@ -653,6 +796,66 @@
'}\n')
cfile.write(string.Template(template).substitute(translations))
+ if self.ms_struct_array_member == True:
+ template = (
+ '\n'
+ 'static gboolean\n'
+ '_mbim_message_read_${name_underscore}_ms_struct_array (\n'
+ ' const MbimMessage *self,\n'
+ ' guint32 offset,\n'
+ ' guint32 *out_array_size,\n'
+ ' ${name}Array **out_array,\n'
+ ' GError **error)\n'
+ '{\n'
+ ' GError *inner_error = NULL;\n'
+ ' ${name}Array *out;\n'
+ ' guint32 i;\n'
+ ' guint32 intermediate_struct_offset;\n'
+ ' guint32 intermediate_struct_size;\n'
+ ' guint32 array_size;\n'
+ '\n'
+ ' if (!_mbim_message_read_guint32 (self, offset, &intermediate_struct_offset, error))\n'
+ ' return FALSE;\n'
+ ' offset += 4;\n'
+ '\n'
+ ' if (!_mbim_message_read_guint32 (self, offset, &intermediate_struct_size, error))\n'
+ ' return FALSE;\n'
+ ' offset += 4;\n'
+ '\n'
+ ' if (!intermediate_struct_offset) {\n'
+ ' *out_array_size = 0;\n'
+ ' *out_array = NULL;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' if (!_mbim_message_read_guint32 (self, intermediate_struct_offset, &array_size, error))\n'
+ ' return FALSE;\n'
+ '\n'
+ ' if (!array_size) {\n'
+ ' *out_array_size = 0;\n'
+ ' *out_array = NULL;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' intermediate_struct_offset += 4;\n'
+ '\n'
+ ' out = g_new0 (${name} *, array_size + 1);\n'
+ '\n'
+ ' for (i = 0; !inner_error && (i < array_size); i++, intermediate_struct_offset += ${struct_size}) {\n'
+ ' out[i] = _mbim_message_read_${name_underscore}_struct (self, intermediate_struct_offset, NULL, &inner_error);\n'
+ ' }\n'
+ '\n'
+ ' if (!inner_error) {\n'
+ ' *out_array_size = array_size;\n'
+ ' *out_array = out;\n'
+ ' return TRUE;\n'
+ ' }\n'
+ '\n'
+ ' ${name_underscore}_array_free (out);\n'
+ ' g_propagate_error (error, inner_error);\n'
+ ' return FALSE;\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
"""
Emit the type's append methods
@@ -691,8 +894,12 @@
inner_template = (' _mbim_struct_builder_append_byte_array (builder, ${has_offset}, FALSE, ${pad_array}, value->${field}, value->${array_size_field}, FALSE);\n')
else:
inner_template = (' _mbim_struct_builder_append_byte_array (builder, ${has_offset}, TRUE, ${pad_array}, value->${field}, value->${field}_size, FALSE);\n')
+ elif field['format'] == 'guint16':
+ inner_template = (' _mbim_struct_builder_append_guint16 (builder, value->${field});\n')
elif field['format'] == 'guint32':
inner_template = (' _mbim_struct_builder_append_guint32 (builder, value->${field});\n')
+ elif field['format'] == 'gint32':
+ inner_template = (' _mbim_struct_builder_append_gint32 (builder, value->${field});\n')
elif field['format'] == 'guint32-array':
inner_template = (' _mbim_struct_builder_append_guint32_array (builder, value->${field}, value->${array_size_field});\n')
elif field['format'] == 'guint64':
@@ -743,93 +950,112 @@
'}\n')
cfile.write(string.Template(template).substitute(translations))
- template = (
- '\n'
- 'static void\n'
- '_mbim_struct_builder_append_${name_underscore}_struct_array (\n'
- ' MbimStructBuilder *builder,\n'
- ' const ${name} *const *values,\n'
- ' guint32 n_values,\n'
- ' gboolean refs)\n'
- '{\n'
- ' guint32 offset;\n'
- ' guint32 i;\n'
- ' GByteArray *raw_all = NULL;\n'
- '\n'
- ' if (!refs) {\n'
- ' for (i = 0; i < n_values; i++) {\n'
- ' GByteArray *raw;\n'
- '\n'
- ' raw = _${name_underscore}_struct_new (values[i]);\n'
- ' if (!raw_all)\n'
- ' raw_all = raw;\n'
- ' else {\n'
- ' g_byte_array_append (raw_all, raw->data, raw->len);\n'
- ' g_byte_array_unref (raw);\n'
- ' }\n'
- ' }\n'
- '\n'
- ' if (!raw_all) {\n'
- ' offset = 0;\n'
- ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
- ' } else {\n'
- ' guint32 offset_offset;\n'
- '\n'
- ' /* Offset of the offset */\n'
- ' offset_offset = builder->fixed_buffer->len;\n'
- ' /* Length *not* in LE yet */\n'
- ' offset = builder->variable_buffer->len;\n'
- ' /* Add the offset value */\n'
- ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
- ' /* Configure the value to get updated */\n'
- ' g_array_append_val (builder->offsets, offset_offset);\n'
- ' /* Add the final array itself */\n'
- ' g_byte_array_append (builder->variable_buffer, raw_all->data, raw_all->len);\n'
- ' g_byte_array_unref (raw_all);\n'
- ' }\n'
- ' } else {\n'
- ' for (i = 0; i < n_values; i++) {\n'
- ' guint32 length;\n'
- ' guint32 offset_offset;\n'
- ' GByteArray *raw;\n'
- '\n'
- ' raw = _${name_underscore}_struct_new (values[i]);\n'
- ' g_assert (raw->len > 0);\n'
- '\n'
- ' /* Offset of the offset */\n'
- ' offset_offset = builder->fixed_buffer->len;\n'
- '\n'
- ' /* Length *not* in LE yet */\n'
- ' offset = builder->variable_buffer->len;\n'
- ' /* Add the offset value */\n'
- ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
- ' /* Configure the value to get updated */\n'
- ' g_array_append_val (builder->offsets, offset_offset);\n'
- '\n'
- ' /* Add the length value */\n'
- ' length = GUINT32_TO_LE (raw->len);\n'
- ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length));\n'
- '\n'
- ' /* And finally, the bytearray itself to the variable buffer */\n'
- ' g_byte_array_append (builder->variable_buffer, (const guint8 *)raw->data, (guint)raw->len);\n'
- ' g_byte_array_unref (raw);\n'
- ' }\n'
- ' }\n'
- '}\n')
- cfile.write(string.Template(template).substitute(translations))
+ if self.struct_array_member == True:
+ template = (
+ '\n'
+ 'static void\n'
+ '_mbim_struct_builder_append_${name_underscore}_struct_array (\n'
+ ' MbimStructBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values)\n'
+ '{\n'
+ ' guint32 offset;\n'
+ ' guint32 i;\n'
+ ' GByteArray *raw_all = NULL;\n'
+ '\n'
+ ' for (i = 0; i < n_values; i++) {\n'
+ ' GByteArray *raw;\n'
+ '\n'
+ ' raw = _${name_underscore}_struct_new (values[i]);\n'
+ ' if (!raw_all)\n'
+ ' raw_all = raw;\n'
+ ' else {\n'
+ ' g_byte_array_append (raw_all, raw->data, raw->len);\n'
+ ' g_byte_array_unref (raw);\n'
+ ' }\n'
+ ' }\n'
+ '\n'
+ ' if (!raw_all) {\n'
+ ' offset = 0;\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
+ ' } else {\n'
+ ' guint32 offset_offset;\n'
+ '\n'
+ ' /* Offset of the offset */\n'
+ ' offset_offset = builder->fixed_buffer->len;\n'
+ ' /* Length *not* in LE yet */\n'
+ ' offset = builder->variable_buffer->len;\n'
+ ' /* Add the offset value */\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
+ ' /* Configure the value to get updated */\n'
+ ' g_array_append_val (builder->offsets, offset_offset);\n'
+ ' /* Add the final array itself */\n'
+ ' g_byte_array_append (builder->variable_buffer, raw_all->data, raw_all->len);\n'
+ ' g_byte_array_unref (raw_all);\n'
+ ' }\n'
+ '}\n'
+ '\n'
+ 'static void\n'
+ '_mbim_message_command_builder_append_${name_underscore}_struct_array (\n'
+ ' MbimMessageCommandBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values)\n'
+ '{\n'
+ ' _mbim_struct_builder_append_${name_underscore}_struct_array (builder->contents_builder, values, n_values);\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
- template = (
- '\n'
- 'static void\n'
- '_mbim_message_command_builder_append_${name_underscore}_struct_array (\n'
- ' MbimMessageCommandBuilder *builder,\n'
- ' const ${name} *const *values,\n'
- ' guint32 n_values,\n'
- ' gboolean refs)\n'
- '{\n'
- ' _mbim_struct_builder_append_${name_underscore}_struct_array (builder->contents_builder, values, n_values, refs);\n'
- '}\n')
- cfile.write(string.Template(template).substitute(translations))
+ if self.ref_struct_array_member == True:
+ template = (
+ '\n'
+ 'static void\n'
+ '_mbim_struct_builder_append_${name_underscore}_ref_struct_array (\n'
+ ' MbimStructBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values)\n'
+ '{\n'
+ ' guint32 offset;\n'
+ ' guint32 i;\n'
+ '\n'
+ ' for (i = 0; i < n_values; i++) {\n'
+ ' guint32 length;\n'
+ ' guint32 offset_offset;\n'
+ ' GByteArray *raw;\n'
+ '\n'
+ ' raw = _${name_underscore}_struct_new (values[i]);\n'
+ ' g_assert (raw->len > 0);\n'
+ '\n'
+ ' /* Offset of the offset */\n'
+ ' offset_offset = builder->fixed_buffer->len;\n'
+ '\n'
+ ' /* Length *not* in LE yet */\n'
+ ' offset = builder->variable_buffer->len;\n'
+ ' /* Add the offset value */\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&offset, sizeof (offset));\n'
+ ' /* Configure the value to get updated */\n'
+ ' g_array_append_val (builder->offsets, offset_offset);\n'
+ '\n'
+ ' /* Add the length value */\n'
+ ' length = GUINT32_TO_LE (raw->len);\n'
+ ' g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length));\n'
+ '\n'
+ ' /* And finally, the bytearray itself to the variable buffer */\n'
+ ' g_byte_array_append (builder->variable_buffer, (const guint8 *)raw->data, (guint)raw->len);\n'
+ ' g_byte_array_unref (raw);\n'
+ ' }\n'
+ '}\n'
+ '\n'
+ 'static void\n'
+ '_mbim_message_command_builder_append_${name_underscore}_ref_struct_array (\n'
+ ' MbimMessageCommandBuilder *builder,\n'
+ ' const ${name} *const *values,\n'
+ ' guint32 n_values)\n'
+ '{\n'
+ ' _mbim_struct_builder_append_${name_underscore}_ref_struct_array (builder->contents_builder, values, n_values);\n'
+ '}\n')
+ cfile.write(string.Template(template).substitute(translations))
+
+ # append operations not implemented for self.ms_struct_array_member == True
"""
@@ -860,13 +1086,13 @@
template = (
'<SUBSECTION ${struct_name}>\n'
'${struct_name}\n')
- if self.array_member == True:
+ if self.struct_array_member == True or self.ref_struct_array_member == True:
template += (
'${struct_name}Array\n')
if self.single_member == True:
template += (
'${name_underscore}_free\n')
- if self.array_member == True:
+ if self.struct_array_member == True or self.ref_struct_array_member == True:
template += (
'${name_underscore}_array_free\n')
sfile.write(string.Template(template).substitute(translations))
diff --git a/build-aux/mbim-codegen/mbim-codegen b/build-aux/mbim-codegen/mbim-codegen
index 4ca6b38..4d7c4ad 100755
--- a/build-aux/mbim-codegen/mbim-codegen
+++ b/build-aux/mbim-codegen/mbim-codegen
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# SPDX-License-Identifier: LGPL-2.1-or-later
@@ -17,13 +17,11 @@
def codegen_main():
# Input arguments
arg_parser = optparse.OptionParser('%prog [options]')
- arg_parser.add_option('', '--input', metavar='JSONFILE',
- help='Input JSON-formatted database')
arg_parser.add_option('', '--output', metavar='OUTFILES',
help='Generate C code in OUTFILES.[ch]')
(opts, args) = arg_parser.parse_args();
- if opts.input == None:
+ if args == None:
raise RuntimeError('Input JSON file is mandatory')
if opts.output == None:
raise RuntimeError('Output file pattern is mandatory')
@@ -33,11 +31,11 @@
output_file_h = open(opts.output + ".h", 'w')
output_file_sections = open(opts.output + ".sections", 'w')
- # Load database file contents
- database_file_contents = utils.read_json_file(opts.input)
-
- # Build message list
- object_list_json = json.loads(database_file_contents)
+ # Build message list from all input files
+ object_list_json = []
+ for input_file in args:
+ database_file_contents = utils.read_json_file(input_file)
+ object_list_json += json.loads(database_file_contents)
object_list = ObjectList(object_list_json)
# Add common stuff to the output files
diff --git a/build-aux/mbim-codegen/utils.py b/build-aux/mbim-codegen/utils.py
index c3a8ac3..6722269 100644
--- a/build-aux/mbim-codegen/utils.py
+++ b/build-aux/mbim-codegen/utils.py
@@ -46,6 +46,7 @@
"#include \"mbim-message.h\"\n"
"#include \"mbim-device.h\"\n"
"#include \"mbim-enums.h\"\n"
+ "#include \"mbim-tlv.h\"\n"
"\n"
"#ifndef ${guard}\n"
"#define ${guard}\n"
@@ -76,6 +77,7 @@
"\n"
"#include \"${name}.h\"\n"
"#include \"mbim-message-private.h\"\n"
+ "#include \"mbim-tlv-private.h\"\n"
"#include \"mbim-enum-types.h\"\n"
"#include \"mbim-error-types.h\"\n"
"#include \"mbim-device.h\"\n"
diff --git a/data/mbim-service-atds.json b/data/mbim-service-atds.json
index 3b8f2ed..717f537 100644
--- a/data/mbim-service-atds.json
+++ b/data/mbim-service-atds.json
@@ -5,7 +5,6 @@
// *********************************************************************************
{ "name" : "Signal",
- "service" : "ATDS",
"type" : "Command",
"since" : "1.16",
"query" : [],
@@ -64,7 +63,6 @@
// *********************************************************************************
{ "name" : "Location",
- "service" : "ATDS",
"type" : "Command",
"since" : "1.16",
"query" : [],
@@ -95,7 +93,6 @@
"format" : "guint32" } ] },
{ "name" : "Operators",
- "service" : "ATDS",
"type" : "Command",
"since" : "1.16",
"query" : [],
@@ -108,7 +105,6 @@
// *********************************************************************************
{ "name" : "RAT",
- "service" : "ATDS",
"type" : "Command",
"since" : "1.16",
"set" : [ { "name" : "Mode",
@@ -121,7 +117,6 @@
// *********************************************************************************
{ "name" : "Register State",
- "service" : "ATDS",
"type" : "Command",
"since" : "1.16",
"query" : [],
diff --git a/data/mbim-service-auth.json b/data/mbim-service-auth.json
index ea8a783..3f099ef 100644
--- a/data/mbim-service-auth.json
+++ b/data/mbim-service-auth.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Aka",
- "service" : "Auth",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "Rand",
@@ -32,7 +31,6 @@
// *********************************************************************************
{ "name" : "Akap",
- "service" : "Auth",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "Rand",
@@ -60,7 +58,6 @@
// *********************************************************************************
{ "name" : "Sim",
- "service" : "Auth",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "Rand1",
diff --git a/data/mbim-service-basic-connect.json b/data/mbim-service-basic-connect.json
index c664a79..6a45143 100644
--- a/data/mbim-service-basic-connect.json
+++ b/data/mbim-service-basic-connect.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Device Caps",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"query" : [],
@@ -48,7 +47,6 @@
// *********************************************************************************
{ "name" : "Subscriber Ready Status",
- "service" : "Basic Connect",
"type" : "Command",
"since-ex" : { "query" : "1.0",
"response" : "1.0",
@@ -87,7 +85,6 @@
// *********************************************************************************
{ "name" : "Radio State",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "RadioState",
@@ -109,7 +106,6 @@
// *********************************************************************************
{ "name" : "Pin",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "PinType",
@@ -148,7 +144,6 @@
"format" : "guint32" } ] },
{ "name" : "Pin List",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"query" : [],
@@ -203,7 +198,6 @@
"format" : "guint32" } ] },
{ "name" : "Home Provider",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.2",
"set" : [ { "name" : "Provider",
@@ -216,7 +210,6 @@
// *********************************************************************************
{ "name" : "Preferred Providers",
- "service" : "Basic Connect",
"type" : "Command",
"since-ex" : { "set" : "1.2",
"query" : "1.2",
@@ -244,7 +237,6 @@
// *********************************************************************************
{ "name" : "Visible Providers",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.2",
"query" : [ { "name" : "Action",
@@ -259,7 +251,6 @@
// *********************************************************************************
{ "name" : "Register State",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "ProviderId",
@@ -322,7 +313,6 @@
// *********************************************************************************
{ "name" : "Signal State",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "SignalStrengthInterval",
@@ -356,7 +346,6 @@
// *********************************************************************************
{ "name" : "Packet Service",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "PacketServiceAction",
@@ -390,7 +379,6 @@
// *********************************************************************************
{ "name" : "Connect",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "SessionId",
@@ -483,7 +471,6 @@
"public-format" : "MbimAuthProtocol" } ] },
{ "name" : "Provisioned Contexts",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"set" : [ { "name" : "ContextId",
@@ -521,7 +508,6 @@
// *********************************************************************************
{ "name" : "Service Activation",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.2",
"set" : [ { "name" : "Buffer",
@@ -550,7 +536,6 @@
"format" : "ipv6" } ] },
{ "name" : "IP Configuration",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"query" : [ { "name" : "SessionId",
@@ -685,7 +670,6 @@
"array-size-field" : "CidsCount" } ] },
{ "name" : "Device Services",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.0",
"query" : [],
@@ -711,7 +695,6 @@
"array-size-field" : "CidsCount" } ] },
{ "name" : "Device Service Subscribe List",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.8",
"set" : [ { "name" : "EventsCount",
@@ -729,7 +712,6 @@
// *********************************************************************************
{ "name" : "Packet Statistics",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.4",
"query" : [],
@@ -752,7 +734,6 @@
// *********************************************************************************
{ "name" : "Network Idle Hint",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.4",
"query" : [],
@@ -765,7 +746,6 @@
// *********************************************************************************
{ "name" : "Emergency Mode",
- "service" : "Basic Connect",
"type" : "Command",
"since-ex" : { "set" : "1.4",
"query" : "1.4",
@@ -796,7 +776,6 @@
"array-size-field" : "FilterSize" } ] },
{ "name" : "IP Packet Filters",
- "service" : "Basic Connect",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "SessionId",
@@ -826,7 +805,6 @@
// *********************************************************************************
{ "name" : "Multicarrier Providers",
- "service" : "Basic Connect",
"type" : "Command",
"since-ex" : { "set" : "1.4",
"query" : "1.4",
diff --git a/data/mbim-service-dss.json b/data/mbim-service-dss.json
index db72d17..93211fb 100644
--- a/data/mbim-service-dss.json
+++ b/data/mbim-service-dss.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Connect",
- "service" : "DSS",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "DeviceServiceId",
diff --git a/data/mbim-service-intel-firmware-update.json b/data/mbim-service-intel-firmware-update.json
index 2998de1..e75af8d 100644
--- a/data/mbim-service-intel-firmware-update.json
+++ b/data/mbim-service-intel-firmware-update.json
@@ -5,7 +5,6 @@
// *********************************************************************************
{ "name" : "Modem Reboot",
- "service" : "Intel Firmware Update",
"type" : "Command",
"since" : "1.16",
"set" : [] }
diff --git a/data/mbim-service-ms-basic-connect-extensions-v2.json b/data/mbim-service-ms-basic-connect-extensions-v2.json
new file mode 100644
index 0000000..d06d9c8
--- /dev/null
+++ b/data/mbim-service-ms-basic-connect-extensions-v2.json
@@ -0,0 +1,21 @@
+[
+ // *********************************************************************************
+ { "type" : "Service",
+ "name" : "Ms Basic Connect Extensions V2",
+ "mbimex-service" : "Ms Basic Connect Extensions",
+ "mbimex-version" : "2.0" },
+
+ // *********************************************************************************
+
+ { "name" : "Version",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [ { "name" : "MbimVersion",
+ "format" : "guint16" },
+ { "name" : "MbimExtendedVersion",
+ "format" : "guint16" } ],
+ "response" : [ { "name" : "MbimVersion",
+ "format" : "guint16" },
+ { "name" : "MbimExtendedVersion",
+ "format" : "guint16" } ] }
+]
diff --git a/data/mbim-service-ms-basic-connect-extensions-v3.json b/data/mbim-service-ms-basic-connect-extensions-v3.json
new file mode 100644
index 0000000..71ed7aa
--- /dev/null
+++ b/data/mbim-service-ms-basic-connect-extensions-v3.json
@@ -0,0 +1,280 @@
+[
+ // *********************************************************************************
+ { "type" : "Service",
+ "name" : "Ms Basic Connect Extensions V3",
+ "mbimex-service" : "Ms Basic Connect Extensions",
+ "mbimex-version" : "3.0" },
+
+ // *********************************************************************************
+
+ { "name" : "Device Caps",
+ "type" : "Command",
+ "since" : "1.28",
+ // query same as in v1
+ "response" : [ { "name" : "DeviceType",
+ "format" : "guint32",
+ "public-format" : "MbimDeviceType" },
+ { "name" : "CellularClass",
+ "format" : "guint32",
+ "public-format" : "MbimCellularClass" },
+ { "name" : "VoiceClass",
+ "format" : "guint32",
+ "public-format" : "MbimVoiceClass" },
+ { "name" : "SimClass",
+ "format" : "guint32",
+ "public-format" : "MbimSimClass" },
+ { "name" : "DataClass",
+ "format" : "guint32",
+ "public-format" : "MbimDataClassV3" },
+ { "name" : "SmsCaps",
+ "format" : "guint32",
+ "public-format" : "MbimSmsCaps" },
+ { "name" : "ControlCaps",
+ "format" : "guint32",
+ "public-format" : "MbimCtrlCaps" },
+ { "name" : "DataSubclass",
+ "format" : "guint64",
+ "public-format" : "MbimDataSubclass" },
+ { "name" : "MaxSessions",
+ "format" : "guint32" },
+ { "name" : "ExecutorIndex",
+ "format" : "guint32" },
+ { "name" : "WcdmaBandClass",
+ "format" : "guint32" },
+ { "name" : "LteBandClass",
+ "format" : "tlv-guint16-array" },
+ { "name" : "NrBandClass",
+ "format" : "tlv-guint16-array" },
+ { "name" : "CustomDataClass",
+ "format" : "tlv-string" },
+ { "name" : "DeviceId",
+ "format" : "tlv-string" },
+ { "name" : "FirmwareInfo",
+ "format" : "tlv-string" },
+ { "name" : "HardwareInfo",
+ "format" : "tlv-string" } ] },
+
+ //**********************************************************************************
+
+ { "name" : "Modem Configuration",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [],
+ "response" : [ { "name" : "ConfigurationStatus",
+ "format" : "guint32",
+ "public-format" : "MbimModemConfigurationStatus" },
+ { "name" : "ConfigurationName",
+ "format" : "tlv-string" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ],
+ "notification" : [ { "name" : "ModemConfigurationStatus",
+ "format" : "guint32",
+ "public-format" : "MbimModemConfigurationStatus" },
+ { "name" : "ConfigurationName",
+ "format" : "tlv-string" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ] },
+
+ //************************************************************************************
+
+ { "name" : "Registration Parameters",
+ "type" : "Command",
+ "since" : "1.28",
+ "set" : [ { "name" : "MicoMode",
+ "format" : "guint32",
+ "public-format" : "MbimMicoMode" },
+ { "name" : "DrxCycle",
+ "format" : "guint32",
+ "public-format" : "MbimDrxCycle" },
+ { "name" : "LadnInfo",
+ "format" : "guint32",
+ "public-format" : "MbimLadnInfo" },
+ { "name" : "DefaultPduActivationHint",
+ "format" : "guint32",
+ "public-format" : "MbimDefaultPduActivationHint" },
+ { "name" : "ReRegisterIfNedeed",
+ "format" : "guint32",
+ "public-format" : "gboolean" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ],
+ "query" : [],
+ "response" : [ { "name" : "MicoMode",
+ "format" : "guint32",
+ "public-format" : "MbimMicoMode" },
+ { "name" : "DrxCycle",
+ "format" : "guint32",
+ "public-format" : "MbimDrxCycle" },
+ { "name" : "LadnInfo",
+ "format" : "guint32",
+ "public-format" : "MbimLadnInfo" },
+ { "name" : "DefaultPduActivationHint",
+ "format" : "guint32",
+ "public-format" : "MbimDefaultPduActivationHint" },
+ { "name" : "ReRegisterIfNedeed",
+ "format" : "guint32",
+ "public-format" : "gboolean" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ] },
+
+ // *********************************************************************************
+ { "name" : "Lte Attach Info",
+ "type" : "Command",
+ "since" : "1.28",
+ // query same as in v1
+ "response" : [ { "name" : "LteAttachState",
+ "format" : "guint32",
+ "public-format" : "MbimLteAttachState" },
+ { "name" : "NwError",
+ "format" : "guint32",
+ "public-format" : "MbimNwError" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "AccessString",
+ "format" : "string" },
+ { "name" : "UserName",
+ "format" : "string" },
+ { "name" : "Password",
+ "format" : "string" },
+ { "name" : "Compression",
+ "format" : "guint32",
+ "public-format" : "MbimCompression" },
+ { "name" : "AuthProtocol",
+ "format" : "guint32",
+ "public-format" : "MbimAuthProtocol" } ],
+ "notification" : [ { "name" : "LteAttachState",
+ "format" : "guint32",
+ "public-format" : "MbimLteAttachState" },
+ { "name" : "NwError",
+ "format" : "guint32",
+ "public-format" : "MbimNwError" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "AccessString",
+ "format" : "string" },
+ { "name" : "UserName",
+ "format" : "string" },
+ { "name" : "Password",
+ "format" : "string" },
+ { "name" : "Compression",
+ "format" : "guint32",
+ "public-format" : "MbimCompression" },
+ { "name" : "AuthProtocol",
+ "format" : "guint32",
+ "public-format" : "MbimAuthProtocol" } ] },
+
+ // *********************************************************************************
+ { "name" : "MbimCellInfoServingNr",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "Nci",
+ "format" : "guint64" },
+ { "name" : "PhysicalCellID",
+ "format" : "guint32" },
+ { "name" : "Nrarfcn",
+ "format" : "guint32" },
+ { "name" : "Tac",
+ "format" : "guint32" },
+ { "name" : "Rsrp",
+ "format" : "guint32" },
+ { "name" : "Rsrq",
+ "format" : "guint32" },
+ { "name" : "Sinr",
+ "format" : "guint32" },
+ { "name" : "TimingAdvance",
+ "format" : "guint64" } ] },
+
+ { "name" : "MbimCellInfoNeighboringNr",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "SystemSubType",
+ "format" : "guint32",
+ "public-format" : "MbimDataSubclass" },
+ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "CellId",
+ "format" : "string" },
+ { "name" : "PhysicalCellID",
+ "format" : "guint32" },
+ { "name" : "Tac",
+ "format" : "guint32" },
+ { "name" : "Rsrp",
+ "format" : "guint32" },
+ { "name" : "Rsrq",
+ "format" : "guint32" },
+ { "name" : "Sinr",
+ "format" : "guint32" } ] },
+
+ { "name" : "Base Stations Info",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [ { "name" : "MaxGsmCount",
+ "format" : "guint32" },
+ { "name" : "MaxUmtsCount",
+ "format" : "guint32" },
+ { "name" : "MaxTdscdmaCount",
+ "format" : "guint32" },
+ { "name" : "MaxLteCount",
+ "format" : "guint32" },
+ { "name" : "MaxCdmaCount",
+ "format" : "guint32" },
+ { "name" : "MaxNrCount",
+ "format" : "guint32" } ],
+ "response" : [ { "name" : "SystemType",
+ "format" : "guint32",
+ "public-format" : "MbimDataClassV3" },
+ { "name" : "SystemSubType",
+ "format" : "guint32",
+ "public-format" : "MbimDataSubclass" },
+ { "name" : "GsmServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingGsm" },
+ { "name" : "UmtsServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingUmts" },
+ { "name" : "TdscdmaServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingTdscdma" },
+ { "name" : "LteServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingLte" },
+ { "name" : "GsmNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringGsm" },
+ { "name" : "UmtsNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringUmts" },
+ { "name" : "TdscdmaNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringTdscdma" },
+ { "name" : "LteNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringLte" },
+ { "name" : "CdmaCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoCdma" },
+ { "name" : "NrServingCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoServingNr" },
+ { "name" : "NrNeighborCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringNr" } ] },
+
+ //************************************************************************************
+
+ { "name" : "Wake Reason",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [],
+ "response" : [ { "name" : "WakeType",
+ "format" : "guint32",
+ "public-format" : "MbimWakeType" },
+ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "WakeTlv",
+ "format" : "tlv" } ] }
+
+]
diff --git a/data/mbim-service-ms-basic-connect-extensions.json b/data/mbim-service-ms-basic-connect-extensions.json
index a5097bd..a220ca9 100755
--- a/data/mbim-service-ms-basic-connect-extensions.json
+++ b/data/mbim-service-ms-basic-connect-extensions.json
@@ -19,7 +19,6 @@
"array-size-field" : "PcoDataSize" } ] },
{ "name" : "PCO",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.18",
"query" : [ { "name" : "PcoValue",
@@ -60,7 +59,6 @@
"public-format" : "MbimAuthProtocol" } ] },
{ "name" : "Lte Attach Configuration",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.18",
"set" : [ { "name" : "Operation",
@@ -89,7 +87,6 @@
// *********************************************************************************
{ "name" : "Lte Attach Info",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.26",
"query" : [],
@@ -133,7 +130,6 @@
//**********************************************************************************
{ "name" : "Sys Caps",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.26",
"query" : [],
@@ -149,7 +145,6 @@
//**********************************************************************************
{ "name" : "Slot Info Status",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.26",
"query" : [ { "name" : "SlotIndex",
@@ -174,7 +169,6 @@
"format" : "guint32" } ] },
{ "name" : "Device Slot Mappings",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "MapCount",
@@ -194,7 +188,6 @@
//************************************************************************************
{ "name" : "Device Caps",
- "service" : "Ms Basic Connect Extensions",
"type" : "Command",
"since" : "1.26",
"query" : [],
@@ -219,8 +212,8 @@
{ "name" : "ControlCaps",
"format" : "guint32",
"public-format" : "MbimCtrlCaps" },
- { "name" : "MaxSessions",
- "format" : "guint32" },
+ { "name" : "MaxSessions",
+ "format" : "guint32" },
{ "name" : "CustomDataClass",
"format" : "string",
"max-size" : "22" },
@@ -233,7 +226,337 @@
{ "name" : "HardwareInfo",
"format" : "string",
"max-size" : "60" },
- { "name" : "ExecutorIndex",
- "format" : "guint32" } ] }
+ { "name" : "ExecutorIndex",
+ "format" : "guint32" } ] },
+//************************************************************************************
+
+ { "name" : "Location Info Status",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [],
+ "response" : [ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "TrackingAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellID",
+ "format" : "guint32" } ],
+ "notification" : [ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "TrackingAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellID",
+ "format" : "guint32" } ] },
+
+ // *********************************************************************************
+
+ { "name" : "MbimProvisionedContextElementV2",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ContextId",
+ "format" : "guint32" },
+ { "name" : "ContextType",
+ "format" : "uuid" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "State",
+ "format" : "guint32",
+ "public-format" : "MbimContextState" },
+ { "name" : "Roaming",
+ "format" : "guint32",
+ "public-format" : "MbimContextRoamingControl" },
+ { "name" : "MediaType",
+ "format" : "guint32",
+ "public-format" : "MbimContextMediaType" },
+ { "name" : "Source",
+ "format" : "guint32",
+ "public-format" : "MbimContextSource" },
+ { "name" : "AccessString",
+ "format" : "string" },
+ { "name" : "UserName",
+ "format" : "string" },
+ { "name" : "Password",
+ "format" : "string" },
+ { "name" : "Compression",
+ "format" : "guint32",
+ "public-format" : "MbimCompression" },
+ { "name" : "AuthProtocol",
+ "format" : "guint32",
+ "public-format" : "MbimAuthProtocol" } ] },
+
+ { "name" : "Provisioned Contexts",
+ "type" : "Command",
+ "since" : "1.28",
+ "set" : [ { "name" : "Operation",
+ "format" : "guint32",
+ "public-format" : "MbimContextOperation" },
+ { "name" : "ContextType",
+ "format" : "uuid" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "State",
+ "format" : "guint32",
+ "public-format" : "MbimContextState" },
+ { "name" : "Roaming",
+ "format" : "guint32",
+ "public-format" : "MbimContextRoamingControl" },
+ { "name" : "MediaType",
+ "format" : "guint32",
+ "public-format" : "MbimContextMediaType" },
+ { "name" : "Source",
+ "format" : "guint32",
+ "public-format" : "MbimContextSource" },
+ { "name" : "AccessString",
+ "format" : "string" },
+ { "name" : "UserName",
+ "format" : "string" },
+ { "name" : "Password",
+ "format" : "string" },
+ { "name" : "Compression",
+ "format" : "guint32",
+ "public-format" : "MbimCompression" },
+ { "name" : "AuthProtocol",
+ "format" : "guint32",
+ "public-format" : "MbimAuthProtocol" } ],
+ "query" : [],
+ "response" : [ { "name" : "ProvisionedContextsCount",
+ "format" : "guint32" },
+ { "name" : "ProvisionedContexts",
+ "format" : "ref-struct-array",
+ "struct-type" : "MbimProvisionedContextElementV2",
+ "array-size-field" : "ProvisionedContextsCount" } ],
+ "notification" : [ { "name" : "ProvisionedContextsCount",
+ "format" : "guint32" },
+ { "name" : "ProvisionedContexts",
+ "format" : "ref-struct-array",
+ "struct-type" : "MbimProvisionedContextElementV2",
+ "array-size-field" : "ProvisionedContextsCount" } ] },
+
+ // *********************************************************************************
+ { "name" : "MbimCellInfoServingGsm",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "TimingAdvance",
+ "format" : "guint32" },
+ { "name" : "Arfcn",
+ "format" : "guint32" },
+ { "name" : "BaseStationId",
+ "format" : "guint32" },
+ { "name" : "RxLevel",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoServingUmts",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "FrequencyInfoUL",
+ "format" : "guint32" },
+ { "name" : "FrequencyInfoDL",
+ "format" : "guint32" },
+ { "name" : "FrequencyInfoNT",
+ "format" : "guint32" },
+ { "name" : "Uarfcn",
+ "format" : "guint32" },
+ { "name" : "PrimaryScramblingCode",
+ "format" : "guint32" },
+ { "name" : "Rscp",
+ "format" : "gint32" },
+ { "name" : "Ecno",
+ "format" : "gint32" },
+ { "name" : "PathLoss",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoServingTdscdma",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Uarfcn",
+ "format" : "guint32" },
+ { "name" : "CellParameterID",
+ "format" : "guint32" },
+ { "name" : "TimingAdvance",
+ "format" : "guint32" },
+ { "name" : "Rscp",
+ "format" : "gint32" },
+ { "name" : "PathLoss",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoServingLte",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Earfcn",
+ "format" : "guint32" },
+ { "name" : "PhysicalCellId",
+ "format" : "guint32" },
+ { "name" : "Tac",
+ "format" : "guint32" },
+ { "name" : "Rsrp",
+ "format" : "gint32" },
+ { "name" : "Rsrq",
+ "format" : "gint32" },
+ { "name" : "TimingAdvance",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoNeighboringGsm",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Arfcn",
+ "format" : "guint32" },
+ { "name" : "BaseStationId",
+ "format" : "guint32" },
+ { "name" : "RxLevel",
+ "format" : "guint32" } ] },
+
+
+ { "name" : "MbimCellInfoNeighboringUmts",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Uarfcn",
+ "format" : "guint32" },
+ { "name" : "PrimaryScramblingCode",
+ "format" : "guint32" },
+ { "name" : "Rscp",
+ "format" : "gint32" },
+ { "name" : "Ecno",
+ "format" : "gint32" },
+ { "name" : "PathLoss",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoNeighboringTdscdma",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "LocationAreaCode",
+ "format" : "guint32" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Uarfcn",
+ "format" : "guint32" },
+ { "name" : "CellParameterID",
+ "format" : "guint32" },
+ { "name" : "TimingAdvance",
+ "format" : "guint32" },
+ { "name" : "Rscp",
+ "format" : "gint32" },
+ { "name" : "PathLoss",
+ "format" : "guint32" } ] },
+
+ { "name" : "MbimCellInfoNeighboringLte",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "CellId",
+ "format" : "guint32" },
+ { "name" : "Earfcn",
+ "format" : "guint32" },
+ { "name" : "PhysicalCellId",
+ "format" : "guint32" },
+ { "name" : "Tac",
+ "format" : "guint32" },
+ { "name" : "Rsrp",
+ "format" : "gint32" },
+ { "name" : "Rsrq",
+ "format" : "gint32" } ] },
+
+ { "name" : "MbimCellInfoCdma",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "ServingCellFlag",
+ "format" : "guint32" },
+ { "name" : "Nid",
+ "format" : "guint32" },
+ { "name" : "Sid",
+ "format" : "guint32" },
+ { "name" : "BaseStationId",
+ "format" : "guint32" },
+ { "name" : "BaseLatitude",
+ "format" : "guint32" },
+ { "name" : "BaseLongitude",
+ "format" : "guint32" },
+ { "name" : "RefPn",
+ "format" : "guint32" },
+ { "name" : "GpsSeconds",
+ "format" : "guint32" },
+ { "name" : "PilotStrength",
+ "format" : "guint32" } ] },
+
+ { "name" : "Base Stations Info",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [ { "name" : "MaxGsmCount",
+ "format" : "guint32" },
+ { "name" : "MaxUmtsCount",
+ "format" : "guint32" },
+ { "name" : "MaxTdscdmaCount",
+ "format" : "guint32" },
+ { "name" : "MaxLteCount",
+ "format" : "guint32" } ,
+ { "name" : "MaxCdmaCount",
+ "format" : "guint32" } ],
+ "response" : [ { "name" : "SystemType",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" },
+ { "name" : "GsmServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingGsm" },
+ { "name" : "UmtsServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingUmts" },
+ { "name" : "TdscdmaServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingTdscdma" },
+ { "name" : "LteServingCell",
+ "format" : "ms-struct",
+ "struct-type" : "MbimCellInfoServingLte" },
+ { "name" : "GsmNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringGsm" },
+ { "name" : "UmtsNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringUmts" },
+ { "name" : "TdscdmaNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringTdscdma" },
+ { "name" : "LteNeighboringCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoNeighboringLte" },
+ { "name" : "CdmaCells",
+ "format" : "ms-struct-array",
+ "struct-type" : "MbimCellInfoCdma" } ] }
]
diff --git a/data/mbim-service-ms-basic-connect-v2.json b/data/mbim-service-ms-basic-connect-v2.json
new file mode 100644
index 0000000..f8c535a
--- /dev/null
+++ b/data/mbim-service-ms-basic-connect-v2.json
@@ -0,0 +1,155 @@
+
+[
+ // *********************************************************************************
+ { "type" : "Service",
+ "name" : "Ms Basic Connect V2",
+ "mbimex-service" : "Basic Connect",
+ "mbimex-version" : "2.0" },
+
+ // *********************************************************************************
+ { "name" : "Register State",
+ "type" : "Command",
+ "since" : "1.28",
+ // set same as in v1
+ // query same as in v1
+ "response" : [ { "name" : "NwError",
+ "format" : "guint32",
+ "public-format" : "MbimNwError" },
+ { "name" : "RegisterState",
+ "format" : "guint32",
+ "public-format" : "MbimRegisterState" },
+ { "name" : "RegisterMode",
+ "format" : "guint32",
+ "public-format" : "MbimRegisterMode" },
+ { "name" : "AvailableDataClasses",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" },
+ { "name" : "CurrentCellularClass",
+ "format" : "guint32",
+ "public-format" : "MbimCellularClass" },
+ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "ProviderName",
+ "format" : "string" },
+ { "name" : "RoamingText",
+ "format" : "string" },
+ { "name" : "RegistrationFlag",
+ "format" : "guint32",
+ "public-format" : "MbimRegistrationFlag" },
+ { "name" : "PreferredDataClasses",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" } ],
+ "notification" : [ { "name" : "NwError",
+ "format" : "guint32",
+ "public-format" : "MbimNwError" },
+ { "name" : "RegisterState",
+ "format" : "guint32",
+ "public-format" : "MbimRegisterState" },
+ { "name" : "RegisterMode",
+ "format" : "guint32",
+ "public-format" : "MbimRegisterMode" },
+ { "name" : "AvailableDataClasses",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" },
+ { "name" : "CurrentCellularClass",
+ "format" : "guint32",
+ "public-format" : "MbimCellularClass" },
+ { "name" : "ProviderId",
+ "format" : "string" },
+ { "name" : "ProviderName",
+ "format" : "string" },
+ { "name" : "RoamingText",
+ "format" : "string" },
+ { "name" : "RegistrationFlag",
+ "format" : "guint32",
+ "public-format" : "MbimRegistrationFlag" },
+ { "name" : "PreferredDataClasses",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" } ] },
+
+ // *********************************************************************************
+ { "name" : "Packet Service",
+ "type" : "Command",
+ "since" : "1.28",
+ // set same as in v1
+ // query same as in v1
+ "response" : [ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "PacketServiceState",
+ "format" : "guint32",
+ "public-format" : "MbimPacketServiceState" },
+ { "name" : "CurrentDataClass",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" },
+ { "name" : "UplinkSpeed",
+ "format" : "guint64" },
+ { "name" : "DownlinkSpeed",
+ "format" : "guint64" },
+ { "name" : "FrequencyRange",
+ "format" : "guint32",
+ "public-format" : "MbimFrequencyRange" } ],
+ "notification" : [ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "PacketServiceState",
+ "format" : "guint32",
+ "public-format" : "MbimPacketServiceState" },
+ { "name" : "CurrentDataClass",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" },
+ { "name" : "UplinkSpeed",
+ "format" : "guint64" },
+ { "name" : "DownlinkSpeed",
+ "format" : "guint64" },
+ { "name" : "FrequencyRange",
+ "format" : "guint32",
+ "public-format" : "MbimFrequencyRange" } ] },
+
+ // *********************************************************************************
+ { "name" : "MbimRsrpSnrInfo",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "Rsrp",
+ "format" : "guint32" },
+ { "name" : "Snr",
+ "format" : "guint32" },
+ { "name" : "RsrpThreshold",
+ "format" : "guint32" },
+ { "name" : "SnrThreshold",
+ "format" : "guint32" },
+ { "name" : "SystemType",
+ "format" : "guint32",
+ "public-format" : "MbimDataClass" } ] },
+
+ { "name" : "Signal State",
+ "type" : "Command",
+ "since" : "1.28",
+ // set same as in v1
+ // query same as in v1
+ "response" : [ { "name" : "Rssi",
+ "format" : "guint32" },
+ { "name" : "ErrorRate",
+ "format" : "guint32" },
+ { "name" : "SignalStrengthInterval",
+ "format" : "guint32" },
+ { "name" : "RssiThreshold",
+ "format" : "guint32" },
+ { "name" : "ErrorRateThreshold",
+ "format" : "guint32" },
+ { "name" : "RsrpSnr",
+ "format" : "ms-struct-array" ,
+ "struct-type" : "MbimRsrpSnrInfo" } ],
+ "notification" : [ { "name" : "Rssi",
+ "format" : "guint32" },
+ { "name" : "ErrorRate",
+ "format" : "guint32" },
+ { "name" : "SignalStrengthInterval",
+ "format" : "guint32" },
+ { "name" : "RssiThreshold",
+ "format" : "guint32" },
+ { "name" : "ErrorRateThreshold",
+ "format" : "guint32" },
+ { "name" : "RsrpSnr",
+ "format" : "ms-struct-array" ,
+ "struct-type" : "MbimRsrpSnrInfo" } ] }
+
+]
diff --git a/data/mbim-service-ms-basic-connect-v3.json b/data/mbim-service-ms-basic-connect-v3.json
new file mode 100644
index 0000000..14a7e30
--- /dev/null
+++ b/data/mbim-service-ms-basic-connect-v3.json
@@ -0,0 +1,232 @@
+
+[
+ // *********************************************************************************
+ { "type" : "Service",
+ "name" : "Ms Basic Connect V3",
+ "mbimex-service" : "Basic Connect",
+ "mbimex-version" : "3.0" },
+
+ // *********************************************************************************
+ { "name" : "Subscriber Ready Status",
+ "type" : "Command",
+ "since" : "1.28",
+ // query same as in v1
+ "response" : [ { "name" : "ReadyState",
+ "format" : "guint32",
+ "public-format" : "MbimSubscriberReadyState" },
+ { "name" : "Flags",
+ "format" : "guint32",
+ "public-format" : "MbimSubscriberReadyStatusFlag" },
+ { "name" : "SubscriberId",
+ "format" : "string" },
+ { "name" : "SimIccId",
+ "format" : "string" },
+ { "name" : "ReadyInfo",
+ "format" : "guint32",
+ "public-format" : "MbimReadyInfoFlag" },
+ { "name" : "TelephoneNumbersCount",
+ "format" : "guint32" },
+ { "name" : "TelephoneNumbers",
+ "format" : "string-array",
+ "array-size-field" : "TelephoneNumbersCount" } ],
+ "notification" : [ { "name" : "ReadyState",
+ "format" : "guint32",
+ "public-format" : "MbimSubscriberReadyState" },
+ { "name" : "Flags",
+ "format" : "guint32",
+ "public-format" : "MbimSubscriberReadyStatusFlag" },
+ { "name" : "SubscriberId",
+ "format" : "string" },
+ { "name" : "SimIccId",
+ "format" : "string" },
+ { "name" : "ReadyInfo",
+ "format" : "guint32",
+ "public-format" : "MbimReadyInfoFlag" },
+ { "name" : "TelephoneNumbersCount",
+ "format" : "guint32" },
+ { "name" : "TelephoneNumbers",
+ "format" : "string-array",
+ "array-size-field" : "TelephoneNumbersCount" } ] },
+
+ // *********************************************************************************
+ { "name" : "MbimTai",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "PlmnMcc",
+ "format" : "guint16" },
+ { "name" : "PlmnMnc",
+ "format" : "guint16" },
+ { "name" : "Tac",
+ "format" : "guint32" } ] },
+
+ { "name" : "Packet Service",
+ "type" : "Command",
+ "since" : "1.28",
+ // set same as in v1
+ // query same as in v1
+ "response" : [ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "PacketServiceState",
+ "format" : "guint32",
+ "public-format" : "MbimPacketServiceState" },
+ { "name" : "HighestAvailableDataClass",
+ "format" : "guint32",
+ "public-format" : "MbimDataClassV3" },
+ { "name" : "UplinkSpeed",
+ "format" : "guint64" },
+ { "name" : "DownlinkSpeed",
+ "format" : "guint64" },
+ { "name" : "FrequencyRange",
+ "format" : "guint32",
+ "public-format" : "MbimFrequencyRange" },
+ { "name" : "DataSubclass",
+ "format" : "guint32",
+ "public-format" : "MbimDataSubclass" },
+ { "name" : "Tai",
+ "format" : "struct",
+ "struct-type" : "MbimTai" } ],
+ "notification" : [ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "PacketServiceState",
+ "format" : "guint32",
+ "public-format" : "MbimPacketServiceState" },
+ { "name" : "HighestAvailableDataClass",
+ "format" : "guint32",
+ "public-format" : "MbimDataClassV3" },
+ { "name" : "UplinkSpeed",
+ "format" : "guint64" },
+ { "name" : "DownlinkSpeed",
+ "format" : "guint64" },
+ { "name" : "FrequencyRange",
+ "format" : "guint32",
+ "public-format" : "MbimFrequencyRange" },
+ { "name" : "DataSubclass",
+ "format" : "guint32",
+ "public-format" : "MbimDataSubclass" },
+ { "name" : "Tai",
+ "format" : "struct",
+ "struct-type" : "MbimTai" } ] },
+
+ // *********************************************************************************
+ { "name" : "Connect",
+ "service" : "Basic Connect",
+ "type" : "Command",
+ "since" : "1.28",
+ "set" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "ActivationCommand",
+ "format" : "guint32",
+ "public-format" : "MbimActivationCommand" },
+ { "name" : "Compression",
+ "format" : "guint32",
+ "public-format" : "MbimCompression" },
+ { "name" : "AuthProtocol",
+ "format" : "guint32",
+ "public-format" : "MbimAuthProtocol" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "ContextType",
+ "format" : "uuid" },
+ { "name" : "MediaPreference",
+ "format" : "guint32",
+ "public-format" : "MbimAccessMediaType" },
+ { "name" : "AccessString",
+ "format" : "tlv-string" },
+ { "name" : "UserName",
+ "format" : "tlv-string" },
+ { "name" : "Password",
+ "format" : "tlv-string" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ],
+ "query" : [ { "name" : "SessionId",
+ "format" : "guint32" } ],
+ "response" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "ActivationState",
+ "format" : "guint32",
+ "public-format" : "MbimActivationState" },
+ { "name" : "VoiceCallState",
+ "format" : "guint32",
+ "public-format" : "MbimVoiceCallState" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "ContextType",
+ "format" : "uuid" },
+ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "MediaPreference",
+ "format" : "guint32",
+ "public-format" : "MbimAccessMediaType" },
+ { "name" : "AccessString",
+ "format" : "tlv-string" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ],
+ "notification" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "ActivationState",
+ "format" : "guint32",
+ "public-format" : "MbimActivationState" },
+ { "name" : "VoiceCallState",
+ "format" : "guint32",
+ "public-format" : "MbimVoiceCallState" },
+ { "name" : "IpType",
+ "format" : "guint32",
+ "public-format" : "MbimContextIpType" },
+ { "name" : "ContextType",
+ "format" : "uuid" },
+ { "name" : "NwError",
+ "format" : "guint32" },
+ { "name" : "MediaPreference",
+ "format" : "guint32",
+ "public-format" : "MbimAccessMediaType" },
+ { "name" : "AccessString",
+ "format" : "tlv-string" },
+ { "name" : "UnnamedIes",
+ "format" : "tlv-list" } ] },
+
+ // *********************************************************************************
+
+ { "name" : "MbimPacketFilterV3",
+ "type" : "Struct",
+ "since" : "1.28",
+ "contents" : [ { "name" : "FilterSize",
+ "format" : "guint32" },
+ { "name" : "PacketFilter",
+ "format" : "ref-byte-array",
+ "array-size-field" : "FilterSize" },
+ { "name" : "PacketMask",
+ "format" : "ref-byte-array",
+ "array-size-field" : "FilterSize" },
+ { "name" : "FilterId",
+ "format" : "guint32" } ] },
+
+ { "name" : "IP Packet Filters",
+ "type" : "Command",
+ "since" : "1.28",
+ "query" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "PacketFiltersCount",
+ "format" : "guint32" },
+ { "name" : "PacketFilters",
+ "format" : "ref-struct-array",
+ "struct-type" : "MbimPacketFilterV3",
+ "array-size-field" : "PacketFiltersCount" } ],
+ "set" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "PacketFiltersCount",
+ "format" : "guint32" },
+ { "name" : "PacketFilters",
+ "format" : "ref-struct-array",
+ "struct-type" : "MbimPacketFilterV3",
+ "array-size-field" : "PacketFiltersCount" } ],
+ "response" : [ { "name" : "SessionId",
+ "format" : "guint32" },
+ { "name" : "PacketFiltersCount",
+ "format" : "guint32" },
+ { "name" : "PacketFilters",
+ "format" : "ref-struct-array",
+ "struct-type" : "MbimPacketFilterV3",
+ "array-size-field" : "PacketFiltersCount" } ] }
+]
diff --git a/data/mbim-service-ms-firmware-id.json b/data/mbim-service-ms-firmware-id.json
index ea3fafe..bb4a430 100644
--- a/data/mbim-service-ms-firmware-id.json
+++ b/data/mbim-service-ms-firmware-id.json
@@ -5,7 +5,6 @@
// *********************************************************************************
{ "name" : "Get",
- "service" : "MS Firmware ID",
"type" : "Command",
"since" : "1.8",
"query" : [],
diff --git a/data/mbim-service-ms-host-shutdown.json b/data/mbim-service-ms-host-shutdown.json
index 7a3e9b5..2192cc0 100644
--- a/data/mbim-service-ms-host-shutdown.json
+++ b/data/mbim-service-ms-host-shutdown.json
@@ -5,7 +5,6 @@
// *********************************************************************************
{ "name" : "Notify",
- "service" : "MS Host Shutdown",
"type" : "Command",
"since" : "1.8",
"set" : [] }
diff --git a/data/mbim-service-ms-sar.json b/data/mbim-service-ms-sar.json
index 402490d..58b3acc 100644
--- a/data/mbim-service-ms-sar.json
+++ b/data/mbim-service-ms-sar.json
@@ -14,7 +14,6 @@
"format" : "guint32" } ] },
{ "name" : "Config",
- "service" : "MS SAR",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "Mode",
@@ -49,7 +48,6 @@
// *********************************************************************************
{ "name" : "Transmission status",
- "service" : "MS SAR",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "ChannelNotification",
diff --git a/data/mbim-service-ms-uicc-low-level-access.json b/data/mbim-service-ms-uicc-low-level-access.json
index 8307d21..a9db9fe 100644
--- a/data/mbim-service-ms-uicc-low-level-access.json
+++ b/data/mbim-service-ms-uicc-low-level-access.json
@@ -5,7 +5,6 @@
// ************************************************************************
{ "name" : "ATR",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"query" : [],
@@ -14,7 +13,6 @@
// ************************************************************************
{ "name" : "Open Channel",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "AppId",
@@ -32,7 +30,6 @@
// ************************************************************************
{ "name" : "Close Channel",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "Channel",
@@ -44,7 +41,6 @@
// ************************************************************************
{ "name" : "APDU",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "Channel",
@@ -71,7 +67,6 @@
"format" : "unsized-byte-array" } ] },
{ "name" : "Terminal Capability",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "TerminalCapabilityCount",
@@ -90,7 +85,6 @@
// *********************************************************************************
{ "name" : "Reset",
- "service" : "MS UICC Low Level Access",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "PassThroughAction",
diff --git a/data/mbim-service-phonebook.json b/data/mbim-service-phonebook.json
index 452d53f..170b0ee 100644
--- a/data/mbim-service-phonebook.json
+++ b/data/mbim-service-phonebook.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Configuration",
- "service" : "Phonebook",
"type" : "Command",
"since" : "1.4",
"query" : [],
@@ -45,7 +44,6 @@
"format" : "string" } ] },
{ "name" : "Read",
- "service" : "Phonebook",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "FilterFlag",
@@ -62,7 +60,6 @@
// *********************************************************************************
{ "name" : "Delete",
- "service" : "Phonebook",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "FilterFlag",
@@ -75,7 +72,6 @@
// *********************************************************************************
{ "name" : "Write",
- "service" : "Phonebook",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "SaveFlag",
diff --git a/data/mbim-service-proxy-control.json b/data/mbim-service-proxy-control.json
index 68e47ef..0450fab 100644
--- a/data/mbim-service-proxy-control.json
+++ b/data/mbim-service-proxy-control.json
@@ -6,13 +6,20 @@
// *********************************************************************************
{ "name" : "Configuration",
- "service" : "Proxy Control",
"type" : "Command",
"since" : "1.10",
"set" : [ { "name" : "DevicePath",
"format" : "string" },
{ "name" : "Timeout",
"format" : "guint32" } ],
- "response" : [] }
+ "response" : [] },
+ // *********************************************************************************
+ { "name" : "Version",
+ "type" : "Command",
+ "since" : "1.28",
+ "notification" : [ { "name" : "MbimVersion",
+ "format" : "guint16" },
+ { "name" : "MbimExtendedVersion",
+ "format" : "guint16" } ] }
]
diff --git a/data/mbim-service-qdu.json b/data/mbim-service-qdu.json
index 285f59d..e2ee9da 100644
--- a/data/mbim-service-qdu.json
+++ b/data/mbim-service-qdu.json
@@ -5,7 +5,6 @@
// *********************************************************************************
{ "name" : "Update Session",
- "service" : "QDU",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "SessionAction",
@@ -31,10 +30,9 @@
"format" : "guint32" },
{ "name" : "LastSessionErrorSize",
"format" : "guint32" } ] },
-
+
// *********************************************************************************
{ "name" : "File Open",
- "service" : "QDU",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "FileType",
@@ -47,10 +45,9 @@
"format" : "guint32" },
{ "name" : "MaxWindowSize",
"format" : "guint32" } ] },
-
+
// *********************************************************************************
{ "name" : "File Write",
- "service" : "QDU",
"type" : "Command",
"since" : "1.26",
"set" : [ { "name" : "DataBuffer",
diff --git a/data/mbim-service-qmi.json b/data/mbim-service-qmi.json
index eed861e..12ef5bb 100644
--- a/data/mbim-service-qmi.json
+++ b/data/mbim-service-qmi.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "msg",
- "service" : "QMI",
"type" : "Command",
"since-ex" : { "set" : "1.14",
"response" : "1.14",
diff --git a/data/mbim-service-sms.json b/data/mbim-service-sms.json
index b6e2ecb..e6c3211 100644
--- a/data/mbim-service-sms.json
+++ b/data/mbim-service-sms.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Configuration",
- "service" : "SMS",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "Format",
@@ -57,14 +56,13 @@
"public-format" : "MbimSmsCdmaEncoding" },
{ "name" : "Language",
"format" : "guint32",
- "public-format" : "MbimSmsCdmaLanguage" },
+ "public-format" : "MbimSmsCdmaLang" },
{ "name" : "EncodedMessage",
"format" : "ref-byte-array" },
{ "name" : "EncodedMessageSizeInCharacters",
"format" : "guint32" } ] },
{ "name" : "Read",
- "service" : "SMS",
"type" : "Command",
"since" : "1.4",
"query" : [ { "name" : "Format",
@@ -129,7 +127,7 @@
"public-format" : "MbimSmsCdmaEncoding" },
{ "name" : "Language",
"format" : "guint32",
- "public-format" : "MbimSmsCdmaLanguage" },
+ "public-format" : "MbimSmsCdmaLang" },
{ "name" : "Address",
"format" : "string" },
{ "name" : "EncodedMessage",
@@ -138,7 +136,6 @@
"format" : "guint32" } ] },
{ "name" : "Send",
- "service" : "SMS",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "Format",
@@ -161,7 +158,6 @@
// *********************************************************************************
{ "name" : "Delete",
- "service" : "SMS",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "Flag",
@@ -173,7 +169,6 @@
// *********************************************************************************
{ "name" : "Message Store Status",
- "service" : "SMS",
"type" : "Command",
"since" : "1.4",
"query" : [],
diff --git a/data/mbim-service-stk.json b/data/mbim-service-stk.json
index 44a7c97..bf3acc7 100644
--- a/data/mbim-service-stk.json
+++ b/data/mbim-service-stk.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "Pac",
- "service" : "STK",
"type" : "Command",
"since" : "1.4",
"query" : [],
@@ -24,7 +23,6 @@
// *********************************************************************************
{ "name" : "Terminal Response",
- "service" : "STK",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "Response",
@@ -36,7 +34,6 @@
// *********************************************************************************
{ "name" : "Envelope",
- "service" : "STK",
"type" : "Command",
"since" : "1.4",
"query" : [],
diff --git a/data/mbim-service-ussd.json b/data/mbim-service-ussd.json
index 7b0f594..047cdfc 100644
--- a/data/mbim-service-ussd.json
+++ b/data/mbim-service-ussd.json
@@ -6,7 +6,6 @@
// *********************************************************************************
{ "name" : "",
- "service" : "USSD",
"type" : "Command",
"since" : "1.4",
"set" : [ { "name" : "Action",
diff --git a/docs/man/meson.build b/docs/man/meson.build
index 12c0125..f8daf10 100644
--- a/docs/man/meson.build
+++ b/docs/man/meson.build
@@ -6,17 +6,13 @@
['mbim-network', [help2man, '--output=@OUTPUT@', '--name=Simple network management of MBIM devices', mbim_network], []],
]
-# https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/issues/75 was filed
-# to track the build failure on cross-compilation. This can be re-enabled when
-# the underlying issue is fixed
-#
-# foreach man: mans
-# custom_target(
-# man[0],
-# output: man[0] + '.1',
-# command: man[1],
-# depend_files: man[2],
-# install: true,
-# install_dir: join_paths(mbim_mandir, 'man1'),
-# )
-# endforeach
+foreach man: mans
+ custom_target(
+ man[0],
+ output: man[0] + '.1',
+ command: man[1],
+ depend_files: man[2],
+ install: true,
+ install_dir: mbim_mandir / 'man1',
+ )
+endforeach
diff --git a/docs/reference/libmbim-glib/libmbim-glib-common.sections b/docs/reference/libmbim-glib/libmbim-glib-common.sections
index b5961a4..cbcb8fa 100755
--- a/docs/reference/libmbim-glib/libmbim-glib-common.sections
+++ b/docs/reference/libmbim-glib/libmbim-glib-common.sections
@@ -233,6 +233,9 @@
mbim_device_get_path
mbim_device_get_path_display
mbim_device_is_open
+mbim_device_get_ms_mbimex_version
+mbim_device_set_ms_mbimex_version
+mbim_device_check_ms_mbimex_version
mbim_device_open
mbim_device_open_finish
MbimDeviceOpenFlags
@@ -365,6 +368,20 @@
MbimUiccClassByteType
MbimUiccPassThroughAction
MbimUiccPassThroughStatus
+MbimFrequencyRange
+MbimContextRoamingControl
+MbimContextMediaType
+MbimContextState
+MbimContextOperation
+MbimMicoMode
+MbimDefaultPduActivationHint
+MbimLadnInfo
+MbimDrxCycle
+MbimSubscriberReadyStatusFlag
+MbimDataClassV3
+MbimDataSublass
+MbimModemConfigurationStatus
+MbimWakeType
<SUBSECTION Methods>
mbim_device_type_get_string
mbim_cellular_class_build_string_from_mask
@@ -436,6 +453,20 @@
mbim_uicc_class_byte_type_get_string
mbim_uicc_pass_through_action_get_string
mbim_uicc_pass_through_status_get_string
+mbim_frequency_range_build_string_from_mask
+mbim_context_roaming_control_get_string
+mbim_context_media_type_get_string
+mbim_context_state_get_string
+mbim_context_operation_get_string
+mbim_mico_mode_get_string
+mbim_default_pdu_activation_hint_get_string
+mbim_ladn_info_get_string
+mbim_drx_cycle_get_string
+mbim_subscriber_ready_status_flag_build_string_from_mask
+mbim_data_class_v3_build_string_from_mask
+mbim_data_subclass_build_string_from_mask
+mbim_modem_configuration_status_get_string
+mbim_wake_type_get_string
<SUBSECTION Private>
mbim_device_type_build_string_from_mask
mbim_cellular_class_get_string
@@ -509,6 +540,20 @@
mbim_uicc_class_byte_type_build_string_from_mask
mbim_uicc_pass_through_action_build_string_from_mask
mbim_uicc_pass_through_status_build_string_from_mask
+mbim_frequency_range_get_string
+mbim_context_roaming_control_build_string_from_mask
+mbim_context_media_type_build_string_from_mask
+mbim_context_state_build_string_from_mask
+mbim_context_operation_build_string_from_mask
+mbim_mico_mode_build_string_from_mask
+mbim_default_pdu_activation_hint_build_string_from_mask
+mbim_ladn_info_build_string_from_mask
+mbim_drx_cycle_build_string_from_mask
+mbim_subscriber_ready_status_flag_get_string
+mbim_data_class_v3_get_string
+mbim_data_subclass_get_string
+mbim_modem_configuration_status_build_string_from_mask
+mbim_wake_type_build_string_from_mask
<SUBSECTION Standard>
MBIM_TYPE_ACTIVATION_COMMAND
MBIM_TYPE_ACTIVATION_STATE
@@ -585,6 +630,20 @@
MBIM_TYPE_UICC_CLASS_BYTE_TYPE
MBIM_TYPE_UICC_PASS_THROUGH_ACTION
MBIM_TYPE_UICC_PASS_THROUGH_STATUS
+MBIM_TYPE_FREQUENCY_RANGE
+MBIM_TYPE_CONTEXT_ROAMING_CONTROL
+MBIM_TYPE_CONTEXT_MEDIA_TYPE
+MBIM_TYPE_CONTEXT_STATE
+MBIM_TYPE_CONTEXT_OPERATION
+MBIM_TYPE_MICO_MODE
+MBIM_TYPE_DEFAULT_PDU_ACTIVATION_HINT
+MBIM_TYPE_LADN_INFO
+MBIM_TYPE_DRX_CYCLE
+MBIM_TYPE_SUBSCRIBER_READY_STATUS_FLAG
+MBIM_TYPE_DATA_CLASS_V3
+MBIM_TYPE_DATA_SUBCLASS
+MBIM_TYPE_MODEM_CONFIGURATION_STATUS
+MBIM_TYPE_WAKE_TYPE
mbim_activation_command_get_type
mbim_activation_state_get_type
mbim_auth_protocol_get_type
@@ -660,6 +719,20 @@
mbim_uicc_secure_messaging_get_type
mbim_uicc_pass_through_action_get_type
mbim_uicc_pass_through_status_get_type
+mbim_frequency_range_get_type
+mbim_context_roaming_control_get_type
+mbim_context_media_type_get_type
+mbim_context_state_get_type
+mbim_context_operation_get_type
+mbim_mico_mode_get_type
+mbim_default_pdu_activation_hint_get_type
+mbim_ladn_info_get_type
+mbim_drx_cycle_get_type
+mbim_subscriber_ready_status_flag_get_type
+mbim_data_class_v3_get_type
+mbim_data_subclass_get_type
+mbim_modem_configuration_status_get_type
+mbim_wake_type_get_type
</SECTION>
<SECTION>
@@ -698,6 +771,35 @@
</SECTION>
<SECTION>
+<FILE>mbim-tlv</FILE>
+MbimTlv
+MbimTlvType
+<SUBSECTION Methods>
+mbim_tlv_new
+mbim_tlv_dup
+mbim_tlv_ref
+mbim_tlv_unref
+mbim_tlv_get_raw
+mbim_tlv_get_tlv_type
+mbim_tlv_get_tlv_data
+mbim_tlv_type_get_string
+<SUBSECTION TlvString>
+mbim_tlv_string_new
+mbim_tlv_string_get
+<SUBSECTION TlvUint16Array>
+mbim_tlv_guint16_array_get
+<SUBSECTION TlvWakeCommand>
+mbim_tlv_wake_command_get
+<SUBSECTION TlvWakePacket>
+mbim_tlv_wake_packet_get
+<SUBSECTION Private>
+mbim_tlv_type_build_string_from_mask
+<SUBSECTION Standard>
+MBIM_TYPE_TLV
+mbim_tlv_get_type
+</SECTION>
+
+<SECTION>
<FILE>mbim-compat</FILE>
<SUBSECTION>
MBIM_CID_BASIC_CONNECT_DEVICE_SERVICE_SUBSCRIBER_LIST
@@ -711,6 +813,10 @@
mbim_message_ms_basic_connect_extensions_lte_attach_status_query_new
mbim_message_ms_basic_connect_extensions_lte_attach_status_response_parse
mbim_message_ms_basic_connect_extensions_lte_attach_status_notification_parse
+<SUBSECTION>
+MBIM_NW_ERROR_UNKNOWN
+<SUBSECTION>
+MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST
<SUBSECTION Private>
MbimDeprecatedCidBasicConnect
MbimDeprecatedRegistrationFlag
diff --git a/docs/reference/libmbim-glib/libmbim-glib-docs.xml b/docs/reference/libmbim-glib/libmbim-glib-docs.xml
index 92b8226..a9d5d31 100644
--- a/docs/reference/libmbim-glib/libmbim-glib-docs.xml
+++ b/docs/reference/libmbim-glib/libmbim-glib-docs.xml
@@ -59,6 +59,7 @@
<xi:include href="xml/mbim-enums.xml"/>
<xi:include href="xml/mbim-errors.xml"/>
<xi:include href="xml/mbim-utils.xml"/>
+ <xi:include href="xml/mbim-tlv.xml"/>
</chapter>
<chapter>
@@ -162,6 +163,10 @@
<title>Index of new symbols in 1.26</title>
<xi:include href="xml/api-index-1.26.xml"></xi:include>
</chapter>
+ <chapter id="api-index-1-28" role="1.28">
+ <title>Index of new symbols in 1.28</title>
+ <xi:include href="xml/api-index-1.28.xml"></xi:include>
+ </chapter>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>
diff --git a/docs/reference/libmbim-glib/meson.build b/docs/reference/libmbim-glib/meson.build
index 68c39c1..a2795ed 100644
--- a/docs/reference/libmbim-glib/meson.build
+++ b/docs/reference/libmbim-glib/meson.build
@@ -24,9 +24,9 @@
glib_prefix = glib_dep.get_pkgconfig_variable('prefix')
fixxref_args = [
- '--html-dir=' + join_paths(mbim_prefix, gnome.gtkdoc_html_dir(doc_module)),
- '--extra-dir=' + join_paths(glib_prefix, gnome.gtkdoc_html_dir('glib')),
- '--extra-dir=' + join_paths(glib_prefix, gnome.gtkdoc_html_dir('gio')),
+ '--html-dir=' + (mbim_prefix / gnome.gtkdoc_html_dir(doc_module)),
+ '--extra-dir=' + (glib_prefix / gnome.gtkdoc_html_dir('glib')),
+ '--extra-dir=' + (glib_prefix / gnome.gtkdoc_html_dir('gio')),
]
name = doc_module + '-sections.txt'
@@ -63,5 +63,6 @@
namespace: 'mbim',
scan_args: scan_args,
fixxref_args: fixxref_args,
+ content_files: [sections_txt, version_xml],
install: true,
)
diff --git a/docs/reference/libmbim-glib/xml/meson.build b/docs/reference/libmbim-glib/xml/meson.build
index 40d4a8d..612f443 100644
--- a/docs/reference/libmbim-glib/xml/meson.build
+++ b/docs/reference/libmbim-glib/xml/meson.build
@@ -1,14 +1,15 @@
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (C) 2021 Iñigo Martinez <inigomartinez@gmail.com>
-ent_conf = configuration_data()
-ent_conf.set('PACKAGE', meson.project_name())
-ent_conf.set('PACKAGE_BUGREPORT', meson.project_name() + '-devel@lists.freedesktop.org')
-ent_conf.set('PACKAGE_NAME', meson.project_name())
-ent_conf.set('PACKAGE_STRING', '@0@ @1@'.format(meson.project_name(), mbim_version))
-ent_conf.set('PACKAGE_TARNAME', meson.project_name())
-ent_conf.set('PACKAGE_URL', '')
-ent_conf.set('PACKAGE_VERSION', mbim_version)
+ent_conf = {
+ 'PACKAGE': mbim_name,
+ 'PACKAGE_BUGREPORT': mbim_name + '-devel@lists.freedesktop.org',
+ 'PACKAGE_NAME': mbim_name,
+ 'PACKAGE_STRING': '@0@ @1@'.format(mbim_name, mbim_version),
+ 'PACKAGE_TARNAME': mbim_name,
+ 'PACKAGE_URL': '',
+ 'PACKAGE_VERSION': mbim_version,
+}
gtkdocentities_ent = configure_file(
input: 'gtkdocentities.ent.in',
diff --git a/examples/simple-tester-python/simple-tester-python b/examples/simple-tester-python/simple-tester-python
index 5b12dd6..1c40f9d 100755
--- a/examples/simple-tester-python/simple-tester-python
+++ b/examples/simple-tester-python/simple-tester-python
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
# -*- Mode: python; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
#
# This program is free software; you can redistribute it and/or modify it under
diff --git a/meson.build b/meson.build
index c80ea2f..59f1727 100644
--- a/meson.build
+++ b/meson.build
@@ -3,16 +3,17 @@
project(
'libmbim', 'c',
- version: '1.27.0',
+ version: '1.27.2',
license: ['GPL-2.0-or-later', 'LGPL-2.1-or-later'],
default_options: [
'buildtype=debugoptimized',
'c_std=gnu89',
'warning_level=2',
],
- meson_version: '>= 0.45.1',
+ meson_version: '>= 0.53.0',
)
+mbim_name = meson.project_name()
mbim_version = meson.project_version()
version_array = mbim_version.split('.')
mbim_major_version = version_array[0].to_int()
@@ -26,8 +27,8 @@
mbim_libexecdir = get_option('libexecdir')
mbim_mandir = get_option('mandir')
-mbim_glib_include_subdir = meson.project_name() + '-glib'
-mbim_glib_pkgincludedir = join_paths(mbim_includedir, mbim_glib_include_subdir)
+mbim_glib_include_subdir = mbim_name + '-glib'
+mbim_glib_pkgincludedir = mbim_includedir / mbim_glib_include_subdir
# libtool versioning for libmbim-glib (-version-info c:r:a)
# - If the interface is unchanged, but the implementation has changed or been fixed, then increment r
@@ -44,15 +45,15 @@
gnome = import('gnome')
i18n = import('i18n')
pkg = import('pkgconfig')
-python = import('python3').find_python()
+python = import('python').find_installation('python3')
source_root = meson.current_source_dir()
-data_dir = join_paths(source_root, 'data')
-templates_dir = join_paths(source_root, 'build-aux/templates')
+data_dir = source_root / 'data'
+templates_dir = source_root / 'build-aux/templates'
-mbim_codegen = find_program(join_paths(source_root, 'build-aux/mbim-codegen/mbim-codegen'))
-mbim_mkenums = find_program(join_paths(source_root, 'build-aux/mbim-mkenums'))
+mbim_codegen = find_program(source_root / 'build-aux/mbim-codegen/mbim-codegen')
+mbim_mkenums = find_program(source_root / 'build-aux/mbim-mkenums')
top_inc = include_directories('.')
@@ -149,8 +150,6 @@
)
endif
-glib_prefix = glib_dep.get_pkgconfig_variable('prefix')
-
# MBIM username
mbim_username = get_option('mbim_username')
enable_mbim_username = (mbim_username != '')
@@ -168,16 +167,14 @@
config_h.set('MBIM_USERNAME_ENABLED', enable_mbim_username)
# introspection support
-enable_gir = get_option('introspection')
-if enable_gir
- dependency('gobject-introspection-1.0', version: '>= 0.9.6')
-endif
+enable_gir = dependency('gobject-introspection-1.0', version: '>= 0.9.6', required: get_option('introspection')).found()
-version_conf = configuration_data()
-version_conf.set('MBIM_MAJOR_VERSION', mbim_major_version)
-version_conf.set('MBIM_MINOR_VERSION', mbim_minor_version)
-version_conf.set('MBIM_MICRO_VERSION', mbim_micro_version)
-version_conf.set('VERSION', mbim_version)
+version_conf = {
+ 'MBIM_MAJOR_VERSION': mbim_major_version,
+ 'MBIM_MINOR_VERSION': mbim_minor_version,
+ 'MBIM_MICRO_VERSION': mbim_micro_version,
+ 'VERSION': mbim_version,
+}
subdir('src')
subdir('utils')
@@ -187,31 +184,33 @@
subdir('docs/reference/libmbim-glib')
endif
-help2man = find_program('help2man', required: false)
-if help2man.found()
- subdir('docs/man')
-endif
+help2man = find_program(
+ 'help2man',
+# When meson >= 0.59 is popular enough, replace with
+# required: get_option('man').require(meson.can_run_host_binaries())
+ required: get_option('man'),
+)
+subdir('docs/man', if_found: help2man)
configure_file(
output: 'config.h',
configuration: config_h,
)
-meson.add_install_script(
- 'meson_post_install.py',
- get_option('bindir'),
-)
+summary({
+ 'compiler': cc.get_id(),
+ 'cflags': cc_flags,
+ 'Documentation': enable_gtk_doc,
+ 'bash completion': enable_bash_completion,
+ 'gobject introspection': enable_gir,
+ 'man pages': help2man.found(),
+}, section: 'Build')
-output = '\n' + meson.project_name() + ' ' + meson.project_version() + '\n\n'
-output += ' Build\n'
-output += ' compiler: ' + cc.get_id() + '\n'
-output += ' cflags: ' + ' '.join(cc_flags) + '\n'
-output += ' Documentation: ' + enable_gtk_doc.to_string() + '\n'
-output += ' bash completion: ' + enable_bash_completion.to_string() + '\n'
-output += ' gobject introspection: ' + enable_gir.to_string() + '\n\n'
-output += ' System paths\n'
-output += ' prefix: ' + mbim_prefix + '\n'
-output += ' udev base directory: ' + mbim_username + '\n\n'
-output += ' Features\n'
-output += ' MBIM username: ' + mbim_username
-message(output)
+summary({
+ 'prefix': mbim_prefix,
+ 'udev base directory': (enable_mbim_username ? udev_udevdir : 'disabled'),
+}, section: 'System paths')
+
+summary({
+ 'MBIM username': mbim_username,
+}, section: 'Features')
diff --git a/meson_options.txt b/meson_options.txt
index bc224e5..bfa33ab 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -5,7 +5,8 @@
option('udevdir', type: 'string', value: '', description: 'where udev base directory is')
-option('introspection', type: 'boolean', value: true, description: 'build introspection support')
+option('introspection', type: 'feature', value: 'auto', description: 'build introspection support')
option('gtk_doc', type: 'boolean', value: false, description: 'use gtk-doc to build documentation')
+option('man', type: 'feature', value: 'auto', description: 'build man pages using help2man')
option('bash_completion', type: 'boolean', value: true, description: 'install bash completion files')
diff --git a/meson_post_install.py b/meson_post_install.py
deleted file mode 100755
index b2d5dfd..0000000
--- a/meson_post_install.py
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/env python3
-
-# SPDX-License-Identifier: GPL-2.0-or-later
-# Copyright (C) 2021 Iñigo Martinez <inigomartinez@gmail.com>
-
-import os
-import subprocess
-import sys
-
-prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX']
-
-bindir = os.path.join(prefix, sys.argv[1])
-subprocess.check_call(['chmod', '755', os.path.join(bindir, 'mbim-network')])
diff --git a/src/common/meson.build b/src/common/meson.build
index efd1835..055d28c 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -9,7 +9,7 @@
)
libmbim_common_dep = declare_dependency(
- include_directories: include_directories('.'),
+ include_directories: '.',
dependencies: glib_dep,
link_with: libmbim_common,
)
diff --git a/src/libmbim-glib/generated/meson.build b/src/libmbim-glib/generated/meson.build
index b8ed1c2..deae5f9 100644
--- a/src/libmbim-glib/generated/meson.build
+++ b/src/libmbim-glib/generated/meson.build
@@ -19,7 +19,7 @@
python,
mbim_mkenums,
'--fhead', '#ifndef __LIBMBIM_GLIB_ERROR_TYPES_H__\n#define __LIBMBIM_GLIB_ERROR_TYPES_H__\n#include "mbim-errors.h"\n',
- '--template', files(join_paths(templates_dir, enum_types + '.h.template')),
+ '--template', files(templates_dir / enum_types + '.h.template'),
'--ftail', '#endif /* __LIBMBIM_GLIB_ERROR_TYPES_H__ */\n',
'@INPUT@'],
capture: true,
@@ -35,7 +35,7 @@
python,
mbim_mkenums,
'--fhead', '#include "mbim-errors.h"\n#include "mbim-error-types.h"\n',
- '--template', files(join_paths(templates_dir, enum_types + '.c.template')),
+ '--template', files(templates_dir / enum_types + '.c.template'),
'@INPUT@'],
capture: true,
)
@@ -50,7 +50,7 @@
python,
mbim_mkenums,
'--fhead', '#include "mbim-errors.h"\n#include "mbim-error-types.h"\n',
- '--template', files(join_paths(templates_dir, enum_types + '.c.template')),
+ '--template', files(templates_dir / enum_types + '.c.template'),
'@INPUT@'],
capture: true,
)
@@ -65,8 +65,8 @@
command: [
python,
mbim_mkenums,
- '--fhead', '#ifndef __LIBMBIM_GLIB_ENUM_TYPES_H__\n#define __LIBMBIM_GLIB_ENUM_TYPES_H__\n#include "mbim-uuid.h"\n#include "mbim-cid.h"\n#include "mbim-message.h"\n#include "mbim-enums.h"\n',
- '--template', files(join_paths(templates_dir, enum_types + '.h.template')),
+ '--fhead', '#ifndef __LIBMBIM_GLIB_ENUM_TYPES_H__\n#define __LIBMBIM_GLIB_ENUM_TYPES_H__\n#include "mbim-uuid.h"\n#include "mbim-cid.h"\n#include "mbim-message.h"\n#include "mbim-enums.h"\n#include "mbim-tlv.h"\n',
+ '--template', files(templates_dir / enum_types + '.h.template'),
'--ftail', '#endif /* __LIBMBIM_GLIB_ENUM_TYPES_H__ */\n',
'@INPUT@'],
capture: true,
@@ -82,40 +82,45 @@
python,
mbim_mkenums,
'--fhead', '#include "mbim-enum-types.h"\n',
- '--template', files(join_paths(templates_dir, enum_types + '.c.template')),
+ '--template', files(templates_dir / enum_types + '.c.template'),
'@INPUT@'],
capture: true,
)
services_data = [
- ['atds', true],
- ['auth', true],
- ['basic-connect', true],
- ['dss', true],
- ['intel-firmware-update', true],
- ['ms-basic-connect-extensions', true],
- ['ms-uicc-low-level-access', true],
- ['ms-firmware-id', true],
- ['ms-host-shutdown', true],
- ['ms-sar', true],
- ['phonebook', true],
- ['proxy-control', false],
- ['qdu', true],
- ['qmi', true],
- ['sms', true],
- ['stk', true],
- ['ussd', true],
+ [['atds'], true],
+ [['auth'], true],
+ [['basic-connect', 'ms-basic-connect-v2', 'ms-basic-connect-v3'], true],
+ [['dss'], true],
+ [['intel-firmware-update'], true],
+ [['ms-basic-connect-extensions', 'ms-basic-connect-extensions-v2', 'ms-basic-connect-extensions-v3'], true],
+ [['ms-uicc-low-level-access'], true],
+ [['ms-firmware-id'], true],
+ [['ms-host-shutdown'], true],
+ [['ms-sar'], true],
+ [['phonebook'], true],
+ [['proxy-control'], false],
+ [['qdu'], true],
+ [['qmi'], true],
+ [['sms'], true],
+ [['stk'], true],
+ [['ussd'], true],
]
foreach service_data: services_data
- service = service_data[0]
+ service = service_data[0][0]
name = 'mbim-' + service
+ input = []
+ foreach service_file: service_data[0]
+ input += data_dir / 'mbim-service-@0@.json'.format(service_file)
+ endforeach
+
generated = custom_target(
name,
- input: join_paths(data_dir, 'mbim-service-@0@.json'.format(service)),
+ input: input,
output: [name + '.c', name + '.h', name + '.sections'],
- command: [mbim_codegen, '--input', '@INPUT@', '--output', join_paths('@OUTDIR@', name)],
+ command: [mbim_codegen, '--output', '@OUTDIR@' / name, '@INPUT@'],
install: true,
install_dir: [false, mbim_glib_pkgincludedir, false],
)
@@ -128,7 +133,7 @@
# source file, to the path has to be used. the first workaround is to use the
# build paths to point to the files, and the second workaround is to use
# custom target objects to force its building.
- gen_sections += [join_paths(meson.current_build_dir(), name + '.sections')]
+ gen_sections += [meson.current_build_dir() / name + '.sections']
gen_sections_deps += [generated]
endif
endforeach
diff --git a/src/libmbim-glib/libmbim-glib.h b/src/libmbim-glib/libmbim-glib.h
index 7fdf8e0..ca5ac26 100644
--- a/src/libmbim-glib/libmbim-glib.h
+++ b/src/libmbim-glib/libmbim-glib.h
@@ -21,6 +21,7 @@
#include "mbim-device.h"
#include "mbim-enums.h"
#include "mbim-proxy.h"
+#include "mbim-tlv.h"
/* generated */
#include "mbim-enum-types.h"
diff --git a/src/libmbim-glib/mbim-cid.c b/src/libmbim-glib/mbim-cid.c
index 1b8da5f..46d2a04 100644
--- a/src/libmbim-glib/mbim-cid.c
+++ b/src/libmbim-glib/mbim-cid.c
@@ -120,9 +120,10 @@
};
/* Note: index of the array is CID-1 */
-#define MBIM_CID_PROXY_CONTROL_LAST MBIM_CID_PROXY_CONTROL_CONFIGURATION
+#define MBIM_CID_PROXY_CONTROL_LAST MBIM_CID_PROXY_CONTROL_VERSION
static const CidConfig cid_proxy_control_config [MBIM_CID_PROXY_CONTROL_LAST] = {
- { SET, NO_QUERY, NO_NOTIFY }, /* MBIM_CID_PROXY_CONTROL_CONFIGURATION */
+ { SET, NO_QUERY, NO_NOTIFY }, /* MBIM_CID_PROXY_CONTROL_CONFIGURATION */
+ { NO_SET, NO_QUERY, NOTIFY }, /* MBIM_CID_PROXY_CONTROL_VERSION */
};
/* Note: index of the array is CID-1 */
@@ -148,10 +149,10 @@
};
/* Note: index of the array is CID-1 */
-#define MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LAST MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_DEVICE_RESET
+#define MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LAST MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS
static const CidConfig cid_ms_basic_connect_extensions_config [MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LAST] = {
{ SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PROVISIONED_CONTEXTS */
- { SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST */
+ { SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_DENYLIST */
{ SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_CONFIG */
{ SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_STATUS */
{ NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SYS_CAPS */
@@ -160,6 +161,13 @@
{ NO_SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SLOT_INFO_STATUS */
{ NO_SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PCO */
{ SET, NO_QUERY, NO_NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_DEVICE_RESET */
+ { NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_BASE_STATIONS_INFO */
+ { NO_SET, QUERY, NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LOCATION_INFO_STATUS */
+ { NO_SET, NO_QUERY, NO_NOTIFY }, /* Unused */
+ { NO_SET, NO_QUERY, NO_NOTIFY }, /* Unused */
+ { NO_SET, QUERY, NO_NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION */
+ { NO_SET, NO_QUERY, NO_NOTIFY }, /* Unused */
+ { NO_SET, NO_QUERY, NO_NOTIFY }, /* MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS */
};
/* Note: index of the array is CID-1 */
diff --git a/src/libmbim-glib/mbim-cid.h b/src/libmbim-glib/mbim-cid.h
index e9e8d64..13c2700 100644
--- a/src/libmbim-glib/mbim-cid.h
+++ b/src/libmbim-glib/mbim-cid.h
@@ -238,6 +238,7 @@
* MbimCidProxyControl:
* @MBIM_CID_PROXY_CONTROL_UNKNOWN: Unknown command.
* @MBIM_CID_PROXY_CONTROL_CONFIGURATION: Configuration.
+ * @MBIM_CID_PROXY_CONTROL_VERSION: MBIM and MBIMEx Version reporting.
*
* MBIM commands in the %MBIM_SERVICE_PROXY_CONTROL service.
*
@@ -245,7 +246,8 @@
*/
typedef enum { /*< since=1.10 >*/
MBIM_CID_PROXY_CONTROL_UNKNOWN = 0,
- MBIM_CID_PROXY_CONTROL_CONFIGURATION = 1
+ MBIM_CID_PROXY_CONTROL_CONFIGURATION = 1,
+ MBIM_CID_PROXY_CONTROL_VERSION = 2,
} MbimCidProxyControl;
/**
@@ -320,7 +322,7 @@
* MbimCidMsBasicConnectExtensions:
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_UNKNOWN: Unknown command.
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PROVISIONED_CONTEXTS: Provisioned contexts (v2).
- * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST: Network blacklist.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_DENYLIST: Network denylist. Since 1.28.
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_CONFIGURATION: LTE attach configuration.
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_INFO: LTE attach status information. Since 1.26.
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SYS_CAPS: System capabilities.
@@ -329,6 +331,12 @@
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SLOT_INFO_STATUS: Slot info status.
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PCO: Protocol configuration operations (PCO).
* @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_DEVICE_RESET: Device reset.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_BASE_STATIONS_INFO: Base stations info. Since 1.28.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LOCATION_INFO_STATUS: Location info status. Since 1.28.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION: Protocol version query and report, defined in MBIMEx v2.0. Since 1.28.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_MODEM_CONFIGURATION: Modem configuration status, defined in MBIMEx v3.0. Since 1.28.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS: Registration parameters, defined in MBIMEx v3.0. Since 1.28.
+ * @MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_WAKE_REASON: Protocol wake reason query and report, defined in MBIMEx v3.0. Since 1.28
*
* MBIM commands in the %MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS service.
*
@@ -337,7 +345,7 @@
typedef enum { /*< since=1.18 >*/
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_UNKNOWN = 0,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PROVISIONED_CONTEXTS = 1,
- MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST = 2,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_DENYLIST = 2,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_CONFIGURATION = 3,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LTE_ATTACH_INFO = 4,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SYS_CAPS = 5,
@@ -346,6 +354,12 @@
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_SLOT_INFO_STATUS = 8,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_PCO = 9,
MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_DEVICE_RESET = 10,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_BASE_STATIONS_INFO = 11,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_LOCATION_INFO_STATUS = 12,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION = 15,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_MODEM_CONFIGURATION = 16,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS = 17,
+ MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_WAKE_REASON = 19,
} MbimCidMsBasicConnectExtensions;
/* Command helpers */
diff --git a/src/libmbim-glib/mbim-compat.h b/src/libmbim-glib/mbim-compat.h
index a535607..58ac6ae 100644
--- a/src/libmbim-glib/mbim-compat.h
+++ b/src/libmbim-glib/mbim-compat.h
@@ -210,6 +210,36 @@
MbimLteAttachStatus **out_lte_attach_status,
GError **error);
+/*****************************************************************************/
+/* Network errors fixup */
+
+/* The following type exists just so that we can get deprecation warnings */
+G_DEPRECATED
+typedef int MbimNwErrorDeprecated;
+
+/**
+ * MBIM_NW_ERROR_UNKNOWN:
+ *
+ * Network error not set.
+ *
+ * Since: 1.0
+ * Deprecated: 1.28: Use %MBIM_NW_ERROR_NONE instead.
+ */
+#define MBIM_NW_ERROR_UNKNOWN (MbimNwErrorDeprecated) MBIM_NW_ERROR_NONE
+
+/*****************************************************************************/
+/* Rename blacklist to denylist */
+
+/**
+ * MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST:
+ *
+ * Network deny list.
+ *
+ * Since: 1.18
+ * Deprecated: 1.28: Use MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_DENYLIST instead.
+ */
+#define MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_BLACKLIST (MbimDeprecatedCidMsBasicConnectExtensions) MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_NETWORK_DENYLIST
+
#endif /* MBIM_DISABLE_DEPRECATED */
G_END_DECLS
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index 327ce12..133ecb0 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -3,8 +3,9 @@
/*
* libmbim-glib -- GLib/GIO based library to control MBIM devices
*
- * Copyright (C) 2013-2014 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2013-2021 Aleksander Morgado <aleksander@aleksander.es>
* Copyright (C) 2014 Smith Micro Software, Inc.
+ * Copyright (C) 2021 Intel Corporation
*
* Implementation based on the 'QmiDevice' GObject from libqmi-glib.
*/
@@ -38,6 +39,8 @@
#include "mbim-proxy.h"
#include "mbim-proxy-control.h"
#include "mbim-net-port-manager.h"
+#include "mbim-basic-connect.h"
+#include "mbim-ms-basic-connect-extensions.h"
static void async_initable_iface_init (GAsyncInitableIface *iface);
@@ -111,6 +114,10 @@
/* message size */
guint16 max_control_transfer;
+ /* MBIM extensions major and minor versions agreed with the device */
+ guint8 ms_mbimex_version_major;
+ guint8 ms_mbimex_version_minor;
+
/* Link management */
MbimNetPortManager *net_port_manager;
};
@@ -434,6 +441,44 @@
return (self->priv->open_status == OPEN_STATUS_OPEN);
}
+guint8
+mbim_device_get_ms_mbimex_version (MbimDevice *self,
+ guint8 *out_ms_mbimex_version_minor)
+{
+ g_return_val_if_fail (MBIM_IS_DEVICE (self), 0);
+
+ if (out_ms_mbimex_version_minor)
+ *out_ms_mbimex_version_minor = self->priv->ms_mbimex_version_minor;
+
+ return self->priv->ms_mbimex_version_major;
+}
+
+gboolean
+mbim_device_set_ms_mbimex_version (MbimDevice *self,
+ guint8 ms_mbimex_version_major,
+ guint8 ms_mbimex_version_minor,
+ GError **error)
+{
+ g_return_val_if_fail (MBIM_IS_DEVICE (self), FALSE);
+
+ /* no checks that may make this method fail for now */
+ self->priv->ms_mbimex_version_major = ms_mbimex_version_major;
+ self->priv->ms_mbimex_version_minor = ms_mbimex_version_minor;
+ return TRUE;
+}
+
+gboolean
+mbim_device_check_ms_mbimex_version (MbimDevice *self,
+ guint8 ms_mbimex_version_major,
+ guint8 ms_mbimex_version_minor)
+{
+ g_return_val_if_fail (MBIM_IS_DEVICE (self), FALSE);
+
+ return ((self->priv->ms_mbimex_version_major > ms_mbimex_version_major) ||
+ ((self->priv->ms_mbimex_version_major == ms_mbimex_version_major) &&
+ (self->priv->ms_mbimex_version_minor >= ms_mbimex_version_minor)));
+}
+
/*****************************************************************************/
static void
@@ -765,6 +810,29 @@
return;
}
+ /* Indications in the internal proxy control service are not emitted as
+ * signals, they're consumed internally */
+ {
+ guint16 mbim_version;
+ guint16 ms_mbimex_version;
+
+ if ((mbim_message_indicate_status_get_service (indication) == MBIM_SERVICE_PROXY_CONTROL) &&
+ (mbim_message_indicate_status_get_cid (indication) == MBIM_CID_PROXY_CONTROL_VERSION) &&
+ mbim_message_proxy_control_version_notification_parse (indication, &mbim_version, &ms_mbimex_version, NULL)) {
+
+ self->priv->ms_mbimex_version_major = (ms_mbimex_version >> 8) & 0xFF;
+ self->priv->ms_mbimex_version_minor = ms_mbimex_version & 0xFF;
+
+ g_debug ("[%s] version information update reported: version %x.%02x, extended version %x.%02x",
+ self->priv->path_display,
+ (mbim_version >> 8) & 0xFF,
+ mbim_version & 0xFF,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor);
+ return;
+ }
+ }
+
g_signal_emit (self, signals[SIGNAL_INDICATE_STATUS], 0, indication);
}
@@ -821,7 +889,12 @@
if (is_partial_fragment) {
g_autofree gchar *translated = NULL;
- translated = mbim_message_get_printable (message, ">>>>>> ", TRUE);
+ translated = mbim_message_get_printable_full (message,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ ">>>>>> ",
+ TRUE,
+ NULL);
g_debug ("[%s] Received message fragment (translated)...\n%s",
self->priv->path_display,
translated);
@@ -868,7 +941,12 @@
g_debug ("[%s] No transaction matched in received message",
self->priv->path_display);
/* Attempt to print a user friendly dump of the packet anyway */
- printable = mbim_message_get_printable (message, ">>>>>> ", is_partial_fragment);
+ printable = mbim_message_get_printable_full (message,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ ">>>>>> ",
+ is_partial_fragment,
+ NULL);
if (printable)
g_debug ("[%s] Received unexpected message (translated)...\n%s",
self->priv->path_display,
@@ -913,7 +991,12 @@
if (mbim_utils_get_traces_enabled ()) {
g_autofree gchar *printable = NULL;
- printable = mbim_message_get_printable (ctx->fragments, ">>>>>> ", FALSE);
+ printable = mbim_message_get_printable_full (ctx->fragments,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ ">>>>>> ",
+ FALSE,
+ NULL);
g_debug ("[%s] Received message (translated)...\n%s",
self->priv->path_display,
printable);
@@ -949,7 +1032,12 @@
if (mbim_utils_get_traces_enabled ()) {
g_autofree gchar *printable = NULL;
- printable = mbim_message_get_printable (message, ">>>>>> ", FALSE);
+ printable = mbim_message_get_printable_full (message,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ ">>>>>> ",
+ FALSE,
+ NULL);
g_debug ("[%s] Received message (translated)...\n%s",
self->priv->path_display,
printable);
@@ -1473,6 +1561,8 @@
DEVICE_OPEN_CONTEXT_STEP_FLAGS_PROXY,
DEVICE_OPEN_CONTEXT_STEP_CLOSE_MESSAGE,
DEVICE_OPEN_CONTEXT_STEP_OPEN_MESSAGE,
+ DEVICE_OPEN_CONTEXT_STEP_DEVICE_SERVICES,
+ DEVICE_OPEN_CONTEXT_STEP_MS_EXT_VERSION,
DEVICE_OPEN_CONTEXT_STEP_LAST
} DeviceOpenContextStep;
@@ -1491,8 +1581,6 @@
g_slice_free (DeviceOpenContext, ctx);
}
-static void device_open_context_step (GTask *task);
-
gboolean
mbim_device_open_full_finish (MbimDevice *self,
GAsyncResult *res,
@@ -1509,7 +1597,167 @@
return mbim_device_open_full_finish (self, res, error);
}
-static void open_message (GTask *task);
+static void device_open_context_step (GTask *task);
+
+static void
+ms_ext_version_message_ready (MbimDevice *self,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint16 mbim_version;
+ guint16 ms_mbimex_version;
+ DeviceOpenContext *ctx;
+
+ ctx = g_task_get_task_data (task);
+
+ response = mbim_device_command_finish (self, res, &error);
+ if (!response ||
+ !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
+ !mbim_message_ms_basic_connect_extensions_v2_version_response_parse (
+ response,
+ &mbim_version,
+ &ms_mbimex_version,
+ &error)){
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ /* We fully ignore the MBIM version for now, we just assume it's 1.0, which
+ * is the only known release from the USB-IF for now. */
+ self->priv->ms_mbimex_version_major = (ms_mbimex_version >> 8) & 0xFF;
+ self->priv->ms_mbimex_version_minor = ms_mbimex_version & 0xFF;
+
+ g_debug ("[%s] successfully exchanged version information: version %x.%02x, extended version %x.%02x",
+ self->priv->path_display,
+ (mbim_version >> 8) & 0xFF,
+ mbim_version & 0xFF,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor);
+
+ ctx->step++;
+ device_open_context_step (task);
+}
+
+static void
+ms_ext_version_message (GTask *task)
+{
+ MbimDevice *self;
+ DeviceOpenContext *ctx;
+ g_autoptr(MbimMessage) request = NULL;
+ guint32 mbim_version = 0;
+ guint32 ms_mbimex_version = 0;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ if ((ctx->flags & MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2) && (ctx->flags & MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3)) {
+ g_task_return_new_error (task, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "Cannot request both MBIMEx v2.0 and v3.0 at the same time");
+ g_object_unref (task);
+ return;
+ }
+
+ /* User requested MBIMEx 2.0 or 3.0, so we'll report it along with MBIM 1.0 */
+ mbim_version = 0x01 << 8 | 0x00;
+ if (ctx->flags & MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2)
+ ms_mbimex_version = 0x02 << 8 | 0x00;
+ else if (ctx->flags & MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3)
+ ms_mbimex_version = 0x03 << 8 | 0x00;
+ else
+ g_assert_not_reached ();
+
+ request = mbim_message_ms_basic_connect_extensions_v2_version_query_new (mbim_version, ms_mbimex_version, NULL);
+ g_assert (request);
+
+ mbim_device_command (self,
+ request,
+ ctx->timeout,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback)ms_ext_version_message_ready,
+ task);
+}
+
+static void
+device_services_message_ready (MbimDevice *device,
+ GAsyncResult *res,
+ GTask *task)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimDeviceServiceElementArray) device_services = NULL;
+ guint32 device_services_count;
+ guint32 max_dss_sessions;
+ DeviceOpenContext *ctx;
+ guint i;
+
+ ctx = g_task_get_task_data (task);
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response ||
+ !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error) ||
+ !mbim_message_device_services_response_parse (
+ response,
+ &device_services_count,
+ &max_dss_sessions,
+ &device_services,
+ &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
+ if (device_services_count == 0) {
+ g_task_return_new_error (task, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "No supported services reported by the modem");
+ g_object_unref (task);
+ return;
+ }
+
+ for (i = 0; i < device_services_count; i++) {
+ MbimService service;
+ guint32 j;
+
+ service = mbim_uuid_to_service (&device_services[i]->device_service_id);
+ for (j = 0; j < device_services[i]->cids_count; j++) {
+
+ if ((service == MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS) &&
+ device_services[i]->cids[j] == MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION) {
+ /* version command is supported, go on */
+ ctx->step++;
+ device_open_context_step (task);
+ return;
+ }
+ }
+ }
+
+ /* the version command isn't supported, so we can just jump to the end */
+ ctx->step = DEVICE_OPEN_CONTEXT_STEP_LAST;;
+ device_open_context_step (task);
+}
+
+static void
+device_services_message (GTask *task)
+{
+ MbimDevice *self;
+ DeviceOpenContext *ctx;
+ g_autoptr(MbimMessage) request = NULL;
+
+ self = g_task_get_source_object (task);
+ ctx = g_task_get_task_data (task);
+
+ request = mbim_message_device_services_query_new (NULL);
+ g_assert (request);
+
+ mbim_device_command (self,
+ request,
+ ctx->timeout,
+ g_task_get_cancellable (task),
+ (GAsyncReadyCallback)device_services_message_ready,
+ task);
+}
static void
open_message_ready (MbimDevice *self,
@@ -1773,6 +2021,22 @@
ctx->step++;
/* Fall through */
+ case DEVICE_OPEN_CONTEXT_STEP_DEVICE_SERVICES:
+ if (ctx->flags & (MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2 | MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3)) {
+ device_services_message (task);
+ return;
+ }
+ ctx->step++;
+ /* Fall through */
+
+ case DEVICE_OPEN_CONTEXT_STEP_MS_EXT_VERSION:
+ if (ctx->flags & (MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2 | MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3)) {
+ ms_ext_version_message (task);
+ return;
+ }
+ ctx->step++;
+ /* Fall through */
+
case DEVICE_OPEN_CONTEXT_STEP_LAST:
/* Nothing else to process, complete without error */
self->priv->open_status = OPEN_STATUS_OPEN;
@@ -1839,8 +2103,6 @@
{
GError *inner_error = NULL;
- self->priv->open_status = OPEN_STATUS_CLOSED;
-
/* Already closed? */
if (!self->priv->iochannel && !self->priv->socket_connection && !self->priv->socket_client)
return TRUE;
@@ -1908,16 +2170,21 @@
GAsyncResult *res,
GTask *task)
{
- g_autoptr(MbimMessage) response = NULL;
- GError *error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(GError) iochannel_error = NULL;
response = mbim_device_command_finish (self, res, &error);
- if (!response)
- g_task_return_error (task, error);
- else if (!mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_CLOSE_DONE, &error))
- g_task_return_error (task, error);
- else if (!destroy_iochannel (self, &error))
- g_task_return_error (task, error);
+ if (response)
+ mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_CLOSE_DONE, &error);
+
+ self->priv->open_status = OPEN_STATUS_CLOSED;
+ destroy_iochannel (self, &iochannel_error);
+
+ if (error)
+ g_task_return_error (task, g_steal_pointer (&error));
+ else if (iochannel_error)
+ g_task_return_error (task, g_steal_pointer (&iochannel_error));
else
g_task_return_boolean (task, TRUE);
g_object_unref (task);
@@ -1942,17 +2209,33 @@
task = g_task_new (self, cancellable, callback, user_data);
g_task_set_task_data (task, ctx, (GDestroyNotify)device_close_context_free);
- /* Already closed? */
- if (!self->priv->iochannel) {
+ /* If already closed, we're done */
+ if (self->priv->open_status == OPEN_STATUS_CLOSED) {
g_task_return_boolean (task, TRUE);
g_object_unref (task);
return;
}
+ /* If we're opening, fail with error. We could say we would abort the
+ * ongoing open attempt, but the way to abort that attempt is with the
+ * cancellable given in the open operation, not with an additional close.
+ */
+ if (self->priv->open_status == OPEN_STATUS_OPENING) {
+ g_task_return_new_error (
+ task, MBIM_CORE_ERROR, MBIM_CORE_ERROR_WRONG_STATE,
+ "Cannot close device: not yet fully open");
+ g_object_unref (task);
+ return;
+ }
+
+ g_debug ("[%s] closing device...", self->priv->path_display);
+ g_assert (self->priv->open_status == OPEN_STATUS_OPEN);
+
/* If the device is in-session, avoid the close message */
if (self->priv->in_session) {
GError *error = NULL;
+ self->priv->open_status = OPEN_STATUS_CLOSED;
if (!destroy_iochannel (self, &error))
g_task_return_error (task, error);
else
@@ -2076,7 +2359,12 @@
((GByteArray *)message)->len,
hex);
- printable = mbim_message_get_printable (message, "<<<<<< ", FALSE);
+ printable = mbim_message_get_printable_full (message,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ "<<<<<< ",
+ FALSE,
+ NULL);
g_debug ("[%s] Sent message (translated)...\n%s",
self->priv->path_display,
printable);
@@ -2099,9 +2387,14 @@
g_byte_array_append (full_fragment, (guint8 *)&fragments[i].header, sizeof (fragments[i].header));
g_byte_array_append (full_fragment, (guint8 *)&fragments[i].fragment_header, sizeof (fragments[i].fragment_header));
- /* Build dummy message with only headers for printable purposes only */
+ /* Build placeholder message with only headers for printable purposes only */
if (mbim_utils_get_traces_enabled ())
- printable_headers = mbim_message_get_printable ((MbimMessage *)full_fragment, "<<<<<< ", TRUE);
+ printable_headers = mbim_message_get_printable_full ((MbimMessage *)full_fragment,
+ self->priv->ms_mbimex_version_major,
+ self->priv->ms_mbimex_version_minor,
+ "<<<<<< ",
+ TRUE,
+ NULL);
/* Append the actual fragment data */
g_byte_array_append (full_fragment, (guint8 *)fragments[i].data, fragments[i].data_length);
@@ -2436,6 +2729,9 @@
/* Initialize transaction ID */
self->priv->transaction_id = 0x01;
self->priv->open_status = OPEN_STATUS_CLOSED;
+
+ /* By default, assume v1.0 supported */
+ self->priv->ms_mbimex_version_major = 0x01;
}
static void
@@ -2445,6 +2741,7 @@
g_clear_object (&self->priv->file);
+ self->priv->open_status = OPEN_STATUS_CLOSED;
destroy_iochannel (self, NULL);
g_clear_object (&self->priv->net_port_manager);
diff --git a/src/libmbim-glib/mbim-device.h b/src/libmbim-glib/mbim-device.h
index 651b15a..d6b1406 100644
--- a/src/libmbim-glib/mbim-device.h
+++ b/src/libmbim-glib/mbim-device.h
@@ -3,7 +3,8 @@
/*
* libmbim-glib -- GLib/GIO based library to control MBIM devices
*
- * Copyright (C) 2013 - 2014 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2013 - 2021 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2021 Intel Corporation
*/
#ifndef _LIBMBIM_GLIB_MBIM_DEVICE_H_
@@ -212,17 +213,87 @@
gboolean mbim_device_is_open (MbimDevice *self);
/**
+ * mbim_device_get_ms_mbimex_version:
+ * @self: a #MbimDevice.
+ * @out_ms_mbimex_version_minor: output location for the minor version number of
+ * the MS MBIMEx support, or %NULL if not needed.
+ *
+ * Get the version number of the MS MBIMEx support.
+ *
+ * The reported version will be 1 if the initialization sequence to agree on
+ * which version to use hasn't been run (e.g. with mbim_device_open_full() and
+ * the explicit %MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2 or
+ * %MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3 flag).
+ *
+ * Returns: the major version number of the MS MBIMEx support.
+ *
+ * Since: 1.28
+ */
+guint8 mbim_device_get_ms_mbimex_version (MbimDevice *self,
+ guint8 *out_ms_mbimex_version_minor);
+
+/**
+ * mbim_device_set_ms_mbimex_version:
+ * @self: a #MbimDevice.
+ * @ms_mbimex_version_major: major version number of the MS MBIMEx support.
+ * @ms_mbimex_version_minor: minor version number of the MS MBIMEx support.
+ * @error: Return location for error or %NULL.
+ *
+ * Set the version number of the MS MBIMEx support assumed in the device
+ * instance, which may have been set already by a different process or
+ * device instance.
+ *
+ * If this operation specifies the wrong MBIMEx version agreed between host
+ * and device, the message processing on this device instance may fail.
+ *
+ * This operation does not do any MBIMEx version exchange with the device,
+ * the only way to do that is with mbim_device_open_full() and the explicit
+ * %MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2 or %MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3
+ * flag.
+ *
+ * Returns: %TRUE if successful, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_device_set_ms_mbimex_version (MbimDevice *self,
+ guint8 ms_mbimex_version_major,
+ guint8 ms_mbimex_version_minor,
+ GError **error);
+
+/**
+ * mbim_device_check_ms_mbimex_version:
+ * @self: a #MbimDevice.
+ * @ms_mbimex_version_major: major version number of the MS MBIMEx support.
+ * @ms_mbimex_version_minor: minor version number of the MS MBIMEx support.
+ *
+ * Checks the version number of the MS MBIMEx support in the device instance
+ * against the one given as input.
+ *
+ * Returns: %TRUE if the version of the device instance is the same as or newer
+ * than the passed-in version.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_device_check_ms_mbimex_version (MbimDevice *self,
+ guint8 ms_mbimex_version_major,
+ guint8 ms_mbimex_version_minor);
+
+/**
* MbimDeviceOpenFlags:
* @MBIM_DEVICE_OPEN_FLAGS_NONE: None.
* @MBIM_DEVICE_OPEN_FLAGS_PROXY: Try to open the port through the 'mbim-proxy'.
+ * @MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2: Try to enable MS MBIMEx 2.0 support. Since 1.28.
+ * @MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3: Try to enable MS MBIMEx 3.0 support. Since 1.28.
*
* Flags to specify which actions to be performed when the device is open.
*
* Since: 1.10
*/
typedef enum { /*< since=1.10 >*/
- MBIM_DEVICE_OPEN_FLAGS_NONE = 0,
- MBIM_DEVICE_OPEN_FLAGS_PROXY = 1 << 0
+ MBIM_DEVICE_OPEN_FLAGS_NONE = 0,
+ MBIM_DEVICE_OPEN_FLAGS_PROXY = 1 << 0,
+ MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2 = 1 << 1,
+ MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3 = 1 << 2,
} MbimDeviceOpenFlags;
/**
diff --git a/src/libmbim-glib/mbim-enums.h b/src/libmbim-glib/mbim-enums.h
old mode 100755
new mode 100644
index a06fb65..11deddb
--- a/src/libmbim-glib/mbim-enums.h
+++ b/src/libmbim-glib/mbim-enums.h
@@ -98,6 +98,8 @@
* @MBIM_DATA_CLASS_HSDPA: HSDPA.
* @MBIM_DATA_CLASS_HSUPA: HSUPA.
* @MBIM_DATA_CLASS_LTE: LTE.
+ * @MBIM_DATA_CLASS_5G_NSA: 5G NSA (MS MBIMEx v2.0). Since 1.28.
+ * @MBIM_DATA_CLASS_5G_SA: 5G SA (MS MBIMEx v2.0). Since 1.28.
* @MBIM_DATA_CLASS_1XRTT: 1xRTT.
* @MBIM_DATA_CLASS_1XEVDO: 1xEV-DO.
* @MBIM_DATA_CLASS_1XEVDO_REVA: 1xEV-DO RevA
@@ -109,6 +111,13 @@
*
* Data class.
*
+ * Both 5G related values are introduced in MBIM Extension v2.0, but given
+ * the update is compatible with the original MBIM enumeration, devices may
+ * report them without having enabled MBIM Extension v2.0 support.
+ *
+ * This type is updated in MBIM Extension v3.0 in a non-backwards compatible
+ * way, see #MbimDataClassV3.
+ *
* Since: 1.0
*/
typedef enum { /*< since=1.0 >*/
@@ -118,7 +127,9 @@
MBIM_DATA_CLASS_HSDPA = 1 << 3,
MBIM_DATA_CLASS_HSUPA = 1 << 4,
MBIM_DATA_CLASS_LTE = 1 << 5,
- /* Bits 6 to 15 reserved for future 3GPP classes */
+ MBIM_DATA_CLASS_5G_NSA = 1 << 6,
+ MBIM_DATA_CLASS_5G_SA = 1 << 7,
+ /* Bits 8 to 15 reserved for future 3GPP classes */
MBIM_DATA_CLASS_1XRTT = 1 << 16,
MBIM_DATA_CLASS_1XEVDO = 1 << 17,
MBIM_DATA_CLASS_1XEVDO_REVA = 1 << 18,
@@ -150,22 +161,30 @@
/**
* MbimCtrlCaps:
+ * MBIM_CTRL_CAPS_NONE: None. Since 1.28.
* @MBIM_CTRL_CAPS_REG_MANUAL: Device allows manual network selection.
* @MBIM_CTRL_CAPS_HW_RADIO_SWITCH: Device has a hardware radio power switch.
* @MBIM_CTRL_CAPS_CDMA_MOBILE_IP: The CDMA function supports Mobile IP.
* @MBIM_CTRL_CAPS_CDMA_SIMPLE_IP: The CDMA function supports Simple IP.
* @MBIM_CTRL_CAPS_MULTI_CARRIER: Device can work with multiple providers.
+ * @MBIM_CTRL_CAPS_ESIM: Device supports eSIM (MS MBIMEx v3.0). Since 1.28.
+ * @MBIM_CTRL_CAPS_UE_POLICY_ROUTE_SELECTION: Device supports including the route selection descriptors as part of the UE policies (MS MBIMEx v3.0). Since 1.28.
+ * @MBIM_CTRL_CAPS_SIM_HOT_SWAP_CAPABLE: Device supports SIM hot-swap (MS MBIMEx v3.0). Since 1.28.
*
* Control capabilities.
*
* Since: 1.0
*/
typedef enum { /*< since=1.0 >*/
- MBIM_CTRL_CAPS_REG_MANUAL = 1 << 0,
- MBIM_CTRL_CAPS_HW_RADIO_SWITCH = 1 << 1,
- MBIM_CTRL_CAPS_CDMA_MOBILE_IP = 1 << 2,
- MBIM_CTRL_CAPS_CDMA_SIMPLE_IP = 1 << 3,
- MBIM_CTRL_CAPS_MULTI_CARRIER = 1 << 4
+ MBIM_CTRL_CAPS_NONE = 0,
+ MBIM_CTRL_CAPS_REG_MANUAL = 1 << 0,
+ MBIM_CTRL_CAPS_HW_RADIO_SWITCH = 1 << 1,
+ MBIM_CTRL_CAPS_CDMA_MOBILE_IP = 1 << 2,
+ MBIM_CTRL_CAPS_CDMA_SIMPLE_IP = 1 << 3,
+ MBIM_CTRL_CAPS_MULTI_CARRIER = 1 << 4,
+ MBIM_CTRL_CAPS_ESIM = 1 << 5,
+ MBIM_CTRL_CAPS_UE_POLICY_ROUTE_SELECTION = 1 << 6,
+ MBIM_CTRL_CAPS_SIM_HOT_SWAP_CAPABLE = 1 << 7,
} MbimCtrlCaps;
/*****************************************************************************/
@@ -180,6 +199,8 @@
* @MBIM_SUBSCRIBER_READY_STATE_FAILURE: Failure.
* @MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED: Not activated.
* @MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED: Device locked.
+ * @MBIM_SUBSCRIBER_READY_STATE_NO_ESIM_PROFILE: The card is ready but does not
+ * have any enabled profiles (MS MBIMEx). Since 1.28.
*
* Ready state of the subscriber.
*
@@ -193,6 +214,7 @@
MBIM_SUBSCRIBER_READY_STATE_FAILURE = 4,
MBIM_SUBSCRIBER_READY_STATE_NOT_ACTIVATED = 5,
MBIM_SUBSCRIBER_READY_STATE_DEVICE_LOCKED = 6,
+ MBIM_SUBSCRIBER_READY_STATE_NO_ESIM_PROFILE = 7,
} MbimSubscriberReadyState;
/**
@@ -370,6 +392,25 @@
} MbimProviderState;
/*****************************************************************************/
+/* Connect V3' enums */
+
+/**
+ * MbimAccessMediaType:
+ * @MBIM_ACCESS_MEDIA_TYPE_UNKNOWN: None, or unknown.
+ * @MBIM_ACCESS_MEDIA_TYPE_3GPP: 3GPP only.
+ * @MBIM_ACCESS_MEDIA_TYPE_3GPP_PREFERRED: 3GPP Preferred.
+ *
+ * Access type preference.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_ACCESS_MEDIA_TYPE_UNKNOWN = 0,
+ MBIM_ACCESS_MEDIA_TYPE_3GPP = 1,
+ MBIM_ACCESS_MEDIA_TYPE_3GPP_PREFERRED = 2,
+} MbimAccessMediaType;
+
+/*****************************************************************************/
/* 'Visible Providers' enums */
/**
@@ -391,7 +432,7 @@
/**
* MbimNwError:
- * @MBIM_NW_ERROR_UNKNOWN: Unknown or unset error.
+ * @MBIM_NW_ERROR_NONE: No error. Since 1.28.
* @MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR: IMSI unknown in the HLR.
* @MBIM_NW_ERROR_ILLEGAL_MS: Illegal MS. Since 1.10.
* @MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR: IMSI unknown in the VLR.
@@ -443,7 +484,7 @@
* Since: 1.0
*/
typedef enum { /*< since=1.0 >*/
- MBIM_NW_ERROR_UNKNOWN = 0,
+ MBIM_NW_ERROR_NONE = 0,
MBIM_NW_ERROR_IMSI_UNKNOWN_IN_HLR = 2,
MBIM_NW_ERROR_ILLEGAL_MS = 3,
MBIM_NW_ERROR_IMSI_UNKNOWN_IN_VLR = 4,
@@ -562,6 +603,24 @@
} MbimRegistrationFlag;
/*****************************************************************************/
+/* 'Wake Reason' enums */
+/**
+ * MbimWaketype:
+ * @MBIM_WAKE_TYPE_CID_RESPONSE: A CID response wakes device.
+ * @MBIM_WAKE_TYPE_CID_INDICATION: A CID indication wakes device.
+ * @MBIM_WAKE_TYPE_PACKET: An incoming packet wakes device.
+ *
+ * Wake type.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_WAKE_TYPE_CID_RESPONSE = 0,
+ MBIM_WAKE_TYPE_CID_INDICATION = 1,
+ MBIM_WAKE_TYPE_PACKET = 2,
+} MbimWakeType;
+
+/*****************************************************************************/
/* 'Packet Service' enums */
/**
@@ -1448,6 +1507,285 @@
MBIM_UICC_PASS_THROUGH_STATUS_ENABLED = 1,
} MbimUiccPassThroughStatus;
+/*****************************************************************************/
+/* 'Modem Configuration' enums */
+
+/**
+ * MbimModemConfigurationStatus:
+ * @MBIM_MODEM_CONFIGURATION_STATUS_UNKNOWN: Unknown
+ * @MBIM_MODEM_CONFIGURATION_STATUS_STARTED: SIM is ready and configuration started.
+ * @MBIM_MODEM_CONFIGURATION_STATUS_COMPLETED: SIM is ready and configuration completed.
+ *
+ * Modem configuration status.
+ *
+ * Since: 1.28
+ */
+typedef enum {/*< since=1.28 >*/
+ MBIM_MODEM_CONFIGURATION_STATUS_UNKNOWN = 0,
+ MBIM_MODEM_CONFIGURATION_STATUS_STARTED = 1,
+ MBIM_MODEM_CONFIGURATION_STATUS_COMPLETED = 2
+} MbimModemConfigurationStatus;
+
+/*****************************************************************************/
+/* 'Packet service v2' enums */
+
+/**
+ * MbimFrequencyRange:
+ * @MBIM_FREQUENCY_RANGE_UNKNOWN: Unknown.
+ * @MBIM_FREQUENCY_RANGE_1: Frequency range 1 (FR1) in 3GPP TS 38.101-1 (Sub-6G).
+ * @MBIM_FREQUENCY_RANGE_2: FR2 in 3GPP TS 38.101-2 (mmWave).
+ *
+ * Frequency Range.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_FREQUENCY_RANGE_UNKNOWN = 0,
+ MBIM_FREQUENCY_RANGE_1 = 1 << 0,
+ MBIM_FREQUENCY_RANGE_2 = 1 << 1
+} MbimFrequencyRange;
+
+/*****************************************************************************/
+/* 'Provisioned Context v2' enums */
+
+/**
+ * MbimContextRoamingControl:
+ * @MBIM_CONTEXT_ROAMING_CONTROL_HOME_ONLY: Context allowed to be used in home network.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_ONLY: Context allowed to be used in partner network.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_NON_PARTNER_ONLY: Context allowed to be used in non-partner network.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_PARTNER: Context allowed to be used in home and partner networks.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_NON_PARTNER: Context allowed to be used in home and non-partner networks.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_AND_NON_PARTNER: Context allowed to be used in partner and non-partner networks.
+ * @MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL: Context allowed to be used in any roaming condition.
+ *
+ * Type of roaming control.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_CONTEXT_ROAMING_CONTROL_HOME_ONLY = 0,
+ MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_ONLY = 1,
+ MBIM_CONTEXT_ROAMING_CONTROL_NON_PARTNER_ONLY = 2,
+ MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_PARTNER = 3,
+ MBIM_CONTEXT_ROAMING_CONTROL_HOME_AND_NON_PARTNER = 4,
+ MBIM_CONTEXT_ROAMING_CONTROL_PARTNER_AND_NON_PARTNER = 5,
+ MBIM_CONTEXT_ROAMING_CONTROL_ALLOW_ALL = 6
+} MbimContextRoamingControl;
+
+/**
+ * MbimContextMediaType:
+ * @MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY: Context allowed to be used only wen registered over cellular.
+ * @MBIM_CONTEXT_MEDIA_TYPE_WIFI_ONLY: Context allowed to be used only when registered over Wi-Fi.
+ * @MBIM_CONTEXT_MEDIA_TYPE_ALL: Context allowed to be used when registered either over cellular or Wi-Fi.
+ *
+ * Media type, specifying whether the modem is used for cellular or
+ * iWLAN (Wi-Fi offload).
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY = 0,
+ MBIM_CONTEXT_MEDIA_TYPE_WIFI_ONLY = 1,
+ MBIM_CONTEXT_MEDIA_TYPE_ALL = 2
+} MbimContextMediaType;
+
+/**
+ * MbimContextState:
+ * @MBIM_CONTEXT_STATE_DISABLED: Disabled.
+ * @MBIM_CONTEXT_STATE_ENABLED: Enabled.
+ *
+ * Status of the context, specifying whether it's enabled or disabled.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_CONTEXT_STATE_DISABLED = 0,
+ MBIM_CONTEXT_STATE_ENABLED = 1,
+} MbimContextState;
+
+/**
+ * MbimContextOperation:
+ * @MBIM_CONTEXT_OPERATION_DEFAULT: Adds or replaces an existing context.
+ * @MBIM_CONTEXT_OPERATION_DELETE: Delete an existing context.
+ * @MBIM_CONTEXT_OPERATION_RESTORE_FACTORY: Restore preconfigured contexts for the provider ID of the current SIM card.
+ *
+ * Command to run when updating context configuration.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_CONTEXT_OPERATION_DEFAULT = 0,
+ MBIM_CONTEXT_OPERATION_DELETE = 1,
+ MBIM_CONTEXT_OPERATION_RESTORE_FACTORY = 2,
+} MbimContextOperation;
+
+/*****************************************************************************/
+/* 'Registration Parameters' enums */
+
+/**
+ * MbimMicoMode:
+ * @MBIM_MICO_MODE_DISABLED: Disabled.
+ * @MBIM_MICO_MODE_ENABLED: Enabled.
+ * @MBIM_MICO_MODE_UNSUPPORTED: Device does not support MICO mode.
+ * @MBIM_MICO_MODE_DEFAULT: Default.
+ *
+ * Mobile Initiated Connection Only (MICO) Mode state.
+ *
+ * The @MBIM_MICO_MODE_DEFAULT value should only be used in set operations, it
+ * should never be returned by the module upon a query.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_MICO_MODE_DISABLED = 0,
+ MBIM_MICO_MODE_ENABLED = 1,
+ MBIM_MICO_MODE_UNSUPPORTED = 2,
+ MBIM_MICO_MODE_DEFAULT = 3,
+} MbimMicoMode;
+
+/**
+ * MbimDefaultPduActivationHint:
+ * @MBIM_DEFAULT_PDU_ACTIVATION_HINT_UNLIKELY: Default PDU session activation is unlikely to happen soon.
+ * @MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY: Default PDU session activation is likely to happen soon.
+ *
+ * Hint regarding the activation of the default PDU session.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_DEFAULT_PDU_ACTIVATION_HINT_UNLIKELY = 0,
+ MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY = 1,
+} MbimDefaultPduActivationHint;
+
+/**
+ * MbimLadnInfo:
+ * @MBIM_LADN_INFO_NOT_NEEDED: Information not needed.
+ * @MBIM_LADN_INFO_REQUESTED: Information requested.
+ *
+ * Local Area Data Network (LADN) information state.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_LADN_INFO_NOT_NEEDED = 0,
+ MBIM_LADN_INFO_REQUESTED = 1,
+} MbimLadnInfo;
+
+/**
+ * MbimDrxCycle:
+ * @MBIM_DRX_CYCLE_NOT_SPECIFIED: DRX cycle not specified.
+ * @MBIM_DRX_CYCLE_NOT_SUPPORTED: DRX cycle setting not supported.
+ * @MBIM_DRX_CYCLE_32: DRX cycle T=32.
+ * @MBIM_DRX_CYCLE_64: DRX cycle T=64.
+ * @MBIM_DRX_CYCLE_128: DRX cycle T=128.
+ * @MBIM_DRX_CYCLE_256: DRX cycle T=256.
+ *
+ * DRX cycle settings.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_DRX_CYCLE_NOT_SPECIFIED = 0,
+ MBIM_DRX_CYCLE_NOT_SUPPORTED = 1,
+ MBIM_DRX_CYCLE_32 = 2,
+ MBIM_DRX_CYCLE_64 = 3,
+ MBIM_DRX_CYCLE_128 = 4,
+ MBIM_DRX_CYCLE_256 = 5,
+} MbimDrxCycle;
+
+/*****************************************************************************/
+/* 'Subscriber Ready Status v3' enums */
+
+/**
+ * MbimSubscriberReadyStatusFlag:
+ * @MBIM_SUBSCRIBER_READY_STATUS_FLAG_NONE: None.
+ * @MBIM_SUBSCRIBER_READY_STATUS_FLAG_ESIM: Whether the SIM is an eSIM or not.
+ * @MBIM_SUBSCRIBER_READY_STATUS_FLAG_SIM_REMOVABILITY_KNOWN: Whether the SIM removability details are know or not.
+ * @MBIM_SUBSCRIBER_READY_STATUS_FLAG_SIM_REMOVABLE: Whether the SIM is removable or not, valid only if @MBIM_SUBSCRIBER_READY_STATUS_FLAG_SIM_REMOVABLITY_KNOWN is also given.
+ *
+ * Flags specifying SIM related details.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_SUBSCRIBER_READY_STATUS_FLAG_NONE = 0,
+ MBIM_SUBSCRIBER_READY_STATUS_FLAG_ESIM = 1 << 0,
+ MBIM_SUBSCRIBER_READY_STATUS_FLAG_SIM_REMOVABILITY_KNOWN = 1 << 1,
+ MBIM_SUBSCRIBER_READY_STATUS_FLAG_SIM_REMOVABLE = 1 << 2,
+} MbimSubscriberReadyStatusFlag;
+
+/*****************************************************************************/
+/* 'Device Caps v3' and 'Base Stations Info v3' enums */
+
+/**
+ * MbimDataClassV3:
+ * @MBIM_DATA_CLASS_V3_GPRS: GPRS.
+ * @MBIM_DATA_CLASS_V3_EDGE: EDGE.
+ * @MBIM_DATA_CLASS_V3_UMTS: UMTS.
+ * @MBIM_DATA_CLASS_V3_HSDPA: HSDPA.
+ * @MBIM_DATA_CLASS_V3_HSUPA: HSUPA.
+ * @MBIM_DATA_CLASS_V3_LTE: LTE.
+ * @MBIM_DATA_CLASS_V3_5G: 5G.
+ * @MBIM_DATA_CLASS_V3_1XRTT: 1xRTT.
+ * @MBIM_DATA_CLASS_V3_1XEVDO: 1xEV-DO.
+ * @MBIM_DATA_CLASS_V3_1XEVDO_REVA: 1xEV-DO RevA
+ * @MBIM_DATA_CLASS_V3_1XEVDV: 1xEV-DV.
+ * @MBIM_DATA_CLASS_V3_3XRTT: 3xRTT.
+ * @MBIM_DATA_CLASS_V3_1XEVDO_REVB: 1xEV-DO RevB.
+ * @MBIM_DATA_CLASS_V3_UMB: UMB.
+ * @MBIM_DATA_CLASS_V3_CUSTOM: Custom.
+ *
+ * Data class update in MBIMEx v3.0.
+ *
+ * There is now a single flag for 5G, and the new #MbimDataSubclass helps to
+ * identify the specific 5G setup.
+ *
+ * This type should be considered incompatible with #MbimDataClass.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_DATA_CLASS_V3_GPRS = 1 << 0,
+ MBIM_DATA_CLASS_V3_EDGE = 1 << 1,
+ MBIM_DATA_CLASS_V3_UMTS = 1 << 2,
+ MBIM_DATA_CLASS_V3_HSDPA = 1 << 3,
+ MBIM_DATA_CLASS_V3_HSUPA = 1 << 4,
+ MBIM_DATA_CLASS_V3_LTE = 1 << 5,
+ MBIM_DATA_CLASS_V3_5G = 1 << 6,
+ /* Bit 7 unused, bits 8 to 15 reserved for future 3GPP classes */
+ MBIM_DATA_CLASS_V3_1XRTT = 1 << 16,
+ MBIM_DATA_CLASS_V3_1XEVDO = 1 << 17,
+ MBIM_DATA_CLASS_V3_1XEVDO_REVA = 1 << 18,
+ MBIM_DATA_CLASS_V3_1XEVDV = 1 << 19,
+ MBIM_DATA_CLASS_V3_3XRTT = 1 << 20,
+ MBIM_DATA_CLASS_V3_1XEVDO_REVB = 1 << 21,
+ MBIM_DATA_CLASS_V3_UMB = 1 << 22,
+ /* Bits 23 to 30 reserved for future 3GPP2 classes */
+ MBIM_DATA_CLASS_V3_CUSTOM = 1 << 31
+} MbimDataClassV3;
+
+/**
+ * MbimDataSubclass:
+ * @MBIM_DATA_SUBCLASS_NONE: No data subclass.
+ * @MBIM_DATA_SUBCLASS_5G_ENDC: EUTRAN and NR dual connectivity as in 5G option 3.
+ * @MBIM_DATA_SUBCLASS_5G_NR: Standalone NR as in 5G option 2.
+ * @MBIM_DATA_SUBCLASS_5G_NEDC: NR and EUTRAN dual connectivity as in 5G option 4.
+ * @MBIM_DATA_SUBCLASS_5G_ELTE: eLTE as in 5G option 5.
+ * @MBIM_DATA_SUBCLASS_5G_NGENDC: Next-gen eLTE and NR dual connectivity as in 5G option 7.
+ *
+ * Flags specifying the data subclass.
+ *
+ * Since: 1.28
+ */
+typedef enum { /*< since=1.28 >*/
+ MBIM_DATA_SUBCLASS_NONE = 0,
+ MBIM_DATA_SUBCLASS_5G_ENDC = 1 << 0,
+ MBIM_DATA_SUBCLASS_5G_NR = 1 << 1,
+ MBIM_DATA_SUBCLASS_5G_NEDC = 1 << 2,
+ MBIM_DATA_SUBCLASS_5G_ELTE = 1 << 3,
+ MBIM_DATA_SUBCLASS_5G_NGENDC = 1 << 4,
+} MbimDataSubclass;
+
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_ENUMS_H_ */
diff --git a/src/libmbim-glib/mbim-message-private.h b/src/libmbim-glib/mbim-message-private.h
index c0638ed..99e878c 100644
--- a/src/libmbim-glib/mbim-message-private.h
+++ b/src/libmbim-glib/mbim-message-private.h
@@ -18,6 +18,7 @@
#include <glib.h>
#include "mbim-message.h"
+#include "mbim-tlv.h"
G_BEGIN_DECLS
@@ -168,8 +169,12 @@
gboolean swapped_offset_length);
void _mbim_struct_builder_append_uuid (MbimStructBuilder *builder,
const MbimUuid *value);
+void _mbim_struct_builder_append_guint16 (MbimStructBuilder *builder,
+ guint16 value);
void _mbim_struct_builder_append_guint32 (MbimStructBuilder *builder,
guint32 value);
+void _mbim_struct_builder_append_gint32 (MbimStructBuilder *builder,
+ gint32 value);
void _mbim_struct_builder_append_guint32_array (MbimStructBuilder *builder,
const guint32 *values,
guint32 n_values);
@@ -192,6 +197,8 @@
void _mbim_struct_builder_append_ipv6_array (MbimStructBuilder *builder,
const MbimIPv6 *values,
guint32 n_values);
+void _mbim_struct_builder_append_string_tlv (MbimStructBuilder *builder,
+ const gchar *values);
/*****************************************************************************/
/* Message builder */
@@ -215,6 +222,8 @@
gboolean swapped_offset_length);
void _mbim_message_command_builder_append_uuid (MbimMessageCommandBuilder *builder,
const MbimUuid *value);
+void _mbim_message_command_builder_append_guint16 (MbimMessageCommandBuilder *builder,
+ guint16 value);
void _mbim_message_command_builder_append_guint32 (MbimMessageCommandBuilder *builder,
guint32 value);
void _mbim_message_command_builder_append_guint32_array (MbimMessageCommandBuilder *builder,
@@ -239,6 +248,12 @@
void _mbim_message_command_builder_append_ipv6_array (MbimMessageCommandBuilder *builder,
const MbimIPv6 *values,
guint32 n_values);
+void _mbim_message_command_builder_append_tlv (MbimMessageCommandBuilder *builder,
+ const MbimTlv *tlv);
+void _mbim_message_command_builder_append_tlv_string (MbimMessageCommandBuilder *builder,
+ const gchar *str);
+void _mbim_message_command_builder_append_tlv_list (MbimMessageCommandBuilder *builder,
+ const GList *tlvs);
/*****************************************************************************/
/* Message parser */
@@ -257,10 +272,18 @@
guint32 relative_offset,
const MbimUuid **uuid,
GError **error);
+gboolean _mbim_message_read_guint16 (const MbimMessage *self,
+ guint32 relative_offset,
+ guint16 *value,
+ GError **error);
gboolean _mbim_message_read_guint32 (const MbimMessage *self,
guint32 relative_offset,
guint32 *value,
GError **error);
+gboolean _mbim_message_read_gint32 (const MbimMessage *self,
+ guint32 relative_offset,
+ gint32 *value,
+ GError **error);
gboolean _mbim_message_read_guint32_array (const MbimMessage *self,
guint32 array_size,
guint32 relative_offset_array_start,
@@ -302,6 +325,28 @@
MbimIPv6 **array,
GError **error);
+gboolean _mbim_message_read_tlv (const MbimMessage *self,
+ guint32 relative_offset,
+ MbimTlv **tlv,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_string (const MbimMessage *self,
+ guint32 relative_offset,
+ gchar **str,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_guint16_array (const MbimMessage *self,
+ guint32 relative_offset,
+ guint32 *array_size,
+ guint16 **array,
+ guint32 *bytes_read,
+ GError **error);
+gboolean _mbim_message_read_tlv_list (const MbimMessage *self,
+ guint32 relative_offset,
+ GList **tlv,
+ guint32 *bytes_read,
+ GError **error);
+
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_MESSAGE_PRIVATE_H_ */
diff --git a/src/libmbim-glib/mbim-message.c b/src/libmbim-glib/mbim-message.c
index 2a8f092..7b6699d 100644
--- a/src/libmbim-glib/mbim-message.c
+++ b/src/libmbim-glib/mbim-message.c
@@ -16,6 +16,7 @@
#include "mbim-message-private.h"
#include "mbim-error-types.h"
#include "mbim-enum-types.h"
+#include "mbim-tlv-private.h"
#include "mbim-basic-connect.h"
#include "mbim-auth.h"
@@ -151,6 +152,34 @@
}
gboolean
+_mbim_message_read_guint16 (const MbimMessage *self,
+ guint32 relative_offset,
+ guint16 *value,
+ GError **error)
+{
+ guint64 required_size;
+ guint32 information_buffer_offset;
+
+ g_assert (value);
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ required_size = (guint64)information_buffer_offset + (guint64)relative_offset + 2;
+ if ((guint64)self->len < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read 16bit unsigned integer (2 bytes) (%u < %" G_GUINT64_FORMAT ")",
+ self->len, required_size);
+ return FALSE;
+ }
+
+ *value = GUINT16_FROM_LE (G_STRUCT_MEMBER (
+ guint16,
+ self->data,
+ (information_buffer_offset + relative_offset)));
+ return TRUE;
+}
+
+gboolean
_mbim_message_read_guint32 (const MbimMessage *self,
guint32 relative_offset,
guint32 *value,
@@ -179,6 +208,34 @@
}
gboolean
+_mbim_message_read_gint32 (const MbimMessage *self,
+ guint32 relative_offset,
+ gint32 *value,
+ GError **error)
+{
+ guint64 required_size;
+ guint32 information_buffer_offset;
+
+ g_assert (value);
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+
+ required_size = (guint64)information_buffer_offset + (guint64)relative_offset + 4;
+ if ((guint64)self->len < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read 32bit signed integer (4 bytes) (%u < %" G_GUINT64_FORMAT ")",
+ self->len, required_size);
+ return FALSE;
+ }
+
+ *value = GINT32_FROM_LE (G_STRUCT_MEMBER (
+ gint32,
+ self->data,
+ (information_buffer_offset + relative_offset)));
+ return TRUE;
+}
+
+gboolean
_mbim_message_read_guint32_array (const MbimMessage *self,
guint32 array_size,
guint32 relative_offset_array_start,
@@ -757,6 +814,151 @@
return TRUE;
}
+gboolean
+_mbim_message_read_tlv (const MbimMessage *self,
+ guint32 relative_offset,
+ MbimTlv **tlv,
+ guint32 *bytes_read,
+ GError **error)
+{
+ guint32 information_buffer_offset;
+ guint64 tlv_offset;
+ guint64 required_size;
+ const guint8 *tlv_raw;
+ guint64 tlv_size;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+ tlv_offset = (guint64)information_buffer_offset + (guint64)relative_offset;
+ tlv_raw = (const guint8 *) G_STRUCT_MEMBER_P (self->data, tlv_offset);
+ tlv_size = ((guint64)sizeof (struct tlv) +
+ (guint64)GUINT32_FROM_LE (((struct tlv *)tlv_raw)->data_length) +
+ (guint64)((struct tlv *)tlv_raw)->padding_length);
+
+ required_size = tlv_offset + tlv_size;
+ if ((guint64)self->len < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read TLV (%" G_GUINT64_FORMAT " bytes) (%u < %" G_GUINT64_FORMAT ")",
+ tlv_size, self->len, required_size);
+ return FALSE;
+ }
+
+ *tlv = _mbim_tlv_new_from_raw (tlv_raw, (guint32)tlv_size, bytes_read, error);
+ return (*tlv) ? TRUE : FALSE;
+}
+
+gboolean
+_mbim_message_read_tlv_string (const MbimMessage *self,
+ guint32 relative_offset,
+ gchar **str,
+ guint32 *bytes_read,
+ GError **error)
+{
+ g_autoptr(MbimTlv) tlv = NULL;
+ guint32 tlv_bytes_read = 0;
+ gchar *tlv_str;
+
+ if (!_mbim_message_read_tlv (self,
+ relative_offset,
+ &tlv,
+ &tlv_bytes_read,
+ error))
+ return FALSE;
+
+ tlv_str = mbim_tlv_string_get (tlv, error);
+ if (!tlv_str)
+ return FALSE;
+
+ *str = tlv_str;
+ *bytes_read = tlv_bytes_read;
+ return TRUE;
+}
+
+gboolean
+_mbim_message_read_tlv_guint16_array (const MbimMessage *self,
+ guint32 relative_offset,
+ guint32 *array_size,
+ guint16 **array,
+ guint32 *bytes_read,
+ GError **error)
+{
+ g_autoptr(MbimTlv) tlv = NULL;
+ guint32 tlv_bytes_read = 0;
+
+ if (!_mbim_message_read_tlv (self,
+ relative_offset,
+ &tlv,
+ &tlv_bytes_read,
+ error))
+ return FALSE;
+
+ if (!mbim_tlv_guint16_array_get (tlv, array_size, array, error))
+ return FALSE;
+
+ *bytes_read = tlv_bytes_read;
+ return TRUE;
+}
+
+gboolean
+_mbim_message_read_tlv_list (const MbimMessage *self,
+ guint32 relative_offset,
+ GList **tlv_list,
+ guint32 *bytes_read,
+ GError **error)
+{
+ guint32 information_buffer_offset;
+ guint64 tlv_list_offset;
+ const guint8 *tlv_list_raw;
+ guint32 tlv_list_raw_size;
+ GList *list = NULL;
+ guint32 total_bytes_read = 0;
+ GError *inner_error = NULL;
+
+ information_buffer_offset = _mbim_message_get_information_buffer_offset (self);
+ tlv_list_offset = (guint64)information_buffer_offset + (guint64)relative_offset;
+
+ /* TLV list always at the end of the message */
+ if ((guint64)self->len < tlv_list_offset) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read TLV at offset (%u < %" G_GUINT64_FORMAT ")",
+ self->len, tlv_list_offset);
+ return FALSE;
+ }
+
+ tlv_list_raw_size = self->len - (guint32)tlv_list_offset;
+ tlv_list_raw = (const guint8 *) G_STRUCT_MEMBER_P (self->data, tlv_list_offset);
+
+ while ((tlv_list_raw_size > 0) && !inner_error) {
+ MbimTlv *tlv;
+ guint32 tlv_size;
+
+ if (tlv_list_raw_size < sizeof (struct tlv)) {
+ g_warning ("Left %u bytes unused after the TLV list", tlv_list_raw_size);
+ break;
+ }
+
+ tlv = _mbim_tlv_new_from_raw (tlv_list_raw, tlv_list_raw_size, &tlv_size, &inner_error);
+ if (!tlv)
+ break;
+
+ list = g_list_append (list, tlv);
+ total_bytes_read += tlv_size;
+
+ g_assert (tlv_list_raw_size >= tlv_size);
+ tlv_list_raw += tlv_size;
+ tlv_list_raw_size -= tlv_size;
+ }
+
+ if (inner_error) {
+ g_propagate_error (error, inner_error);
+ g_list_free_full (list, (GDestroyNotify)mbim_tlv_unref);
+ return FALSE;
+ }
+
+ *bytes_read = total_bytes_read;
+ *tlv_list = list;
+ return TRUE;
+}
+
/*****************************************************************************/
/* Struct builder interface
*
@@ -913,6 +1115,17 @@
}
void
+_mbim_struct_builder_append_guint16 (MbimStructBuilder *builder,
+ guint16 value)
+{
+ guint16 tmp;
+
+ /* guint16 values are added in the static buffer only */
+ tmp = GUINT16_TO_LE (value);
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&tmp, sizeof (tmp));
+}
+
+void
_mbim_struct_builder_append_guint32 (MbimStructBuilder *builder,
guint32 value)
{
@@ -924,6 +1137,17 @@
}
void
+_mbim_struct_builder_append_gint32 (MbimStructBuilder *builder,
+ gint32 value)
+{
+ gint32 tmp;
+
+ /* gint32 values are added in the static buffer only */
+ tmp = GINT32_TO_LE (value);
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&tmp, sizeof (tmp));
+}
+
+void
_mbim_struct_builder_append_guint32_array (MbimStructBuilder *builder,
const guint32 *values,
guint32 n_values)
@@ -1014,6 +1238,61 @@
}
void
+_mbim_struct_builder_append_string_tlv (MbimStructBuilder *builder,
+ const gchar *value)
+{
+ guint8 reserved = 0;
+ guint8 padding = 0;
+ guint32 length;
+ gunichar2 *utf16 = NULL;
+ guint32 utf16_bytes = 0;
+ GError *error = NULL;
+
+ /* Add the reserved value */
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&reserved, sizeof (reserved));
+
+ /* Convert the string from UTF-8 to UTF-16HE */
+ if (value && value[0]) {
+ glong items_written = 0;
+ utf16 = g_utf8_to_utf16 (value,
+ -1,
+ NULL, /* bytes */
+ &items_written, /* gunichar2 */
+ &error);
+
+ if (!utf16) {
+ g_warning ("Error converting string: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+ utf16_bytes = items_written * 2;
+
+ /* Add the padding value */
+ padding = utf16_bytes % 4;
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&padding, sizeof (padding));
+ g_debug ("padding:%d", padding);
+ }
+
+ /* Add the length value */
+ length = GUINT32_TO_LE (utf16_bytes);
+ g_byte_array_append (builder->fixed_buffer, (guint8 *)&length, sizeof (length));
+
+ /* And finally, the string itself to the variable buffer */
+ if (utf16_bytes) {
+ /* For BE systems, convert from BE to LE */
+ if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+ guint i;
+
+ for (i = 0; i < (utf16_bytes / 2); i++)
+ utf16[i] = GUINT16_TO_LE (utf16[i]);
+ }
+ g_byte_array_append (builder->variable_buffer, (const guint8 *)utf16, (guint)utf16_bytes);
+ bytearray_apply_padding (builder->variable_buffer, &utf16_bytes);
+ }
+ g_free (utf16);
+}
+
+void
_mbim_struct_builder_append_string_array (MbimStructBuilder *builder,
const gchar *const *values,
guint32 n_values)
@@ -1172,6 +1451,13 @@
}
void
+_mbim_message_command_builder_append_guint16 (MbimMessageCommandBuilder *builder,
+ guint16 value)
+{
+ _mbim_struct_builder_append_guint16 (builder->contents_builder, value);
+}
+
+void
_mbim_message_command_builder_append_guint32_array (MbimMessageCommandBuilder *builder,
const guint32 *values,
guint32 n_values)
@@ -1234,6 +1520,47 @@
}
/*****************************************************************************/
+/* TLVs only expected as primary message fields, not inside structs */
+
+void
+_mbim_message_command_builder_append_tlv (MbimMessageCommandBuilder *builder,
+ const MbimTlv *tlv)
+{
+ const guint8 *raw_tlv;
+ guint32 raw_tlv_size;
+
+ raw_tlv = mbim_tlv_get_raw (tlv, &raw_tlv_size, NULL);
+ _mbim_struct_builder_append_byte_array (builder->contents_builder,
+ FALSE, FALSE, FALSE,
+ raw_tlv, raw_tlv_size,
+ FALSE);
+}
+
+void
+_mbim_message_command_builder_append_tlv_string (MbimMessageCommandBuilder *builder,
+ const gchar *str)
+{
+ g_autoptr(MbimTlv) tlv = NULL;
+ g_autoptr(GError) error = NULL;
+
+ tlv = mbim_tlv_string_new (str, &error);
+ if (!tlv)
+ g_warning ("Error appending TLV: %s", error->message);
+ else
+ _mbim_message_command_builder_append_tlv (builder, tlv);
+}
+
+void
+_mbim_message_command_builder_append_tlv_list (MbimMessageCommandBuilder *builder,
+ const GList *tlvs)
+{
+ const GList *l;
+
+ for (l = tlvs; l; l = g_list_next (l))
+ _mbim_message_command_builder_append_tlv (builder, (MbimTlv *)(l->data));
+}
+
+/*****************************************************************************/
/* Generic message interface */
MbimMessage *
@@ -1332,12 +1659,38 @@
const gchar *line_prefix,
gboolean headers_only)
{
- GString *printable;
- MbimService service_read_fields = MBIM_SERVICE_INVALID;
+ gchar *str;
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (line_prefix != NULL, NULL);
+ str = mbim_message_get_printable_full (self, 1, 0, line_prefix, headers_only, NULL);
+ g_assert (str);
+
+ return str;
+}
+
+gchar *
+mbim_message_get_printable_full (const MbimMessage *self,
+ guint8 mbimex_version_major,
+ guint8 mbimex_version_minor,
+ const gchar *line_prefix,
+ gboolean headers_only,
+ GError **error)
+{
+ GString *printable = NULL;
+ MbimService service_read_fields = MBIM_SERVICE_INVALID;
+
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (line_prefix != NULL, NULL);
+
+ if (mbimex_version_major > 3) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "MBIMEx version %x.%02x is unsupported",
+ mbimex_version_major, mbimex_version_minor);
+ return NULL;
+ }
+
if (!line_prefix)
line_prefix = "";
@@ -1398,14 +1751,14 @@
case MBIM_MESSAGE_TYPE_HOST_ERROR:
case MBIM_MESSAGE_TYPE_FUNCTION_ERROR:
if (!headers_only) {
- MbimProtocolError error;
+ MbimProtocolError protocol_error;
- error = mbim_message_error_get_error_status_code (self);
+ protocol_error = mbim_message_error_get_error_status_code (self);
g_string_append_printf (printable,
"%sContents:\n"
"%s error = '%s' (0x%08x)\n",
line_prefix,
- line_prefix, mbim_protocol_error_get_string (error), error);
+ line_prefix, mbim_protocol_error_get_string (protocol_error), protocol_error);
}
break;
@@ -1502,59 +1855,103 @@
if (service_read_fields != MBIM_SERVICE_INVALID) {
g_autofree gchar *fields_printable = NULL;
- g_autoptr(GError) error = NULL;
+ g_autoptr(GError) inner_error = NULL;
switch (service_read_fields) {
case MBIM_SERVICE_BASIC_CONNECT:
- fields_printable = __mbim_message_basic_connect_get_printable_fields (self, line_prefix, &error);
+ if (mbimex_version_major < 2)
+ fields_printable = __mbim_message_basic_connect_get_printable_fields (self, line_prefix, &inner_error);
+ else if (mbimex_version_major == 2) {
+ fields_printable = __mbim_message_ms_basic_connect_v2_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v1 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_basic_connect_get_printable_fields (self, line_prefix, &inner_error);
+ }
+ } else if (mbimex_version_major == 3) {
+ fields_printable = __mbim_message_ms_basic_connect_v3_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v2 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_ms_basic_connect_v2_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v1 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_basic_connect_get_printable_fields (self, line_prefix, &inner_error);
+ }
+ }
+ } else
+ g_assert_not_reached ();
break;
case MBIM_SERVICE_SMS:
- fields_printable = __mbim_message_sms_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_sms_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_USSD:
- fields_printable = __mbim_message_ussd_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_ussd_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_PHONEBOOK:
- fields_printable = __mbim_message_phonebook_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_phonebook_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_STK:
- fields_printable = __mbim_message_stk_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_stk_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_AUTH:
- fields_printable = __mbim_message_auth_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_auth_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_DSS:
- fields_printable = __mbim_message_dss_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_dss_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_MS_FIRMWARE_ID:
- fields_printable = __mbim_message_ms_firmware_id_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_ms_firmware_id_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_MS_HOST_SHUTDOWN:
- fields_printable = __mbim_message_ms_host_shutdown_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_ms_host_shutdown_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_MS_SAR:
- fields_printable = __mbim_message_ms_sar_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_ms_sar_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_PROXY_CONTROL:
- fields_printable = __mbim_message_proxy_control_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_proxy_control_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_QMI:
- fields_printable = __mbim_message_qmi_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_qmi_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_ATDS:
- fields_printable = __mbim_message_atds_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_atds_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_INTEL_FIRMWARE_UPDATE:
- fields_printable = __mbim_message_intel_firmware_update_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_intel_firmware_update_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_QDU:
- fields_printable = __mbim_message_qdu_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_qdu_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS:
- fields_printable = __mbim_message_ms_basic_connect_extensions_get_printable_fields (self, line_prefix, &error);
+ if (mbimex_version_major < 2)
+ fields_printable = __mbim_message_ms_basic_connect_extensions_get_printable_fields (self, line_prefix, &inner_error);
+ else if (mbimex_version_major == 2) {
+ fields_printable = __mbim_message_ms_basic_connect_extensions_v2_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v1 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_ms_basic_connect_extensions_get_printable_fields (self, line_prefix, &inner_error);
+ }
+ } else if (mbimex_version_major == 3) {
+ fields_printable = __mbim_message_ms_basic_connect_extensions_v3_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v2 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_ms_basic_connect_extensions_v2_get_printable_fields (self, line_prefix, &inner_error);
+ /* attempt fallback to v1 printable */
+ if (g_error_matches (inner_error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_UNSUPPORTED)) {
+ g_clear_error (&inner_error);
+ fields_printable = __mbim_message_ms_basic_connect_extensions_get_printable_fields (self, line_prefix, &inner_error);
+ }
+ }
+ } else
+ g_assert_not_reached ();
break;
case MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS:
- fields_printable = __mbim_message_ms_uicc_low_level_access_get_printable_fields (self, line_prefix, &error);
+ fields_printable = __mbim_message_ms_uicc_low_level_access_get_printable_fields (self, line_prefix, &inner_error);
break;
case MBIM_SERVICE_INVALID:
case MBIM_SERVICE_LAST:
@@ -1563,10 +1960,10 @@
break;
}
- if (error)
+ if (inner_error)
g_string_append_printf (printable,
"%sFields: %s\n",
- line_prefix, error->message);
+ line_prefix, inner_error->message);
else if (fields_printable && fields_printable[0])
g_string_append_printf (printable,
"%sFields:\n"
diff --git a/src/libmbim-glib/mbim-message.h b/src/libmbim-glib/mbim-message.h
index 571d45a..86bd9b0 100644
--- a/src/libmbim-glib/mbim-message.h
+++ b/src/libmbim-glib/mbim-message.h
@@ -160,6 +160,10 @@
*
* Gets a printable string with the contents of the whole MBIM message.
*
+ * This method will not fail if the parsing of the message contents fails,
+ * a fallback text with the error will be included in the generated printable
+ * information instead.
+ *
* Returns: a newly allocated string, which should be freed with g_free().
*
* Since: 1.0
@@ -169,6 +173,43 @@
gboolean headers_only);
/**
+ * mbim_message_get_printable_full:
+ * @self: a #MbimMessage.
+ * @mbimex_version_major: major version of the agreed MBIMEx support.
+ * @mbimex_version_minor: minor version of the agreed MBIMEx support.
+ * @line_prefix: prefix string to use in each new generated line.
+ * @headers_only: %TRUE if only basic headers should be printed.
+ * @error: return location for error or %NULL.
+ *
+ * Gets a printable string with the contents of the whole MBIM message.
+ *
+ * Unlike mbim_message_get_printable(), this method allows specifying the
+ * MBIMEx version agreed between host and device, so that the correct
+ * processing and parsing is done on messages in the newer MBIMEx versions.
+ *
+ * If @mbimex_version_major < 2, this method behaves exactly as
+ * mbim_message_get_printable().
+ *
+ * If the specified @mbimex_version_major is unsupported, an error will be
+ * returned.
+ *
+ * This method will not fail if the parsing of the message contents fails,
+ * a fallback text with the error will be included in the generated printable
+ * information instead.
+ *
+ * Returns: a newly allocated string which should be freed with g_free(), or
+ * #NULL if @error is set.
+ *
+ * Since: 1.28
+ */
+gchar *mbim_message_get_printable_full (const MbimMessage *self,
+ guint8 mbimex_version_major,
+ guint8 mbimex_version_minor,
+ const gchar *line_prefix,
+ gboolean headers_only,
+ GError **error);
+
+/**
* mbim_message_get_raw:
* @self: a #MbimMessage.
* @length: (out): return location for the size of the output buffer.
diff --git a/src/libmbim-glib/mbim-proxy.c b/src/libmbim-glib/mbim-proxy.c
index 084b255..dcbed96 100644
--- a/src/libmbim-glib/mbim-proxy.c
+++ b/src/libmbim-glib/mbim-proxy.c
@@ -27,6 +27,7 @@
#include "mbim-enum-types.h"
#include "mbim-error-types.h"
#include "mbim-basic-connect.h"
+#include "mbim-ms-basic-connect-extensions.h"
#include "mbim-proxy-helpers.h"
/* The mbim-proxy may be used for bulk data transfer, such as modem
@@ -36,6 +37,10 @@
*/
#define BUFFER_SIZE 4096
+/* The proxy control "Version" indication reporting the last agreed
+ * MBIMEx version, if any */
+#define MBIM_DEVICE_PROXY_CONTROL_VERSION "mbim-device-proxy-control-version"
+
G_DEFINE_TYPE (MbimProxy, mbim_proxy, G_TYPE_OBJECT)
enum {
@@ -589,8 +594,9 @@
Client *client,
MbimMessage *message)
{
- Request *request;
- MbimStatusError status = MBIM_STATUS_ERROR_FAILURE;
+ Request *request;
+ MbimStatusError status = MBIM_STATUS_ERROR_FAILURE;
+ g_autoptr(MbimMessage) indication = NULL;
/* create request holder */
request = request_new (self, client, message);
@@ -659,7 +665,8 @@
GAsyncResult *res,
Request *request)
{
- g_autoptr(GError) error = NULL;
+ g_autoptr(GError) error = NULL;
+ MbimMessage *indication;
if (!internal_device_open_finish (self, res, &error)) {
g_warning ("[client %lu,0x%08x] cannot configure proxy: couldn't open MBIM device: %s",
@@ -673,6 +680,15 @@
g_debug ("[client %lu,0x%08x] proxy configured",
request->client->id, request->original_transaction_id);
+ /* notify the client about the MBIMEx version */
+ indication = (MbimMessage *) g_object_get_data (G_OBJECT (request->client->device), MBIM_DEVICE_PROXY_CONTROL_VERSION);
+ if (indication) {
+ if (!client_send_message (request->client, indication, &error))
+ g_warning ("[client %lu] couldn't report MBIMEx version update: %s", request->client->id, error->message);
+ else
+ g_debug ("[client %lu] reported MBIMEx version update", request->client->id);
+ }
+
if (request->client->config_ongoing == TRUE)
request->client->config_ongoing = FALSE;
request->response = build_proxy_control_command_done (request->message, MBIM_STATUS_ERROR_NONE);
@@ -959,6 +975,94 @@
}
/*****************************************************************************/
+/* MBIMEx version detection */
+
+static MbimMessage *
+build_proxy_control_version_notification (guint16 mbim_version,
+ guint16 ms_mbimex_version)
+{
+ MbimMessage *message;
+ struct indicate_status_message *indicate_status;
+ guint16 tmp;
+ guint buffer_i = 0;
+ gsize buffer_length = 0;
+
+ buffer_length = sizeof (mbim_version) + sizeof (ms_mbimex_version);
+
+ message = (MbimMessage *) _mbim_message_allocate (MBIM_MESSAGE_TYPE_INDICATE_STATUS,
+ 0,
+ sizeof (struct indicate_status_message) + buffer_length);
+ indicate_status = &(((struct full_message *)(message->data))->message.indicate_status);
+ indicate_status->fragment_header.total = GUINT32_TO_LE (1);
+ indicate_status->fragment_header.current = 0;
+ memcpy (indicate_status->service_id, MBIM_UUID_PROXY_CONTROL, sizeof (MbimUuid));
+ indicate_status->command_id = GUINT32_TO_LE (MBIM_CID_PROXY_CONTROL_VERSION);
+ indicate_status->buffer_length = GUINT32_TO_LE (buffer_length);
+
+ tmp = GUINT16_TO_LE (mbim_version);
+ memcpy (&indicate_status->buffer[buffer_i], &tmp, sizeof (tmp));
+ buffer_i += sizeof (tmp);
+ tmp = GUINT16_TO_LE (ms_mbimex_version);
+ memcpy (&indicate_status->buffer[buffer_i], &tmp, sizeof (tmp));
+ buffer_i += sizeof (tmp);
+ g_assert (buffer_i == buffer_length);
+
+ return message;
+}
+
+static void
+monitor_ms_basic_connect_extensions_version_response (MbimProxy *self,
+ MbimDevice *device,
+ MbimMessage *response)
+{
+ g_autoptr(MbimMessage) indication = NULL;
+ guint16 mbim_version;
+ guint16 ms_mbimex_version;
+ guint8 ms_mbimex_version_major;
+ guint8 ms_mbimex_version_minor;
+ GList *l;
+
+ /* monitor the MBIMEx version agreed between the clients and the device */
+ if (!mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, NULL) ||
+ (mbim_message_command_done_get_service (response) != MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS) ||
+ (mbim_message_command_done_get_cid (response) != MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_VERSION) ||
+ !mbim_message_ms_basic_connect_extensions_v2_version_response_parse (response, &mbim_version, &ms_mbimex_version, NULL))
+ return;
+
+ ms_mbimex_version_major = ms_mbimex_version >> 8;
+ ms_mbimex_version_minor = ms_mbimex_version & 0xFF;
+
+ g_message ("Proxy monitoring detected MBIMEx version agreed with device: %x.%02x",
+ ms_mbimex_version_major, ms_mbimex_version_minor);
+ mbim_device_set_ms_mbimex_version (device, ms_mbimex_version_major, ms_mbimex_version_minor, NULL);
+
+ /* notify to all clients about the MBIMEx version update */
+ indication = build_proxy_control_version_notification (mbim_version, ms_mbimex_version);
+ for (l = self->priv->clients; l; l = g_list_next (l)) {
+ g_autoptr(GError) error = NULL;
+ Client *client;
+
+ client = l->data;
+ if (client->device != device)
+ continue;
+
+ if (!client_send_message (client, indication, &error))
+ g_warning ("[client %lu] couldn't report MBIMEx version update to %x.%02x: %s",
+ client->id, ms_mbimex_version_major, ms_mbimex_version_minor, error->message);
+ else
+ g_debug ("[client %lu] reported MBIMEx version update to %x.%02x",
+ client->id, ms_mbimex_version_major, ms_mbimex_version_minor);
+ }
+
+ /* the indication is stored as data associated to the device, so that it can
+ * be reused any time new clients attempt an open */
+ g_object_set_data_full (G_OBJECT (device),
+ MBIM_DEVICE_PROXY_CONTROL_VERSION,
+ mbim_message_ref (indication),
+ (GDestroyNotify)mbim_message_unref);
+}
+
+/*****************************************************************************/
/* Standard command */
static void
@@ -989,6 +1093,10 @@
/* replace reponse transaction id with the requested transaction id */
g_debug ("[client %lu,0x%08x] response from device received",
request->client->id, request->original_transaction_id);
+
+ /* try to match the MBIMEx version exchange */
+ monitor_ms_basic_connect_extensions_version_response (request->self, device, request->response);
+
mbim_message_set_transaction_id (request->response, request->original_transaction_id);
request_complete_and_free (request);
}
diff --git a/src/libmbim-glib/mbim-tlv-private.h b/src/libmbim-glib/mbim-tlv-private.h
new file mode 100644
index 0000000..7dc2d8f
--- /dev/null
+++ b/src/libmbim-glib/mbim-tlv-private.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * libmbim-glib -- GLib/GIO based library to control MBIM devices
+ *
+ * Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2021 Intel Corporation
+ *
+ * This is a private non-installed header
+ */
+
+#ifndef _LIBMBIM_GLIB_MBIM_TLV_PRIVATE_H_
+#define _LIBMBIM_GLIB_MBIM_TLV_PRIVATE_H_
+
+#if !defined (LIBMBIM_GLIB_COMPILATION)
+#error "This is a private header!!"
+#endif
+
+#include <glib.h>
+
+#include "mbim-tlv.h"
+
+G_BEGIN_DECLS
+
+/*****************************************************************************/
+/* The MbimTlv */
+
+/* Defined in the same way as GByteArray */
+struct _MbimTlv {
+ guint8 *data;
+ guint len;
+};
+
+struct tlv {
+ guint16 type;
+ guint8 reserved;
+ guint8 padding_length;
+ guint32 data_length;
+ guint8 data[];
+} __attribute__((packed));
+
+#define MBIM_TLV_HEADER(self) ((struct tlv *)(((MbimTlv *)self)->data))
+
+#define MBIM_TLV_FIELD_TYPE(self) MBIM_TLV_HEADER (self)->type
+#define MBIM_TLV_FIELD_RESERVED(self) MBIM_TLV_HEADER (self)->reserved
+#define MBIM_TLV_FIELD_PADDING_LENGTH(self) MBIM_TLV_HEADER (self)->padding_length
+#define MBIM_TLV_FIELD_DATA_LENGTH(self) MBIM_TLV_HEADER (self)->data_length
+#define MBIM_TLV_FIELD_DATA(self) MBIM_TLV_HEADER (self)->data
+
+#define MBIM_TLV_GET_TLV_TYPE(self) (MbimTlvType) GUINT16_FROM_LE (MBIM_TLV_FIELD_TYPE (self))
+#define MBIM_TLV_GET_DATA_LENGTH(self) GUINT32_FROM_LE (MBIM_TLV_FIELD_DATA_LENGTH (self))
+
+/*****************************************************************************/
+/* Print support */
+
+gchar *_mbim_tlv_print (const MbimTlv *tlv,
+ const gchar *line_prefix);
+
+/*****************************************************************************/
+/* Parsing support */
+
+MbimTlv *_mbim_tlv_new_from_raw (const guint8 *raw,
+ guint32 raw_length,
+ guint32 *bytes_read,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* _LIBMBIM_GLIB_MBIM_TLV_PRIVATE_H_ */
diff --git a/src/libmbim-glib/mbim-tlv.c b/src/libmbim-glib/mbim-tlv.c
new file mode 100644
index 0000000..8058836
--- /dev/null
+++ b/src/libmbim-glib/mbim-tlv.c
@@ -0,0 +1,476 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * libmbim-glib -- GLib/GIO based library to control MBIM devices
+ *
+ * Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#include <glib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <endian.h>
+
+#include "mbim-tlv.h"
+#include "mbim-tlv-private.h"
+#include "mbim-error-types.h"
+#include "mbim-enum-types.h"
+#include "mbim-common.h"
+
+/*****************************************************************************/
+
+GType
+mbim_tlv_get_type (void)
+{
+ static gsize g_define_type_id_initialized = 0;
+
+ if (g_once_init_enter (&g_define_type_id_initialized)) {
+ GType g_define_type_id =
+ g_boxed_type_register_static (g_intern_static_string ("MbimTlv"),
+ (GBoxedCopyFunc) mbim_tlv_ref,
+ (GBoxedFreeFunc) mbim_tlv_unref);
+
+ g_once_init_leave (&g_define_type_id_initialized, g_define_type_id);
+ }
+
+ return g_define_type_id_initialized;
+}
+
+/*****************************************************************************/
+
+gchar *
+_mbim_tlv_print (const MbimTlv *tlv,
+ const gchar *line_prefix)
+{
+ GString *str;
+ MbimTlvType tlv_type;
+ const gchar *tlv_type_str;
+ const guint8 *tlv_data;
+ guint32 tlv_data_size;
+ g_autofree gchar *tlv_data_str = NULL;
+
+ tlv_type = mbim_tlv_get_tlv_type (tlv);
+ tlv_type_str = mbim_tlv_type_get_string (tlv_type);
+
+ str = g_string_new ("");
+ g_string_append_printf (str, "{\n");
+ g_string_append_printf (str, "%s tlv type = %s (0x%04x)\n", line_prefix, tlv_type_str ? tlv_type_str : "unknown", tlv_type);
+
+ tlv_data = mbim_tlv_get_tlv_data (tlv, &tlv_data_size);
+ tlv_data_str = mbim_common_str_hex (tlv_data, tlv_data_size, ':');
+ g_string_append_printf (str, "%s tlv data = %s\n", line_prefix, tlv_data_str ? tlv_data_str : "");
+
+ if (tlv_type == MBIM_TLV_TYPE_WCHAR_STR) {
+ g_autoptr(GError) error = NULL;
+ g_autofree gchar *tlv_data_string_str = NULL;
+
+ tlv_data_string_str = mbim_tlv_string_get (tlv, &error);
+ if (!tlv_data_string_str)
+ tlv_data_string_str = g_strdup_printf ("*** error: %s", error->message);
+ g_string_append_printf (str, "%s tlv string = %s\n", line_prefix, tlv_data_string_str ? tlv_data_string_str : "");
+ } else if (tlv_type == MBIM_TLV_TYPE_UINT16_TBL) {
+ g_autoptr(GError) error = NULL;
+ guint32 array_size = 0;
+ g_autofree guint16 *array = NULL;
+ g_autofree gchar *tlv_data_string_str = NULL;
+
+ if (!mbim_tlv_guint16_array_get (tlv, &array_size, &array, &error))
+ tlv_data_string_str = g_strdup_printf ("*** error: %s", error->message);
+ else {
+ GString *aux;
+ guint32 i;
+
+ aux = g_string_new ("[");
+ for (i = 0; i < array_size; i++)
+ g_string_append_printf (aux, "%s%" G_GUINT16_FORMAT, (i == 0) ? "" : ",", array[i]);
+ g_string_append (aux, "]");
+ tlv_data_string_str = g_string_free (aux, FALSE);
+ }
+ g_string_append_printf (str, "%s tlv uint16 array = %s\n", line_prefix, tlv_data_string_str ? tlv_data_string_str : "");
+ }
+
+ g_string_append_printf (str, "%s}", line_prefix);
+
+ return g_string_free (str, FALSE);
+}
+
+/*****************************************************************************/
+
+MbimTlv *
+mbim_tlv_new (MbimTlvType tlv_type,
+ const guint8 *tlv_data,
+ guint32 tlv_data_length)
+{
+ GByteArray *self;
+ guint32 tlv_size;
+ guint32 padding_size;
+
+ g_return_val_if_fail (tlv_type != MBIM_TLV_TYPE_INVALID, NULL);
+
+ /* Compute size of the TLV and allocate heap for it */
+ padding_size = (tlv_data_length % 4) ? (4 - (tlv_data_length % 4)) : 0;
+ tlv_size = sizeof (struct tlv) + tlv_data_length + padding_size;
+ self = g_byte_array_sized_new (tlv_size);
+ g_byte_array_set_size (self, tlv_size);
+
+ /* Set TLV header */
+ MBIM_TLV_FIELD_TYPE (self) = GUINT16_TO_LE (tlv_type);
+ MBIM_TLV_FIELD_RESERVED (self) = 0;
+ MBIM_TLV_FIELD_PADDING_LENGTH (self) = padding_size;
+ MBIM_TLV_FIELD_DATA_LENGTH (self) = GUINT32_TO_LE (tlv_data_length);
+
+ if (tlv_data && tlv_data_length) {
+ memcpy (MBIM_TLV_FIELD_DATA (self), tlv_data, tlv_data_length);
+ if (padding_size)
+ memset (MBIM_TLV_FIELD_DATA (self) + tlv_data_length, 0, padding_size);
+ }
+
+ return (MbimTlv *)self;
+}
+
+MbimTlv *
+_mbim_tlv_new_from_raw (const guint8 *raw,
+ guint32 raw_length,
+ guint32 *bytes_read,
+ GError **error)
+{
+ guint32 tlv_size;
+
+ g_assert (raw_length >= sizeof (struct tlv));
+ tlv_size = sizeof (struct tlv) + GUINT32_FROM_LE (((struct tlv *)raw)->data_length) + ((struct tlv *)raw)->padding_length;
+
+ *bytes_read = tlv_size;
+ return (MbimTlv *) g_byte_array_append (g_byte_array_sized_new (tlv_size), raw, tlv_size);
+}
+
+MbimTlv *
+mbim_tlv_dup (const MbimTlv *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ return mbim_tlv_new (MBIM_TLV_GET_TLV_TYPE (self),
+ MBIM_TLV_FIELD_DATA (self),
+ MBIM_TLV_GET_DATA_LENGTH (self));
+}
+
+MbimTlv *
+mbim_tlv_ref (MbimTlv *self)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+
+ return (MbimTlv *) g_byte_array_ref ((GByteArray *)self);
+}
+
+void
+mbim_tlv_unref (MbimTlv *self)
+{
+ g_return_if_fail (self != NULL);
+
+ g_byte_array_unref ((GByteArray *)self);
+}
+
+MbimTlvType
+mbim_tlv_get_tlv_type (const MbimTlv *self)
+{
+ g_return_val_if_fail (self != NULL, MBIM_TLV_TYPE_INVALID);
+
+ return MBIM_TLV_GET_TLV_TYPE (self);
+}
+
+const guint8 *
+mbim_tlv_get_tlv_data (const MbimTlv *self,
+ guint32 *out_length)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (out_length != NULL, NULL);
+
+ *out_length = MBIM_TLV_GET_DATA_LENGTH (self);
+ return MBIM_TLV_FIELD_DATA (self);
+}
+
+const guint8 *
+mbim_tlv_get_raw (const MbimTlv *self,
+ guint32 *length,
+ GError **error)
+{
+ g_return_val_if_fail (self != NULL, NULL);
+ g_return_val_if_fail (length != NULL, NULL);
+
+ if (!self->data || !self->len) {
+ g_set_error_literal (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED, "TLV is invalid");
+ return NULL;
+ }
+
+ *length = (guint32) self->len;
+ return self->data;
+}
+
+/*****************************************************************************/
+
+MbimTlv *
+mbim_tlv_string_new (const gchar *str,
+ GError **error)
+{
+ g_autofree gunichar2 *utf16 = NULL;
+ guint32 utf16_bytes = 0;
+
+ /* Convert the string from UTF-8 to UTF-16HE */
+ if (str && str[0]) {
+ glong items_written = 0;
+
+ utf16 = g_utf8_to_utf16 (str,
+ -1,
+ NULL, /* bytes */
+ &items_written, /* gunichar2 */
+ error);
+ if (!utf16)
+ return NULL;
+
+ utf16_bytes = items_written * 2;
+
+ /* For BE systems, convert from BE to LE */
+ if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+ guint i;
+
+ for (i = 0; i < items_written; i++)
+ utf16[i] = GUINT16_TO_LE (utf16[i]);
+ }
+ }
+
+ return mbim_tlv_new (MBIM_TLV_TYPE_WCHAR_STR, (const guint8 *)utf16, utf16_bytes);
+}
+
+gchar *
+mbim_tlv_string_get (const MbimTlv *self,
+ GError **error)
+{
+ const gunichar2 *utf16 = NULL;
+ g_autofree gunichar2 *utf16d = NULL;
+ guint32 size;
+
+ g_return_val_if_fail (self != NULL, NULL);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_WCHAR_STR) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a WCHAR string");
+ return NULL;
+ }
+
+ utf16 = (const gunichar2 *) MBIM_TLV_FIELD_DATA (self);
+ size = MBIM_TLV_GET_DATA_LENGTH (self);
+
+ /* For BE systems, convert from LE to BE */
+ if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+ guint i;
+
+ utf16d = (gunichar2 *) g_malloc (size);
+ for (i = 0; i < (size / 2); i++)
+ utf16d[i] = GUINT16_FROM_LE (utf16[i]);
+ }
+
+ return g_utf16_to_utf8 (utf16d ? utf16d : utf16,
+ size / 2,
+ NULL,
+ NULL,
+ error);
+}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_guint16_array_get (const MbimTlv *self,
+ guint32 *array_size,
+ guint16 **array,
+ GError **error)
+{
+ guint32 size;
+ g_autofree guint16 *tmp = NULL;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_UINT16_TBL) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a UINT16 array");
+ return FALSE;
+ }
+
+ size = MBIM_TLV_GET_DATA_LENGTH (self);
+ if (size % 2 != 0) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "Invalid TLV data length, must be multiple of 2: %u",
+ size);
+ return FALSE;
+ }
+
+ if (size) {
+ tmp = (guint16 *) g_memdup ((const guint16 *)MBIM_TLV_FIELD_DATA (self), size);
+
+ /* For BE systems, convert from LE to BE */
+ if (G_BYTE_ORDER == G_BIG_ENDIAN) {
+ guint i;
+
+ for (i = 0; i < (size / 2); i++)
+ tmp[i] = GUINT16_FROM_LE (tmp[i]);
+ }
+ }
+
+ if (array_size)
+ *array_size = size / 2;
+ if (array)
+ *array = g_steal_pointer (&tmp);
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_wake_command_get (const MbimTlv *self,
+ const MbimUuid **service,
+ guint32 *cid,
+ guint32 *payload_size,
+ guint8 **payload,
+ GError **error)
+{
+ const guint8 *tlv_data;
+ guint32 tlv_data_size;
+ guint32 buffer_offset;
+ guint32 buffer_size;
+ guint32 offset = 0;
+ guint64 required_size;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_WAKE_COMMAND) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a wake command");
+ return FALSE;
+ }
+
+ tlv_data = mbim_tlv_get_tlv_data (self, &tlv_data_size);
+ tlv_data_size = MBIM_TLV_GET_DATA_LENGTH (self);
+
+ required_size = 28;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV (%u < %" G_GUINT64_FORMAT ")",
+ tlv_data_size, required_size);
+ return FALSE;
+ }
+
+ if (service)
+ *service = (const MbimUuid *) G_STRUCT_MEMBER_P (tlv_data, offset);
+ offset += 16;
+
+ if (cid)
+ *cid = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (buffer_size > 0) {
+ if (buffer_offset != required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV: invalid payload offset (%u)",
+ buffer_offset);
+ return FALSE;
+ }
+
+ required_size += buffer_size;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake command TLV payload (%u bytes) (%u < %" G_GUINT64_FORMAT ")",
+ buffer_size, tlv_data_size, required_size);
+ return FALSE;
+ }
+ }
+
+ if (payload_size)
+ *payload_size = buffer_size;
+ if (payload)
+ *payload = (buffer_size ? g_memdup (&tlv_data[offset], buffer_size) : NULL);
+
+ return TRUE;
+}
+
+/*****************************************************************************/
+
+gboolean
+mbim_tlv_wake_packet_get (const MbimTlv *self,
+ guint32 *filter_id,
+ guint32 *original_packet_size,
+ guint32 *packet_size,
+ guint8 **packet,
+ GError **error)
+{
+
+ const guint8 *tlv_data;
+ guint32 tlv_data_size;
+ guint32 buffer_offset;
+ guint32 buffer_size;
+ guint32 offset = 0;
+ guint64 required_size;
+
+ g_return_val_if_fail (self != NULL, FALSE);
+
+ if (MBIM_TLV_GET_TLV_TYPE (self) != MBIM_TLV_TYPE_WAKE_PACKET) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "TLV is not a wake packet");
+ return FALSE;
+ }
+
+ tlv_data = mbim_tlv_get_tlv_data (self, &tlv_data_size);
+ tlv_data_size = MBIM_TLV_GET_DATA_LENGTH (self);
+
+ required_size = 16;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV (%u < %" G_GUINT64_FORMAT ")",
+ tlv_data_size, required_size);
+ return FALSE;
+ }
+
+ if (filter_id)
+ *filter_id = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (original_packet_size)
+ *original_packet_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_offset = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ buffer_size = GUINT32_FROM_LE (G_STRUCT_MEMBER (guint32, tlv_data, offset));
+ offset += 4;
+
+ if (buffer_size > 0) {
+ if (buffer_offset != offset) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV: invalid saved packet offset (%u)",
+ buffer_offset);
+ return FALSE;
+ }
+
+ required_size += buffer_size;
+ if (tlv_data_size < required_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_MESSAGE,
+ "cannot read wake packet TLV payload (%u bytes) (%u < %" G_GUINT64_FORMAT ")",
+ buffer_size, tlv_data_size, required_size);
+ return FALSE;
+ }
+ }
+
+ if (packet_size)
+ *packet_size = buffer_size;
+ if (packet)
+ *packet = (buffer_size ? g_memdup (&tlv_data[offset], buffer_size) : NULL);
+
+ return TRUE;
+}
diff --git a/src/libmbim-glib/mbim-tlv.h b/src/libmbim-glib/mbim-tlv.h
new file mode 100644
index 0000000..64b9c8b
--- /dev/null
+++ b/src/libmbim-glib/mbim-tlv.h
@@ -0,0 +1,315 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ * libmbim-glib -- GLib/GIO based library to control MBIM devices
+ *
+ * Copyright (C) 2021 Aleksander Morgado <aleksander@aleksander.es>
+ * Copyright (C) 2021 Intel Corporation
+ */
+
+#ifndef _LIBMBIM_GLIB_MBIM_TLV_H_
+#define _LIBMBIM_GLIB_MBIM_TLV_H_
+
+#if !defined (__LIBMBIM_GLIB_H_INSIDE__) && !defined (LIBMBIM_GLIB_COMPILATION)
+#error "Only <libmbim-glib.h> can be included directly."
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "mbim-uuid.h"
+
+G_BEGIN_DECLS
+
+/**
+ * SECTION:mbim-tlv
+ * @title: MbimTlv
+ * @short_description: A variable-sized data structure specified in Microsoft
+ * MBIM extension v3.0.
+ *
+ * The #MbimTlv structure is capable of exchanging a wide range of information
+ * between an MBIM host and an MBIM device.
+ *
+ * CID payloads for requests, responses, and/or notifications may contain zero
+ * or more unnamed and optional Information Elements (IE) encoded as #MbimTlv
+ * fields.
+ */
+
+/**
+ * MbimTlv:
+ *
+ * An opaque type representing a MBIM TLV.
+ *
+ * Since: 1.28
+ */
+typedef struct _MbimTlv MbimTlv;
+
+GType mbim_tlv_get_type (void) G_GNUC_CONST;
+#define MBIM_TYPE_TLV (mbim_tlv_get_type ())
+
+/*****************************************************************************/
+/* Generic TLV interface */
+
+/**
+ * MbimTlvType:
+ * @MBIM_TLV_TYPE_INVALID: Invalid TLV type.
+ * @MBIM_TLV_TYPE_UE_POLICITES: UE policies.
+ * @MBIM_TLV_TYPE_SINGLE_NSSAI: Single NSSAI.
+ * @MBIM_TLV_TYPE_ALLOWED_NSSAI: Allowed NSSAI.
+ * @MBIM_TLV_TYPE_CFG_NSSAI: Configured NSSAI.
+ * @MBIM_TLV_TYPE_DFLT_CFG_NSSAI: Default configured NSSAI.
+ * @MBIM_TLV_TYPE_PRECFG_DFLT_CFG_NSSAI: Preconfigured default configured NSSAI.
+ * @MBIM_TLV_TYPE_REJ_NSSAI: Rejected NSSAI.
+ * @MBIM_TLV_TYPE_LADN: Local Area Data Network (LADN).
+ * @MBIM_TLV_TYPE_TAI: Tracking Area Identity (TAI).
+ * @MBIM_TLV_TYPE_WCHAR_STR: WCHAR string.
+ * @MBIM_TLV_TYPE_UINT16_TBL: Array of 1 or more @guint16 entries.
+ * @MBIM_TLV_TYPE_EAP_PACKET: Extensible Authentication Protocol packet.
+ * @MBIM_TLV_TYPE_PCO: Protocol Configuration Option (PCO).
+ * @MBIM_TLV_TYPE_ROUTE_SELECTION_DESCRIPTORS: One or more route selection descriptors.
+ * @MBIM_TLV_TYPE_TRAFFIC_PARAMETERS: A traffic parameters record.
+ * @MBIM_TLV_TYPE_WAKE_COMMAND: Wake command.
+ * @MBIM_TLV_TYPE_WAKE_PACKET: Wake packet.
+ *
+ * Type of the MBIM TLV.
+ *
+ * Since: 1.28
+ */
+typedef enum {
+ MBIM_TLV_TYPE_INVALID = 0,
+ MBIM_TLV_TYPE_UE_POLICITES = 1,
+ MBIM_TLV_TYPE_SINGLE_NSSAI = 2,
+ MBIM_TLV_TYPE_ALLOWED_NSSAI = 3,
+ MBIM_TLV_TYPE_CFG_NSSAI = 4,
+ MBIM_TLV_TYPE_DFLT_CFG_NSSAI = 5,
+ MBIM_TLV_TYPE_PRECFG_DFLT_CFG_NSSAI = 6,
+ MBIM_TLV_TYPE_REJ_NSSAI = 7,
+ MBIM_TLV_TYPE_LADN = 8,
+ MBIM_TLV_TYPE_TAI = 9,
+ MBIM_TLV_TYPE_WCHAR_STR = 10,
+ MBIM_TLV_TYPE_UINT16_TBL = 11,
+ MBIM_TLV_TYPE_EAP_PACKET = 12,
+ MBIM_TLV_TYPE_PCO = 13,
+ MBIM_TLV_TYPE_ROUTE_SELECTION_DESCRIPTORS = 14,
+ MBIM_TLV_TYPE_TRAFFIC_PARAMETERS = 15,
+ MBIM_TLV_TYPE_WAKE_COMMAND = 16,
+ MBIM_TLV_TYPE_WAKE_PACKET = 17,
+} MbimTlvType;
+
+/**
+ * mbim_tlv_new:
+ * @type: a #MbimTlvType.
+ * @data: contents of the TLV.
+ * @data_length: length of the message.
+ *
+ * Create a #MbimTlv with the given contents.
+ *
+ * Returns: (transfer full): a newly created #MbimTlv, which should be freed with mbim_tlv_unref().
+ *
+ * Since: 1.28
+ */
+MbimTlv *mbim_tlv_new (MbimTlvType type,
+ const guint8 *data,
+ guint32 data_length);
+
+/**
+ * mbim_tlv_dup:
+ * @self: a #MbimTlv to duplicate.
+ *
+ * Create a #MbimTlv with the same contents as @self.
+ *
+ * Returns: (transfer full): a newly created #MbimTlv, which should be freed with mbim_tlv_unref().
+ *
+ * Since: 1.28
+ */
+MbimTlv *mbim_tlv_dup (const MbimTlv *self);
+
+/**
+ * mbim_tlv_ref:
+ * @self: a #MbimTlv.
+ *
+ * Atomically increments the reference count of @self by one.
+ *
+ * Returns: (transfer full): the new reference to @self.
+ *
+ * Since: 1.28
+ */
+MbimTlv *mbim_tlv_ref (MbimTlv *self);
+
+/**
+ * mbim_tlv_unref:
+ * @self: a #MbimTlv.
+ *
+ * Atomically decrements the reference count of @self by one.
+ * If the reference count drops to 0, @self is completely disposed.
+ *
+ * Since: 1.28
+ */
+void mbim_tlv_unref (MbimTlv *self);
+
+/**
+ * mbim_tlv_get_raw:
+ * @self: a #MbimTlv.
+ * @length: (out): return location for the size of the output buffer.
+ * @error: return location for error or %NULL.
+ *
+ * Gets the whole raw data buffer of the #MbimTlv.
+ *
+ * Returns: The raw data buffer, or #NULL if @error is set.
+ *
+ * Since: 1.28
+ */
+const guint8 *mbim_tlv_get_raw (const MbimTlv *self,
+ guint32 *length,
+ GError **error);
+
+/**
+ * mbim_tlv_get_tlv_type:
+ * @self: a #MbimTlv.
+ *
+ * Gets the message type.
+ *
+ * Returns: a #MbimTlvType.
+ *
+ * Since: 1.28
+ */
+MbimTlvType mbim_tlv_get_tlv_type (const MbimTlv *self);
+
+/**
+ * mbim_tlv_get_tlv_data:
+ * @self: a #MbimTlv.
+ * @out_length: (out): return location for the size of the output buffer.
+ *
+ * Gets the TLV raw data.
+ *
+ * Returns: (transfer none): The raw data buffer, or #NULL if empty.
+ *
+ * Since: 1.28
+ */
+const guint8 *mbim_tlv_get_tlv_data (const MbimTlv *self,
+ guint32 *out_length);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (MbimTlv, mbim_tlv_unref)
+
+/*****************************************************************************/
+/* String TLV type helpers */
+
+/**
+ * mbim_tlv_string_new:
+ * @str: a string.
+ * @error: return location for error or %NULL.
+ *
+ * Create a #MbimTlv of type %MBIM_TLV_TYPE_WCHAR_STR with the given contents.
+ *
+ * Returns: (transfer full): a newly created #MbimTlv which should be freed with mbim_tlv_unref(), or %NULL if @error is set.
+ *
+ * Since: 1.28
+ */
+MbimTlv *mbim_tlv_string_new (const gchar *str,
+ GError **error);
+
+/**
+ * mbim_tlv_string_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_WCHAR_STR.
+ * @error: return location for error or %NULL.
+ *
+ * Get a string with the contents in the #MbimTlv.
+ *
+ * Returns: (transfer full): a newly created string, which should be freed with g_free(), or %NULL if @error is set.
+ *
+ * Since: 1.28
+ */
+gchar *mbim_tlv_string_get (const MbimTlv *self,
+ GError **error);
+
+/*****************************************************************************/
+/* guint16 array type helpers */
+
+/**
+ * mbim_tlv_guint16_array_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_UINT16_TBL.
+ * @array_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @array: (out)(optional)(transfer full)(type guint16): return location for a
+ * newly allocated array of #guint16 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ * @error: return location for error or %NULL.
+ *
+ * Get an array of #guint16 values with the contents in the #MbimTlv.
+ *
+ * The method may return a successful return even with on empty arrays (i.e.
+ * with @array_size set to 0 and @array set to %NULL).
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_guint16_array_get (const MbimTlv *self,
+ guint32 *array_size,
+ guint16 **array,
+ GError **error);
+
+/*****************************************************************************/
+/* wake command type helpers */
+
+/**
+ * mbim_tlv_wake_command_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_WAKE_COMMAND.
+ * @service: (out)(optional)(transfer none): return location for a #MbimUuid
+ * specifying the service that triggered the wake.
+ * @cid: (out)(optional)(transfer none): return location for the command id that
+ * triggered the wake.
+ * @payload_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @payload: (out)(optional)(transfer full)(type guint8): return location for a
+ * newly allocated array of #guint8 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ *
+ * Get the contents of a wake command TLV.
+ *
+ * The method may return a successful return even with on empty payload (i.e.
+ * with @payload_size set to 0 and @payload set to %NULL).
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_wake_command_get (const MbimTlv *self,
+ const MbimUuid **service,
+ guint32 *cid,
+ guint32 *payload_size,
+ guint8 **payload,
+ GError **error);
+
+/*****************************************************************************/
+/* wake packet type helpers */
+
+/**
+ * mbim_tlv_wake_packet_get:
+ * @self: a #MbimTlv of type %MBIM_TLV_TYPE_WAKE_PACKET.
+ * @filter_id: (out)(optional)(transfer none): return location for a #guint32
+ * specifying the filter id.
+ * @original_packet_size: (out)(optional)(transfer none): return location for a
+ * #guint32, or %NULL if the field is not needed.
+ * @packet_size: (out)(optional)(transfer none): return location for a #guint32,
+ * or %NULL if the field is not needed.
+ * @packet: (out)(optional)(transfer full)(type guint8): return location for a
+ * newly allocated array of #guint8 values, or %NULL if the field is not
+ * needed. Free the returned value with g_free().
+ *
+ * Get the contents of a wake packet TLV.
+ *
+ * Returns: %TRUE if on success, %FALSE if @error is set.
+ *
+ * Since: 1.28
+ */
+gboolean mbim_tlv_wake_packet_get (const MbimTlv *self,
+ guint32 *filter_id,
+ guint32 *original_packet_size,
+ guint32 *packet_size,
+ guint8 **packet,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* _LIBMBIM_GLIB_MBIM_TLV_H_ */
diff --git a/src/libmbim-glib/mbim-uuid.c b/src/libmbim-glib/mbim-uuid.c
index dcadb27..4e90a37 100644
--- a/src/libmbim-glib/mbim-uuid.c
+++ b/src/libmbim-glib/mbim-uuid.c
@@ -510,6 +510,46 @@
.e = { 0x03, 0x3C, 0x39, 0xF6, 0x0D, 0xB9 }
};
+static const MbimUuid uuid_context_type_admin = {
+ .a = { 0x5F, 0x7E, 0x4C, 0x2E },
+ .b = { 0xE8, 0x0B },
+ .c = { 0x40, 0xA9 },
+ .d = { 0xA2, 0x39 },
+ .e = { 0xF0, 0xAB, 0xCF, 0xD1, 0x1F, 0x4B }
+};
+
+static const MbimUuid uuid_context_type_app = {
+ .a = { 0x74, 0xD8, 0x8A, 0x3D },
+ .b = { 0xDF, 0xBD },
+ .c = { 0x47, 0x99 },
+ .d = { 0x9A, 0x8C },
+ .e = { 0x73, 0x10, 0xA3, 0x7B, 0xB2, 0xEE }
+};
+
+static const MbimUuid uuid_context_type_xcap = {
+ .a = { 0x50, 0xD3, 0x78, 0xA7 },
+ .b = { 0xBA, 0xA5 },
+ .c = { 0x4A, 0x50 },
+ .d = { 0xB8, 0x72 },
+ .e = { 0x3F, 0xE5, 0xBB, 0x46, 0x34, 0x11 }
+};
+
+static const MbimUuid uuid_context_type_tethering = {
+ .a = { 0x5E, 0x4E, 0x06, 0x01 },
+ .b = { 0x48, 0xDC },
+ .c = { 0x4E, 0x2B },
+ .d = { 0xAC, 0xB8 },
+ .e = { 0x08, 0xB4, 0x01, 0x6B, 0xBA, 0xAC }
+};
+
+static const MbimUuid uuid_context_type_emergency_calling = {
+ .a = { 0x5F, 0x41, 0xAD, 0xB8 },
+ .b = { 0x20, 0x4E },
+ .c = { 0x4D, 0x31 },
+ .d = { 0x9D, 0xA8 },
+ .e = { 0xB3, 0xC9, 0x70, 0xE3, 0x60, 0xF2 }
+};
+
const MbimUuid *
mbim_uuid_from_context_type (MbimContextType context_type)
{
@@ -536,6 +576,16 @@
return &uuid_context_type_mms;
case MBIM_CONTEXT_TYPE_LOCAL:
return &uuid_context_type_local;
+ case MBIM_CONTEXT_TYPE_ADMIN:
+ return &uuid_context_type_admin;
+ case MBIM_CONTEXT_TYPE_APP:
+ return &uuid_context_type_app;
+ case MBIM_CONTEXT_TYPE_XCAP:
+ return &uuid_context_type_xcap;
+ case MBIM_CONTEXT_TYPE_TETHERING:
+ return &uuid_context_type_tethering;
+ case MBIM_CONTEXT_TYPE_EMERGENCY_CALLING:
+ return &uuid_context_type_emergency_calling;
default:
g_assert_not_reached ();
}
@@ -571,5 +621,20 @@
if (mbim_uuid_cmp (uuid, &uuid_context_type_local))
return MBIM_CONTEXT_TYPE_LOCAL;
+ if (mbim_uuid_cmp (uuid, &uuid_context_type_admin))
+ return MBIM_CONTEXT_TYPE_ADMIN;
+
+ if (mbim_uuid_cmp (uuid, &uuid_context_type_app))
+ return MBIM_CONTEXT_TYPE_APP;
+
+ if (mbim_uuid_cmp (uuid, &uuid_context_type_xcap))
+ return MBIM_CONTEXT_TYPE_XCAP;
+
+ if (mbim_uuid_cmp (uuid, &uuid_context_type_tethering))
+ return MBIM_CONTEXT_TYPE_TETHERING;
+
+ if (mbim_uuid_cmp (uuid, &uuid_context_type_emergency_calling))
+ return MBIM_CONTEXT_TYPE_EMERGENCY_CALLING;
+
return MBIM_CONTEXT_TYPE_INVALID;
}
diff --git a/src/libmbim-glib/mbim-uuid.h b/src/libmbim-glib/mbim-uuid.h
index 0ffed7c..fa62d86 100644
--- a/src/libmbim-glib/mbim-uuid.h
+++ b/src/libmbim-glib/mbim-uuid.h
@@ -328,6 +328,17 @@
#define MBIM_UUID_MS_BASIC_CONNECT_EXTENSIONS mbim_uuid_from_service (MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS)
/**
+ * MBIM_UUID_MS_UICC_LOW_LEVEL_ACCESS:
+ *
+ * Get the UUID of the %MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS service.
+ *
+ * Returns: (transfer none): a #MbimUuid.
+ *
+ * Since: 1.26
+ */
+#define MBIM_UUID_MS_UICC_LOW_LEVEL_ACCESS mbim_uuid_from_service (MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS)
+
+/**
* mbim_service_lookup_name:
* @service: a MbimService or custom service.
*
@@ -413,30 +424,50 @@
* MbimContextType:
* @MBIM_CONTEXT_TYPE_INVALID: Invalid context type.
* @MBIM_CONTEXT_TYPE_NONE: Context not yet provisioned.
- * @MBIM_CONTEXT_TYPE_INTERNET: Connection to the Internet.
- * @MBIM_CONTEXT_TYPE_VPN: Connection to a VPN.
- * @MBIM_CONTEXT_TYPE_VOICE: Connection to a VoIP service.
- * @MBIM_CONTEXT_TYPE_VIDEO_SHARE: Connection to a video sharing service.
- * @MBIM_CONTEXT_TYPE_PURCHASE: Connection to an over-the-air activation site.
- * @MBIM_CONTEXT_TYPE_IMS: Connection to IMS.
- * @MBIM_CONTEXT_TYPE_MMS: Connection to MMS.
- * @MBIM_CONTEXT_TYPE_LOCAL: A local.
+ * @MBIM_CONTEXT_TYPE_INTERNET: Context representing a connection to the
+ * Internet.
+ * @MBIM_CONTEXT_TYPE_VPN: Context representing a connection to a a private
+ * network (e.g. VPN to a corporate network).
+ * @MBIM_CONTEXT_TYPE_VOICE: Context representing a connection to a VoIP service.
+ * @MBIM_CONTEXT_TYPE_VIDEO_SHARE: Context representing a connection to a video
+ * sharing service.
+ * @MBIM_CONTEXT_TYPE_PURCHASE: Context representing a connection to an
+ * OTA (over-the-air) activation site.
+ * @MBIM_CONTEXT_TYPE_IMS: Context representing a connection to IMS.
+ * @MBIM_CONTEXT_TYPE_MMS: Context representing a connection to MMS.
+ * @MBIM_CONTEXT_TYPE_LOCAL: Context representing a connection which is
+ * terminated at the device. No IP traffic sent over the air.
+ * @MBIM_CONTEXT_TYPE_ADMIN: Context used for administrative purposes, such as
+ * device management (MS MBIMEx). Since 1.28.
+ * @MBIM_CONTEXT_TYPE_APP: Context used for certain applications allowed by
+ * mobile operators (MS MBIMEx). Since 1.28.
+ * @MBIM_CONTEXT_TYPE_XCAP: Context used for XCAP provisioning on IMS services
+ * (MS MBIMEx). Since 1.28.
+ * @MBIM_CONTEXT_TYPE_TETHERING: Context used for mobile hotspot tethering
+ * (MS MBIMEx). Since 1.28.
+ * @MBIM_CONTEXT_TYPE_EMERGENCY_CALLING: Context used for IMS emergency calling
+ * (MS MBIMEx). Since 1.28.
*
* Enumeration of the generic MBIM context types.
*
* Since: 1.0
*/
typedef enum { /*< since=1.0 >*/
- MBIM_CONTEXT_TYPE_INVALID = 0,
- MBIM_CONTEXT_TYPE_NONE = 1,
- MBIM_CONTEXT_TYPE_INTERNET = 2,
- MBIM_CONTEXT_TYPE_VPN = 3,
- MBIM_CONTEXT_TYPE_VOICE = 4,
- MBIM_CONTEXT_TYPE_VIDEO_SHARE = 5,
- MBIM_CONTEXT_TYPE_PURCHASE = 6,
- MBIM_CONTEXT_TYPE_IMS = 7,
- MBIM_CONTEXT_TYPE_MMS = 8,
- MBIM_CONTEXT_TYPE_LOCAL = 9,
+ MBIM_CONTEXT_TYPE_INVALID = 0,
+ MBIM_CONTEXT_TYPE_NONE = 1,
+ MBIM_CONTEXT_TYPE_INTERNET = 2,
+ MBIM_CONTEXT_TYPE_VPN = 3,
+ MBIM_CONTEXT_TYPE_VOICE = 4,
+ MBIM_CONTEXT_TYPE_VIDEO_SHARE = 5,
+ MBIM_CONTEXT_TYPE_PURCHASE = 6,
+ MBIM_CONTEXT_TYPE_IMS = 7,
+ MBIM_CONTEXT_TYPE_MMS = 8,
+ MBIM_CONTEXT_TYPE_LOCAL = 9,
+ MBIM_CONTEXT_TYPE_ADMIN = 10,
+ MBIM_CONTEXT_TYPE_APP = 11,
+ MBIM_CONTEXT_TYPE_XCAP = 12,
+ MBIM_CONTEXT_TYPE_TETHERING = 13,
+ MBIM_CONTEXT_TYPE_EMERGENCY_CALLING = 14,
} MbimContextType;
/**
@@ -463,15 +494,6 @@
*/
MbimContextType mbim_uuid_to_context_type (const MbimUuid *uuid);
-/**
- * MBIM_UUID_MS_UICC_LOW_LEVEL_ACCESS:
- *
- * Get the UUID of the %MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS service.
- *
- * Returns: (transfer none): a #MbimUuid.
- */
-#define MBIM_UUID_MS_UICC_LOW_LEVEL_ACCESS mbim_uuid_from_service (MBIM_SERVICE_MS_UICC_LOW_LEVEL_ACCESS)
-
G_END_DECLS
#endif /* _LIBMBIM_GLIB_MBIM_UUID_H_ */
diff --git a/src/libmbim-glib/meson.build b/src/libmbim-glib/meson.build
index 1202ca2..7574f5b 100644
--- a/src/libmbim-glib/meson.build
+++ b/src/libmbim-glib/meson.build
@@ -10,6 +10,7 @@
'mbim-enums.h',
'mbim-message.h',
'mbim-uuid.h',
+ 'mbim-tlv.h',
)
subdir('generated')
@@ -24,13 +25,13 @@
install_headers(
headers,
- subdir: mbim_glib_include_subdir,
+ install_dir: mbim_glib_pkgincludedir,
)
common_c_flags = [
'-DLIBMBIM_GLIB_COMPILATION',
'-DG_LOG_DOMAIN="Mbim"',
- '-DLIBEXEC_PATH="@0@"'.format(join_paths(mbim_prefix, mbim_libexecdir)),
+ '-DLIBEXEC_PATH="@0@"'.format(mbim_prefix / mbim_libexecdir),
]
sources = files(
@@ -44,6 +45,7 @@
'mbim-proxy-helpers.c',
'mbim-utils.c',
'mbim-uuid.c',
+ 'mbim-tlv.c',
)
deps = [
@@ -75,7 +77,8 @@
install_dir: mbim_glib_pkgincludedir,
)
-symbol_map = join_paths(meson.current_source_dir(), 'symbol.map')
+symbol_map = meson.current_source_dir() / 'symbol.map'
+ldflags = cc.get_supported_link_arguments('-Wl,--version-script,@0@'.format(symbol_map))
libmbim_glib = library(
libname,
@@ -83,7 +86,7 @@
sources: version_header,
include_directories: top_inc,
dependencies: generated_dep,
- link_args: '-Wl,--version-script,' + symbol_map,
+ link_args: ldflags,
link_depends: symbol_map,
link_whole: libmbim_glib_core,
install: true,
diff --git a/src/libmbim-glib/test/meson.build b/src/libmbim-glib/test/meson.build
index 3c33bdb..a501cfe 100644
--- a/src/libmbim-glib/test/meson.build
+++ b/src/libmbim-glib/test/meson.build
@@ -11,14 +11,12 @@
'proxy-helpers',
]
-random_number = mbim_minor_version + meson.version().split('.').get(1).to_int()
-
-test_env = environment()
-test_env.set('G_DEBUG', 'gc-friendly')
-test_env.set('MALLOC_CHECK_', '2')
-test_env.set('MALLOC_PERTURB_', (random_number % 256).to_string())
-test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
-test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
+test_env = {
+ 'G_DEBUG': 'gc-friendly',
+ 'MALLOC_CHECK_': '2',
+ 'G_TEST_SRCDIR': meson.current_source_dir(),
+ 'G_TEST_BUILDDIR': meson.current_build_dir(),
+}
foreach test_unit: test_units
test_name = 'test-' + test_unit
diff --git a/src/libmbim-glib/test/test-message-builder.c b/src/libmbim-glib/test/test-message-builder.c
index 45442d7..df50bc1 100644
--- a/src/libmbim-glib/test/test-message-builder.c
+++ b/src/libmbim-glib/test/test-message-builder.c
@@ -18,8 +18,8 @@
#include "mbim-stk.h"
#include "mbim-dss.h"
#include "mbim-ms-host-shutdown.h"
+#include "mbim-ms-basic-connect-extensions.h"
-#if defined ENABLE_TEST_MESSAGE_TRACES
static void
test_message_trace (const guint8 *computed,
guint32 computed_size,
@@ -55,12 +55,28 @@
g_free (message_str);
g_free (expected_str);
}
-#else
-#define test_message_trace(...)
-#endif
static void
-test_message_builder_basic_connect_pin_set_raw (void)
+test_message_printable (MbimMessage *message,
+ guint8 mbimex_version_major,
+ guint8 mbimex_version_minor)
+{
+ g_autofree gchar *printable = NULL;
+
+ printable = mbim_message_get_printable_full (message,
+ mbimex_version_major,
+ mbimex_version_minor,
+ "---- ",
+ FALSE,
+ NULL);
+ g_print ("\n"
+ "Message printable:\n"
+ "%s\n",
+ printable);
+}
+
+static void
+test_basic_connect_pin_set_raw (void)
{
MbimMessage *message;
MbimMessageCommandBuilder *builder;
@@ -120,11 +136,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_pin_set (void)
+test_basic_connect_pin_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -181,11 +199,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_connect_set_raw (void)
+test_basic_connect_connect_set_raw (void)
{
MbimMessage *message;
MbimMessageCommandBuilder *builder;
@@ -262,11 +282,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_connect_set (void)
+test_basic_connect_connect_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -341,11 +363,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_service_activation_set (void)
+test_basic_connect_service_activation_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -398,11 +422,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_device_service_subscribe_list_set (void)
+test_basic_connect_device_service_subscribe_list_set (void)
{
GError *error = NULL;
MbimEventEntry **entries;
@@ -488,11 +514,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_ussd_set (void)
+test_ussd_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -558,11 +586,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_auth_akap_query (void)
+test_auth_akap_query (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -638,11 +668,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_stk_pac_set (void)
+test_stk_pac_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -709,11 +741,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_stk_terminal_response_set (void)
+test_stk_terminal_response_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -780,11 +814,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_stk_envelope_set (void)
+test_stk_envelope_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -856,11 +892,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_ip_packet_filters_set_none (void)
+test_basic_connect_ip_packet_filters_set_none (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -908,11 +946,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_ip_packet_filters_set_one (void)
+test_basic_connect_ip_packet_filters_set_one (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -993,13 +1033,15 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
mbim_packet_filter_array_free (filters);
}
static void
-test_message_builder_basic_connect_ip_packet_filters_set_two (void)
+test_basic_connect_ip_packet_filters_set_two (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -1107,13 +1149,15 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
mbim_packet_filter_array_free (filters);
}
static void
-test_message_builder_dss_connect_set (void)
+test_dss_connect_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -1177,11 +1221,13 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
}
static void
-test_message_builder_basic_connect_multicarrier_providers_set (void)
+test_basic_connect_multicarrier_providers_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -1284,12 +1330,14 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
mbim_message_unref (message);
mbim_provider_array_free (providers);
}
static void
-test_message_builder_ms_host_shutdown_notify_set (void)
+test_ms_host_shutdown_notify_set (void)
{
GError *error = NULL;
MbimMessage *message;
@@ -1334,6 +1382,332 @@
g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+ test_message_printable (message, 1, 0);
+
+ mbim_message_unref (message);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_set_0_unnamed_tlvs (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ const guint8 expected_message [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x00, /* type */
+ 0x44, 0x00, 0x00, 0x00, /* length */
+ 0x01, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x01, 0x00, 0x00, 0x00, /* command_type */
+ 0x14, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* no unnamed TLVs */
+ };
+
+ message = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_set_new (
+ MBIM_MICO_MODE_DISABLED,
+ MBIM_DRX_CYCLE_NOT_SPECIFIED,
+ MBIM_LADN_INFO_NOT_NEEDED,
+ MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY,
+ TRUE,
+ NULL, /* 0 unnamed ies */
+ &error));
+ g_assert_no_error (error);
+ g_assert (message != NULL);
+
+ mbim_message_set_transaction_id (message, 1);
+
+ test_message_trace ((const guint8 *)((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ expected_message,
+ sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_get_transaction_id (message), ==, 1);
+ g_assert_cmpuint (mbim_message_get_message_type (message), ==, MBIM_MESSAGE_TYPE_COMMAND);
+ g_assert_cmpuint (mbim_message_get_message_length (message), ==, sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_command_get_service (message), ==, MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS);
+ g_assert_cmpuint (mbim_message_command_get_cid (message), ==, MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS);
+ g_assert_cmpuint (mbim_message_command_get_command_type (message), ==, MBIM_MESSAGE_COMMAND_TYPE_SET);
+
+ g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
+ g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+
+ test_message_printable (message, 3, 0);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_set_1_unnamed_tlv (void)
+{
+ MbimTlv *tlv;
+ GList *tlv_list = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ const guint8 expected_message [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x00, /* type */
+ 0x58, 0x00, 0x00, 0x00, /* length */
+ 0x01, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x01, 0x00, 0x00, 0x00, /* command_type */
+ 0x28, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ };
+
+ tlv = mbim_tlv_string_new ("Orange", &error);
+ g_assert_no_error (error);
+ g_assert (tlv);
+ tlv_list = g_list_append (tlv_list, tlv);
+
+ message = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_set_new (
+ MBIM_MICO_MODE_DISABLED,
+ MBIM_DRX_CYCLE_NOT_SPECIFIED,
+ MBIM_LADN_INFO_NOT_NEEDED,
+ MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY,
+ TRUE,
+ tlv_list,
+ &error));
+ g_assert_no_error (error);
+ g_assert (message != NULL);
+
+ mbim_message_set_transaction_id (message, 1);
+
+ test_message_trace ((const guint8 *)((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ expected_message,
+ sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_get_transaction_id (message), ==, 1);
+ g_assert_cmpuint (mbim_message_get_message_type (message), ==, MBIM_MESSAGE_TYPE_COMMAND);
+ g_assert_cmpuint (mbim_message_get_message_length (message), ==, sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_command_get_service (message), ==, MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS);
+ g_assert_cmpuint (mbim_message_command_get_cid (message), ==, MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS);
+ g_assert_cmpuint (mbim_message_command_get_command_type (message), ==, MBIM_MESSAGE_COMMAND_TYPE_SET);
+
+ g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
+ g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+
+ g_list_free_full (tlv_list, (GDestroyNotify)mbim_tlv_unref);
+
+ test_message_printable (message, 3, 0);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_set_3_unnamed_tlvs (void)
+{
+ MbimTlv *tlv;
+ GList *tlv_list = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) message = NULL;
+ const guint8 pco[] = {
+ 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B };
+ const guint8 expected_message [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x00, /* type */
+ 0x80, 0x00, 0x00, 0x00, /* length */
+ 0x01, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x01, 0x00, 0x00, 0x00, /* command_type */
+ 0x50, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x02, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, padding 2 */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x61, 0x00, 0x62, 0x00, /* TLV data string */
+ 0x63, 0x00, 0x64, 0x00,
+ 0x65, 0x00, 0x00, 0x00,
+ /* Second unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ /* Third unnamed TLV */
+ 0x0D, 0x00, 0x00, 0x01, /* TLV type MBIM_TLV_TYPE_PCO, padding 1 */
+ 0x0B, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x01, 0x02, 0x03, 0x04, /* TLV data bytes */
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x00,
+ };
+
+ tlv = mbim_tlv_string_new ("abcde", &error);
+ g_assert_no_error (error);
+ g_assert (tlv);
+ tlv_list = g_list_append (tlv_list, tlv);
+
+ tlv = mbim_tlv_string_new ("Orange", &error);
+ g_assert_no_error (error);
+ g_assert (tlv);
+ tlv_list = g_list_append (tlv_list, tlv);
+
+ tlv = mbim_tlv_new (MBIM_TLV_TYPE_PCO, pco, sizeof (pco));
+ g_assert (tlv);
+ tlv_list = g_list_append (tlv_list, tlv);
+
+ message = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_set_new (
+ MBIM_MICO_MODE_DISABLED,
+ MBIM_DRX_CYCLE_NOT_SPECIFIED,
+ MBIM_LADN_INFO_NOT_NEEDED,
+ MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY,
+ TRUE,
+ tlv_list,
+ &error));
+ g_assert_no_error (error);
+ g_assert (message != NULL);
+
+ mbim_message_set_transaction_id (message, 1);
+
+ test_message_trace ((const guint8 *)((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ expected_message,
+ sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_get_transaction_id (message), ==, 1);
+ g_assert_cmpuint (mbim_message_get_message_type (message), ==, MBIM_MESSAGE_TYPE_COMMAND);
+ g_assert_cmpuint (mbim_message_get_message_length (message), ==, sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_command_get_service (message), ==, MBIM_SERVICE_MS_BASIC_CONNECT_EXTENSIONS);
+ g_assert_cmpuint (mbim_message_command_get_cid (message), ==, MBIM_CID_MS_BASIC_CONNECT_EXTENSIONS_REGISTRATION_PARAMETERS);
+ g_assert_cmpuint (mbim_message_command_get_command_type (message), ==, MBIM_MESSAGE_COMMAND_TYPE_SET);
+
+ g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
+ g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+
+ g_list_free_full (tlv_list, (GDestroyNotify)mbim_tlv_unref);
+
+ test_message_printable (message, 3, 0);
+}
+
+static void
+test_ms_basic_connect_v3_connect_set (void)
+{
+ GError *error = NULL;
+ MbimMessage *message;
+ const guint8 expected_message [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x00, /* type */
+ 0x80, 0x00, 0x00, 0x00, /* length */
+ 0x01, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_message */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id */
+ 0x01, 0x00, 0x00, 0x00, /* command_type */
+ 0x50, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* session id */
+ 0x01, 0x00, 0x00, 0x00, /* activation command */
+ 0x00, 0x00, 0x00, 0x00, /* compression */
+ 0x01, 0x00, 0x00, 0x00, /* auth protocol */
+ 0x01, 0x00, 0x00, 0x00, /* ip type */
+ 0x7E, 0x5E, 0x2A, 0x7E, /* context type */
+ 0x4E, 0x6F, 0x72, 0x72,
+ 0x73, 0x6B, 0x65, 0x6E,
+ 0x7E, 0x5E, 0x2A, 0x7E,
+ 0x01, 0x00, 0x00, 0x00, /* media preference */
+ 0x0A, 0x00, 0x00, 0x00, /* access string */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x69, 0x00, 0x6E, 0x00,
+ 0x74, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6E, 0x00,
+ 0x65, 0x00, 0x74, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, /* username */
+ 0x00, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, /* password */
+ 0x00, 0x00, 0x00, 0x00,
+ /* no unnamed TLVs */
+ };
+
+ /* CONNECT set message */
+ message = (mbim_message_ms_basic_connect_v3_connect_set_new (
+ 0x01,
+ MBIM_ACTIVATION_COMMAND_ACTIVATE,
+ MBIM_COMPRESSION_NONE,
+ MBIM_AUTH_PROTOCOL_PAP,
+ MBIM_CONTEXT_IP_TYPE_IPV4,
+ mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
+ MBIM_ACCESS_MEDIA_TYPE_3GPP,
+ "internet",
+ "",
+ "",
+ NULL, /* no unnamed ies */
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (message != NULL);
+ mbim_message_set_transaction_id (message, 1);
+
+ test_message_trace ((const guint8 *)((GByteArray *)message)->data,
+ ((GByteArray *)message)->len,
+ expected_message,
+ sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_get_transaction_id (message), ==, 1);
+ g_assert_cmpuint (mbim_message_get_message_type (message), ==, MBIM_MESSAGE_TYPE_COMMAND);
+ g_assert_cmpuint (mbim_message_get_message_length (message), ==, sizeof (expected_message));
+
+ g_assert_cmpuint (mbim_message_command_get_service (message), ==, MBIM_SERVICE_BASIC_CONNECT);
+ g_assert_cmpuint (mbim_message_command_get_cid (message), ==, MBIM_CID_BASIC_CONNECT_CONNECT);
+ g_assert_cmpuint (mbim_message_command_get_command_type (message), ==, MBIM_MESSAGE_COMMAND_TYPE_SET);
+
+ g_assert_cmpuint (((GByteArray *)message)->len, ==, sizeof (expected_message));
+ g_assert (memcmp (((GByteArray *)message)->data, expected_message, sizeof (expected_message)) == 0);
+
+ test_message_printable (message, 3, 0);
+
mbim_message_unref (message);
}
@@ -1341,23 +1715,31 @@
{
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/pin/set/raw", test_message_builder_basic_connect_pin_set_raw);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/pin/set", test_message_builder_basic_connect_pin_set);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/connect/set/raw", test_message_builder_basic_connect_connect_set_raw);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/connect/set", test_message_builder_basic_connect_connect_set);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/service-activation/set", test_message_builder_basic_connect_service_activation_set);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/device-service-subscribe-list/set", test_message_builder_basic_connect_device_service_subscribe_list_set);
- g_test_add_func ("/libmbim-glib/message/builder/ussd/set", test_message_builder_ussd_set);
- g_test_add_func ("/libmbim-glib/message/builder/auth/akap/query", test_message_builder_auth_akap_query);
- g_test_add_func ("/libmbim-glib/message/builder/stk/pac/set", test_message_builder_stk_pac_set);
- g_test_add_func ("/libmbim-glib/message/builder/stk/terminal-response/set", test_message_builder_stk_terminal_response_set);
- g_test_add_func ("/libmbim-glib/message/builder/stk/envelope/set", test_message_builder_stk_envelope_set);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/ip-packet-filters/set/none", test_message_builder_basic_connect_ip_packet_filters_set_none);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/ip-packet-filters/set/one", test_message_builder_basic_connect_ip_packet_filters_set_one);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/ip-packet-filters/set/two", test_message_builder_basic_connect_ip_packet_filters_set_two);
- g_test_add_func ("/libmbim-glib/message/builder/dss/connect/set", test_message_builder_dss_connect_set);
- g_test_add_func ("/libmbim-glib/message/builder/basic-connect/multicarrier-providers/set", test_message_builder_basic_connect_multicarrier_providers_set);
- g_test_add_func ("/libmbim-glib/message/builder/ms-host-shutdown/notify/set", test_message_builder_ms_host_shutdown_notify_set);
+#define PREFIX "/libmbim-glib/message/builder"
+
+ g_test_add_func (PREFIX "/basic-connect/pin/set/raw", test_basic_connect_pin_set_raw);
+ g_test_add_func (PREFIX "/basic-connect/pin/set", test_basic_connect_pin_set);
+ g_test_add_func (PREFIX "/basic-connect/connect/set/raw", test_basic_connect_connect_set_raw);
+ g_test_add_func (PREFIX "/basic-connect/connect/set", test_basic_connect_connect_set);
+ g_test_add_func (PREFIX "/basic-connect/service-activation/set", test_basic_connect_service_activation_set);
+ g_test_add_func (PREFIX "/basic-connect/device-service-subscribe-list/set", test_basic_connect_device_service_subscribe_list_set);
+ g_test_add_func (PREFIX "/ussd/set", test_ussd_set);
+ g_test_add_func (PREFIX "/auth/akap/query", test_auth_akap_query);
+ g_test_add_func (PREFIX "/stk/pac/set", test_stk_pac_set);
+ g_test_add_func (PREFIX "/stk/terminal-response/set", test_stk_terminal_response_set);
+ g_test_add_func (PREFIX "/stk/envelope/set", test_stk_envelope_set);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/set/none", test_basic_connect_ip_packet_filters_set_none);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/set/one", test_basic_connect_ip_packet_filters_set_one);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/set/two", test_basic_connect_ip_packet_filters_set_two);
+ g_test_add_func (PREFIX "/dss/connect/set", test_dss_connect_set);
+ g_test_add_func (PREFIX "/basic-connect/multicarrier-providers/set", test_basic_connect_multicarrier_providers_set);
+ g_test_add_func (PREFIX "/ms-host-shutdown/notify/set", test_ms_host_shutdown_notify_set);
+ g_test_add_func (PREFIX "/ms-basic-connect-extensions/registration-parameters/set/0-unnamed-tlvs", test_ms_basic_connect_extensions_registration_parameters_set_0_unnamed_tlvs);
+ g_test_add_func (PREFIX "/ms-basic-connect-extensions/registration-parameters/set/1-unnamed-tlv", test_ms_basic_connect_extensions_registration_parameters_set_1_unnamed_tlv);
+ g_test_add_func (PREFIX "/ms-basic-connect-extensions/registration-parameters/set/3-unnamed-tlvs", test_ms_basic_connect_extensions_registration_parameters_set_3_unnamed_tlvs);
+ g_test_add_func (PREFIX "/ms-basic-connect-v3/connect/set", test_ms_basic_connect_v3_connect_set);
+
+#undef PREFIX
return g_test_run ();
}
diff --git a/src/libmbim-glib/test/test-message-parser.c b/src/libmbim-glib/test/test-message-parser.c
index e3e2730..afdab19 100644
--- a/src/libmbim-glib/test/test-message-parser.c
+++ b/src/libmbim-glib/test/test-message-parser.c
@@ -13,12 +13,13 @@
#include "mbim-auth.h"
#include "mbim-stk.h"
#include "mbim-ms-firmware-id.h"
+#include "mbim-ms-basic-connect-extensions.h"
#include "mbim-message.h"
+#include "mbim-tlv.h"
#include "mbim-cid.h"
#include "mbim-common.h"
#include "mbim-error-types.h"
-#if defined ENABLE_TEST_MESSAGE_TRACES
static void
test_message_trace (const guint8 *computed,
guint32 computed_size,
@@ -51,12 +52,28 @@
}
}
}
-#else
-#define test_message_trace(...)
-#endif
static void
-test_message_parser_basic_connect_visible_providers (void)
+test_message_printable (MbimMessage *message,
+ guint8 mbimex_version_major,
+ guint8 mbimex_version_minor)
+{
+ g_autofree gchar *printable = NULL;
+
+ printable = mbim_message_get_printable_full (message,
+ mbimex_version_major,
+ mbimex_version_minor,
+ "---- ",
+ FALSE,
+ NULL);
+ g_print ("\n"
+ "Message printable:\n"
+ "%s\n",
+ printable);
+}
+
+static void
+test_basic_connect_visible_providers (void)
{
guint32 n_providers;
g_autoptr(GError) error = NULL;
@@ -117,6 +134,7 @@
0x67, 0x00, 0x65, 0x00 };
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_visible_providers_response_parse (
response,
@@ -162,7 +180,7 @@
}
static void
-test_message_parser_basic_connect_subscriber_ready_status (void)
+test_basic_connect_subscriber_ready_status (void)
{
MbimSubscriberReadyState ready_state;
MbimReadyInfoFlag ready_info;
@@ -234,6 +252,7 @@
0x31, 0x00, 0x32, 0x00 };
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_subscriber_ready_status_response_parse (
response,
@@ -258,7 +277,7 @@
}
static void
-test_message_parser_basic_connect_device_caps (void)
+test_basic_connect_device_caps (void)
{
MbimDeviceType device_type;
MbimCellularClass cellular_class;
@@ -329,6 +348,7 @@
0x4D, 0x00, 0x00, 0x00 };
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_device_caps_response_parse (
response,
@@ -367,7 +387,7 @@
}
static void
-test_message_parser_basic_connect_ip_configuration (void)
+test_basic_connect_ip_configuration (void)
{
guint32 session_id;
MbimIPConfigurationAvailableFlag ipv4configurationavailable;
@@ -428,6 +448,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ip_configuration_response_parse (
response,
@@ -499,7 +520,7 @@
}
static void
-test_message_parser_basic_connect_service_activation (void)
+test_basic_connect_service_activation (void)
{
guint32 nw_error;
const guint8 *databuffer;
@@ -533,6 +554,7 @@
0x05, 0x06, 0x07, 0x08 };
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_service_activation_response_parse (
response,
@@ -549,7 +571,7 @@
}
static void
-test_message_parser_basic_connect_register_state (void)
+test_basic_connect_register_state (void)
{
MbimNwError nw_error;
MbimRegisterState register_state;
@@ -598,6 +620,7 @@
0x36, 0x00, 0x00, 0x00 };
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_register_state_response_parse (
response,
@@ -614,7 +637,7 @@
g_assert_no_error (error);
- g_assert_cmpuint (nw_error, ==, MBIM_NW_ERROR_UNKNOWN);
+ g_assert_cmpuint (nw_error, ==, MBIM_NW_ERROR_NONE);
g_assert_cmpuint (register_state, ==, MBIM_REGISTER_STATE_HOME);
g_assert_cmpuint (register_mode, ==, MBIM_REGISTER_MODE_AUTOMATIC);
g_assert_cmpuint (available_data_classes, ==, (MBIM_DATA_CLASS_UMTS |
@@ -628,7 +651,7 @@
}
static void
-test_message_parser_provisioned_contexts (void)
+test_provisioned_contexts (void)
{
guint32 provisioned_contexts_count = 0;
g_autoptr(MbimProvisionedContextElementArray) provisioned_contexts = NULL;
@@ -654,6 +677,8 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
+
g_assert (!mbim_message_provisioned_contexts_response_parse (
response,
&provisioned_contexts_count,
@@ -664,7 +689,7 @@
}
static void
-test_message_parser_sms_read_zero_pdu (void)
+test_sms_read_zero_pdu (void)
{
MbimSmsFormat format;
guint32 messages_count;
@@ -695,6 +720,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_sms_read_response_parse (
response,
@@ -712,7 +738,7 @@
}
static void
-test_message_parser_sms_read_single_pdu (void)
+test_sms_read_single_pdu (void)
{
MbimSmsFormat format;
guint32 messages_count;
@@ -762,6 +788,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_sms_read_response_parse (
response,
@@ -788,7 +815,7 @@
}
static void
-test_message_parser_sms_read_multiple_pdu (void)
+test_sms_read_multiple_pdu (void)
{
guint32 idx;
MbimSmsFormat format;
@@ -858,6 +885,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_sms_read_response_parse (
response,
@@ -907,7 +935,7 @@
}
static void
-test_message_parser_ussd (void)
+test_ussd (void)
{
MbimUssdResponse ussd_response;
MbimUssdSessionState ussd_session_state;
@@ -954,6 +982,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ussd_response_parse (
response,
@@ -978,7 +1007,7 @@
}
static void
-test_message_parser_auth_akap (void)
+test_auth_akap (void)
{
const guint8 *res;
guint32 res_len;
@@ -1049,8 +1078,8 @@
0x73, 0x72
};
-
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_auth_akap_response_parse (
response,
@@ -1090,7 +1119,7 @@
}
static void
-test_message_parser_stk_pac_notification (void)
+test_stk_pac_notification (void)
{
const guint8 *databuffer;
guint32 databuffer_len;
@@ -1139,6 +1168,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_stk_pac_notification_parse (
response,
@@ -1159,7 +1189,7 @@
}
static void
-test_message_parser_stk_pac_response (void)
+test_stk_pac_response (void)
{
const guint8 *databuffer;
g_autoptr(GError) error = NULL;
@@ -1316,6 +1346,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_stk_pac_response_parse (
response,
@@ -1331,7 +1362,7 @@
}
static void
-test_message_parser_stk_terminal_response (void)
+test_stk_terminal_response (void)
{
const guint8 *databuffer;
guint32 databuffer_len;
@@ -1372,6 +1403,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_stk_terminal_response_response_parse (
response,
@@ -1392,7 +1424,7 @@
}
static void
-test_message_parser_stk_envelope_response (void)
+test_stk_envelope_response (void)
{
const guint8 *databuffer;
g_autoptr(GError) error = NULL;
@@ -1437,6 +1469,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_stk_envelope_response_parse (
response,
@@ -1452,7 +1485,7 @@
}
static void
-test_message_parser_basic_connect_ip_packet_filters_none (void)
+test_basic_connect_ip_packet_filters_none (void)
{
guint32 n_filters;
guint32 session_id;
@@ -1482,6 +1515,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ip_packet_filters_response_parse (
response,
@@ -1497,7 +1531,7 @@
}
static void
-test_message_parser_basic_connect_ip_packet_filters_one (void)
+test_basic_connect_ip_packet_filters_one (void)
{
guint32 n_filters;
guint32 session_id;
@@ -1546,6 +1580,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ip_packet_filters_response_parse (
response,
@@ -1573,7 +1608,7 @@
}
static void
-test_message_parser_basic_connect_ip_packet_filters_two (void)
+test_basic_connect_ip_packet_filters_two (void)
{
guint32 n_filters;
guint32 session_id;
@@ -1644,6 +1679,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ip_packet_filters_response_parse (
response,
@@ -1679,7 +1715,7 @@
}
static void
-test_message_parser_ms_firmware_id_get (void)
+test_ms_firmware_id_get (void)
{
const MbimUuid *firmware_id;
g_autoptr(GError) error = NULL;
@@ -1716,6 +1752,7 @@
};
response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
g_assert (mbim_message_ms_firmware_id_get_response_parse (
response,
@@ -1728,7 +1765,7 @@
}
static void
-test_message_parser_basic_connect_connect_short (void)
+test_basic_connect_connect_short (void)
{
guint32 session_id;
MbimActivationState activation_state;
@@ -1775,7 +1812,7 @@
}
static void
-test_message_parser_basic_connect_visible_providers_overflow (void)
+test_basic_connect_visible_providers_overflow (void)
{
guint32 n_providers;
g_autoptr(GError) error = NULL;
@@ -1847,32 +1884,1102 @@
g_assert (!result);
}
+static void
+test_ms_basic_connect_extensions_base_stations (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimDataClass system_type;
+ g_autoptr(MbimCellInfoServingGsm) gsm_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingUmts) umts_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingTdscdma) tdscdma_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingLte) lte_serving_cell = NULL;
+ guint32 gsm_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringGsmArray) gsm_neighboring_cells = NULL;
+ guint32 umts_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringUmtsArray) umts_neighboring_cells = NULL;
+ guint32 tdscdma_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringTdscdmaArray) tdscdma_neighboring_cells = NULL;
+ guint32 lte_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringLteArray) lte_neighboring_cells = NULL;
+ guint32 cdma_cells_count;
+ g_autoptr(MbimCellInfoCdmaArray) cdma_cells = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0xD8, 0x00, 0x00, 0x00, /* length */
+ 0x03, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x0B, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0xA8, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x60, 0x00, 0x00, 0x00, /* system type */
+ 0x00, 0x00, 0x00, 0x00, /* gsm serving cell offset */
+ 0x00, 0x00, 0x00, 0x00, /* gsm serving cell size */
+ 0x00, 0x00, 0x00, 0x00, /* umts serving cell offset */
+ 0x00, 0x00, 0x00, 0x00, /* umts serving cell size */
+ 0x00, 0x00, 0x00, 0x00, /* tdscdma serving cell offset */
+ 0x00, 0x00, 0x00, 0x00, /* tdscdma serving cell size */
+ 0x4C, 0x00, 0x00, 0x00, /* lte serving cell offset*/
+ 0x2E, 0x00, 0x00, 0x00, /* lte serving cell size*/
+ 0xA0, 0x00, 0x00, 0x00, /* gsm network measurement report offset */
+ 0x04, 0x00, 0x00, 0x00, /* gsm network measurement report size */
+ 0xA4, 0x00, 0x00, 0x00, /* umts network measurement report offset */
+ 0x04, 0x00, 0x00, 0x00, /* umts network measurement report size */
+ 0x00, 0x00, 0x00, 0x00, /* tdscdma network measurement report offset */
+ 0x00, 0x00, 0x00, 0x00, /* tdscdma network measurement report size */
+ 0x7C, 0x00, 0x00, 0x00, /* lte network measurement report offset */
+ 0x24, 0x00, 0x00, 0x00, /* lte network measurement report size */
+ 0x00, 0x00, 0x00, 0x00, /* cdma network measurement report offset */
+ 0x00, 0x00, 0x00, 0x00, /* cdma network measurement report size */
+ /* lte serving cell */
+/*4C*/ 0x24, 0x00, 0x00, 0x00, /* provider id offset */
+ 0x0A, 0x00, 0x00, 0x00, /* provider id size */
+ 0x1F, 0xCD, 0x65, 0x04, /* cell id */
+ 0x00, 0x19, 0x00, 0x00, /* earfcn */
+ 0x36, 0x01, 0x00, 0x00, /* physical cell id */
+ 0xFE, 0x6F, 0x00, 0x00, /* tac */
+ 0x99, 0xFF, 0xFF, 0xFF, /* rsrp */
+ 0xF4, 0xFF, 0xFF, 0xFF, /* rsrq */
+ 0xFF, 0xFF, 0xFF, 0xFF, /* timing advance */
+ 0x32, 0x00, 0x31, 0x00, /* provider id string */
+ 0x34, 0x00, 0x30, 0x00,
+ 0x37, 0x00, 0x00, 0x00,
+ /* lte network measurement report */
+/*7C*/ 0x01, 0x00, 0x00, 0x00, /* element count */
+ 0x00, 0x00, 0x00, 0x00, /* provider id offset */
+ 0x00, 0x00, 0x00, 0x00, /* provider id size */
+ 0xFF, 0xFF, 0xFF, 0xFF, /* cell id */
+ 0xFF, 0xFF, 0xFF, 0xFF, /* earfcn */
+ 0x36, 0x01, 0x00, 0x00, /* physical cell id */
+ 0xFF, 0xFF, 0xFF, 0xFF, /* tac */
+ 0x99, 0xFF, 0xFF, 0xFF, /* rsrp */
+ 0xF4, 0xFF, 0xFF, 0xFF, /* rsrq */
+ /* gsm network measurement report */
+/*A0*/ 0x00, 0x00, 0x00, 0x00,
+ /* umts network measurement report */
+/*A4*/ 0x00, 0x00, 0x00, 0x00
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 1, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_base_stations_info_response_parse (
+ response,
+ &system_type,
+ &gsm_serving_cell,
+ &umts_serving_cell,
+ &tdscdma_serving_cell,
+ <e_serving_cell,
+ &gsm_neighboring_cells_count,
+ &gsm_neighboring_cells,
+ &umts_neighboring_cells_count,
+ &umts_neighboring_cells,
+ &tdscdma_neighboring_cells_count,
+ &tdscdma_neighboring_cells,
+ <e_neighboring_cells_count,
+ <e_neighboring_cells,
+ &cdma_cells_count,
+ &cdma_cells,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_null (gsm_serving_cell);
+ g_assert_null (umts_serving_cell);
+ g_assert_null (tdscdma_serving_cell);
+ g_assert_nonnull (lte_serving_cell);
+ g_assert_cmpuint (gsm_neighboring_cells_count, ==, 0);
+ g_assert_null (gsm_neighboring_cells);
+ g_assert_cmpuint (umts_neighboring_cells_count, ==, 0);
+ g_assert_null (umts_neighboring_cells);
+ g_assert_cmpuint (tdscdma_neighboring_cells_count, ==, 0);
+ g_assert_null (tdscdma_neighboring_cells);
+ g_assert_cmpuint (lte_neighboring_cells_count, ==, 1);
+ g_assert_nonnull (lte_neighboring_cells);
+ g_assert_cmpuint (cdma_cells_count, ==, 0);
+ g_assert_null (cdma_cells);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_0_unnamed_tlvs (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimMicoMode mico_mode;
+ MbimDrxCycle drx_cycle;
+ MbimLadnInfo ladn_info;
+ MbimDefaultPduActivationHint pdu_hint;
+ gboolean re_register_if_needed;
+ GList *unnamed_ies = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x44, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x14, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* no unnamed TLVs */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_response_parse (
+ response,
+ &mico_mode,
+ &drx_cycle,
+ &ladn_info,
+ &pdu_hint,
+ &re_register_if_needed,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mico_mode, ==, MBIM_MICO_MODE_DISABLED);
+ g_assert_cmpuint (drx_cycle, ==, MBIM_DRX_CYCLE_NOT_SPECIFIED);
+ g_assert_cmpuint (ladn_info, ==, MBIM_LADN_INFO_NOT_NEEDED);
+ g_assert_cmpuint (pdu_hint, ==, MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY);
+ g_assert_cmpuint (re_register_if_needed, ==, TRUE);
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 0);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_1_unnamed_tlv (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimMicoMode mico_mode;
+ MbimDrxCycle drx_cycle;
+ MbimLadnInfo ladn_info;
+ MbimDefaultPduActivationHint pdu_hint;
+ gboolean re_register_if_needed;
+ GList *unnamed_ies = NULL;
+ MbimTlv *tlv;
+ g_autofree gchar *tlv_str = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x58, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x28, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_response_parse (
+ response,
+ &mico_mode,
+ &drx_cycle,
+ &ladn_info,
+ &pdu_hint,
+ &re_register_if_needed,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mico_mode, ==, MBIM_MICO_MODE_DISABLED);
+ g_assert_cmpuint (drx_cycle, ==, MBIM_DRX_CYCLE_NOT_SPECIFIED);
+ g_assert_cmpuint (ladn_info, ==, MBIM_LADN_INFO_NOT_NEEDED);
+ g_assert_cmpuint (pdu_hint, ==, MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY);
+ g_assert_cmpuint (re_register_if_needed, ==, TRUE);
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 1);
+
+ tlv = (MbimTlv *)(unnamed_ies->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+
+ tlv_str = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str, ==, "Orange");
+
+ g_list_free_full (unnamed_ies, (GDestroyNotify)mbim_tlv_unref);
+}
+
+static void
+test_ms_basic_connect_extensions_registration_parameters_3_unnamed_tlvs (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimMicoMode mico_mode;
+ MbimDrxCycle drx_cycle;
+ MbimLadnInfo ladn_info;
+ MbimDefaultPduActivationHint pdu_hint;
+ gboolean re_register_if_needed;
+ GList *unnamed_ies = NULL;
+ GList *iter;
+ MbimTlv *tlv;
+ g_autofree gchar *tlv_str_1 = NULL;
+ const gchar *expected_tlv_str_1 = "abcde";
+ g_autofree gchar *tlv_str_2 = NULL;
+ const gchar *expected_tlv_str_2 = "Orange";
+ const guint8 *pco_3 = NULL;
+ guint32 pco_3_size = 0;
+ const guint8 expected_pco[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B };
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x80, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x11, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x50, 0x00, 0x00, 0x00, /* buffer length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* mico mode */
+ 0x00, 0x00, 0x00, 0x00, /* drx cycle */
+ 0x00, 0x00, 0x00, 0x00, /* ladn info */
+ 0x01, 0x00, 0x00, 0x00, /* pdu hint */
+ 0x01, 0x00, 0x00, 0x00, /* re register if needed */
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x02, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, padding 2 */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x61, 0x00, 0x62, 0x00, /* TLV data string */
+ 0x63, 0x00, 0x64, 0x00,
+ 0x65, 0x00, 0x00, 0x00,
+ /* Second unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ /* Third unnamed TLV */
+ 0x0D, 0x00, 0x00, 0x01, /* TLV type MBIM_TLV_TYPE_PCO, padding 1 */
+ 0x0B, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x01, 0x02, 0x03, 0x04, /* TLV data bytes */
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x00,
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_response_parse (
+ response,
+ &mico_mode,
+ &drx_cycle,
+ &ladn_info,
+ &pdu_hint,
+ &re_register_if_needed,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mico_mode, ==, MBIM_MICO_MODE_DISABLED);
+ g_assert_cmpuint (drx_cycle, ==, MBIM_DRX_CYCLE_NOT_SPECIFIED);
+ g_assert_cmpuint (ladn_info, ==, MBIM_LADN_INFO_NOT_NEEDED);
+ g_assert_cmpuint (pdu_hint, ==, MBIM_DEFAULT_PDU_ACTIVATION_HINT_LIKELY);
+ g_assert_cmpuint (re_register_if_needed, ==, TRUE);
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 3);
+
+ iter = unnamed_ies;
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+ tlv_str_1 = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str_1, ==, expected_tlv_str_1);
+
+ iter = g_list_next (iter);
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+ tlv_str_2 = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str_2, ==, expected_tlv_str_2);
+
+ iter = g_list_next (iter);
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_PCO);
+ pco_3 = mbim_tlv_get_tlv_data (tlv, &pco_3_size);
+ g_assert_cmpuint (pco_3_size, ==, sizeof (expected_pco));
+ g_assert (memcmp (pco_3, expected_pco, sizeof (expected_pco)) == 0);
+
+ g_list_free_full (unnamed_ies, (GDestroyNotify)mbim_tlv_unref);
+}
+
+static void
+test_ms_basic_connect_v3_connect_0_unnamed_tlvs (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ GList *unnamed_ies = NULL;
+ guint32 session_id;
+ MbimActivationState activation_state;
+ MbimVoiceCallState voice_call_state;
+ MbimContextIpType ip_type;
+ MbimAccessMediaType media_type = MBIM_ACCESS_MEDIA_TYPE_UNKNOWN;
+ g_autofree gchar *access_string = NULL;
+ const MbimUuid *context_type;
+ guint32 nw_error;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x6C, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x3C, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* session id */
+ 0x01, 0x00, 0x00, 0x00, /* activation state */
+ 0x00, 0x00, 0x00, 0x00, /* voice call state */
+ 0x01, 0x00, 0x00, 0x00, /* ip type */
+ 0x7E, 0x5E, 0x2A, 0x7E, /* context type */
+ 0x4E, 0x6F, 0x72, 0x72,
+ 0x73, 0x6B, 0x65, 0x6E,
+ 0x7E, 0x5E, 0x2A, 0x7E,
+ 0x00, 0x00, 0x00, 0x00, /* nw error */
+ 0x01, 0x00, 0x00, 0x00, /* media type */
+ 0x0A, 0x00, 0x00, 0x00, /* access string */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x69, 0x00, 0x6E, 0x00,
+ 0x74, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6E, 0x00,
+ 0x65, 0x00, 0x74, 0x00,
+ /* no unnamed TLVs */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_v3_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ &voice_call_state,
+ &ip_type,
+ &context_type,
+ &nw_error,
+ &media_type,
+ &access_string,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (session_id, ==, 1);
+ g_assert_cmpuint (activation_state, ==, MBIM_ACTIVATION_STATE_ACTIVATED);
+ g_assert_cmpuint (voice_call_state, ==, MBIM_VOICE_CALL_STATE_NONE);
+ g_assert_cmpuint (ip_type, ==, MBIM_CONTEXT_IP_TYPE_IPV4);
+ g_assert_cmpuint (mbim_uuid_to_context_type (context_type), ==, MBIM_CONTEXT_TYPE_INTERNET);
+ g_assert_cmpuint (media_type, ==, MBIM_ACCESS_MEDIA_TYPE_3GPP);
+ g_assert_cmpstr (access_string, ==, "internet");
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 0);
+}
+
+static void
+test_ms_basic_connect_v3_connect_1_unnamed_tlv (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ GList *unnamed_ies = NULL;
+ guint32 session_id;
+ MbimActivationState activation_state;
+ MbimVoiceCallState voice_call_state;
+ MbimContextIpType ip_type;
+ MbimAccessMediaType media_type = MBIM_ACCESS_MEDIA_TYPE_UNKNOWN;
+ g_autofree gchar *access_string = NULL;
+ const MbimUuid *context_type;
+ guint32 nw_error;
+ MbimTlv *tlv;
+ g_autofree gchar *tlv_str = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x82, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x52, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* session id */
+ 0x01, 0x00, 0x00, 0x00, /* activation state */
+ 0x00, 0x00, 0x00, 0x00, /* voice call state */
+ 0x01, 0x00, 0x00, 0x00, /* ip type */
+ 0x7E, 0x5E, 0x2A, 0x7E, /* context type */
+ 0x4E, 0x6F, 0x72, 0x72,
+ 0x73, 0x6B, 0x65, 0x6E,
+ 0x7E, 0x5E, 0x2A, 0x7E,
+ 0x00, 0x00, 0x00, 0x00, /* nw error */
+ 0x01, 0x00, 0x00, 0x00, /* media type */
+ 0x0A, 0x00, 0x00, 0x00, /* access string */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x69, 0x00, 0x6E, 0x00,
+ 0x74, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6E, 0x00,
+ 0x65, 0x00, 0x74, 0x00,
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_v3_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ &voice_call_state,
+ &ip_type,
+ &context_type,
+ &nw_error,
+ &media_type,
+ &access_string,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (session_id, ==, 1);
+ g_assert_cmpuint (activation_state, ==, MBIM_ACTIVATION_STATE_ACTIVATED);
+ g_assert_cmpuint (voice_call_state, ==, MBIM_VOICE_CALL_STATE_NONE);
+ g_assert_cmpuint (ip_type, ==, MBIM_CONTEXT_IP_TYPE_IPV4);
+ g_assert_cmpuint (mbim_uuid_to_context_type (context_type), ==, MBIM_CONTEXT_TYPE_INTERNET);
+ g_assert_cmpuint (media_type, ==, MBIM_ACCESS_MEDIA_TYPE_3GPP);
+ g_assert_cmpstr (access_string, ==, "internet");
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 1);
+
+ tlv = (MbimTlv *)(unnamed_ies->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+
+ tlv_str = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str, ==, "Orange");
+
+ g_list_free_full (unnamed_ies, (GDestroyNotify)mbim_tlv_unref);
+}
+
+static void
+test_ms_basic_connect_v3_connect_3_unnamed_tlvs (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ GList *unnamed_ies = NULL;
+ guint32 session_id;
+ MbimActivationState activation_state;
+ MbimVoiceCallState voice_call_state;
+ MbimContextIpType ip_type;
+ MbimAccessMediaType media_type = MBIM_ACCESS_MEDIA_TYPE_UNKNOWN;
+ g_autofree gchar *access_string = NULL;
+ const MbimUuid *context_type;
+ guint32 nw_error;
+ GList *iter;
+ MbimTlv *tlv;
+ g_autofree gchar *tlv_str_1 = NULL;
+ const gchar *expected_tlv_str_1 = "abcde";
+ g_autofree gchar *tlv_str_2 = NULL;
+ const gchar *expected_tlv_str_2 = "Orange";
+ const guint8 *pco_3 = NULL;
+ guint32 pco_3_size = 0;
+ const guint8 expected_pco[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B };
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0xAA, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x7A, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* session id */
+ 0x01, 0x00, 0x00, 0x00, /* activation state */
+ 0x00, 0x00, 0x00, 0x00, /* voice call state */
+ 0x01, 0x00, 0x00, 0x00, /* ip type */
+ 0x7E, 0x5E, 0x2A, 0x7E, /* context type */
+ 0x4E, 0x6F, 0x72, 0x72,
+ 0x73, 0x6B, 0x65, 0x6E,
+ 0x7E, 0x5E, 0x2A, 0x7E,
+ 0x00, 0x00, 0x00, 0x00, /* nw error */
+ 0x01, 0x00, 0x00, 0x00, /* media type */
+ 0x0A, 0x00, 0x00, 0x00, /* access string */
+ 0x10, 0x00, 0x00, 0x00,
+ 0x69, 0x00, 0x6E, 0x00,
+ 0x74, 0x00, 0x65, 0x00,
+ 0x72, 0x00, 0x6E, 0x00,
+ 0x65, 0x00, 0x74, 0x00,
+ /* First unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x02, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, padding 2 */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x61, 0x00, 0x62, 0x00, /* TLV data string */
+ 0x63, 0x00, 0x64, 0x00,
+ 0x65, 0x00, 0x00, 0x00,
+ /* Second unnamed TLV */
+ 0x0A, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WCHAR_STR, no padding */
+ 0x0C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x4F, 0x00, 0x72, 0x00, /* TLV data string */
+ 0x61, 0x00, 0x6E, 0x00,
+ 0x67, 0x00, 0x65, 0x00,
+ /* Third unnamed TLV */
+ 0x0D, 0x00, 0x00, 0x01, /* TLV type MBIM_TLV_TYPE_PCO, padding 1 */
+ 0x0B, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x01, 0x02, 0x03, 0x04, /* TLV data bytes */
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x0B, 0x00,
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_v3_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ &voice_call_state,
+ &ip_type,
+ &context_type,
+ &nw_error,
+ &media_type,
+ &access_string,
+ &unnamed_ies,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (session_id, ==, 1);
+ g_assert_cmpuint (activation_state, ==, MBIM_ACTIVATION_STATE_ACTIVATED);
+ g_assert_cmpuint (voice_call_state, ==, MBIM_VOICE_CALL_STATE_NONE);
+ g_assert_cmpuint (ip_type, ==, MBIM_CONTEXT_IP_TYPE_IPV4);
+ g_assert_cmpuint (mbim_uuid_to_context_type (context_type), ==, MBIM_CONTEXT_TYPE_INTERNET);
+ g_assert_cmpuint (media_type, ==, MBIM_ACCESS_MEDIA_TYPE_3GPP);
+ g_assert_cmpstr (access_string, ==, "internet");
+ g_assert_cmpuint (g_list_length (unnamed_ies), ==, 3);
+
+
+ iter = unnamed_ies;
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+ tlv_str_1 = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str_1, ==, expected_tlv_str_1);
+
+ iter = g_list_next (iter);
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_WCHAR_STR);
+ tlv_str_2 = mbim_tlv_string_get (tlv, &error);
+ g_assert_no_error (error);
+ g_assert_cmpstr (tlv_str_2, ==, expected_tlv_str_2);
+
+ iter = g_list_next (iter);
+ tlv = (MbimTlv *)(iter->data);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (tlv), ==, MBIM_TLV_TYPE_PCO);
+ pco_3 = mbim_tlv_get_tlv_data (tlv, &pco_3_size);
+ g_assert_cmpuint (pco_3_size, ==, sizeof (expected_pco));
+ g_assert (memcmp (pco_3, expected_pco, sizeof (expected_pco)) == 0);
+
+ g_list_free_full (unnamed_ies, (GDestroyNotify)mbim_tlv_unref);
+}
+
+static void
+test_ms_basic_connect_extensions_device_caps_v3 (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimDeviceType device_type;
+ MbimVoiceClass voice_class;
+ MbimCellularClass cellular_class;
+ MbimSimClass sim_class;
+ MbimDataClassV3 data_class;
+ MbimDataSubclass data_subclass;
+ MbimSmsCaps sms_caps;
+ MbimCtrlCaps ctrl_caps;
+ guint32 max_sessions;
+ guint32 wcdma_band_class = 0;
+ guint32 lte_band_class_array_size = 0;
+ g_autofree guint16 *lte_band_class_array = NULL;
+ guint32 nr_band_class_array_size = 0;
+ g_autofree guint16 *nr_band_class_array = NULL;
+ g_autofree gchar *custom_data_class = NULL;
+ g_autofree gchar *device_id = NULL;
+ g_autofree gchar *firmware_info = NULL;
+ g_autofree gchar *hardware_info = NULL;
+ guint32 executor_index;
+ static const guint16 expected_lte_band_class_array[] = {
+ 1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 28, 29, 30, 32, 34, 38, 39, 40, 41, 42, 43, 46, 48
+ };
+ static const guint16 expected_nr_band_class_array[] = {
+ 1, 2, 3, 5, 7, 8, 20, 25, 28, 30, 38, 40, 41, 48, 66, 71, 77, 78, 79
+ };
+
+ const guint8 buffer [] = {
+ 0x03, 0x00, 0x00, 0x80, 0x68, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x3D, 0x01, 0xDC, 0xC5, 0xFE, 0xF5, 0x4D, 0x05, 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+ 0x7C, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xA3, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x00,
+ 0x0B, 0x00, 0x00, 0x02, 0x3A, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00,
+ 0x05, 0x00, 0x07, 0x00, 0x08, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x11, 0x00, 0x12, 0x00,
+ 0x13, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x20, 0x00,
+ 0x22, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, 0x2E, 0x00,
+ 0x30, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x02, 0x26, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
+ 0x03, 0x00, 0x05, 0x00, 0x07, 0x00, 0x08, 0x00, 0x14, 0x00, 0x19, 0x00, 0x1C, 0x00, 0x1E, 0x00,
+ 0x26, 0x00, 0x28, 0x00, 0x29, 0x00, 0x30, 0x00, 0x42, 0x00, 0x47, 0x00, 0x4D, 0x00, 0x4E, 0x00,
+ 0x4F, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x02, 0x0A, 0x00, 0x00, 0x00, 0x48, 0x00, 0x53, 0x00,
+ 0x50, 0x00, 0x41, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x02, 0x1E, 0x00, 0x00, 0x00,
+ 0x38, 0x00, 0x36, 0x00, 0x32, 0x00, 0x31, 0x00, 0x34, 0x00, 0x36, 0x00, 0x30, 0x00, 0x35, 0x00,
+ 0x30, 0x00, 0x30, 0x00, 0x38, 0x00, 0x34, 0x00, 0x35, 0x00, 0x35, 0x00, 0x35, 0x00, 0x00, 0x00,
+ 0x0A, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x38, 0x00, 0x31, 0x00, 0x36, 0x00, 0x30, 0x00,
+ 0x30, 0x00, 0x2E, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x39, 0x00,
+ 0x39, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x39, 0x00, 0x2E, 0x00, 0x31, 0x00, 0x37, 0x00, 0x2E, 0x00,
+ 0x31, 0x00, 0x39, 0x00, 0x5F, 0x00, 0x47, 0x00, 0x43, 0x00, 0x0D, 0x00, 0x0A, 0x00, 0x42, 0x00,
+ 0x39, 0x00, 0x30, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x56, 0x00, 0x31, 0x00,
+ 0x2E, 0x00, 0x30, 0x00, 0x2E, 0x00, 0x36, 0x00
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_device_caps_response_parse (
+ response,
+ &device_type,
+ &cellular_class,
+ &voice_class,
+ &sim_class,
+ &data_class,
+ &sms_caps,
+ &ctrl_caps,
+ &data_subclass,
+ &max_sessions,
+ &executor_index,
+ &wcdma_band_class,
+ <e_band_class_array_size,
+ <e_band_class_array,
+ &nr_band_class_array_size,
+ &nr_band_class_array,
+ &custom_data_class,
+ &device_id,
+ &firmware_info,
+ &hardware_info,
+ &error));
+
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (device_type, ==, MBIM_DEVICE_TYPE_EMBEDDED);
+ g_assert_cmpuint (cellular_class, ==, MBIM_CELLULAR_CLASS_GSM);
+ g_assert_cmpuint (voice_class, ==, MBIM_VOICE_CLASS_NO_VOICE);
+ g_assert_cmpuint (sim_class, ==, MBIM_SIM_CLASS_REMOVABLE);
+ g_assert_cmpuint (data_class, ==, (MBIM_DATA_CLASS_V3_UMTS |
+ MBIM_DATA_CLASS_V3_HSDPA |
+ MBIM_DATA_CLASS_V3_HSUPA |
+ MBIM_DATA_CLASS_V3_LTE |
+ MBIM_DATA_CLASS_V3_5G |
+ MBIM_DATA_CLASS_V3_CUSTOM));
+ g_assert_cmpuint (sms_caps, ==, (MBIM_SMS_CAPS_PDU_RECEIVE |
+ MBIM_SMS_CAPS_PDU_SEND));
+ g_assert_cmpuint (ctrl_caps, ==, (MBIM_CTRL_CAPS_REG_MANUAL |
+ MBIM_CTRL_CAPS_HW_RADIO_SWITCH |
+ MBIM_CTRL_CAPS_ESIM |
+ MBIM_CTRL_CAPS_SIM_HOT_SWAP_CAPABLE));
+ g_assert_cmpuint (data_subclass, ==, (MBIM_DATA_SUBCLASS_5G_ENDC |
+ MBIM_DATA_SUBCLASS_5G_NR));
+ g_assert_cmpuint (max_sessions, ==, 2);
+ g_assert_cmpuint (executor_index, ==, 0);
+ g_assert_cmpuint (wcdma_band_class, ==, (1 << (1 - 1) |
+ 1 << (2 - 1) |
+ 1 << (4 - 1) |
+ 1 << (5 - 1) |
+ 1 << (8 - 1)));
+ g_assert_cmpuint (G_N_ELEMENTS (expected_lte_band_class_array), ==, lte_band_class_array_size);
+ g_assert (memcmp (lte_band_class_array, expected_lte_band_class_array, lte_band_class_array_size * sizeof (guint16)) == 0);
+ g_assert_cmpuint (G_N_ELEMENTS (expected_nr_band_class_array), ==, nr_band_class_array_size);
+ g_assert (memcmp (nr_band_class_array, expected_nr_band_class_array, nr_band_class_array_size * sizeof (guint16)) == 0);
+ g_assert_cmpstr (custom_data_class, ==, "HSPA+");
+ g_assert_cmpstr (device_id, ==, "862146050084555");
+ g_assert_cmpstr (firmware_info, ==, "81600.0000.99.29.17.19_GC\r\nB90");
+ g_assert_cmpstr (hardware_info, ==, "V1.0.6");
+}
+
+static void
+test_ms_basic_connect_extensions_wake_reason_command (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ const MbimUuid *service = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x5C, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x2C, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x01, 0x00, 0x00, 0x00, /* wake type: cid indication */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x10, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WAKE_COMMAND, padding 0 */
+ 0x1C, 0x00, 0x00, 0x00, /* TLV data length */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id: basic connect */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0B, 0x00, 0x00, 0x00, /* command id: signal state */
+ 0x00, 0x00, 0x00, 0x00, /* payload offset: none */
+ 0x00, 0x00, 0x00, 0x00, /* payload size: none */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_CID_INDICATION);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_COMMAND);
+
+ result = (mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mbim_uuid_to_service (service), ==, MBIM_SERVICE_BASIC_CONNECT);
+ g_assert_cmpuint (cid, ==, MBIM_CID_BASIC_CONNECT_SIGNAL_STATE);
+ g_assert_cmpuint (payload_size, ==, 0);
+ g_assert_null (payload);
+}
+
+static void
+test_ms_basic_connect_extensions_wake_reason_command_payload (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ const MbimUuid *service = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+ guint32 payload_uint;
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x60, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x30, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x00, 0x00, 0x00, 0x00, /* wake type: cid response */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x10, 0x00, 0x00, 0x00, /* TLV type MBIM_TLV_TYPE_WAKE_COMMAND, padding 0 */
+ 0x20, 0x00, 0x00, 0x00, /* TLV data length */
+ 0xA2, 0x89, 0xCC, 0x33, /* service id: basic connect */
+ 0xBC, 0xBB, 0x8B, 0x4F,
+ 0xB6, 0xB0, 0x13, 0x3E,
+ 0xC2, 0xAA, 0xE6, 0xDF,
+ 0x0C, 0x00, 0x00, 0x00, /* command id: connect */
+ 0x1C, 0x00, 0x00, 0x00, /* payload offset: 28 */
+ 0x04, 0x00, 0x00, 0x00, /* payload size: 4 */
+ 0x01, 0x00, 0x00, 0x00, /* payload: a guint32 */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_CID_RESPONSE);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_COMMAND);
+
+ result = (mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (mbim_uuid_to_service (service), ==, MBIM_SERVICE_BASIC_CONNECT);
+ g_assert_cmpuint (cid, ==, MBIM_CID_BASIC_CONNECT_CONNECT);
+ g_assert_cmpuint (payload_size, ==, 4);
+ g_assert_nonnull (payload);
+
+ memcpy (&payload_uint, payload, payload_size);
+ payload_uint = GUINT32_FROM_LE (payload_uint);
+ g_assert_cmpuint (payload_uint, ==, 1);
+}
+
+static void
+test_ms_basic_connect_extensions_wake_reason_packet (void)
+{
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimMessage) response = NULL;
+ gboolean result;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ g_autoptr(MbimTlv) wake_tlv = NULL;
+ guint32 filter_id = 0;
+ guint32 original_packet_size = 0;
+ guint32 packet_size = 0;
+ g_autofree guint8 *packet = NULL;
+ const guint8 expected_packet[] = { 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A };
+
+ const guint8 buffer [] = {
+ /* header */
+ 0x03, 0x00, 0x00, 0x80, /* type */
+ 0x5C, 0x00, 0x00, 0x00, /* length */
+ 0x04, 0x00, 0x00, 0x00, /* transaction id */
+ /* fragment header */
+ 0x01, 0x00, 0x00, 0x00, /* total */
+ 0x00, 0x00, 0x00, 0x00, /* current */
+ /* command_done_message */
+ 0x3D, 0x01, 0xDC, 0xC5, /* service id */
+ 0xFE, 0xF5, 0x4D, 0x05,
+ 0x0D, 0x3A, 0xBE, 0xF7,
+ 0x05, 0x8E, 0x9A, 0xAF,
+ 0x13, 0x00, 0x00, 0x00, /* command id */
+ 0x00, 0x00, 0x00, 0x00, /* status code */
+ 0x2C, 0x00, 0x00, 0x00, /* buffer_length */
+ /* information buffer */
+ 0x02, 0x00, 0x00, 0x00, /* wake type: packet */
+ 0x02, 0x00, 0x00, 0x00, /* session id */
+ /* TLV */
+ 0x11, 0x00, 0x00, 0x02, /* TLV type MBIM_TLV_TYPE_WAKE_PACKET, padding 2 */
+ 0x1A, 0x00, 0x00, 0x00, /* TLV data length */
+ 0x0B, 0x00, 0x00, 0x00, /* filter id */
+ 0x0C, 0x00, 0x00, 0x00, /* original packet size: 12 */
+ 0x10, 0x00, 0x00, 0x00, /* packet offset: 16 */
+ 0x0A, 0x00, 0x00, 0x00, /* packet size: 10 */
+ 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0A, 0x00, 0x00, /* last 2 bytes padding */
+ };
+
+ response = mbim_message_new (buffer, sizeof (buffer));
+ test_message_printable (response, 3, 0);
+
+ result = (mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (wake_type, ==, MBIM_WAKE_TYPE_PACKET);
+ g_assert_cmpuint (session_id, ==, 2);
+ g_assert_nonnull (wake_tlv);
+ g_assert_cmpuint (mbim_tlv_get_tlv_type (wake_tlv), ==, MBIM_TLV_TYPE_WAKE_PACKET);
+
+ result = (mbim_tlv_wake_packet_get (wake_tlv,
+ &filter_id,
+ &original_packet_size,
+ &packet_size,
+ &packet,
+ &error));
+ g_assert_no_error (error);
+ g_assert (result);
+
+ g_assert_cmpuint (filter_id, ==, 0x0B);
+ g_assert_cmpuint (original_packet_size, ==, 12);
+ g_assert_cmpuint (packet_size, ==, sizeof (expected_packet));
+ g_assert_nonnull (packet);
+ g_assert (memcmp (packet, expected_packet, sizeof (expected_packet)) == 0);
+}
+
int main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/visible-providers", test_message_parser_basic_connect_visible_providers);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/subscriber-ready-status", test_message_parser_basic_connect_subscriber_ready_status);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/device-caps", test_message_parser_basic_connect_device_caps);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/ip-configuration", test_message_parser_basic_connect_ip_configuration);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/service-activation", test_message_parser_basic_connect_service_activation);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/register-state", test_message_parser_basic_connect_register_state);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/provisioned-contexts", test_message_parser_provisioned_contexts);
- g_test_add_func ("/libmbim-glib/message/parser/sms/read/zero-pdu", test_message_parser_sms_read_zero_pdu);
- g_test_add_func ("/libmbim-glib/message/parser/sms/read/single-pdu", test_message_parser_sms_read_single_pdu);
- g_test_add_func ("/libmbim-glib/message/parser/sms/read/multiple-pdu", test_message_parser_sms_read_multiple_pdu);
- g_test_add_func ("/libmbim-glib/message/parser/ussd", test_message_parser_ussd);
- g_test_add_func ("/libmbim-glib/message/parser/auth/akap", test_message_parser_auth_akap);
- g_test_add_func ("/libmbim-glib/message/parser/stk/pac/notification", test_message_parser_stk_pac_notification);
- g_test_add_func ("/libmbim-glib/message/parser/stk/pac/response", test_message_parser_stk_pac_response);
- g_test_add_func ("/libmbim-glib/message/parser/stk/terminal/response", test_message_parser_stk_terminal_response);
- g_test_add_func ("/libmbim-glib/message/parser/stk/envelope/response", test_message_parser_stk_envelope_response);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/ip-packet-filters/none", test_message_parser_basic_connect_ip_packet_filters_none);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/ip-packet-filters/one", test_message_parser_basic_connect_ip_packet_filters_one);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/ip-packet-filters/two", test_message_parser_basic_connect_ip_packet_filters_two);
- g_test_add_func ("/libmbim-glib/message/parser/ms-firmware-id/get", test_message_parser_ms_firmware_id_get);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/connect/short", test_message_parser_basic_connect_connect_short);
- g_test_add_func ("/libmbim-glib/message/parser/basic-connect/visible-providers/overflow", test_message_parser_basic_connect_visible_providers_overflow);
+#define PREFIX "/libmbim-glib/message/parser"
+
+ g_test_add_func (PREFIX "/basic-connect/visible-providers", test_basic_connect_visible_providers);
+ g_test_add_func (PREFIX "/basic-connect/subscriber-ready-status", test_basic_connect_subscriber_ready_status);
+ g_test_add_func (PREFIX "/basic-connect/device-caps", test_basic_connect_device_caps);
+ g_test_add_func (PREFIX "/basic-connect/ip-configuration", test_basic_connect_ip_configuration);
+ g_test_add_func (PREFIX "/basic-connect/service-activation", test_basic_connect_service_activation);
+ g_test_add_func (PREFIX "/basic-connect/register-state", test_basic_connect_register_state);
+ g_test_add_func (PREFIX "/basic-connect/provisioned-contexts", test_provisioned_contexts);
+ g_test_add_func (PREFIX "/sms/read/zero-pdu", test_sms_read_zero_pdu);
+ g_test_add_func (PREFIX "/sms/read/single-pdu", test_sms_read_single_pdu);
+ g_test_add_func (PREFIX "/sms/read/multiple-pdu", test_sms_read_multiple_pdu);
+ g_test_add_func (PREFIX "/ussd", test_ussd);
+ g_test_add_func (PREFIX "/auth/akap", test_auth_akap);
+ g_test_add_func (PREFIX "/stk/pac/notification", test_stk_pac_notification);
+ g_test_add_func (PREFIX "/stk/pac/response", test_stk_pac_response);
+ g_test_add_func (PREFIX "/stk/terminal/response", test_stk_terminal_response);
+ g_test_add_func (PREFIX "/stk/envelope/response", test_stk_envelope_response);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/none", test_basic_connect_ip_packet_filters_none);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/one", test_basic_connect_ip_packet_filters_one);
+ g_test_add_func (PREFIX "/basic-connect/ip-packet-filters/two", test_basic_connect_ip_packet_filters_two);
+ g_test_add_func (PREFIX "/ms-firmware-id/get", test_ms_firmware_id_get);
+ g_test_add_func (PREFIX "/basic-connect/connect/short", test_basic_connect_connect_short);
+ g_test_add_func (PREFIX "/basic-connect/visible-providers/overflow", test_basic_connect_visible_providers_overflow);
+ g_test_add_func (PREFIX "/basic-connect-extensions/base-stations", test_ms_basic_connect_extensions_base_stations);
+ g_test_add_func (PREFIX "/basic-connect-extensions/registration-parameters/0-unnamed-tlvs", test_ms_basic_connect_extensions_registration_parameters_0_unnamed_tlvs);
+ g_test_add_func (PREFIX "/basic-connect-extensions/registration-parameters/1-unnamed-tlv", test_ms_basic_connect_extensions_registration_parameters_1_unnamed_tlv);
+ g_test_add_func (PREFIX "/basic-connect-extensions/registration-parameters/3-unnamed-tlvs", test_ms_basic_connect_extensions_registration_parameters_3_unnamed_tlvs);
+ g_test_add_func (PREFIX "/basic-connect-v3/connect/0-unnamed-tlvs", test_ms_basic_connect_v3_connect_0_unnamed_tlvs);
+ g_test_add_func (PREFIX "/basic-connect-v3/connect/1-unnamed-tlv", test_ms_basic_connect_v3_connect_1_unnamed_tlv);
+ g_test_add_func (PREFIX "/basic-connect-v3/connect/3-unnamed-tlvs", test_ms_basic_connect_v3_connect_3_unnamed_tlvs);
+ g_test_add_func (PREFIX "/basic-connect-extensions/device-caps-v3", test_ms_basic_connect_extensions_device_caps_v3);
+ g_test_add_func (PREFIX "/basic-connect-extensions/wake-reason/command", test_ms_basic_connect_extensions_wake_reason_command);
+ g_test_add_func (PREFIX "/basic-connect-extensions/wake-reason/command/payload", test_ms_basic_connect_extensions_wake_reason_command_payload);
+ g_test_add_func (PREFIX "/basic-connect-extensions/wake-reason/packet", test_ms_basic_connect_extensions_wake_reason_packet);
+
+#undef PREFIX
return g_test_run ();
}
diff --git a/src/mbim-proxy/meson.build b/src/mbim-proxy/meson.build
index 8c21c02..c316aa6 100644
--- a/src/mbim-proxy/meson.build
+++ b/src/mbim-proxy/meson.build
@@ -16,7 +16,7 @@
configure_file(
input: '76-mbim-proxy-device-ownership.rules.in',
output: '@BASENAME@',
- configuration: config_h,
- install_dir: join_paths(udev_udevdir, 'rules.d'),
+ configuration: {'MBIM_USERNAME': mbim_username},
+ install_dir: udev_udevdir / 'rules.d',
)
endif
diff --git a/src/mbimcli/mbimcli-basic-connect.c b/src/mbimcli/mbimcli-basic-connect.c
index 0ac3c9a..50ca6d9 100644
--- a/src/mbimcli/mbimcli-basic-connect.c
+++ b/src/mbimcli/mbimcli-basic-connect.c
@@ -58,6 +58,7 @@
static gchar *set_connect_deactivate_str;
static gboolean query_packet_statistics_flag;
static gchar *query_ip_packet_filters_str;
+static gchar *set_ip_packet_filters_str;
static gboolean query_provisioned_contexts_flag;
static gboolean query_connection_state_arg_parse (const char *option_name,
@@ -172,7 +173,7 @@
"[SessionID]"
},
{ "connect", 0, 0, G_OPTION_ARG_STRING, &set_connect_activate_str,
- "Connect (allowed keys: session-id, apn, ip-type (ipv4|ipv6|ipv4v6), auth (PAP|CHAP|MSCHAPV2), username, password)",
+ "Connect (allowed keys: session-id, access-string, ip-type, auth, username, password, compression, context-type)",
"[\"key=value,...\"]"
},
{ "query-ip-configuration", 0, G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, G_CALLBACK (query_ip_configuration_arg_parse),
@@ -191,6 +192,10 @@
"Query IP packet filters (SessionID is optional, defaults to 0)",
"[SessionID]"
},
+ { "set-ip-packet-filters", 0, 0, G_OPTION_ARG_STRING, &set_ip_packet_filters_str,
+ "Set IP packet filters (allowed keys: session-id, packet-filter, packet-mask, filter-id)",
+ "[\"key=value,...\"]"
+ },
{ "query-provisioned-contexts", 0, 0, G_OPTION_ARG_NONE, &query_provisioned_contexts_flag,
"Query provisioned contexts",
NULL
@@ -289,6 +294,7 @@
!!set_connect_deactivate_str +
query_packet_statistics_flag +
!!query_ip_packet_filters_str +
+ !!set_ip_packet_filters_str +
query_provisioned_contexts_flag);
if (n_actions > 1) {
@@ -416,17 +422,18 @@
query_subscriber_ready_status_ready (MbimDevice *device,
GAsyncResult *res)
{
- g_autoptr (MbimMessage) response = NULL;
- g_autoptr (GError) error = NULL;
- MbimSubscriberReadyState ready_state;
- const gchar *ready_state_str;
- g_autofree gchar *subscriber_id = NULL;
- g_autofree gchar *sim_iccid = NULL;
- MbimReadyInfoFlag ready_info;
- g_autofree gchar *ready_info_str = NULL;
- guint32 telephone_numbers_count;
- g_auto(GStrv) telephone_numbers = NULL;
- g_autofree gchar *telephone_numbers_str = NULL;
+ g_autoptr (MbimMessage) response = NULL;
+ g_autoptr (GError) error = NULL;
+ MbimSubscriberReadyState ready_state;
+ const gchar *ready_state_str;
+ g_autofree gchar *subscriber_id = NULL;
+ g_autofree gchar *sim_iccid = NULL;
+ MbimReadyInfoFlag ready_info;
+ g_autofree gchar *ready_info_str = NULL;
+ guint32 telephone_numbers_count;
+ g_auto(GStrv) telephone_numbers = NULL;
+ g_autofree gchar *telephone_numbers_str = NULL;
+ MbimSubscriberReadyStatusFlag flags;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -435,18 +442,40 @@
return;
}
- if (!mbim_message_subscriber_ready_status_response_parse (
- response,
- &ready_state,
- &subscriber_id,
- &sim_iccid,
- &ready_info,
- &telephone_numbers_count,
- &telephone_numbers,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 3.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_v3_subscriber_ready_status_response_parse (response,
+ &ready_state,
+ &flags,
+ &subscriber_id,
+ &sim_iccid,
+ &ready_info,
+ &telephone_numbers_count,
+ &telephone_numbers,
+ &error)) {
+
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 3.0 Subscriber State");
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_subscriber_ready_status_response_parse (response,
+ &ready_state,
+ &subscriber_id,
+ &sim_iccid,
+ &ready_info,
+ &telephone_numbers_count,
+ &telephone_numbers,
+ &error)) {
+
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 1.0 Subscriber State");
}
telephone_numbers_str = (telephone_numbers ? g_strjoinv (", ", telephone_numbers) : NULL);
@@ -466,6 +495,14 @@
VALIDATE_UNKNOWN (ready_info_str),
telephone_numbers_count, VALIDATE_UNKNOWN (telephone_numbers_str));
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_autofree gchar *flags_str = NULL;
+
+ flags_str = mbim_subscriber_ready_status_flag_build_string_from_mask (flags);
+ g_print ("\t Flags: '%s'\n",
+ VALIDATE_UNKNOWN (flags_str));
+ }
+
shutdown (TRUE);
}
@@ -678,7 +715,13 @@
}
if (pin_type && (g_strv_length (split) == n_max)) {
- new_pin_type = mbimcli_read_pintype_from_string (split[n++]);
+ const gchar *pin_type_str;
+
+ pin_type_str = split[n++];
+ if (!mbimcli_read_pin_type_from_string (pin_type_str, &new_pin_type)) {
+ g_printerr ("error: couldn't parse input pin-type: %s\n", pin_type_str);
+ return FALSE;
+ }
if (new_pin_type == MBIM_PIN_TYPE_UNKNOWN ||
(*pin_type == MBIM_PIN_TYPE_PIN1 && new_pin_type >= MBIM_PIN_TYPE_PUK1) ||
(*pin_type == MBIM_PIN_TYPE_PUK1 && new_pin_type < MBIM_PIN_TYPE_PUK1)) {
@@ -843,14 +886,16 @@
GAsyncResult *res,
gpointer user_data)
{
- g_autoptr(MbimMessage) response = NULL;
- g_autoptr(GError) error = NULL;
- guint32 session_id;
- MbimActivationState activation_state;
- MbimVoiceCallState voice_call_state;
- MbimContextIpType ip_type;
- const MbimUuid *context_type;
- guint32 nw_error;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint32 session_id;
+ MbimActivationState activation_state;
+ MbimVoiceCallState voice_call_state;
+ MbimContextIpType ip_type;
+ MbimAccessMediaType media_type = MBIM_ACCESS_MEDIA_TYPE_UNKNOWN;
+ g_autofree gchar *access_string = NULL;
+ const MbimUuid *context_type;
+ guint32 nw_error;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -859,18 +904,37 @@
return;
}
- if (!mbim_message_connect_response_parse (
- response,
- &session_id,
- &activation_state,
- &voice_call_state,
- &ip_type,
- &context_type,
- &nw_error,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_v3_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ &voice_call_state,
+ &ip_type,
+ &context_type,
+ &nw_error,
+ &media_type,
+ &access_string,
+ NULL, /* unnamed IEs ignored */
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ } else {
+ if (!mbim_message_connect_response_parse (
+ response,
+ &session_id,
+ &activation_state,
+ &voice_call_state,
+ &ip_type,
+ &context_type,
+ &nw_error,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
}
switch (GPOINTER_TO_UINT (user_data)) {
@@ -901,6 +965,13 @@
VALIDATE_UNKNOWN (mbim_context_type_get_string (mbim_uuid_to_context_type (context_type))),
VALIDATE_UNKNOWN (mbim_nw_error_get_string (nw_error)));
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_print ("\tAccess media type: '%s'\n"
+ "\t Access string: '%s'\n",
+ VALIDATE_UNKNOWN (mbim_access_media_type_get_string (media_type)),
+ access_string);
+ }
+
if (GPOINTER_TO_UINT (user_data) == CONNECT) {
ip_configuration_query (device, NULL, session_id);
return;
@@ -913,11 +984,12 @@
ip_packet_filters_ready (MbimDevice *device,
GAsyncResult *res)
{
- g_autoptr(MbimMessage) response = NULL;
- g_autoptr(GError) error = NULL;
- g_autoptr(MbimPacketFilterArray) filters = NULL;
- guint32 filters_count;
- guint32 i;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ g_autoptr(MbimPacketFilterArray) filters = NULL;
+ g_autoptr(MbimPacketFilterV3Array) filters_v3 = NULL;
+ guint32 filters_count;
+ guint32 i;
response = mbim_device_command_finish (device, res, &error);
if (!response ||
@@ -927,76 +999,65 @@
return;
}
- if (!mbim_message_ip_packet_filters_response_parse (
- response,
- NULL, /* sessionid */
- &filters_count,
- &filters,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 3.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_v3_ip_packet_filters_response_parse (
+ response,
+ NULL, /* sessionid */
+ &filters_count,
+ &filters_v3,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 3.0 IP Packet Filters");
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_ip_packet_filters_response_parse (
+ response,
+ NULL, /* sessionid */
+ &filters_count,
+ &filters,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 1.0 IP Packet Filters");
}
- g_print ("\n[%s] IP packet filters: (%u)\n", mbim_device_get_path_display (device), filters_count);
+ g_print ("[%s] IP packet filters: (%u)\n", mbim_device_get_path_display (device), filters_count);
for (i = 0; i < filters_count; i++) {
g_autofree gchar *packet_filter = NULL;
- g_autofree gchar *packet_mask = NULL;
+ g_autofree gchar *packet_mask = NULL;
+ guint32 filter_size = 0;
- packet_filter = mbim_common_str_hex (filters[i]->packet_filter, filters[i]->filter_size, ' ');
- packet_mask = mbim_common_str_hex (filters[i]->packet_mask, filters[i]->filter_size, ' ');
+ if (filters_v3) {
+ filter_size = filters_v3[i]->filter_size;
+ packet_filter = mbim_common_str_hex (filters_v3[i]->packet_filter, filter_size, ' ');
+ packet_mask = mbim_common_str_hex (filters_v3[i]->packet_mask, filter_size, ' ');
+ } else if (filters) {
+ filter_size = filters[i]->filter_size;
+ packet_filter = mbim_common_str_hex (filters[i]->packet_filter, filter_size, ' ');
+ packet_mask = mbim_common_str_hex (filters[i]->packet_mask, filter_size, ' ');
+ } else
+ g_assert_not_reached ();
- g_print ("\n");
- g_print ("\tFilter size: %u\n", filters[i]->filter_size);
- g_print ("\tPacket filter: %s\n", VALIDATE_UNKNOWN (packet_filter));
- g_print ("\tPacket mask: %s\n", VALIDATE_UNKNOWN (packet_mask));
+ g_print ("Filter %u:\n", i);
+ g_print ("\tFilter size : %u\n", filter_size);
+ g_print ("\tPacket filter : %s\n", VALIDATE_UNKNOWN (packet_filter));
+ g_print ("\tPacket mask : %s\n", VALIDATE_UNKNOWN (packet_mask));
+ if (filters_v3)
+ g_print ("\tFilter ID : %u\n", filters_v3[i]->filter_id);
}
shutdown (TRUE);
}
static gboolean
-mbim_auth_protocol_from_string (const gchar *str,
- MbimAuthProtocol *auth_protocol)
-{
- if (g_ascii_strcasecmp (str, "PAP") == 0) {
- *auth_protocol = MBIM_AUTH_PROTOCOL_PAP;
- return TRUE;
- }
- if (g_ascii_strcasecmp (str, "CHAP") == 0) {
- *auth_protocol = MBIM_AUTH_PROTOCOL_CHAP;
- return TRUE;
- }
- if (g_ascii_strcasecmp (str, "MSCHAPV2") == 0) {
- *auth_protocol = MBIM_AUTH_PROTOCOL_MSCHAPV2;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-mbim_context_ip_type_from_string (const gchar *str,
- MbimContextIpType *ip_type)
-{
- if (g_ascii_strcasecmp (str, "ipv4") == 0) {
- *ip_type = MBIM_CONTEXT_IP_TYPE_IPV4;
- return TRUE;
- }
- if (g_ascii_strcasecmp (str, "ipv6") == 0) {
- *ip_type = MBIM_CONTEXT_IP_TYPE_IPV6;
- return TRUE;
- }
- if (g_ascii_strcasecmp (str, "ipv4v6") == 0) {
- *ip_type = MBIM_CONTEXT_IP_TYPE_IPV4V6;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
connect_session_id_parse (const gchar *str,
gboolean allow_empty,
guint32 *session_id,
@@ -1036,18 +1097,209 @@
}
typedef struct {
- guint32 session_id;
- gchar *apn;
- MbimAuthProtocol auth_protocol;
- gchar *username;
- gchar *password;
- MbimContextIpType ip_type;
+ gboolean v3;
+ guint32 session_id;
+ GPtrArray *array;
+ gchar *tmp_packet_filter;
+ gchar *tmp_packet_mask;
+ gchar *tmp_filter_id;
+} SetIpPacketFiltersProperties;
+
+static void
+mbim_packet_filter_v3_free (MbimPacketFilterV3 *var)
+{
+ if (!var)
+ return;
+
+ g_free (var->packet_filter);
+ g_free (var->packet_mask);
+ g_free (var);
+}
+
+static void
+mbim_packet_filter_free (MbimPacketFilter *var)
+{
+ if (!var)
+ return;
+
+ g_free (var->packet_filter);
+ g_free (var->packet_mask);
+ g_free (var);
+}
+
+static void
+set_ip_packet_filters_properties_clear (SetIpPacketFiltersProperties *props)
+{
+ g_free (props->tmp_packet_filter);
+ g_free (props->tmp_packet_mask);
+ g_free (props->tmp_filter_id);
+ g_ptr_array_unref (props->array);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(SetIpPacketFiltersProperties, set_ip_packet_filters_properties_clear);
+
+static gboolean
+check_filter_add (SetIpPacketFiltersProperties *props,
+ GError **error)
+{
+ g_autofree guint8 *packet_filter = NULL;
+ gsize packet_filter_size = 0;
+ g_autofree guint8 *packet_mask = NULL;
+ gsize packet_mask_size = 0;
+
+ if (!props->tmp_packet_filter) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'packet-filter' is missing");
+ return FALSE;
+ }
+
+ if (!props->tmp_packet_mask) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'packet-mask' is missing");
+ return FALSE;
+ }
+
+ if (!props->v3 && props->tmp_filter_id) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'filter-id' is specific to MBIMEx v3.0");
+ return FALSE;
+ }
+
+ if (props->v3 && !props->tmp_filter_id) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'filter-id' is missing");
+ return FALSE;
+ }
+
+ packet_filter = mbimcli_read_buffer_from_string (props->tmp_packet_filter, -1, &packet_filter_size, error);
+ if (!packet_filter)
+ return FALSE;
+
+ packet_mask = mbimcli_read_buffer_from_string (props->tmp_packet_mask, -1, &packet_mask_size, error);
+ if (!packet_mask)
+ return FALSE;
+
+ if (packet_filter_size != packet_mask_size) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Option 'packet-filter' and 'packet-mask' must have same size");
+ return FALSE;
+ }
+
+ if (props->v3) {
+ MbimPacketFilterV3 *filter;
+ guint filter_id;
+
+ if (!mbimcli_read_uint_from_string (props->tmp_filter_id, &filter_id)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Failed to parse 'filter-id' field as an integer");
+ return FALSE;
+ }
+
+ filter = g_new0 (MbimPacketFilterV3, 1);
+ filter->filter_size = packet_filter_size;
+ filter->packet_filter = g_steal_pointer (&packet_filter);
+ filter->packet_mask = g_steal_pointer (&packet_mask);
+ filter->filter_id = filter_id;
+ g_ptr_array_add (props->array, filter);
+ } else {
+ MbimPacketFilter *filter;
+
+ filter = g_new0 (MbimPacketFilter, 1);
+ filter->filter_size = packet_filter_size;
+ filter->packet_filter = g_steal_pointer (&packet_filter);
+ filter->packet_mask = g_steal_pointer (&packet_mask);
+ g_ptr_array_add (props->array, filter);
+ }
+
+ g_clear_pointer (&props->tmp_filter_id, g_free);
+ g_clear_pointer (&props->tmp_packet_filter, g_free);
+ g_clear_pointer (&props->tmp_packet_mask, g_free);
+
+ return TRUE;
+}
+
+static gboolean
+set_ip_packet_filters_properties_handle (const gchar *key,
+ const gchar *value,
+ GError **error,
+ gpointer user_data)
+{
+ SetIpPacketFiltersProperties *props = user_data;
+
+ if (g_ascii_strcasecmp (key, "session-id") == 0) {
+ if (!connect_session_id_parse (value, FALSE, &props->session_id, error))
+ return FALSE;
+ } else if (g_ascii_strcasecmp (key, "packet-filter") == 0) {
+ if (props->tmp_packet_filter) {
+ if (!check_filter_add (props, error))
+ return FALSE;
+ g_clear_pointer (&props->tmp_packet_filter, g_free);
+ }
+ props->tmp_packet_filter = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "packet-mask") == 0) {
+ if (props->tmp_packet_mask) {
+ if (!check_filter_add (props, error))
+ return FALSE;
+ g_clear_pointer (&props->tmp_packet_mask, g_free);
+ }
+ props->tmp_packet_mask = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "filter-id") == 0) {
+ if (props->tmp_filter_id) {
+ if (!check_filter_add (props, error))
+ return FALSE;
+ g_clear_pointer (&props->tmp_filter_id, g_free);
+ }
+ props->tmp_filter_id = g_strdup (value);
+ } else {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "unrecognized option '%s'", key);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+set_ip_packet_filters_parse (const gchar *str,
+ SetIpPacketFiltersProperties *props,
+ MbimDevice *device)
+{
+ g_auto(GStrv) split = NULL;
+ g_autoptr(GError) error = NULL;
+
+ if (!mbimcli_parse_key_value_string (str,
+ &error,
+ set_ip_packet_filters_properties_handle,
+ props)) {
+ g_printerr ("error: couldn't parse input string: %s\n", error->message);
+ return FALSE;
+ }
+
+ if ((props->tmp_packet_filter || props->tmp_packet_mask) &&
+ !check_filter_add (props, &error)) {
+ g_printerr ("error: failed to add last packet filter item: %s\n", error->message);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+typedef struct {
+ guint32 session_id;
+ gchar *access_string;
+ MbimAuthProtocol auth_protocol;
+ gchar *username;
+ gchar *password;
+ MbimContextIpType ip_type;
+ MbimCompression compression;
+ MbimContextType context_type;
+ MbimAccessMediaType media_type;
} ConnectActivateProperties;
static void
connect_activate_properties_clear (ConnectActivateProperties *props)
{
- g_free (props->apn);
+ g_free (props->access_string);
g_free (props->username);
g_free (props->password);
}
@@ -1062,49 +1314,64 @@
{
ConnectActivateProperties *props = user_data;
- /* APN may be empty */
- if ((g_ascii_strcasecmp (key, "apn") != 0) && (!value || !value[0])) {
- g_set_error (error,
- MBIM_CORE_ERROR,
- MBIM_CORE_ERROR_FAILED,
- "key '%s' required a value",
- key);
+ /* access-string/apn may be empty */
+ if ((g_ascii_strcasecmp (key, "access-string") != 0) &&
+ (g_ascii_strcasecmp (key, "apn") != 0) &&
+ (!value || !value[0])) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "key '%s' required a value", key);
return FALSE;
}
if (g_ascii_strcasecmp (key, "session-id") == 0) {
if (!connect_session_id_parse (value, FALSE, &props->session_id, error))
return FALSE;
- } else if (g_ascii_strcasecmp (key, "apn") == 0 && !props->apn) {
- props->apn = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "apn") == 0) {
+ g_printerr ("warning: key 'apn' is deprecated, use 'access-string' instead\n");
+ g_free (props->access_string);
+ props->access_string = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "access-string") == 0) {
+ g_free (props->access_string);
+ props->access_string = g_strdup (value);
} else if (g_ascii_strcasecmp (key, "auth") == 0) {
- if (!mbim_auth_protocol_from_string (value, &props->auth_protocol)) {
- g_set_error (error,
- MBIM_CORE_ERROR,
- MBIM_CORE_ERROR_FAILED,
- "unknown auth protocol '%s'",
- value);
+ if (!mbimcli_read_auth_protocol_from_string (value, &props->auth_protocol)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown auth: '%s'", value);
return FALSE;
}
- } else if (g_ascii_strcasecmp (key, "username") == 0 && !props->username) {
+ } else if (g_ascii_strcasecmp (key, "username") == 0) {
+ g_free (props->username);
props->username = g_strdup (value);
- } else if (g_ascii_strcasecmp (key, "password") == 0 && !props->password) {
+ } else if (g_ascii_strcasecmp (key, "password") == 0) {
+ g_free (props->password);
props->password = g_strdup (value);
} else if (g_ascii_strcasecmp (key, "ip-type") == 0) {
- if (!mbim_context_ip_type_from_string (value, &props->ip_type)) {
- g_set_error (error,
- MBIM_CORE_ERROR,
- MBIM_CORE_ERROR_FAILED,
- "unknown ip type '%s'",
- value);
+ if (!mbimcli_read_context_ip_type_from_string (value, &props->ip_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown ip-type: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "compression") == 0) {
+ if (!mbimcli_read_compression_from_string (value, &props->compression)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown compression: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "context-type") == 0) {
+ if (!mbimcli_read_context_type_from_string (value, &props->context_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown context-type: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "media-type") == 0) {
+ if (!mbimcli_read_access_media_type_from_string (value, &props->media_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown media-type: '%s'", value);
return FALSE;
}
} else {
- g_set_error (error,
- MBIM_CORE_ERROR,
- MBIM_CORE_ERROR_FAILED,
- "unrecognized or duplicate option '%s'",
- key);
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "unrecognized option '%s'", key);
return FALSE;
}
@@ -1112,32 +1379,13 @@
}
static gboolean
-set_connect_activate_parse (const gchar *str,
- guint32 *session_id,
- gchar **apn,
- MbimAuthProtocol *auth_protocol,
- gchar **username,
- gchar **password,
- MbimContextIpType *ip_type)
+set_connect_activate_parse (const gchar *str,
+ ConnectActivateProperties *props,
+ MbimDevice *device)
{
- g_auto(ConnectActivateProperties) props = {
- .session_id = 0,
- .apn = NULL,
- .auth_protocol = MBIM_AUTH_PROTOCOL_NONE,
- .username = NULL,
- .password = NULL,
- .ip_type = MBIM_CONTEXT_IP_TYPE_DEFAULT
- };
g_auto(GStrv) split = NULL;
g_autoptr(GError) error = NULL;
- g_assert (session_id != NULL);
- g_assert (apn != NULL);
- g_assert (auth_protocol != NULL);
- g_assert (username != NULL);
- g_assert (password != NULL);
- g_assert (ip_type != NULL);
-
if (strchr (str, '=')) {
/* New key=value format */
if (!mbimcli_parse_key_value_string (str,
@@ -1151,52 +1399,46 @@
/* Old non key=value format, like this:
* "[(APN),(PAP|CHAP|MSCHAPV2),(Username),(Password)]"
*/
+ g_printerr ("warning: positional input arguments format is deprecated, use key-value format instead\n");
split = g_strsplit (str, ",", -1);
if (g_strv_length (split) > 4) {
g_printerr ("error: couldn't parse input string, too many arguments\n");
return FALSE;
- }
+ }
if (g_strv_length (split) > 0) {
/* APN */
- props.apn = g_strdup (split[0]);
+ props->access_string = g_strdup (split[0]);
/* Use authentication method */
if (split[1]) {
- if (!mbim_auth_protocol_from_string (split[1], &props.auth_protocol)) {
+ if (!mbimcli_read_auth_protocol_from_string (split[1], &props->auth_protocol)) {
g_printerr ("error: couldn't parse input string, unknown auth protocol '%s'\n", split[1]);
return FALSE;
}
/* Username */
if (split[2]) {
- props.username = g_strdup (split[2]);
+ props->username = g_strdup (split[2]);
/* Password */
- props.password = g_strdup (split[3]);
+ props->password = g_strdup (split[3]);
}
}
}
- }
- if (props.auth_protocol == MBIM_AUTH_PROTOCOL_NONE) {
- if (props.username || props.password) {
- g_printerr ("error: username or password requires an auth protocol\n");
- return FALSE;
- }
- } else {
- if (!props.username) {
- g_printerr ("error: auth protocol requires a username\n");
- return FALSE;
+ if (props->auth_protocol == MBIM_AUTH_PROTOCOL_NONE) {
+ if (props->username || props->password) {
+ g_printerr ("error: username or password requires an auth protocol\n");
+ return FALSE;
+ }
+ } else {
+ if (!props->username) {
+ g_printerr ("error: auth protocol requires a username\n");
+ return FALSE;
+ }
}
}
- *session_id = props.session_id;
- *apn = g_steal_pointer (&props.apn);
- *auth_protocol = props.auth_protocol;
- *username = g_steal_pointer (&props.username);
- *password = g_steal_pointer (&props.password);
- *ip_type = props.ip_type;
-
return TRUE;
}
@@ -1371,6 +1613,7 @@
g_autofree gchar *roaming_text = NULL;
MbimRegistrationFlag registration_flag;
g_autofree gchar *registration_flag_str = NULL;
+ MbimDataClass preferred_data_classes;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -1379,20 +1622,44 @@
return;
}
- if (!mbim_message_register_state_response_parse (response,
- &nw_error,
- ®ister_state,
- ®ister_mode,
- &available_data_classes,
- &cellular_class,
- &provider_id,
- &provider_name,
- &roaming_text,
- ®istration_flag,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 2.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ if (!mbim_message_ms_basic_connect_v2_register_state_response_parse (response,
+ &nw_error,
+ ®ister_state,
+ ®ister_mode,
+ &available_data_classes,
+ &cellular_class,
+ &provider_id,
+ &provider_name,
+ &roaming_text,
+ ®istration_flag,
+ &preferred_data_classes,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 2.0 Register State");
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_register_state_response_parse (response,
+ &nw_error,
+ ®ister_state,
+ ®ister_mode,
+ &available_data_classes,
+ &cellular_class,
+ &provider_id,
+ &provider_name,
+ &roaming_text,
+ ®istration_flag,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 1.0 Register State");
}
if (GPOINTER_TO_UINT (user_data))
@@ -1424,6 +1691,14 @@
VALIDATE_UNKNOWN (roaming_text),
VALIDATE_UNKNOWN (registration_flag_str));
+ if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ g_autofree gchar *preferred_data_classes_str = NULL;
+
+ preferred_data_classes_str = mbim_data_class_build_string_from_mask (preferred_data_classes);
+ g_print ("\tPreferred data classes: '%s'\n",
+ VALIDATE_UNKNOWN (preferred_data_classes_str));
+ }
+
shutdown (TRUE);
}
@@ -1431,13 +1706,15 @@
signal_state_ready (MbimDevice *device,
GAsyncResult *res)
{
- g_autoptr(MbimMessage) response = NULL;
- g_autoptr(GError) error = NULL;
- guint32 rssi;
- guint32 error_rate;
- guint32 signal_strength_interval;
- guint32 rssi_threshold;
- guint32 error_rate_threshold;
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint32 rssi;
+ guint32 error_rate;
+ guint32 signal_strength_interval;
+ guint32 rssi_threshold;
+ guint32 error_rate_threshold;
+ guint32 rsrp_snr_count;
+ g_autoptr(MbimRsrpSnrInfoArray) rsrp_snr = NULL;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -1446,16 +1723,35 @@
return;
}
- if (!mbim_message_signal_state_response_parse (response,
- &rssi,
- &error_rate,
- &signal_strength_interval,
- &rssi_threshold,
- &error_rate_threshold,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 2.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ if (!mbim_message_ms_basic_connect_v2_signal_state_response_parse (response,
+ &rssi,
+ &error_rate,
+ &signal_strength_interval,
+ &rssi_threshold,
+ &error_rate_threshold,
+ &rsrp_snr_count,
+ &rsrp_snr,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_signal_state_response_parse (response,
+ &rssi,
+ &error_rate,
+ &signal_strength_interval,
+ &rssi_threshold,
+ &error_rate_threshold,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
}
g_print ("[%s] Signal state:\n"
@@ -1474,6 +1770,52 @@
else
g_print ("\t Error rate threshold: '%u'\n", error_rate_threshold);
+ if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ g_print ("\n");
+ if (rsrp_snr_count == 0) {
+ g_print ("[%s] RSRP/SNR info: 'n/a'\n", mbim_device_get_path_display (device));
+ } else {
+ guint i;
+
+ for (i = 0; i < rsrp_snr_count; i++) {
+ g_autofree gchar *system_type_str = NULL;
+ MbimRsrpSnrInfo *info;
+
+ info = rsrp_snr[i];
+
+ system_type_str = mbim_data_class_build_string_from_mask (info->system_type);
+ g_print ("[%s] RSRP/SNR info: '%s'\n",
+ mbim_device_get_path_display (device),
+ system_type_str);
+
+ if (info->rsrp >= 127)
+ g_print ("\t RSRP: 'unknown'\n");
+ else
+ g_print ("\t RSRP: '%d dBm'\n", -157 + info->rsrp);
+
+ if (info->snr >= 128)
+ g_print ("\t SNR: 'unknown'\n");
+ else
+ g_print ("\t SNR: '%.1lf dB'\n", -23.5 + (info->snr * 0.5));
+
+ if (info->rsrp_threshold == 0)
+ g_print ("\t RSRP threshold: 'default'\n");
+ else if (info->rsrp_threshold == 0xFFFFFFFF)
+ g_print ("\t RSRP threshold: 'unspecified'\n");
+ else
+ g_print ("\t RSRP threshold: '%u'\n", info->rsrp_threshold);
+
+ if (info->snr_threshold == 0)
+ g_print ("\t SNR threshold: 'default'\n");
+ else if (info->snr_threshold == 0xFFFFFFFF)
+ g_print ("\t SNR threshold: 'unspecified'\n");
+ else
+ g_print ("\t SNR threshold: '%u'\n", info->snr_threshold);
+ g_print ("\n");
+ }
+ }
+ }
+
shutdown (TRUE);
}
@@ -1493,9 +1835,13 @@
guint32 nw_error;
MbimPacketServiceState packet_service_state;
MbimDataClass highest_available_data_class;
+ MbimDataClassV3 highest_available_data_class_v3;
g_autofree gchar *highest_available_data_class_str = NULL;
guint64 uplink_speed;
guint64 downlink_speed;
+ MbimFrequencyRange frequency_range;
+ MbimDataSubclass data_subclass;
+ g_autoptr(MbimTai) tai = NULL;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -1504,16 +1850,54 @@
return;
}
- if (!mbim_message_packet_service_response_parse (response,
- &nw_error,
- &packet_service_state,
- &highest_available_data_class,
- &uplink_speed,
- &downlink_speed,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 3.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_v3_packet_service_response_parse (response,
+ &nw_error,
+ &packet_service_state,
+ &highest_available_data_class_v3,
+ &uplink_speed,
+ &downlink_speed,
+ &frequency_range,
+ &data_subclass,
+ &tai,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 3.0 Packet Service");
+ }
+ /* MBIMEx 2.0 support */
+ else if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ if (!mbim_message_ms_basic_connect_v2_packet_service_response_parse (response,
+ &nw_error,
+ &packet_service_state,
+ &highest_available_data_class,
+ &uplink_speed,
+ &downlink_speed,
+ &frequency_range,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 2.0 Packet Service");
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_packet_service_response_parse (response,
+ &nw_error,
+ &packet_service_state,
+ &highest_available_data_class,
+ &uplink_speed,
+ &downlink_speed,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIM 1.0 Packet Service");
}
switch (GPOINTER_TO_UINT (user_data)) {
@@ -1529,7 +1913,10 @@
break;
}
- highest_available_data_class_str = mbim_data_class_build_string_from_mask (highest_available_data_class);
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0))
+ highest_available_data_class_str = mbim_data_class_v3_build_string_from_mask (highest_available_data_class_v3);
+ else
+ highest_available_data_class_str = mbim_data_class_build_string_from_mask (highest_available_data_class);
g_print ("[%s] Packet service status:\n"
"\t Network error: '%s'\n"
@@ -1544,6 +1931,57 @@
uplink_speed,
downlink_speed);
+ if (mbim_device_check_ms_mbimex_version (device, 2, 0)) {
+ g_autofree gchar *frequency_range_str = NULL;
+
+ frequency_range_str = mbim_frequency_range_build_string_from_mask (frequency_range);
+ g_print ("\t Frequency range: '%s'\n",
+ VALIDATE_UNKNOWN (frequency_range_str));
+ }
+
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_autofree gchar *data_subclass_str = NULL;
+ g_autofree gchar *tai_plmn_mcc_str = NULL;
+ g_autofree gchar *tai_plmn_mnc_str = NULL;
+
+ /* Mobile Country Code of 3 decimal digits; The
+ * least significant 12 bits contains BCD-encoded
+ * 3 decimal digits sequentially for the MCC, with
+ * the last digit of the MCC in the least significant
+ * 4 bits. The unused bits in the UINT16 integer
+ * must be zeros. */
+ tai_plmn_mcc_str = g_strdup_printf ("%03x", tai->plmn_mcc & 0x0FFF);
+
+ /* Mobile Network Code of either 3 or 2 decimal
+ * digits; The most significant bit indicates
+ * whether the MNC has 2 decimal digits or 3
+ * decimal digits. If this bit has 1, the MNC has 2
+ * decimal digits and the least significant 8 bits
+ * contains them in BCD-encoded form
+ * sequentially, with the last digit of the MNC in
+ * the least significant 4 bits. If the most
+ * significant bit has 0, the MNC has 3 decimal
+ * digits and the least significant 12 bits contains
+ * them in BCD-encoded form sequentially, with
+ * the last digit of the MNC in the least
+ * esignificant 4 bits. The unused bits in the
+ * UINT16 integer must be zeros. */
+ if (tai->plmn_mnc & 0x8000)
+ tai_plmn_mnc_str = g_strdup_printf ("%02x", tai->plmn_mnc & 0x00FF);
+ else
+ tai_plmn_mnc_str = g_strdup_printf ("%03x", tai->plmn_mnc & 0x0FFF);
+
+ data_subclass_str = mbim_data_subclass_build_string_from_mask (data_subclass);
+ g_print ("\t Data sub class: '%s'\n"
+ "\t TAI PLMN MCC: '%s'\n"
+ "\t TAI PLMN MNC: '%s'\n"
+ "\t TAI TAC: '%u'\n",
+ VALIDATE_UNKNOWN (data_subclass_str),
+ tai_plmn_mcc_str,
+ tai_plmn_mnc_str,
+ tai->tac);
+ }
+
shutdown (TRUE);
}
@@ -1889,10 +2327,7 @@
/* Launch automatic registration? */
if (set_register_state_automatic_flag) {
- request = mbim_message_register_state_set_new (NULL,
- MBIM_REGISTER_ACTION_AUTOMATIC,
- 0,
- &error);
+ request = mbim_message_register_state_set_new (NULL, MBIM_REGISTER_ACTION_AUTOMATIC, 0, &error);
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
@@ -1972,13 +2407,18 @@
return;
}
- request = mbim_message_connect_query_new (session_id,
- MBIM_ACTIVATION_STATE_UNKNOWN,
- MBIM_VOICE_CALL_STATE_NONE,
- MBIM_CONTEXT_IP_TYPE_DEFAULT,
- mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
- 0,
- &error);
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ request = mbim_message_ms_basic_connect_v3_connect_query_new (session_id,
+ &error);
+ } else {
+ request = mbim_message_connect_query_new (session_id,
+ MBIM_ACTIVATION_STATE_UNKNOWN,
+ MBIM_VOICE_CALL_STATE_NONE,
+ MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
+ 0,
+ &error);
+ }
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
@@ -1996,34 +2436,48 @@
/* Connect? */
if (set_connect_activate_str) {
- guint32 session_id = 0;
- g_autofree gchar *apn = NULL;
- MbimAuthProtocol auth_protocol;
- g_autofree gchar *username = NULL;
- g_autofree gchar *password = NULL;
- MbimContextIpType ip_type = MBIM_CONTEXT_IP_TYPE_DEFAULT;
+ g_auto(ConnectActivateProperties) props = {
+ .session_id = 0,
+ .access_string = NULL,
+ .auth_protocol = MBIM_AUTH_PROTOCOL_NONE,
+ .username = NULL,
+ .password = NULL,
+ .ip_type = MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ .compression = MBIM_COMPRESSION_NONE,
+ .context_type = MBIM_CONTEXT_TYPE_INTERNET,
+ .media_type = MBIM_ACCESS_MEDIA_TYPE_UNKNOWN,
+ };
- if (!set_connect_activate_parse (set_connect_activate_str,
- &session_id,
- &apn,
- &auth_protocol,
- &username,
- &password,
- &ip_type)) {
+ if (!set_connect_activate_parse (set_connect_activate_str, &props, device)) {
shutdown (FALSE);
return;
}
- request = mbim_message_connect_set_new (session_id,
- MBIM_ACTIVATION_COMMAND_ACTIVATE,
- apn,
- username,
- password,
- MBIM_COMPRESSION_NONE,
- auth_protocol,
- ip_type,
- mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
- &error);
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ request = mbim_message_ms_basic_connect_v3_connect_set_new (props.session_id,
+ MBIM_ACTIVATION_COMMAND_ACTIVATE,
+ props.compression,
+ props.auth_protocol,
+ props.ip_type,
+ mbim_uuid_from_context_type (props.context_type),
+ props.media_type,
+ props.access_string,
+ props.username,
+ props.password,
+ NULL, /* unnamed IEs */
+ &error);
+ } else {
+ request = mbim_message_connect_set_new (props.session_id,
+ MBIM_ACTIVATION_COMMAND_ACTIVATE,
+ props.access_string,
+ props.username,
+ props.password,
+ props.compression,
+ props.auth_protocol,
+ props.ip_type,
+ mbim_uuid_from_context_type (props.context_type),
+ &error);
+ }
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
@@ -2064,16 +2518,32 @@
return;
}
- request = mbim_message_connect_set_new (session_id,
- MBIM_ACTIVATION_COMMAND_DEACTIVATE,
- NULL,
- NULL,
- NULL,
- MBIM_COMPRESSION_NONE,
- MBIM_AUTH_PROTOCOL_NONE,
- MBIM_CONTEXT_IP_TYPE_DEFAULT,
- mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
- &error);
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ request = mbim_message_ms_basic_connect_v3_connect_set_new (session_id,
+ MBIM_ACTIVATION_COMMAND_DEACTIVATE,
+ MBIM_COMPRESSION_NONE,
+ MBIM_AUTH_PROTOCOL_NONE,
+ MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
+ MBIM_ACCESS_MEDIA_TYPE_UNKNOWN,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &error);
+ } else {
+ request = mbim_message_connect_set_new (session_id,
+ MBIM_ACTIVATION_COMMAND_DEACTIVATE,
+ NULL,
+ NULL,
+ NULL,
+ MBIM_COMPRESSION_NONE,
+ MBIM_AUTH_PROTOCOL_NONE,
+ MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ mbim_uuid_from_context_type (MBIM_CONTEXT_TYPE_INTERNET),
+ &error);
+ }
+
if (!request) {
g_printerr ("error: couldn't create request: %s\n", error->message);
shutdown (FALSE);
@@ -2111,11 +2581,62 @@
return;
}
- request = (mbim_message_ip_packet_filters_query_new (
- session_id,
- 0, /* packet_filters_count */
- NULL, /* packet_filters */
- &error));
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_debug ("Asychronously querying v3.0 IP packet filter......");
+ request = mbim_message_ms_basic_connect_v3_ip_packet_filters_query_new (session_id, 0, NULL, &error);
+ } else {
+ g_debug ("Asychronously querying v1.0 IP packet filter......");
+ request = mbim_message_ip_packet_filters_query_new (session_id, 0, NULL, &error);
+ }
+
+ if (!request) {
+ g_printerr ("error: couldn't create IP packet filters request: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)ip_packet_filters_ready,
+ NULL);
+ return;
+ }
+
+ /* Set IP packet filters? */
+ if (set_ip_packet_filters_str) {
+ g_auto(SetIpPacketFiltersProperties) props = {
+ .v3 = FALSE,
+ .session_id = 0,
+ .array = NULL,
+ };
+
+ props.v3 = mbim_device_check_ms_mbimex_version (device, 3, 0);
+ if (props.v3)
+ props.array = g_ptr_array_new_with_free_func ((GDestroyNotify)mbim_packet_filter_v3_free);
+ else
+ props.array = g_ptr_array_new_with_free_func ((GDestroyNotify)mbim_packet_filter_free);
+
+ if (!set_ip_packet_filters_parse (set_ip_packet_filters_str, &props, device)) {
+ shutdown (FALSE);
+ return;
+ }
+
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_debug ("Asychronously set v3.0 IP packet filter......");
+ request = mbim_message_ms_basic_connect_v3_ip_packet_filters_set_new (props.session_id,
+ props.array->len,
+ (const MbimPacketFilterV3 *const *)props.array->pdata,
+ &error);
+ } else {
+ g_debug ("Asychronously set v1.0 IP packet filter......");
+ request = mbim_message_ip_packet_filters_set_new (props.session_id,
+ props.array->len,
+ (const MbimPacketFilter *const *)props.array->pdata,
+ &error);
+ }
+
if (!request) {
g_printerr ("error: couldn't create IP packet filters request: %s\n", error->message);
shutdown (FALSE);
diff --git a/src/mbimcli/mbimcli-helpers.c b/src/mbimcli/mbimcli-helpers.c
index dd19fe3..4025e53 100644
--- a/src/mbimcli/mbimcli-helpers.c
+++ b/src/mbimcli/mbimcli-helpers.c
@@ -37,6 +37,134 @@
}
gboolean
+mbimcli_read_uint_from_bcd_string (const gchar *str,
+ guint *out)
+{
+ gulong num;
+
+ if (!str || !str[0])
+ return FALSE;
+
+ /* in bcd, only numeric values (0-9) */
+ for (num = 0; str[num]; num++) {
+ if (!g_ascii_isdigit (str[num]))
+ return FALSE;
+ }
+
+ /* for the numeric values of str, we can just read the string as hex
+ * (base 16) and it will be valid bcd */
+ errno = 0;
+ num = strtoul (str, NULL, 16);
+ if (!errno && num <= G_MAXUINT) {
+ *out = (guint)num;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+mbimcli_read_uint8_from_bcd_string (const gchar *str,
+ guint8 *out)
+{
+ guint num;
+
+ if (!mbimcli_read_uint_from_bcd_string (str, &num) || (num > G_MAXUINT8))
+ return FALSE;
+
+ *out = (guint8)num;
+ return TRUE;
+}
+
+gboolean
+mbimcli_read_boolean_from_string (const gchar *value,
+ gboolean *out)
+{
+ if (!g_ascii_strcasecmp (value, "true") || g_str_equal (value, "1") || !g_ascii_strcasecmp (value, "yes")) {
+ *out = TRUE;
+ return TRUE;
+ }
+
+ if (!g_ascii_strcasecmp (value, "false") || g_str_equal (value, "0") || !g_ascii_strcasecmp (value, "no")) {
+ *out = FALSE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/* Based on ModemManager's mm_utils_hexstr2bin() */
+
+static gint
+hex2num (gchar c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ return -1;
+}
+
+static gint
+hex2byte (const gchar *hex)
+{
+ gint a, b;
+
+ a = hex2num (*hex++);
+ if (a < 0)
+ return -1;
+ b = hex2num (*hex++);
+ if (b < 0)
+ return -1;
+ return (a << 4) | b;
+}
+
+guint8 *
+mbimcli_read_buffer_from_string (const gchar *hex,
+ gssize len,
+ gsize *out_len,
+ GError **error)
+{
+ const gchar *ipos = hex;
+ g_autofree guint8 *buf = NULL;
+ gssize i;
+ gint a;
+ guint8 *opos;
+
+ if (len < 0)
+ len = strlen (hex);
+
+ if (len == 0) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Hex conversion failed: empty string");
+ return NULL;
+ }
+
+ /* Length must be a multiple of 2 */
+ if ((len % 2) != 0) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Hex conversion failed: invalid input length");
+ return NULL;
+ }
+
+ opos = buf = g_malloc0 (len / 2);
+ for (i = 0; i < len; i += 2) {
+ a = hex2byte (ipos);
+ if (a < 0) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "Hex byte conversion from '%c%c' failed",
+ ipos[0], ipos[1]);
+ return NULL;
+ }
+ *opos++ = (guint8)a;
+ ipos += 2;
+ }
+ *out_len = len / 2;
+ return g_steal_pointer (&buf);
+}
+
+gboolean
mbimcli_print_ip_config (MbimDevice *device,
MbimMessage *response,
GError **error)
@@ -319,22 +447,85 @@
return TRUE;
}
-MbimPinType
-mbimcli_read_pintype_from_string (const gchar *str)
+gboolean
+mbimcli_parse_sar_config_state_array (const gchar *str,
+ GPtrArray **out)
{
- const gchar *feature;
- gint i;
+ g_autoptr(GPtrArray) config_state_array = NULL;
+ g_autoptr(GRegex) regex = NULL;
+ g_autoptr(GMatchInfo) match_info = NULL;
+ g_autoptr(GError) inner_error = NULL;
- if (str == NULL)
- return MBIM_PIN_TYPE_UNKNOWN;
+ config_state_array = g_ptr_array_new_with_free_func (g_free);
- /* Compare string to nicknames from mbim_pin_type_values */
- i = MBIM_PIN_TYPE_CUSTOM;
- while (NULL != (feature = mbim_pin_type_get_string (i))) {
- if (g_str_equal (feature, str))
- return i;
- i++;
+ if (!str || !str[0]) {
+ *out = NULL;
+ return TRUE;
}
- return MBIM_PIN_TYPE_UNKNOWN;
+ regex = g_regex_new ("\\s*{\\s*(\\d+|all)\\s*,\\s*(\\d+)\\s*}(?:\\s*,)?", G_REGEX_RAW, 0, NULL);
+ g_assert (regex);
+
+ g_regex_match_full (regex, str, strlen (str), 0, 0, &match_info, &inner_error);
+ while (!inner_error && g_match_info_matches (match_info)) {
+ g_autofree MbimSarConfigState *config_state = NULL;
+ g_autofree gchar *antenna_index_str = NULL;
+ g_autofree gchar *backoff_index_str = NULL;
+
+ config_state = g_new (MbimSarConfigState, 1);
+
+ antenna_index_str = g_match_info_fetch (match_info, 1);
+ backoff_index_str = g_match_info_fetch (match_info, 2);
+
+ if (g_ascii_strcasecmp (antenna_index_str, "all") == 0)
+ config_state->antenna_index = 0xFFFFFFFF;
+ else if (!mbimcli_read_uint_from_string (antenna_index_str, &config_state->antenna_index)) {
+ g_printerr ("error: invalid antenna index: '%s'\n", antenna_index_str);
+ return FALSE;
+ }
+ if (!mbimcli_read_uint_from_string (backoff_index_str, &config_state->backoff_index)) {
+ g_printerr ("error: invalid backoff index: '%s'\n", backoff_index_str);
+ return FALSE;
+ }
+
+ g_ptr_array_add (config_state_array, g_steal_pointer (&config_state));
+ g_match_info_next (match_info, &inner_error);
+ }
+
+ if (inner_error) {
+ g_printerr ("error: couldn't match config state array: %s\n", inner_error->message);
+ return FALSE;
+ }
+
+ if (config_state_array->len == 0) {
+ g_printerr ("error: no elements found in the array\n");
+ return FALSE;
+ }
+
+ *out = (config_state_array->len > 0) ? g_steal_pointer (&config_state_array) : NULL;
+ return TRUE;
}
+
+#define MBIMCLI_ENUM_LIST_ITEM(TYPE,TYPE_UNDERSCORE,DESCR) \
+ gboolean \
+ mbimcli_read_## TYPE_UNDERSCORE ##_from_string (const gchar *str, \
+ TYPE *out) \
+ { \
+ GType type; \
+ GEnumClass *enum_class; \
+ GEnumValue *enum_value; \
+ \
+ type = mbim_## TYPE_UNDERSCORE ##_get_type (); \
+ enum_class = G_ENUM_CLASS (g_type_class_ref (type)); \
+ enum_value = g_enum_get_value_by_nick (enum_class, str); \
+ \
+ if (enum_value) \
+ *out = (TYPE)enum_value->value; \
+ else \
+ g_printerr ("error: invalid " DESCR " value given: '%s'\n", str); \
+ \
+ g_type_class_unref (enum_class); \
+ return !!enum_value; \
+ }
+MBIMCLI_ENUM_LIST
+#undef MBIMCLI_ENUM_LIST_ITEM
diff --git a/src/mbimcli/mbimcli-helpers.h b/src/mbimcli/mbimcli-helpers.h
index 39e654d..cf99bb6 100644
--- a/src/mbimcli/mbimcli-helpers.h
+++ b/src/mbimcli/mbimcli-helpers.h
@@ -13,8 +13,20 @@
#ifndef __MBIMCLI_HELPERS_H__
#define __MBIMCLI_HELPERS_H__
-gboolean mbimcli_read_uint_from_string (const gchar *str,
- guint *out);
+gboolean mbimcli_read_uint_from_string (const gchar *str,
+ guint *out);
+gboolean mbimcli_read_uint_from_bcd_string (const gchar *str,
+ guint *out);
+gboolean mbimcli_read_uint8_from_bcd_string (const gchar *str,
+ guint8 *out);
+
+gboolean mbimcli_read_boolean_from_string (const gchar *value,
+ gboolean *out);
+
+guint8 *mbimcli_read_buffer_from_string (const gchar *hex,
+ gssize len,
+ gsize *out_len,
+ GError **error);
gboolean mbimcli_print_ip_config (MbimDevice *device,
MbimMessage *response,
@@ -30,6 +42,33 @@
MbimParseKeyValueForeachFn callback,
gpointer user_data);
-MbimPinType mbimcli_read_pintype_from_string (const gchar *str);
+gboolean mbimcli_parse_sar_config_state_array (const gchar *str,
+ GPtrArray **out);
+
+/* Common helpers to read enums from strings */
+
+#define MBIMCLI_ENUM_LIST \
+ MBIMCLI_ENUM_LIST_ITEM (MbimPinType, pin_type, "pin type") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextType, context_type, "context type") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextIpType, context_ip_type, "context ip type") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextState, context_state, "context state") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextRoamingControl, context_roaming_control, "context roaming control") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextMediaType, context_media_type, "context media type") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextSource, context_source, "context source") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimContextOperation, context_operation, "context operation") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimAuthProtocol, auth_protocol, "auth protocol") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimCompression, compression, "compression") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimSarControlMode, sar_control_mode, "sar control mode") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimSarBackoffState, sar_backoff_state, "sar backoff state") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimMicoMode, mico_mode, "mico mode") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimDrxCycle, drx_cycle, "drx cycle") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimLadnInfo, ladn_info, "ladn info") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimDefaultPduActivationHint, default_pdu_activation_hint, "default pdu activation hint") \
+ MBIMCLI_ENUM_LIST_ITEM (MbimAccessMediaType, access_media_type, "access media type")
+
+#define MBIMCLI_ENUM_LIST_ITEM(TYPE,TYPE_UNDERSCORE,DESCR) \
+ gboolean mbimcli_read_## TYPE_UNDERSCORE ##_from_string (const gchar *str, TYPE *out);
+MBIMCLI_ENUM_LIST
+#undef MBIMCLI_ENUM_LIST_ITEM
#endif /* __MBIMCLI_H__ */
diff --git a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
old mode 100755
new mode 100644
index 46a2cef..3149b70
--- a/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
+++ b/src/mbimcli/mbimcli-ms-basic-connect-extensions.c
@@ -22,6 +22,7 @@
#include "mbim-common.h"
#include "mbimcli.h"
+#include "mbimcli-helpers.h"
/* Context */
typedef struct {
@@ -40,6 +41,15 @@
static gchar *query_slot_info_status_str;
static gboolean query_device_slot_mappings_flag;
static gchar *set_device_slot_mappings_str;
+static gboolean query_location_info_status_flag;
+static gboolean query_provisioned_contexts_flag;
+static gchar *set_provisioned_contexts_str;
+static gboolean query_base_stations_flag;
+static gchar *query_version_str;
+static gboolean query_registration_parameters_flag;
+static gchar *set_registration_parameters_str;
+static gboolean query_modem_configuration_flag;
+static gboolean query_wake_reason_flag;
static gboolean query_pco_arg_parse (const gchar *option_name,
const gchar *value,
@@ -84,8 +94,43 @@
"Query device slot mappings",
NULL
},
-
- { NULL }
+ { "ms-query-location-info-status", 0, 0, G_OPTION_ARG_NONE, &query_location_info_status_flag,
+ "Query location info status",
+ NULL
+ },
+ { "ms-set-provisioned-contexts", 0, 0, G_OPTION_ARG_STRING, &set_provisioned_contexts_str,
+ "Set provisioned contexts (allowed keys: operation, context-type, ip-type, state, roaming-control, media-type, source, auth, compression, username, password, access-string)",
+ "[\"key=value,...\"]"
+ },
+ { "ms-query-provisioned-contexts", 0, 0, G_OPTION_ARG_NONE, &query_provisioned_contexts_flag,
+ "Query provisioned contexts",
+ NULL
+ },
+ { "ms-query-base-stations-info", 0, 0, G_OPTION_ARG_NONE, &query_base_stations_flag,
+ "Query base stations info",
+ NULL
+ },
+ { "ms-query-version", 0, 0,G_OPTION_ARG_STRING , &query_version_str,
+ "Exchange supported version information. Since MBIMEx v2.0.",
+ "[(MBIM version),(MBIM extended version)]"
+ },
+ { "ms-query-registration-parameters", 0, 0, G_OPTION_ARG_NONE, &query_registration_parameters_flag,
+ "Query registration parameters. Since MBIMEx v3.0.",
+ NULL
+ },
+ { "ms-set-registration-parameters", 0, 0,G_OPTION_ARG_STRING , &set_registration_parameters_str,
+ "Set registration parameters (required keys: mico-mode, drx-cycle, ladn-info, default-pdu-activation-hint, re-register-if-needed). Since MBIMEx v3.0.",
+ "[\"key=value,...\"]"
+ },
+ { "ms-query-modem-configuration", 0, 0, G_OPTION_ARG_NONE, &query_modem_configuration_flag,
+ "Query modem configuration. Since MBIMEx v3.0.",
+ NULL
+ },
+ { "ms-query-wake-reason", 0, 0, G_OPTION_ARG_NONE, &query_wake_reason_flag,
+ "Query wake reason. Since MBIMEx v3.0.",
+ NULL
+ },
+ {NULL }
};
static gboolean
@@ -160,7 +205,16 @@
query_device_caps_flag +
!!query_slot_info_status_str +
!!set_device_slot_mappings_str +
- query_device_slot_mappings_flag);
+ query_device_slot_mappings_flag +
+ query_location_info_status_flag +
+ query_provisioned_contexts_flag +
+ !!set_provisioned_contexts_str +
+ query_base_stations_flag +
+ !!query_version_str +
+ query_registration_parameters_flag +
+ !!set_registration_parameters_str +
+ query_modem_configuration_flag +
+ query_wake_reason_flag);
if (n_actions > 1) {
g_printerr ("error: too many Microsoft Basic Connect Extensions Service actions requested\n");
@@ -294,6 +348,7 @@
g_autofree gchar *password = NULL;
guint32 compression;
guint32 auth_protocol;
+ MbimNwError nw_error = 0;
response = mbim_device_command_finish (device, res, &error);
if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
@@ -302,22 +357,45 @@
return;
}
- g_print ("[%s] Successfully queried LTE attach info\n",
- mbim_device_get_path_display (device));
- if (!mbim_message_ms_basic_connect_extensions_lte_attach_info_response_parse (
- response,
- <e_attach_state,
- &ip_type,
- &access_string,
- &user_name,
- &password,
- &compression,
- &auth_protocol,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ /* MBIMEx 3.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_extensions_v3_lte_attach_info_response_parse (
+ response,
+ <e_attach_state,
+ &nw_error,
+ &ip_type,
+ &access_string,
+ &user_name,
+ &password,
+ &compression,
+ &auth_protocol,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_print ("[%s] Successfully received v3.0 LTE attach info\n",
+ mbim_device_get_path_display (device));
+ }
+ /* MBIM 1.0 support */
+ else {
+ if (!mbim_message_ms_basic_connect_extensions_lte_attach_info_response_parse (
+ response,
+ <e_attach_state,
+ &ip_type,
+ &access_string,
+ &user_name,
+ &password,
+ &compression,
+ &auth_protocol,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_print ("[%s] Successfully received v1.0 LTE attach info\n",
+ mbim_device_get_path_display (device));
}
#define VALIDATE_NA(str) (str ? str : "n/a")
@@ -328,6 +406,21 @@
g_print (" Password: %s\n", VALIDATE_NA (password));
g_print (" Compression: %s\n", mbim_compression_get_string (compression));
g_print (" Auth protocol: %s\n", mbim_auth_protocol_get_string (auth_protocol));
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (nw_error == 0)
+ g_print (" Network error: none\n");
+ else if (nw_error == 0xFFFFFFFF)
+ g_print (" Network error: unknown\n");
+ else {
+ const gchar *nw_error_str;
+
+ nw_error_str = mbim_nw_error_get_string (nw_error);
+ if (nw_error_str)
+ g_print (" Network error: %s\n", nw_error_str);
+ else
+ g_print (" Network error: unknown (0x%08x)\n", nw_error);
+ }
+ }
#undef VALIDATE_NA
shutdown (TRUE);
@@ -394,13 +487,20 @@
g_autofree gchar *cellular_class_str = NULL;
MbimSimClass sim_class;
g_autofree gchar *sim_class_str = NULL;
- MbimDataClass data_class;
+ MbimDataClass data_class = 0;
+ MbimDataClassV3 data_class_v3 = 0;
g_autofree gchar *data_class_str = NULL;
+ MbimDataSubclass data_subclass;
MbimSmsCaps sms_caps;
g_autofree gchar *sms_caps_str = NULL;
MbimCtrlCaps ctrl_caps;
g_autofree gchar *ctrl_caps_str = NULL;
guint32 max_sessions;
+ guint32 wcdma_band_class = 0;
+ guint32 lte_band_class_array_size = 0;
+ g_autofree guint16 *lte_band_class_array = NULL;
+ guint32 nr_band_class_array_size = 0;
+ g_autofree guint16 *nr_band_class_array = NULL;
g_autofree gchar *custom_data_class = NULL;
g_autofree gchar *device_id = NULL;
g_autofree gchar *firmware_info = NULL;
@@ -414,32 +514,67 @@
return;
}
- if (!mbim_message_ms_basic_connect_extensions_device_caps_response_parse (
- response,
- &device_type,
- &cellular_class,
- &voice_class,
- &sim_class,
- &data_class,
- &sms_caps,
- &ctrl_caps,
- &max_sessions,
- &custom_data_class,
- &device_id,
- &firmware_info,
- &hardware_info,
- &executor_index,
- &error)) {
- g_printerr ("error: couldn't parse response message: %s\n", error->message);
- shutdown (FALSE);
- return;
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_extensions_v3_device_caps_response_parse (
+ response,
+ &device_type,
+ &cellular_class,
+ &voice_class,
+ &sim_class,
+ &data_class_v3,
+ &sms_caps,
+ &ctrl_caps,
+ &data_subclass,
+ &max_sessions,
+ &executor_index,
+ &wcdma_band_class,
+ <e_band_class_array_size,
+ <e_band_class_array,
+ &nr_band_class_array_size,
+ &nr_band_class_array,
+ &custom_data_class,
+ &device_id,
+ &firmware_info,
+ &hardware_info,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 3.0 Device Caps");
+ } else {
+ if (!mbim_message_ms_basic_connect_extensions_device_caps_response_parse (
+ response,
+ &device_type,
+ &cellular_class,
+ &voice_class,
+ &sim_class,
+ &data_class,
+ &sms_caps,
+ &ctrl_caps,
+ &max_sessions,
+ &custom_data_class,
+ &device_id,
+ &firmware_info,
+ &hardware_info,
+ &executor_index,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 1.0 Device Caps");
}
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0))
+ data_class_str = mbim_data_class_v3_build_string_from_mask (data_class_v3);
+ else
+ data_class_str = mbim_data_class_build_string_from_mask (data_class);
+
device_type_str = mbim_device_type_get_string (device_type);
cellular_class_str = mbim_cellular_class_build_string_from_mask (cellular_class);
voice_class_str = mbim_voice_class_get_string (voice_class);
sim_class_str = mbim_sim_class_build_string_from_mask (sim_class);
- data_class_str = mbim_data_class_build_string_from_mask (data_class);
sms_caps_str = mbim_sms_caps_build_string_from_mask (sms_caps);
ctrl_caps_str = mbim_ctrl_caps_build_string_from_mask (ctrl_caps);
@@ -472,6 +607,34 @@
VALIDATE_UNKNOWN (hardware_info),
executor_index);
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_autofree gchar *data_subclass_str = NULL;
+ guint i;
+ gboolean n_printed;
+
+ data_subclass_str = mbim_data_subclass_build_string_from_mask (data_subclass);
+ g_print ("\t Data subclass: '%s'\n", data_subclass_str);
+
+ g_print ("\t WCDMA band class: '");
+ for (n_printed = 0, i = 0; i < 31; i++) {
+ if (wcdma_band_class & (1 << i)) {
+ g_print ("%s%u", n_printed > 0 ? ", " : "", i + 1);
+ n_printed++;
+ }
+ }
+ g_print ("'\n");
+
+ g_print ("\t LTE band class: '");
+ for (i = 0; i < lte_band_class_array_size; i++)
+ g_print ("%s%" G_GUINT16_FORMAT, i > 0 ? ", " : "", lte_band_class_array[i]);
+ g_print ("'\n");
+
+ g_print ("\t NR band class: '");
+ for (i = 0; i < nr_band_class_array_size; i++)
+ g_print ("%s%" G_GUINT16_FORMAT, i > 0 ? ", " : "", nr_band_class_array[i]);
+ g_print ("'\n");
+ }
+
shutdown (TRUE);
}
@@ -635,6 +798,859 @@
shutdown (TRUE);
}
+static void
+query_location_info_status_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint32 location_area_code = 0;
+ guint32 tracking_area_code = 0;
+ guint32 cell_id = 0;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully queried location info status\n",
+ mbim_device_get_path_display (device));
+
+ if (!mbim_message_ms_basic_connect_extensions_location_info_status_response_parse (
+ response,
+ &location_area_code,
+ &tracking_area_code,
+ &cell_id,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print (" Location area code: %04X\n", location_area_code);
+ g_print (" Tracking area code: %06X\n", tracking_area_code);
+ g_print (" Cell ID: %08X\n", cell_id);
+
+ shutdown (TRUE);
+}
+
+typedef struct {
+ MbimContextOperation operation;
+ MbimContextIpType ip_type;
+ MbimContextState state;
+ MbimContextRoamingControl roaming_control;
+ MbimContextMediaType media_type;
+ MbimContextSource source;
+ gchar *access_string;
+ gchar *username;
+ gchar *password;
+ MbimCompression compression;
+ MbimAuthProtocol auth_protocol;
+ MbimContextType context_type;
+} ProvisionedContextProperties;
+
+static void
+provisioned_context_properties_clear (ProvisionedContextProperties *props)
+{
+ g_free (props->access_string);
+ g_free (props->username);
+ g_free (props->password);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(ProvisionedContextProperties, provisioned_context_properties_clear)
+
+static gboolean
+set_provisioned_contexts_foreach_cb (const gchar *key,
+ const gchar *value,
+ GError **error,
+ ProvisionedContextProperties *props)
+{
+ if (g_ascii_strcasecmp (key, "operation") == 0) {
+ if (!mbimcli_read_context_operation_from_string (value, &props->operation)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown operation: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "context-type") == 0) {
+ if (!mbimcli_read_context_type_from_string (value, &props->context_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown context-type: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "ip-type") == 0) {
+ if (!mbimcli_read_context_ip_type_from_string (value, &props->ip_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown ip-type: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "state") == 0) {
+ if (!mbimcli_read_context_state_from_string (value, &props->state)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown state: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "roaming-control") == 0) {
+ if (!mbimcli_read_context_roaming_control_from_string (value, &props->roaming_control)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown roaming-control: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "media-type") == 0) {
+ if (!mbimcli_read_context_media_type_from_string (value, &props->media_type)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown media-type: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "source") == 0) {
+ if (!mbimcli_read_context_source_from_string (value, &props->source)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown source: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "auth") == 0) {
+ if (!mbimcli_read_auth_protocol_from_string (value, &props->auth_protocol)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown auth: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "compression") == 0) {
+ if (!mbimcli_read_compression_from_string (value, &props->compression)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown compression: '%s'", value);
+ return FALSE;
+ }
+ } else if (g_ascii_strcasecmp (key, "username") == 0) {
+ g_free (props->username);
+ props->username = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "password") == 0) {
+ g_free (props->password);
+ props->password = g_strdup (value);
+ } else if (g_ascii_strcasecmp (key, "access-string") == 0) {
+ g_free (props->access_string);
+ props->access_string = g_strdup (value);
+ } else {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "unrecognized option '%s'", key);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+provisioned_contexts_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(MbimProvisionedContextElementV2Array) provisioned_contexts = NULL;
+ g_autoptr(GError) error = NULL;
+ guint32 provisioned_contexts_count;
+ guint32 i = 0;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!mbim_message_ms_basic_connect_extensions_provisioned_contexts_response_parse (
+ response,
+ &provisioned_contexts_count,
+ &provisioned_contexts,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Provisioned contexts (%u):\n",
+ mbim_device_get_path_display (device),
+ provisioned_contexts_count);
+
+ for (i = 0; i < provisioned_contexts_count; i++) {
+ g_print ("\tContext ID %u:\n"
+ "\t Context type: '%s'\n"
+ "\t IP type: '%s'\n"
+ "\t State: '%s'\n"
+ "\tRoaming control: '%s'\n"
+ "\t Media type: '%s'\n"
+ "\t Source: '%s'\n"
+ "\t Access string: '%s'\n"
+ "\t Username: '%s'\n"
+ "\t Password: '%s'\n"
+ "\t Compression: '%s'\n"
+ "\t Auth protocol: '%s'\n",
+ provisioned_contexts[i]->context_id,
+ VALIDATE_UNKNOWN (mbim_context_type_get_string (
+ mbim_uuid_to_context_type (&provisioned_contexts[i]->context_type))),
+ VALIDATE_UNKNOWN (mbim_context_ip_type_get_string (
+ provisioned_contexts[i]->ip_type)),
+ VALIDATE_UNKNOWN (mbim_context_state_get_string (
+ provisioned_contexts[i]->state)),
+ VALIDATE_UNKNOWN (mbim_context_roaming_control_get_string (
+ provisioned_contexts[i]->roaming)),
+ VALIDATE_UNKNOWN (mbim_context_media_type_get_string (
+ provisioned_contexts[i]->media_type)),
+ VALIDATE_UNKNOWN (mbim_context_source_get_string (
+ provisioned_contexts[i]->source)),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->access_string),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->user_name),
+ VALIDATE_UNKNOWN (provisioned_contexts[i]->password),
+ VALIDATE_UNKNOWN (mbim_compression_get_string (
+ provisioned_contexts[i]->compression)),
+ VALIDATE_UNKNOWN (mbim_auth_protocol_get_string (
+ provisioned_contexts[i]->auth_protocol)));
+ }
+
+ shutdown (TRUE);
+}
+
+static void
+query_base_stations_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ MbimDataClass system_type;
+ MbimDataClassV3 system_type_v3;
+ MbimDataSubclass system_subtype;
+ g_autoptr(MbimCellInfoServingGsm) gsm_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingUmts) umts_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingTdscdma) tdscdma_serving_cell = NULL;
+ g_autoptr(MbimCellInfoServingLte) lte_serving_cell = NULL;
+ guint32 gsm_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringGsmArray) gsm_neighboring_cells = NULL;
+ guint32 umts_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringUmtsArray) umts_neighboring_cells = NULL;
+ guint32 tdscdma_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringTdscdmaArray) tdscdma_neighboring_cells = NULL;
+ guint32 lte_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringLteArray) lte_neighboring_cells = NULL;
+ guint32 cdma_cells_count;
+ g_autoptr(MbimCellInfoCdmaArray) cdma_cells = NULL;
+ guint32 nr_serving_cells_count;
+ g_autoptr(MbimCellInfoServingNrArray) nr_serving_cells = NULL;
+ guint32 nr_neighboring_cells_count;
+ g_autoptr(MbimCellInfoNeighboringNrArray) nr_neighboring_cells = NULL;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ /* MBIMEx 3.0 support */
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ if (!mbim_message_ms_basic_connect_extensions_v3_base_stations_info_response_parse (
+ response,
+ &system_type_v3,
+ &system_subtype,
+ &gsm_serving_cell,
+ &umts_serving_cell,
+ &tdscdma_serving_cell,
+ <e_serving_cell,
+ &gsm_neighboring_cells_count,
+ &gsm_neighboring_cells,
+ &umts_neighboring_cells_count,
+ &umts_neighboring_cells,
+ &tdscdma_neighboring_cells_count,
+ &tdscdma_neighboring_cells,
+ <e_neighboring_cells_count,
+ <e_neighboring_cells,
+ &cdma_cells_count,
+ &cdma_cells,
+ &nr_serving_cells_count,
+ &nr_serving_cells,
+ &nr_neighboring_cells_count,
+ &nr_neighboring_cells,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 3.0 Base Stations Info");
+ }
+ /* MBIMEx 1.0 support */
+ else {
+ if (!mbim_message_ms_basic_connect_extensions_base_stations_info_response_parse (
+ response,
+ &system_type,
+ &gsm_serving_cell,
+ &umts_serving_cell,
+ &tdscdma_serving_cell,
+ <e_serving_cell,
+ &gsm_neighboring_cells_count,
+ &gsm_neighboring_cells,
+ &umts_neighboring_cells_count,
+ &umts_neighboring_cells,
+ &tdscdma_neighboring_cells_count,
+ &tdscdma_neighboring_cells,
+ <e_neighboring_cells_count,
+ <e_neighboring_cells,
+ &cdma_cells_count,
+ &cdma_cells,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+ g_debug ("Successfully parsed response as MBIMEx 1.0 Base Stations Info");
+ }
+
+#define PRINT_VALIDATED_UINT(number, invalid, format, units) do { \
+ if (number == invalid) \
+ g_print ("%s: unknown\n", format); \
+ else \
+ g_print ("%s: %u%s\n", format, number, units ? units : ""); \
+ } while (0)
+
+#define PRINT_VALIDATED_UINT64(number, invalid, format, units) do { \
+ if (number == invalid) \
+ g_print ("%s: unknown\n", format); \
+ else \
+ g_print ("%s: %" G_GUINT64_FORMAT "%s\n", format, number, units ? units : ""); \
+ } while (0)
+
+#define PRINT_VALIDATED_INT(number, invalid, format, units) do { \
+ if (number == (gint32)invalid) \
+ g_print ("%s: unknown\n", format); \
+ else \
+ g_print ("%s: %d%s\n", format, number, units ? units : ""); \
+ } while (0)
+
+#define PRINT_VALIDATED_SCALED_UINT(number, invalid, scale, format, units) do { \
+ if (number == 0xFFFFFFFF) \
+ g_print ("%s: unknown\n", format); \
+ else \
+ g_print ("%s: %d%s\n", format, ((gint32)number) + scale, units ? units : ""); \
+ } while (0)
+
+ if (mbim_device_check_ms_mbimex_version (device, 3, 0)) {
+ g_autofree gchar *system_type_str = NULL;
+ g_autofree gchar *system_subtype_str = NULL;
+
+ system_type_str = mbim_data_class_v3_build_string_from_mask (system_type_v3);
+ g_print ("System type: %s\n", system_type_str);
+ system_subtype_str = mbim_data_subclass_build_string_from_mask (system_subtype);
+ g_print ("System subtype: %s\n", VALIDATE_UNKNOWN (system_subtype_str));
+ } else {
+ g_autofree gchar *system_type_str = NULL;
+
+ system_type_str = mbim_data_class_build_string_from_mask (system_type);
+ g_print ("System type: %s\n", system_type_str);
+ }
+
+ if (gsm_serving_cell) {
+ g_print ("GSM serving cell:\n"
+ "\t Provider id: %s\n",
+ VALIDATE_UNKNOWN (gsm_serving_cell->provider_id));
+ PRINT_VALIDATED_UINT (gsm_serving_cell->location_area_code, 0xFFFFFFFF, "\t LAC", NULL);
+ PRINT_VALIDATED_UINT (gsm_serving_cell->cell_id, 0xFFFFFFFF, "\t Cell ID", NULL);
+ PRINT_VALIDATED_UINT (gsm_serving_cell->timing_advance, 0xFFFFFFFF, "\t Timing advance", " bit periods");
+ PRINT_VALIDATED_UINT (gsm_serving_cell->arfcn, 0xFFFFFFFF, "\t ARFCN", NULL);
+ PRINT_VALIDATED_UINT (gsm_serving_cell->base_station_id, 0xFFFFFFFF, "\tBase station ID", NULL);
+ PRINT_VALIDATED_SCALED_UINT (gsm_serving_cell->rx_level, 0xFFFFFFFF, -110, "\t Rx level", " dBm");
+ } else
+ g_print ("GSM serving cell: n/a\n");
+
+ if (gsm_neighboring_cells_count && gsm_neighboring_cells) {
+ guint i;
+
+ g_print ("Neighboring GSM cells: %d\n", gsm_neighboring_cells_count);
+ for (i = 0; i < gsm_neighboring_cells_count; i++) {
+ g_print ("\tNeighboring cell [%u]:\n"
+ "\t\t Provider id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (gsm_neighboring_cells[i]->provider_id));
+ PRINT_VALIDATED_UINT (gsm_neighboring_cells[i]->location_area_code, 0xFFFFFFFF, "\t\t LAC", NULL);
+ PRINT_VALIDATED_UINT (gsm_neighboring_cells[i]->cell_id, 0xFFFFFFFF, "\t\t Cell ID", NULL);
+ PRINT_VALIDATED_UINT (gsm_neighboring_cells[i]->arfcn, 0xFFFFFFFF, "\t\t ARFCN", NULL);
+ PRINT_VALIDATED_UINT (gsm_neighboring_cells[i]->base_station_id, 0xFFFFFFFF, "\t\tBase station ID", NULL);
+ PRINT_VALIDATED_SCALED_UINT (gsm_neighboring_cells[i]->rx_level, 0xFFFFFFFF, -110, "\t\t Rx level", " dBm");
+ }
+ } else
+ g_print ("Neighboring GSM cells: n/a\n");
+
+ if (umts_serving_cell) {
+ g_print ("UMTS Serving cell:\n"
+ "\t Provider id: %s\n",
+ VALIDATE_UNKNOWN (umts_serving_cell->provider_id));
+ PRINT_VALIDATED_UINT (umts_serving_cell->location_area_code, 0xFFFFFFFF, "\t LAC", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->cell_id, 0xFFFFFFFF, "\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->frequency_info_ul, 0xFFFFFFFF, "\t Frequency info uplink", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->frequency_info_dl, 0xFFFFFFFF, "\tFrequency info downlink", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->frequency_info_nt, 0xFFFFFFFF, "\t Frequency info TDD", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->uarfcn, 0xFFFFFFFF, "\t UARFCN", NULL);
+ PRINT_VALIDATED_UINT (umts_serving_cell->primary_scrambling_code, 0xFFFFFFFF, "\tPrimary Scrambling Code", NULL);
+ /* note: docs say unknown value in this case is 0
+ * https://github.com/MicrosoftDocs/windows-driver-docs/issues/2932 */
+ PRINT_VALIDATED_INT (umts_serving_cell->rscp, 0xFFFFFFFF, "\t RSCP", " dBm");
+ PRINT_VALIDATED_INT (umts_serving_cell->ecno, 1, "\t ECNO", " dBm");
+ PRINT_VALIDATED_UINT (umts_serving_cell->path_loss, 0xFFFFFFFF, "\t Path loss", NULL);
+ } else
+ g_print ("UMTS serving cell: n/a\n");
+
+ if (umts_neighboring_cells_count && umts_neighboring_cells) {
+ guint i;
+
+ g_print ("Neighboring UMTS cells: %d\n", umts_neighboring_cells_count);
+ for (i = 0; i < umts_neighboring_cells_count; i++) {
+ g_print ("\tNeighboring cell [%u]:\n"
+ "\t\t Provider id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (umts_neighboring_cells[i]->provider_id));
+ PRINT_VALIDATED_UINT (umts_neighboring_cells[i]->location_area_code, 0xFFFFFFFF, "\t\t LAC", NULL);
+ PRINT_VALIDATED_UINT (umts_neighboring_cells[i]->cell_id, 0xFFFFFFFF, "\t\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (umts_neighboring_cells[i]->uarfcn, 0xFFFFFFFF, "\t\t UARFCN", NULL);
+ PRINT_VALIDATED_UINT (umts_neighboring_cells[i]->primary_scrambling_code, 0xFFFFFFFF, "\t\tPrimary Scrambling Code", NULL);
+ PRINT_VALIDATED_INT (umts_neighboring_cells[i]->rscp, 0xFFFFFFFF, "\t\t RSCP", " dBm");
+ PRINT_VALIDATED_INT (umts_neighboring_cells[i]->ecno, 1, "\t\t ECNO", " dBm");
+ PRINT_VALIDATED_UINT (umts_neighboring_cells[i]->path_loss, 0xFFFFFFFF, "\t\t Path loss", NULL);
+ }
+ } else
+ g_print ("Neighboring UMTS cells: n/a\n");
+
+ if (tdscdma_serving_cell) {
+ g_print ("TDSCDMA Serving cell:\n"
+ "\t Provider id: %s\n",
+ VALIDATE_UNKNOWN (tdscdma_serving_cell->provider_id));
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->location_area_code, 0xFFFFFFFF, "\t LAC", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->cell_id, 0xFFFFFFFF, "\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->uarfcn, 0xFFFFFFFF, "\t UARFCN", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->cell_parameter_id, 0xFFFFFFFF, "\tCell parameter id", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->timing_advance, 0xFFFFFFFF, "\t Timing advance", NULL);
+ PRINT_VALIDATED_INT (tdscdma_serving_cell->rscp, 0xFFFFFFFF, "\t RSCP", " dBm");
+ PRINT_VALIDATED_UINT (tdscdma_serving_cell->path_loss, 0xFFFFFFFF, "\t Path loss", NULL);
+ } else
+ g_print ("TDSCDMA serving cell: n/a\n");
+
+ if (tdscdma_neighboring_cells_count && tdscdma_neighboring_cells) {
+ guint i;
+
+ g_print ("Neighboring TDSCDMA cells: %d\n", tdscdma_neighboring_cells_count);
+ for (i = 0; i < tdscdma_neighboring_cells_count; i++) {
+ g_print ("\tNeighboring cell [%u]:\n"
+ "\t\t Provider id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (tdscdma_neighboring_cells[i]->provider_id));
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->location_area_code, 0xFFFFFFFF, "\t\t LAC", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->cell_id, 0xFFFFFFFF, "\t\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->uarfcn, 0xFFFFFFFF, "\t\t UARFCN", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->cell_parameter_id, 0xFFFFFFFF, "\t\tCell parameter id", NULL);
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->timing_advance, 0xFFFFFFFF, "\t\t Timing advance", NULL);
+ PRINT_VALIDATED_INT (tdscdma_neighboring_cells[i]->rscp, 0xFFFFFFFF, "\t\t RSCP", " dBm");
+ PRINT_VALIDATED_UINT (tdscdma_neighboring_cells[i]->path_loss, 0xFFFFFFFF, "\t\t Path Loss", NULL);
+ }
+ } else
+ g_print ("Neighboring TDSCDMA cells: n/a\n");
+
+ if (lte_serving_cell) {
+ g_print ("LTE Serving cell:\n"
+ "\t Provider id: %s\n",
+ VALIDATE_UNKNOWN (lte_serving_cell->provider_id));
+ PRINT_VALIDATED_UINT (lte_serving_cell->cell_id, 0xFFFFFFFF, "\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (lte_serving_cell->earfcn, 0xFFFFFFFF, "\t EARFCN", NULL);
+ PRINT_VALIDATED_UINT (lte_serving_cell->physical_cell_id, 0xFFFFFFFF, "\t Physical cell id", NULL);
+ PRINT_VALIDATED_UINT (lte_serving_cell->tac, 0xFFFFFFFF, "\t TAC", NULL);
+ PRINT_VALIDATED_INT (lte_serving_cell->rsrp, 0xFFFFFFFF, "\t RSRP", " dBm");
+ PRINT_VALIDATED_INT (lte_serving_cell->rsrq, 0xFFFFFFFF, "\t RSRQ", " dBm");
+ PRINT_VALIDATED_UINT (lte_serving_cell->timing_advance, 0xFFFFFFFF, "\t Timing advance", NULL);
+ } else
+ g_print ("LTE serving cell: n/a\n");
+
+ if (lte_neighboring_cells_count && lte_neighboring_cells) {
+ guint i;
+
+ g_print ("Neighboring LTE cells: %d\n", lte_neighboring_cells_count);
+ for (i = 0; i < lte_neighboring_cells_count; i++) {
+ g_print ("\tNeighboring cell [%u]:\n"
+ "\t\t Provider id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (lte_neighboring_cells[i]->provider_id));
+ PRINT_VALIDATED_UINT (lte_neighboring_cells[i]->cell_id, 0xFFFFFFFF, "\t\t Cell id", NULL);
+ PRINT_VALIDATED_UINT (lte_neighboring_cells[i]->earfcn, 0xFFFFFFFF, "\t\t EARFCN", NULL);
+ PRINT_VALIDATED_UINT (lte_neighboring_cells[i]->physical_cell_id, 0xFFFFFFFF, "\t\t Physical cell id", NULL);
+ PRINT_VALIDATED_UINT (lte_neighboring_cells[i]->tac, 0xFFFFFFFF, "\t\t TAC", NULL);
+ PRINT_VALIDATED_INT (lte_neighboring_cells[i]->rsrp, 0xFFFFFFFF, "\t\t RSRP", " dBm");
+ PRINT_VALIDATED_INT (lte_neighboring_cells[i]->rsrq, 0xFFFFFFFF, "\t\t RSRQ", " dBm");
+ }
+ } else
+ g_print ("Neighboring LTE cells: n/a\n");
+
+ if (cdma_cells_count && cdma_cells) {
+ guint i;
+
+ g_print ("CDMA cells: %d\n", cdma_cells_count);
+ for (i = 0; i < cdma_cells_count; i++)
+ g_print ("Cell [%u]:\n"
+ "\t Serving: %s\n",
+ i + 1,
+ cdma_cells[i]->serving_cell_flag ? "yes" : "no");
+ PRINT_VALIDATED_UINT (cdma_cells[i]->nid, 0xFFFFFFFF, "\t NID", NULL);
+ PRINT_VALIDATED_UINT (cdma_cells[i]->sid, 0xFFFFFFFF, "\t SID", NULL);
+ PRINT_VALIDATED_UINT (cdma_cells[i]->base_station_id, 0xFFFFFFFF, "\tBase station id", NULL);
+ /* TODO: The Base Station Latitude (0-4194303). This is encoded in units of 0.25 seconds, expressed
+ * in two’s complement representation within the low 22 bits of the DWORD. As a signed value,
+ * North latitudes are positive. Use 0xFFFFFFFF when this information is not available. */
+ PRINT_VALIDATED_UINT (cdma_cells[i]->base_latitude, 0xFFFFFFFF, "\t Base latitude", NULL);
+ /* TODO: The Base Station Longitude (0-8388607). This is encoded in units of 0.25 seconds, expressed
+ * in two’s complement representation within the low 23 bits of the DWORD. As a signed value, East
+ * longitudes are positive. Use 0xFFFFFFFF when this information is not available. */
+ PRINT_VALIDATED_UINT (cdma_cells[i]->base_longitude, 0xFFFFFFFF, "\t Base longitude", NULL);
+ PRINT_VALIDATED_UINT (cdma_cells[i]->ref_pn, 0xFFFFFFFF, "\t RefPN", NULL);
+ PRINT_VALIDATED_UINT (cdma_cells[i]->gps_seconds, 0xFFFFFFFF, "\t GPS seconds", " seconds");
+ PRINT_VALIDATED_UINT (cdma_cells[i]->pilot_strength, 0xFFFFFFFF, "\t Pilot strength", NULL);
+ } else
+ g_print ("CDMA cells: n/a\n");
+
+ if (nr_serving_cells_count && nr_serving_cells) {
+ guint i;
+
+ g_print ("Serving NR cells: %d\n", nr_serving_cells_count);
+ for (i = 0; i < nr_serving_cells_count; i++) {
+ g_print ("\tServing cell [%u]:\n"
+ "\t\t Provider id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (nr_serving_cells[i]->provider_id));
+ PRINT_VALIDATED_UINT64 (nr_serving_cells[i]->nci, 0xFFFFFFFFFFFFFFFF, "\t\t NCI", NULL);
+ PRINT_VALIDATED_UINT (nr_serving_cells[i]->physical_cell_id, 0xFFFFFFFF, "\t\tPhysical cell id", NULL);
+ PRINT_VALIDATED_UINT (nr_serving_cells[i]->nrarfcn, 0xFFFFFFFF, "\t\t NRARFCN", NULL);
+ PRINT_VALIDATED_UINT (nr_serving_cells[i]->tac, 0xFFFFFFFF, "\t\t TAC", NULL);
+ PRINT_VALIDATED_SCALED_UINT (nr_serving_cells[i]->rsrp, 0xFFFFFFFF, -156, "\t\t RSRP", " dBm");
+ PRINT_VALIDATED_SCALED_UINT (nr_serving_cells[i]->rsrq, 0xFFFFFFFF, -43, "\t\t RSRQ", " dB");
+ PRINT_VALIDATED_SCALED_UINT (nr_serving_cells[i]->sinr, 0xFFFFFFFF, -23, "\t\t SINR", " dB");
+ PRINT_VALIDATED_UINT64 (nr_serving_cells[i]->timing_advance, 0xFFFFFFFFFFFFFFFF, "\t\t Timing advance", " us");
+ }
+ } else
+ g_print ("Serving NR cells: n/a\n");
+
+ if (nr_neighboring_cells_count && nr_neighboring_cells) {
+ guint i;
+
+ g_print ("Neighboring NR cells: %d\n", nr_neighboring_cells_count);
+ for (i = 0; i < nr_neighboring_cells_count; i++) {
+ g_autofree gchar *system_subtype_str = NULL;
+
+ system_subtype_str = mbim_data_subclass_build_string_from_mask (nr_neighboring_cells[i]->system_sub_type);
+ g_print ("\tNeighboring cell [%u]:\n"
+ "\t\t System subtype: %s\n"
+ "\t\t Provider id: %s\n"
+ "\t\t Cell id: %s\n",
+ i + 1,
+ VALIDATE_UNKNOWN (system_subtype_str),
+ VALIDATE_UNKNOWN (nr_neighboring_cells[i]->provider_id),
+ VALIDATE_UNKNOWN (nr_neighboring_cells[i]->cell_id));
+ PRINT_VALIDATED_UINT (nr_neighboring_cells[i]->physical_cell_id, 0xFFFFFFFF, "\t\tPhysical cell id", NULL);
+ PRINT_VALIDATED_UINT (nr_neighboring_cells[i]->tac, 0xFFFFFFFF, "\t\t TAC", NULL);
+ PRINT_VALIDATED_SCALED_UINT (nr_neighboring_cells[i]->rsrp, 0xFFFFFFFF, -156, "\t\t RSRP", " dBm");
+ PRINT_VALIDATED_SCALED_UINT (nr_neighboring_cells[i]->rsrq, 0xFFFFFFFF, -43, "\t\t RSRQ", " dB");
+ PRINT_VALIDATED_SCALED_UINT (nr_neighboring_cells[i]->sinr, 0xFFFFFFFF, -23, "\t\t SINR", " dB");
+ }
+ } else
+ g_print ("Neighboring NR cells: n/a\n");
+
+#undef PRINT_VALIDATED_SCALED_UINT
+#undef PRINT_VALIDATED_UINT64
+#undef PRINT_VALIDATED_UINT
+#undef PRINT_VALIDATED_INT
+
+ shutdown (TRUE);
+}
+
+static void
+query_version_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ guint16 mbim_version;
+ guint16 mbim_ext_version;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully exchanged version information\n",
+ mbim_device_get_path_display (device));
+ if (!mbim_message_ms_basic_connect_extensions_v2_version_response_parse (
+ response,
+ &mbim_version,
+ &mbim_ext_version,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print (" MBIM version : %x.%02x\n", mbim_version >> 8, mbim_version & 0xFF);
+ g_print (" MBIM extended version : %x.%02x\n", mbim_ext_version >> 8, mbim_ext_version & 0xFF);
+
+ shutdown (TRUE);
+ return;
+}
+
+typedef struct {
+ MbimMicoMode mico_mode;
+ gboolean mico_mode_set;
+ MbimDrxCycle drx_cycle;
+ gboolean drx_cycle_set;
+ MbimLadnInfo ladn_info;
+ gboolean ladn_info_set;
+ MbimDefaultPduActivationHint pdu_hint;
+ gboolean pdu_hint_set;
+ gboolean re_register_if_needed;
+ gboolean re_register_if_needed_set;
+} RegistrationParameters;
+
+static gboolean
+set_registration_parameters_foreach_cb (const gchar *key,
+ const gchar *value,
+ GError **error,
+ RegistrationParameters *params)
+{
+ if (g_ascii_strcasecmp (key, "mico-mode") == 0) {
+ if (!mbimcli_read_mico_mode_from_string (value, ¶ms->mico_mode)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown mico-mode: '%s'", value);
+ return FALSE;
+ }
+ params->mico_mode_set = TRUE;
+ } else if (g_ascii_strcasecmp (key, "drx-cycle") == 0) {
+ if (!mbimcli_read_drx_cycle_from_string (value, ¶ms->drx_cycle)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown drx-cycle: '%s'", value);
+ return FALSE;
+ }
+ params->drx_cycle_set = TRUE;
+ } else if (g_ascii_strcasecmp (key, "ladn-info") == 0) {
+ if (!mbimcli_read_ladn_info_from_string (value, ¶ms->ladn_info)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown ladn-info: '%s'", value);
+ return FALSE;
+ }
+ params->ladn_info_set = TRUE;
+ } else if (g_ascii_strcasecmp (key, "default-pdu-activation-hint") == 0) {
+ if (!mbimcli_read_default_pdu_activation_hint_from_string (value, ¶ms->pdu_hint)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown default-pdu-activation-hint: '%s'", value);
+ return FALSE;
+ }
+ params->pdu_hint_set = TRUE;
+ } else if (g_ascii_strcasecmp (key, "re-register-if-needed") == 0) {
+ if (!mbimcli_read_boolean_from_string (value, ¶ms->re_register_if_needed)) {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_INVALID_ARGS,
+ "unknown re-register-if-needed: '%s'", value);
+ return FALSE;
+ }
+ params->re_register_if_needed_set = TRUE;
+ } else {
+ g_set_error (error, MBIM_CORE_ERROR, MBIM_CORE_ERROR_FAILED,
+ "unrecognized option '%s'", key);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+registration_parameters_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ MbimMicoMode mico_mode;
+ MbimDrxCycle drx_cycle;
+ MbimLadnInfo ladn_info;
+ MbimDefaultPduActivationHint pdu_hint;
+ gboolean re_register_if_nedeed;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully received registration parameters information\n",
+ mbim_device_get_path_display (device));
+ if (!mbim_message_ms_basic_connect_extensions_v3_registration_parameters_response_parse (
+ response,
+ &mico_mode,
+ &drx_cycle,
+ &ladn_info,
+ &pdu_hint,
+ &re_register_if_nedeed,
+ NULL, /* ignore unnamed IEs for now */
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("\t MICO mode: %s\n", mbim_mico_mode_get_string (mico_mode));
+ g_print ("\t DRX cycle: %s\n", mbim_drx_cycle_get_string (drx_cycle));
+ g_print ("\t LADN information: %s\n", mbim_ladn_info_get_string (ladn_info));
+ g_print ("\tDefault PDU activation: %s\n", mbim_default_pdu_activation_hint_get_string (pdu_hint));
+ g_print ("\t Re-register if needed: %s\n", re_register_if_nedeed ? "yes" : "no");
+
+ shutdown (TRUE);
+}
+
+static void
+query_modem_configuration_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ MbimModemConfigurationStatus configuration_status;
+ g_autofree gchar *configuration_name = NULL;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!mbim_message_ms_basic_connect_extensions_v3_modem_configuration_response_parse (
+ response,
+ &configuration_status,
+ &configuration_name,
+ NULL, /* ignore unnamed IEs for now */
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Modem configuration retrieved: \n",
+ mbim_device_get_path_display (device));
+ g_print ("\tStatus: '%s'\n"
+ "\t Name: '%s'\n",
+ VALIDATE_UNKNOWN (mbim_modem_configuration_status_get_string (configuration_status)),
+ VALIDATE_UNKNOWN (configuration_name));
+
+ shutdown (TRUE);
+}
+
+static void
+query_wake_reason_ready (MbimDevice *device,
+ GAsyncResult *res)
+{
+ g_autoptr(MbimMessage) response = NULL;
+ g_autoptr(GError) error = NULL;
+ MbimWakeType wake_type;
+ guint32 session_id;
+ MbimTlv *wake_tlv = NULL;
+
+ response = mbim_device_command_finish (device, res, &error);
+ if (!response || !mbim_message_response_get_result (response, MBIM_MESSAGE_TYPE_COMMAND_DONE, &error)) {
+ g_printerr ("error: operation failed: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!mbim_message_ms_basic_connect_extensions_v3_wake_reason_response_parse (
+ response,
+ &wake_type,
+ &session_id,
+ &wake_tlv,
+ &error)) {
+ g_printerr ("error: couldn't parse response message: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ g_print ("[%s] Successfully queried wake reason\n",
+ mbim_device_get_path_display (device));
+
+ g_print ("\t Wake type: '%s'\n", mbim_wake_type_get_string (wake_type));
+ g_print ("\tSession ID: '%u'\n", session_id);
+
+ if ((wake_type == MBIM_WAKE_TYPE_CID_RESPONSE) ||
+ (wake_type == MBIM_WAKE_TYPE_CID_INDICATION)) {
+ const MbimUuid *service = NULL;
+ g_autofree gchar *service_str = NULL;
+ guint32 cid = 0;
+ guint32 payload_size = 0;
+ g_autofree guint8 *payload = NULL;
+ g_autofree gchar *payload_str = NULL;
+
+ if (!mbim_tlv_wake_command_get (wake_tlv,
+ &service,
+ &cid,
+ &payload_size,
+ &payload,
+ &error)) {
+ g_printerr ("error: couldn't parse wake command TLV: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ /* Known payload defined right now only for the Connect CID */
+ if ((mbim_uuid_to_service (service) == MBIM_SERVICE_BASIC_CONNECT) &&
+ (cid == MBIM_CID_BASIC_CONNECT_CONNECT) &&
+ (payload_size == 4)) {
+ guint32 activate;
+
+ memcpy (&activate, payload, payload_size);
+ activate = GUINT32_FROM_LE (activate);
+ if (activate == 0x00000001 || activate == 0x00000000)
+ payload_str = g_strdup (activate ? "activate" : "deactivate");
+ }
+
+ if (!payload_str)
+ payload_str = mbim_common_str_hex (payload, payload_size, ':');
+
+ service_str = mbim_uuid_get_printable (service);
+
+ g_print ("\t Service: '%s'\n", service_str);
+ g_print ("\t CID: '0x%08x'\n", cid);
+ g_print ("\t Payload: '%s'\n", payload_str);
+ shutdown (TRUE);
+ return;
+ }
+
+ if (wake_type == MBIM_WAKE_TYPE_PACKET) {
+ guint32 filter_id = 0;
+ guint32 original_packet_size = 0;
+ guint32 packet_size = 0;
+ g_autofree guint8 *packet = NULL;
+ g_autofree gchar *packet_str = NULL;
+
+ if (!mbim_tlv_wake_packet_get (wake_tlv,
+ &filter_id,
+ &original_packet_size,
+ &packet_size,
+ &packet,
+ &error)) {
+ g_printerr ("error: couldn't parse wake packet TLV: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ packet_str = mbim_common_str_hex (packet, packet_size, ':');
+
+ g_print ("\t Filter ID: '%u'\n", filter_id);
+ g_print ("\tOriginal size: '%u'\n", original_packet_size);
+ g_print ("\t Saved size: '%u'\n", packet_size);
+ g_print ("\t Packet: '%s'\n", packet_str);
+
+ shutdown (TRUE);
+ return;
+ }
+
+ g_printerr ("error: unknown wake type: 0x%08x\n", wake_type);
+ shutdown (FALSE);
+}
+
void
mbimcli_ms_basic_connect_extensions_run (MbimDevice *device,
GCancellable *cancellable)
@@ -672,7 +1688,6 @@
return;
}
- /* Request to query LTE attach configuration? */
if (query_lte_attach_configuration_flag) {
g_debug ("Asynchronously querying LTE attach configuration...");
request = mbim_message_ms_basic_connect_extensions_lte_attach_configuration_query_new (NULL);
@@ -685,7 +1700,6 @@
return;
}
- /* Request to query LTE attach info? */
if (query_lte_attach_status_flag || query_lte_attach_info_flag) {
g_debug ("Asynchronously querying LTE attach info...");
request = mbim_message_ms_basic_connect_extensions_lte_attach_info_query_new (NULL);
@@ -721,8 +1735,7 @@
NULL);
return;
}
-
- /*Request to query slot information status? */
+
if (query_slot_info_status_str) {
guint32 slot_index;
@@ -743,7 +1756,6 @@
return;
}
- /*Request to set device slot mappings */
if (set_device_slot_mappings_str) {
g_autoptr(GPtrArray) slot_array = NULL;
@@ -766,7 +1778,6 @@
return;
}
- /*Request to query device slot mappings? */
if (query_device_slot_mappings_flag) {
g_debug ("Asynchronously querying device slot mappings...");
request = mbim_message_ms_basic_connect_extensions_device_slot_mappings_query_new (NULL);
@@ -779,5 +1790,245 @@
return;
}
+ if (query_location_info_status_flag) {
+ g_debug ("Asynchronously querying location info status...");
+ request = mbim_message_ms_basic_connect_extensions_location_info_status_query_new (NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)query_location_info_status_ready,
+ NULL);
+ return;
+ }
+
+ if (set_provisioned_contexts_str) {
+ g_auto(ProvisionedContextProperties) props = {
+ .access_string = NULL,
+ .operation = MBIM_CONTEXT_OPERATION_DELETE,
+ .auth_protocol = MBIM_AUTH_PROTOCOL_NONE,
+ .username = NULL,
+ .password = NULL,
+ .ip_type = MBIM_CONTEXT_IP_TYPE_DEFAULT,
+ .state = MBIM_CONTEXT_STATE_DISABLED,
+ .roaming_control = MBIM_CONTEXT_ROAMING_CONTROL_HOME_ONLY,
+ .media_type = MBIM_CONTEXT_MEDIA_TYPE_CELLULAR_ONLY,
+ .source = MBIM_CONTEXT_SOURCE_ADMIN,
+ .compression = MBIM_COMPRESSION_NONE,
+ .context_type = MBIM_CONTEXT_TYPE_INVALID
+ };
+
+ if (!mbimcli_parse_key_value_string (set_provisioned_contexts_str,
+ &error,
+ (MbimParseKeyValueForeachFn)set_provisioned_contexts_foreach_cb,
+ &props)) {
+ g_printerr ("error: couldn't parse input string: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ request = mbim_message_ms_basic_connect_extensions_provisioned_contexts_set_new (
+ props.operation,
+ mbim_uuid_from_context_type (props.context_type),
+ props.ip_type,
+ props.state,
+ props.roaming_control,
+ props.media_type,
+ props.source,
+ props.access_string,
+ props.username,
+ props.password,
+ props.compression,
+ props.auth_protocol,
+ &error);
+
+ if (!request) {
+ g_printerr ("error: couldn't create request: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ mbim_device_command (ctx->device,
+ request,
+ 60,
+ ctx->cancellable,
+ (GAsyncReadyCallback)provisioned_contexts_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to query Provisioned contexts? */
+ if (query_provisioned_contexts_flag) {
+ g_debug ("Asynchronously query provisioned contexts...");
+
+ request = mbim_message_ms_basic_connect_extensions_provisioned_contexts_query_new (NULL);
+ if (!request) {
+ g_printerr ("error: couldn't create request: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)provisioned_contexts_ready,
+ NULL);
+ return;
+ }
+
+ if (query_base_stations_flag) {
+ g_debug ("Asynchronously querying base stations...");
+ /* default capacity is 15, so use that value when querying */
+ request = mbim_message_ms_basic_connect_extensions_base_stations_info_query_new (15, 15, 15, 15, 15, NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)query_base_stations_ready,
+ NULL);
+ return;
+ }
+
+ if (query_version_str) {
+ guint16 bcd_mbim_version = 0;
+ guint16 bcd_mbim_extended_version = 0;
+ guint8 mbim_version_major = 0;
+ guint8 mbim_version_minor = 0;
+ guint8 mbim_extended_version_major = 0;
+ guint8 mbim_extended_version_minor = 0;
+ g_auto(GStrv) split = NULL;
+ g_auto(GStrv) mbim_version = NULL;
+ g_auto(GStrv) mbim_extended_version = NULL;
+
+ split = g_strsplit (query_version_str, ",", -1);
+
+ if (g_strv_length (split) > 2) {
+ g_printerr ("error: couldn't parse input string, too many arguments\n");
+ return;
+ }
+
+ if (g_strv_length (split) < 2) {
+ g_printerr ("error: couldn't parse input string, missing arguments\n");
+ return;
+ }
+
+ mbim_version = g_strsplit (split[0], ".", -1);
+ if (!mbimcli_read_uint8_from_bcd_string (mbim_version[0], &mbim_version_major) ||
+ !mbimcli_read_uint8_from_bcd_string (mbim_version[1], &mbim_version_minor)) {
+ g_printerr ("error: couldn't parse version string\n");
+ return;
+ }
+ bcd_mbim_version = mbim_version_major << 8 | mbim_version_minor;
+ g_debug ("BCD version built: 0x%x", bcd_mbim_version);
+
+ mbim_extended_version = g_strsplit (split[1], ".", -1);
+ if (!mbimcli_read_uint8_from_bcd_string (mbim_extended_version[0], &mbim_extended_version_major) ||
+ !mbimcli_read_uint8_from_bcd_string (mbim_extended_version[1], &mbim_extended_version_minor)) {
+ g_printerr ("error: couldn't parse extended version string\n");
+ return;
+ }
+ bcd_mbim_extended_version = mbim_extended_version_major << 8 | mbim_extended_version_minor;
+ g_debug ("BCD extended version built: 0x%x", bcd_mbim_extended_version);
+
+ g_debug ("Asynchronously querying Version...");
+ request = mbim_message_ms_basic_connect_extensions_v2_version_query_new (bcd_mbim_version, bcd_mbim_extended_version, NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)query_version_ready,
+ NULL);
+ return;
+ }
+
+ if (query_registration_parameters_flag) {
+ g_debug (" Asynchronously querying registration parameters...");
+ request = mbim_message_ms_basic_connect_extensions_v3_registration_parameters_query_new (NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)registration_parameters_ready,
+ NULL);
+ return;
+ }
+
+ if (set_registration_parameters_str) {
+ RegistrationParameters params = { 0 };
+
+ if (!mbimcli_parse_key_value_string (set_registration_parameters_str,
+ &error,
+ (MbimParseKeyValueForeachFn)set_registration_parameters_foreach_cb,
+ ¶ms)) {
+ g_printerr ("error: couldn't parse input string: %s\n", error->message);
+ shutdown (FALSE);
+ return;
+ }
+
+ if (!params.mico_mode_set ||
+ !params.drx_cycle_set ||
+ !params.ladn_info_set ||
+ !params.pdu_hint_set ||
+ !params.re_register_if_needed_set) {
+ g_printerr ("error: missing required keys\n");
+ if (!params.mico_mode_set)
+ g_printerr ("error: key 'mico-mode' is missing\n");
+ if (!params.drx_cycle_set)
+ g_printerr ("error: key 'drx-cycle' is missing\n");
+ if (!params.ladn_info_set)
+ g_printerr ("error: key 'ladn-info' is missing\n");
+ if (!params.pdu_hint_set)
+ g_printerr ("error: key 'default-pdu-activation-hint' is missing\n");
+ if (!params.re_register_if_needed_set)
+ g_printerr ("error: key 're-register-is-needed' is missing\n");
+ shutdown (FALSE);
+ return;
+ }
+
+ g_debug ("Asynchronously set registration parameters\n");
+ request = (mbim_message_ms_basic_connect_extensions_v3_registration_parameters_set_new (
+ params.mico_mode,
+ params.drx_cycle,
+ params.ladn_info,
+ params.pdu_hint,
+ params.re_register_if_needed,
+ NULL, /* ignore unnamed IEs for now */
+ NULL));
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)registration_parameters_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to query modem configuration? */
+ if (query_modem_configuration_flag) {
+ g_debug ("Asynchronously query modem configuration\n");
+ request = mbim_message_ms_basic_connect_extensions_v3_modem_configuration_query_new (NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)query_modem_configuration_ready,
+ NULL);
+ return;
+ }
+
+ /* Request to query Wake Reason? */
+ if (query_wake_reason_flag) {
+ g_debug ("Asynchronously querying wake reason...");
+ request = mbim_message_ms_basic_connect_extensions_v3_wake_reason_query_new (NULL);
+ mbim_device_command (ctx->device,
+ request,
+ 10,
+ ctx->cancellable,
+ (GAsyncReadyCallback)query_wake_reason_ready,
+ NULL);
+ return;
+ }
+
g_warn_if_reached ();
}
diff --git a/src/mbimcli/mbimcli-ms-sar.c b/src/mbimcli/mbimcli-ms-sar.c
index 7f612e4..247454f 100644
--- a/src/mbimcli/mbimcli-ms-sar.c
+++ b/src/mbimcli/mbimcli-ms-sar.c
@@ -157,18 +157,21 @@
"\t Mode: %s\n"
"\t Backoff state: %s\n"
"\tWi-Fi hardware state: %s\n"
- "\t Config States: (%u)\n",
+ "\t Config states: %u\n",
mbim_device_get_path_display (device),
VALIDATE_UNKNOWN (mode_str),
VALIDATE_UNKNOWN (backoff_state_str),
VALIDATE_UNKNOWN (wifi_integration_str),
config_states_count);
+
+
for (i = 0; i < config_states_count; i++) {
- g_print ("\t\t[%u] Antenna index: %u\n"
- "\t\t Backoff index: %u\n",
- i,
- config_states[i]->antenna_index,
- config_states[i]->backoff_index);
+ g_print ("\t\t[%u]\n", i);
+ if (config_states[i]->antenna_index == 0xFFFFFFFF)
+ g_print ("\t\t Antenna index: all\n");
+ else
+ g_print ("\t\t Antenna index: %u\n", config_states[i]->antenna_index);
+ g_print ("\t\t Backoff index: %u\n", config_states[i]->backoff_index);
}
shutdown (TRUE);
@@ -242,49 +245,37 @@
return FALSE;
}
- if (g_ascii_strcasecmp (split[0], "device") == 0) {
- *mode = MBIM_SAR_CONTROL_MODE_DEVICE;
- } else if (g_ascii_strcasecmp (split[0], "os") == 0) {
- *mode = MBIM_SAR_CONTROL_MODE_OS;
- } else {
- g_printerr ("error: invalid mode: '%s', it must be device or os\n", split[0]);
+ if (!mbimcli_read_sar_control_mode_from_string (split[0], mode)) {
+ g_printerr ("error: invalid mode: '%s'\n", split[0]);
return FALSE;
}
- if (g_ascii_strcasecmp (split[1], "disabled") == 0) {
- *state = MBIM_SAR_BACKOFF_STATE_DISABLED;
- } else if (g_ascii_strcasecmp (split[1], "enabled") == 0) {
- *state = MBIM_SAR_BACKOFF_STATE_ENABLED;
- } else {
- g_printerr ("error: invalid state: '%s', it must be enabled or disabled\n", split[1]);
+ if (!mbimcli_read_sar_backoff_state_from_string (split[1], state)) {
+ g_printerr ("error: invalid state: '%s'\n", split[1]);
return FALSE;
}
/* Check whether we have the optional item array: [{antenna_index,backoff_index}...] */
if (split[2]) {
- const gchar *state_begin;
+ const gchar *array_begin;
+ const gchar *array_end;
+ g_autofree gchar *array_str = NULL;
- state_begin = strchr (split[2], '[');
- if (state_begin != NULL) {
- *states_array = g_ptr_array_new_with_free_func (g_free);
- while ((state_begin = strchr (state_begin, '{')) != NULL) {
- guint32 antenna_index;
- guint32 backoff_index;
+ array_begin = strchr (split[2], '[');
+ array_end = strchr (split[2], ']');
- if (sscanf (state_begin, "{%d,%d}", &antenna_index, &backoff_index) == 2) {
- MbimSarConfigState *config_state;
-
- config_state = g_new (MbimSarConfigState, 1);
- config_state->antenna_index = antenna_index;
- config_state->backoff_index = backoff_index;
- g_ptr_array_add (*states_array, config_state);
- ++state_begin;
- } else {
- break;
- }
- }
+ if (!array_begin || !array_end || (array_begin > array_end)) {
+ g_printerr ("error: invalid SAR config state array: '%s'\n", split[2]);
+ return FALSE;
}
- }
+
+ array_str = g_strndup (&array_begin[1], array_end - array_begin - 1);
+ if (!mbimcli_parse_sar_config_state_array (array_str, states_array)) {
+ g_printerr ("error: failure parsing the SAR config state array contents: '%s'\n", array_str);
+ return FALSE;
+ }
+ } else
+ *states_array = NULL;
return TRUE;
}
@@ -345,24 +336,20 @@
/* Request to set SAR config */
if (set_sar_config_str) {
g_autoptr(GPtrArray) states_array = NULL;
+ MbimSarControlMode mode;
+ MbimSarBackoffState state;
- MbimSarControlMode mode;
- MbimSarBackoffState state;
- guint states_count = 0;
- const MbimSarConfigState **states_ptrs = NULL;
-
- g_print ("Asynchronously set sar config\n");
+ g_debug ("Asynchronously setting SAR config");
if (!sar_config_input_parse (set_sar_config_str, &mode, &state, &states_array)) {
shutdown (FALSE);
return;
}
- if (states_array != NULL) {
- states_count = states_array->len;
- states_ptrs = (const MbimSarConfigState **)states_array->pdata;
- }
-
- request = mbim_message_ms_sar_config_set_new (mode, state, states_count, states_ptrs, NULL);
+ request = mbim_message_ms_sar_config_set_new (mode,
+ state,
+ states_array ? states_array->len : 0,
+ states_array ? (const MbimSarConfigState **)states_array->pdata : NULL,
+ NULL);
mbim_device_command (ctx->device,
request,
10,
diff --git a/src/mbimcli/mbimcli.c b/src/mbimcli/mbimcli.c
index 1161b7c..d68142d 100644
--- a/src/mbimcli/mbimcli.c
+++ b/src/mbimcli/mbimcli.c
@@ -37,6 +37,8 @@
/* Main options */
static gchar *device_str;
static gboolean device_open_proxy_flag;
+static gboolean device_open_ms_mbimex_v2_flag;
+static gboolean device_open_ms_mbimex_v3_flag;
static gchar *no_open_str;
static gboolean no_close_flag;
static gboolean noop_flag;
@@ -53,6 +55,14 @@
"Request to use the 'mbim-proxy' proxy",
NULL
},
+ { "device-open-ms-mbimex-v2", 0, 0, G_OPTION_ARG_NONE, &device_open_ms_mbimex_v2_flag,
+ "Request to enable Microsoft MBIMEx v2.0 support",
+ NULL
+ },
+ { "device-open-ms-mbimex-v3", 0, 0, G_OPTION_ARG_NONE, &device_open_ms_mbimex_v3_flag,
+ "Request to enable Microsoft MBIMEx v3.0 support",
+ NULL
+ },
{ "no-open", 0, 0, G_OPTION_ARG_STRING, &no_open_str,
"Do not explicitly open the MBIM device before running the command",
"[Transaction ID]"
@@ -332,6 +342,10 @@
/* Setup device open flags */
if (device_open_proxy_flag)
open_flags |= MBIM_DEVICE_OPEN_FLAGS_PROXY;
+ if (device_open_ms_mbimex_v2_flag)
+ open_flags |= MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V2;
+ if (device_open_ms_mbimex_v3_flag)
+ open_flags |= MBIM_DEVICE_OPEN_FLAGS_MS_MBIMEX_V3;
/* Open the device */
mbim_device_open_full (device,
@@ -413,6 +427,11 @@
exit (EXIT_FAILURE);
}
+ if (device_open_ms_mbimex_v2_flag && device_open_ms_mbimex_v3_flag) {
+ g_printerr ("error: cannot request both MBIMEx v2.0 and 3.0 at the same time\n");
+ exit (EXIT_FAILURE);
+ }
+
/* Go on! */
}
diff --git a/utils/meson.build b/utils/meson.build
index 24412a6..280afab 100644
--- a/utils/meson.build
+++ b/utils/meson.build
@@ -6,4 +6,5 @@
output: '@BASENAME@',
configuration: version_conf,
install_dir: mbim_bindir,
+ install_mode: 'rwxr-xr-x',
)