Compare commits
102 Commits
1.2.1
...
eb631f637c
| Author | SHA1 | Date | |
|---|---|---|---|
| eb631f637c | |||
| ae08826314 | |||
|
|
a4a19a374a | ||
|
|
00248f8da3 | ||
|
|
418405697e | ||
|
|
12133c9685 | ||
|
|
50c615095b | ||
|
|
fa6a4d7e1a | ||
|
|
bedb4a7659 | ||
|
|
500465507e | ||
|
|
b8917f5985 | ||
|
|
453595be28 | ||
|
|
4803615920 | ||
|
|
d4a04ab083 | ||
|
|
5cf3d8c3cc | ||
|
|
b319fa4dc6 | ||
|
|
5cfa6756ee | ||
|
|
a997d138fa | ||
|
|
48da098644 | ||
|
|
3d3e023fe8 | ||
|
|
a9da4c95d2 | ||
|
|
6407a0271c | ||
|
|
05073a8367 | ||
|
|
7725869a27 | ||
|
|
7b33c6d70b | ||
|
|
b38ddeb4c0 | ||
|
|
db387d213a | ||
|
|
ae0af8512f | ||
|
|
bf51970422 | ||
|
|
e11e9a7eb1 | ||
|
|
606801a3c3 | ||
|
|
881dd6eef9 | ||
|
|
66ed8a3c7d | ||
|
|
89f3f5886f | ||
|
|
499e48df9a | ||
|
|
ad536645e7 | ||
|
|
0281a5ccdc | ||
|
|
ce70fb9744 | ||
|
|
4e0723ca6c | ||
|
|
050f83a22b | ||
|
|
736032efa0 | ||
|
|
c6d8e8d1e6 | ||
|
|
ee7fdd06d4 | ||
|
|
8fa78cc777 | ||
|
|
f4276f8602 | ||
|
|
ff1195ffc6 | ||
|
|
11673897fa | ||
|
|
520fe4257a | ||
|
|
179e8d6160 | ||
|
|
6d52c79f6c | ||
|
|
48026e4fe6 | ||
|
|
451711a1ce | ||
|
|
32523f2b1a | ||
|
|
e0e475c4e3 | ||
|
|
02789fa6a4 | ||
|
|
6a4f434592 | ||
|
|
a96fdf6c42 | ||
|
|
77a9b126ef | ||
|
|
5085ccc3c6 | ||
|
|
4eb1ced700 | ||
|
|
68ff7696d7 | ||
|
|
b6021807dd | ||
|
|
ea6071fb11 | ||
|
|
b50d08ddd9 | ||
|
|
2f4b216758 | ||
|
|
0af836aa7a | ||
|
|
d2227efa9e | ||
|
|
092bc3aa5f | ||
|
|
f52b5e98d6 | ||
|
|
d81a883289 | ||
|
|
a1de914f94 | ||
|
|
b1e7cb78d2 | ||
|
|
309383a3dd | ||
|
|
24a5e281d7 | ||
|
|
6a9a0b7d5e | ||
|
|
4b95a7efef | ||
|
|
1d14925196 | ||
|
|
77d600150a | ||
|
|
7684a717de | ||
|
|
6be4596f0d | ||
|
|
76f7fa6ee1 | ||
|
|
c3135de5c7 | ||
|
|
4595539656 | ||
|
|
62a0764577 | ||
|
|
ff65e170e1 | ||
|
|
0ce5f268c9 | ||
|
|
ab379e4fe3 | ||
|
|
e4ab7078a1 | ||
|
|
9b1c2df489 | ||
|
|
62212c5165 | ||
|
|
ea502d417a | ||
|
|
1ce4ff615b | ||
|
|
72b3fc58ec | ||
|
|
4140def1fc | ||
|
|
901396b385 | ||
|
|
052a0e11fb | ||
|
|
024f319164 | ||
|
|
91f7b80459 | ||
|
|
13076eb3ec | ||
|
|
27695ee5ff | ||
|
|
7b5656d2a8 | ||
|
|
788d472839 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -8,6 +8,8 @@ debian/*.substvars
|
||||
debian/*.install
|
||||
debian/tmp
|
||||
documentation.list
|
||||
unit/coverage/*.gcov
|
||||
unit/coverage/report
|
||||
installroot
|
||||
build
|
||||
RPMS
|
||||
|
||||
2
AUTHORS
2
AUTHORS
@@ -1,4 +1,6 @@
|
||||
Danct12 <danct12@disroot.org>
|
||||
Denis Grigorev <d.grigorev@omprussia.ru>
|
||||
Frajo Haider <f_haider@gmx.at>
|
||||
Matti Lehtimäki <matti.lehtimaki@jolla.com>
|
||||
Rinigus <rinigus.git@gmail.com>
|
||||
Slava Monich <slava@monich.com>
|
||||
|
||||
4
LICENSE
4
LICENSE
@@ -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:
|
||||
|
||||
|
||||
27
Makefile
27
Makefile
@@ -1,7 +1,8 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
.PHONY: clean all debug release coverage
|
||||
.PHONY: clean all debug release coverage test
|
||||
.PHONY: debug_lib release_lib coverage_lib
|
||||
.PHONY: print_debug_lib print_release_lib print_coverage_lib
|
||||
.PHONY: pkgconfig install install-dev
|
||||
|
||||
|
||||
@@ -22,8 +23,8 @@ all: debug release pkgconfig
|
||||
#
|
||||
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 2
|
||||
VERSION_RELEASE = 1
|
||||
VERSION_MINOR = 6
|
||||
VERSION_RELEASE = 0
|
||||
|
||||
# Version for pkg-config
|
||||
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
|
||||
@@ -46,8 +47,13 @@ LIB = $(LIB_NAME).a
|
||||
#
|
||||
|
||||
SRC = \
|
||||
radio_base.c \
|
||||
radio_client.c \
|
||||
radio_config.c \
|
||||
radio_instance.c \
|
||||
radio_registry.c \
|
||||
radio_request.c \
|
||||
radio_request_group.c \
|
||||
radio_util.c
|
||||
|
||||
#
|
||||
@@ -138,7 +144,17 @@ coverage_lib: $(COVERAGE_LIB)
|
||||
|
||||
pkgconfig: $(PKGCONFIG)
|
||||
|
||||
print_debug_lib:
|
||||
@echo $(DEBUG_LIB)
|
||||
|
||||
print_release_lib:
|
||||
@echo $(RELEASE_LIB)
|
||||
|
||||
print_coverage_lib:
|
||||
@echo $(COVERAGE_LIB)
|
||||
|
||||
clean:
|
||||
make -C unit clean
|
||||
rm -f *~ $(SRC_DIR)/*~ $(INCLUDE_DIR)/*~
|
||||
rm -fr $(BUILD_DIR) RPMS installroot
|
||||
rm -fr debian/tmp debian/libgbinder-radio debian/libgbinder-radio-dev
|
||||
@@ -146,6 +162,9 @@ clean:
|
||||
rm -f debian/*.debhelper.log debian/*.debhelper debian/*~
|
||||
rm -f debian/*.install
|
||||
|
||||
test:
|
||||
make -C unit test
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
@@ -219,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)
|
||||
|
||||
2
README
Normal file
2
README
Normal file
@@ -0,0 +1,2 @@
|
||||
A library for communicating with Android IRadio binder services,
|
||||
built on top of libgbinder.
|
||||
10
debian/Jenkinsfile
vendored
Normal file
10
debian/Jenkinsfile
vendored
Normal 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'])
|
||||
54
debian/changelog
vendored
54
debian/changelog
vendored
@@ -1,33 +1,49 @@
|
||||
libgbinder-radio (1.2.1) unstable; urgency=medium
|
||||
libgbinder-radio (1.6.0-0ubports1) UNRELEASED; urgency=unknown
|
||||
|
||||
* Fixed backward compatibility with radio@1.0
|
||||
* New upstream release v1.6.0
|
||||
|
||||
-- Slava Monich <slava.monich@jolla.com> Fri, 05 Mar 2021 12:33:50 +0200
|
||||
-- UBports package upgrader bot <dev@ubports.com> Fri, 13 Dec 2024 04:07:25 +0000
|
||||
|
||||
libgbinder-radio (1.2.0) unstable; urgency=medium
|
||||
libgbinder-radio (1.5.6-0ubports1) UNRELEASED; urgency=unknown
|
||||
|
||||
* Support for radio@1.2 interfaces
|
||||
* New upstream release v1.5.6
|
||||
|
||||
-- Slava Monich <slava.monich@jolla.com> Thu, 04 Mar 2021 13:36:51 +0200
|
||||
-- UBports package upgrader bot <dev@ubports.com> Thu, 09 Nov 2023 00:27:17 +0000
|
||||
|
||||
libgbinder-radio (1.0.11) unstable; urgency=medium
|
||||
libgbinder-radio (1.5.4-0ubports1) focal; urgency=medium
|
||||
|
||||
* Make library executable on RPM based systems
|
||||
* Added req => resp mapping for radio@1.1 calls
|
||||
* Update from upstream
|
||||
|
||||
-- Slava Monich <slava.monich@jolla.com> Thu, 01 Oct 2020 21:04:59 +0300
|
||||
-- Lionel Duboeuf <lduboeuf@ouvaton.org> Wed, 08 Jan 2023 10:52:34 +0100
|
||||
|
||||
libgbinder-radio (1.0.10) unstable; urgency=medium
|
||||
libgbinder-radio (1.4.2-0ubports4) focal; urgency=medium
|
||||
|
||||
* Hide internal symbols
|
||||
* Respect arch specific lib dir
|
||||
* Ignore GLib deprecation warnings
|
||||
* Added constants for android.hardware.radio@1.1 interfaces
|
||||
* Rename libgbinder-radio-dev to libgbinder-radio1-dev
|
||||
* Generate install files correctly again
|
||||
|
||||
-- Slava Monich <slava.monich@jolla.com> Wed, 03 Jun 2020 15:24:17 +0300
|
||||
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Wed, 24 Nov 2021 10:52:34 +0100
|
||||
|
||||
libgbinder-radio (1.0.9) unstable; urgency=medium
|
||||
libgbinder-radio (1.4.2-0ubports3) focal; urgency=medium
|
||||
|
||||
* Added packaging for Debian-based distros.
|
||||
* 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
|
||||
|
||||
-- Danct12 <danct12@disroot.org> Tue, 24 Mar 2020 02:55:50 +0700
|
||||
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Mon, 15 Nov 2021 15:02:18 +0100
|
||||
|
||||
libgbinder-radio (1.4.2-0ubports2) focal; urgency=medium
|
||||
|
||||
* Bump version, no changes.
|
||||
|
||||
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Thu, 11 Nov 2021 15:02:07 +0100
|
||||
|
||||
libgbinder-radio (1.4.2-0ubports1) focal; urgency=medium
|
||||
|
||||
* Initial packaging for UBPorts
|
||||
|
||||
-- Guido Berhoerster <guido+gitlab.com@berhoerster.name> Mon, 11 Oct 2021 16:38:02 +0200
|
||||
|
||||
30
debian/control
vendored
30
debian/control
vendored
@@ -1,17 +1,31 @@
|
||||
Source: libgbinder-radio
|
||||
Priority: optional
|
||||
Maintainer: Danct12 <danct12@disroot.org>
|
||||
Build-Depends: debhelper (>=9), libgbinder-dev (>= 1.0.9)
|
||||
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.0.9), ${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.
|
||||
|
||||
3
debian/libgbinder-radio1-dev.install.in
vendored
Normal file
3
debian/libgbinder-radio1-dev.install.in
vendored
Normal 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
1
debian/libgbinder-radio1.install.in
vendored
Normal file
@@ -0,0 +1 @@
|
||||
debian/tmp/@LIBDIR@/libgbinder-radio.so.* @LIBDIR@
|
||||
2
debian/rules
vendored
2
debian/rules
vendored
@@ -5,7 +5,7 @@
|
||||
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
|
||||
|
||||
147
include/radio_client.h
Normal file
147
include/radio_client.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_CLIENT_H
|
||||
#define RADIO_CLIENT_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioClientIndicationFunc)(
|
||||
RadioClient* client,
|
||||
RADIO_IND code,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioClientFunc)(
|
||||
RadioClient* client,
|
||||
gpointer user_data);
|
||||
|
||||
RadioClient*
|
||||
radio_client_new(
|
||||
RadioInstance* instance)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioClient*
|
||||
radio_client_ref(
|
||||
RadioClient* client);
|
||||
|
||||
void
|
||||
radio_client_unref(
|
||||
RadioClient* client);
|
||||
|
||||
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);
|
||||
|
||||
gboolean
|
||||
radio_client_dead(
|
||||
RadioClient* client);
|
||||
|
||||
gboolean
|
||||
radio_client_connected(
|
||||
RadioClient* client);
|
||||
|
||||
void
|
||||
radio_client_set_default_timeout(
|
||||
RadioClient* client,
|
||||
int milliseconds);
|
||||
|
||||
gulong
|
||||
radio_client_add_indication_handler(
|
||||
RadioClient* client,
|
||||
RADIO_IND code,
|
||||
RadioClientIndicationFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_owner_changed_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_death_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_connected_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
radio_client_remove_handler(
|
||||
RadioClient* client,
|
||||
gulong id);
|
||||
|
||||
void
|
||||
radio_client_remove_handlers(
|
||||
RadioClient* client,
|
||||
gulong* ids,
|
||||
int count);
|
||||
|
||||
#define radio_client_remove_all_handlers(client,ids) \
|
||||
radio_client_remove_handlers(client, ids, G_N_ELEMENTS(ids))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* RADIO_CLIENT_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
208
include/radio_config.h
Normal file
208
include/radio_config.h
Normal 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:
|
||||
*/
|
||||
161
include/radio_config_aidl_types.h
Normal file
161
include/radio_config_aidl_types.h
Normal 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:
|
||||
*/
|
||||
207
include/radio_config_types.h
Normal file
207
include/radio_config_types.h
Normal 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
134
include/radio_data_types.h
Normal 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
123
include/radio_ims_types.h
Normal 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:
|
||||
*/
|
||||
@@ -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>
|
||||
|
||||
@@ -45,13 +52,6 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct radio_instance_priv RadioInstancePriv;
|
||||
|
||||
typedef enum radio_interface {
|
||||
RADIO_INTERFACE_1_0,
|
||||
RADIO_INTERFACE_1_1,
|
||||
RADIO_INTERFACE_1_2,
|
||||
RADIO_INTERFACE_COUNT
|
||||
} RADIO_INTERFACE; /* Since 1.2.0 */
|
||||
|
||||
struct radio_instance {
|
||||
GObject parent;
|
||||
RadioInstancePriv* priv;
|
||||
@@ -65,14 +65,33 @@ struct radio_instance {
|
||||
gboolean enabled;
|
||||
/* Since 1.2.0 */
|
||||
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;
|
||||
};
|
||||
|
||||
/* 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
|
||||
(*RadioInstanceFunc)(
|
||||
RadioInstance* radio,
|
||||
gpointer user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioRequestObserverFunc)(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
typedef
|
||||
gboolean
|
||||
(*RadioResponseHandlerFunc)(
|
||||
@@ -147,16 +166,25 @@ 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,
|
||||
const char* name);
|
||||
|
||||
RadioInstance*
|
||||
radio_instance_get_with_interface(
|
||||
radio_instance_get_with_version(
|
||||
const char* dev,
|
||||
const char* name,
|
||||
RADIO_INTERFACE version); /* Since 1.2.1 */
|
||||
RADIO_INTERFACE version); /* Since 1.2.2 */
|
||||
|
||||
RadioInstance* const*
|
||||
radio_instance_get_all(
|
||||
@@ -170,6 +198,11 @@ void
|
||||
radio_instance_unref(
|
||||
RadioInstance* radio);
|
||||
|
||||
gsize
|
||||
radio_instance_rpc_header_size(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ req); /* Since 1.4.3 */
|
||||
|
||||
const char*
|
||||
radio_instance_req_name(
|
||||
RadioInstance* radio,
|
||||
@@ -206,12 +239,35 @@ radio_instance_set_enabled(
|
||||
gboolean enabled); /* Since 1.0.7 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_handler(
|
||||
radio_instance_add_request_observer(
|
||||
RadioInstance* radio,
|
||||
RADIO_IND code,
|
||||
RadioIndicationHandlerFunc func,
|
||||
RADIO_REQ code,
|
||||
RadioRequestObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_request_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_OBSERVER_PRIORITY priority,
|
||||
RADIO_REQ code,
|
||||
RadioRequestObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_OBSERVER_PRIORITY priority,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer(
|
||||
RadioInstance* radio,
|
||||
@@ -219,6 +275,14 @@ radio_instance_add_indication_observer(
|
||||
RadioIndicationObserverFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_OBSERVER_PRIORITY priority,
|
||||
RADIO_IND code,
|
||||
RadioIndicationObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_handler(
|
||||
RadioInstance* radio,
|
||||
@@ -227,10 +291,10 @@ radio_instance_add_response_handler(
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
radio_instance_add_indication_handler(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
RADIO_IND code,
|
||||
RadioIndicationHandlerFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
@@ -251,6 +315,12 @@ radio_instance_add_enabled_handler(
|
||||
RadioInstanceFunc func,
|
||||
gpointer user_data); /* Since 1.0.7 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_connected_handler(
|
||||
RadioInstance* radio,
|
||||
RadioInstanceFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
void
|
||||
radio_instance_remove_handler(
|
||||
RadioInstance* radio,
|
||||
|
||||
143
include/radio_messaging_types.h
Normal file
143
include/radio_messaging_types.h
Normal 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
135
include/radio_modem_types.h
Normal 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:
|
||||
*/
|
||||
163
include/radio_network_types.h
Normal file
163
include/radio_network_types.h
Normal 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:
|
||||
*/
|
||||
224
include/radio_request.h
Normal file
224
include/radio_request.h
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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_REQUEST_H
|
||||
#define RADIO_REQUEST_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_config_types.h>
|
||||
|
||||
/*
|
||||
* Basic workflow
|
||||
*
|
||||
* 1. radio_request_new() or radio_request_new2() creates the request.
|
||||
* That assigns a serial and initializes GBinderWriter for appending
|
||||
* more arguments. GBinderWriter pointer can be NULL if serial is the
|
||||
* only argument.
|
||||
* 2. The caller (optionally) uses GBinderWriter to add more arguments
|
||||
* to the request.
|
||||
* 3. radio_request_submit() submits the request
|
||||
* 4. radio_request_unref() can be called at this point to release the
|
||||
* reference produced by radio_request_new() unless the caller needs
|
||||
* to keep it. In any case, radio_request_unref() has to be called
|
||||
* sooner or later for each request created by radio_request_new().
|
||||
* The library keeps its own internal reference while the request is
|
||||
* being processed.
|
||||
* 5. RadioRequestCompleteFunc receives the response from the radio service.
|
||||
*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum radio_tx_status {
|
||||
RADIO_TX_STATUS_OK, /* Successful completion, no error */
|
||||
RADIO_TX_STATUS_FAILED, /* Request transaction failed */
|
||||
RADIO_TX_STATUS_TIMEOUT /* No response transaction received */
|
||||
} RADIO_TX_STATUS;
|
||||
|
||||
/*
|
||||
* RadioRequestCompleteFunc
|
||||
* RadioConfigRequestCompleteFunc
|
||||
*
|
||||
* Invoked upon completion of each request. If an error occurs,
|
||||
* 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
|
||||
* transaction failed (or response didn't arrive in time) and
|
||||
* the other arguments can be ignored.
|
||||
*
|
||||
* If status is RADIO_TX_STATUS_OK then the resp, error and args
|
||||
* arguments contain the information received in the response.
|
||||
*/
|
||||
typedef
|
||||
void
|
||||
(*RadioRequestCompleteFunc)(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
RADIO_RESP resp,
|
||||
RADIO_ERROR error,
|
||||
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
|
||||
*
|
||||
* If retries are enabled with radio_request_set_retry_func(), then this
|
||||
* callback is invoiked to check whether the request should be retried,
|
||||
* based on the status received from the radio service and the contents
|
||||
* of the reply. If such callback returns TRUE, the request is retried
|
||||
* at some point in the future with a new serial, otherwise it gets
|
||||
* completed right away.
|
||||
*
|
||||
* user_data is the pointer passed to radio_request_new() when the request
|
||||
* was created.
|
||||
*/
|
||||
typedef
|
||||
gboolean
|
||||
(*RadioRequestRetryFunc)(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
guint32 resp, /* Was RADIO_RESP before 1.4.6 */
|
||||
RADIO_ERROR error,
|
||||
const GBinderReader* args,
|
||||
void* user_data);
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new(
|
||||
RadioClient* client,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* args, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new2(
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
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);
|
||||
|
||||
void
|
||||
radio_request_unref(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_set_blocking(
|
||||
RadioRequest* req,
|
||||
gboolean blocking);
|
||||
|
||||
void
|
||||
radio_request_set_timeout(
|
||||
RadioRequest* req,
|
||||
guint milliseconds); /* Zero to use the default timeout */
|
||||
|
||||
void
|
||||
radio_request_set_retry(
|
||||
RadioRequest* req,
|
||||
guint delay_ms, /* Delay before each retry, in milliseconds */
|
||||
int max_count); /* Negative count to keep retrying indefinitely */
|
||||
|
||||
void
|
||||
radio_request_set_retry_func(
|
||||
RadioRequest* req,
|
||||
RadioRequestRetryFunc retry);
|
||||
|
||||
gboolean
|
||||
radio_request_submit(
|
||||
RadioRequest* req);
|
||||
|
||||
gboolean
|
||||
radio_request_retry(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_cancel(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_drop( /* cancel and unref */
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
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 */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
96
include/radio_request_group.h
Normal file
96
include/radio_request_group.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_REQUEST_GROUP_H
|
||||
#define RADIO_REQUEST_GROUP_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
/*
|
||||
* In addition to being just a group of requests and making it easier
|
||||
* to perform bulk operations (i.e. cancel all), RadioRequestGroup can
|
||||
* be given the "blocker" status by its RadioClient and then only requests
|
||||
* belonging to this group will be submitted until the block is released.
|
||||
*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct radio_request_group {
|
||||
RadioClient* client;
|
||||
};
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_new(
|
||||
RadioClient* client)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_ref(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_unref(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_cancel(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block_status(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_unblock(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* RADIO_REQUEST_GROUP_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
160
include/radio_sim_types.h
Normal file
160
include/radio_sim_types.h
Normal 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
@@ -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
168
include/radio_voice_types.h
Normal 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:
|
||||
*/
|
||||
@@ -1,17 +1,25 @@
|
||||
Name: libgbinder-radio
|
||||
Version: 1.2.1
|
||||
|
||||
Version: 1.6.0
|
||||
Release: 0
|
||||
Summary: Binder client library for Android radio interfaces
|
||||
Group: Development/Libraries
|
||||
License: BSD
|
||||
URL: https://github.com/mer-hybris/libgbinder-radio
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
|
||||
%define libgbinder_version 1.0.9
|
||||
%define libgbinder_version 1.1.14
|
||||
%define libglibutil_version 1.0.49
|
||||
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: pkgconfig(glib-2.0)
|
||||
BuildRequires: pkgconfig(libglibutil)
|
||||
BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version}
|
||||
BuildRequires: pkgconfig(libgbinder) >= %{libgbinder_version}
|
||||
|
||||
# license macro requires rpm >= 4.11
|
||||
BuildRequires: pkgconfig(rpm)
|
||||
%define license_support %(pkg-config --exists 'rpm >= 4.11'; echo $?)
|
||||
|
||||
Requires: libglibutil >= %{libglibutil_version}
|
||||
Requires: libgbinder >= %{libgbinder_version}
|
||||
Requires(post): /sbin/ldconfig
|
||||
Requires(postun): /sbin/ldconfig
|
||||
@@ -22,7 +30,6 @@ Binder client library for Android radio interfaces
|
||||
%package devel
|
||||
Summary: Development library for %{name}
|
||||
Requires: %{name} = %{version}
|
||||
Requires: pkgconfig
|
||||
|
||||
%description devel
|
||||
This package contains the development library for %{name}.
|
||||
@@ -31,12 +38,15 @@ This package contains the development library for %{name}.
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
|
||||
make %{_smp_mflags} LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
|
||||
|
||||
%install
|
||||
rm -rf %{buildroot}
|
||||
make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
|
||||
|
||||
%check
|
||||
make -C unit test
|
||||
|
||||
%post -p /sbin/ldconfig
|
||||
|
||||
%postun -p /sbin/ldconfig
|
||||
@@ -44,6 +54,9 @@ make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%{_libdir}/%{name}.so.*
|
||||
%if %{license_support} == 0
|
||||
%license LICENSE
|
||||
%endif
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
1014
src/radio_base.c
Normal file
1014
src/radio_base.c
Normal file
File diff suppressed because it is too large
Load Diff
198
src/radio_base.h
Normal file
198
src/radio_base.h
Normal 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:
|
||||
*/
|
||||
480
src/radio_client.c
Normal file
480
src/radio_client.c
Normal file
@@ -0,0 +1,480 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "radio_base.h"
|
||||
#include "radio_client.h"
|
||||
#include "radio_instance_p.h"
|
||||
#include "radio_request_p.h"
|
||||
#include "radio_util.h"
|
||||
#include "radio_log.h"
|
||||
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
enum radio_events {
|
||||
RADIO_EVENT_IND,
|
||||
RADIO_EVENT_RESP,
|
||||
RADIO_EVENT_ACK,
|
||||
RADIO_EVENT_DEATH,
|
||||
RADIO_EVENT_CONNECTED,
|
||||
RADIO_EVENT_COUNT
|
||||
};
|
||||
|
||||
struct radio_client {
|
||||
RadioBase base;
|
||||
RadioInstance* instance;
|
||||
gulong event_ids[RADIO_EVENT_COUNT];
|
||||
};
|
||||
|
||||
typedef RadioBaseClass RadioClientClass;
|
||||
GType radio_client_get_type() RADIO_INTERNAL;
|
||||
G_DEFINE_TYPE(RadioClient, radio_client, RADIO_TYPE_BASE)
|
||||
|
||||
#define PARENT_CLASS radio_client_parent_class
|
||||
#define THIS_TYPE radio_client_get_type()
|
||||
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, THIS_TYPE, RadioClient)
|
||||
|
||||
typedef struct radio_client_call {
|
||||
RadioRequest* req;
|
||||
RadioBaseRequestSentFunc callback;
|
||||
} RadioClientCall;
|
||||
|
||||
enum radio_client_signal {
|
||||
SIGNAL_INDICATION,
|
||||
SIGNAL_DEATH,
|
||||
SIGNAL_CONNECTED,
|
||||
SIGNAL_COUNT
|
||||
};
|
||||
|
||||
#define SIGNAL_INDICATION_NAME "radio-client-indication"
|
||||
#define SIGNAL_DEATH_NAME "radio-client-death"
|
||||
#define SIGNAL_CONNECTED_NAME "radio-client-connected"
|
||||
|
||||
static guint radio_client_signals[SIGNAL_COUNT] = { 0 };
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_call_free(
|
||||
RadioClientCall* call)
|
||||
{
|
||||
radio_request_unref(call->req);
|
||||
gutil_slice_free(call);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_call_destroy(
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
radio_client_call_free(user_data2);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_call_complete(
|
||||
RadioInstance* instance,
|
||||
gulong id,
|
||||
int status,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
RadioClientCall* call = user_data2;
|
||||
|
||||
call->callback(RADIO_BASE(user_data1), call->req, status);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_handle_death(
|
||||
RadioInstance* instance,
|
||||
gpointer user_data)
|
||||
{
|
||||
RadioBase* base = RADIO_BASE(user_data);
|
||||
|
||||
g_object_ref(base);
|
||||
radio_base_handle_death(base);
|
||||
g_signal_emit(base, radio_client_signals[SIGNAL_DEATH], 0);
|
||||
g_object_unref(base);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_handle_connected(
|
||||
RadioInstance* instance,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit(THIS(user_data), radio_client_signals[SIGNAL_CONNECTED], 0);
|
||||
radio_base_submit_requests(RADIO_BASE(user_data));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_handle_ack(
|
||||
RadioInstance* instance,
|
||||
guint32 serial,
|
||||
gpointer user_data)
|
||||
{
|
||||
radio_base_handle_ack(RADIO_BASE(user_data), serial);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_handle_ind(
|
||||
RadioInstance* instance,
|
||||
RADIO_IND code,
|
||||
RADIO_IND_TYPE type,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit(THIS(user_data), radio_client_signals[SIGNAL_INDICATION],
|
||||
radio_instance_ind_quark(instance, code), code, reader);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_handle_resp(
|
||||
RadioInstance* instance,
|
||||
RADIO_RESP code,
|
||||
const RadioResponseInfo* info,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!radio_base_handle_resp(RADIO_BASE(user_data), code, info, reader)) {
|
||||
const char* name = radio_resp_name2(instance, code);
|
||||
|
||||
/* Most likely this is a response to a cancelled request */
|
||||
GDEBUG("Ignoring IRadio response [%08x] %u %s", info->serial, code,
|
||||
name ? name : "");
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gulong
|
||||
radio_client_add_handler(
|
||||
RadioClient* self,
|
||||
enum radio_client_signal sig,
|
||||
RadioClientFunc fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(fn)) ?
|
||||
g_signal_connect_closure_by_id(self, radio_client_signals[sig], 0,
|
||||
g_cclosure_new(G_CALLBACK(fn), user_data, NULL), FALSE) : 0;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
RadioClient*
|
||||
radio_client_new(
|
||||
RadioInstance* instance)
|
||||
{
|
||||
RadioClient* self = NULL;
|
||||
|
||||
if (G_LIKELY(instance)) {
|
||||
self = g_object_new(THIS_TYPE, NULL);
|
||||
radio_base_initialize(&self->base);
|
||||
self->instance = radio_instance_ref(instance);
|
||||
self->event_ids[RADIO_EVENT_IND] =
|
||||
radio_instance_add_indication_observer(instance, RADIO_IND_ANY,
|
||||
radio_client_handle_ind, self);
|
||||
self->event_ids[RADIO_EVENT_RESP] =
|
||||
radio_instance_add_response_observer(instance, RADIO_RESP_ANY,
|
||||
radio_client_handle_resp, self);
|
||||
self->event_ids[RADIO_EVENT_ACK] =
|
||||
radio_instance_add_ack_handler(instance,
|
||||
radio_client_handle_ack, self);
|
||||
self->event_ids[RADIO_EVENT_DEATH] =
|
||||
radio_instance_add_death_handler(instance,
|
||||
radio_client_handle_death, self);
|
||||
self->event_ids[RADIO_EVENT_CONNECTED] =
|
||||
radio_instance_add_connected_handler(instance,
|
||||
radio_client_handle_connected, self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RadioClient*
|
||||
radio_client_ref(
|
||||
RadioClient* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_ref(self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
radio_client_unref(
|
||||
RadioClient* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_unref(self);
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
radio_client_slot(
|
||||
RadioClient* self)
|
||||
{
|
||||
return G_LIKELY(self) ? self->instance->slot : NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
radio_client_dead(
|
||||
RadioClient* self)
|
||||
{
|
||||
return !self || self->instance->dead;
|
||||
}
|
||||
|
||||
gboolean
|
||||
radio_client_connected(
|
||||
RadioClient* self)
|
||||
{
|
||||
return self && self->instance->connected;
|
||||
}
|
||||
|
||||
RADIO_INTERFACE
|
||||
radio_client_interface(
|
||||
RadioClient* self)
|
||||
{
|
||||
return G_LIKELY(self) ? self->instance->version : RADIO_INTERFACE_NONE;
|
||||
}
|
||||
|
||||
RADIO_AIDL_INTERFACE
|
||||
radio_client_aidl_interface(
|
||||
RadioClient* self)
|
||||
{
|
||||
return G_LIKELY(self) ? self->instance->interface_aidl : RADIO_AIDL_INTERFACE_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
radio_client_set_default_timeout(
|
||||
RadioClient* self,
|
||||
int milliseconds)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
radio_base_set_default_timeout(&self->base, milliseconds);
|
||||
}
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_client_add_indication_handler(
|
||||
RadioClient* self,
|
||||
RADIO_IND code,
|
||||
RadioClientIndicationFunc fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(fn)) ?
|
||||
g_signal_connect_closure_by_id(self,
|
||||
radio_client_signals[SIGNAL_INDICATION],
|
||||
radio_instance_ind_quark(self->instance, code),
|
||||
g_cclosure_new(G_CALLBACK(fn), user_data, NULL), FALSE) : 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_client_add_owner_changed_handler(
|
||||
RadioClient* self,
|
||||
RadioClientFunc fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
return self ? radio_base_add_owner_changed_handler(&self->base,
|
||||
(RadioBaseFunc) fn, user_data) : 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_client_add_death_handler(
|
||||
RadioClient* self,
|
||||
RadioClientFunc fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
return radio_client_add_handler(self, SIGNAL_DEATH, fn, user_data);
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_client_add_connected_handler(
|
||||
RadioClient* self,
|
||||
RadioClientFunc fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
return radio_client_add_handler(self, SIGNAL_CONNECTED, fn, user_data);
|
||||
}
|
||||
|
||||
void
|
||||
radio_client_remove_handler(
|
||||
RadioClient* self,
|
||||
gulong id)
|
||||
{
|
||||
if (G_LIKELY(id) && G_LIKELY(self)) {
|
||||
g_signal_handler_disconnect(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_client_remove_handlers(
|
||||
RadioClient* self,
|
||||
gulong* ids,
|
||||
int count)
|
||||
{
|
||||
gutil_disconnect_handlers(self, ids, count);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Methods
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
gboolean
|
||||
radio_client_is_dead(
|
||||
RadioBase* base)
|
||||
{
|
||||
return THIS(base)->instance->dead;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
radio_client_can_submit_requests(
|
||||
RadioBase* base)
|
||||
{
|
||||
return THIS(base)->instance->connected;
|
||||
}
|
||||
|
||||
static
|
||||
GBinderLocalRequest*
|
||||
radio_client_new_request(
|
||||
RadioBase* base,
|
||||
guint32 code)
|
||||
{
|
||||
return radio_instance_new_request(THIS(base)->instance, code);
|
||||
}
|
||||
|
||||
static
|
||||
gulong
|
||||
radio_client_send_request(
|
||||
RadioBase* base,
|
||||
RadioRequest* req,
|
||||
RadioBaseRequestSentFunc callback)
|
||||
{
|
||||
RadioClientCall* call = g_slice_new(RadioClientCall);
|
||||
gulong tx_id;
|
||||
|
||||
call->callback = callback;
|
||||
call->req = radio_request_ref(req);
|
||||
tx_id = radio_instance_send_request(THIS(base)->instance,
|
||||
req->code, req->args, radio_client_call_complete,
|
||||
radio_client_call_destroy, base, call);
|
||||
if (tx_id) {
|
||||
return tx_id;
|
||||
} else {
|
||||
radio_client_call_free(call);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_cancel_request(
|
||||
RadioBase* base,
|
||||
gulong id)
|
||||
{
|
||||
radio_instance_cancel_request(THIS(base)->instance, id);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internals
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_init(
|
||||
RadioClient* self)
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_finalize(
|
||||
GObject* object)
|
||||
{
|
||||
RadioClient* self = THIS(object);
|
||||
|
||||
radio_instance_remove_all_handlers(self->instance, self->event_ids);
|
||||
radio_instance_unref(self->instance);
|
||||
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_client_class_init(
|
||||
RadioClientClass* klass)
|
||||
{
|
||||
RadioBaseClass* base_class = RADIO_BASE_CLASS(klass);
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
GType type = G_OBJECT_CLASS_TYPE(klass);
|
||||
|
||||
base_class->is_dead = radio_client_is_dead;
|
||||
base_class->can_submit_requests = radio_client_can_submit_requests;
|
||||
base_class->new_request = radio_client_new_request;
|
||||
base_class->send_request = radio_client_send_request;
|
||||
base_class->cancel_request = radio_client_cancel_request;
|
||||
object_class->finalize = radio_client_finalize;
|
||||
|
||||
radio_client_signals[SIGNAL_INDICATION] =
|
||||
g_signal_new(SIGNAL_INDICATION_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
radio_client_signals[SIGNAL_DEATH] =
|
||||
g_signal_new(SIGNAL_DEATH_NAME, type, G_SIGNAL_RUN_FIRST, 0,
|
||||
NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
radio_client_signals[SIGNAL_CONNECTED] =
|
||||
g_signal_new(SIGNAL_CONNECTED_NAME, type, G_SIGNAL_RUN_FIRST, 0,
|
||||
NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
1145
src/radio_config.c
Normal file
1145
src/radio_config.c
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
89
src/radio_instance_p.h
Normal file
89
src/radio_instance_p.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_INSTANCE_PRIVATE_H
|
||||
#define RADIO_INSTANCE_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_instance.h"
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioInstanceTxCompleteFunc)(
|
||||
RadioInstance* instance,
|
||||
gulong id,
|
||||
int status,
|
||||
void* user_data1,
|
||||
void* user_data2);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioInstanceTxDestroyFunc)(
|
||||
void* user_data1,
|
||||
void* user_data2);
|
||||
|
||||
gulong
|
||||
radio_instance_send_request(
|
||||
RadioInstance* instance,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
RadioInstanceTxCompleteFunc complete,
|
||||
RadioInstanceTxDestroyFunc destroy,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_instance_cancel_request(
|
||||
RadioInstance* instance,
|
||||
gulong id)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
GQuark
|
||||
radio_instance_ind_quark(
|
||||
RadioInstance* instance,
|
||||
RADIO_IND ind)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_INSTANCE_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -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:
|
||||
*
|
||||
@@ -44,6 +44,7 @@ struct radio_registry {
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
GType radio_registry_get_type(void) RADIO_INTERNAL;
|
||||
G_DEFINE_TYPE(RadioRegistry, radio_registry, G_TYPE_OBJECT)
|
||||
#define RADIO_TYPE_REGISTRY (radio_registry_get_type())
|
||||
#define RADIO_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
@@ -110,7 +111,7 @@ radio_registry_new(
|
||||
(gpointer*)(&radio_registry_instance));
|
||||
}
|
||||
return radio_registry_instance;
|
||||
|
||||
|
||||
}
|
||||
|
||||
RadioRegistry*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 Jolla Ltd.
|
||||
* Copyright (C) 2018-2020 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:
|
||||
*
|
||||
@@ -37,17 +37,18 @@
|
||||
#ifndef RADIO_REGISTRY_PRIVATE_H
|
||||
#define RADIO_REGISTRY_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_registry.h"
|
||||
|
||||
void
|
||||
radio_registry_instance_added(
|
||||
RadioInstance* instance)
|
||||
G_GNUC_INTERNAL;
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_registry_instance_removed(
|
||||
const char* key)
|
||||
G_GNUC_INTERNAL;
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REGISTRY_PRIVATE_H */
|
||||
|
||||
|
||||
382
src/radio_request.c
Normal file
382
src/radio_request.c
Normal file
@@ -0,0 +1,382 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "radio_base.h"
|
||||
#include "radio_request_p.h"
|
||||
#include "radio_request_group_p.h"
|
||||
#include "radio_log.h"
|
||||
|
||||
#include <gbinder_local_request.h>
|
||||
#include <gbinder_writer.h>
|
||||
|
||||
#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;
|
||||
GDestroyNotify destroy;
|
||||
gsize serial_offset;
|
||||
RADIO_REQUEST_FLAGS flags;
|
||||
gint refcount;
|
||||
} RadioRequestObject;
|
||||
|
||||
static inline RadioRequestObject* radio_request_cast(RadioRequest* req)
|
||||
{ return req ? G_CAST(req, RadioRequestObject, pub) : NULL; }
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_object_cancel(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
RadioRequest* req = &self->pub;
|
||||
|
||||
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_base_request_dropped(req);
|
||||
}
|
||||
radio_base_unregister_request(req->object, req);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_free(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
RadioRequest* req = &self->pub;
|
||||
|
||||
GVERBOSE_("%u (%08x) %p", req->code, req->serial, req);
|
||||
radio_request_object_cancel(self);
|
||||
|
||||
/* 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 */
|
||||
req->complete = NULL;
|
||||
complete(req, RADIO_TX_STATUS_FAILED, RADIO_RESP_NONE,
|
||||
RADIO_ERROR_NONE, NULL, req->user_data);
|
||||
}
|
||||
if (self->destroy) {
|
||||
GDestroyNotify destroy = self->destroy;
|
||||
|
||||
self->destroy = NULL;
|
||||
destroy(req->user_data);
|
||||
}
|
||||
gbinder_local_request_unref(req->args);
|
||||
gutil_slice_free(self);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_object_unref(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
radio_request_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
radio_request_default_retry(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
RADIO_RESP resp,
|
||||
RADIO_ERROR error,
|
||||
const GBinderReader* reader,
|
||||
void* user_data)
|
||||
{
|
||||
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(
|
||||
RadioBase* base,
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer,
|
||||
RadioRequestGenericCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
RadioRequestObject* self = g_slice_new0(RadioRequestObject);
|
||||
RadioRequest* req = &self->pub;
|
||||
GBinderWriter tmp;
|
||||
|
||||
self->destroy = destroy;
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
|
||||
req->state = RADIO_REQUEST_STATE_NEW;
|
||||
req->code = code;
|
||||
req->complete = complete;
|
||||
req->user_data = user_data;
|
||||
req->retry = radio_request_default_retry;
|
||||
|
||||
/* Assign serial and add to the group */
|
||||
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_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);
|
||||
return req;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_unref_func(
|
||||
gpointer req)
|
||||
{
|
||||
radio_request_object_unref(radio_request_cast(req));
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_update_serial(
|
||||
RadioRequest* req,
|
||||
guint32 serial)
|
||||
{
|
||||
GBinderWriter writer;
|
||||
|
||||
gbinder_local_request_init_writer(req->args, &writer);
|
||||
gbinder_writer_overwrite_int32(&writer,
|
||||
radio_request_cast(req)->serial_offset, serial);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new(
|
||||
RadioClient* client,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
return client ? radio_request_object_new(RADIO_BASE(client), NULL,
|
||||
code, writer, (RadioRequestGenericCompleteFunc) complete,
|
||||
destroy, user_data) : NULL;
|
||||
}
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new2(
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
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 */
|
||||
{
|
||||
return config ? radio_request_object_new(RADIO_BASE(config), NULL,
|
||||
code, writer, (RadioRequestGenericCompleteFunc) complete,
|
||||
destroy, user_data) : NULL;
|
||||
}
|
||||
|
||||
RadioRequest*
|
||||
radio_request_ref(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_unref(
|
||||
RadioRequest* req)
|
||||
{
|
||||
radio_request_object_unref(radio_request_cast(req));
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_blocking(
|
||||
RadioRequest* req,
|
||||
gboolean blocking)
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->blocking = blocking;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_timeout(
|
||||
RadioRequest* req,
|
||||
guint ms)
|
||||
{
|
||||
if (G_LIKELY(req) && req->timeout_ms != ms) {
|
||||
RadioBase* base = req->object;
|
||||
|
||||
req->timeout_ms = ms;
|
||||
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_base_reset_timeout(base);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_retry(
|
||||
RadioRequest* req,
|
||||
guint delay_ms, /* Delay before each retry, in milliseconds */
|
||||
int max_count) /* Negative count to keep retrying indefinitely */
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->retry_delay_ms = delay_ms;
|
||||
req->max_retries = max_count;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_retry_func(
|
||||
RadioRequest* req,
|
||||
RadioRequestRetryFunc retry)
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->retry = retry ? retry : radio_request_default_retry;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
radio_request_submit(
|
||||
RadioRequest* req)
|
||||
{
|
||||
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->object && radio_base_retry_request(req->object, req);
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_cancel(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
req->complete = NULL;
|
||||
radio_request_object_cancel(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_drop(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
req->complete = NULL;
|
||||
radio_request_object_cancel(self);
|
||||
radio_request_object_unref(self);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
radio_request_user_data(
|
||||
RadioRequest* req) /* Since 1.4.11 */
|
||||
{
|
||||
return G_LIKELY(req) ? req->user_data : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
224
src/radio_request_group.c
Normal file
224
src/radio_request_group.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "radio_base.h"
|
||||
#include "radio_client.h"
|
||||
#include "radio_request_group_p.h"
|
||||
#include "radio_request_p.h"
|
||||
#include "radio_log.h"
|
||||
|
||||
#include <gutil_macros.h>
|
||||
|
||||
typedef struct radio_request_group_object {
|
||||
RadioRequestGroup pub;
|
||||
GHashTable* requests;
|
||||
gint refcount;
|
||||
} RadioRequestGroupObject;
|
||||
|
||||
static inline RadioRequestGroupObject*
|
||||
radio_request_group_cast(RadioRequestGroup* group)
|
||||
{ return group ? G_CAST(group, RadioRequestGroupObject, pub) : NULL; }
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_group_unlink_func(
|
||||
gpointer req)
|
||||
{
|
||||
((RadioRequest*)req)->group = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_group_free(
|
||||
RadioRequestGroupObject* self)
|
||||
{
|
||||
RadioRequestGroup* group = &self->pub;
|
||||
|
||||
radio_base_unblock(RADIO_BASE(group->client), group);
|
||||
g_hash_table_destroy(self->requests);
|
||||
radio_client_unref(group->client);
|
||||
gutil_slice_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_group_add(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
/* Request is never NULL but the group may be */
|
||||
if (self) {
|
||||
g_hash_table_insert(self->requests, req, req);
|
||||
req->group = group;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_remove(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
/* Request is never NULL but the group may be */
|
||||
if (self) {
|
||||
g_hash_table_remove(self->requests, req);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_new(
|
||||
RadioClient* client)
|
||||
{
|
||||
if (G_LIKELY(client)) {
|
||||
RadioRequestGroupObject* self = g_slice_new0(RadioRequestGroupObject);
|
||||
RadioRequestGroup* group = &self->pub;
|
||||
|
||||
group->client = radio_client_ref(client);
|
||||
self->requests = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
||||
NULL, radio_request_group_unlink_func);
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
return group;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_ref(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_unref(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
radio_request_group_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_cancel(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GHashTableIter it;
|
||||
gpointer value;
|
||||
GSList* list = NULL;
|
||||
GSList* l;
|
||||
|
||||
/*
|
||||
* Move requests to the list and temporarily reference them
|
||||
* before invoking any callbacks.
|
||||
*/
|
||||
g_hash_table_iter_init(&it, self->requests);
|
||||
while (g_hash_table_iter_next(&it, NULL, &value)) {
|
||||
list = g_slist_prepend(list, radio_request_ref(value));
|
||||
g_hash_table_iter_remove(&it);
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually cancel the requests. This invokes completion callbacks.
|
||||
* The group is already empty at this point.
|
||||
*/
|
||||
for (l = list; l; l = l->next) {
|
||||
radio_request_cancel(l->data);
|
||||
}
|
||||
|
||||
/* Release the temporary references */
|
||||
g_slist_free_full(list, radio_request_unref_func);
|
||||
}
|
||||
}
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block_status(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
return group ? radio_base_block_status(RADIO_BASE(group->client), group) :
|
||||
RADIO_BLOCK_NONE;
|
||||
}
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
return group ? radio_base_block(RADIO_BASE(group->client), group) :
|
||||
RADIO_BLOCK_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_unblock(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
if (group) {
|
||||
radio_base_unblock(RADIO_BASE(group->client), group);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
63
src/radio_request_group_p.h
Normal file
63
src/radio_request_group_p.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_REQUEST_GROUP_PRIVATE_H
|
||||
#define RADIO_REQUEST_GROUP_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include <radio_request_group.h>
|
||||
|
||||
void
|
||||
radio_request_group_add(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_request_group_remove(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REQUEST_GROUP_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
162
src/radio_request_p.h
Normal file
162
src/radio_request_p.h
Normal file
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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_REQUEST_PRIVATE_H
|
||||
#define RADIO_REQUEST_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_request.h"
|
||||
|
||||
/*
|
||||
* Request lifecycle
|
||||
* =================
|
||||
*
|
||||
* +=====+
|
||||
* | NEW | ----------------------[cancel]------------+
|
||||
* +=====+ |
|
||||
* | |
|
||||
* [submit] |
|
||||
* | |
|
||||
* | |
|
||||
* +----> +---------------+ |
|
||||
* | | | |
|
||||
* | | (blocked) |
|
||||
* | (unblocked) | |
|
||||
* | | v v
|
||||
* | | +========+ +===========+
|
||||
* (retry) | | QUEUED | ----[cancel]----> | CANCELLED |
|
||||
* | | +========+ +===========+
|
||||
* | | | ^
|
||||
* | | (unblocked) |
|
||||
* | | | |
|
||||
* | | +----------+ |
|
||||
* | | | |
|
||||
* | v v |
|
||||
* | +-------------+ |
|
||||
* | | submit | +========+ |
|
||||
* | | request | ---(error)---> | FAILED | |
|
||||
* | | transaction | +========+ |
|
||||
* | +-------------+ ^ |
|
||||
* | | | |
|
||||
* | (ok) +---(error)---------+ |
|
||||
* | | / |
|
||||
* | v / |
|
||||
* | +=========+ +=========+ |
|
||||
* +--- | PENDING | ---(timeout)---> | TIMEOUT | |
|
||||
* +=========+ +=========+ |
|
||||
* | \ |
|
||||
* | +----------------[cancel]------------+
|
||||
* (response)
|
||||
* |
|
||||
* v
|
||||
* +======+
|
||||
* | DONE |
|
||||
* +======+
|
||||
*
|
||||
* Timeout starts ticking when request enters the PENDING state.
|
||||
* The library maintains an internal reference to the request in
|
||||
* QUEUED and PENDING states.
|
||||
*/
|
||||
|
||||
typedef enum radio_request_state {
|
||||
RADIO_REQUEST_STATE_INVALID,
|
||||
RADIO_REQUEST_STATE_NEW,
|
||||
RADIO_REQUEST_STATE_QUEUED,
|
||||
RADIO_REQUEST_STATE_PENDING,
|
||||
/*
|
||||
* Reorder states carefully or better don't reorder at all.
|
||||
* States >= RADIO_REQUEST_STATE_FAILED are assumed to be
|
||||
* terminal states in the state machine.
|
||||
*/
|
||||
RADIO_REQUEST_STATE_FAILED,
|
||||
RADIO_REQUEST_STATE_CANCELLED,
|
||||
RADIO_REQUEST_STATE_TIMEOUT,
|
||||
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;
|
||||
guint32 code;
|
||||
GBinderLocalRequest* args;
|
||||
RadioRequestGenericCompleteFunc complete;
|
||||
RadioRequestRetryFunc retry;
|
||||
void* user_data;
|
||||
guint32 serial; /* Immutable, generated at creation time */
|
||||
guint32 serial2; /* Mutable, used by the last transaction */
|
||||
int max_retries; /* Negative = retry indefinitely */
|
||||
int retry_count; /* Number of times we have already retried */
|
||||
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;
|
||||
RadioBase* object; /* Not a reference */
|
||||
RadioRequestGroup* group; /* Not a reference */
|
||||
RadioRequest* queue_next;
|
||||
};
|
||||
|
||||
void
|
||||
radio_request_unref_func(
|
||||
gpointer req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_request_update_serial(
|
||||
RadioRequest* req,
|
||||
guint32 serial)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REQUEST_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
75
src/radio_types_p.h
Normal file
75
src/radio_types_p.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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_TYPES_PRIVATE_H
|
||||
#define RADIO_TYPES_PRIVATE_H
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
611
src/radio_util.c
611
src/radio_util.c
@@ -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,30 +34,139 @@
|
||||
* 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)
|
||||
{
|
||||
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";
|
||||
return radio_req_name2(NULL, req);
|
||||
}
|
||||
|
||||
const char*
|
||||
radio_req_name2(
|
||||
RadioInstance* instance,
|
||||
RADIO_REQ req)
|
||||
{
|
||||
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_)
|
||||
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_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;
|
||||
}
|
||||
@@ -66,28 +175,128 @@ const char*
|
||||
radio_resp_name(
|
||||
RADIO_RESP resp)
|
||||
{
|
||||
switch (resp) {
|
||||
case RADIO_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
|
||||
return radio_resp_name2(NULL, resp);
|
||||
}
|
||||
|
||||
const char*
|
||||
radio_resp_name2(
|
||||
RadioInstance* instance,
|
||||
RADIO_RESP resp)
|
||||
{
|
||||
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_)
|
||||
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_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;
|
||||
}
|
||||
@@ -96,42 +305,340 @@ const char*
|
||||
radio_ind_name(
|
||||
RADIO_IND ind)
|
||||
{
|
||||
switch (ind) {
|
||||
return radio_ind_name2(NULL, ind);
|
||||
}
|
||||
|
||||
const char*
|
||||
radio_ind_name2(
|
||||
RadioInstance* instance,
|
||||
RADIO_IND ind)
|
||||
{
|
||||
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_)
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function no longer makes as much sense as it did in IRadio 1.0 times.
|
||||
* Later it turned out that that same call may produce different responses
|
||||
* under different circumstances. For example, getIccCardStatus call may
|
||||
* cause getIccCardStatusResponse or getIccCardStatusResponse_1_2 to be
|
||||
* sent back, depending on which interfaces are supported by the caller.
|
||||
* There's no longer one-to-one match between requests and responses,
|
||||
* that would be too easy and straightforward for Google designers :)
|
||||
*
|
||||
* Use this function carefully or better don't use it at all.
|
||||
*/
|
||||
RADIO_RESP
|
||||
radio_req_resp(
|
||||
RADIO_REQ req)
|
||||
{
|
||||
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_)
|
||||
#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_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 */
|
||||
{
|
||||
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
|
||||
|
||||
56
src/radio_util_p.h
Normal file
56
src/radio_util_p.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_UTIL_PRIVATE_H
|
||||
#define RADIO_UTIL_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_util.h"
|
||||
|
||||
guint
|
||||
radio_observer_priority_index(
|
||||
RADIO_OBSERVER_PRIORITY priority)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_UTIL_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
15
unit/Makefile
Normal file
15
unit/Makefile
Normal file
@@ -0,0 +1,15 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all:
|
||||
%:
|
||||
@$(MAKE) -C unit_client $*
|
||||
@$(MAKE) -C unit_config $*
|
||||
@$(MAKE) -C unit_instance $*
|
||||
@$(MAKE) -C unit_registry $*
|
||||
@$(MAKE) -C unit_util $*
|
||||
|
||||
clean: unitclean
|
||||
rm -f coverage/*.gcov
|
||||
rm -fr coverage/report
|
||||
216
unit/common/Makefile
Normal file
216
unit/common/Makefile
Normal file
@@ -0,0 +1,216 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
.PHONY: clean cleaner unitclean all debug release coverage valgrind
|
||||
.PHONY: debug_lib release_lib coverage_lib
|
||||
.PHONY: test test_banner
|
||||
|
||||
#
|
||||
# Real test makefile defines EXE (and possibly SRC) and includes this one.
|
||||
#
|
||||
|
||||
ifndef EXE
|
||||
${error EXE not defined}
|
||||
endif
|
||||
|
||||
SRC ?= $(EXE).c
|
||||
COMMON_SRC ?= \
|
||||
test_gbinder_client.c \
|
||||
test_gbinder_local_object.c \
|
||||
test_gbinder_local_request.c \
|
||||
test_gbinder_local_reply.c \
|
||||
test_gbinder_reader_writer.c \
|
||||
test_gbinder_remote_object.c \
|
||||
test_gbinder_remote_request.c \
|
||||
test_gbinder_remote_reply.c \
|
||||
test_gbinder_servicemanager.c \
|
||||
test_main.c
|
||||
|
||||
#
|
||||
# Required packages
|
||||
#
|
||||
|
||||
LINK_PKGS += libglibutil glib-2.0 gobject-2.0
|
||||
PKGS += $(LINK_PKGS) libgbinder
|
||||
|
||||
#
|
||||
# Default target
|
||||
#
|
||||
|
||||
all: debug release
|
||||
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
|
||||
SRC_DIR = .
|
||||
LIB_DIR = ../..
|
||||
COMMON_DIR = ../common
|
||||
BUILD_DIR = build
|
||||
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
|
||||
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
|
||||
COVERAGE_BUILD_DIR = $(BUILD_DIR)/coverage
|
||||
COMMON_BUILD_DIR = $(COMMON_DIR)/build
|
||||
COMMON_DEBUG_BUILD_DIR = $(COMMON_BUILD_DIR)/debug
|
||||
COMMON_RELEASE_BUILD_DIR = $(COMMON_BUILD_DIR)/release
|
||||
COMMON_COVERAGE_BUILD_DIR = $(COMMON_BUILD_DIR)/coverage
|
||||
|
||||
#
|
||||
# Tools and flags
|
||||
#
|
||||
|
||||
CC ?= $(CROSS_COMPILE)gcc
|
||||
LD = $(CC)
|
||||
WARNINGS += -Wall -Wno-deprecated-declarations
|
||||
INCLUDES += -I$(COMMON_DIR) -I$(LIB_DIR)/src -I$(LIB_DIR)/include
|
||||
BASE_FLAGS = -fPIC
|
||||
FULL_CFLAGS = $(BASE_FLAGS) $(CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) \
|
||||
-MMD -MP $(shell pkg-config --cflags $(PKGS))
|
||||
FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS)
|
||||
LIBS = $(shell pkg-config --libs $(LINK_PKGS)) -lpthread
|
||||
QUIET_MAKE = make --no-print-directory
|
||||
DEBUG_FLAGS = -g
|
||||
RELEASE_FLAGS =
|
||||
COVERAGE_FLAGS = -g
|
||||
|
||||
DEBUG_LDFLAGS = $(FULL_LDFLAGS) $(DEBUG_FLAGS)
|
||||
RELEASE_LDFLAGS = $(FULL_LDFLAGS) $(RELEASE_FLAGS)
|
||||
COVERAGE_LDFLAGS = $(FULL_LDFLAGS) $(COVERAGE_FLAGS) --coverage
|
||||
|
||||
DEBUG_CFLAGS = $(FULL_CFLAGS) $(DEBUG_FLAGS) -DDEBUG
|
||||
RELEASE_CFLAGS = $(FULL_CFLAGS) $(RELEASE_FLAGS) -O2
|
||||
COVERAGE_CFLAGS = $(FULL_CFLAGS) $(COVERAGE_FLAGS) --coverage
|
||||
|
||||
DEBUG_LIB_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_debug_lib)
|
||||
RELEASE_LIB_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_release_lib)
|
||||
COVERAGE_LIB_FILE := $(shell $(QUIET_MAKE) -C $(LIB_DIR) print_coverage_lib)
|
||||
|
||||
DEBUG_LIB = $(LIB_DIR)/$(DEBUG_LIB_FILE)
|
||||
RELEASE_LIB = $(LIB_DIR)/$(RELEASE_LIB_FILE)
|
||||
COVERAGE_LIB = $(LIB_DIR)/$(COVERAGE_LIB_FILE)
|
||||
|
||||
DEBUG_LIBS = $(DEBUG_LIB) $(LIBS)
|
||||
RELEASE_LIBS = $(RELEASE_LIB) $(LIBS)
|
||||
COVERAGE_LIBS = $(COVERAGE_LIB) $(LIBS)
|
||||
|
||||
#
|
||||
# Files
|
||||
#
|
||||
|
||||
TEST_DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
|
||||
TEST_RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
|
||||
TEST_COVERAGE_OBJS = $(SRC:%.c=$(COVERAGE_BUILD_DIR)/%.o)
|
||||
COMMON_DEBUG_OBJS = $(COMMON_SRC:%.c=$(COMMON_DEBUG_BUILD_DIR)/%.o)
|
||||
COMMON_RELEASE_OBJS = $(COMMON_SRC:%.c=$(COMMON_RELEASE_BUILD_DIR)/%.o)
|
||||
COMMON_COVERAGE_OBJS = $(COMMON_SRC:%.c=$(COMMON_COVERAGE_BUILD_DIR)/%.o)
|
||||
DEBUG_OBJS = $(COMMON_DEBUG_OBJS) $(TEST_DEBUG_OBJS)
|
||||
RELEASE_OBJS = $(COMMON_RELEASE_OBJS) $(TEST_RELEASE_OBJS)
|
||||
COVERAGE_OBJS = $(COMMON_COVERAGE_OBJS) $(TEST_COVERAGE_OBJS)
|
||||
|
||||
#
|
||||
# Dependencies
|
||||
#
|
||||
|
||||
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
|
||||
ifneq ($(MAKECMDGOALS),clean)
|
||||
ifneq ($(strip $(DEPS)),)
|
||||
-include $(DEPS)
|
||||
endif
|
||||
endif
|
||||
|
||||
$(DEBUG_LIB): | debug_lib
|
||||
$(RELEASE_LIB): | release_lib
|
||||
$(COVERAGE_LIB): | coverage_lib
|
||||
|
||||
$(TEST_DEBUG_OBJS): | $(DEBUG_BUILD_DIR)
|
||||
$(TEST_RELEASE_OBJS): | $(RELEASE_BUILD_DIR)
|
||||
$(TEST_COVERAGE_OBJS): | $(COVERAGE_BUILD_DIR)
|
||||
|
||||
$(COMMON_DEBUG_OBJS): | $(COMMON_DEBUG_BUILD_DIR)
|
||||
$(COMMON_RELEASE_OBJS): | $(COMMON_RELEASE_BUILD_DIR)
|
||||
$(COMMON_COVERAGE_OBJS): | $(COMMON_COVERAGE_BUILD_DIR)
|
||||
|
||||
#
|
||||
# Rules
|
||||
#
|
||||
|
||||
DEBUG_EXE = $(DEBUG_BUILD_DIR)/$(EXE)
|
||||
RELEASE_EXE = $(RELEASE_BUILD_DIR)/$(EXE)
|
||||
COVERAGE_EXE = $(COVERAGE_BUILD_DIR)/$(EXE)
|
||||
|
||||
debug: debug_lib $(DEBUG_EXE)
|
||||
|
||||
release: release_lib $(RELEASE_EXE)
|
||||
|
||||
coverage: coverage_lib $(COVERAGE_EXE)
|
||||
|
||||
unitclean:
|
||||
rm -f *~
|
||||
rm -fr $(BUILD_DIR) $(COMMON_BUILD_DIR)
|
||||
|
||||
clean: unitclean
|
||||
|
||||
cleaner: unitclean
|
||||
@make -C $(LIB_DIR) clean
|
||||
|
||||
test_banner:
|
||||
@echo "===========" $(EXE) "=========== "
|
||||
|
||||
test: test_banner debug
|
||||
@$(DEBUG_EXE)
|
||||
|
||||
valgrind: test_banner debug
|
||||
@G_DEBUG=gc-friendly G_SLICE=always-malloc valgrind --tool=memcheck --leak-check=full --show-possibly-lost=no $(DEBUG_EXE)
|
||||
|
||||
$(DEBUG_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(RELEASE_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(COVERAGE_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(COMMON_DEBUG_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(COMMON_RELEASE_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(COMMON_COVERAGE_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
$(DEBUG_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
|
||||
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(RELEASE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
|
||||
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(COVERAGE_BUILD_DIR)/%.o : $(SRC_DIR)/%.c
|
||||
$(CC) -c $(COVERAGE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(COMMON_DEBUG_BUILD_DIR)/%.o : $(COMMON_DIR)/%.c
|
||||
$(CC) -c $(DEBUG_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(COMMON_RELEASE_BUILD_DIR)/%.o : $(COMMON_DIR)/%.c
|
||||
$(CC) -c $(RELEASE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(COMMON_COVERAGE_BUILD_DIR)/%.o : $(COMMON_DIR)/%.c
|
||||
$(CC) -c $(COVERAGE_CFLAGS) -MT"$@" -MF"$(@:%.o=%.d)" $< -o $@
|
||||
|
||||
$(DEBUG_EXE): $(DEBUG_LIB) $(DEBUG_OBJS)
|
||||
$(LD) $(DEBUG_LDFLAGS) $(DEBUG_OBJS) $(DEBUG_LIBS) -o $@
|
||||
|
||||
$(RELEASE_EXE): $(RELEASE_LIB) $(RELEASE_OBJS)
|
||||
$(LD) $(RELEASE_LDFLAGS) $(RELEASE_OBJS) $(RELEASE_LIBS) -o $@
|
||||
|
||||
$(COVERAGE_EXE): $(COVERAG_LIB) $(COVERAGE_OBJS)
|
||||
$(LD) $(COVERAGE_LDFLAGS) $(COVERAGE_OBJS) $(COVERAGE_LIBS) -o $@
|
||||
|
||||
debug_lib:
|
||||
$(MAKE) -C $(LIB_DIR) $@
|
||||
|
||||
release_lib:
|
||||
$(MAKE) -C $(LIB_DIR) $@
|
||||
|
||||
coverage_lib:
|
||||
$(MAKE) -C $(LIB_DIR) $@
|
||||
109
unit/common/test_common.h
Normal file
109
unit/common/test_common.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef TEST_COMMON_H
|
||||
#define TEST_COMMON_H
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
#define TEST_FLAG_DEBUG (0x01)
|
||||
typedef struct test_opt {
|
||||
int flags;
|
||||
} TestOpt;
|
||||
|
||||
/* Should be invoked after g_test_init */
|
||||
void
|
||||
test_init(
|
||||
TestOpt* opt,
|
||||
int argc,
|
||||
char* argv[]);
|
||||
|
||||
/* Run loop with a timeout */
|
||||
void
|
||||
test_run(
|
||||
const TestOpt* opt,
|
||||
GMainLoop* loop);
|
||||
|
||||
/* Quits the event loop on the next iteration */
|
||||
void
|
||||
test_quit_later(
|
||||
GMainLoop* loop);
|
||||
|
||||
/* Quits the event loop after n iterations */
|
||||
void
|
||||
test_quit_later_n(
|
||||
GMainLoop* loop,
|
||||
guint n);
|
||||
|
||||
#define TEST_TIMEOUT_SEC (20)
|
||||
#define TEST_TIMEOUT_MS (1000*TEST_TIMEOUT_SEC)
|
||||
|
||||
/* Helper macros */
|
||||
|
||||
#if G_BYTE_ORDER == G_LITTLE_ENDIAN
|
||||
# define TEST_INT16_BYTES(v) \
|
||||
(guint8)(v), (guint8)((v) >> 8)
|
||||
# define TEST_INT32_BYTES(v) \
|
||||
(guint8)(v), (guint8)((v) >> 8), \
|
||||
(guint8)((v) >> 16), (guint8)((v) >> 24)
|
||||
# define TEST_INT64_BYTES(v) \
|
||||
(guint8)(v), (guint8)((v) >> 8), \
|
||||
(guint8)((v) >> 16), (guint8)((v) >> 24), \
|
||||
(guint8)(((guint64)(v)) >> 32), (guint8)(((guint64)(v)) >> 40), \
|
||||
(guint8)(((guint64)(v)) >> 48), (guint8)(((guint64)(v)) >> 56)
|
||||
#elif G_BYTE_ORDER == G_BIG_ENDIAN
|
||||
# define TEST_INT16_BYTES(v) \
|
||||
(guint8)((v) >> 8), (guint8)(v)
|
||||
# define TEST_INT32_BYTES(v) \
|
||||
(guint8)((v) >> 24), (guint8)((v) >> 16), \
|
||||
(guint8)((v) >> 8), (guint8)(v)
|
||||
# define TEST_INT64_BYTES(v) \
|
||||
(guint8)(((guint64)(v)) >> 56), (guint8)(((guint64)(v)) >> 48), \
|
||||
(guint8)(((guint64)(v)) >> 40), (guint8)(((guint64)(v)) >> 32), \
|
||||
(guint8)((v) >> 24), (guint8)((v) >> 16), \
|
||||
(guint8)((v) >> 8), (guint8)(v)
|
||||
#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
|
||||
#error unknown ENDIAN type
|
||||
#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
|
||||
|
||||
#define TEST_ARRAY_AND_COUNT(a) a, G_N_ELEMENTS(a)
|
||||
#define TEST_ARRAY_AND_SIZE(a) a, sizeof(a)
|
||||
|
||||
#endif /* TEST_COMMON_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
165
unit/common/test_gbinder.h
Normal file
165
unit/common/test_gbinder.h
Normal file
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef TEST_GBINDER_H
|
||||
#define TEST_GBINDER_H
|
||||
|
||||
#include <gbinder.h>
|
||||
|
||||
typedef struct test_gbinder_data TestGBinderData;
|
||||
|
||||
/* test_gbinder_reader_writer.c */
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_new(
|
||||
const char* iface);
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_ref(
|
||||
TestGBinderData* data);
|
||||
|
||||
void
|
||||
test_gbinder_data_unref(
|
||||
TestGBinderData* data);
|
||||
|
||||
void
|
||||
test_gbinder_data_add_int32(
|
||||
TestGBinderData* data,
|
||||
guint32 value);
|
||||
|
||||
void
|
||||
test_gbinder_data_add_hidl_struct(
|
||||
TestGBinderData* data,
|
||||
const void* buf,
|
||||
gsize size);
|
||||
|
||||
void
|
||||
test_gbinder_data_init_reader(
|
||||
TestGBinderData* data,
|
||||
GBinderReader* reader);
|
||||
|
||||
void
|
||||
test_gbinder_data_init_writer(
|
||||
TestGBinderData* data,
|
||||
GBinderWriter* writer);
|
||||
|
||||
/* test_gbinder_local_request.c */
|
||||
|
||||
GBinderLocalRequest*
|
||||
test_gbinder_local_request_new(
|
||||
const char* iface);
|
||||
|
||||
const char*
|
||||
test_gbinder_local_request_interface(
|
||||
GBinderLocalRequest* local);
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_local_request_data(
|
||||
GBinderLocalRequest* local);
|
||||
|
||||
/* test_gbinder_local_reply.c */
|
||||
|
||||
GBinderLocalReply*
|
||||
test_gbinder_local_reply_new(
|
||||
void);
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_local_reply_data(
|
||||
GBinderLocalReply* reply);
|
||||
|
||||
/* test_gbinder_remote_request.c */
|
||||
|
||||
GBinderRemoteRequest*
|
||||
test_gbinder_remote_request_new(
|
||||
GBinderLocalRequest* req);
|
||||
|
||||
/* test_gbinder_remote_reply.c */
|
||||
|
||||
GBinderRemoteReply*
|
||||
test_gbinder_remote_reply_new(
|
||||
GBinderLocalReply* reply);
|
||||
|
||||
/* test_gbinder_local_object.c */
|
||||
|
||||
GBinderLocalObject*
|
||||
test_gbinder_local_object_new(
|
||||
const char* const* ifaces,
|
||||
GBinderLocalTransactFunc txproc,
|
||||
void* user_data);
|
||||
|
||||
GBinderLocalReply*
|
||||
test_gbinder_local_object_handle_tx(
|
||||
GBinderLocalObject* self,
|
||||
GBinderRemoteRequest* req,
|
||||
guint code,
|
||||
guint flags,
|
||||
int* status);
|
||||
|
||||
/* test_gbinder_remote_object.c */
|
||||
|
||||
GBinderRemoteObject*
|
||||
test_gbinder_remote_object_new(
|
||||
GBinderLocalObject* local);
|
||||
|
||||
void
|
||||
test_gbinder_remote_object_kill(
|
||||
GBinderRemoteObject* remote);
|
||||
|
||||
gboolean
|
||||
test_gbinder_remote_object_dead(
|
||||
GBinderRemoteObject* remote);
|
||||
|
||||
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*
|
||||
test_gbinder_servicemanager_new_service(
|
||||
GBinderServiceManager* manager,
|
||||
const char* name,
|
||||
GBinderLocalObject* local);
|
||||
|
||||
#endif /* TEST_GBINDER_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
402
unit/common/test_gbinder_client.c
Normal file
402
unit/common/test_gbinder_client.c
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "test_gbinder.h"
|
||||
|
||||
#include <gutil_log.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct test_gbinder_client_tx {
|
||||
GBinderClient* client;
|
||||
guint32 code;
|
||||
guint32 flags;
|
||||
GBinderLocalRequest* req;
|
||||
GBinderClientReplyFunc reply;
|
||||
GDestroyNotify destroy;
|
||||
void* user_data;
|
||||
} TestGBinderClientTx;
|
||||
|
||||
typedef struct test_gbinder_client_iface_range {
|
||||
char* iface;
|
||||
GBytes* header;
|
||||
guint32 last_code;
|
||||
} TestGBinderClientIfaceRange;
|
||||
|
||||
struct gbinder_client {
|
||||
guint32 refcount;
|
||||
GBinderRemoteObject* remote;
|
||||
TestGBinderClientIfaceRange* ranges;
|
||||
guint nr;
|
||||
};
|
||||
|
||||
int test_gbinder_client_tx_fail_count = 0;
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_client_free(
|
||||
GBinderClient* self)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->nr; i++) {
|
||||
TestGBinderClientIfaceRange* r = self->ranges + i;
|
||||
|
||||
g_bytes_unref(r->header);
|
||||
g_free(r->iface);
|
||||
}
|
||||
g_free(self->ranges);
|
||||
gbinder_remote_object_unref(self->remote);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_client_init_range(
|
||||
TestGBinderClientIfaceRange* r,
|
||||
const GBinderClientIfaceInfo* info)
|
||||
{
|
||||
r->header = g_bytes_new(info->iface, strlen(info->iface));
|
||||
r->iface = g_strdup(info->iface);
|
||||
r->last_code = info->last_code;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
test_gbinder_client_sort_ranges(
|
||||
const void* p1,
|
||||
const void* p2)
|
||||
{
|
||||
const TestGBinderClientIfaceRange* r1 = p1;
|
||||
const TestGBinderClientIfaceRange* r2 = p2;
|
||||
|
||||
return (r1->last_code < r2->last_code) ? (-1) :
|
||||
(r1->last_code > r2->last_code) ? 1 : 0;
|
||||
}
|
||||
|
||||
static
|
||||
const TestGBinderClientIfaceRange*
|
||||
test_gbinder_client_find_range(
|
||||
GBinderClient* self,
|
||||
guint32 code)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->nr; i++) {
|
||||
const TestGBinderClientIfaceRange* r = self->ranges + i;
|
||||
|
||||
if (r->last_code >= code) {
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
GBinderRemoteReply*
|
||||
test_gbinder_client_transact(
|
||||
GBinderClient* self,
|
||||
guint32 code,
|
||||
guint32 flags,
|
||||
GBinderLocalRequest* req,
|
||||
int* status)
|
||||
{
|
||||
GBinderLocalObject* obj = test_gbinder_remote_object_to_local(self->remote);
|
||||
GBinderRemoteRequest* remote_req = test_gbinder_remote_request_new(req);
|
||||
GBinderLocalReply* reply = test_gbinder_local_object_handle_tx(obj,
|
||||
remote_req, code, flags, status);
|
||||
GBinderRemoteReply* remote_reply = test_gbinder_remote_reply_new(reply);
|
||||
|
||||
gbinder_remote_request_unref(remote_req);
|
||||
gbinder_local_reply_unref(reply);
|
||||
return remote_reply;
|
||||
}
|
||||
|
||||
static
|
||||
GBinderRemoteReply*
|
||||
test_gbinder_client_transact_sync(
|
||||
GBinderClient* self,
|
||||
guint32 code,
|
||||
guint32 flags,
|
||||
GBinderLocalRequest* req,
|
||||
int* status)
|
||||
{
|
||||
GBinderRemoteReply* reply = NULL;
|
||||
|
||||
if (self) {
|
||||
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 (req) {
|
||||
reply = test_gbinder_client_transact(self, code, flags, req,
|
||||
status);
|
||||
}
|
||||
gbinder_local_request_unref(tmp);
|
||||
} else {
|
||||
GDEBUG("Refusing to perform transaction with a dead object");
|
||||
}
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
test_gbinder_client_tx_handle(
|
||||
gpointer data)
|
||||
{
|
||||
int status = -1;
|
||||
TestGBinderClientTx* tx = data;
|
||||
GBinderRemoteReply* reply = test_gbinder_client_transact
|
||||
(tx->client, tx->code, tx->flags, tx->req, &status);
|
||||
|
||||
if (tx->reply) {
|
||||
tx->reply(tx->client, reply, status, tx->user_data);
|
||||
}
|
||||
gbinder_remote_reply_unref(reply);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_client_tx_destroy(
|
||||
gpointer data)
|
||||
{
|
||||
TestGBinderClientTx* tx = data;
|
||||
|
||||
if (tx->destroy) {
|
||||
tx->destroy(tx->user_data);
|
||||
}
|
||||
gbinder_local_request_unref(tx->req);
|
||||
gbinder_client_unref(tx->client);
|
||||
g_free(tx);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderClient*
|
||||
gbinder_client_new2(
|
||||
GBinderRemoteObject* remote,
|
||||
const GBinderClientIfaceInfo* ifaces,
|
||||
gsize count)
|
||||
{
|
||||
if (remote) {
|
||||
GBinderClient* self = g_new0(GBinderClient, 1);
|
||||
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->remote = gbinder_remote_object_ref(remote);
|
||||
if (count > 0) {
|
||||
gsize i;
|
||||
|
||||
self->nr = count;
|
||||
self->ranges = g_new(TestGBinderClientIfaceRange, self->nr);
|
||||
for (i = 0; i < count; i++) {
|
||||
test_gbinder_client_init_range(self->ranges + i, ifaces + i);
|
||||
}
|
||||
qsort(self->ranges, count, sizeof(TestGBinderClientIfaceRange),
|
||||
test_gbinder_client_sort_ranges);
|
||||
} else {
|
||||
/* No interface info */
|
||||
self->nr = 1;
|
||||
self->ranges = g_new0(TestGBinderClientIfaceRange, 1);
|
||||
self->ranges[0].last_code = UINT_MAX;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBinderClient*
|
||||
gbinder_client_ref(
|
||||
GBinderClient* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_client_unref(
|
||||
GBinderClient* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_client_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GBytes*
|
||||
gbinder_client_rpc_header(
|
||||
GBinderClient* self,
|
||||
guint32 code)
|
||||
{
|
||||
if (self) {
|
||||
const TestGBinderClientIfaceRange* r =
|
||||
test_gbinder_client_find_range(self, code);
|
||||
|
||||
if (r) {
|
||||
return r->header;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBinderLocalRequest*
|
||||
gbinder_client_new_request2(
|
||||
GBinderClient* self,
|
||||
guint32 code)
|
||||
{
|
||||
if (self) {
|
||||
const TestGBinderClientIfaceRange* r =
|
||||
test_gbinder_client_find_range(self, code);
|
||||
|
||||
if (r) {
|
||||
return test_gbinder_local_request_new(r->iface);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBinderRemoteReply*
|
||||
gbinder_client_transact_sync_reply(
|
||||
GBinderClient* self,
|
||||
guint32 code,
|
||||
GBinderLocalRequest* req,
|
||||
int* status)
|
||||
{
|
||||
return test_gbinder_client_transact_sync(self, code, 0, req, status);
|
||||
}
|
||||
|
||||
int
|
||||
gbinder_client_transact_sync_oneway(
|
||||
GBinderClient* self,
|
||||
guint32 code,
|
||||
GBinderLocalRequest* req)
|
||||
{
|
||||
int status = -1;
|
||||
|
||||
g_assert(!test_gbinder_client_transact_sync(self, code,
|
||||
GBINDER_TX_FLAG_ONEWAY, req, &status));
|
||||
return status;
|
||||
}
|
||||
|
||||
gulong
|
||||
gbinder_client_transact(
|
||||
GBinderClient* self,
|
||||
guint32 code,
|
||||
guint32 flags,
|
||||
GBinderLocalRequest* req,
|
||||
GBinderClientReplyFunc reply,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
gulong id = 0;
|
||||
|
||||
if (self) {
|
||||
GBinderRemoteObject* obj = self->remote;
|
||||
|
||||
if (!test_gbinder_remote_object_dead(obj)) {
|
||||
if (test_gbinder_client_tx_fail_count) {
|
||||
if (test_gbinder_client_tx_fail_count > 0) {
|
||||
test_gbinder_client_tx_fail_count--;
|
||||
}
|
||||
GDEBUG("Simulating transaction failure");
|
||||
} else {
|
||||
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 (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);
|
||||
}
|
||||
} else {
|
||||
GDEBUG("Refusing to perform transaction with a dead object");
|
||||
}
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_client_cancel(
|
||||
GBinderClient* self,
|
||||
gulong id)
|
||||
{
|
||||
if (id) {
|
||||
g_source_remove((guint)id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
164
unit/common/test_gbinder_local_object.c
Normal file
164
unit/common/test_gbinder_local_object.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
#include <gutil_strv.h>
|
||||
|
||||
struct gbinder_local_object {
|
||||
guint32 refcount;
|
||||
char** ifaces;
|
||||
GBinderLocalTransactFunc txproc;
|
||||
void* user_data;
|
||||
GBINDER_STABILITY_LEVEL stability;
|
||||
};
|
||||
|
||||
static const char hidl_base_interface[] = "android.hidl.base@1.0::IBase";
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_local_object_free(
|
||||
GBinderLocalObject* self)
|
||||
{
|
||||
g_strfreev(self->ifaces);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalObject*
|
||||
test_gbinder_local_object_new(
|
||||
const char* const* ifaces,
|
||||
GBinderLocalTransactFunc txproc,
|
||||
void* user_data)
|
||||
{
|
||||
GBinderLocalObject* self = g_new0(GBinderLocalObject, 1);
|
||||
guint i = 0, n = gutil_strv_length((char**)ifaces);
|
||||
gboolean append_base_interface;
|
||||
|
||||
if (g_strcmp0(gutil_strv_last((char**)ifaces), hidl_base_interface)) {
|
||||
append_base_interface = TRUE;
|
||||
n++;
|
||||
} else {
|
||||
append_base_interface = FALSE;
|
||||
}
|
||||
|
||||
self->ifaces = g_new(char*, n + 1);
|
||||
if (ifaces) {
|
||||
while (*ifaces) {
|
||||
self->ifaces[i++] = g_strdup(*ifaces++);
|
||||
}
|
||||
}
|
||||
if (append_base_interface) {
|
||||
self->ifaces[i++] = g_strdup(hidl_base_interface);
|
||||
}
|
||||
self->ifaces[i] = NULL;
|
||||
self->txproc = txproc;
|
||||
self->user_data = user_data;
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
return self;
|
||||
}
|
||||
|
||||
GBinderLocalReply*
|
||||
test_gbinder_local_object_handle_tx(
|
||||
GBinderLocalObject* self,
|
||||
GBinderRemoteRequest* req,
|
||||
guint code,
|
||||
guint flags,
|
||||
int* status)
|
||||
{
|
||||
return (self && self->txproc) ?
|
||||
self->txproc(self, req, code, flags, status, self->user_data) :
|
||||
NULL;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalObject*
|
||||
gbinder_local_object_ref(
|
||||
GBinderLocalObject* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_object_unref(
|
||||
GBinderLocalObject* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_local_object_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_object_drop(
|
||||
GBinderLocalObject* self)
|
||||
{
|
||||
if (self) {
|
||||
self->txproc = NULL;
|
||||
self->user_data = NULL;
|
||||
gbinder_local_object_unref(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_object_set_stability(
|
||||
GBinderLocalObject* self,
|
||||
GBINDER_STABILITY_LEVEL stability)
|
||||
{
|
||||
if (self) {
|
||||
self->stability = stability;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
118
unit/common/test_gbinder_local_reply.c
Normal file
118
unit/common/test_gbinder_local_reply.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
struct gbinder_local_reply {
|
||||
guint32 refcount;
|
||||
TestGBinderData* data;
|
||||
char* iface;
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_local_reply_free(
|
||||
GBinderLocalReply* self)
|
||||
{
|
||||
test_gbinder_data_unref(self->data);
|
||||
g_free(self->iface);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalReply*
|
||||
test_gbinder_local_reply_new(
|
||||
void)
|
||||
{
|
||||
GBinderLocalReply* self = g_new0(GBinderLocalReply, 1);
|
||||
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_new(NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_local_reply_data(
|
||||
GBinderLocalReply* self)
|
||||
{
|
||||
return self ? self->data : NULL;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalReply*
|
||||
gbinder_local_reply_ref(
|
||||
GBinderLocalReply* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_reply_unref(
|
||||
GBinderLocalReply* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_local_reply_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_reply_init_writer(
|
||||
GBinderLocalReply* self,
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
test_gbinder_data_init_writer(self->data, writer);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
141
unit/common/test_gbinder_local_request.c
Normal file
141
unit/common/test_gbinder_local_request.c
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
struct gbinder_local_request {
|
||||
guint32 refcount;
|
||||
TestGBinderData* data;
|
||||
char* iface;
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_local_request_free(
|
||||
GBinderLocalRequest* self)
|
||||
{
|
||||
test_gbinder_data_unref(self->data);
|
||||
g_free(self->iface);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalRequest*
|
||||
test_gbinder_local_request_new(
|
||||
const char* iface)
|
||||
{
|
||||
GBinderLocalRequest* self = g_new0(GBinderLocalRequest, 1);
|
||||
|
||||
g_assert(iface);
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_new(iface);
|
||||
self->iface = g_strdup(iface);
|
||||
return self;
|
||||
}
|
||||
|
||||
const char*
|
||||
test_gbinder_local_request_interface(
|
||||
GBinderLocalRequest* self)
|
||||
{
|
||||
return self ? self->iface : NULL;
|
||||
}
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_local_request_data(
|
||||
GBinderLocalRequest* self)
|
||||
{
|
||||
return self ? self->data : NULL;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderLocalRequest*
|
||||
gbinder_local_request_ref(
|
||||
GBinderLocalRequest* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_request_unref(
|
||||
GBinderLocalRequest* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_local_request_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_local_request_init_writer(
|
||||
GBinderLocalRequest* self,
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
test_gbinder_data_init_writer(self->data, writer);
|
||||
}
|
||||
|
||||
GBinderLocalRequest*
|
||||
gbinder_local_request_append_int32(
|
||||
GBinderLocalRequest* self,
|
||||
guint32 value)
|
||||
{
|
||||
if (self) {
|
||||
GBinderWriter writer;
|
||||
|
||||
test_gbinder_data_init_writer(self->data, &writer);
|
||||
gbinder_writer_append_int32(&writer, value);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
506
unit/common/test_gbinder_reader_writer.c
Normal file
506
unit/common/test_gbinder_reader_writer.c
Normal file
@@ -0,0 +1,506 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_idlepool.h>
|
||||
|
||||
typedef enum test_gbinder_data_type {
|
||||
DATA_TYPE_BOOLEAN,
|
||||
DATA_TYPE_INT32,
|
||||
DATA_TYPE_BUFFER,
|
||||
DATA_TYPE_LOCAL_OBJ
|
||||
} DATA_TYPE;
|
||||
|
||||
typedef struct test_gbinder_data_item TestGBinderDataItem;
|
||||
struct test_gbinder_data_item {
|
||||
TestGBinderDataItem* next;
|
||||
DATA_TYPE type;
|
||||
union {
|
||||
gboolean b;
|
||||
gint32 i32;
|
||||
struct {
|
||||
void* buf;
|
||||
gsize size;
|
||||
} blob;
|
||||
GBinderLocalObject* obj;
|
||||
} data;
|
||||
void (*destroy)(TestGBinderDataItem*);
|
||||
};
|
||||
|
||||
struct test_gbinder_data {
|
||||
guint32 refcount;
|
||||
TestGBinderDataItem* items;
|
||||
GUtilIdlePool* pool;
|
||||
char* iface;
|
||||
};
|
||||
|
||||
typedef struct test_gbinder_reader {
|
||||
TestGBinderDataItem* item;
|
||||
} TestGBinderReader;
|
||||
|
||||
typedef struct test_gbinder_writer {
|
||||
TestGBinderData* data;
|
||||
} TestGBinderWriter;
|
||||
|
||||
static inline TestGBinderReader* test_gbinder_reader_cast(GBinderReader* reader)
|
||||
{ return (TestGBinderReader*)reader; }
|
||||
|
||||
static inline TestGBinderWriter* test_gbinder_writer_cast(GBinderWriter* writer)
|
||||
{ return (TestGBinderWriter*)writer; }
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_item_destroy_local_obj(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
g_assert_cmpint(item->type, == ,DATA_TYPE_LOCAL_OBJ);
|
||||
gbinder_local_object_unref(item->data.obj);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_item_destroy_buffer(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
g_assert_cmpint(item->type, == ,DATA_TYPE_BUFFER);
|
||||
g_free(item->data.blob.buf);
|
||||
}
|
||||
|
||||
static
|
||||
TestGBinderDataItem*
|
||||
test_gbinder_data_item_new(
|
||||
DATA_TYPE type)
|
||||
{
|
||||
TestGBinderDataItem* item = g_new0(TestGBinderDataItem, 1);
|
||||
|
||||
item->type = type;
|
||||
return item;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_item_free(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
if (item) {
|
||||
test_gbinder_data_item_free(item->next);
|
||||
if (item->destroy) {
|
||||
item->destroy(item);
|
||||
}
|
||||
g_free(item);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_free(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
test_gbinder_data_item_free(data->items);
|
||||
gutil_idle_pool_destroy(data->pool);
|
||||
g_free(data->iface);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static
|
||||
guint
|
||||
test_gbinder_data_count_buffers(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
TestGBinderDataItem* item;
|
||||
guint n;
|
||||
|
||||
for (n = 0, item = data->items; item; item = item->next) {
|
||||
if (item->type == DATA_TYPE_BUFFER) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_append(
|
||||
TestGBinderData* data,
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
TestGBinderDataItem* last = data->items;
|
||||
|
||||
if (last) {
|
||||
while (last->next) {
|
||||
last = last->next;
|
||||
}
|
||||
last->next = item;
|
||||
} else {
|
||||
data->items = item;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gsize
|
||||
test_gbinder_data_item_size(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
switch (item->type) {
|
||||
case DATA_TYPE_BOOLEAN:
|
||||
return sizeof(item->data.b);
|
||||
case DATA_TYPE_INT32:
|
||||
return sizeof(item->data.i32);
|
||||
case DATA_TYPE_BUFFER:
|
||||
return sizeof(item->data.blob);
|
||||
case DATA_TYPE_LOCAL_OBJ:
|
||||
return sizeof(item->data.obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void*
|
||||
test_gbinder_data_buffer(
|
||||
TestGBinderData* data,
|
||||
gsize* out_size)
|
||||
{
|
||||
gsize size = 0;
|
||||
void* ptr = NULL;
|
||||
|
||||
if (data) {
|
||||
TestGBinderDataItem* item;
|
||||
GByteArray* buf = g_byte_array_new();
|
||||
|
||||
if (data->iface) {
|
||||
gsize header_size = strlen(data->iface);
|
||||
|
||||
g_byte_array_append(buf, (void*)data->iface, header_size);
|
||||
size += header_size;
|
||||
}
|
||||
for (item = data->items; item; item = item->next) {
|
||||
gsize item_size = test_gbinder_data_item_size(item);
|
||||
|
||||
g_byte_array_append(buf, (void*)&item->data, item_size);
|
||||
size += item_size;
|
||||
}
|
||||
ptr = g_byte_array_free(buf, FALSE);
|
||||
}
|
||||
if (out_size) *out_size = size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static
|
||||
gsize
|
||||
test_gbinder_data_size(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
gsize size = 0;
|
||||
|
||||
if (data) {
|
||||
TestGBinderDataItem* item;
|
||||
|
||||
if (data->iface) size += strlen(data->iface);
|
||||
for (item = data->items; item; item = item->next) {
|
||||
size += test_gbinder_data_item_size(item);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static
|
||||
guint32
|
||||
test_gbinder_date_replace_int32(
|
||||
TestGBinderData* data,
|
||||
gsize offset,
|
||||
guint32 value)
|
||||
{
|
||||
if (data) {
|
||||
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;
|
||||
|
||||
g_assert_cmpint(item->type, == ,DATA_TYPE_INT32);
|
||||
prev = item->data.i32;
|
||||
item->data.i32 = value;
|
||||
return prev;
|
||||
}
|
||||
size += test_gbinder_data_item_size(item);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_new(
|
||||
const char* iface)
|
||||
{
|
||||
TestGBinderData* data = g_new0(TestGBinderData, 1);
|
||||
|
||||
g_atomic_int_set(&data->refcount, 1);
|
||||
data->iface = g_strdup(iface); /* Doubles as a request header */
|
||||
return data;
|
||||
}
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_ref(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
if (data) {
|
||||
g_assert_cmpint(data->refcount, > ,0);
|
||||
g_atomic_int_inc(&data->refcount);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
test_gbinder_data_unref(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
if (data) {
|
||||
g_assert_cmpint(data->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&data->refcount)) {
|
||||
test_gbinder_data_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_gbinder_data_init_reader(
|
||||
TestGBinderData* data,
|
||||
GBinderReader* reader)
|
||||
{
|
||||
memset(reader, 0, sizeof(*reader));
|
||||
if (data) {
|
||||
test_gbinder_reader_cast(reader)->item = data->items;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_gbinder_data_init_writer(
|
||||
TestGBinderData* data,
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
if (writer) {
|
||||
memset(writer, 0, sizeof(*writer));
|
||||
if (data) {
|
||||
test_gbinder_writer_cast(writer)->data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
gboolean
|
||||
gbinder_reader_read_uint32(
|
||||
GBinderReader* reader,
|
||||
guint32* value)
|
||||
{
|
||||
TestGBinderReader* self = test_gbinder_reader_cast(reader);
|
||||
TestGBinderDataItem* item = self->item;
|
||||
|
||||
if (item && item->type == DATA_TYPE_INT32) {
|
||||
if (value) {
|
||||
*value = item->data.i32;
|
||||
}
|
||||
self->item = item->next;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gbinder_reader_read_int32(
|
||||
GBinderReader* reader,
|
||||
gint32* value)
|
||||
{
|
||||
return gbinder_reader_read_uint32(reader, (guint32*)value);
|
||||
}
|
||||
|
||||
const void*
|
||||
gbinder_reader_read_hidl_struct1(
|
||||
GBinderReader* reader,
|
||||
gsize size)
|
||||
{
|
||||
TestGBinderReader* self = test_gbinder_reader_cast(reader);
|
||||
TestGBinderDataItem* item = self->item;
|
||||
|
||||
if (item && item->type == DATA_TYPE_BUFFER &&
|
||||
item->data.blob.size == size) {
|
||||
self->item = item->next;
|
||||
return item->data.blob.buf;
|
||||
}
|
||||
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)
|
||||
{
|
||||
TestGBinderReader* self = test_gbinder_reader_cast(reader);
|
||||
TestGBinderDataItem* item = self->item;
|
||||
|
||||
if (item && item->type == DATA_TYPE_LOCAL_OBJ) {
|
||||
self->item = item->next;
|
||||
return test_gbinder_remote_object_new(item->data.obj);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void*
|
||||
gbinder_writer_get_data(
|
||||
GBinderWriter* writer,
|
||||
gsize* size)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderData* data = self->data;
|
||||
void* buf = test_gbinder_data_buffer(data, size);
|
||||
|
||||
if (buf) {
|
||||
if (!data->pool) {
|
||||
data->pool = gutil_idle_pool_new();
|
||||
}
|
||||
gutil_idle_pool_add(data->pool, buf, g_free);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
gsize
|
||||
gbinder_writer_bytes_written(
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
|
||||
return test_gbinder_data_size(self->data);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_append_int32(
|
||||
GBinderWriter* writer,
|
||||
guint32 value)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_INT32);
|
||||
|
||||
item->data.i32 = value;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_overwrite_int32(
|
||||
GBinderWriter* writer,
|
||||
gsize offset,
|
||||
gint32 value)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
|
||||
test_gbinder_date_replace_int32(self->data, offset, value);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_append_bool(
|
||||
GBinderWriter* writer,
|
||||
gboolean value)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_BOOLEAN);
|
||||
|
||||
item->data.b = value;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
}
|
||||
|
||||
guint
|
||||
gbinder_writer_append_buffer_object(
|
||||
GBinderWriter* writer,
|
||||
const void* buf,
|
||||
gsize size)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_BUFFER);
|
||||
const guint index = test_gbinder_data_count_buffers(self->data);
|
||||
|
||||
item->destroy = test_gbinder_data_item_destroy_buffer;
|
||||
item->data.blob.buf = gutil_memdup(buf, size);
|
||||
item->data.blob.size = size;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
return index;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_append_local_object(
|
||||
GBinderWriter* writer,
|
||||
GBinderLocalObject* obj)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_LOCAL_OBJ);
|
||||
|
||||
item->data.obj = gbinder_local_object_ref(obj);
|
||||
item->destroy = test_gbinder_data_item_destroy_local_obj;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
180
unit/common/test_gbinder_remote_object.c
Normal file
180
unit/common/test_gbinder_remote_object.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
struct gbinder_remote_object {
|
||||
GObject parent;
|
||||
GBinderLocalObject* local;
|
||||
gboolean dead;
|
||||
};
|
||||
|
||||
typedef GObjectClass GBinderRemoteObjectClass;
|
||||
G_DEFINE_TYPE(GBinderRemoteObject, gbinder_remote_object, G_TYPE_OBJECT)
|
||||
|
||||
#define PARENT_CLASS gbinder_remote_object_parent_class
|
||||
#define THIS_TYPE (gbinder_remote_object_get_type())
|
||||
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,THIS_TYPE,GBinderRemoteObject)
|
||||
|
||||
enum gbinder_remote_object_signal {
|
||||
SIGNAL_DEATH,
|
||||
SIGNAL_COUNT
|
||||
};
|
||||
|
||||
#define SIGNAL_DEATH_NAME "death"
|
||||
|
||||
static guint remote_object_signals[SIGNAL_COUNT] = { 0 };
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_remote_object_init(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_remote_object_finalize(
|
||||
GObject* object)
|
||||
{
|
||||
GBinderRemoteObject* self = THIS(object);
|
||||
|
||||
gbinder_local_object_unref(self->local);
|
||||
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
gbinder_remote_object_class_init(
|
||||
GBinderRemoteObjectClass* klass)
|
||||
{
|
||||
G_OBJECT_CLASS(klass)->finalize = gbinder_remote_object_finalize;
|
||||
remote_object_signals[SIGNAL_DEATH] =
|
||||
g_signal_new(SIGNAL_DEATH_NAME, G_OBJECT_CLASS_TYPE(klass),
|
||||
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteObject*
|
||||
test_gbinder_remote_object_new(
|
||||
GBinderLocalObject* local)
|
||||
{
|
||||
GBinderRemoteObject* self = g_object_new(THIS_TYPE, NULL);
|
||||
|
||||
g_assert(local);
|
||||
self->local = gbinder_local_object_ref(local);
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
test_gbinder_remote_object_kill(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
if (self && !self->dead) {
|
||||
self->dead = TRUE;
|
||||
g_signal_emit(self, remote_object_signals[SIGNAL_DEATH], 0);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
test_gbinder_remote_object_dead(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
return !self || self->dead;
|
||||
}
|
||||
|
||||
GBinderLocalObject*
|
||||
test_gbinder_remote_object_to_local(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
return self ? self->local : NULL;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteObject*
|
||||
gbinder_remote_object_ref(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_ref(THIS(self));
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_remote_object_unref(
|
||||
GBinderRemoteObject* self)
|
||||
{
|
||||
if (self) {
|
||||
g_object_unref(THIS(self));
|
||||
}
|
||||
}
|
||||
|
||||
gulong
|
||||
gbinder_remote_object_add_death_handler(
|
||||
GBinderRemoteObject* self,
|
||||
GBinderRemoteObjectNotifyFunc fn,
|
||||
void* data)
|
||||
{
|
||||
return (self && fn) ? g_signal_connect(self, SIGNAL_DEATH_NAME,
|
||||
G_CALLBACK(fn), data) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_remote_object_remove_handler(
|
||||
GBinderRemoteObject* self,
|
||||
gulong id)
|
||||
{
|
||||
if (self && id) {
|
||||
g_signal_handler_disconnect(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remote Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
106
unit/common/test_gbinder_remote_reply.c
Normal file
106
unit/common/test_gbinder_remote_reply.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
struct gbinder_remote_reply {
|
||||
guint32 refcount;
|
||||
TestGBinderData* data;
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_remote_reply_free(
|
||||
GBinderRemoteReply* self)
|
||||
{
|
||||
test_gbinder_data_unref(self->data);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteReply*
|
||||
test_gbinder_remote_reply_new(
|
||||
GBinderLocalReply* reply)
|
||||
{
|
||||
if (reply) {
|
||||
GBinderRemoteReply* self = g_new0(GBinderRemoteReply, 1);
|
||||
TestGBinderData* data = test_gbinder_local_reply_data(reply);
|
||||
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_ref(data);
|
||||
return self;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteReply*
|
||||
gbinder_remote_reply_ref(
|
||||
GBinderRemoteReply* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_remote_reply_unref(
|
||||
GBinderRemoteReply* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_remote_reply_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
119
unit/common/test_gbinder_remote_request.c
Normal file
119
unit/common/test_gbinder_remote_request.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
struct gbinder_remote_request {
|
||||
guint32 refcount;
|
||||
TestGBinderData* data;
|
||||
char* iface;
|
||||
};
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_remote_request_free(
|
||||
GBinderRemoteRequest* self)
|
||||
{
|
||||
test_gbinder_data_unref(self->data);
|
||||
g_free(self->iface);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteRequest*
|
||||
test_gbinder_remote_request_new(
|
||||
GBinderLocalRequest* req)
|
||||
{
|
||||
GBinderRemoteRequest* self = g_new0(GBinderRemoteRequest, 1);
|
||||
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_ref(test_gbinder_local_request_data(req));
|
||||
self->iface = g_strdup(test_gbinder_local_request_interface(req));
|
||||
return self;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteRequest*
|
||||
gbinder_remote_request_ref(
|
||||
GBinderRemoteRequest* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_remote_request_unref(
|
||||
GBinderRemoteRequest* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_remote_request_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
gbinder_remote_request_interface(
|
||||
GBinderRemoteRequest* self)
|
||||
{
|
||||
return self ? self->iface : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_remote_request_init_reader(
|
||||
GBinderRemoteRequest* self,
|
||||
GBinderReader* reader)
|
||||
{
|
||||
test_gbinder_data_init_reader(self->data, reader);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
180
unit/common/test_gbinder_servicemanager.c
Normal file
180
unit/common/test_gbinder_servicemanager.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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_gbinder.h"
|
||||
|
||||
#include <gutil_idlepool.h>
|
||||
#include <gutil_log.h>
|
||||
|
||||
struct gbinder_servicemanager {
|
||||
guint32 refcount;
|
||||
GHashTable* services;
|
||||
GUtilIdlePool* pool;
|
||||
char* dev;
|
||||
};
|
||||
|
||||
static GHashTable* test_servermanagers = NULL;
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_servicemanager_free(
|
||||
GBinderServiceManager* self)
|
||||
{
|
||||
/* Update the global table */
|
||||
g_assert(test_servermanagers);
|
||||
g_assert(g_hash_table_contains(test_servermanagers, self->dev));
|
||||
g_hash_table_remove(test_servermanagers, self->dev); /* Frees self->dev */
|
||||
if (g_hash_table_size(test_servermanagers) == 0) {
|
||||
g_hash_table_unref(test_servermanagers);
|
||||
test_servermanagers = NULL;
|
||||
}
|
||||
|
||||
gutil_idle_pool_destroy(self->pool);
|
||||
g_hash_table_destroy(self->services);
|
||||
g_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderRemoteObject*
|
||||
test_gbinder_servicemanager_new_service(
|
||||
GBinderServiceManager* self,
|
||||
const char* name,
|
||||
GBinderLocalObject* local)
|
||||
{
|
||||
GBinderRemoteObject* remote = test_gbinder_remote_object_new(local);
|
||||
|
||||
g_hash_table_replace(self->services, g_strdup(name), remote);
|
||||
return gbinder_remote_object_ref(remote);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* libgbinder API
|
||||
*==========================================================================*/
|
||||
|
||||
GBinderServiceManager*
|
||||
gbinder_servicemanager_new(
|
||||
const char* dev)
|
||||
{
|
||||
GBinderServiceManager* self = NULL;
|
||||
|
||||
g_assert(dev && dev[0]);
|
||||
if (test_servermanagers) {
|
||||
self = g_hash_table_lookup(test_servermanagers, dev);
|
||||
}
|
||||
|
||||
if (self) {
|
||||
gbinder_servicemanager_ref(self);
|
||||
} else {
|
||||
self = g_new0(GBinderServiceManager, 1);
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->pool = gutil_idle_pool_new();
|
||||
self->dev = g_strdup(dev); /* Owned by test_servermanagers */
|
||||
self->services = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify) gbinder_remote_object_unref);
|
||||
|
||||
/* Update the global table */
|
||||
if (!test_servermanagers) {
|
||||
test_servermanagers = g_hash_table_new_full(g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
}
|
||||
g_hash_table_replace(test_servermanagers, self->dev, self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
GBinderServiceManager*
|
||||
gbinder_servicemanager_ref(
|
||||
GBinderServiceManager* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_servicemanager_unref(
|
||||
GBinderServiceManager* self)
|
||||
{
|
||||
if (self) {
|
||||
g_assert_cmpint(self->refcount, > ,0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
test_gbinder_servicemanager_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GBinderRemoteObject* /* autoreleased */
|
||||
gbinder_servicemanager_get_service_sync(
|
||||
GBinderServiceManager* self,
|
||||
const char* name,
|
||||
int* status)
|
||||
{
|
||||
if (self && name) {
|
||||
GBinderRemoteObject* obj = g_hash_table_lookup(self->services, name);
|
||||
|
||||
if (obj) {
|
||||
gutil_idle_pool_add(self->pool, gbinder_remote_object_ref(obj),
|
||||
(GDestroyNotify) gbinder_remote_object_unref);
|
||||
return obj;
|
||||
} else {
|
||||
GDEBUG("Name %s not found", name);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBinderLocalObject*
|
||||
gbinder_servicemanager_new_local_object2(
|
||||
GBinderServiceManager* self,
|
||||
const char* const* ifaces,
|
||||
GBinderLocalTransactFunc fn,
|
||||
void* user_data)
|
||||
{
|
||||
return self ? test_gbinder_local_object_new(ifaces, fn, user_data) : NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
166
unit/common/test_main.c
Normal file
166
unit/common/test_main.c
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* 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 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.
|
||||
*/
|
||||
|
||||
#include "test_common.h"
|
||||
|
||||
#include <gutil_log.h>
|
||||
|
||||
typedef struct test_quit_later_data{
|
||||
GMainLoop* loop;
|
||||
guint n;
|
||||
} TestQuitLaterData;
|
||||
|
||||
typedef struct test_context_data{
|
||||
GMainLoop* loop;
|
||||
GTestFunc func;
|
||||
} TestContextData;
|
||||
|
||||
static
|
||||
gboolean
|
||||
test_timeout_expired(
|
||||
gpointer data)
|
||||
{
|
||||
g_assert(!"TIMEOUT");
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_quit_later_n_free(
|
||||
gpointer user_data)
|
||||
{
|
||||
TestQuitLaterData* data = user_data;
|
||||
|
||||
g_main_loop_unref(data->loop);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
test_quit_later_n_func(
|
||||
gpointer user_data)
|
||||
{
|
||||
TestQuitLaterData* data = user_data;
|
||||
|
||||
if (data->n > 0) {
|
||||
data->n--;
|
||||
return G_SOURCE_CONTINUE;
|
||||
} else {
|
||||
g_main_loop_quit(data->loop);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_quit_later_n(
|
||||
GMainLoop* loop,
|
||||
guint n)
|
||||
{
|
||||
TestQuitLaterData* data = g_new0(TestQuitLaterData, 1);
|
||||
|
||||
data->loop = g_main_loop_ref(loop);
|
||||
data->n = n;
|
||||
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, test_quit_later_n_func, data,
|
||||
test_quit_later_n_free);
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
test_quit_later_cb(
|
||||
gpointer data)
|
||||
{
|
||||
g_main_loop_quit((GMainLoop*)data);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
void
|
||||
test_quit_later(
|
||||
GMainLoop* loop)
|
||||
{
|
||||
g_idle_add(test_quit_later_cb, loop);
|
||||
}
|
||||
|
||||
void
|
||||
test_run(
|
||||
const TestOpt* opt,
|
||||
GMainLoop* loop)
|
||||
{
|
||||
if (opt->flags & TEST_FLAG_DEBUG) {
|
||||
g_main_loop_run(loop);
|
||||
} else {
|
||||
const guint timeout_id = g_timeout_add_seconds(TEST_TIMEOUT_SEC,
|
||||
test_timeout_expired, NULL);
|
||||
g_main_loop_run(loop);
|
||||
g_source_remove(timeout_id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test_init(
|
||||
TestOpt* opt,
|
||||
int argc,
|
||||
char* argv[])
|
||||
{
|
||||
const char* sep1;
|
||||
const char* sep2;
|
||||
int i;
|
||||
|
||||
memset(opt, 0, sizeof(*opt));
|
||||
for (i=1; i<argc; i++) {
|
||||
const char* arg = argv[i];
|
||||
if (!strcmp(arg, "-d") || !strcmp(arg, "--debug")) {
|
||||
opt->flags |= TEST_FLAG_DEBUG;
|
||||
} else if (!strcmp(arg, "-v")) {
|
||||
GTestConfig* config = (GTestConfig*)g_test_config_vars;
|
||||
config->test_verbose = TRUE;
|
||||
} else {
|
||||
GWARN("Unsupported command line option %s", arg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup logging */
|
||||
sep1 = strrchr(argv[0], '/');
|
||||
sep2 = strrchr(argv[0], '\\');
|
||||
gutil_log_default.name = (sep1 && sep2) ? (MAX(sep1, sep2) + 1) :
|
||||
sep1 ? (sep1 + 1) : sep2 ? (sep2 + 1) : argv[0];
|
||||
gutil_log_default.level = g_test_verbose() ?
|
||||
GLOG_LEVEL_VERBOSE : GLOG_LEVEL_NONE;
|
||||
gutil_log_timestamp = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
56
unit/coverage/run
Executable file
56
unit/coverage/run
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# This script requires lcov, dirname
|
||||
#
|
||||
|
||||
TESTS="\
|
||||
unit_client \
|
||||
unit_config \
|
||||
unit_instance \
|
||||
unit_registry \
|
||||
unit_util"
|
||||
|
||||
function err() {
|
||||
echo "*** ERROR!" $1
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Check the required tools
|
||||
which lcov >> /dev/null || err "Please install lcov"
|
||||
which dirname >> /dev/null || err "Please install dirname"
|
||||
|
||||
# LCOV 1.10 has branch coverage disabled per default
|
||||
# Previous versions didn't have the --rc option
|
||||
if [ ! -z "$(lcov --help | grep ' --rc ')" ] ; then
|
||||
LCOV_OPT="--rc lcov_branch_coverage=1"
|
||||
GENHTML_OPT="--branch-coverage"
|
||||
fi
|
||||
|
||||
pushd `dirname $0` > /dev/null
|
||||
COV_DIR="$PWD"
|
||||
pushd .. > /dev/null
|
||||
TEST_DIR="$PWD"
|
||||
pushd .. > /dev/null
|
||||
TOP_DIR="$PWD"
|
||||
popd > /dev/null
|
||||
popd > /dev/null
|
||||
popd > /dev/null
|
||||
|
||||
make -C "$TOP_DIR" clean
|
||||
for t in $TESTS ; do
|
||||
pushd "$TEST_DIR/$t"
|
||||
make -C "$TEST_DIR/$t" clean coverage || exit 1
|
||||
build/coverage/$t || exit 1
|
||||
popd
|
||||
done
|
||||
|
||||
# Sometimes you need this, sometimes that :S
|
||||
BASE_DIR="$TOP_DIR"
|
||||
#BASE_DIR="$TOP_DIR/src"
|
||||
|
||||
FULL_COV="$COV_DIR/full.gcov"
|
||||
LIB_COV="$COV_DIR/lib.gcov"
|
||||
rm -f "$FULL_COV" "$LIB_COV"
|
||||
lcov $LCOV_OPT -c -d "$TOP_DIR/build/coverage" -b "$BASE_DIR" -o "$FULL_COV" || exit 1
|
||||
lcov $LCOV_OPT -e "$FULL_COV" "$BASE_DIR/*" -o "$LIB_COV" || exit 1
|
||||
genhtml $GENHTML_OPT "$LIB_COV" -t "libgbinder-radio" --output-directory "$COV_DIR/report" || exit 1
|
||||
5
unit/unit_client/Makefile
Normal file
5
unit/unit_client/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_client
|
||||
|
||||
include ../common/Makefile
|
||||
2106
unit/unit_client/unit_client.c
Normal file
2106
unit/unit_client/unit_client.c
Normal file
File diff suppressed because it is too large
Load Diff
5
unit/unit_config/Makefile
Normal file
5
unit/unit_config/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_config
|
||||
|
||||
include ../common/Makefile
|
||||
918
unit/unit_config/unit_config.c
Normal file
918
unit/unit_config/unit_config.c
Normal 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:
|
||||
*/
|
||||
5
unit/unit_instance/Makefile
Normal file
5
unit/unit_instance/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_instance
|
||||
|
||||
include ../common/Makefile
|
||||
1207
unit/unit_instance/unit_instance.c
Normal file
1207
unit/unit_instance/unit_instance.c
Normal file
File diff suppressed because it is too large
Load Diff
5
unit/unit_registry/Makefile
Normal file
5
unit/unit_registry/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_registry
|
||||
|
||||
include ../common/Makefile
|
||||
170
unit/unit_registry/unit_registry.c
Normal file
170
unit/unit_registry/unit_registry.c
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 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 "radio_instance.h"
|
||||
#include "radio_registry_p.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
static TestOpt test_opt;
|
||||
|
||||
/*==========================================================================*
|
||||
* null
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_null(
|
||||
void)
|
||||
{
|
||||
radio_registry_instance_added(NULL);
|
||||
radio_registry_instance_removed(NULL);
|
||||
radio_registry_remove_handler(NULL, 0);
|
||||
radio_registry_remove_handlers(NULL, NULL, 0);
|
||||
radio_registry_unref(NULL);
|
||||
g_assert(!radio_registry_ref(NULL));
|
||||
g_assert(!radio_registry_add_instance_added_handler(NULL,NULL,NULL,NULL));
|
||||
g_assert(!radio_registry_add_instance_removed_handler(NULL,NULL,NULL,NULL));
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* basic
|
||||
*==========================================================================*/
|
||||
|
||||
static const char* test_basic_key = "foo";
|
||||
static const char* test_basic_bad_key = "bar";
|
||||
|
||||
static
|
||||
void
|
||||
test_basic_add_cb(
|
||||
RadioRegistry* registry,
|
||||
RadioInstance* radio,
|
||||
gpointer user_data)
|
||||
{
|
||||
(*((int*)user_data))++;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_basic_remove_cb(
|
||||
RadioRegistry* registry,
|
||||
const char* str,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_assert_cmpstr(str, == ,test_basic_key);
|
||||
(*((int*)user_data))++;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_basic(
|
||||
void)
|
||||
{
|
||||
RadioRegistry* reg = radio_registry_new();
|
||||
int add_count = 0, remove_count = 0;
|
||||
gulong id[6];
|
||||
GObject* instance;
|
||||
|
||||
g_assert(reg);
|
||||
g_assert(reg == radio_registry_new()); /* New ref to the same instance */
|
||||
radio_registry_unref(reg);
|
||||
|
||||
g_assert(!radio_registry_add_instance_added_handler(reg,NULL,NULL,NULL));
|
||||
g_assert(!radio_registry_add_instance_removed_handler(reg,NULL,NULL,NULL));
|
||||
|
||||
/* Add/remove handlers */
|
||||
id[0] = radio_registry_add_instance_added_handler(reg, "",
|
||||
test_basic_add_cb, &add_count);
|
||||
radio_registry_remove_handler(reg, id[0]);
|
||||
id[0] = radio_registry_add_instance_added_handler(reg, NULL,
|
||||
test_basic_add_cb, &add_count);
|
||||
id[1] = radio_registry_add_instance_added_handler(reg, test_basic_bad_key,
|
||||
test_basic_add_cb, &add_count); /* won't get called */
|
||||
|
||||
id[2] = radio_registry_add_instance_removed_handler(reg, NULL,
|
||||
test_basic_remove_cb, &remove_count);
|
||||
id[3] = radio_registry_add_instance_removed_handler(reg, "",
|
||||
test_basic_remove_cb, &remove_count);
|
||||
id[4] = radio_registry_add_instance_removed_handler(reg, test_basic_key,
|
||||
test_basic_remove_cb, &remove_count);
|
||||
id[5] = radio_registry_add_instance_removed_handler(reg, test_basic_bad_key,
|
||||
test_basic_remove_cb, &remove_count); /* won't get called */
|
||||
|
||||
/* Well, this wouldn't be a real functional instance but we don't care */
|
||||
instance = g_object_new(RADIO_TYPE_INSTANCE, NULL);
|
||||
radio_registry_instance_added(RADIO_INSTANCE(instance));
|
||||
g_assert_cmpint(add_count, == ,1); /* 1 out of 2 is called */
|
||||
g_assert_cmpint(remove_count, == ,0);
|
||||
|
||||
radio_registry_instance_removed(test_basic_key);
|
||||
g_assert_cmpint(add_count, == ,1);
|
||||
g_assert_cmpint(remove_count, == ,3); /* 3 our of 4 are called */
|
||||
g_object_unref(instance);
|
||||
|
||||
/* remove_all zeros the ids */
|
||||
radio_registry_remove_all_handlers(reg, id);
|
||||
g_assert(!id[0]);
|
||||
g_assert(!id[4]);
|
||||
|
||||
radio_registry_remove_handler(reg, 0); /* No effect */
|
||||
radio_registry_unref(reg);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Common
|
||||
*==========================================================================*/
|
||||
|
||||
#define TEST_PREFIX "/registry/"
|
||||
#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_("basic"), test_basic);
|
||||
test_init(&test_opt, argc, argv);
|
||||
return g_test_run();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
5
unit/unit_util/Makefile
Normal file
5
unit/unit_util/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_util
|
||||
|
||||
include ../common/Makefile
|
||||
370
unit/unit_util/unit_util.c
Normal file
370
unit/unit_util/unit_util.c
Normal file
@@ -0,0 +1,370 @@
|
||||
/*
|
||||
* 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 "radio_util.h"
|
||||
|
||||
#define UNKNOWN_VALUE (0x7fffffff)
|
||||
#define UNKNOWN_REQ ((RADIO_REQ)UNKNOWN_VALUE)
|
||||
#define UNKNOWN_IND ((RADIO_REQ)UNKNOWN_VALUE)
|
||||
#define UNKNOWN_RESP ((RADIO_RESP)UNKNOWN_VALUE)
|
||||
|
||||
static TestOpt test_opt;
|
||||
|
||||
/*==========================================================================*
|
||||
* req_name
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_req_name(
|
||||
void)
|
||||
{
|
||||
g_assert(!radio_req_name(UNKNOWN_REQ));
|
||||
g_assert(!radio_req_name(RADIO_REQ_ANY));
|
||||
g_assert_cmpstr(radio_req_name(RADIO_REQ_GET_ICC_CARD_STATUS),==,
|
||||
"getIccCardStatus");
|
||||
g_assert_cmpstr(radio_req_name(RADIO_REQ_START_NETWORK_SCAN),==,
|
||||
"startNetworkScan");
|
||||
g_assert_cmpstr(radio_req_name(RADIO_REQ_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA),==,
|
||||
"setSignalStrengthReportingCriteria");
|
||||
g_assert_cmpstr(radio_req_name(RADIO_REQ_SET_SYSTEM_SELECTION_CHANNELS),==,
|
||||
"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");
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* resp_name
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_resp_name(
|
||||
void)
|
||||
{
|
||||
g_assert(!radio_resp_name(UNKNOWN_RESP));
|
||||
g_assert(!radio_resp_name(RADIO_RESP_ANY));
|
||||
g_assert_cmpstr(radio_resp_name(RADIO_RESP_GET_ICC_CARD_STATUS),==,
|
||||
"getIccCardStatusResponse");
|
||||
g_assert_cmpstr(radio_resp_name(RADIO_RESP_START_NETWORK_SCAN),==,
|
||||
"startNetworkScanResponse");
|
||||
g_assert_cmpstr(radio_resp_name(RADIO_RESP_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA),==,
|
||||
"setSignalStrengthReportingCriteriaResponse");
|
||||
g_assert_cmpstr(radio_resp_name(RADIO_RESP_SET_SYSTEM_SELECTION_CHANNELS),==,
|
||||
"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");
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* ind_name
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_ind_name(
|
||||
void)
|
||||
{
|
||||
g_assert(!radio_ind_name(UNKNOWN_IND));
|
||||
g_assert(!radio_ind_name(RADIO_IND_ANY));
|
||||
g_assert_cmpstr(radio_ind_name(RADIO_IND_RADIO_STATE_CHANGED),==,
|
||||
"radioStateChanged");
|
||||
g_assert_cmpstr(radio_ind_name(RADIO_IND_NETWORK_SCAN_RESULT),==,
|
||||
"networkScanResult");
|
||||
g_assert_cmpstr(radio_ind_name(RADIO_IND_CURRENT_LINK_CAPACITY_ESTIMATE),==,
|
||||
"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");
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* req_resp
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_req_resp(
|
||||
void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Common
|
||||
*==========================================================================*/
|
||||
|
||||
#define TEST_PREFIX "/util/"
|
||||
#define TEST_(t) TEST_PREFIX t
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func(TEST_("req_name"), test_req_name);
|
||||
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();
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
Reference in New Issue
Block a user