From 5d2f50b98a3f0d99b359c0a5f2f699e075ac177b Mon Sep 17 00:00:00 2001 From: Dennis Grunert Date: Mon, 29 Jan 2024 10:58:54 +0100 Subject: [PATCH] Change IE_METERING timing information from deciseconds to seconds and milliseconds --- src/isdn/dss1.c | 42 +++++++++++++++++------------------------- src/isdn/isdn.h | 3 +-- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/isdn/dss1.c b/src/isdn/dss1.c index bed1dfd..d81e77b 100644 --- a/src/isdn/dss1.c +++ b/src/isdn/dss1.c @@ -199,7 +199,7 @@ static void snd_msg_fac_aocs(call_t *call) fac.u.inv.invokeId = 2; /* doesn't matter since no response is expected */ fac.u.inv.operationValue = Fac_AOCSCurrency; - LOGP(DISDN, LOGL_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); + LOGP(DISDN, LOGL_DEBUG, "Sending AOC-S facility from metering data: connect_units=%d unit_period_sec=%d.%03d\n", call->metering_connect_units, (uint16_t)call->metering_unit_period.tv_sec, (uint32_t)call->metering_unit_period.tv_usec / 1000); if(call->metering_connect_units == 0) { /* Free call */ @@ -210,7 +210,7 @@ static void snd_msg_fac_aocs(call_t *call) fac.u.inv.o.AOCcuril.currencyInfo[1].chargedItem = 0x02; // CallSetup fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0x84; // Free } - else if(call->metering_unit_period_decisecs == 0) { + else if(call->metering_unit_period.tv_sec == 0 && call->metering_unit_period.tv_usec == 0) { /* Connect-only FlatRate call; note some payphones (e.g. BluePhone) only interpret 'BasicComm' charged item, therefore we don't use 'CallSetup' charged item */ LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FlatRate %d/100 EUR; CallSetup FreeOfCharge\n", AOCS_CURRENCY_AMOUNT_PER_UNIT * call->metering_connect_units); fac.u.inv.o.AOCcuril.currencyInfoCount = 2; @@ -231,14 +231,14 @@ static void snd_msg_fac_aocs(call_t *call) fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.currencyAmount = AOCS_CURRENCY_AMOUNT_PER_UNIT; fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.multiplier = 1; // 1/100 EUR fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.typeOfCharging = 1; // StepFunction - fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeUnit = call->metering_unit_period_decisecs * 10; // Unit duration + fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeUnit = ((uint32_t)call->metering_unit_period.tv_sec * 100) + ((uint32_t)call->metering_unit_period.tv_usec / 10000); // Unit duration fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeScale = 0; // 1/100 s - fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeUnit = call->metering_unit_period_decisecs * 10; // Granularity + fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeUnit = ((uint32_t)call->metering_unit_period.tv_sec * 100) + ((uint32_t)call->metering_unit_period.tv_usec / 10000); // Granularity fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeScale = 0; // 1/100 s fac.u.inv.o.AOCcuril.currencyInfo[1].chargedItem = 0x02; // CallSetup if(call->metering_connect_units > 1) { /* Additional CallSetup charge */ - LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency %d/100 EUR per %d/100 seconds; CallSetup FlatRate %d/100 EUR\n", AOCS_CURRENCY_AMOUNT_PER_UNIT, call->metering_unit_period_decisecs * 10, AOCS_CURRENCY_AMOUNT_PER_UNIT * (call->metering_connect_units - 1)); + LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency %d/100 EUR per %d.%02d seconds; CallSetup FlatRate %d/100 EUR\n", AOCS_CURRENCY_AMOUNT_PER_UNIT, (uint16_t)call->metering_unit_period.tv_sec, (uint32_t)call->metering_unit_period.tv_usec / 10000, AOCS_CURRENCY_AMOUNT_PER_UNIT * (call->metering_connect_units - 1)); fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0xA2; // FlatRate strncpy((char *)fac.u.inv.o.AOCcuril.currencyInfo[1].FlatRateCurrency.currency, "EUR", 10); // Currency value fac.u.inv.o.AOCcuril.currencyInfo[1].FlatRateCurrency.currencyAmount = AOCS_CURRENCY_AMOUNT_PER_UNIT * (call->metering_connect_units - 1); @@ -246,7 +246,7 @@ static void snd_msg_fac_aocs(call_t *call) } else { /* No additional CallSetup charge */ - LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency %d/100 EUR per %d/100 seconds; CallSetup FreeOfCharge\n", AOCS_CURRENCY_AMOUNT_PER_UNIT, call->metering_unit_period_decisecs * 10); + LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency %d/100 EUR per %d.%02d seconds; CallSetup FreeOfCharge\n", AOCS_CURRENCY_AMOUNT_PER_UNIT, (uint16_t)call->metering_unit_period.tv_sec, (uint32_t)call->metering_unit_period.tv_usec / 10000); fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0x84; // Free } } @@ -313,7 +313,7 @@ static void metering_unit_timer_cb(void *data) call_t *call = data; call->metering_total_units++; - osmo_timer_schedule(&call->metering_unit_timer, call->metering_unit_period_decisecs / 10, (call->metering_unit_period_decisecs % 10) * 100000); + osmo_timer_schedule(&call->metering_unit_timer, call->metering_unit_period.tv_sec, call->metering_unit_period.tv_usec); snd_msg_fac_aocd(call); } @@ -489,7 +489,6 @@ void setup_ind(call_t *call, uint32_t pid, struct l3_msg *l3m) /* reset AOC information */ call->metering_info_received = 0; - call->metering_unit_timer_started = 0; call->metering_total_units = 0; new_state(call, ISDN_STATE_IN_SETUP); @@ -906,10 +905,7 @@ void disconnect_ind(call_t *call, uint32_t pid, struct l3_msg *l3m) osmo_cc_ll_msg(&call->isdn_ep->cc_ep, call->cc_callref, msg); /* stop AOC-D timer and send AOC-E facility */ - if(call->metering_unit_timer_started) { - osmo_timer_del(&call->metering_unit_timer); - call->metering_unit_timer_started = 0; - } + osmo_timer_del(&call->metering_unit_timer); } /* CC-DISCONNECT INDICATION of child instance */ @@ -2135,7 +2131,7 @@ skip_ies: 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)); + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period)); if(rc >= 0) { call->metering_info_received = 1; snd_msg_fac_aocs(call); @@ -2198,7 +2194,7 @@ void alert_req(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) 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)); + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period)); if(rc >= 0) { call->metering_info_received = 1; snd_msg_fac_aocs(call); @@ -2276,7 +2272,7 @@ void setup_rsp(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) 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)); + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period)); if(rc >= 0) { call->metering_info_received = 1; snd_msg_fac_aocs(call); @@ -2287,11 +2283,10 @@ void setup_rsp(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) call->metering_total_units = call->metering_connect_units; snd_msg_fac_aocd(call); - if(call->metering_unit_period_decisecs > 0) { - LOGP(DISDN, LOGL_DEBUG, "Scheduling metering unit timer every %d deciseconds.\n", call->metering_unit_period_decisecs); - call->metering_unit_timer_started = 1; + if(call->metering_unit_period.tv_sec > 0 || call->metering_unit_period.tv_usec > 0) { + LOGP(DISDN, LOGL_DEBUG, "Scheduling metering unit timer every %d.%03d seconds.\n", (uint16_t)call->metering_unit_period.tv_sec, (uint32_t)call->metering_unit_period.tv_usec / 1000); osmo_timer_setup(&call->metering_unit_timer, metering_unit_timer_cb, call); - osmo_timer_schedule(&call->metering_unit_timer, call->metering_unit_period_decisecs / 10, (call->metering_unit_period_decisecs % 10) * 100000); + osmo_timer_schedule(&call->metering_unit_timer, call->metering_unit_period.tv_sec, call->metering_unit_period.tv_usec); } } @@ -2397,7 +2392,7 @@ void progress_req(call_t *call, uint32_t pid, osmo_cc_msg_t *msg) free_l3msg(l3m); /* Metering handling and AOC-S generation */ - rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period_decisecs)); + rc = osmo_cc_get_ie_metering(msg, 0, &(call->metering_connect_units), &(call->metering_unit_period)); if(rc >= 0) { call->metering_info_received = 1; snd_msg_fac_aocs(call); @@ -2533,11 +2528,8 @@ void disc_req(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_DISCONNECT, call->l3_pid, l3m); - /* stop AOC-D timer and send AOC-E facility */ - if(call->metering_unit_timer_started) { - osmo_timer_del(&call->metering_unit_timer); - call->metering_unit_timer_started = 0; - } + /* stop AOC-D timer */ + osmo_timer_del(&call->metering_unit_timer); } /* CC-RELEASE REQUEST */ diff --git a/src/isdn/isdn.h b/src/isdn/isdn.h index d2c5bc4..ced1dec 100644 --- a/src/isdn/isdn.h +++ b/src/isdn/isdn.h @@ -186,10 +186,9 @@ typedef struct call_list { uint8_t park_callid[8]; /* metering/AOC-D/AOC-S */ struct osmo_timer_list metering_unit_timer; - int metering_unit_timer_started; int metering_info_received; + struct timeval metering_unit_period; uint16_t metering_connect_units; - uint16_t metering_unit_period_decisecs; uint16_t metering_total_units; /* bridge states */