Author Topic: Call Forward - proposed feature discussion  (Read 15382 times)

Michael

  • Askozia Staff
  • Hero Member
  • *
  • Posts: 1020
  • Karma: 49
    • View Profile
Re: Call Forward - proposed feature discussion
« Reply #15 on: August 19, 2010, 09:29:49 PM »
Wish I had more time to participate, guys. I've also been busy with everything leading up to a vacation this week. Let's continue this discussion once I'm back and get call forwarding into 2.1.

Facundo Ameal

  • Full Member
  • ***
  • Posts: 83
  • Karma: 5
  • VoIPing
    • View Profile
    • Railtion
Re: Call Forward - proposed feature discussion
« Reply #16 on: August 21, 2010, 06:06:11 AM »
I understand Giovanni. It happens often to me, when I try to contribute. Even, when I tried to talk with the main developer. But, I think this is not the case. We are not many, but a few that try to make Askozia a better project. I'm kind of newbie in Askozia and rely on you, Giovanni and Michael, because I haven't got much knowledge about the project.

I try to contribute as much as I can, but Michael's and Giovanni's opinion are important for me. You two have experience in the project.


PS: Michael, bring some presents for us from your vacations :P

Cheers!

luckman212

  • Newbie
  • *
  • Posts: 8
  • Karma: 0
    • View Profile
Re: Call Forward - proposed feature discussion
« Reply #17 on: August 25, 2010, 01:51:26 AM »
giovanni-
I am sorry for this off-topic request, but I really like the look of your flowchart.
would you mind telling me what application you used to create it?
cheers
Luke

Facundo Ameal

  • Full Member
  • ***
  • Posts: 83
  • Karma: 5
  • VoIPing
    • View Profile
    • Railtion
Re: Call Forward - proposed feature discussion
« Reply #18 on: September 16, 2010, 05:38:13 PM »
I've been with a lot of work. Here I am again. Guys, let me know if you are OK with what was proposed, and I'll try to make it work.

Cheers!

Michael

  • Askozia Staff
  • Hero Member
  • *
  • Posts: 1020
  • Karma: 49
    • View Profile
Re: Call Forward - proposed feature discussion
« Reply #19 on: September 17, 2010, 11:06:48 AM »
Next week I'm back on development for a few days. If you have some extensions.conf logic prototyped, I can build it into an image and add the necessary gui elements.

Keep the hope alive! 2.1 should have call forwarding :)

Facundo Ameal

  • Full Member
  • ***
  • Posts: 83
  • Karma: 5
  • VoIPing
    • View Profile
    • Railtion
Re: Call Forward - proposed feature discussion
« Reply #20 on: September 17, 2010, 11:22:46 AM »
You'll have on monday :)

giovanni.v

  • Hero Member
  • *****
  • Posts: 694
  • Karma: 53
    • View Profile
    • BoneOS SDK &  TeeBX VoIP communication platform
Re: Call Forward - proposed feature discussion
« Reply #21 on: September 19, 2010, 09:07:03 PM »
I've done some rough benchmark to get an idea about latency introduced by calling an parsing the asterisk DB.

The application script used to fill the db:
1,Answer()
n,Set(LOOPCOUNT=60000)
n,Set(LOOPMAX=69999)
n,Set(TARGET_MINLEN=3)
n,Set(TARGET_MAXLEN=11)
n,Set(START_TS=${EPOCH})
n,NoOp(${STRFTIME(${START_TS},Europe/Rome,"%d/%m/%Y %H:%M:%S.%1q")})
n,While($[${LOOPCOUNT} <= ${LOOPMAX}])
  ; init vars used in the nested while loop
  n,Set(TARGET_LEN=${RAND(${TARGET_MINLEN},${TARGET_MAXLEN})})
  n,Set(TARGET_COUNT=1)
  n,Set(TARGET_STR="")
  ;
  n,While($[${TARGET_COUNT} <= ${TARGET_LEN}])
    n,Set(TARGET_STR=${TARGET_STR}${RAND(0,9)})
    n,Set(TARGET_COUNT=$[${TARGET_COUNT} + 1])
  n,EndWhile()
  ;
  n,Set(FWD_STATUS_OPT1=${RAND(1,3)})
  n,Set(FWD_STATUS_OPT2=${RAND(1,3)})
  n,Set(DB(callforward/${LOOPCOUNT})=${FWD_STATUS_OPT1}-${FWD_STATUS_OPT2}-${TARGET_STR})
  n,Set(LOOPCOUNT=$[${LOOPCOUNT} + 1])
n,EndWhile()
n,Set(END_TS=${EPOCH})
n,NoOp(${STRFTIME(${END_TS},Europe/Rome,"%d/%m/%Y %H:%M:%S.%1q")})
n,NoOp(Elapsed ticks: $[${END_TS} - ${START_TS}])
n,Hangup()

Resuls:
- writing 10000 keys to memory -> 70 seconds.
- writing 10000 keys to usb storage -> 274 seconds.

The application script used to do random reads from the db:
1,Answer()
n,Set(LOOPCOUNT=1)
n,Set(LOOPEND=1000)
n,Set(START_TS=${EPOCH})
n,NoOp(${STRFTIME(${START_TS},Europe/Rome,"%d/%m/%Y %H:%M:%S.%1q")})
n,While($[${LOOPCOUNT} <= ${LOOPEND}])
  n,Set(CURR_KEY=${RAND(60000,69999)})
  n,Set(DB_RESULT=${DB(callforward/${CURR_KEY})})
  n,Set(FWD_STATUS_OPT1=${CUT(DB_RESULT,,1)})
  n,Set(FWD_STATUS_OPT2=${CUT(DB_RESULT,,2)})
  n,Set(FWD_TARGET=${CUT(DB_RESULT,,3)})
  n,Set(LOOPCOUNT=$[${LOOPCOUNT} + 1])
  n,NoOp(Status Option 1:[${FWD_STATUS_OPT1}], Option 2:[${FWD_STATUS_OPT2}] target:[${FWD_TARGET}])
n,EndWhile()
n,Set(END_TS=${EPOCH})
n,NoOp(${STRFTIME(${END_TS},Europe/Rome,"%d/%m/%Y %H:%M:%S.%1q")})
n,NoOp(Elapsed seconds: $[${END_TS} - ${START_TS}])
n,Hangup()


Results:
- random reading 1000 times from a 10000 keys family from usb storage -> 1 seconds.
- random reading 10000 times from a 10000 keys family from usb storage -> 17 seconds.
- random reading 100000 times from a 10000 keys family from usb storage -> !!Kills the test appliance!!
- random reading 1000 times from a 10000 keys family from memory -> 1 seconds.
- random reading 10000 times from a 10000 keys family from memory -> 14 seconds.
- random reading 100000 times from a 10000 keys family from memory -> 172 seconds.

The test was done using askozia 2.0.1 running on a Futro thin client (1 Ghz Geode NX, 256MB ram) and a Transcend 4GB usb stick as storage.
Unfortunately i'm unable to get precision better than 1 second.

I think the final app must also check for key existence (like  Set(KEY_EXISTS=${DB_EXISTS(callforward/602)}) but forgot to do that at  test time.

Facundo Ameal

  • Full Member
  • ***
  • Posts: 83
  • Karma: 5
  • VoIPing
    • View Profile
    • Railtion
Re: Call Forward - proposed feature discussion
« Reply #22 on: September 21, 2010, 05:48:51 AM »
Giovanni,
     Great tests! For a simple application, AstDB, seems to be OK. Not the same for something large with extensive use of it. Do you agree?

I've manage to write a draft for Call Forward Unconditional. I can't figure out how to make it possible to do forwarding to external numbers. Perhaps you guys can help with that.

The first code quote has both activate and deactivate applications. They do test for loops, so, as Giovanni suggested, doesn't put delay in the dialing process.

Code: [Select]
Extension: 00002321
Description: Call Forward All Activate
Logic:
1,Answer()
n,Playback(beep)
n,Read(CF_DESTINATION,beep,,,,5)
n,GotoIf($[${CF_DESTINATION} = ${CALLERID(num)}]?error)
n,GotoIf($[${DB_EXISTS(CF/${CF_DESTINATION})}]:do-cf)
n,Set(CHECK_EXTEN=${DB(CF/${extension})})
n,While($[${CHECK_EXTEN} != 0])
n,Set(CHECK_EXTEN = ${IF(${DB_EXISTS(CF/${CHECK_EXTEN})}?${DB(CF/${CHECK_EXTEN}:0)})})
n,GotoIf($[${CHECK_EXTEN} = ${CALLERID(num)}]?error)
n,EndWhile
n(do-cf),Set(DB(CF/${CALLERID(num)})=${CF_DESTINATION})
n,Playback(beep)
n,Hangup()
n(error),Playback(beeper)
n,Hangup()

Extension: 00002320
Description: Call Forward All Deactivate
Logic:
1,Answer()
2,Set(to_del=${IF(${DB_EXISTS(CF/${CALLERID(num)})})?${DB_DELETE(CF/${CALLERID(num)})}})
3,Playback(beep)
4,Hangup()

Here there's a piece of the dialplan generated for an extension with some lines added. They are commented and make CF possible, it's not perfect and needs some changes. Perhaps, going to original extension's voicemail. What do you think?

Code: [Select]
[internal]                                  
; internal phone : Facundo Ameal - <101>    
exten => 101,1,NoOp(internal calling internal phone: Facundo Ameal - <101>)
exten => 101,n,ExecIf(${DB_EXISTS(CF/${EXTEN})}?Goto(${EXTEN})) ;Added to make CF work
exten => 101,n,Set(HASVOICEMAIL="yes")                      
exten => 101,n,Set(SENDNOTIFICATIONS="f@a.com")
exten => 101,n,Set(NOVOICEMAILWHENBUSY="yes")              
exten => 101,n,Gosub(macro-main,s,1(SIP/101,101,101,tTo,))          

Hope it helps. Cheers!
« Last Edit: October 04, 2010, 10:47:24 PM by Facundo Ameal »

Scapal

  • Full Member
  • ***
  • Posts: 58
  • Karma: 4
    • View Profile
Re: Call Forward - proposed feature discussion
« Reply #23 on: September 21, 2010, 09:58:03 AM »
I like that  :)

giovanni.v

  • Hero Member
  • *****
  • Posts: 694
  • Karma: 53
    • View Profile
    • BoneOS SDK &  TeeBX VoIP communication platform
Re: Call Forward - proposed feature discussion
« Reply #24 on: September 27, 2010, 07:03:28 PM »
Sorry for that delay... I'm really short in spare time.

For a simple application, AstDB, seems to be OK. Not the same for something large with extensive use of it. Do you agree?

Yes, it's the expected behaviour... tested just to touch it.

Quote
I've manage to write a draft for Call Forward Unconditional. I can't figure out how to make it possible to do forwarding to external numbers.
(...omissis)

Will continue working on that near to the next weekend.

giovanni.v

  • Hero Member
  • *****
  • Posts: 694
  • Karma: 53
    • View Profile
    • BoneOS SDK &  TeeBX VoIP communication platform
Re: Call Forward - proposed feature discussion [step 1: cfw setup done]
« Reply #25 on: October 07, 2010, 07:57:14 PM »
After a lot of experiments finally got a working logic to implement the whole logic planned in my first draft. I chose to use mainly a non-interactive process, I think not being able to use specific prompts it's easier and quicker.

That manage to setup the call forward feature status for extensions:

Code: [Select]
[feat-cfw-control]
; feature base code *239 (*CFW)
; activation
;
exten => _*239[1-3][1-3]!,1,Answer()
exten => _*239[1-3][1-3]!,n,Set(CALLEREXT=${CALLERID(num)})
exten => _*239[1-3][1-3]!,n,Set(CTRL_EXTSTATUS=${EXTEN:4:1})
exten => _*239[1-3][1-3]!,n,Set(CTRL_CALLER=${EXTEN:5:1})
exten => _*239[1-3][1-3]!,n,Set(CFW_DEST=${EXTEN:6})
exten => _*239[1-3][1-3]!,n,Set(CFW_FAIL=${ISNULL(${CFW_DEST})})
exten => _*239[1-3][1-3]!,n,GotoIf($[${CFW_FAIL}=1]?s-err,1)
exten => _*239[1-3][1-3]!,n,GotoIf($["${CFW_DEST:0:1}"="*"]?keepdest:setup)
exten => _*239[1-3][1-3]!,n,Goto(s-err,1)
exten => _*239[1-3][1-3]!,n(keepdest),GotoIf($[${DB_EXISTS(cfw/${CALLEREXT})}=0]?s-err,1)
exten => _*239[1-3][1-3]!,n,Set(CFW_DEST=${CUT(DB_RESULT,,3)})
exten => _*239[1-3][1-3]!,n(setup),GotoIf($[${ISNULL(${CFW_DEST})}=1]?s-unallowed,1)
exten => _*239[1-3][1-3]!,n,Gosub(s-looptest,1)
exten => _*239[1-3][1-3]!,n,GotoIf($[${GOSUB_RETVAL}>0]?s-unallowed,1)
exten => _*239[1-3][1-3]!,n,Set(DB(cfw/${CALLEREXT})=${CTRL_EXTSTATUS}-${CTRL_CALLER}-${CFW_DEST})
exten => _*239[1-3][1-3]!,n,Goto(s-ok,1)
;
; deactivation
;
exten => _*2390[0*],1,Answer()
exten => _*2390[0*],n,Set(CALLEREXT=${CALLERID(num)})
exten => _*2390[0*],n,GotoIf($[${DB_EXISTS(cfw/${CALLEREXT})}=1]?unset:s-err,1)
exten => _*2390[0*],n(unset),Set(CTRL=${EXTEN:-1})
exten => _*2390[0*],n,NoOp(Control digit: [${CTRL}])
exten => _*2390[0*],n,GotoIf($["${CTRL}"="0"]?delkey)
exten => _*2390[0*],n,GotoIf($["${CTRL}"="*"]?keepkey)
exten => _*2390[0*],n,NoOp(Failure due to unmanaged condition!)
exten => _*2390[0*],n,Goto(s-err,1)
exten => _*2390[0*],n(delkey),Set(DELETED_KEY=${DB_DELETE(cfw/${CALLEREXT})})
exten => _*2390[0*],n,Goto(s-ok,1)
exten => _*2390[0*],n(keepkey),Set(OLD_CFW_DEST=${CUT(DB_RESULT,,3)})
exten => _*2390[0*],n,NoOp(Old CFW dest: [${OLD_CFW_DEST}])
exten => _*2390[0*],n,GotoIf($[${ISNULL(${OLD_CFW_DEST})}=1]?s-unallowed,1)
exten => _*2390[0*],n,Set(DB(cfw/${CALLEREXT})=0-0-${OLD_CFW_DEST})
exten => _*2390[0*],n,Goto(s-ok,1)
;
; check status
;
exten => _*239,1,Answer()
exten => _*239,n,Set(CALLEREXT=${CALLERID(num)})
exten => _*239,n,GotoIf($[${DB_EXISTS(cfw/${CALLEREXT})}=1]?readstatus:s-err,1)
exten => _*239,n,Goto(s-err,1)
exten => _*239,n(readstatus),NoOp(Going to read feature status)
exten => _*239,n,Set(CTRL_EXTSTATUS=${CUT(DB_RESULT,,1))
exten => _*239,n,Set(CTRL_CALLER=${CUT(DB_RESULT,,2))
exten => _*239,n,Set(CFW_DEST=${CUT(DB_RESULT,,3)})
exten => _*239,n,Gosub(s-ctrl-one,1)
exten => _*239,n,SayDigits(${CTRL_EXTSTATUS})
exten => _*239,n,Gosub(s-ctrl-two,1)
exten => _*239,n,SayDigits(${CTRL_CALLER})
exten => _*239,n,GotoIf($[${CTRL_EXTSTATUS)}=0]?s-ok,1)
exten => _*239,n,GotoIf($[${ISNULL(${CFW_DEST})}=1]?s-unallowed,1)
exten => _*239,n,Gosub(s-ctrl-tree,1)
exten => _*239,n,SayAlpha(${CFW_DEST})
exten => _*239,n,Goto(s-ok,1)
;
; feedback, loop test and exit place
;
exten => s-ok,1,Playtones(!425/300,!0/100,!425/300)
exten => s-ok,n,Wait(1)
exten => s-ok,n,StopPlaytones()
exten => s-ok,n,Hangup()
exten => s-unallowed,1,Playtones(stutter)
exten => s-unallowed,n,Wait(3)
exten => s-unallowed,n,StopPlaytones()
exten => s-unallowed,n,Hangup()
exten => s-err,1,Playtones(congestion)
exten => s-err,n,Wait(3)
exten => s-err,n,StopPlaytones()
exten => s-err,n,Hangup()
exten => s-ctrl-one,1,Playtones(!425/100)
exten => s-ctrl-one,n,Wait(1)
exten => s-ctrl-one,n,StopPlaytones()
exten => s-ctrl-one,n,Return()
exten => s-ctrl-two,1,Playtones(!425/100,!0/100,!425/100)
exten => s-ctrl-two,n,Wait(1)
exten => s-ctrl-two,n,StopPlaytones()
exten => s-ctrl-two,n,Return()
exten => s-ctrl-tree,1,Playtones(!425/100,!0/100,!425/100,!0/100,!425/100)
exten => s-ctrl-tree,n,Wait(1)
exten => s-ctrl-tree,n,StopPlaytones()
exten => s-ctrl-tree,n,Return()
exten => s-looptest,1,Set(CFW_STACK="")
exten => s-looptest,n,Set(CFW_CALLEREXT=${CALLEREXT})
exten => s-looptest,n,Set(CFW_STEPDEST=${CFW_DEST})
exten => s-looptest,n,Set(CFW_LOOP=$["${CFW_CALLEREXT}"="${CFW_STEPDEST}"])
exten => s-looptest,n,ExecIf($[${CFW_LOOP}>0],Set,CFW_STACK=${CFW_CALLEREXT})
exten => s-looptest,n,GotoIf($[${CFW_LOOP}>0]?say)
exten => s-looptest,n,While(${DB_EXISTS(cfw/${CFW_STEPDEST})})
  exten => s-looptest,n,Set(CFW_CTRLEXTSTATUS=${CUT(DB_RESULT,,1)})
  exten => s-looptest,n,ExecIf($[${CFW_CTRLEXTSTATUS}=0],ExitWhile,)
  exten => s-looptest,n,Set(CFW_STEPDEST=${CUT(DB_RESULT,,3)})
  exten => s-looptest,n,ExecIf($[${ISNULL(${CFW_STACK})}=0],Set,CFW_STACK=${CFW_STACK}@)
  exten => s-looptest,n,Set(CFW_STACK=${CFW_STACK}${CFW_STEPDEST})
  exten => s-looptest,n,ExecIf($[${CFW_STEPDEST}=${CFW_CALLEREXT}],Set,CFW_LOOP=1)
  exten => s-looptest,n,ExecIf($[${CFW_LOOP}>0],ExitWhile,)
exten => s-looptest,n,EndWhile()
exten => s-looptest,n(say),ExecIf($[${CFW_LOOP}>0],SayAlpha,${CFW_DEST}@${CFW_STACK})
exten => s-looptest,n,Return(${CFW_LOOP})

The feature code *239 (*CFW) control the call forward option using some suffixes.
To activate CFW the feature code must be followed by two suffixes (control digits) plus an optional one.

The first control digit sets the valid status to fire the call forward when the extension will be called:
- 1 immediate/unconditional
- 2 no answer
- 3 busy

The second digit sets to fire the call forward depending on the source of the call (caller location):
- 1 internal calls from the pbx
- 2 external calls
- 3 any

Any digit following the first two will be considered as the call forward destination; instead of dialling the destination each time the third (optional) control digit may be choosed to restore the same number used the last time.
- * forward to the last stored destination number

Examples (spaces in dialled numbers used only to make things cleaner) :
*239 11 604 -> activate CFW to extension 604, will fire immediately but only for internal calls.
*239 13 011223344 -> activate CFW to 011223344, will fire immediately for all calls.
*239 23 * -> Change the CFW setup to no answer for all calls to the last used number. Trow an error if no destination exists, e.g. destination deleted or CFW never used.

To avoid loops the destination is checked, also the whole CFW chain if applicable; if a loop is detected the CFW chain will be played to the user followed by a special error tone.

The feature deactivation will be managed by a two digit control suffix:
- 00 deactivate CFW and also delete the existing destination.
- 0* deactivate CFW but keep the last destination number.

Example:
*239 0* -> Stop the call forward on the extension but keep the last destination number.

Additionally the user will be able to check the CFW status by dialling the feature code alone, calling *239 plays the options then the destination number (if applicable); options and dest. number separated by different very short tones.

If anyone wants to test do it appending the dialplan code to extensions.conf via the integrator panel then include it to the internal context by adding also:
[internal](+)
include => feat-cfw-control


Feel free to report any bug, comments or unexpected behaviour.

I'm working to complete the dial logic to effectively make CFW runs. It's actually a macro that called via a Gosub check the CFW status and destination to return the exension to be dialled.
The whole runtime logic must work for every destination and, as Facundo pointed out, if the call does not complete we must go to original extension's voicemail.
« Last Edit: October 07, 2010, 08:30:55 PM by giovanni.v »

Facundo Ameal

  • Full Member
  • ***
  • Posts: 83
  • Karma: 5
  • VoIPing
    • View Profile
    • Railtion
Re: Call Forward - proposed feature discussion
« Reply #26 on: October 07, 2010, 08:15:10 PM »
:o WOW!! That is far better than mine. Love it. I'm gonna try to test it during the following days.

Please let me know if you need any help.

Cheers!

Genius

  • Newbie
  • *
  • Posts: 19
  • Karma: 0
    • View Profile
Re: Call Forward - proposed feature discussion [step 1: cfw setup done]
« Reply #27 on: October 22, 2010, 11:38:36 AM »
After a lot of experiments finally got a working logic to implement the whole logic planned in my first draft. I chose to use mainly a non-interactive process, I think not being able to use specific prompts it's easier and quicker.
**
Feel free to report any bug, comments or unexpected behaviour.
**
Giovanni great job on implementing this feature!
However, it just doesn't seem to work in a reliable way for me, any progress on the final piece of code ?

For example: When I dial *239 13 101 (on extension 102) I hear the confirmation beeps but when I dial 102 (from ext 101) the phone on ext 102 still rings.
« Last Edit: October 22, 2010, 11:45:12 AM by Genius »

giovanni.v

  • Hero Member
  • *****
  • Posts: 694
  • Karma: 53
    • View Profile
    • BoneOS SDK &  TeeBX VoIP communication platform
Re: Call Forward - proposed feature discussion [step 1: cfw setup done]
« Reply #28 on: October 26, 2010, 11:51:36 AM »
However, it just doesn't seem to work in a reliable way for me, any progress on the final piece of code ?

For example: When I dial *239 13 101 (on extension 102) I hear the confirmation beeps but when I dial 102 (from ext 101) the phone on ext 102 still rings.

Sorry but the published draft implements only the logic to setup CFW in the system, not the dialplan logic to get a working feature.
The whole feature still is under development and require some effort to get it working as designed.

Genius

  • Newbie
  • *
  • Posts: 19
  • Karma: 0
    • View Profile
Re: Call Forward - proposed feature discussion [step 1: cfw setup done]
« Reply #29 on: November 10, 2010, 01:43:43 AM »
Sorry but the published draft implements only the logic to setup CFW in the system, not the dialplan logic to get a working feature.
The whole feature still is under development and require some effort to get it working as designed.

Any plans on finishing this awsome feature ?