Compare commits

..

64 Commits
1.0.2 ... 1.4.2

Author SHA1 Message Date
Slava Monich
1d14925196 Version 1.4.2 2021-09-12 18:08:18 +03:00
Slava Monich
77d600150a Merge pull request #13 from monich/unit
Unit tests + some housekeeping
2021-09-12 17:42:26 +03:00
Slava Monich
7684a717de [gbinder-radio] Added unit tests. JB#55524 2021-09-12 17:28:22 +03:00
Slava Monich
6be4596f0d [gbinder-radio] Housekeeping 2021-09-11 16:03:17 +03:00
Slava Monich
76f7fa6ee1 [gbinder-radio] Don't assume that GBinderServiceManager is a GObject
It's an implementation detail and not a part of libgbinder interface.
2021-09-11 16:01:44 +03:00
Slava Monich
c3135de5c7 Version 1.4.1 2021-05-20 16:34:13 +03:00
Slava Monich
4595539656 Merge pull request #12 from d-grigorev/jb54258
Define RADIO_CELL_INFO_TYPE_1_4
2021-05-20 16:29:53 +03:00
Denis Grigorev
62a0764577 [gbinder-radio] Define RADIO_CELL_INFO_TYPE_1_4. JB#54258
Cell info type is encoded by hidl_discriminator, and is actually part of
struct CellInfo.Info. For simplicity it is defined here as part of struct
CellInfo, so the code for android@1.2 can be reused for android@1.4.
The values are taken from the generated types.h:

    struct CellInfo final {
      struct Info final {
        enum class hidl_discriminator : uint8_t {
          gsm = 0,  // ::android::hardware:📻:V1_2::CellInfoGsm
          cdma = 1,  // ::android::hardware:📻:V1_2::CellInfoCdma
          wcdma = 2,  // ::android::hardware:📻:V1_2::CellInfoWcdma
          tdscdma = 3,  // ::android::hardware:📻:V1_2::CellInfoTdscdma
          lte = 4,  // ::android::hardware:📻:V1_4::CellInfoLte
          nr = 5,  // ::android::hardware:📻:V1_4::CellInfoNr
        };
2021-05-20 11:03:44 +03:00
Slava Monich
ff65e170e1 Version 1.4.0 2021-05-18 18:59:08 +03:00
Slava Monich
0ce5f268c9 Acknowledge contributions 2021-05-18 18:52:06 +03:00
Slava Monich
ab379e4fe3 Merge pull request #11 from d-grigorev/jb54258
Add support for android.hardware.radio@1.4
2021-05-18 18:47:24 +03:00
Denis Grigorev
e4ab7078a1 [gbinder-radio] Fix RadioCellInfo_1_4 structure. JB#54258 2021-05-18 18:02:41 +03:00
Denis Grigorev
9b1c2df489 [gbinder-radio] Support radio@1.4 interface. JB#54258 2021-05-18 18:02:32 +03:00
Slava Monich
62212c5165 Version 1.2.6 2021-04-25 14:42:33 +03:00
Slava Monich
ea502d417a [gbinder-radio] Added RadioSimApdu type. JB#54048
It exists since radio@1.0 but for whatever reason it's been missing.
2021-04-25 14:39:41 +03:00
Slava Monich
1ce4ff615b [gbinder-radio] Avoid hardcoding list of ifaces twice 2021-04-22 14:41:39 +03:00
Slava Monich
72b3fc58ec Version 1.2.5 2021-03-25 20:16:27 +02:00
Slava Monich
4140def1fc Merge pull request #10 from monich/radio1.4
Add radio@1.4 types
2021-03-25 20:15:29 +02:00
Slava Monich
901396b385 [gbinder-radio] Added radio@1.4 types. JB#48905 2021-03-25 20:07:19 +02:00
Slava Monich
052a0e11fb [gbinder-radio] Added radio@1.3 types. JB#48905 2021-03-25 20:07:00 +02:00
Slava Monich
024f319164 Version 1.2.4 2021-03-20 02:43:01 +02:00
Slava Monich
91f7b80459 [gbinder-radio] Added more radio@1.2 types. JB#53501
RadioCellIdentity_1_2
RadioVoiceRegStateResult_1_2
RadioDataRegStateResult_1_2

Also added RADIO_1_x_RESP_LAST and RADIO_1_x_IND_LAST constants in addition
to already existing RADIO_1_x_REQ_LAST
2021-03-20 02:41:25 +02:00
Slava Monich
13076eb3ec Version 1.2.3 2021-03-19 05:22:35 +02:00
Slava Monich
27695ee5ff [gbinder-radio] Reformatted radio@1.2 types. JB#53501
To resemble types.hal definitions. This change is binary but not
compile-time compatible.
2021-03-19 05:18:29 +02:00
Slava Monich
7b5656d2a8 Version 1.2.2 2021-03-05 14:01:30 +02:00
Slava Monich
788d472839 [gbinder-radio] Added radio_instance_get_with_version(). JB#50597
That's consistent with other API calls.

radio_instance_get_with_interface() has been removed from the header
and shouldn't be used.
2021-03-05 13:58:59 +02:00
Slava Monich
7f4446b3fd Version 1.2.1 2021-03-05 12:35:10 +02:00
Slava Monich
e08ef1bdae Merge pull request #9 from monich/backcompat
Backward compatibility with radio@1.0
2021-03-05 12:30:13 +02:00
Slava Monich
8039bfe66e [gbinder-radio] Backward compatibility with radio@1.0. JB#50597
Once you say you support radio@1.2 responses, getIccCardStatus@1.0
responds with getIccCardStatusResponse@1.2. That breaks clients
which only handle radio@1.0 responses.

Intention to support higher interface levels must be explicitly
expressed.
2021-03-05 12:23:10 +02:00
Slava Monich
7e23a74fbf Version 1.2.0
Version bump marks radio@1.2 support
2021-03-04 13:39:04 +02:00
Slava Monich
a9463baaaf Freshened up license 2021-03-04 13:38:42 +02:00
Slava Monich
ddee97fc93 Acknowledge Matti's contribution 2021-03-04 13:34:24 +02:00
Slava Monich
f562149d18 Merge pull request #8 from monich/radio-1.2
Support for android.hardware.radio@1.2 interfaces
2021-03-04 13:26:42 +02:00
Matti Lehtimäki
21d659a5c5 [gbinder-radio] Attach to the highest supported interface. JB#50597 2021-03-04 02:28:52 +02:00
Matti Lehtimäki
71f5632e2d [gbinder-radio] Added android.hardware.radio@1.2 types. JB#50597
Add missing android.hardware.radio@1.1 entry to radio_req_resp.
2021-03-03 18:15:45 +02:00
Slava Monich
30e7563d94 Version 1.0.11 2020-10-01 21:05:56 +03:00
Slava Monich
26a321bc36 [gbinder-radio] Added req => resp mapping for radio@1.1 calls 2020-10-01 21:03:42 +03:00
Slava Monich
f141bd1615 Merge pull request #7 from nemomobile-ux/permissions
Install the library with exe permissions.
2020-10-01 20:58:26 +03:00
Rinigus
d3a63909c7 [gbinder-radio] Install the library with exe permissions. JB#51013
Signed-off-by: Rinigus <rinigus.git@gmail.com>
2020-09-30 23:02:43 +03:00
Slava Monich
aaa1c0c9a0 Version 1.0.10 2020-06-03 15:35:18 +03:00
Slava Monich
e0ffc4d60c Merge pull request #6 from monich/lib64
Respect arch specific lib dir
2020-06-03 15:22:39 +03:00
Slava Monich
94d469380e [gbinder-radio] Respect arch specific lib dir. JB#49681 2020-06-03 04:04:01 +03:00
Slava Monich
7e4b839fc6 [gbinder-radio] Hide internal symbols 2020-06-03 04:04:01 +03:00
Slava Monich
0708177e94 [gbinder-radio] Constants for android.hardware.radio@1.1 interfaces 2020-06-03 04:03:54 +03:00
Slava Monich
9047ef9a56 [gbinder-radio] Ignore GLib deprecation warnings 2020-06-02 20:14:05 +03:00
Slava Monich
bb61f00d57 Version 1.0.9 2020-03-24 12:37:01 +02:00
Slava Monich
601ef084ee Added AUTHORS file 2020-03-24 12:33:40 +02:00
Slava Monich
3cd41646b4 Merge pull request #5 from Danct12/1.0.8-deb
[debian] Packaging for Debian-based distros. JB#42254
2020-03-24 12:29:17 +02:00
Danct12
d1fb490f9b Initial packaging for Debian
Signed-off-by: Danct12 <danct12@disroot.org>
2020-03-24 09:16:30 +07:00
Slava Monich
7e0c222f1d Version 1.0.8 2019-08-14 18:03:57 +03:00
Slava Monich
f5b2cc062c [gbinder-radio] Added RADIO_DEVICE_STATE enum. JB#46836 2019-08-14 18:00:57 +03:00
Slava Monich
9e246ebb55 Version 1.0.7 2019-07-02 14:23:45 +03:00
Slava Monich
5f5afc3d76 Fixed syntax error in a last-minute change 2019-07-02 14:23:32 +03:00
Slava Monich
eab404c46b Merge pull request #4 from monich/enabled
Add enabled attribute to RadioInstance
2019-07-02 14:11:40 +03:00
Slava Monich
395a50ba3d [gbinder-radio] Added enabled attribute to RadioInstance. JB#46324
And these new functions:

  radio_instance_new_with_modem_and_slot()
  radio_instance_set_enabled()
  radio_instance_add_enabled_handler()
2019-06-28 19:00:26 +03:00
Slava Monich
79379ea3d1 Version 1.0.6 2019-04-30 12:04:25 +03:00
Slava Monich
197e84e71a [gbinder-radio] Added RadioDataProfile enums. JB#45342
RADIO_DATA_PROFILE_ID and RADIO_APN_TYPES
2019-04-30 12:02:32 +03:00
Slava Monich
30ea57a3cb Version 1.0.5 2019-03-19 12:45:16 +02:00
Slava Monich
49fcc2a599 Merge pull request #2 from krnlyng/jb44067
Add HardwareConfig types
2019-03-19 12:43:01 +02:00
Frajo Haider
6d9f87f7ea [gbinder-radio] add HardwareConfig types. JB#44067 2019-03-19 12:39:42 +02:00
Slava Monich
efc30cd06d Version 1.0.4 2019-03-06 00:41:13 +02:00
Slava Monich
6959979384 [gbinder-radio] Fixed death handling. JB#44551
Listeners were being registered for the wrong signal.
2019-03-06 00:38:32 +02:00
Slava Monich
1ebf32bc73 Version 1.0.3 2019-03-05 02:59:50 +02:00
Slava Monich
a119a68374 [gbinder-radio] Added RADIO_APN_AUTH_TYPE enum. JB#44551 2019-03-05 02:56:47 +02:00
40 changed files with 4810 additions and 131 deletions

12
.gitignore vendored
View File

@@ -1,15 +1,15 @@
*~
debian/files
debian/libgbinder-radio-dev.debhelper.log
debian/libgbinder-radio-dev.substvars
debian/libgbinder-radio-dev
debian/libgbinder-radio.debhelper.log
debian/libgbinder-radio.postinst.debhelper
debian/libgbinder-radio.postrm.debhelper
debian/libgbinder-radio.substvars
debian/libgbinder-radio
debian/*.debhelper.log
debian/*.debhelper
debian/*.substvars
debian/*.install
debian/tmp
documentation.list
unit/coverage/*.gcov
unit/coverage/report
installroot
build
RPMS

6
AUTHORS Normal file
View File

@@ -0,0 +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>

33
LICENSE Normal file
View File

@@ -0,0 +1,33 @@
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:
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.

View File

@@ -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,7 +23,7 @@ all: debug release pkgconfig
#
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_MINOR = 4
VERSION_RELEASE = 2
# Version for pkg-config
@@ -78,10 +79,7 @@ DEBUG_FLAGS = -g
RELEASE_FLAGS =
COVERAGE_FLAGS = -g
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
KEEP_SYMBOLS ?= 0
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
endif
@@ -141,12 +139,26 @@ 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 debian/libgbinder-dev
rm -fr debian/tmp debian/libgbinder-radio debian/libgbinder-radio-dev
rm -f documentation.list debian/files debian/*.substvars
rm -f debian/*.debhelper.log debian/*.debhelper debian/*~
rm -f debian/*.install
test:
make -C unit test
$(BUILD_DIR):
mkdir -p $@
@@ -192,25 +204,34 @@ $(COVERAGE_LIB): $(COVERAGE_OBJS)
$(AR) rc $@ $?
ranlib $@
#
# LIBDIR usually gets substituted with arch specific dir.
# It's relative in deb build and can be whatever in rpm build.
#
LIBDIR ?= usr/lib
ABS_LIBDIR := $(shell echo /$(LIBDIR) | sed -r 's|/+|/|g')
$(PKGCONFIG): $(LIB_NAME).pc.in Makefile
sed -e 's/\[version\]/'$(PCVERSION)/g $< > $@
sed -e 's|@version@|$(PCVERSION)|g' -e 's|@libdir@|$(ABS_LIBDIR)|g' $< > $@
debian/%.install: debian/%.install.in
sed 's|@LIBDIR@|$(LIBDIR)|g' $< > $@
#
# Install
#
INSTALL_PERM = 644
INSTALL = install
INSTALL_DIRS = $(INSTALL) -d
INSTALL_FILES = $(INSTALL) -m $(INSTALL_PERM)
INSTALL_FILES = $(INSTALL) -m 644
INSTALL_LIB_DIR = $(DESTDIR)/usr/lib
INSTALL_LIB_DIR = $(DESTDIR)$(ABS_LIBDIR)
INSTALL_INCLUDE_DIR = $(DESTDIR)/usr/include/$(NAME)
INSTALL_PKGCONFIG_DIR = $(DESTDIR)/usr/lib/pkgconfig
INSTALL_PKGCONFIG_DIR = $(DESTDIR)$(ABS_LIBDIR)/pkgconfig
install: $(INSTALL_LIB_DIR)
$(INSTALL_FILES) $(RELEASE_SO) $(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)

84
debian/changelog vendored Normal file
View File

@@ -0,0 +1,84 @@
libgbinder-radio (1.4.2) unstable; urgency=medium
* Don't assume that GBinderServiceManager is a GObject
* Added unit tests
-- Slava Monich <slava.monich@jolla.com> Sun, 12 Sep 2021 18:05:19 +0300
libgbinder-radio (1.4.1) unstable; urgency=medium
* Added RADIO_CELL_INFO_TYPE_1_4 enum
-- Slava Monich <slava.monich@jolla.com> Thu, 20 May 2021 16:32:16 +0300
libgbinder-radio (1.4.0) unstable; urgency=medium
* Support for radio@1.4 interfaces
* Fixed RadioCellInfo_1_4 definition
-- Slava Monich <slava.monich@jolla.com> Tue, 18 May 2021 18:54:52 +0300
libgbinder-radio (1.2.6) unstable; urgency=medium
* Added RadioSimApdu type
-- Slava Monich <slava.monich@jolla.com> Sun, 25 Apr 2021 14:41:32 +0300
libgbinder-radio (1.2.5) unstable; urgency=medium
* Added radio@1.3 types
* Added radio@1.4 types
-- Slava Monich <slava.monich@jolla.com> Thu, 25 Mar 2021 20:13:08 +0200
libgbinder-radio (1.2.4) unstable; urgency=medium
* Added more radio@1.2 types
-- Slava Monich <slava.monich@jolla.com> Sat, 20 Mar 2021 02:41:07 +0200
libgbinder-radio (1.2.3) unstable; urgency=medium
* Reformatted radio@1.2 types
-- Slava Monich <slava.monich@jolla.com> Fri, 19 Mar 2021 05:21:52 +0200
libgbinder-radio (1.2.2) unstable; urgency=medium
* Added radio_instance_get_with_version()
-- Slava Monich <slava.monich@jolla.com> Fri, 05 Mar 2021 14:00:20 +0200
libgbinder-radio (1.2.1) unstable; urgency=medium
* Fixed backward compatibility with radio@1.0
-- Slava Monich <slava.monich@jolla.com> Fri, 05 Mar 2021 12:33:50 +0200
libgbinder-radio (1.2.0) unstable; urgency=medium
* Support for radio@1.2 interfaces
-- Slava Monich <slava.monich@jolla.com> Thu, 04 Mar 2021 13:36:51 +0200
libgbinder-radio (1.0.11) unstable; urgency=medium
* Make library executable on RPM based systems
* Added req => resp mapping for radio@1.1 calls
-- Slava Monich <slava.monich@jolla.com> Thu, 01 Oct 2020 21:04:59 +0300
libgbinder-radio (1.0.10) unstable; urgency=medium
* Hide internal symbols
* Respect arch specific lib dir
* Ignore GLib deprecation warnings
* Added constants for android.hardware.radio@1.1 interfaces
-- Slava Monich <slava.monich@jolla.com> Wed, 03 Jun 2020 15:24:17 +0300
libgbinder-radio (1.0.9) unstable; urgency=medium
* Added packaging for Debian-based distros.
-- Danct12 <danct12@disroot.org> Tue, 24 Mar 2020 02:55:50 +0700

1
debian/compat vendored Normal file
View File

@@ -0,0 +1 @@
9

17
debian/control vendored Normal file
View File

@@ -0,0 +1,17 @@
Source: libgbinder-radio
Priority: optional
Maintainer: Danct12 <danct12@disroot.org>
Build-Depends: debhelper (>=9), libgbinder-dev (>= 1.0.9)
Standards-Version: 3.9.6
Package: libgbinder-radio-dev
Section: libdevel
Architecture: any
Depends: libgbinder-radio (= ${binary:Version}), ${misc:Depends}
Description: Development files for libgbinder-radio
Package: libgbinder-radio
Section: libs
Architecture: any
Depends: libgbinder (>= 1.0.9), ${shlibs:Depends}, ${misc:Depends}
Description: Binder client library for Android radio interfaces

33
debian/copyright vendored Normal file
View File

@@ -0,0 +1,33 @@
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:
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.

View File

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

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

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

14
debian/rules vendored Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/make -f
# Uncomment to enable verbose build
#export DH_VERBOSE = 1
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
override_dh_auto_install:
dh_auto_install -- LIBDIR=$(LIBDIR) install-dev
%:
dh $@

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (native)

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -45,6 +45,15 @@ 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_1_3,
RADIO_INTERFACE_1_4,
RADIO_INTERFACE_COUNT
} RADIO_INTERFACE; /* Since 1.2.0 */
struct radio_instance {
GObject parent;
RadioInstancePriv* priv;
@@ -52,6 +61,12 @@ struct radio_instance {
const char* dev;
const char* slot;
const char* key;
/* Since 1.0.7 */
const char* modem; /* D-Bus path */
int slot_index; /* 0 for SIM1, 1 for SIM2 and so on */
gboolean enabled;
/* Since 1.2.0 */
RADIO_INTERFACE version;
};
typedef
@@ -113,11 +128,38 @@ radio_instance_new(
const char* dev,
const char* name);
RadioInstance*
radio_instance_new_with_modem_and_slot(
const char* dev,
const char* name,
const char* modem,
int slot_index); /* Since 1.0.7 */
RadioInstance*
radio_instance_new_with_version(
const char* dev,
const char* name,
RADIO_INTERFACE version); /* Since 1.2.1 */
RadioInstance*
radio_instance_new_with_modem_slot_and_version(
const char* dev,
const char* name,
const char* modem,
int slot_index,
RADIO_INTERFACE version); /* Since 1.2.1 */
RadioInstance*
radio_instance_get(
const char* dev,
const char* name);
RadioInstance*
radio_instance_get_with_version(
const char* dev,
const char* name,
RADIO_INTERFACE version); /* Since 1.2.2 */
RadioInstance* const*
radio_instance_get_all(
void);
@@ -160,6 +202,11 @@ radio_instance_send_request_sync(
RADIO_REQ code,
GBinderLocalRequest* args);
void
radio_instance_set_enabled(
RadioInstance* radio,
gboolean enabled); /* Since 1.0.7 */
gulong
radio_instance_add_indication_handler(
RadioInstance* radio,
@@ -200,6 +247,12 @@ radio_instance_add_death_handler(
RadioInstanceFunc func,
gpointer user_data);
gulong
radio_instance_add_enabled_handler(
RadioInstance* radio,
RadioInstanceFunc func,
gpointer user_data); /* Since 1.0.7 */
void
radio_instance_remove_handler(
RadioInstance* radio,

View File

@@ -1,6 +1,7 @@
/*
* 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>
* Copyright (C) 2021 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -45,10 +46,29 @@ typedef struct radio_instance RadioInstance;
typedef struct radio_registry RadioRegistry;
#define RADIO_IFACE_PREFIX "android.hardware.radio@"
#define RADIO_IFACE "IRadio"
#define RADIO_RESPONSE_IFACE "IRadioResponse"
#define RADIO_INDICATION_IFACE "IRadioIndication"
#define RADIO_IFACE_1_0(x) RADIO_IFACE_PREFIX "1.0::" x
#define RADIO_1_0 RADIO_IFACE_1_0("IRadio")
#define RADIO_RESPONSE_1_0 RADIO_IFACE_1_0("IRadioResponse")
#define RADIO_INDICATION_1_0 RADIO_IFACE_1_0("IRadioIndication")
#define RADIO_IFACE_1_1(x) RADIO_IFACE_PREFIX "1.1::" x
#define RADIO_IFACE_1_2(x) RADIO_IFACE_PREFIX "1.2::" x
#define RADIO_IFACE_1_3(x) RADIO_IFACE_PREFIX "1.3::" x
#define RADIO_IFACE_1_4(x) RADIO_IFACE_PREFIX "1.4::" x
#define RADIO_1_0 RADIO_IFACE_1_0(RADIO_IFACE)
#define RADIO_1_1 RADIO_IFACE_1_1(RADIO_IFACE)
#define RADIO_1_2 RADIO_IFACE_1_2(RADIO_IFACE)
#define RADIO_1_3 RADIO_IFACE_1_3(RADIO_IFACE)
#define RADIO_1_4 RADIO_IFACE_1_4(RADIO_IFACE)
#define RADIO_RESPONSE_1_0 RADIO_IFACE_1_0(RADIO_RESPONSE_IFACE)
#define RADIO_RESPONSE_1_1 RADIO_IFACE_1_1(RADIO_RESPONSE_IFACE)
#define RADIO_RESPONSE_1_2 RADIO_IFACE_1_2(RADIO_RESPONSE_IFACE)
#define RADIO_RESPONSE_1_3 RADIO_IFACE_1_3(RADIO_RESPONSE_IFACE)
#define RADIO_RESPONSE_1_4 RADIO_IFACE_1_4(RADIO_RESPONSE_IFACE)
#define RADIO_INDICATION_1_0 RADIO_IFACE_1_0(RADIO_INDICATION_IFACE)
#define RADIO_INDICATION_1_1 RADIO_IFACE_1_1(RADIO_INDICATION_IFACE)
#define RADIO_INDICATION_1_2 RADIO_IFACE_1_2(RADIO_INDICATION_IFACE)
#define RADIO_INDICATION_1_3 RADIO_IFACE_1_3(RADIO_INDICATION_IFACE)
#define RADIO_INDICATION_1_4 RADIO_IFACE_1_4(RADIO_INDICATION_IFACE)
/* Types defined in types.hal */
@@ -127,6 +147,16 @@ typedef enum radio_cell_info_type {
} RADIO_CELL_INFO_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_CELL_INFO_TYPE) == 4);
/* Cast guint8 RadioCellInfo_1_4.cellInfoType to this. */
typedef enum radio_cell_info_type_1_4 {
RADIO_CELL_INFO_1_4_GSM = 0,
RADIO_CELL_INFO_1_4_CDMA,
RADIO_CELL_INFO_1_4_WCDMA,
RADIO_CELL_INFO_1_4_TD_SCDMA,
RADIO_CELL_INFO_1_4_LTE,
RADIO_CELL_INFO_1_4_NR
} RADIO_CELL_INFO_TYPE_1_4; /* Since 1.4.1 */
typedef enum radio_tech {
RADIO_TECH_UNKNOWN = 0,
RADIO_TECH_GPRS,
@@ -175,6 +205,45 @@ typedef enum radio_access_family {
} RADIO_ACCESS_FAMILY;
G_STATIC_ASSERT(sizeof(RADIO_ACCESS_FAMILY) == 4);
typedef enum radio_apn_auth_type {
RADIO_APN_AUTH_NONE,
RADIO_APN_AUTH_PAP,
RADIO_APN_AUTH_CHAP,
RADIO_APN_AUTH_PAP_CHAP
} RADIO_APN_AUTH_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_APN_AUTH_TYPE) == 4);
typedef enum radio_apn_types {
RADIO_APN_TYPE_NONE = 0,
RADIO_APN_TYPE_DEFAULT = 1 << 0,
RADIO_APN_TYPE_MMS = 1 << 1,
RADIO_APN_TYPE_SUPL = 1 << 2,
RADIO_APN_TYPE_DUN = 1 << 3,
RADIO_APN_TYPE_HIPRI = 1 << 4,
RADIO_APN_TYPE_FOTA = 1 << 5,
RADIO_APN_TYPE_IMS = 1 << 6,
RADIO_APN_TYPE_CBS = 1 << 7,
RADIO_APN_TYPE_IA = 1 << 8,
RADIO_APN_TYPE_EMERGENCY = 1 << 9,
RADIO_APN_TYPE_MCX = 1 << 10, /* Since 1.2.5 */
RADIO_APN_TYPE_ALL = RADIO_APN_TYPE_DEFAULT | RADIO_APN_TYPE_MMS |
RADIO_APN_TYPE_SUPL | RADIO_APN_TYPE_DUN | RADIO_APN_TYPE_HIPRI |
RADIO_APN_TYPE_FOTA | RADIO_APN_TYPE_IMS | RADIO_APN_TYPE_CBS |
RADIO_APN_TYPE_IA | RADIO_APN_TYPE_EMERGENCY | RADIO_APN_TYPE_MCX
} RADIO_APN_TYPES;
G_STATIC_ASSERT(sizeof(RADIO_APN_TYPES) == 4);
typedef enum radio_data_profile_id {
RADIO_DATA_PROFILE_INVALID = -1,
RADIO_DATA_PROFILE_DEFAULT = 0,
RADIO_DATA_PROFILE_TETHERED = 1,
RADIO_DATA_PROFILE_IMS = 2,
RADIO_DATA_PROFILE_FOTA = 3,
RADIO_DATA_PROFILE_CBS = 4,
RADIO_DATA_PROFILE_OEM_BASE = 1000
} RADIO_DATA_PROFILE_ID;
G_STATIC_ASSERT(sizeof(RADIO_DATA_PROFILE_ID) == 4);
typedef enum radio_card_state {
RADIO_CARD_STATE_ABSENT,
RADIO_CARD_STATE_PRESENT,
@@ -258,6 +327,81 @@ typedef enum radio_capability_status {
} RADIO_CAPABILITY_STATUS;
G_STATIC_ASSERT(sizeof(RADIO_CAPABILITY_STATUS) == 4);
typedef enum radio_device_state {
RADIO_DEVICE_STATE_POWER_SAVE_MODE,
RADIO_DEVICE_STATE_CHARGING_STATE,
RADIO_DEVICE_STATE_LOW_DATA_EXPECTED
} RADIO_DEVICE_STATE;
G_STATIC_ASSERT(sizeof(RADIO_DEVICE_STATE) == 4);
typedef enum radio_data_request_reason {
RADIO_DATA_REQUEST_REASON_NORMAL = 1,
RADIO_DATA_REQUEST_REASON_SHUTDOWN,
RADIO_DATA_REQUEST_REASON_HANDOVER
} RADIO_DATA_REQUEST_REASON; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RADIO_DATA_REQUEST_REASON) == 4);
typedef enum radio_access_network {
RADIO_ACCESS_NETWORK_UNKNOWN,
RADIO_ACCESS_NETWORK_GERAN,
RADIO_ACCESS_NETWORK_UTRAN,
RADIO_ACCESS_NETWORK_EUTRAN,
RADIO_ACCESS_NETWORK_CDMA2000,
RADIO_ACCESS_NETWORK_IWLAN
} RADIO_ACCESS_NETWORK; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RADIO_ACCESS_NETWORK) == 4);
typedef enum radio_data_profile_type {
RADIO_DATA_PROFILE_COMMON,
RADIO_DATA_PROFILE_3GPP,
RADIO_DATA_PROFILE_3GPP2
} RADIO_DATA_PROFILE_TYPE; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_DATA_PROFILE_TYPE) == 4);
typedef enum radio_pdp_protocol_type {
RADIO_PDP_PROTOCOL_UNKNOWN = -1,
RADIO_PDP_PROTOCOL_IP,
RADIO_PDP_PROTOCOL_IPV6,
RADIO_PDP_PROTOCOL_IPV4V6,
RADIO_PDP_PROTOCOL_PPP,
RADIO_PDP_PROTOCOL_NON_IP,
RADIO_PDP_PROTOCOL_UNSTRUCTURED
} RADIO_PDP_PROTOCOL_TYPE; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_PDP_PROTOCOL_TYPE) == 4);
typedef enum radio_emergency_service_category {
RADIO_EMERGENCY_SERVICE_UNSPECIFIED = 0,
RADIO_EMERGENCY_SERVICE_POLICE = 1 << 0,
RADIO_EMERGENCY_SERVICE_AMBULANCE = 1 << 1,
RADIO_EMERGENCY_SERVICE_FIRE_BRIGADE = 1 << 2,
RADIO_EMERGENCY_SERVICE_MARINE_GUARD = 1 << 3,
RADIO_EMERGENCY_SERVICE_MOUNTAIN_RESCUE = 1 << 4,
RADIO_EMERGENCY_SERVICE_MIEC = 1 << 5,
RADIO_EMERGENCY_SERVICE_AIEC = 1 << 6
} RADIO_EMERGENCY_SERVICE_CATEGORY; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_EMERGENCY_SERVICE_CATEGORY) == 4);
typedef enum radio_emergency_number_source {
RADIO_EMERGENCY_NUMBER_NETWORK_SIGNALING = 1 << 0,
RADIO_EMERGENCY_NUMBER_SIM = 1 << 1,
RADIO_EMERGENCY_NUMBER_MODEM_CONFIG = 1 << 2,
RADIO_EMERGENCY_NUMBER_DEFAULT = 1 << 3
} RADIO_EMERGENCY_NUMBER_SOURCE; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_EMERGENCY_NUMBER_SOURCE) == 4);
typedef enum radio_cell_connection_status {
RADIO_CELL_CONNECTION_NONE,
RADIO_CELL_CONNECTION_PRIMARY_SERVING,
RADIO_CELL_CONNECTION_SECONDARY_SERVING
} RADIO_CELL_CONNECTION_STATUS; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_CELL_CONNECTION_STATUS) == 4);
typedef enum radio_scan_status {
RADIO_SCAN_PARTIAL = 1,
RADIO_SCAN_COMPLETE = 2
} RADIO_SCAN_STATUS; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RADIO_SCAN_STATUS) == 4);
typedef struct radio_response_info {
RADIO_RESP_TYPE type RADIO_ALIGNED(4);
guint32 serial RADIO_ALIGNED(4);
@@ -275,6 +419,23 @@ typedef struct radio_card_status {
} RADIO_ALIGNED(8) RadioCardStatus;
G_STATIC_ASSERT(sizeof(RadioCardStatus) == 40);
typedef struct radio_card_status_1_2 {
RadioCardStatus base RADIO_ALIGNED(8);
gint32 physicalSlotId RADIO_ALIGNED(4);
GBinderHidlString atr RADIO_ALIGNED(8);
GBinderHidlString iccid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCardStatus_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCardStatus_1_2) == 80);
typedef struct radio_card_status_1_4 {
RadioCardStatus base RADIO_ALIGNED(8);
gint32 physicalSlotId RADIO_ALIGNED(4);
GBinderHidlString atr RADIO_ALIGNED(8);
GBinderHidlString iccid RADIO_ALIGNED(8);
GBinderHidlString eid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCardStatus_1_4; /* Since 1.4.0 */
G_STATIC_ASSERT(sizeof(RadioCardStatus_1_4) == 96);
typedef struct radio_app_status {
RADIO_APP_TYPE appType RADIO_ALIGNED(4);
RADIO_APP_STATE appState RADIO_ALIGNED(4);
@@ -311,6 +472,12 @@ typedef struct radio_call {
} RADIO_ALIGNED(8) RadioCall;
G_STATIC_ASSERT(sizeof(RadioCall) == 88);
typedef struct radio_call_1_2 {
RadioCall base RADIO_ALIGNED(8);
gint32 audioQuality RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCall_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCall_1_2) == 96);
typedef struct radio_dial {
GBinderHidlString address RADIO_ALIGNED(8);
gint32 clir RADIO_ALIGNED(4);
@@ -333,26 +500,47 @@ typedef struct radio_operator_info {
G_STATIC_ASSERT(sizeof(RadioOperatorInfo) == 56);
typedef struct radio_data_profile {
gint32 profileId RADIO_ALIGNED(4);
RADIO_DATA_PROFILE_ID profileId RADIO_ALIGNED(4);
GBinderHidlString apn RADIO_ALIGNED(8);
GBinderHidlString protocol RADIO_ALIGNED(8);
GBinderHidlString roamingProtocol RADIO_ALIGNED(8);
gint32 authType RADIO_ALIGNED(4);
RADIO_APN_AUTH_TYPE authType RADIO_ALIGNED(4);
GBinderHidlString user RADIO_ALIGNED(8);
GBinderHidlString password RADIO_ALIGNED(8);
gint32 type RADIO_ALIGNED(4);
RADIO_DATA_PROFILE_TYPE type RADIO_ALIGNED(4);
gint32 maxConnsTime RADIO_ALIGNED(4);
gint32 maxConns RADIO_ALIGNED(4);
gint32 waitTime RADIO_ALIGNED(4);
guint8 enabled RADIO_ALIGNED(1);
gint32 supportedApnTypesBitmap RADIO_ALIGNED(4);
gint32 bearerBitmap RADIO_ALIGNED(4);
RADIO_APN_TYPES supportedApnTypesBitmap RADIO_ALIGNED(4);
RADIO_ACCESS_FAMILY bearerBitmap RADIO_ALIGNED(4);
gint32 mtu RADIO_ALIGNED(4);
gint32 mvnoType RADIO_ALIGNED(4);
GBinderHidlString mvnoMatchData RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioDataProfile;
G_STATIC_ASSERT(sizeof(RadioDataProfile) == 152);
typedef struct radio_data_profile_1_4 {
RADIO_DATA_PROFILE_ID profileId RADIO_ALIGNED(4);
GBinderHidlString apn RADIO_ALIGNED(8);
RADIO_PDP_PROTOCOL_TYPE protocol RADIO_ALIGNED(4);
RADIO_PDP_PROTOCOL_TYPE roamingProtocol RADIO_ALIGNED(4);
RADIO_APN_AUTH_TYPE authType RADIO_ALIGNED(4);
GBinderHidlString user RADIO_ALIGNED(8);
GBinderHidlString password RADIO_ALIGNED(8);
RADIO_DATA_PROFILE_TYPE type RADIO_ALIGNED(4);
gint32 maxConnsTime RADIO_ALIGNED(4);
gint32 maxConns RADIO_ALIGNED(4);
gint32 waitTime RADIO_ALIGNED(4);
guint8 enabled RADIO_ALIGNED(1);
RADIO_APN_TYPES supportedApnTypesBitmap RADIO_ALIGNED(4);
RADIO_ACCESS_FAMILY bearerBitmap RADIO_ALIGNED(4);
gint32 mtu RADIO_ALIGNED(4);
guint8 preferred RADIO_ALIGNED(1);
guint8 persistent RADIO_ALIGNED(1);
} RADIO_ALIGNED(8) RadioDataProfile_1_4; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioDataProfile_1_4) == 112);
typedef struct radio_data_call {
gint32 status RADIO_ALIGNED(4);
gint32 suggestedRetryTime RADIO_ALIGNED(4);
@@ -368,6 +556,21 @@ typedef struct radio_data_call {
} RADIO_ALIGNED(8) RadioDataCall;
G_STATIC_ASSERT(sizeof(RadioDataCall) == 120);
typedef struct radio_data_call_1_4 {
gint32 cause RADIO_ALIGNED(4);
gint32 suggestedRetryTime RADIO_ALIGNED(4);
gint32 cid RADIO_ALIGNED(4);
gint32 active RADIO_ALIGNED(4);
RADIO_PDP_PROTOCOL_TYPE type RADIO_ALIGNED(4);
GBinderHidlString ifname RADIO_ALIGNED(8);
GBinderHidlVec addresses RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
GBinderHidlVec dnses RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
GBinderHidlVec gateways RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
GBinderHidlVec pcscf RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
gint32 mtu RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioDataCall_1_4; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioDataCall_1_4) == 112);
#define DATA_CALL_VERSION (11)
typedef struct radio_sms_write_args {
@@ -377,13 +580,13 @@ typedef struct radio_sms_write_args {
} RADIO_ALIGNED(8) RadioSmsWriteArgs;
G_STATIC_ASSERT(sizeof(RadioSmsWriteArgs) == 40);
typedef struct GsmSmsMessage {
typedef struct radio_gsm_sms_message {
GBinderHidlString smscPdu RADIO_ALIGNED(8);
GBinderHidlString pdu RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioGsmSmsMessage;
G_STATIC_ASSERT(sizeof(RadioGsmSmsMessage) == 32);
typedef struct SendSmsResult {
typedef struct radio_send_sms_result {
gint32 messageRef RADIO_ALIGNED(4);
GBinderHidlString ackPDU RADIO_ALIGNED(8);
gint32 errorCode RADIO_ALIGNED(4);
@@ -403,6 +606,17 @@ typedef struct radio_icc_io {
} RADIO_ALIGNED(8) RadioIccIo;
G_STATIC_ASSERT(sizeof(RadioIccIo) == 88);
typedef struct radio_sim_apdu {
gint32 sessionId RADIO_ALIGNED(4);
gint32 cla RADIO_ALIGNED(4);
gint32 instruction RADIO_ALIGNED(4);
gint32 p1 RADIO_ALIGNED(4);
gint32 p2 RADIO_ALIGNED(4);
gint32 p3 RADIO_ALIGNED(4);
GBinderHidlString data RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioSimApdu;
G_STATIC_ASSERT(sizeof(RadioSimApdu) == 40); /* Since 1.2.6 */
typedef struct radio_icc_io_result {
gint32 sw1 RADIO_ALIGNED(4);
gint32 sw2 RADIO_ALIGNED(4);
@@ -420,6 +634,16 @@ typedef struct radio_call_forward_info {
} RADIO_ALIGNED(8) RadioCallForwardInfo;
G_STATIC_ASSERT(sizeof(RadioCallForwardInfo) == 40);
typedef struct radio_emergency_number {
GBinderHidlString number RADIO_ALIGNED(8);
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
RADIO_EMERGENCY_SERVICE_CATEGORY categories RADIO_ALIGNED(4);
GBinderHidlVec urns RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
RADIO_EMERGENCY_NUMBER_SOURCE sources RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioEmergencyNumber; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioEmergencyNumber) == 80);
#define RADIO_CELL_INVALID_VALUE (INT_MAX)
typedef struct radio_cell_identity {
@@ -432,19 +656,49 @@ typedef struct radio_cell_identity {
} RADIO_ALIGNED(8) RadioCellIdentity;
G_STATIC_ASSERT(sizeof(RadioCellIdentity) == 88);
typedef struct radio_cell_identity_1_2 {
RADIO_CELL_INFO_TYPE cellInfoType RADIO_ALIGNED(4);
GBinderHidlVec gsm RADIO_ALIGNED(8); /* vec<RadioCellIdentityGsm_1_2> */
GBinderHidlVec wcdma RADIO_ALIGNED(8); /* vec<RadioCellIdentityWcdma_1_2> */
GBinderHidlVec cdma RADIO_ALIGNED(8); /* vec<RadioCellIdentityCdma_1_2> */
GBinderHidlVec lte RADIO_ALIGNED(8); /* vec<RadioCellIdentityLte_1_2> */
GBinderHidlVec tdscdma RADIO_ALIGNED(8);/*vec<RadioCellIdentityTdscdma_1_2>*/
} RADIO_ALIGNED(8) RadioCellIdentity_1_2; /* Since 1.2.4 */
G_STATIC_ASSERT(sizeof(RadioCellIdentity_1_2) == 88);
typedef struct radio_cell_info {
RADIO_CELL_INFO_TYPE cellInfoType RADIO_ALIGNED(4);
guint8 registered RADIO_ALIGNED(1);
gint32 timeStampType RADIO_ALIGNED(4);
guint64 timeStamp RADIO_ALIGNED(8);
GBinderHidlVec gsm RADIO_ALIGNED(8); /* vec<RadioCellInfoGsm> */
GBinderHidlVec cdma RADIO_ALIGNED(8); /* vec<RadioCellInfoCdma> */
GBinderHidlVec gsm RADIO_ALIGNED(8); /* vec<RadioCellInfoGsm> */
GBinderHidlVec cdma RADIO_ALIGNED(8); /* vec<RadioCellInfoCdma> */
GBinderHidlVec lte RADIO_ALIGNED(8); /* vec<RadioCellInfoLte> */
GBinderHidlVec wcdma RADIO_ALIGNED(8); /* vec<RadioCellInfoWcdma> */
GBinderHidlVec tdscdma RADIO_ALIGNED(8); /* vec<RadioCellInfoTdscdma> */
GBinderHidlVec wcdma RADIO_ALIGNED(8); /* vec<RadioCellInfoWcdma> */
GBinderHidlVec tdscdma RADIO_ALIGNED(8); /* vec<RadioCellInfoTdscdma> */
} RADIO_ALIGNED(8) RadioCellInfo;
G_STATIC_ASSERT(sizeof(RadioCellInfo) == 104);
typedef struct radio_cell_info_1_2 {
RADIO_CELL_INFO_TYPE cellInfoType RADIO_ALIGNED(4);
guint8 registered RADIO_ALIGNED(1);
gint32 timeStampType RADIO_ALIGNED(4);
guint64 timeStamp RADIO_ALIGNED(8);
GBinderHidlVec gsm RADIO_ALIGNED(8); /* vec<RadioCellInfoGsm> */
GBinderHidlVec cdma RADIO_ALIGNED(8); /* vec<RadioCellInfoCdma> */
GBinderHidlVec lte RADIO_ALIGNED(8); /* vec<RadioCellInfoLte> */
GBinderHidlVec wcdma RADIO_ALIGNED(8); /* vec<RadioCellInfoWcdma> */
GBinderHidlVec tdscdma RADIO_ALIGNED(8); /* vec<RadioCellInfoTdscdma> */
RADIO_CELL_CONNECTION_STATUS connectionStatus RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfo_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfo_1_2) == 112);
typedef struct radio_cell_identity_operator_names {
GBinderHidlString alphaLong RADIO_ALIGNED(8);
GBinderHidlString alphaShort RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellIdentityOperatorNames; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityOperatorNames) == 32);
typedef struct radio_cell_identity_gsm {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
@@ -455,6 +709,12 @@ typedef struct radio_cell_identity_gsm {
} RADIO_ALIGNED(8) RadioCellIdentityGsm;
G_STATIC_ASSERT(sizeof(RadioCellIdentityGsm) == 48);
typedef struct radio_cell_identity_gsm_1_2 {
RadioCellIdentityGsm base RADIO_ALIGNED(8);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellIdentityGsm_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityGsm_1_2) == 80);
typedef struct radio_cell_identity_wcdma {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
@@ -465,6 +725,12 @@ typedef struct radio_cell_identity_wcdma {
} RADIO_ALIGNED(8) RadioCellIdentityWcdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityWcdma) == 48);
typedef struct radio_cell_identity_wcdma_1_2 {
RadioCellIdentityWcdma base RADIO_ALIGNED(8);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellIdentityWcdma_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityWcdma_1_2) == 80);
typedef struct radio_cell_identity_cdma {
gint32 networkId RADIO_ALIGNED(4);
gint32 systemId RADIO_ALIGNED(4);
@@ -474,6 +740,12 @@ typedef struct radio_cell_identity_cdma {
} RADIO_ALIGNED(4) RadioCellIdentityCdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityCdma) == 20);
typedef struct radio_cell_identity_cdma_1_2 {
RadioCellIdentityCdma base RADIO_ALIGNED(4);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
} RADIO_ALIGNED(4) RadioCellIdentityCdma_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityCdma_1_2) == 56);
typedef struct radio_cell_identity_lte {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
@@ -484,6 +756,13 @@ typedef struct radio_cell_identity_lte {
} RADIO_ALIGNED(8) RadioCellIdentityLte;
G_STATIC_ASSERT(sizeof(RadioCellIdentityLte) == 48);
typedef struct radio_cell_identity_lte_1_2 {
RadioCellIdentityLte base RADIO_ALIGNED(8);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
gint32 bandwidth RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellIdentityLte_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityLte_1_2) == 88);
typedef struct radio_cell_identity_tdscdma {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
@@ -493,6 +772,24 @@ typedef struct radio_cell_identity_tdscdma {
} RADIO_ALIGNED(8) RadioCellIdentityTdscdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityTdscdma) == 48);
typedef struct radio_cell_identity_tdscdma_1_2 {
RadioCellIdentityTdscdma base RADIO_ALIGNED(8);
gint32 uarfcn RADIO_ALIGNED(8);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellIdentityTdscdma_1_2; /* Since 1.2.3 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityTdscdma_1_2) == 88);
typedef struct radio_cell_identity_nr {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
guint64 nci RADIO_ALIGNED(8);
guint32 pci RADIO_ALIGNED(4);
gint32 tac RADIO_ALIGNED(4);
gint32 nrarfcn RADIO_ALIGNED(4);
RadioCellIdentityOperatorNames operatorNames RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellIdentityNr; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioCellIdentityNr) == 88);
typedef struct radio_voice_reg_state_result {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
@@ -505,6 +802,18 @@ typedef struct radio_voice_reg_state_result {
} RADIO_ALIGNED(8) RadioVoiceRegStateResult;
G_STATIC_ASSERT(sizeof(RadioVoiceRegStateResult) == 120);
typedef struct radio_voice_reg_state_result_1_2 {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
guint8 cssSupported RADIO_ALIGNED(1);
gint32 roamingIndicator RADIO_ALIGNED(4);
gint32 systemIsInPrl RADIO_ALIGNED(4);
gint32 defaultRoamingIndicator RADIO_ALIGNED(4);
gint32 reasonForDenial RADIO_ALIGNED(4);
RadioCellIdentity_1_2 cellIdentity RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioVoiceRegStateResult_1_2; /* Since 1.2.4 */
G_STATIC_ASSERT(sizeof(RadioVoiceRegStateResult_1_2) == 120);
typedef struct radio_data_reg_state_result {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
@@ -514,6 +823,31 @@ typedef struct radio_data_reg_state_result {
} RADIO_ALIGNED(8) RadioDataRegStateResult;
G_STATIC_ASSERT(sizeof(RadioDataRegStateResult) == 104);
typedef struct radio_data_reg_state_result_1_2 {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
gint32 reasonDataDenied RADIO_ALIGNED(4);
gint32 maxDataCalls RADIO_ALIGNED(4);
RadioCellIdentity_1_2 cellIdentity RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioDataRegStateResult_1_2; /* Since 1.2.4 */
G_STATIC_ASSERT(sizeof(RadioDataRegStateResult_1_2) == 104);
typedef struct radio_data_reg_lte_vops_info {
guint32 isVopsSupported RADIO_ALIGNED(4);
guint32 isEmcBearerSupported RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioDataRegLteVopsInfo; /* Since 1.4.0 */
G_STATIC_ASSERT(sizeof(RadioDataRegLteVopsInfo) == 8);
typedef struct radio_data_reg_state_result_1_4 {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
gint32 reasonDataDenied RADIO_ALIGNED(4);
gint32 maxDataCalls RADIO_ALIGNED(4);
RadioCellIdentity_1_2 cellIdentity RADIO_ALIGNED(8);
RadioDataRegLteVopsInfo lteVopsInfo RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioDataRegStateResult_1_4; /* Since 1.4.0 */
G_STATIC_ASSERT(sizeof(RadioDataRegStateResult_1_4) == 112);
typedef struct radio_signal_strength_gsm {
guint32 signalStrength RADIO_ALIGNED(4);
guint32 bitErrorRate RADIO_ALIGNED(4);
@@ -527,6 +861,13 @@ typedef struct radio_signal_strength_wcdma {
} RADIO_ALIGNED(4) RadioSignalStrengthWcdma;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthWcdma) == 8);
typedef struct radio_signal_strength_wcdma_1_2 {
RadioSignalStrengthWcdma base RADIO_ALIGNED(4);
gint32 rscp RADIO_ALIGNED(4);
gint32 ecno RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthWcdma_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioSignalStrengthWcdma_1_2) == 16);
typedef struct radio_signal_strength_cdma {
guint32 dbm RADIO_ALIGNED(4);
guint32 ecio RADIO_ALIGNED(4);
@@ -555,6 +896,13 @@ typedef struct radio_signal_strength_tdscdma {
} RADIO_ALIGNED(4) RadioSignalStrengthTdScdma;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthTdScdma) == 4);
typedef struct radio_signal_strength_tdscdma_1_2 {
guint32 signalStrength RADIO_ALIGNED(4);
guint32 bitErrorRate RADIO_ALIGNED(4);
guint32 rscp RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthTdScdma_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioSignalStrengthTdScdma_1_2) == 12);
typedef struct radio_signal_strength {
RadioSignalStrengthGsm gw RADIO_ALIGNED(4);
RadioSignalStrengthCdma cdma RADIO_ALIGNED(4);
@@ -564,6 +912,37 @@ typedef struct radio_signal_strength {
} RADIO_ALIGNED(4) RadioSignalStrength;
G_STATIC_ASSERT(sizeof(RadioSignalStrength) == 60);
typedef struct radio_signal_strength_1_2 {
RadioSignalStrengthGsm gw RADIO_ALIGNED(4);
RadioSignalStrengthCdma cdma RADIO_ALIGNED(4);
RadioSignalStrengthEvdo evdo RADIO_ALIGNED(4);
RadioSignalStrengthLte lte RADIO_ALIGNED(4);
RadioSignalStrengthTdScdma tdScdma RADIO_ALIGNED(4);
RadioSignalStrengthWcdma_1_2 wcdma RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrength_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioSignalStrength_1_2) == 76);
typedef struct radio_signal_strength_nr {
gint32 ssRsrp RADIO_ALIGNED(4);
gint32 ssRsrq RADIO_ALIGNED(4);
gint32 ssSinr RADIO_ALIGNED(4);
gint32 csiRsrp RADIO_ALIGNED(4);
gint32 csiRsrq RADIO_ALIGNED(4);
gint32 csiSinr RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthNr; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioSignalStrengthNr) == 24);
typedef struct radio_signal_strength_1_4 {
RadioSignalStrengthGsm gsm RADIO_ALIGNED(4);
RadioSignalStrengthCdma cdma RADIO_ALIGNED(4);
RadioSignalStrengthEvdo evdo RADIO_ALIGNED(4);
RadioSignalStrengthLte lte RADIO_ALIGNED(4);
RadioSignalStrengthTdScdma_1_2 tdscdma RADIO_ALIGNED(4);
RadioSignalStrengthWcdma_1_2 wcdma RADIO_ALIGNED(4);
RadioSignalStrengthNr nr RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrength_1_4; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioSignalStrength_1_4) == 108);
typedef struct radio_cell_info_gsm {
RadioCellIdentityGsm cellIdentityGsm RADIO_ALIGNED(8);
RadioSignalStrengthGsm signalStrengthGsm RADIO_ALIGNED(4);
@@ -595,6 +974,64 @@ typedef struct radio_cell_info_tdscdma {
} RADIO_ALIGNED(8) RadioCellInfoTdscdma;
G_STATIC_ASSERT(sizeof(RadioCellInfoTdscdma) == 56);
typedef struct radio_cell_info_gsm_1_2 {
RadioCellIdentityGsm_1_2 cellIdentityGsm RADIO_ALIGNED(8);
RadioSignalStrengthGsm signalStrengthGsm RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoGsm_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfoGsm_1_2) == 96);
typedef struct radio_cell_info_wcdma_1_2 {
RadioCellIdentityWcdma_1_2 cellIdentityWcdma RADIO_ALIGNED(8);
RadioSignalStrengthWcdma_1_2 signalStrengthWcdma RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoWcdma_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfoWcdma_1_2) == 96);
typedef struct radio_cell_info_cdma_1_2 {
RadioCellIdentityCdma_1_2 cellIdentityCdma RADIO_ALIGNED(4);
RadioSignalStrengthCdma signalStrengthCdma RADIO_ALIGNED(4);
RadioSignalStrengthEvdo signalStrengthEvdo RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioCellInfoCdma_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfoCdma_1_2) == 80);
typedef struct radio_cell_info_lte_1_2 {
RadioCellIdentityLte_1_2 cellIdentityLte RADIO_ALIGNED(8);
RadioSignalStrengthLte signalStrengthLte RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoLte_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfoLte_1_2) == 112);
typedef struct radio_cell_info_lte_1_4 {
RadioCellInfoLte_1_2 base RADIO_ALIGNED(8);
guint8 isEndcAvailable RADIO_ALIGNED(1);
} RADIO_ALIGNED(8) RadioCellInfoLte_1_4; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioCellInfoLte_1_4) == 120);
typedef struct radio_cell_info_tdscdma_1_2 {
RadioCellIdentityTdscdma_1_2 cellIdentityTdscdma RADIO_ALIGNED(8);
RadioSignalStrengthTdScdma_1_2 signalStrengthTdscdma RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoTdscdma_1_2; /* Since 1.2.0 */
G_STATIC_ASSERT(sizeof(RadioCellInfoTdscdma_1_2) == 104);
typedef struct radio_cell_info_nr {
RadioSignalStrengthNr signalStrength RADIO_ALIGNED(4);
RadioCellIdentityNr cellidentity RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellInfoNr; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioCellInfoNr) == 112);
typedef struct radio_cell_info_1_4 {
guint32 registered RADIO_ALIGNED(1);
guint32 connectionStatus RADIO_ALIGNED(4);
guint8 cellInfoType RADIO_ALIGNED(1); /* RADIO_CELL_INFO_TYPE_1_4 */
union {
RadioCellInfoGsm_1_2 gsm RADIO_ALIGNED(8);
RadioCellInfoCdma_1_2 cdma RADIO_ALIGNED(8);
RadioCellInfoWcdma_1_2 wcdma RADIO_ALIGNED(8);
RadioCellInfoTdscdma_1_2 tdscdma RADIO_ALIGNED(8);
RadioCellInfoLte_1_4 lte RADIO_ALIGNED(8);
RadioCellInfoNr nr RADIO_ALIGNED(8);
} info RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioCellInfo_1_4; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioCellInfo_1_4) == 136);
typedef struct radio_gsm_broadcast_sms_config {
gint32 fromServiceId RADIO_ALIGNED(4);
gint32 toServiceId RADIO_ALIGNED(4);
@@ -651,6 +1088,37 @@ typedef struct radio_activity_stats_info {
} RADIO_ALIGNED(4) RadioActivityStatsInfo;
G_STATIC_ASSERT(sizeof(RadioActivityStatsInfo) == 32);
typedef struct radio_hardware_config {
gint32 type RADIO_ALIGNED(4);
GBinderHidlString uuid RADIO_ALIGNED(8);
gint32 state RADIO_ALIGNED(4);
GBinderHidlVec modem RADIO_ALIGNED(8); /* vec<RadioHardwareConfigModem> */
GBinderHidlVec sim RADIO_ALIGNED(8); /* vec<RadioHardwareConfigSim> */
} RADIO_ALIGNED(8) RadioHardwareConfig;
G_STATIC_ASSERT(sizeof(RadioHardwareConfig) == 64);
typedef struct radio_hardware_config_modem {
gint32 rilModel RADIO_ALIGNED(4);
guint32 rat RADIO_ALIGNED(4);
gint32 maxVoice RADIO_ALIGNED(4);
gint32 maxData RADIO_ALIGNED(4);
gint32 maxStandby RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioHardwareConfigModem;
G_STATIC_ASSERT(sizeof(RadioHardwareConfigModem) == 20);
typedef struct radio_hardware_config_sim {
GBinderHidlString modemUuid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioHardwareConfigSim;
G_STATIC_ASSERT(sizeof(RadioHardwareConfigSim) == 16);
typedef struct radio_network_scan_result {
RADIO_SCAN_STATUS status RADIO_ALIGNED(4);
guint32 error RADIO_ALIGNED(4);
GBinderHidlVec networkInfos RADIO_ALIGNED(8); /* vec<RadioCellInfo> */
/* or vec<RadioCellInfo_1_4> */
} RADIO_ALIGNED(8) RadioNetworkScanResult; /* Since 1.2.5 */
G_STATIC_ASSERT(sizeof(RadioNetworkScanResult) == 24);
/* c(req,resp,callName,CALL_NAME) */
#define RADIO_CALL_1_0(c) \
c(2,1,getIccCardStatus,GET_ICC_CARD_STATUS) \
@@ -782,6 +1250,32 @@ G_STATIC_ASSERT(sizeof(RadioActivityStatsInfo) == 32);
c(128,127,setIndicationFilter,SET_INDICATION_FILTER) \
c(129,128,setSimCardPower,SET_SIM_CARD_POWER)
#define RADIO_CALL_1_1(c) \
c(131,130,setCarrierInfoForImsiEncryption,SET_CARRIER_INFO_FOR_IMSI_ENCRYPTION) \
c(132,131,setSimCardPower_1_1,SET_SIM_CARD_POWER_1_1) \
c(133,132,startNetworkScan,START_NETWORK_SCAN) \
c(134,133,stopNetworkScan,STOP_NETWORK_SCAN) \
c(135,134,startKeepalive,START_KEEPALIVE) \
c(136,135,stopKeepalive,STOP_KEEPALIVE)
#define RADIO_CALL_1_2(c) /* Since 1.2.0 */ \
c(139,138,setSignalStrengthReportingCriteria,SET_SIGNAL_STRENGTH_REPORTING_CRITERIA) \
c(140,139,setLinkCapacityReportingCriteria,SET_LINK_CAPACITY_REPORTING_CRITERIA)
#define RADIO_CALL_1_3(c) /* Since 1.2.5 */ \
c(143,144,setSystemSelectionChannels,SET_SYSTEM_SELECTION_CHANNELS) \
c(144,145,enableModem,ENABLE_MODEM) \
c(145,146,getModemStackStatus,GET_MODEM_STACK_STATUS)
#define RADIO_CALL_1_4(c) /* Since 1.2.5 */ \
c(149,147,emergencyDial,EMERGENCY_DIAL) \
c(150,148,startNetworkScan_1_4,START_NETWORKSCAN_1_4) \
c(151,152,getPreferredNetworkTypeBitmap,GET_PREFERRED_NETWORK_TYPE_BITMAP) \
c(152,153,setPreferredNetworkTypeBitmap,SET_PREFERRED_NETWORK_TYPE_BITMAP) \
c(153,156,setAllowedCarriers_1_4,SET_ALLOWED_CARRIERS_1_4) \
c(154,157,getAllowedCarriers_1_4,GET_ALLOWED_CARRIERS_1_4) \
c(155,158,getSignalStrength_1_4,GET_SIGNAL_STRENGTH_1_4)
/* e(code,eventName,EVENT_NAME) */
#define RADIO_EVENT_1_0(e) \
e(1,radioStateChanged,RADIO_STATE_CHANGED) \
@@ -830,30 +1324,124 @@ G_STATIC_ASSERT(sizeof(RadioActivityStatsInfo) == 32);
e(44,pcoData,PCO_DATA) \
e(45,modemReset,MODEM_RESET)
#define RADIO_EVENT_1_1(e) \
e(46,carrierInfoForImsiEncryption,CARRIER_INFO_FOR_IMSI_ENCRYPTION) \
e(47,networkScanResult,NETWORK_SCAN_RESULT) \
e(48,keepaliveStatus,KEEPALIVE_STATUS)
#define RADIO_EVENT_1_2(e) /* Since 1.2.0 */ \
e(49,networkScanResult_1_2,NETWORK_SCAN_RESULT_1_2) \
e(50,cellInfoList_1_2,CELL_INFO_LIST_1_2) \
e(51,currentLinkCapacityEstimate,CURRENT_LINK_CAPACITY_ESTIMATE) \
e(52,currentPhysicalChannelConfigs,CURRENT_PHYSICAL_CHANNEL_CONFIGS) \
e(53,currentSignalStrength_1_2,CURRENT_SIGNAL_STRENGTH_1_2)
#define RADIO_EVENT_1_4(e) /* Since 1.2.5 */ \
e(54,currentEmergencyNumberList,CURRENT_EMERGENCY_NUMBER_LIST) \
e(55,cellInfoList_1_4,CELL_INFO_LIST_1_4) \
e(56,networkScanResult_1_4,NETWORK_SCAN_RESULT_1_4) \
e(57,currentPhysicalChannelConfigs_1_4,CURRENT_PHYSICAL_CHANNEL_CONFIGS_1_4) \
e(58,dataCallListChanged_1_4,DATA_CALL_LIST_CHANGED_1_4) \
e(59,currentSignalStrength_1_4,CURRENT_SIGNAL_STRENGTH_1_4)
typedef enum radio_req {
RADIO_REQ_ANY = 0,
RADIO_REQ_NONE = 0,
RADIO_REQ_SET_RESPONSE_FUNCTIONS = 1, /* setResponseFunctions */
#define RADIO_REQ_(req,resp,Name,NAME) RADIO_REQ_##NAME = req,
/* android.hardware.radio@1.0::IRadio */
RADIO_REQ_SET_RESPONSE_FUNCTIONS = 1, /* setResponseFunctions */
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT = 130, /* responseAcknowledgement */
RADIO_1_0_REQ_LAST = RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT,
/* android.hardware.radio@1.1::IRadio */
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_1_1_REQ_LAST = RADIO_REQ_STOP_KEEPALIVE,
/* android.hardware.radio@1.2::IRadio */
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_REQ_START_NETWORK_SCAN_1_2 = 137,
RADIO_REQ_SET_INDICATION_FILTER_1_2 = 138,
RADIO_REQ_SETUP_DATA_CALL_1_2 = 141,
RADIO_REQ_DEACTIVATE_DATA_CALL_1_2 = 142,
RADIO_1_2_REQ_LAST = RADIO_REQ_DEACTIVATE_DATA_CALL_1_2,
/* android.hardware.radio@1.3::IRadio */
RADIO_CALL_1_3(RADIO_REQ_) /* Since 1.2.5 */
RADIO_1_3_REQ_LAST = RADIO_REQ_GET_MODEM_STACK_STATUS,
/* android.hardware.radio@1.4::IRadio */
RADIO_CALL_1_4(RADIO_REQ_) /* Since 1.2.5 */
RADIO_REQ_SETUP_DATA_CALL_1_4 = 146,
RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4 = 147,
RADIO_REQ_SET_DATA_PROFILE_1_4 = 148,
RADIO_1_4_REQ_LAST = RADIO_REQ_GET_SIGNAL_STRENGTH_1_4
#undef RADIO_REQ_
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT = 130 /* responseAcknowledgement */
} RADIO_REQ;
typedef enum radio_resp {
RADIO_RESP_ANY = 0,
RADIO_RESP_NONE = 0,
#define RADIO_RESP_(req,resp,Name,NAME) RADIO_RESP_##NAME = resp,
/* android.hardware.radio@1.0::IRadioResponse */
RADIO_CALL_1_0(RADIO_RESP_)
RADIO_RESP_ACKNOWLEDGE_REQUEST = 129, /* acknowledgeRequest */
RADIO_1_0_RESP_LAST = RADIO_RESP_ACKNOWLEDGE_REQUEST, /* Since 1.2.4 */
/* android.hardware.radio@1.1::IRadioResponse */
RADIO_CALL_1_1(RADIO_RESP_)
RADIO_1_1_RESP_LAST = RADIO_RESP_STOP_KEEPALIVE, /* Since 1.2.4 */
/* android.hardware.radio@1.2::IRadioResponse */
RADIO_CALL_1_2(RADIO_RESP_)
RADIO_RESP_GET_CELL_INFO_LIST_1_2 = 136,
RADIO_RESP_GET_ICC_CARD_STATUS_1_2 = 137,
RADIO_RESP_GET_CURRENT_CALLS_1_2 = 140,
RADIO_RESP_GET_SIGNAL_STRENGTH_1_2 = 141,
RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2 = 142,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2 = 143,
RADIO_1_2_RESP_LAST = RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2, /* Since 1.2.4 */
/* android.hardware.radio@1.3::IRadioResponse */
RADIO_CALL_1_3(RADIO_RESP_) /* Since 1.2.5 */
RADIO_1_3_RESP_LAST = RADIO_RESP_GET_MODEM_STACK_STATUS,
/* android.hardware.radio@1.4::IRadioResponse */
RADIO_CALL_1_4(RADIO_RESP_) /* Since 1.2.5 */
RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4 = 149,
RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4 = 150,
RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4 = 151,
RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4 = 154,
RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4 = 155,
RADIO_1_4_RESP_LAST = RADIO_RESP_GET_SIGNAL_STRENGTH_1_4
#undef RADIO_RESP_
RADIO_RESP_ACKNOWLEDGE_REQUEST = 129
} RADIO_RESP;
typedef enum radio_ind {
RADIO_IND_ANY = 0,
RADIO_IND_NONE = 0,
#define RADIO_IND_(code,Name,NAME) RADIO_IND_##NAME = code,
/* android.hardware.radio@1.0::IRadioIndication */
RADIO_EVENT_1_0(RADIO_IND_)
RADIO_1_0_IND_LAST = RADIO_IND_MODEM_RESET, /* Since 1.2.4 */
/* android.hardware.radio@1.1::IRadioIndication */
RADIO_EVENT_1_1(RADIO_IND_)
RADIO_1_1_IND_LAST = RADIO_IND_KEEPALIVE_STATUS, /* Since 1.2.4 */
/* android.hardware.radio@1.2::IRadioIndication */
RADIO_EVENT_1_2(RADIO_IND_)
RADIO_1_2_IND_LAST = RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_2, /* Since 1.2.4 */
/* android.hardware.radio@1.3::IRadioIndication */
RADIO_1_3_IND_LAST = RADIO_1_2_IND_LAST, /* Since 1.2.5 */
/* android.hardware.radio@1.4::IRadioIndication */
RADIO_EVENT_1_4(RADIO_IND_)
RADIO_1_4_IND_LAST = RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_4 /* Since 1.2.5 */
#undef RADIO_IND_
} RADIO_IND;

View File

@@ -1,10 +1,10 @@
name=gbinder-radio
libdir=/usr/lib
libdir=@libdir@
includedir=/usr/include
Name: libgbinder-radio
Description: Binder client library for Android radio interfaces
Version: [version]
Requires: glib-2.0 libglibutil libgbinder
Version: @version@
Requires.private: glib-2.0 libglibutil libgbinder
Libs: -L${libdir} -l${name}
Cflags: -I${includedir} -I${includedir}/${name}

View File

@@ -1,15 +1,20 @@
Name: libgbinder-radio
Version: 1.0.2
Version: 1.4.2
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 libglibutil_version 1.0.34
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libglibutil)
BuildRequires: pkgconfig(libgbinder) >= 1.0.9
Requires: libgbinder >= 1.0.9
BuildRequires: pkgconfig(libglibutil) >= %{libglibutil_version}
BuildRequires: pkgconfig(libgbinder) >= %{libgbinder_version}
Requires: libglibutil >= %{libglibutil_version}
Requires: libgbinder >= %{libgbinder_version}
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
@@ -28,11 +33,14 @@ This package contains the development library for %{name}.
%setup -q
%build
make KEEP_SYMBOLS=1 release pkgconfig
make %{_smp_mflags} LIBDIR=%{_libdir} KEEP_SYMBOLS=1 release pkgconfig
%install
rm -rf %{buildroot}
make install-dev DESTDIR=%{buildroot}
make LIBDIR=%{_libdir} DESTDIR=%{buildroot} install-dev
%check
make -C unit test
%post -p /sbin/ldconfig

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -34,6 +34,8 @@
* any official policies, either expressed or implied.
*/
#define GLIB_DISABLE_DEPRECATION_WARNINGS
#include "radio_instance.h"
#include "radio_registry_p.h"
#include "radio_util.h"
@@ -43,6 +45,7 @@
#include <gutil_idlepool.h>
#include <gutil_misc.h>
#include <gutil_strv.h>
#include <glib-object.h>
@@ -59,6 +62,7 @@ struct radio_instance_priv {
char* dev;
char* slot;
char* key;
char* modem;
};
G_DEFINE_TYPE(RadioInstance, radio_instance, G_TYPE_OBJECT)
@@ -70,6 +74,7 @@ enum radio_instance_signal {
SIGNAL_OBSERVE_RESPONSE,
SIGNAL_ACK,
SIGNAL_DEATH,
SIGNAL_ENABLED,
SIGNAL_COUNT
};
@@ -79,11 +84,66 @@ enum radio_instance_signal {
#define SIGNAL_OBSERVE_RESPONSE_NAME "radio-instance-observe-response"
#define SIGNAL_ACK_NAME "radio-instance-ack"
#define SIGNAL_DEATH_NAME "radio-instance-death"
#define SIGNAL_ENABLED_NAME "radio-instance-enabled"
static guint radio_instance_signals[SIGNAL_COUNT] = { 0 };
static GHashTable* radio_instance_table = NULL;
#define DEFAULT_INTERFACE RADIO_INTERFACE_1_0
static const GBinderClientIfaceInfo radio_iface_info[] = {
{RADIO_1_4, RADIO_1_4_REQ_LAST },
{RADIO_1_3, RADIO_1_3_REQ_LAST },
{RADIO_1_2, RADIO_1_2_REQ_LAST },
{RADIO_1_1, RADIO_1_1_REQ_LAST },
{RADIO_1_0, RADIO_1_0_REQ_LAST }
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_iface_info) == RADIO_INTERFACE_COUNT);
static const char* const radio_indication_ifaces[] = {
RADIO_INDICATION_1_4,
RADIO_INDICATION_1_3,
RADIO_INDICATION_1_2,
RADIO_INDICATION_1_1,
RADIO_INDICATION_1_0,
NULL
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_indication_ifaces) == RADIO_INTERFACE_COUNT + 1);
static const char* const radio_response_ifaces[] = {
RADIO_RESPONSE_1_4,
RADIO_RESPONSE_1_3,
RADIO_RESPONSE_1_2,
RADIO_RESPONSE_1_1,
RADIO_RESPONSE_1_0,
NULL
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_response_ifaces) == RADIO_INTERFACE_COUNT + 1);
typedef struct radio_interface_desc {
RADIO_INTERFACE version;
const char* radio_iface;
const char* const* ind_ifaces;
const char* const* resp_ifaces;
} RadioInterfaceDesc;
#define RADIO_INTERFACE_INDEX(x) (RADIO_INTERFACE_COUNT - x - 1)
#define RADIO_INTERFACE_DESC(v) \
RADIO_INTERFACE_##v, RADIO_##v, \
radio_indication_ifaces + RADIO_INTERFACE_INDEX(RADIO_INTERFACE_##v), \
radio_response_ifaces + RADIO_INTERFACE_INDEX(RADIO_INTERFACE_##v)
static const RadioInterfaceDesc radio_interfaces[] = {
{ RADIO_INTERFACE_DESC(1_4) },
{ RADIO_INTERFACE_DESC(1_3) },
{ RADIO_INTERFACE_DESC(1_2) },
{ RADIO_INTERFACE_DESC(1_1) },
{ RADIO_INTERFACE_DESC(1_0) }
};
G_STATIC_ASSERT(G_N_ELEMENTS(radio_interfaces) == RADIO_INTERFACE_COUNT);
/*==========================================================================*
* Implementation
*==========================================================================*/
@@ -155,7 +215,7 @@ radio_instance_indication(
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
if (!g_strcmp0(iface, RADIO_INDICATION_1_0)) {
if (gutil_strv_contains((const GStrV*)radio_indication_ifaces, iface)) {
GBinderReader reader;
guint type;
@@ -202,25 +262,26 @@ radio_instance_response(
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
if (!g_strcmp0(iface, RADIO_RESPONSE_1_0)) {
if (gutil_strv_contains((const GStrV*)radio_response_ifaces, iface)) {
GBinderReader reader;
/* All these should be one-way transactions */
GASSERT(flags & GBINDER_TX_FLAG_ONEWAY);
gbinder_remote_request_init_reader(req, &reader);
if (code == RADIO_RESP_ACKNOWLEDGE_REQUEST) {
/* oneway acknowledgeRequest(int32_t serial) */
gint32 serial;
GDEBUG(RADIO_RESPONSE_1_0 " %u acknowledgeRequest", code);
if (gbinder_remote_request_read_int32(req, &serial)) {
GDEBUG("%s %u acknowledgeRequest", iface, code);
if (gbinder_reader_read_int32(&reader, &serial)) {
g_signal_emit(self, radio_instance_signals[SIGNAL_ACK], 0,
serial);
}
} else {
/* All other responses have RadioResponseInfo */
GBinderReader reader;
const RadioResponseInfo* info;
const RadioResponseInfo* info =
gbinder_reader_read_hidl_struct(&reader, RadioResponseInfo);
gbinder_remote_request_init_reader(req, &reader);
info = gbinder_reader_read_hidl_struct(&reader, RadioResponseInfo);
if (info) {
GQuark quark = radio_instance_resp_quark(self, code);
gboolean handled = FALSE;
@@ -309,76 +370,101 @@ radio_instance_gone(
{
char* key = key_ptr;
GASSERT(radio_instance_table);
GVERBOSE_("%s", key);
radio_instance_remove(key);
g_free(key);
}
static
RadioInstance*
radio_instance_create_version(
GBinderServiceManager* sm,
GBinderRemoteObject* remote,
const char* dev,
const char* slot,
const char* key,
const char* modem,
int slot_index,
const RadioInterfaceDesc* desc)
{
RadioInstance* self = g_object_new(RADIO_TYPE_INSTANCE, NULL);
RadioInstancePriv* priv = self->priv;
GBinderLocalRequest* req;
GBinderWriter writer;
int status;
self->slot = priv->slot = g_strdup(slot);
self->dev = priv->dev = g_strdup(dev);
self->key = priv->key = g_strdup(key);
self->modem = priv->modem = g_strdup(modem);
self->slot_index = slot_index;
self->version = desc->version;
priv->remote = gbinder_remote_object_ref(remote);
priv->client = gbinder_client_new2(remote,
radio_iface_info, G_N_ELEMENTS(radio_iface_info));
priv->indication = gbinder_servicemanager_new_local_object2(sm,
desc->ind_ifaces, radio_instance_indication, self);
priv->response = gbinder_servicemanager_new_local_object2(sm,
desc->resp_ifaces, radio_instance_response, self);
priv->death_id = gbinder_remote_object_add_death_handler(remote,
radio_instance_died, self);
/* IRadio::setResponseFunctions */
req = gbinder_client_new_request2(priv->client,
RADIO_REQ_SET_RESPONSE_FUNCTIONS);
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_local_object(&writer, priv->response);
gbinder_writer_append_local_object(&writer, priv->indication);
gbinder_remote_reply_unref(gbinder_client_transact_sync_reply(priv->client,
RADIO_REQ_SET_RESPONSE_FUNCTIONS, req, &status));
GVERBOSE_("setResponseFunctions %s status %d", slot, status);
gbinder_local_request_unref(req);
GDEBUG("Instance '%s'", slot);
/*
* Don't destroy GBinderServiceManager right away in case if we
* have another slot to initialize.
*/
gutil_idle_pool_add(priv->idle, gbinder_servicemanager_ref(sm),
(GDestroyNotify) gbinder_servicemanager_unref);
return self;
}
static
RadioInstance*
radio_instance_create(
const char* dev,
const char* slot,
const char* key)
const char* key,
const char* modem,
int slot_index,
RADIO_INTERFACE max_version)
{
RadioInstance* self = NULL;
GBinderServiceManager* sm = gbinder_servicemanager_new(dev);
if (sm) {
int status = 0;
const char* iface = RADIO_1_0;
char* fqname = g_strconcat(iface, "/", slot, NULL);
GBinderRemoteObject* remote = gbinder_servicemanager_get_service_sync
(sm, fqname, &status);
guint i;
if (remote) {
RadioInstancePriv* priv;
GBinderLocalRequest* req;
GBinderRemoteReply* reply;
GBinderWriter writer;
for (i = 0; i < G_N_ELEMENTS(radio_interfaces) && !self; i++) {
const RadioInterfaceDesc* desc = radio_interfaces + i;
GINFO("Connected to %s", fqname);
/* get_service returns auto-released reference,
* we need to add a reference of our own */
gbinder_remote_object_ref(remote);
if (desc->version <= max_version) {
char* fqname = g_strconcat(desc->radio_iface, "/", slot, NULL);
GBinderRemoteObject* obj = /* autoreleased */
gbinder_servicemanager_get_service_sync(sm, fqname, NULL);
self = g_object_new(RADIO_TYPE_INSTANCE, NULL);
priv = self->priv;
self->slot = priv->slot = g_strdup(slot);
self->dev = priv->dev = g_strdup(dev);
self->key = priv->key = g_strdup(key);
priv->remote = remote;
priv->client = gbinder_client_new(remote, iface);
priv->indication = gbinder_servicemanager_new_local_object
(sm, RADIO_INDICATION_1_0, radio_instance_indication, self);
priv->response = gbinder_servicemanager_new_local_object
(sm, RADIO_RESPONSE_1_0, radio_instance_response, self);
priv->death_id = gbinder_remote_object_add_death_handler
(remote, radio_instance_died, self);
/* IRadio::setResponseFunctions */
req = gbinder_client_new_request(priv->client);
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_local_object(&writer, priv->response);
gbinder_writer_append_local_object(&writer, priv->indication);
reply = gbinder_client_transact_sync_reply(priv->client,
RADIO_REQ_SET_RESPONSE_FUNCTIONS, req, &status);
GVERBOSE_("setResponseFunctions %s status %d", slot, status);
gbinder_local_request_unref(req);
gbinder_remote_reply_unref(reply);
GDEBUG("Instance '%s'", slot);
/*
* Don't destroy GBinderServiceManager right away in case if we
* have another slot to initialize.
*/
gutil_idle_pool_add_object(priv->idle, g_object_ref(sm));
if (obj) {
GINFO("Connected to %s", fqname);
self = radio_instance_create_version(sm, obj, dev, slot,
key, modem, slot_index, desc);
}
g_free(fqname);
}
}
gbinder_servicemanager_unref(sm);
g_free(fqname);
}
return self;
}
@@ -387,9 +473,10 @@ static
char*
radio_instance_make_key(
const char* dev,
const char* name)
const char* name,
RADIO_INTERFACE version)
{
return g_strconcat(dev, ":", name, NULL);
return g_strdup_printf("%s:%s:%d", dev, name, version);
}
/*==========================================================================*
@@ -400,9 +487,58 @@ RadioInstance*
radio_instance_new(
const char* dev,
const char* name)
{
return radio_instance_new_with_version(dev, name, DEFAULT_INTERFACE);
}
RadioInstance*
radio_instance_new_with_modem_and_slot(
const char* dev,
const char* name,
const char* modem,
int slot) /* Since 1.0.7 */
{
return radio_instance_new_with_modem_slot_and_version(dev, name, modem,
slot, DEFAULT_INTERFACE);
}
RadioInstance*
radio_instance_new_with_version(
const char* dev,
const char* name,
RADIO_INTERFACE version) /* Since 1.2.1 */
{
if (name && name[0]) {
const char* modem;
int slot;
if (!g_strcmp0(name, "slot1")) {
modem = "/ril_0";
slot = 0;
} else if (!g_strcmp0(name, "slot2")) {
modem = "/ril_1";
slot = 1;
} else {
GWARN("Unexpected slot '%s'", name);
modem = NULL;
slot = 0;
}
return radio_instance_new_with_modem_slot_and_version(dev, name, modem,
slot, version);
}
return NULL;
}
RadioInstance*
radio_instance_new_with_modem_slot_and_version(
const char* dev,
const char* name,
const char* modem,
int slot,
RADIO_INTERFACE version) /* Since 1.2.1 */
{
if (dev && dev[0] && name && name[0]) {
char* key = radio_instance_make_key(dev, name);
char* key = radio_instance_make_key(dev, name, version);
RadioInstance* self = NULL;
if (radio_instance_table) {
@@ -412,7 +548,7 @@ radio_instance_new(
g_free(key);
return radio_instance_ref(self);
} else {
self = radio_instance_create(dev, name, key);
self = radio_instance_create(dev, name, key, modem, slot, version);
if (self) {
if (!radio_instance_table) {
radio_instance_table = g_hash_table_new_full
@@ -433,15 +569,31 @@ RadioInstance*
radio_instance_get(
const char* dev,
const char* name)
{
return radio_instance_get_with_version(dev, name, DEFAULT_INTERFACE);
}
RadioInstance*
radio_instance_get_with_interface(
const char* dev,
const char* name,
RADIO_INTERFACE version) /* 1.2.1, deprecated */
{
return radio_instance_get_with_version(dev, name, version);
}
RadioInstance*
radio_instance_get_with_version(
const char* dev,
const char* name,
RADIO_INTERFACE version) /* Since 1.2.2 */
{
RadioInstance* self = NULL;
if (dev && dev[0] && name && name[0]) {
char* key = radio_instance_make_key(dev, name);
if (dev && dev[0] && name && name[0] && radio_instance_table) {
char* key = radio_instance_make_key(dev, name, version);
if (radio_instance_table) {
self = g_hash_table_lookup(radio_instance_table, key);
}
self = g_hash_table_lookup(radio_instance_table, key);
g_free(key);
}
return self;
@@ -550,7 +702,6 @@ radio_instance_ind_name(
}
}
gboolean
radio_instance_is_dead(
RadioInstance* self)
@@ -575,7 +726,7 @@ radio_instance_new_request(
RADIO_REQ code)
{
if (G_LIKELY(self)) {
return gbinder_client_new_request(self->priv->client);
return gbinder_client_new_request2(self->priv->client, code);
}
return NULL;
}
@@ -593,6 +744,18 @@ radio_instance_send_request_sync(
return FALSE;
}
void
radio_instance_set_enabled(
RadioInstance* self,
gboolean enabled) /* Since 1.0.7 */
{
if (G_LIKELY(self) && self->enabled != enabled) {
self->enabled = enabled;
GDEBUG("%s %sabled", self->slot, enabled ? "en" : "dis");
g_signal_emit(self, radio_instance_signals[SIGNAL_ENABLED], 0);
}
}
gulong
radio_instance_add_indication_handler(
RadioInstance* self,
@@ -665,7 +828,17 @@ radio_instance_add_death_handler(
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ACK_NAME, G_CALLBACK(func), user_data) : 0;
SIGNAL_DEATH_NAME, G_CALLBACK(func), user_data) : 0;
}
gulong
radio_instance_add_enabled_handler(
RadioInstance* self,
RadioInstanceFunc func,
gpointer user_data) /* Since 1.0.7 */
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ENABLED_NAME, G_CALLBACK(func), user_data) : 0;
}
void
@@ -721,6 +894,7 @@ radio_instance_finalize(
g_free(priv->slot);
g_free(priv->dev);
g_free(priv->key);
g_free(priv->modem);
G_OBJECT_CLASS(radio_instance_parent_class)->finalize(object);
}
@@ -761,6 +935,10 @@ radio_instance_class_init(
g_signal_new(SIGNAL_DEATH_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
radio_instance_signals[SIGNAL_ENABLED] =
g_signal_new(SIGNAL_ENABLED_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
/*

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2020 Jolla Ltd.
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -41,11 +41,13 @@
void
radio_registry_instance_added(
RadioInstance* instance);
RadioInstance* instance)
G_GNUC_INTERNAL;
void
radio_registry_instance_removed(
const char* key);
const char* key)
G_GNUC_INTERNAL;
#endif /* RADIO_REGISTRY_PRIVATE_H */

View File

@@ -1,6 +1,6 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2018-2021 Jolla Ltd.
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
@@ -49,7 +49,18 @@ radio_req_name(
#define RADIO_REQ_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return #Name;
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_CALL_1_3(RADIO_REQ_)
RADIO_CALL_1_4(RADIO_REQ_)
#undef RADIO_REQ_
case RADIO_REQ_START_NETWORK_SCAN_1_2: return "startNetworkScan_1_2";
case RADIO_REQ_SET_INDICATION_FILTER_1_2: return "setIndicationFilter_1_2";
case RADIO_REQ_SETUP_DATA_CALL_1_2: return "setupDataCall_1_2";
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2: return "deactivateDataCall_1_2";
case RADIO_REQ_SETUP_DATA_CALL_1_4: return "setupDataCall_1_4";
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4: return "setInitialAttachApn_1_4";
case RADIO_REQ_SET_DATA_PROFILE_1_4: return "setDataProfile_1_4";
case RADIO_REQ_ANY:
break;
}
@@ -65,7 +76,33 @@ radio_resp_name(
#define RADIO_RESP_(req,resp,Name,NAME) \
case RADIO_RESP_##NAME: return #Name "Response";
RADIO_CALL_1_0(RADIO_RESP_)
RADIO_CALL_1_1(RADIO_RESP_)
RADIO_CALL_1_2(RADIO_RESP_)
RADIO_CALL_1_3(RADIO_RESP_)
RADIO_CALL_1_4(RADIO_RESP_)
#undef RADIO_RESP_
case RADIO_RESP_GET_CELL_INFO_LIST_1_2:
return "getCellInfoListResponse_1_2";
case RADIO_RESP_GET_ICC_CARD_STATUS_1_2:
return "getIccCardStatusResponse_1_2";
case RADIO_RESP_GET_CURRENT_CALLS_1_2:
return "getCurrentCallsResponse_1_2";
case RADIO_RESP_GET_SIGNAL_STRENGTH_1_2:
return "getSignalStrengthResponse_1_2";
case RADIO_RESP_GET_VOICE_REGISTRATION_STATE_1_2:
return "getVoiceRegistrationStateResponse_1_2";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_2:
return "getDataRegistrationStateResponse_1_2";
case RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4:
return "getCellInfoListResponse_1_4";
case RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4:
return "getDataRegistrationStateResponse_1_4";
case RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4:
return "getIccCardStatusResponse_1_4";
case RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4:
return "getDataCallListResponse_1_4";
case RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4:
return "setupDataCallResponse_1_4";
case RADIO_RESP_ANY:
break;
}
@@ -80,6 +117,9 @@ radio_ind_name(
#define RADIO_IND_(code,Name,NAME) \
case RADIO_IND_##NAME: return #Name;
RADIO_EVENT_1_0(RADIO_IND_)
RADIO_EVENT_1_1(RADIO_IND_)
RADIO_EVENT_1_2(RADIO_IND_)
RADIO_EVENT_1_4(RADIO_IND_)
#undef RADIO_IND_
case RADIO_IND_ANY:
break;
@@ -87,6 +127,17 @@ radio_ind_name(
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)
@@ -95,10 +146,24 @@ radio_req_resp(
#define RADIO_REQ_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return RADIO_RESP_##NAME;
RADIO_CALL_1_0(RADIO_REQ_)
RADIO_CALL_1_1(RADIO_REQ_)
RADIO_CALL_1_2(RADIO_REQ_)
RADIO_CALL_1_3(RADIO_REQ_)
RADIO_CALL_1_4(RADIO_REQ_)
#undef RADIO_REQ_
default:
return RADIO_RESP_NONE;
case RADIO_REQ_SET_RESPONSE_FUNCTIONS:
case RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT:
case RADIO_REQ_START_NETWORK_SCAN_1_2:
case RADIO_REQ_SET_INDICATION_FILTER_1_2:
case RADIO_REQ_SETUP_DATA_CALL_1_2:
case RADIO_REQ_DEACTIVATE_DATA_CALL_1_2:
case RADIO_REQ_SETUP_DATA_CALL_1_4:
case RADIO_REQ_SET_INITIAL_ATTACH_APN_1_4:
case RADIO_REQ_SET_DATA_PROFILE_1_4:
case RADIO_REQ_ANY:
break;
}
return RADIO_RESP_NONE;
}
/*

11
unit/Makefile Normal file
View File

@@ -0,0 +1,11 @@
# -*- Mode: makefile-gmake -*-
all:
%:
@$(MAKE) -C unit_instance $*
@$(MAKE) -C unit_registry $*
@$(MAKE) -C unit_util $*
clean: unitclean
rm -f coverage/*.gcov
rm -fr coverage/report

217
unit/common/Makefile Normal file
View File

@@ -0,0 +1,217 @@
# -*- Mode: makefile-gmake -*-
.PHONY: clean all debug release coverage
.PHONY: debug_lib release_lib coverage_lib
#
# 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
BASE_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS)
BASE_CFLAGS = $(BASE_FLAGS) $(CFLAGS)
FULL_CFLAGS = $(BASE_CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
$(shell pkg-config --cflags $(PKGS))
FULL_LDFLAGS = $(BASE_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) $@

108
unit/common/test_common.h Normal file
View File

@@ -0,0 +1,108 @@
/*
* 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.
*/
#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)
/* 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:
*/

161
unit/common/test_gbinder.h Normal file
View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2021 Jolla Ltd.
* Copyright (C) 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.
*/
#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(
void);
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_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:
*/

View File

@@ -0,0 +1,366 @@
/*
* 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_log.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;
guint32 last_code;
} TestGBinderClientIfaceRange;
struct gbinder_client {
guint32 refcount;
GBinderRemoteObject* remote;
TestGBinderClientIfaceRange* ranges;
guint nr;
};
static
void
test_gbinder_client_free(
GBinderClient* self)
{
guint i;
for (i = 0; i < self->nr; i++) {
g_free(self->ranges[i].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->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);
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);
}
}
}
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)) {
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)
{
g_source_remove((guint)id);
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -0,0 +1,153 @@
/*
* 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;
};
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);
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View 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();
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:
*/

View 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();
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:
*/

View File

@@ -0,0 +1,324 @@
/*
* 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_macros.h>
typedef enum test_gbinder_data_type {
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 {
gint32 i32;
struct {
const void* buf;
gsize size;
} blob;
GBinderLocalObject* obj;
} data;
void (*destroy)(TestGBinderDataItem*);
};
struct test_gbinder_data {
guint32 refcount;
TestGBinderDataItem* items;
};
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
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);
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;
}
}
/*==========================================================================*
* Internal API
*==========================================================================*/
TestGBinderData*
test_gbinder_data_new(
void)
{
TestGBinderData* data = g_new0(TestGBinderData, 1);
g_atomic_int_set(&data->refcount, 1);
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)
{
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;
}
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;
}
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);
}
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->data.blob.buf = buf;
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:
*/

View 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:
*/

View 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:
*/

View 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:
*/

View 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
View 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:
*/

54
unit/coverage/run Executable file
View File

@@ -0,0 +1,54 @@
#!/bin/bash
#
# This script requires lcov, dirname
#
TESTS="\
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

View File

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

View File

@@ -0,0 +1,820 @@
/*
* 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 "test_gbinder.h"
#include "radio_instance.h"
#include "radio_util.h"
#include <gutil_strv.h>
#include <gutil_log.h>
#define DEFAULT_INTERFACE RADIO_INTERFACE_1_0
#define DEV GBINDER_DEFAULT_BINDER
#define UNKNOWN_VALUE (0x7fffffff)
#define UNKNOWN_VALUE_STR "2147483647" /* 0x7fffffff */
#define UNKNOWN_REQ ((RADIO_REQ)UNKNOWN_VALUE)
#define UNKNOWN_REQ_STR UNKNOWN_VALUE_STR
#define UNKNOWN_IND ((RADIO_IND)UNKNOWN_VALUE)
#define UNKNOWN_IND_STR UNKNOWN_VALUE_STR
#define UNKNOWN_RESP ((RADIO_RESP)UNKNOWN_VALUE)
#define UNKNOWN_RESP_STR UNKNOWN_VALUE_STR
#define INVALID_IND_TYPE ((RADIO_IND_TYPE)UNKNOWN_VALUE)
RadioInstance*
radio_instance_get_with_interface(
const char* dev,
const char* name,
RADIO_INTERFACE version); /* Deprecated and removed from the .h file */
gboolean
radio_instance_is_dead(
RadioInstance* self); /* No sure why this one is missing */
typedef struct test_radio_service {
GBinderLocalObject* obj;
GBinderRemoteObject* resp_obj;
GBinderRemoteObject* ind_obj;
GHashTable* req_count;
} TestRadioService;
static TestOpt test_opt;
static const GBinderClientIfaceInfo radio_ind_iface_info[] = {
{RADIO_INDICATION_1_4, RADIO_1_4_IND_LAST },
{RADIO_INDICATION_1_3, RADIO_1_3_IND_LAST },
{RADIO_INDICATION_1_2, RADIO_1_2_IND_LAST },
{RADIO_INDICATION_1_1, RADIO_1_1_IND_LAST },
{RADIO_INDICATION_1_0, RADIO_1_0_IND_LAST }
};
static const GBinderClientIfaceInfo radio_resp_iface_info[] = {
{RADIO_RESPONSE_1_4, RADIO_1_4_RESP_LAST },
{RADIO_RESPONSE_1_3, RADIO_1_3_RESP_LAST },
{RADIO_RESPONSE_1_2, RADIO_1_2_RESP_LAST },
{RADIO_RESPONSE_1_1, RADIO_1_1_RESP_LAST },
{RADIO_RESPONSE_1_0, RADIO_1_0_RESP_LAST }
};
static const char* const radio_req_ifaces[] = {
RADIO_1_4,
RADIO_1_3,
RADIO_1_2,
RADIO_1_1,
RADIO_1_0,
NULL
};
static
gboolean
test_response_not_handled(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data)
{
g_assert_not_reached();
return FALSE;
}
static
void
test_response_not_observed(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data)
{
g_assert_not_reached();
}
/*==========================================================================*
* Test IRadio service
*==========================================================================*/
static
int
test_service_req_count(
TestRadioService* service,
RADIO_REQ req)
{
return GPOINTER_TO_INT(g_hash_table_lookup(service->req_count,
GINT_TO_POINTER(req)));
}
static
GBinderLocalReply*
test_service_txproc(
GBinderLocalObject* obj,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status,
void* user_data)
{
TestRadioService* service = user_data;
const char* iface = gbinder_remote_request_interface(req);
if (gutil_strv_contains((const GStrV*)radio_req_ifaces, iface)) {
const int count = test_service_req_count(service, code) + 1;
GBinderReader reader;
GDEBUG("%s %s %d", iface, radio_req_name(code), count);
g_hash_table_insert(service->req_count, GINT_TO_POINTER(code),
GINT_TO_POINTER(count));
gbinder_remote_request_init_reader(req, &reader);
switch (code) {
case RADIO_REQ_SET_RESPONSE_FUNCTIONS:
gbinder_remote_object_unref(service->resp_obj);
gbinder_remote_object_unref(service->ind_obj);
service->resp_obj = gbinder_reader_read_object(&reader);
service->ind_obj = gbinder_reader_read_object(&reader);
g_assert(service->resp_obj);
g_assert(service->ind_obj);
break;
}
*status = GBINDER_STATUS_OK;
return NULL;
} else {
GDEBUG("%s %u", iface, code);
*status = GBINDER_STATUS_FAILED;
return NULL;
}
}
static
void
test_service_init(
TestRadioService* service)
{
memset(service, 0, sizeof(*service));
service->obj = test_gbinder_local_object_new(NULL,
test_service_txproc, service);
service->req_count = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static
void
test_service_cleanup(
TestRadioService* service)
{
g_hash_table_destroy(service->req_count);
gbinder_remote_object_unref(service->resp_obj);
gbinder_remote_object_unref(service->ind_obj);
gbinder_local_object_unref(service->obj);
memset(service, 0, sizeof(*service));
}
/*==========================================================================*
* null
*==========================================================================*/
static
void
test_null(
void)
{
radio_instance_set_enabled(NULL, FALSE);
radio_instance_remove_handler(NULL, 0);
radio_instance_remove_handlers(NULL, NULL, 0);
radio_instance_unref(NULL);
g_assert(radio_instance_is_dead(NULL));
g_assert(!radio_instance_get(NULL, NULL));
g_assert(!radio_instance_get("", NULL));
g_assert(!radio_instance_get("/dev/binder", NULL));
g_assert(!radio_instance_get("/dev/binder", ""));
g_assert(!radio_instance_get_with_interface("", "", DEFAULT_INTERFACE));
g_assert(!radio_instance_get_with_version("foo", "bar", DEFAULT_INTERFACE));
g_assert(!radio_instance_new(NULL, NULL));
g_assert(!radio_instance_new_with_modem_and_slot(NULL, NULL, NULL, 0));
g_assert(!radio_instance_new_with_version(NULL, NULL, DEFAULT_INTERFACE));
g_assert(!radio_instance_new_with_version(NULL, "", DEFAULT_INTERFACE));
g_assert(!radio_instance_new_request(NULL, 0));
g_assert(!radio_instance_ack(NULL));
g_assert(!radio_instance_ref(NULL));
g_assert(!radio_instance_send_request_sync(NULL, 0, NULL));
g_assert(!radio_instance_add_indication_handler(NULL, 0, NULL, NULL));
g_assert(!radio_instance_add_indication_observer(NULL, 0, NULL, NULL));
g_assert(!radio_instance_add_response_handler(NULL, 0, NULL, NULL));
g_assert(!radio_instance_add_response_observer(NULL, 0, NULL, NULL));
g_assert(!radio_instance_add_ack_handler(NULL, NULL, NULL));
g_assert(!radio_instance_add_death_handler(NULL, NULL, NULL));
g_assert(!radio_instance_add_enabled_handler(NULL, NULL, NULL));
g_assert(!radio_instance_req_name(NULL, UNKNOWN_REQ));
g_assert(!radio_instance_resp_name(NULL, UNKNOWN_RESP));
g_assert(!radio_instance_ind_name(NULL, UNKNOWN_IND));
}
/*==========================================================================*
* basic
*==========================================================================*/
static
void
test_basic(
void)
{
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
RadioInstance* radio;
RadioInstance* const* radios;
TestRadioService service;
const RADIO_INTERFACE version = RADIO_INTERFACE_1_4;
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
/* This fails because there's no radio service */
g_assert(!radio_instance_new_with_version(DEV, slot, DEFAULT_INTERFACE));
g_assert(!radio_instance_get_all());
/* Register the service to create an instance */
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, version);
g_assert(radio);
g_assert(service.ind_obj);
g_assert(service.resp_obj);
/* The second call returns new reference to the same instance */
g_assert(radio == radio_instance_new_with_version(DEV, slot, version));
radio_instance_unref(radio);
/* The one we have created must still be there */
g_assert(radio == radio_instance_get_with_version(DEV, slot, version));
/* NULL callbacks are ignored */
g_assert(!radio_instance_add_indication_handler(radio, 0, NULL, NULL));
g_assert(!radio_instance_add_indication_observer(radio, 0, NULL, NULL));
g_assert(!radio_instance_add_response_handler(radio, 0, NULL, NULL));
g_assert(!radio_instance_add_response_observer(radio, 0, NULL, NULL));
g_assert(!radio_instance_add_ack_handler(radio, NULL, NULL));
g_assert(!radio_instance_add_death_handler(radio, NULL, NULL));
g_assert(!radio_instance_add_enabled_handler(radio, NULL, NULL));
/* Formatting unknown codes (RadioInstance owns the string) */
g_assert_cmpstr(radio_instance_req_name(radio, UNKNOWN_REQ), == ,
UNKNOWN_REQ_STR);
g_assert_cmpstr(radio_instance_resp_name(radio, UNKNOWN_RESP), == ,
UNKNOWN_RESP_STR);
g_assert_cmpstr(radio_instance_ind_name(radio, UNKNOWN_IND), == ,
UNKNOWN_IND_STR);
g_assert_cmpstr(radio_instance_req_name(radio,
RADIO_REQ_DIAL), == ,"dial");
g_assert_cmpstr(radio_instance_resp_name(radio,
RADIO_RESP_DIAL), == ,"dialResponse");
g_assert_cmpstr(radio_instance_ind_name(radio,
RADIO_IND_MODEM_RESET), == ,"modemReset");
/* The entire list consists of that one instance */
radios = radio_instance_get_all();
g_assert(radios);
g_assert(radios[0] == radio);
g_assert(!radios[1]);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* ind
*==========================================================================*/
static
gboolean
test_ind_handle(
RadioInstance* radio,
RADIO_IND code,
RADIO_IND_TYPE type,
const GBinderReader* reader,
gpointer user_data)
{
int* expected = user_data;
g_assert_cmpint(code, == ,*expected);
*expected = RADIO_IND_NONE;
radio_instance_ack(radio);
return TRUE;
}
static
void
test_ind_observe(
RadioInstance* radio,
RADIO_IND code,
RADIO_IND_TYPE type,
const GBinderReader* reader,
gpointer user_data)
{
int* expected = user_data;
g_assert_cmpint(code, == ,*expected);
*expected = RADIO_IND_NONE;
}
static
void
test_ind(
void)
{
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
RadioInstance* radio;
TestRadioService service;
GBinderClient* ind;
GBinderLocalRequest* req;
const RADIO_INTERFACE version = RADIO_INTERFACE_1_4;
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
int code[2];
ulong id[2];
/* Register the service to create an instance */
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, version);
g_assert(radio);
/* Issue invalid indication (no type) */
code[0] = code[1] = RADIO_IND_RIL_CONNECTED;
id[0] = radio_instance_add_indication_handler(radio, RADIO_IND_RIL_CONNECTED,
test_ind_handle, code + 0);
id[1] = radio_instance_add_indication_observer(radio, RADIO_IND_ANY,
test_ind_observe, code + 1);
g_assert(service.ind_obj);
ind = gbinder_client_new2(service.ind_obj,
TEST_ARRAY_AND_COUNT(radio_ind_iface_info));
req = gbinder_client_new_request2(ind, RADIO_IND_RIL_CONNECTED);
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
RADIO_IND_RIL_CONNECTED, req), == ,GBINDER_STATUS_FAILED);
/* No signals issued and no acks sent */
g_assert_cmpint(code[0], == ,RADIO_IND_RIL_CONNECTED);
g_assert_cmpint(code[1], == ,RADIO_IND_RIL_CONNECTED);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,0);
/* Another invalid indication (invalid type) */
gbinder_local_request_append_int32(req, INVALID_IND_TYPE);
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
RADIO_IND_RIL_CONNECTED, req), == ,GBINDER_STATUS_FAILED);
/* No signals issued and no acks sent */
g_assert_cmpint(code[0], == ,RADIO_IND_RIL_CONNECTED);
g_assert_cmpint(code[0], == ,RADIO_IND_RIL_CONNECTED);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,0);
/* Build a valid request and try again */
gbinder_local_request_unref(req);
req = gbinder_client_new_request2(ind, RADIO_IND_RIL_CONNECTED);
gbinder_local_request_append_int32(req, RADIO_IND_ACK_EXP);
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
RADIO_IND_RIL_CONNECTED, req), == ,GBINDER_STATUS_OK);
/* This time both handler and observer are notified, ack is sent */
g_assert_cmpint(code[0], == ,RADIO_IND_NONE);
g_assert_cmpint(code[1], == ,RADIO_IND_NONE);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,1);
/* Now issue callStateChanged but only observe it (don't handle) */
radio_instance_remove_handlers(radio, id, 1);
code[1] = RADIO_IND_CALL_STATE_CHANGED;
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
RADIO_IND_CALL_STATE_CHANGED, req), == ,GBINDER_STATUS_OK);
g_assert_cmpint(code[1], == ,RADIO_IND_NONE);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Unhandled but acked */
/* Same thing but without ack */
gbinder_local_request_unref(req);
req = gbinder_client_new_request2(ind, RADIO_IND_CALL_STATE_CHANGED);
gbinder_local_request_append_int32(req, RADIO_IND_UNSOLICITED);
code[1] = RADIO_IND_CALL_STATE_CHANGED;
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
RADIO_IND_CALL_STATE_CHANGED, req), == ,GBINDER_STATUS_OK);
g_assert_cmpint(code[1], == ,RADIO_IND_NONE);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Still 2 (not acked) */
/* Unsupported interface */
gbinder_local_request_unref(req);
req = test_gbinder_local_request_new("foo");
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
UNKNOWN_IND, req), == ,GBINDER_STATUS_FAILED);
gbinder_local_request_unref(req);
gbinder_client_unref(ind);
radio_instance_remove_all_handlers(radio, id);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* req
*==========================================================================*/
#define TEST_REQ RADIO_REQ_DIAL
static
void
test_req(
void)
{
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
TestRadioService service;
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
GBinderLocalRequest* req;
RadioInstance* radio;
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
req = radio_instance_new_request(radio, TEST_REQ);
gbinder_local_request_append_int32(req, 123);
g_assert(radio_instance_send_request_sync(radio, TEST_REQ, req));
g_assert_cmpint(test_service_req_count(&service, TEST_REQ), == ,1);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_local_request_unref(req);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* resp
*==========================================================================*/
#define TEST_RESP RADIO_RESP_DIAL
static
void
test_resp_observe(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data)
{
guint* expected = user_data;
GDEBUG("Observing resp %u", code);
g_assert_cmpuint(info->serial, == ,*expected);
*expected = 0;
}
static
gboolean
test_resp_handle(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data)
{
guint* expected = user_data;
GDEBUG("Handling resp %u", code);
g_assert_cmpuint(info->serial, == ,*expected);
*expected = 0;
if (info->type == RADIO_RESP_SOLICITED_ACK_EXP) {
radio_instance_ack(radio);
}
return TRUE;
}
static
void
test_resp(
void)
{
const char* slot = "slot2";
const char* fqname = RADIO_1_0 "/slot2";
TestRadioService service;
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
GBinderLocalRequest* req;
GBinderClient* resp;
RadioInstance* radio;
RadioResponseInfo info;
GBinderWriter writer;
guint handle_serial, observe_serial;
gulong id[2];
test_service_init(&service);
memset(&info, 0, sizeof(info));
info.type = RADIO_RESP_SOLICITED_ACK_EXP;
handle_serial = observe_serial = info.serial = 123;
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
id[0] = radio_instance_add_response_handler(radio, TEST_RESP,
test_resp_handle, &handle_serial);
id[1] = radio_instance_add_response_observer(radio, TEST_RESP,
test_resp_observe, &observe_serial);
g_assert(service.resp_obj);
resp = gbinder_client_new2(service.resp_obj,
TEST_ARRAY_AND_COUNT(radio_resp_iface_info));
/* Submit broken respose first (without info) */
req = gbinder_client_new_request2(resp, TEST_RESP);
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
== ,GBINDER_STATUS_OK);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,0);
/* Add the info and try again */
gbinder_local_request_init_writer(req, &writer);
gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
== ,GBINDER_STATUS_OK);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,1);
g_assert(!handle_serial); /* Cleared by the handler */
g_assert(!observe_serial); /* Cleared by the observer */
/* Remove the handler and check auto-ack */
radio_instance_remove_handlers(radio, id, 1);
handle_serial = observe_serial = info.serial = 124;
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
== ,GBINDER_STATUS_OK);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Acked */
g_assert_cmpuint(handle_serial, == ,info.serial); /* No handler */
g_assert(!observe_serial); /* Cleared by the observer */
/* RADIO_RESP_SOLICITED won't be acked */
info.type = RADIO_RESP_SOLICITED;
handle_serial = observe_serial = info.serial = 125;
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
== ,GBINDER_STATUS_OK);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Not acked */
g_assert_cmpuint(handle_serial, == ,info.serial); /* No handler */
g_assert(!observe_serial); /* Cleared by the observer */
/* Unsupported interface */
gbinder_local_request_unref(req);
req = test_gbinder_local_request_new("foo");
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
== ,GBINDER_STATUS_FAILED);
g_assert_cmpint(test_service_req_count(&service,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Didn't change */
gbinder_local_request_unref(req);
gbinder_client_unref(resp);
radio_instance_remove_all_handlers(radio, id);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* ack
*==========================================================================*/
static
void
test_ack_cb(
RadioInstance* radio,
guint32 serial,
gpointer user_data)
{
guint* expected = user_data;
GDEBUG("ack %u", serial);
g_assert_cmpuint(serial, == ,*expected);
*expected = 0;
}
static
void
test_ack(
void)
{
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
TestRadioService service;
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
GBinderLocalRequest* req;
GBinderClient* resp;
RadioInstance* radio;
guint serial = 123;
gulong id[3];
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
id[0] = radio_instance_add_ack_handler(radio, test_ack_cb, &serial);
id[1] = radio_instance_add_response_handler(radio, RADIO_RESP_ANY,
test_response_not_handled, NULL);
id[2] = radio_instance_add_response_observer(radio,
RADIO_RESP_ACKNOWLEDGE_REQUEST, test_response_not_observed, NULL);
g_assert(service.resp_obj);
resp = gbinder_client_new2(service.resp_obj,
TEST_ARRAY_AND_COUNT(radio_resp_iface_info));
/* Submit broken ack first (without serial) */
req = gbinder_client_new_request2(resp, RADIO_RESP_ACKNOWLEDGE_REQUEST);
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp,
RADIO_RESP_ACKNOWLEDGE_REQUEST, req), == ,GBINDER_STATUS_OK);
g_assert(serial); /* Transaction succeeds but handler is not called */
/* Add the serial and try again */
gbinder_local_request_append_int32(req, serial);
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp,
RADIO_RESP_ACKNOWLEDGE_REQUEST, req), == ,GBINDER_STATUS_OK);
g_assert(!serial); /* Cleared by the handler */
gbinder_local_request_unref(req);
gbinder_client_unref(resp);
radio_instance_remove_all_handlers(radio, id);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* enabled
*==========================================================================*/
static
void
test_enabled_cb(
RadioInstance* radio,
gpointer user_data)
{
GDEBUG("%sabled", radio->enabled ? "En" : "Dis");
(*((int*)user_data))++;
}
static
void
test_enabled(
void)
{
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
TestRadioService service;
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
RadioInstance* radio;
int n = 0;
gulong id;
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
id = radio_instance_add_enabled_handler(radio, test_enabled_cb, &n);
g_assert(id);
g_assert(!radio->enabled);
radio_instance_set_enabled(radio, TRUE);
g_assert_cmpint(n, == ,1);
g_assert(radio->enabled);
radio_instance_set_enabled(radio, TRUE);
g_assert(radio->enabled);
g_assert_cmpint(n, == ,1); /* Nothing changed */
radio_instance_set_enabled(radio, FALSE);
g_assert_cmpint(n, == ,2);
g_assert(!radio->enabled);
radio_instance_remove_handler(radio, id);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* death
*==========================================================================*/
static
void
test_death_cb(
RadioInstance* radio,
gpointer user_data)
{
GDEBUG("Boom");
(*((int*)user_data))++;
}
static
void
test_death(
void)
{
const char* slot = "slot1";
const char* fqname = RADIO_1_0 "/slot1";
TestRadioService service;
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
GBinderRemoteObject* remote;
RadioInstance* radio;
int n = 0;
gulong id;
test_service_init(&service);
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
id = radio_instance_add_death_handler(radio, test_death_cb, &n);
g_assert(id);
g_assert(!radio_instance_is_dead(radio));
test_gbinder_remote_object_kill(remote);
g_assert_cmpint(n, == ,1);
g_assert(radio_instance_is_dead(radio));
radio_instance_remove_handler(radio, 0); /* no effect */
radio_instance_remove_handler(radio, id);
radio_instance_unref(radio);
test_service_cleanup(&service);
gbinder_remote_object_unref(remote);
gbinder_servicemanager_unref(sm);
}
/*==========================================================================*
* Common
*==========================================================================*/
#define TEST_PREFIX "/instance/"
#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);
g_test_add_func(TEST_("ind"), test_ind);
g_test_add_func(TEST_("req"), test_req);
g_test_add_func(TEST_("resp"), test_resp);
g_test_add_func(TEST_("ack"), test_ack);
g_test_add_func(TEST_("enabled"), test_enabled);
g_test_add_func(TEST_("death"), test_death);
test_init(&test_opt, argc, argv);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

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

View 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
View File

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

162
unit/unit_util/unit_util.c Normal file
View File

@@ -0,0 +1,162 @@
/*
* 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_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");
}
/*==========================================================================*
* 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");
}
/*==========================================================================*
* 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");
}
/*==========================================================================*
* req_resp
*==========================================================================*/
static
void
test_req_resp(
void)
{
g_assert_cmpint(radio_req_resp(UNKNOWN_REQ), == ,RADIO_RESP_NONE);
g_assert_cmpint(radio_req_resp(RADIO_REQ_ANY), == ,RADIO_RESP_NONE);
g_assert_cmpint(radio_req_resp(RADIO_REQ_GET_ICC_CARD_STATUS),==,
RADIO_RESP_GET_ICC_CARD_STATUS);
g_assert_cmpint(radio_req_resp(RADIO_REQ_START_NETWORK_SCAN),==,
RADIO_RESP_START_NETWORK_SCAN);
g_assert_cmpint(radio_req_resp(RADIO_REQ_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA),==,
RADIO_RESP_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA);
g_assert_cmpint(radio_req_resp(RADIO_REQ_SET_SYSTEM_SELECTION_CHANNELS),==,
RADIO_RESP_SET_SYSTEM_SELECTION_CHANNELS);
g_assert_cmpint(radio_req_resp(RADIO_REQ_EMERGENCY_DIAL),==,
RADIO_RESP_EMERGENCY_DIAL);
}
/*==========================================================================*
* 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);
test_init(&test_opt, argc, argv);
return g_test_run();
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/