AOC-S: Use variable time unit length (1...3 Bytes). Fixes wrong time calculation on Clubtelefon 5 ISDN

This commit is contained in:
Dennis Grunert 2024-01-11 02:27:02 +01:00 committed by Andreas Eversberg
parent dfa07323c3
commit a390e93d9a
3 changed files with 48 additions and 31 deletions

View File

@ -202,36 +202,29 @@ static void generate_aocs_fac(call_t *call)
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);
if(call->metering_connect_units == 0) { // Free call
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FreeOfCharge\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 1;
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FreeOfCharge / CallSetup FreeOfCharge\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 2;
fac.u.inv.o.AOCcuril.currencyInfo[0].chargedItem = 0x00; // basic comm
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0x84; // free
fac.u.inv.o.AOCcuril.currencyInfo[1].chargedItem = 0x02; // call setup
fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0x84; // free
}
else if(call->metering_unit_period_decisecs == 0) { // setup/connect FlatRate
else if(call->metering_unit_period_decisecs == 0) { // CallSetup-only FlatRate
/* note some payphones (e.g. BluePhone) only interpret 'basic comm' charged item, therefore we don't use 'call setup' charged item */
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FlatRate\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 1;
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FlatRate / CallSetup FlatRate\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 2;
fac.u.inv.o.AOCcuril.currencyInfo[0].chargedItem = 0x00; // basic comm
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0xA2; // FlatRate
strncpy((char *)fac.u.inv.o.AOCcuril.currencyInfo[0].FlatRateCurrency.currency, "EUR", 10); // Currency value
fac.u.inv.o.AOCcuril.currencyInfo[0].FlatRateCurrency.currencyAmount = AOCS_CURRENCY_AMOUNT_PER_UNIT * call->metering_connect_units;
fac.u.inv.o.AOCcuril.currencyInfo[0].FlatRateCurrency.multiplier = 1; // 1/100 EUR
fac.u.inv.o.AOCcuril.currencyInfo[1].chargedItem = 0x02; // call setup
fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0xA2; // FlatRate
strncpy((char *)fac.u.inv.o.AOCcuril.currencyInfo[0].FlatRateCurrency.currency, "EUR", 10); // Currency value
fac.u.inv.o.AOCcuril.currencyInfo[1].FlatRateCurrency.currencyAmount = AOCS_CURRENCY_AMOUNT_PER_UNIT * call->metering_connect_units;
fac.u.inv.o.AOCcuril.currencyInfo[1].FlatRateCurrency.multiplier = 1; // 1/100 EUR
}
else if(call->metering_connect_units == 1) { // Normal call
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 1;
fac.u.inv.o.AOCcuril.currencyInfo[0].chargedItem = 0x00; // basic comm
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0xA1; // DurationCurrency
strncpy((char *)fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.currency, "EUR", 10); // Currency value
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 = 0x00; // Contin. Charging
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeUnit = call->metering_unit_period_decisecs; // Unit duration
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeScale = 1; // 1/10 s
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeUnit = call->metering_unit_period_decisecs; // Granularity
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeScale = 1; // 1/10 s
}
else { // Special call with setup/connect FlatRate
else { // Normal call
/* note some payphones (e.g. BluePhone) only interpret 'basic comm' charged item */
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency / CallSetup FlatRate\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 2;
@ -239,12 +232,12 @@ static void generate_aocs_fac(call_t *call)
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0xA1; // DurationCurrency
strncpy((char *)fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.currency, "EUR", 10); // Currency value
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.multiplier = 1; // 1/100 EUR
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.typeOfCharging = 0x00; // Contin. Charging
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeUnit = call->metering_unit_period_decisecs; // Unit duration
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeScale = 1; // 1/10 s
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeUnit = call->metering_unit_period_decisecs; // Granularity
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.granLengthTimeScale = 1; // 1/10 s
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.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.granLengthTimeScale = 0; // 1/100 s
fac.u.inv.o.AOCcuril.currencyInfo[1].chargedItem = 0x02; // call setup
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

View File

@ -315,9 +315,9 @@ extern "C" {
__u16 currencyAmount;
__u8 multiplier;
__u8 typeOfCharging;
__u16 durLengthTimeUnit;
__u32 durLengthTimeUnit;
__u8 durLengthTimeScale;
__u8 granLengthTimeUnit;
__u32 granLengthTimeUnit;
__u8 granLengthTimeScale;
};

View File

@ -274,7 +274,15 @@ static int encodeAOCSChargingUnitOperation(__u8 * dest, const struct asn1_parm *
ci_len++; c_len++;
p[i++] = 0x81; // durationLengthOfTimeUnit
ci_len++; c_len++;
if(currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit > 0xff) {
if(currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit > 32767) {
p[i++] = 0x03; // Length
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit) >> 16) & 0xff;
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit) >> 8) & 0xff;
ci_len++; c_len++;
}
else if(currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit > 127) {
p[i++] = 0x02; // Length
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit) >> 8) & 0xff;
@ -298,9 +306,25 @@ static int encodeAOCSChargingUnitOperation(__u8 * dest, const struct asn1_parm *
ci_len++; c_len++;
p[i++] = 0x81; // granuLengthOfTimeUnit
ci_len++; c_len++;
p[i++] = 0x01; // Length
ci_len++; c_len++;
p[i++] = currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit;
if(currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit > 32767) {
p[i++] = 0x03; // Length
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit) >> 16) & 0xff;
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit) >> 8) & 0xff;
ci_len++; c_len++;
}
else if(currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit > 127) {
p[i++] = 0x02; // Length
ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit) >> 8) & 0xff;
ci_len++; c_len++;
}
else {
p[i++] = 0x01; // Length
ci_len++; c_len++;
}
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit) >> 0) & 0xff;
ci_len++; c_len++;
p[i++] = 0x82; // granuScaleOfTimeUnit
ci_len++; c_len++;