src: Add sms support

This commit is contained in:
Marius Gripsgard
2025-03-19 03:58:27 +01:00
parent c6a260bac3
commit 82ba26101a
9 changed files with 841 additions and 9 deletions

View File

@@ -41,7 +41,8 @@ SRC = \
qti_plugin.c \
qti_slot.c \
qti_radio_ext.c \
qti_ims_call.c
qti_ims_call.c \
qti_ims_sms.c
#
# Directories

View File

@@ -315,7 +315,7 @@ qti_ims_iface_init(
BinderExtImsInterface* iface)
{
iface->version = BINDER_EXT_IMS_INTERFACE_VERSION;
iface->flags = BINDER_EXT_IMS_INTERFACE_FLAG_VOICE_SUPPORT;
iface->flags = BINDER_EXT_IMS_INTERFACE_FLAG_VOICE_SUPPORT | BINDER_EXT_IMS_INTERFACE_FLAG_SMS_SUPPORT;
iface->get_state = qti_ims_get_state;
iface->set_registration = qti_ims_set_registration;
iface->cancel = qti_ims_cancel;

View File

@@ -31,6 +31,7 @@
#include <gutil_misc.h>
#include <gutil_log.h>
#undef DBG
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "ims:"fmt, ##__VA_ARGS__)

408
src/qti_ims_sms.c Normal file
View File

@@ -0,0 +1,408 @@
/*
* oFono - Open Source Telephony - binder based adaptation QTI plugin
*
* Copyright (C) 2022 Jolla Ltd.
* Copyright (C) 2024 TheKit <thekit@disroot.org>
* Copyright (C) 2024 Marius Gripsgard <marius@ubports.com>
*
* 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 <glib-object.h>
#include "qti_ims_sms.h"
#include "qti_radio_ext.h"
#include "qti_radio_ext_types.h"
#include <binder_ext_sms_impl.h>
#include <ofono/log.h>
#include <radio_client.h>
#include <radio_request.h>
#include <gbinder.h>
#include <gutil_idlepool.h>
#include <gutil_macros.h>
#include <gutil_misc.h>
#include <gutil_log.h>
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "ims:"fmt, ##__VA_ARGS__)
typedef GObjectClass QtiImsSmsClass;
typedef struct qti_ims_sms {
GObject parent;
GUtilIdlePool* pool;
QtiRadioExt* radio_ext;
GPtrArray* sms;
GHashTable* id_map;
} QtiImsSms;
typedef struct qti_ims_sms_result_request {
int ref_count;
guint id;
guint id_mapped;
guint param;
BinderExtSms* ext;
BinderExtSmsSendFunc complete;
GDestroyNotify destroy;
void* user_data;
} QtiImsSmsResultRequest;
static
void
qti_ims_sms_iface_init(
BinderExtSmsInterface* iface);
GType qti_ims_sms_get_type() G_GNUC_INTERNAL;
G_DEFINE_TYPE_WITH_CODE(QtiImsSms, qti_ims_sms, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE(BINDER_EXT_TYPE_SMS, qti_ims_sms_iface_init))
#define THIS_TYPE qti_ims_sms_get_type()
#define THIS(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, THIS_TYPE, QtiImsSms)
#define PARENT_CLASS qti_ims_sms_parent_class
#define ID_KEY(id) GUINT_TO_POINTER(id)
#define ID_VALUE(id) GUINT_TO_POINTER(id)
enum qti_ims_sms_signal {
SIGNAL_SMS_STATE_CHANGED,
SIGNAL_SMS_RECEIVED,
SIGNAL_COUNT
};
#define SIGNAL_SMS_STATE_CHANGED_NAME "qti-ims-sms-state-changed"
#define SIGNAL_SMS_RECEIVED_NAME "qti-ims-sms-received"
static guint qti_ims_sms_signals[SIGNAL_COUNT] = { 0 };
static
QtiImsSmsResultRequest*
qti_ims_sms_result_request_new(
BinderExtSms* self,
BinderExtSmsSendFunc complete,
GDestroyNotify destroy,
void* user_data)
{
QtiImsSmsResultRequest* req =
g_slice_new0(QtiImsSmsResultRequest);
req->ref_count = 1;
req->ext = binder_ext_sms_ref(self);
req->complete = complete;
req->destroy = destroy;
req->user_data = user_data;
return req;
}
static
void
qti_ims_sms_result_request_free(
QtiImsSmsResultRequest* req)
{
BinderExtSms* ext = req->ext;
if (req->destroy) {
req->destroy(req->user_data);
}
if (req->id_mapped) {
g_hash_table_remove(THIS(ext)->id_map, ID_KEY(req->id_mapped));
}
binder_ext_sms_unref(ext);
gutil_slice_free(req);
}
static
gboolean
qti_ims_sms_result_request_unref(
QtiImsSmsResultRequest* req)
{
if (!--(req->ref_count)) {
qti_ims_sms_result_request_free(req);
return TRUE;
} else {
return FALSE;
}
}
static
void
qti_ims_sms_result_request_destroy(
gpointer req)
{
qti_ims_sms_result_request_unref(req);
}
static
void
qti_ims_sms_result_request_response(
QtiRadioExt* radio,
int msg_ref,
GBinderReader* reader,
void* user_data)
{
gint32 result;
GBinderReader r;
QtiImsSmsResultRequest* req = user_data;
BINDER_EXT_SMS_SEND_RESULT send_result;
gbinder_reader_copy(&r, reader);
if (!gbinder_reader_read_int32(&r, &result)) {
ofono_warn("Failed to parse response");
result = QTI_RADIO_SEND_STATUS_ERROR;
}
DBG("qti_ims_sms_result_request_response\n");
DBG("result: %d\n", result);
if (result == QTI_RADIO_SEND_STATUS_OK) {
send_result = BINDER_EXT_SMS_SEND_RESULT_OK;
} else {
send_result = BINDER_EXT_SMS_SEND_RESULT_ERROR;
}
if (req->complete) {
req->complete(req->ext, send_result, 0, req->user_data);
}
}
static
void
qti_ims_sms_incoming_sms_handler(
QtiRadioExt* radio,
const void* pdu,
guint pdu_len,
void* user_data)
{
QtiImsSms* self = user_data;
DBG("Incoming SMS!!!: pdu_len=%d", pdu_len);
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, pdu, pdu_len);
}
/*==========================================================================*
* BinderExtSmsInterface
*==========================================================================*/
static
guint
qti_ims_sms_send(
BinderExtSms* ext,
const char* smsc,
const void* pdu,
gsize pdu_len,
guint msg_ref,
BINDER_EXT_SMS_SEND_FLAGS flags,
BinderExtSmsSendFunc complete,
GDestroyNotify destroy,
void* user_data)
{
QtiImsSms* self = THIS(ext);
QtiImsSmsResultRequest* req = qti_ims_sms_result_request_new(ext,
complete, destroy, user_data);
guint id = qti_radio_ext_send_ims_sms(self->radio_ext, smsc, pdu, pdu_len, msg_ref, flags,
qti_ims_sms_result_request_response, qti_ims_sms_result_request_destroy, req);
DBG("Sending SMS: pdu_len=%u, msg_ref=%u", pdu_len, msg_ref);
if (id) {
req->id = id;
g_hash_table_insert(self->id_map, ID_KEY(id), ID_VALUE(id));
} else {
qti_ims_sms_result_request_free(req);
}
return id;
}
static
void
qti_ims_sms_cancel(
BinderExtSms* ext,
guint id)
{
QtiImsSms* self = THIS(ext);
const guint mapped = GPOINTER_TO_UINT(g_hash_table_lookup(self->id_map,
ID_KEY(id)));
qti_radio_ext_cancel(self->radio_ext, mapped ? mapped : id);
}
static
void
qti_ims_sms_ack_report(
BinderExtSms* ext,
guint msg_ref,
gboolean ok)
{
QtiImsSms* self = THIS(ext);
QtiImsSmsResultRequest* req = qti_ims_sms_result_request_new(ext,
NULL, NULL, NULL);
guint id = qti_radio_ext_acknowledge_sms(self->radio_ext, msg_ref, ok,
qti_ims_sms_result_request_response, qti_ims_sms_result_request_destroy, req);
DBG("Acknowledging SMS report: msg_ref=%u, ok=%d", msg_ref, ok);
if (id) {
req->id = id;
g_hash_table_insert(self->id_map, ID_KEY(id), ID_VALUE(id));
} else {
qti_ims_sms_result_request_free(req);
}
}
static
void
qti_ims_sms_ack_incoming(
BinderExtSms* ext,
gboolean ok)
{
QtiImsSms* self = THIS(ext);
QtiImsSmsResultRequest* req = qti_ims_sms_result_request_new(ext,
NULL, NULL, NULL);
// We *should* have message reference, but we don't
// so we use -1, we have to change upstream to fix this
// TODO: fix this
guint id = qti_radio_ext_acknowledge_sms(self->radio_ext, -1, ok,
qti_ims_sms_result_request_response, qti_ims_sms_result_request_destroy, req);
DBG("Acknowledging incoming SMS: ok=%d", ok);
if (id) {
req->id = id;
g_hash_table_insert(self->id_map, ID_KEY(id), ID_VALUE(id));
} else {
qti_ims_sms_result_request_free(req);
}
}
static
gulong
qti_ims_sms_add_report_handler(
BinderExtSms* ext,
BinderExtSmsReportFunc handler,
void* user_data)
{
return g_signal_connect(ext, SIGNAL_SMS_STATE_CHANGED_NAME, G_CALLBACK(handler), user_data);
}
static
gulong
qti_ims_sms_add_incoming_handler(
BinderExtSms* ext,
BinderExtSmsIncomingFunc handler,
void* user_data)
{
return g_signal_connect(ext, SIGNAL_SMS_RECEIVED_NAME, G_CALLBACK(handler), user_data);
}
static
void
qti_ims_sms_remove_handler(
BinderExtSms* ext,
gulong id)
{
g_signal_handler_disconnect(ext, id);
}
void
qti_ims_sms_iface_init(
BinderExtSmsInterface* iface)
{
iface->flags |= BINDER_EXT_SMS_INTERFACE_FLAG_IMS_SUPPORT |
BINDER_EXT_SMS_INTERFACE_FLAG_IMS_REQUIRED;
iface->version = BINDER_EXT_SMS_INTERFACE_VERSION;
iface->send = qti_ims_sms_send;
iface->cancel = qti_ims_sms_cancel;
iface->ack_report = qti_ims_sms_ack_report;
iface->ack_incoming = qti_ims_sms_ack_incoming;
iface->add_report_handler = qti_ims_sms_add_report_handler;
iface->add_incoming_handler = qti_ims_sms_add_incoming_handler;
iface->remove_handler = qti_ims_sms_remove_handler;
}
/*==========================================================================*
* API
*==========================================================================*/
BinderExtSms*
qti_ims_sms_new(
QtiRadioExt* radio_ext)
{
if (G_LIKELY(radio_ext)) {
QtiImsSms* self = g_object_new(THIS_TYPE, NULL);
self->radio_ext = qti_radio_ext_ref(radio_ext);
self->sms = g_ptr_array_new_with_free_func(g_free);
qti_radio_ext_add_incoming_sms_handler(radio_ext, qti_ims_sms_incoming_sms_handler, self);
return BINDER_EXT_SMS(self);
}
return NULL;
}
/*==========================================================================*
* Internals
*==========================================================================*/
static
void
qti_ims_sms_finalize(
GObject* object)
{
QtiImsSms* self = THIS(object);
qti_radio_ext_unref(self->radio_ext);
gutil_idle_pool_destroy(self->pool);
g_ptr_array_free(self->sms, TRUE);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
static
void
qti_ims_sms_init(
QtiImsSms* self)
{
self->pool = gutil_idle_pool_new();
}
static
void
qti_ims_sms_class_init(
QtiImsSmsClass* klass)
{
GType type = G_OBJECT_CLASS_TYPE(klass);
G_OBJECT_CLASS(klass)->finalize = qti_ims_sms_finalize;
qti_ims_sms_signals[SIGNAL_SMS_STATE_CHANGED] =
g_signal_new(SIGNAL_SMS_STATE_CHANGED_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 0);
qti_ims_sms_signals[SIGNAL_SMS_RECEIVED] =
g_signal_new(SIGNAL_SMS_RECEIVED_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
2, G_TYPE_POINTER, G_TYPE_UINT);
}
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

38
src/qti_ims_sms.h Normal file
View File

@@ -0,0 +1,38 @@
/*
* oFono - Open Source Telephony - binder based adaptation QTI plugin
*
* Copyright (C) 2024 TheKit <thekit@disroot.org>
* Copyright (C) 2024 Marius Gripsgard <marius@ubports.com>
*
* 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 QTI_IMS_SMS_H
#define QTI_IMS_SMS_H
#include <binder_ext_sms.h>
typedef struct qti_radio_ext QtiRadioExt;
typedef struct radio_client RadioClient;
BinderExtSms*
qti_ims_sms_new(
QtiRadioExt* radio_ext)
G_GNUC_INTERNAL;
#endif /* QTI_IMS_SMS_H */
/*
* Local Variables:
* mode: C
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/

View File

@@ -23,8 +23,11 @@
#include <radio_types.h>
#include <binder_ext_ims_impl.h>
#include <binder_ext_call_impl.h>
#include <binder_ext_sms_impl.h>
#include <ofono/log.h>
#include <ofono/misc.h>
#include <gbinder.h>
#include <gutil_idlepool.h>
@@ -93,12 +96,14 @@ enum qti_radio_ext_signal {
SIGNAL_IMS_REG_STATUS_CHANGED,
SIGNAL_EXT_CALL_STATE_CHANGED,
SIGNAL_EXT_ON_RING,
SIGNAL_EXT_ON_INCOMING_SMS,
SIGNAL_COUNT
};
#define SIGNAL_IMS_REG_STATUS_CHANGED_NAME "qti-radio-ext-ims-reg-status-changed"
#define SIGNAL_EXT_CALL_STATE_CHANGED_NAME "qti-radio-ext-call-state-changed"
#define SIGNAL_EXT_ON_RING_NAME "qti-radio-ext-on-ring"
#define SIGNAL_EXT_ON_INCOMING_SMS_NAME "qti-radio-ext-on-incoming-sms"
static guint qti_radio_ext_signals[SIGNAL_COUNT] = { 0 };
@@ -440,6 +445,45 @@ qti_radio_ext_handle_call_state_indication(
}
}
/*
typedef struct qti_radio_incoming_ims_sms {
GBinderHidlString format RADIO_ALIGNED(8);
GBinderHidlVec pdu RADIO_ALIGNED(8);
guint32 verstat RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) QtiRadioIncomingImsSms;
*/
static
void
qti_radio_ext_handle_incoming_sms_indication(
QtiRadioExt* self,
const GBinderReader* args)
{
GBinderReader reader;
QtiRadioIncomingImsSms* sms;
gbinder_reader_copy(&reader, args);
sms = gbinder_reader_read_hidl_struct(&reader, QtiRadioIncomingImsSms);
if (sms) {
const char *format = sms->format.data.str ? sms->format.data.str : "";
const guint32 verstat = sms->verstat;
const guint pdu_len = sms->pdu.count;
const void* pdu = sms->pdu.data.ptr;
// copy pdu to a new buffer
const void* pdu_copy = g_memdup(pdu, pdu_len);
DBG("%s: Incoming SMS indication format:%s verstat:%d pdu_len:%d",
self->slot, format, verstat, pdu_len);
gutil_log_dump(&qti_radio_ext_binder_dump_module, GLOG_LEVEL_VERBOSE, " ", pdu_copy, pdu_len);
g_signal_emit(self, qti_radio_ext_signals[SIGNAL_EXT_ON_INCOMING_SMS], 0, pdu_copy, pdu_len);
} else {
DBG("%s: failed to parse incoming SMS data", self->slot);
}
}
static
GBinderLocalReply*
@@ -482,6 +526,12 @@ qti_radio_ext_indication(
case QTI_RADIO_IND_CALL_STATE_INDICATION_1_2:
qti_radio_ext_handle_call_state_indication(self, &args);
return NULL;
case QTI_RADIO_IND_SMS_STATUS_REPORT_INDICATION:
DBG("SMS status report indication");
return NULL;
case QTI_RADIO_IND_INCOMING_SMS_INDICATION:
qti_radio_ext_handle_incoming_sms_indication(self, &args);
return NULL;
}
}
@@ -518,6 +568,16 @@ qti_radio_ext_add_ring_handler(
SIGNAL_EXT_ON_RING_NAME, G_CALLBACK(handler), user_data) : 0;
}
gulong
qti_radio_ext_add_incoming_sms_handler(
QtiRadioExt* self,
QtiRadioExtIncomingSmsFunc handler,
void* user_data)
{
return (G_LIKELY(self) && G_LIKELY(handler)) ? g_signal_connect(self,
SIGNAL_EXT_ON_INCOMING_SMS_NAME, G_CALLBACK(handler), user_data) : 0;
}
static
GBinderLocalReply*
qti_radio_ext_response(
@@ -1061,8 +1121,6 @@ qti_radio_ext_answer_args(
gint32 presentation = va_arg(va, gint32);
gint32 mode = va_arg(va, gint32);
// answer(CallType callType, IpPresentation presentation, RttMode mode);
gbinder_writer_append_int32(args, call_type);
gbinder_writer_append_int32(args, presentation);
gbinder_writer_append_int32(args, mode);
@@ -1111,7 +1169,6 @@ qti_radio_ext_hangup_args(
qti_radio_hangup_request_info_f
};
// hangup(HangupRequestInfo hangup);
QtiRadioHangupRequestInfo* hangup_request_writer = gbinder_writer_new0(args, QtiRadioHangupRequestInfo);
// empty vec
@@ -1156,7 +1213,126 @@ qti_radio_ext_hangup(
call_id);
}
// GET_IMS_REG_STATE
static
void
qti_radio_ext_send_ims_sms_args(
GBinderWriter* args,
va_list va)
{
const char* smsc = va_arg(va, const char*);
const void* pdu = va_arg(va, const void*);
gsize pdu_len = va_arg(va, gsize);
guint msg_ref = va_arg(va, guint);
BINDER_EXT_SMS_SEND_FLAGS flags = va_arg(va, BINDER_EXT_SMS_SEND_FLAGS);
static const GBinderWriterField qti_radio_ims_sms_message_f[] = {
GBINDER_WRITER_FIELD_HIDL_STRING
(QtiRadioImsSmsMessage, format),
GBINDER_WRITER_FIELD_HIDL_STRING
(QtiRadioImsSmsMessage, smsc),
GBINDER_WRITER_FIELD_HIDL_VEC_BYTE
(QtiRadioImsSmsMessage, pdu),
GBINDER_WRITER_FIELD_END()
};
static const GBinderWriterType qti_radio_ims_sms_message_t = {
GBINDER_WRITER_STRUCT_NAME_AND_SIZE(QtiRadioImsSmsMessage),
qti_radio_ims_sms_message_f
};
QtiRadioImsSmsMessage* sms = gbinder_writer_new0(args, QtiRadioImsSmsMessage);
sms->message_ref = msg_ref;
// I guess?
// we don't need to retry as ofono will handle it
sms->shall_retry = FALSE;
binder_copy_hidl_string(args, &sms->format, "3gpp");
binder_copy_hidl_string(args, &sms->smsc, smsc);
GBinderHidlVec* pdu_vec = gbinder_writer_new0(args, GBinderHidlVec);
pdu_vec->count = pdu_len;
pdu_vec->data.ptr = gbinder_writer_memdup(args, pdu, pdu_len);
pdu_vec->owns_buffer = TRUE;
sms->pdu = *pdu_vec;
gbinder_writer_append_struct(args, sms, &qti_radio_ims_sms_message_t, NULL);
}
guint
qti_radio_ext_send_ims_sms(
QtiRadioExt* self,
const char* smsc,
const void* pdu,
gsize pdu_len,
guint msg_ref,
BINDER_EXT_SMS_SEND_FLAGS flags,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data)
{
return qti_radio_ext_result_request_submit(self,
QTI_RADIO_REQ_SEND_IMS_SMS,
QTI_RADIO_RESP_SEND_IMS_SMS,
qti_radio_ext_send_ims_sms_args,
complete, destroy, user_data,
smsc, pdu, pdu_len, msg_ref, flags);
}
static
void
qti_radio_ext_acknowledge_sms_args(
GBinderWriter* args,
va_list va)
{
guint32 message_ref = va_arg(va, guint32);
guint32 sms_result = va_arg(va, guint32);
gbinder_writer_append_int32(args, message_ref);
gbinder_writer_append_int32(args, sms_result);
}
guint
qti_radio_ext_acknowledge_sms(
QtiRadioExt* self,
guint32 message_ref,
gboolean sms_result,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data)
{
QTI_RADIO_IMS_SMS_DELIVER_STATUS_RESULT sms_result_code = sms_result ? QTI_RADIO_DELIVER_STATUS_OK : QTI_RADIO_DELIVER_STATUS_ERROR;
return qti_radio_ext_result_request_submit(self,
QTI_RADIO_REQ_ACK_SMS,
QTI_RADIO_RESP_ACK_SMS,
qti_radio_ext_acknowledge_sms_args,
complete, destroy, user_data,
message_ref, sms_result_code);
}
guint
qti_radio_ext_acknowledge_sms_report(
QtiRadioExt* self,
guint32 message_ref,
gboolean sms_report,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data)
{
QTI_RADIO_IMS_SMS_STATUS_REPORT_RESULT sms_report_code = sms_report ? QTI_RADIO_STATUS_REPORT_OK : QTI_RADIO_STATUS_REPORT_ERROR;
return qti_radio_ext_result_request_submit(self,
QTI_RADIO_REQ_ACK_SMS_REPORT,
QTI_RADIO_RESP_ACK_SMS_REPORT,
qti_radio_ext_acknowledge_sms_args,
complete, destroy, user_data,
message_ref, sms_report_code);
}
static
void
@@ -1224,6 +1400,10 @@ qti_radio_ext_class_init(
g_signal_new(SIGNAL_EXT_ON_RING_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
0);
qti_radio_ext_signals[SIGNAL_EXT_ON_INCOMING_SMS] =
g_signal_new(SIGNAL_EXT_ON_INCOMING_SMS_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
2, G_TYPE_POINTER, G_TYPE_UINT);
}
/*

View File

@@ -20,6 +20,7 @@
#include <radio_types.h>
#include <binder_ext_ims_impl.h>
#include <binder_ext_call_impl.h>
#include <binder_ext_sms_impl.h>
#include "qti_radio_ext_types.h"
@@ -47,6 +48,13 @@ typedef void (*QtiRadioExtRingFunc)(
QtiRadioExt* radio,
void* user_data);
typedef void (*QtiRadioExtIncomingSmsFunc)(
QtiRadioExt* radio,
const void* pdu,
guint pdu_len,
void* user_data);
QtiRadioExt*
qti_radio_ext_new(
const char* dev,
@@ -107,6 +115,18 @@ qti_radio_ext_hangup(
GDestroyNotify destroy,
void* user_data);
guint
qti_radio_ext_send_ims_sms(
QtiRadioExt* self,
const char* smsc,
const void* pdu,
gsize pdu_len,
guint msg_ref,
BINDER_EXT_SMS_SEND_FLAGS flags,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data);
guint
qti_radio_ext_get_ims_reg_state(
QtiRadioExt* self,
@@ -132,6 +152,30 @@ qti_radio_ext_add_ring_handler(
QtiRadioExtRingFunc handler,
void* user_data);
gulong
qti_radio_ext_add_incoming_sms_handler(
QtiRadioExt* self,
QtiRadioExtIncomingSmsFunc handler,
void* user_data);
guint
qti_radio_ext_acknowledge_sms(
QtiRadioExt* self,
guint32 message_ref,
gboolean sms_result,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data);
guint
qti_radio_ext_acknowledge_sms_report(
QtiRadioExt* self,
guint32 message_ref,
gboolean sms_report,
QtiRadioExtResultFunc complete,
GDestroyNotify destroy,
void* user_data);
#endif /* QTI_RADIO_EXT_H */
/*

View File

@@ -2,6 +2,7 @@
* oFono - Open Source Telephony - binder based adaptation QTI plugin
*
* Copyright (C) 2024 TheKit <thekit@disroot.org>
* Copyright (C) 2024 Marius Gripsgard <marius@ubports.com>
*
* 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
@@ -208,6 +209,157 @@ typedef enum qti_radio_rtt_mode {
QTI_RADIO_RTT_MODE_INVALID = 2,
} QTI_RADIO_RTT_MODE;
/*
enum ImsSmsSendStatusResult : int32_t {
// Message was sent successfully.
SEND_STATUS_OK,
// IMS provider failed to send the message and platform
should not retry falling back to sending the message
using the radio.
SEND_STATUS_ERROR,
// IMS provider failed to send the message and platform
should retry again after setting TP-RD
SEND_STATUS_ERROR_RETRY,
// IMS provider failed to send the message and platform
should retry falling back to sending the message
using the radio.
SEND_STATUS_ERROR_FALLBACK,
};
*/
typedef enum qti_radio_ims_sms_send_status_result {
QTI_RADIO_SEND_STATUS_OK = 0,
QTI_RADIO_SEND_STATUS_ERROR = 1,
QTI_RADIO_SEND_STATUS_ERROR_RETRY = 2,
QTI_RADIO_SEND_STATUS_ERROR_FALLBACK = 3,
} QTI_RADIO_IMS_SMS_SEND_STATUS_RESULT;
/*
enum ImsSmsSendFailureReason : int32_t {
RESULT_ERROR_NONE,
// Generic failure cause
RESULT_ERROR_GENERIC_FAILURE,
// Failed because radio was explicitly turned off
RESULT_ERROR_RADIO_OFF,
// Failed because no pdu provided
RESULT_ERROR_NULL_PDU,
// Failed because service is currently unavailable
RESULT_ERROR_NO_SERVICE,
// Failed because we reached the sending queue limit.
RESULT_ERROR_LIMIT_EXCEEDED,
// Failed because user denied the sending of this short code.
RESULT_ERROR_SHORT_CODE_NOT_ALLOWED,
// Failed because the user has denied this app
ever send premium short codes.
RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED,
};
*/
typedef enum qti_radio_ims_sms_send_failure_reason {
QTI_RADIO_RESULT_ERROR_NONE = 0,
QTI_RADIO_RESULT_ERROR_GENERIC_FAILURE = 1,
QTI_RADIO_RESULT_ERROR_RADIO_OFF = 2,
QTI_RADIO_RESULT_ERROR_NULL_PDU = 3,
QTI_RADIO_RESULT_ERROR_NO_SERVICE = 4,
QTI_RADIO_RESULT_ERROR_LIMIT_EXCEEDED = 5,
QTI_RADIO_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED = 6,
QTI_RADIO_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED = 7,
} QTI_RADIO_IMS_SMS_SEND_FAILURE_REASON;
/*
enum ImsSmsDeliverStatusResult : int32_t {
Message was delivered successfully.
DELIVER_STATUS_OK,
Message was not delivered.
DELIVER_STATUS_ERROR,
};
*/
typedef enum qti_radio_ims_sms_deliver_status_result {
QTI_RADIO_DELIVER_STATUS_OK = 0,
QTI_RADIO_DELIVER_STATUS_ERROR = 1,
} QTI_RADIO_IMS_SMS_DELIVER_STATUS_RESULT;
/*
enum ImsSmsStatusReportResult : int32_t {
// Status Report was set successfully.
STATUS_REPORT_STATUS_OK,
// Error while setting status report
STATUS_REPORT_STATUS_ERROR,
};
*/
typedef enum qti_radio_ims_sms_status_report_result {
QTI_RADIO_STATUS_REPORT_OK = 0,
QTI_RADIO_STATUS_REPORT_ERROR = 1,
} QTI_RADIO_IMS_SMS_STATUS_REPORT_RESULT;
/*
enum VerificationStatus : int32_t {
//Telephone number is not validated.
STATUS_VALIDATION_NONE,
//Telephone number validation passed.
STATUS_VALIDATION_PASS,
// Telephone number validation failed.
STATUS_VALIDATION_FAIL,
};
*/
typedef enum qti_radio_verification_status {
QTI_RADIO_VALIDATION_NONE = 0,
QTI_RADIO_VALIDATION_PASS = 1,
QTI_RADIO_VALIDATION_FAIL = 2,
} QTI_RADIO_VERIFICATION_STATUS;
/*
struct ImsSmsMessage {
uint32_t messageRef;
string format;
string smsc;
bool shallRetry;
vec<uint8_t> pdu;
};
*/
typedef struct qti_radio_ims_sms_message {
guint32 message_ref RADIO_ALIGNED(4);
GBinderHidlString format RADIO_ALIGNED(8);
GBinderHidlString smsc RADIO_ALIGNED(8);
guint8 shall_retry RADIO_ALIGNED(1);
GBinderHidlVec pdu RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) QtiRadioImsSmsMessage;
/*
struct ImsSmsSendStatusReport {
uint32_t messageRef;
string format;
vec<uint8_t> pdu;
};
*/
typedef struct qti_radio_ims_sms_send_status_report {
guint32 message_ref RADIO_ALIGNED(4);
GBinderHidlString format RADIO_ALIGNED(8);
GBinderHidlVec pdu RADIO_ALIGNED(8);
} RADIO_ALIGNED(8) QtiRadioImsSmsSendStatusReport;
/*
struct IncomingImsSms {
string format;
vec<uint8_t> pdu;
VerificationStatus verstat;
};
*/
typedef struct qti_radio_incoming_ims_sms {
GBinderHidlString format RADIO_ALIGNED(8);
GBinderHidlVec pdu RADIO_ALIGNED(8);
guint32 verstat RADIO_ALIGNED(4);
} RADIO_ALIGNED(8) QtiRadioIncomingImsSms;
/*
struct RegistrationInfo {
@@ -216,7 +368,7 @@ struct RegistrationInfo {
string errorMessage;
RadioTechType radioTech;
string pAssociatedUris;
};
};
*/
typedef struct qti_radio_reg_info {
@@ -273,7 +425,7 @@ struct ServiceStatusInfo {
vec<StatusForAccessTech> accTechStatus;
RttMode rttMode;
};
*/
typedef struct qti_radio_service_status_info {
@@ -490,7 +642,10 @@ typedef enum ims_radio_resp {
e(23, callStateChanged_1_1, CALL_STATE_INDICATION_1_1)
#define QTI_RADIO_IND_1_2(e) \
e(24, callStateChanged_1_2, CALL_STATE_INDICATION_1_2)
e(24, callStateChanged_1_2, CALL_STATE_INDICATION_1_2) \
e(25, onImsSmsStatusReport, SMS_STATUS_REPORT_INDICATION) \
e(26, onIncomingImsSms, INCOMING_SMS_INDICATION) \
e(27, onVopsChanged, VOPS_CHANGED_INDICATION)
typedef enum ims_radio_ind {
/* vendor.mediatek.hardware.qtiradioex@3.0::IImsRadioIndication */

View File

@@ -40,6 +40,7 @@
#include "qti_ims.h"
#include "qti_radio_ext.h"
#include "qti_ims_call.h"
#include "qti_ims_sms.h"
#include <binder_ext_slot_impl.h>
@@ -56,6 +57,7 @@ typedef struct qti_slot {
BinderExtIms* ims;
QtiRadioExt* radio_ext;
BinderExtCall* call;
BinderExtSms* sms;
} QtiSlot;
GType qti_slot_get_type() G_GNUC_INTERNAL;
@@ -92,6 +94,8 @@ qti_slot_get_interface(
return self->ims;
} else if (iface == BINDER_EXT_TYPE_CALL) {
return self->call;
} else if (iface == BINDER_EXT_TYPE_SMS) {
return self->sms;
} else {
return BINDER_EXT_SLOT_CLASS(PARENT_CLASS)->get_interface(slot, iface);
}
@@ -123,6 +127,7 @@ qti_slot_new(
if (self->radio_ext) {
self->ims = qti_ims_new(radio_slot, self->radio_ext);
self->call = qti_ims_call_new(self->radio_ext);
self->sms = qti_ims_sms_new(self->radio_ext);
} else {
DBG("slot->radio_ext is null ");
}