[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