[ofono-binder] Extension for voice calls. JB#57724
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -2,3 +2,11 @@
|
||||
build
|
||||
unit/coverage/*.gcov
|
||||
unit/coverage/report
|
||||
debian/.debhelper
|
||||
debian/files
|
||||
debian/*.debhelper.log
|
||||
debian/*.install
|
||||
debian/*.substvars
|
||||
debian/libofonobinderpluginext-dev
|
||||
debian/libofonobinderpluginext
|
||||
debian/tmp
|
||||
|
||||
@@ -46,6 +46,7 @@ LIB = $(LIB_NAME).a
|
||||
#
|
||||
|
||||
SRC = \
|
||||
binder_ext_call.c \
|
||||
binder_ext_plugin.c \
|
||||
binder_ext_slot.c \
|
||||
binder_ext_sms.c
|
||||
|
||||
309
lib/include/binder_ext_call.h
Normal file
309
lib/include/binder_ext_call.h
Normal file
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef BINDER_EXT_CALL_H
|
||||
#define BINDER_EXT_CALL_H
|
||||
|
||||
#include "binder_ext_types.h"
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef enum binder_ext_call_interface_flags {
|
||||
BINDER_EXT_CALL_INTERFACE_NO_FLAGS = 0,
|
||||
BINDER_EXT_CALL_INTERFACE_FLAG_IMS_SUPPORT = 0x01,
|
||||
BINDER_EXT_CALL_INTERFACE_FLAG_IMS_REQUIRED = 0x02
|
||||
} BINDER_EXT_CALL_INTERFACE_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_type {
|
||||
BINDER_EXT_CALL_TYPE_UNKNOWN,
|
||||
BINDER_EXT_CALL_TYPE_VOICE
|
||||
} BINDER_EXT_CALL_TYPE;
|
||||
|
||||
typedef enum binder_ext_call_state {
|
||||
BINDER_EXT_CALL_STATE_INVALID = -1,
|
||||
BINDER_EXT_CALL_STATE_ACTIVE,
|
||||
BINDER_EXT_CALL_STATE_HOLDING,
|
||||
BINDER_EXT_CALL_STATE_DIALING,
|
||||
BINDER_EXT_CALL_STATE_ALERTING,
|
||||
BINDER_EXT_CALL_STATE_INCOMING,
|
||||
BINDER_EXT_CALL_STATE_WAITING
|
||||
} BINDER_EXT_CALL_STATE;
|
||||
|
||||
typedef enum binder_ext_call_flags {
|
||||
BINDER_EXT_CALL_FLAGS_NONE = 0,
|
||||
BINDER_EXT_CALL_FLAG_INCOMING = 0x0001,
|
||||
BINDER_EXT_CALL_FLAG_EMERGENCY = 0x0002,
|
||||
BINDER_EXT_CALL_FLAG_ENCRYPTED = 0x0004,
|
||||
BINDER_EXT_CALL_FLAG_MPTY = 0x0008,
|
||||
BINDER_EXT_CALL_FLAG_RTT = 0x0010,
|
||||
BINDER_EXT_CALL_FLAG_IMS = 0x0020
|
||||
} BINDER_EXT_CALL_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_direction {
|
||||
BINDER_EXT_CALL_DIRECTION_NONE,
|
||||
BINDER_EXT_CALL_DIRECTION_RECEIVE,
|
||||
BINDER_EXT_CALL_DIRECTION_SEND,
|
||||
BINDER_EXT_CALL_DIRECTION_SEND_RECEIVE
|
||||
} BINDER_EXT_CALL_DIRECTION;
|
||||
|
||||
typedef enum binder_ext_call_clir {
|
||||
BINDER_EXT_CALL_CLIR_DEFAULT,
|
||||
BINDER_EXT_CALL_CLIR_INVOCATION, /* Restrict CLI presentation */
|
||||
BINDER_EXT_CALL_CLIR_SUPPRESSION /* Allow CLI presentation */
|
||||
} BINDER_EXT_CALL_CLIR;
|
||||
|
||||
typedef enum binder_ext_call_hangup_reason {
|
||||
BINDER_EXT_CALL_HANGUP_TERMINATE,
|
||||
BINDER_EXT_CALL_HANGUP_IGNORE,
|
||||
BINDER_EXT_CALL_HANGUP_REJECT
|
||||
} BINDER_EXT_CALL_HANGUP_REASON;
|
||||
|
||||
typedef enum binder_ext_call_disconnect_reason {
|
||||
BINDER_EXT_CALL_DISCONNECT_UNKNOWN,
|
||||
BINDER_EXT_CALL_DISCONNECT_LOCAL,
|
||||
BINDER_EXT_CALL_DISCONNECT_REMOTE,
|
||||
BINDER_EXT_CALL_DISCONNECT_ERROR
|
||||
} BINDER_EXT_CALL_DISCONNECT_REASON;
|
||||
|
||||
typedef enum binder_ext_call_result {
|
||||
BINDER_EXT_CALL_RESULT_OK = 0,
|
||||
BINDER_EXT_CALL_RESULT_ERROR
|
||||
} BINDER_EXT_CALL_RESULT;
|
||||
|
||||
typedef enum binder_ext_call_dial_flags {
|
||||
BINDER_EXT_CALL_DIAL_FLAGS_NONE = 0
|
||||
} BINDER_EXT_CALL_DIAL_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_deflect_flags {
|
||||
BINDER_EXT_CALL_DEFLECT_FLAGS_NONE = 0
|
||||
} BINDER_EXT_CALL_DEFLECT_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_answer_flags {
|
||||
BINDER_EXT_CALL_ANSWER_NO_FLAGS = 0,
|
||||
BINDER_EXT_CALL_ANSWER_FLAG_RTT = 0x01 /* Enable Real-Time Text */
|
||||
} BINDER_EXT_CALL_ANSWER_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_transfer_flags {
|
||||
BINDER_EXT_CALL_TRANSFER_FLAGS_NONE = 0
|
||||
} BINDER_EXT_CALL_TRANSFER_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_conference_flags {
|
||||
BINDER_EXT_CALL_CONFERENCE_FLAGS_NONE = 0
|
||||
} BINDER_EXT_CALL_CONFERENCE_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_hangup_flags {
|
||||
BINDER_EXT_CALL_HANGUP_NO_FLAGS = 0
|
||||
} BINDER_EXT_CALL_HANGUP_FLAGS;
|
||||
|
||||
typedef enum binder_ext_call_swap_flags {
|
||||
BINDER_EXT_CALL_SWAP_NO_FLAGS = 0,
|
||||
BINDER_EXT_CALL_SWAP_FLAG_HANGUP = 0x01 /* Hangup active call */
|
||||
} BINDER_EXT_CALL_SWAP_FLAGS;
|
||||
|
||||
typedef struct binder_ext_call_supp_svc_notify {
|
||||
gboolean mt;
|
||||
int code;
|
||||
int index;
|
||||
BINDER_EXT_TOA type; /* MT only */
|
||||
const char* number; /* MT only */
|
||||
} BinderExtCallSuppSvcNotify;
|
||||
|
||||
typedef struct binder_ext_call_info {
|
||||
guint call_id;
|
||||
BINDER_EXT_CALL_TYPE type;
|
||||
BINDER_EXT_CALL_STATE state;
|
||||
BINDER_EXT_CALL_FLAGS flags;
|
||||
BINDER_EXT_TOA toa;
|
||||
const char* number;
|
||||
const char* name;
|
||||
} BinderExtCallInfo;
|
||||
|
||||
typedef
|
||||
void
|
||||
(*BinderExtCallResultFunc)(
|
||||
BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_RESULT result,
|
||||
void* user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*BinderExtCallFunc)(
|
||||
BinderExtCall* ext,
|
||||
void* user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*BinderExtCallSuppSvcNotifyFunc)(
|
||||
BinderExtCall* ext,
|
||||
const BinderExtCallSuppSvcNotify* ssn,
|
||||
void* user_data);
|
||||
|
||||
typedef
|
||||
void
|
||||
(*BinderExtCallDisconnectFunc)(
|
||||
BinderExtCall* ext,
|
||||
guint call_id,
|
||||
BINDER_EXT_CALL_DISCONNECT_REASON reason,
|
||||
void* user_data);
|
||||
|
||||
GType binder_ext_call_get_type(void);
|
||||
#define BINDER_EXT_TYPE_CALL (binder_ext_call_get_type())
|
||||
#define BINDER_EXT_CALL(obj) (G_TYPE_CHECK_INSTANCE_CAST(obj, \
|
||||
BINDER_EXT_TYPE_CALL, BinderExtCall))
|
||||
|
||||
BinderExtCall*
|
||||
binder_ext_call_ref(
|
||||
BinderExtCall* ext);
|
||||
|
||||
void
|
||||
binder_ext_call_unref(
|
||||
BinderExtCall* ext);
|
||||
|
||||
BINDER_EXT_CALL_INTERFACE_FLAGS
|
||||
binder_ext_call_get_interface_flags(
|
||||
BinderExtCall* ext);
|
||||
|
||||
const BinderExtCallInfo* const*
|
||||
binder_ext_call_get_calls(
|
||||
BinderExtCall* ext);
|
||||
|
||||
guint
|
||||
binder_ext_call_dial(
|
||||
BinderExtCall* ext,
|
||||
const char* number,
|
||||
BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_CLIR clir,
|
||||
BINDER_EXT_CALL_DIAL_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_deflect(
|
||||
BinderExtCall* ext,
|
||||
const char* number,
|
||||
BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_DEFLECT_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_answer(
|
||||
BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_ANSWER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_swap(
|
||||
BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_SWAP_FLAGS swap_flags,
|
||||
BINDER_EXT_CALL_ANSWER_FLAGS answer_flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_transfer(
|
||||
BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_TRANSFER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_conference(
|
||||
BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_CONFERENCE_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_send_dtmf(
|
||||
BinderExtCall* ext,
|
||||
const char* tones,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
guint
|
||||
binder_ext_call_hangup(
|
||||
BinderExtCall* ext,
|
||||
guint call_id,
|
||||
BINDER_EXT_CALL_HANGUP_REASON reason,
|
||||
BINDER_EXT_CALL_HANGUP_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
|
||||
void
|
||||
binder_ext_call_cancel(
|
||||
BinderExtCall* ext,
|
||||
guint id);
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_calls_changed_handler(
|
||||
BinderExtCall* ext,
|
||||
BinderExtCallFunc handler,
|
||||
void* user_data);
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_disconnect_handler(
|
||||
BinderExtCall* ext,
|
||||
BinderExtCallDisconnectFunc handler,
|
||||
void* user_data);
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_ring_handler(
|
||||
BinderExtCall* ext,
|
||||
BinderExtCallFunc handler,
|
||||
void* user_data);
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_ssn_handler(
|
||||
BinderExtCall* ext,
|
||||
BinderExtCallSuppSvcNotifyFunc handler,
|
||||
void* user_data);
|
||||
|
||||
void
|
||||
binder_ext_call_remove_handler(
|
||||
BinderExtCall* ext,
|
||||
gulong id);
|
||||
|
||||
void
|
||||
binder_ext_call_remove_handlers(
|
||||
BinderExtCall* ext,
|
||||
gulong* ids,
|
||||
guint count);
|
||||
|
||||
#define binder_ext_call_remove_all_handlers(ext, ids) \
|
||||
binder_ext_call_remove_handlers(ext, ids, G_N_ELEMENTS(ids))
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* BINDER_EXT_CALL_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
110
lib/include/binder_ext_call_impl.h
Normal file
110
lib/include/binder_ext_call_impl.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef BINDER_EXT_CALL_IMPL_H
|
||||
#define BINDER_EXT_CALL_IMPL_H
|
||||
|
||||
#include "binder_ext_call.h"
|
||||
|
||||
/* Internal API for use by BinderExtCall implemenations */
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define BINDER_EXT_CALL_INTERFACE_VERSION 1
|
||||
|
||||
/*
|
||||
* Implementation sets field to BINDER_EXT_CALL_INTERFACE_VERSION.
|
||||
*
|
||||
* It allows more callbacks to be added to BinderExtCallInterface
|
||||
* in the future. If the vtable gets extended, the version field will be
|
||||
* used to figure out the size of the (possibly smaller) vtable which
|
||||
* the implementation was compiled against.
|
||||
*
|
||||
* But let's hope that we will never run out of the reserved fields.
|
||||
*/
|
||||
typedef struct binder_ext_call_interface {
|
||||
GTypeInterface parent;
|
||||
BINDER_EXT_CALL_INTERFACE_FLAGS flags;
|
||||
int version;
|
||||
|
||||
const BinderExtCallInfo* const* (*get_calls)(BinderExtCall* ext);
|
||||
guint (*dial)(BinderExtCall* ext, const char* number, BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_CLIR clir, BINDER_EXT_CALL_DIAL_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*deflect)(BinderExtCall* ext, const char* number, BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_DEFLECT_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*answer)(BinderExtCall* ext, BINDER_EXT_CALL_ANSWER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*swap)(BinderExtCall* ext, BINDER_EXT_CALL_SWAP_FLAGS swap_flags,
|
||||
BINDER_EXT_CALL_ANSWER_FLAGS answer_flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*transfer)(BinderExtCall* ext, BINDER_EXT_CALL_TRANSFER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*conference)(BinderExtCall* ext,
|
||||
BINDER_EXT_CALL_CONFERENCE_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*send_dtmf)(BinderExtCall* ext, const char* tones,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
guint (*hangup)(BinderExtCall* ext, guint call_id,
|
||||
BINDER_EXT_CALL_HANGUP_REASON reason,
|
||||
BINDER_EXT_CALL_HANGUP_FLAGS flags,
|
||||
BinderExtCallResultFunc complete, GDestroyNotify destroy,
|
||||
void* user_data);
|
||||
void (*cancel)(BinderExtCall* ext, guint id);
|
||||
gulong (*add_calls_changed_handler)(BinderExtCall* ext,
|
||||
BinderExtCallFunc handler, void* user_data);
|
||||
gulong (*add_disconnect_handler)(BinderExtCall* ext,
|
||||
BinderExtCallDisconnectFunc handler, void* user_data);
|
||||
gulong (*add_ring_handler)(BinderExtCall* ext,
|
||||
BinderExtCallFunc handler, void* user_data);
|
||||
gulong (*add_ssn_handler)(BinderExtCall* ext,
|
||||
BinderExtCallSuppSvcNotifyFunc handler, void* user_data);
|
||||
void (*remove_handler)(BinderExtCall* ext, gulong id);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_reserved1)(void);
|
||||
void (*_reserved2)(void);
|
||||
void (*_reserved3)(void);
|
||||
void (*_reserved4)(void);
|
||||
void (*_reserved5)(void);
|
||||
void (*_reserved6)(void);
|
||||
void (*_reserved7)(void);
|
||||
void (*_reserved8)(void);
|
||||
void (*_reserved9)(void);
|
||||
void (*_reserved10)(void);
|
||||
} BinderExtCallInterface;
|
||||
|
||||
#define BINDER_EXT_CALL_GET_IFACE(obj) G_TYPE_INSTANCE_GET_INTERFACE(obj,\
|
||||
BINDER_EXT_TYPE_CALL, BinderExtCallInterface)
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* BINDER_EXT_CALL_IMPL_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -20,9 +20,17 @@
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct binder_ext_sms BinderExtSms;
|
||||
typedef struct binder_ext_call BinderExtCall;
|
||||
typedef struct binder_ext_plugin BinderExtPlugin;
|
||||
typedef struct binder_ext_slot BinderExtSlot;
|
||||
typedef struct binder_ext_sms BinderExtSms;
|
||||
|
||||
/* Type of address, 3GPP TS 24.008 subclause 10.5.4.7 */
|
||||
typedef enum binder_ext_toa {
|
||||
BINDER_EXT_TOA_LOCAL = 129,
|
||||
BINDER_EXT_TOA_INTERNATIONAL = 145,
|
||||
BINDER_EXT_TOA_UNKNOWN = 0x7fffffff
|
||||
} BINDER_EXT_TOA;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
380
lib/src/binder_ext_call.c
Normal file
380
lib/src/binder_ext_call.c
Normal file
@@ -0,0 +1,380 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "binder_ext_call_impl.h"
|
||||
|
||||
G_DEFINE_INTERFACE(BinderExtCall, binder_ext_call, G_TYPE_OBJECT)
|
||||
#define GET_IFACE(obj) BINDER_EXT_CALL_GET_IFACE(obj)
|
||||
|
||||
/*==========================================================================*
|
||||
* API
|
||||
*==========================================================================*/
|
||||
|
||||
BinderExtCall*
|
||||
binder_ext_call_ref(
|
||||
BinderExtCall* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_ref(self);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
binder_ext_call_unref(
|
||||
BinderExtCall* self)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
g_object_unref(self);
|
||||
}
|
||||
}
|
||||
|
||||
BINDER_EXT_CALL_INTERFACE_FLAGS
|
||||
binder_ext_call_get_interface_flags(
|
||||
BinderExtCall* self)
|
||||
{
|
||||
return G_LIKELY(self) ? GET_IFACE(self)->flags :
|
||||
BINDER_EXT_CALL_INTERFACE_NO_FLAGS;
|
||||
}
|
||||
|
||||
const BinderExtCallInfo* const*
|
||||
binder_ext_call_get_calls(
|
||||
BinderExtCall* self)
|
||||
{
|
||||
static const BinderExtCallInfo* none = NULL;
|
||||
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->get_calls) {
|
||||
const BinderExtCallInfo* const* calls = iface->get_calls(self);
|
||||
|
||||
if (calls) {
|
||||
return calls;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function never returns NULL */
|
||||
return &none;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_dial(
|
||||
BinderExtCall* self,
|
||||
const char* number,
|
||||
BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_CLIR clir,
|
||||
BINDER_EXT_CALL_DIAL_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(number)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->dial) {
|
||||
return iface->dial(self, number, toa, clir, flags, complete,
|
||||
destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_deflect(
|
||||
BinderExtCall* self,
|
||||
const char* number,
|
||||
BINDER_EXT_TOA toa,
|
||||
BINDER_EXT_CALL_DEFLECT_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(number)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->deflect) {
|
||||
return iface->deflect(self, number, toa, flags, complete,
|
||||
destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_answer(
|
||||
BinderExtCall* self,
|
||||
BINDER_EXT_CALL_ANSWER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->answer) {
|
||||
return iface->answer(self, flags, complete, destroy, data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_swap(
|
||||
BinderExtCall* self,
|
||||
BINDER_EXT_CALL_SWAP_FLAGS swap_flags,
|
||||
BINDER_EXT_CALL_ANSWER_FLAGS answer_flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->swap) {
|
||||
return iface->swap(self, swap_flags, answer_flags, complete,
|
||||
destroy, data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_transfer(
|
||||
BinderExtCall* self,
|
||||
BINDER_EXT_CALL_TRANSFER_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->transfer) {
|
||||
return iface->transfer(self, flags, complete, destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_conference(
|
||||
BinderExtCall* self,
|
||||
BINDER_EXT_CALL_CONFERENCE_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->conference) {
|
||||
return iface->conference(self, flags, complete, destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_send_dtmf(
|
||||
BinderExtCall* self,
|
||||
const char* tones,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(tones)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->send_dtmf) {
|
||||
return iface->send_dtmf(self, tones, complete, destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
guint
|
||||
binder_ext_call_hangup(
|
||||
BinderExtCall* self,
|
||||
guint call_id,
|
||||
BINDER_EXT_CALL_HANGUP_REASON reason,
|
||||
BINDER_EXT_CALL_HANGUP_FLAGS flags,
|
||||
BinderExtCallResultFunc complete,
|
||||
GDestroyNotify destroy,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->hangup) {
|
||||
return iface->hangup(self, call_id, reason, flags, complete,
|
||||
destroy, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
binder_ext_call_cancel(
|
||||
BinderExtCall* self,
|
||||
guint id)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(id)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->cancel) {
|
||||
iface->cancel(self, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_calls_changed_handler(
|
||||
BinderExtCall* self,
|
||||
BinderExtCallFunc handler,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->add_calls_changed_handler) {
|
||||
iface->add_calls_changed_handler(self, handler, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_disconnect_handler(
|
||||
BinderExtCall* self,
|
||||
BinderExtCallDisconnectFunc handler,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->add_disconnect_handler) {
|
||||
iface->add_disconnect_handler(self, handler, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_ring_handler(
|
||||
BinderExtCall* self,
|
||||
BinderExtCallFunc handler,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->add_ring_handler) {
|
||||
iface->add_ring_handler(self, handler, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gulong
|
||||
binder_ext_call_add_ssn_handler(
|
||||
BinderExtCall* self,
|
||||
BinderExtCallSuppSvcNotifyFunc handler,
|
||||
void* user_data)
|
||||
{
|
||||
if (G_LIKELY(self)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
|
||||
if (iface->add_ssn_handler) {
|
||||
iface->add_ssn_handler(self, handler, user_data);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
binder_ext_call_remove_handler(
|
||||
BinderExtCall* self,
|
||||
gulong id)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(id)) {
|
||||
/*
|
||||
* Since we provide the default callback, we can safely assume
|
||||
* that remove_handler is always there.
|
||||
*/
|
||||
GET_IFACE(self)->remove_handler(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
binder_ext_call_remove_handlers(
|
||||
BinderExtCall* self,
|
||||
gulong* ids,
|
||||
guint count)
|
||||
{
|
||||
if (G_LIKELY(self) && G_LIKELY(ids) && G_LIKELY(count)) {
|
||||
BinderExtCallInterface* iface = GET_IFACE(self);
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Since we provide the default callback, we can safely assume
|
||||
* that remove_handler is always there.
|
||||
*/
|
||||
for (i = 0; i < count; i++) {
|
||||
if (ids[i]) {
|
||||
iface->remove_handler(self, ids[i]);
|
||||
ids[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
* Internals
|
||||
*==========================================================================*/
|
||||
|
||||
static
|
||||
void
|
||||
binder_ext_call_default_remove_handler(
|
||||
BinderExtCall* self,
|
||||
gulong id)
|
||||
{
|
||||
if (id) {
|
||||
g_signal_handler_disconnect(self, id);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ext_call_default_init(
|
||||
BinderExtCallInterface* iface)
|
||||
{
|
||||
/*
|
||||
* Assume the smallest interface version. Implementation must overwrite
|
||||
* iface->version with BINDER_EXT_CALL_INTERFACE_VERSION known to it at
|
||||
* the compile time.
|
||||
*/
|
||||
iface->version = 1;
|
||||
iface->remove_handler = binder_ext_call_default_remove_handler;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: C
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "binder_modem.h"
|
||||
#include "binder_util.h"
|
||||
|
||||
#include "binder_ext_call.h"
|
||||
#include "binder_ext_slot.h"
|
||||
#include "binder_ext_sms.h"
|
||||
|
||||
@@ -114,10 +115,17 @@ binder_ims_probe(
|
||||
if (binder_ext_sms_get_interface_flags
|
||||
(binder_ext_slot_get_interface(modem->ext, BINDER_EXT_TYPE_SMS)) &
|
||||
BINDER_EXT_SMS_INTERFACE_FLAG_IMS_SUPPORT) {
|
||||
DBG_(self, "ims sms seems to be supported");
|
||||
DBG_(self, "ims sms support is detected");
|
||||
self->caps |= OFONO_IMS_SMS_CAPABLE;
|
||||
}
|
||||
|
||||
if (binder_ext_call_get_interface_flags
|
||||
(binder_ext_slot_get_interface(modem->ext, BINDER_EXT_TYPE_CALL)) &
|
||||
BINDER_EXT_CALL_INTERFACE_FLAG_IMS_SUPPORT) {
|
||||
DBG_(self, "ims call support is detected");
|
||||
self->caps |= OFONO_IMS_VOICE_CAPABLE;
|
||||
}
|
||||
|
||||
self->start_id = g_idle_add(binder_ims_start, self);
|
||||
ofono_ims_set_data(ims, self);
|
||||
return 0;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user