[asterisk-users] Asterisk Realtime Billing Question???

Sherwood McGowan sherwood.mcgowan at gmail.com
Thu Oct 21 04:17:16 CDT 2010


On Thu, Oct 21, 2010 at 3:23 AM, DHAVAL INDRODIYA
<dhaval.it01034 at gmail.com>wrote:

> thanks mate,
>
> for useful and good information provided by you, i am not asking you that
> please write down your all LOGIC and explain everything to me, as per your
> explanation i can see it will deduct amount for only 1 call but what
> actually i am searching for is if user made 5 concurrent calls and i have to
> limit
> all calls and each destination number having different rate may be some of
> them ISD and some of them local. that will create more problem to me, i
> think there is some solutions for this . could you suggest any reference for
> the same, it will be more helpful to me.
>
> thanks in advance,
> regards
> Dhaval
>
>  *snip*
>>>
>>>

>  Dhaval,
>>>> This sounds very much like a system I'm working on for a client right
>>>> now. I'm not permitted to disclose much about it due to the NDA i signed,
>>>> but I'll risk giving you a point in the right direction.
>>>>
>>>> First, you should create a table in your database that has a column
>>>> called callid, and other columns that you will have to decide upon. This
>>>> table will be called something like '*call_references*'. Oh, and you'll
>>>> want to define callid as the primary key for records in that table, but DO
>>>> NOT make it an autoincrement, you're going to populate it with a value that
>>>> is described in the next step.
>>>>
>>>> Second, at the beginning of the original call you mentioned, define a
>>>> variable that will be unique to that call. I personally have done this by
>>>> stripping all non-digits from the caller's callerid (using
>>>> Set(newcid=${FILTER(0123456789,${CALLERID(number)})} ), and then adding the
>>>> to ${EPOCH}. I did it this way: ${MATH(${newcid}+${EPOCH})}.
>>>>
>>>> Next (this is where I have to start being a bit vague), you're going to
>>>> perform an INSERT query, creating a new call_references record (using that
>>>> variable I just showed you how to construct as callid's value).
>>>>
>>>> Now, when you defined that variable, you should have preceded the
>>>> variable name with two underscores ( __ ), which will tell Asterisk that
>>>> channels spawned by the current channel will inherit that variable and it's
>>>> value.
>>>>
>>>> Voila, you now have a method for storing realtime data such as billing
>>>> information between MULTIPLE calls.
>>>>
>>>> I wish I could tell you more, but I can't violate my client's
>>>> Non-Disclosure Agreement.
>>>>
>>>> Hope this helps you out!
>>>>
>>>> Sherwood McGowan
>>>>
>>>>
>> Well, you got the right guy, I've written several different RT billing
>> setups for clients ranging from small residential ITSPs all the way up to a
>> wholesale carrier in Austria. . .
>>
>> What you'd have to do is have a column called "freeze" in your table that
>> you keep customer accounts and billing info in (mainly, the balance). Then,
>> you'd need a 'frozen' table, with three columns: id, accountid (or some
>> other name/reference that references the customer in question), and amount.
>>
>> Now, the "freeze" column in the account table defines how many minutes
>> worth of funds (at the rate the call is being charged to the customer)
>> you're going to make unavailable to the customer until the call is
>> completed. You multiply the value from "freeze" against the rate the call is
>> going to be charged at, resulting in "amount_to_freeze". Subtract that
>> number from the customer's current balance, and then create a record in the
>> "frozen" table with that customer's accountid and put the value of
>> amount_to_freeze into the "amount" column.
>>
>> Finally,when the customer's call(s) completes, calculate the total charge
>> for the call, check to see if it's more than `frozen`.`amount`, and if it
>> is, subtract `frozen`.`amount` from the total charge, and then subtract the
>> remaining amount from the customer's balance. If the total is *not* more
>> than than `frozen`.`amount`, you'll subtract total from `frozen`.`amount`,
>> and then ADDING the remaining amount to the customer's balance. (Being the
>> doofus I am, I called that procedure "thawing", LOL)
>>
>> In addition to the freezing of funds, you'll need to perform some magic
>> and limit the length of the customer's calls based on the balance of the
>> account just before freezing funds. This will need to be in conjunction with
>> having a maximum number of concurrent calls the customer can have, and
>> taking that into account when limiting each call.
>>
>> It sounds complicated but I wrote this type of system several times, the
>> first couple were native to Asterisk using AELv2 (no AGI calls, more secure,
>> less resources hogged, etc), and then I wrote the last one using MySQL
>> stored procedures to perform just about ALL of the calculations and logic.
>> Basically at the beginning of a call, Asterisk would execute a stored
>> procedure called something like freeze_and_limit and passing two arguments,
>> the accountid and the rate per minute their call is going to cost (could
>> have also just fed the SP the destination and let it calculate THAT too).
>> MySQL would return the number of milliseconds the customer's call could be.
>>
>> Alright, hopefully THAT gets you heading in the right direction, because
>> if I write much more I'd be getting into EXACTLY how I wrote up the "FLaT"
>> (Freeze, Limit, and Thaw) system, and that would be depriving me of
>> potential consulting fees I'd normally get for just implementing it for a
>> customer.
>>
>> Cheers mate, and good luck :)
>> Sherwood McGowan
>>
>
(*Note: Portions of the previous emails were removed in order to keep the
size of the message low)*

Dhaval,

You're right, I forgot one thing. The "frozen" table's id column should not
be an autoincrement, it should be set by the insert statement, using the
original method I decsribed for creating a unique integer from the callerid
number and the current EPOCH. That way, you can be sure that multiple
concurrent calls that have frozen funds will *only* retrieve the record they
created. (Oh and, once you thaw the frozen funds, delete the appropriate
record in the frozen table)

I'm not sure why you think this will only work for a single call at a time.
Each time a call occurs that is related to an account will cause more money
to be "frozen" from that account, thereby causing future calls to have less
available balance and therefore less time for a call limit. This works for
ANY number of concurrent calls on an account, and every one of those calls
freezes funds based on the rate at which THAT call's amount to freeze was
calculated against.

EACH call determines IT'S rate, which is then used to determine the amount
to freeze from the account ON THAT CALL. Additionally, since the rate is
specific to each call, the limiting of the length of THAT call, your issue
of limiting is also a non-issue.

I've got to go to bed now, it's 4AM here. I urge you to read my overview of
my FLaT system again, I think you're not seeing the big picture. The frozen
funds are only accessible by the call that created that record (since it's
the only call that would have that callid).. Since previously STARTED calls
have frozen some of the balance, making it unavailable for other calls that
occur (even within milliseconds of each other), the balance is lower EVERY
time another concurrent (as well as consecutive) call checks CompanyA's
balance and prepares to freeze part of it.

Trust me, I spent the better part of two and a half years working on the
FLaT system, I know it works and that it works on multiple concurrent calls.
Like I said, I haven't given you EVERYTHING, there's additional data that
should be checked against and acted upon, but even what I've described would
work for what you've asked about, much much better than you appear to think
it would.

Slainte Mate
Sherwood McGowan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.digium.com/pipermail/asterisk-users/attachments/20101021/e3eb659b/attachment.htm 


More information about the asterisk-users mailing list