pespin submitted this change.
asterisk: extensions.conf: Allow extra MO call from SIP UA which HOLDed previous call
We need to keep track of the SIP UA using the IMS endpoint, so that when
the IMS call is set on HOLD we can identidy that the same SIP UA can
still initiate new calls on the IMS endpoint.
Related: SYS#7003
Change-Id: Idad9e613669466f3aac8b1c7b43f8d9b6e0494e6
---
M ttcn3-asterisk-ims-ue-test/asterisk/extensions.conf
1 file changed, 59 insertions(+), 9 deletions(-)
diff --git a/ttcn3-asterisk-ims-ue-test/asterisk/extensions.conf b/ttcn3-asterisk-ims-ue-test/asterisk/extensions.conf
index fdfae23..e2ec574 100644
--- a/ttcn3-asterisk-ims-ue-test/asterisk/extensions.conf
+++ b/ttcn3-asterisk-ims-ue-test/asterisk/extensions.conf
@@ -1,3 +1,11 @@
+[globals]
+; local SIP UA Channels (PJSIP/50X-*) using the IMS endpoint are put in this group.
+; This group is used as a semaphore/mutex by using COUNT_GROUP() on it.
+IMS_GROUP=ims_group
+; Stores channel name of local SIP UA (PJSIP/50X-*) using the IMS service (in a call)
+; This is used to figure out which local SIP UA can create extra calls due to having its other IMS calls on HOLD.
+IMS_PEER=none
+
[get-valid-endpoints-500]
; usage: no arguments, returns DIALGROUP object of registered and valid 050x endpoints
exten => s,1,Verbose(5, Entering get-valid-endpoints gosub.)
@@ -19,6 +27,7 @@
[from-phone]
+; Local SIP UA calls 500, broadcast to all other available local SIP UAs:
exten => 0500,1,Verbose(5,${EXTEN}: Call all registered pjsips from ${CALLERID(num)})
same => n,Gosub(get-valid-endpoints-500,s,1())
same => n,Set(DIALGROUP(CALL_EVERYONE_LIST)=${GOSUB_RETVAL})
@@ -26,16 +35,26 @@
same => n,Dial(${DIALGROUP(CALL_EVERYONE_LIST)})
same => n,Hangup(16)
+; Local SIP UA calls 50X, call the target local SIP UA:
exten => _050X,1,Verbose(5,${EXTEN}: Call pjsip endpoint from ${CALLERID(num)})
same => n,Dial(PJSIP/${EXTEN})
same => n,Hangup(16)
-exten => _.!,1,Verbose(5,${EXTEN}: Call external number from ${CALLERID(num)})
- same => n,Set(GROUP()=IMSgroup)
- same => n,GotoIf($[${GROUP_COUNT(IMSgroup)} > 1]?999)
+; MO Call SIP UA -> IMS:
+exten => _X.!,1,Verbose(5,${EXTEN}: Call external number from ${CALLERID(num)}, IMS DEVICE_STATE=${DEVICE_STATE(PJSIP/volte_ims)}, IMS_PEER=${GLOBAL(IMS_PEER)})
+ ; Allow only 1 MO call towards IMS, or extra ones if the same SIP UA has put previous call(s) on HOLD:
+ same => n,Set(GROUP()=${GLOBAL(IMS_GROUP)})
+ same => n,Set(ALLOW_EXTRA_CALL=$[ $["${DEVICE_STATE(PJSIP/volte_ims)}" == "ONHOLD"] & $["${GLOBAL(IMS_PEER)}" == "PJSIP/${CALLERID(num)}"] ])
+ same => n,GotoIf($[ $[ ${GROUP_COUNT(${GLOBAL(IMS_GROUP)})} > 1] & !${ALLOW_EXTRA_CALL} ]?999)
+ same => n,Set(GLOBAL(IMS_PEER)=PJSIP/${CALLERID(num)})
same => n,Dial(PJSIP/${EXTEN}@volte_ims)
+ ; Channel is removed from GROUP() automatically when it is destroyed after the call finishes.
+ ; It's fine leaving IMS_PEER set since anyway it's only checked in the case where there's a call in place (GROUP_COUNT()>1),
+ ; so it will be set properly whenever an initial call enters the exclusion zone guarded by GROUP_COUNT().
same => n,Hangup(16)
- same => 999,Verbose(1,${EXTEN}: VoLTE client already busy (${GROUP_COUNT(IMSgroup)}) rejecting call from SIP UA ${CALLERID(num)})
+
+ ; Reject path:
+ same => 999,Verbose(1,${EXTEN}: VoLTE client already busy (${GROUP_COUNT(${GLOBAL(IMS_GROUP)})}, ${GLOBAL(IMS_PEER)}) rejecting call from SIP UA ${CALLERID(num)})
same => n,Set(DIALSTATUS=CHANUNAVAIL)
@@ -57,16 +76,33 @@
same => n,ExecIf($[${ENDPOINT_4_EXPR} != 0]?Set(DIALGROUP(CALL_VALID_LIST,add)=PJSIP/0504))
same => n,Return(${DIALGROUP(CALL_VALID_LIST)})
+[volte-ims-call-established]
+; no arguments, SUB to set global variable IMS_PEER to the Channel name of the SIP UA (501-504) using the IMS endpoint
+; This SUB (Dial(U())) runs under the Channel context of the SIP UA who answered the MT call.
+exten => s,1,Verbose(5, PJSIP/${CALLERID(num)}: Entering volte-ims-call-established gosub.)
+ same => n,Set(GLOBAL(IMS_PEER)=PJSIP/${CALLERID(num)})
+ same => n,Return()
[volte_ims]
-exten => _.!,1,Verbose(5,${EXTEN}: Call internal number from ${CALLERID(num)})
- same => n,Set(GROUP()=IMSgroup)
- same => n,GotoIf($[${GROUP_COUNT(IMSgroup)} > 1]?999)
+; MT Call IMS -> SIP UA:
+exten => _X.!,1,Verbose(5,${EXTEN}: Call internal number from ${CALLERID(num)}, IMS DEVICE_STATE=${DEVICE_STATE(PJSIP/volte_ims)}, IMS_PEER=${GLOBAL(IMS_PEER)})
+ ; If IMS endpoint is already in use, reject it (999):
+ same => n,Set(GROUP()=${GLOBAL(IMS_GROUP)})
+ same => n,GotoIf($[${GROUP_COUNT(${GLOBAL(IMS_GROUP)})} > 1]?999)
+ ; Figure out SIP UAs to ring:
same => n,Gosub(get-valid-endpoints-from-volte-ims,s,1())
same => n,Set(DIALGROUP(CALL_EVERYONE_LIST)=${GOSUB_RETVAL})
+ ; Process call establishment:
same => n,WaitForPrecondition(10,2000)
- same => n,Dial(${DIALGROUP(CALL_EVERYONE_LIST)})
+ ; OUTBOUND_GROUP var tells Dial() app to set the GROUP() of the newly created channel (501-504) instead of the calling channel (volte_ims).
+ ; This way IMS_GROUP always contains channels PJSIP/50X:
+ same => n,Set(OUTBOUND_GROUP=${GLOBAL(IMS_GROUP)})
+ ; Once a SIP UA answers the call, volte-ims-call-established takes care of updating IMS_PEER with the new PJSIP/50X channel name:
+ same => n,Dial(${DIALGROUP(CALL_EVERYONE_LIST)},,U(volte-ims-call-established))
+ ; Channel is removed from GROUP() automatically when it is destroyed after the call finishes.
same => n,Hangup(16)
- same => 999,Verbose(1,${EXTEN}: VoLTE client already busy (${GROUP_COUNT(IMSgroup)}) rejecting call from IMS ${CALLERID(num)})
+
+ ; Reject path:
+ same => 999,Verbose(1,${EXTEN}: VoLTE client already busy (${GROUP_COUNT(${GLOBAL(IMS_GROUP)})}, ${GLOBAL(IMS_PEER)}) rejecting call from IMS ${CALLERID(num)})
same => n,Set(DIALSTATUS=BUSY)
To view, visit change 37527. To unsubscribe, or for help writing mail filters, visit settings.