Change IE_METERING timing information from deciseconds to seconds and milliseconds

This commit is contained in:
Dennis Grunert 2024-01-29 10:58:54 +01:00 committed by Andreas Eversberg
parent 04aa799e25
commit 5ed88bacae
2 changed files with 18 additions and 27 deletions

View File

@ -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 */

View File

@ -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 */