[gbinder-radio] Initial commit. JB#44067

This library would allow to share radio binder client between ofono
RIL I/O plugin and hypothetical Alien telephony emulation plugin.

And it generally incapsulates IRadio binder interface.
This commit is contained in:
Slava Monich
2019-01-05 02:00:40 +03:00
commit 292c1bfc13
13 changed files with 2772 additions and 0 deletions

15
.gitignore vendored Normal file
View File

@@ -0,0 +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/tmp
documentation.list
installroot
build
RPMS

229
Makefile Normal file
View File

@@ -0,0 +1,229 @@
# -*- Mode: makefile-gmake -*-
.PHONY: clean all debug release coverage
.PHONY: debug_lib release_lib coverage_lib
.PHONY: pkgconfig install install-dev
#
# Required packages
#
PKGS = libgbinder libglibutil glib-2.0 gobject-2.0
#
# Default target
#
all: debug release pkgconfig
#
# Library version
#
VERSION_MAJOR = 1
VERSION_MINOR = 0
VERSION_RELEASE = 0
# Version for pkg-config
PCVERSION = $(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_RELEASE)
#
# Library name
#
NAME = gbinder-radio
LIB_NAME = lib$(NAME)
LIB_DEV_SYMLINK = $(LIB_NAME).so
LIB_SYMLINK1 = $(LIB_DEV_SYMLINK).$(VERSION_MAJOR)
LIB_SYMLINK2 = $(LIB_SYMLINK1).$(VERSION_MINOR)
LIB_SONAME = $(LIB_SYMLINK1)
LIB_SO = $(LIB_SONAME).$(VERSION_MINOR).$(VERSION_RELEASE)
LIB = $(LIB_NAME).a
#
# Sources
#
SRC = \
radio_instance.c \
radio_registry.c \
radio_util.c
#
# Directories
#
SRC_DIR = src
INCLUDE_DIR = include
BUILD_DIR = build
DEBUG_BUILD_DIR = $(BUILD_DIR)/debug
RELEASE_BUILD_DIR = $(BUILD_DIR)/release
COVERAGE_BUILD_DIR = $(BUILD_DIR)/coverage
#
# Tools and flags
#
CC = $(CROSS_COMPILE)gcc
LD = $(CC)
WARNINGS = -Wall -Wstrict-aliasing -Wunused-result
INCLUDES = -I$(INCLUDE_DIR)
BASE_FLAGS = -fPIC
FULL_CFLAGS = $(BASE_FLAGS) $(CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) \
-MMD -MP $(shell pkg-config --cflags $(PKGS))
FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS) -shared -Wl,-soname,$(LIB_SONAME) \
$(shell pkg-config --libs $(PKGS)) -lpthread
DEBUG_FLAGS = -g
RELEASE_FLAGS =
COVERAGE_FLAGS = -g
ifndef KEEP_SYMBOLS
KEEP_SYMBOLS = 0
endif
ifneq ($(KEEP_SYMBOLS),0)
RELEASE_FLAGS += -g
endif
DEBUG_LDFLAGS = $(FULL_LDFLAGS) $(DEBUG_FLAGS)
RELEASE_LDFLAGS = $(FULL_LDFLAGS) $(RELEASE_FLAGS)
DEBUG_CFLAGS = $(FULL_CFLAGS) $(DEBUG_FLAGS) -DDEBUG
RELEASE_CFLAGS = $(FULL_CFLAGS) $(RELEASE_FLAGS) -O2
COVERAGE_CFLAGS = $(FULL_CFLAGS) $(COVERAGE_FLAGS) --coverage
#
# Files
#
PKGCONFIG = $(BUILD_DIR)/$(LIB_NAME).pc
DEBUG_OBJS = $(SRC:%.c=$(DEBUG_BUILD_DIR)/%.o)
RELEASE_OBJS = $(SRC:%.c=$(RELEASE_BUILD_DIR)/%.o)
COVERAGE_OBJS = $(SRC:%.c=$(COVERAGE_BUILD_DIR)/%.o)
#
# Dependencies
#
DEPS = $(DEBUG_OBJS:%.o=%.d) $(RELEASE_OBJS:%.o=%.d)
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(DEPS)),)
-include $(DEPS)
endif
endif
$(PKGCONFIG): | $(BUILD_DIR)
$(DEBUG_OBJS) $(DEBUG_SO): | $(DEBUG_BUILD_DIR)
$(RELEASE_OBJS) $(RELEASE_SO): | $(RELEASE_BUILD_DIR)
$(COVERAGE_OBJS) $(COVERAGE_LIB): | $(COVERAGE_BUILD_DIR)
#
# Rules
#
DEBUG_SO = $(DEBUG_BUILD_DIR)/$(LIB_SO)
RELEASE_SO = $(RELEASE_BUILD_DIR)/$(LIB_SO)
DEBUG_LINK = $(DEBUG_BUILD_DIR)/$(LIB_SYMLINK1)
RELEASE_LINK = $(RELEASE_BUILD_DIR)/$(LIB_SYMLINK1)
DEBUG_LIB = $(DEBUG_BUILD_DIR)/$(LIB)
RELEASE_LIB = $(RELEASE_BUILD_DIR)/$(LIB)
COVERAGE_LIB = $(COVERAGE_BUILD_DIR)/$(LIB)
debug: $(DEBUG_SO)
release: $(RELEASE_SO)
debug_lib: $(DEBUG_LIB)
release_lib: $(RELEASE_LIB)
coverage_lib: $(COVERAGE_LIB)
pkgconfig: $(PKGCONFIG)
clean:
rm -f *~ $(SRC_DIR)/*~ $(INCLUDE_DIR)/*~
rm -fr $(BUILD_DIR) RPMS installroot
rm -fr debian/tmp debian/libgbinder debian/libgbinder-dev
rm -f documentation.list debian/files debian/*.substvars
rm -f debian/*.debhelper.log debian/*.debhelper debian/*~
$(BUILD_DIR):
mkdir -p $@
$(DEBUG_BUILD_DIR):
mkdir -p $@
$(RELEASE_BUILD_DIR):
mkdir -p $@
$(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 $@
$(DEBUG_SO): $(DEBUG_OBJS)
$(LD) $(DEBUG_OBJS) $(DEBUG_LDFLAGS) -o $@
ln -sf $(LIB_SO) $(DEBUG_LINK)
$(RELEASE_SO): $(RELEASE_OBJS)
$(LD) $(RELEASE_OBJS) $(RELEASE_LDFLAGS) -o $@
ln -sf $(LIB_SO) $(RELEASE_LINK)
ifeq ($(KEEP_SYMBOLS),0)
strip $@
endif
$(DEBUG_LIB): $(DEBUG_OBJS)
$(AR) rc $@ $?
ranlib $@
$(RELEASE_LIB): $(RELEASE_OBJS)
$(AR) rc $@ $?
ranlib $@
$(COVERAGE_LIB): $(COVERAGE_OBJS)
$(AR) rc $@ $?
ranlib $@
$(PKGCONFIG): $(LIB_NAME).pc.in Makefile
sed -e 's/\[version\]/'$(PCVERSION)/g $< > $@
#
# Install
#
INSTALL_PERM = 644
INSTALL = install
INSTALL_DIRS = $(INSTALL) -d
INSTALL_FILES = $(INSTALL) -m $(INSTALL_PERM)
INSTALL_LIB_DIR = $(DESTDIR)/usr/lib
INSTALL_INCLUDE_DIR = $(DESTDIR)/usr/include/$(NAME)
INSTALL_PKGCONFIG_DIR = $(DESTDIR)/usr/lib/pkgconfig
install: $(INSTALL_LIB_DIR)
$(INSTALL_FILES) $(RELEASE_SO) $(INSTALL_LIB_DIR)
ln -sf $(LIB_SO) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK2)
ln -sf $(LIB_SYMLINK2) $(INSTALL_LIB_DIR)/$(LIB_SYMLINK1)
install-dev: install $(INSTALL_INCLUDE_DIR) $(INSTALL_PKGCONFIG_DIR)
$(INSTALL_FILES) $(INCLUDE_DIR)/*.h $(INSTALL_INCLUDE_DIR)
$(INSTALL_FILES) $(PKGCONFIG) $(INSTALL_PKGCONFIG_DIR)
ln -sf $(LIB_SYMLINK1) $(INSTALL_LIB_DIR)/$(LIB_DEV_SYMLINK)
$(INSTALL_LIB_DIR):
$(INSTALL_DIRS) $@
$(INSTALL_INCLUDE_DIR):
$(INSTALL_DIRS) $@
$(INSTALL_PKGCONFIG_DIR):
$(INSTALL_DIRS) $@

233
include/radio_instance.h Normal file
View File

@@ -0,0 +1,233 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_INSTANCE_H
#define RADIO_INSTANCE_H
#include <radio_types.h>
#include <glib-object.h>
G_BEGIN_DECLS
typedef struct radio_instance_priv RadioInstancePriv;
struct radio_instance {
GObject parent;
RadioInstancePriv* priv;
gboolean dead;
const char* dev;
const char* slot;
const char* key;
};
typedef struct radio_response_info {
RADIO_RESP_TYPE type;
guint32 serial;
guint32 error;
} RadioResponseInfo;
typedef
void
(*RadioInstanceFunc)(
RadioInstance* radio,
gpointer user_data);
typedef
gboolean
(*RadioResponseHandlerFunc)(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data);
typedef
void
(*RadioResponseObserverFunc)(
RadioInstance* radio,
RADIO_RESP code,
const RadioResponseInfo* info,
const GBinderReader* reader,
gpointer user_data);
typedef
gboolean
(*RadioIndicationHandlerFunc)(
RadioInstance* radio,
RADIO_IND code,
RADIO_IND_TYPE type,
const GBinderReader* reader,
gpointer user_data);
typedef
void
(*RadioIndicationObserverFunc)(
RadioInstance* radio,
RADIO_IND code,
RADIO_IND_TYPE type,
const GBinderReader* reader,
gpointer user_data);
typedef
void
(*RadioAckFunc)(
RadioInstance* radio,
guint32 serial,
gpointer user_data);
GType radio_instance_get_type();
#define RADIO_TYPE_INSTANCE (radio_instance_get_type())
#define RADIO_INSTANCE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
RADIO_TYPE_INSTANCE, RadioInstance))
RadioInstance*
radio_instance_new(
const char* dev,
const char* name);
RadioInstance*
radio_instance_get(
const char* dev,
const char* name);
RadioInstance* const*
radio_instance_get_all(
void);
RadioInstance*
radio_instance_ref(
RadioInstance* radio);
void
radio_instance_unref(
RadioInstance* radio);
const char*
radio_instance_req_name(
RadioInstance* radio,
RADIO_REQ req);
const char*
radio_instance_resp_name(
RadioInstance* radio,
RADIO_RESP resp);
const char*
radio_instance_ind_name(
RadioInstance* radio,
RADIO_IND ind);
gboolean
radio_instance_ack(
RadioInstance* radio);
GBinderLocalRequest*
radio_instance_new_request(
RadioInstance* radio,
RADIO_REQ code);
gboolean
radio_instance_send_request_sync(
RadioInstance* radio,
RADIO_REQ code,
GBinderLocalRequest* args);
gulong
radio_instance_add_indication_handler(
RadioInstance* radio,
RADIO_IND code,
RadioIndicationHandlerFunc func,
gpointer user_data);
gulong
radio_instance_add_indication_observer(
RadioInstance* radio,
RADIO_IND code,
RadioIndicationObserverFunc func,
gpointer user_data);
gulong
radio_instance_add_response_handler(
RadioInstance* radio,
RADIO_RESP code,
RadioResponseHandlerFunc func,
gpointer user_data);
gulong
radio_instance_add_response_observer(
RadioInstance* radio,
RADIO_RESP code,
RadioResponseObserverFunc func,
gpointer user_data);
gulong
radio_instance_add_ack_handler(
RadioInstance* radio,
RadioAckFunc func,
gpointer user_data);
gulong
radio_instance_add_death_handler(
RadioInstance* radio,
RadioInstanceFunc func,
gpointer user_data);
void
radio_instance_remove_handler(
RadioInstance* radio,
gulong id);
void
radio_instance_remove_handlers(
RadioInstance* radio,
gulong* ids,
int count);
#define radio_instance_remove_all_handlers(radio,ids) \
radio_instance_remove_handlers(radio, ids, G_N_ELEMENTS(ids))
G_END_DECLS
#endif /* RADIO_INSTANCE_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

109
include/radio_registry.h Normal file
View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_REGISTRY_H
#define RADIO_REGISTRY_H
#include <radio_types.h>
G_BEGIN_DECLS
typedef
void
(*RadioRegistryInstanceFunc)(
RadioRegistry* registry,
RadioInstance* radio,
gpointer user_data);
typedef
void
(*RadioRegistryStrFunc)(
RadioRegistry* registry,
const char* str,
gpointer user_data);
RadioRegistry*
radio_registry_new(
void);
RadioRegistry*
radio_registry_ref(
RadioRegistry* reg);
void
radio_registry_unref(
RadioRegistry* reg);
gulong
radio_registry_add_instance_added_handler(
RadioRegistry* reg,
const char* key, /* NULL for any */
RadioRegistryInstanceFunc func,
gpointer user_data);
gulong
radio_registry_add_instance_removed_handler(
RadioRegistry* reg,
const char* key, /* NULL for any */
RadioRegistryStrFunc func,
gpointer user_data);
void
radio_registry_remove_handler(
RadioRegistry* reg,
gulong id);
void
radio_registry_remove_handlers(
RadioRegistry* reg,
gulong* ids,
int count);
#define radio_registry_remove_all_handlers(reg,ids) \
radio_registry_remove_handlers(reg, ids, G_N_ELEMENTS(ids))
G_END_DECLS
#endif /* RADIO_REGISTRY_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

839
include/radio_types.h Normal file
View File

@@ -0,0 +1,839 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_TYPES_H
#define RADIO_TYPES_H
#include <gbinder_types.h>
G_BEGIN_DECLS
typedef struct radio_instance RadioInstance;
typedef struct radio_registry RadioRegistry;
#define RADIO_IFACE_PREFIX "android.hardware.radio@"
#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")
/* Types defined in types.hal */
#define RADIO_ALIGNED(x) __attribute__ ((aligned(x)))
typedef enum radio_resp_type {
RADIO_RESP_SOLICITED,
RADIO_RESP_SOLICITED_ACK,
RADIO_RESP_SOLICITED_ACK_EXP
} RADIO_RESP_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_RESP_TYPE) == 4);
typedef enum radio_ind_type {
RADIO_IND_UNSOLICITED,
RADIO_IND_ACK_EXP
} RADIO_IND_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_IND_TYPE) == 4);
typedef enum radio_state {
RADIO_STATE_OFF = 0,
RADIO_STATE_UNAVAILABLE = 1,
RADIO_STATE_ON = 10
} RADIO_STATE;
G_STATIC_ASSERT(sizeof(RADIO_STATE) == 4);
typedef enum radio_reg_state {
RADIO_REG_STATE_NOT_REG_NOT_SEARCHING = 0,
RADIO_REG_STATE_REG_HOME = 1,
RADIO_REG_STATE_NOT_REG_MT_SEARCHING = 2,
RADIO_REG_STATE_REG_DENIED = 3,
RADIO_REG_STATE_UNKNOWN = 4,
RADIO_REG_STATE_REG_ROAMING = 5,
RADIO_REG_STATE_NOT_REG_MT_NOT_SEARCHING_EM = 10,
RADIO_REG_STATE_NOT_REG_MT_SEARCHING_EM = 12,
RADIO_REG_STATE_REG_DENIED_EM = 13,
RADIO_REG_STATE_UNKNOWN_EM = 14
} RADIO_REG_STATE;
G_STATIC_ASSERT(sizeof(RADIO_REG_STATE) == 4);
typedef enum radio_ind_filter {
RADIO_IND_FILTER_NONE = 0,
RADIO_IND_FILTER_SIGNAL_STRENGTH = 0x01,
RADIO_IND_FILTER_FULL_NETWORK_STATE = 0x02,
RADIO_IND_FILTER_DATA_CALL_DORMANCY = 0x04,
RADIO_IND_FILTER_ALL =
RADIO_IND_FILTER_SIGNAL_STRENGTH |
RADIO_IND_FILTER_FULL_NETWORK_STATE |
RADIO_IND_FILTER_DATA_CALL_DORMANCY
} RADIO_IND_FILTER;
G_STATIC_ASSERT(sizeof(RADIO_IND_FILTER) == 4);
typedef enum radio_call_state {
RADIO_CALL_ACTIVE,
RADIO_CALL_HOLDING,
RADIO_CALL_DIALING,
RADIO_CALL_ALERTING,
RADIO_CALL_INCOMING,
RADIO_CALL_WAITING
} RADIO_CALL_STATE;
G_STATIC_ASSERT(sizeof(RADIO_CALL_STATE) == 4);
typedef enum radio_operator_status {
RADIO_OP_STATUS_UNKNOWN = 0,
RADIO_OP_AVAILABLE,
RADIO_OP_CURRENT,
RADIO_OP_FORBIDDEN
} RADIO_OP_STATUS;
G_STATIC_ASSERT(sizeof(RADIO_OP_STATUS) == 4);
typedef enum radio_cell_info_type {
RADIO_CELL_INFO_GSM = 1,
RADIO_CELL_INFO_CDMA,
RADIO_CELL_INFO_LTE,
RADIO_CELL_INFO_WCDMA,
RADIO_CELL_INFO_TD_SCDMA
} RADIO_CELL_INFO_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_CELL_INFO_TYPE) == 4);
typedef enum radio_tech {
RADIO_TECH_UNKNOWN = 0,
RADIO_TECH_GPRS,
RADIO_TECH_EDGE,
RADIO_TECH_UMTS,
RADIO_TECH_IS95A,
RADIO_TECH_IS95B,
RADIO_TECH_ONE_X_RTT,
RADIO_TECH_EVDO_0,
RADIO_TECH_EVDO_A,
RADIO_TECH_HSDPA,
RADIO_TECH_HSUPA,
RADIO_TECH_HSPA,
RADIO_TECH_EVDO_B,
RADIO_TECH_EHRPD,
RADIO_TECH_LTE,
RADIO_TECH_HSPAP,
RADIO_TECH_GSM,
RADIO_TECH_TD_SCDMA,
RADIO_TECH_IWLAN,
RADIO_TECH_LTE_CA
} RADIO_TECH;
G_STATIC_ASSERT(sizeof(RADIO_TECH) == 4);
typedef enum radio_card_state {
RADIO_CARD_STATE_ABSENT,
RADIO_CARD_STATE_PRESENT,
RADIO_CARD_STATE_ERROR,
RADIO_CARD_STATE_RESTRICTED
} RADIO_CARD_STATE;
G_STATIC_ASSERT(sizeof(RADIO_CARD_STATE) == 4);
typedef enum radio_pin_state {
RADIO_PIN_STATE_UNKNOWN,
RADIO_PIN_STATE_ENABLED_NOT_VERIFIED,
RADIO_PIN_STATE_ENABLED_VERIFIED,
RADIO_PIN_STATE_DISABLED,
RADIO_PIN_STATE_ENABLED_BLOCKED,
RADIO_PIN_STATE_ENABLED_PERM_BLOCKED
} RADIO_PIN_STATE;
G_STATIC_ASSERT(sizeof(RADIO_PIN_STATE) == 4);
typedef enum radio_app_type {
RADIO_APP_TYPE_UNKNOWN,
RADIO_APP_TYPE_SIM,
RADIO_APP_TYPE_USIM,
RADIO_APP_TYPE_RUIM,
RADIO_APP_TYPE_CSIM,
RADIO_APP_TYPE_ISIM
} RADIO_APP_TYPE;
G_STATIC_ASSERT(sizeof(RADIO_APP_TYPE) == 4);
typedef enum radio_app_state {
RADIO_APP_STATE_UNKNOWN,
RADIO_APP_STATE_DETECTED,
RADIO_APP_STATE_PIN,
RADIO_APP_STATE_PUK,
RADIO_APP_STATE_SUBSCRIPTION_PERSO,
RADIO_APP_STATE_READY
} RADIO_APP_STATE;
G_STATIC_ASSERT(sizeof(RADIO_APP_STATE) == 4);
typedef enum radio_perso_substate {
RADIO_PERSO_SUBSTATE_UNKNOWN,
RADIO_PERSO_SUBSTATE_IN_PROGRESS,
RADIO_PERSO_SUBSTATE_READY,
RADIO_PERSO_SUBSTATE_SIM_NETWORK,
RADIO_PERSO_SUBSTATE_SIM_NETWORK_SUBSET,
RADIO_PERSO_SUBSTATE_SIM_CORPORATE,
RADIO_PERSO_SUBSTATE_SIM_SERVICE_PROVIDER,
RADIO_PERSO_SUBSTATE_SIM_SIM,
RADIO_PERSO_SUBSTATE_SIM_NETWORK_PUK,
RADIO_PERSO_SUBSTATE_SIM_NETWORK_SUBSET_PUK,
RADIO_PERSO_SUBSTATE_SIM_CORPORATE_PUK,
RADIO_PERSO_SUBSTATE_SIM_SERVICE_PROVIDER_PUK,
RADIO_PERSO_SUBSTATE_SIM_SIM_PUK,
RADIO_PERSO_SUBSTATE_RUIM_NETWORK1,
RADIO_PERSO_SUBSTATE_RUIM_NETWORK2,
RADIO_PERSO_SUBSTATE_RUIM_HRPD,
RADIO_PERSO_SUBSTATE_RUIM_CORPORATE,
RADIO_PERSO_SUBSTATE_RUIM_SERVICE_PROVIDER,
RADIO_PERSO_SUBSTATE_RUIM_RUIM,
RADIO_PERSO_SUBSTATE_RUIM_NETWORK1_PUK,
RADIO_PERSO_SUBSTATE_RUIM_NETWORK2_PUK,
RADIO_PERSO_SUBSTATE_RUIM_HRPD_PUK,
RADIO_PERSO_SUBSTATE_RUIM_CORPORATE_PUK,
RADIO_PERSO_SUBSTATE_RUIM_SERVICE_PROVIDER_PUK,
RADIO_PERSO_SUBSTATE_RUIM_RUIM_PUK,
} RADIO_PERSO_SUBSTATE;
G_STATIC_ASSERT(sizeof(RADIO_PERSO_SUBSTATE) == 4);
typedef enum radio_capability_phase {
RADIO_CAPABILITY_PHASE_CONFIGURED,
RADIO_CAPABILITY_PHASE_START,
RADIO_CAPABILITY_PHASE_APPLY,
RADIO_CAPABILITY_PHASE_UNSOL_RSP,
RADIO_CAPABILITY_PHASE_FINISH
} RADIO_CAPABILITY_PHASE;
G_STATIC_ASSERT(sizeof(RADIO_CAPABILITY_PHASE) == 4);
typedef enum radio_capability_status {
RADIO_CAPABILITY_STATUS_NONE,
RADIO_CAPABILITY_STATUS_SUCCESS,
RADIO_CAPABILITY_STATUS_FAIL
} RADIO_CAPABILITY_STATUS;
G_STATIC_ASSERT(sizeof(RADIO_CAPABILITY_STATUS) == 4);
typedef struct radio_card_status {
RADIO_CARD_STATE cardState RADIO_ALIGNED(4);
RADIO_PIN_STATE universalPinState RADIO_ALIGNED(4);
gint32 gsmUmtsSubscriptionAppIndex RADIO_ALIGNED(4);
gint32 cdmaSubscriptionAppIndex RADIO_ALIGNED(4);
gint32 imsSubscriptionAppIndex RADIO_ALIGNED(4);
GBinderHidlVec apps RADIO_ALIGNED(8); /* vec<RadioAppStatus> */
} RADIO_ALIGNED(8) RadioCardStatus;
G_STATIC_ASSERT(sizeof(RadioCardStatus) == 40);
typedef struct radio_app_status {
RADIO_APP_TYPE appType RADIO_ALIGNED(4);
RADIO_APP_STATE appState RADIO_ALIGNED(4);
RADIO_PERSO_SUBSTATE persoSubstate RADIO_ALIGNED(4);
GBinderHidlString aid RADIO_ALIGNED(8);
GBinderHidlString label RADIO_ALIGNED(8);
gint32 pinReplaced RADIO_ALIGNED(4);
RADIO_PIN_STATE pin1 RADIO_ALIGNED(4);
RADIO_PIN_STATE pin2 RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioAppStatus;
G_STATIC_ASSERT(sizeof(RadioAppStatus) == 64);
typedef struct radio_uus_info {
gint32 uusType RADIO_ALIGNED(4);
gint32 uusDcs RADIO_ALIGNED(4);
GBinderHidlString uusData RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioUusInfo;
G_STATIC_ASSERT(sizeof(RadioUusInfo) == 24);
typedef struct radio_call {
RADIO_CALL_STATE state RADIO_ALIGNED(4);
gint32 index RADIO_ALIGNED(4);
gint32 toa RADIO_ALIGNED(4);
guint8 isMpty RADIO_ALIGNED(1);
guint8 isMT RADIO_ALIGNED(1);
guint8 als RADIO_ALIGNED(1);
guint8 isVoice RADIO_ALIGNED(1);
guint8 isVoicePrivacy RADIO_ALIGNED(1);
GBinderHidlString number RADIO_ALIGNED(8);
gint32 numberPresentation RADIO_ALIGNED(4);
GBinderHidlString name RADIO_ALIGNED(8);
gint32 namePresentation RADIO_ALIGNED(4);
GBinderHidlVec uusInfo RADIO_ALIGNED(8); /* vec<RadioUusInfo> */
} RADIO_ALIGNED(8) RadioCall;
G_STATIC_ASSERT(sizeof(RadioCall) == 88);
typedef struct radio_dial {
GBinderHidlString address RADIO_ALIGNED(8);
gint32 clir RADIO_ALIGNED(4);
GBinderHidlVec uusInfo RADIO_ALIGNED(8); /* vec<RadioUusInfo> */
} RADIO_ALIGNED(8) RadioDial;
G_STATIC_ASSERT(sizeof(RadioDial) == 40);
typedef struct radio_last_call_fail_cause_info {
gint32 causeCode RADIO_ALIGNED(4);
GBinderHidlString vendorCause RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioLastCallFailCauseInfo;
G_STATIC_ASSERT(sizeof(RadioLastCallFailCauseInfo) == 24);
typedef struct radio_operator_info {
GBinderHidlString alphaLong RADIO_ALIGNED(8);
GBinderHidlString alphaShort RADIO_ALIGNED(8);
GBinderHidlString operatorNumeric RADIO_ALIGNED(8);
RADIO_OP_STATUS status RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioOperatorInfo;
G_STATIC_ASSERT(sizeof(RadioOperatorInfo) == 56);
typedef struct radio_data_profile {
gint32 profileId RADIO_ALIGNED(4);
GBinderHidlString apn RADIO_ALIGNED(8);
GBinderHidlString protocol RADIO_ALIGNED(8);
GBinderHidlString roamingProtocol RADIO_ALIGNED(8);
gint32 authType RADIO_ALIGNED(4);
GBinderHidlString user RADIO_ALIGNED(8);
GBinderHidlString password RADIO_ALIGNED(8);
gint32 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);
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_call {
gint32 status RADIO_ALIGNED(4);
gint32 suggestedRetryTime RADIO_ALIGNED(4);
gint32 cid RADIO_ALIGNED(4);
gint32 active RADIO_ALIGNED(4);
GBinderHidlString type RADIO_ALIGNED(8);
GBinderHidlString ifname RADIO_ALIGNED(8);
GBinderHidlString addresses RADIO_ALIGNED(8);
GBinderHidlString dnses RADIO_ALIGNED(8);
GBinderHidlString gateways RADIO_ALIGNED(8);
GBinderHidlString pcscf RADIO_ALIGNED(8);
gint32 mtu RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioDataCall;
G_STATIC_ASSERT(sizeof(RadioDataCall) == 120);
#define DATA_CALL_VERSION (11)
#define DATA_CALL_VERSION (11)
typedef struct radio_sms_write_args {
gint32 status RADIO_ALIGNED(4);
GBinderHidlString pdu RADIO_ALIGNED(8);
GBinderHidlString smsc RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioSmsWriteArgs;
G_STATIC_ASSERT(sizeof(RadioSmsWriteArgs) == 40);
typedef struct GsmSmsMessage {
GBinderHidlString smscPdu RADIO_ALIGNED(8);
GBinderHidlString pdu RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioGsmSmsMessage;
G_STATIC_ASSERT(sizeof(RadioGsmSmsMessage) == 32);
typedef struct SendSmsResult {
gint32 messageRef RADIO_ALIGNED(4);
GBinderHidlString ackPDU RADIO_ALIGNED(8);
gint32 errorCode RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioSendSmsResult;
G_STATIC_ASSERT(sizeof(RadioSendSmsResult) == 32);
typedef struct radio_icc_io {
gint32 command RADIO_ALIGNED(4);
gint32 fileId RADIO_ALIGNED(4);
GBinderHidlString path RADIO_ALIGNED(8);
gint32 p1 RADIO_ALIGNED(4);
gint32 p2 RADIO_ALIGNED(4);
gint32 p3 RADIO_ALIGNED(4);
GBinderHidlString data RADIO_ALIGNED(8);
GBinderHidlString pin2 RADIO_ALIGNED(8);
GBinderHidlString aid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioIccIo;
G_STATIC_ASSERT(sizeof(RadioIccIo) == 88);
typedef struct radio_icc_io_result {
gint32 sw1 RADIO_ALIGNED(4);
gint32 sw2 RADIO_ALIGNED(4);
GBinderHidlString response RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioIccIoResult;
G_STATIC_ASSERT(sizeof(RadioIccIoResult) == 24);
typedef struct radio_call_forward_info {
gint32 status RADIO_ALIGNED(4);
gint32 reason RADIO_ALIGNED(4);
gint32 serviceClass RADIO_ALIGNED(4);
gint32 toa RADIO_ALIGNED(4);
GBinderHidlString number RADIO_ALIGNED(8);
gint32 timeSeconds RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCallForwardInfo;
G_STATIC_ASSERT(sizeof(RadioCallForwardInfo) == 40);
#define RADIO_CELL_INVALID_VALUE (INT_MAX)
typedef struct radio_cell_identity {
RADIO_CELL_INFO_TYPE cellInfoType RADIO_ALIGNED(4);
GBinderHidlVec gsm RADIO_ALIGNED(8); /* vec<RadioCellIdentityGsm> */
GBinderHidlVec wcdma RADIO_ALIGNED(8); /* vec<RadioCellIdentityWcdma> */
GBinderHidlVec cdma RADIO_ALIGNED(8); /* vec<RadioCellIdentityCdma> */
GBinderHidlVec lte RADIO_ALIGNED(8); /* vec<RadioCellIdentityLte> */
GBinderHidlVec tdscdma RADIO_ALIGNED(8); /* vec<RadioCellIdentityTdscdma> */
} RADIO_ALIGNED(8) RadioCellIdentity;
G_STATIC_ASSERT(sizeof(RadioCellIdentity) == 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 lte RADIO_ALIGNED(8); /* vec<RadioCellInfoLte> */
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_identity_gsm {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
gint32 lac RADIO_ALIGNED(4);
gint32 cid RADIO_ALIGNED(4);
gint32 arfcn RADIO_ALIGNED(4);
guint8 bsic RADIO_ALIGNED(1);
} RADIO_ALIGNED(8) RadioCellIdentityGsm;
G_STATIC_ASSERT(sizeof(RadioCellIdentityGsm) == 48);
typedef struct radio_cell_identity_wcdma {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
gint32 lac RADIO_ALIGNED(4);
gint32 cid RADIO_ALIGNED(4);
gint32 psc RADIO_ALIGNED(4);
gint32 uarfcn RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellIdentityWcdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityWcdma) == 48);
typedef struct radio_cell_identity_cdma {
gint32 networkId RADIO_ALIGNED(4);
gint32 systemId RADIO_ALIGNED(4);
gint32 baseStationId RADIO_ALIGNED(4);
gint32 longitude RADIO_ALIGNED(4);
gint32 latitude RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioCellIdentityCdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityCdma) == 20);
typedef struct radio_cell_identity_lte {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
gint32 ci RADIO_ALIGNED(4);
gint32 pci RADIO_ALIGNED(4);
gint32 tac RADIO_ALIGNED(4);
gint32 earfcn RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellIdentityLte;
G_STATIC_ASSERT(sizeof(RadioCellIdentityLte) == 48);
typedef struct radio_cell_identity_tdscdma {
GBinderHidlString mcc RADIO_ALIGNED(8);
GBinderHidlString mnc RADIO_ALIGNED(8);
gint32 lac RADIO_ALIGNED(4);
gint32 cid RADIO_ALIGNED(4);
gint32 cpid RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellIdentityTdscdma;
G_STATIC_ASSERT(sizeof(RadioCellIdentityTdscdma) == 48);
typedef struct radio_voice_reg_state_result {
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 cellIdentity RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioVoiceRegStateResult;
G_STATIC_ASSERT(sizeof(RadioVoiceRegStateResult) == 120);
typedef struct radio_data_reg_state_result {
RADIO_REG_STATE regState RADIO_ALIGNED(4);
RADIO_TECH rat RADIO_ALIGNED(4);
gint32 reasonDataDenied RADIO_ALIGNED(4);
gint32 maxDataCalls RADIO_ALIGNED(4);
RadioCellIdentity cellIdentity RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioDataRegStateResult;
G_STATIC_ASSERT(sizeof(RadioDataRegStateResult) == 104);
typedef struct radio_signal_strength_gsm {
guint32 signalStrength RADIO_ALIGNED(4);
guint32 bitErrorRate RADIO_ALIGNED(4);
gint32 timingAdvance RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthGsm;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthGsm) == 12);
typedef struct radio_signal_strength_wcdma {
gint32 signalStrength RADIO_ALIGNED(4);
gint32 bitErrorRate RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthWcdma;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthWcdma) == 8);
typedef struct radio_signal_strength_cdma {
guint32 dbm RADIO_ALIGNED(4);
guint32 ecio RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthCdma;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthCdma) == 8);
typedef struct radio_signal_strength_evdo {
guint32 dbm RADIO_ALIGNED(4);
guint32 ecio RADIO_ALIGNED(4);
guint32 signalNoiseRatio RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthEvdo;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthEvdo) == 12);
typedef struct radio_signal_strength_lte {
guint32 signalStrength RADIO_ALIGNED(4);
guint32 rsrp RADIO_ALIGNED(4);
guint32 rsrq RADIO_ALIGNED(4);
gint32 rssnr RADIO_ALIGNED(4);
guint32 cqi RADIO_ALIGNED(4);
guint32 timingAdvance RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthLte;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthLte) == 24);
typedef struct radio_signal_strength_tdscdma {
guint32 rscp RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSignalStrengthTdScdma;
G_STATIC_ASSERT(sizeof(RadioSignalStrengthTdScdma) == 4);
typedef struct radio_signal_strength {
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);
} RADIO_ALIGNED(4) RadioSignalStrength;
G_STATIC_ASSERT(sizeof(RadioSignalStrength) == 60);
typedef struct radio_cell_info_gsm {
RadioCellIdentityGsm cellIdentityGsm RADIO_ALIGNED(8);
RadioSignalStrengthGsm signalStrengthGsm RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoGsm;
G_STATIC_ASSERT(sizeof(RadioCellInfoGsm) == 64);
typedef struct radio_cell_info_wcdma {
RadioCellIdentityWcdma cellIdentityWcdma RADIO_ALIGNED(8);
RadioSignalStrengthWcdma signalStrengthWcdma RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoWcdma;
G_STATIC_ASSERT(sizeof(RadioCellInfoWcdma) == 56);
typedef struct radio_cell_info_cdma {
RadioCellIdentityCdma cellIdentityCdma RADIO_ALIGNED(4);
RadioSignalStrengthCdma signalStrengthCdma RADIO_ALIGNED(4);
RadioSignalStrengthEvdo signalStrengthEvdo RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioCellInfoCdma;
G_STATIC_ASSERT(sizeof(RadioCellInfoCdma) == 40);
typedef struct radio_cell_info_lte {
RadioCellIdentityLte cellIdentityLte RADIO_ALIGNED(8);
RadioSignalStrengthLte signalStrengthLte RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoLte;
G_STATIC_ASSERT(sizeof(RadioCellInfoLte) == 72);
typedef struct radio_cell_info_tdscdma {
RadioCellIdentityTdscdma cellIdentityTdscdma RADIO_ALIGNED(8);
RadioSignalStrengthTdScdma signalStrengthTdscdma RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCellInfoTdscdma;
G_STATIC_ASSERT(sizeof(RadioCellInfoTdscdma) == 56);
typedef struct radio_gsm_broadcast_sms_config {
gint32 fromServiceId RADIO_ALIGNED(4);
gint32 toServiceId RADIO_ALIGNED(4);
gint32 fromCodeScheme RADIO_ALIGNED(4);
gint32 toCodeScheme RADIO_ALIGNED(4);
guint8 selected RADIO_ALIGNED(1);
} RADIO_ALIGNED(4) RadioGsmBroadcastSmsConfig;
G_STATIC_ASSERT(sizeof(RadioGsmBroadcastSmsConfig) == 20);
typedef struct radio_select_uicc_sub {
gint32 slot RADIO_ALIGNED(4);
gint32 appIndex RADIO_ALIGNED(4);
gint32 subType RADIO_ALIGNED(4);
gint32 actStatus RADIO_ALIGNED(4);
} RADIO_ALIGNED(4) RadioSelectUiccSub;
G_STATIC_ASSERT(sizeof(RadioSelectUiccSub) == 16);
typedef struct radio_supp_svc_notification {
guint8 isMT RADIO_ALIGNED(1);
gint32 code RADIO_ALIGNED(4);
gint32 index RADIO_ALIGNED(4);
gint32 type RADIO_ALIGNED(4);
GBinderHidlString number RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioSuppSvcNotification;
G_STATIC_ASSERT(sizeof(RadioSuppSvcNotification) == 32);
typedef struct radio_sim_refresh {
gint32 type RADIO_ALIGNED(4);
gint32 efId RADIO_ALIGNED(4);
GBinderHidlString aid RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) RadioSimRefresh;
G_STATIC_ASSERT(sizeof(RadioSimRefresh) == 24);
typedef struct radio_capability {
gint32 session RADIO_ALIGNED(4);
RADIO_CAPABILITY_PHASE phase RADIO_ALIGNED(4);
gint32 raf RADIO_ALIGNED(4);
GBinderHidlString logicalModemUuid RADIO_ALIGNED(8);
RADIO_CAPABILITY_STATUS status RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) RadioCapability;
G_STATIC_ASSERT(sizeof(RadioCapability) == 40);
typedef struct radio_lce_status_info {
guint32 lceStatus RADIO_ALIGNED(4);
guint8 actualIntervalMs RADIO_ALIGNED(1);
} RADIO_ALIGNED(4) RadioLceStatusInfo;
G_STATIC_ASSERT(sizeof(RadioLceStatusInfo) == 8);
/* c(req,resp,callName,CALL_NAME) */
#define RADIO_CALL_1_0(c) \
c(2,1,getIccCardStatus,GET_ICC_CARD_STATUS) \
c(3,2,supplyIccPinForApp,SUPPLY_ICC_PIN_FOR_APP) \
c(4,3,supplyIccPukForApp,SUPPLY_ICC_PUK_FOR_APP) \
c(5,4,supplyIccPin2ForApp,SUPPLY_ICC_PIN2_FOR_APP) \
c(6,5,supplyIccPuk2ForApp,SUPPLY_ICC_PUK2_FOR_APP) \
c(7,6,changeIccPinForApp,CHANGE_ICC_PIN_FOR_APP) \
c(8,7,changeIccPin2ForApp,CHANGE_ICC_PIN2_FOR_APP) \
c(9,8,supplyNetworkDepersonalization,SUPPLY_NETWORK_DEPERSONALIZATION) \
c(10,9,getCurrentCalls,GET_CURRENT_CALLS) \
c(11,10,dial,DIAL) \
c(12,11,getImsiForApp,GET_IMSI_FOR_APP) \
c(13,12,hangup,HANGUP) \
c(14,13,hangupWaitingOrBackground,HANGUP_WAITING_OR_BACKGROUND) \
c(15,14,hangupForegroundResumeBackground,HANGUP_FOREGROUND_RESUME_BACKGROUND) \
c(16,15,switchWaitingOrHoldingAndActive,SWITCH_WAITING_OR_HOLDING_AND_ACTIVE) \
c(17,16,conference,CONFERENCE) \
c(18,17,rejectCall,REJECT_CALL) \
c(19,18,getLastCallFailCause,GET_LAST_CALL_FAIL_CAUSE) \
c(20,19,getSignalStrength,GET_SIGNAL_STRENGTH) \
c(21,20,getVoiceRegistrationState,GET_VOICE_REGISTRATION_STATE) \
c(22,21,getDataRegistrationState,GET_DATA_REGISTRATION_STATE) \
c(23,22,getOperator,GET_OPERATOR) \
c(24,23,setRadioPower,SET_RADIO_POWER) \
c(25,24,sendDtmf,SEND_DTMF) \
c(26,25,sendSms,SEND_SMS) \
c(27,26,sendSMSExpectMore,SEND_SMS_EXPECT_MORE) \
c(28,27,setupDataCall,SETUP_DATA_CALL) \
c(29,28,iccIOForApp,ICC_IO_FOR_APP) \
c(30,29,sendUssd,SEND_USSD) \
c(31,30,cancelPendingUssd,CANCEL_PENDING_USSD) \
c(32,31,getClir,GET_CLIR) \
c(33,32,setClir,SET_CLIR) \
c(34,33,getCallForwardStatus,GET_CALL_FORWARD_STATUS) \
c(35,34,setCallForward,SET_CALL_FORWARD) \
c(36,35,getCallWaiting,GET_CALL_WAITING) \
c(37,36,setCallWaiting,SET_CALL_WAITING) \
c(38,37,acknowledgeLastIncomingGsmSms,ACKNOWLEDGE_LAST_INCOMING_GSM_SMS) \
c(39,38,acceptCall,ACCEPT_CALL) \
c(40,39,deactivateDataCall,DEACTIVATE_DATA_CALL) \
c(41,40,getFacilityLockForApp,GET_FACILITY_LOCK_FOR_APP) \
c(42,41,setFacilityLockForApp,SET_FACILITY_LOCK_FOR_APP) \
c(43,42,setBarringPassword,SET_BARRING_PASSWORD) \
c(44,43,getNetworkSelectionMode,GET_NETWORK_SELECTION_MODE) \
c(45,44,setNetworkSelectionModeAutomatic,SET_NETWORK_SELECTION_MODE_AUTOMATIC) \
c(46,45,setNetworkSelectionModeManual,SET_NETWORK_SELECTION_MODE_MANUAL) \
c(47,46,getAvailableNetworks,GET_AVAILABLE_NETWORKS) \
c(48,47,startDtmf,START_DTMF) \
c(49,48,stopDtmf,STOP_DTMF) \
c(50,49,getBasebandVersion,GET_BASEBAND_VERSION) \
c(51,50,separateConnection,SEPARATE_CONNECTION) \
c(52,51,setMute,SET_MUTE) \
c(53,52,getMute,GET_MUTE) \
c(54,53,getClip,GET_CLIP) \
c(55,54,getDataCallList,GET_DATA_CALL_LIST) \
c(56,55,setSuppServiceNotifications,SET_SUPP_SERVICE_NOTIFICATIONS) \
c(57,56,writeSmsToSim,WRITE_SMS_TO_SIM) \
c(58,57,deleteSmsOnSim,DELETE_SMS_ON_SIM) \
c(59,58,setBandMode,SET_BAND_MODE) \
c(60,59,getAvailableBandModes,GET_AVAILABLE_BAND_MODES) \
c(61,60,sendEnvelope,SEND_ENVELOPE) \
c(62,61,sendTerminalResponseToSim,SEND_TERMINAL_RESPONSE_TO_SIM) \
c(63,62,handleStkCallSetupRequestFromSim,HANDLE_STK_CALL_SETUP_REQUEST_FROM_SIM) \
c(64,63,explicitCallTransfer,EXPLICIT_CALL_TRANSFER) \
c(65,64,setPreferredNetworkType,SET_PREFERRED_NETWORK_TYPE) \
c(66,65,getPreferredNetworkType,GET_PREFERRED_NETWORK_TYPE) \
c(67,66,getNeighboringCids,GET_NEIGHBORING_CIDS) \
c(68,67,setLocationUpdates,SET_LOCATION_UPDATES) \
c(69,68,setCdmaSubscriptionSource,SET_CDMA_SUBSCRIPTION_SOURCE) \
c(70,69,setCdmaRoamingPreference,SET_CDMA_ROAMING_PREFERENCE) \
c(71,70,getCdmaRoamingPreference,GET_CDMA_ROAMING_PREFERENCE) \
c(72,71,setTTYMode,SET_TTY_MODE) \
c(73,72,getTTYMode,GET_TTY_MODE) \
c(74,73,setPreferredVoicePrivacy,SET_PREFERRED_VOICE_PRIVACY) \
c(75,74,getPreferredVoicePrivacy,GET_PREFERRED_VOICE_PRIVACY) \
c(76,75,sendCDMAFeatureCode,SEND_CDMA_FEATURE_CODE) \
c(77,76,sendBurstDtmf,SEND_BURST_DTMF) \
c(78,77,sendCdmaSms,SEND_CDMA_SMS) \
c(79,78,acknowledgeLastIncomingCdmaSms,ACKNOWLEDGE_LAST_INCOMING_CDMA_SMS) \
c(80,79,getGsmBroadcastConfig,GET_GSM_BROADCAST_CONFIG) \
c(81,80,setGsmBroadcastConfig,SET_GSM_BROADCAST_CONFIG) \
c(82,81,setGsmBroadcastActivation,SET_GSM_BROADCAST_ACTIVATION) \
c(83,82,getCdmaBroadcastConfig,GET_CDMA_BROADCAST_CONFIG) \
c(84,83,setCdmaBroadcastConfig,SET_CDMA_BROADCAST_CONFIG) \
c(85,84,setCdmaBroadcastActivation,SET_CDMA_BROADCAST_ACTIVATION) \
c(86,85,getCDMASubscription,GET_CDMA_SUBSCRIPTION) \
c(87,86,writeSmsToRuim,WRITE_SMS_TO_RUIM) \
c(88,87,deleteSmsOnRuim,DELETE_SMS_ON_RUIM) \
c(89,88,getDeviceIdentity,GET_DEVICE_IDENTITY) \
c(90,89,exitEmergencyCallbackMode,EXIT_EMERGENCY_CALLBACK_MODE) \
c(91,90,getSmscAddress,GET_SMSC_ADDRESS) \
c(92,91,setSmscAddress,SET_SMSC_ADDRESS) \
c(93,92,reportSmsMemoryStatus,REPORT_SMS_MEMORY_STATUS) \
c(94,93,reportStkServiceIsRunning,REPORT_STK_SERVICE_IS_RUNNING) \
c(95,94,getCdmaSubscriptionSource,GET_CDMA_SUBSCRIPTION_SOURCE) \
c(96,95,requestIsimAuthentication,REQUEST_ISIM_AUTHENTICATION) \
c(97,96,acknowledgeIncomingGsmSmsWithPdu,ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU) \
c(98,97,sendEnvelopeWithStatus,SEND_ENVELOPE_WITH_STATUS) \
c(99,98,getVoiceRadioTechnology,GET_VOICE_RADIO_TECHNOLOGY) \
c(100,99,getCellInfoList,GET_CELL_INFO_LIST) \
c(101,100,setCellInfoListRate,SET_CELL_INFO_LIST_RATE) \
c(102,101,setInitialAttachApn,SET_INITIAL_ATTACH_APN) \
c(103,102,getImsRegistrationState,GET_IMS_REGISTRATION_STATE) \
c(104,103,sendImsSms,SEND_IMS_SMS) \
c(105,104,iccTransmitApduBasicChannel,ICC_TRANSMIT_APDU_BASIC_CHANNEL) \
c(106,105,iccOpenLogicalChannel,ICC_OPEN_LOGICAL_CHANNEL) \
c(107,106,iccCloseLogicalChannel,ICC_CLOSE_LOGICAL_CHANNEL) \
c(108,107,iccTransmitApduLogicalChannel,ICC_TRANSMIT_APDU_LOGICAL_CHANNEL) \
c(109,108,nvReadItem,NV_READ_ITEM) \
c(110,109,nvWriteItem,NV_WRITE_ITEM) \
c(111,110,nvWriteCdmaPrl,NV_WRITE_CDMA_PRL) \
c(112,111,nvResetConfig,NV_RESET_CONFIG) \
c(113,112,setUiccSubscription,SET_UICC_SUBSCRIPTION) \
c(114,113,setDataAllowed,SET_DATA_ALLOWED) \
c(115,114,getHardwareConfig,GET_HARDWARE_CONFIG) \
c(116,115,requestIccSimAuthentication,REQUEST_ICC_SIM_AUTHENTICATION) \
c(117,116,setDataProfile,SET_DATA_PROFILE) \
c(118,117,requestShutdown,REQUEST_SHUTDOWN) \
c(119,118,getRadioCapability,GET_RADIO_CAPABILITY) \
c(120,119,setRadioCapability,SET_RADIO_CAPABILITY) \
c(121,120,startLceService,START_LCE_SERVICE) \
c(122,121,stopLceService,STOP_LCE_SERVICE) \
c(123,122,pullLceData,PULL_LCE_DATA) \
c(124,123,getModemActivityInfo,GET_MODEM_ACTIVITY_INFO) \
c(125,124,setAllowedCarriers,SET_ALLOWED_CARRIERS) \
c(126,125,getAllowedCarriers,GET_ALLOWED_CARRIERS) \
c(127,126,sendDeviceState,SEND_DEVICE_STATE) \
c(128,127,setIndicationFilter,SET_INDICATION_FILTER) \
c(129,128,setSimCardPower,SET_SIM_CARD_POWER)
/* e(code,eventName,EVENT_NAME) */
#define RADIO_EVENT_1_0(e) \
e(1,radioStateChanged,RADIO_STATE_CHANGED) \
e(2,callStateChanged,CALL_STATE_CHANGED) \
e(3,networkStateChanged,NETWORK_STATE_CHANGED) \
e(4,newSms,NEW_SMS) \
e(5,newSmsStatusReport,NEW_SMS_STATUS_REPORT) \
e(6,newSmsOnSim,NEW_SMS_ON_SIM) \
e(7,onUssd,ON_USSD) \
e(8,nitzTimeReceived,NITZ_TIME_RECEIVED) \
e(9,currentSignalStrength,CURRENT_SIGNAL_STRENGTH) \
e(10,dataCallListChanged,DATA_CALL_LIST_CHANGED) \
e(11,suppSvcNotify,SUPP_SVC_NOTIFY) \
e(12,stkSessionEnd,STK_SESSION_END) \
e(13,stkProactiveCommand,STK_PROACTIVE_COMMAND) \
e(14,stkEventNotify,STK_EVENT_NOTIFY) \
e(15,stkCallSetup,STK_CALL_SETUP) \
e(16,simSmsStorageFull,SIM_SMS_STORAGE_FULL) \
e(17,simRefresh,SIM_REFRESH) \
e(18,callRing,CALL_RING) \
e(19,simStatusChanged,SIM_STATUS_CHANGED) \
e(20,cdmaNewSms,CDMA_NEW_SMS) \
e(21,newBroadcastSms,NEW_BROADCAST_SMS) \
e(22,cdmaRuimSmsStorageFull,CDMA_RUIM_SMS_STORAGE_FULL) \
e(23,restrictedStateChanged,RESTRICTED_STATE_CHANGED) \
e(24,enterEmergencyCallbackMode,ENTER_EMERGENCY_CALLBACK_MODE) \
e(25,cdmaCallWaiting,CDMA_CALL_WAITING) \
e(26,cdmaOtaProvisionStatus,CDMA_OTA_PROVISION_STATUS) \
e(27,cdmaInfoRec,CDMA_INFO_REC) \
e(28,indicateRingbackTone,INDICATE_RINGBACK_TONE) \
e(29,resendIncallMute,RESEND_INCALL_MUTE) \
e(30,cdmaSubscriptionSourceChanged,CDMA_SUBSCRIPTION_SOURCE_CHANGED) \
e(31,cdmaPrlChanged,CDMA_PRL_CHANGED) \
e(32,exitEmergencyCallbackMode,EXIT_EMERGENCY_CALLBACK_MODE) \
e(33,rilConnected,RIL_CONNECTED) \
e(34,voiceRadioTechChanged,VOICE_RADIO_TECH_CHANGED) \
e(35,cellInfoList,CELL_INFO_LIST) \
e(36,imsNetworkStateChanged,IMS_NETWORK_STATE_CHANGED) \
e(37,subscriptionStatusChanged,SUBSCRIPTION_STATUS_CHANGED) \
e(38,srvccStateNotify,SRVCC_STATE_NOTIFY) \
e(39,hardwareConfigChanged,HARDWARE_CONFIG_CHANGED) \
e(40,radioCapabilityIndication,RADIO_CAPABILITY_INDICATION) \
e(41,onSupplementaryServiceIndication,ON_SUPPLEMENTARY_SERVICE_INDICATION) \
e(42,stkCallControlAlphaNotify,STK_CALL_CONTROL_ALPHA_NOTIFY) \
e(43,lceData,LCE_DATA) \
e(44,pcoData,PCO_DATA) \
e(45,modemReset,MODEM_RESET)
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,
RADIO_CALL_1_0(RADIO_REQ_)
#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,
RADIO_CALL_1_0(RADIO_RESP_)
#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,
RADIO_EVENT_1_0(RADIO_IND_)
#undef RADIO_IND_
} RADIO_IND;
/* Logging */
#define GBINDER_RADIO_LOG_MODULE gbinder_radio_log
extern GLogModule GBINDER_RADIO_LOG_MODULE;
G_END_DECLS
#endif /* RADIO_TYPES_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

70
include/radio_util.h Normal file
View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_UTIL_H
#define RADIO_UTIL_H
#include <radio_types.h>
G_BEGIN_DECLS
const char*
radio_req_name(
RADIO_REQ req);
const char*
radio_resp_name(
RADIO_RESP resp);
const char*
radio_ind_name(
RADIO_IND ind);
RADIO_RESP
radio_req_resp(
RADIO_REQ req);
G_END_DECLS
#endif /* RADIO_UTIL_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

10
libgbinder-radio.pc.in Normal file
View File

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

48
rpm/libgbinder-radio.spec Normal file
View File

@@ -0,0 +1,48 @@
Name: libgbinder-radio
Version: 0.0.1
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
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libglibutil)
BuildRequires: pkgconfig(libgbinder)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
%description
Binder client library for Android radio interfaces
%package devel
Summary: Development library for %{name}
Requires: %{name} = %{version}
Requires: pkgconfig
%description devel
This package contains the development library for %{name}.
%prep
%setup -q
%build
make KEEP_SYMBOLS=1 release pkgconfig
%install
rm -rf %{buildroot}
make install-dev DESTDIR=%{buildroot}
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig
%files
%defattr(-,root,root,-)
%{_libdir}/%{name}.so.*
%files devel
%defattr(-,root,root,-)
%{_libdir}/pkgconfig/*.pc
%{_libdir}/%{name}.so
%{_includedir}/gbinder-radio/*.h

776
src/radio_instance.c Normal file
View File

@@ -0,0 +1,776 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#include "radio_instance.h"
#include "radio_registry_p.h"
#include "radio_util.h"
#include "radio_log.h"
#include <gbinder.h>
#include <gutil_idlepool.h>
#include <gutil_misc.h>
#include <glib-object.h>
typedef GObjectClass RadioInstanceClass;
struct radio_instance_priv {
GUtilIdlePool* idle;
GBinderClient* client;
GBinderRemoteObject* remote;
GBinderLocalObject* response;
GBinderLocalObject* indication;
GHashTable* resp_quarks;
GHashTable* ind_quarks;
gulong death_id;
char* dev;
char* slot;
char* key;
};
G_DEFINE_TYPE(RadioInstance, radio_instance, G_TYPE_OBJECT)
enum radio_instance_signal {
SIGNAL_HANDLE_INDICATION,
SIGNAL_HANDLE_RESPONSE,
SIGNAL_OBSERVE_INDICATION,
SIGNAL_OBSERVE_RESPONSE,
SIGNAL_ACK,
SIGNAL_DEATH,
SIGNAL_COUNT
};
#define SIGNAL_HANDLE_INDICATION_NAME "radio-instance-handle-indication"
#define SIGNAL_HANDLE_RESPONSE_NAME "radio-instance-handle-response"
#define SIGNAL_OBSERVE_INDICATION_NAME "radio-instance-observe-indication"
#define SIGNAL_OBSERVE_RESPONSE_NAME "radio-instance-observe-response"
#define SIGNAL_ACK_NAME "radio-instance-ack"
#define SIGNAL_DEATH_NAME "radio-instance-death"
static guint radio_instance_signals[SIGNAL_COUNT] = { 0 };
static GHashTable* radio_instance_table = NULL;
/*==========================================================================*
* Implementation
*==========================================================================*/
static
GQuark
radio_instance_ind_quark(
RadioInstance* self,
RADIO_IND ind)
{
GQuark q = 0;
if (ind != RADIO_IND_ANY) {
RadioInstancePriv* priv = self->priv;
gpointer key = GUINT_TO_POINTER(ind);
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->ind_quarks, key));
if (!q) {
const char* known = radio_ind_name(ind);
if (known) {
q = g_quark_from_static_string(known);
} else {
q = g_quark_from_string(radio_instance_ind_name(self, ind));
}
g_hash_table_insert(priv->ind_quarks, key, GUINT_TO_POINTER(q));
}
}
return q;
}
static
GQuark
radio_instance_resp_quark(
RadioInstance* self,
RADIO_RESP resp)
{
GQuark q = 0;
if (resp != RADIO_RESP_ANY) {
RadioInstancePriv* priv = self->priv;
gpointer key = GUINT_TO_POINTER(resp);
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->resp_quarks, key));
if (!q) {
const char* known = radio_resp_name(resp);
if (known) {
q = g_quark_from_static_string(known);
} else {
q = g_quark_from_string(radio_instance_resp_name(self, resp));
}
g_hash_table_insert(priv->resp_quarks, key, GUINT_TO_POINTER(q));
}
}
return q;
}
static
GBinderLocalReply*
radio_instance_indication(
GBinderLocalObject* obj,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status,
void* user_data)
{
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
if (!g_strcmp0(iface, RADIO_INDICATION_1_0)) {
GBinderReader reader;
guint type;
/* All these should be one-way */
GASSERT(flags & GBINDER_TX_FLAG_ONEWAY);
gbinder_remote_request_init_reader(req, &reader);
if (gbinder_reader_read_uint32(&reader, &type) &&
(type == RADIO_IND_UNSOLICITED || type == RADIO_IND_ACK_EXP)) {
GQuark quark = radio_instance_ind_quark(self, code);
gboolean handled = FALSE;
g_signal_emit(self,
radio_instance_signals[SIGNAL_HANDLE_INDICATION], quark,
code, type, &reader, &handled);
g_signal_emit(self,
radio_instance_signals[SIGNAL_OBSERVE_INDICATION], quark,
code, type, &reader);
if (type == RADIO_IND_ACK_EXP && !handled) {
GDEBUG("ack unhandled indication");
radio_instance_ack(self);
}
*status = GBINDER_STATUS_OK;
} else {
GWARN("Failed to decode indication %u", code);
*status = GBINDER_STATUS_FAILED;
}
} else {
GWARN("Unexpected indication %s %u", iface, code);
*status = GBINDER_STATUS_FAILED;
}
return NULL;
}
static
GBinderLocalReply*
radio_instance_response(
GBinderLocalObject* obj,
GBinderRemoteRequest* req,
guint code,
guint flags,
int* status,
void* user_data)
{
RadioInstance* self = RADIO_INSTANCE(user_data);
const char* iface = gbinder_remote_request_interface(req);
if (!g_strcmp0(iface, RADIO_RESPONSE_1_0)) {
/* All these should be one-way transactions */
GASSERT(flags & GBINDER_TX_FLAG_ONEWAY);
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)) {
g_signal_emit(self, radio_instance_signals[SIGNAL_ACK], 0,
serial);
}
} else {
/* All other responses have RadioResponseInfo */
GBinderReader reader;
GBinderBuffer* buf;
gbinder_remote_request_init_reader(req, &reader);
buf = gbinder_reader_read_buffer(&reader);
GASSERT(buf && buf->size == sizeof(RadioResponseInfo));
if (buf && buf->size == sizeof(RadioResponseInfo)) {
GQuark quark = radio_instance_resp_quark(self, code);
const RadioResponseInfo* info = buf->data;
gboolean handled = FALSE;
g_signal_emit(self,
radio_instance_signals[SIGNAL_HANDLE_RESPONSE], quark,
code, info, &reader, &handled);
g_signal_emit(self,
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE], quark,
code, info, &reader);
if (info->type == RADIO_RESP_SOLICITED_ACK_EXP && !handled) {
GDEBUG("ack unhandled response");
radio_instance_ack(self);
}
}
gbinder_buffer_free(buf);
}
*status = GBINDER_STATUS_OK;
} else {
GWARN("Unexpected response %s %u", iface, code);
*status = GBINDER_STATUS_FAILED;
}
return NULL;
}
static
void
radio_instance_drop_binder(
RadioInstance* self)
{
RadioInstancePriv* priv = self->priv;
if (priv->indication) {
gbinder_local_object_drop(priv->indication);
priv->indication = NULL;
}
if (priv->response) {
gbinder_local_object_drop(priv->response);
priv->response = NULL;
}
if (priv->remote) {
gbinder_remote_object_remove_handler(priv->remote, priv->death_id);
gbinder_remote_object_unref(priv->remote);
priv->death_id = 0;
priv->remote = NULL;
}
}
static
void
radio_instance_remove(
const char* key)
{
if (radio_instance_table &&
g_hash_table_contains(radio_instance_table, key)) {
g_hash_table_remove(radio_instance_table, key);
radio_registry_instance_removed(key);
if (g_hash_table_size(radio_instance_table) == 0) {
g_hash_table_unref(radio_instance_table);
radio_instance_table = NULL;
}
}
}
static
void
radio_instance_died(
GBinderRemoteObject* obj,
void* user_data)
{
RadioInstance* self = RADIO_INSTANCE(user_data);
self->dead = TRUE;
GWARN("%s died", self->key);
radio_instance_ref(self);
radio_instance_drop_binder(self);
g_signal_emit(self, radio_instance_signals[SIGNAL_DEATH], 0);
radio_instance_remove(self->key);
radio_instance_unref(self);
}
static
void
radio_instance_gone(
gpointer key_ptr,
GObject* dead)
{
char* key = key_ptr;
GASSERT(radio_instance_table);
GVERBOSE_("%s", key);
radio_instance_remove(key);
g_free(key);
}
static
RadioInstance*
radio_instance_create(
const char* dev,
const char* slot,
const char* key)
{
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);
if (remote) {
RadioInstancePriv* priv;
GBinderLocalRequest* req;
GBinderRemoteReply* reply;
GBinderWriter writer;
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);
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));
}
gbinder_servicemanager_unref(sm);
g_free(fqname);
}
return self;
}
static
char*
radio_instance_make_key(
const char* dev,
const char* name)
{
return g_strconcat(dev, ":", name, NULL);
}
/*==========================================================================*
* API
*==========================================================================*/
RadioInstance*
radio_instance_new(
const char* dev,
const char* name)
{
if (dev && dev[0] && name && name[0]) {
char* key = radio_instance_make_key(dev, name);
RadioInstance* self = NULL;
if (radio_instance_table) {
self = g_hash_table_lookup(radio_instance_table, key);
}
if (self) {
g_free(key);
return radio_instance_ref(self);
} else {
self = radio_instance_create(dev, name, key);
if (self) {
if (!radio_instance_table) {
radio_instance_table = g_hash_table_new_full
(g_str_hash, g_str_equal, g_free, NULL);
}
g_hash_table_replace(radio_instance_table, g_strdup(key), self);
g_object_weak_ref(G_OBJECT(self), radio_instance_gone, key);
radio_registry_instance_added(self);
return self;
}
}
g_free(key);
}
return NULL;
}
RadioInstance*
radio_instance_get(
const char* dev,
const char* name)
{
RadioInstance* self = NULL;
if (dev && dev[0] && name && name[0]) {
char* key = radio_instance_make_key(dev, name);
if (radio_instance_table) {
self = g_hash_table_lookup(radio_instance_table, key);
}
g_free(key);
}
return self;
}
RadioInstance* const*
radio_instance_get_all(
void)
{
if (radio_instance_table) {
/* If the table exists, it must be non-empty */
const guint n = g_hash_table_size(radio_instance_table);
RadioInstance** all = g_new0(RadioInstance*, n + 1);
RadioInstance* last = NULL;
GHashTableIter it;
gpointer value;
guint i = 0;
g_hash_table_iter_init(&it, radio_instance_table);
while (g_hash_table_iter_next(&it, NULL, &value)) {
last = all[i++] = value;
}
/* Add the array itself to the idle pool of the last instance */
gutil_idle_pool_add(last->priv->idle, all, g_free);
return all;
}
return NULL;
}
RadioInstance*
radio_instance_ref(
RadioInstance* self)
{
if (G_LIKELY(self)) {
g_object_ref(RADIO_INSTANCE(self));
return self;
} else {
return NULL;
}
}
void
radio_instance_unref(
RadioInstance* self)
{
if (G_LIKELY(self)) {
g_object_unref(RADIO_INSTANCE(self));
}
}
const char*
radio_instance_req_name(
RadioInstance* self,
RADIO_REQ req)
{
const char* known = radio_req_name(req);
if (known) {
return known;
} else if (G_LIKELY(self)) {
char* str = g_strdup_printf("%u", (guint)req);
gutil_idle_pool_add(self->priv->idle, str, g_free);
return str;
} else {
return NULL;
}
}
const char*
radio_instance_resp_name(
RadioInstance* self,
RADIO_RESP resp)
{
const char* known = radio_resp_name(resp);
if (known) {
return known;
} else if (G_LIKELY(self)) {
char* str = g_strdup_printf("%u", (guint)resp);
gutil_idle_pool_add(self->priv->idle, str, g_free);
return str;
} else {
return NULL;
}
}
const char*
radio_instance_ind_name(
RadioInstance* self,
RADIO_IND ind)
{
const char* known = radio_ind_name(ind);
if (known) {
return known;
} else if (G_LIKELY(self)) {
char* str = g_strdup_printf("%u", (guint)ind);
gutil_idle_pool_add(self->priv->idle, str, g_free);
return str;
} else {
return NULL;
}
}
gboolean
radio_instance_is_dead(
RadioInstance* self)
{
return G_UNLIKELY(!self) || self->dead;
}
gboolean
radio_instance_ack(
RadioInstance* self)
{
if (G_LIKELY(self)) {
return gbinder_client_transact_sync_oneway(self->priv->client,
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT, NULL) >= 0;
}
return 0;
}
GBinderLocalRequest*
radio_instance_new_request(
RadioInstance* self,
RADIO_REQ code)
{
if (G_LIKELY(self)) {
return gbinder_client_new_request(self->priv->client);
}
return NULL;
}
gboolean
radio_instance_send_request_sync(
RadioInstance* self,
RADIO_REQ code,
GBinderLocalRequest* args)
{
if (G_LIKELY(self)) {
return gbinder_client_transact_sync_oneway(self->priv->client,
code, args) >= 0;
}
return FALSE;
}
gulong
radio_instance_add_indication_handler(
RadioInstance* self,
RADIO_IND ind,
RadioIndicationHandlerFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_HANDLE_INDICATION],
radio_instance_ind_quark(self, ind),
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
}
gulong
radio_instance_add_indication_observer(
RadioInstance* self,
RADIO_IND ind,
RadioIndicationObserverFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_OBSERVE_INDICATION],
radio_instance_ind_quark(self, ind),
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
}
gulong
radio_instance_add_response_handler(
RadioInstance* self,
RADIO_RESP resp,
RadioResponseHandlerFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_HANDLE_RESPONSE],
radio_instance_resp_quark(self, resp),
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
}
gulong
radio_instance_add_response_observer(
RadioInstance* self,
RADIO_RESP resp,
RadioResponseObserverFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ?
g_signal_connect_closure_by_id(self,
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE],
radio_instance_resp_quark(self, resp),
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
}
gulong
radio_instance_add_ack_handler(
RadioInstance* self,
RadioAckFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ACK_NAME, G_CALLBACK(func), user_data) : 0;
}
gulong
radio_instance_add_death_handler(
RadioInstance* self,
RadioInstanceFunc func,
gpointer user_data)
{
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
SIGNAL_ACK_NAME, G_CALLBACK(func), user_data) : 0;
}
void
radio_instance_remove_handler(
RadioInstance* self,
gulong id)
{
if (G_LIKELY(self) && G_LIKELY(id)) {
g_signal_handler_disconnect(self, id);
}
}
void
radio_instance_remove_handlers(
RadioInstance* self,
gulong* ids,
int count)
{
gutil_disconnect_handlers(self, ids, count);
}
/*==========================================================================*
* Internals
*==========================================================================*/
static
void
radio_instance_init(
RadioInstance* self)
{
RadioInstancePriv* priv = G_TYPE_INSTANCE_GET_PRIVATE
(self, RADIO_TYPE_INSTANCE, RadioInstancePriv);
self->priv = priv;
priv->idle = gutil_idle_pool_new();
priv->resp_quarks = g_hash_table_new(g_direct_hash, g_direct_equal);
priv->ind_quarks = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static
void
radio_instance_finalize(
GObject* object)
{
RadioInstance* self = RADIO_INSTANCE(object);
RadioInstancePriv* priv = self->priv;
radio_instance_drop_binder(self);
gbinder_client_unref(priv->client);
gutil_idle_pool_destroy(priv->idle);
g_hash_table_destroy(priv->resp_quarks);
g_hash_table_destroy(priv->ind_quarks);
g_free(priv->slot);
g_free(priv->dev);
g_free(priv->key);
G_OBJECT_CLASS(radio_instance_parent_class)->finalize(object);
}
static
void
radio_instance_class_init(
RadioInstanceClass* klass)
{
GObjectClass* object_class = G_OBJECT_CLASS(klass);
GType type = G_OBJECT_CLASS_TYPE(klass);
g_type_class_add_private(klass, sizeof(RadioInstancePriv));
object_class->finalize = radio_instance_finalize;
radio_instance_signals[SIGNAL_HANDLE_INDICATION] =
g_signal_new(SIGNAL_HANDLE_INDICATION_NAME, type,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0,
g_signal_accumulator_true_handled, NULL, NULL,
G_TYPE_BOOLEAN, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
radio_instance_signals[SIGNAL_HANDLE_RESPONSE] =
g_signal_new(SIGNAL_HANDLE_RESPONSE_NAME, type,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0,
g_signal_accumulator_true_handled, NULL, NULL,
G_TYPE_BOOLEAN, 3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
radio_instance_signals[SIGNAL_OBSERVE_INDICATION] =
g_signal_new(SIGNAL_OBSERVE_INDICATION_NAME, type,
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE] =
g_signal_new(SIGNAL_OBSERVE_RESPONSE_NAME, type,
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
radio_instance_signals[SIGNAL_ACK] =
g_signal_new(SIGNAL_ACK_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_UINT);
radio_instance_signals[SIGNAL_DEATH] =
g_signal_new(SIGNAL_DEATH_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

53
src/radio_log.h Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_LOG_H
#define RADIO_LOG_H
#include "radio_types.h"
#define GLOG_MODULE_NAME GBINDER_RADIO_LOG_MODULE
#include <gutil_log.h>
#endif /* RADIO_LOG_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

221
src/radio_registry.c Normal file
View File

@@ -0,0 +1,221 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#include "radio_registry_p.h"
#include "radio_instance.h"
#include <gutil_misc.h>
typedef GObjectClass RadioRegistryClass;
struct radio_registry {
GObject parent;
};
G_DEFINE_TYPE(RadioRegistry, radio_registry, G_TYPE_OBJECT)
#define RADIO_TYPE_REGISTRY (radio_registry_get_type())
#define RADIO_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
RADIO_TYPE_REGISTRY, RadioRegistry))
enum radio_registry_signal {
SIGNAL_INSTANCE_ADDED,
SIGNAL_INSTANCE_REMOVED,
SIGNAL_COUNT
};
#define SIGNAL_INSTANCE_ADDED_NAME "radio-instance-added"
#define SIGNAL_INSTANCE_REMOVED_NAME "radio-instance-removed"
static guint radio_registry_signals[SIGNAL_COUNT] = { 0 };
static RadioRegistry* radio_registry_instance = NULL;
/*==========================================================================*
* Internal API
*==========================================================================*/
void
radio_registry_instance_added(
RadioInstance* radio)
{
RadioRegistry* self = radio_registry_instance;
if (self) {
radio_registry_ref(self);
g_signal_emit(self, radio_registry_signals[SIGNAL_INSTANCE_ADDED],
g_quark_from_string(radio->key), radio);
radio_registry_unref(self);
}
}
void
radio_registry_instance_removed(
const char* key)
{
RadioRegistry* self = radio_registry_instance;
if (self) {
radio_registry_ref(self);
g_signal_emit(self, radio_registry_signals[SIGNAL_INSTANCE_REMOVED],
g_quark_from_string(key), key);
radio_registry_unref(self);
}
}
/*==========================================================================*
* API
*==========================================================================*/
RadioRegistry*
radio_registry_new(
void)
{
if (radio_registry_instance) {
radio_registry_ref(radio_registry_instance);
} else {
radio_registry_instance = g_object_new(RADIO_TYPE_REGISTRY, NULL);
g_object_add_weak_pointer(G_OBJECT(radio_registry_instance),
(gpointer*)(&radio_registry_instance));
}
return radio_registry_instance;
}
RadioRegistry*
radio_registry_ref(
RadioRegistry* self)
{
if (G_LIKELY(self)) {
g_object_ref(RADIO_REGISTRY(self));
return self;
} else {
return NULL;
}
}
void
radio_registry_unref(
RadioRegistry* self)
{
if (G_LIKELY(self)) {
g_object_unref(RADIO_REGISTRY(self));
}
}
gulong
radio_registry_add_instance_added_handler(
RadioRegistry* self,
const char* key, /* NULL for any */
RadioRegistryInstanceFunc func,
gpointer user_data)
{
if (G_LIKELY(self) && G_LIKELY(func)) {
return g_signal_connect_closure_by_id(self,
radio_registry_signals[SIGNAL_INSTANCE_ADDED],
(key && key[0]) ? g_quark_from_string(key) : 0,
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE);
}
return 0;
}
gulong
radio_registry_add_instance_removed_handler(
RadioRegistry* self,
const char* key, /* NULL for any */
RadioRegistryStrFunc func,
gpointer user_data)
{
if (G_LIKELY(self) && G_LIKELY(func)) {
return g_signal_connect_closure_by_id(self,
radio_registry_signals[SIGNAL_INSTANCE_REMOVED],
(key && key[0]) ? g_quark_from_string(key) : 0,
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE);
}
return 0;
}
void
radio_registry_remove_handler(
RadioRegistry* self,
gulong id)
{
if (G_LIKELY(self) && G_LIKELY(id)) {
g_signal_handler_disconnect(self, id);
}
}
void
radio_registry_remove_handlers(
RadioRegistry* self,
gulong* ids,
int count)
{
gutil_disconnect_handlers(self, ids, count);
}
/*==========================================================================*
* Internals
*==========================================================================*/
static
void
radio_registry_init(
RadioRegistry* self)
{
}
static
void
radio_registry_class_init(
RadioRegistryClass* klass)
{
radio_registry_signals[SIGNAL_INSTANCE_ADDED] =
g_signal_new(SIGNAL_INSTANCE_ADDED_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, RADIO_TYPE_INSTANCE);
radio_registry_signals[SIGNAL_INSTANCE_REMOVED] =
g_signal_new(SIGNAL_INSTANCE_REMOVED_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
G_TYPE_NONE, 1, G_TYPE_STRING);
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

58
src/radio_registry_p.h Normal file
View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#ifndef RADIO_REGISTRY_PRIVATE_H
#define RADIO_REGISTRY_PRIVATE_H
#include "radio_registry.h"
void
radio_registry_instance_added(
RadioInstance* instance);
void
radio_registry_instance_removed(
const char* key);
#endif /* RADIO_REGISTRY_PRIVATE_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

111
src/radio_util.c Normal file
View File

@@ -0,0 +1,111 @@
/*
* Copyright (C) 2018-2019 Jolla Ltd.
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation
* are those of the authors and should not be interpreted as representing
* any official policies, either expressed or implied.
*/
#include "radio_util.h"
#include "radio_log.h"
GLOG_MODULE_DEFINE("gbinder-radio");
const char*
radio_req_name(
RADIO_REQ req)
{
switch (req) {
case RADIO_REQ_SET_RESPONSE_FUNCTIONS: return "setResponseFunctions";
case RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT: return "responseAcknowledgement";
#define RADIO_REQ_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return #Name;
RADIO_CALL_1_0(RADIO_REQ_)
#undef RADIO_REQ_
case RADIO_REQ_ANY:
break;
}
return NULL;
}
const char*
radio_resp_name(
RADIO_RESP resp)
{
switch (resp) {
case RADIO_RESP_ACKNOWLEDGE_REQUEST: return "acknowledgeRequest";
#define RADIO_RESP_(req,resp,Name,NAME) \
case RADIO_RESP_##NAME: return #Name "Response";
RADIO_CALL_1_0(RADIO_RESP_)
#undef RADIO_RESP_
case RADIO_RESP_ANY:
break;
}
return NULL;
}
const char*
radio_ind_name(
RADIO_IND ind)
{
switch (ind) {
#define RADIO_IND_(code,Name,NAME) \
case RADIO_IND_##NAME: return #Name;
RADIO_EVENT_1_0(RADIO_IND_)
#undef RADIO_IND_
case RADIO_IND_ANY:
break;
}
return NULL;
}
RADIO_RESP
radio_req_resp(
RADIO_REQ req)
{
switch (req) {
#define RADIO_REQ_(req,resp,Name,NAME) \
case RADIO_REQ_##NAME: return RADIO_RESP_##NAME;
RADIO_CALL_1_0(RADIO_REQ_)
#undef RADIO_REQ_
default:
return RADIO_RESP_NONE;
}
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/