mirror of
https://gitlab.com/ubports/development/core/hybris-support/ofono-binder-plugin-ext-qti
synced 2025-11-03 12:35:42 +08:00
src: Add sms support
This commit is contained in:
3
Makefile
3
Makefile
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
408
src/qti_ims_sms.c
Normal 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
38
src/qti_ims_sms.h
Normal 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:
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 ");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user