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); 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 if(call->metering_connect_units == 0) { // Free call
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FreeOfCharge\n"); LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FreeOfCharge / CallSetup FreeOfCharge\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 1; 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].chargedItem = 0x00; // basic comm
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0x84; // free 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 */ /* 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"); LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm FlatRate / CallSetup FlatRate\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 1; 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].chargedItem = 0x00; // basic comm
fac.u.inv.o.AOCcuril.currencyInfo[0].currencyType = 0xA2; // FlatRate 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 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.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[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 else { // 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
/* note some payphones (e.g. BluePhone) only interpret 'basic comm' charged item */ /* note some payphones (e.g. BluePhone) only interpret 'basic comm' charged item */
LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency / CallSetup FlatRate\n"); LOGP(DISDN, LOGL_DEBUG, "AOC-S currencyInfoList: BasicComm DurationCurrency / CallSetup FlatRate\n");
fac.u.inv.o.AOCcuril.currencyInfoCount = 2; 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 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 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.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.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.durLengthTimeUnit = call->metering_unit_period_decisecs * 10; // Unit duration
fac.u.inv.o.AOCcuril.currencyInfo[0].durationCurrency.durLengthTimeScale = 1; // 1/10 s 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; // Granularity 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 = 1; // 1/10 s 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].chargedItem = 0x02; // call setup
fac.u.inv.o.AOCcuril.currencyInfo[1].currencyType = 0xA2; // FlatRate 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 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; __u16 currencyAmount;
__u8 multiplier; __u8 multiplier;
__u8 typeOfCharging; __u8 typeOfCharging;
__u16 durLengthTimeUnit; __u32 durLengthTimeUnit;
__u8 durLengthTimeScale; __u8 durLengthTimeScale;
__u8 granLengthTimeUnit; __u32 granLengthTimeUnit;
__u8 granLengthTimeScale; __u8 granLengthTimeScale;
}; };

View File

@ -274,7 +274,15 @@ static int encodeAOCSChargingUnitOperation(__u8 * dest, const struct asn1_parm *
ci_len++; c_len++; ci_len++; c_len++;
p[i++] = 0x81; // durationLengthOfTimeUnit p[i++] = 0x81; // durationLengthOfTimeUnit
ci_len++; c_len++; 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 p[i++] = 0x02; // Length
ci_len++; c_len++; ci_len++; c_len++;
p[i++] = ((currinfolist->currencyInfo[ci].durationCurrency.durLengthTimeUnit) >> 8) & 0xff; 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++; ci_len++; c_len++;
p[i++] = 0x81; // granuLengthOfTimeUnit p[i++] = 0x81; // granuLengthOfTimeUnit
ci_len++; c_len++; ci_len++; c_len++;
p[i++] = 0x01; // Length if(currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit > 32767) {
ci_len++; c_len++; p[i++] = 0x03; // Length
p[i++] = currinfolist->currencyInfo[ci].durationCurrency.granLengthTimeUnit; 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++; ci_len++; c_len++;
p[i++] = 0x82; // granuScaleOfTimeUnit p[i++] = 0x82; // granuScaleOfTimeUnit
ci_len++; c_len++; ci_len++; c_len++;