diff --git a/src/qti_ims.c b/src/qti_ims.c index c11c229..6fee976 100644 --- a/src/qti_ims.c +++ b/src/qti_ims.c @@ -48,6 +48,7 @@ #include #include +#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 diff --git a/src/qti_ims_call.c b/src/qti_ims_call.c index fa6b2af..f19a801 100644 --- a/src/qti_ims_call.c +++ b/src/qti_ims_call.c @@ -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); diff --git a/src/qti_ims_sms.c b/src/qti_ims_sms.c index 4c033fc..3549c00 100644 --- a/src/qti_ims_sms.c +++ b/src/qti_ims_sms.c @@ -35,16 +35,38 @@ #include #include +#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, diff --git a/src/qti_radio_ext.c b/src/qti_radio_ext.c index 5c730de..aab55a8 100644 --- a/src/qti_radio_ext.c +++ b/src/qti_radio_ext.c @@ -34,6 +34,7 @@ #include #include +#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 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, + 4, G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_UINT); } /* diff --git a/src/qti_radio_ext.h b/src/qti_radio_ext.h index 67ee233..d045f86 100644 --- a/src/qti_radio_ext.h +++ b/src/qti_radio_ext.h @@ -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,