Compare commits
	
		
			64 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					1d14925196 | ||
| 
						 | 
					77d600150a | ||
| 
						 | 
					7684a717de | ||
| 
						 | 
					6be4596f0d | ||
| 
						 | 
					76f7fa6ee1 | ||
| 
						 | 
					c3135de5c7 | ||
| 
						 | 
					4595539656 | ||
| 
						 | 
					62a0764577 | ||
| 
						 | 
					ff65e170e1 | ||
| 
						 | 
					0ce5f268c9 | ||
| 
						 | 
					ab379e4fe3 | ||
| 
						 | 
					e4ab7078a1 | ||
| 
						 | 
					9b1c2df489 | ||
| 
						 | 
					62212c5165 | ||
| 
						 | 
					ea502d417a | ||
| 
						 | 
					1ce4ff615b | ||
| 
						 | 
					72b3fc58ec | ||
| 
						 | 
					4140def1fc | ||
| 
						 | 
					901396b385 | ||
| 
						 | 
					052a0e11fb | ||
| 
						 | 
					024f319164 | ||
| 
						 | 
					91f7b80459 | ||
| 
						 | 
					13076eb3ec | ||
| 
						 | 
					27695ee5ff | ||
| 
						 | 
					7b5656d2a8 | ||
| 
						 | 
					788d472839 | ||
| 
						 | 
					7f4446b3fd | ||
| 
						 | 
					e08ef1bdae | ||
| 
						 | 
					8039bfe66e | ||
| 
						 | 
					7e23a74fbf | ||
| 
						 | 
					a9463baaaf | ||
| 
						 | 
					ddee97fc93 | ||
| 
						 | 
					f562149d18 | ||
| 
						 | 
					21d659a5c5 | ||
| 
						 | 
					71f5632e2d | ||
| 
						 | 
					30e7563d94 | ||
| 
						 | 
					26a321bc36 | ||
| 
						 | 
					f141bd1615 | ||
| 
						 | 
					d3a63909c7 | ||
| 
						 | 
					aaa1c0c9a0 | ||
| 
						 | 
					e0ffc4d60c | ||
| 
						 | 
					94d469380e | ||
| 
						 | 
					7e4b839fc6 | ||
| 
						 | 
					0708177e94 | ||
| 
						 | 
					9047ef9a56 | ||
| 
						 | 
					bb61f00d57 | ||
| 
						 | 
					601ef084ee | ||
| 
						 | 
					3cd41646b4 | ||
| 
						 | 
					d1fb490f9b | ||
| 
						 | 
					7e0c222f1d | ||
| 
						 | 
					f5b2cc062c | ||
| 
						 | 
					9e246ebb55 | ||
| 
						 | 
					5f5afc3d76 | ||
| 
						 | 
					eab404c46b | ||
| 
						 | 
					395a50ba3d | ||
| 
						 | 
					79379ea3d1 | ||
| 
						 | 
					197e84e71a | ||
| 
						 | 
					30ea57a3cb | ||
| 
						 | 
					49fcc2a599 | ||
| 
						 | 
					6d9f87f7ea | ||
| 
						 | 
					efc30cd06d | ||
| 
						 | 
					6959979384 | ||
| 
						 | 
					1ebf32bc73 | ||
| 
						 | 
					a119a68374 | 
							
								
								
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -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
									
								
							
							
						
						
									
										6
									
								
								AUTHORS
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										33
									
								
								LICENSE
									
									
									
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										49
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										49
									
								
								Makefile
									
									
									
									
									
								
							@@ -1,7 +1,8 @@
 | 
			
		||||
# -*- Mode: makefile-gmake -*-
 | 
			
		||||
 | 
			
		||||
.PHONY: clean all debug release coverage
 | 
			
		||||
.PHONY: clean all debug release coverage test
 | 
			
		||||
.PHONY: debug_lib release_lib coverage_lib
 | 
			
		||||
.PHONY: print_debug_lib print_release_lib print_coverage_lib
 | 
			
		||||
.PHONY: pkgconfig install install-dev
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -22,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
									
								
							
							
						
						
									
										84
									
								
								debian/changelog
									
									
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										1
									
								
								debian/compat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
9
 | 
			
		||||
							
								
								
									
										17
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								debian/control
									
									
									
									
										vendored
									
									
										Normal 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
									
								
							
							
						
						
									
										33
									
								
								debian/copyright
									
									
									
									
										vendored
									
									
										Normal 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.
 | 
			
		||||
							
								
								
									
										3
									
								
								debian/libgbinder-radio-dev.install.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								debian/libgbinder-radio-dev.install.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
			
		||||
debian/tmp/@LIBDIR@/libgbinder-radio.so @LIBDIR@
 | 
			
		||||
debian/tmp/@LIBDIR@/pkgconfig/libgbinder-radio.pc @LIBDIR@/pkgconfig
 | 
			
		||||
debian/tmp/usr/include/* usr/include
 | 
			
		||||
							
								
								
									
										1
									
								
								debian/libgbinder-radio.install.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								debian/libgbinder-radio.install.in
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
debian/tmp/@LIBDIR@/libgbinder-radio.so.* @LIBDIR@
 | 
			
		||||
							
								
								
									
										14
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								debian/rules
									
									
									
									
										vendored
									
									
										Executable 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
									
								
							
							
						
						
									
										1
									
								
								debian/source/format
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
3.0 (native)
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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}
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -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 */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										11
									
								
								unit/Makefile
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										217
									
								
								unit/common/Makefile
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										108
									
								
								unit/common/test_common.h
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										161
									
								
								unit/common/test_gbinder.h
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										366
									
								
								unit/common/test_gbinder_client.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								unit/common/test_gbinder_client.c
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										153
									
								
								unit/common/test_gbinder_local_object.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								unit/common/test_gbinder_local_object.c
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										118
									
								
								unit/common/test_gbinder_local_reply.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								unit/common/test_gbinder_local_reply.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
struct gbinder_local_reply {
 | 
			
		||||
    guint32 refcount;
 | 
			
		||||
    TestGBinderData* data;
 | 
			
		||||
    char* iface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_local_reply_free(
 | 
			
		||||
    GBinderLocalReply* self)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_unref(self->data);
 | 
			
		||||
    g_free(self->iface);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderLocalReply*
 | 
			
		||||
test_gbinder_local_reply_new(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    GBinderLocalReply* self = g_new0(GBinderLocalReply, 1);
 | 
			
		||||
 | 
			
		||||
    g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
    self->data = test_gbinder_data_new();
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TestGBinderData*
 | 
			
		||||
test_gbinder_local_reply_data(
 | 
			
		||||
    GBinderLocalReply* self)
 | 
			
		||||
{
 | 
			
		||||
    return self ? self->data : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * libgbinder API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderLocalReply*
 | 
			
		||||
gbinder_local_reply_ref(
 | 
			
		||||
    GBinderLocalReply* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        g_atomic_int_inc(&self->refcount);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_local_reply_unref(
 | 
			
		||||
    GBinderLocalReply* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        if (g_atomic_int_dec_and_test(&self->refcount)) {
 | 
			
		||||
            test_gbinder_local_reply_free(self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_local_reply_init_writer(
 | 
			
		||||
    GBinderLocalReply* self,
 | 
			
		||||
    GBinderWriter* writer)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_init_writer(self->data, writer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										141
									
								
								unit/common/test_gbinder_local_request.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								unit/common/test_gbinder_local_request.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
struct gbinder_local_request {
 | 
			
		||||
    guint32 refcount;
 | 
			
		||||
    TestGBinderData* data;
 | 
			
		||||
    char* iface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_local_request_free(
 | 
			
		||||
    GBinderLocalRequest* self)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_unref(self->data);
 | 
			
		||||
    g_free(self->iface);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderLocalRequest*
 | 
			
		||||
test_gbinder_local_request_new(
 | 
			
		||||
    const char* iface)
 | 
			
		||||
{
 | 
			
		||||
    GBinderLocalRequest* self = g_new0(GBinderLocalRequest, 1);
 | 
			
		||||
 | 
			
		||||
    g_assert(iface);
 | 
			
		||||
    g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
    self->data = test_gbinder_data_new();
 | 
			
		||||
    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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										324
									
								
								unit/common/test_gbinder_reader_writer.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								unit/common/test_gbinder_reader_writer.c
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										180
									
								
								unit/common/test_gbinder_remote_object.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								unit/common/test_gbinder_remote_object.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
struct gbinder_remote_object {
 | 
			
		||||
    GObject parent;
 | 
			
		||||
    GBinderLocalObject* local;
 | 
			
		||||
    gboolean dead;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef GObjectClass GBinderRemoteObjectClass;
 | 
			
		||||
G_DEFINE_TYPE(GBinderRemoteObject, gbinder_remote_object, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
#define PARENT_CLASS gbinder_remote_object_parent_class
 | 
			
		||||
#define THIS_TYPE (gbinder_remote_object_get_type())
 | 
			
		||||
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj,THIS_TYPE,GBinderRemoteObject)
 | 
			
		||||
 | 
			
		||||
enum gbinder_remote_object_signal {
 | 
			
		||||
    SIGNAL_DEATH,
 | 
			
		||||
    SIGNAL_COUNT
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SIGNAL_DEATH_NAME "death"
 | 
			
		||||
 | 
			
		||||
static guint remote_object_signals[SIGNAL_COUNT] = { 0 };
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_object_init(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_object_finalize(
 | 
			
		||||
    GObject* object)
 | 
			
		||||
{
 | 
			
		||||
    GBinderRemoteObject* self = THIS(object);
 | 
			
		||||
 | 
			
		||||
    gbinder_local_object_unref(self->local);
 | 
			
		||||
    G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_object_class_init(
 | 
			
		||||
    GBinderRemoteObjectClass* klass)
 | 
			
		||||
{
 | 
			
		||||
    G_OBJECT_CLASS(klass)->finalize = gbinder_remote_object_finalize;
 | 
			
		||||
    remote_object_signals[SIGNAL_DEATH] =
 | 
			
		||||
        g_signal_new(SIGNAL_DEATH_NAME, G_OBJECT_CLASS_TYPE(klass),
 | 
			
		||||
            G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteObject*
 | 
			
		||||
test_gbinder_remote_object_new(
 | 
			
		||||
    GBinderLocalObject* local)
 | 
			
		||||
{
 | 
			
		||||
    GBinderRemoteObject* self = g_object_new(THIS_TYPE, NULL);
 | 
			
		||||
 | 
			
		||||
    g_assert(local);
 | 
			
		||||
    self->local = gbinder_local_object_ref(local);
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_remote_object_kill(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self && !self->dead) {
 | 
			
		||||
        self->dead = TRUE;
 | 
			
		||||
        g_signal_emit(self, remote_object_signals[SIGNAL_DEATH], 0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
test_gbinder_remote_object_dead(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
    return !self || self->dead;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderLocalObject*
 | 
			
		||||
test_gbinder_remote_object_to_local(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
    return self ? self->local : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * libgbinder API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteObject*
 | 
			
		||||
gbinder_remote_object_ref(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_object_ref(THIS(self));
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_object_unref(
 | 
			
		||||
    GBinderRemoteObject* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_object_unref(THIS(self));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
gbinder_remote_object_add_death_handler(
 | 
			
		||||
    GBinderRemoteObject* self,
 | 
			
		||||
    GBinderRemoteObjectNotifyFunc fn,
 | 
			
		||||
    void* data)
 | 
			
		||||
{
 | 
			
		||||
    return (self && fn) ? g_signal_connect(self, SIGNAL_DEATH_NAME,
 | 
			
		||||
        G_CALLBACK(fn), data) : 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_object_remove_handler(
 | 
			
		||||
    GBinderRemoteObject* self,
 | 
			
		||||
    gulong id)
 | 
			
		||||
{
 | 
			
		||||
    if (self && id) {
 | 
			
		||||
        g_signal_handler_disconnect(self, id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Remote Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										106
									
								
								unit/common/test_gbinder_remote_reply.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								unit/common/test_gbinder_remote_reply.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
struct gbinder_remote_reply {
 | 
			
		||||
    guint32 refcount;
 | 
			
		||||
    TestGBinderData* data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_remote_reply_free(
 | 
			
		||||
    GBinderRemoteReply* self)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_unref(self->data);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteReply*
 | 
			
		||||
test_gbinder_remote_reply_new(
 | 
			
		||||
    GBinderLocalReply* reply)
 | 
			
		||||
{
 | 
			
		||||
    if (reply) {
 | 
			
		||||
        GBinderRemoteReply* self = g_new0(GBinderRemoteReply, 1);
 | 
			
		||||
        TestGBinderData* data = test_gbinder_local_reply_data(reply);
 | 
			
		||||
 | 
			
		||||
        g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
        self->data = test_gbinder_data_ref(data);
 | 
			
		||||
        return self;
 | 
			
		||||
    } else {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * libgbinder API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteReply*
 | 
			
		||||
gbinder_remote_reply_ref(
 | 
			
		||||
    GBinderRemoteReply* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        g_atomic_int_inc(&self->refcount);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_reply_unref(
 | 
			
		||||
    GBinderRemoteReply* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        if (g_atomic_int_dec_and_test(&self->refcount)) {
 | 
			
		||||
            test_gbinder_remote_reply_free(self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										119
									
								
								unit/common/test_gbinder_remote_request.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								unit/common/test_gbinder_remote_request.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
struct gbinder_remote_request {
 | 
			
		||||
    guint32 refcount;
 | 
			
		||||
    TestGBinderData* data;
 | 
			
		||||
    char* iface;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_remote_request_free(
 | 
			
		||||
    GBinderRemoteRequest* self)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_unref(self->data);
 | 
			
		||||
    g_free(self->iface);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteRequest*
 | 
			
		||||
test_gbinder_remote_request_new(
 | 
			
		||||
    GBinderLocalRequest* req)
 | 
			
		||||
{
 | 
			
		||||
    GBinderRemoteRequest* self = g_new0(GBinderRemoteRequest, 1);
 | 
			
		||||
 | 
			
		||||
    g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
    self->data = test_gbinder_data_ref(test_gbinder_local_request_data(req));
 | 
			
		||||
    self->iface = g_strdup(test_gbinder_local_request_interface(req));
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * libgbinder API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteRequest*
 | 
			
		||||
gbinder_remote_request_ref(
 | 
			
		||||
    GBinderRemoteRequest* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        g_atomic_int_inc(&self->refcount);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_request_unref(
 | 
			
		||||
    GBinderRemoteRequest* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        if (g_atomic_int_dec_and_test(&self->refcount)) {
 | 
			
		||||
            test_gbinder_remote_request_free(self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
gbinder_remote_request_interface(
 | 
			
		||||
    GBinderRemoteRequest* self)
 | 
			
		||||
{
 | 
			
		||||
    return self ? self->iface : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_remote_request_init_reader(
 | 
			
		||||
    GBinderRemoteRequest* self,
 | 
			
		||||
    GBinderReader* reader)
 | 
			
		||||
{
 | 
			
		||||
    test_gbinder_data_init_reader(self->data, reader);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										180
									
								
								unit/common/test_gbinder_servicemanager.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								unit/common/test_gbinder_servicemanager.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,180 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_idlepool.h>
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
struct gbinder_servicemanager {
 | 
			
		||||
    guint32 refcount;
 | 
			
		||||
    GHashTable* services;
 | 
			
		||||
    GUtilIdlePool* pool;
 | 
			
		||||
    char* dev;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GHashTable* test_servermanagers = NULL;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_gbinder_servicemanager_free(
 | 
			
		||||
    GBinderServiceManager* self)
 | 
			
		||||
{
 | 
			
		||||
    /* Update the global table */
 | 
			
		||||
    g_assert(test_servermanagers);
 | 
			
		||||
    g_assert(g_hash_table_contains(test_servermanagers, self->dev));
 | 
			
		||||
    g_hash_table_remove(test_servermanagers, self->dev); /* Frees self->dev */
 | 
			
		||||
    if (g_hash_table_size(test_servermanagers) == 0) {
 | 
			
		||||
        g_hash_table_unref(test_servermanagers);
 | 
			
		||||
        test_servermanagers = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    gutil_idle_pool_destroy(self->pool);
 | 
			
		||||
    g_hash_table_destroy(self->services);
 | 
			
		||||
    g_free(self);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Internal API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderRemoteObject*
 | 
			
		||||
test_gbinder_servicemanager_new_service(
 | 
			
		||||
    GBinderServiceManager* self,
 | 
			
		||||
    const char* name,
 | 
			
		||||
    GBinderLocalObject* local)
 | 
			
		||||
{
 | 
			
		||||
    GBinderRemoteObject* remote = test_gbinder_remote_object_new(local);
 | 
			
		||||
 | 
			
		||||
    g_hash_table_replace(self->services, g_strdup(name), remote);
 | 
			
		||||
    return gbinder_remote_object_ref(remote);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * libgbinder API
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
GBinderServiceManager*
 | 
			
		||||
gbinder_servicemanager_new(
 | 
			
		||||
    const char* dev)
 | 
			
		||||
{
 | 
			
		||||
    GBinderServiceManager* self = NULL;
 | 
			
		||||
 | 
			
		||||
    g_assert(dev && dev[0]);
 | 
			
		||||
    if (test_servermanagers) {
 | 
			
		||||
        self = g_hash_table_lookup(test_servermanagers, dev);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (self) {
 | 
			
		||||
        gbinder_servicemanager_ref(self);
 | 
			
		||||
    } else {
 | 
			
		||||
        self = g_new0(GBinderServiceManager, 1);
 | 
			
		||||
        g_atomic_int_set(&self->refcount, 1);
 | 
			
		||||
        self->pool = gutil_idle_pool_new();
 | 
			
		||||
        self->dev = g_strdup(dev);  /* Owned by test_servermanagers */
 | 
			
		||||
        self->services = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
 | 
			
		||||
            (GDestroyNotify) gbinder_remote_object_unref);
 | 
			
		||||
 | 
			
		||||
        /* Update the global table */
 | 
			
		||||
        if (!test_servermanagers) {
 | 
			
		||||
            test_servermanagers = g_hash_table_new_full(g_str_hash, g_str_equal,
 | 
			
		||||
                g_free, NULL);
 | 
			
		||||
        }
 | 
			
		||||
        g_hash_table_replace(test_servermanagers, self->dev, self);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderServiceManager*
 | 
			
		||||
gbinder_servicemanager_ref(
 | 
			
		||||
    GBinderServiceManager* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        g_atomic_int_inc(&self->refcount);
 | 
			
		||||
    }
 | 
			
		||||
    return self;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gbinder_servicemanager_unref(
 | 
			
		||||
    GBinderServiceManager* self)
 | 
			
		||||
{
 | 
			
		||||
    if (self) {
 | 
			
		||||
        g_assert_cmpint(self->refcount, > ,0);
 | 
			
		||||
        if (g_atomic_int_dec_and_test(&self->refcount)) {
 | 
			
		||||
            test_gbinder_servicemanager_free(self);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderRemoteObject* /* autoreleased */
 | 
			
		||||
gbinder_servicemanager_get_service_sync(
 | 
			
		||||
    GBinderServiceManager* self,
 | 
			
		||||
    const char* name,
 | 
			
		||||
    int* status)
 | 
			
		||||
{
 | 
			
		||||
    if (self && name) {
 | 
			
		||||
        GBinderRemoteObject* obj = g_hash_table_lookup(self->services, name);
 | 
			
		||||
 | 
			
		||||
        if (obj) {
 | 
			
		||||
            gutil_idle_pool_add(self->pool, gbinder_remote_object_ref(obj),
 | 
			
		||||
                (GDestroyNotify) gbinder_remote_object_unref);
 | 
			
		||||
            return obj;
 | 
			
		||||
        } else {
 | 
			
		||||
            GDEBUG("Name %s not found", name);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GBinderLocalObject*
 | 
			
		||||
gbinder_servicemanager_new_local_object2(
 | 
			
		||||
    GBinderServiceManager* self,
 | 
			
		||||
    const char* const* ifaces,
 | 
			
		||||
    GBinderLocalTransactFunc fn,
 | 
			
		||||
    void* user_data)
 | 
			
		||||
{
 | 
			
		||||
    return self ? test_gbinder_local_object_new(ifaces, fn, user_data) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										166
									
								
								unit/common/test_main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								unit/common/test_main.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,166 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
typedef struct test_quit_later_data{
 | 
			
		||||
    GMainLoop* loop;
 | 
			
		||||
    guint n;
 | 
			
		||||
} TestQuitLaterData;
 | 
			
		||||
 | 
			
		||||
typedef struct test_context_data{
 | 
			
		||||
    GMainLoop* loop;
 | 
			
		||||
    GTestFunc func;
 | 
			
		||||
} TestContextData;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
gboolean
 | 
			
		||||
test_timeout_expired(
 | 
			
		||||
    gpointer data)
 | 
			
		||||
{
 | 
			
		||||
    g_assert(!"TIMEOUT");
 | 
			
		||||
    return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_quit_later_n_free(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestQuitLaterData* data = user_data;
 | 
			
		||||
 | 
			
		||||
    g_main_loop_unref(data->loop);
 | 
			
		||||
    g_free(data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
gboolean
 | 
			
		||||
test_quit_later_n_func(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestQuitLaterData* data = user_data;
 | 
			
		||||
 | 
			
		||||
    if (data->n > 0) {
 | 
			
		||||
        data->n--;
 | 
			
		||||
        return G_SOURCE_CONTINUE;
 | 
			
		||||
    } else {
 | 
			
		||||
        g_main_loop_quit(data->loop);
 | 
			
		||||
        return G_SOURCE_REMOVE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_quit_later_n(
 | 
			
		||||
    GMainLoop* loop,
 | 
			
		||||
    guint n)
 | 
			
		||||
{
 | 
			
		||||
    TestQuitLaterData* data = g_new0(TestQuitLaterData, 1);
 | 
			
		||||
 | 
			
		||||
    data->loop = g_main_loop_ref(loop);
 | 
			
		||||
    data->n = n;
 | 
			
		||||
    g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, test_quit_later_n_func, data,
 | 
			
		||||
        test_quit_later_n_free);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
gboolean
 | 
			
		||||
test_quit_later_cb(
 | 
			
		||||
    gpointer data)
 | 
			
		||||
{
 | 
			
		||||
    g_main_loop_quit((GMainLoop*)data);
 | 
			
		||||
    return G_SOURCE_REMOVE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_quit_later(
 | 
			
		||||
    GMainLoop* loop)
 | 
			
		||||
{
 | 
			
		||||
    g_idle_add(test_quit_later_cb, loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_run(
 | 
			
		||||
    const TestOpt* opt,
 | 
			
		||||
    GMainLoop* loop)
 | 
			
		||||
{
 | 
			
		||||
    if (opt->flags & TEST_FLAG_DEBUG) {
 | 
			
		||||
        g_main_loop_run(loop);
 | 
			
		||||
    } else {
 | 
			
		||||
        const guint timeout_id = g_timeout_add_seconds(TEST_TIMEOUT_SEC,
 | 
			
		||||
            test_timeout_expired, NULL);
 | 
			
		||||
        g_main_loop_run(loop);
 | 
			
		||||
        g_source_remove(timeout_id);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
test_init(
 | 
			
		||||
    TestOpt* opt,
 | 
			
		||||
    int argc,
 | 
			
		||||
    char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    const char* sep1;
 | 
			
		||||
    const char* sep2;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    memset(opt, 0, sizeof(*opt));
 | 
			
		||||
    for (i=1; i<argc; i++) {
 | 
			
		||||
        const char* arg = argv[i];
 | 
			
		||||
        if (!strcmp(arg, "-d") || !strcmp(arg, "--debug")) {
 | 
			
		||||
            opt->flags |= TEST_FLAG_DEBUG;
 | 
			
		||||
        } else if (!strcmp(arg, "-v")) {
 | 
			
		||||
            GTestConfig* config = (GTestConfig*)g_test_config_vars;
 | 
			
		||||
            config->test_verbose = TRUE;
 | 
			
		||||
        } else {
 | 
			
		||||
            GWARN("Unsupported command line option %s", arg);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Setup logging */
 | 
			
		||||
    sep1 = strrchr(argv[0], '/');
 | 
			
		||||
    sep2 = strrchr(argv[0], '\\');
 | 
			
		||||
    gutil_log_default.name = (sep1 && sep2) ? (MAX(sep1, sep2) + 1) :
 | 
			
		||||
        sep1 ? (sep1 + 1) : sep2 ? (sep2 + 1) : argv[0];
 | 
			
		||||
    gutil_log_default.level = g_test_verbose() ?
 | 
			
		||||
        GLOG_LEVEL_VERBOSE : GLOG_LEVEL_NONE;
 | 
			
		||||
    gutil_log_timestamp = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										54
									
								
								unit/coverage/run
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										54
									
								
								unit/coverage/run
									
									
									
									
									
										Executable 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
 | 
			
		||||
							
								
								
									
										5
									
								
								unit/unit_instance/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								unit/unit_instance/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# -*- Mode: makefile-gmake -*-
 | 
			
		||||
 | 
			
		||||
EXE = unit_instance
 | 
			
		||||
 | 
			
		||||
include ../common/Makefile
 | 
			
		||||
							
								
								
									
										820
									
								
								unit/unit_instance/unit_instance.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										820
									
								
								unit/unit_instance/unit_instance.c
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										5
									
								
								unit/unit_registry/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								unit/unit_registry/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# -*- Mode: makefile-gmake -*-
 | 
			
		||||
 | 
			
		||||
EXE = unit_registry
 | 
			
		||||
 | 
			
		||||
include ../common/Makefile
 | 
			
		||||
							
								
								
									
										170
									
								
								unit/unit_registry/unit_registry.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								unit/unit_registry/unit_registry.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,170 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
 | 
			
		||||
#include "radio_instance.h"
 | 
			
		||||
#include "radio_registry_p.h"
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * null
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_null(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    radio_registry_instance_added(NULL);
 | 
			
		||||
    radio_registry_instance_removed(NULL);
 | 
			
		||||
    radio_registry_remove_handler(NULL, 0);
 | 
			
		||||
    radio_registry_remove_handlers(NULL, NULL, 0);
 | 
			
		||||
    radio_registry_unref(NULL);
 | 
			
		||||
    g_assert(!radio_registry_ref(NULL));
 | 
			
		||||
    g_assert(!radio_registry_add_instance_added_handler(NULL,NULL,NULL,NULL));
 | 
			
		||||
    g_assert(!radio_registry_add_instance_removed_handler(NULL,NULL,NULL,NULL));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * basic
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static const char* test_basic_key = "foo";
 | 
			
		||||
static const char* test_basic_bad_key = "bar";
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_basic_add_cb(
 | 
			
		||||
    RadioRegistry* registry,
 | 
			
		||||
    RadioInstance* radio,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    (*((int*)user_data))++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_basic_remove_cb(
 | 
			
		||||
    RadioRegistry* registry,
 | 
			
		||||
    const char* str,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    g_assert_cmpstr(str, == ,test_basic_key);
 | 
			
		||||
    (*((int*)user_data))++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_basic(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    RadioRegistry* reg = radio_registry_new();
 | 
			
		||||
    int add_count = 0, remove_count = 0;
 | 
			
		||||
    gulong id[6];
 | 
			
		||||
    GObject* instance;
 | 
			
		||||
 | 
			
		||||
    g_assert(reg);
 | 
			
		||||
    g_assert(reg == radio_registry_new()); /* New ref to the same instance */
 | 
			
		||||
    radio_registry_unref(reg);
 | 
			
		||||
 | 
			
		||||
    g_assert(!radio_registry_add_instance_added_handler(reg,NULL,NULL,NULL));
 | 
			
		||||
    g_assert(!radio_registry_add_instance_removed_handler(reg,NULL,NULL,NULL));
 | 
			
		||||
 | 
			
		||||
    /* Add/remove handlers */
 | 
			
		||||
    id[0] = radio_registry_add_instance_added_handler(reg, "",
 | 
			
		||||
        test_basic_add_cb, &add_count);
 | 
			
		||||
    radio_registry_remove_handler(reg, id[0]);
 | 
			
		||||
    id[0] = radio_registry_add_instance_added_handler(reg, NULL,
 | 
			
		||||
        test_basic_add_cb, &add_count);
 | 
			
		||||
    id[1] = radio_registry_add_instance_added_handler(reg, test_basic_bad_key,
 | 
			
		||||
        test_basic_add_cb, &add_count);  /* won't get called */
 | 
			
		||||
 | 
			
		||||
    id[2] = radio_registry_add_instance_removed_handler(reg, NULL,
 | 
			
		||||
        test_basic_remove_cb, &remove_count);
 | 
			
		||||
    id[3] = radio_registry_add_instance_removed_handler(reg, "",
 | 
			
		||||
        test_basic_remove_cb, &remove_count);
 | 
			
		||||
    id[4] = radio_registry_add_instance_removed_handler(reg, test_basic_key,
 | 
			
		||||
        test_basic_remove_cb, &remove_count);
 | 
			
		||||
    id[5] = radio_registry_add_instance_removed_handler(reg, test_basic_bad_key,
 | 
			
		||||
        test_basic_remove_cb, &remove_count); /* won't get called */
 | 
			
		||||
 | 
			
		||||
    /* Well, this wouldn't be a real functional instance but we don't care */
 | 
			
		||||
    instance = g_object_new(RADIO_TYPE_INSTANCE, NULL);
 | 
			
		||||
    radio_registry_instance_added(RADIO_INSTANCE(instance));
 | 
			
		||||
    g_assert_cmpint(add_count, == ,1); /* 1 out of 2 is called */
 | 
			
		||||
    g_assert_cmpint(remove_count, == ,0);
 | 
			
		||||
 | 
			
		||||
    radio_registry_instance_removed(test_basic_key);
 | 
			
		||||
    g_assert_cmpint(add_count, == ,1);
 | 
			
		||||
    g_assert_cmpint(remove_count, == ,3); /* 3 our of 4 are called */
 | 
			
		||||
    g_object_unref(instance);
 | 
			
		||||
 | 
			
		||||
    /* remove_all zeros the ids */
 | 
			
		||||
    radio_registry_remove_all_handlers(reg, id);
 | 
			
		||||
    g_assert(!id[0]);
 | 
			
		||||
    g_assert(!id[4]);
 | 
			
		||||
 | 
			
		||||
    radio_registry_remove_handler(reg, 0); /* No effect */
 | 
			
		||||
    radio_registry_unref(reg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
#define TEST_PREFIX "/registry/"
 | 
			
		||||
#define TEST_(t) TEST_PREFIX t
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    g_test_init(&argc, &argv, NULL);
 | 
			
		||||
    g_test_add_func(TEST_("null"), test_null);
 | 
			
		||||
    g_test_add_func(TEST_("basic"), test_basic);
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										5
									
								
								unit/unit_util/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								unit/unit_util/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# -*- Mode: makefile-gmake -*-
 | 
			
		||||
 | 
			
		||||
EXE = unit_util
 | 
			
		||||
 | 
			
		||||
include ../common/Makefile
 | 
			
		||||
							
								
								
									
										162
									
								
								unit/unit_util/unit_util.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								unit/unit_util/unit_util.c
									
									
									
									
									
										Normal 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:
 | 
			
		||||
 */
 | 
			
		||||
		Reference in New Issue
	
	Block a user