diff --git a/src/isdn/dss1.c b/src/isdn/dss1.c index d682d61..f05bd1e 100644 --- a/src/isdn/dss1.c +++ b/src/isdn/dss1.c @@ -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 diff --git a/src/libmisdnuser/include/mISDN/suppserv.h b/src/libmisdnuser/include/mISDN/suppserv.h index d03bc91..a4a5cc5 100644 --- a/src/libmisdnuser/include/mISDN/suppserv.h +++ b/src/libmisdnuser/include/mISDN/suppserv.h @@ -315,9 +315,9 @@ extern "C" { __u16 currencyAmount; __u8 multiplier; __u8 typeOfCharging; - __u16 durLengthTimeUnit; + __u32 durLengthTimeUnit; __u8 durLengthTimeScale; - __u8 granLengthTimeUnit; + __u32 granLengthTimeUnit; __u8 granLengthTimeScale; }; diff --git a/src/libmisdnuser/suppserv/fac.c b/src/libmisdnuser/suppserv/fac.c index 43c588a..6e3cd90 100644 --- a/src/libmisdnuser/suppserv/fac.c +++ b/src/libmisdnuser/suppserv/fac.c @@ -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++;