From 5d1e364340221fb7729d87f99dbf4b21f2bab688 Mon Sep 17 00:00:00 2001 From: Frederic LE FOLL Date: Mon, 2 Oct 2023 18:51:51 +0200 Subject: [PATCH] SETUP or RELEASE retransmission: resend UUI in retransmitted message When retransmitting a message, libpri currently does not include User-user Information IE, because storage field was cleared at first transmission. This fix introduces a retransmission cache for information lost after first transmission. It applies to potentially retransmitted messages: SETUP and RELEASE. Resolves: #7 --- pri_internal.h | 9 +++++++++ q931.c | 15 +++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/pri_internal.h b/pri_internal.h index ee1796d..e1b1323 100644 --- a/pri_internal.h +++ b/pri_internal.h @@ -675,6 +675,15 @@ struct q931_call { /*! Encoded RESTART channel id. */ int channel; } restart_tx; + /*! Message retransmission cache */ + struct { + /*! Cache status: set valid as soon as filled in */ + int valid; + /*! Sent message type */ + int msgtype; + /*! User-user information */ + char useruserinfo[256]; + } retrans_cache; }; enum CC_STATES { diff --git a/q931.c b/q931.c index ed24fa2..cc0804a 100644 --- a/q931.c +++ b/q931.c @@ -4451,6 +4451,7 @@ void q931_init_call_record(struct q921_link *link, struct q931_call *call, int c q931_party_id_init(&call->remote_id); q931_party_number_init(&call->ani); q931_party_redirecting_init(&call->redirecting); + call->retrans_cache.valid = 0; /* The call is now attached to whoever called us */ ctrl = link->ctrl; @@ -5312,6 +5313,20 @@ static int send_message(struct pri *ctrl, q931_call *call, int msgtype, int ies[ return -1; } + /* Message retransmission cache */ + if (msgtype == Q931_SETUP || msgtype == Q931_RELEASE) { + if (call->retrans_cache.valid && call->retrans_cache.msgtype == msgtype) { + /* Restore User-user information */ + libpri_copy_string(call->useruserinfo, call->retrans_cache.useruserinfo, sizeof(call->useruserinfo)); + } else { + /* Update cache with new message information */ + call->retrans_cache.msgtype = msgtype; + /* Store useruserinfo: q931_call useruserinfo field is ephemeral, cleared as soon as transmitted */ + libpri_copy_string(call->retrans_cache.useruserinfo, call->useruserinfo, sizeof(call->retrans_cache.useruserinfo)); + call->retrans_cache.valid = 1; + } + } + memset(buf, 0, sizeof(buf)); len = sizeof(buf); init_header(ctrl, call, buf, &h, &mh, &len, (msgtype >> 8));