[gbinder-radio] Added RadioConfig API. JB#56824
Simplifies talking to IRadioConfig binder service.
This commit is contained in:
		
							
								
								
									
										1
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Makefile
									
									
									
									
									
								
							@@ -49,6 +49,7 @@ LIB = $(LIB_NAME).a
 | 
			
		||||
SRC = \
 | 
			
		||||
  radio_base.c \
 | 
			
		||||
  radio_client.c \
 | 
			
		||||
  radio_config.c \
 | 
			
		||||
  radio_instance.c \
 | 
			
		||||
  radio_registry.c \
 | 
			
		||||
  radio_request.c \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										197
									
								
								include/radio_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								include/radio_config.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,197 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef RADIO_CONFIG_H
 | 
			
		||||
#define RADIO_CONFIG_H
 | 
			
		||||
 | 
			
		||||
/* This API exists since 1.4.6 */
 | 
			
		||||
 | 
			
		||||
#include <radio_config_types.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioConfigFunc)(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioConfigRequestObserverFunc)(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    GBinderLocalRequest* args,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioConfigResponseObserverFunc)(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_RESP code,
 | 
			
		||||
    const RadioResponseInfo* info,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioConfigIndicationObserverFunc)(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
RadioConfig*
 | 
			
		||||
radio_config_new(void)
 | 
			
		||||
    G_GNUC_WARN_UNUSED_RESULT;
 | 
			
		||||
 | 
			
		||||
RadioConfig*
 | 
			
		||||
radio_config_new_with_version(
 | 
			
		||||
    RADIO_CONFIG_INTERFACE max_version)
 | 
			
		||||
    G_GNUC_WARN_UNUSED_RESULT;
 | 
			
		||||
 | 
			
		||||
RadioConfig*
 | 
			
		||||
radio_config_ref(
 | 
			
		||||
    RadioConfig* config);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
radio_config_unref(
 | 
			
		||||
    RadioConfig* config);
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
radio_config_dead(
 | 
			
		||||
    RadioConfig* config);
 | 
			
		||||
 | 
			
		||||
RADIO_CONFIG_INTERFACE
 | 
			
		||||
radio_config_interface(
 | 
			
		||||
    RadioConfig* config);
 | 
			
		||||
 | 
			
		||||
gsize
 | 
			
		||||
radio_config_rpc_header_size(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ req);
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
radio_config_req_name(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ req);
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
radio_config_resp_name(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_RESP resp);
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
radio_config_ind_name(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND ind);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_death_handler(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RadioConfigFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_request_observer(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    RadioConfigRequestObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_request_observer_with_priority(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    RadioConfigRequestObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_response_observer(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_RESP code,
 | 
			
		||||
    RadioConfigResponseObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_response_observer_with_priority(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_CONFIG_RESP code,
 | 
			
		||||
    RadioConfigResponseObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_indication_observer(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    RadioConfigIndicationObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_config_add_indication_observer_with_priority(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    RadioConfigIndicationObserverFunc func,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
radio_config_remove_handler(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    gulong id);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
radio_config_remove_handlers(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    gulong* ids,
 | 
			
		||||
    int count);
 | 
			
		||||
 | 
			
		||||
#define radio_config_remove_all_handlers(config,ids) \
 | 
			
		||||
    radio_config_remove_handlers(config, ids, G_N_ELEMENTS(ids))
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* RADIO_CONFIG_H */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
							
								
								
									
										188
									
								
								include/radio_config_types.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								include/radio_config_types.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,188 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef RADIO_CONFIG_TYPES_H
 | 
			
		||||
#define RADIO_CONFIG_TYPES_H
 | 
			
		||||
 | 
			
		||||
/* This API exists since 1.4.6 */
 | 
			
		||||
 | 
			
		||||
#include <radio_types.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef enum radio_config_interface {
 | 
			
		||||
    RADIO_CONFIG_INTERFACE_NONE = -1,
 | 
			
		||||
    RADIO_CONFIG_INTERFACE_1_0,
 | 
			
		||||
    RADIO_CONFIG_INTERFACE_1_1,
 | 
			
		||||
    RADIO_CONFIG_INTERFACE_COUNT
 | 
			
		||||
} RADIO_CONFIG_INTERFACE;
 | 
			
		||||
 | 
			
		||||
#define RADIO_CONFIG_INTERFACE_MAX (RADIO_CONFIG_INTERFACE_COUNT - 1)
 | 
			
		||||
 | 
			
		||||
#define RADIO_CONFIG_INSTANCE         "default"
 | 
			
		||||
#define RADIO_CONFIG_IFACE_PREFIX     "android.hardware.radio.config@"
 | 
			
		||||
#define RADIO_CONFIG_IFACE            "IRadioConfig"
 | 
			
		||||
#define RADIO_CONFIG_RESPONSE_IFACE   "IRadioConfigResponse"
 | 
			
		||||
#define RADIO_CONFIG_INDICATION_IFACE "IRadioConfigIndication"
 | 
			
		||||
#define RADIO_CONFIG_IFACE_1_0(x)     RADIO_CONFIG_IFACE_PREFIX "1.0::" x
 | 
			
		||||
#define RADIO_CONFIG_IFACE_1_1(x)     RADIO_CONFIG_IFACE_PREFIX "1.1::" x
 | 
			
		||||
#define RADIO_CONFIG_1_0              RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_IFACE)
 | 
			
		||||
#define RADIO_CONFIG_1_1              RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_IFACE)
 | 
			
		||||
#define RADIO_CONFIG_1_0_FQNAME       RADIO_CONFIG_1_0 "/" RADIO_CONFIG_INSTANCE
 | 
			
		||||
#define RADIO_CONFIG_1_1_FQNAME       RADIO_CONFIG_1_1 "/" RADIO_CONFIG_INSTANCE
 | 
			
		||||
#define RADIO_CONFIG_RESPONSE_1_0 \
 | 
			
		||||
        RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_RESPONSE_IFACE)
 | 
			
		||||
#define RADIO_CONFIG_RESPONSE_1_1 \
 | 
			
		||||
        RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_RESPONSE_IFACE)
 | 
			
		||||
#define RADIO_CONFIG_INDICATION_1_0 \
 | 
			
		||||
        RADIO_CONFIG_IFACE_1_0(RADIO_CONFIG_INDICATION_IFACE)
 | 
			
		||||
#define RADIO_CONFIG_INDICATION_1_1 \
 | 
			
		||||
        RADIO_CONFIG_IFACE_1_1(RADIO_CONFIG_INDICATION_IFACE)
 | 
			
		||||
 | 
			
		||||
/* Types defined in types.hal */
 | 
			
		||||
 | 
			
		||||
/* SlotState */
 | 
			
		||||
typedef enum radio_slot_state {
 | 
			
		||||
    RADIO_SLOT_STATE_INACTIVE,
 | 
			
		||||
    RADIO_SLOT_STATE_ACTIVE
 | 
			
		||||
} RADIO_SLOT_STATE;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_SLOT_STATE) == 4);
 | 
			
		||||
 | 
			
		||||
/* SimSlotStatus */
 | 
			
		||||
typedef struct radio_sim_slot_status {
 | 
			
		||||
    RADIO_CARD_STATE cardState RADIO_ALIGNED(4);
 | 
			
		||||
    RADIO_SLOT_STATE slotState RADIO_ALIGNED(4);
 | 
			
		||||
    GBinderHidlString atr RADIO_ALIGNED(8);
 | 
			
		||||
    guint32 logicalSlotId RADIO_ALIGNED(4);
 | 
			
		||||
    GBinderHidlString iccid RADIO_ALIGNED(8);
 | 
			
		||||
} RADIO_ALIGNED(8) RadioSimSlotStatus;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RadioSimSlotStatus) == 48);
 | 
			
		||||
 | 
			
		||||
/* ModemInfo */
 | 
			
		||||
typedef struct radio_modem_info {
 | 
			
		||||
    guint8 modemId RADIO_ALIGNED(1);
 | 
			
		||||
} RADIO_ALIGNED(1) RadioModemInfo;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RadioModemInfo) == 1);
 | 
			
		||||
 | 
			
		||||
/* PhoneCapability */
 | 
			
		||||
typedef struct radio_phone_capability {
 | 
			
		||||
    guint8 maxActiveData RADIO_ALIGNED(1);
 | 
			
		||||
    guint8 maxActiveInternetData RADIO_ALIGNED(1);
 | 
			
		||||
    guint8 isInternetLingeringSupported RADIO_ALIGNED(1);
 | 
			
		||||
    GBinderHidlVec logicalModemList RADIO_ALIGNED(8); /* vec<ModemInfo> */
 | 
			
		||||
} RADIO_ALIGNED(8) RadioPhoneCapability;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RadioPhoneCapability) == 24);
 | 
			
		||||
 | 
			
		||||
/* ModemsConfig */
 | 
			
		||||
typedef struct radio_modems_config {
 | 
			
		||||
    guint8 numOfLiveModems RADIO_ALIGNED(1);
 | 
			
		||||
} RADIO_ALIGNED(1) RadioModemsConfig;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RadioModemsConfig) == 1);
 | 
			
		||||
 | 
			
		||||
/* Transaction codes */
 | 
			
		||||
 | 
			
		||||
/* c(req,resp,Name,CALL_NAME) */
 | 
			
		||||
#define RADIO_CONFIG_CALL_1_0(c) \
 | 
			
		||||
    c(2,1,getSimSlotsStatus,GET_SIM_SLOTS_STATUS) \
 | 
			
		||||
    c(3,2,setSimSlotsMapping,SET_SIM_SLOTS_MAPPING)
 | 
			
		||||
 | 
			
		||||
#define RADIO_CONFIG_CALL_1_1(c) \
 | 
			
		||||
    c(4,3,getPhoneCapability,GET_PHONE_CAPABILITY) \
 | 
			
		||||
    c(5,4,setPreferredDataModem,SET_PREFERRED_DATA_MODEM) \
 | 
			
		||||
    c(6,5,setModemsConfig,SET_MODEMS_CONFIG) \
 | 
			
		||||
    c(7,6,getModemsConfig,GET_MODEMS_CONFIG)
 | 
			
		||||
 | 
			
		||||
/* i(code,Name,IND_NAME) */
 | 
			
		||||
#define RADIO_CONFIG_IND_1_0(i) \
 | 
			
		||||
    i(1,simSlotsStatusChanged,SIM_SLOTS_STATUS_CHANGED)
 | 
			
		||||
 | 
			
		||||
typedef enum radio_config_req {
 | 
			
		||||
    RADIO_CONFIG_REQ_ANY = 0,
 | 
			
		||||
    RADIO_CONFIG_REQ_NONE = 0,
 | 
			
		||||
#define RADIO_CONFIG_REQ_(req,resp,Name,NAME) RADIO_CONFIG_REQ_##NAME = req,
 | 
			
		||||
 | 
			
		||||
    /* android.hardware.radio.config@1.0::IRadioConfig */
 | 
			
		||||
    RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS = 1, /* setResponseFunctions */
 | 
			
		||||
    RADIO_CONFIG_CALL_1_0(RADIO_CONFIG_REQ_)
 | 
			
		||||
    RADIO_CONFIG_1_0_REQ_LAST = RADIO_CONFIG_REQ_SET_SIM_SLOTS_MAPPING,
 | 
			
		||||
 | 
			
		||||
    /* android.hardware.radio.config@1.1::IRadioConfig */
 | 
			
		||||
    RADIO_CONFIG_CALL_1_1(RADIO_CONFIG_REQ_)
 | 
			
		||||
    RADIO_CONFIG_1_1_REQ_LAST = RADIO_CONFIG_REQ_GET_MODEMS_CONFIG
 | 
			
		||||
 | 
			
		||||
#undef RADIO_CONFIG_REQ_
 | 
			
		||||
} RADIO_CONFIG_REQ;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_REQ) == 4);
 | 
			
		||||
 | 
			
		||||
typedef enum radio_config_resp {
 | 
			
		||||
    RADIO_CONFIG_RESP_ANY = 0,
 | 
			
		||||
    RADIO_CONFIG_RESP_NONE = 0,
 | 
			
		||||
#define RADIO_CONFIG_RESP_(req,resp,Name,NAME) RADIO_CONFIG_RESP_##NAME = resp,
 | 
			
		||||
 | 
			
		||||
    /* android.hardware.radio.config@1.0::IRadioConfigResponse */
 | 
			
		||||
    RADIO_CONFIG_CALL_1_0(RADIO_CONFIG_RESP_)
 | 
			
		||||
    RADIO_CONFIG_1_0_RESP_LAST = RADIO_CONFIG_RESP_SET_SIM_SLOTS_MAPPING,
 | 
			
		||||
 | 
			
		||||
    /* android.hardware.radio.config@1.1::IRadioConfigResponse */
 | 
			
		||||
    RADIO_CONFIG_CALL_1_1(RADIO_CONFIG_RESP_)
 | 
			
		||||
    RADIO_CONFIG_1_1_RESP_LAST = RADIO_CONFIG_RESP_GET_MODEMS_CONFIG
 | 
			
		||||
#undef RADIO_CONFIG_RESP_
 | 
			
		||||
} RADIO_CONFIG_RESP;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_RESP) == 4);
 | 
			
		||||
 | 
			
		||||
typedef enum radio_config_ind {
 | 
			
		||||
    RADIO_CONFIG_IND_ANY = 0,
 | 
			
		||||
    RADIO_CONFIG_IND_NONE = 0,
 | 
			
		||||
#define RADIO_CONFIG_IND_(code,Name,NAME) RADIO_CONFIG_IND_##NAME = code,
 | 
			
		||||
 | 
			
		||||
    /* android.hardware.radio.config@1.0::IRadioConfigIndication */
 | 
			
		||||
    RADIO_CONFIG_IND_1_0(RADIO_CONFIG_IND_)
 | 
			
		||||
    RADIO_CONFIG_1_0_IND_LAST = RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED
 | 
			
		||||
#undef RADIO_CONFIG_IND_
 | 
			
		||||
} RADIO_CONFIG_IND;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_CONFIG_IND) == 4);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* RADIO_CONFIG_TYPES_H */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -62,11 +62,11 @@ struct radio_instance {
 | 
			
		||||
    gboolean connected; /* rilConnected received */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum radio_instance_priority {
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY_LOWEST,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY_DEFAULT = 2,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY_HIGHEST = 7
 | 
			
		||||
} RADIO_INSTANCE_PRIORITY; /* Since 1.4.3 */
 | 
			
		||||
/* These were introduced in 1.4.3 and then renamed in 1.4.6 */
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY_LOWEST RADIO_OBSERVER_PRIORITY_LOWEST
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY_DEFAULT RADIO_OBSERVER_PRIORITY_DEFAULT
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY_HIGHEST RADIO_OBSERVER_PRIORITY_HIGHEST
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY RADIO_OBSERVER_PRIORITY
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
@@ -229,7 +229,7 @@ radio_instance_add_request_observer(
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_request_observer_with_priority(
 | 
			
		||||
    RadioInstance* radio,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_REQ code,
 | 
			
		||||
    RadioRequestObserverFunc func,
 | 
			
		||||
    gpointer user_data); /* Since 1.4.3 */
 | 
			
		||||
@@ -244,7 +244,7 @@ radio_instance_add_response_observer(
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_response_observer_with_priority(
 | 
			
		||||
    RadioInstance* radio,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_RESP code,
 | 
			
		||||
    RadioResponseObserverFunc func,
 | 
			
		||||
    gpointer user_data); /* Since 1.4.3 */
 | 
			
		||||
@@ -259,7 +259,7 @@ radio_instance_add_indication_observer(
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_indication_observer_with_priority(
 | 
			
		||||
    RadioInstance* radio,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_IND code,
 | 
			
		||||
    RadioIndicationObserverFunc func,
 | 
			
		||||
    gpointer user_data); /* Since 1.4.3 */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -39,7 +39,7 @@
 | 
			
		||||
 | 
			
		||||
/* This API exists since 1.4.3 */
 | 
			
		||||
 | 
			
		||||
#include <radio_types.h>
 | 
			
		||||
#include <radio_config_types.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Basic workflow
 | 
			
		||||
@@ -70,9 +70,11 @@ typedef enum radio_tx_status {
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * RadioRequestCompleteFunc
 | 
			
		||||
 * RadioConfigRequestCompleteFunc
 | 
			
		||||
 *
 | 
			
		||||
 * Invoked upon completion of each request. If an error occurs,
 | 
			
		||||
 * resp is set to RADIO_RESP_NONE (zero) and args is NULL.
 | 
			
		||||
 * resp is set to zero (RADIO_RESP_NONE, RADIO_CONFIG_RESP_NONE)
 | 
			
		||||
 * and args is NULL.
 | 
			
		||||
 *
 | 
			
		||||
 * The status argument is the status of the request transaction.
 | 
			
		||||
 * If it's anything other than RADIO_TX_STATUS_OK, the request
 | 
			
		||||
@@ -92,6 +94,16 @@ void
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioConfigRequestCompleteFunc)(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    RADIO_CONFIG_RESP resp,
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data); /* Since 1.4.6 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * RadioRequestRetryFunc
 | 
			
		||||
 *
 | 
			
		||||
@@ -110,7 +122,7 @@ gboolean
 | 
			
		||||
(*RadioRequestRetryFunc)(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    RADIO_RESP resp,
 | 
			
		||||
    guint32 resp, /* Was RADIO_RESP before 1.4.6 */
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    void* user_data);
 | 
			
		||||
@@ -119,7 +131,7 @@ RadioRequest*
 | 
			
		||||
radio_request_new(
 | 
			
		||||
    RadioClient* client,
 | 
			
		||||
    RADIO_REQ code,
 | 
			
		||||
    GBinderWriter* writer, /* NULL if serial is the only arg */
 | 
			
		||||
    GBinderWriter* args, /* NULL if serial is the only arg */
 | 
			
		||||
    RadioRequestCompleteFunc complete,
 | 
			
		||||
    GDestroyNotify destroy,
 | 
			
		||||
    void* user_data)
 | 
			
		||||
@@ -129,12 +141,22 @@ RadioRequest*
 | 
			
		||||
radio_request_new2(
 | 
			
		||||
    RadioRequestGroup* group,
 | 
			
		||||
    RADIO_REQ code,
 | 
			
		||||
    GBinderWriter* writer, /* NULL if serial is the only arg */
 | 
			
		||||
    GBinderWriter* args, /* NULL if serial is the only arg */
 | 
			
		||||
    RadioRequestCompleteFunc complete,
 | 
			
		||||
    GDestroyNotify destroy,
 | 
			
		||||
    void* user_data)
 | 
			
		||||
    G_GNUC_WARN_UNUSED_RESULT;
 | 
			
		||||
 | 
			
		||||
RadioRequest*
 | 
			
		||||
radio_config_request_new(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    GBinderWriter* args, /* NULL if serial is the only arg */
 | 
			
		||||
    RadioConfigRequestCompleteFunc complete,
 | 
			
		||||
    GDestroyNotify destroy,
 | 
			
		||||
    void* user_data) /* Since 1.4.6 */
 | 
			
		||||
    G_GNUC_WARN_UNUSED_RESULT;
 | 
			
		||||
 | 
			
		||||
RadioRequest*
 | 
			
		||||
radio_request_ref(
 | 
			
		||||
    RadioRequest* req);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021 Open Mobile Platform LLC.
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
@@ -43,6 +43,7 @@
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct radio_client RadioClient;
 | 
			
		||||
typedef struct radio_config RadioConfig;
 | 
			
		||||
typedef struct radio_instance RadioInstance;
 | 
			
		||||
typedef struct radio_registry RadioRegistry;
 | 
			
		||||
typedef struct radio_request RadioRequest;
 | 
			
		||||
@@ -64,6 +65,12 @@ typedef enum radio_interface {
 | 
			
		||||
    RADIO_INTERFACE_COUNT
 | 
			
		||||
} RADIO_INTERFACE; /* Since 1.2.0 */
 | 
			
		||||
 | 
			
		||||
typedef enum radio_observer_priority {
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY_LOWEST,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY_DEFAULT = 2,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY_HIGHEST = 7
 | 
			
		||||
} RADIO_OBSERVER_PRIORITY; /* Since 1.4.6 */
 | 
			
		||||
 | 
			
		||||
#define RADIO_IFACE_PREFIX     "android.hardware.radio@"
 | 
			
		||||
#define RADIO_IFACE            "IRadio"
 | 
			
		||||
#define RADIO_RESPONSE_IFACE   "IRadioResponse"
 | 
			
		||||
@@ -93,6 +100,19 @@ typedef enum radio_interface {
 | 
			
		||||
 | 
			
		||||
#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_error {
 | 
			
		||||
    RADIO_ERROR_NONE = 0,
 | 
			
		||||
    RADIO_ERROR_RADIO_NOT_AVAILABLE = 1,
 | 
			
		||||
@@ -181,19 +201,6 @@ typedef enum radio_error {
 | 
			
		||||
} RADIO_ERROR; /* Since 1.4.3 */
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_ERROR) == 4);
 | 
			
		||||
 | 
			
		||||
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,
 | 
			
		||||
@@ -1221,8 +1228,6 @@ typedef struct radio_data_call_1_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 {
 | 
			
		||||
    gint32 status RADIO_ALIGNED(4);
 | 
			
		||||
    GBinderHidlString pdu RADIO_ALIGNED(8);
 | 
			
		||||
@@ -2029,6 +2034,7 @@ typedef enum radio_req {
 | 
			
		||||
    RADIO_1_4_REQ_LAST = RADIO_REQ_GET_SIGNAL_STRENGTH_1_4
 | 
			
		||||
#undef RADIO_REQ_
 | 
			
		||||
} RADIO_REQ;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_REQ) == 4);
 | 
			
		||||
 | 
			
		||||
typedef enum radio_resp {
 | 
			
		||||
    RADIO_RESP_ANY = 0,
 | 
			
		||||
@@ -2067,6 +2073,7 @@ typedef enum radio_resp {
 | 
			
		||||
    RADIO_1_4_RESP_LAST = RADIO_RESP_GET_SIGNAL_STRENGTH_1_4
 | 
			
		||||
#undef RADIO_RESP_
 | 
			
		||||
} RADIO_RESP;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_RESP) == 4);
 | 
			
		||||
 | 
			
		||||
/* These identifiers were shortened in 1.4.3 */
 | 
			
		||||
#define RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4 \
 | 
			
		||||
@@ -2109,6 +2116,11 @@ typedef enum radio_ind {
 | 
			
		||||
    RADIO_1_4_IND_LAST = RADIO_IND_CURRENT_SIGNAL_STRENGTH_1_4 /* Since 1.2.5 */
 | 
			
		||||
#undef RADIO_IND_
 | 
			
		||||
} RADIO_IND;
 | 
			
		||||
G_STATIC_ASSERT(sizeof(RADIO_IND) == 4);
 | 
			
		||||
 | 
			
		||||
/* Legacy macro. Ignore it */
 | 
			
		||||
 | 
			
		||||
#define DATA_CALL_VERSION (11)
 | 
			
		||||
 | 
			
		||||
/* Logging */
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1000
									
								
								src/radio_config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1000
									
								
								src/radio_config.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -38,7 +38,7 @@
 | 
			
		||||
 | 
			
		||||
#include "radio_instance_p.h"
 | 
			
		||||
#include "radio_registry_p.h"
 | 
			
		||||
#include "radio_util.h"
 | 
			
		||||
#include "radio_util_p.h"
 | 
			
		||||
#include "radio_log.h"
 | 
			
		||||
 | 
			
		||||
#include <gbinder.h>
 | 
			
		||||
@@ -69,22 +69,15 @@ struct radio_instance_priv {
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE(RadioInstance, radio_instance, G_TYPE_OBJECT)
 | 
			
		||||
 | 
			
		||||
G_STATIC_ASSERT(RADIO_INSTANCE_PRIORITY_LOWEST == 0);
 | 
			
		||||
G_STATIC_ASSERT(RADIO_INSTANCE_PRIORITY_HIGHEST == 7);
 | 
			
		||||
#define FOREACH_PRIORITY(p) p(0) p(1) p(2) p(3) p(4) p(5) p(6) p(7)
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY_INDEX(p) ((p) - RADIO_INSTANCE_PRIORITY_LOWEST)
 | 
			
		||||
#define RADIO_INSTANCE_PRIORITY_COUNT \
 | 
			
		||||
    (RADIO_INSTANCE_PRIORITY_INDEX(RADIO_INSTANCE_PRIORITY_HIGHEST) + 1)
 | 
			
		||||
 | 
			
		||||
typedef enum radio_instance_signal {
 | 
			
		||||
    #define SIGNAL_INDEX(x) SIGNAL_OBSERVE_REQUEST_##x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    #undef SIGNAL_INDEX
 | 
			
		||||
    #define SIGNAL_INDEX(x) SIGNAL_OBSERVE_RESPONSE_##x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    #undef SIGNAL_INDEX
 | 
			
		||||
    #define SIGNAL_INDEX(x) SIGNAL_OBSERVE_INDICATION_##x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_INDEX)
 | 
			
		||||
    #undef SIGNAL_INDEX
 | 
			
		||||
    SIGNAL_HANDLE_RESPONSE,
 | 
			
		||||
    SIGNAL_HANDLE_INDICATION,
 | 
			
		||||
@@ -97,21 +90,21 @@ typedef enum radio_instance_signal {
 | 
			
		||||
 | 
			
		||||
static const char* radio_instance_signal_observe_request_name[] = {
 | 
			
		||||
    #define SIGNAL_NAME(x) "radio-instance-observe-request-" #x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    #undef SIGNAL_NAME
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* radio_instance_signal_observe_response_name[] = {
 | 
			
		||||
    #define SIGNAL_NAME(x) "radio-instance-observe-response-" #x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    #undef SIGNAL_NAME
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* radio_instance_signal_observe_indication_name[] = {
 | 
			
		||||
    #define SIGNAL_NAME(x) "radio-instance-observe-indication-" #x,
 | 
			
		||||
    FOREACH_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    FOREACH_OBSERVER_PRIORITY(SIGNAL_NAME)
 | 
			
		||||
    #undef SIGNAL_NAME
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
@@ -248,20 +241,6 @@ radio_instance_resp_quark(
 | 
			
		||||
    return q;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
guint
 | 
			
		||||
radio_instance_priority_index(
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority)
 | 
			
		||||
{
 | 
			
		||||
    if (priority < RADIO_INSTANCE_PRIORITY_LOWEST) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else if (priority > RADIO_INSTANCE_PRIORITY_HIGHEST) {
 | 
			
		||||
        return RADIO_INSTANCE_PRIORITY_COUNT - 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        return priority - RADIO_INSTANCE_PRIORITY_LOWEST;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
radio_instance_notify_request_observers(
 | 
			
		||||
@@ -272,7 +251,7 @@ radio_instance_notify_request_observers(
 | 
			
		||||
    GQuark quark = 0;
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    for (i = RADIO_INSTANCE_PRIORITY_COUNT - 1; i >= 0; i--) {
 | 
			
		||||
    for (i = RADIO_OBSERVER_PRIORITY_COUNT - 1; i >= 0; i--) {
 | 
			
		||||
        guint id = radio_instance_signals[SIGNAL_OBSERVE_REQUEST_0 + i];
 | 
			
		||||
 | 
			
		||||
        if (id) {
 | 
			
		||||
@@ -309,14 +288,14 @@ radio_instance_indication(
 | 
			
		||||
            const GQuark quark = radio_instance_ind_quark(self, code);
 | 
			
		||||
            const guint* signals = radio_instance_signals +
 | 
			
		||||
                SIGNAL_OBSERVE_INDICATION_0;
 | 
			
		||||
            int p = RADIO_INSTANCE_PRIORITY_HIGHEST;
 | 
			
		||||
            int p = RADIO_OBSERVER_PRIORITY_HIGHEST;
 | 
			
		||||
            gboolean handled = FALSE;
 | 
			
		||||
 | 
			
		||||
            /* High-priority observers are notified first */
 | 
			
		||||
            for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
 | 
			
		||||
                if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
 | 
			
		||||
            for (; p > RADIO_OBSERVER_PRIORITY_DEFAULT; p--) {
 | 
			
		||||
                if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                    g_signal_emit(self, signals
 | 
			
		||||
                        [RADIO_INSTANCE_PRIORITY_INDEX(p)],
 | 
			
		||||
                        [RADIO_OBSERVER_PRIORITY_INDEX(p)],
 | 
			
		||||
                        quark, code, type, &reader);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -340,10 +319,10 @@ radio_instance_indication(
 | 
			
		||||
                quark, code, type, &reader, &handled);
 | 
			
		||||
 | 
			
		||||
            /* And then remaining observers in their priority order */
 | 
			
		||||
            for (; p >= RADIO_INSTANCE_PRIORITY_LOWEST; p--) {
 | 
			
		||||
                if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
 | 
			
		||||
            for (; p >= RADIO_OBSERVER_PRIORITY_LOWEST; p--) {
 | 
			
		||||
                if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                    g_signal_emit(self, signals
 | 
			
		||||
                        [RADIO_INSTANCE_PRIORITY_INDEX(p)],
 | 
			
		||||
                        [RADIO_OBSERVER_PRIORITY_INDEX(p)],
 | 
			
		||||
                        quark, code, type, &reader);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -402,14 +381,14 @@ radio_instance_response(
 | 
			
		||||
                const GQuark quark = radio_instance_resp_quark(self, code);
 | 
			
		||||
                const guint* signals = radio_instance_signals +
 | 
			
		||||
                    SIGNAL_OBSERVE_RESPONSE_0;
 | 
			
		||||
                int p = RADIO_INSTANCE_PRIORITY_HIGHEST;
 | 
			
		||||
                int p = RADIO_OBSERVER_PRIORITY_HIGHEST;
 | 
			
		||||
                gboolean handled = FALSE;
 | 
			
		||||
 | 
			
		||||
                /* High-priority observers are notified first */
 | 
			
		||||
                for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
 | 
			
		||||
                    if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                for (; p > RADIO_OBSERVER_PRIORITY_DEFAULT; p--) {
 | 
			
		||||
                    if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                        g_signal_emit(self, signals
 | 
			
		||||
                            [RADIO_INSTANCE_PRIORITY_INDEX(p)],
 | 
			
		||||
                            [RADIO_OBSERVER_PRIORITY_INDEX(p)],
 | 
			
		||||
                            quark, code, info, &reader);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -420,10 +399,10 @@ radio_instance_response(
 | 
			
		||||
                    quark, code, info, &reader, &handled);
 | 
			
		||||
 | 
			
		||||
                /* And then remaining observers in their priority order */
 | 
			
		||||
                for (; p >= RADIO_INSTANCE_PRIORITY_LOWEST; p--) {
 | 
			
		||||
                    if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                for (; p >= RADIO_OBSERVER_PRIORITY_LOWEST; p--) {
 | 
			
		||||
                    if (signals[RADIO_OBSERVER_PRIORITY_INDEX(p)]) {
 | 
			
		||||
                        g_signal_emit(self, signals
 | 
			
		||||
                            [RADIO_INSTANCE_PRIORITY_INDEX(p)],
 | 
			
		||||
                            [RADIO_OBSERVER_PRIORITY_INDEX(p)],
 | 
			
		||||
                            quark, code, info, &reader);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -1041,19 +1020,19 @@ radio_instance_add_request_observer(
 | 
			
		||||
    gpointer user_data) /* Since 1.4.3 */
 | 
			
		||||
{
 | 
			
		||||
    return radio_instance_add_request_observer_with_priority(self,
 | 
			
		||||
        RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_request_observer_with_priority(
 | 
			
		||||
    RadioInstance* self,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_REQ code,
 | 
			
		||||
    RadioRequestObserverFunc func,
 | 
			
		||||
    gpointer user_data) /* Since 1.4.3 */
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self) && G_LIKELY(func)) {
 | 
			
		||||
        const guint index = radio_instance_priority_index(priority);
 | 
			
		||||
        const guint index = radio_observer_priority_index(priority);
 | 
			
		||||
        const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_REQUEST_0 + index;
 | 
			
		||||
 | 
			
		||||
        /* Register signal on demand */
 | 
			
		||||
@@ -1082,19 +1061,19 @@ radio_instance_add_response_observer(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    return radio_instance_add_response_observer_with_priority(self,
 | 
			
		||||
        RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_response_observer_with_priority(
 | 
			
		||||
    RadioInstance* self,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_RESP code,
 | 
			
		||||
    RadioResponseObserverFunc func,
 | 
			
		||||
    gpointer user_data) /* Since 1.4.3 */
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self) && G_LIKELY(func)) {
 | 
			
		||||
        const guint index = radio_instance_priority_index(priority);
 | 
			
		||||
        const guint index = radio_observer_priority_index(priority);
 | 
			
		||||
        const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_RESPONSE_0 + index;
 | 
			
		||||
 | 
			
		||||
        /* Register signal on demand */
 | 
			
		||||
@@ -1123,19 +1102,19 @@ radio_instance_add_indication_observer(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    return radio_instance_add_indication_observer_with_priority(self,
 | 
			
		||||
        RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_DEFAULT, code, func, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gulong
 | 
			
		||||
radio_instance_add_indication_observer_with_priority(
 | 
			
		||||
    RadioInstance* self,
 | 
			
		||||
    RADIO_INSTANCE_PRIORITY priority,
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority,
 | 
			
		||||
    RADIO_IND code,
 | 
			
		||||
    RadioIndicationObserverFunc func,
 | 
			
		||||
    gpointer user_data) /* Since 1.4.3 */
 | 
			
		||||
{
 | 
			
		||||
    if (G_LIKELY(self) && G_LIKELY(func)) {
 | 
			
		||||
        const guint index = radio_instance_priority_index(priority);
 | 
			
		||||
        const guint index = radio_observer_priority_index(priority);
 | 
			
		||||
        const RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_INDICATION_0 + index;
 | 
			
		||||
 | 
			
		||||
        /* Register signal on demand */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -134,7 +134,7 @@ radio_request_object_new(
 | 
			
		||||
    RadioRequestGroup* group,
 | 
			
		||||
    RADIO_REQ code,
 | 
			
		||||
    GBinderWriter* writer,
 | 
			
		||||
    RadioRequestCompleteFunc complete,
 | 
			
		||||
    RadioRequestGenericCompleteFunc complete,
 | 
			
		||||
    GDestroyNotify destroy,
 | 
			
		||||
    void* user_data)
 | 
			
		||||
{
 | 
			
		||||
@@ -201,7 +201,8 @@ radio_request_new(
 | 
			
		||||
    void* user_data)
 | 
			
		||||
{
 | 
			
		||||
    return client ? radio_request_object_new(RADIO_BASE(client), NULL,
 | 
			
		||||
        code, writer, complete, destroy, user_data) : NULL;
 | 
			
		||||
        code, writer, (RadioRequestGenericCompleteFunc) complete,
 | 
			
		||||
        destroy, user_data) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RadioRequest*
 | 
			
		||||
@@ -214,7 +215,22 @@ radio_request_new2(
 | 
			
		||||
    void* user_data)
 | 
			
		||||
{
 | 
			
		||||
    return group ? radio_request_object_new(RADIO_BASE(group->client), group,
 | 
			
		||||
        code, writer, complete, destroy, user_data) : NULL;
 | 
			
		||||
        code, writer, (RadioRequestGenericCompleteFunc) complete,
 | 
			
		||||
        destroy, user_data) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RadioRequest*
 | 
			
		||||
radio_config_request_new(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    GBinderWriter* writer, /* NULL if serial is the only arg */
 | 
			
		||||
    RadioConfigRequestCompleteFunc complete,
 | 
			
		||||
    GDestroyNotify destroy,
 | 
			
		||||
    void* user_data) /* Since 1.4.6 */
 | 
			
		||||
{
 | 
			
		||||
    return config ? radio_request_object_new(RADIO_BASE(config), NULL,
 | 
			
		||||
        code, writer, (RadioRequestGenericCompleteFunc) complete,
 | 
			
		||||
        destroy, user_data) : NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RadioRequest*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -107,11 +107,21 @@ typedef enum radio_request_state {
 | 
			
		||||
    RADIO_REQUEST_STATE_DONE
 | 
			
		||||
} RADIO_REQUEST_STATE;
 | 
			
		||||
 | 
			
		||||
typedef
 | 
			
		||||
void
 | 
			
		||||
(*RadioRequestGenericCompleteFunc)(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    guint32 resp,
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
struct radio_request {
 | 
			
		||||
    RADIO_REQUEST_STATE state;
 | 
			
		||||
    RADIO_REQ code;
 | 
			
		||||
    guint32 code;
 | 
			
		||||
    GBinderLocalRequest* args;
 | 
			
		||||
    RadioRequestCompleteFunc complete;
 | 
			
		||||
    RadioRequestGenericCompleteFunc complete;
 | 
			
		||||
    RadioRequestRetryFunc retry;
 | 
			
		||||
    void* user_data;
 | 
			
		||||
    guint32 serial;             /* Immutable, generated at creation time */
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -46,6 +46,14 @@ typedef struct radio_base RadioBase;
 | 
			
		||||
/* Miliseconds to microseconds */
 | 
			
		||||
#define MICROSEC(ms) (((gint64)(ms)) * 1000)
 | 
			
		||||
 | 
			
		||||
/* Preprocessor magic related to observers */
 | 
			
		||||
G_STATIC_ASSERT(RADIO_OBSERVER_PRIORITY_LOWEST == 0);
 | 
			
		||||
G_STATIC_ASSERT(RADIO_OBSERVER_PRIORITY_HIGHEST == 7);
 | 
			
		||||
#define FOREACH_OBSERVER_PRIORITY(p) p(0) p(1) p(2) p(3) p(4) p(5) p(6) p(7)
 | 
			
		||||
#define RADIO_OBSERVER_PRIORITY_INDEX(p) ((p) - RADIO_OBSERVER_PRIORITY_LOWEST)
 | 
			
		||||
#define RADIO_OBSERVER_PRIORITY_COUNT \
 | 
			
		||||
    (RADIO_OBSERVER_PRIORITY_INDEX(RADIO_OBSERVER_PRIORITY_HIGHEST) + 1)
 | 
			
		||||
 | 
			
		||||
#endif /* RADIO_TYPES_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
@@ -34,11 +34,24 @@
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "radio_util.h"
 | 
			
		||||
#include "radio_util_p.h"
 | 
			
		||||
#include "radio_log.h"
 | 
			
		||||
 | 
			
		||||
GLOG_MODULE_DEFINE("gbinder-radio");
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
radio_observer_priority_index(
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority)
 | 
			
		||||
{
 | 
			
		||||
    if (priority < RADIO_OBSERVER_PRIORITY_LOWEST) {
 | 
			
		||||
        return 0;
 | 
			
		||||
    } else if (priority > RADIO_OBSERVER_PRIORITY_HIGHEST) {
 | 
			
		||||
        return RADIO_OBSERVER_PRIORITY_COUNT - 1;
 | 
			
		||||
    } else {
 | 
			
		||||
        return priority - RADIO_OBSERVER_PRIORITY_LOWEST;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const char*
 | 
			
		||||
radio_req_name(
 | 
			
		||||
    RADIO_REQ req)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										56
									
								
								src/radio_util_p.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/radio_util_p.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef RADIO_UTIL_PRIVATE_H
 | 
			
		||||
#define RADIO_UTIL_PRIVATE_H
 | 
			
		||||
 | 
			
		||||
#include "radio_types_p.h"
 | 
			
		||||
#include "radio_util.h"
 | 
			
		||||
 | 
			
		||||
guint
 | 
			
		||||
radio_observer_priority_index(
 | 
			
		||||
    RADIO_OBSERVER_PRIORITY priority)
 | 
			
		||||
    RADIO_INTERNAL;
 | 
			
		||||
 | 
			
		||||
#endif /* RADIO_UTIL_PRIVATE_H */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
all:
 | 
			
		||||
%:
 | 
			
		||||
	@$(MAKE) -C unit_client $*
 | 
			
		||||
	@$(MAKE) -C unit_config $*
 | 
			
		||||
	@$(MAKE) -C unit_instance $*
 | 
			
		||||
	@$(MAKE) -C unit_registry $*
 | 
			
		||||
	@$(MAKE) -C unit_util $*
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2018-2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2018-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2018-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@
 | 
			
		||||
 | 
			
		||||
TESTS="\
 | 
			
		||||
unit_client \
 | 
			
		||||
unit_config \
 | 
			
		||||
unit_instance \
 | 
			
		||||
unit_registry \
 | 
			
		||||
unit_util"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2021 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 * Copyright (C) 2021-2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2021-2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								unit/unit_config/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								unit/unit_config/Makefile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# -*- Mode: makefile-gmake -*-
 | 
			
		||||
 | 
			
		||||
EXE = unit_config
 | 
			
		||||
 | 
			
		||||
include ../common/Makefile
 | 
			
		||||
							
								
								
									
										915
									
								
								unit/unit_config/unit_config.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										915
									
								
								unit/unit_config/unit_config.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,915 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2022 Jolla Ltd.
 | 
			
		||||
 * Copyright (C) 2022 Slava Monich <slava.monich@jolla.com>
 | 
			
		||||
 *
 | 
			
		||||
 * You may use this file under the terms of the BSD license as follows:
 | 
			
		||||
 *
 | 
			
		||||
 * Redistribution and use in source and binary forms, with or without
 | 
			
		||||
 * modification, are permitted provided that the following conditions
 | 
			
		||||
 * are met:
 | 
			
		||||
 *
 | 
			
		||||
 *   1. Redistributions of source code must retain the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer.
 | 
			
		||||
 *   2. Redistributions in binary form must reproduce the above copyright
 | 
			
		||||
 *      notice, this list of conditions and the following disclaimer in the
 | 
			
		||||
 *      documentation and/or other materials provided with the distribution.
 | 
			
		||||
 *   3. Neither the names of the copyright holders nor the names of its
 | 
			
		||||
 *      contributors may be used to endorse or promote products derived
 | 
			
		||||
 *      from this software without specific prior written permission.
 | 
			
		||||
 *
 | 
			
		||||
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | 
			
		||||
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | 
			
		||||
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | 
			
		||||
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
 | 
			
		||||
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | 
			
		||||
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | 
			
		||||
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | 
			
		||||
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | 
			
		||||
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | 
			
		||||
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 | 
			
		||||
 * THE POSSIBILITY OF SUCH DAMAGE.
 | 
			
		||||
 *
 | 
			
		||||
 * The views and conclusions contained in the software and documentation
 | 
			
		||||
 * are those of the authors and should not be interpreted as representing
 | 
			
		||||
 * any official policies, either expressed or implied.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "test_common.h"
 | 
			
		||||
#include "test_gbinder.h"
 | 
			
		||||
 | 
			
		||||
#include "radio_config.h"
 | 
			
		||||
#include "radio_request_p.h"
 | 
			
		||||
 | 
			
		||||
#include <gutil_strv.h>
 | 
			
		||||
#include <gutil_log.h>
 | 
			
		||||
 | 
			
		||||
#define DEV GBINDER_DEFAULT_HWBINDER
 | 
			
		||||
 | 
			
		||||
static TestOpt test_opt;
 | 
			
		||||
 | 
			
		||||
static const GBinderClientIfaceInfo radio_config_ind_iface_info[] = {
 | 
			
		||||
    {RADIO_CONFIG_INDICATION_1_0, RADIO_CONFIG_1_0_IND_LAST }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const GBinderClientIfaceInfo radio_config_resp_iface_info[] = {
 | 
			
		||||
    {RADIO_CONFIG_RESPONSE_1_1, RADIO_CONFIG_1_1_RESP_LAST },
 | 
			
		||||
    {RADIO_CONFIG_RESPONSE_1_0, RADIO_CONFIG_1_0_RESP_LAST }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* const radio_config_req_ifaces[] = {
 | 
			
		||||
    RADIO_CONFIG_1_1,
 | 
			
		||||
    RADIO_CONFIG_1_0,
 | 
			
		||||
    NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const char* const radio_config_fqnames[] = {
 | 
			
		||||
    RADIO_CONFIG_1_0_FQNAME,
 | 
			
		||||
    RADIO_CONFIG_1_1_FQNAME
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_complete_not_reached(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    RADIO_CONFIG_RESP resp,
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* reader,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    g_assert_not_reached();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_destroy_once(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    gboolean* destroyed = user_data;
 | 
			
		||||
 | 
			
		||||
    g_assert(!*destroyed);
 | 
			
		||||
    *destroyed = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_ind_not_reached(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    g_assert_not_reached();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_inc_cb(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    (*((int*)user_data))++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_inc_cb(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    (*((int*)user_data))++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
RADIO_CONFIG_RESP
 | 
			
		||||
test_config_req_resp(
 | 
			
		||||
    RADIO_CONFIG_REQ req)
 | 
			
		||||
{
 | 
			
		||||
    switch (req) {
 | 
			
		||||
#define REQ_RESP_(req,resp,Name,NAME) \
 | 
			
		||||
    case RADIO_CONFIG_REQ_##NAME: return RADIO_CONFIG_RESP_##NAME;
 | 
			
		||||
    RADIO_CONFIG_CALL_1_0(REQ_RESP_)
 | 
			
		||||
    RADIO_CONFIG_CALL_1_1(REQ_RESP_)
 | 
			
		||||
#undef REQ_RESP_
 | 
			
		||||
    case RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS:
 | 
			
		||||
        return RADIO_CONFIG_RESP_NONE;
 | 
			
		||||
    case RADIO_CONFIG_REQ_ANY:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    g_assert_not_reached();
 | 
			
		||||
    return RADIO_CONFIG_RESP_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Test IRadioConfig service
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_config_service {
 | 
			
		||||
    GBinderLocalObject* obj;
 | 
			
		||||
    GBinderClient* resp_client;
 | 
			
		||||
    GBinderClient* ind_client;
 | 
			
		||||
    GHashTable* req_count;
 | 
			
		||||
} TestConfigService;
 | 
			
		||||
 | 
			
		||||
#define FAIL_REQ RADIO_CONFIG_REQ_GET_PHONE_CAPABILITY
 | 
			
		||||
#define ERROR_REQ RADIO_CONFIG_REQ_SET_SIM_SLOTS_MAPPING
 | 
			
		||||
#define ERROR_RESP RADIO_CONFIG_RESP_SET_SIM_SLOTS_MAPPING
 | 
			
		||||
#define IGNORE_REQ RADIO_CONFIG_REQ_SET_MODEMS_CONFIG
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
int
 | 
			
		||||
test_config_service_req_count(
 | 
			
		||||
    TestConfigService* service,
 | 
			
		||||
    RADIO_CONFIG_REQ req)
 | 
			
		||||
{
 | 
			
		||||
    return GPOINTER_TO_INT(g_hash_table_lookup(service->req_count,
 | 
			
		||||
        GINT_TO_POINTER(req)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
GBinderLocalReply*
 | 
			
		||||
test_config_service_txproc(
 | 
			
		||||
    GBinderLocalObject* obj,
 | 
			
		||||
    GBinderRemoteRequest* req,
 | 
			
		||||
    guint code,
 | 
			
		||||
    guint flags,
 | 
			
		||||
    int* status,
 | 
			
		||||
    void* user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestConfigService* service = user_data;
 | 
			
		||||
    const char* iface = gbinder_remote_request_interface(req);
 | 
			
		||||
 | 
			
		||||
    if (gutil_strv_contains((const GStrV*)radio_config_req_ifaces, iface)) {
 | 
			
		||||
        const int count = test_config_service_req_count(service, code) + 1;
 | 
			
		||||
        GBinderReader reader;
 | 
			
		||||
 | 
			
		||||
        GDEBUG("%s %s %d", iface, radio_config_req_name(NULL, code), count);
 | 
			
		||||
        g_hash_table_insert(service->req_count, GINT_TO_POINTER(code),
 | 
			
		||||
            GINT_TO_POINTER(count));
 | 
			
		||||
 | 
			
		||||
        gbinder_remote_request_init_reader(req, &reader);
 | 
			
		||||
        if (code == RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS) {
 | 
			
		||||
            GBinderRemoteObject* resp_obj = gbinder_reader_read_object(&reader);
 | 
			
		||||
            GBinderRemoteObject* ind_obj = gbinder_reader_read_object(&reader);
 | 
			
		||||
 | 
			
		||||
            g_assert(resp_obj);
 | 
			
		||||
            g_assert(ind_obj);
 | 
			
		||||
            gbinder_client_unref(service->resp_client);
 | 
			
		||||
            gbinder_client_unref(service->ind_client);
 | 
			
		||||
            service->resp_client = gbinder_client_new2(resp_obj,
 | 
			
		||||
                TEST_ARRAY_AND_COUNT(radio_config_resp_iface_info));
 | 
			
		||||
            service->ind_client = gbinder_client_new2(ind_obj,
 | 
			
		||||
                TEST_ARRAY_AND_COUNT(radio_config_ind_iface_info));
 | 
			
		||||
            gbinder_remote_object_unref(resp_obj);
 | 
			
		||||
            gbinder_remote_object_unref(ind_obj);
 | 
			
		||||
        } else if (code == FAIL_REQ) {
 | 
			
		||||
            GDEBUG("failing request transaction");
 | 
			
		||||
            *status = GBINDER_STATUS_FAILED;
 | 
			
		||||
            return NULL;
 | 
			
		||||
        } else if (code == IGNORE_REQ) {
 | 
			
		||||
            GDEBUG("ignoring request transaction");
 | 
			
		||||
        } else {
 | 
			
		||||
            RadioResponseInfo info;
 | 
			
		||||
            GBinderWriter writer;
 | 
			
		||||
            RADIO_CONFIG_RESP resp_code = test_config_req_resp(code);
 | 
			
		||||
            GBinderLocalRequest* resp = gbinder_client_new_request2
 | 
			
		||||
                (service->resp_client, resp_code);
 | 
			
		||||
 | 
			
		||||
            memset(&info, 0, sizeof(info));
 | 
			
		||||
            info.type = RADIO_RESP_SOLICITED;
 | 
			
		||||
            info.error = (code == ERROR_REQ) ?
 | 
			
		||||
                RADIO_ERROR_GENERIC_FAILURE :
 | 
			
		||||
                RADIO_ERROR_NONE;
 | 
			
		||||
            g_assert(gbinder_reader_read_uint32(&reader, &info.serial));
 | 
			
		||||
            GDEBUG("serial %08x", info.serial);
 | 
			
		||||
 | 
			
		||||
            g_assert(resp);
 | 
			
		||||
            gbinder_local_request_init_writer(resp, &writer);
 | 
			
		||||
            gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
 | 
			
		||||
 | 
			
		||||
            switch (code) {
 | 
			
		||||
            case RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM:
 | 
			
		||||
                g_assert(gbinder_client_transact(service->resp_client,
 | 
			
		||||
                    resp_code, GBINDER_TX_FLAG_ONEWAY, resp, NULL, NULL, NULL));
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                /* No expecting anything else */
 | 
			
		||||
                g_assert_not_reached();
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            gbinder_local_request_unref(resp);
 | 
			
		||||
        }
 | 
			
		||||
        *status = GBINDER_STATUS_OK;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    } else {
 | 
			
		||||
        GDEBUG("%s %u", iface, code);
 | 
			
		||||
        *status = GBINDER_STATUS_FAILED;
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_service_init(
 | 
			
		||||
    TestConfigService* service)
 | 
			
		||||
{
 | 
			
		||||
    memset(service, 0, sizeof(*service));
 | 
			
		||||
    service->obj = test_gbinder_local_object_new(NULL,
 | 
			
		||||
        test_config_service_txproc, service);
 | 
			
		||||
    service->req_count = g_hash_table_new(g_direct_hash, g_direct_equal);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_config_service_cleanup(
 | 
			
		||||
    TestConfigService* service)
 | 
			
		||||
{
 | 
			
		||||
    g_hash_table_destroy(service->req_count);
 | 
			
		||||
    gbinder_client_unref(service->resp_client);
 | 
			
		||||
    gbinder_client_unref(service->ind_client);
 | 
			
		||||
    gbinder_local_object_unref(service->obj);
 | 
			
		||||
    memset(service, 0, sizeof(*service));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common setup for all tests
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_common {
 | 
			
		||||
    TestConfigService service;
 | 
			
		||||
    GBinderServiceManager* sm;
 | 
			
		||||
    GBinderRemoteObject* remote[RADIO_CONFIG_INTERFACE_COUNT];
 | 
			
		||||
    RadioConfig* client;
 | 
			
		||||
} TestCommon;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
RadioConfig*
 | 
			
		||||
test_common_init(
 | 
			
		||||
    TestCommon* test,
 | 
			
		||||
    RADIO_CONFIG_INTERFACE version)
 | 
			
		||||
{
 | 
			
		||||
    RADIO_CONFIG_INTERFACE v;
 | 
			
		||||
 | 
			
		||||
    memset(test, 0, sizeof(*test));
 | 
			
		||||
    test->sm = gbinder_servicemanager_new(DEV);
 | 
			
		||||
    test_config_service_init(&test->service);
 | 
			
		||||
    for (v = RADIO_CONFIG_INTERFACE_1_0; v <= version; v++) {
 | 
			
		||||
        test->remote[v] = test_gbinder_servicemanager_new_service(test->sm,
 | 
			
		||||
            radio_config_fqnames[v], test->service.obj);
 | 
			
		||||
    }
 | 
			
		||||
    test->client = radio_config_new();
 | 
			
		||||
    g_assert(test->client);
 | 
			
		||||
    return test->client;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_common_cleanup(
 | 
			
		||||
    TestCommon* test)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
 | 
			
		||||
    radio_config_unref(test->client);
 | 
			
		||||
    test_config_service_cleanup(&test->service);
 | 
			
		||||
    for (i = 0; i < G_N_ELEMENTS(test->remote); i++) {
 | 
			
		||||
        gbinder_remote_object_unref(test->remote[i]);
 | 
			
		||||
    }
 | 
			
		||||
    gbinder_servicemanager_unref(test->sm);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Another common setup
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_simple_data {
 | 
			
		||||
    TestCommon common;
 | 
			
		||||
    GMainLoop* loop;
 | 
			
		||||
    int completed; /* Typically used as a boolean */
 | 
			
		||||
    int destroyed; /* Typically used as a boolean */
 | 
			
		||||
} TestSimple;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
RadioConfig*
 | 
			
		||||
test_simple_init(
 | 
			
		||||
    TestSimple* test)
 | 
			
		||||
{
 | 
			
		||||
    memset(test, 0, sizeof(*test));
 | 
			
		||||
    test->loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
    return test_common_init(&test->common, RADIO_CONFIG_INTERFACE_1_1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_simple_cleanup(
 | 
			
		||||
    TestSimple* test)
 | 
			
		||||
{
 | 
			
		||||
    g_main_loop_unref(test->loop);
 | 
			
		||||
    test_common_cleanup(&test->common);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_simple_destroy_cb(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple* test = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("done");
 | 
			
		||||
    g_assert(test->completed);
 | 
			
		||||
    g_assert(!test->destroyed);
 | 
			
		||||
    test->destroyed = TRUE;
 | 
			
		||||
    test_quit_later(test->loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * null
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_null(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    g_assert(!radio_config_ref(NULL));
 | 
			
		||||
    g_assert(radio_config_dead(NULL));
 | 
			
		||||
    g_assert_cmpint(radio_config_interface(NULL),==,RADIO_CONFIG_INTERFACE_NONE);
 | 
			
		||||
    g_assert(!radio_config_rpc_header_size(NULL, RADIO_CONFIG_REQ_NONE));
 | 
			
		||||
    g_assert(!radio_config_req_name(NULL, RADIO_CONFIG_REQ_NONE));
 | 
			
		||||
    g_assert(!radio_config_resp_name(NULL, RADIO_CONFIG_RESP_NONE));
 | 
			
		||||
    g_assert(!radio_config_ind_name(NULL, RADIO_CONFIG_IND_NONE));
 | 
			
		||||
    g_assert(!radio_config_add_death_handler(NULL, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_request_observer(NULL,
 | 
			
		||||
        RADIO_CONFIG_REQ_ANY, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_request_observer_with_priority(NULL,
 | 
			
		||||
        RADIO_CONFIG_REQ_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
 | 
			
		||||
    radio_config_unref(NULL);
 | 
			
		||||
    g_assert(!radio_config_add_response_observer(NULL,
 | 
			
		||||
        RADIO_CONFIG_RESP_ANY, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_response_observer_with_priority(NULL,
 | 
			
		||||
        RADIO_CONFIG_RESP_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_indication_observer(NULL,
 | 
			
		||||
        RADIO_CONFIG_IND_ANY, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_indication_observer_with_priority(NULL,
 | 
			
		||||
        RADIO_CONFIG_IND_ANY, RADIO_OBSERVER_PRIORITY_LOWEST, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_request_new(NULL, ERROR_REQ, NULL, NULL, NULL, NULL));
 | 
			
		||||
 | 
			
		||||
    radio_config_unref(NULL);
 | 
			
		||||
    radio_config_remove_handler(NULL, 0);
 | 
			
		||||
    radio_config_remove_handlers(NULL, NULL, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * name
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_name(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestCommon test;
 | 
			
		||||
    RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_1);
 | 
			
		||||
 | 
			
		||||
    g_assert_cmpstr(radio_config_req_name(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_SET_RESPONSE_FUNCTIONS), == ,
 | 
			
		||||
        "setResponseFunctions");
 | 
			
		||||
    g_assert_cmpstr(radio_config_req_name(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_SIM_SLOTS_STATUS), == ,
 | 
			
		||||
        "getSimSlotsStatus");
 | 
			
		||||
    g_assert_cmpstr(radio_config_req_name(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_PHONE_CAPABILITY), == ,
 | 
			
		||||
        "getPhoneCapability");
 | 
			
		||||
    g_assert_cmpstr(radio_config_req_name(client,
 | 
			
		||||
        (RADIO_CONFIG_REQ)123), == ,
 | 
			
		||||
        "123");
 | 
			
		||||
 | 
			
		||||
    g_assert_cmpstr(radio_config_resp_name(client,
 | 
			
		||||
        RADIO_CONFIG_RESP_GET_SIM_SLOTS_STATUS), == ,
 | 
			
		||||
        "getSimSlotsStatusResponse");
 | 
			
		||||
    g_assert_cmpstr(radio_config_resp_name(client,
 | 
			
		||||
        RADIO_CONFIG_RESP_GET_PHONE_CAPABILITY), == ,
 | 
			
		||||
        "getPhoneCapabilityResponse");
 | 
			
		||||
    g_assert_cmpstr(radio_config_resp_name(client,
 | 
			
		||||
        (RADIO_CONFIG_RESP)1234), == ,
 | 
			
		||||
        "1234");
 | 
			
		||||
 | 
			
		||||
    g_assert_cmpstr(radio_config_ind_name(client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED), == ,
 | 
			
		||||
        "simSlotsStatusChanged");
 | 
			
		||||
    g_assert_cmpstr(radio_config_ind_name(client,
 | 
			
		||||
        (RADIO_CONFIG_IND)12345), == ,
 | 
			
		||||
        "12345");
 | 
			
		||||
 | 
			
		||||
    test_common_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * none
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_none(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    /* No service => no client */
 | 
			
		||||
    g_assert(!radio_config_new());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * basic
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_basic(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestCommon test;
 | 
			
		||||
    RADIO_CONFIG_INTERFACE version = RADIO_CONFIG_INTERFACE_1_0;
 | 
			
		||||
    RadioConfig* client = test_common_init(&test, version);
 | 
			
		||||
    RadioRequest* req;
 | 
			
		||||
    int destroyed = 0;
 | 
			
		||||
 | 
			
		||||
    g_assert(!radio_config_dead(client));
 | 
			
		||||
    g_assert(radio_config_rpc_header_size(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_SIM_SLOTS_STATUS));
 | 
			
		||||
    g_assert_cmpint(radio_config_interface(client), == ,version);
 | 
			
		||||
    g_assert(radio_config_ref(client) == client);
 | 
			
		||||
    radio_config_unref(client);
 | 
			
		||||
 | 
			
		||||
    /* Instances are reused */
 | 
			
		||||
    g_assert(radio_config_new() == client);
 | 
			
		||||
    radio_config_unref(client);
 | 
			
		||||
    g_assert(radio_config_new_with_version(version) == client);
 | 
			
		||||
    radio_config_unref(client);
 | 
			
		||||
    g_assert(radio_config_new_with_version(RADIO_CONFIG_INTERFACE_COUNT) ==
 | 
			
		||||
        client);
 | 
			
		||||
    radio_config_unref(client);
 | 
			
		||||
 | 
			
		||||
    /* Adding NULL observer is a nop */
 | 
			
		||||
    g_assert(!radio_config_add_death_handler(client, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_request_observer(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_ANY, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_response_observer(client,
 | 
			
		||||
        RADIO_CONFIG_RESP_ANY, NULL, NULL));
 | 
			
		||||
    g_assert(!radio_config_add_indication_observer(client,
 | 
			
		||||
        RADIO_CONFIG_IND_ANY, NULL, NULL));
 | 
			
		||||
 | 
			
		||||
    /* Zero handler id is tolerated */
 | 
			
		||||
    radio_config_remove_handler(client, 0);
 | 
			
		||||
 | 
			
		||||
    /* Create and destroy the request */
 | 
			
		||||
    req = radio_config_request_new(client, RADIO_CONFIG_REQ_GET_MODEMS_CONFIG,
 | 
			
		||||
        NULL, NULL, test_inc_cb, &destroyed);
 | 
			
		||||
    g_assert(req);
 | 
			
		||||
    radio_request_unref(req);
 | 
			
		||||
    g_assert(destroyed);
 | 
			
		||||
 | 
			
		||||
    test_common_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * ind
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
typedef struct test_ind_data {
 | 
			
		||||
    TestCommon common;
 | 
			
		||||
    GMainLoop* loop;
 | 
			
		||||
    RADIO_CONFIG_IND ind;
 | 
			
		||||
} TestInd;
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_ind_cb(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestInd* test = user_data;
 | 
			
		||||
 | 
			
		||||
    /* This one is invoked first */
 | 
			
		||||
    GDEBUG("first indication  %d", code);
 | 
			
		||||
    g_assert_cmpint(code, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    g_assert_cmpint(test->ind, == ,RADIO_CONFIG_IND_NONE);
 | 
			
		||||
    test->ind = code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_ind_cb2(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_IND code,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestInd* test = user_data;
 | 
			
		||||
 | 
			
		||||
    /* This one is invoked second */
 | 
			
		||||
    GDEBUG("second indication %d", code);
 | 
			
		||||
    g_assert_cmpint(test->ind, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    g_assert_cmpint(code, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    test_quit_later(test->loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_ind(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    GBinderLocalRequest* req;
 | 
			
		||||
    GBinderClient* ind_client;
 | 
			
		||||
    RadioConfig* client;
 | 
			
		||||
    TestInd test;
 | 
			
		||||
    gulong id[2];
 | 
			
		||||
 | 
			
		||||
    memset(&test, 0, sizeof(test));
 | 
			
		||||
    test.loop = g_main_loop_new(NULL, FALSE);
 | 
			
		||||
    client = test_common_init(&test.common, RADIO_CONFIG_INTERFACE_1_1);
 | 
			
		||||
    ind_client = test.common.service.ind_client;
 | 
			
		||||
 | 
			
		||||
    /* Register and unregister one listener */
 | 
			
		||||
    id[0] = radio_config_add_indication_observer(client, RADIO_CONFIG_IND_ANY,
 | 
			
		||||
        test_ind_not_reached, NULL);
 | 
			
		||||
    radio_config_remove_handler(client, id[0]);
 | 
			
		||||
 | 
			
		||||
    /* Register actual listeners */
 | 
			
		||||
    id[0] = radio_config_add_indication_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_HIGHEST,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED,
 | 
			
		||||
        test_ind_cb, &test);
 | 
			
		||||
    id[1] = radio_config_add_indication_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_DEFAULT,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED,
 | 
			
		||||
        test_ind_cb2, &test);
 | 
			
		||||
 | 
			
		||||
    /* This one will be ignored because type is missing */
 | 
			
		||||
    req = gbinder_client_new_request2(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    g_assert_cmpint(gbinder_client_transact(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
 | 
			
		||||
        req, NULL, NULL, NULL), != ,0);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    /* This one will be ignored because RADIO_IND_ACK_EXP is not expected */
 | 
			
		||||
    req = gbinder_client_new_request2(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    gbinder_local_request_append_int32(req, RADIO_IND_ACK_EXP);
 | 
			
		||||
    g_assert_cmpint(gbinder_client_transact(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
 | 
			
		||||
        req, NULL, NULL, NULL), != ,0);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    /* And this one will be handled */
 | 
			
		||||
    req = gbinder_client_new_request2(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
    gbinder_local_request_append_int32(req, RADIO_IND_UNSOLICITED);
 | 
			
		||||
    /*
 | 
			
		||||
     * RadioIndicationType should be followed by vec<SimSlotStatus> but
 | 
			
		||||
     * that's not required for the purposes of this unit test.
 | 
			
		||||
     */
 | 
			
		||||
    g_assert_cmpint(gbinder_client_transact(ind_client,
 | 
			
		||||
        RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED, GBINDER_TX_FLAG_ONEWAY,
 | 
			
		||||
        req, NULL, NULL, NULL), != ,0);
 | 
			
		||||
    gbinder_local_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    /* And wait for test_ind_cb2 to terminate the loop */
 | 
			
		||||
    test_run(&test_opt, test.loop);
 | 
			
		||||
    g_assert_cmpint(test.ind, == ,RADIO_CONFIG_IND_SIM_SLOTS_STATUS_CHANGED);
 | 
			
		||||
 | 
			
		||||
    /* Cleanup */
 | 
			
		||||
    radio_config_remove_all_handlers(client, id);
 | 
			
		||||
    g_main_loop_unref(test.loop);
 | 
			
		||||
    test_common_cleanup(&test.common);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * resp
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp_observe_req1(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    GBinderLocalRequest* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    int* observed = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("high prio observed req %d", code);
 | 
			
		||||
    g_assert(!*observed);
 | 
			
		||||
    *observed = -((int)code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp_observe_req2(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_REQ code,
 | 
			
		||||
    GBinderLocalRequest* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    int* observed = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("low prio observed req %d", code);
 | 
			
		||||
    g_assert_cmpint(*observed, == ,-((int)code));
 | 
			
		||||
    *observed = code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp_observe_resp1(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_RESP code,
 | 
			
		||||
    const RadioResponseInfo* info,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    int* observed = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("high prio observed resp %d", code);
 | 
			
		||||
    g_assert(!*observed);
 | 
			
		||||
    *observed = -((int)code);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp_observe_resp2(
 | 
			
		||||
    RadioConfig* config,
 | 
			
		||||
    RADIO_CONFIG_RESP code,
 | 
			
		||||
    const RadioResponseInfo* info,
 | 
			
		||||
    const GBinderReader* args,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    int* observed = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("low prio observed resp %d", code);
 | 
			
		||||
    g_assert_cmpint(*observed, == ,-((int)code));
 | 
			
		||||
    *observed = code;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp_complete_cb(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    RADIO_CONFIG_RESP resp,
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* reader,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple* test = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("resp %d", resp);
 | 
			
		||||
    g_assert_cmpint(status, == ,RADIO_TX_STATUS_OK);
 | 
			
		||||
    g_assert_cmpint(resp, == ,RADIO_CONFIG_RESP_SET_PREFERRED_DATA_MODEM);
 | 
			
		||||
    g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
 | 
			
		||||
    g_assert(!test->completed);
 | 
			
		||||
    g_assert(!test->destroyed);
 | 
			
		||||
    test->completed = TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_resp(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple test;
 | 
			
		||||
    RadioConfig* client = test_simple_init(&test);
 | 
			
		||||
    RadioRequest* req = radio_config_request_new(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM, NULL,
 | 
			
		||||
        test_resp_complete_cb, test_simple_destroy_cb, &test);
 | 
			
		||||
    int observed_req = 0, observed_resp = 0;
 | 
			
		||||
    gulong id[4];
 | 
			
		||||
 | 
			
		||||
    id[0] = radio_config_add_request_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_HIGHEST, RADIO_CONFIG_REQ_ANY,
 | 
			
		||||
        test_resp_observe_req1, &observed_req);
 | 
			
		||||
    id[1] = radio_config_add_request_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_LOWEST, RADIO_CONFIG_REQ_ANY,
 | 
			
		||||
        test_resp_observe_req2, &observed_req);
 | 
			
		||||
    id[2] = radio_config_add_response_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_HIGHEST, RADIO_CONFIG_RESP_ANY,
 | 
			
		||||
        test_resp_observe_resp1, &observed_resp);
 | 
			
		||||
    id[3] = radio_config_add_response_observer_with_priority(client,
 | 
			
		||||
        RADIO_OBSERVER_PRIORITY_LOWEST, RADIO_CONFIG_RESP_ANY,
 | 
			
		||||
        test_resp_observe_resp2, &observed_resp);
 | 
			
		||||
 | 
			
		||||
    g_assert(radio_request_submit(req));
 | 
			
		||||
    radio_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    test_run(&test_opt, test.loop);
 | 
			
		||||
 | 
			
		||||
    g_assert(test.completed);
 | 
			
		||||
    g_assert(test.destroyed);
 | 
			
		||||
    g_assert_cmpint(observed_req,==,RADIO_CONFIG_REQ_SET_PREFERRED_DATA_MODEM);
 | 
			
		||||
    g_assert_cmpint(observed_resp,==,RADIO_CONFIG_RESP_SET_PREFERRED_DATA_MODEM);
 | 
			
		||||
 | 
			
		||||
    /* Cleanup */
 | 
			
		||||
    radio_config_remove_all_handlers(client, id);
 | 
			
		||||
    test_simple_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * cancel
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_cancel(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestCommon test;
 | 
			
		||||
    gboolean destroyed = FALSE;
 | 
			
		||||
    RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_0);
 | 
			
		||||
    RadioRequest* req = radio_config_request_new(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
 | 
			
		||||
        test_complete_not_reached, test_destroy_once, &destroyed);
 | 
			
		||||
 | 
			
		||||
    g_assert(radio_request_submit(req));
 | 
			
		||||
    radio_request_cancel(req);
 | 
			
		||||
    g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_CANCELLED);
 | 
			
		||||
    radio_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    g_assert(destroyed);
 | 
			
		||||
    test_common_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * fail_tx
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_fail_tx(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestCommon test;
 | 
			
		||||
    gboolean destroyed = FALSE;
 | 
			
		||||
    RadioConfig* client = test_common_init(&test, RADIO_CONFIG_INTERFACE_1_0);
 | 
			
		||||
    RadioRequest* req = radio_config_request_new(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
 | 
			
		||||
        test_complete_not_reached, test_destroy_once, &destroyed);
 | 
			
		||||
 | 
			
		||||
    g_assert(req);
 | 
			
		||||
    g_assert(req->serial);
 | 
			
		||||
 | 
			
		||||
    /* Fail one transaction */
 | 
			
		||||
    test_gbinder_client_tx_fail_count = 1;
 | 
			
		||||
 | 
			
		||||
    /* Request switches in the FAILED state */
 | 
			
		||||
    g_assert(req);
 | 
			
		||||
    g_assert(!radio_request_submit(req));
 | 
			
		||||
    g_assert_cmpint(req->state, == ,RADIO_REQUEST_STATE_FAILED);
 | 
			
		||||
 | 
			
		||||
    g_assert(!destroyed);
 | 
			
		||||
    radio_request_drop(req);
 | 
			
		||||
    g_assert(destroyed);
 | 
			
		||||
 | 
			
		||||
    test_common_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * death
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_death_complete_cb(
 | 
			
		||||
    RadioRequest* req,
 | 
			
		||||
    RADIO_TX_STATUS status,
 | 
			
		||||
    RADIO_CONFIG_RESP resp,
 | 
			
		||||
    RADIO_ERROR error,
 | 
			
		||||
    const GBinderReader* reader,
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple* test = user_data;
 | 
			
		||||
 | 
			
		||||
    GDEBUG("status %u", status);
 | 
			
		||||
    g_assert_cmpint(status, == ,RADIO_TX_STATUS_FAILED);
 | 
			
		||||
    g_assert_cmpint(resp, == ,RADIO_CONFIG_RESP_NONE);
 | 
			
		||||
    g_assert_cmpint(error, == ,RADIO_ERROR_NONE);
 | 
			
		||||
    test->completed++;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_death_destroy_cb(
 | 
			
		||||
    gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple* test = user_data;
 | 
			
		||||
 | 
			
		||||
    test->destroyed++;
 | 
			
		||||
    GDEBUG("done");
 | 
			
		||||
    g_assert_cmpint(test->completed, == ,test->destroyed);
 | 
			
		||||
    test_quit_later(test->loop);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static
 | 
			
		||||
void
 | 
			
		||||
test_death(
 | 
			
		||||
    void)
 | 
			
		||||
{
 | 
			
		||||
    TestSimple test;
 | 
			
		||||
    RadioConfig* client = test_simple_init(&test);
 | 
			
		||||
    RadioRequest* req = radio_config_request_new(client,
 | 
			
		||||
        RADIO_CONFIG_REQ_GET_MODEMS_CONFIG, NULL,
 | 
			
		||||
        test_death_complete_cb, test_death_destroy_cb, &test);
 | 
			
		||||
    RADIO_CONFIG_INTERFACE v;
 | 
			
		||||
    int death_count = 0;
 | 
			
		||||
    gulong id = radio_config_add_death_handler(client, test_config_inc_cb,
 | 
			
		||||
        &death_count);
 | 
			
		||||
 | 
			
		||||
    g_assert(radio_request_submit(req));
 | 
			
		||||
    radio_request_unref(req);
 | 
			
		||||
 | 
			
		||||
    /* Kill the remote objects */
 | 
			
		||||
    g_assert(!radio_config_dead(client));
 | 
			
		||||
    for (v = RADIO_CONFIG_INTERFACE_1_0;
 | 
			
		||||
         v <= radio_config_interface(client); v++) {
 | 
			
		||||
        test_gbinder_remote_object_kill(test.common.remote[v]);
 | 
			
		||||
    }
 | 
			
		||||
    g_assert(radio_config_dead(client));
 | 
			
		||||
    g_assert_cmpint(death_count, == ,1);
 | 
			
		||||
 | 
			
		||||
    /* Now expect the request to fail */
 | 
			
		||||
    test_run(&test_opt, test.loop);
 | 
			
		||||
    g_assert(test.completed);
 | 
			
		||||
    g_assert(test.destroyed);
 | 
			
		||||
 | 
			
		||||
    /* Cleanup */
 | 
			
		||||
    radio_config_remove_handler(client, id);
 | 
			
		||||
    test_simple_cleanup(&test);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*==========================================================================*
 | 
			
		||||
 * Common
 | 
			
		||||
 *==========================================================================*/
 | 
			
		||||
 | 
			
		||||
#define TEST_PREFIX "/config/"
 | 
			
		||||
#define TEST_(t) TEST_PREFIX t
 | 
			
		||||
 | 
			
		||||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
    g_test_init(&argc, &argv, NULL);
 | 
			
		||||
    g_test_add_func(TEST_("null"), test_null);
 | 
			
		||||
    g_test_add_func(TEST_("name"), test_name);
 | 
			
		||||
    g_test_add_func(TEST_("none"), test_none);
 | 
			
		||||
    g_test_add_func(TEST_("basic"), test_basic);
 | 
			
		||||
    g_test_add_func(TEST_("ind"), test_ind);
 | 
			
		||||
    g_test_add_func(TEST_("resp"), test_resp);
 | 
			
		||||
    g_test_add_func(TEST_("cancel"), test_cancel);
 | 
			
		||||
    g_test_add_func(TEST_("fail_tx"), test_fail_tx);
 | 
			
		||||
    g_test_add_func(TEST_("death"), test_death);
 | 
			
		||||
    test_init(&test_opt, argc, argv);
 | 
			
		||||
    return g_test_run();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Local Variables:
 | 
			
		||||
 * mode: C
 | 
			
		||||
 * c-basic-offset: 4
 | 
			
		||||
 * indent-tabs-mode: nil
 | 
			
		||||
 * End:
 | 
			
		||||
 */
 | 
			
		||||
		Reference in New Issue
	
	Block a user