Merge pull request #40 from monich/jb62411-1
Respect sms and voice IMS caps
This commit is contained in:
150
src/binder_ims.c
150
src/binder_ims.c
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -19,36 +20,20 @@
|
||||
#include "binder_modem.h"
|
||||
#include "binder_util.h"
|
||||
|
||||
#include "binder_ext_call.h"
|
||||
#include "binder_ext_ims.h"
|
||||
#include "binder_ext_slot.h"
|
||||
#include "binder_ext_sms.h"
|
||||
|
||||
#include <ofono/ims.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include <gutil_macros.h>
|
||||
|
||||
enum binder_ims_events {
|
||||
EVENT_IMS_REGISTRATION_CHANGED,
|
||||
EVENT_COUNT
|
||||
};
|
||||
|
||||
enum binder_ims_ext_events {
|
||||
IMS_EXT_STATE_CHANGED,
|
||||
IMS_EXT_EVENT_COUNT
|
||||
};
|
||||
|
||||
typedef struct binder_ims {
|
||||
struct ofono_ims* ims;
|
||||
struct ofono_ims* handle;
|
||||
char* log_prefix;
|
||||
BinderImsReg* reg;
|
||||
BinderImsReg* ims;
|
||||
BinderExtIms* ext;
|
||||
gulong radio_event[EVENT_COUNT];
|
||||
gulong ext_event[IMS_EXT_EVENT_COUNT];
|
||||
gulong event_id;
|
||||
guint ext_req_id;
|
||||
guint start_id;
|
||||
int caps;
|
||||
} BinderIms;
|
||||
|
||||
typedef struct binder_ims_cbd {
|
||||
@@ -59,8 +44,8 @@ typedef struct binder_ims_cbd {
|
||||
|
||||
#define DBG_(self,fmt,args...) DBG("%s" fmt, (self)->log_prefix, ##args)
|
||||
|
||||
static inline BinderIms* binder_ims_get_data(struct ofono_ims* ims)
|
||||
{ return ofono_ims_get_data(ims); }
|
||||
static inline BinderIms* binder_ims_get_data(struct ofono_ims* handle)
|
||||
{ return ofono_ims_get_data(handle); }
|
||||
|
||||
static
|
||||
BinderImsCbData*
|
||||
@@ -105,29 +90,15 @@ binder_ims_register_complete(
|
||||
cbd->cb(&err, cbd->cb_data);
|
||||
}
|
||||
|
||||
static
|
||||
gboolean
|
||||
binder_ims_is_registered(
|
||||
BinderIms* self)
|
||||
{
|
||||
if (self->ext) {
|
||||
return binder_ext_ims_get_state(self->ext) ==
|
||||
BINDER_EXT_IMS_STATE_REGISTERED;
|
||||
} else if (self->reg) {
|
||||
return self->reg->registered;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_notify(
|
||||
BinderIms* self)
|
||||
{
|
||||
const gboolean registered = binder_ims_is_registered(self);
|
||||
BinderImsReg* ims = self->ims;
|
||||
|
||||
ofono_ims_status_notify(self->ims, registered, registered ? self->caps : 0);
|
||||
ofono_ims_status_notify(self->handle, ims->registered,
|
||||
ims->registered ? ims->caps : 0);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -140,30 +111,19 @@ binder_ims_registration_changed(
|
||||
BinderIms* self = user_data;
|
||||
|
||||
DBG_(self, "");
|
||||
binder_ims_notify(self);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_ext_state_changed(
|
||||
BinderExtIms* ext,
|
||||
void* user_data)
|
||||
{
|
||||
BinderIms* self = user_data;
|
||||
|
||||
DBG_(self, "");
|
||||
GASSERT(property == BINDER_IMS_REG_PROPERTY_REGISTERED);
|
||||
binder_ims_notify(self);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_control(
|
||||
struct ofono_ims* ims,
|
||||
struct ofono_ims* handle,
|
||||
BINDER_EXT_IMS_REGISTRATION registration,
|
||||
ofono_ims_register_cb_t cb,
|
||||
void* data)
|
||||
{
|
||||
BinderIms* self = binder_ims_get_data(ims);
|
||||
BinderIms* self = binder_ims_get_data(handle);
|
||||
struct ofono_error err;
|
||||
|
||||
if (self->ext) {
|
||||
@@ -185,35 +145,36 @@ binder_ims_control(
|
||||
static
|
||||
void
|
||||
binder_ims_register(
|
||||
struct ofono_ims* ims,
|
||||
struct ofono_ims* handle,
|
||||
ofono_ims_register_cb_t cb,
|
||||
void* data)
|
||||
{
|
||||
binder_ims_control(ims, BINDER_EXT_IMS_REGISTRATION_ON, cb, data);
|
||||
binder_ims_control(handle, BINDER_EXT_IMS_REGISTRATION_ON, cb, data);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_unregister(
|
||||
struct ofono_ims* ims,
|
||||
struct ofono_ims* handle,
|
||||
ofono_ims_register_cb_t cb,
|
||||
void* data)
|
||||
{
|
||||
binder_ims_control(ims, BINDER_EXT_IMS_REGISTRATION_OFF, cb, data);
|
||||
binder_ims_control(handle, BINDER_EXT_IMS_REGISTRATION_OFF, cb, data);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_registration_status(
|
||||
struct ofono_ims* ims,
|
||||
struct ofono_ims* handle,
|
||||
ofono_ims_status_cb_t cb,
|
||||
void* data)
|
||||
{
|
||||
BinderIms* self = binder_ims_get_data(ims);
|
||||
const gboolean registered = binder_ims_is_registered(self);
|
||||
BinderIms* self = binder_ims_get_data(handle);
|
||||
BinderImsReg* ims = self->ims;
|
||||
struct ofono_error err;
|
||||
|
||||
cb(binder_error_ok(&err), registered, registered ? self->caps : 0, data);
|
||||
cb(binder_error_ok(&err), ims->registered,
|
||||
ims->registered ? ims->caps : 0, data);
|
||||
}
|
||||
|
||||
static
|
||||
@@ -227,27 +188,19 @@ binder_ims_start(
|
||||
GASSERT(self->start_id);
|
||||
self->start_id = 0;
|
||||
|
||||
if (self->ext) {
|
||||
self->ext_event[IMS_EXT_STATE_CHANGED] =
|
||||
binder_ext_ims_add_state_handler(self->ext,
|
||||
binder_ims_ext_state_changed, self);
|
||||
}
|
||||
GASSERT(!self->event_id);
|
||||
self->event_id = binder_ims_reg_add_property_handler(self->ims,
|
||||
BINDER_IMS_REG_PROPERTY_REGISTERED, binder_ims_registration_changed,
|
||||
self);
|
||||
|
||||
if (!self->ext_event[IMS_EXT_STATE_CHANGED]) {
|
||||
self->radio_event[EVENT_IMS_REGISTRATION_CHANGED] =
|
||||
binder_ims_reg_add_property_handler(self->reg,
|
||||
BINDER_IMS_REG_PROPERTY_REGISTERED,
|
||||
binder_ims_registration_changed, self);
|
||||
}
|
||||
|
||||
ofono_ims_register(self->ims);
|
||||
ofono_ims_register(self->handle);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
binder_ims_probe(
|
||||
struct ofono_ims* ims,
|
||||
struct ofono_ims* handle,
|
||||
void* data)
|
||||
{
|
||||
BinderModem* modem = binder_modem_get_data(data);
|
||||
@@ -256,51 +209,19 @@ binder_ims_probe(
|
||||
self->log_prefix = binder_dup_prefix(modem->log_prefix);
|
||||
DBG_(self, "");
|
||||
|
||||
self->reg = binder_ims_reg_ref(modem->ims);
|
||||
self->ims = ims;
|
||||
|
||||
if (modem->ext && (self->ext =
|
||||
binder_ext_slot_get_interface(modem->ext,
|
||||
BINDER_EXT_TYPE_IMS)) != NULL) {
|
||||
BINDER_EXT_IMS_INTERFACE_FLAGS flags =
|
||||
binder_ext_ims_get_interface_flags(self->ext);
|
||||
|
||||
DBG_(self, "using ims extension");
|
||||
binder_ext_ims_ref(self->ext);
|
||||
if (flags & BINDER_EXT_IMS_INTERFACE_FLAG_SMS_SUPPORT) {
|
||||
DBG_(self, "ims sms support is detected");
|
||||
self->caps |= OFONO_IMS_SMS_CAPABLE;
|
||||
}
|
||||
if (flags & BINDER_EXT_IMS_INTERFACE_FLAG_VOICE_SUPPORT) {
|
||||
DBG_(self, "ims call support is detected");
|
||||
self->caps |= OFONO_IMS_VOICE_CAPABLE;
|
||||
}
|
||||
} else {
|
||||
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 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->handle = handle;
|
||||
self->ims = binder_ims_reg_ref(modem->ims);
|
||||
self->start_id = g_idle_add(binder_ims_start, self);
|
||||
ofono_ims_set_data(ims, self);
|
||||
ofono_ims_set_data(handle, self);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_remove(
|
||||
struct ofono_ims* ims)
|
||||
struct ofono_ims* handle)
|
||||
{
|
||||
BinderIms* self = binder_ims_get_data(ims);
|
||||
BinderIms* self = binder_ims_get_data(handle);
|
||||
|
||||
DBG_(self, "");
|
||||
|
||||
@@ -309,18 +230,17 @@ binder_ims_remove(
|
||||
}
|
||||
|
||||
if (self->ext) {
|
||||
binder_ext_ims_remove_all_handlers(self->ext, self->ext_event);
|
||||
binder_ext_ims_cancel(self->ext, self->ext_req_id);
|
||||
binder_ext_ims_unref(self->ext);
|
||||
}
|
||||
|
||||
binder_ims_reg_remove_all_handlers(self->reg, self->radio_event);
|
||||
binder_ims_reg_unref(self->reg);
|
||||
binder_ims_reg_remove_handler(self->ims, self->event_id);
|
||||
binder_ims_reg_unref(self->ims);
|
||||
|
||||
g_free(self->log_prefix);
|
||||
g_free(self);
|
||||
|
||||
ofono_ims_set_data(ims, NULL);
|
||||
ofono_ims_set_data(handle, NULL);
|
||||
}
|
||||
|
||||
/*==========================================================================*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,8 +19,10 @@
|
||||
#include "binder_log.h"
|
||||
#include "binder_util.h"
|
||||
|
||||
#include "binder_ext_call.h"
|
||||
#include "binder_ext_ims.h"
|
||||
#include "binder_ext_slot.h"
|
||||
#include "binder_ext_sms.h"
|
||||
|
||||
#include <radio_client.h>
|
||||
#include <radio_request.h>
|
||||
@@ -27,6 +30,8 @@
|
||||
|
||||
#include <radio_network_types.h>
|
||||
|
||||
#include <ofono/ims.h>
|
||||
|
||||
#include <gbinder_reader.h>
|
||||
#include <gutil_macros.h>
|
||||
#include <gutil_misc.h>
|
||||
@@ -84,14 +89,11 @@ binder_ims_reg_query_done(
|
||||
BinderBase* base = &self->base;
|
||||
BinderImsReg* ims = &self->pub;
|
||||
gboolean registered = FALSE;
|
||||
guint32 code =
|
||||
radio_client_aidl_interface(self->g->client) == RADIO_NETWORK_INTERFACE ?
|
||||
RADIO_NETWORK_RESP_GET_IMS_REGISTRATION_STATE :
|
||||
RADIO_RESP_GET_IMS_REGISTRATION_STATE;
|
||||
|
||||
if (status != RADIO_TX_STATUS_OK) {
|
||||
ofono_error("getImsRegistrationState failed");
|
||||
} else if (resp != code) {
|
||||
} else if (resp != RADIO_RESP_GET_IMS_REGISTRATION_STATE &&
|
||||
resp != RADIO_NETWORK_RESP_GET_IMS_REGISTRATION_STATE) {
|
||||
ofono_error("Unexpected getImsRegistrationState response %d", resp);
|
||||
} else if (error != RADIO_ERROR_NONE) {
|
||||
DBG_(self, "%s", binder_radio_error_string(error));
|
||||
@@ -126,13 +128,12 @@ void
|
||||
binder_ims_reg_query(
|
||||
BinderImsRegObject* self)
|
||||
{
|
||||
guint32 code =
|
||||
radio_client_aidl_interface(self->g->client) == RADIO_NETWORK_INTERFACE ?
|
||||
RadioRequestGroup* g = self->g;
|
||||
RadioRequest* req = radio_request_new2(g,
|
||||
radio_client_aidl_interface(g->client) == RADIO_NETWORK_INTERFACE ?
|
||||
RADIO_NETWORK_REQ_GET_IMS_REGISTRATION_STATE :
|
||||
RADIO_REQ_GET_IMS_REGISTRATION_STATE;
|
||||
RadioRequest* req = radio_request_new2(self->g,
|
||||
code, NULL,
|
||||
binder_ims_reg_query_done, NULL, self);
|
||||
RADIO_REQ_GET_IMS_REGISTRATION_STATE,
|
||||
NULL, binder_ims_reg_query_done, NULL, self);
|
||||
|
||||
radio_request_submit(req);
|
||||
radio_request_unref(req);
|
||||
@@ -154,7 +155,7 @@ binder_ims_reg_state_changed(
|
||||
|
||||
static
|
||||
void
|
||||
binder_ims_ext_update_state(
|
||||
binder_ims_reg_update_state(
|
||||
BinderImsRegObject* self)
|
||||
{
|
||||
const BINDER_EXT_IMS_STATE state = binder_ext_ims_get_state(self->ext);
|
||||
@@ -177,7 +178,7 @@ binder_ims_ext_state_changed(
|
||||
{
|
||||
BinderImsRegObject* self = THIS(user_data);
|
||||
|
||||
binder_ims_ext_update_state(self);
|
||||
binder_ims_reg_update_state(self);
|
||||
binder_base_emit_queued_signals(&self->base);
|
||||
}
|
||||
|
||||
@@ -198,28 +199,59 @@ binder_ims_reg_new(
|
||||
|
||||
ims = &self->pub;
|
||||
self->log_prefix = binder_dup_prefix(log_prefix);
|
||||
self->ext = binder_ext_ims_ref(binder_ext_slot_get_interface(ext_slot,
|
||||
BINDER_EXT_TYPE_IMS));
|
||||
self->ext = binder_ext_slot_get_interface(ext_slot,
|
||||
BINDER_EXT_TYPE_IMS);
|
||||
|
||||
if (self->ext) {
|
||||
BINDER_EXT_IMS_INTERFACE_FLAGS flags =
|
||||
binder_ext_ims_get_interface_flags(self->ext);
|
||||
|
||||
DBG_(self, "using ims ext");
|
||||
binder_ims_ext_update_state(self);
|
||||
binder_ext_ims_ref(self->ext);
|
||||
|
||||
/* Query flags from the extension */
|
||||
if (flags & BINDER_EXT_IMS_INTERFACE_FLAG_SMS_SUPPORT) {
|
||||
DBG_(self, "ims sms support is detected");
|
||||
ims->caps |= OFONO_IMS_SMS_CAPABLE;
|
||||
}
|
||||
if (flags & BINDER_EXT_IMS_INTERFACE_FLAG_VOICE_SUPPORT) {
|
||||
DBG_(self, "ims call support is detected");
|
||||
ims->caps |= OFONO_IMS_VOICE_CAPABLE;
|
||||
}
|
||||
|
||||
binder_ims_reg_update_state(self);
|
||||
|
||||
/* Register event handler */
|
||||
self->ext_event_id[EVENT_EXT_IMS_STATE_CHANGED] =
|
||||
binder_ext_ims_add_state_handler(self->ext,
|
||||
binder_ims_ext_state_changed, self);
|
||||
} else {
|
||||
guint32 code =
|
||||
radio_client_aidl_interface(client) == RADIO_NETWORK_INTERFACE ?
|
||||
RADIO_NETWORK_IND_IMS_NETWORK_STATE_CHANGED :
|
||||
RADIO_IND_IMS_NETWORK_STATE_CHANGED;
|
||||
DBG_(self, "using ims radio api");
|
||||
self->g = radio_request_group_new(client); /* Keeps ref to client */
|
||||
|
||||
/* Initialize the flags based on which interfaces are supported */
|
||||
if (binder_ext_sms_get_interface_flags
|
||||
(binder_ext_slot_get_interface(ext_slot,
|
||||
BINDER_EXT_TYPE_SMS)) &
|
||||
BINDER_EXT_SMS_INTERFACE_FLAG_IMS_SUPPORT) {
|
||||
DBG_(self, "ims sms support is detected");
|
||||
ims->caps |= OFONO_IMS_SMS_CAPABLE;
|
||||
}
|
||||
if (binder_ext_call_get_interface_flags
|
||||
(binder_ext_slot_get_interface(ext_slot,
|
||||
BINDER_EXT_TYPE_CALL)) &
|
||||
BINDER_EXT_CALL_INTERFACE_FLAG_IMS_SUPPORT) {
|
||||
DBG_(self, "ims call support is detected");
|
||||
ims->caps |= OFONO_IMS_VOICE_CAPABLE;
|
||||
}
|
||||
|
||||
/* Register event handler */
|
||||
self->event_id[EVENT_IMS_NETWORK_STATE_CHANGED] =
|
||||
radio_client_add_indication_handler(client,
|
||||
code,
|
||||
radio_client_aidl_interface(client) ==
|
||||
RADIO_NETWORK_INTERFACE ?
|
||||
RADIO_NETWORK_IND_IMS_NETWORK_STATE_CHANGED :
|
||||
RADIO_IND_IMS_NETWORK_STATE_CHANGED,
|
||||
binder_ims_reg_state_changed, self);
|
||||
|
||||
/* Query the initial state */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/*
|
||||
* oFono - Open Source Telephony - binder based adaptation
|
||||
*
|
||||
* Copyright (C) 2024 Slava Monich <slava@monich.com>
|
||||
* Copyright (C) 2022 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -29,6 +30,7 @@ typedef enum binder_ims_reg_property {
|
||||
|
||||
struct binder_ims_reg {
|
||||
gboolean registered;
|
||||
int caps; /* OFONO_IMS_xxx bits */
|
||||
};
|
||||
|
||||
typedef
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "binder_ext_slot.h"
|
||||
#include "binder_ext_sms.h"
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/ims.h>
|
||||
#include <ofono/misc.h>
|
||||
#include <ofono/sim.h>
|
||||
#include <ofono/sms.h>
|
||||
@@ -375,7 +375,8 @@ gboolean
|
||||
binder_sms_can_send_ims_message(
|
||||
BinderSms* self)
|
||||
{
|
||||
return self->ims_reg && self->ims_reg->registered;
|
||||
return self->ims_reg && self->ims_reg->registered &&
|
||||
(self->ims_reg->caps & OFONO_IMS_SMS_CAPABLE);
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "binder_ext_slot.h"
|
||||
#include "binder_ext_call.h"
|
||||
|
||||
#include <ofono/log.h>
|
||||
#include <ofono/ims.h>
|
||||
#include <ofono/misc.h>
|
||||
#include <ofono/voicecall.h>
|
||||
|
||||
@@ -1030,7 +1030,8 @@ binder_voicecall_can_ext_dial(
|
||||
{
|
||||
return self->ext && (!(binder_ext_call_get_interface_flags
|
||||
(self->ext) & BINDER_EXT_CALL_INTERFACE_FLAG_IMS_REQUIRED) ||
|
||||
(self->ims_reg && self->ims_reg->registered));
|
||||
(self->ims_reg && self->ims_reg->registered &&
|
||||
(self->ims_reg->caps & OFONO_IMS_VOICE_CAPABLE)));
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
Reference in New Issue
Block a user