Compare commits

...

75 Commits

Author SHA1 Message Date
690e4de7d5 debug logs 2025-10-23 23:17:41 +08:00
fddd1b7d56 debug logs 2025-10-23 23:01:30 +08:00
4cdc4cfe65 debug logs 2025-10-23 22:39:33 +08:00
1396126a6b debug logs 2025-10-18 14:56:12 +08:00
a8fe0fe5c3 debug logs 2025-10-18 13:49:55 +08:00
50d6f649fa debian files 2025-10-17 23:50:44 +08:00
eb631f637c debian files 2025-10-17 23:15:20 +08:00
ae08826314 Fix symlink according to Debian policy 2025-10-17 23:13:54 +08:00
Matti Lehtimäki
a4a19a374a Version 1.6.0 2024-09-26 14:06:44 +03:00
Matti Lehtimäki
00248f8da3 Merge pull request #28 from mer-hybris/aidl
Add support for AIDL interfaces
2024-09-26 14:01:59 +03:00
Matti Lehtimäki
418405697e [gbinder-radio] Implement support for AIDL IRadioIms. JB#61702 2024-09-23 23:37:55 +03:00
Matti Lehtimäki
12133c9685 [gbinder-radio] Implement support for AIDL IRadioVoice. JB#61702 2024-09-23 23:37:55 +03:00
Matti Lehtimäki
50c615095b [gbinder-radio] Implement support for AIDL IRadioMessaging. JB#61702 2024-09-23 23:37:55 +03:00
Matti Lehtimäki
fa6a4d7e1a [gbinder-radio] Implement support for AIDL IRadioData. JB#61702 2024-09-23 23:37:55 +03:00
Matti Lehtimäki
bedb4a7659 [gbinder-radio] Implement support for AIDL IRadioNetwork. JB#61702 2024-09-23 23:37:55 +03:00
Nikita Ukhrenkov
500465507e [gbinder-radio] Implement support for AIDL IRadioSim. JB#61702 2024-09-23 23:37:55 +03:00
Nikita Ukhrenkov
b8917f5985 [gbinder-radio] Implement support for AIDL IRadioModem. JB#61702 2024-09-23 23:37:55 +03:00
Nikita Ukhrenkov
453595be28 [gbinder-radio] Implement support for AIDL IRadioConfig. JB#61702 2024-09-23 23:37:55 +03:00
Matti Lehtimäki
4803615920 Version 1.5.6 2023-04-21 14:56:04 +03:00
Matti Lehtimäki
d4a04ab083 Version 1.5.5 2023-04-14 22:44:58 +03:00
Matti Lehtimäki
5cf3d8c3cc Merge pull request #27 from mer-hybris/jb58746-fixes
Add missing RadioAppStatus_1_5 struct and radio indication filter enum values. Fix cell identity enum values.
2023-04-14 22:40:27 +03:00
Matti Lehtimäki
b319fa4dc6 [gbinder-radio] Add missing RadioAppStatus_1_5 struct. JB#58746 2023-04-12 16:55:21 +03:00
Matti Lehtimäki
5cfa6756ee [gbinder-radio] Add missing radio indication filter enum values for IRadio@1.5 interface. JB#58746 2023-04-12 16:55:18 +03:00
Matti Lehtimäki
a997d138fa [gbinder-radio] Fix RADIO_CELL_IDENTITY_TYPE_1_5 enum values. JB#58746 2023-04-12 16:51:52 +03:00
Slava Monich
48da098644 Version 1.5.4 2022-11-30 19:17:31 +02:00
Slava Monich
3d3e023fe8 Merge pull request #26 from mer-hybris/jb58763
Add NR support
2022-11-30 19:10:06 +02:00
Matti Lehtimäki
a9da4c95d2 [gbinder-radio] Add RadioPhysicalChannelConfig structs. JB#58763
Available for IRadio@1.2 and IRadio@1.4.
2022-11-30 18:57:25 +02:00
Matti Lehtimäki
6407a0271c [gbinder-radio] Add missing enums for NR. JB#58763 2022-11-30 18:57:25 +02:00
Matti Lehtimäki
05073a8367 [gbinder-radio] Fix RadioCellIdentity_1_5 struct. JB#58746 2022-11-30 18:57:25 +02:00
Slava Monich
7725869a27 Version 1.5.3 2022-11-19 17:52:18 +02:00
Slava Monich
7b33c6d70b Merge pull request #25 from monich/ran
Add RADIO_ACCESS_NETWORKS enum
2022-11-19 17:41:50 +02:00
Slava Monich
b38ddeb4c0 [gbinder-radio] Added RADIO_ACCESS_NETWORKS enum. JB#58746
There are two similar enums defined in types.hal files, AccessNetwork
and RadioAccessNetworks. They can be easily confused with each other
and yet their enum values e.g. for NGRAN are different (although GERAN,
UTRAN and EUTRAN values match). Our mapping goes like this:

  AccessNetwork => RADIO_ACCESS_NETWORK
  RadioAccessNetworks => RADIO_ACCESS_NETWORKS
2022-11-19 03:48:48 +02:00
Slava Monich
db387d213a [gbinder-radio] Housekeeping. JB#58006
Fixed comments, use appropriate enums
2022-11-19 03:44:50 +02:00
Slava Monich
ae0af8512f Version 1.5.2 2022-11-17 03:13:49 +02:00
Slava Monich
bf51970422 Merge pull request #24 from monich/scan
Added network scan related types
2022-11-17 03:07:29 +02:00
Slava Monich
e11e9a7eb1 [gbinder-radio] Added network scan related types. JB#58746 2022-11-17 03:04:32 +02:00
Slava Monich
606801a3c3 Version 1.5.1 2022-11-14 22:37:48 +02:00
Slava Monich
881dd6eef9 Merge pull request #23 from monich/resp-names
Fixed names of 1.4 and 1.5 responses
2022-11-14 21:43:43 +02:00
Slava Monich
66ed8a3c7d [gbinder-radio] Fixed names of 1.4 and 1.5 responses. JB#58006
Now they match declarations in the .hal files instead of being e.g.
startNetworkScan_1_4Response vs startNetworkScanResponse_1_4
2022-11-14 21:02:05 +02:00
Slava Monich
89f3f5886f Version 1.5.0 2022-09-16 14:17:18 +03:00
Slava Monich
499e48df9a [gbinder-radio] Fixed getCellInfoList/getDataCallList response mapping
Since getCellInfoListResponse_1_5 is the last one, it must be returned
not just for 1.5 but also for all subsequent versions of the interface.

The same logic applies to getDataCallListResponse_1_5
2022-09-16 14:08:05 +03:00
Slava Monich
ad536645e7 Merge pull request #22 from mer-hybris/jb58746
Add support for Radio@1.5 and RadioConfig@1.2
2022-09-16 13:36:21 +03:00
Matti Lehtimäki
0281a5ccdc [gbinder-radio] Add support for RadioConfig@1.2. JB#58746 2022-09-16 03:36:29 +03:00
Matti Lehtimäki
ce70fb9744 [gbinder-radio] Add support for IRadio@1.5. JB#58746 2022-09-16 03:36:28 +03:00
Slava Monich
4e0723ca6c Version 1.4.12 2022-09-11 21:38:15 +03:00
Slava Monich
050f83a22b Merge pull request #21 from mer-hybris/jb58091-struct
Fix RadioDataRegStateResult struct for IRadio@1.4
2022-09-11 21:31:26 +03:00
Matti Lehtimäki
736032efa0 [gbinder-radio] Fix RadioDataRegStateResult struct for IRadio@1.4. JB#58091 2022-09-11 20:43:43 +03:00
Slava Monich
c6d8e8d1e6 Version 1.4.11 2022-08-31 19:12:54 +03:00
Slava Monich
ee7fdd06d4 Merge pull request #20 from monich/user_data
Add radio_request_user_data()
2022-08-31 19:08:22 +03:00
Slava Monich
8fa78cc777 [gbinder-radio] Added radio_request_user_data(). JB#58006 2022-08-31 14:29:45 +03:00
Slava Monich
f4276f8602 Version 1.4.10 2022-04-15 22:01:08 +03:00
Slava Monich
ff1195ffc6 Merge pull request #19 from monich/complete
Tweak completion callback criteria
2022-04-15 21:55:43 +03:00
Slava Monich
11673897fa [gbinder-radio] Tweaked completion callback criteria. JB#58006
Don't invoke completion callback for the requests that were
never submitted.
2022-04-15 21:22:06 +03:00
Slava Monich
520fe4257a Version 1.4.9 2022-02-17 01:49:55 +02:00
Slava Monich
179e8d6160 Merge pull request #18 from monich/ims
Add IMS types
2022-02-17 01:32:49 +02:00
Slava Monich
6d52c79f6c [gbinder-radio] Added IMS types. JB#57425 2022-02-17 00:53:56 +02:00
Slava Monich
48026e4fe6 Version 1.4.8 2022-01-19 03:34:14 +02:00
Slava Monich
451711a1ce Merge pull request #17 from monich/block-retry
Fix retries of blocking requests
2022-01-19 03:29:44 +02:00
Slava Monich
32523f2b1a [unit] Added test for retry of a blocking request. JB#57102 2022-01-19 03:24:54 +02:00
Slava Monich
e0e475c4e3 [gbinder-radio] Fixed retries of blocking requests. JB#57102
A blocking request shouldn't block itself.
2022-01-19 01:25:00 +02:00
Slava Monich
02789fa6a4 [gbinder-radio] More logging in radio_request_default_retry()
To make it clear why request was (or wasn't) retried
2022-01-19 01:22:12 +02:00
Slava Monich
6a4f434592 Version 1.4.7 2022-01-10 01:04:17 +02:00
Slava Monich
a96fdf6c42 [gbinder-radio] Fixed owner queue logic. JB#56824 2022-01-10 01:02:01 +02:00
Slava Monich
77a9b126ef [gbinder-radio] Added internal DEBUG_ASSERT macro
It's an assert fatal in debug build and non-fatal in release.
Marks truely unavoidable conditions.
2022-01-09 19:30:39 +02:00
Slava Monich
5085ccc3c6 [gbinder-radio] Houskeeping
radio_base_ref/unref are unnecessary. It's an internal API, it
doesn't add much to compile time type safety, and the object
pointer is always checked for NULL by the caller anyway,
there's no need to check it twice.
2022-01-09 19:28:02 +02:00
Slava Monich
4eb1ced700 Version 1.4.6 2022-01-08 21:23:41 +02:00
Slava Monich
68ff7696d7 [license] Freshened up copyright 2022-01-08 21:23:30 +02:00
Slava Monich
b6021807dd [gbinder-radio] Fixed compilation issues
Older build environments don't know uint and ulong:

src/radio_base.c: In function 'radio_base_submit_request':
src/radio_base.c:527:9: error: unknown type name 'uint'
         const uint timeout = radio_base_timeout_ms(self, req);
         ^

src/radio_request.c: In function 'radio_request_set_timeout':
src/radio_request.c:276:13: error: unknown type name 'uint'
             const uint timeout = radio_base_timeout_ms(base, req);
             ^

unit_instance.c: In function 'test_connected':
unit_instance.c:425:5: error: unknown type name 'ulong'
     ulong id[4];
     ^
2022-01-08 21:20:39 +02:00
Slava Monich
ea6071fb11 Merge pull request #16 from monich/radio-config
Added RadioConfig API
2022-01-08 20:52:34 +02:00
Slava Monich
b50d08ddd9 [gbinder-radio] Added RadioConfig API. JB#56824
Simplifies talking to IRadioConfig binder service.
2022-01-08 20:46:00 +02:00
Slava Monich
2f4b216758 [gbinder-radio] Fixed compilation warning
Some older systems produce this:

test_gbinder_client.c:236:13: warning: implicit declaration of
function 'qsort' [-Wimplicit-function-declaration]

    qsort(self->ranges, count, sizeof(TestGBinderClientIfaceRange),
    ^
2022-01-03 04:14:23 +02:00
Slava Monich
0af836aa7a [gbinder-radio] Moved reusable code to RadioBase class. JB#56824 2021-12-29 21:26:06 +02:00
Slava Monich
d2227efa9e Version 1.4.5 2021-12-16 01:25:42 +02:00
Slava Monich
092bc3aa5f Merge pull request #15 from monich/radio_req_resp2
Add radio_req_resp2()
2021-12-16 01:23:12 +02:00
Slava Monich
f52b5e98d6 [gbinder-radio] Added radio_req_resp2(). JB#56484
Reliable request-to-response mapping requires interface version
as a parameter.
2021-12-16 01:12:38 +02:00
50 changed files with 7771 additions and 1424 deletions

View File

@@ -1,5 +1,5 @@
Copyright (C) 2018-2021 Jolla Ltd.
Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
Copyright (C) 2018-2022 Jolla Ltd.
Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
You may use this file under the terms of the BSD license as follows:

View File

@@ -23,8 +23,8 @@ all: debug release pkgconfig
#
VERSION_MAJOR = 1
VERSION_MINOR = 4
VERSION_RELEASE = 4
VERSION_MINOR = 6
VERSION_RELEASE = 0
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
@@ -47,7 +47,9 @@ LIB = $(LIB_NAME).a
#
SRC = \
radio_base.c \
radio_client.c \
radio_config.c \
radio_instance.c \
radio_registry.c \
radio_request.c \
@@ -236,7 +238,7 @@ INSTALL_PKGCONFIG_DIR = $(DESTDIR)$(ABS_LIBDIR)/pkgconfig
install: $(INSTALL_LIB_DIR)
$(INSTALL) -m 755 $(RELEASE_SO) $(INSTALL_LIB_DIR)
ln -sf $(LIB_SO) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK2)
ln -sf $(LIB_SYMLINK2) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK1)
ln -sf $(LIB_SO) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK1)
install-dev: install $(INSTALL_INCLUDE_DIR) $(INSTALL_PKGCONFIG_DIR)
$(INSTALL_FILES) $(INCLUDE_DIR)/*.h $(INSTALL_INCLUDE_DIR)

10
debian/Jenkinsfile vendored Normal file
View File

@@ -0,0 +1,10 @@
@Library('ubports-build-tools') _
buildAndProvideDebianPackage()
// Or if the package consists entirely of arch-independent packages:
// (optional optimization, will confuse BlueOcean's live view at build stage)
// buildAndProvideDebianPackage(/* isArchIndependent */ true)
// Optionally, to skip building on some architectures (amd64 is always built):
// buildAndProvideDebianPackage(false, /* ignoredArchs */ ['arm64'])

105
debian/changelog vendored
View File

@@ -1,96 +1,49 @@
libgbinder-radio (1.4.4) unstable; urgency=medium
libgbinder-radio (1.6.0-0ubports1) UNRELEASED; urgency=unknown
* Added IRadio@1.2 IndicationFilter bits
* New upstream release v1.6.0
-- Slava Monich <slava.monich@jolla.com> Tue, 14 Dec 2021 18:01:43 +0200
-- UBports package upgrader bot <dev@ubports.com> Fri, 13 Dec 2024 04:07:25 +0000
libgbinder-radio (1.4.3) unstable; urgency=medium
libgbinder-radio (1.5.6-0ubports1) UNRELEASED; urgency=unknown
* Added RadioClient and related APIs
* New upstream release v1.5.6
-- Slava Monich <slava.monich@jolla.com> Thu, 02 Dec 2021 19:08:47 +0200
-- UBports package upgrader bot <dev@ubports.com> Thu, 09 Nov 2023 00:27:17 +0000
libgbinder-radio (1.4.2) unstable; urgency=medium
libgbinder-radio (1.5.4-0ubports1) focal; urgency=medium
* Don't assume that GBinderServiceManager is a GObject
* Added unit tests
* Update from upstream
-- Slava Monich <slava.monich@jolla.com> Sun, 12 Sep 2021 18:05:19 +0300
-- Lionel Duboeuf <lduboeuf@ouvaton.org> Wed, 08 Jan 2023 10:52:34 +0100
libgbinder-radio (1.4.1) unstable; urgency=medium
libgbinder-radio (1.4.2-0ubports4) focal; urgency=medium
* Added RADIO_CELL_INFO_TYPE_1_4 enum
* Rename libgbinder-radio-dev to libgbinder-radio1-dev
* Generate install files correctly again
-- Slava Monich <slava.monich@jolla.com> Thu, 20 May 2021 16:32:16 +0300
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Wed, 24 Nov 2021 10:52:34 +0100
libgbinder-radio (1.4.0) unstable; urgency=medium
libgbinder-radio (1.4.2-0ubports3) focal; urgency=medium
* Support for radio@1.4 interfaces
* Fixed RadioCellInfo_1_4 definition
* Switch to dh version 12
* Fix lintian warnings and errors
* Add fix-library-symlink.patch: fix symlink according to Debian policy
* Rename library package based on soname
* Add long description, improve short description
* Use static install files
* Add section to source package
* Specify homepage and VCS
-- Slava Monich <slava.monich@jolla.com> Tue, 18 May 2021 18:54:52 +0300
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Mon, 15 Nov 2021 15:02:18 +0100
libgbinder-radio (1.2.6) unstable; urgency=medium
libgbinder-radio (1.4.2-0ubports2) focal; urgency=medium
* Added RadioSimApdu type
* Bump version, no changes.
-- Slava Monich <slava.monich@jolla.com> Sun, 25 Apr 2021 14:41:32 +0300
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Thu, 11 Nov 2021 15:02:07 +0100
libgbinder-radio (1.2.5) unstable; urgency=medium
libgbinder-radio (1.4.2-0ubports1) focal; urgency=medium
* Added radio@1.3 types
* Added radio@1.4 types
* Initial packaging for UBPorts
-- Slava Monich <slava.monich@jolla.com> Thu, 25 Mar 2021 20:13:08 +0200
libgbinder-radio (1.2.4) unstable; urgency=medium
* Added more radio@1.2 types
-- Slava Monich <slava.monich@jolla.com> Sat, 20 Mar 2021 02:41:07 +0200
libgbinder-radio (1.2.3) unstable; urgency=medium
* Reformatted radio@1.2 types
-- Slava Monich <slava.monich@jolla.com> Fri, 19 Mar 2021 05:21:52 +0200
libgbinder-radio (1.2.2) unstable; urgency=medium
* Added radio_instance_get_with_version()
-- Slava Monich <slava.monich@jolla.com> Fri, 05 Mar 2021 14:00:20 +0200
libgbinder-radio (1.2.1) unstable; urgency=medium
* Fixed backward compatibility with radio@1.0
-- Slava Monich <slava.monich@jolla.com> Fri, 05 Mar 2021 12:33:50 +0200
libgbinder-radio (1.2.0) unstable; urgency=medium
* Support for radio@1.2 interfaces
-- Slava Monich <slava.monich@jolla.com> Thu, 04 Mar 2021 13:36:51 +0200
libgbinder-radio (1.0.11) unstable; urgency=medium
* Make library executable on RPM based systems
* Added req => resp mapping for radio@1.1 calls
-- Slava Monich <slava.monich@jolla.com> Thu, 01 Oct 2020 21:04:59 +0300
libgbinder-radio (1.0.10) unstable; urgency=medium
* Hide internal symbols
* Respect arch specific lib dir
* Ignore GLib deprecation warnings
* Added constants for android.hardware.radio@1.1 interfaces
-- Slava Monich <slava.monich@jolla.com> Wed, 03 Jun 2020 15:24:17 +0300
libgbinder-radio (1.0.9) unstable; urgency=medium
* Added packaging for Debian-based distros.
-- Danct12 <danct12@disroot.org> Tue, 24 Mar 2020 02:55:50 +0700
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Mon, 11 Oct 2021 16:38:02 +0200

1
debian/compat vendored
View File

@@ -1 +0,0 @@
9

30
debian/control vendored
View File

@@ -1,17 +1,31 @@
Source: libgbinder-radio
Priority: optional
Maintainer: Danct12 <danct12@disroot.org>
Build-Depends: debhelper (>=9), libgbinder-dev (>= 1.1.14), libglibutil-dev (>= 1.0.49)
Maintainer: UBports developers <devs@ubports.com>
Build-Depends: debhelper-compat (= 12),
libgbinder-dev (>= 1.1.14),
libglib2.0-dev,
libglibutil-dev,
Standards-Version: 3.9.6
Section: libs
Homepage: https://github.com/mer-hybris/libgbinder-radio
Vcs-Git: https://github.com/mer-hybris/libgbinder-radio.git
Vcs-Browser: https://github.com/mer-hybris/libgbinder-radio
Package: libgbinder-radio-dev
Package: libgbinder-radio1-dev
Section: libdevel
Architecture: any
Depends: libgbinder-radio (= ${binary:Version}), ${misc:Depends}
Description: Development files for libgbinder-radio
Depends: libgbinder-radio1 (= ${binary:Version}),
${misc:Depends}
Description: Client library for Android radio interfaces (development files)
A helper library based on glib which allows communicating with Android radio
interfaces via Binder.
Package: libgbinder-radio
Package: libgbinder-radio1
Section: libs
Architecture: any
Depends: libgbinder (>= 1.1.14), libglibutil (>= 1.0.49), ${shlibs:Depends}, ${misc:Depends}
Description: Binder client library for Android radio interfaces
Depends: libgbinder (>= 1.0.9),
${shlibs:Depends},
${misc:Depends}
Description: Client library for Android radio interfaces
A helper library based on glib which allows communicating with Android radio
interfaces via Binder.

View File

@@ -0,0 +1,3 @@
debian/tmp/@LIBDIR@/libgbinder-radio.so @LIBDIR@
debian/tmp/@LIBDIR@/pkgconfig/libgbinder-radio.pc @LIBDIR@/pkgconfig
debian/tmp/usr/include/* usr/include

1
debian/libgbinder-radio1.install.in vendored Normal file
View File

@@ -0,0 +1 @@
debian/tmp/@LIBDIR@/libgbinder-radio.so.* @LIBDIR@

3
debian/rules vendored
View File

@@ -1,11 +1,12 @@
#!/usr/bin/make -f
# Uncomment to enable verbose build
#export DH_VERBOSE = 1
export DEB_BUILD_OPTIONS='nostrip debug'
LIBDIR=usr/lib/$(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
override_dh_auto_build:
dh_auto_build -- LIBDIR=$(LIBDIR) release pkgconfig debian/libgbinder-radio.install debian/libgbinder-radio-dev.install
dh_auto_build -- LIBDIR=$(LIBDIR) release pkgconfig debian/libgbinder-radio1.install debian/libgbinder-radio1-dev.install
override_dh_auto_install:
dh_auto_install -- LIBDIR=$(LIBDIR) install-dev

View File

@@ -74,6 +74,10 @@ RADIO_INTERFACE
radio_client_interface(
RadioClient* client);
RADIO_AIDL_INTERFACE
radio_client_aidl_interface(
RadioClient* client); /* Since 1.6.0 */
const char*
radio_client_slot(
RadioClient* client);

208
include/radio_config.h Normal file
View File

@@ -0,0 +1,208 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_CONFIG_H
#define RADIO_CONFIG_H
/* This API exists since 1.4.6 */
#include <radio_config_types.h>
#include <radio_config_aidl_types.h>
G_BEGIN_DECLS
typedef
void
(*RadioConfigFunc)(
RadioConfig* config,
gpointer user_data);
typedef
void
(*RadioConfigRequestObserverFunc)(
RadioConfig* config,
RADIO_CONFIG_REQ code,
GBinderLocalRequest* args,
gpointer user_data);
typedef
void
(*RadioConfigResponseObserverFunc)(
RadioConfig* config,
RADIO_CONFIG_RESP code,
const RadioResponseInfo* info,
const GBinderReader* args,
gpointer user_data);
typedef
void
(*RadioConfigIndicationObserverFunc)(
RadioConfig* config,
RADIO_CONFIG_IND code,
const GBinderReader* args,
gpointer user_data);
RadioConfig*
radio_config_new(void)
G_GNUC_WARN_UNUSED_RESULT;
RadioConfig*
radio_config_new_with_version(
RADIO_CONFIG_INTERFACE max_version)
G_GNUC_WARN_UNUSED_RESULT;
RadioConfig*
radio_config_new_with_version_and_interface_type(
RADIO_CONFIG_INTERFACE max_version,
RADIO_INTERFACE_TYPE interface_type)
G_GNUC_WARN_UNUSED_RESULT; /* Since 1.6.0 */
RadioConfig*
radio_config_ref(
RadioConfig* config);
void
radio_config_unref(
RadioConfig* config);
gboolean
radio_config_dead(
RadioConfig* config);
RADIO_INTERFACE_TYPE
radio_config_interface_type(
RadioConfig* self); /* Since 1.6.0 */
RADIO_CONFIG_INTERFACE
radio_config_interface(
RadioConfig* config);
gsize
radio_config_rpc_header_size(
RadioConfig* config,
RADIO_CONFIG_REQ req);
const char*
radio_config_req_name(
RadioConfig* config,
RADIO_CONFIG_REQ req);
const char*
radio_config_resp_name(
RadioConfig* config,
RADIO_CONFIG_RESP resp);
const char*
radio_config_ind_name(
RadioConfig* config,
RADIO_CONFIG_IND ind);
gulong
radio_config_add_death_handler(
RadioConfig* config,
RadioConfigFunc func,
gpointer user_data);
gulong
radio_config_add_request_observer(
RadioConfig* config,
RADIO_CONFIG_REQ code,
RadioConfigRequestObserverFunc func,
gpointer user_data);
gulong
radio_config_add_request_observer_with_priority(
RadioConfig* config,
RADIO_OBSERVER_PRIORITY priority,
RADIO_CONFIG_REQ code,
RadioConfigRequestObserverFunc func,
gpointer user_data);
gulong
radio_config_add_response_observer(
RadioConfig* config,
RADIO_CONFIG_RESP code,
RadioConfigResponseObserverFunc func,
gpointer user_data);
gulong
radio_config_add_response_observer_with_priority(
RadioConfig* config,
RADIO_OBSERVER_PRIORITY priority,
RADIO_CONFIG_RESP code,
RadioConfigResponseObserverFunc func,
gpointer user_data);
gulong
radio_config_add_indication_observer(
RadioConfig* config,
RADIO_CONFIG_IND code,
RadioConfigIndicationObserverFunc func,
gpointer user_data);
gulong
radio_config_add_indication_observer_with_priority(
RadioConfig* config,
RADIO_OBSERVER_PRIORITY priority,
RADIO_CONFIG_IND code,
RadioConfigIndicationObserverFunc func,
gpointer user_data);
void
radio_config_remove_handler(
RadioConfig* config,
gulong id);
void
radio_config_remove_handlers(
RadioConfig* config,
gulong* ids,
int count);
#define radio_config_remove_all_handlers(config,ids) \
radio_config_remove_handlers(config, ids, G_N_ELEMENTS(ids))
G_END_DECLS
#endif /* RADIO_CONFIG_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_CONFIG_AIDL_TYPES_H
#define RADIO_CONFIG_AIDL_TYPES_H
#include <radio_types.h>
G_BEGIN_DECLS
typedef enum radio_config_aidl_interface {
RADIO_CONFIG_AIDL_INTERFACE_NONE = -1,
RADIO_CONFIG_AIDL_INTERFACE_1,
RADIO_CONFIG_AIDL_INTERFACE_COUNT
} RADIO_CONFIG_AIDL_INTERFACE;
#define RADIO_CONFIG_AIDL_INTERFACE_MAX (RADIO_CONFIG_AIDL_INTERFACE_COUNT - 1)
#define RADIO_CONFIG_AIDL_INSTANCE "default"
#define RADIO_CONFIG_AIDL_IFACE_PREFIX "android.hardware.radio.config."
#define RADIO_CONFIG_AIDL_IFACE "IRadioConfig"
#define RADIO_CONFIG_AIDL_RESPONSE_IFACE "IRadioConfigResponse"
#define RADIO_CONFIG_AIDL_INDICATION_IFACE "IRadioConfigIndication"
#define RADIO_CONFIG_AIDL RADIO_CONFIG_AIDL_IFACE_PREFIX RADIO_CONFIG_AIDL_IFACE
#define RADIO_CONFIG_AIDL_FQNAME RADIO_CONFIG_AIDL "/" RADIO_CONFIG_AIDL_INSTANCE
#define RADIO_CONFIG_AIDL_RESPONSE RADIO_CONFIG_AIDL_IFACE_PREFIX RADIO_CONFIG_AIDL_RESPONSE_IFACE
#define RADIO_CONFIG_AIDL_INDICATION RADIO_CONFIG_AIDL_IFACE_PREFIX RADIO_CONFIG_AIDL_INDICATION_IFACE
/* Types defined in android.hardware.radio.config package */
/* PhoneCapability */
typedef struct radio_aidl_phone_capability {
guint8 maxActiveData RADIO_ALIGNED(4);
guint8 maxActiveInternetData RADIO_ALIGNED(4);
guint8 isInternetLingeringSupported RADIO_ALIGNED(4);
struct {
guint32 length;
guint8 data[];
} logicalModemList;
} RadioAidlPhoneCapability;
/* SimPortInfo */
typedef struct radio_aidl_sim_port_info {
struct {
guint32 length;
gchar data[];
} iccId;
gint32 logicalSlotId;
gboolean portActive;
} RadioAidlSimPortInfo;
/* SimSlotStatus */
typedef struct radio_aidl_sim_slot_status {
RADIO_CARD_STATE cardState;
GString* atr;
GString* eid;
struct {
guint32 length;
RadioAidlSimPortInfo data[];
} portInfo;
} RadioAidlSimSlotStatus;
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_CONFIG_AIDL_CALL_1(c) \
c(1,1,getHalDeviceCapabilities,GET_HAL_DEVICE_CAPABILITIES) \
c(2,2,getNumOfLiveModems,GET_NUM_OF_LIVE_MODEMS) \
c(3,3,getPhoneCapability,GET_PHONE_CAPABILITY) \
c(4,4,getSimSlotsStatus,GET_SIM_SLOTS_STATUS) \
c(5,5,setNumOfLiveModems,SET_NUM_OF_LIVE_MODEMS) \
c(6,6,setPreferredDataModem,SET_PREFERRED_DATA_MODEM) \
c(8,7,setSimSlotsMapping,SET_SIM_SLOTS_MAPPING) \
/* i(code,Name,IND_NAME) */
#define RADIO_CONFIG_AIDL_IND_1(i) \
i(1,simSlotsStatusChanged,SIM_SLOTS_STATUS_CHANGED) \
typedef enum radio_aidl_config_req {
RADIO_CONFIG_AIDL_REQ_ANY = 0,
RADIO_CONFIG_AIDL_REQ_NONE = 0,
#define RADIO_CONFIG_AIDL_REQ_(req,resp,Name,NAME) RADIO_CONFIG_AIDL_REQ_##NAME = req,
/* android.hardware.radio.config.IRadioConfig v1 */
RADIO_CONFIG_AIDL_REQ_SET_RESPONSE_FUNCTIONS = 7, /* setResponseFunctions */
RADIO_CONFIG_AIDL_CALL_1(RADIO_CONFIG_AIDL_REQ_)
RADIO_CONFIG_AIDL_1_REQ_LAST = RADIO_CONFIG_AIDL_REQ_SET_SIM_SLOTS_MAPPING,
#undef RADIO_CONFIG_AIDL_REQ_
} RADIO_CONFIG_AIDL_REQ;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_AIDL_REQ) == 4);
typedef enum radio_aidl_config_resp {
RADIO_CONFIG_AIDL_RESP_ANY = 0,
RADIO_CONFIG_AIDL_RESP_NONE = 0,
#define RADIO_CONFIG_AIDL_RESP_(req,resp,Name,NAME) RADIO_CONFIG_AIDL_RESP_##NAME = resp,
/* android.hardware.radio.config.IRadioConfigResponse v1 */
RADIO_CONFIG_AIDL_CALL_1(RADIO_CONFIG_AIDL_RESP_)
RADIO_CONFIG_AIDL_1_RESP_LAST = RADIO_CONFIG_AIDL_RESP_SET_SIM_SLOTS_MAPPING,
#undef RADIO_CONFIG_AIDL_RESP_
} RADIO_CONFIG_AIDL_RESP;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_AIDL_RESP) == 4);
typedef enum radio_aidl_config_ind {
RADIO_CONFIG_AIDL_IND_ANY = 0,
RADIO_CONFIG_AIDL_IND_NONE = 0,
#define RADIO_CONFIG_AIDL_IND_(code,Name,NAME) RADIO_CONFIG_AIDL_IND_##NAME = code,
/* android.hardware.radio.config.IRadioConfigIndication v1 */
RADIO_CONFIG_AIDL_IND_1(RADIO_CONFIG_AIDL_IND_)
RADIO_CONFIG_AIDL_1_IND_LAST = RADIO_CONFIG_AIDL_IND_SIM_SLOTS_STATUS_CHANGED,
#undef RADIO_CONFIG_AIDL_IND_
} RADIO_CONFIG_AIDL_IND;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_AIDL_IND) == 4);
G_END_DECLS
#endif /* RADIO_CONFIG_AIDL_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_CONFIG_TYPES_H
#define RADIO_CONFIG_TYPES_H
/* This API exists since 1.4.6 */
#include <radio_types.h>
G_BEGIN_DECLS
typedef enum radio_config_interface {
RADIO_CONFIG_INTERFACE_NONE = -1,
RADIO_CONFIG_INTERFACE_1_0,
RADIO_CONFIG_INTERFACE_1_1,
RADIO_CONFIG_INTERFACE_1_2, /* Since 1.5.0 */
RADIO_CONFIG_INTERFACE_COUNT
} RADIO_CONFIG_INTERFACE;
#define RADIO_CONFIG_INTERFACE_MAX (RADIO_CONFIG_INTERFACE_COUNT - 1)
#define RADIO_CONFIG_INSTANCE "default"
#define RADIO_CONFIG_IFACE_PREFIX "android.hardware.radio.config@"
#define RADIO_CONFIG_IFACE "IRadioConfig"
#define RADIO_CONFIG_RESPONSE_IFACE "IRadioConfigResponse"
#define RADIO_CONFIG_INDICATION_IFACE "IRadioConfigIndication"
#define RADIO_CONFIG_IFACE_1_0(x) RADIO_CONFIG_IFACE_PREFIX "1.0::" x
#define RADIO_CONFIG_IFACE_1_1(x) RADIO_CONFIG_IFACE_PREFIX "1.1::" x
#define RADIO_CONFIG_IFACE_1_2(x) RADIO_CONFIG_IFACE_PREFIX "1.2::" x
#define RADIO_CONFIG_1_0 RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_IFACE)
#define RADIO_CONFIG_1_1 RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_IFACE)
#define RADIO_CONFIG_1_2 RADIO_CONFIG_IFACE_1_2(RADIO_CONFIG_IFACE)
#define RADIO_CONFIG_1_0_FQNAME RADIO_CONFIG_1_0 "/" RADIO_CONFIG_INSTANCE
#define RADIO_CONFIG_1_1_FQNAME RADIO_CONFIG_1_1 "/" RADIO_CONFIG_INSTANCE
#define RADIO_CONFIG_1_2_FQNAME RADIO_CONFIG_1_2 "/" RADIO_CONFIG_INSTANCE
#define RADIO_CONFIG_RESPONSE_1_0 \
RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_RESPONSE_IFACE)
#define RADIO_CONFIG_RESPONSE_1_1 \
RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_RESPONSE_IFACE)
#define RADIO_CONFIG_RESPONSE_1_2 \
RADIO_CONFIG_IFACE_1_2(RADIO_CONFIG_RESPONSE_IFACE)
#define RADIO_CONFIG_INDICATION_1_0 \
RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_INDICATION_IFACE)
#define RADIO_CONFIG_INDICATION_1_1 \
RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_INDICATION_IFACE)
#define RADIO_CONFIG_INDICATION_1_2 \
RADIO_CONFIG_IFACE_1_2(RADIO_CONFIG_INDICATION_IFACE)
/* Types defined in types.hal */
/* SlotState */
typedef enum radio_slot_state {
RADIO_SLOT_STATE_INACTIVE,
RADIO_SLOT_STATE_ACTIVE
} RADIO_SLOT_STATE;
G_STATIC_ASSERT(sizeof(RADIO_SLOT_STATE) == 4);
/* SimSlotStatus */
typedef struct radio_sim_slot_status {
RADIO_CARD_STATE cardState RADIO_ALIGNED(4);
RADIO_SLOT_STATE slotState RADIO_ALIGNED(4);
GBinderHidlString atr RADIO_ALIGNED(8);
guint32 logicalSlotId RADIO_ALIGNED(4);
GBinderHidlString iccid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioSimSlotStatus;
G_STATIC_ASSERT(sizeof(RadioSimSlotStatus) == 48);
/* ModemInfo */
typedef struct radio_modem_info {
guint8 modemId RADIO_ALIGNED(1);
} RADIO_ALIGNED(1) RadioModemInfo;
G_STATIC_ASSERT(sizeof(RadioModemInfo) == 1);
/* PhoneCapability */
typedef struct radio_phone_capability {
guint8 maxActiveData RADIO_ALIGNED(1);
guint8 maxActiveInternetData RADIO_ALIGNED(1);
guint8 isInternetLingeringSupported RADIO_ALIGNED(1);
GBinderHidlVec logicalModemList RADIO_ALIGNED(8); /* vec<ModemInfo> */
} RADIO_ALIGNED(8) RadioPhoneCapability;
G_STATIC_ASSERT(sizeof(RadioPhoneCapability) == 24);
/* ModemsConfig */
typedef struct radio_modems_config {
guint8 numOfLiveModems RADIO_ALIGNED(1);
} RADIO_ALIGNED(1) RadioModemsConfig;
G_STATIC_ASSERT(sizeof(RadioModemsConfig) == 1);
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_CONFIG_CALL_1_0(c) \
c(2,1,getSimSlotsStatus,GET_SIM_SLOTS_STATUS) \
c(3,2,setSimSlotsMapping,SET_SIM_SLOTS_MAPPING)
#define RADIO_CONFIG_CALL_1_1(c) \
c(4,3,getPhoneCapability,GET_PHONE_CAPABILITY) \
c(5,4,setPreferredDataModem,SET_PREFERRED_DATA_MODEM) \
c(6,5,setModemsConfig,SET_MODEMS_CONFIG) \
c(7,6,getModemsConfig,GET_MODEMS_CONFIG)
/* i(code,Name,IND_NAME) */
#define RADIO_CONFIG_IND_1_0(i) \
i(1,simSlotsStatusChanged,SIM_SLOTS_STATUS_CHANGED)
#define RADIO_CONFIG_IND_1_2(i) \
i(2,simSlotsStatusChanged_1_2,SIM_SLOTS_STATUS_CHANGED_1_2) /* Since 1.5.0 */
typedef enum radio_config_req {
RADIO_CONFIG_REQ_ANY = 0,
RADIO_CONFIG_REQ_NONE = 0,
#define RADIO_CONFIG_REQ_(req,resp,Name,NAME) RADIO_CONFIG_REQ_##NAME = req,
/* android.hardware.radio.config@1.0::IRadioConfig */
RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS = 1, /* setResponseFunctions */
RADIO_CONFIG_CALL_1_0(RADIO_CONFIG_REQ_)
RADIO_CONFIG_1_0_REQ_LAST = RADIO_CONFIG_REQ_SET_SIM_SLOTS_MAPPING,
/* android.hardware.radio.config@1.1::IRadioConfig */
RADIO_CONFIG_CALL_1_1(RADIO_CONFIG_REQ_)
RADIO_CONFIG_1_1_REQ_LAST = RADIO_CONFIG_REQ_GET_MODEMS_CONFIG
#undef RADIO_CONFIG_REQ_
} RADIO_CONFIG_REQ;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_REQ) == 4);
typedef enum radio_config_resp {
RADIO_CONFIG_RESP_ANY = 0,
RADIO_CONFIG_RESP_NONE = 0,
#define RADIO_CONFIG_RESP_(req,resp,Name,NAME) RADIO_CONFIG_RESP_##NAME = resp,
/* android.hardware.radio.config@1.0::IRadioConfigResponse */
RADIO_CONFIG_CALL_1_0(RADIO_CONFIG_RESP_)
RADIO_CONFIG_1_0_RESP_LAST = RADIO_CONFIG_RESP_SET_SIM_SLOTS_MAPPING,
/* android.hardware.radio.config@1.1::IRadioConfigResponse */
RADIO_CONFIG_CALL_1_1(RADIO_CONFIG_RESP_)
RADIO_CONFIG_1_1_RESP_LAST = RADIO_CONFIG_RESP_GET_MODEMS_CONFIG,
/* android.hardware.radio.config@1.2::IRadioConfigResponse */
RADIO_CONFIG_RESP_GET_SIM_SLOTS_STATUS_1_2 = 7, /* Since 1.5.0 */
RADIO_CONFIG_1_2_RESP_LAST = RADIO_CONFIG_RESP_GET_SIM_SLOTS_STATUS_1_2
#undef RADIO_CONFIG_RESP_
} RADIO_CONFIG_RESP;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_RESP) == 4);
typedef enum radio_config_ind {
RADIO_CONFIG_IND_ANY = 0,
RADIO_CONFIG_IND_NONE = 0,
#define RADIO_CONFIG_IND_(code,Name,NAME) RADIO_CONFIG_IND_##NAME = code,
/* android.hardware.radio.config@1.0::IRadioConfigIndication */
RADIO_CONFIG_IND_1_0(RADIO_CONFIG_IND_)
RADIO_CONFIG_1_0_IND_LAST = RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED,
/* android.hardware.radio.config@1.2::IRadioConfigIndication */
RADIO_CONFIG_IND_1_2(RADIO_CONFIG_IND_) /* Since 1.5.0 */
RADIO_CONFIG_1_2_IND_LAST = RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED_1_2
#undef RADIO_CONFIG_IND_
} RADIO_CONFIG_IND;
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_IND) == 4);
G_END_DECLS
#endif /* RADIO_CONFIG_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

134
include/radio_data_types.h Normal file
View File

@@ -0,0 +1,134 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_DATA_TYPES_H
#define RADIO_DATA_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_DATA_INTERFACE_MAX (RADIO_DATA_INTERFACE_COUNT - 1)
#define RADIO_DATA_INSTANCE "default"
#define RADIO_DATA_IFACE_PREFIX "android.hardware.radio.data."
#define RADIO_DATA_IFACE "IRadioData"
#define RADIO_DATA_RESPONSE_IFACE "IRadioDataResponse"
#define RADIO_DATA_INDICATION_IFACE "IRadioDataIndication"
#define RADIO_DATA RADIO_DATA_IFACE_PREFIX RADIO_DATA_IFACE
#define RADIO_DATA_FQNAME RADIO_DATA "/" RADIO_DATA_INSTANCE
#define RADIO_DATA_RESPONSE RADIO_DATA_IFACE_PREFIX RADIO_DATA_RESPONSE_IFACE
#define RADIO_DATA_INDICATION RADIO_DATA_IFACE_PREFIX RADIO_DATA_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_DATA_CALL_1(c) \
c(1,2,allocatePduSessionId,ALLOCATE_PDU_SESSION_ID) \
c(2,3,cancelHandover,CANCEL_HANDOVER) \
c(3,4,deactivateDataCall,DEACTIVATE_DATA_CALL) \
c(4,5,getDataCallList,GET_DATA_CALL_LIST) \
c(5,6,getSlicingConfig,GET_SLICING_CONFIG) \
c(6,7,releasePduSessionId,RELEASE_PDU_SESSION_ID) \
c(8,8,setDataAllowed,SET_DATA_ALLOWED) \
c(9,9,setDataProfile,SET_DATA_PROFILE) \
c(10,10,setDataThrottling,SET_DATA_THROTTLING) \
c(11,11,setInitialAttachApn,SET_INITIAL_ATTACH_APN) \
c(13,12,setupDataCall,SETUP_DATA_CALL) \
c(14,13,startHandover,START_HANDOVER) \
c(15,14,startKeepalive,START_KEEPALIVE) \
c(16,15,stopKeepalive,STOP_KEEPALIVE) \
/* i(code,Name,IND_NAME) */
#define RADIO_DATA_IND_1(i) \
i(1,dataCallListChanged,DATA_CALL_LIST_CHANGED) \
i(2,keepaliveStatus,KEEPALIVE_STATUS) \
i(3,pcoData,PCO_DATA) \
i(4,unthrottleApn,UNTHROTTLE_APN) \
i(5,slicingConfigChanged,SLICING_CONFIG_CHANGED) \
typedef enum radio_data_req {
RADIO_DATA_REQ_ANY = 0,
RADIO_DATA_REQ_NONE = 0,
#define RADIO_DATA_REQ_(req,resp,Name,NAME) RADIO_DATA_REQ_##NAME = req,
/* android.hardware.radio.data.IRadioData v1 */
RADIO_DATA_CALL_1(RADIO_DATA_REQ_)
RADIO_DATA_REQ_RESPONSE_ACKNOWLEDGEMENT = 7, /* responseAcknowledgement */
RADIO_DATA_REQ_SET_RESPONSE_FUNCTIONS = 12, /* setResponseFunctions */
RADIO_DATA_1_REQ_LAST = RADIO_DATA_REQ_STOP_KEEPALIVE,
#undef RADIO_DATA_REQ_
} RADIO_DATA_REQ;
G_STATIC_ASSERT(sizeof(RADIO_DATA_REQ) == 4);
typedef enum radio_data_resp {
RADIO_DATA_RESP_ANY = 0,
RADIO_DATA_RESP_NONE = 0,
#define RADIO_DATA_RESP_(req,resp,Name,NAME) RADIO_DATA_RESP_##NAME = resp,
/* android.hardware.radio.data.IRadioDataResponse v1 */
RADIO_DATA_CALL_1(RADIO_DATA_RESP_)
RADIO_DATA_RESP_ACKNOWLEDGE_REQUEST = 1, /* acknowledgeRequest */
RADIO_DATA_1_RESP_LAST = RADIO_DATA_RESP_STOP_KEEPALIVE,
#undef RADIO_DATA_RESP_
} RADIO_DATA_RESP;
G_STATIC_ASSERT(sizeof(RADIO_DATA_RESP) == 4);
typedef enum radio_data_ind {
RADIO_DATA_IND_ANY = 0,
RADIO_DATA_IND_NONE = 0,
#define RADIO_DATA_IND_(code,Name,NAME) RADIO_DATA_IND_##NAME = code,
/* android.hardware.radio.data.IRadioDataIndication v1 */
RADIO_DATA_IND_1(RADIO_DATA_IND_)
RADIO_DATA_1_IND_LAST = RADIO_DATA_IND_SLICING_CONFIG_CHANGED,
#undef RADIO_DATA_IND_
} RADIO_DATA_IND;
G_STATIC_ASSERT(sizeof(RADIO_DATA_IND) == 4);
G_END_DECLS
#endif /* RADIO_DATA_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

123
include/radio_ims_types.h Normal file
View File

@@ -0,0 +1,123 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_IMS_TYPES_H
#define RADIO_IMS_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_IMS_INTERFACE_MAX (RADIO_IMS_INTERFACE_COUNT - 1)
#define RADIO_IMS_INSTANCE "default"
#define RADIO_IMS_IFACE_PREFIX "android.hardware.radio.ims."
#define RADIO_IMS_IFACE "IRadioIms"
#define RADIO_IMS_RESPONSE_IFACE "IRadioImsResponse"
#define RADIO_IMS_INDICATION_IFACE "IRadioImsIndication"
#define RADIO_IMS RADIO_IMS_IFACE_PREFIX RADIO_IMS_IFACE
#define RADIO_IMS_FQNAME RADIO_IMS "/" RADIO_IMS_INSTANCE
#define RADIO_IMS_RESPONSE RADIO_IMS_IFACE_PREFIX RADIO_IMS_RESPONSE_IFACE
#define RADIO_IMS_INDICATION RADIO_IMS_IFACE_PREFIX RADIO_IMS_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_IMS_CALL_1(c) \
c(1,1,setSrvccCallInfo,SET_SRVCC_CALL_INFO) \
c(2,2,updateImsRegistrationInfo,UPDATE_IMS_REGISTRATION_INFO) \
c(3,3,startImsTraffic,START_IMS_TRAFFIC) \
c(4,4,stopImsTraffic,STOP_IMS_TRAFFIC) \
c(5,5,triggerEpsFallback,TRIGGER_EPS_FALLBACK) \
c(7,6,sendAnbrQuery,SEND_ANBR_QUERY) \
c(8,7,updateImsCallStatus,UPDATE_IMS_CALL_STATUS) \
/* i(code,Name,IND_NAME) */
#define RADIO_IMS_IND_1(i) \
i(1,onConnectionSetupFailure,ON_CONNECTION_SETUP_FAILURE) \
i(2,notifyAnbr,NOTIFY_ANBR) \
i(3,triggerImsDeregistration,TRIGGER_IMS_DEREGISTRATION) \
typedef enum radio_ims_req {
RADIO_IMS_REQ_ANY = 0,
RADIO_IMS_REQ_NONE = 0,
#define RADIO_IMS_REQ_(req,resp,Name,NAME) RADIO_IMS_REQ_##NAME = req,
/* android.hardware.radio.ims.IRadioIms v1 */
RADIO_IMS_CALL_1(RADIO_IMS_REQ_)
RADIO_IMS_REQ_SET_RESPONSE_FUNCTIONS = 6, /* setResponseFunctions */
RADIO_IMS_1_REQ_LAST = RADIO_IMS_REQ_UPDATE_IMS_CALL_STATUS,
#undef RADIO_IMS_REQ_
} RADIO_IMS_REQ;
G_STATIC_ASSERT(sizeof(RADIO_IMS_REQ) == 4);
typedef enum radio_ims_resp {
RADIO_IMS_RESP_ANY = 0,
RADIO_IMS_RESP_NONE = 0,
#define RADIO_IMS_RESP_(req,resp,Name,NAME) RADIO_IMS_RESP_##NAME = resp,
/* android.hardware.radio.ims.IRadioImsResponse v1 */
RADIO_IMS_CALL_1(RADIO_IMS_RESP_)
RADIO_IMS_1_RESP_LAST = RADIO_IMS_RESP_UPDATE_IMS_CALL_STATUS,
#undef RADIO_IMS_RESP_
} RADIO_IMS_RESP;
G_STATIC_ASSERT(sizeof(RADIO_IMS_RESP) == 4);
typedef enum radio_ims_ind {
RADIO_IMS_IND_ANY = 0,
RADIO_IMS_IND_NONE = 0,
#define RADIO_IMS_IND_(code,Name,NAME) RADIO_IMS_IND_##NAME = code,
/* android.hardware.radio.ims.IRadioImsIndication v1 */
RADIO_IMS_IND_1(RADIO_IMS_IND_)
RADIO_IMS_1_IND_LAST = RADIO_IMS_IND_TRIGGER_IMS_DEREGISTRATION,
#undef RADIO_IMS_IND_
} RADIO_IMS_IND;
G_STATIC_ASSERT(sizeof(RADIO_IMS_IND) == 4);
G_END_DECLS
#endif /* RADIO_IMS_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2022 Jolla Ltd.
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -38,6 +38,13 @@
#define RADIO_INSTANCE_H
#include <radio_types.h>
#include <radio_data_types.h>
#include <radio_ims_types.h>
#include <radio_messaging_types.h>
#include <radio_modem_types.h>
#include <radio_network_types.h>
#include <radio_sim_types.h>
#include <radio_voice_types.h>
#include <glib-object.h>
@@ -60,13 +67,16 @@ struct radio_instance {
RADIO_INTERFACE version;
/* Since 1.4.3 */
gboolean connected; /* rilConnected received */
/* Since 1.6.0 */
RADIO_INTERFACE_TYPE interface_type;
RADIO_AIDL_INTERFACE interface_aidl;
};
typedef enum radio_instance_priority {
RADIO_INSTANCE_PRIORITY_LOWEST,
RADIO_INSTANCE_PRIORITY_DEFAULT = 2,
RADIO_INSTANCE_PRIORITY_HIGHEST = 7
} RADIO_INSTANCE_PRIORITY; /* Since 1.4.3 */
/* These were introduced in 1.4.3 and then renamed in 1.4.6 */
#define RADIO_INSTANCE_PRIORITY_LOWEST RADIO_OBSERVER_PRIORITY_LOWEST
#define RADIO_INSTANCE_PRIORITY_DEFAULT RADIO_OBSERVER_PRIORITY_DEFAULT
#define RADIO_INSTANCE_PRIORITY_HIGHEST RADIO_OBSERVER_PRIORITY_HIGHEST
#define RADIO_INSTANCE_PRIORITY RADIO_OBSERVER_PRIORITY
typedef
void
@@ -156,6 +166,15 @@ radio_instance_new_with_modem_slot_and_version(
int slot_index,
RADIO_INTERFACE version); /* Since 1.2.1 */
RadioInstance*
radio_instance_new_with_modem_slot_version_and_interface(
const char* dev,
const char* name,
const char* modem,
int slot,
RADIO_INTERFACE version,
RADIO_AIDL_INTERFACE aidl_interface); /* Since 1.6.0 */
RadioInstance*
radio_instance_get(
const char* dev,
@@ -229,7 +248,7 @@ radio_instance_add_request_observer(
gulong
radio_instance_add_request_observer_with_priority(
RadioInstance* radio,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_REQ code,
RadioRequestObserverFunc func,
gpointer user_data); /* Since 1.4.3 */
@@ -244,7 +263,7 @@ radio_instance_add_response_observer(
gulong
radio_instance_add_response_observer_with_priority(
RadioInstance* radio,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_RESP code,
RadioResponseObserverFunc func,
gpointer user_data); /* Since 1.4.3 */
@@ -259,7 +278,7 @@ radio_instance_add_indication_observer(
gulong
radio_instance_add_indication_observer_with_priority(
RadioInstance* radio,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_IND code,
RadioIndicationObserverFunc func,
gpointer user_data); /* Since 1.4.3 */

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_MESSAGING_TYPES_H
#define RADIO_MESSAGING_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_MESSAGING_INTERFACE_MAX (RADIO_MESSAGING_INTERFACE_COUNT - 1)
#define RADIO_MESSAGING_INSTANCE "default"
#define RADIO_MESSAGING_IFACE_PREFIX "android.hardware.radio.messaging."
#define RADIO_MESSAGING_IFACE "IRadioMessaging"
#define RADIO_MESSAGING_RESPONSE_IFACE "IRadioMessagingResponse"
#define RADIO_MESSAGING_INDICATION_IFACE "IRadioMessagingIndication"
#define RADIO_MESSAGING RADIO_MESSAGING_IFACE_PREFIX RADIO_MESSAGING_IFACE
#define RADIO_MESSAGING_FQNAME RADIO_MESSAGING "/" RADIO_MESSAGING_INSTANCE
#define RADIO_MESSAGING_RESPONSE RADIO_MESSAGING_IFACE_PREFIX RADIO_MESSAGING_RESPONSE_IFACE
#define RADIO_MESSAGING_INDICATION RADIO_MESSAGING_IFACE_PREFIX RADIO_MESSAGING_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_MESSAGING_CALL_1(c) \
c(1,1,acknowledgeIncomingGsmSmsWithPdu,ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU) \
c(2,2,acknowledgeLastIncomingCdmaSms,ACKNOWLEDGE_LAST_INCOMING_CDMA_SMS) \
c(3,3,acknowledgeLastIncomingGsmSms,ACKNOWLEDGE_LAST_INCOMING_GSM_SMS) \
c(4,5,deleteSmsOnRuim,DELETE_SMS_ON_RUIM) \
c(5,6,deleteSmsOnSim,DELETE_SMS_ON_SIM) \
c(6,7,getCdmaBroadcastConfig,GET_CDMA_BROADCAST_CONFIG) \
c(7,8,getGsmBroadcastConfig,GET_GSM_BROADCAST_CONFIG) \
c(8,9,getSmscAddress,GET_SMSC_ADDRESS) \
c(9,10,reportSmsMemoryStatus,REPORT_SMS_MEMORY_STATUS) \
c(11,12,sendCdmaSms,SEND_CDMA_SMS) \
c(12,11,sendCdmaSmsExpectMore,SEND_CDMA_SMS_EXPECT_MORE) \
c(13,13,sendImsSms,SEND_IMS_SMS) \
c(14,15,sendSms,SEND_SMS) \
c(15,14,sendSmsExpectMore,SEND_SMS_EXPECT_MORE) \
c(16,16,setCdmaBroadcastActivation,SET_CDMA_BROADCAST_ACTIVATION) \
c(17,17,setCdmaBroadcastConfig,SET_CDMA_BROADCAST_CONFIG) \
c(18,18,setGsmBroadcastActivation,SET_GSM_BROADCAST_ACTIVATION) \
c(19,19,setGsmBroadcastConfig,SET_GSM_BROADCAST_CONFIG) \
c(21,20,setSmscAddress,SET_SMSC_ADDRESS) \
c(22,21,writeSmsToRuim,WRITE_SMS_TO_RUIM) \
c(23,22,writeSmsToSim,WRITE_SMS_TO_SIM) \
/* i(code,Name,IND_NAME) */
#define RADIO_MESSAGING_IND_1(i) \
i(1,cdmaNewSms,CDMA_NEW_SMS) \
i(2,cdmaRuimSmsStorageFull,CDMA_RUIM_SMS_STORAGE_FULL) \
i(3,newBroadcastSms,NEW_BROADCAST_SMS) \
i(4,newSms,NEW_SMS) \
i(5,newSmsOnSim,NEW_SMS_ON_SIM) \
i(6,newSmsStatusReport,NEW_SMS_STATUS_REPORT) \
i(7,simSmsStorageFull,SIM_SMS_STORAGE_FULL) \
typedef enum radio_messaging_req {
RADIO_MESSAGING_REQ_ANY = 0,
RADIO_MESSAGING_REQ_NONE = 0,
#define RADIO_MESSAGING_REQ_(req,resp,Name,NAME) RADIO_MESSAGING_REQ_##NAME = req,
/* android.hardware.radio.messaging.IRadioMessaging v1 */
RADIO_MESSAGING_CALL_1(RADIO_MESSAGING_REQ_)
RADIO_MESSAGING_REQ_RESPONSE_ACKNOWLEDGEMENT = 10, /* responseAcknowledgement */
RADIO_MESSAGING_REQ_SET_RESPONSE_FUNCTIONS = 20, /* setResponseFunctions */
RADIO_MESSAGING_1_REQ_LAST = RADIO_MESSAGING_REQ_WRITE_SMS_TO_SIM,
#undef RADIO_MESSAGING_REQ_
} RADIO_MESSAGING_REQ;
G_STATIC_ASSERT(sizeof(RADIO_MESSAGING_REQ) == 4);
typedef enum radio_messaging_resp {
RADIO_MESSAGING_RESP_ANY = 0,
RADIO_MESSAGING_RESP_NONE = 0,
#define RADIO_MESSAGING_RESP_(req,resp,Name,NAME) RADIO_MESSAGING_RESP_##NAME = resp,
/* android.hardware.radio.messaging.IRadioMessagingResponse v1 */
RADIO_MESSAGING_CALL_1(RADIO_MESSAGING_RESP_)
RADIO_MESSAGING_RESP_ACKNOWLEDGE_REQUEST = 4, /* acknowledgeRequest */
RADIO_MESSAGING_1_RESP_LAST = RADIO_MESSAGING_RESP_WRITE_SMS_TO_SIM,
#undef RADIO_MESSAGING_RESP_
} RADIO_MESSAGING_RESP;
G_STATIC_ASSERT(sizeof(RADIO_MESSAGING_RESP) == 4);
typedef enum radio_messaging_ind {
RADIO_MESSAGING_IND_ANY = 0,
RADIO_MESSAGING_IND_NONE = 0,
#define RADIO_MESSAGING_IND_(code,Name,NAME) RADIO_MESSAGING_IND_##NAME = code,
/* android.hardware.radio.messaging.IRadioMessagingIndication v1 */
RADIO_MESSAGING_IND_1(RADIO_MESSAGING_IND_)
RADIO_MESSAGING_1_IND_LAST = RADIO_MESSAGING_IND_SIM_SMS_STORAGE_FULL,
#undef RADIO_MESSAGING_IND_
} RADIO_MESSAGING_IND;
G_STATIC_ASSERT(sizeof(RADIO_MESSAGING_IND) == 4);
G_END_DECLS
#endif /* RADIO_MESSAGING_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

135
include/radio_modem_types.h Normal file
View File

@@ -0,0 +1,135 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_MODEM_TYPES_H
#define RADIO_MODEM_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_MODEM_INTERFACE_MAX (RADIO_MODEM_INTERFACE_COUNT - 1)
#define RADIO_MODEM_INSTANCE "default"
#define RADIO_MODEM_IFACE_PREFIX "android.hardware.radio.modem."
#define RADIO_MODEM_IFACE "IRadioModem"
#define RADIO_MODEM_RESPONSE_IFACE "IRadioModemResponse"
#define RADIO_MODEM_INDICATION_IFACE "IRadioModemIndication"
#define RADIO_MODEM RADIO_MODEM_IFACE_PREFIX RADIO_MODEM_IFACE
#define RADIO_MODEM_FQNAME RADIO_MODEM "/" RADIO_MODEM_INSTANCE
#define RADIO_MODEM_RESPONSE RADIO_MODEM_IFACE_PREFIX RADIO_MODEM_RESPONSE_IFACE
#define RADIO_MODEM_INDICATION RADIO_MODEM_IFACE_PREFIX RADIO_MODEM_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_MODEM_CALL_1(c) \
c(1,2,enableModem,ENABLE_MODEM) \
c(2,3,getBasebandVersion,GET_BASEBAND_VERSION) \
c(3,4,getDeviceIdentity,GET_DEVICE_IDENTITY) \
c(4,5,getHardwareConfig,GET_HARDWARE_CONFIG) \
c(5,6,getModemActivityInfo,GET_MODEM_ACTIVITY_INFO) \
c(6,7,getModemStackStatus,GET_MODEM_STACK_STATUS) \
c(7,8,getRadioCapability,GET_RADIO_CAPABILITY) \
c(8,9,nvReadItem,NV_READ_ITEM) \
c(9,10,nvResetConfig,NV_RESET_CONFIG) \
c(10,11,nvWriteCdmaPrl,NV_WRITE_CDMA_PRL) \
c(11,12,nvWriteItem,NV_WRITE_ITEM) \
c(12,13,requestShutdown,REQUEST_SHUTDOWN) \
c(14,14,sendDeviceState,SEND_DEVICE_STATE) \
c(15,15,setRadioCapability,SET_RADIO_CAPABILITY) \
c(16,16,setRadioPower,SET_RADIO_POWER) \
/* i(code,Name,IND_NAME) */
#define RADIO_MODEM_IND_1(i) \
i(1,hardwareConfigChanged,HARDWARE_CONFIG_CHANGED) \
i(2,modemReset,MODEM_RESET) \
i(3,radioCapabilityIndication,RADIO_CAPABILITY_INDICATION) \
i(4,radioStateChanged,RADIO_STATE_CHANGED) \
i(5,rilConnected,RIL_CONNECTED) \
typedef enum radio_modem_req {
RADIO_MODEM_REQ_ANY = 0,
RADIO_MODEM_REQ_NONE = 0,
#define RADIO_MODEM_REQ_(req,resp,Name,NAME) RADIO_MODEM_REQ_##NAME = req,
/* android.hardware.radio.modem.IRadioModem v1 */
RADIO_MODEM_CALL_1(RADIO_MODEM_REQ_)
RADIO_MODEM_REQ_RESPONSE_ACKNOWLEDGEMENT = 13, /* responseAcknowledgement */
RADIO_MODEM_REQ_SET_RESPONSE_FUNCTIONS = 17, /* setResponseFunctions */
RADIO_MODEM_1_REQ_LAST = RADIO_MODEM_REQ_SET_RESPONSE_FUNCTIONS,
#undef RADIO_MODEM_REQ_
} RADIO_MODEM_REQ;
G_STATIC_ASSERT(sizeof(RADIO_MODEM_REQ) == 4);
typedef enum radio_modem_resp {
RADIO_MODEM_RESP_ANY = 0,
RADIO_MODEM_RESP_NONE = 0,
#define RADIO_MODEM_RESP_(req,resp,Name,NAME) RADIO_MODEM_RESP_##NAME = resp,
/* android.hardware.radio.modem.IRadioModemResponse v1 */
RADIO_MODEM_CALL_1(RADIO_MODEM_RESP_)
RADIO_MODEM_RESP_ACKNOWLEDGE_REQUEST = 1, /* acknowledgeRequest */
RADIO_MODEM_1_RESP_LAST = RADIO_MODEM_RESP_SET_RADIO_POWER,
#undef RADIO_MODEM_RESP_
} RADIO_MODEM_RESP;
G_STATIC_ASSERT(sizeof(RADIO_MODEM_RESP) == 4);
typedef enum radio_modem_ind {
RADIO_MODEM_IND_ANY = 0,
RADIO_MODEM_IND_NONE = 0,
#define RADIO_MODEM_IND_(code,Name,NAME) RADIO_MODEM_IND_##NAME = code,
/* android.hardware.radio.modem.IRadioModemIndication v1 */
RADIO_MODEM_IND_1(RADIO_MODEM_IND_)
RADIO_MODEM_1_IND_LAST = RADIO_MODEM_IND_RIL_CONNECTED,
#undef RADIO_MODEM_IND_
} RADIO_MODEM_IND;
G_STATIC_ASSERT(sizeof(RADIO_MODEM_IND) == 4);
G_END_DECLS
#endif /* RADIO_MODEM_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_NETWORK_TYPES_H
#define RADIO_NETWORK_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_NETWORK_INTERFACE_MAX (RADIO_NETWORK_INTERFACE_COUNT - 1)
#define RADIO_NETWORK_INSTANCE "default"
#define RADIO_NETWORK_IFACE_PREFIX "android.hardware.radio.network."
#define RADIO_NETWORK_IFACE "IRadioNetwork"
#define RADIO_NETWORK_RESPONSE_IFACE "IRadioNetworkResponse"
#define RADIO_NETWORK_INDICATION_IFACE "IRadioNetworkIndication"
#define RADIO_NETWORK RADIO_NETWORK_IFACE_PREFIX RADIO_NETWORK_IFACE
#define RADIO_NETWORK_FQNAME RADIO_NETWORK "/" RADIO_NETWORK_INSTANCE
#define RADIO_NETWORK_RESPONSE RADIO_NETWORK_IFACE_PREFIX RADIO_NETWORK_RESPONSE_IFACE
#define RADIO_NETWORK_INDICATION RADIO_NETWORK_IFACE_PREFIX RADIO_NETWORK_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_NETWORK_CALL_1(c) \
c(1,2,getAllowedNetworkTypesBitmap,GET_ALLOWED_NETWORK_TYPES_BITMAP) \
c(2,3,getAvailableBandModes,GET_AVAILABLE_BAND_MODES) \
c(3,4,getAvailableNetworks,GET_AVAILABLE_NETWORKS) \
c(4,5,getBarringInfo,GET_BARRING_INFO) \
c(5,6,getCdmaRoamingPreference,GET_CDMA_ROAMING_PREFERENCE) \
c(6,7,getCellInfoList,GET_CELL_INFO_LIST) \
c(7,8,getDataRegistrationState,GET_DATA_REGISTRATION_STATE) \
c(8,9,getImsRegistrationState,GET_IMS_REGISTRATION_STATE) \
c(9,10,getNetworkSelectionMode,GET_NETWORK_SELECTION_MODE) \
c(10,11,getOperator,GET_OPERATOR) \
c(11,12,getSignalStrength,GET_SIGNAL_STRENGTH) \
c(12,13,getSystemSelectionChannels,GET_SYSTEM_SELECTION_CHANNELS) \
c(13,14,getVoiceRadioTechnology,GET_VOICE_RADIO_TECHNOLOGY) \
c(14,15,getVoiceRegistrationState,GET_VOICE_REGISTRATION_STATE) \
c(15,16,isNrDualConnectivityEnabled,IS_NR_DUAL_CONNECTIVITY_ENABLED) \
c(17,17,setAllowedNetworkTypesBitmap,SET_ALLOWED_NETWORK_TYPES_BITMAP) \
c(18,18,setBandMode,SET_BAND_MODE) \
c(19,19,setBarringPassword,SET_BARRING_PASSWORD) \
c(20,20,setCdmaRoamingPreference,SET_CDMA_ROAMING_PREFERENCE) \
c(21,21,setCellInfoListRate,SET_CELL_INFO_LIST_RATE) \
c(22,22,setIndicationFilter,SET_INDICATION_FILTER) \
c(23,23,setLinkCapacityReportingCriteria,SET_LINK_CAPACITY_REPORTING_CRITERIA) \
c(24,24,setLocationUpdates,SET_LOCATION_UPDATES) \
c(25,25,setNetworkSelectionModeAutomatic,SET_NETWORK_SELECTION_MODE_AUTOMATIC) \
c(26,26,setNetworkSelectionModeManual,SET_NETWORK_SELECTION_MODE_MANUAL) \
c(27,27,setNrDualConnectivityState,SET_NR_DUAL_CONNECTIVITY_STATE) \
c(29,28,setSignalStrengthReportingCriteria,SET_SIGNAL_STRENGTH_REPORTING_CRITERIA) \
c(30,29,setSuppServiceNotifications,SET_SUPP_SERVICE_NOTIFICATIONS) \
c(31,30,setSystemSelectionChannels,SET_SYSTEM_SELECTION_CHANNELS) \
c(32,31,startNetworkScan,START_NETWORK_SCAN) \
c(33,32,stopNetworkScan,STOP_NETWORK_SCAN) \
c(34,33,supplyNetworkDepersonalization,SUPPLY_NETWORK_DEPERSONALIZATION) \
c(35,34,setUsageSetting,SET_USAGE_SETTING) \
c(36,35,getUsageSetting,GET_USAGE_SETTING) \
/* i(code,Name,IND_NAME) */
#define RADIO_NETWORK_IND_1(i) \
i(1,barringInfoChanged,BARRING_INFO_CHANGED) \
i(2,cdmaPrlChanged,CDMA_PRL_CHANGED) \
i(3,cellInfoList,CELL_INFO_LIST) \
i(4,currentLinkCapacityEstimate,CURRENT_LINK_CAPACITY_ESTIMATE) \
i(5,currentPhysicalChannelConfigs,CURRENT_PHYSICAL_CHANNEL_CONFIGS) \
i(6,currentSignalStrength,CURRENT_SIGNAL_STRENGTH) \
i(7,imsNetworkStateChanged,IMS_NETWORK_STATE_CHANGED) \
i(8,networkScanResult,NETWORK_SCAN_RESULT) \
i(9,networkStateChanged,NETWORK_STATE_CHANGED) \
i(10,nitzTimeReceived,NITZ_TIME_RECEIVED) \
i(11,registrationFailed,REGISTRATION_FAILED) \
i(12,restrictedStateChanged,RESTRICTED_STATE_CHANGED) \
i(13,suppSvcNotify,SUPP_SVC_NOTIFY) \
i(14,voiceRadioTechChanged,VOICE_RADIO_TECH_CHANGED) \
typedef enum radio_network_req {
RADIO_NETWORK_REQ_ANY = 0,
RADIO_NETWORK_REQ_NONE = 0,
#define RADIO_NETWORK_REQ_(req,resp,Name,NAME) RADIO_NETWORK_REQ_##NAME = req,
/* android.hardware.radio.network.IRadioNetwork v1 */
RADIO_NETWORK_CALL_1(RADIO_NETWORK_REQ_)
RADIO_NETWORK_REQ_RESPONSE_ACKNOWLEDGEMENT = 16, /* responseAcknowledgement */
RADIO_NETWORK_REQ_SET_RESPONSE_FUNCTIONS = 28, /* setResponseFunctions */
RADIO_NETWORK_1_REQ_LAST = RADIO_NETWORK_REQ_GET_USAGE_SETTING,
#undef RADIO_NETWORK_REQ_
} RADIO_NETWORK_REQ;
G_STATIC_ASSERT(sizeof(RADIO_NETWORK_REQ) == 4);
typedef enum radio_network_resp {
RADIO_NETWORK_RESP_ANY = 0,
RADIO_NETWORK_RESP_NONE = 0,
#define RADIO_NETWORK_RESP_(req,resp,Name,NAME) RADIO_NETWORK_RESP_##NAME = resp,
/* android.hardware.radio.network.IRadioNetworkResponse v1 */
RADIO_NETWORK_CALL_1(RADIO_NETWORK_RESP_)
RADIO_NETWORK_RESP_ACKNOWLEDGE_REQUEST = 1, /* acknowledgeRequest */
RADIO_NETWORK_1_RESP_LAST = RADIO_NETWORK_RESP_GET_USAGE_SETTING,
#undef RADIO_NETWORK_RESP_
} RADIO_NETWORK_RESP;
G_STATIC_ASSERT(sizeof(RADIO_NETWORK_RESP) == 4);
typedef enum radio_network_ind {
RADIO_NETWORK_IND_ANY = 0,
RADIO_NETWORK_IND_NONE = 0,
#define RADIO_NETWORK_IND_(code,Name,NAME) RADIO_NETWORK_IND_##NAME = code,
/* android.hardware.radio.network.IRadioNetworkIndication v1 */
RADIO_NETWORK_IND_1(RADIO_NETWORK_IND_)
RADIO_NETWORK_1_IND_LAST = RADIO_NETWORK_IND_VOICE_RADIO_TECH_CHANGED,
#undef RADIO_NETWORK_IND_
} RADIO_NETWORK_IND;
G_STATIC_ASSERT(sizeof(RADIO_NETWORK_IND) == 4);
G_END_DECLS
#endif /* RADIO_NETWORK_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -39,7 +39,7 @@
/* This API exists since 1.4.3 */
#include <radio_types.h>
#include <radio_config_types.h>
/*
* Basic workflow
@@ -70,9 +70,11 @@ typedef enum radio_tx_status {
/*
* RadioRequestCompleteFunc
* RadioConfigRequestCompleteFunc
*
* Invoked upon completion of each request. If an error occurs,
* resp is set to RADIO_RESP_NONE (zero) and args is NULL.
* resp is set to zero (RADIO_RESP_NONE, RADIO_CONFIG_RESP_NONE)
* and args is NULL.
*
* The status argument is the status of the request transaction.
* If it's anything other than RADIO_TX_STATUS_OK, the request
@@ -92,6 +94,16 @@ void
const GBinderReader* args,
gpointer user_data);
typedef
void
(*RadioConfigRequestCompleteFunc)(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_CONFIG_RESP resp,
RADIO_ERROR error,
const GBinderReader* args,
gpointer user_data); /* Since 1.4.6 */
/*
* RadioRequestRetryFunc
*
@@ -110,7 +122,7 @@ gboolean
(*RadioRequestRetryFunc)(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_RESP resp,
guint32 resp, /* Was RADIO_RESP before 1.4.6 */
RADIO_ERROR error,
const GBinderReader* args,
void* user_data);
@@ -119,7 +131,7 @@ RadioRequest*
radio_request_new(
RadioClient* client,
RADIO_REQ code,
GBinderWriter* writer, /* NULL if serial is the only arg */
GBinderWriter* args, /* NULL if serial is the only arg */
RadioRequestCompleteFunc complete,
GDestroyNotify destroy,
void* user_data)
@@ -129,12 +141,22 @@ RadioRequest*
radio_request_new2(
RadioRequestGroup* group,
RADIO_REQ code,
GBinderWriter* writer, /* NULL if serial is the only arg */
GBinderWriter* args, /* NULL if serial is the only arg */
RadioRequestCompleteFunc complete,
GDestroyNotify destroy,
void* user_data)
G_GNUC_WARN_UNUSED_RESULT;
RadioRequest*
radio_config_request_new(
RadioConfig* config,
RADIO_CONFIG_REQ code,
GBinderWriter* args, /* NULL if serial is the only arg */
RadioConfigRequestCompleteFunc complete,
GDestroyNotify destroy,
void* user_data) /* Since 1.4.6 */
G_GNUC_WARN_UNUSED_RESULT;
RadioRequest*
radio_request_ref(
RadioRequest* req);
@@ -185,6 +207,10 @@ radio_request_set_retry_func(
RadioRequest* req,
RadioRequestRetryFunc retry);
void*
radio_request_user_data(
RadioRequest* req); /* Since 1.4.11 */
G_END_DECLS
#endif /* RADIO_REQUEST_H */

160
include/radio_sim_types.h Normal file
View File

@@ -0,0 +1,160 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_SIM_TYPES_H
#define RADIO_SIM_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_SIM_INTERFACE_MAX (RADIO_SIM_INTERFACE_COUNT - 1)
#define RADIO_SIM_INSTANCE "default"
#define RADIO_SIM_IFACE_PREFIX "android.hardware.radio.sim."
#define RADIO_SIM_IFACE "IRadioSim"
#define RADIO_SIM_RESPONSE_IFACE "IRadioSimResponse"
#define RADIO_SIM_INDICATION_IFACE "IRadioSimIndication"
#define RADIO_SIM RADIO_SIM_IFACE_PREFIX RADIO_SIM_IFACE
#define RADIO_SIM_FQNAME RADIO_SIM "/" RADIO_SIM_INSTANCE
#define RADIO_SIM_RESPONSE RADIO_SIM_IFACE_PREFIX RADIO_SIM_RESPONSE_IFACE
#define RADIO_SIM_INDICATION RADIO_SIM_IFACE_PREFIX RADIO_SIM_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_SIM_CALL_1(c) \
c(1,2,areUiccApplicationsEnabled,ARE_UICC_APPLICATIONS_ENABLED) \
c(2,3,changeIccPin2ForApp,CHANGE_ICC_PIN2_FOR_APP) \
c(3,4,changeIccPinForApp,CHANGE_ICC_PIN_FOR_APP) \
c(4,5,enableUiccApplications,ENABLE_UICC_APPLICATIONS) \
c(5,6,getAllowedCarriers,GET_ALLOWED_CARRIERS) \
c(6,7,getCdmaSubscription,GET_CDMA_SUBSCRIPTION) \
c(7,8,getCdmaSubscriptionSource,GET_CDMA_SUBSCRIPTION_SOURCE) \
c(8,9,getFacilityLockForApp,GET_FACILITY_LOCK_FOR_APP) \
c(9,10,getIccCardStatus,GET_ICC_CARD_STATUS) \
c(10,11,getImsiForApp,GET_IMSI_FOR_APP) \
c(11,12,getSimPhonebookCapacity,GET_SIM_PHONEBOOK_CAPACITY) \
c(12,13,getSimPhonebookRecords,GET_SIM_PHONEBOOK_RECORDS) \
c(13,14,iccCloseLogicalChannel,ICC_CLOSE_LOGICAL_CHANNEL) \
c(14,15,iccIoForApp,ICC_IO_FOR_APP) \
c(15,16,iccOpenLogicalChannel,ICC_OPEN_LOGICAL_CHANNEL) \
c(16,17,iccTransmitApduBasicChannel,ICC_TRANSMIT_APDU_BASIC_CHANNEL) \
c(17,18,iccTransmitApduLogicalChannel,ICC_TRANSMIT_APDU_LOGICAL_CHANNEL) \
c(18,19,reportStkServiceIsRunning,REPORT_STK_SERVICE_IS_RUNNING) \
c(19,20,requestIccSimAuthentication,REQUEST_ICC_SIM_AUTHENTICATION) \
c(21,21,sendEnvelope,SEND_ENVELOPE) \
c(22,22,sendEnvelopeWithStatus,SEND_ENVELOPE_WITH_STATUS) \
c(23,23,sendTerminalResponseToSim,SEND_TERMINAL_RESPONSE_TO_SIM) \
c(24,24,setAllowedCarriers,SET_ALLOWED_CARRIERS) \
c(25,25,setCarrierInfoForImsiEncryption,SET_CARRIER_INFO_FOR_IMSI_ENCRYPTION) \
c(26,26,setCdmaSubscriptionSource,SET_CDMA_SUBSCRIPTION_SOURCE) \
c(27,27,setFacilityLockForApp,SET_FACILITY_LOCK_FOR_APP) \
c(29,28,setSimCardPower,SET_SIM_CARD_POWER) \
c(30,29,setUiccSubscription,SET_UICC_SUBSCRIPTION) \
c(31,30,supplyIccPin2ForApp,SUPPLY_ICC_PIN2_FOR_APP) \
c(32,31,supplyIccPinForApp,SUPPLY_ICC_PIN_FOR_APP) \
c(33,32,supplyIccPuk2ForApp,SUPPLY_ICC_PUK2_FOR_APP) \
c(34,33,supplyIccPukForApp,SUPPLY_ICC_PUK_FOR_APP) \
c(35,34,supplySimDepersonalization,SUPPLY_SIM_DEPERSONALIZATION) \
c(36,35,updateSimPhonebookRecords,UPDATE_SIM_PHONEBOOK_RECORDS) \
/* i(code,Name,IND_NAME) */
#define RADIO_SIM_IND_1(i) \
i(1,carrierInfoForImsiEncryption,CARRIER_INFO_FOR_IMSI_ENCRYPTION) \
i(2,cdmaSubscriptionSourceChanged,CDMA_SUBSCRIPTION_SOURCE_CHANGED) \
i(3,simPhonebookChanged,SIM_PHONEBOOK_CHANGED) \
i(4,simPhonebookRecordsReceived,SIM_PHONEBOOK_RECORDS_RECEIVED) \
i(5,simRefresh,SIM_REFRESH) \
i(6,simStatusChanged,SIM_STATUS_CHANGED) \
i(7,stkEventNotify,STK_EVENT_NOTIFY) \
i(8,stkProactiveCommand,STK_PROACTIVE_COMMAND) \
i(9,stkSessionEnd,STK_SESSION_END) \
i(10,subscriptionStatusChanged,SUBSCRIPTION_STATUS_CHANGED) \
i(11,uiccApplicationsEnablementChanged,UICC_APPLICATIONS_ENABLEMENT_CHANGED) \
typedef enum radio_sim_req {
RADIO_SIM_REQ_ANY = 0,
RADIO_SIM_REQ_NONE = 0,
#define RADIO_SIM_REQ_(req,resp,Name,NAME) RADIO_SIM_REQ_##NAME = req,
/* android.hardware.radio.sim.IRadioSim v1 */
RADIO_SIM_CALL_1(RADIO_SIM_REQ_)
RADIO_SIM_REQ_RESPONSE_ACKNOWLEDGEMENT = 20, /* responseAcknowledgement */
RADIO_SIM_REQ_SET_RESPONSE_FUNCTIONS = 28, /* setResponseFunctions */
RADIO_SIM_1_REQ_LAST = RADIO_SIM_REQ_UPDATE_SIM_PHONEBOOK_RECORDS,
#undef RADIO_SIM_REQ_
} RADIO_SIM_REQ;
G_STATIC_ASSERT(sizeof(RADIO_SIM_REQ) == 4);
typedef enum radio_sim_resp {
RADIO_SIM_RESP_ANY = 0,
RADIO_SIM_RESP_NONE = 0,
#define RADIO_SIM_RESP_(req,resp,Name,NAME) RADIO_SIM_RESP_##NAME = resp,
/* android.hardware.radio.sim.IRadioSimResponse v1 */
RADIO_SIM_CALL_1(RADIO_SIM_RESP_)
RADIO_SIM_RESP_ACKNOWLEDGE_REQUEST = 1, /* acknowledgeRequest */
RADIO_SIM_1_RESP_LAST = RADIO_SIM_RESP_UPDATE_SIM_PHONEBOOK_RECORDS,
#undef RADIO_SIM_RESP_
} RADIO_SIM_RESP;
G_STATIC_ASSERT(sizeof(RADIO_SIM_RESP) == 4);
typedef enum radio_sim_ind {
RADIO_SIM_IND_ANY = 0,
RADIO_SIM_IND_NONE = 0,
#define RADIO_SIM_IND_(code,Name,NAME) RADIO_SIM_IND_##NAME = code,
/* android.hardware.radio.sim.IRadioSimIndication v1 */
RADIO_SIM_IND_1(RADIO_SIM_IND_)
RADIO_SIM_1_IND_LAST = RADIO_SIM_IND_UICC_APPLICATIONS_ENABLEMENT_CHANGED,
#undef RADIO_SIM_IND_
} RADIO_SIM_IND;
G_STATIC_ASSERT(sizeof(RADIO_SIM_IND) == 4);
G_END_DECLS
#endif /* RADIO_SIM_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -45,17 +45,38 @@ const char*
radio_req_name(
RADIO_REQ req);
const char*
radio_req_name2(
RadioInstance* instance,
RADIO_REQ req); /* Since 1.6.0 */
const char*
radio_resp_name(
RADIO_RESP resp);
const char*
radio_resp_name2(
RadioInstance* instance,
RADIO_RESP resp); /* Since 1.6.0 */
const char*
radio_ind_name(
RADIO_IND ind);
const char*
radio_ind_name2(
RadioInstance* instance,
RADIO_IND ind); /* Since 1.6.0 */
RADIO_RESP
radio_req_resp(
RADIO_REQ req);
RADIO_REQ req)
G_GNUC_DEPRECATED_FOR(radio_req_resp2);
RADIO_RESP
radio_req_resp2(
RADIO_REQ req,
RADIO_INTERFACE iface); /* Since 1.4.5 */
G_END_DECLS

168
include/radio_voice_types.h Normal file
View File

@@ -0,0 +1,168 @@
/*
* Copyright (C) 2024 Jollyboys Ltd
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_VOICE_TYPES_H
#define RADIO_VOICE_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
#define RADIO_VOICE_INTERFACE_MAX (RADIO_VOICE_INTERFACE_COUNT - 1)
#define RADIO_VOICE_INSTANCE "default"
#define RADIO_VOICE_IFACE_PREFIX "android.hardware.radio.voice."
#define RADIO_VOICE_IFACE "IRadioVoice"
#define RADIO_VOICE_RESPONSE_IFACE "IRadioVoiceResponse"
#define RADIO_VOICE_INDICATION_IFACE "IRadioVoiceIndication"
#define RADIO_VOICE RADIO_VOICE_IFACE_PREFIX RADIO_VOICE_IFACE
#define RADIO_VOICE_FQNAME RADIO_VOICE "/" RADIO_VOICE_INSTANCE
#define RADIO_VOICE_RESPONSE RADIO_VOICE_IFACE_PREFIX RADIO_VOICE_RESPONSE_IFACE
#define RADIO_VOICE_INDICATION RADIO_VOICE_IFACE_PREFIX RADIO_VOICE_INDICATION_IFACE
/* Transaction codes */
/* c(req,resp,Name,CALL_NAME) */
#define RADIO_VOICE_CALL_1(c) \
c(1,1,acceptCall,ACCEPT_CALL) \
c(2,3,cancelPendingUssd,CANCEL_PENDING_USSD) \
c(3,4,conference,CONFERENCE) \
c(4,5,dial,DIAL) \
c(5,6,emergencyDial,EMERGENCY_DIAL) \
c(6,7,exitEmergencyCallbackMode,EXIT_EMERGENCY_CALLBACK_MODE) \
c(7,8,explicitCallTransfer,EXPLICIT_CALL_TRANSFER) \
c(8,9,getCallForwardStatus,GET_CALL_FORWARD_STATUS) \
c(9,10,getCallWaiting,GET_CALL_WAITING) \
c(10,11,getClip,GET_CLIP) \
c(11,12,getClir,GET_CLIR) \
c(12,13,getCurrentCalls,GET_CURRENT_CALLS) \
c(13,14,getLastCallFailCause,GET_LAST_CALL_FAIL_CAUSE) \
c(14,15,getMute,GET_MUTE) \
c(15,16,getPreferredVoicePrivacy,GET_PREFERRED_VOICE_PRIVACY) \
c(16,17,getTtyMode,GET_TTY_MODE) \
c(17,18,handleStkCallSetupRequestFromSim,HANDLE_STK_CALL_SETUP_REQUEST_FROM_SIM) \
c(19,20,hangupForegroundResumeBackground,HANGUP_FOREGROUND_RESUME_BACKGROUND) \
c(20,21,hangupWaitingOrBackground,HANGUP_WAITING_OR_BACKGROUND) \
c(21,22,isVoNrEnabled,IS_VO_NR_ENABLED) \
c(22,23,rejectCall,REJECT_CALL) \
c(24,24,sendBurstDtmf,SEND_BURST_DTMF) \
c(25,25,sendCdmaFeatureCode,SEND_CDMA_FEATURE_CODE) \
c(26,26,sendDtmf,SEND_DTMF) \
c(27,27,sendUssd,SEND_USSD) \
c(28,28,separateConnection,SEPARATE_CONNECTION) \
c(29,29,setCallForward,SET_CALL_FORWARD) \
c(30,30,setCallWaiting,SET_CALL_WAITING) \
c(31,31,setClir,SET_CLIR) \
c(32,32,setMute,SET_MUTE) \
c(33,33,setPreferredVoicePrivacy,SET_PREFERRED_VOICE_PRIVACY) \
c(35,34,setTtyMode,SET_TTY_MODE) \
c(36,35,setVoNrEnabled,SET_VO_NR_ENABLED) \
c(37,36,startDtmf,START_DTMF) \
c(38,37,stopDtmf,STOP_DTMF) \
c(39,38,switchWaitingOrHoldingAndActive,SWITCH_WAITING_OR_HOLDING_AND_ACTIVE) \
/* i(code,Name,IND_NAME) */
#define RADIO_VOICE_IND_1(i) \
i(1,callRing,CALL_RING) \
i(2,callStateChanged,CALL_STATE_CHANGED) \
i(3,cdmaCallWaiting,CDMA_CALL_WAITING) \
i(4,cdmaInfoRec,CDMA_INFO_REC) \
i(5,cdmaOtaProvisionStatus,CDMA_OTA_PROVISION_STATUS) \
i(6,currentEmergencyNumberList,CURRENT_EMERGENCY_NUMBER_LIST) \
i(7,enterEmergencyCallbackMode,ENTER_EMERGENCY_CALLBACK_MODE) \
i(8,exitEmergencyCallbackMode,EXIT_EMERGENCY_CALLBACK_MODE) \
i(9,indicateRingbackTone,INDICATE_RINGBACK_TONE) \
i(10,onSupplementaryServiceIndication,ON_SUPPLEMENTARY_SERVICE_INDICATION) \
i(11,onUssd,ON_USSD) \
i(12,resendIncallMute,RESEND_INCALL_MUTE) \
i(13,srvccStateNotify,SRVCC_STATE_NOTIFY) \
i(14,stkCallControlAlphaNotify,STK_CALL_CONTROL_ALPHA_NOTIFY) \
i(15,stkCallSetup,STK_CALL_SETUP) \
typedef enum radio_voice_req {
RADIO_VOICE_REQ_ANY = 0,
RADIO_VOICE_REQ_NONE = 0,
#define RADIO_VOICE_REQ_(req,resp,Name,NAME) RADIO_VOICE_REQ_##NAME = req,
/* android.hardware.radio.voice.IRadioVoice v1 */
RADIO_VOICE_CALL_1(RADIO_VOICE_REQ_)
RADIO_VOICE_REQ_HANGUP = 18, /* hangup */
RADIO_VOICE_REQ_RESPONSE_ACKNOWLEDGEMENT = 23, /* responseAcknowledgement */
RADIO_VOICE_REQ_SET_RESPONSE_FUNCTIONS = 34, /* setResponseFunctions */
RADIO_VOICE_1_REQ_LAST = RADIO_VOICE_REQ_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
#undef RADIO_VOICE_REQ_
} RADIO_VOICE_REQ;
G_STATIC_ASSERT(sizeof(RADIO_VOICE_REQ) == 4);
typedef enum radio_voice_resp {
RADIO_VOICE_RESP_ANY = 0,
RADIO_VOICE_RESP_NONE = 0,
#define RADIO_VOICE_RESP_(req,resp,Name,NAME) RADIO_VOICE_RESP_##NAME = resp,
/* android.hardware.radio.voice.IRadioVoiceResponse v1 */
RADIO_VOICE_CALL_1(RADIO_VOICE_RESP_)
RADIO_VOICE_RESP_ACKNOWLEDGE_REQUEST = 2, /* acknowledgeRequest */
RADIO_VOICE_RESP_HANGUP_CONNECTION_RESPONSE = 19, /* hangupConnectionResponse */
RADIO_VOICE_1_RESP_LAST = RADIO_VOICE_RESP_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE,
#undef RADIO_VOICE_RESP_
} RADIO_VOICE_RESP;
G_STATIC_ASSERT(sizeof(RADIO_VOICE_RESP) == 4);
typedef enum radio_voice_ind {
RADIO_VOICE_IND_ANY = 0,
RADIO_VOICE_IND_NONE = 0,
#define RADIO_VOICE_IND_(code,Name,NAME) RADIO_VOICE_IND_##NAME = code,
/* android.hardware.radio.voice.IRadioVoiceIndication v1 */
RADIO_VOICE_IND_1(RADIO_VOICE_IND_)
RADIO_VOICE_1_IND_LAST = RADIO_VOICE_IND_STK_CALL_SETUP,
#undef RADIO_VOICE_IND_
} RADIO_VOICE_IND;
G_STATIC_ASSERT(sizeof(RADIO_VOICE_IND) == 4);
G_END_DECLS
#endif /* RADIO_VOICE_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,6 +1,6 @@
Name: libgbinder-radio
Version: 1.4.4
Version: 1.6.0
Release: 0
Summary: Binder client library for Android radio interfaces
License: BSD

1051
src/radio_base.c Normal file

File diff suppressed because it is too large Load Diff

198
src/radio_base.h Normal file
View File

@@ -0,0 +1,198 @@
/*
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_BASE_H
#define RADIO_BASE_H
#include "radio_types_p.h"
#include <glib-object.h>
/* RadioBaseFunc must be compatible with RadioClientFunc */
typedef
void
(*RadioBaseFunc)(
RadioBase* base,
gpointer user_data);
typedef
void
(*RadioBaseRequestSentFunc)(
RadioBase* base,
RadioRequest* req,
int status);
typedef struct radio_base_priv RadioBasePriv;
struct radio_base {
GObject object;
RadioBasePriv* priv;
};
typedef struct radio_base_class {
GObjectClass parent;
gboolean (*is_dead)(RadioBase* base);
gboolean (*can_submit_requests)(RadioBase* base);
GBinderLocalRequest* (*new_request)(RadioBase* base, guint32 code);
gulong (*send_request)(RadioBase* base, RadioRequest* req,
RadioBaseRequestSentFunc sent);
void (*cancel_request)(RadioBase* base, gulong id);
} RadioBaseClass;
GType radio_base_get_type(void) RADIO_INTERNAL;
#define RADIO_TYPE_BASE radio_base_get_type()
#define RADIO_BASE(obj) G_TYPE_CHECK_INSTANCE_CAST((obj), \
RADIO_TYPE_BASE, RadioBase)
#define RADIO_BASE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST((klass), \
RADIO_TYPE_BASE, RadioBaseClass)
#define RADIO_BASE_GET_CLASS(obj) G_TYPE_INSTANCE_GET_CLASS((obj), \
THIS_TYPE, RadioBaseClass)
void
radio_base_initialize(
RadioBase* base)
RADIO_INTERNAL;
void
radio_base_register_request(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_base_unregister_request(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
gboolean
radio_base_submit_request(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
gboolean
radio_base_retry_request(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_base_request_dropped(
RadioRequest* req)
RADIO_INTERNAL;
guint
radio_base_timeout_ms(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_base_reset_timeout(
RadioBase* base)
RADIO_INTERNAL;
RADIO_BLOCK
radio_base_block_status(
RadioBase* base,
RadioRequestGroup* group)
RADIO_INTERNAL;
RADIO_BLOCK
radio_base_block(
RadioBase* base,
RadioRequestGroup* group)
RADIO_INTERNAL;
void
radio_base_unblock(
RadioBase* base,
RadioRequestGroup* group)
RADIO_INTERNAL;
gboolean
radio_base_handle_resp(
RadioBase* base,
guint32 code,
const RadioResponseInfo* info,
const GBinderReader* reader)
RADIO_INTERNAL;
void
radio_base_handle_ack(
RadioBase* base,
guint32 serial)
RADIO_INTERNAL;
void
radio_base_handle_death(
RadioBase* base)
RADIO_INTERNAL;
void
radio_base_submit_requests(
RadioBase* base)
RADIO_INTERNAL;
void
radio_base_cancel_request(
RadioBase* base,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_base_set_default_timeout(
RadioBase* self,
int ms)
RADIO_INTERNAL;
gulong
radio_base_add_owner_changed_handler(
RadioBase* base,
RadioBaseFunc func,
gpointer user_data)
RADIO_INTERNAL;
#endif /* RADIO_BASE_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

File diff suppressed because it is too large Load Diff

1188
src/radio_config.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2022 Jolla Ltd.
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -38,7 +38,7 @@
#include "radio_instance_p.h"
#include "radio_registry_p.h"
#include "radio_util.h"
#include "radio_util_p.h"
#include "radio_log.h"
#include <gbinder.h>
@@ -69,22 +69,15 @@ struct radio_instance_priv {
G_DEFINE_TYPE(RadioInstance, radio_instance, G_TYPE_OBJECT)
G_STATIC_ASSERT(RADIO_INSTANCE_PRIORITY_LOWEST == 0);
G_STATIC_ASSERT(RADIO_INSTANCE_PRIORITY_HIGHEST == 7);
#define FOREACH_PRIORITY(p) p(0) p(1) p(2) p(3) p(4) p(5) p(6) p(7)
#define RADIO_INSTANCE_PRIORITY_INDEX(p) ((p) - RADIO_INSTANCE_PRIORITY_LOWEST)
#define RADIO_INSTANCE_PRIORITY_COUNT \
(RADIO_INSTANCE_PRIORITY_INDEX(RADIO_INSTANCE_PRIORITY_HIGHEST) + 1)
typedef enum radio_instance_signal {
#define SIGNAL_INDEX(x) SIGNAL_OBSERVE_REQUEST_##x,
FOREACH_PRIORITY(SIGNAL_INDEX)
FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
#undef SIGNAL_INDEX
#define SIGNAL_INDEX(x) SIGNAL_OBSERVE_RESPONSE_##x,
FOREACH_PRIORITY(SIGNAL_INDEX)
FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
#undef SIGNAL_INDEX
#define SIGNAL_INDEX(x) SIGNAL_OBSERVE_INDICATION_##x,
FOREACH_PRIORITY(SIGNAL_INDEX)
FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
#undef SIGNAL_INDEX
SIGNAL_HANDLE_RESPONSE,
SIGNAL_HANDLE_INDICATION,
@@ -97,21 +90,21 @@ typedef enum radio_instance_signal {
static const char* radio_instance_signal_observe_request_name[] = {
#define SIGNAL_NAME(x) "radio-instance-observe-request-" #x,
FOREACH_PRIORITY(SIGNAL_NAME)
FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
#undef SIGNAL_NAME
NULL
};
static const char* radio_instance_signal_observe_response_name[] = {
#define SIGNAL_NAME(x) "radio-instance-observe-response-" #x,
FOREACH_PRIORITY(SIGNAL_NAME)
FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
#undef SIGNAL_NAME
NULL
};
static const char* radio_instance_signal_observe_indication_name[] = {
#define SIGNAL_NAME(x) "radio-instance-observe-indication-" #x,
FOREACH_PRIORITY(SIGNAL_NAME)
FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
#undef SIGNAL_NAME
NULL
};
@@ -130,6 +123,7 @@ static GHashTable* radio_instance_table = NULL;
#define DEFAULT_INTERFACE RADIO_INTERFACE_1_0
static const GBinderClientIfaceInfo radio_iface_info[] = {
{RADIO_1_5, RADIO_1_5_REQ_LAST },
{RADIO_1_4, RADIO_1_4_REQ_LAST },
{RADIO_1_3, RADIO_1_3_REQ_LAST },
{RADIO_1_2, RADIO_1_2_REQ_LAST },
@@ -139,6 +133,7 @@ static const GBinderClientIfaceInfo radio_iface_info[] = {
G_STATIC_ASSERT(G_N_ELEMENTS(radio_iface_info) == RADIO_INTERFACE_COUNT);
static const char* const radio_indication_ifaces[] = {
RADIO_INDICATION_1_5,
RADIO_INDICATION_1_4,
RADIO_INDICATION_1_3,
RADIO_INDICATION_1_2,
@@ -149,6 +144,7 @@ static const char* const radio_indication_ifaces[] = {
G_STATIC_ASSERT(G_N_ELEMENTS(radio_indication_ifaces) == RADIO_INTERFACE_COUNT + 1);
static const char* const radio_response_ifaces[] = {
RADIO_RESPONSE_1_5,
RADIO_RESPONSE_1_4,
RADIO_RESPONSE_1_3,
RADIO_RESPONSE_1_2,
@@ -160,19 +156,25 @@ G_STATIC_ASSERT(G_N_ELEMENTS(radio_response_ifaces) == RADIO_INTERFACE_COUNT + 1
typedef struct radio_interface_desc {
RADIO_INTERFACE version;
RADIO_AIDL_INTERFACE aidl_interface;
const char* radio_iface;
const char* const* ind_ifaces;
const char* const* resp_ifaces;
gint32 set_response_functions_req;
} RadioInterfaceDesc;
#define RADIO_INTERFACE_INDEX(x) (RADIO_INTERFACE_COUNT - x - 1)
#define RADIO_INTERFACE_DESC(v) \
RADIO_INTERFACE_##v, RADIO_##v, \
RADIO_INTERFACE_##v, \
RADIO_AIDL_INTERFACE_NONE, \
RADIO_##v, \
radio_indication_ifaces + RADIO_INTERFACE_INDEX(RADIO_INTERFACE_##v), \
radio_response_ifaces + RADIO_INTERFACE_INDEX(RADIO_INTERFACE_##v)
radio_response_ifaces + RADIO_INTERFACE_INDEX(RADIO_INTERFACE_##v), \
RADIO_REQ_SET_RESPONSE_FUNCTIONS
static const RadioInterfaceDesc radio_interfaces[] = {
{ RADIO_INTERFACE_DESC(1_5) },
{ RADIO_INTERFACE_DESC(1_4) },
{ RADIO_INTERFACE_DESC(1_3) },
{ RADIO_INTERFACE_DESC(1_2) },
@@ -181,6 +183,146 @@ static const RadioInterfaceDesc radio_interfaces[] = {
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_interfaces) == RADIO_INTERFACE_COUNT);
static const GBinderClientIfaceInfo radio_aidl_iface_info[] = {
{RADIO_DATA, RADIO_DATA_1_REQ_LAST},
{RADIO_IMS, RADIO_IMS_1_REQ_LAST},
{RADIO_MESSAGING, RADIO_MESSAGING_1_REQ_LAST},
{RADIO_MODEM, RADIO_MODEM_1_REQ_LAST},
{RADIO_NETWORK, RADIO_NETWORK_1_REQ_LAST},
{RADIO_SIM, RADIO_SIM_1_REQ_LAST},
{RADIO_VOICE, RADIO_VOICE_1_REQ_LAST},
};
static const char* const radio_data_indication_ifaces[] = {
RADIO_DATA_INDICATION,
NULL
};
static const char* const radio_data_response_ifaces[] = {
RADIO_DATA_RESPONSE,
NULL
};
static const char* const radio_ims_indication_ifaces[] = {
RADIO_IMS_INDICATION,
NULL
};
static const char* const radio_ims_response_ifaces[] = {
RADIO_IMS_RESPONSE,
NULL
};
static const char* const radio_messaging_indication_ifaces[] = {
RADIO_MESSAGING_INDICATION,
NULL
};
static const char* const radio_messaging_response_ifaces[] = {
RADIO_MESSAGING_RESPONSE,
NULL
};
static const char* const radio_modem_indication_ifaces[] = {
RADIO_MODEM_INDICATION,
NULL
};
static const char* const radio_modem_response_ifaces[] = {
RADIO_MODEM_RESPONSE,
NULL
};
static const char* const radio_network_indication_ifaces[] = {
RADIO_NETWORK_INDICATION,
NULL
};
static const char* const radio_network_response_ifaces[] = {
RADIO_NETWORK_RESPONSE,
NULL
};
static const char* const radio_sim_indication_ifaces[] = {
RADIO_SIM_INDICATION,
NULL
};
static const char* const radio_sim_response_ifaces[] = {
RADIO_SIM_RESPONSE,
NULL
};
static const char* const radio_voice_indication_ifaces[] = {
RADIO_VOICE_INDICATION,
NULL
};
static const char* const radio_voice_response_ifaces[] = {
RADIO_VOICE_RESPONSE,
NULL
};
static const RadioInterfaceDesc radio_aidl_interfaces[] = {
{
RADIO_INTERFACE_NONE,
RADIO_DATA_INTERFACE,
RADIO_DATA,
radio_data_indication_ifaces,
radio_data_response_ifaces,
RADIO_DATA_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_IMS_INTERFACE,
RADIO_IMS,
radio_ims_indication_ifaces,
radio_ims_response_ifaces,
RADIO_IMS_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_MESSAGING_INTERFACE,
RADIO_MESSAGING,
radio_messaging_indication_ifaces,
radio_messaging_response_ifaces,
RADIO_MESSAGING_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_MODEM_INTERFACE,
RADIO_MODEM,
radio_modem_indication_ifaces,
radio_modem_response_ifaces,
RADIO_MODEM_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_NETWORK_INTERFACE,
RADIO_NETWORK,
radio_network_indication_ifaces,
radio_network_response_ifaces,
RADIO_NETWORK_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_SIM_INTERFACE,
RADIO_SIM,
radio_sim_indication_ifaces,
radio_sim_response_ifaces,
RADIO_SIM_REQ_SET_RESPONSE_FUNCTIONS,
},
{
RADIO_INTERFACE_NONE,
RADIO_VOICE_INTERFACE,
RADIO_VOICE,
radio_voice_indication_ifaces,
radio_voice_response_ifaces,
RADIO_VOICE_REQ_SET_RESPONSE_FUNCTIONS,
}
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_aidl_interfaces) == RADIO_AIDL_INTERFACE_COUNT);
typedef struct radio_instance_tx {
RadioInstance* instance;
RadioInstanceTxCompleteFunc complete;
@@ -208,7 +350,7 @@ radio_instance_req_quark(
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->req_quarks, key));
if (!q) {
const char* known = radio_req_name(req);
const char* known = radio_req_name2(self, req);
if (known) {
q = g_quark_from_static_string(known);
@@ -235,7 +377,7 @@ radio_instance_resp_quark(
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->resp_quarks, key));
if (!q) {
const char* known = radio_resp_name(resp);
const char* known = radio_resp_name2(self, resp);
if (known) {
q = g_quark_from_static_string(known);
@@ -248,20 +390,6 @@ radio_instance_resp_quark(
return q;
}
static
guint
radio_instance_priority_index(
RADIO_INSTANCE_PRIORITY priority)
{
if (priority < RADIO_INSTANCE_PRIORITY_LOWEST) {
return 0;
} else if (priority > RADIO_INSTANCE_PRIORITY_HIGHEST) {
return RADIO_INSTANCE_PRIORITY_COUNT - 1;
} else {
return priority - RADIO_INSTANCE_PRIORITY_LOWEST;
}
}
static
void
radio_instance_notify_request_observers(
@@ -272,7 +400,7 @@ radio_instance_notify_request_observers(
GQuark quark = 0;
int i;
for (i = RADIO_INSTANCE_PRIORITY_COUNT - 1; i >= 0; i--) {
for (i = RADIO_OBSERVER_PRIORITY_COUNT - 1; i >= 0; i--) {
guint id = radio_instance_signals[SIGNAL_OBSERVE_REQUEST_0 + i];
if (id) {
@@ -297,7 +425,14 @@ radio_instance_indication(
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
if (gutil_strv_contains((const GStrV*)radio_indication_ifaces, iface)) {
if (gutil_strv_contains((const GStrV*)radio_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_data_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_ims_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_messaging_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_modem_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_network_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_sim_indication_ifaces, iface)
|| gutil_strv_contains((const GStrV*)radio_voice_indication_ifaces, iface)) {
GBinderReader reader;
guint type;
@@ -309,20 +444,28 @@ radio_instance_indication(
const GQuark quark = radio_instance_ind_quark(self, code);
const guint* signals = radio_instance_signals +
SIGNAL_OBSERVE_INDICATION_0;
int p = RADIO_INSTANCE_PRIORITY_HIGHEST;
int p = RADIO_OBSERVER_PRIORITY_HIGHEST;
gboolean handled = FALSE;
guint ind_ril_connected = 0;
/* High-priority observers are notified first */
for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
for (; p > RADIO_OBSERVER_PRIORITY_DEFAULT; p--) {
if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
[RADIO_OBSERVER_PRIORITY_INDEX(p)],
quark, code, type, &reader);
}
}
/* rilConnected is a special case */
if (code == RADIO_IND_RIL_CONNECTED) {
if (self->interface_type == RADIO_INTERFACE_TYPE_HIDL) {
ind_ril_connected = RADIO_IND_RIL_CONNECTED;
} else if (self->interface_type == RADIO_INTERFACE_TYPE_AIDL
&& gutil_strv_contains((const GStrV*)radio_modem_indication_ifaces, iface)) {
ind_ril_connected = RADIO_MODEM_IND_RIL_CONNECTED;
}
if (ind_ril_connected && code == ind_ril_connected) {
if (G_UNLIKELY(self->connected)) {
/* We are only supposed to receive it once */
GWARN("%s received unexpected rilConnected", self->slot);
@@ -340,10 +483,10 @@ radio_instance_indication(
quark, code, type, &reader, &handled);
/* And then remaining observers in their priority order */
for (; p >= RADIO_INSTANCE_PRIORITY_LOWEST; p--) {
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
for (; p >= RADIO_OBSERVER_PRIORITY_LOWEST; p--) {
if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
[RADIO_OBSERVER_PRIORITY_INDEX(p)],
quark, code, type, &reader);
}
}
@@ -377,69 +520,126 @@ radio_instance_response(
{
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
const RadioResponseInfo* info = NULL;
GBinderReader reader;
gint32 ack_serial = 0;
gbinder_remote_request_init_reader(req, &reader);
if (gutil_strv_contains((const GStrV*)radio_response_ifaces, iface)) {
GBinderReader reader;
/* All these should be one-way transactions */
GASSERT(flags & GBINDER_TX_FLAG_ONEWAY);
gbinder_remote_request_init_reader(req, &reader);
if (code == RADIO_RESP_ACKNOWLEDGE_REQUEST) {
/* oneway acknowledgeRequest(int32_t serial) */
gint32 serial;
GDEBUG("%s %u acknowledgeRequest", iface, code);
if (gbinder_reader_read_int32(&reader, &serial)) {
g_signal_emit(self, radio_instance_signals[SIGNAL_ACK], 0,
serial);
}
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
/* All other responses have RadioResponseInfo */
const RadioResponseInfo* info =
gbinder_reader_read_hidl_struct(&reader, RadioResponseInfo);
if (info) {
const GQuark quark = radio_instance_resp_quark(self, code);
const guint* signals = radio_instance_signals +
SIGNAL_OBSERVE_RESPONSE_0;
int p = RADIO_INSTANCE_PRIORITY_HIGHEST;
gboolean handled = FALSE;
/* High-priority observers are notified first */
for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
quark, code, info, &reader);
}
}
/* Then handlers */
g_signal_emit(self, radio_instance_signals
[SIGNAL_HANDLE_RESPONSE],
quark, code, info, &reader, &handled);
/* And then remaining observers in their priority order */
for (; p >= RADIO_INSTANCE_PRIORITY_LOWEST; p--) {
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
quark, code, info, &reader);
}
}
/* Ack unhandled responses */
if (info->type == RADIO_RESP_SOLICITED_ACK_EXP && !handled) {
GDEBUG("ack unhandled response");
radio_instance_ack(self);
}
}
info = gbinder_reader_read_hidl_struct(&reader, RadioResponseInfo);
}
} else if (gutil_strv_contains((const GStrV*)radio_data_response_ifaces, iface)) {
if (code == RADIO_DATA_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_ims_response_ifaces, iface)) {
{
/* RadioResponseInfo has the same fields/padding between HIDL and AIDL */
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_messaging_response_ifaces, iface)) {
if (code == RADIO_MESSAGING_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
/* RadioResponseInfo has the same fields/padding between HIDL and AIDL */
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_modem_response_ifaces, iface)) {
if (code == RADIO_MODEM_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
/* RadioResponseInfo has the same fields/padding between HIDL and AIDL */
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_network_response_ifaces, iface)) {
if (code == RADIO_NETWORK_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_sim_response_ifaces, iface)) {
if (code == RADIO_SIM_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
} else if (gutil_strv_contains((const GStrV*)radio_voice_response_ifaces, iface)) {
if (code == RADIO_VOICE_RESP_ACKNOWLEDGE_REQUEST) {
gbinder_reader_read_int32(&reader, &ack_serial);
} else {
gsize out_size;
info = gbinder_reader_read_parcelable(&reader, &out_size);
GASSERT(out_size >= sizeof(RadioResponseInfo));
}
*status = GBINDER_STATUS_OK;
} else {
GWARN("Unexpected response %s %u", iface, code);
*status = GBINDER_STATUS_FAILED;
return NULL;
}
/* All these should be one-way transactions */
GASSERT(flags & GBINDER_TX_FLAG_ONEWAY);
if (ack_serial) {
GDEBUG("%s %u acknowledgeRequest", iface, code);
g_signal_emit(self, radio_instance_signals[SIGNAL_ACK], 0,
ack_serial);
} else if (info) {
const GQuark quark = radio_instance_resp_quark(self, code);
const guint* signals = radio_instance_signals +
SIGNAL_OBSERVE_RESPONSE_0;
int p = RADIO_OBSERVER_PRIORITY_HIGHEST;
gboolean handled = FALSE;
/* High-priority observers are notified first */
for (; p > RADIO_OBSERVER_PRIORITY_DEFAULT; p--) {
if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_OBSERVER_PRIORITY_INDEX(p)],
quark, code, info, &reader);
}
}
/* Then handlers */
g_signal_emit(self, radio_instance_signals
[SIGNAL_HANDLE_RESPONSE],
quark, code, info, &reader, &handled);
/* And then remaining observers in their priority order */
for (; p >= RADIO_OBSERVER_PRIORITY_LOWEST; p--) {
if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
g_signal_emit(self, signals
[RADIO_OBSERVER_PRIORITY_INDEX(p)],
quark, code, info, &reader);
}
}
/* Ack unhandled responses */
if (info->type == RADIO_RESP_SOLICITED_ACK_EXP && !handled) {
GDEBUG("ack unhandled response");
radio_instance_ack(self);
}
}
*status = GBINDER_STATUS_OK;
return NULL;
}
@@ -537,10 +737,9 @@ radio_instance_create_version(
self->modem = priv->modem = g_strdup(modem);
self->slot_index = slot_index;
self->version = desc->version;
self->interface_aidl = desc->aidl_interface;
priv->remote = gbinder_remote_object_ref(remote);
priv->client = gbinder_client_new2(remote,
radio_iface_info, G_N_ELEMENTS(radio_iface_info));
priv->indication = gbinder_servicemanager_new_local_object2(sm,
desc->ind_ifaces, radio_instance_indication, self);
priv->response = gbinder_servicemanager_new_local_object2(sm,
@@ -548,14 +747,27 @@ radio_instance_create_version(
priv->death_id = gbinder_remote_object_add_death_handler(remote,
radio_instance_died, self);
if (desc->version != RADIO_INTERFACE_NONE) {
self->interface_type = RADIO_INTERFACE_TYPE_HIDL;
priv->client = gbinder_client_new2(remote,
radio_iface_info, G_N_ELEMENTS(radio_iface_info));
} else if (desc->aidl_interface != RADIO_AIDL_INTERFACE_NONE) {
self->interface_type = RADIO_INTERFACE_TYPE_AIDL;
priv->client = gbinder_client_new2(remote,
radio_aidl_iface_info + desc->aidl_interface, 1);
gbinder_local_object_set_stability(priv->indication, GBINDER_STABILITY_VINTF);
gbinder_local_object_set_stability(priv->response, GBINDER_STABILITY_VINTF);
}
/* IRadio::setResponseFunctions */
req = gbinder_client_new_request2(priv->client,
RADIO_REQ_SET_RESPONSE_FUNCTIONS);
desc->set_response_functions_req);
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_local_object(&writer, priv->response);
gbinder_writer_append_local_object(&writer, priv->indication);
gbinder_remote_reply_unref(gbinder_client_transact_sync_reply(priv->client,
RADIO_REQ_SET_RESPONSE_FUNCTIONS, req, &status));
desc->set_response_functions_req, req, &status));
GVERBOSE_("setResponseFunctions %s status %d", slot, status);
gbinder_local_request_unref(req);
@@ -578,32 +790,47 @@ radio_instance_create(
const char* key,
const char* modem,
int slot_index,
RADIO_INTERFACE max_version)
RADIO_INTERFACE max_version,
RADIO_AIDL_INTERFACE aidl_interface)
{
RadioInstance* self = NULL;
GBinderServiceManager* sm = gbinder_servicemanager_new(dev);
const RadioInterfaceDesc* interfaces = NULL;
gsize num_interfaces = 0;
if (sm) {
guint i;
for (i = 0; i < G_N_ELEMENTS(radio_interfaces) && !self; i++) {
const RadioInterfaceDesc* desc = radio_interfaces + i;
if (desc->version <= max_version) {
char* fqname = g_strconcat(desc->radio_iface, "/", slot, NULL);
GBinderRemoteObject* obj = /* autoreleased */
gbinder_servicemanager_get_service_sync(sm, fqname, NULL);
if (obj) {
GINFO("Connected to %s", fqname);
self = radio_instance_create_version(sm, obj, dev, slot,
key, modem, slot_index, desc);
}
g_free(fqname);
}
}
gbinder_servicemanager_unref(sm);
if (!sm) {
GERR_("Failed to get ServiceManager on %s", dev);
return NULL;
}
if (aidl_interface == RADIO_AIDL_INTERFACE_NONE) {
interfaces = radio_interfaces;
num_interfaces = G_N_ELEMENTS(radio_interfaces);
} else if (aidl_interface > RADIO_AIDL_INTERFACE_NONE
&& aidl_interface < RADIO_AIDL_INTERFACE_COUNT) {
interfaces = radio_aidl_interfaces + aidl_interface;
num_interfaces = 1;
}
for (guint i = 0; i < num_interfaces && !self; i++) {
const RadioInterfaceDesc* desc = interfaces + i;
if (desc->version <= max_version) {
char* fqname = g_strconcat(desc->radio_iface, "/", slot, NULL);
GBinderRemoteObject* obj = /* autoreleased */
gbinder_servicemanager_get_service_sync(sm, fqname, NULL);
if (obj) {
GINFO("Connected to %s", fqname);
self = radio_instance_create_version(sm, obj, dev, slot,
key, modem, slot_index, desc);
}
g_free(fqname);
}
}
gbinder_servicemanager_unref(sm);
return self;
}
@@ -612,9 +839,10 @@ char*
radio_instance_make_key(
const char* dev,
const char* name,
RADIO_INTERFACE version)
RADIO_INTERFACE version,
RADIO_AIDL_INTERFACE aidl_interface)
{
return g_strdup_printf("%s:%s:%d", dev, name, version);
return g_strdup_printf("%s:%s:%d:%d", dev, name, version, aidl_interface);
}
static
@@ -722,7 +950,7 @@ radio_instance_ind_quark(
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->ind_quarks, key));
if (!q) {
const char* known = radio_ind_name(ind);
const char* known = radio_ind_name2(self, ind);
if (known) {
q = g_quark_from_static_string(known);
@@ -793,8 +1021,24 @@ radio_instance_new_with_modem_slot_and_version(
int slot,
RADIO_INTERFACE version) /* Since 1.2.1 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_new_with_modem_slot_version_and_interface(
dev, name, modem, slot, version, RADIO_AIDL_INTERFACE_NONE);
}
RadioInstance*
radio_instance_new_with_modem_slot_version_and_interface(
const char* dev,
const char* name,
const char* modem,
int slot,
RADIO_INTERFACE version,
RADIO_AIDL_INTERFACE aidl_interface) /* Since 1.6.0 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (dev && dev[0] && name && name[0]) {
char* key = radio_instance_make_key(dev, name, version);
/* HIDL and AIDL would use different binder devices */
char* key = radio_instance_make_key(dev, name, version, aidl_interface);
RadioInstance* self = NULL;
if (radio_instance_table) {
@@ -804,7 +1048,8 @@ radio_instance_new_with_modem_slot_and_version(
g_free(key);
return radio_instance_ref(self);
} else {
self = radio_instance_create(dev, name, key, modem, slot, version);
self = radio_instance_create(dev, name, key, modem, slot, version,
aidl_interface);
if (self) {
if (!radio_instance_table) {
radio_instance_table = g_hash_table_new_full
@@ -826,6 +1071,7 @@ radio_instance_get(
const char* dev,
const char* name)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_get_with_version(dev, name, DEFAULT_INTERFACE);
}
@@ -835,6 +1081,7 @@ radio_instance_get_with_interface(
const char* name,
RADIO_INTERFACE version) /* 1.2.1, deprecated */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_get_with_version(dev, name, version);
}
@@ -844,10 +1091,11 @@ radio_instance_get_with_version(
const char* name,
RADIO_INTERFACE version) /* Since 1.2.2 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioInstance* self = NULL;
if (dev && dev[0] && name && name[0] && radio_instance_table) {
char* key = radio_instance_make_key(dev, name, version);
char* key = radio_instance_make_key(dev, name, version, RADIO_AIDL_INTERFACE_NONE);
self = g_hash_table_lookup(radio_instance_table, key);
g_free(key);
@@ -859,6 +1107,7 @@ RadioInstance* const*
radio_instance_get_all(
void)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (radio_instance_table) {
/* If the table exists, it must be non-empty */
const guint n = g_hash_table_size(radio_instance_table);
@@ -884,6 +1133,7 @@ RadioInstance*
radio_instance_ref(
RadioInstance* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
g_object_ref(RADIO_INSTANCE(self));
return self;
@@ -896,6 +1146,7 @@ void
radio_instance_unref(
RadioInstance* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
g_object_unref(RADIO_INSTANCE(self));
}
@@ -906,6 +1157,7 @@ radio_instance_rpc_header_size(
RadioInstance* self,
RADIO_REQ req) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
RadioInstancePriv* priv = self->priv;
GBytes* header = gbinder_client_rpc_header(priv->client, req);
@@ -922,7 +1174,8 @@ radio_instance_req_name(
RadioInstance* self,
RADIO_REQ req)
{
const char* known = radio_req_name(req);
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
const char* known = radio_req_name2(self, req);
if (known) {
return known;
@@ -941,7 +1194,8 @@ radio_instance_resp_name(
RadioInstance* self,
RADIO_RESP resp)
{
const char* known = radio_resp_name(resp);
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
const char* known = radio_resp_name2(self, resp);
if (known) {
return known;
@@ -960,7 +1214,8 @@ radio_instance_ind_name(
RadioInstance* self,
RADIO_IND ind)
{
const char* known = radio_ind_name(ind);
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
const char* known = radio_ind_name2(self, ind);
if (known) {
return known;
@@ -978,6 +1233,7 @@ gboolean
radio_instance_is_dead(
RadioInstance* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return G_UNLIKELY(!self) || self->dead;
}
@@ -985,6 +1241,7 @@ gboolean
radio_instance_ack(
RadioInstance* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
GBinderClient* client = self->priv->client;
const RADIO_REQ code = RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT;
@@ -1000,6 +1257,7 @@ radio_instance_new_request(
RadioInstance* self,
RADIO_REQ code)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
return gbinder_client_new_request2(self->priv->client, code);
}
@@ -1012,6 +1270,7 @@ radio_instance_send_request_sync(
RADIO_REQ code,
GBinderLocalRequest* args)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
GBinderClient* client = self->priv->client;
@@ -1026,6 +1285,7 @@ radio_instance_set_enabled(
RadioInstance* self,
gboolean enabled) /* Since 1.0.7 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && self->enabled != enabled) {
self->enabled = enabled;
GDEBUG("%s %sabled", self->slot, enabled ? "en" : "dis");
@@ -1040,20 +1300,22 @@ radio_instance_add_request_observer(
RadioRequestObserverFunc func,
gpointer user_data) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_add_request_observer_with_priority(self,
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
}
gulong
radio_instance_add_request_observer_with_priority(
RadioInstance* self,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_REQ code,
RadioRequestObserverFunc func,
gpointer user_data) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(func)) {
const guint index = radio_instance_priority_index(priority);
const guint index = radio_observer_priority_index(priority);
const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_REQUEST_0 + index;
/* Register signal on demand */
@@ -1081,20 +1343,22 @@ radio_instance_add_response_observer(
RadioResponseObserverFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_add_response_observer_with_priority(self,
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
}
gulong
radio_instance_add_response_observer_with_priority(
RadioInstance* self,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_RESP code,
RadioResponseObserverFunc func,
gpointer user_data) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(func)) {
const guint index = radio_instance_priority_index(priority);
const guint index = radio_observer_priority_index(priority);
const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_RESPONSE_0 + index;
/* Register signal on demand */
@@ -1122,20 +1386,22 @@ radio_instance_add_indication_observer(
RadioIndicationObserverFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_instance_add_indication_observer_with_priority(self,
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
}
gulong
radio_instance_add_indication_observer_with_priority(
RadioInstance* self,
RADIO_INSTANCE_PRIORITY priority,
RADIO_OBSERVER_PRIORITY priority,
RADIO_IND code,
RadioIndicationObserverFunc func,
gpointer user_data) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(func)) {
const guint index = radio_instance_priority_index(priority);
const guint index = radio_observer_priority_index(priority);
const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_INDICATION_0 + index;
/* Register signal on demand */
@@ -1163,6 +1429,7 @@ radio_instance_add_response_handler(
RadioResponseHandlerFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_HANDLE_RESPONSE],
@@ -1177,6 +1444,7 @@ radio_instance_add_indication_handler(
RadioIndicationHandlerFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_HANDLE_INDICATION],
@@ -1190,6 +1458,7 @@ radio_instance_add_ack_handler(
RadioAckFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ACK_NAME, G_CALLBACK(func), user_data) : 0;
}
@@ -1200,6 +1469,7 @@ radio_instance_add_death_handler(
RadioInstanceFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_DEATH_NAME, G_CALLBACK(func), user_data) : 0;
}
@@ -1210,6 +1480,7 @@ radio_instance_add_enabled_handler(
RadioInstanceFunc func,
gpointer user_data) /* Since 1.0.7 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ENABLED_NAME, G_CALLBACK(func), user_data) : 0;
}
@@ -1220,6 +1491,7 @@ radio_instance_add_connected_handler(
RadioInstanceFunc func,
gpointer user_data) /* Since 1.4.3 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_CONNECTED_NAME, G_CALLBACK(func), user_data) : 0;
}
@@ -1229,6 +1501,7 @@ radio_instance_remove_handler(
RadioInstance* self,
gulong id)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(id)) {
g_signal_handler_disconnect(self, id);
}
@@ -1240,6 +1513,7 @@ radio_instance_remove_handlers(
gulong* ids,
int count)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
gutil_disconnect_handlers(self, ids, count);
}
@@ -1252,6 +1526,7 @@ void
radio_instance_init(
RadioInstance* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioInstancePriv* priv = G_TYPE_INSTANCE_GET_PRIVATE
(self, RADIO_TYPE_INSTANCE, RadioInstancePriv);
@@ -1267,6 +1542,7 @@ void
radio_instance_finalize(
GObject* object)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioInstance* self = RADIO_INSTANCE(object);
RadioInstancePriv* priv = self->priv;
@@ -1288,6 +1564,7 @@ void
radio_instance_class_init(
RadioInstanceClass* klass)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
GObjectClass* object_class = G_OBJECT_CLASS(klass);
GType type = G_OBJECT_CLASS_TYPE(klass);

View File

@@ -41,6 +41,8 @@
#define GLOG_MODULE_NAME GBINDER_RADIO_LOG_MODULE
#include <gutil_log.h>
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "gbinder-radio:"fmt, ##__VA_ARGS__)
#endif /* RADIO_LOG_H */

View File

@@ -36,6 +36,7 @@
#include "radio_registry_p.h"
#include "radio_instance.h"
#include "radio_log.h"
#include <gutil_misc.h>
@@ -71,6 +72,7 @@ void
radio_registry_instance_added(
RadioInstance* radio)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRegistry* self = radio_registry_instance;
if (self) {
@@ -85,6 +87,7 @@ void
radio_registry_instance_removed(
const char* key)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRegistry* self = radio_registry_instance;
if (self) {
@@ -103,6 +106,7 @@ RadioRegistry*
radio_registry_new(
void)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (radio_registry_instance) {
radio_registry_ref(radio_registry_instance);
} else {
@@ -118,6 +122,7 @@ RadioRegistry*
radio_registry_ref(
RadioRegistry* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
g_object_ref(RADIO_REGISTRY(self));
return self;
@@ -130,6 +135,7 @@ void
radio_registry_unref(
RadioRegistry* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
g_object_unref(RADIO_REGISTRY(self));
}
@@ -142,6 +148,7 @@ radio_registry_add_instance_added_handler(
RadioRegistryInstanceFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(func)) {
return g_signal_connect_closure_by_id(self,
radio_registry_signals[SIGNAL_INSTANCE_ADDED],
@@ -158,6 +165,7 @@ radio_registry_add_instance_removed_handler(
RadioRegistryStrFunc func,
gpointer user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(func)) {
return g_signal_connect_closure_by_id(self,
radio_registry_signals[SIGNAL_INSTANCE_REMOVED],
@@ -172,6 +180,7 @@ radio_registry_remove_handler(
RadioRegistry* self,
gulong id)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self) && G_LIKELY(id)) {
g_signal_handler_disconnect(self, id);
}
@@ -183,6 +192,7 @@ radio_registry_remove_handlers(
gulong* ids,
int count)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
gutil_disconnect_handlers(self, ids, count);
}
@@ -195,6 +205,7 @@ void
radio_registry_init(
RadioRegistry* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
}
static
@@ -202,6 +213,7 @@ void
radio_registry_class_init(
RadioRegistryClass* klass)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
radio_registry_signals[SIGNAL_INSTANCE_ADDED] =
g_signal_new(SIGNAL_INSTANCE_ADDED_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -34,10 +34,9 @@
* any official policies, either expressed or implied.
*/
#include "radio_base.h"
#include "radio_request_p.h"
#include "radio_request_group_p.h"
#include "radio_instance_p.h"
#include "radio_client_p.h"
#include "radio_log.h"
#include <gbinder_local_request.h>
@@ -45,12 +44,17 @@
#include <gutil_macros.h>
typedef enum radio_request_flags {
RADIO_REQUEST_NO_FLAGS = 0,
RADIO_REQUEST_FLAG_DROPPED = 0x01,
RADIO_REQUEST_FLAG_SUBMITTED = 0x02
} RADIO_REQUEST_FLAGS;
typedef struct radio_request_object {
RadioRequest pub;
RadioInstance* instance;
GDestroyNotify destroy;
gsize serial_offset;
gboolean dropped;
RADIO_REQUEST_FLAGS flags;
gint refcount;
} RadioRequestObject;
@@ -66,18 +70,16 @@ void
radio_request_object_cancel(
RadioRequestObject* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequest* req = &self->pub;
if (req->tx_id) {
radio_instance_cancel_request(self->instance, req->tx_id);
req->tx_id = 0;
}
if (!self->dropped) {
self->dropped = TRUE;
radio_base_cancel_request(req->object, req);
if (!(self->flags & RADIO_REQUEST_FLAG_DROPPED)) {
self->flags |= RADIO_REQUEST_FLAG_DROPPED;
radio_request_group_remove(req->group, req);
radio_client_request_dropped(req);
radio_base_request_dropped(req);
}
radio_client_unregister_request(req->client, req);
radio_base_unregister_request(req->object, req);
}
static
@@ -85,10 +87,14 @@ void
radio_request_free(
RadioRequestObject* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequest* req = &self->pub;
GVERBOSE_("%u (%08x) %p", req->code, req->serial, req);
radio_request_object_cancel(self);
if (req->complete) {
/* Don't invoke completion routine if the request was never submitted */
if (req->complete && (self->flags & RADIO_REQUEST_FLAG_SUBMITTED)) {
RadioRequestCompleteFunc complete = req->complete;
/* Request is being freed too early, before completion */
@@ -103,7 +109,6 @@ radio_request_free(
destroy(req->user_data);
}
gbinder_local_request_unref(req->args);
radio_instance_unref(self->instance);
gutil_slice_free(self);
}
@@ -112,6 +117,7 @@ void
radio_request_object_unref(
RadioRequestObject* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(self)) {
GASSERT(self->refcount > 0);
if (g_atomic_int_dec_and_test(&self->refcount)) {
@@ -130,25 +136,36 @@ radio_request_default_retry(
const GBinderReader* reader,
void* user_data)
{
return status != RADIO_TX_STATUS_OK || error != RADIO_ERROR_NONE;
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (status != RADIO_TX_STATUS_OK) {
GVERBOSE_("req %p %u (%08x) status %d", req, req->code, req->serial,
status);
return TRUE;
} else if (error != RADIO_ERROR_NONE) {
GVERBOSE_("req %p %u (%08x) error %d", req, req->code, req->serial,
error);
return TRUE;
} else {
return FALSE;
}
}
static
RadioRequest*
radio_request_object_new(
RadioClient* client,
RadioBase* base,
RadioRequestGroup* group,
RADIO_REQ code,
GBinderWriter* writer,
RadioRequestCompleteFunc complete,
RadioRequestGenericCompleteFunc complete,
GDestroyNotify destroy,
void* user_data)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestObject* self = g_slice_new0(RadioRequestObject);
RadioRequest* req = &self->pub;
GBinderWriter tmp;
self->instance = radio_instance_ref(client->instance);
self->destroy = destroy;
g_atomic_int_set(&self->refcount, 1);
@@ -159,12 +176,13 @@ radio_request_object_new(
req->retry = radio_request_default_retry;
/* Assign serial and add to the group */
radio_client_register_request(client, req);
radio_base_register_request(base, req);
radio_request_group_add(group, req);
GVERBOSE_("%u (%08x) %p group %p", req->code, req->serial, req, group);
/* Build the argument list */
if (!writer) writer = &tmp;
req->args = radio_instance_new_request(client->instance, code);
req->args = RADIO_BASE_GET_CLASS(base)->new_request(base, code);
gbinder_local_request_init_writer(req->args, writer);
self->serial_offset = gbinder_writer_bytes_written(writer);
gbinder_writer_append_int32(writer, req->serial);
@@ -179,6 +197,7 @@ void
radio_request_unref_func(
gpointer req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
radio_request_object_unref(radio_request_cast(req));
}
@@ -187,6 +206,7 @@ radio_request_update_serial(
RadioRequest* req,
guint32 serial)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
GBinderWriter writer;
gbinder_local_request_init_writer(req->args, &writer);
@@ -207,8 +227,10 @@ radio_request_new(
GDestroyNotify destroy,
void* user_data)
{
return client ? radio_request_object_new(client, NULL, code,
writer, complete, destroy, user_data) : NULL;
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return client ? radio_request_object_new(RADIO_BASE(client), NULL,
code, writer, (RadioRequestGenericCompleteFunc) complete,
destroy, user_data) : NULL;
}
RadioRequest*
@@ -220,14 +242,32 @@ radio_request_new2(
GDestroyNotify destroy,
void* user_data)
{
return group ? radio_request_object_new(group->client, group, code,
writer, complete, destroy, user_data) : NULL;
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return group ? radio_request_object_new(RADIO_BASE(group->client), group,
code, writer, (RadioRequestGenericCompleteFunc) complete,
destroy, user_data) : NULL;
}
RadioRequest*
radio_config_request_new(
RadioConfig* config,
RADIO_CONFIG_REQ code,
GBinderWriter* writer, /* NULL if serial is the only arg */
RadioConfigRequestCompleteFunc complete,
GDestroyNotify destroy,
void* user_data) /* Since 1.4.6 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return config ? radio_request_object_new(RADIO_BASE(config), NULL,
code, writer, (RadioRequestGenericCompleteFunc) complete,
destroy, user_data) : NULL;
}
RadioRequest*
radio_request_ref(
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestObject* self = radio_request_cast(req);
if (G_LIKELY(self)) {
@@ -241,6 +281,7 @@ void
radio_request_unref(
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
radio_request_object_unref(radio_request_cast(req));
}
@@ -249,6 +290,7 @@ radio_request_set_blocking(
RadioRequest* req,
gboolean blocking)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(req)) {
req->blocking = blocking;
}
@@ -259,15 +301,16 @@ radio_request_set_timeout(
RadioRequest* req,
guint ms)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(req) && req->timeout_ms != ms) {
RadioClient* client = req->client;
RadioBase* base = req->object;
req->timeout_ms = ms;
if (client && req->state >= RADIO_REQUEST_STATE_QUEUED) {
const uint timeout = radio_client_timeout_ms(client, req);
if (base && req->state >= RADIO_REQUEST_STATE_QUEUED) {
const guint timeout = radio_base_timeout_ms(base, req);
req->deadline = g_get_monotonic_time() + MICROSEC(timeout);
radio_client_reset_timeout(client);
radio_base_reset_timeout(base);
}
}
}
@@ -278,6 +321,7 @@ radio_request_set_retry(
guint delay_ms, /* Delay before each retry, in milliseconds */
int max_count) /* Negative count to keep retrying indefinitely */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(req)) {
req->retry_delay_ms = delay_ms;
req->max_retries = max_count;
@@ -289,6 +333,7 @@ radio_request_set_retry_func(
RadioRequest* req,
RadioRequestRetryFunc retry)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(req)) {
req->retry = retry ? retry : radio_request_default_retry;
}
@@ -298,20 +343,27 @@ gboolean
radio_request_submit(
RadioRequest* req)
{
return req && req->client && radio_client_submit_request(req->client, req);
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (req && req->object && radio_base_submit_request(req->object, req)) {
radio_request_cast(req)->flags |= RADIO_REQUEST_FLAG_SUBMITTED;
return TRUE;
}
return FALSE;
}
gboolean
radio_request_retry(
RadioRequest* req)
{
return req && req->client && radio_client_retry_request(req->client, req);
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return req && req->object && radio_base_retry_request(req->object, req);
}
void
radio_request_cancel(
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestObject* self = radio_request_cast(req);
if (G_LIKELY(self)) {
@@ -324,6 +376,7 @@ void
radio_request_drop(
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestObject* self = radio_request_cast(req);
if (G_LIKELY(self)) {
@@ -333,6 +386,14 @@ radio_request_drop(
}
}
void*
radio_request_user_data(
RadioRequest* req) /* Since 1.4.11 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return G_LIKELY(req) ? req->user_data : NULL;
}
/*
* Local Variables:
* mode: C

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -34,9 +34,10 @@
* any official policies, either expressed or implied.
*/
#include "radio_base.h"
#include "radio_client.h"
#include "radio_request_group_p.h"
#include "radio_request_p.h"
#include "radio_client_p.h"
#include "radio_log.h"
#include <gutil_macros.h>
@@ -59,6 +60,7 @@ void
radio_request_group_unlink_func(
gpointer req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
((RadioRequest*)req)->group = NULL;
}
@@ -67,12 +69,12 @@ void
radio_request_group_free(
RadioRequestGroupObject* self)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroup* group = &self->pub;
RadioClient* client = group->client;
radio_client_unblock(client, group);
radio_base_unblock(RADIO_BASE(group->client), group);
g_hash_table_destroy(self->requests);
radio_client_unref(client);
radio_client_unref(group->client);
gutil_slice_free(self);
}
@@ -85,6 +87,7 @@ radio_request_group_add(
RadioRequestGroup* group,
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroupObject* self = radio_request_group_cast(group);
/* Request is never NULL but the group may be */
@@ -99,6 +102,7 @@ radio_request_group_remove(
RadioRequestGroup* group,
RadioRequest* req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroupObject* self = radio_request_group_cast(group);
/* Request is never NULL but the group may be */
@@ -115,6 +119,7 @@ RadioRequestGroup*
radio_request_group_new(
RadioClient* client)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (G_LIKELY(client)) {
RadioRequestGroupObject* self = g_slice_new0(RadioRequestGroupObject);
RadioRequestGroup* group = &self->pub;
@@ -132,6 +137,7 @@ RadioRequestGroup*
radio_request_group_ref(
RadioRequestGroup* group)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroupObject* self = radio_request_group_cast(group);
if (G_LIKELY(self)) {
@@ -145,6 +151,7 @@ void
radio_request_group_unref(
RadioRequestGroup* group)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroupObject* self = radio_request_group_cast(group);
if (G_LIKELY(self)) {
@@ -159,6 +166,7 @@ void
radio_request_group_cancel(
RadioRequestGroup* group)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
RadioRequestGroupObject* self = radio_request_group_cast(group);
if (G_LIKELY(self)) {
@@ -194,7 +202,8 @@ RADIO_BLOCK
radio_request_group_block_status(
RadioRequestGroup* group)
{
return group ? radio_client_block_status(group->client, group) :
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return group ? radio_base_block_status(RADIO_BASE(group->client), group) :
RADIO_BLOCK_NONE;
}
@@ -202,7 +211,8 @@ RADIO_BLOCK
radio_request_group_block(
RadioRequestGroup* group)
{
return group ? radio_client_block(group->client, group) :
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return group ? radio_base_block(RADIO_BASE(group->client), group) :
RADIO_BLOCK_NONE;
}
@@ -210,8 +220,9 @@ void
radio_request_group_unblock(
RadioRequestGroup* group)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (group) {
radio_client_unblock(group->client, group);
radio_base_unblock(RADIO_BASE(group->client), group);
}
}

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -107,11 +107,21 @@ typedef enum radio_request_state {
RADIO_REQUEST_STATE_DONE
} RADIO_REQUEST_STATE;
typedef
void
(*RadioRequestGenericCompleteFunc)(
RadioRequest* req,
RADIO_TX_STATUS status,
guint32 resp,
RADIO_ERROR error,
const GBinderReader* args,
gpointer user_data);
struct radio_request {
RADIO_REQUEST_STATE state;
RADIO_REQ code;
guint32 code;
GBinderLocalRequest* args;
RadioRequestCompleteFunc complete;
RadioRequestGenericCompleteFunc complete;
RadioRequestRetryFunc retry;
void* user_data;
guint32 serial; /* Immutable, generated at creation time */
@@ -121,10 +131,11 @@ struct radio_request {
guint retry_delay_ms; /* Delay before each retry, in milliseconds */
guint timeout_ms; /* Timeout, in milliseconds (0 = default) */
gint64 deadline; /* Monotonic time, in microseconds */
gint64 scheduled; /* Monotonic time, in microseconds */
gulong tx_id; /* Id of the request transaction */
gboolean blocking; /* TRUE if this request blocks all others */
gboolean acked;
RadioClient* client; /* Not a reference */
RadioBase* object; /* Not a reference */
RadioRequestGroup* group; /* Not a reference */
RadioRequest* queue_next;
};

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -39,11 +39,31 @@
#include <radio_types.h>
typedef struct radio_base RadioBase;
#define RADIO_INTERNAL G_GNUC_INTERNAL
/* Miliseconds to microseconds */
#define MICROSEC(ms) (((gint64)(ms)) * 1000)
/* Preprocessor magic related to observers */
G_STATIC_ASSERT(RADIO_OBSERVER_PRIORITY_LOWEST == 0);
G_STATIC_ASSERT(RADIO_OBSERVER_PRIORITY_HIGHEST == 7);
#define FOREACH_OBSERVER_PRIORITY(p) p(0) p(1) p(2) p(3) p(4) p(5) p(6) p(7)
#define RADIO_OBSERVER_PRIORITY_INDEX(p) ((p) - RADIO_OBSERVER_PRIORITY_LOWEST)
#define RADIO_OBSERVER_PRIORITY_COUNT \
(RADIO_OBSERVER_PRIORITY_INDEX(RADIO_OBSERVER_PRIORITY_HIGHEST) + 1)
/*
* A special assert fatal in debug build and non-fatal in release.
* Marks truely unavoidable conditions.
*/
#ifdef DEBUG
# define DEBUG_ASSERT(expr) g_assert(expr)
#else
# define DEBUG_ASSERT(expr)
#endif
#endif /* RADIO_TYPES_PRIVATE_H */
/*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2022 Jolla Ltd.
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -34,35 +34,142 @@
* any official policies, either expressed or implied.
*/
#include "radio_util.h"
#include "radio_util_p.h"
#include "radio_instance.h"
#include "radio_log.h"
GLOG_MODULE_DEFINE("gbinder-radio");
guint
radio_observer_priority_index(
RADIO_OBSERVER_PRIORITY priority)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (priority < RADIO_OBSERVER_PRIORITY_LOWEST) {
return 0;
} else if (priority > RADIO_OBSERVER_PRIORITY_HIGHEST) {
return RADIO_OBSERVER_PRIORITY_COUNT - 1;
} else {
return priority - RADIO_OBSERVER_PRIORITY_LOWEST;
}
}
const char*
radio_req_name(
RADIO_REQ req)
{
switch (req) {
case RADIO_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_req_name2(NULL, req);
}
const char*
radio_req_name2(
RadioInstance* instance,
RADIO_REQ req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (!G_LIKELY(instance) || instance->interface_type == RADIO_INTERFACE_TYPE_HIDL) {
switch (req) {
case RADIO_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
#define RADIO_REQ_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return #Name;
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_CALL_1_3(RADIO_REQ_)
RADIO_CALL_1_4(RADIO_REQ_)
case RADIO_REQ_##NAME: return #Name;
#define RADIO_REQ__(req,resp,Name,NAME,x) \
case RADIO_REQ_##NAME##x: return #Name #x;
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_CALL_1_3(RADIO_REQ_)
RADIO_CALL_1_4_(RADIO_REQ__)
RADIO_CALL_1_5_(RADIO_REQ__)
#undef RADIO_REQ_
case RADIO_REQ_START_NETWORK_SCAN_1_2: return "startNetworkScan_1_2";
case RADIO_REQ_SET_INDICATION_FILTER_1_2: return "setIndicationFilter_1_2";
case RADIO_REQ_SETUP_DATA_CALL_1_2: return "setupDataCall_1_2";
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2: return "deactivateDataCall_1_2";
case RADIO_REQ_SETUP_DATA_CALL_1_4: return "setupDataCall_1_4";
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4: return "setInitialAttachApn_1_4";
case RADIO_REQ_SET_DATA_PROFILE_1_4: return "setDataProfile_1_4";
case RADIO_REQ_ANY:
break;
#undef RADIO_REQ__
case RADIO_REQ_START_NETWORK_SCAN_1_2: return "startNetworkScan_1_2";
case RADIO_REQ_SET_INDICATION_FILTER_1_2: return "setIndicationFilter_1_2";
case RADIO_REQ_SETUP_DATA_CALL_1_2: return "setupDataCall_1_2";
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2: return "deactivateDataCall_1_2";
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4: return "setInitialAttachApn_1_4";
case RADIO_REQ_SET_DATA_PROFILE_1_4: return "setDataProfile_1_4";
case RADIO_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_DATA_INTERFACE) {
switch ((RADIO_DATA_REQ)req) {
#define RADIO_DATA_REQ_(req,resp,Name,NAME) \
case RADIO_DATA_REQ_##NAME: return #Name;
RADIO_DATA_CALL_1(RADIO_DATA_REQ_)
#undef RADIO_DATA_REQ_
case RADIO_DATA_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_DATA_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_DATA_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_IMS_INTERFACE) {
switch ((RADIO_IMS_REQ)req) {
#define RADIO_IMS_REQ_(req,resp,Name,NAME) \
case RADIO_IMS_REQ_##NAME: return #Name;
RADIO_IMS_CALL_1(RADIO_IMS_REQ_)
#undef RADIO_IMS_REQ_
case RADIO_IMS_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_IMS_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MESSAGING_INTERFACE) {
switch ((RADIO_MESSAGING_REQ)req) {
#define RADIO_MESSAGING_REQ_(req,resp,Name,NAME) \
case RADIO_MESSAGING_REQ_##NAME: return #Name;
RADIO_MESSAGING_CALL_1(RADIO_MESSAGING_REQ_)
#undef RADIO_MESSAGING_REQ_
case RADIO_MESSAGING_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_MESSAGING_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_MESSAGING_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MODEM_INTERFACE) {
switch ((RADIO_MODEM_REQ)req) {
#define RADIO_MODEM_REQ_(req,resp,Name,NAME) \
case RADIO_MODEM_REQ_##NAME: return #Name;
RADIO_MODEM_CALL_1(RADIO_MODEM_REQ_)
#undef RADIO_MODEM_REQ_
case RADIO_MODEM_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_MODEM_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_MODEM_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_NETWORK_INTERFACE) {
switch ((RADIO_NETWORK_REQ)req) {
#define RADIO_NETWORK_REQ_(req,resp,Name,NAME) \
case RADIO_NETWORK_REQ_##NAME: return #Name;
RADIO_NETWORK_CALL_1(RADIO_NETWORK_REQ_)
#undef RADIO_NETWORK_REQ_
case RADIO_NETWORK_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_NETWORK_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_NETWORK_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_SIM_INTERFACE) {
switch ((RADIO_SIM_REQ)req) {
#define RADIO_SIM_REQ_(req,resp,Name,NAME) \
case RADIO_SIM_REQ_##NAME: return #Name;
RADIO_SIM_CALL_1(RADIO_SIM_REQ_)
#undef RADIO_SIM_REQ_
case RADIO_SIM_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_SIM_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_SIM_REQ_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_VOICE_INTERFACE) {
switch ((RADIO_VOICE_REQ)req) {
#define RADIO_VOICE_REQ_(req,resp,Name,NAME) \
case RADIO_VOICE_REQ_##NAME: return #Name;
RADIO_VOICE_CALL_1(RADIO_VOICE_REQ_)
#undef RADIO_VOICE_REQ_
case RADIO_VOICE_REQ_HANGUP: return "hangup";
case RADIO_VOICE_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_VOICE_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
case RADIO_VOICE_REQ_ANY:
break;
}
}
return NULL;
}
@@ -71,40 +178,130 @@ const char*
radio_resp_name(
RADIO_RESP resp)
{
switch (resp) {
case RADIO_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_resp_name2(NULL, resp);
}
const char*
radio_resp_name2(
RadioInstance* instance,
RADIO_RESP resp)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (!G_LIKELY(instance) || instance->interface_type == RADIO_INTERFACE_TYPE_HIDL) {
switch (resp) {
case RADIO_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_RESP_(req,resp,Name,NAME) \
case RADIO_RESP_##NAME: return #Name "Response";
RADIO_CALL_1_0(RADIO_RESP_)
RADIO_CALL_1_1(RADIO_RESP_)
RADIO_CALL_1_2(RADIO_RESP_)
RADIO_CALL_1_3(RADIO_RESP_)
RADIO_CALL_1_4(RADIO_RESP_)
case RADIO_RESP_##NAME: return #Name "Response";
#define RADIO_RESP__(req,resp,Name,NAME,x) \
case RADIO_RESP_##NAME##x: return #Name "Response" #x;
RADIO_CALL_1_0(RADIO_RESP_)
RADIO_CALL_1_1(RADIO_RESP_)
RADIO_CALL_1_2(RADIO_RESP_)
RADIO_CALL_1_3(RADIO_RESP_)
RADIO_CALL_1_4_(RADIO_RESP__)
RADIO_CALL_1_5_(RADIO_RESP__)
#undef RADIO_RESP_
case RADIO_RESP_GET_CELL_INFO_LIST_1_2:
return "getCellInfoListResponse_1_2";
case RADIO_RESP_GET_ICC_CARD_STATUS_1_2:
return "getIccCardStatusResponse_1_2";
case RADIO_RESP_GET_CURRENT_CALLS_1_2:
return "getCurrentCallsResponse_1_2";
case RADIO_RESP_GET_SIGNAL_STRENGTH_1_2:
return "getSignalStrengthResponse_1_2";
case RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2:
return "getVoiceRegistrationStateResponse_1_2";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2:
return "getDataRegistrationStateResponse_1_2";
case RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4:
return "getCellInfoListResponse_1_4";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4:
return "getDataRegistrationStateResponse_1_4";
case RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4:
return "getIccCardStatusResponse_1_4";
case RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4:
return "getDataCallListResponse_1_4";
case RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4:
return "setupDataCallResponse_1_4";
case RADIO_RESP_ANY:
break;
#undef RADIO_RESP__
case RADIO_RESP_GET_CELL_INFO_LIST_1_2:
return "getCellInfoListResponse_1_2";
case RADIO_RESP_GET_ICC_CARD_STATUS_1_2:
return "getIccCardStatusResponse_1_2";
case RADIO_RESP_GET_CURRENT_CALLS_1_2:
return "getCurrentCallsResponse_1_2";
case RADIO_RESP_GET_SIGNAL_STRENGTH_1_2:
return "getSignalStrengthResponse_1_2";
case RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2:
return "getVoiceRegistrationStateResponse_1_2";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2:
return "getDataRegistrationStateResponse_1_2";
case RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4:
return "getCellInfoListResponse_1_4";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4:
return "getDataRegistrationStateResponse_1_4";
case RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4:
return "getIccCardStatusResponse_1_4";
case RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4:
return "getDataCallListResponse_1_4";
case RADIO_RESP_GET_DATA_CALL_LIST_1_5:
return "getDataCallList_1_5";
case RADIO_RESP_GET_CELL_INFO_LIST_1_5:
return "getCellInfoListResponse_1_5";
case RADIO_RESP_GET_ICC_CARD_STATUS_1_5:
return "getIccCardStatus_1_5";
case RADIO_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_DATA_INTERFACE) {
switch ((RADIO_DATA_RESP)resp) {
case RADIO_DATA_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_DATA_RESP_(req,resp,Name,NAME) \
case RADIO_DATA_RESP_##NAME: return #Name "Response";
RADIO_DATA_CALL_1(RADIO_DATA_RESP_)
#undef RADIO_DATA_RESP_
case RADIO_DATA_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_IMS_INTERFACE) {
switch ((RADIO_IMS_RESP)resp) {
#define RADIO_IMS_RESP_(req,resp,Name,NAME) \
case RADIO_IMS_RESP_##NAME: return #Name "Response";
RADIO_IMS_CALL_1(RADIO_IMS_RESP_)
#undef RADIO_IMS_RESP_
case RADIO_IMS_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MESSAGING_INTERFACE) {
switch ((RADIO_MESSAGING_RESP)resp) {
case RADIO_MESSAGING_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_MESSAGING_RESP_(req,resp,Name,NAME) \
case RADIO_MESSAGING_RESP_##NAME: return #Name "Response";
RADIO_MESSAGING_CALL_1(RADIO_MESSAGING_RESP_)
#undef RADIO_MESSAGING_RESP_
case RADIO_MESSAGING_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MODEM_INTERFACE) {
switch ((RADIO_MODEM_RESP)resp) {
case RADIO_MODEM_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_MODEM_RESP_(req,resp,Name,NAME) \
case RADIO_MODEM_RESP_##NAME: return #Name "Response";
RADIO_MODEM_CALL_1(RADIO_MODEM_RESP_)
#undef RADIO_MODEM_RESP_
case RADIO_MODEM_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_NETWORK_INTERFACE) {
switch ((RADIO_NETWORK_RESP)resp) {
case RADIO_NETWORK_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_NETWORK_RESP_(req,resp,Name,NAME) \
case RADIO_NETWORK_RESP_##NAME: return #Name "Response";
RADIO_NETWORK_CALL_1(RADIO_NETWORK_RESP_)
#undef RADIO_NETWORK_RESP_
case RADIO_NETWORK_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_SIM_INTERFACE) {
switch ((RADIO_SIM_RESP)resp) {
case RADIO_SIM_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_SIM_RESP_(req,resp,Name,NAME) \
case RADIO_SIM_RESP_##NAME: return #Name "Response";
RADIO_SIM_CALL_1(RADIO_SIM_RESP_)
#undef RADIO_SIM_RESP_
case RADIO_SIM_RESP_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_VOICE_INTERFACE) {
switch ((RADIO_VOICE_RESP)resp) {
case RADIO_VOICE_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
case RADIO_VOICE_RESP_HANGUP_CONNECTION_RESPONSE: return "hangupConnectionResponse";
#define RADIO_VOICE_RESP_(req,resp,Name,NAME) \
case RADIO_VOICE_RESP_##NAME: return #Name "Response";
RADIO_VOICE_CALL_1(RADIO_VOICE_RESP_)
#undef RADIO_VOICE_RESP_
case RADIO_VOICE_RESP_ANY:
break;
}
}
return NULL;
}
@@ -113,16 +310,92 @@ const char*
radio_ind_name(
RADIO_IND ind)
{
switch (ind) {
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
return radio_ind_name2(NULL, ind);
}
const char*
radio_ind_name2(
RadioInstance* instance,
RADIO_IND ind)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
if (!G_LIKELY(instance) || instance->interface_type == RADIO_INTERFACE_TYPE_HIDL) {
switch (ind) {
#define RADIO_IND_(code,Name,NAME) \
case RADIO_IND_##NAME: return #Name;
RADIO_EVENT_1_0(RADIO_IND_)
RADIO_EVENT_1_1(RADIO_IND_)
RADIO_EVENT_1_2(RADIO_IND_)
RADIO_EVENT_1_4(RADIO_IND_)
case RADIO_IND_##NAME: return #Name;
RADIO_EVENT_1_0(RADIO_IND_)
RADIO_EVENT_1_1(RADIO_IND_)
RADIO_EVENT_1_2(RADIO_IND_)
RADIO_EVENT_1_4(RADIO_IND_)
RADIO_EVENT_1_5(RADIO_IND_)
#undef RADIO_IND_
case RADIO_IND_ANY:
break;
case RADIO_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_DATA_INTERFACE) {
switch ((RADIO_DATA_IND)ind) {
#define RADIO_DATA_IND_(code,Name,NAME) \
case RADIO_DATA_IND_##NAME: return #Name;
RADIO_DATA_IND_1(RADIO_DATA_IND_)
#undef RADIO_DATA_IND_
case RADIO_DATA_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_IMS_INTERFACE) {
switch ((RADIO_IMS_IND)ind) {
#define RADIO_IMS_IND_(code,Name,NAME) \
case RADIO_IMS_IND_##NAME: return #Name;
RADIO_IMS_IND_1(RADIO_IMS_IND_)
#undef RADIO_IMS_IND_
case RADIO_IMS_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MESSAGING_INTERFACE) {
switch ((RADIO_MESSAGING_IND)ind) {
#define RADIO_MESSAGING_IND_(code,Name,NAME) \
case RADIO_MESSAGING_IND_##NAME: return #Name;
RADIO_MESSAGING_IND_1(RADIO_MESSAGING_IND_)
#undef RADIO_MESSAGING_IND_
case RADIO_MESSAGING_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_MODEM_INTERFACE) {
switch ((RADIO_MODEM_IND)ind) {
#define RADIO_MODEM_IND_(code,Name,NAME) \
case RADIO_MODEM_IND_##NAME: return #Name;
RADIO_MODEM_IND_1(RADIO_MODEM_IND_)
#undef RADIO_MODEM_IND_
case RADIO_MODEM_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_NETWORK_INTERFACE) {
switch ((RADIO_NETWORK_IND)ind) {
#define RADIO_NETWORK_IND_(code,Name,NAME) \
case RADIO_NETWORK_IND_##NAME: return #Name;
RADIO_NETWORK_IND_1(RADIO_NETWORK_IND_)
#undef RADIO_NETWORK_IND_
case RADIO_NETWORK_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_SIM_INTERFACE) {
switch ((RADIO_SIM_IND)ind) {
#define RADIO_SIM_IND_(code,Name,NAME) \
case RADIO_SIM_IND_##NAME: return #Name;
RADIO_SIM_IND_1(RADIO_SIM_IND_)
#undef RADIO_SIM_IND_
case RADIO_SIM_IND_ANY:
break;
}
} else if (instance->interface_aidl == RADIO_VOICE_INTERFACE) {
switch ((RADIO_VOICE_IND)ind) {
#define RADIO_VOICE_IND_(code,Name,NAME) \
case RADIO_VOICE_IND_##NAME: return #Name;
RADIO_VOICE_IND_1(RADIO_VOICE_IND_)
#undef RADIO_VOICE_IND_
case RADIO_VOICE_IND_ANY:
break;
}
}
return NULL;
}
@@ -142,30 +415,239 @@ RADIO_RESP
radio_req_resp(
RADIO_REQ req)
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
switch (req) {
#define RADIO_REQ_(req,resp,Name,NAME) \
#define RADIO_REQ_RESP_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return RADIO_RESP_##NAME;
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_CALL_1_3(RADIO_REQ_)
RADIO_CALL_1_4(RADIO_REQ_)
#undef RADIO_REQ_
#define RADIO_REQ_RESP__(req,resp,Name,NAME,x) \
case RADIO_REQ_##NAME##x: return RADIO_RESP_##NAME##x;
RADIO_CALL_1_0(RADIO_REQ_RESP_)
RADIO_CALL_1_1(RADIO_REQ_RESP_)
RADIO_CALL_1_2(RADIO_REQ_RESP_)
RADIO_CALL_1_3(RADIO_REQ_RESP_)
RADIO_CALL_1_4_(RADIO_REQ_RESP__)
RADIO_CALL_1_5_(RADIO_REQ_RESP__)
#undef RADIO_REQ_RESP_
#undef RADIO_REQ_RESP__
case RADIO_REQ_SETUP_DATA_CALL_1_2:
return RADIO_RESP_SETUP_DATA_CALL;
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2:
return RADIO_RESP_DEACTIVATE_DATA_CALL;
case RADIO_REQ_START_NETWORK_SCAN_1_2:
return RADIO_RESP_START_NETWORK_SCAN;
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4:
return RADIO_RESP_SET_INITIAL_ATTACH_APN;
case RADIO_REQ_SET_DATA_PROFILE_1_4:
return RADIO_RESP_SET_DATA_PROFILE;
case RADIO_REQ_SET_INDICATION_FILTER_1_2:
return RADIO_RESP_SET_INDICATION_FILTER;
/*
* All these still need to be listed here to ensure a compilation
* warnings when something gets added to RADIO_REQ enum.
*/
case RADIO_REQ_SET_RESPONSE_FUNCTIONS:
case RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT:
case RADIO_REQ_START_NETWORK_SCAN_1_2:
case RADIO_REQ_SET_INDICATION_FILTER_1_2:
case RADIO_REQ_SETUP_DATA_CALL_1_2:
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2:
case RADIO_REQ_SETUP_DATA_CALL_1_4:
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4:
case RADIO_REQ_SET_DATA_PROFILE_1_4:
case RADIO_REQ_ANY:
break;
}
return RADIO_RESP_NONE;
}
/**
* And this is a version of radio_req_resp which takes IRadio interface
* version into account. This one is OK to use.
*/
RADIO_RESP
radio_req_resp2(
RADIO_REQ req,
RADIO_INTERFACE iface) /* Since 1.4.5 */
{
DBG("func:%s,line:%d,file:%s", __func__, __LINE__, __FILE__);
switch (req) {
/*
* Requests expecting a response from a previous version of the
* interface.
*/
case RADIO_REQ_SETUP_DATA_CALL_1_2:
return RADIO_RESP_SETUP_DATA_CALL;
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2:
return RADIO_RESP_DEACTIVATE_DATA_CALL;
case RADIO_REQ_START_NETWORK_SCAN_1_2:
return RADIO_RESP_START_NETWORK_SCAN;
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4:
return RADIO_RESP_SET_INITIAL_ATTACH_APN;
case RADIO_REQ_SET_DATA_PROFILE_1_4:
return RADIO_RESP_SET_DATA_PROFILE;
case RADIO_REQ_SET_INDICATION_FILTER_1_2:
/* case RADIO_REQ_SET_INDICATION_FILTER_1_5: */
return RADIO_RESP_SET_INDICATION_FILTER;
/*
* Requests which may receive a response from a higher version of
* the interface.
*/
/*
* getIccCardStatus
* getIccCardStatusResponse
* getIccCardStatusResponse_1_2
* getIccCardStatusResponse_1_4
* getIccCardStatusResponse_1_5
* ...
*/
case RADIO_REQ_GET_ICC_CARD_STATUS:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_ICC_CARD_STATUS;
case RADIO_INTERFACE_1_2:
case RADIO_INTERFACE_1_3:
return RADIO_RESP_GET_ICC_CARD_STATUS_1_2;
case RADIO_INTERFACE_1_4:
return RADIO_RESP_GET_ICC_CARD_STATUS_1_4;
case RADIO_INTERFACE_1_5:
return RADIO_RESP_GET_ICC_CARD_STATUS_1_5;
case RADIO_INTERFACE_NONE:
case RADIO_INTERFACE_COUNT:
break;
}
return RADIO_RESP_NONE;
/*
* getCellInfoList
* getCellInfoListResponse
* getCellInfoListResponse_1_2
* getCellInfoListResponse_1_4
* getCellInfoListResponse_1_5 <= the last one
* getCellInfoList_1_6
*/
case RADIO_REQ_GET_CELL_INFO_LIST:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_CELL_INFO_LIST;
case RADIO_INTERFACE_1_2:
case RADIO_INTERFACE_1_3:
return RADIO_RESP_GET_CELL_INFO_LIST_1_2;
case RADIO_INTERFACE_1_4:
return RADIO_RESP_GET_CELL_INFO_LIST_1_4;
default:
return RADIO_RESP_GET_CELL_INFO_LIST_1_5;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
/*
* getCurrentCalls{
* getCurrentCallsResponse
* getCurrentCallsResponse_1_2 <= the last one
* getCurrentCalls_1_6
*/
case RADIO_REQ_GET_CURRENT_CALLS:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_CURRENT_CALLS;
default: /* The last one */
return RADIO_RESP_GET_CURRENT_CALLS_1_2;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
/*
* getSignalStrength
* getSignalStrengthResponse
* getSignalStrengthResponse_1_2 <= the last one
* getSignalStrength_1_4
*/
case RADIO_REQ_GET_SIGNAL_STRENGTH:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_SIGNAL_STRENGTH;
default: /* The last one */
return RADIO_RESP_GET_SIGNAL_STRENGTH_1_2;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
/*
* getVoiceRegistrationState
* getVoiceRegistrationStateResponse
* getVoiceRegistrationStateResponse_1_2 <= the last one
* getVoiceRegistrationState_1_5
*/
case RADIO_REQ_GET_VOICE_REGISTRATION_STATE:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_VOICE_REGISTRATION_STATE;
default: /* The last one */
return RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
/*
* getDataRegistrationState
* getDataRegistrationStateResponse
* getDataRegistrationStateResponse_1_2
* getDataRegistrationStateResponse_1_4 <= the last one
* getDataRegistrationState_1_5
*/
case RADIO_REQ_GET_DATA_REGISTRATION_STATE:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
return RADIO_RESP_GET_DATA_REGISTRATION_STATE;
case RADIO_INTERFACE_1_2:
case RADIO_INTERFACE_1_3:
return RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2;
default: /* The last one */
return RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_4;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
/*
* getDataCallList
* getDataCallListResponse
* getDataCallListResponse_1_4
* getDataCallListResponse_1_5 <= the last one
* getDataCallList_1_6
*/
case RADIO_REQ_GET_DATA_CALL_LIST:
switch (iface) {
case RADIO_INTERFACE_1_0:
case RADIO_INTERFACE_1_1:
case RADIO_INTERFACE_1_2:
case RADIO_INTERFACE_1_3:
return RADIO_RESP_GET_DATA_CALL_LIST;
case RADIO_INTERFACE_1_4:
return RADIO_RESP_GET_DATA_CALL_LIST_1_4;
default: /* The last one */
return RADIO_RESP_GET_DATA_CALL_LIST_1_5;
case RADIO_INTERFACE_NONE:
break;
}
return RADIO_RESP_NONE;
default:
break;
}
/* Fallback */
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
return radio_req_resp(req);
G_GNUC_END_IGNORE_DEPRECATIONS
}
/*
* Local Variables:
* mode: C

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -34,83 +34,18 @@
* any official policies, either expressed or implied.
*/
#ifndef RADIO_CLIENT_PRIVATE_H
#define RADIO_CLIENT_PRIVATE_H
#ifndef RADIO_UTIL_PRIVATE_H
#define RADIO_UTIL_PRIVATE_H
#include "radio_types_p.h"
#include "radio_client.h"
#include <glib-object.h>
struct radio_client {
GObject object;
RadioInstance* instance;
};
void
radio_client_register_request(
RadioClient* client,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_client_unregister_request(
RadioClient* client,
RadioRequest* req)
RADIO_INTERNAL;
gboolean
radio_client_submit_request(
RadioClient* client,
RadioRequest* req)
RADIO_INTERNAL;
gboolean
radio_client_retry_request(
RadioClient* client,
RadioRequest* req)
RADIO_INTERNAL;
void
radio_client_request_dropped(
RadioRequest* req)
RADIO_INTERNAL;
#include "radio_util.h"
guint
radio_client_timeout_ms(
RadioClient* client,
RadioRequest* req)
radio_observer_priority_index(
RADIO_OBSERVER_PRIORITY priority)
RADIO_INTERNAL;
void
radio_client_reset_timeout(
RadioClient* client)
RADIO_INTERNAL;
void
radio_client_reset_timeout(
RadioClient* client)
RADIO_INTERNAL;
RADIO_BLOCK
radio_client_block_status(
RadioClient* client,
RadioRequestGroup* group)
RADIO_INTERNAL;
RADIO_BLOCK
radio_client_block(
RadioClient* client,
RadioRequestGroup* group)
RADIO_INTERNAL;
void
radio_client_unblock(
RadioClient* client,
RadioRequestGroup* group)
RADIO_INTERNAL;
#endif /* RADIO_CLIENT_PRIVATE_H */
#endif /* RADIO_UTIL_PRIVATE_H */
/*
* Local Variables:

View File

@@ -5,6 +5,7 @@
all:
%:
@$(MAKE) -C unit_client $*
@$(MAKE) -C unit_config $*
@$(MAKE) -C unit_instance $*
@$(MAKE) -C unit_registry $*
@$(MAKE) -C unit_util $*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2022 Jolla Ltd.
* Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -65,6 +65,7 @@ test_quit_later_n(
guint n);
#define TEST_TIMEOUT_SEC (20)
#define TEST_TIMEOUT_MS (1000*TEST_TIMEOUT_SEC)
/* Helper macros */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
@@ -142,6 +142,10 @@ GBinderLocalObject*
test_gbinder_remote_object_to_local(
GBinderRemoteObject* remote);
/* test_gbinder_client.c */
extern int test_gbinder_client_tx_fail_count;
/* test_gbinder_servicemanager.c */
GBinderRemoteObject*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -38,6 +38,8 @@
#include <gutil_log.h>
#include <stdlib.h>
typedef struct test_gbinder_client_tx {
GBinderClient* client;
guint32 code;
@@ -61,6 +63,8 @@ struct gbinder_client {
guint nr;
};
int test_gbinder_client_tx_fail_count = 0;
static
void
test_gbinder_client_free(
@@ -340,31 +344,38 @@ gbinder_client_transact(
GBinderRemoteObject* obj = self->remote;
if (!test_gbinder_remote_object_dead(obj)) {
GBinderLocalRequest* tmp = NULL;
if (!req) {
const TestGBinderClientIfaceRange* r =
test_gbinder_client_find_range(self, code);
if (r) {
req = tmp = test_gbinder_local_request_new(r->iface);
if (test_gbinder_client_tx_fail_count) {
if (test_gbinder_client_tx_fail_count > 0) {
test_gbinder_client_tx_fail_count--;
}
}
if (req) {
TestGBinderClientTx* tx = g_new0(TestGBinderClientTx, 1);
GDEBUG("Simulating transaction failure");
} else {
GBinderLocalRequest* tmp = NULL;
tx->client = gbinder_client_ref(self);
tx->code = code;
tx->flags = flags;
tx->req = gbinder_local_request_ref(req);
tx->reply = reply;
tx->destroy = destroy;
tx->user_data = user_data;
id = g_idle_add_full(G_PRIORITY_DEFAULT,
test_gbinder_client_tx_handle, tx,
test_gbinder_client_tx_destroy);
if (!req) {
const TestGBinderClientIfaceRange* r =
test_gbinder_client_find_range(self, code);
if (r) {
req = tmp = test_gbinder_local_request_new(r->iface);
}
}
if (req) {
TestGBinderClientTx* tx = g_new0(TestGBinderClientTx, 1);
tx->client = gbinder_client_ref(self);
tx->code = code;
tx->flags = flags;
tx->req = gbinder_local_request_ref(req);
tx->reply = reply;
tx->destroy = destroy;
tx->user_data = user_data;
id = g_idle_add_full(G_PRIORITY_DEFAULT,
test_gbinder_client_tx_handle, tx,
test_gbinder_client_tx_destroy);
}
gbinder_local_request_unref(tmp);
}
gbinder_local_request_unref(tmp);
} else {
GDEBUG("Refusing to perform transaction with a dead object");
}

View File

@@ -43,6 +43,7 @@ struct gbinder_local_object {
char** ifaces;
GBinderLocalTransactFunc txproc;
void* user_data;
GBINDER_STABILITY_LEVEL stability;
};
static const char hidl_base_interface[] = "android.hidl.base@1.0::IBase";
@@ -144,6 +145,16 @@ gbinder_local_object_drop(
}
}
void
gbinder_local_object_set_stability(
GBinderLocalObject* self,
GBINDER_STABILITY_LEVEL stability)
{
if (self) {
self->stability = stability;
}
}
/*
* Local Variables:
* mode: C

View File

@@ -249,6 +249,7 @@ test_gbinder_date_replace_int32(
gsize size = 0;
TestGBinderDataItem* item;
if (data->iface) size += strlen(data->iface);
for (item = data->items; item; item = item->next) {
if (size == offset) {
guint32 prev;
@@ -372,6 +373,24 @@ gbinder_reader_read_hidl_struct1(
return NULL;
}
const void*
gbinder_reader_read_parcelable(
GBinderReader* reader,
gsize* size)
{
TestGBinderReader* self = test_gbinder_reader_cast(reader);
TestGBinderDataItem* item = self->item;
if (item && item->type == DATA_TYPE_BUFFER) {
if (size) {
*size = item->data.blob.size;
}
self->item = item->next;
return item->data.blob.buf;
}
return NULL;
}
GBinderRemoteObject*
gbinder_reader_read_object(
GBinderReader* reader)

View File

@@ -5,6 +5,7 @@
TESTS="\
unit_client \
unit_config \
unit_instance \
unit_registry \
unit_util"

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -37,8 +37,8 @@
#include "test_common.h"
#include "test_gbinder.h"
#include "radio_client.h"
#include "radio_instance.h"
#include "radio_client_p.h"
#include "radio_request_p.h"
#include "radio_request_group_p.h"
#include "radio_util.h"
@@ -47,7 +47,7 @@
#include <gutil_log.h>
#define DEFAULT_INTERFACE RADIO_INTERFACE_1_0
#define DEV GBINDER_DEFAULT_BINDER
#define DEV GBINDER_DEFAULT_HWBINDER
static TestOpt test_opt;
@@ -390,6 +390,26 @@ test_simple_destroy_cb(
test_quit_later(test->loop);
}
static
void
test_simple_complete_ok_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("status %u", status);
g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
g_assert(!test->completed);
g_assert(!test->destroyed);
test->completed = TRUE;
}
static
void
test_simple_complete_fail_cb(
@@ -446,8 +466,6 @@ test_null(
radio_client_remove_handler(NULL, 0);
radio_client_remove_handler(NULL, 1);
radio_client_remove_handlers(NULL, NULL, 0);
radio_client_block(NULL, NULL);
radio_client_unblock(NULL, NULL);
g_assert(!radio_client_new(NULL));
g_assert(!radio_client_ref(NULL));
@@ -459,8 +477,6 @@ test_null(
g_assert(!radio_client_add_death_handler(NULL, NULL, NULL));
g_assert(!radio_client_add_connected_handler(NULL, NULL, NULL));
g_assert_cmpint(radio_client_interface(NULL), == ,RADIO_INTERFACE_NONE);
g_assert_cmpint(radio_client_block_status(NULL, NULL), == ,
RADIO_BLOCK_NONE);
radio_request_unref(NULL);
radio_request_drop(NULL);
@@ -475,6 +491,7 @@ test_null(
g_assert(!radio_request_ref(NULL));
g_assert(!radio_request_submit(NULL));
g_assert(!radio_request_retry(NULL));
g_assert(!radio_request_user_data(NULL));
radio_request_group_cancel(NULL);
radio_request_group_unref(NULL);
@@ -499,6 +516,7 @@ test_basic(
TestCommon test;
RadioRequest* req;
RadioClient* client = test_common_init(&test);
GBinderWriter args;
gboolean destroyed = FALSE;
g_assert_cmpstr(radio_client_slot(client), == ,test.radio->slot);
@@ -528,9 +546,10 @@ test_basic(
radio_request_drop(req); /* Matches radio_request_ref() above */
radio_request_drop(req); /* Releases the final ref */
/* Make sure destroy callback is invoked */
req = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL, NULL,
test_destroy_once, &destroyed);
/* Make sure destroy (but not completion) callback is invoked */
req = radio_request_new(client, RADIO_REQ_GET_MUTE, &args,
test_complete_not_reached, test_destroy_once, &destroyed);
g_assert(radio_request_user_data(req) == &destroyed);
radio_request_unref(req);
g_assert(destroyed);
@@ -728,13 +747,28 @@ test_resp_complete_cb(
{
TestSimple* test = user_data;
GDEBUG("resp %d", resp);
g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
g_assert_cmpint(resp, == ,RADIO_RESP_GET_MUTE);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
g_assert(!test->completed);
g_assert(!test->destroyed);
test->completed = TRUE;
g_assert_cmpint(test->completed, <= ,test->destroyed);
test->completed++;
GDEBUG("resp %d %d", resp, test->completed);
}
static
void
test_resp_destroy_cb(
gpointer user_data)
{
TestSimple* test = user_data;
test->destroyed++;
g_assert_cmpint(test->completed, >= ,test->destroyed);
GDEBUG("destroy %d", test->destroyed);
if (test->destroyed == 2) {
GDEBUG("done");
test_quit_later(test->loop);
}
}
static
@@ -749,30 +783,37 @@ test_resp(
TestSimple test;
RadioClient* client = test_simple_init(&test);
GBinderClient* resp_client = test.common.service.resp_client;
RadioRequest* req = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_resp_complete_cb, test_simple_destroy_cb, &test);
RadioRequest* req1 = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_resp_complete_cb, test_resp_destroy_cb, &test);
RadioRequest* req2 = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_resp_complete_cb, test_resp_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
radio_request_submit(req);
radio_request_submit(req); /* Second submit is ignored */
g_assert(req1);
g_assert(req2);
g_assert(req1->serial);
g_assert(req2->serial);
g_assert(radio_request_submit(req1));
g_assert(!radio_request_submit(req1)); /* Second time it fails */
radio_request_set_retry(req2, 0, -1); /* Won't actually be retried */
g_assert(radio_request_submit(req2));
test_common_connected(&test.common);
/* Ack the request*/
/* Ack the first one */
ack = gbinder_client_new_request2(resp_client,
RADIO_RESP_ACKNOWLEDGE_REQUEST);
gbinder_local_request_append_int32(ack, req->serial);
gbinder_local_request_append_int32(ack, req1->serial);
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp_client,
RADIO_RESP_ACKNOWLEDGE_REQUEST, ack), == ,GBINDER_STATUS_OK);
g_assert(req->acked);
g_assert(req1->acked);
/* Release our ref, the internal one will be dropped when req is done */
radio_request_unref(req);
/* Release our refs */
radio_request_unref(req1);
radio_request_unref(req2);
test_run(&test_opt, test.loop);
g_assert(test.completed);
g_assert(test.destroyed);
g_assert_cmpint(test.completed, == ,2);
g_assert_cmpint(test.destroyed, == ,test.completed);
/* This ack is invalid and will be ignored */
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp_client,
@@ -806,9 +847,9 @@ void
test_group(
void)
{
TestCommon test;
TestSimple test;
RadioRequest* req;
RadioClient* client = test_common_init(&test);
RadioClient* client = test_simple_init(&test);
RadioRequestGroup* group = radio_request_group_new(client);
RadioRequestGroup* group2;
gulong id;
@@ -816,7 +857,7 @@ test_group(
int blocked = 0;
g_assert(group);
test_common_connected(&test);
test_common_connected(&test.common);
/* Test ref/unref */
g_assert(radio_request_group_ref(group) == group);
@@ -853,17 +894,28 @@ test_group(
req = radio_request_new2(group, RADIO_REQ_GET_MUTE, NULL,
test_complete_not_reached, test_inc_cb, &destroyed);
g_assert(req);
radio_request_submit(req);
g_assert(radio_request_submit(req));
radio_request_unref(req);
req = radio_request_new2(group, RADIO_REQ_GET_MUTE, NULL,
test_complete_not_reached, test_inc_cb, &destroyed);
g_assert(req);
radio_request_submit(req);
g_assert(radio_request_submit(req));
radio_request_unref(req);
/* And cancel them all in one shot */
/* Create a request without a group */
req = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_simple_complete_ok_cb, test_simple_destroy_cb, &test);
/* It can't be submitted right away because client is owned by group */
GDEBUG("Submitting a standalone request");
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_QUEUED);
radio_request_unref(req);
/* Cancel the whole group in one shot */
g_assert(!destroyed);
GDEBUG("Cancelling group");
radio_request_group_cancel(group);
g_assert_cmpint(destroyed, == ,2);
@@ -876,10 +928,17 @@ test_group(
radio_request_unref(req);
g_assert_cmpint(destroyed, == ,3);
/* Cleanup */
/*
* Unblocking the group will allow the group-less request to get
* actually submitted, complete and quit the loop.
*/
GDEBUG("Unblocking");
radio_request_group_unblock(group);
test_run(&test_opt, test.loop);
/* Cleanup */
radio_request_group_unref(group);
test_common_cleanup(&test);
test_simple_cleanup(&test);
}
/*==========================================================================*
@@ -908,7 +967,7 @@ test_group2(
req = radio_request_new2(group, RADIO_REQ_GET_MUTE, NULL,
test_complete_not_reached, test_inc_cb, &destroyed);
g_assert(req);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
/* The group immediately becomes an owner because the pending
@@ -1033,7 +1092,7 @@ test_group3(
req = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_group3_complete_cb, test_group3_destroy_continue_cb, &test);
g_assert(req);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
radio_request_unref(req);
@@ -1069,19 +1128,19 @@ test_group3(
req3 = radio_request_new2(group3, RADIO_REQ_GET_MUTE, NULL,
test_group3_complete2_cb, test_group3_destroy_continue_cb, &test);
g_assert(req3);
radio_request_submit(req3);
g_assert(radio_request_submit(req3));
g_assert_cmpint(req3->state, == ,RADIO_REQUEST_STATE_QUEUED);
req2 = radio_request_new2(group2, RADIO_REQ_GET_MUTE, NULL,
test_group3_complete2_cb, test_group3_destroy_continue_cb, &test);
g_assert(req2);
radio_request_submit(req2);
g_assert(radio_request_submit(req2));
g_assert_cmpint(req2->state, == ,RADIO_REQUEST_STATE_QUEUED);
req1 = radio_request_new2(group1, RADIO_REQ_GET_MUTE, NULL,
test_group3_complete2_cb, test_group3_destroy_continue_cb, &test);
g_assert(req1);
radio_request_submit(req1);
g_assert(radio_request_submit(req1));
g_assert_cmpint(req1->state, == ,RADIO_REQUEST_STATE_QUEUED);
/* Wait for the first request to complete */
@@ -1201,7 +1260,7 @@ test_block(
g_assert(req);
g_assert(req->serial);
radio_request_set_blocking(req, TRUE);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
radio_request_unref(req);
@@ -1210,7 +1269,7 @@ test_block(
test_block_complete_cb, test_block_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_QUEUED);
radio_request_unref(req);
@@ -1218,7 +1277,7 @@ test_block(
test_block_complete_cb, test_block_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_QUEUED);
radio_request_unref(req);
@@ -1309,7 +1368,7 @@ test_block_timeout(
g_assert(req->serial);
radio_request_set_blocking(req, TRUE);
radio_request_set_timeout(req, 100);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
radio_request_unref(req);
@@ -1318,7 +1377,106 @@ test_block_timeout(
test_block_timeout_complete2_cb, test_block_timeout_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
radio_request_submit(req);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_QUEUED);
radio_request_unref(req);
/* And wait for both request to get destroyed */
test_run(&test_opt, test.loop);
g_assert_cmpint(test.completed, == ,2);
g_assert_cmpint(test.destroyed, == ,2);
/* Cleanup */
test_simple_cleanup(&test);
}
/*==========================================================================*
* block_retry
*==========================================================================*/
static
void
test_block_retry_complete1_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
g_assert_cmpint(resp, == ,ERROR_RESP);
g_assert_cmpint(error, == ,RADIO_ERROR_GENERIC_FAILURE);
g_assert_cmpint(req->retry_count, == ,req->max_retries);
g_assert(req->blocking);
g_assert(!test->completed);
test->completed++;
GDEBUG("block timed out");
}
static
void
test_block_retry_complete2_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
g_assert_cmpint(resp, == ,RADIO_RESP_GET_MUTE);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
g_assert_cmpint(test->completed, == ,1);
test->completed++;
GDEBUG("second request completed");
test_quit_later(test->loop);
}
static
void
test_block_retry_destroy_cb(
gpointer user_data)
{
TestSimple* test = user_data;
test->destroyed++;
GDEBUG("destruction %u", test->destroyed);
g_assert_cmpint(test->completed, >= ,test->destroyed);
}
static
void
test_block_retry(
void)
{
TestSimple test;
RadioClient* client = test_simple_init(&test);
RadioRequest* req = radio_request_new(client, ERROR_REQ, NULL,
test_block_retry_complete1_cb, test_block_retry_destroy_cb, &test);
test_common_connected(&test.common);
/* Make it blocking and retriable */
g_assert(req);
g_assert(req->serial);
radio_request_set_blocking(req, TRUE);
radio_request_set_retry(req, 10, 5);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
radio_request_unref(req);
/* And non-blocking */
req = radio_request_new(client, RADIO_REQ_GET_MUTE, NULL,
test_block_retry_complete2_cb, test_block_retry_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_QUEUED);
radio_request_unref(req);
@@ -1374,8 +1532,8 @@ test_retry(
test_common_connected(&test.common);
radio_request_set_retry_func(req, NULL); /* Use the default */
radio_request_set_retry(req, 0, TEST_RETRY_COUNT);
radio_request_submit(req);
radio_request_set_retry(req, 10, TEST_RETRY_COUNT);
g_assert(radio_request_submit(req));
radio_request_unref(req);
test_run(&test_opt, test.loop);
@@ -1401,8 +1559,8 @@ test_retry2(
test_common_connected(&test.common);
/* Long timeout (longer than the test timeout) */
radio_request_set_timeout(req, TEST_TIMEOUT_SEC * 2000);
radio_request_set_retry(req, 0, TEST_RETRY_COUNT);
radio_request_set_timeout(req, TEST_TIMEOUT_MS * 2);
radio_request_set_retry(req, 10, TEST_RETRY_COUNT);
g_assert(radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_PENDING);
@@ -1461,6 +1619,41 @@ test_fail(
test_common_cleanup(&test);
}
/*==========================================================================*
* fail_tx
*==========================================================================*/
static
void
test_fail_tx(
void)
{
TestCommon test;
RadioRequest* req;
gboolean destroyed = FALSE;
test_common_init(&test);
test_common_connected(&test);
req = radio_request_new(test.client, RADIO_REQ_GET_MUTE, NULL,
test_complete_not_reached, test_destroy_once, &destroyed);
g_assert(req);
g_assert(req->serial);
/* Fail one transaction */
test_gbinder_client_tx_fail_count = 1;
/* Request switches in the FAILED state */
g_assert(!radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_FAILED);
g_assert(!destroyed);
radio_request_drop(req);
g_assert(destroyed);
test_common_cleanup(&test);
}
/*==========================================================================*
* err
*==========================================================================*/
@@ -1481,7 +1674,7 @@ test_err(
/* Just setting retry function has no effect until non-zero number of
* retries is set, too. */
radio_request_set_retry_func(req, test_retry_not_reached);
radio_request_submit(req);
g_assert(radio_request_submit(req));
radio_request_unref(req);
test_common_connected(&test.common);
@@ -1560,8 +1753,8 @@ test_timeout(
g_assert(req);
g_assert(req->serial);
radio_request_set_timeout(req, 2000 * TEST_TIMEOUT_SEC);
radio_request_submit(req);
radio_request_set_timeout(req, 2 * TEST_TIMEOUT_MS);
g_assert(radio_request_submit(req));
radio_request_set_timeout(req, 100); /* Resets the timeout */
radio_request_set_timeout(req, 100); /* Has no effect */
radio_request_unref(req);
@@ -1595,7 +1788,7 @@ test_timeout2(
g_assert(req);
g_assert(req->serial);
radio_request_set_timeout(req, 2000 * TEST_TIMEOUT_SEC);
radio_request_submit(req);
g_assert(radio_request_submit(req));
radio_request_set_timeout(req, 100); /* Resets the timeout */
radio_request_set_timeout(req, 100); /* Has no effect */
radio_request_unref(req);
@@ -1614,10 +1807,81 @@ test_timeout2(
* timeout3
*==========================================================================*/
static
void
test_timeout3_complete_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("status %u", status);
g_assert_cmpuint(req->retry_count, == ,1);
g_assert_cmpint(status, == ,RADIO_TX_STATUS_TIMEOUT);
g_assert_cmpint(resp, == ,RADIO_RESP_NONE);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
g_assert(!test->completed);
g_assert(!test->destroyed);
test->completed = TRUE;
test_quit_later(test->loop);
}
static
void
test_timeout3_destroy_cb(
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("done");
g_assert(test->completed);
g_assert(!test->destroyed);
test->destroyed = TRUE;
}
static
void
test_timeout3(
void)
{
TestSimple test;
RadioClient* client = test_simple_init(&test);
RadioRequest* req = radio_request_new(client, ERROR_REQ, NULL,
test_timeout3_complete_cb, test_timeout3_destroy_cb, &test);
g_assert(req);
g_assert(req->serial);
radio_request_set_retry(req, TEST_TIMEOUT_MS, 2);
radio_request_set_timeout(req, 2 * TEST_TIMEOUT_MS);
g_assert(radio_request_submit(req));
radio_request_set_timeout(req, 100); /* Resets the timeout */
radio_request_set_timeout(req, 100); /* Has no effect */
/* And expect the request to fail */
test_common_connected(&test.common);
test_run(&test_opt, test.loop);
g_assert(test.completed);
g_assert(!test.destroyed);
radio_request_unref(req);
g_assert(test.destroyed);
/* Cleanup */
test_simple_cleanup(&test);
}
/*==========================================================================*
* timeout4
*==========================================================================*/
static
void
test_timeout4(
void)
{
TestSimple test;
RadioRequest* req1;
@@ -1634,15 +1898,15 @@ test_timeout3(
test_complete_not_reached, NULL, NULL);
g_assert(req1);
g_assert(req1->serial);
radio_request_set_timeout(req1, TEST_TIMEOUT_SEC * 2000);
radio_request_submit(req1);
radio_request_set_timeout(req1, TEST_TIMEOUT_MS * 2);
g_assert(radio_request_submit(req1));
/* And this one will time out quickly */
req2 = radio_request_new(client, IGNORE_REQ, NULL,
test_timeout_complete_cb, test_simple_destroy_cb, &test);
g_assert(req2);
g_assert(req2->serial);
radio_request_submit(req2);
g_assert(radio_request_submit(req2));
radio_request_unref(req2);
radio_client_set_default_timeout(client, 100);
radio_client_set_default_timeout(client, 100); /* Has no effect */
@@ -1680,7 +1944,7 @@ test_destroy(
g_assert(req);
g_assert(req->serial);
radio_request_submit(req);
g_assert(radio_request_submit(req));
radio_request_unref(req);
/* Destroy the client without waiting for request to complete */
@@ -1816,14 +2080,17 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_("group3"), test_group3);
g_test_add_func(TEST_("block"), test_block);
g_test_add_func(TEST_("block_timeout"), test_block_timeout);
g_test_add_func(TEST_("block_retry"), test_block_retry);
g_test_add_func(TEST_("retry"), test_retry);
g_test_add_func(TEST_("retry2"), test_retry2);
g_test_add_func(TEST_("fail"), test_fail);
g_test_add_func(TEST_("fail_tx"), test_fail_tx);
g_test_add_func(TEST_("err"), test_err);
g_test_add_func(TEST_("err2"), test_err2);
g_test_add_func(TEST_("timeout"), test_timeout);
g_test_add_func(TEST_("timeout2"), test_timeout2);
g_test_add_func(TEST_("timeout3"), test_timeout3);
g_test_add_func(TEST_("timeout4"), test_timeout4);
g_test_add_func(TEST_("death"), test_death);
g_test_add_func(TEST_("destroy"), test_destroy);
test_init(&test_opt, argc, argv);

View File

@@ -0,0 +1,5 @@
# -*- Mode: makefile-gmake -*-
EXE = unit_config
include ../common/Makefile

View File

@@ -0,0 +1,918 @@
/*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#include "test_common.h"
#include "test_gbinder.h"
#include "radio_config.h"
#include "radio_request_p.h"
#include <gutil_strv.h>
#include <gutil_log.h>
#define DEV GBINDER_DEFAULT_HWBINDER
static TestOpt test_opt;
static const GBinderClientIfaceInfo radio_config_ind_iface_info[] = {
{RADIO_CONFIG_INDICATION_1_0, RADIO_CONFIG_1_0_IND_LAST }
};
static const GBinderClientIfaceInfo radio_config_resp_iface_info[] = {
{RADIO_CONFIG_RESPONSE_1_2, RADIO_CONFIG_1_2_RESP_LAST },
{RADIO_CONFIG_RESPONSE_1_1, RADIO_CONFIG_1_1_RESP_LAST },
{RADIO_CONFIG_RESPONSE_1_0, RADIO_CONFIG_1_0_RESP_LAST }
};
static const char* const radio_config_req_ifaces[] = {
RADIO_CONFIG_1_2,
RADIO_CONFIG_1_1,
RADIO_CONFIG_1_0,
NULL
};
static const char* const radio_config_fqnames[] = {
RADIO_CONFIG_1_0_FQNAME,
RADIO_CONFIG_1_1_FQNAME,
RADIO_CONFIG_1_2_FQNAME
};
static
void
test_complete_not_reached(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_CONFIG_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
g_assert_not_reached();
}
static
void
test_destroy_once(
gpointer user_data)
{
gboolean* destroyed = user_data;
g_assert(!*destroyed);
*destroyed = TRUE;
}
static
void
test_ind_not_reached(
RadioConfig* config,
RADIO_CONFIG_IND code,
const GBinderReader* args,
gpointer user_data)
{
g_assert_not_reached();
}
static
void
test_inc_cb(
gpointer user_data)
{
(*((int*)user_data))++;
}
static
void
test_config_inc_cb(
RadioConfig* config,
gpointer user_data)
{
(*((int*)user_data))++;
}
static
RADIO_CONFIG_RESP
test_config_req_resp(
RADIO_CONFIG_REQ req)
{
switch (req) {
#define REQ_RESP_(req,resp,Name,NAME) \
case RADIO_CONFIG_REQ_##NAME: return RADIO_CONFIG_RESP_##NAME;
RADIO_CONFIG_CALL_1_0(REQ_RESP_)
RADIO_CONFIG_CALL_1_1(REQ_RESP_)
#undef REQ_RESP_
case RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS:
return RADIO_CONFIG_RESP_NONE;
case RADIO_CONFIG_REQ_ANY:
break;
}
g_assert_not_reached();
return RADIO_CONFIG_RESP_NONE;
}
/*==========================================================================*
* Test IRadioConfig service
*==========================================================================*/
typedef struct test_config_service {
GBinderLocalObject* obj;
GBinderClient* resp_client;
GBinderClient* ind_client;
GHashTable* req_count;
} TestConfigService;
#define FAIL_REQ RADIO_CONFIG_REQ_GET_PHONE_CAPABILITY
#define ERROR_REQ RADIO_CONFIG_REQ_SET_SIM_SLOTS_MAPPING
#define ERROR_RESP RADIO_CONFIG_RESP_SET_SIM_SLOTS_MAPPING
#define IGNORE_REQ RADIO_CONFIG_REQ_SET_MODEMS_CONFIG
static
int
test_config_service_req_count(
TestConfigService* service,
RADIO_CONFIG_REQ req)
{
return GPOINTER_TO_INT(g_hash_table_lookup(service->req_count,
GINT_TO_POINTER(req)));
}
static
GBinderLocalReply*
test_config_service_txproc(
GBinderLocalObject* obj,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status,
void* user_data)
{
TestConfigService* service = user_data;
const char* iface = gbinder_remote_request_interface(req);
if (gutil_strv_contains((const GStrV*)radio_config_req_ifaces, iface)) {
const int count = test_config_service_req_count(service, code) + 1;
GBinderReader reader;
GDEBUG("%s %s %d", iface, radio_config_req_name(NULL, code), count);
g_hash_table_insert(service->req_count, GINT_TO_POINTER(code),
GINT_TO_POINTER(count));
gbinder_remote_request_init_reader(req, &reader);
if (code == RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS) {
GBinderRemoteObject* resp_obj = gbinder_reader_read_object(&reader);
GBinderRemoteObject* ind_obj = gbinder_reader_read_object(&reader);
g_assert(resp_obj);
g_assert(ind_obj);
gbinder_client_unref(service->resp_client);
gbinder_client_unref(service->ind_client);
service->resp_client = gbinder_client_new2(resp_obj,
TEST_ARRAY_AND_COUNT(radio_config_resp_iface_info));
service->ind_client = gbinder_client_new2(ind_obj,
TEST_ARRAY_AND_COUNT(radio_config_ind_iface_info));
gbinder_remote_object_unref(resp_obj);
gbinder_remote_object_unref(ind_obj);
} else if (code == FAIL_REQ) {
GDEBUG("failing request transaction");
*status = GBINDER_STATUS_FAILED;
return NULL;
} else if (code == IGNORE_REQ) {
GDEBUG("ignoring request transaction");
} else {
RadioResponseInfo info;
GBinderWriter writer;
RADIO_CONFIG_RESP resp_code = test_config_req_resp(code);
GBinderLocalRequest* resp = gbinder_client_new_request2
(service->resp_client, resp_code);
memset(&info, 0, sizeof(info));
info.type = RADIO_RESP_SOLICITED;
info.error = (code == ERROR_REQ) ?
RADIO_ERROR_GENERIC_FAILURE :
RADIO_ERROR_NONE;
g_assert(gbinder_reader_read_uint32(&reader, &info.serial));
GDEBUG("serial %08x", info.serial);
g_assert(resp);
gbinder_local_request_init_writer(resp, &writer);
gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
switch (code) {
case RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM:
g_assert(gbinder_client_transact(service->resp_client,
resp_code, GBINDER_TX_FLAG_ONEWAY, resp, NULL, NULL, NULL));
break;
default:
/* No expecting anything else */
g_assert_not_reached();
break;
}
gbinder_local_request_unref(resp);
}
*status = GBINDER_STATUS_OK;
return NULL;
} else {
GDEBUG("%s %u", iface, code);
*status = GBINDER_STATUS_FAILED;
return NULL;
}
}
static
void
test_config_service_init(
TestConfigService* service)
{
memset(service, 0, sizeof(*service));
service->obj = test_gbinder_local_object_new(NULL,
test_config_service_txproc, service);
service->req_count = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static
void
test_config_service_cleanup(
TestConfigService* service)
{
g_hash_table_destroy(service->req_count);
gbinder_client_unref(service->resp_client);
gbinder_client_unref(service->ind_client);
gbinder_local_object_unref(service->obj);
memset(service, 0, sizeof(*service));
}
/*==========================================================================*
* Common setup for all tests
*==========================================================================*/
typedef struct test_common {
TestConfigService service;
GBinderServiceManager* sm;
GBinderRemoteObject* remote[RADIO_CONFIG_INTERFACE_COUNT];
RadioConfig* client;
} TestCommon;
static
RadioConfig*
test_common_init(
TestCommon* test,
RADIO_CONFIG_INTERFACE version)
{
RADIO_CONFIG_INTERFACE v;
memset(test, 0, sizeof(*test));
test->sm = gbinder_servicemanager_new(DEV);
test_config_service_init(&test->service);
for (v = RADIO_CONFIG_INTERFACE_1_0; v <= version; v++) {
test->remote[v] = test_gbinder_servicemanager_new_service(test->sm,
radio_config_fqnames[v], test->service.obj);
}
test->client = radio_config_new();
g_assert(test->client);
return test->client;
}
static
void
test_common_cleanup(
TestCommon* test)
{
int i;
radio_config_unref(test->client);
test_config_service_cleanup(&test->service);
for (i = 0; i < G_N_ELEMENTS(test->remote); i++) {
gbinder_remote_object_unref(test->remote[i]);
}
gbinder_servicemanager_unref(test->sm);
}
/*==========================================================================*
* Another common setup
*==========================================================================*/
typedef struct test_simple_data {
TestCommon common;
GMainLoop* loop;
int completed; /* Typically used as a boolean */
int destroyed; /* Typically used as a boolean */
} TestSimple;
static
RadioConfig*
test_simple_init(
TestSimple* test)
{
memset(test, 0, sizeof(*test));
test->loop = g_main_loop_new(NULL, FALSE);
return test_common_init(&test->common, RADIO_CONFIG_INTERFACE_1_1);
}
static
void
test_simple_cleanup(
TestSimple* test)
{
g_main_loop_unref(test->loop);
test_common_cleanup(&test->common);
}
static
void
test_simple_destroy_cb(
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("done");
g_assert(test->completed);
g_assert(!test->destroyed);
test->destroyed = TRUE;
test_quit_later(test->loop);
}
/*==========================================================================*
* null
*==========================================================================*/
static
void
test_null(
void)
{
g_assert(!radio_config_ref(NULL));
g_assert(radio_config_dead(NULL));
g_assert_cmpint(radio_config_interface(NULL),==,RADIO_CONFIG_INTERFACE_NONE);
g_assert(!radio_config_rpc_header_size(NULL, RADIO_CONFIG_REQ_NONE));
g_assert(!radio_config_req_name(NULL, RADIO_CONFIG_REQ_NONE));
g_assert(!radio_config_resp_name(NULL, RADIO_CONFIG_RESP_NONE));
g_assert(!radio_config_ind_name(NULL, RADIO_CONFIG_IND_NONE));
g_assert(!radio_config_add_death_handler(NULL, NULL, NULL));
g_assert(!radio_config_add_request_observer(NULL,
RADIO_CONFIG_REQ_ANY, NULL, NULL));
g_assert(!radio_config_add_request_observer_with_priority(NULL,
RADIO_CONFIG_REQ_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
radio_config_unref(NULL);
g_assert(!radio_config_add_response_observer(NULL,
RADIO_CONFIG_RESP_ANY, NULL, NULL));
g_assert(!radio_config_add_response_observer_with_priority(NULL,
RADIO_CONFIG_RESP_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
g_assert(!radio_config_add_indication_observer(NULL,
RADIO_CONFIG_IND_ANY, NULL, NULL));
g_assert(!radio_config_add_indication_observer_with_priority(NULL,
RADIO_CONFIG_IND_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
g_assert(!radio_config_request_new(NULL, ERROR_REQ, NULL, NULL, NULL, NULL));
radio_config_unref(NULL);
radio_config_remove_handler(NULL, 0);
radio_config_remove_handlers(NULL, NULL, 0);
}
/*==========================================================================*
* name
*==========================================================================*/
static
void
test_name(
void)
{
TestCommon test;
RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_1);
g_assert_cmpstr(radio_config_req_name(client,
RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS), == ,
"setResponseFunctions");
g_assert_cmpstr(radio_config_req_name(client,
RADIO_CONFIG_REQ_GET_SIM_SLOTS_STATUS), == ,
"getSimSlotsStatus");
g_assert_cmpstr(radio_config_req_name(client,
RADIO_CONFIG_REQ_GET_PHONE_CAPABILITY), == ,
"getPhoneCapability");
g_assert_cmpstr(radio_config_req_name(client,
(RADIO_CONFIG_REQ)123), == ,
"123");
g_assert_cmpstr(radio_config_resp_name(client,
RADIO_CONFIG_RESP_GET_SIM_SLOTS_STATUS), == ,
"getSimSlotsStatusResponse");
g_assert_cmpstr(radio_config_resp_name(client,
RADIO_CONFIG_RESP_GET_PHONE_CAPABILITY), == ,
"getPhoneCapabilityResponse");
g_assert_cmpstr(radio_config_resp_name(client,
(RADIO_CONFIG_RESP)1234), == ,
"1234");
g_assert_cmpstr(radio_config_ind_name(client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED), == ,
"simSlotsStatusChanged");
g_assert_cmpstr(radio_config_ind_name(client,
(RADIO_CONFIG_IND)12345), == ,
"12345");
test_common_cleanup(&test);
}
/*==========================================================================*
* none
*==========================================================================*/
static
void
test_none(
void)
{
/* No service => no client */
g_assert(!radio_config_new());
}
/*==========================================================================*
* basic
*==========================================================================*/
static
void
test_basic(
void)
{
TestCommon test;
RADIO_CONFIG_INTERFACE version = RADIO_CONFIG_INTERFACE_1_0;
RadioConfig* client = test_common_init(&test, version);
RadioRequest* req;
int destroyed = 0;
g_assert(!radio_config_dead(client));
g_assert(radio_config_rpc_header_size(client,
RADIO_CONFIG_REQ_GET_SIM_SLOTS_STATUS));
g_assert_cmpint(radio_config_interface(client), == ,version);
g_assert(radio_config_ref(client) == client);
radio_config_unref(client);
/* Instances are reused */
g_assert(radio_config_new() == client);
radio_config_unref(client);
g_assert(radio_config_new_with_version(version) == client);
radio_config_unref(client);
g_assert(radio_config_new_with_version(RADIO_CONFIG_INTERFACE_COUNT) ==
client);
radio_config_unref(client);
/* Adding NULL observer is a nop */
g_assert(!radio_config_add_death_handler(client, NULL, NULL));
g_assert(!radio_config_add_request_observer(client,
RADIO_CONFIG_REQ_ANY, NULL, NULL));
g_assert(!radio_config_add_response_observer(client,
RADIO_CONFIG_RESP_ANY, NULL, NULL));
g_assert(!radio_config_add_indication_observer(client,
RADIO_CONFIG_IND_ANY, NULL, NULL));
/* Zero handler id is tolerated */
radio_config_remove_handler(client, 0);
/* Create and destroy the request */
req = radio_config_request_new(client, RADIO_CONFIG_REQ_GET_MODEMS_CONFIG,
NULL, NULL, test_inc_cb, &destroyed);
g_assert(req);
radio_request_unref(req);
g_assert(destroyed);
test_common_cleanup(&test);
}
/*==========================================================================*
* ind
*==========================================================================*/
typedef struct test_ind_data {
TestCommon common;
GMainLoop* loop;
RADIO_CONFIG_IND ind;
} TestInd;
static
void
test_ind_cb(
RadioConfig* config,
RADIO_CONFIG_IND code,
const GBinderReader* args,
gpointer user_data)
{
TestInd* test = user_data;
/* This one is invoked first */
GDEBUG("first indication %d", code);
g_assert_cmpint(code, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
g_assert_cmpint(test->ind, == ,RADIO_CONFIG_IND_NONE);
test->ind = code;
}
static
void
test_ind_cb2(
RadioConfig* config,
RADIO_CONFIG_IND code,
const GBinderReader* args,
gpointer user_data)
{
TestInd* test = user_data;
/* This one is invoked second */
GDEBUG("second indication %d", code);
g_assert_cmpint(test->ind, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
g_assert_cmpint(code, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
test_quit_later(test->loop);
}
static
void
test_ind(
void)
{
GBinderLocalRequest* req;
GBinderClient* ind_client;
RadioConfig* client;
TestInd test;
gulong id[2];
memset(&test, 0, sizeof(test));
test.loop = g_main_loop_new(NULL, FALSE);
client = test_common_init(&test.common, RADIO_CONFIG_INTERFACE_1_1);
ind_client = test.common.service.ind_client;
/* Register and unregister one listener */
id[0] = radio_config_add_indication_observer(client, RADIO_CONFIG_IND_ANY,
test_ind_not_reached, NULL);
radio_config_remove_handler(client, id[0]);
/* Register actual listeners */
id[0] = radio_config_add_indication_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_HIGHEST,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED,
test_ind_cb, &test);
id[1] = radio_config_add_indication_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_DEFAULT,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED,
test_ind_cb2, &test);
/* This one will be ignored because type is missing */
req = gbinder_client_new_request2(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
g_assert_cmpint(gbinder_client_transact(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
req, NULL, NULL, NULL), != ,0);
gbinder_local_request_unref(req);
/* This one will be ignored because RADIO_IND_ACK_EXP is not expected */
req = gbinder_client_new_request2(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
gbinder_local_request_append_int32(req, RADIO_IND_ACK_EXP);
g_assert_cmpint(gbinder_client_transact(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
req, NULL, NULL, NULL), != ,0);
gbinder_local_request_unref(req);
/* And this one will be handled */
req = gbinder_client_new_request2(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
gbinder_local_request_append_int32(req, RADIO_IND_UNSOLICITED);
/*
* RadioIndicationType should be followed by vec<SimSlotStatus> but
* that's not required for the purposes of this unit test.
*/
g_assert_cmpint(gbinder_client_transact(ind_client,
RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
req, NULL, NULL, NULL), != ,0);
gbinder_local_request_unref(req);
/* And wait for test_ind_cb2 to terminate the loop */
test_run(&test_opt, test.loop);
g_assert_cmpint(test.ind, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
/* Cleanup */
radio_config_remove_all_handlers(client, id);
g_main_loop_unref(test.loop);
test_common_cleanup(&test.common);
}
/*==========================================================================*
* resp
*==========================================================================*/
static
void
test_resp_observe_req1(
RadioConfig* config,
RADIO_CONFIG_REQ code,
GBinderLocalRequest* args,
gpointer user_data)
{
int* observed = user_data;
GDEBUG("high prio observed req %d", code);
g_assert(!*observed);
*observed = -((int)code);
}
static
void
test_resp_observe_req2(
RadioConfig* config,
RADIO_CONFIG_REQ code,
GBinderLocalRequest* args,
gpointer user_data)
{
int* observed = user_data;
GDEBUG("low prio observed req %d", code);
g_assert_cmpint(*observed, == ,-((int)code));
*observed = code;
}
static
void
test_resp_observe_resp1(
RadioConfig* config,
RADIO_CONFIG_RESP code,
const RadioResponseInfo* info,
const GBinderReader* args,
gpointer user_data)
{
int* observed = user_data;
GDEBUG("high prio observed resp %d", code);
g_assert(!*observed);
*observed = -((int)code);
}
static
void
test_resp_observe_resp2(
RadioConfig* config,
RADIO_CONFIG_RESP code,
const RadioResponseInfo* info,
const GBinderReader* args,
gpointer user_data)
{
int* observed = user_data;
GDEBUG("low prio observed resp %d", code);
g_assert_cmpint(*observed, == ,-((int)code));
*observed = code;
}
static
void
test_resp_complete_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_CONFIG_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("resp %d", resp);
g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
g_assert_cmpint(resp, == ,RADIO_CONFIG_RESP_SET_PREFERRED_DATA_MODEM);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
g_assert(!test->completed);
g_assert(!test->destroyed);
test->completed = TRUE;
}
static
void
test_resp(
void)
{
TestSimple test;
RadioConfig* client = test_simple_init(&test);
RadioRequest* req = radio_config_request_new(client,
RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM, NULL,
test_resp_complete_cb, test_simple_destroy_cb, &test);
int observed_req = 0, observed_resp = 0;
gulong id[4];
id[0] = radio_config_add_request_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_HIGHEST, RADIO_CONFIG_REQ_ANY,
test_resp_observe_req1, &observed_req);
id[1] = radio_config_add_request_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_LOWEST, RADIO_CONFIG_REQ_ANY,
test_resp_observe_req2, &observed_req);
id[2] = radio_config_add_response_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_HIGHEST, RADIO_CONFIG_RESP_ANY,
test_resp_observe_resp1, &observed_resp);
id[3] = radio_config_add_response_observer_with_priority(client,
RADIO_OBSERVER_PRIORITY_LOWEST, RADIO_CONFIG_RESP_ANY,
test_resp_observe_resp2, &observed_resp);
g_assert(radio_request_submit(req));
radio_request_unref(req);
test_run(&test_opt, test.loop);
g_assert(test.completed);
g_assert(test.destroyed);
g_assert_cmpint(observed_req,==,RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM);
g_assert_cmpint(observed_resp,==,RADIO_CONFIG_RESP_SET_PREFERRED_DATA_MODEM);
/* Cleanup */
radio_config_remove_all_handlers(client, id);
test_simple_cleanup(&test);
}
/*==========================================================================*
* cancel
*==========================================================================*/
static
void
test_cancel(
void)
{
TestCommon test;
gboolean destroyed = FALSE;
RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_0);
RadioRequest* req = radio_config_request_new(client,
RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
test_complete_not_reached, test_destroy_once, &destroyed);
g_assert(radio_request_submit(req));
radio_request_cancel(req);
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_CANCELLED);
radio_request_unref(req);
g_assert(destroyed);
test_common_cleanup(&test);
}
/*==========================================================================*
* fail_tx
*==========================================================================*/
static
void
test_fail_tx(
void)
{
TestCommon test;
gboolean destroyed = FALSE;
RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_0);
RadioRequest* req = radio_config_request_new(client,
RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
test_complete_not_reached, test_destroy_once, &destroyed);
g_assert(req);
g_assert(req->serial);
/* Fail one transaction */
test_gbinder_client_tx_fail_count = 1;
/* Request switches in the FAILED state */
g_assert(req);
g_assert(!radio_request_submit(req));
g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_FAILED);
g_assert(!destroyed);
radio_request_drop(req);
g_assert(destroyed);
test_common_cleanup(&test);
}
/*==========================================================================*
* death
*==========================================================================*/
static
void
test_death_complete_cb(
RadioRequest* req,
RADIO_TX_STATUS status,
RADIO_CONFIG_RESP resp,
RADIO_ERROR error,
const GBinderReader* reader,
gpointer user_data)
{
TestSimple* test = user_data;
GDEBUG("status %u", status);
g_assert_cmpint(status, == ,RADIO_TX_STATUS_FAILED);
g_assert_cmpint(resp, == ,RADIO_CONFIG_RESP_NONE);
g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
test->completed++;
}
static
void
test_death_destroy_cb(
gpointer user_data)
{
TestSimple* test = user_data;
test->destroyed++;
GDEBUG("done");
g_assert_cmpint(test->completed, == ,test->destroyed);
test_quit_later(test->loop);
}
static
void
test_death(
void)
{
TestSimple test;
RadioConfig* client = test_simple_init(&test);
RadioRequest* req = radio_config_request_new(client,
RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
test_death_complete_cb, test_death_destroy_cb, &test);
RADIO_CONFIG_INTERFACE v;
int death_count = 0;
gulong id = radio_config_add_death_handler(client, test_config_inc_cb,
&death_count);
g_assert(radio_request_submit(req));
radio_request_unref(req);
/* Kill the remote objects */
g_assert(!radio_config_dead(client));
for (v = RADIO_CONFIG_INTERFACE_1_0;
v <= radio_config_interface(client); v++) {
test_gbinder_remote_object_kill(test.common.remote[v]);
}
g_assert(radio_config_dead(client));
g_assert_cmpint(death_count, == ,1);
/* Now expect the request to fail */
test_run(&test_opt, test.loop);
g_assert(test.completed);
g_assert(test.destroyed);
/* Cleanup */
radio_config_remove_handler(client, id);
test_simple_cleanup(&test);
}
/*==========================================================================*
* Common
*==========================================================================*/
#define TEST_PREFIX "/config/"
#define TEST_(t) TEST_PREFIX t
int main(int argc, char* argv[])
{
g_test_init(&argc, &argv, NULL);
g_test_add_func(TEST_("null"), test_null);
g_test_add_func(TEST_("name"), test_name);
g_test_add_func(TEST_("none"), test_none);
g_test_add_func(TEST_("basic"), test_basic);
g_test_add_func(TEST_("ind"), test_ind);
g_test_add_func(TEST_("resp"), test_resp);
g_test_add_func(TEST_("cancel"), test_cancel);
g_test_add_func(TEST_("fail_tx"), test_fail_tx);
g_test_add_func(TEST_("death"), test_death);
test_init(&test_opt, argc, argv);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2021-2022 Jolla Ltd.
* Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -422,7 +422,7 @@ test_connected(
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
TestConnected test;
ulong id[4];
gulong id[4];
memset(&test, 0, sizeof(test));
@@ -526,7 +526,7 @@ test_ind(
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
int code[2];
ulong id[2];
gulong id[2];
/* Register the service to create an instance */
test_service_init(&service);

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -66,6 +66,12 @@ test_req_name(
"setSystemSelectionChannels");
g_assert_cmpstr(radio_req_name(RADIO_REQ_EMERGENCY_DIAL),==,
"emergencyDial");
g_assert_cmpstr(radio_req_name(RADIO_REQ_ENABLE_UICC_APPLICATIONS),==,
"enableUiccApplications");
g_assert_cmpstr(radio_req_name(RADIO_REQ_START_NETWORK_SCAN_1_4),==,
"startNetworkScan_1_4");
g_assert_cmpstr(radio_req_name(RADIO_REQ_START_NETWORK_SCAN_1_5),==,
"startNetworkScan_1_5");
}
/*==========================================================================*
@@ -89,6 +95,12 @@ test_resp_name(
"setSystemSelectionChannelsResponse");
g_assert_cmpstr(radio_resp_name(RADIO_RESP_EMERGENCY_DIAL),==,
"emergencyDialResponse");
g_assert_cmpstr(radio_resp_name(RADIO_RESP_ENABLE_UICC_APPLICATIONS),==,
"enableUiccApplicationsResponse");
g_assert_cmpstr(radio_resp_name(RADIO_RESP_START_NETWORK_SCAN_1_4),==,
"startNetworkScanResponse_1_4");
g_assert_cmpstr(radio_resp_name(RADIO_RESP_START_NETWORK_SCAN_1_5),==,
"startNetworkScanResponse_1_5");
}
/*==========================================================================*
@@ -110,6 +122,8 @@ test_ind_name(
"currentLinkCapacityEstimate");
g_assert_cmpstr(radio_ind_name(RADIO_IND_CURRENT_EMERGENCY_NUMBER_LIST),==,
"currentEmergencyNumberList");
g_assert_cmpstr(radio_ind_name(RADIO_IND_REGISTRATION_FAILED),==,
"registrationFailed");
}
/*==========================================================================*
@@ -121,18 +135,211 @@ void
test_req_resp(
void)
{
g_assert_cmpint(radio_req_resp(UNKNOWN_REQ), == ,RADIO_RESP_NONE);
g_assert_cmpint(radio_req_resp(RADIO_REQ_ANY), == ,RADIO_RESP_NONE);
g_assert_cmpint(radio_req_resp(RADIO_REQ_GET_ICC_CARD_STATUS),==,
RADIO_RESP_GET_ICC_CARD_STATUS);
g_assert_cmpint(radio_req_resp(RADIO_REQ_START_NETWORK_SCAN),==,
RADIO_RESP_START_NETWORK_SCAN);
g_assert_cmpint(radio_req_resp(RADIO_REQ_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA),==,
RADIO_RESP_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA);
g_assert_cmpint(radio_req_resp(RADIO_REQ_SET_SYSTEM_SELECTION_CHANNELS),==,
RADIO_RESP_SET_SYSTEM_SELECTION_CHANNELS);
g_assert_cmpint(radio_req_resp(RADIO_REQ_EMERGENCY_DIAL),==,
RADIO_RESP_EMERGENCY_DIAL);
static const struct radio_req_resp_data {
RADIO_REQ req;
RADIO_RESP resp;
} tests[] = {
{ UNKNOWN_REQ, RADIO_RESP_NONE },
{ RADIO_REQ_ANY, RADIO_RESP_NONE },
{ RADIO_REQ_SETUP_DATA_CALL_1_2, RADIO_RESP_SETUP_DATA_CALL },
{ RADIO_REQ_DEACTIVATE_DATA_CALL_1_2, RADIO_RESP_DEACTIVATE_DATA_CALL },
{ RADIO_REQ_START_NETWORK_SCAN_1_2, RADIO_RESP_START_NETWORK_SCAN },
{ RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4,
RADIO_RESP_SET_INITIAL_ATTACH_APN },
{ RADIO_REQ_SET_DATA_PROFILE_1_4, RADIO_RESP_SET_DATA_PROFILE },
{ RADIO_REQ_SET_INDICATION_FILTER_1_2,
RADIO_RESP_SET_INDICATION_FILTER },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_RESP_GET_ICC_CARD_STATUS },
{ RADIO_REQ_START_NETWORK_SCAN, RADIO_RESP_START_NETWORK_SCAN },
{ RADIO_REQ_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
RADIO_RESP_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA },
{ RADIO_REQ_SET_SYSTEM_SELECTION_CHANNELS,
RADIO_RESP_SET_SYSTEM_SELECTION_CHANNELS },
{ RADIO_REQ_EMERGENCY_DIAL, RADIO_RESP_EMERGENCY_DIAL }
};
int i;
for (i = 0; i < G_N_ELEMENTS(tests); i++) {
g_assert_cmpint(radio_req_resp(tests[i].req), ==, tests[i].resp);
}
}
/*==========================================================================*
* req_resp2
*==========================================================================*/
static
void
test_req_resp2(
void)
{
static const struct radio_req_resp2_data {
RADIO_REQ req;
RADIO_INTERFACE iface;
RADIO_RESP resp;
} tests[] = {
{ UNKNOWN_REQ, RADIO_INTERFACE_NONE, RADIO_RESP_NONE },
{ RADIO_REQ_SUPPLY_ICC_PIN_FOR_APP, RADIO_INTERFACE_1_0,
RADIO_RESP_SUPPLY_ICC_PIN_FOR_APP },
{ RADIO_REQ_SUPPLY_ICC_PUK_FOR_APP, RADIO_INTERFACE_1_1,
RADIO_RESP_SUPPLY_ICC_PUK_FOR_APP },
{ RADIO_REQ_SUPPLY_ICC_PIN2_FOR_APP, RADIO_INTERFACE_1_2,
RADIO_RESP_SUPPLY_ICC_PIN2_FOR_APP },
{ RADIO_REQ_SUPPLY_ICC_PUK2_FOR_APP, RADIO_INTERFACE_1_3,
RADIO_RESP_SUPPLY_ICC_PUK2_FOR_APP },
{ RADIO_REQ_CHANGE_ICC_PIN_FOR_APP, RADIO_INTERFACE_1_4,
RADIO_RESP_CHANGE_ICC_PIN_FOR_APP },
{ RADIO_REQ_CHANGE_ICC_PIN2_FOR_APP, RADIO_INTERFACE_COUNT,
RADIO_RESP_CHANGE_ICC_PIN2_FOR_APP },
{ RADIO_REQ_SETUP_DATA_CALL_1_2, RADIO_INTERFACE_1_2,
RADIO_RESP_SETUP_DATA_CALL },
{ RADIO_REQ_SETUP_DATA_CALL_1_2, RADIO_INTERFACE_1_4,
RADIO_RESP_SETUP_DATA_CALL },
{ RADIO_REQ_DEACTIVATE_DATA_CALL_1_2, RADIO_INTERFACE_1_2,
RADIO_RESP_DEACTIVATE_DATA_CALL },
{ RADIO_REQ_DEACTIVATE_DATA_CALL_1_2, RADIO_INTERFACE_1_4,
RADIO_RESP_DEACTIVATE_DATA_CALL },
{ RADIO_REQ_START_NETWORK_SCAN_1_2, RADIO_INTERFACE_1_2,
RADIO_RESP_START_NETWORK_SCAN },
{ RADIO_REQ_START_NETWORK_SCAN_1_2, RADIO_INTERFACE_1_4,
RADIO_RESP_START_NETWORK_SCAN },
{ RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4, RADIO_INTERFACE_1_4,
RADIO_RESP_SET_INITIAL_ATTACH_APN },
{ RADIO_REQ_SET_DATA_PROFILE_1_4, RADIO_INTERFACE_1_4,
RADIO_RESP_SET_DATA_PROFILE },
{ RADIO_REQ_SET_INDICATION_FILTER_1_2, RADIO_INTERFACE_1_2,
RADIO_RESP_SET_INDICATION_FILTER },
{ RADIO_REQ_SET_INDICATION_FILTER_1_2, RADIO_INTERFACE_1_4,
RADIO_RESP_SET_INDICATION_FILTER },
{ RADIO_REQ_SET_INDICATION_FILTER_1_5, RADIO_INTERFACE_1_5,
RADIO_RESP_SET_INDICATION_FILTER_1_5 },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_ICC_CARD_STATUS },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_ICC_CARD_STATUS },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_ICC_CARD_STATUS_1_2 },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_ICC_CARD_STATUS_1_2 },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_ICC_CARD_STATUS_1_4 },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_1_5,
RADIO_RESP_GET_ICC_CARD_STATUS_1_5 },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_COUNT,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_ICC_CARD_STATUS, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_CELL_INFO_LIST },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_CELL_INFO_LIST },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_CELL_INFO_LIST_1_2 },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_CELL_INFO_LIST_1_2 },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_CELL_INFO_LIST_1_4 },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_1_5,
RADIO_RESP_GET_CELL_INFO_LIST_1_5 },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_CELL_INFO_LIST_1_5 },
{ RADIO_REQ_GET_CELL_INFO_LIST, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_CURRENT_CALLS },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_CURRENT_CALLS },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_CURRENT_CALLS_1_2 },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_CURRENT_CALLS_1_2 },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_CURRENT_CALLS_1_2 },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_CURRENT_CALLS_1_2 },
{ RADIO_REQ_GET_CURRENT_CALLS, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_SIGNAL_STRENGTH },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_SIGNAL_STRENGTH },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_SIGNAL_STRENGTH_1_2 },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_SIGNAL_STRENGTH_1_2 },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_SIGNAL_STRENGTH_1_2 },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_SIGNAL_STRENGTH_1_2 },
{ RADIO_REQ_GET_SIGNAL_STRENGTH, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_VOICE_REGISTRATION_STATE, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_DATA_REGISTRATION_STATE },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_DATA_REGISTRATION_STATE },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2 },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_4 },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_4 },
{ RADIO_REQ_GET_DATA_REGISTRATION_STATE, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_0,
RADIO_RESP_GET_DATA_CALL_LIST },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_1,
RADIO_RESP_GET_DATA_CALL_LIST },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_2,
RADIO_RESP_GET_DATA_CALL_LIST },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_3,
RADIO_RESP_GET_DATA_CALL_LIST },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_4,
RADIO_RESP_GET_DATA_CALL_LIST_1_4 },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_1_5,
RADIO_RESP_GET_DATA_CALL_LIST_1_5 },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_COUNT,
RADIO_RESP_GET_DATA_CALL_LIST_1_5 },
{ RADIO_REQ_GET_DATA_CALL_LIST, RADIO_INTERFACE_NONE,
RADIO_RESP_NONE }
};
int i;
for (i = 0; i < G_N_ELEMENTS(tests); i++) {
g_assert_cmpint(radio_req_resp2(tests[i].req, tests[i].iface), ==,
tests[i].resp);
}
}
/*==========================================================================*
@@ -149,6 +356,7 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_("resp_name"), test_resp_name);
g_test_add_func(TEST_("ind_name"), test_ind_name);
g_test_add_func(TEST_("req_resp"), test_req_resp);
g_test_add_func(TEST_("req_resp2"), test_req_resp2);
test_init(&test_opt, argc, argv);
return g_test_run();
}