mirror of
https://github.com/mer-hybris/libgbinder-radio
synced 2025-11-04 05:45:51 +08:00
[gbinder-radio] Add RadioClient and related APIs. JB#55524
Replacement of some gint32 fields with enums may cause "warning: passing argument xxx from incompatible pointer type" or something similar at compile time but it's safe from the ABI prospective because those enums have the same size as gint32 (and that's checked at compiled time). It may, however, cause compilation errors in the projects compiled with -Werror
This commit is contained in:
3
Makefile
3
Makefile
@@ -47,8 +47,11 @@ LIB = $(LIB_NAME).a
|
||||
#
|
||||
|
||||
SRC = \
|
||||
radio_client.c \
|
||||
radio_instance.c \
|
||||
radio_registry.c \
|
||||
radio_request.c \
|
||||
radio_request_group.c \
|
||||
radio_util.c
|
||||
|
||||
#
|
||||
|
||||
2
README
Normal file
2
README
Normal file
@@ -0,0 +1,2 @@
|
||||
A library for communicating with Android IRadio binder services,
|
||||
built on top of libgbinder.
|
||||
143
include/radio_client.h
Normal file
143
include/radio_client.h
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CLIENT_H
|
||||
#define RADIO_CLIENT_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioClientIndicationFunc)(
|
||||
RadioClient* client,
|
||||
RADIO_IND code,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioClientFunc)(
|
||||
RadioClient* client,
|
||||
gpointer user_data);
|
||||
|
||||
RadioClient*
|
||||
radio_client_new(
|
||||
RadioInstance* instance)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioClient*
|
||||
radio_client_ref(
|
||||
RadioClient* client);
|
||||
|
||||
void
|
||||
radio_client_unref(
|
||||
RadioClient* client);
|
||||
|
||||
RADIO_INTERFACE
|
||||
radio_client_interface(
|
||||
RadioClient* client);
|
||||
|
||||
const char*
|
||||
radio_client_slot(
|
||||
RadioClient* client);
|
||||
|
||||
gboolean
|
||||
radio_client_dead(
|
||||
RadioClient* client);
|
||||
|
||||
gboolean
|
||||
radio_client_connected(
|
||||
RadioClient* client);
|
||||
|
||||
void
|
||||
radio_client_set_default_timeout(
|
||||
RadioClient* client,
|
||||
int milliseconds);
|
||||
|
||||
gulong
|
||||
radio_client_add_indication_handler(
|
||||
RadioClient* client,
|
||||
RADIO_IND code,
|
||||
RadioClientIndicationFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_owner_changed_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_death_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_client_add_connected_handler(
|
||||
RadioClient* client,
|
||||
RadioClientFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
radio_client_remove_handler(
|
||||
RadioClient* client,
|
||||
gulong id);
|
||||
|
||||
void
|
||||
radio_client_remove_handlers(
|
||||
RadioClient* client,
|
||||
gulong* ids,
|
||||
int count);
|
||||
|
||||
#define radio_client_remove_all_handlers(client,ids) \
|
||||
radio_client_remove_handlers(client, ids, G_N_ELEMENTS(ids))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* RADIO_CLIENT_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -45,15 +45,6 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef struct radio_instance_priv RadioInstancePriv;
|
||||
|
||||
typedef enum radio_interface {
|
||||
RADIO_INTERFACE_1_0,
|
||||
RADIO_INTERFACE_1_1,
|
||||
RADIO_INTERFACE_1_2,
|
||||
RADIO_INTERFACE_1_3,
|
||||
RADIO_INTERFACE_1_4,
|
||||
RADIO_INTERFACE_COUNT
|
||||
} RADIO_INTERFACE; /* Since 1.2.0 */
|
||||
|
||||
struct radio_instance {
|
||||
GObject parent;
|
||||
RadioInstancePriv* priv;
|
||||
@@ -67,14 +58,30 @@ struct radio_instance {
|
||||
gboolean enabled;
|
||||
/* Since 1.2.0 */
|
||||
RADIO_INTERFACE version;
|
||||
/* Since 1.4.3 */
|
||||
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 */
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioInstanceFunc)(
|
||||
RadioInstance* radio,
|
||||
gpointer user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioRequestObserverFunc)(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
typedef
|
||||
gboolean
|
||||
(*RadioResponseHandlerFunc)(
|
||||
@@ -172,6 +179,11 @@ void
|
||||
radio_instance_unref(
|
||||
RadioInstance* radio);
|
||||
|
||||
gsize
|
||||
radio_instance_rpc_header_size(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ req); /* Since 1.4.3 */
|
||||
|
||||
const char*
|
||||
radio_instance_req_name(
|
||||
RadioInstance* radio,
|
||||
@@ -208,12 +220,35 @@ radio_instance_set_enabled(
|
||||
gboolean enabled); /* Since 1.0.7 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_handler(
|
||||
radio_instance_add_request_observer(
|
||||
RadioInstance* radio,
|
||||
RADIO_IND code,
|
||||
RadioIndicationHandlerFunc func,
|
||||
RADIO_REQ code,
|
||||
RadioRequestObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_request_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_INSTANCE_PRIORITY priority,
|
||||
RADIO_REQ code,
|
||||
RadioRequestObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_INSTANCE_PRIORITY priority,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer(
|
||||
RadioInstance* radio,
|
||||
@@ -221,6 +256,14 @@ radio_instance_add_indication_observer(
|
||||
RadioIndicationObserverFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer_with_priority(
|
||||
RadioInstance* radio,
|
||||
RADIO_INSTANCE_PRIORITY priority,
|
||||
RADIO_IND code,
|
||||
RadioIndicationObserverFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_handler(
|
||||
RadioInstance* radio,
|
||||
@@ -229,10 +272,10 @@ radio_instance_add_response_handler(
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
radio_instance_add_indication_handler(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
RADIO_IND code,
|
||||
RadioIndicationHandlerFunc func,
|
||||
gpointer user_data);
|
||||
|
||||
gulong
|
||||
@@ -253,6 +296,12 @@ radio_instance_add_enabled_handler(
|
||||
RadioInstanceFunc func,
|
||||
gpointer user_data); /* Since 1.0.7 */
|
||||
|
||||
gulong
|
||||
radio_instance_add_connected_handler(
|
||||
RadioInstance* radio,
|
||||
RadioInstanceFunc func,
|
||||
gpointer user_data); /* Since 1.4.3 */
|
||||
|
||||
void
|
||||
radio_instance_remove_handler(
|
||||
RadioInstance* radio,
|
||||
|
||||
198
include/radio_request.h
Normal file
198
include/radio_request.h
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_REQUEST_H
|
||||
#define RADIO_REQUEST_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
/*
|
||||
* Basic workflow
|
||||
*
|
||||
* 1. radio_request_new() or radio_request_new2() creates the request.
|
||||
* That assigns a serial and initializes GBinderWriter for appending
|
||||
* more arguments. GBinderWriter pointer can be NULL if serial is the
|
||||
* only argument.
|
||||
* 2. The caller (optionally) uses GBinderWriter to add more arguments
|
||||
* to the request.
|
||||
* 3. radio_request_submit() submits the request
|
||||
* 4. radio_request_unref() can be called at this point to release the
|
||||
* reference produced by radio_request_new() unless the caller needs
|
||||
* to keep it. In any case, radio_request_unref() has to be called
|
||||
* sooner or later for each request created by radio_request_new().
|
||||
* The library keeps its own internal reference while the request is
|
||||
* being processed.
|
||||
* 5. RadioRequestCompleteFunc receives the response from the radio service.
|
||||
*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum radio_tx_status {
|
||||
RADIO_TX_STATUS_OK, /* Successful completion, no error */
|
||||
RADIO_TX_STATUS_FAILED, /* Request transaction failed */
|
||||
RADIO_TX_STATUS_TIMEOUT /* No response transaction received */
|
||||
} RADIO_TX_STATUS;
|
||||
|
||||
/*
|
||||
* RadioRequestCompleteFunc
|
||||
*
|
||||
* Invoked upon completion of each request. If an error occurs,
|
||||
* resp is set to RADIO_RESP_NONE (zero) 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
|
||||
* transaction failed (or response didn't arrive in time) and
|
||||
* the other arguments can be ignored.
|
||||
*
|
||||
* If status is RADIO_TX_STATUS_OK then the resp, error and args
|
||||
* arguments contain the information received in the response.
|
||||
*/
|
||||
typedef
|
||||
void
|
||||
(*RadioRequestCompleteFunc)(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
RADIO_RESP resp,
|
||||
RADIO_ERROR error,
|
||||
const GBinderReader* args,
|
||||
gpointer user_data);
|
||||
|
||||
/*
|
||||
* RadioRequestRetryFunc
|
||||
*
|
||||
* If retries are enabled with radio_request_set_retry_func(), then this
|
||||
* callback is invoiked to check whether the request should be retried,
|
||||
* based on the status received from the radio service and the contents
|
||||
* of the reply. If such callback returns TRUE, the request is retried
|
||||
* at some point in the future with a new serial, otherwise it gets
|
||||
* completed right away.
|
||||
*
|
||||
* user_data is the pointer passed to radio_request_new() when the request
|
||||
* was created.
|
||||
*/
|
||||
typedef
|
||||
gboolean
|
||||
(*RadioRequestRetryFunc)(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
RADIO_RESP resp,
|
||||
RADIO_ERROR error,
|
||||
const GBinderReader* args,
|
||||
void* user_data);
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new(
|
||||
RadioClient* client,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new2(
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioRequest*
|
||||
radio_request_ref(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_unref(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_set_blocking(
|
||||
RadioRequest* req,
|
||||
gboolean blocking);
|
||||
|
||||
void
|
||||
radio_request_set_timeout(
|
||||
RadioRequest* req,
|
||||
guint milliseconds); /* Zero to use the default timeout */
|
||||
|
||||
void
|
||||
radio_request_set_retry(
|
||||
RadioRequest* req,
|
||||
guint delay_ms, /* Delay before each retry, in milliseconds */
|
||||
int max_count); /* Negative count to keep retrying indefinitely */
|
||||
|
||||
void
|
||||
radio_request_set_retry_func(
|
||||
RadioRequest* req,
|
||||
RadioRequestRetryFunc retry);
|
||||
|
||||
gboolean
|
||||
radio_request_submit(
|
||||
RadioRequest* req);
|
||||
|
||||
gboolean
|
||||
radio_request_retry(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_cancel(
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_drop( /* cancel and unref */
|
||||
RadioRequest* req);
|
||||
|
||||
void
|
||||
radio_request_set_retry_func(
|
||||
RadioRequest* req,
|
||||
RadioRequestRetryFunc retry);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* RADIO_REQUEST_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
96
include/radio_request_group.h
Normal file
96
include/radio_request_group.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_REQUEST_GROUP_H
|
||||
#define RADIO_REQUEST_GROUP_H
|
||||
|
||||
/* This API exists since 1.4.3 */
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
/*
|
||||
* In addition to being just a group of requests and making it easier
|
||||
* to perform bulk operations (i.e. cancel all), RadioRequestGroup can
|
||||
* be given the "blocker" status by its RadioClient and then only requests
|
||||
* belonging to this group will be submitted until the block is released.
|
||||
*/
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
struct radio_request_group {
|
||||
RadioClient* client;
|
||||
};
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_new(
|
||||
RadioClient* client)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_ref(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_unref(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_cancel(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block_status(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
void
|
||||
radio_request_group_unblock(
|
||||
RadioRequestGroup* group);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* RADIO_REQUEST_GROUP_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -42,8 +42,27 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct radio_client RadioClient;
|
||||
typedef struct radio_instance RadioInstance;
|
||||
typedef struct radio_registry RadioRegistry;
|
||||
typedef struct radio_request RadioRequest;
|
||||
typedef struct radio_request_group RadioRequestGroup;
|
||||
|
||||
typedef enum radio_block_status {
|
||||
RADIO_BLOCK_NONE,
|
||||
RADIO_BLOCK_QUEUED,
|
||||
RADIO_BLOCK_ACQUIRED
|
||||
} RADIO_BLOCK; /* Since 1.4.3 */
|
||||
|
||||
typedef enum radio_interface {
|
||||
RADIO_INTERFACE_NONE = -1, /* Since 1.4.3 */
|
||||
RADIO_INTERFACE_1_0,
|
||||
RADIO_INTERFACE_1_1,
|
||||
RADIO_INTERFACE_1_2,
|
||||
RADIO_INTERFACE_1_3,
|
||||
RADIO_INTERFACE_1_4,
|
||||
RADIO_INTERFACE_COUNT
|
||||
} RADIO_INTERFACE; /* Since 1.2.0 */
|
||||
|
||||
#define RADIO_IFACE_PREFIX "android.hardware.radio@"
|
||||
#define RADIO_IFACE "IRadio"
|
||||
@@ -74,6 +93,94 @@ typedef struct radio_registry RadioRegistry;
|
||||
|
||||
#define RADIO_ALIGNED(x) __attribute__ ((aligned(x)))
|
||||
|
||||
typedef enum radio_error {
|
||||
RADIO_ERROR_NONE = 0,
|
||||
RADIO_ERROR_RADIO_NOT_AVAILABLE = 1,
|
||||
RADIO_ERROR_GENERIC_FAILURE = 2,
|
||||
RADIO_ERROR_PASSWORD_INCORRECT = 3,
|
||||
RADIO_ERROR_SIM_PIN2 = 4,
|
||||
RADIO_ERROR_SIM_PUK2 = 5,
|
||||
RADIO_ERROR_REQUEST_NOT_SUPPORTED = 6,
|
||||
RADIO_ERROR_CANCELLED = 7,
|
||||
RADIO_ERROR_OP_NOT_ALLOWED_DURING_VOICE_CALL = 8,
|
||||
RADIO_ERROR_OP_NOT_ALLOWED_BEFORE_REG_TO_NW = 9,
|
||||
RADIO_ERROR_SMS_SEND_FAIL_RETRY = 10,
|
||||
RADIO_ERROR_SIM_ABSENT = 11,
|
||||
RADIO_ERROR_SUBSCRIPTION_NOT_AVAILABLE = 12,
|
||||
RADIO_ERROR_MODE_NOT_SUPPORTED = 13,
|
||||
RADIO_ERROR_FDN_CHECK_FAILURE = 14,
|
||||
RADIO_ERROR_ILLEGAL_SIM_OR_ME = 15,
|
||||
RADIO_ERROR_MISSING_RESOURCE = 16,
|
||||
RADIO_ERROR_NO_SUCH_ELEMENT = 17,
|
||||
RADIO_ERROR_DIAL_MODIFIED_TO_USSD = 18,
|
||||
RADIO_ERROR_DIAL_MODIFIED_TO_SS = 19,
|
||||
RADIO_ERROR_DIAL_MODIFIED_TO_DIAL = 20,
|
||||
RADIO_ERROR_USSD_MODIFIED_TO_DIAL = 21,
|
||||
RADIO_ERROR_USSD_MODIFIED_TO_SS = 22,
|
||||
RADIO_ERROR_USSD_MODIFIED_TO_USSD = 23,
|
||||
RADIO_ERROR_SS_MODIFIED_TO_DIAL = 24,
|
||||
RADIO_ERROR_SS_MODIFIED_TO_USSD = 25,
|
||||
RADIO_ERROR_SUBSCRIPTION_NOT_SUPPORTED = 26,
|
||||
RADIO_ERROR_SS_MODIFIED_TO_SS = 27,
|
||||
RADIO_ERROR_LCE_NOT_SUPPORTED = 36,
|
||||
RADIO_ERROR_NO_MEMORY = 37,
|
||||
RADIO_ERROR_INTERNAL_ERR = 38,
|
||||
RADIO_ERROR_SYSTEM_ERR = 39,
|
||||
RADIO_ERROR_MODEM_ERR = 40,
|
||||
RADIO_ERROR_INVALID_STATE = 41,
|
||||
RADIO_ERROR_NO_RESOURCES = 42,
|
||||
RADIO_ERROR_SIM_ERR = 43,
|
||||
RADIO_ERROR_INVALID_ARGUMENTS = 44,
|
||||
RADIO_ERROR_INVALID_SIM_STATE = 45,
|
||||
RADIO_ERROR_INVALID_MODEM_STATE = 46,
|
||||
RADIO_ERROR_INVALID_CALL_ID = 47,
|
||||
RADIO_ERROR_NO_SMS_TO_ACK = 48,
|
||||
RADIO_ERROR_NETWORK_ERR = 49,
|
||||
RADIO_ERROR_REQUEST_RATE_LIMITED = 50,
|
||||
RADIO_ERROR_SIM_BUSY = 51,
|
||||
RADIO_ERROR_SIM_FULL = 52,
|
||||
RADIO_ERROR_NETWORK_REJECT = 53,
|
||||
RADIO_ERROR_OPERATION_NOT_ALLOWED = 54,
|
||||
RADIO_ERROR_EMPTY_RECORD = 55,
|
||||
RADIO_ERROR_INVALID_SMS_FORMAT = 56,
|
||||
RADIO_ERROR_ENCODING_ERR = 57,
|
||||
RADIO_ERROR_INVALID_SMSC_ADDRESS = 58,
|
||||
RADIO_ERROR_NO_SUCH_ENTRY = 59,
|
||||
RADIO_ERROR_NETWORK_NOT_READY = 60,
|
||||
RADIO_ERROR_NOT_PROVISIONED = 61,
|
||||
RADIO_ERROR_NO_SUBSCRIPTION = 62,
|
||||
RADIO_ERROR_NO_NETWORK_FOUND = 63,
|
||||
RADIO_ERROR_DEVICE_IN_USE = 64,
|
||||
RADIO_ERROR_ABORTED = 65,
|
||||
RADIO_ERROR_INVALID_RESPONSE = 66,
|
||||
RADIO_ERROR_OEM_ERROR_1 = 501,
|
||||
RADIO_ERROR_OEM_ERROR_2 = 502,
|
||||
RADIO_ERROR_OEM_ERROR_3 = 503,
|
||||
RADIO_ERROR_OEM_ERROR_4 = 504,
|
||||
RADIO_ERROR_OEM_ERROR_5 = 505,
|
||||
RADIO_ERROR_OEM_ERROR_6 = 506,
|
||||
RADIO_ERROR_OEM_ERROR_7 = 507,
|
||||
RADIO_ERROR_OEM_ERROR_8 = 508,
|
||||
RADIO_ERROR_OEM_ERROR_9 = 509,
|
||||
RADIO_ERROR_OEM_ERROR_10 = 510,
|
||||
RADIO_ERROR_OEM_ERROR_11 = 511,
|
||||
RADIO_ERROR_OEM_ERROR_12 = 512,
|
||||
RADIO_ERROR_OEM_ERROR_13 = 513,
|
||||
RADIO_ERROR_OEM_ERROR_14 = 514,
|
||||
RADIO_ERROR_OEM_ERROR_15 = 515,
|
||||
RADIO_ERROR_OEM_ERROR_16 = 516,
|
||||
RADIO_ERROR_OEM_ERROR_17 = 517,
|
||||
RADIO_ERROR_OEM_ERROR_18 = 518,
|
||||
RADIO_ERROR_OEM_ERROR_19 = 519,
|
||||
RADIO_ERROR_OEM_ERROR_20 = 520,
|
||||
RADIO_ERROR_OEM_ERROR_21 = 521,
|
||||
RADIO_ERROR_OEM_ERROR_22 = 522,
|
||||
RADIO_ERROR_OEM_ERROR_23 = 523,
|
||||
RADIO_ERROR_OEM_ERROR_24 = 524,
|
||||
RADIO_ERROR_OEM_ERROR_25 = 525
|
||||
} 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,
|
||||
@@ -182,6 +289,7 @@ typedef enum radio_tech {
|
||||
G_STATIC_ASSERT(sizeof(RADIO_TECH) == 4);
|
||||
|
||||
typedef enum radio_access_family {
|
||||
RAF_NONE = 0, /* Since 1.4.3 */
|
||||
RAF_UNKNOWN = (1 << RADIO_TECH_UNKNOWN),
|
||||
RAF_GPRS = (1 << RADIO_TECH_GPRS),
|
||||
RAF_EDGE = (1 << RADIO_TECH_EDGE),
|
||||
@@ -402,10 +510,548 @@ typedef enum radio_scan_status {
|
||||
} RADIO_SCAN_STATUS; /* Since 1.2.5 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_SCAN_STATUS) == 4);
|
||||
|
||||
typedef enum radio_uicc_sub_act {
|
||||
RADIO_UICC_SUB_DEACTIVATE,
|
||||
RADIO_UICC_SUB_ACTIVATE
|
||||
} RADIO_UICC_SUB_ACT; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_UICC_SUB_ACT) == 4);
|
||||
|
||||
typedef enum radio_service_class {
|
||||
RADIO_SERVICE_CLASS_NONE = 0,
|
||||
RADIO_SERVICE_CLASS_VOICE = 1 << 0,
|
||||
RADIO_SERVICE_CLASS_DATA = 1 << 1,
|
||||
RADIO_SERVICE_CLASS_FAX = 1 << 2,
|
||||
RADIO_SERVICE_CLASS_SMS = 1 << 3,
|
||||
RADIO_SERVICE_CLASS_DATA_SYNC = 1 << 4,
|
||||
RADIO_SERVICE_CLASS_DATA_ASYNC = 1 << 5,
|
||||
RADIO_SERVICE_CLASS_PACKET = 1 << 6,
|
||||
RADIO_SERVICE_CLASS_PAD = 1 << 7
|
||||
} RADIO_SERVICE_CLASS; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_SERVICE_CLASS) == 4);
|
||||
|
||||
typedef enum radio_call_forward {
|
||||
RADIO_CALL_FORWARD_DISABLE,
|
||||
RADIO_CALL_FORWARD_ENABLE,
|
||||
RADIO_CALL_FORWARD_INTERROGATE,
|
||||
RADIO_CALL_FORWARD_REGISTRATION,
|
||||
RADIO_CALL_FORWARD_ERASURE
|
||||
} RADIO_CALL_FORWARD; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_CALL_FORWARD) == 4);
|
||||
|
||||
typedef enum radio_data_call_active_status {
|
||||
RADIO_DATA_CALL_INACTIVE = 0,
|
||||
RADIO_DATA_CALL_DORMANT = 1,
|
||||
RADIO_DATA_CALL_ACTIVE = 2
|
||||
} RADIO_DATA_CALL_ACTIVE_STATUS; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_DATA_CALL_ACTIVE_STATUS) == 4);
|
||||
|
||||
typedef enum radio_restricted_state {
|
||||
RADIO_RESTRICTED_STATE_NONE = 0x00,
|
||||
RADIO_RESTRICTED_STATE_CS_EMERGENCY = 0x01,
|
||||
RADIO_RESTRICTED_STATE_CS_NORMAL = 0x02,
|
||||
RADIO_RESTRICTED_STATE_CS_ALL = 0x04,
|
||||
RADIO_RESTRICTED_STATE_PS_ALL = 0x10
|
||||
} RADIO_RESTRICTED_STATE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_RESTRICTED_STATE) == 4);
|
||||
|
||||
typedef enum radio_pref_net_type {
|
||||
RADIO_PREF_NET_INVALID = -1,
|
||||
RADIO_PREF_NET_GSM_WCDMA,
|
||||
RADIO_PREF_NET_GSM_ONLY,
|
||||
RADIO_PREF_NET_WCDMA,
|
||||
RADIO_PREF_NET_GSM_WCDMA_AUTO,
|
||||
RADIO_PREF_NET_CDMA_EVDO_AUTO,
|
||||
RADIO_PREF_NET_CDMA_ONLY,
|
||||
RADIO_PREF_NET_EVDO_ONLY,
|
||||
RADIO_PREF_NET_GSM_WCDMA_CDMA_EVDO_AUTO,
|
||||
RADIO_PREF_NET_LTE_CDMA_EVDO,
|
||||
RADIO_PREF_NET_LTE_GSM_WCDMA,
|
||||
RADIO_PREF_NET_LTE_CMDA_EVDO_GSM_WCDMA,
|
||||
RADIO_PREF_NET_LTE_ONLY,
|
||||
RADIO_PREF_NET_LTE_WCDMA,
|
||||
RADIO_PREF_NET_TD_SCDMA_ONLY,
|
||||
RADIO_PREF_NET_TD_SCDMA_WCDMA,
|
||||
RADIO_PREF_NET_TD_SCDMA_LTE,
|
||||
RADIO_PREF_NET_TD_SCDMA_GSM,
|
||||
RADIO_PREF_NET_TD_SCDMA_GSM_LTE,
|
||||
RADIO_PREF_NET_TD_SCDMA_GSM_WCDMA,
|
||||
RADIO_PREF_NET_TD_SCDMA_WCDMA_LTE,
|
||||
RADIO_PREF_NET_TD_SCDMA_GSM_WCDMA_LTE,
|
||||
RADIO_PREF_NET_TD_SCDMA_GSM_WCDMA_CDMA_EVDO_AUTO,
|
||||
RADIO_PREF_NET_TD_SCDMA_LTE_CDMA_EVDO_GSM_WCDMA
|
||||
} RADIO_PREF_NET_TYPE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_PREF_NET_TYPE) == 4);
|
||||
|
||||
typedef enum radio_ussd_type {
|
||||
RADIO_USSD_NOTIFY,
|
||||
RADIO_USSD_REQUEST,
|
||||
RADIO_USSD_NW_RELEASE,
|
||||
RADIO_USSD_LOCAL_CLIENT,
|
||||
RADIO_USSD_NOT_SUPPORTED,
|
||||
RADIO_USSD_NW_TIMEOUT
|
||||
} RADIO_USSD_TYPE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_USSD_TYPE) == 4);
|
||||
|
||||
typedef enum radio_sms_ack_fail_cause {
|
||||
RADIO_SMS_ACK_FAIL_NONE = 0,
|
||||
RADIO_SMS_ACK_FAIL_MEMORY_CAPACITY_EXCEEDED = 0xD3,
|
||||
RADIO_SMS_ACK_FAIL_UNSPECIFIED_ERROR = 0XFF
|
||||
} RADIO_SMS_ACK_FAIL_CAUSE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_SMS_ACK_FAIL_CAUSE) == 4);
|
||||
|
||||
typedef enum radio_clir {
|
||||
RADIO_CLIR_DEFAULT,
|
||||
RADIO_CLIR_INVOCATION,
|
||||
RADIO_CLIR_SUPPRESSION
|
||||
} RADIO_CLIR; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_CLIR) == 4);
|
||||
|
||||
typedef enum radio_last_call_fail_cause {
|
||||
RADIO_LAST_CALL_FAIL_NONE = 0,
|
||||
RADIO_LAST_CALL_FAIL_UNOBTAINABLE_NUMBER = 1,
|
||||
RADIO_LAST_CALL_FAIL_NO_ROUTE_TO_DESTINATION = 3,
|
||||
RADIO_LAST_CALL_FAIL_CHANNEL_UNACCEPTABLE = 6,
|
||||
RADIO_LAST_CALL_FAIL_OPERATOR_DETERMINED_BARRING = 8,
|
||||
RADIO_LAST_CALL_FAIL_NORMAL = 16,
|
||||
RADIO_LAST_CALL_FAIL_BUSY = 17,
|
||||
RADIO_LAST_CALL_FAIL_NO_USER_RESPONDING = 18,
|
||||
RADIO_LAST_CALL_FAIL_NO_ANSWER_FROM_USER = 19,
|
||||
RADIO_LAST_CALL_FAIL_CALL_REJECTED = 21,
|
||||
RADIO_LAST_CALL_FAIL_NUMBER_CHANGED = 22,
|
||||
RADIO_LAST_CALL_FAIL_PREEMPTION = 25,
|
||||
RADIO_LAST_CALL_FAIL_DESTINATION_OUT_OF_ORDER = 27,
|
||||
RADIO_LAST_CALL_FAIL_INVALID_NUMBER_FORMAT = 28,
|
||||
RADIO_LAST_CALL_FAIL_FACILITY_REJECTED = 29,
|
||||
RADIO_LAST_CALL_FAIL_RESP_TO_STATUS_ENQUIRY = 30,
|
||||
RADIO_LAST_CALL_FAIL_NORMAL_UNSPECIFIED = 31,
|
||||
RADIO_LAST_CALL_FAIL_CONGESTION = 34,
|
||||
RADIO_LAST_CALL_FAIL_NETWORK_OUT_OF_ORDER = 38,
|
||||
RADIO_LAST_CALL_FAIL_TEMPORARY_FAILURE = 41,
|
||||
RADIO_LAST_CALL_FAIL_SWITCHING_EQUIPMENT_CONGESTION = 42,
|
||||
RADIO_LAST_CALL_FAIL_ACCESS_INFORMATION_DISCARDED = 43,
|
||||
RADIO_LAST_CALL_FAIL_REQUESTED_CIRCUIT_OR_CHANNEL_NOT_AVAILABLE = 44,
|
||||
RADIO_LAST_CALL_FAIL_RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47,
|
||||
RADIO_LAST_CALL_FAIL_QOS_UNAVAILABLE = 49,
|
||||
RADIO_LAST_CALL_FAIL_REQUESTED_FACILITY_NOT_SUBSCRIBED = 50,
|
||||
RADIO_LAST_CALL_FAIL_INCOMING_CALLS_BARRED_WITHIN_CUG = 55,
|
||||
RADIO_LAST_CALL_FAIL_BEARER_CAPABILITY_NOT_AUTHORIZED = 57,
|
||||
RADIO_LAST_CALL_FAIL_BEARER_CAPABILITY_UNAVAILABLE = 58,
|
||||
RADIO_LAST_CALL_FAIL_SERVICE_OPTION_NOT_AVAILABLE = 63,
|
||||
RADIO_LAST_CALL_FAIL_BEARER_SERVICE_NOT_IMPLEMENTED = 65,
|
||||
RADIO_LAST_CALL_FAIL_ACM_LIMIT_EXCEEDED = 68,
|
||||
RADIO_LAST_CALL_FAIL_REQUESTED_FACILITY_NOT_IMPLEMENTED = 69,
|
||||
RADIO_LAST_CALL_FAIL_ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70,
|
||||
RADIO_LAST_CALL_FAIL_SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79,
|
||||
RADIO_LAST_CALL_FAIL_INVALID_TRANSACTION_IDENTIFIER = 81,
|
||||
RADIO_LAST_CALL_FAIL_USER_NOT_MEMBER_OF_CUG = 87,
|
||||
RADIO_LAST_CALL_FAIL_INCOMPATIBLE_DESTINATION = 88,
|
||||
RADIO_LAST_CALL_FAIL_INVALID_TRANSIT_NW_SELECTION = 91,
|
||||
RADIO_LAST_CALL_FAIL_SEMANTICALLY_INCORRECT_MESSAGE = 95,
|
||||
RADIO_LAST_CALL_FAIL_INVALID_MANDATORY_INFORMATION = 96,
|
||||
RADIO_LAST_CALL_FAIL_MESSAGE_TYPE_NON_IMPLEMENTED = 97,
|
||||
RADIO_LAST_CALL_FAIL_MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98,
|
||||
RADIO_LAST_CALL_FAIL_INFORMATION_ELEMENT_NON_EXISTENT = 99,
|
||||
RADIO_LAST_CALL_FAIL_CONDITIONAL_IE_ERROR = 100,
|
||||
RADIO_LAST_CALL_FAIL_MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101,
|
||||
RADIO_LAST_CALL_FAIL_RECOVERY_ON_TIMER_EXPIRED = 102,
|
||||
RADIO_LAST_CALL_FAIL_PROTOCOL_ERROR_UNSPECIFIED = 111,
|
||||
RADIO_LAST_CALL_FAIL_INTERWORKING_UNSPECIFIED = 127,
|
||||
RADIO_LAST_CALL_FAIL_CALL_BARRED = 240,
|
||||
RADIO_LAST_CALL_FAIL_FDN_BLOCKED = 241,
|
||||
RADIO_LAST_CALL_FAIL_IMSI_UNKNOWN_IN_VLR = 242,
|
||||
RADIO_LAST_CALL_FAIL_IMEI_NOT_ACCEPTED = 243,
|
||||
RADIO_LAST_CALL_FAIL_DIAL_MODIFIED_TO_USSD = 244,
|
||||
RADIO_LAST_CALL_FAIL_DIAL_MODIFIED_TO_SS = 245,
|
||||
RADIO_LAST_CALL_FAIL_DIAL_MODIFIED_TO_DIAL = 246,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_OFF = 247,
|
||||
RADIO_LAST_CALL_FAIL_OUT_OF_SERVICE = 248,
|
||||
RADIO_LAST_CALL_FAIL_NO_VALID_SIM = 249,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_INTERNAL_ERROR = 250,
|
||||
RADIO_LAST_CALL_FAIL_NETWORK_RESP_TIMEOUT = 251,
|
||||
RADIO_LAST_CALL_FAIL_NETWORK_REJECT = 252,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_ACCESS_FAILURE = 253,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_LINK_FAILURE = 254,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_LINK_LOST = 255,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_UPLINK_FAILURE = 256,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_SETUP_FAILURE = 257,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_RELEASE_NORMAL = 258,
|
||||
RADIO_LAST_CALL_FAIL_RADIO_RELEASE_ABNORMAL = 259,
|
||||
RADIO_LAST_CALL_FAIL_ACCESS_CLASS_BLOCKED = 260,
|
||||
RADIO_LAST_CALL_FAIL_NETWORK_DETACH = 261,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_DROP = 1001,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_INTERCEPT = 1002,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_REORDER = 1003,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_SO_REJECT = 1004,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_RETRY_ORDER = 1005,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_ACCESS_FAILURE = 1006,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_PREEMPTED = 1007,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_NOT_EMERGENCY = 1008,
|
||||
RADIO_LAST_CALL_FAIL_CDMA_ACCESS_BLOCKED = 1009,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_1 = 0xf001,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_2 = 0xf002,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_3 = 0xf003,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_4 = 0xf004,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_5 = 0xf005,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_6 = 0xf006,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_7 = 0xf007,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_8 = 0xf008,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_9 = 0xf009,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_10 = 0xf00a,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_11 = 0xf00b,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_12 = 0xf00c,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_13 = 0xf00d,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_14 = 0xf00e,
|
||||
RADIO_LAST_CALL_FAIL_OEM_CAUSE_15 = 0xf00f,
|
||||
RADIO_LAST_CALL_FAIL_ERROR_UNSPECIFIED = 0xffff
|
||||
} RADIO_LAST_CALL_FAIL_CAUSE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_LAST_CALL_FAIL_CAUSE) == 4);
|
||||
|
||||
typedef enum radio_data_call_fail_cause {
|
||||
RADIO_DATA_CALL_FAIL_NONE = 0,
|
||||
RADIO_DATA_CALL_FAIL_OPERATOR_BARRED = 0x08,
|
||||
RADIO_DATA_CALL_FAIL_NAS_SIGNALLING = 0x0E,
|
||||
RADIO_DATA_CALL_FAIL_LLC_SNDCP = 0x19,
|
||||
RADIO_DATA_CALL_FAIL_INSUFFICIENT_RESOURCES = 0x1A,
|
||||
RADIO_DATA_CALL_FAIL_MISSING_UKNOWN_APN = 0x1B,
|
||||
RADIO_DATA_CALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE = 0x1C,
|
||||
RADIO_DATA_CALL_FAIL_USER_AUTHENTICATION = 0x1D,
|
||||
RADIO_DATA_CALL_FAIL_ACTIVATION_REJECT_GGSN = 0x1E,
|
||||
RADIO_DATA_CALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED = 0x1F,
|
||||
RADIO_DATA_CALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED = 0x20,
|
||||
RADIO_DATA_CALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21,
|
||||
RADIO_DATA_CALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22,
|
||||
RADIO_DATA_CALL_FAIL_NSAPI_IN_USE = 0x23,
|
||||
RADIO_DATA_CALL_FAIL_REGULAR_DEACTIVATION = 0x24,
|
||||
RADIO_DATA_CALL_FAIL_QOS_NOT_ACCEPTED = 0x25,
|
||||
RADIO_DATA_CALL_FAIL_NETWORK_FAILURE = 0x26,
|
||||
RADIO_DATA_CALL_FAIL_UMTS_REACTIVATION_REQ = 0x27,
|
||||
RADIO_DATA_CALL_FAIL_FEATURE_NOT_SUPP = 0x28,
|
||||
RADIO_DATA_CALL_FAIL_TFT_SEMANTIC_ERROR = 0x29,
|
||||
RADIO_DATA_CALL_FAIL_TFT_SYTAX_ERROR = 0x2A,
|
||||
RADIO_DATA_CALL_FAIL_UNKNOWN_PDP_CONTEXT = 0x2B,
|
||||
RADIO_DATA_CALL_FAIL_FILTER_SEMANTIC_ERROR = 0x2C,
|
||||
RADIO_DATA_CALL_FAIL_FILTER_SYTAX_ERROR = 0x2D,
|
||||
RADIO_DATA_CALL_FAIL_PDP_WITHOUT_ACTIVE_TFT = 0x2E,
|
||||
RADIO_DATA_CALL_FAIL_ACTIVATION_REJECTED_BCM_VIOLATION = 0x30,
|
||||
RADIO_DATA_CALL_FAIL_ONLY_IPV4_ALLOWED = 0x32,
|
||||
RADIO_DATA_CALL_FAIL_ONLY_IPV6_ALLOWED = 0x33,
|
||||
RADIO_DATA_CALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34,
|
||||
RADIO_DATA_CALL_FAIL_ESM_INFO_NOT_RECEIVED = 0x35,
|
||||
RADIO_DATA_CALL_FAIL_PDN_CONN_DOES_NOT_EXIST = 0x36,
|
||||
RADIO_DATA_CALL_FAIL_MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37,
|
||||
RADIO_DATA_CALL_FAIL_COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38,
|
||||
RADIO_DATA_CALL_FAIL_ONLY_IPV4V6_ALLOWED = 0x39,
|
||||
RADIO_DATA_CALL_FAIL_ONLY_NON_IP_ALLOWED = 0x3A,
|
||||
RADIO_DATA_CALL_FAIL_UNSUPPORTED_QCI_VALUE = 0x3B,
|
||||
RADIO_DATA_CALL_FAIL_BEARER_HANDLING_NOT_SUPPORTED = 0x3C,
|
||||
RADIO_DATA_CALL_FAIL_MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41,
|
||||
RADIO_DATA_CALL_FAIL_UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_TRANSACTION_ID = 0x51,
|
||||
RADIO_DATA_CALL_FAIL_MESSAGE_INCORRECT_SEMANTIC = 0x5F,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_MANDATORY_INFO = 0x60,
|
||||
RADIO_DATA_CALL_FAIL_MESSAGE_TYPE_UNSUPPORTED = 0x61,
|
||||
RADIO_DATA_CALL_FAIL_MSG_TYPE_NONCOMPATIBLE_STATE = 0x62,
|
||||
RADIO_DATA_CALL_FAIL_UNKNOWN_INFO_ELEMENT = 0x63,
|
||||
RADIO_DATA_CALL_FAIL_CONDITIONAL_IE_ERROR = 0x64,
|
||||
RADIO_DATA_CALL_FAIL_MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65,
|
||||
RADIO_DATA_CALL_FAIL_PROTOCOL_ERRORS = 0x6F,
|
||||
RADIO_DATA_CALL_FAIL_APN_TYPE_CONFLICT = 0x70,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_PCSCF_ADDR = 0x71,
|
||||
RADIO_DATA_CALL_FAIL_INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72,
|
||||
RADIO_DATA_CALL_FAIL_EMM_ACCESS_BARRED = 0x73,
|
||||
RADIO_DATA_CALL_FAIL_EMERGENCY_IFACE_ONLY = 0x74,
|
||||
RADIO_DATA_CALL_FAIL_IFACE_MISMATCH = 0x75,
|
||||
RADIO_DATA_CALL_FAIL_COMPANION_IFACE_IN_USE = 0x76,
|
||||
RADIO_DATA_CALL_FAIL_IP_ADDRESS_MISMATCH = 0x77,
|
||||
RADIO_DATA_CALL_FAIL_IFACE_AND_POL_FAMILY_MISMATCH = 0x78,
|
||||
RADIO_DATA_CALL_FAIL_EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79,
|
||||
RADIO_DATA_CALL_FAIL_AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_DNS_ADDR = 0x7B,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C,
|
||||
RADIO_DATA_CALL_FAIL_CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F,
|
||||
RADIO_DATA_CALL_FAIL_UE_INITIATED_DETACH_OR_DISCONNECT = 0x80,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_REASON_UNSPECIFIED = 0x7D0,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_ADMIN_PROHIBITED = 0x7D1,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MALFORMED_REQUEST = 0x7D6,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MALFORMED_REPLY = 0x7D7,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MISSING_NAI = 0x7DD,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MISSING_HOME_AGENT = 0x7DE,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MISSING_HOME_ADDRESS = 0x7DF,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_UNKNOWN_CHALLENGE = 0x7E0,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_MISSING_CHALLENGE = 0x7E1,
|
||||
RADIO_DATA_CALL_FAIL_MIP_FA_STALE_CHALLENGE = 0x7E2,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_REASON_UNSPECIFIED = 0x7E3,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_ADMIN_PROHIBITED = 0x7E4,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_MALFORMED_REQUEST = 0x7E9,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC,
|
||||
RADIO_DATA_CALL_FAIL_MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED,
|
||||
RADIO_DATA_CALL_FAIL_CLOSE_IN_PROGRESS = 0x7EE,
|
||||
RADIO_DATA_CALL_FAIL_NETWORK_INITIATED_TERMINATION = 0x7EF,
|
||||
RADIO_DATA_CALL_FAIL_MODEM_APP_PREEMPTED = 0x7F0,
|
||||
RADIO_DATA_CALL_FAIL_PDN_IPV4_CALL_DISALLOWED = 0x7F1,
|
||||
RADIO_DATA_CALL_FAIL_PDN_IPV4_CALL_THROTTLED = 0x7F2,
|
||||
RADIO_DATA_CALL_FAIL_PDN_IPV6_CALL_DISALLOWED = 0x7F3,
|
||||
RADIO_DATA_CALL_FAIL_PDN_IPV6_CALL_THROTTLED = 0x7F4,
|
||||
RADIO_DATA_CALL_FAIL_MODEM_RESTART = 0x7F5,
|
||||
RADIO_DATA_CALL_FAIL_PDP_PPP_NOT_SUPPORTED = 0x7F6,
|
||||
RADIO_DATA_CALL_FAIL_UNPREFERRED_RAT = 0x7F7,
|
||||
RADIO_DATA_CALL_FAIL_PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8,
|
||||
RADIO_DATA_CALL_FAIL_APN_PENDING_HANDOVER = 0x7F9,
|
||||
RADIO_DATA_CALL_FAIL_PROFILE_BEARER_INCOMPATIBLE = 0x7FA,
|
||||
RADIO_DATA_CALL_FAIL_SIM_CARD_CHANGED = 0x7FB,
|
||||
RADIO_DATA_CALL_FAIL_LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC,
|
||||
RADIO_DATA_CALL_FAIL_APN_DISABLED = 0x7FD,
|
||||
RADIO_DATA_CALL_FAIL_MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE,
|
||||
RADIO_DATA_CALL_FAIL_IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF,
|
||||
RADIO_DATA_CALL_FAIL_TRAT_SWAP_FAILED = 0x800,
|
||||
RADIO_DATA_CALL_FAIL_EHRPD_TO_HRPD_FALLBACK = 0x801,
|
||||
RADIO_DATA_CALL_FAIL_MIP_CONFIG_FAILURE = 0x802,
|
||||
RADIO_DATA_CALL_FAIL_PDN_INACTIVITY_TIMER_EXPIRED = 0x803,
|
||||
RADIO_DATA_CALL_FAIL_MAX_IPV4_CONNECTIONS = 0x804,
|
||||
RADIO_DATA_CALL_FAIL_MAX_IPV6_CONNECTIONS = 0x805,
|
||||
RADIO_DATA_CALL_FAIL_APN_MISMATCH = 0x806,
|
||||
RADIO_DATA_CALL_FAIL_IP_VERSION_MISMATCH = 0x807,
|
||||
RADIO_DATA_CALL_FAIL_DUN_CALL_DISALLOWED = 0x808,
|
||||
RADIO_DATA_CALL_FAIL_INTERNAL_EPC_NONEPC_TRANSITION = 0x809,
|
||||
RADIO_DATA_CALL_FAIL_INTERFACE_IN_USE = 0x80A,
|
||||
RADIO_DATA_CALL_FAIL_APN_DISALLOWED_ON_ROAMING = 0x80B,
|
||||
RADIO_DATA_CALL_FAIL_APN_PARAMETERS_CHANGED = 0x80C,
|
||||
RADIO_DATA_CALL_FAIL_NULL_APN_DISALLOWED = 0x80D,
|
||||
RADIO_DATA_CALL_FAIL_THERMAL_MITIGATION = 0x80E,
|
||||
RADIO_DATA_CALL_FAIL_DATA_SETTINGS_DISABLED = 0x80F,
|
||||
RADIO_DATA_CALL_FAIL_DATA_ROAMING_SETTINGS_DISABLED = 0x810,
|
||||
RADIO_DATA_CALL_FAIL_DDS_SWITCHED = 0x811,
|
||||
RADIO_DATA_CALL_FAIL_FORBIDDEN_APN_NAME = 0x812,
|
||||
RADIO_DATA_CALL_FAIL_DDS_SWITCH_IN_PROGRESS = 0x813,
|
||||
RADIO_DATA_CALL_FAIL_CALL_DISALLOWED_IN_ROAMING = 0x814,
|
||||
RADIO_DATA_CALL_FAIL_NON_IP_NOT_SUPPORTED = 0x815,
|
||||
RADIO_DATA_CALL_FAIL_PDN_NON_IP_CALL_THROTTLED = 0x816,
|
||||
RADIO_DATA_CALL_FAIL_PDN_NON_IP_CALL_DISALLOWED = 0x817,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_LOCK = 0x818,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_INTERCEPT = 0x819,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_REORDER = 0x81A,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_INCOMING_CALL = 0x81C,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_ALERT_STOP = 0x81D,
|
||||
RADIO_DATA_CALL_FAIL_CHANNEL_ACQUISITION_FAILURE = 0x81E,
|
||||
RADIO_DATA_CALL_FAIL_MAX_ACCESS_PROBE = 0x81F,
|
||||
RADIO_DATA_CALL_FAIL_CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STA = 0x820,
|
||||
RADIO_DATA_CALL_FAIL_NO_RESPONSE_FROM_BASE_STATION = 0x821,
|
||||
RADIO_DATA_CALL_FAIL_REJECTED_BY_BASE_STATION = 0x822,
|
||||
RADIO_DATA_CALL_FAIL_CONCURRENT_SERVICES_INCOMPATIBLE = 0x823,
|
||||
RADIO_DATA_CALL_FAIL_NO_CDMA_SERVICE = 0x824,
|
||||
RADIO_DATA_CALL_FAIL_RUIM_NOT_PRESENT = 0x825,
|
||||
RADIO_DATA_CALL_FAIL_CDMA_RETRY_ORDER = 0x826,
|
||||
RADIO_DATA_CALL_FAIL_ACCESS_BLOCK = 0x827,
|
||||
RADIO_DATA_CALL_FAIL_ACCESS_BLOCK_ALL = 0x828,
|
||||
RADIO_DATA_CALL_FAIL_IS707B_MAX_ACCESS_PROBES = 0x829,
|
||||
RADIO_DATA_CALL_FAIL_THERMAL_EMERGENCY = 0x82A,
|
||||
RADIO_DATA_CALL_FAIL_CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B,
|
||||
RADIO_DATA_CALL_FAIL_INCOMING_CALL_REJECTED = 0x82C,
|
||||
RADIO_DATA_CALL_FAIL_NO_SERVICE_ON_GATEWAY = 0x82D,
|
||||
RADIO_DATA_CALL_FAIL_NO_GPRS_CONTEXT = 0x82E,
|
||||
RADIO_DATA_CALL_FAIL_ILLEGAL_MS = 0x82F,
|
||||
RADIO_DATA_CALL_FAIL_ILLEGAL_ME = 0x830,
|
||||
RADIO_DATA_CALL_FAIL_GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831,
|
||||
RADIO_DATA_CALL_FAIL_GPRS_SERVICES_NOT_ALLOWED = 0x832,
|
||||
RADIO_DATA_CALL_FAIL_MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833,
|
||||
RADIO_DATA_CALL_FAIL_IMPLICITLY_DETACHED = 0x834,
|
||||
RADIO_DATA_CALL_FAIL_PLMN_NOT_ALLOWED = 0x835,
|
||||
RADIO_DATA_CALL_FAIL_LOCATION_AREA_NOT_ALLOWED = 0x836,
|
||||
RADIO_DATA_CALL_FAIL_GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837,
|
||||
RADIO_DATA_CALL_FAIL_PDP_DUPLICATE = 0x838,
|
||||
RADIO_DATA_CALL_FAIL_UE_RAT_CHANGE = 0x839,
|
||||
RADIO_DATA_CALL_FAIL_CONGESTION = 0x83A,
|
||||
RADIO_DATA_CALL_FAIL_NO_PDP_CONTEXT_ACTIVATED = 0x83B,
|
||||
RADIO_DATA_CALL_FAIL_ACCESS_CLASS_DSAC_REJECTION = 0x83C,
|
||||
RADIO_DATA_CALL_FAIL_PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D,
|
||||
RADIO_DATA_CALL_FAIL_RADIO_ACCESS_BEARER_FAILURE = 0x83E,
|
||||
RADIO_DATA_CALL_FAIL_ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F,
|
||||
RADIO_DATA_CALL_FAIL_DRB_RELEASED_BY_RRC = 0x840,
|
||||
RADIO_DATA_CALL_FAIL_CONNECTION_RELEASED = 0x841,
|
||||
RADIO_DATA_CALL_FAIL_EMM_DETACHED = 0x842,
|
||||
RADIO_DATA_CALL_FAIL_EMM_ATTACH_FAILED = 0x843,
|
||||
RADIO_DATA_CALL_FAIL_EMM_ATTACH_STARTED = 0x844,
|
||||
RADIO_DATA_CALL_FAIL_LTE_NAS_SERVICE_REQUEST_FAILED = 0x845,
|
||||
RADIO_DATA_CALL_FAIL_DUPLICATE_BEARER_ID = 0x846,
|
||||
RADIO_DATA_CALL_FAIL_ESM_COLLISION_SCENARIOS = 0x847,
|
||||
RADIO_DATA_CALL_FAIL_ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848,
|
||||
RADIO_DATA_CALL_FAIL_ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849,
|
||||
RADIO_DATA_CALL_FAIL_ESM_BAD_OTA_MESSAGE = 0x84A,
|
||||
RADIO_DATA_CALL_FAIL_ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B,
|
||||
RADIO_DATA_CALL_FAIL_ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C,
|
||||
RADIO_DATA_CALL_FAIL_DS_EXPLICIT_DEACTIVATION = 0x84D,
|
||||
RADIO_DATA_CALL_FAIL_ESM_LOCAL_CAUSE_NONE = 0x84E,
|
||||
RADIO_DATA_CALL_FAIL_LTE_THROTTLING_NOT_REQUIRED = 0x84F,
|
||||
RADIO_DATA_CALL_FAIL_ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850,
|
||||
RADIO_DATA_CALL_FAIL_SERVICE_NOT_ALLOWED_ON_PLMN = 0x851,
|
||||
RADIO_DATA_CALL_FAIL_EMM_T3417_EXPIRED = 0x852,
|
||||
RADIO_DATA_CALL_FAIL_EMM_T3417_EXT_EXPIRED = 0x853,
|
||||
RADIO_DATA_CALL_FAIL_RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854,
|
||||
RADIO_DATA_CALL_FAIL_RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855,
|
||||
RADIO_DATA_CALL_FAIL_RRC_UPLINK_CONNECTION_RELEASE = 0x856,
|
||||
RADIO_DATA_CALL_FAIL_RRC_UPLINK_RADIO_LINK_FAILURE = 0x857,
|
||||
RADIO_DATA_CALL_FAIL_RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_ACCESS_STRATUM_FAILURE = 0x859,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_ACCESS_BARRED = 0x85B,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_CELL_RESELECTION = 0x85C,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_CONFIG_FAILURE = 0x85D,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_TIMER_EXPIRED = 0x85E,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_LINK_FAILURE = 0x85F,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_CELL_NOT_CAMPED = 0x860,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_SYSTEM_INTERVAL_FAILURE = 0x861,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_REJECT_BY_NETWORK = 0x862,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_NORMAL_RELEASE = 0x863,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_RADIO_LINK_FAILURE = 0x864,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_REESTABLISHMENT_FAILURE = 0x865,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_ABORT_REQUEST = 0x867,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONN_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868,
|
||||
RADIO_DATA_CALL_FAIL_NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869,
|
||||
RADIO_DATA_CALL_FAIL_NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A,
|
||||
RADIO_DATA_CALL_FAIL_ESM_PROCEDURE_TIME_OUT = 0x86B,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_CONNECTION_ID = 0x86C,
|
||||
RADIO_DATA_CALL_FAIL_MAXIMIUM_NSAPIS_EXCEEDED = 0x86D,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_PRIMARY_NSAPI = 0x86E,
|
||||
RADIO_DATA_CALL_FAIL_CANNOT_ENCODE_OTA_MESSAGE = 0x86F,
|
||||
RADIO_DATA_CALL_FAIL_RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870,
|
||||
RADIO_DATA_CALL_FAIL_PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871,
|
||||
RADIO_DATA_CALL_FAIL_PDP_MODIFY_TIMEOUT_EXPIRED = 0x872,
|
||||
RADIO_DATA_CALL_FAIL_PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873,
|
||||
RADIO_DATA_CALL_FAIL_PDP_LOWERLAYER_ERROR = 0x874,
|
||||
RADIO_DATA_CALL_FAIL_PDP_MODIFY_COLLISION = 0x875,
|
||||
RADIO_DATA_CALL_FAIL_MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876,
|
||||
RADIO_DATA_CALL_FAIL_NAS_REQUEST_REJECTED_BY_NETWORK = 0x877,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_INVALID_REQUEST = 0x878,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_RF_UNAVAILABLE = 0x87A,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E,
|
||||
RADIO_DATA_CALL_FAIL_RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F,
|
||||
RADIO_DATA_CALL_FAIL_IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880,
|
||||
RADIO_DATA_CALL_FAIL_IMEI_NOT_ACCEPTED = 0x881,
|
||||
RADIO_DATA_CALL_FAIL_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882,
|
||||
RADIO_DATA_CALL_FAIL_EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883,
|
||||
RADIO_DATA_CALL_FAIL_MSC_TEMPORARILY_NOT_REACHABLE = 0x884,
|
||||
RADIO_DATA_CALL_FAIL_CS_DOMAIN_NOT_AVAILABLE = 0x885,
|
||||
RADIO_DATA_CALL_FAIL_ESM_FAILURE = 0x886,
|
||||
RADIO_DATA_CALL_FAIL_MAC_FAILURE = 0x887,
|
||||
RADIO_DATA_CALL_FAIL_SYNCHRONIZATION_FAILURE = 0x888,
|
||||
RADIO_DATA_CALL_FAIL_UE_SECURITY_CAPABILITIES_MISMATCH = 0x889,
|
||||
RADIO_DATA_CALL_FAIL_SECURITY_MODE_REJECTED = 0x88A,
|
||||
RADIO_DATA_CALL_FAIL_UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B,
|
||||
RADIO_DATA_CALL_FAIL_CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C,
|
||||
RADIO_DATA_CALL_FAIL_NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_EMM_STATE = 0x88E,
|
||||
RADIO_DATA_CALL_FAIL_NAS_LAYER_FAILURE = 0x88F,
|
||||
RADIO_DATA_CALL_FAIL_MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890,
|
||||
RADIO_DATA_CALL_FAIL_EMBMS_NOT_ENABLED = 0x891,
|
||||
RADIO_DATA_CALL_FAIL_IRAT_HANDOVER_FAILED = 0x892,
|
||||
RADIO_DATA_CALL_FAIL_EMBMS_REGULAR_DEACTIVATION = 0x893,
|
||||
RADIO_DATA_CALL_FAIL_TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894,
|
||||
RADIO_DATA_CALL_FAIL_LOWER_LAYER_REGISTRATION_FAILURE = 0x895,
|
||||
RADIO_DATA_CALL_FAIL_DATA_PLAN_EXPIRED = 0x896,
|
||||
RADIO_DATA_CALL_FAIL_UMTS_HANDOVER_TO_IWLAN = 0x897,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_CONN_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_CONN_DENY_BY_BILLING_OR_AUTH_FAILURE = 0x899,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_HDR_CHANGED = 0x89A,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_HDR_EXITED = 0x89B,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_HDR_NO_SESSION = 0x89C,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D,
|
||||
RADIO_DATA_CALL_FAIL_EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E,
|
||||
RADIO_DATA_CALL_FAIL_FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F,
|
||||
RADIO_DATA_CALL_FAIL_OTASP_COMMIT_IN_PROGRESS = 0x8A0,
|
||||
RADIO_DATA_CALL_FAIL_NO_HYBRID_HDR_SERVICE = 0x8A1,
|
||||
RADIO_DATA_CALL_FAIL_HDR_NO_LOCK_GRANTED = 0x8A2,
|
||||
RADIO_DATA_CALL_FAIL_DBM_OR_SMS_IN_PROGRESS = 0x8A3,
|
||||
RADIO_DATA_CALL_FAIL_HDR_FADE = 0x8A4,
|
||||
RADIO_DATA_CALL_FAIL_HDR_ACCESS_FAILURE = 0x8A5,
|
||||
RADIO_DATA_CALL_FAIL_UNSUPPORTED_1X_PREV = 0x8A6,
|
||||
RADIO_DATA_CALL_FAIL_LOCAL_END = 0x8A7,
|
||||
RADIO_DATA_CALL_FAIL_NO_SERVICE = 0x8A8,
|
||||
RADIO_DATA_CALL_FAIL_FADE = 0x8A9,
|
||||
RADIO_DATA_CALL_FAIL_NORMAL_RELEASE = 0x8AA,
|
||||
RADIO_DATA_CALL_FAIL_ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB,
|
||||
RADIO_DATA_CALL_FAIL_REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC,
|
||||
RADIO_DATA_CALL_FAIL_EMERGENCY_MODE = 0x8AD,
|
||||
RADIO_DATA_CALL_FAIL_PHONE_IN_USE = 0x8AE,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_MODE = 0x8AF,
|
||||
RADIO_DATA_CALL_FAIL_INVALID_SIM_STATE = 0x8B0,
|
||||
RADIO_DATA_CALL_FAIL_NO_COLLOCATED_HDR = 0x8B1,
|
||||
RADIO_DATA_CALL_FAIL_UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2,
|
||||
RADIO_DATA_CALL_FAIL_DUAL_SWITCH = 0x8B3,
|
||||
RADIO_DATA_CALL_FAIL_PPP_TIMEOUT = 0x8B4,
|
||||
RADIO_DATA_CALL_FAIL_PPP_AUTH_FAILURE = 0x8B5,
|
||||
RADIO_DATA_CALL_FAIL_PPP_OPTION_MISMATCH = 0x8B6,
|
||||
RADIO_DATA_CALL_FAIL_PPP_PAP_FAILURE = 0x8B7,
|
||||
RADIO_DATA_CALL_FAIL_PPP_CHAP_FAILURE = 0x8B8,
|
||||
RADIO_DATA_CALL_FAIL_PPP_CLOSE_IN_PROGRESS = 0x8B9,
|
||||
RADIO_DATA_CALL_FAIL_LIMITED_TO_IPV4 = 0x8BA,
|
||||
RADIO_DATA_CALL_FAIL_LIMITED_TO_IPV6 = 0x8BB,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_TIMEOUT = 0x8BC,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_GEN_ERROR = 0x8BD,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_APN_UNATHORIZED = 0x8BE,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_PDN_GATEWAY_REJECT = 0x8C2,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_RESOURCE_UNAVAILABLE = 0x8C4,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_PDN_ID_IN_USE = 0x8C6,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_SUBSCRIBER_LIMITATION = 0x8C7,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8,
|
||||
RADIO_DATA_CALL_FAIL_VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9,
|
||||
RADIO_DATA_CALL_FAIL_IPV6_PREFIX_UNAVAILABLE = 0x8CA,
|
||||
RADIO_DATA_CALL_FAIL_HANDOFF_PREFERENCE_CHANGED = 0x8CB,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_1 = 0x1001,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_2 = 0x1002,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_3 = 0x1003,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_4 = 0x1004,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_5 = 0x1005,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_6 = 0x1006,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_7 = 0x1007,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_8 = 0x1008,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_9 = 0x1009,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_10 = 0x100A,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_11 = 0x100B,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_12 = 0x100C,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_13 = 0x100D,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_14 = 0x100E,
|
||||
RADIO_DATA_CALL_FAIL_OEM_DCFAILCAUSE_15 = 0x100F,
|
||||
RADIO_DATA_CALL_FAIL_VOICE_REGISTRATION_FAIL = -1,
|
||||
RADIO_DATA_CALL_FAIL_DATA_REGISTRATION_FAIL = -2,
|
||||
RADIO_DATA_CALL_FAIL_SIGNAL_LOST = -3,
|
||||
RADIO_DATA_CALL_FAIL_PREF_RADIO_TECH_CHANGED = -4,
|
||||
RADIO_DATA_CALL_FAIL_RADIO_POWER_OFF = -5,
|
||||
RADIO_DATA_CALL_FAIL_TETHERED_CALL_ACTIVE = -6,
|
||||
RADIO_DATA_CALL_FAIL_UNSPECIFIED = 0xffff
|
||||
} RADIO_DATA_CALL_FAIL_CAUSE; /* Since 1.4.3 */
|
||||
G_STATIC_ASSERT(sizeof(RADIO_DATA_CALL_FAIL_CAUSE) == 4);
|
||||
|
||||
typedef struct radio_response_info {
|
||||
RADIO_RESP_TYPE type RADIO_ALIGNED(4);
|
||||
guint32 serial RADIO_ALIGNED(4);
|
||||
guint32 error RADIO_ALIGNED(4);
|
||||
RADIO_ERROR error RADIO_ALIGNED(4);
|
||||
} RadioResponseInfo;
|
||||
G_STATIC_ASSERT(sizeof(RadioResponseInfo) == 12);
|
||||
|
||||
@@ -480,13 +1126,13 @@ G_STATIC_ASSERT(sizeof(RadioCall_1_2) == 96);
|
||||
|
||||
typedef struct radio_dial {
|
||||
GBinderHidlString address RADIO_ALIGNED(8);
|
||||
gint32 clir RADIO_ALIGNED(4);
|
||||
RADIO_CLIR clir RADIO_ALIGNED(4);
|
||||
GBinderHidlVec uusInfo RADIO_ALIGNED(8); /* vec<RadioUusInfo> */
|
||||
} RADIO_ALIGNED(8) RadioDial;
|
||||
G_STATIC_ASSERT(sizeof(RadioDial) == 40);
|
||||
|
||||
typedef struct radio_last_call_fail_cause_info {
|
||||
gint32 causeCode RADIO_ALIGNED(4);
|
||||
RADIO_LAST_CALL_FAIL_CAUSE causeCode RADIO_ALIGNED(4);
|
||||
GBinderHidlString vendorCause RADIO_ALIGNED(8);
|
||||
} RADIO_ALIGNED(8) RadioLastCallFailCauseInfo;
|
||||
G_STATIC_ASSERT(sizeof(RadioLastCallFailCauseInfo) == 24);
|
||||
@@ -542,10 +1188,10 @@ typedef struct radio_data_profile_1_4 {
|
||||
G_STATIC_ASSERT(sizeof(RadioDataProfile_1_4) == 112);
|
||||
|
||||
typedef struct radio_data_call {
|
||||
gint32 status RADIO_ALIGNED(4);
|
||||
RADIO_DATA_CALL_FAIL_CAUSE status RADIO_ALIGNED(4);
|
||||
gint32 suggestedRetryTime RADIO_ALIGNED(4);
|
||||
gint32 cid RADIO_ALIGNED(4);
|
||||
gint32 active RADIO_ALIGNED(4);
|
||||
RADIO_DATA_CALL_ACTIVE_STATUS active RADIO_ALIGNED(4);
|
||||
GBinderHidlString type RADIO_ALIGNED(8);
|
||||
GBinderHidlString ifname RADIO_ALIGNED(8);
|
||||
GBinderHidlString addresses RADIO_ALIGNED(8);
|
||||
@@ -557,10 +1203,10 @@ typedef struct radio_data_call {
|
||||
G_STATIC_ASSERT(sizeof(RadioDataCall) == 120);
|
||||
|
||||
typedef struct radio_data_call_1_4 {
|
||||
gint32 cause RADIO_ALIGNED(4);
|
||||
RADIO_DATA_CALL_FAIL_CAUSE cause RADIO_ALIGNED(4);
|
||||
gint32 suggestedRetryTime RADIO_ALIGNED(4);
|
||||
gint32 cid RADIO_ALIGNED(4);
|
||||
gint32 active RADIO_ALIGNED(4);
|
||||
RADIO_DATA_CALL_ACTIVE_STATUS active RADIO_ALIGNED(4);
|
||||
RADIO_PDP_PROTOCOL_TYPE type RADIO_ALIGNED(4);
|
||||
GBinderHidlString ifname RADIO_ALIGNED(8);
|
||||
GBinderHidlVec addresses RADIO_ALIGNED(8); /* vec<GBinderHidlString> */
|
||||
@@ -625,7 +1271,7 @@ typedef struct radio_icc_io_result {
|
||||
G_STATIC_ASSERT(sizeof(RadioIccIoResult) == 24);
|
||||
|
||||
typedef struct radio_call_forward_info {
|
||||
gint32 status RADIO_ALIGNED(4);
|
||||
RADIO_CALL_FORWARD status RADIO_ALIGNED(4);
|
||||
gint32 reason RADIO_ALIGNED(4);
|
||||
gint32 serviceClass RADIO_ALIGNED(4);
|
||||
gint32 toa RADIO_ALIGNED(4);
|
||||
@@ -1018,7 +1664,7 @@ typedef struct radio_cell_info_nr {
|
||||
G_STATIC_ASSERT(sizeof(RadioCellInfoNr) == 112);
|
||||
|
||||
typedef struct radio_cell_info_1_4 {
|
||||
guint32 registered RADIO_ALIGNED(1);
|
||||
guint8 registered RADIO_ALIGNED(1);
|
||||
guint32 connectionStatus RADIO_ALIGNED(4);
|
||||
guint8 cellInfoType RADIO_ALIGNED(1); /* RADIO_CELL_INFO_TYPE_1_4 */
|
||||
union {
|
||||
@@ -1045,7 +1691,7 @@ typedef struct radio_select_uicc_sub {
|
||||
gint32 slot RADIO_ALIGNED(4);
|
||||
gint32 appIndex RADIO_ALIGNED(4);
|
||||
gint32 subType RADIO_ALIGNED(4);
|
||||
gint32 actStatus RADIO_ALIGNED(4);
|
||||
RADIO_UICC_SUB_ACT actStatus RADIO_ALIGNED(4);
|
||||
} RADIO_ALIGNED(4) RadioSelectUiccSub;
|
||||
G_STATIC_ASSERT(sizeof(RadioSelectUiccSub) == 16);
|
||||
|
||||
@@ -1068,7 +1714,7 @@ G_STATIC_ASSERT(sizeof(RadioSimRefresh) == 24);
|
||||
typedef struct radio_capability {
|
||||
gint32 session RADIO_ALIGNED(4);
|
||||
RADIO_CAPABILITY_PHASE phase RADIO_ALIGNED(4);
|
||||
gint32 raf RADIO_ALIGNED(4);
|
||||
RADIO_ACCESS_FAMILY raf RADIO_ALIGNED(4);
|
||||
GBinderHidlString logicalModemUuid RADIO_ALIGNED(8);
|
||||
RADIO_CAPABILITY_STATUS status RADIO_ALIGNED(4);
|
||||
} RADIO_ALIGNED(8) RadioCapability;
|
||||
@@ -1113,7 +1759,7 @@ G_STATIC_ASSERT(sizeof(RadioHardwareConfigSim) == 16);
|
||||
|
||||
typedef struct radio_network_scan_result {
|
||||
RADIO_SCAN_STATUS status RADIO_ALIGNED(4);
|
||||
guint32 error RADIO_ALIGNED(4);
|
||||
RADIO_ERROR error RADIO_ALIGNED(4);
|
||||
GBinderHidlVec networkInfos RADIO_ALIGNED(8); /* vec<RadioCellInfo> */
|
||||
/* or vec<RadioCellInfo_1_4> */
|
||||
} RADIO_ALIGNED(8) RadioNetworkScanResult; /* Since 1.2.5 */
|
||||
@@ -1410,15 +2056,27 @@ typedef enum radio_resp {
|
||||
|
||||
/* android.hardware.radio@1.4::IRadioResponse */
|
||||
RADIO_CALL_1_4(RADIO_RESP_) /* Since 1.2.5 */
|
||||
RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4 = 149,
|
||||
RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4 = 150,
|
||||
RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4 = 151,
|
||||
RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4 = 154,
|
||||
RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4 = 155,
|
||||
RADIO_RESP_GET_CELL_INFO_LIST_1_4 = 149,
|
||||
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_4 = 150,
|
||||
RADIO_RESP_GET_ICC_CARD_STATUS_1_4 = 151,
|
||||
RADIO_RESP_GET_DATA_CALL_LIST_1_4 = 154,
|
||||
RADIO_RESP_SETUP_DATA_CALL_1_4 = 155,
|
||||
RADIO_1_4_RESP_LAST = RADIO_RESP_GET_SIGNAL_STRENGTH_1_4
|
||||
#undef RADIO_RESP_
|
||||
} RADIO_RESP;
|
||||
|
||||
/* These identifiers were shortened in 1.4.3 */
|
||||
#define RADIO_RESP_GET_CELL_INFO_LIST_RESPONSE_1_4 \
|
||||
RADIO_RESP_GET_CELL_INFO_LIST_1_4
|
||||
#define RADIO_RESP_GET_DATA_REGISTRATION_STATE_RESPONSE_1_4 \
|
||||
RADIO_RESP_GET_DATA_REGISTRATION_STATE_1_4
|
||||
#define RADIO_RESP_GET_ICC_CARD_STATUS_RESPONSE_1_4 \
|
||||
RADIO_RESP_GET_ICC_CARD_STATUS_1_4
|
||||
#define RADIO_RESP_GET_DATA_CALL_LIST_RESPONSE_1_4 \
|
||||
RADIO_RESP_GET_DATA_CALL_LIST_1_4
|
||||
#define RADIO_RESP_SETUP_DATA_CALL_RESPONSE_1_4 \
|
||||
RADIO_RESP_SETUP_DATA_CALL_1_4
|
||||
|
||||
typedef enum radio_ind {
|
||||
RADIO_IND_ANY = 0,
|
||||
RADIO_IND_NONE = 0,
|
||||
@@ -1462,4 +2120,3 @@ G_END_DECLS
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,8 +7,8 @@ License: BSD
|
||||
URL: https://github.com/mer-hybris/libgbinder-radio
|
||||
Source: %{name}-%{version}.tar.bz2
|
||||
|
||||
%define libgbinder_version 1.0.9
|
||||
%define libglibutil_version 1.0.34
|
||||
%define libgbinder_version 1.1.14
|
||||
%define libglibutil_version 1.0.49
|
||||
|
||||
BuildRequires: pkgconfig
|
||||
BuildRequires: pkgconfig(glib-2.0)
|
||||
|
||||
1141
src/radio_client.c
Normal file
1141
src/radio_client.c
Normal file
File diff suppressed because it is too large
Load Diff
121
src/radio_client_p.h
Normal file
121
src/radio_client_p.h
Normal file
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_CLIENT_PRIVATE_H
|
||||
#define RADIO_CLIENT_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_client.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
struct radio_client {
|
||||
GObject object;
|
||||
RadioInstance* instance;
|
||||
};
|
||||
|
||||
void
|
||||
radio_client_register_request(
|
||||
RadioClient* client,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_client_unregister_request(
|
||||
RadioClient* client,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
gboolean
|
||||
radio_client_submit_request(
|
||||
RadioClient* client,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
gboolean
|
||||
radio_client_retry_request(
|
||||
RadioClient* client,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_client_request_dropped(
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
guint
|
||||
radio_client_timeout_ms(
|
||||
RadioClient* client,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_client_reset_timeout(
|
||||
RadioClient* client)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_client_reset_timeout(
|
||||
RadioClient* client)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_client_block_status(
|
||||
RadioClient* client,
|
||||
RadioRequestGroup* group)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_client_block(
|
||||
RadioClient* client,
|
||||
RadioRequestGroup* group)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_client_unblock(
|
||||
RadioClient* client,
|
||||
RadioRequestGroup* group)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_CLIENT_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
|
||||
#include "radio_instance.h"
|
||||
#include "radio_instance_p.h"
|
||||
#include "radio_registry_p.h"
|
||||
#include "radio_util.h"
|
||||
#include "radio_log.h"
|
||||
@@ -44,6 +44,7 @@
|
||||
#include <gbinder.h>
|
||||
|
||||
#include <gutil_idlepool.h>
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_strv.h>
|
||||
|
||||
@@ -56,6 +57,7 @@ struct radio_instance_priv {
|
||||
GBinderRemoteObject* remote;
|
||||
GBinderLocalObject* response;
|
||||
GBinderLocalObject* indication;
|
||||
GHashTable* req_quarks;
|
||||
GHashTable* resp_quarks;
|
||||
GHashTable* ind_quarks;
|
||||
gulong death_id;
|
||||
@@ -67,24 +69,59 @@ struct radio_instance_priv {
|
||||
|
||||
G_DEFINE_TYPE(RadioInstance, radio_instance, G_TYPE_OBJECT)
|
||||
|
||||
enum radio_instance_signal {
|
||||
SIGNAL_HANDLE_INDICATION,
|
||||
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)
|
||||
#undef SIGNAL_INDEX
|
||||
#define SIGNAL_INDEX(x) SIGNAL_OBSERVE_RESPONSE_##x,
|
||||
FOREACH_PRIORITY(SIGNAL_INDEX)
|
||||
#undef SIGNAL_INDEX
|
||||
#define SIGNAL_INDEX(x) SIGNAL_OBSERVE_INDICATION_##x,
|
||||
FOREACH_PRIORITY(SIGNAL_INDEX)
|
||||
#undef SIGNAL_INDEX
|
||||
SIGNAL_HANDLE_RESPONSE,
|
||||
SIGNAL_OBSERVE_INDICATION,
|
||||
SIGNAL_OBSERVE_RESPONSE,
|
||||
SIGNAL_HANDLE_INDICATION,
|
||||
SIGNAL_ACK,
|
||||
SIGNAL_DEATH,
|
||||
SIGNAL_ENABLED,
|
||||
SIGNAL_CONNECTED,
|
||||
SIGNAL_COUNT
|
||||
} 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)
|
||||
#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)
|
||||
#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)
|
||||
#undef SIGNAL_NAME
|
||||
NULL
|
||||
};
|
||||
|
||||
#define SIGNAL_HANDLE_INDICATION_NAME "radio-instance-handle-indication"
|
||||
#define SIGNAL_HANDLE_RESPONSE_NAME "radio-instance-handle-response"
|
||||
#define SIGNAL_OBSERVE_INDICATION_NAME "radio-instance-observe-indication"
|
||||
#define SIGNAL_OBSERVE_RESPONSE_NAME "radio-instance-observe-response"
|
||||
#define SIGNAL_ACK_NAME "radio-instance-ack"
|
||||
#define SIGNAL_DEATH_NAME "radio-instance-death"
|
||||
#define SIGNAL_ENABLED_NAME "radio-instance-enabled"
|
||||
#define SIGNAL_CONNECTED_NAME "radio-instance-connected"
|
||||
|
||||
static guint radio_instance_signals[SIGNAL_COUNT] = { 0 };
|
||||
|
||||
@@ -144,32 +181,41 @@ static const RadioInterfaceDesc radio_interfaces[] = {
|
||||
};
|
||||
G_STATIC_ASSERT(G_N_ELEMENTS(radio_interfaces) == RADIO_INTERFACE_COUNT);
|
||||
|
||||
typedef struct radio_instance_tx {
|
||||
RadioInstance* instance;
|
||||
RadioInstanceTxCompleteFunc complete;
|
||||
RadioInstanceTxDestroyFunc destroy;
|
||||
gulong id;
|
||||
void* user_data1;
|
||||
void* user_data2;
|
||||
} RadioInstanceTx;
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
GQuark
|
||||
radio_instance_ind_quark(
|
||||
radio_instance_req_quark(
|
||||
RadioInstance* self,
|
||||
RADIO_IND ind)
|
||||
RADIO_REQ req)
|
||||
{
|
||||
GQuark q = 0;
|
||||
|
||||
if (ind != RADIO_IND_ANY) {
|
||||
if (req != RADIO_REQ_ANY) {
|
||||
RadioInstancePriv* priv = self->priv;
|
||||
gpointer key = GUINT_TO_POINTER(ind);
|
||||
gpointer key = GUINT_TO_POINTER(req);
|
||||
|
||||
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->ind_quarks, key));
|
||||
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->req_quarks, key));
|
||||
if (!q) {
|
||||
const char* known = radio_ind_name(ind);
|
||||
const char* known = radio_req_name(req);
|
||||
|
||||
if (known) {
|
||||
q = g_quark_from_static_string(known);
|
||||
} else {
|
||||
q = g_quark_from_string(radio_instance_ind_name(self, ind));
|
||||
q = g_quark_from_string(radio_instance_req_name(self, req));
|
||||
}
|
||||
g_hash_table_insert(priv->ind_quarks, key, GUINT_TO_POINTER(q));
|
||||
g_hash_table_insert(priv->req_quarks, key, GUINT_TO_POINTER(q));
|
||||
}
|
||||
}
|
||||
return q;
|
||||
@@ -202,6 +248,42 @@ 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(
|
||||
RadioInstance* self,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args)
|
||||
{
|
||||
GQuark quark = 0;
|
||||
int i;
|
||||
|
||||
for (i = RADIO_INSTANCE_PRIORITY_COUNT - 1; i >= 0; i--) {
|
||||
guint id = radio_instance_signals[SIGNAL_OBSERVE_REQUEST_0 + i];
|
||||
|
||||
if (id) {
|
||||
if (!quark) {
|
||||
quark = radio_instance_req_quark(self, code);
|
||||
}
|
||||
g_signal_emit(self, id, quark, code, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
GBinderLocalReply*
|
||||
radio_instance_indication(
|
||||
@@ -224,15 +306,49 @@ radio_instance_indication(
|
||||
gbinder_remote_request_init_reader(req, &reader);
|
||||
if (gbinder_reader_read_uint32(&reader, &type) &&
|
||||
(type == RADIO_IND_UNSOLICITED || type == RADIO_IND_ACK_EXP)) {
|
||||
GQuark quark = radio_instance_ind_quark(self, code);
|
||||
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;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
g_signal_emit(self,
|
||||
radio_instance_signals[SIGNAL_HANDLE_INDICATION], quark,
|
||||
code, type, &reader, &handled);
|
||||
g_signal_emit(self,
|
||||
radio_instance_signals[SIGNAL_OBSERVE_INDICATION], quark,
|
||||
code, type, &reader);
|
||||
/* High-priority observers are notified first */
|
||||
for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
|
||||
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
|
||||
g_signal_emit(self, signals
|
||||
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
|
||||
quark, code, type, &reader);
|
||||
}
|
||||
}
|
||||
|
||||
/* rilConnected is a special case */
|
||||
if (code == RADIO_IND_RIL_CONNECTED) {
|
||||
if (G_UNLIKELY(self->connected)) {
|
||||
/* We are only supposed to receive it once */
|
||||
GWARN("%s received unexpected rilConnected", self->slot);
|
||||
} else {
|
||||
GDEBUG("%s connected", self->slot);
|
||||
self->connected = TRUE;
|
||||
g_signal_emit(self, radio_instance_signals
|
||||
[SIGNAL_CONNECTED], 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Notify handlers */
|
||||
g_signal_emit(self, radio_instance_signals
|
||||
[SIGNAL_HANDLE_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)]) {
|
||||
g_signal_emit(self, signals
|
||||
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
|
||||
quark, code, type, &reader);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ack unhandled indications */
|
||||
if (type == RADIO_IND_ACK_EXP && !handled) {
|
||||
GDEBUG("ack unhandled indication");
|
||||
radio_instance_ack(self);
|
||||
@@ -283,15 +399,36 @@ radio_instance_response(
|
||||
gbinder_reader_read_hidl_struct(&reader, RadioResponseInfo);
|
||||
|
||||
if (info) {
|
||||
GQuark quark = radio_instance_resp_quark(self, code);
|
||||
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;
|
||||
gboolean handled = FALSE;
|
||||
|
||||
g_signal_emit(self,
|
||||
radio_instance_signals[SIGNAL_HANDLE_RESPONSE], quark,
|
||||
code, info, &reader, &handled);
|
||||
g_signal_emit(self,
|
||||
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE], quark,
|
||||
code, info, &reader);
|
||||
/* High-priority observers are notified first */
|
||||
for (; p > RADIO_INSTANCE_PRIORITY_DEFAULT; p--) {
|
||||
if (signals[RADIO_INSTANCE_PRIORITY_INDEX(p)]) {
|
||||
g_signal_emit(self, signals
|
||||
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
|
||||
quark, code, info, &reader);
|
||||
}
|
||||
}
|
||||
|
||||
/* Then handlers */
|
||||
g_signal_emit(self, radio_instance_signals
|
||||
[SIGNAL_HANDLE_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)]) {
|
||||
g_signal_emit(self, signals
|
||||
[RADIO_INSTANCE_PRIORITY_INDEX(p)],
|
||||
quark, code, info, &reader);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ack unhandled responses */
|
||||
if (info->type == RADIO_RESP_SOLICITED_ACK_EXP && !handled) {
|
||||
GDEBUG("ack unhandled response");
|
||||
radio_instance_ack(self);
|
||||
@@ -354,6 +491,7 @@ radio_instance_died(
|
||||
RadioInstance* self = RADIO_INSTANCE(user_data);
|
||||
|
||||
self->dead = TRUE;
|
||||
self->connected = FALSE;
|
||||
GWARN("%s died", self->key);
|
||||
radio_instance_ref(self);
|
||||
radio_instance_drop_binder(self);
|
||||
@@ -479,6 +617,124 @@ radio_instance_make_key(
|
||||
return g_strdup_printf("%s:%s:%d", dev, name, version);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_instance_tx_free(
|
||||
RadioInstanceTx* tx)
|
||||
{
|
||||
radio_instance_unref(tx->instance);
|
||||
gutil_slice_free(tx);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_instance_tx_destroy(
|
||||
gpointer tx_data)
|
||||
{
|
||||
RadioInstanceTx* tx = tx_data;
|
||||
|
||||
if (tx->destroy) {
|
||||
tx->destroy(tx->user_data1, tx->user_data2);
|
||||
}
|
||||
radio_instance_tx_free(tx);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_instance_tx_complete(
|
||||
GBinderClient* client,
|
||||
GBinderRemoteReply* reply,
|
||||
int status,
|
||||
void* tx_data)
|
||||
{
|
||||
RadioInstanceTx* tx = tx_data;
|
||||
|
||||
if (tx->complete) {
|
||||
tx->complete(tx->instance, tx->id, status, tx->user_data1,
|
||||
tx->user_data2);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
gulong
|
||||
radio_instance_send_request(
|
||||
RadioInstance* self,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
RadioInstanceTxCompleteFunc complete,
|
||||
RadioInstanceTxDestroyFunc destroy,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
RadioInstancePriv* priv = self->priv;
|
||||
|
||||
if (complete || destroy) {
|
||||
RadioInstanceTx* tx = g_slice_new(RadioInstanceTx);
|
||||
|
||||
tx->instance = radio_instance_ref(self);
|
||||
tx->complete = complete;
|
||||
tx->destroy = destroy;
|
||||
tx->user_data1 = user_data1;
|
||||
tx->user_data2 = user_data2;
|
||||
radio_instance_notify_request_observers(self, code, args);
|
||||
tx->id = gbinder_client_transact(priv->client, code,
|
||||
GBINDER_TX_FLAG_ONEWAY, args, radio_instance_tx_complete,
|
||||
radio_instance_tx_destroy, tx);
|
||||
if (tx->id) {
|
||||
return tx->id;
|
||||
} else {
|
||||
radio_instance_tx_free(tx);
|
||||
}
|
||||
} else {
|
||||
/* No need to allocate the context */
|
||||
radio_instance_notify_request_observers(self, code, args);
|
||||
return gbinder_client_transact(priv->client, code,
|
||||
GBINDER_TX_FLAG_ONEWAY, args, NULL, NULL, NULL);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
radio_instance_cancel_request(
|
||||
RadioInstance* self,
|
||||
gulong id)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
gbinder_client_cancel(self->priv->client, id);
|
||||
}
|
||||
}
|
||||
|
||||
GQuark
|
||||
radio_instance_ind_quark(
|
||||
RadioInstance* self,
|
||||
RADIO_IND ind)
|
||||
{
|
||||
GQuark q = 0;
|
||||
|
||||
if (ind != RADIO_IND_ANY) {
|
||||
RadioInstancePriv* priv = self->priv;
|
||||
gpointer key = GUINT_TO_POINTER(ind);
|
||||
|
||||
q = GPOINTER_TO_UINT(g_hash_table_lookup(priv->ind_quarks, key));
|
||||
if (!q) {
|
||||
const char* known = radio_ind_name(ind);
|
||||
|
||||
if (known) {
|
||||
q = g_quark_from_static_string(known);
|
||||
} else {
|
||||
q = g_quark_from_string(radio_instance_ind_name(self, ind));
|
||||
}
|
||||
g_hash_table_insert(priv->ind_quarks, key, GUINT_TO_POINTER(q));
|
||||
}
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
@@ -645,6 +901,22 @@ radio_instance_unref(
|
||||
}
|
||||
}
|
||||
|
||||
gsize
|
||||
radio_instance_rpc_header_size(
|
||||
RadioInstance* self,
|
||||
RADIO_REQ req) /* Since 1.4.3 */
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
RadioInstancePriv* priv = self->priv;
|
||||
GBytes* header = gbinder_client_rpc_header(priv->client, req);
|
||||
|
||||
if (header) {
|
||||
return g_bytes_get_size(header);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char*
|
||||
radio_instance_req_name(
|
||||
RadioInstance* self,
|
||||
@@ -714,8 +986,11 @@ radio_instance_ack(
|
||||
RadioInstance* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
return gbinder_client_transact_sync_oneway(self->priv->client,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT, NULL) >= 0;
|
||||
GBinderClient* client = self->priv->client;
|
||||
const RADIO_REQ code = RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT;
|
||||
|
||||
radio_instance_notify_request_observers(self, code, NULL);
|
||||
return gbinder_client_transact_sync_oneway(client, code, NULL) >= 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -738,8 +1013,10 @@ radio_instance_send_request_sync(
|
||||
GBinderLocalRequest* args)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
return gbinder_client_transact_sync_oneway(self->priv->client,
|
||||
code, args) >= 0;
|
||||
GBinderClient* client = self->priv->client;
|
||||
|
||||
radio_instance_notify_request_observers(self, code, args);
|
||||
return gbinder_client_transact_sync_oneway(client, code, args) >= 0;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -757,57 +1034,153 @@ radio_instance_set_enabled(
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_handler(
|
||||
radio_instance_add_request_observer(
|
||||
RadioInstance* self,
|
||||
RADIO_IND ind,
|
||||
RadioIndicationHandlerFunc func,
|
||||
RADIO_REQ code,
|
||||
RadioRequestObserverFunc func,
|
||||
gpointer user_data) /* Since 1.4.3 */
|
||||
{
|
||||
return radio_instance_add_request_observer_with_priority(self,
|
||||
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_request_observer_with_priority(
|
||||
RadioInstance* self,
|
||||
RADIO_INSTANCE_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 RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_REQUEST_0 + index;
|
||||
|
||||
/* Register signal on demand */
|
||||
if (!radio_instance_signals[sig]) {
|
||||
radio_instance_signals[sig] =
|
||||
g_signal_new(radio_instance_signal_observe_request_name
|
||||
[index], RADIO_TYPE_INSTANCE,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE,
|
||||
2, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
return g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[sig],
|
||||
radio_instance_req_quark(self, code),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
RadioInstance* self,
|
||||
RADIO_RESP code,
|
||||
RadioResponseObserverFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(func)) ?
|
||||
g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[SIGNAL_HANDLE_INDICATION],
|
||||
radio_instance_ind_quark(self, ind),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
|
||||
return radio_instance_add_response_observer_with_priority(self,
|
||||
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer_with_priority(
|
||||
RadioInstance* self,
|
||||
RADIO_INSTANCE_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 RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_RESPONSE_0 + index;
|
||||
|
||||
/* Register signal on demand */
|
||||
if (!radio_instance_signals[sig]) {
|
||||
radio_instance_signals[sig] =
|
||||
g_signal_new(radio_instance_signal_observe_response_name
|
||||
[index], RADIO_TYPE_INSTANCE,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE,
|
||||
3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
return g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[sig],
|
||||
radio_instance_resp_quark(self, code),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer(
|
||||
RadioInstance* self,
|
||||
RADIO_IND ind,
|
||||
RADIO_IND code,
|
||||
RadioIndicationObserverFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(func)) ?
|
||||
g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[SIGNAL_OBSERVE_INDICATION],
|
||||
radio_instance_ind_quark(self, ind),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
|
||||
return radio_instance_add_indication_observer_with_priority(self,
|
||||
RADIO_INSTANCE_PRIORITY_DEFAULT, code, func, user_data);
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_indication_observer_with_priority(
|
||||
RadioInstance* self,
|
||||
RADIO_INSTANCE_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 RADIO_INSTANCE_SIGNAL sig = SIGNAL_OBSERVE_INDICATION_0 + index;
|
||||
|
||||
/* Register signal on demand */
|
||||
if (!radio_instance_signals[sig]) {
|
||||
radio_instance_signals[sig] =
|
||||
g_signal_new(radio_instance_signal_observe_indication_name
|
||||
[index], RADIO_TYPE_INSTANCE,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
|
||||
0, NULL, NULL, NULL, G_TYPE_NONE,
|
||||
3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
return g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[sig],
|
||||
radio_instance_ind_quark(self, code),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_handler(
|
||||
RadioInstance* self,
|
||||
RADIO_RESP resp,
|
||||
RADIO_RESP code,
|
||||
RadioResponseHandlerFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(func)) ?
|
||||
g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[SIGNAL_HANDLE_RESPONSE],
|
||||
radio_instance_resp_quark(self, resp),
|
||||
radio_instance_resp_quark(self, code),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_response_observer(
|
||||
radio_instance_add_indication_handler(
|
||||
RadioInstance* self,
|
||||
RADIO_RESP resp,
|
||||
RadioResponseObserverFunc func,
|
||||
RADIO_IND code,
|
||||
RadioIndicationHandlerFunc func,
|
||||
gpointer user_data)
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(func)) ?
|
||||
g_signal_connect_closure_by_id(self,
|
||||
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE],
|
||||
radio_instance_resp_quark(self, resp),
|
||||
radio_instance_signals[SIGNAL_HANDLE_INDICATION],
|
||||
radio_instance_ind_quark(self, code),
|
||||
g_cclosure_new(G_CALLBACK(func), user_data, NULL), FALSE) : 0;
|
||||
}
|
||||
|
||||
@@ -841,6 +1214,16 @@ radio_instance_add_enabled_handler(
|
||||
SIGNAL_ENABLED_NAME, G_CALLBACK(func), user_data) : 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
radio_instance_add_connected_handler(
|
||||
RadioInstance* self,
|
||||
RadioInstanceFunc func,
|
||||
gpointer user_data) /* Since 1.4.3 */
|
||||
{
|
||||
return (G_LIKELY(self) && G_LIKELY(func)) ? g_signal_connect(self,
|
||||
SIGNAL_CONNECTED_NAME, G_CALLBACK(func), user_data) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
radio_instance_remove_handler(
|
||||
RadioInstance* self,
|
||||
@@ -874,6 +1257,7 @@ radio_instance_init(
|
||||
|
||||
self->priv = priv;
|
||||
priv->idle = gutil_idle_pool_new();
|
||||
priv->req_quarks = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
priv->resp_quarks = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
priv->ind_quarks = g_hash_table_new(g_direct_hash, g_direct_equal);
|
||||
}
|
||||
@@ -889,6 +1273,7 @@ radio_instance_finalize(
|
||||
radio_instance_drop_binder(self);
|
||||
gbinder_client_unref(priv->client);
|
||||
gutil_idle_pool_destroy(priv->idle);
|
||||
g_hash_table_destroy(priv->req_quarks);
|
||||
g_hash_table_destroy(priv->resp_quarks);
|
||||
g_hash_table_destroy(priv->ind_quarks);
|
||||
g_free(priv->slot);
|
||||
@@ -909,24 +1294,17 @@ radio_instance_class_init(
|
||||
g_type_class_add_private(klass, sizeof(RadioInstancePriv));
|
||||
object_class->finalize = radio_instance_finalize;
|
||||
|
||||
radio_instance_signals[SIGNAL_HANDLE_INDICATION] =
|
||||
g_signal_new(SIGNAL_HANDLE_INDICATION_NAME, type,
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0,
|
||||
g_signal_accumulator_true_handled, NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
/* Priority-based signals are registered on demand */
|
||||
radio_instance_signals[SIGNAL_HANDLE_RESPONSE] =
|
||||
g_signal_new(SIGNAL_HANDLE_RESPONSE_NAME, type,
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0,
|
||||
g_signal_accumulator_true_handled, NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
radio_instance_signals[SIGNAL_OBSERVE_INDICATION] =
|
||||
g_signal_new(SIGNAL_OBSERVE_INDICATION_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
radio_instance_signals[SIGNAL_OBSERVE_RESPONSE] =
|
||||
g_signal_new(SIGNAL_OBSERVE_RESPONSE_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 3, G_TYPE_UINT, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
radio_instance_signals[SIGNAL_HANDLE_INDICATION] =
|
||||
g_signal_new(SIGNAL_HANDLE_INDICATION_NAME, type,
|
||||
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED, 0,
|
||||
g_signal_accumulator_true_handled, NULL, NULL,
|
||||
G_TYPE_BOOLEAN, 3, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_POINTER);
|
||||
radio_instance_signals[SIGNAL_ACK] =
|
||||
g_signal_new(SIGNAL_ACK_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
|
||||
@@ -939,6 +1317,10 @@ radio_instance_class_init(
|
||||
g_signal_new(SIGNAL_ENABLED_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
radio_instance_signals[SIGNAL_CONNECTED] =
|
||||
g_signal_new(SIGNAL_CONNECTED_NAME, type,
|
||||
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
89
src/radio_instance_p.h
Normal file
89
src/radio_instance_p.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_INSTANCE_PRIVATE_H
|
||||
#define RADIO_INSTANCE_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_instance.h"
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioInstanceTxCompleteFunc)(
|
||||
RadioInstance* instance,
|
||||
gulong id,
|
||||
int status,
|
||||
void* user_data1,
|
||||
void* user_data2);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*RadioInstanceTxDestroyFunc)(
|
||||
void* user_data1,
|
||||
void* user_data2);
|
||||
|
||||
gulong
|
||||
radio_instance_send_request(
|
||||
RadioInstance* instance,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
RadioInstanceTxCompleteFunc complete,
|
||||
RadioInstanceTxDestroyFunc destroy,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_instance_cancel_request(
|
||||
RadioInstance* instance,
|
||||
gulong id)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
GQuark
|
||||
radio_instance_ind_quark(
|
||||
RadioInstance* instance,
|
||||
RADIO_IND ind)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_INSTANCE_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2019 Jolla Ltd.
|
||||
* Copyright (C) 2018-2019 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
@@ -44,6 +44,7 @@ struct radio_registry {
|
||||
GObject parent;
|
||||
};
|
||||
|
||||
GType radio_registry_get_type(void) RADIO_INTERNAL;
|
||||
G_DEFINE_TYPE(RadioRegistry, radio_registry, G_TYPE_OBJECT)
|
||||
#define RADIO_TYPE_REGISTRY (radio_registry_get_type())
|
||||
#define RADIO_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
|
||||
@@ -110,7 +111,7 @@ radio_registry_new(
|
||||
(gpointer*)(&radio_registry_instance));
|
||||
}
|
||||
return radio_registry_instance;
|
||||
|
||||
|
||||
}
|
||||
|
||||
RadioRegistry*
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018-2020 Jolla Ltd.
|
||||
* Copyright (C) 2018-2020 Slava Monich <slava.monich@jolla.com>
|
||||
* Copyright (C) 2018-2021 Jolla Ltd.
|
||||
* Copyright (C) 2018-2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
@@ -37,17 +37,18 @@
|
||||
#ifndef RADIO_REGISTRY_PRIVATE_H
|
||||
#define RADIO_REGISTRY_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_registry.h"
|
||||
|
||||
void
|
||||
radio_registry_instance_added(
|
||||
RadioInstance* instance)
|
||||
G_GNUC_INTERNAL;
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_registry_instance_removed(
|
||||
const char* key)
|
||||
G_GNUC_INTERNAL;
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REGISTRY_PRIVATE_H */
|
||||
|
||||
|
||||
342
src/radio_request.c
Normal file
342
src/radio_request.c
Normal file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#include "radio_request_p.h"
|
||||
#include "radio_request_group_p.h"
|
||||
#include "radio_instance_p.h"
|
||||
#include "radio_client_p.h"
|
||||
#include "radio_log.h"
|
||||
|
||||
#include <gbinder_local_request.h>
|
||||
#include <gbinder_writer.h>
|
||||
|
||||
#include <gutil_macros.h>
|
||||
|
||||
typedef struct radio_request_object {
|
||||
RadioRequest pub;
|
||||
RadioInstance* instance;
|
||||
GDestroyNotify destroy;
|
||||
gsize serial_offset;
|
||||
gboolean dropped;
|
||||
gint refcount;
|
||||
} RadioRequestObject;
|
||||
|
||||
static inline RadioRequestObject* radio_request_cast(RadioRequest* req)
|
||||
{ return req ? G_CAST(req, RadioRequestObject, pub) : NULL; }
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_object_cancel(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
RadioRequest* req = &self->pub;
|
||||
|
||||
if (req->tx_id) {
|
||||
radio_instance_cancel_request(self->instance, req->tx_id);
|
||||
req->tx_id = 0;
|
||||
}
|
||||
if (!self->dropped) {
|
||||
self->dropped = TRUE;
|
||||
radio_request_group_remove(req->group, req);
|
||||
radio_client_request_dropped(req);
|
||||
}
|
||||
radio_client_unregister_request(req->client, req);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_free(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
RadioRequest* req = &self->pub;
|
||||
|
||||
radio_request_object_cancel(self);
|
||||
if (req->complete) {
|
||||
RadioRequestCompleteFunc complete = req->complete;
|
||||
|
||||
/* Request is being freed too early, before completion */
|
||||
req->complete = NULL;
|
||||
complete(req, RADIO_TX_STATUS_FAILED, RADIO_RESP_NONE,
|
||||
RADIO_ERROR_NONE, NULL, req->user_data);
|
||||
}
|
||||
if (self->destroy) {
|
||||
GDestroyNotify destroy = self->destroy;
|
||||
|
||||
self->destroy = NULL;
|
||||
destroy(req->user_data);
|
||||
}
|
||||
gbinder_local_request_unref(req->args);
|
||||
radio_instance_unref(self->instance);
|
||||
gutil_slice_free(self);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_object_unref(
|
||||
RadioRequestObject* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
radio_request_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
radio_request_default_retry(
|
||||
RadioRequest* req,
|
||||
RADIO_TX_STATUS status,
|
||||
RADIO_RESP resp,
|
||||
RADIO_ERROR error,
|
||||
const GBinderReader* reader,
|
||||
void* user_data)
|
||||
{
|
||||
return status != RADIO_TX_STATUS_OK || error != RADIO_ERROR_NONE;
|
||||
}
|
||||
|
||||
static
|
||||
RadioRequest*
|
||||
radio_request_object_new(
|
||||
RadioClient* client,
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer,
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
RadioRequestObject* self = g_slice_new0(RadioRequestObject);
|
||||
RadioRequest* req = &self->pub;
|
||||
GBinderWriter tmp;
|
||||
|
||||
self->instance = radio_instance_ref(client->instance);
|
||||
self->destroy = destroy;
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
|
||||
req->state = RADIO_REQUEST_STATE_NEW;
|
||||
req->code = code;
|
||||
req->complete = complete;
|
||||
req->user_data = user_data;
|
||||
req->retry = radio_request_default_retry;
|
||||
|
||||
/* Assign serial and add to the group */
|
||||
radio_client_register_request(client, req);
|
||||
radio_request_group_add(group, req);
|
||||
|
||||
/* Build the argument list */
|
||||
if (!writer) writer = &tmp;
|
||||
req->args = radio_instance_new_request(client->instance, code);
|
||||
gbinder_local_request_init_writer(req->args, writer);
|
||||
self->serial_offset = gbinder_writer_bytes_written(writer);
|
||||
gbinder_writer_append_int32(writer, req->serial);
|
||||
return req;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_unref_func(
|
||||
gpointer req)
|
||||
{
|
||||
radio_request_object_unref(radio_request_cast(req));
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_update_serial(
|
||||
RadioRequest* req,
|
||||
guint32 serial)
|
||||
{
|
||||
GBinderWriter writer;
|
||||
|
||||
gbinder_local_request_init_writer(req->args, &writer);
|
||||
gbinder_writer_overwrite_int32(&writer,
|
||||
radio_request_cast(req)->serial_offset, serial);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new(
|
||||
RadioClient* client,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
return client ? radio_request_object_new(client, NULL, code,
|
||||
writer, complete, destroy, user_data) : NULL;
|
||||
}
|
||||
|
||||
RadioRequest*
|
||||
radio_request_new2(
|
||||
RadioRequestGroup* group,
|
||||
RADIO_REQ code,
|
||||
GBinderWriter* writer, /* NULL if serial is the only arg */
|
||||
RadioRequestCompleteFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
return group ? radio_request_object_new(group->client, group, code,
|
||||
writer, complete, destroy, user_data) : NULL;
|
||||
}
|
||||
|
||||
RadioRequest*
|
||||
radio_request_ref(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return req;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_unref(
|
||||
RadioRequest* req)
|
||||
{
|
||||
radio_request_object_unref(radio_request_cast(req));
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_blocking(
|
||||
RadioRequest* req,
|
||||
gboolean blocking)
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->blocking = blocking;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_timeout(
|
||||
RadioRequest* req,
|
||||
guint ms)
|
||||
{
|
||||
if (G_LIKELY(req) && req->timeout_ms != ms) {
|
||||
RadioClient* client = req->client;
|
||||
|
||||
req->timeout_ms = ms;
|
||||
if (client && req->state >= RADIO_REQUEST_STATE_QUEUED) {
|
||||
const uint timeout = radio_client_timeout_ms(client, req);
|
||||
|
||||
req->deadline = g_get_monotonic_time() + MICROSEC(timeout);
|
||||
radio_client_reset_timeout(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_retry(
|
||||
RadioRequest* req,
|
||||
guint delay_ms, /* Delay before each retry, in milliseconds */
|
||||
int max_count) /* Negative count to keep retrying indefinitely */
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->retry_delay_ms = delay_ms;
|
||||
req->max_retries = max_count;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_set_retry_func(
|
||||
RadioRequest* req,
|
||||
RadioRequestRetryFunc retry)
|
||||
{
|
||||
if (G_LIKELY(req)) {
|
||||
req->retry = retry ? retry : radio_request_default_retry;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
radio_request_submit(
|
||||
RadioRequest* req)
|
||||
{
|
||||
return req && req->client && radio_client_submit_request(req->client, req);
|
||||
}
|
||||
|
||||
gboolean
|
||||
radio_request_retry(
|
||||
RadioRequest* req)
|
||||
{
|
||||
return req && req->client && radio_client_retry_request(req->client, req);
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_cancel(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
req->complete = NULL;
|
||||
radio_request_object_cancel(self);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_drop(
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestObject* self = radio_request_cast(req);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
req->complete = NULL;
|
||||
radio_request_object_cancel(self);
|
||||
radio_request_object_unref(self);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
224
src/radio_request_group.c
Normal file
224
src/radio_request_group.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#include "radio_request_group_p.h"
|
||||
#include "radio_request_p.h"
|
||||
#include "radio_client_p.h"
|
||||
#include "radio_log.h"
|
||||
|
||||
#include <gutil_macros.h>
|
||||
|
||||
typedef struct radio_request_group_object {
|
||||
RadioRequestGroup pub;
|
||||
GHashTable* requests;
|
||||
gint refcount;
|
||||
} RadioRequestGroupObject;
|
||||
|
||||
static inline RadioRequestGroupObject*
|
||||
radio_request_group_cast(RadioRequestGroup* group)
|
||||
{ return group ? G_CAST(group, RadioRequestGroupObject, pub) : NULL; }
|
||||
|
||||
/*==========================================================================*
|
||||
* Implementation
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_group_unlink_func(
|
||||
gpointer req)
|
||||
{
|
||||
((RadioRequest*)req)->group = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
radio_request_group_free(
|
||||
RadioRequestGroupObject* self)
|
||||
{
|
||||
RadioRequestGroup* group = &self->pub;
|
||||
RadioClient* client = group->client;
|
||||
|
||||
radio_client_unblock(client, group);
|
||||
g_hash_table_destroy(self->requests);
|
||||
radio_client_unref(client);
|
||||
gutil_slice_free(self);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
void
|
||||
radio_request_group_add(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
/* Request is never NULL but the group may be */
|
||||
if (self) {
|
||||
g_hash_table_insert(self->requests, req, req);
|
||||
req->group = group;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_remove(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
/* Request is never NULL but the group may be */
|
||||
if (self) {
|
||||
g_hash_table_remove(self->requests, req);
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_new(
|
||||
RadioClient* client)
|
||||
{
|
||||
if (G_LIKELY(client)) {
|
||||
RadioRequestGroupObject* self = g_slice_new0(RadioRequestGroupObject);
|
||||
RadioRequestGroup* group = &self->pub;
|
||||
|
||||
group->client = radio_client_ref(client);
|
||||
self->requests = g_hash_table_new_full(g_direct_hash, g_direct_equal,
|
||||
NULL, radio_request_group_unlink_func);
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
return group;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RadioRequestGroup*
|
||||
radio_request_group_ref(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
g_atomic_int_inc(&self->refcount);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_unref(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GASSERT(self->refcount > 0);
|
||||
if (g_atomic_int_dec_and_test(&self->refcount)) {
|
||||
radio_request_group_free(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_cancel(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
RadioRequestGroupObject* self = radio_request_group_cast(group);
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
GHashTableIter it;
|
||||
gpointer value;
|
||||
GSList* list = NULL;
|
||||
GSList* l;
|
||||
|
||||
/*
|
||||
* Move requests to the list and temporarily reference them
|
||||
* before invoking any callbacks.
|
||||
*/
|
||||
g_hash_table_iter_init(&it, self->requests);
|
||||
while (g_hash_table_iter_next(&it, NULL, &value)) {
|
||||
list = g_slist_prepend(list, radio_request_ref(value));
|
||||
g_hash_table_iter_remove(&it);
|
||||
}
|
||||
|
||||
/*
|
||||
* Actually cancel the requests. This invokes completion callbacks.
|
||||
* The group is already empty at this point.
|
||||
*/
|
||||
for (l = list; l; l = l->next) {
|
||||
radio_request_cancel(l->data);
|
||||
}
|
||||
|
||||
/* Release the temporary references */
|
||||
g_slist_free_full(list, radio_request_unref_func);
|
||||
}
|
||||
}
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block_status(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
return group ? radio_client_block_status(group->client, group) :
|
||||
RADIO_BLOCK_NONE;
|
||||
}
|
||||
|
||||
RADIO_BLOCK
|
||||
radio_request_group_block(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
return group ? radio_client_block(group->client, group) :
|
||||
RADIO_BLOCK_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
radio_request_group_unblock(
|
||||
RadioRequestGroup* group)
|
||||
{
|
||||
if (group) {
|
||||
radio_client_unblock(group->client, group);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
63
src/radio_request_group_p.h
Normal file
63
src/radio_request_group_p.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_REQUEST_GROUP_PRIVATE_H
|
||||
#define RADIO_REQUEST_GROUP_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include <radio_request_group.h>
|
||||
|
||||
void
|
||||
radio_request_group_add(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_request_group_remove(
|
||||
RadioRequestGroup* group,
|
||||
RadioRequest* req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REQUEST_GROUP_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
151
src/radio_request_p.h
Normal file
151
src/radio_request_p.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_REQUEST_PRIVATE_H
|
||||
#define RADIO_REQUEST_PRIVATE_H
|
||||
|
||||
#include "radio_types_p.h"
|
||||
#include "radio_request.h"
|
||||
|
||||
/*
|
||||
* Request lifecycle
|
||||
* =================
|
||||
*
|
||||
* +=====+
|
||||
* | NEW | ----------------------[cancel]------------+
|
||||
* +=====+ |
|
||||
* | |
|
||||
* [submit] |
|
||||
* | |
|
||||
* | |
|
||||
* +----> +---------------+ |
|
||||
* | | | |
|
||||
* | | (blocked) |
|
||||
* | (unblocked) | |
|
||||
* | | v v
|
||||
* | | +========+ +===========+
|
||||
* (retry) | | QUEUED | ----[cancel]----> | CANCELLED |
|
||||
* | | +========+ +===========+
|
||||
* | | | ^
|
||||
* | | (unblocked) |
|
||||
* | | | |
|
||||
* | | +----------+ |
|
||||
* | | | |
|
||||
* | v v |
|
||||
* | +-------------+ |
|
||||
* | | submit | +========+ |
|
||||
* | | request | ---(error)---> | FAILED | |
|
||||
* | | transaction | +========+ |
|
||||
* | +-------------+ ^ |
|
||||
* | | | |
|
||||
* | (ok) +---(error)---------+ |
|
||||
* | | / |
|
||||
* | v / |
|
||||
* | +=========+ +=========+ |
|
||||
* +--- | PENDING | ---(timeout)---> | TIMEOUT | |
|
||||
* +=========+ +=========+ |
|
||||
* | \ |
|
||||
* | +----------------[cancel]------------+
|
||||
* (response)
|
||||
* |
|
||||
* v
|
||||
* +======+
|
||||
* | DONE |
|
||||
* +======+
|
||||
*
|
||||
* Timeout starts ticking when request enters the PENDING state.
|
||||
* The library maintains an internal reference to the request in
|
||||
* QUEUED and PENDING states.
|
||||
*/
|
||||
|
||||
typedef enum radio_request_state {
|
||||
RADIO_REQUEST_STATE_INVALID,
|
||||
RADIO_REQUEST_STATE_NEW,
|
||||
RADIO_REQUEST_STATE_QUEUED,
|
||||
RADIO_REQUEST_STATE_PENDING,
|
||||
/*
|
||||
* Reorder states carefully or better don't reorder at all.
|
||||
* States >= RADIO_REQUEST_STATE_FAILED are assumed to be
|
||||
* terminal states in the state machine.
|
||||
*/
|
||||
RADIO_REQUEST_STATE_FAILED,
|
||||
RADIO_REQUEST_STATE_CANCELLED,
|
||||
RADIO_REQUEST_STATE_TIMEOUT,
|
||||
RADIO_REQUEST_STATE_DONE
|
||||
} RADIO_REQUEST_STATE;
|
||||
|
||||
struct radio_request {
|
||||
RADIO_REQUEST_STATE state;
|
||||
RADIO_REQ code;
|
||||
GBinderLocalRequest* args;
|
||||
RadioRequestCompleteFunc complete;
|
||||
RadioRequestRetryFunc retry;
|
||||
void* user_data;
|
||||
guint32 serial; /* Immutable, generated at creation time */
|
||||
guint32 serial2; /* Mutable, used by the last transaction */
|
||||
int max_retries; /* Negative = retry indefinitely */
|
||||
int retry_count; /* Number of times we have already retried */
|
||||
guint retry_delay_ms; /* Delay before each retry, in milliseconds */
|
||||
guint timeout_ms; /* Timeout, in milliseconds (0 = default) */
|
||||
gint64 deadline; /* Monotonic time, in microseconds */
|
||||
gulong tx_id; /* Id of the request transaction */
|
||||
gboolean blocking; /* TRUE if this request blocks all others */
|
||||
gboolean acked;
|
||||
RadioClient* client; /* Not a reference */
|
||||
RadioRequestGroup* group; /* Not a reference */
|
||||
RadioRequest* queue_next;
|
||||
};
|
||||
|
||||
void
|
||||
radio_request_unref_func(
|
||||
gpointer req)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
void
|
||||
radio_request_update_serial(
|
||||
RadioRequest* req,
|
||||
guint32 serial)
|
||||
RADIO_INTERNAL;
|
||||
|
||||
#endif /* RADIO_REQUEST_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
55
src/radio_types_p.h
Normal file
55
src/radio_types_p.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2021 Jolla Ltd.
|
||||
* Copyright (C) 2021 Slava Monich <slava.monich@jolla.com>
|
||||
*
|
||||
* You may use this file under the terms of the BSD license as follows:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the names of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation
|
||||
* are those of the authors and should not be interpreted as representing
|
||||
* any official policies, either expressed or implied.
|
||||
*/
|
||||
|
||||
#ifndef RADIO_TYPES_PRIVATE_H
|
||||
#define RADIO_TYPES_PRIVATE_H
|
||||
|
||||
#include <radio_types.h>
|
||||
|
||||
#define RADIO_INTERNAL G_GNUC_INTERNAL
|
||||
|
||||
/* Miliseconds to microseconds */
|
||||
#define MICROSEC(ms) (((gint64)(ms)) * 1000)
|
||||
|
||||
#endif /* RADIO_TYPES_PRIVATE_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -1,7 +1,10 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
.PHONY: clean all
|
||||
|
||||
all:
|
||||
%:
|
||||
@$(MAKE) -C unit_client $*
|
||||
@$(MAKE) -C unit_instance $*
|
||||
@$(MAKE) -C unit_registry $*
|
||||
@$(MAKE) -C unit_util $*
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
.PHONY: clean all debug release coverage
|
||||
.PHONY: clean cleaner unitclean all debug release coverage valgrind
|
||||
.PHONY: debug_lib release_lib coverage_lib
|
||||
.PHONY: test test_banner
|
||||
|
||||
#
|
||||
# Real test makefile defines EXE (and possibly SRC) and includes this one.
|
||||
@@ -62,11 +63,9 @@ LD = $(CC)
|
||||
WARNINGS += -Wall -Wno-deprecated-declarations
|
||||
INCLUDES += -I$(COMMON_DIR) -I$(LIB_DIR)/src -I$(LIB_DIR)/include
|
||||
BASE_FLAGS = -fPIC
|
||||
BASE_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS)
|
||||
BASE_CFLAGS = $(BASE_FLAGS) $(CFLAGS)
|
||||
FULL_CFLAGS = $(BASE_CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) -MMD -MP \
|
||||
$(shell pkg-config --cflags $(PKGS))
|
||||
FULL_LDFLAGS = $(BASE_LDFLAGS)
|
||||
FULL_CFLAGS = $(BASE_FLAGS) $(CFLAGS) $(DEFINES) $(WARNINGS) $(INCLUDES) \
|
||||
-MMD -MP $(shell pkg-config --cflags $(PKGS))
|
||||
FULL_LDFLAGS = $(BASE_FLAGS) $(LDFLAGS)
|
||||
LIBS = $(shell pkg-config --libs $(LINK_PKGS)) -lpthread
|
||||
QUIET_MAKE = make --no-print-directory
|
||||
DEBUG_FLAGS = -g
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef struct test_gbinder_data TestGBinderData;
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_new(
|
||||
void);
|
||||
const char* iface);
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_ref(
|
||||
|
||||
@@ -50,6 +50,7 @@ typedef struct test_gbinder_client_tx {
|
||||
|
||||
typedef struct test_gbinder_client_iface_range {
|
||||
char* iface;
|
||||
GBytes* header;
|
||||
guint32 last_code;
|
||||
} TestGBinderClientIfaceRange;
|
||||
|
||||
@@ -68,7 +69,10 @@ test_gbinder_client_free(
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->nr; i++) {
|
||||
g_free(self->ranges[i].iface);
|
||||
TestGBinderClientIfaceRange* r = self->ranges + i;
|
||||
|
||||
g_bytes_unref(r->header);
|
||||
g_free(r->iface);
|
||||
}
|
||||
g_free(self->ranges);
|
||||
gbinder_remote_object_unref(self->remote);
|
||||
@@ -81,6 +85,7 @@ test_gbinder_client_init_range(
|
||||
TestGBinderClientIfaceRange* r,
|
||||
const GBinderClientIfaceInfo* info)
|
||||
{
|
||||
r->header = g_bytes_new(info->iface, strlen(info->iface));
|
||||
r->iface = g_strdup(info->iface);
|
||||
r->last_code = info->last_code;
|
||||
}
|
||||
@@ -183,7 +188,9 @@ test_gbinder_client_tx_handle(
|
||||
GBinderRemoteReply* reply = test_gbinder_client_transact
|
||||
(tx->client, tx->code, tx->flags, tx->req, &status);
|
||||
|
||||
tx->reply(tx->client, reply, status, tx->user_data);
|
||||
if (tx->reply) {
|
||||
tx->reply(tx->client, reply, status, tx->user_data);
|
||||
}
|
||||
gbinder_remote_reply_unref(reply);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
@@ -262,6 +269,22 @@ gbinder_client_unref(
|
||||
}
|
||||
}
|
||||
|
||||
GBytes*
|
||||
gbinder_client_rpc_header(
|
||||
GBinderClient* self,
|
||||
guint32 code)
|
||||
{
|
||||
if (self) {
|
||||
const TestGBinderClientIfaceRange* r =
|
||||
test_gbinder_client_find_range(self, code);
|
||||
|
||||
if (r) {
|
||||
return r->header;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GBinderLocalRequest*
|
||||
gbinder_client_new_request2(
|
||||
GBinderClient* self,
|
||||
@@ -354,7 +377,9 @@ gbinder_client_cancel(
|
||||
GBinderClient* self,
|
||||
gulong id)
|
||||
{
|
||||
g_source_remove((guint)id);
|
||||
if (id) {
|
||||
g_source_remove((guint)id);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -63,7 +63,7 @@ test_gbinder_local_reply_new(
|
||||
GBinderLocalReply* self = g_new0(GBinderLocalReply, 1);
|
||||
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_new();
|
||||
self->data = test_gbinder_data_new(NULL);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ test_gbinder_local_request_new(
|
||||
|
||||
g_assert(iface);
|
||||
g_atomic_int_set(&self->refcount, 1);
|
||||
self->data = test_gbinder_data_new();
|
||||
self->data = test_gbinder_data_new(iface);
|
||||
self->iface = g_strdup(iface);
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,11 @@
|
||||
|
||||
#include "test_gbinder.h"
|
||||
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
#include <gutil_idlepool.h>
|
||||
|
||||
typedef enum test_gbinder_data_type {
|
||||
DATA_TYPE_BOOLEAN,
|
||||
DATA_TYPE_INT32,
|
||||
DATA_TYPE_BUFFER,
|
||||
DATA_TYPE_LOCAL_OBJ
|
||||
@@ -49,9 +51,10 @@ struct test_gbinder_data_item {
|
||||
TestGBinderDataItem* next;
|
||||
DATA_TYPE type;
|
||||
union {
|
||||
gboolean b;
|
||||
gint32 i32;
|
||||
struct {
|
||||
const void* buf;
|
||||
void* buf;
|
||||
gsize size;
|
||||
} blob;
|
||||
GBinderLocalObject* obj;
|
||||
@@ -62,6 +65,8 @@ struct test_gbinder_data_item {
|
||||
struct test_gbinder_data {
|
||||
guint32 refcount;
|
||||
TestGBinderDataItem* items;
|
||||
GUtilIdlePool* pool;
|
||||
char* iface;
|
||||
};
|
||||
|
||||
typedef struct test_gbinder_reader {
|
||||
@@ -87,6 +92,15 @@ test_gbinder_data_item_destroy_local_obj(
|
||||
gbinder_local_object_unref(item->data.obj);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_gbinder_data_item_destroy_buffer(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
g_assert_cmpint(item->type, == ,DATA_TYPE_BUFFER);
|
||||
g_free(item->data.blob.buf);
|
||||
}
|
||||
|
||||
static
|
||||
TestGBinderDataItem*
|
||||
test_gbinder_data_item_new(
|
||||
@@ -118,6 +132,8 @@ test_gbinder_data_free(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
test_gbinder_data_item_free(data->items);
|
||||
gutil_idle_pool_destroy(data->pool);
|
||||
g_free(data->iface);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
@@ -155,17 +171,111 @@ test_gbinder_data_append(
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
gsize
|
||||
test_gbinder_data_item_size(
|
||||
TestGBinderDataItem* item)
|
||||
{
|
||||
switch (item->type) {
|
||||
case DATA_TYPE_BOOLEAN:
|
||||
return sizeof(item->data.b);
|
||||
case DATA_TYPE_INT32:
|
||||
return sizeof(item->data.i32);
|
||||
case DATA_TYPE_BUFFER:
|
||||
return sizeof(item->data.blob);
|
||||
case DATA_TYPE_LOCAL_OBJ:
|
||||
return sizeof(item->data.obj);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void*
|
||||
test_gbinder_data_buffer(
|
||||
TestGBinderData* data,
|
||||
gsize* out_size)
|
||||
{
|
||||
gsize size = 0;
|
||||
void* ptr = NULL;
|
||||
|
||||
if (data) {
|
||||
TestGBinderDataItem* item;
|
||||
GByteArray* buf = g_byte_array_new();
|
||||
|
||||
if (data->iface) {
|
||||
gsize header_size = strlen(data->iface);
|
||||
|
||||
g_byte_array_append(buf, (void*)data->iface, header_size);
|
||||
size += header_size;
|
||||
}
|
||||
for (item = data->items; item; item = item->next) {
|
||||
gsize item_size = test_gbinder_data_item_size(item);
|
||||
|
||||
g_byte_array_append(buf, (void*)&item->data, item_size);
|
||||
size += item_size;
|
||||
}
|
||||
ptr = g_byte_array_free(buf, FALSE);
|
||||
}
|
||||
if (out_size) *out_size = size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static
|
||||
gsize
|
||||
test_gbinder_data_size(
|
||||
TestGBinderData* data)
|
||||
{
|
||||
gsize size = 0;
|
||||
|
||||
if (data) {
|
||||
TestGBinderDataItem* item;
|
||||
|
||||
if (data->iface) size += strlen(data->iface);
|
||||
for (item = data->items; item; item = item->next) {
|
||||
size += test_gbinder_data_item_size(item);
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
static
|
||||
guint32
|
||||
test_gbinder_date_replace_int32(
|
||||
TestGBinderData* data,
|
||||
gsize offset,
|
||||
guint32 value)
|
||||
{
|
||||
if (data) {
|
||||
gsize size = 0;
|
||||
TestGBinderDataItem* item;
|
||||
|
||||
for (item = data->items; item; item = item->next) {
|
||||
if (size == offset) {
|
||||
guint32 prev;
|
||||
|
||||
g_assert_cmpint(item->type, == ,DATA_TYPE_INT32);
|
||||
prev = item->data.i32;
|
||||
item->data.i32 = value;
|
||||
return prev;
|
||||
}
|
||||
size += test_gbinder_data_item_size(item);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internal API
|
||||
*==========================================================================*/
|
||||
|
||||
TestGBinderData*
|
||||
test_gbinder_data_new(
|
||||
void)
|
||||
const char* iface)
|
||||
{
|
||||
TestGBinderData* data = g_new0(TestGBinderData, 1);
|
||||
|
||||
g_atomic_int_set(&data->refcount, 1);
|
||||
data->iface = g_strdup(iface); /* Doubles as a request header */
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -208,9 +318,11 @@ test_gbinder_data_init_writer(
|
||||
TestGBinderData* data,
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
memset(writer, 0, sizeof(*writer));
|
||||
if (data) {
|
||||
test_gbinder_writer_cast(writer)->data = data;
|
||||
if (writer) {
|
||||
memset(writer, 0, sizeof(*writer));
|
||||
if (data) {
|
||||
test_gbinder_writer_cast(writer)->data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,6 +386,33 @@ gbinder_reader_read_object(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const void*
|
||||
gbinder_writer_get_data(
|
||||
GBinderWriter* writer,
|
||||
gsize* size)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderData* data = self->data;
|
||||
void* buf = test_gbinder_data_buffer(data, size);
|
||||
|
||||
if (buf) {
|
||||
if (!data->pool) {
|
||||
data->pool = gutil_idle_pool_new();
|
||||
}
|
||||
gutil_idle_pool_add(data->pool, buf, g_free);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
gsize
|
||||
gbinder_writer_bytes_written(
|
||||
GBinderWriter* writer)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
|
||||
return test_gbinder_data_size(self->data);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_append_int32(
|
||||
GBinderWriter* writer,
|
||||
@@ -286,6 +425,29 @@ gbinder_writer_append_int32(
|
||||
test_gbinder_data_append(self->data, item);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_overwrite_int32(
|
||||
GBinderWriter* writer,
|
||||
gsize offset,
|
||||
gint32 value)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
|
||||
test_gbinder_date_replace_int32(self->data, offset, value);
|
||||
}
|
||||
|
||||
void
|
||||
gbinder_writer_append_bool(
|
||||
GBinderWriter* writer,
|
||||
gboolean value)
|
||||
{
|
||||
TestGBinderWriter* self = test_gbinder_writer_cast(writer);
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_BOOLEAN);
|
||||
|
||||
item->data.b = value;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
}
|
||||
|
||||
guint
|
||||
gbinder_writer_append_buffer_object(
|
||||
GBinderWriter* writer,
|
||||
@@ -296,7 +458,8 @@ gbinder_writer_append_buffer_object(
|
||||
TestGBinderDataItem* item = test_gbinder_data_item_new(DATA_TYPE_BUFFER);
|
||||
const guint index = test_gbinder_data_count_buffers(self->data);
|
||||
|
||||
item->data.blob.buf = buf;
|
||||
item->destroy = test_gbinder_data_item_destroy_buffer;
|
||||
item->data.blob.buf = gutil_memdup(buf, size);
|
||||
item->data.blob.size = size;
|
||||
test_gbinder_data_append(self->data, item);
|
||||
return index;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#
|
||||
|
||||
TESTS="\
|
||||
unit_client \
|
||||
unit_instance \
|
||||
unit_registry \
|
||||
unit_util"
|
||||
|
||||
5
unit/unit_client/Makefile
Normal file
5
unit/unit_client/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
# -*- Mode: makefile-gmake -*-
|
||||
|
||||
EXE = unit_client
|
||||
|
||||
include ../common/Makefile
|
||||
1839
unit/unit_client/unit_client.c
Normal file
1839
unit/unit_client/unit_client.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -37,7 +37,7 @@
|
||||
#include "test_common.h"
|
||||
#include "test_gbinder.h"
|
||||
|
||||
#include "radio_instance.h"
|
||||
#include "radio_instance_p.h"
|
||||
#include "radio_util.h"
|
||||
|
||||
#include <gutil_strv.h>
|
||||
@@ -216,9 +216,9 @@ test_null(
|
||||
radio_instance_remove_handler(NULL, 0);
|
||||
radio_instance_remove_handlers(NULL, NULL, 0);
|
||||
radio_instance_unref(NULL);
|
||||
radio_instance_cancel_request(NULL, 0);
|
||||
|
||||
g_assert(radio_instance_is_dead(NULL));
|
||||
|
||||
g_assert(!radio_instance_get(NULL, NULL));
|
||||
g_assert(!radio_instance_get("", NULL));
|
||||
g_assert(!radio_instance_get("/dev/binder", NULL));
|
||||
@@ -229,10 +229,13 @@ test_null(
|
||||
g_assert(!radio_instance_new_with_modem_and_slot(NULL, NULL, NULL, 0));
|
||||
g_assert(!radio_instance_new_with_version(NULL, NULL, DEFAULT_INTERFACE));
|
||||
g_assert(!radio_instance_new_with_version(NULL, "", DEFAULT_INTERFACE));
|
||||
g_assert(!radio_instance_new_with_version(NULL, "foo", DEFAULT_INTERFACE));
|
||||
g_assert(!radio_instance_new_request(NULL, 0));
|
||||
g_assert(!radio_instance_ack(NULL));
|
||||
g_assert(!radio_instance_ref(NULL));
|
||||
g_assert(!radio_instance_rpc_header_size(NULL, 0));
|
||||
g_assert(!radio_instance_send_request_sync(NULL, 0, NULL));
|
||||
g_assert(!radio_instance_add_request_observer(NULL, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_indication_handler(NULL, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_indication_observer(NULL, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_response_handler(NULL, 0, NULL, NULL));
|
||||
@@ -240,9 +243,11 @@ test_null(
|
||||
g_assert(!radio_instance_add_ack_handler(NULL, NULL, NULL));
|
||||
g_assert(!radio_instance_add_death_handler(NULL, NULL, NULL));
|
||||
g_assert(!radio_instance_add_enabled_handler(NULL, NULL, NULL));
|
||||
g_assert(!radio_instance_add_connected_handler(NULL, NULL, NULL));
|
||||
g_assert(!radio_instance_req_name(NULL, UNKNOWN_REQ));
|
||||
g_assert(!radio_instance_resp_name(NULL, UNKNOWN_RESP));
|
||||
g_assert(!radio_instance_ind_name(NULL, UNKNOWN_IND));
|
||||
g_assert(!radio_instance_send_request(NULL,0,NULL,NULL,NULL,NULL,NULL));
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
@@ -262,6 +267,7 @@ test_basic(
|
||||
const RADIO_INTERFACE version = RADIO_INTERFACE_1_4;
|
||||
const char* slot = "slot1";
|
||||
const char* fqname = RADIO_1_0 "/slot1";
|
||||
GQuark q;
|
||||
|
||||
/* This fails because there's no radio service */
|
||||
g_assert(!radio_instance_new_with_version(DEV, slot, DEFAULT_INTERFACE));
|
||||
@@ -279,10 +285,20 @@ test_basic(
|
||||
g_assert(radio == radio_instance_new_with_version(DEV, slot, version));
|
||||
radio_instance_unref(radio);
|
||||
|
||||
/* Test quarks */
|
||||
q = radio_instance_ind_quark(radio, UNKNOWN_IND);
|
||||
g_assert(q);
|
||||
g_assert(q == radio_instance_ind_quark(radio, UNKNOWN_IND));
|
||||
|
||||
/* Expecting non-zero RPC header size for a valid request code */
|
||||
g_assert(radio_instance_rpc_header_size(radio, RADIO_REQ_DIAL));
|
||||
g_assert_cmpuint(radio_instance_rpc_header_size(radio, UNKNOWN_REQ),==,0);
|
||||
|
||||
/* The one we have created must still be there */
|
||||
g_assert(radio == radio_instance_get_with_version(DEV, slot, version));
|
||||
|
||||
/* NULL callbacks are ignored */
|
||||
g_assert(!radio_instance_add_request_observer(radio, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_indication_handler(radio, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_indication_observer(radio, 0, NULL, NULL));
|
||||
g_assert(!radio_instance_add_response_handler(radio, 0, NULL, NULL));
|
||||
@@ -290,6 +306,7 @@ test_basic(
|
||||
g_assert(!radio_instance_add_ack_handler(radio, NULL, NULL));
|
||||
g_assert(!radio_instance_add_death_handler(radio, NULL, NULL));
|
||||
g_assert(!radio_instance_add_enabled_handler(radio, NULL, NULL));
|
||||
g_assert(!radio_instance_add_connected_handler(radio, NULL, NULL));
|
||||
|
||||
/* Formatting unknown codes (RadioInstance owns the string) */
|
||||
g_assert_cmpstr(radio_instance_req_name(radio, UNKNOWN_REQ), == ,
|
||||
@@ -317,6 +334,147 @@ test_basic(
|
||||
gbinder_servicemanager_unref(sm);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* connected
|
||||
*==========================================================================*/
|
||||
|
||||
typedef struct test_connected_data {
|
||||
int observed;
|
||||
int connected;
|
||||
} TestConnected;
|
||||
|
||||
static
|
||||
void
|
||||
test_connected_observer_high(
|
||||
RadioInstance* radio,
|
||||
RADIO_IND code,
|
||||
RADIO_IND_TYPE type,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestConnected* test = user_data;
|
||||
|
||||
g_assert_cmpint(test->observed % 3, == ,0);
|
||||
g_assert(!test->observed || test->connected);
|
||||
test->observed++;
|
||||
GDEBUG_("%d", test->observed);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_connected_observer_default(
|
||||
RadioInstance* radio,
|
||||
RADIO_IND code,
|
||||
RADIO_IND_TYPE type,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestConnected* test = user_data;
|
||||
|
||||
g_assert_cmpint(test->observed % 3, == ,1);
|
||||
g_assert_cmpint(test->connected, == ,1);
|
||||
test->observed++;
|
||||
GDEBUG_("%d", test->observed);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_connected_observer_low(
|
||||
RadioInstance* radio,
|
||||
RADIO_IND code,
|
||||
RADIO_IND_TYPE type,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestConnected* test = user_data;
|
||||
|
||||
g_assert_cmpint(test->observed % 3, == ,2);
|
||||
g_assert_cmpint(test->connected, == ,1);
|
||||
test->observed++;
|
||||
GDEBUG_("%d", test->observed);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_connected_cb(
|
||||
RadioInstance* radio,
|
||||
gpointer user_data)
|
||||
{
|
||||
TestConnected* test = user_data;
|
||||
|
||||
g_assert(!test->connected);
|
||||
test->connected++;
|
||||
GDEBUG_("");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_connected(
|
||||
void)
|
||||
{
|
||||
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
|
||||
GBinderRemoteObject* remote;
|
||||
RadioInstance* radio;
|
||||
TestRadioService service;
|
||||
GBinderClient* ind;
|
||||
GBinderLocalRequest* req;
|
||||
const RADIO_INTERFACE version = RADIO_INTERFACE_1_4;
|
||||
const char* slot = "slot1";
|
||||
const char* fqname = RADIO_1_0 "/slot1";
|
||||
TestConnected test;
|
||||
ulong id[4];
|
||||
|
||||
memset(&test, 0, sizeof(test));
|
||||
|
||||
/* Register the service to create an instance */
|
||||
test_service_init(&service);
|
||||
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
|
||||
radio = radio_instance_new_with_version(DEV, slot, version);
|
||||
g_assert(radio);
|
||||
g_assert(!radio->connected);
|
||||
|
||||
id[0] = radio_instance_add_indication_observer_with_priority(radio,
|
||||
RADIO_INSTANCE_PRIORITY_LOWEST, RADIO_IND_ANY,
|
||||
test_connected_observer_low, &test);
|
||||
id[1] = radio_instance_add_indication_observer(radio,RADIO_IND_ANY,
|
||||
test_connected_observer_default, &test);
|
||||
id[2] = radio_instance_add_indication_observer_with_priority(radio,
|
||||
RADIO_INSTANCE_PRIORITY_HIGHEST + 1 /* becomes HIGHEST */,
|
||||
RADIO_IND_ANY, test_connected_observer_high, &test);
|
||||
id[3] = radio_instance_add_connected_handler(radio, test_connected_cb,
|
||||
&test);
|
||||
|
||||
/* Issue rilConnected */
|
||||
g_assert(service.ind_obj);
|
||||
ind = gbinder_client_new2(service.ind_obj,
|
||||
TEST_ARRAY_AND_COUNT(radio_ind_iface_info));
|
||||
g_assert(ind);
|
||||
req = gbinder_client_new_request2(ind, RADIO_IND_RIL_CONNECTED);
|
||||
gbinder_local_request_append_int32(req, RADIO_IND_ACK_EXP);
|
||||
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
|
||||
RADIO_IND_RIL_CONNECTED, req), == ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(test.observed, == ,3);
|
||||
g_assert_cmpint(test.connected, == ,1);
|
||||
g_assert(radio->connected);
|
||||
|
||||
/* Second time around observer is still called but connect handler isn't */
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(ind,
|
||||
RADIO_IND_RIL_CONNECTED, req), == ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(test.observed, == ,6);
|
||||
g_assert_cmpint(test.connected, == ,1);
|
||||
g_assert(radio->connected);
|
||||
|
||||
gbinder_local_request_unref(req);
|
||||
gbinder_client_unref(ind);
|
||||
|
||||
radio_instance_remove_all_handlers(radio, id);
|
||||
radio_instance_unref(radio);
|
||||
test_service_cleanup(&service);
|
||||
gbinder_remote_object_unref(remote);
|
||||
gbinder_servicemanager_unref(sm);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* ind
|
||||
*==========================================================================*/
|
||||
@@ -446,7 +604,7 @@ test_ind(
|
||||
UNKNOWN_IND, req), == ,GBINDER_STATUS_FAILED);
|
||||
gbinder_local_request_unref(req);
|
||||
gbinder_client_unref(ind);
|
||||
|
||||
|
||||
radio_instance_remove_all_handlers(radio, id);
|
||||
radio_instance_unref(radio);
|
||||
test_service_cleanup(&service);
|
||||
@@ -460,6 +618,20 @@ test_ind(
|
||||
|
||||
#define TEST_REQ RADIO_REQ_DIAL
|
||||
|
||||
static
|
||||
void
|
||||
test_req_observe(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
gpointer user_data)
|
||||
{
|
||||
int* count = user_data;
|
||||
|
||||
(*count)++;
|
||||
GDEBUG_("%d", *count);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_req(
|
||||
@@ -472,14 +644,32 @@ test_req(
|
||||
GBinderRemoteObject* remote;
|
||||
GBinderLocalRequest* req;
|
||||
RadioInstance* radio;
|
||||
int count[3];
|
||||
gulong id[3];
|
||||
|
||||
test_service_init(&service);
|
||||
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
|
||||
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
|
||||
|
||||
memset(count, 0, sizeof(count));
|
||||
id[0] = radio_instance_add_request_observer(radio, RADIO_REQ_ANY,
|
||||
test_req_observe, count + 0);
|
||||
id[1] = radio_instance_add_request_observer(radio, TEST_REQ,
|
||||
test_req_observe, count + 1);
|
||||
id[2] = radio_instance_add_request_observer(radio, TEST_REQ + 1,
|
||||
test_req_observe, count + 2); /* Won't be called */
|
||||
g_assert(id[0]);
|
||||
g_assert(id[1]);
|
||||
g_assert(id[2]);
|
||||
|
||||
req = radio_instance_new_request(radio, TEST_REQ);
|
||||
gbinder_local_request_append_int32(req, 123);
|
||||
g_assert(radio_instance_send_request_sync(radio, TEST_REQ, req));
|
||||
g_assert_cmpint(test_service_req_count(&service, TEST_REQ), == ,1);
|
||||
g_assert_cmpint(count[0], == ,1);
|
||||
g_assert_cmpint(count[1], == ,1);
|
||||
g_assert_cmpint(count[2], == ,0);
|
||||
radio_instance_remove_all_handlers(radio, id);
|
||||
|
||||
radio_instance_unref(radio);
|
||||
test_service_cleanup(&service);
|
||||
@@ -496,7 +686,22 @@ test_req(
|
||||
|
||||
static
|
||||
void
|
||||
test_resp_observe(
|
||||
test_resp_ack_observe(
|
||||
RadioInstance* radio,
|
||||
RADIO_REQ code,
|
||||
GBinderLocalRequest* args,
|
||||
gpointer user_data)
|
||||
{
|
||||
int* count = user_data;
|
||||
|
||||
(*count)++;
|
||||
GDEBUG_("%d", *count);
|
||||
g_assert_cmpint(code, == ,RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_resp_observe1(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
const RadioResponseInfo* info,
|
||||
@@ -505,11 +710,27 @@ test_resp_observe(
|
||||
{
|
||||
guint* expected = user_data;
|
||||
|
||||
GDEBUG("Observing resp %u", code);
|
||||
GDEBUG("Observing resp %u (high prio)", code);
|
||||
g_assert_cmpuint(info->serial, == ,*expected);
|
||||
*expected = 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_resp_observe2(
|
||||
RadioInstance* radio,
|
||||
RADIO_RESP code,
|
||||
const RadioResponseInfo* info,
|
||||
const GBinderReader* reader,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint* expected = user_data;
|
||||
|
||||
/* Serial must be already cleared by test_resp_observe1 */
|
||||
GDEBUG("Observing resp %u (default prio)", code);
|
||||
g_assert_cmpuint(*expected, == ,0);
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
test_resp_handle(
|
||||
@@ -546,7 +767,8 @@ test_resp(
|
||||
RadioResponseInfo info;
|
||||
GBinderWriter writer;
|
||||
guint handle_serial, observe_serial;
|
||||
gulong id[2];
|
||||
int ack_count = 0;
|
||||
gulong id[4];
|
||||
|
||||
test_service_init(&service);
|
||||
|
||||
@@ -558,8 +780,13 @@ test_resp(
|
||||
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
|
||||
id[0] = radio_instance_add_response_handler(radio, TEST_RESP,
|
||||
test_resp_handle, &handle_serial);
|
||||
id[1] = radio_instance_add_response_observer(radio, TEST_RESP,
|
||||
test_resp_observe, &observe_serial);
|
||||
id[1] = radio_instance_add_response_observer_with_priority(radio,
|
||||
RADIO_INSTANCE_PRIORITY_HIGHEST, TEST_RESP,
|
||||
test_resp_observe1, &observe_serial);
|
||||
id[2] = radio_instance_add_response_observer(radio, TEST_RESP,
|
||||
test_resp_observe2, &observe_serial);
|
||||
id[3] = radio_instance_add_request_observer(radio,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT, test_resp_ack_observe, &ack_count);
|
||||
|
||||
g_assert(service.resp_obj);
|
||||
resp = gbinder_client_new2(service.resp_obj,
|
||||
@@ -569,36 +796,52 @@ test_resp(
|
||||
req = gbinder_client_new_request2(resp, TEST_RESP);
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
|
||||
== ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(ack_count, == ,0);
|
||||
g_assert_cmpint(test_service_req_count(&service,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,0);
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,ack_count);
|
||||
|
||||
/* Add the info and try again */
|
||||
gbinder_local_request_init_writer(req, &writer);
|
||||
gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
|
||||
== ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(ack_count, == ,1);
|
||||
g_assert_cmpint(test_service_req_count(&service,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,1);
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,ack_count);
|
||||
g_assert(!handle_serial); /* Cleared by the handler */
|
||||
g_assert(!observe_serial); /* Cleared by the observer */
|
||||
|
||||
/* Remove the handler and check auto-ack */
|
||||
radio_instance_remove_handlers(radio, id, 1);
|
||||
handle_serial = observe_serial = info.serial = 124;
|
||||
|
||||
gbinder_local_request_unref(req);
|
||||
req = gbinder_client_new_request2(resp, TEST_RESP);
|
||||
gbinder_local_request_init_writer(req, &writer);
|
||||
gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
|
||||
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
|
||||
== ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(ack_count, == ,2); /* Acked */
|
||||
g_assert_cmpint(test_service_req_count(&service,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Acked */
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,ack_count);
|
||||
g_assert_cmpuint(handle_serial, == ,info.serial); /* No handler */
|
||||
g_assert(!observe_serial); /* Cleared by the observer */
|
||||
|
||||
/* RADIO_RESP_SOLICITED won't be acked */
|
||||
info.type = RADIO_RESP_SOLICITED;
|
||||
handle_serial = observe_serial = info.serial = 125;
|
||||
|
||||
gbinder_local_request_unref(req);
|
||||
req = gbinder_client_new_request2(resp, TEST_RESP);
|
||||
gbinder_local_request_init_writer(req, &writer);
|
||||
gbinder_writer_append_buffer_object(&writer, &info, sizeof(info));
|
||||
|
||||
g_assert_cmpint(gbinder_client_transact_sync_oneway(resp, TEST_RESP, req),
|
||||
== ,GBINDER_STATUS_OK);
|
||||
g_assert_cmpint(ack_count, == ,2); /* Not acked */
|
||||
g_assert_cmpint(test_service_req_count(&service,
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,2); /* Not acked */
|
||||
RADIO_REQ_RESPONSE_ACKNOWLEDGEMENT), == ,ack_count);
|
||||
g_assert_cmpuint(handle_serial, == ,info.serial); /* No handler */
|
||||
g_assert(!observe_serial); /* Cleared by the observer */
|
||||
|
||||
@@ -688,6 +931,148 @@ test_ack(
|
||||
gbinder_servicemanager_unref(sm);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* send_req
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
test_send_req_complete_cb(
|
||||
RadioInstance* instance,
|
||||
gulong id,
|
||||
int status,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
gulong* expected_id = user_data1;
|
||||
|
||||
GDEBUG("tx %lu completed", id);
|
||||
g_assert_cmpuint(id, == ,*expected_id);
|
||||
*expected_id = 0;
|
||||
test_quit_later((GMainLoop*)user_data2);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_send_req_destroy_cb(
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
gulong* id = user_data1;
|
||||
|
||||
GDEBUG("tx %lu done", *id);
|
||||
g_assert(*id);
|
||||
*id = 0;
|
||||
test_quit_later((GMainLoop*)user_data2);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_send_req_complete_not_reached(
|
||||
RadioInstance* instance,
|
||||
gulong id,
|
||||
int status,
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_send_req_destroy_not_reached(
|
||||
void* user_data1,
|
||||
void* user_data2)
|
||||
{
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
test_send_req(
|
||||
void)
|
||||
{
|
||||
const char* slot = "slot1";
|
||||
const char* fqname = RADIO_1_0 "/slot1";
|
||||
TestRadioService service;
|
||||
GMainLoop* loop = g_main_loop_new(NULL, FALSE);
|
||||
GBinderServiceManager* sm = gbinder_servicemanager_new(DEV);
|
||||
GBinderRemoteObject* remote;
|
||||
GBinderLocalRequest* req;
|
||||
RadioInstance* radio;
|
||||
guint serial = 123;
|
||||
gulong tx;
|
||||
|
||||
test_service_init(&service);
|
||||
remote = test_gbinder_servicemanager_new_service(sm, fqname, service.obj);
|
||||
radio = radio_instance_new_with_version(DEV, slot, RADIO_INTERFACE_1_4);
|
||||
|
||||
/* Submit and wait for the completion callback to be invoked */
|
||||
req = radio_instance_new_request(radio, RADIO_REQ_GET_MUTE);
|
||||
gbinder_local_request_append_int32(req, serial);
|
||||
tx = radio_instance_send_request(radio, RADIO_REQ_GET_MUTE, req,
|
||||
test_send_req_complete_cb, NULL, &tx, loop);
|
||||
gbinder_local_request_unref(req);
|
||||
g_assert(tx);
|
||||
GDEBUG("tx %lu submitted", tx);
|
||||
|
||||
test_run(&test_opt, loop);
|
||||
g_assert(!tx); /* Cleared by the completion handler */
|
||||
|
||||
/* Submit and wait for the destroy callback to be invoked */
|
||||
serial = 124;
|
||||
req = radio_instance_new_request(radio, RADIO_REQ_GET_MUTE);
|
||||
gbinder_local_request_append_int32(req, serial);
|
||||
tx = radio_instance_send_request(radio, RADIO_REQ_GET_MUTE, req,
|
||||
NULL, test_send_req_destroy_cb, &tx, loop);
|
||||
gbinder_local_request_unref(req);
|
||||
g_assert(tx);
|
||||
GDEBUG("tx %lu submitted", tx);
|
||||
|
||||
test_run(&test_opt, loop);
|
||||
g_assert(!tx); /* Cleared by the destroy callback */
|
||||
|
||||
/* Submit, cancel and wait for the destroy callback to be invoked */
|
||||
serial = 125;
|
||||
req = radio_instance_new_request(radio, RADIO_REQ_GET_MUTE);
|
||||
gbinder_local_request_append_int32(req, serial);
|
||||
tx = radio_instance_send_request(radio, RADIO_REQ_GET_MUTE, req,
|
||||
test_send_req_complete_not_reached, test_send_req_destroy_cb,
|
||||
&tx, loop);
|
||||
gbinder_local_request_unref(req);
|
||||
g_assert(tx);
|
||||
GDEBUG("canceling tx %lu and waiting for destroy callback", tx);
|
||||
radio_instance_cancel_request(radio, tx);
|
||||
|
||||
test_run(&test_opt, loop);
|
||||
g_assert(!tx); /* Cleared by the destroy callback */
|
||||
|
||||
/* Submit without callbacks and cancel */
|
||||
req = radio_instance_new_request(radio, RADIO_REQ_GET_MUTE);
|
||||
gbinder_local_request_append_int32(req, serial);
|
||||
tx = radio_instance_send_request(radio, RADIO_REQ_GET_MUTE, req,
|
||||
NULL, NULL, NULL, NULL);
|
||||
gbinder_local_request_unref(req);
|
||||
g_assert(tx);
|
||||
GDEBUG("canceling tx %lu", tx);
|
||||
radio_instance_cancel_request(radio, tx);
|
||||
|
||||
/* radio_instance_send_request() fails if the remote is dead */
|
||||
test_gbinder_remote_object_kill(remote);
|
||||
req = radio_instance_new_request(radio, RADIO_REQ_GET_MUTE);
|
||||
gbinder_local_request_append_int32(req, serial);
|
||||
tx = radio_instance_send_request(radio, RADIO_REQ_GET_MUTE, req,
|
||||
NULL, test_send_req_destroy_not_reached, NULL, NULL);
|
||||
gbinder_local_request_unref(req);
|
||||
g_assert(!tx);
|
||||
|
||||
radio_instance_unref(radio);
|
||||
test_service_cleanup(&service);
|
||||
gbinder_remote_object_unref(remote);
|
||||
gbinder_servicemanager_unref(sm);
|
||||
g_main_loop_unref(loop);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* enabled
|
||||
*==========================================================================*/
|
||||
@@ -801,10 +1186,12 @@ int main(int argc, char* argv[])
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
g_test_add_func(TEST_("null"), test_null);
|
||||
g_test_add_func(TEST_("basic"), test_basic);
|
||||
g_test_add_func(TEST_("connected"), test_connected);
|
||||
g_test_add_func(TEST_("ind"), test_ind);
|
||||
g_test_add_func(TEST_("req"), test_req);
|
||||
g_test_add_func(TEST_("resp"), test_resp);
|
||||
g_test_add_func(TEST_("ack"), test_ack);
|
||||
g_test_add_func(TEST_("send_req"), test_send_req);
|
||||
g_test_add_func(TEST_("enabled"), test_enabled);
|
||||
g_test_add_func(TEST_("death"), test_death);
|
||||
test_init(&test_opt, argc, argv);
|
||||
|
||||
Reference in New Issue
Block a user