9 Commits

Author SHA1 Message Date
Marius Gripsgard
a2220f7ff7 Merge branch 'backports/mr-7/ubports/24.04-1.x' into 'ubports/24.04-1.x'
[ubports/24.04-1.x] Fix incorrect amount of args

See merge request ubports/development/core/hybris-support/ofono-binder-plugin-ext-qti!8
2025-09-08 02:53:20 +00:00
Marius Gripsgard
af6611446b Fix incorrect amount of args
(cherry picked from commit 43010c38ed)
2025-09-08 02:39:01 +00:00
Alfred Neumayer
b5223dd2ea Merge branch 'backports/mr-5/ubports/24.04-1.x' into 'ubports/24.04-1.x'
[ubports/24.04-1.x] Add SMS status report handling support and Implement proper SMS message reference tracking and queueing

See merge request ubports/development/core/hybris-support/ofono-binder-plugin-ext-qti!6
2025-09-07 18:55:16 +00:00
Marius Gripsgard
53af4d002e Address review comments
(cherry picked from commit 7b54162992)
2025-09-07 16:07:24 +00:00
Marius Gripsgard
eb829746bc Fix compiler warnings
(cherry picked from commit cffd140f74)
2025-09-07 16:07:24 +00:00
Marius Gripsgard
c60c48d8f9 ims: Implement proper SMS message reference tracking and queueing
- Add message reference tracking for incoming SMS acknowledgments using FIFO queue
- Implement SMS and report queueing when no handlers are connected
- Add proper SMS status report signal handling (SIGNAL_SMS_REPORT)
- Fix SMS acknowledgment to use proper message references instead of hardcoded -1
- Add handler connection tracking to process queued messages when handlers connect
- Improve memory management with proper cleanup of queues and structures
- Fix format string warnings in debug messages

(cherry picked from commit f7fa1f1fc1)
2025-09-07 16:07:24 +00:00
Marius Gripsgard
f35fcf04e7 radio: Add SMS status report handling support
- Add QtiRadioExtSmsReportFunc typedef for SMS report callbacks
- Add qti_radio_ext_add_sms_report_handler() function
- Implement qti_radio_ext_handle_sms_report_indication() to parse SMS status reports
- Add SIGNAL_EXT_ON_SMS_REPORT signal for SMS status reports
- Enable SMS_STATUS_REPORT_INDICATION handling in indication dispatcher

(cherry picked from commit ea91202d49)
2025-09-07 16:07:24 +00:00
Mike Gabriel
0b26827078 Merge branch 'rpm' into 'main'
This plugin does not require androidproperties/libhybris unlike the mtk plugin this was taken from

See merge request ubports/development/core/hybris-support/ofono-binder-plugin-ext-qti!4
2025-05-25 19:15:19 +00:00
Adam Pigg
c609ee8d84 This plugin does not require androidproperties/libhybris unlike the mtk
plugin this was taken from
2025-05-14 20:35:17 +01:00
7 changed files with 362 additions and 34 deletions

1
debian/control vendored
View File

@@ -9,7 +9,6 @@ Build-Depends: debhelper-compat (= 12),
libgbinder-radio1-dev,
ofono-sailfish-dev (>= 1.29+git8-0ubports1~),
libofonobinderpluginext-dev,
libandroid-properties-dev,
Standards-Version: 3.8.4
Package: ofono-binder-plugin-ext-qti

View File

@@ -14,7 +14,6 @@ BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(libglibutil)
BuildRequires: pkgconfig(libgbinder-radio)
BuildRequires: pkgconfig(libofonobinderpluginext)
BuildRequires: libhybris-devel
%define plugin_dir %(pkg-config ofono --variable=plugindir)
%define config_dir /etc/ofono/binder.d/

View File

@@ -48,6 +48,7 @@
#include <gutil_log.h>
#include <gbinder.h>
#undef DBG
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "ims:"fmt, ##__VA_ARGS__)
@@ -99,7 +100,7 @@ qti_ims_result_request_new(
GDestroyNotify destroy,
void* user_data)
{
QtiImsResultRequest* req = g_slice_new(QtiImsResultRequest);
QtiImsResultRequest* req = g_new(QtiImsResultRequest, 1);
req->ext = binder_ext_ims_ref(ext);
req->complete = complete;
@@ -114,7 +115,7 @@ qti_ims_result_request_free(
QtiImsResultRequest* req)
{
binder_ext_ims_unref(req->ext);
gutil_slice_free(req);
g_free(req);
}
static

View File

@@ -95,7 +95,7 @@ qti_ims_call_result_request_new(
void* user_data)
{
QtiImsCallResultRequest* req =
g_slice_new0(QtiImsCallResultRequest);
g_new0(QtiImsCallResultRequest, 1);
req->ref_count = 1;
req->ext = binder_ext_call_ref(ext);
@@ -119,7 +119,7 @@ qti_ims_call_result_request_free(
g_hash_table_remove(THIS(ext)->id_map, ID_KEY(req->id_mapped));
}
binder_ext_call_unref(ext);
gutil_slice_free(req);
g_free(req);
}
static
@@ -189,7 +189,7 @@ qti_ims_call_handle_call_info(
call->state = info->state;
} else {
// add a new call
BinderExtCallInfo* copy = g_memdup(info, sizeof(BinderExtCallInfo));
BinderExtCallInfo* copy = g_memdup2(info, sizeof(BinderExtCallInfo));
copy->number = g_strdup(info->number);
copy->name = g_strdup(info->name);
g_ptr_array_add(self->calls, copy);

View File

@@ -35,16 +35,38 @@
#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__)
typedef GObjectClass QtiImsSmsClass;
typedef struct qti_ims_sms_pending_ack {
guint msg_ref;
gboolean processed;
} QtiImsSmssPendingAck;
typedef struct qti_ims_sms_queued_incoming {
void* pdu;
guint pdu_len;
guint msg_ref;
} QtiImsSmsQueuedIncoming;
typedef struct qti_ims_sms_queued_report {
void* pdu;
gsize pdu_len;
guint32 message_ref;
} QtiImsSmsQueuedReport;
typedef struct qti_ims_sms {
GObject parent;
GUtilIdlePool* pool;
QtiRadioExt* radio_ext;
GPtrArray* sms;
GHashTable* id_map;
GQueue* pending_ack_queue; /* Queue for incoming SMS message refs (FIFO) */
guint next_msg_ref; /* Counter for generating message references */
GQueue* incoming_queue; /* Queue for incoming SMS when no handlers connected */
GQueue* report_queue; /* Queue for SMS reports when no handlers connected */
} QtiImsSms;
typedef struct qti_ims_sms_result_request {
@@ -75,16 +97,130 @@ G_IMPLEMENT_INTERFACE(BINDER_EXT_TYPE_SMS, qti_ims_sms_iface_init))
#define ID_VALUE(id) GUINT_TO_POINTER(id)
enum qti_ims_sms_signal {
SIGNAL_SMS_STATE_CHANGED,
SIGNAL_SMS_REPORT,
SIGNAL_SMS_RECEIVED,
SIGNAL_COUNT
};
#define SIGNAL_SMS_STATE_CHANGED_NAME "qti-ims-sms-state-changed"
#define SIGNAL_SMS_REPORT_NAME "qti-ims-sms-report"
#define SIGNAL_SMS_RECEIVED_NAME "qti-ims-sms-received"
static guint qti_ims_sms_signals[SIGNAL_COUNT] = { 0 };
static
QtiImsSmssPendingAck*
qti_ims_sms_pending_ack_new(
guint msg_ref)
{
QtiImsSmssPendingAck* ack = g_new0(QtiImsSmssPendingAck, 1);
ack->msg_ref = msg_ref;
ack->processed = FALSE;
return ack;
}
static
void
qti_ims_sms_pending_ack_free(
QtiImsSmssPendingAck* ack)
{
if (ack) {
g_free(ack);
}
}
static
QtiImsSmsQueuedIncoming*
qti_ims_sms_queued_incoming_new(
const void* pdu,
guint pdu_len,
guint msg_ref)
{
QtiImsSmsQueuedIncoming* incoming = g_new0(QtiImsSmsQueuedIncoming, 1);
incoming->pdu = g_memdup2(pdu, pdu_len);
incoming->pdu_len = pdu_len;
incoming->msg_ref = msg_ref;
return incoming;
}
static
void
qti_ims_sms_queued_incoming_free(
QtiImsSmsQueuedIncoming* incoming)
{
if (incoming) {
g_free(incoming->pdu);
g_free(incoming);
}
}
static
QtiImsSmsQueuedReport*
qti_ims_sms_queued_report_new(
const void* pdu,
gsize pdu_len,
guint32 message_ref)
{
QtiImsSmsQueuedReport* report = g_new0(QtiImsSmsQueuedReport, 1);
report->pdu = g_memdup2(pdu, pdu_len);
report->pdu_len = pdu_len;
report->message_ref = message_ref;
return report;
}
static
void
qti_ims_sms_queued_report_free(
QtiImsSmsQueuedReport* report)
{
if (report) {
g_free(report->pdu);
g_free(report);
}
}
static
void
qti_ims_sms_process_queued_incoming(
QtiImsSms* self)
{
QtiImsSmsQueuedIncoming* incoming;
DBG("Processing queued incoming SMS, queue_length=%u",
g_queue_get_length(self->incoming_queue));
while ((incoming = g_queue_pop_head(self->incoming_queue)) != NULL) {
DBG("Processing queued incoming SMS: pdu_len=%u, msg_ref=%u",
incoming->pdu_len, incoming->msg_ref);
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0,
incoming->pdu, incoming->pdu_len);
qti_ims_sms_queued_incoming_free(incoming);
}
}
static
void
qti_ims_sms_process_queued_reports(
QtiImsSms* self)
{
QtiImsSmsQueuedReport* report;
DBG("Processing queued SMS reports, queue_length=%u",
g_queue_get_length(self->report_queue));
while ((report = g_queue_pop_head(self->report_queue)) != NULL) {
DBG("Processing queued SMS report: message_ref=%u, pdu_len=%zu",
report->message_ref, report->pdu_len);
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_REPORT], 0,
report->pdu, report->pdu_len, report->message_ref);
qti_ims_sms_queued_report_free(report);
}
}
static
QtiImsSmsResultRequest*
qti_ims_sms_result_request_new(
@@ -94,7 +230,7 @@ qti_ims_sms_result_request_new(
void* user_data)
{
QtiImsSmsResultRequest* req =
g_slice_new0(QtiImsSmsResultRequest);
g_new0(QtiImsSmsResultRequest, 1);
req->ref_count = 1;
req->ext = binder_ext_sms_ref(self);
@@ -118,7 +254,7 @@ qti_ims_sms_result_request_free(
g_hash_table_remove(THIS(ext)->id_map, ID_KEY(req->id_mapped));
}
binder_ext_sms_unref(ext);
gutil_slice_free(req);
g_free(req);
}
static
@@ -183,13 +319,59 @@ qti_ims_sms_incoming_sms_handler(
guint pdu_len,
void* user_data)
{
QtiImsSms* self = user_data;
QtiImsSms* self = THIS(user_data);
DBG("Incoming SMS!!!: pdu_len=%d", pdu_len);
/* Generate a message reference for this incoming SMS */
guint msg_ref = ++self->next_msg_ref;
/* Store the message reference in the pending ack queue */
QtiImsSmssPendingAck* pending_ack = qti_ims_sms_pending_ack_new(msg_ref);
g_queue_push_tail(self->pending_ack_queue, pending_ack);
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, pdu, pdu_len);
DBG("Incoming SMS: pdu_len=%d, assigned msg_ref=%u, queue_length=%u",
pdu_len, msg_ref, g_queue_get_length(self->pending_ack_queue));
/* Check if there are any connected handlers */
if (g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, FALSE)) {
/* Emit signal immediately if handlers are connected */
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, pdu, pdu_len);
} else {
/* Queue the SMS for later processing */
QtiImsSmsQueuedIncoming* queued = qti_ims_sms_queued_incoming_new(pdu, pdu_len, msg_ref);
g_queue_push_tail(self->incoming_queue, queued);
DBG("No incoming SMS handlers connected, queuing SMS (queue_length=%u)",
g_queue_get_length(self->incoming_queue));
}
}
static
void
qti_ims_sms_report_handler(
QtiRadioExt* radio,
const void* pdu,
gsize pdu_len,
guint32 message_ref,
void* user_data)
{
QtiImsSms* self = user_data;
/* Process the SMS report */
DBG("SMS report: message_ref=%u, pdu_len=%zu", message_ref, pdu_len);
/* Check if there are any connected handlers */
if (g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_REPORT], 0, FALSE)) {
/* Emit signal immediately if handlers are connected */
g_signal_emit(self, qti_ims_sms_signals[SIGNAL_SMS_REPORT], 0, pdu, pdu_len, message_ref);
} else {
/* Queue the report for later processing */
QtiImsSmsQueuedReport* queued = qti_ims_sms_queued_report_new(pdu, pdu_len, message_ref);
g_queue_push_tail(self->report_queue, queued);
DBG("No SMS report handlers connected, queuing report (queue_length=%u)",
g_queue_get_length(self->report_queue));
}
}
/*==========================================================================*
* BinderExtSmsInterface
@@ -215,7 +397,7 @@ qti_ims_sms_send(
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);
DBG("Sending SMS: pdu_len=%zu, msg_ref=%u", pdu_len, msg_ref);
if (id) {
req->id = id;
@@ -272,18 +454,30 @@ qti_ims_sms_ack_incoming(
gboolean ok)
{
QtiImsSms* self = THIS(ext);
QtiImsSmssPendingAck* pending_ack;
guint msg_ref = 0;
/* Get the next pending acknowledgment from the queue (FIFO) */
pending_ack = g_queue_pop_head(self->pending_ack_queue);
if (pending_ack) {
msg_ref = pending_ack->msg_ref;
qti_ims_sms_pending_ack_free(pending_ack);
DBG("Acknowledging incoming SMS from queue: msg_ref=%u, ok=%d, remaining_queue_length=%u",
msg_ref, ok, g_queue_get_length(self->pending_ack_queue));
} else {
/* Fallback to the old behavior if queue is empty */
msg_ref = -1;
DBG("No pending SMS in queue, using fallback msg_ref=-1, ok=%d", ok);
}
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,
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 incoming SMS: ok=%d", ok);
if (id) {
req->id = id;
g_hash_table_insert(self->id_map, ID_KEY(id), ID_VALUE(id));
@@ -299,7 +493,21 @@ qti_ims_sms_add_report_handler(
BinderExtSmsReportFunc handler,
void* user_data)
{
return g_signal_connect(ext, SIGNAL_SMS_STATE_CHANGED_NAME, G_CALLBACK(handler), user_data);
QtiImsSms* self = THIS(ext);
DBG("Adding SMS report handler");
/* Check if this is the first handler being added */
gboolean had_handlers = g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_REPORT], 0, FALSE);
gulong id = g_signal_connect(ext, SIGNAL_SMS_REPORT_NAME, G_CALLBACK(handler), user_data);
/* Process any queued reports if this is the first handler */
if (!had_handlers) {
qti_ims_sms_process_queued_reports(self);
}
return id;
}
static
@@ -309,7 +517,21 @@ qti_ims_sms_add_incoming_handler(
BinderExtSmsIncomingFunc handler,
void* user_data)
{
return g_signal_connect(ext, SIGNAL_SMS_RECEIVED_NAME, G_CALLBACK(handler), user_data);
QtiImsSms* self = THIS(ext);
DBG("Adding incoming SMS handler");
/* Check if this is the first handler being added */
gboolean had_handlers = g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, FALSE);
gulong id = g_signal_connect(ext, SIGNAL_SMS_RECEIVED_NAME, G_CALLBACK(handler), user_data);
/* Process any queued SMS if this is the first handler */
if (!had_handlers) {
qti_ims_sms_process_queued_incoming(self);
}
return id;
}
static
@@ -318,7 +540,18 @@ qti_ims_sms_remove_handler(
BinderExtSms* ext,
gulong id)
{
QtiImsSms* self = THIS(ext);
g_signal_handler_disconnect(ext, id);
/* Log status for debugging */
if (!g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_RECEIVED], 0, FALSE)) {
DBG("No more incoming SMS handlers connected");
}
if (!g_signal_has_handler_pending(self, qti_ims_sms_signals[SIGNAL_SMS_REPORT], 0, FALSE)) {
DBG("No more SMS report handlers connected");
}
}
void
@@ -350,8 +583,13 @@ qti_ims_sms_new(
self->radio_ext = qti_radio_ext_ref(radio_ext);
self->sms = g_ptr_array_new_with_free_func(g_free);
self->pending_ack_queue = g_queue_new();
self->incoming_queue = g_queue_new();
self->report_queue = g_queue_new();
self->next_msg_ref = 0;
qti_radio_ext_add_incoming_sms_handler(radio_ext, qti_ims_sms_incoming_sms_handler, self);
qti_radio_ext_add_sms_report_handler(radio_ext, qti_ims_sms_report_handler, self);
return BINDER_EXT_SMS(self);
}
@@ -368,9 +606,26 @@ qti_ims_sms_finalize(
GObject* object)
{
QtiImsSms* self = THIS(object);
/* Clean up the pending ack queue */
if (self->pending_ack_queue) {
g_queue_free_full(self->pending_ack_queue, (GDestroyNotify)qti_ims_sms_pending_ack_free);
}
/* Clean up the incoming SMS queue */
if (self->incoming_queue) {
g_queue_free_full(self->incoming_queue, (GDestroyNotify)qti_ims_sms_queued_incoming_free);
}
/* Clean up the SMS report queue */
if (self->report_queue) {
g_queue_free_full(self->report_queue, (GDestroyNotify)qti_ims_sms_queued_report_free);
}
qti_radio_ext_unref(self->radio_ext);
gutil_idle_pool_destroy(self->pool);
g_ptr_array_free(self->sms, TRUE);
g_hash_table_destroy(self->id_map);
G_OBJECT_CLASS(PARENT_CLASS)->finalize(object);
}
@@ -380,6 +635,7 @@ qti_ims_sms_init(
QtiImsSms* self)
{
self->pool = gutil_idle_pool_new();
self->id_map = g_hash_table_new(g_direct_hash, g_direct_equal);
}
static
@@ -390,9 +646,10 @@ qti_ims_sms_class_init(
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_REPORT] =
g_signal_new(SIGNAL_SMS_REPORT_NAME, type,
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2
, G_TYPE_POINTER, G_TYPE_UINT);
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,

View File

@@ -34,6 +34,7 @@
#include <gutil_log.h>
#include <gutil_macros.h>
#undef DBG
#define DBG(fmt, ...) \
gutil_log(GLOG_MODULE_CURRENT, GLOG_LEVEL_ALWAYS, "ims:"fmt, ##__VA_ARGS__)
@@ -97,6 +98,7 @@ enum qti_radio_ext_signal {
SIGNAL_EXT_CALL_STATE_CHANGED,
SIGNAL_EXT_ON_RING,
SIGNAL_EXT_ON_INCOMING_SMS,
SIGNAL_EXT_ON_SMS_REPORT,
SIGNAL_COUNT
};
@@ -104,6 +106,7 @@ enum qti_radio_ext_signal {
#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"
#define SIGNAL_EXT_ON_SMS_REPORT_NAME "qti-radio-ext-on-sms-report"
static guint qti_radio_ext_signals[SIGNAL_COUNT] = { 0 };
@@ -404,14 +407,14 @@ qti_ims_call_info_new(
static
GPtrArray*
qti_radio_ext_read_call_state_info(
QtiRadioCallInfo* call_info_array,
const QtiRadioCallInfo* call_info_array,
gsize count)
{
// array of QtiRadioCallInfo
GPtrArray* call_ext_info_array = g_ptr_array_new_with_free_func(g_free);
for (gsize i = 0; i < count; i++) {
QtiRadioCallInfo* call_info = &call_info_array[i];
const QtiRadioCallInfo* call_info = &call_info_array[i];
BinderExtCallInfo* dest = qti_ims_call_info_new(call_info->index, call_info->state, call_info->number, call_info->name);
g_ptr_array_add(call_ext_info_array, dest);
@@ -428,7 +431,7 @@ qti_radio_ext_handle_call_state_indication(
const GBinderReader* args)
{
/* callInfoIndication(vec<CallInfo> callList) */
QtiRadioCallInfo* call_infos;
const QtiRadioCallInfo* call_infos;
GBinderReader reader;
gsize count;
@@ -460,7 +463,7 @@ qti_radio_ext_handle_incoming_sms_indication(
const GBinderReader* args)
{
GBinderReader reader;
QtiRadioIncomingImsSms* sms;
const QtiRadioIncomingImsSms* sms;
gbinder_reader_copy(&reader, args);
sms = gbinder_reader_read_hidl_struct(&reader, QtiRadioIncomingImsSms);
@@ -472,7 +475,7 @@ qti_radio_ext_handle_incoming_sms_indication(
const void* pdu = sms->pdu.data.ptr;
// copy pdu to a new buffer
const void* pdu_copy = g_memdup(pdu, pdu_len);
const void* pdu_copy = g_memdup2(pdu, pdu_len);
DBG("%s: Incoming SMS indication format:%s verstat:%d pdu_len:%d",
self->slot, format, verstat, pdu_len);
@@ -484,6 +487,48 @@ qti_radio_ext_handle_incoming_sms_indication(
}
}
/*
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;
*/
// implement sms report
static
void
qti_radio_ext_handle_sms_report_indication(
QtiRadioExt* self,
const GBinderReader* args)
{
GBinderReader reader;
const QtiRadioImsSmsSendStatusReport* report;
gbinder_reader_copy(&reader, args);
report = gbinder_reader_read_hidl_struct(&reader, QtiRadioImsSmsSendStatusReport);
if (report) {
const guint32 message_ref = report->message_ref;
const char *format = report->format.data.str ? report->format.data.str : "";
const guint32 pdu_len = report->pdu.count;
const void* pdu = report->pdu.data.ptr;
// copy pdu to a new buffer
const void* pdu_copy = g_memdup2(pdu, pdu_len);
DBG("%s: SMS status report indication message_ref:%d format:%s pdu_len:%d",
self->slot, message_ref, format, 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_SMS_REPORT], 0, pdu_copy, pdu_len, message_ref);
} else {
DBG("%s: failed to parse SMS status report data", self->slot);
}
}
static
GBinderLocalReply*
@@ -527,7 +572,7 @@ qti_radio_ext_indication(
qti_radio_ext_handle_call_state_indication(self, &args);
return NULL;
case QTI_RADIO_IND_SMS_STATUS_REPORT_INDICATION:
DBG("SMS status report indication");
qti_radio_ext_handle_sms_report_indication(self, &args);
return NULL;
case QTI_RADIO_IND_INCOMING_SMS_INDICATION:
qti_radio_ext_handle_incoming_sms_indication(self, &args);
@@ -578,6 +623,16 @@ qti_radio_ext_add_incoming_sms_handler(
SIGNAL_EXT_ON_INCOMING_SMS_NAME, G_CALLBACK(handler), user_data) : 0;
}
gulong
qti_radio_ext_add_sms_report_handler(
QtiRadioExt* self,
QtiRadioExtSmsReportFunc handler,
void* user_data)
{
return (G_LIKELY(self) && G_LIKELY(handler)) ? g_signal_connect(self,
SIGNAL_EXT_ON_SMS_REPORT_NAME, G_CALLBACK(handler), user_data) : 0;
}
static
GBinderLocalReply*
qti_radio_ext_response(
@@ -1246,8 +1301,8 @@ qti_radio_ext_send_ims_sms_args(
sms->message_ref = msg_ref;
// I guess?
// we don't need to retry as ofono will handle it
sms->shall_retry = FALSE;
// True if BINDER_EXT_SMS_SEND_RETRY is set
sms->shall_retry = BINDER_EXT_SMS_SEND_RETRY == (flags & BINDER_EXT_SMS_SEND_RETRY);
binder_copy_hidl_string(args, &sms->format, "3gpp");
binder_copy_hidl_string(args, &sms->smsc, smsc);
@@ -1404,6 +1459,10 @@ qti_radio_ext_class_init(
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);
qti_radio_ext_signals[SIGNAL_EXT_ON_SMS_REPORT] =
g_signal_new(SIGNAL_EXT_ON_SMS_REPORT_NAME, G_OBJECT_CLASS_TYPE(klass),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
3, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT);
}
/*

View File

@@ -55,6 +55,13 @@ typedef void (*QtiRadioExtIncomingSmsFunc)(
guint pdu_len,
void* user_data);
typedef void (*QtiRadioExtSmsReportFunc)(
QtiRadioExt* radio,
const void* pdu,
gsize pdu_len,
guint32 message_ref,
void* user_data);
QtiRadioExt*
qti_radio_ext_new(
const char* dev,
@@ -158,6 +165,12 @@ qti_radio_ext_add_incoming_sms_handler(
QtiRadioExtIncomingSmsFunc handler,
void* user_data);
gulong
qti_radio_ext_add_sms_report_handler(
QtiRadioExt* self,
QtiRadioExtSmsReportFunc handler,
void* user_data);
guint
qti_radio_ext_acknowledge_sms(
QtiRadioExt* self,