From 71aec2ec7a05b9f30f515f385f5863a9825e04a1 Mon Sep 17 00:00:00 2001 From: Dennis Grunert Date: Wed, 10 Jan 2024 18:13:14 +0100 Subject: [PATCH] AOC information as separate facility messages for compatibility (CONNECT-attached AOC-D IE ignored by NT1plus) --- src/isdn/dss1.c | 59 ++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/isdn/dss1.c b/src/isdn/dss1.c index c17b915..ccf10c2 100644 --- a/src/isdn/dss1.c +++ b/src/isdn/dss1.c @@ -186,8 +186,9 @@ static void split_3pty(call_t *call) /* Generate AOC-S facility IE from metering information */ #define AOCS_CURRENCY_AMOUNT_PER_UNIT 5 -static void generate_aocs_ie(call_t *call, struct l3_msg *l3m) +static void generate_aocs_fac(call_t *call) { + struct l3_msg *l3m; uint8_t fac_ie[256]; struct asn1_parm fac; @@ -198,7 +199,7 @@ static void generate_aocs_ie(call_t *call, struct l3_msg *l3m) fac.u.inv.invokeId = 2; /* doesn't matter since no response is expected */ fac.u.inv.operationValue = Fac_AOCSCurrency; - PDEBUG(DISDN, DEBUG_DEBUG, "Sending AOC-S information from metering data: connect_units=%d unit_period_decisecs=%d\n", call->metering_connect_units, call->metering_unit_period_decisecs); + PDEBUG(DISDN, DEBUG_DEBUG, "Sending AOC-S facility from metering data: connect_units=%d unit_period_decisecs=%d\n", call->metering_connect_units, call->metering_unit_period_decisecs); if(call->metering_connect_units == 0) { // Free call PDEBUG(DISDN, DEBUG_DEBUG, "AOC-S currencyInfoList: BasicComm FreeOfCharge\n"); @@ -252,7 +253,11 @@ static void generate_aocs_ie(call_t *call, struct l3_msg *l3m) } encodeFac(fac_ie, &fac); + + // sending facility + l3m = create_l3msg(); enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]); + call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_FACILITY, call->l3_pid, l3m); } } @@ -266,7 +271,7 @@ static void aocd_timer_cb(void *data) call->metering_total_units++; - PDEBUG(DISDN, DEBUG_DEBUG, "Sending next AOC-D unit information, total_units=%d\n", call->metering_total_units); + PDEBUG(DISDN, DEBUG_DEBUG, "Sending next AOC-D facility, total_units=%d\n", call->metering_total_units); timer_start(&call->aocd_unit_timer, (double)call->metering_unit_period_decisecs / (double)10); @@ -2097,18 +2102,18 @@ void proc_req(call_t *call, uint32_t pid, osmo_cc_msg_t *msg, int with_ies) if (rc >= 0 && call->isdn_ep->ntmode) enc_ie_redirection(l3m, type, plan, 1, present, redir); - /* Metering handling and AOC-S generation */ - rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); - if(rc >= 0) { - call->metering_info_received = 1; - generate_aocs_ie(call, l3m); - } - skip_ies: new_state(call, ISDN_STATE_IN_PROCEEDING); /* send message to ISDN */ call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_CALL_PROCEEDING, call->l3_pid, l3m); + + /* Metering handling and AOC-S generation */ + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); + if(rc >= 0) { + call->metering_info_received = 1; + generate_aocs_fac(call); + } } /* CC-ALERTING REQUEST */ @@ -2161,17 +2166,17 @@ void alert_req(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) if (rc >= 0 && call->isdn_ep->ntmode) enc_ie_redirection(l3m, type, plan, 1, present, redir); - /* Metering handling and AOC-S generation */ - rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); - if(rc >= 0) { - call->metering_info_received = 1; - generate_aocs_ie(call, l3m); - } - new_state(call, ISDN_STATE_IN_ALERTING); /* send message to ISDN */ call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_ALERTING, call->l3_pid, l3m); + + /* Metering handling and AOC-S generation */ + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); + if(rc >= 0) { + call->metering_info_received = 1; + generate_aocs_fac(call); + } } /* CC-CONNECT REQUEST */ @@ -2241,19 +2246,22 @@ void setup_rsp(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) enc_ie_connected_pn(l3m, type, plan, 1, present, screen, connected); } + new_state(call, ISDN_STATE_IN_CONNECTING); + + /* send message to ISDN */ + call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_CONNECT, call->l3_pid, l3m); + /* Metering handling and AOC-S generation */ rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); if(rc >= 0) { call->metering_info_received = 1; - generate_aocs_ie(call, l3m); + generate_aocs_fac(call); } - new_state(call, ISDN_STATE_IN_CONNECTING); - /* AOC-D handling on connect */ if(call->isdn_ep->ntmode && call->isdn_ep->aocd && call->metering_info_received && call->metering_connect_units > 0) { - PDEBUG(DISDN, DEBUG_DEBUG, "Attaching AOC-D connect facility, units: %d\n", call->metering_connect_units); + PDEBUG(DISDN, DEBUG_DEBUG, "Sending first AOC-D facility, units: %d\n", call->metering_connect_units); call->metering_total_units = call->metering_connect_units; memset(&fac, 0, sizeof(fac)); @@ -2261,10 +2269,14 @@ void setup_rsp(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) fac.comp = CompInvoke; fac.u.inv.invokeId = 2; /* doesn't matter since no response is expected */ fac.u.inv.operationValue = Fac_AOCDChargingUnit; - + fac.u.inv.o.AOCchu.recordedUnits = call->metering_total_units; encodeFac(fac_ie, &fac); + + // sending facility + l3m = create_l3msg(); enc_ie_facility(l3m, fac_ie + 2, fac_ie[1]); + call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_FACILITY, call->l3_pid, l3m); if(call->metering_unit_period_decisecs > 0) { PDEBUG(DISDN, DEBUG_DEBUG, "Scheduling AOC-D unit information every %d deciseconds.\n", call->metering_unit_period_decisecs); @@ -2274,9 +2286,6 @@ void setup_rsp(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) } } - /* send message to ISDN */ - call->isdn_ep->ml3->to_layer3(call->isdn_ep->ml3, MT_CONNECT, call->l3_pid, l3m); - /* in NT mode we might not receive CONNECT ACKNOWLEDGE */ if (call->isdn_ep->ntmode) { new_state(call, ISDN_STATE_CONNECT);