[ofono-binder] Extension for voice calls. JB#57724

This commit is contained in:
Slava Monich
2022-03-19 01:23:25 +02:00
parent 040f3ba35f
commit 7a5f48005e
8 changed files with 1830 additions and 286 deletions

8
.gitignore vendored
View File

@@ -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

View File

@@ -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

View 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:
*/

View 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:
*/

View File

@@ -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
View 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:
*/

View File

@@ -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