;Version("3.1.2.139")
;InformationalVersion("3.1.2.0")

[nixxis-inbound]

 exten => _X.,1,Verbose(1,  Nixxis standard inbound ${CUT(NixxisFileVersion,\",2)})
 same => n,Set(CallExtension=${EXTEN})
 same => n,ExecIf($["${PeerName}" = ""]?Set(PeerName=${CHANNEL(peername)}))
 same => n,ExecIf($["${PeerPrefix}" = ""]?Set(PeerPrefix=${SHIFT(PeerName,-)}))
 same => n,ExecIf($["${PeerName}" != "${PeerPrefix}" & "${PeerAccount}" = ""]?Set(PeerAccount=${SHIFT(PeerName,-)}))
 same => n,ExecIf($["${PeerProvider}" = ""]?Set(PeerProvider=${PeerPrefix}))
 same => n,ExecIf($["${PeerAccount}" = ""]?Set(PeerAccount=${CDR(accountcode)}))
 same => n,Set(CallActivityId=)
 same => n,Set(CallRecordingId=)

 same => n,Verbose(1,    from peer ${PeerPrefix})

 same => n,Set(CacheValid=${IF($[(0${EPOCH}-60)>0${CacheTime_${PeerPrefix}_${EXTEN}}]?0:1)})

 same => n,Set(RawAnswer=${DirectorCache_${PeerPrefix}_${EXTEN}})
 same => n,GotoIf(${CacheValid}?DirectorLoaded)

 same => n,GotoIf($["${NixxisTrafficDirector}" == ""]?DirectorLoaded)

 same => n(LoadFromDirector),Set(GLOBAL(CacheTime_${PeerPrefix}_${EXTEN})=${EPOCH})
 same => n,Set(CURLOPT(httptimeout)=3)
 same => n,Set(RequestUri=${NixxisTrafficDirector}/inbound)

 same => n,Set(RequestData=destination=${EXTEN}&peer=${CHANNEL(peername)}&context=${CONTEXT}&account=${CDR(accountcode)}&domain=${SIPDOMAIN}&version=${CUT(NixxisFileVersion,\",2)})
 same => n,ExecIf($["${NixxisTrafficDirectorKey}" != ""]?Set(RequestData==${AES_ENCRYPT(${NixxisTrafficDirectorKey},${RequestData})}))
 same => n,Set(RawAnswer=${CURL(${RequestUri},${RequestData})})
 same => n,ExecIf($["${RawAnswer:0:1}" == "="]?Set(RawAnswer=${AES_DECRYPT(${NixxisTrafficDirectorKey},${RawAnswer:1})}))
 same => n,Set(GLOBAL(DirectorCache_${PeerPrefix}_${EXTEN})=${RawAnswer})

 same => n(DirectorLoaded),GoSub(ParseSettings(${RawAnswer}))

 same => n,GotoIf($["${NixxisAppServerPeer}" != ""]?AppServerPeerSet)
 same => n,Set(NixxisAppServerPeer=AppServer${IF($["${PeerAccount}" != ""]?-${PeerAccount})})
 same => n,ExecIf($["${SIPPEER(${NixxisAppServerPeer})}" == "(null)" | "${SIPPEER(${NixxisAppServerPeer})}" == "" ]?Set(NixxisAppServerPeer=AppServer))
 
 same => n(AppServerPeerSet),ExecIf($["${NixxisAppServerPeer}" != ""]?Verbose(1,    to peer ${NixxisAppServerPeer}))
 same => n,ExecIf($["${PeerAccount}" != ""]?Verbose(1,    with account code ${PeerAccount}))
 same => n,NoOp(Verifying Nixxis App Server peer ${NixxisAppServerPeer} status)
 same => n,Set(PeerIp=${SIPPEER(${NixxisAppServerPeer})})
 same => n,Set(PeerStatus=${SIPPEER(${NixxisAppServerPeer},status)})

 same => n,ExecIf($["${PeerIp}" == "(null)"]?Set(PeerIp=))
 same => n,ExecIf($["${PeerStatus}" == "UNREACHABLE"]?Set(PeerIp=))

 same => n,GotoIf($["${PeerIp}" == ""]?NoAppServerPeer)

 same => n,ExecIf($["${NixxisAppServerUri}" == ""]?Set(NixxisAppServerUri=http://${PeerIp}:8088))

 ; May not cache recording id
 ; same => n,Set(RawAnswer=${AppServerCache_${PeerPrefix}_${EXTEN}})
 ; same => n,GotoIf(${CacheValid}?AppServerLoaded)

 same => n(LoadFromAppServer),NoOp(Loading additional settings from AppServer)
 same => n,Set(RequestUri=${NixxisAppServerUri}/admin?action=inboundSettings&destination=${CallExtension}&peer=${CHANNEL(peername)}&context=${CONTEXT}&account=${PeerAccount}&domain=${SIPDOMAIN}&provider=${PeerProvider}&version=${CUT(NixxisFileVersion,\",2)})
 same => n,Set(RawAnswer=${CURL(${RequestUri})})
 ; same => n,Set(GLOBAL(AppServerCache_${PeerPrefix}_${EXTEN})=${RawAnswer})

 same => n,GotoIf($["${RawAnswer}" != "" ]?AppServerLoaded)

 same => n,Verbose(1,    -- Looking for backoffice extension)
 same => n,GotoIf(${DIALPLAN_EXISTS(${IF($["${PeerAccount}" != ""]?${PeerAccount}-)}BackOffice,${EXTEN},1)}?${IF($["${PeerAccount}" != ""]?${PeerAccount}-)}BackOffice,${EXTEN},1:NoAppServerPeer)


 same => n(AppServerLoaded),GoSub(ParseSettings(${RawAnswer}))

 same => n(SettingsLoaded),ExecIf($["${NixxisAppServerPeer}" == ""]?Set(NixxisAppServerPeer=AppServer${IF($["${PeerAccount}" != ""]?-${PeerAccount})}))

 same => n,Verbose(1,    -- Dialing application server at ${PeerIp})
 same => n,SIPAddHeader(x-cr-prov: ${PeerProvider})
 same => n,Verbose(1,    for activity ${CallActivityId})

 same => n,ExecIf($["${USERUSERINFO}" != ""]?SIPAddHeader(x-cr-uui: ${USERUSERINFO}))
 same => n,SIPAddHeader(x-cr-mon: ${CHANNEL})

 same => n,GotoIf($["${CallRecordingId}" == ""]?NoRecording)
 same => n,Verbose(1,    with recording ${CallRecordingId})
 same => n,SIPAddHeader(x-cr-rec: ${CallRecordingId})
 same => n,Set(RecordingPath=${NixxisRecordingPath})
 same => n,ExecIf($["${RecordingPath}" == "" ]?Set(RecordingPath=${NixxisRecordingPath}))
 same => n,ExecIf($["${NixxisRecordingProcessing}" = "" ]?MixMonitor(${RecordingPath}/${PeerAccount}/${CallRecordingId}.wav):MixMonitor(${RecordingPath}/${PeerAccount}/${CallRecordingId}.wav,,${NixxisRecordingProcessing} "^{MIXMONITOR_FILENAME}"))
 same => n(NoRecording),Dial(SIP/${CallExtension}@${NixxisAppServerPeer})
 same => n,Hangup()

 same => n(NoAppServerPeer),Verbose(1,    -- Application server not defined or not available)
 same => n,Hangup(1)

 same => n(ParseSettings),NoOp(Parsing settings)
 same => n,While($["${SET(AnswerPart=${SHIFT(ARG1,&)})}" != ""])
 same => n,Set(PartName=${CUT(AnswerPart,=,1)})
 same => n,Set(PartValue=${CUT(AnswerPart,=,2)})
 same => n,ExecIf($["${PartName}" = "account"]?Set(CDR(accountcode)=${PartValue}))
 same => n,ExecIf($["${PartName}" = "account"]?Set(PeerAccount=${PartValue}))
 same => n,ExecIf($["${PartName}" = "extension"]?Set(CallExtension=${PartValue}))
 same => n,ExecIf($["${PartName}" = "peer"]?Set(NixxisAppServerPeer=${PartValue}))
 same => n,ExecIf($["${PartName}" = "activity"]?Set(CallActivityId=${PartValue}))
 same => n,ExecIf($["${PartName}" = "recording"]?Set(CallRecordingId=${PartValue}))
 same => n,ExecIf($["${PartName}" = "appserver"]?Set(NixxisAppServerUri=${PartValue}))
 same => n,EndWhile
 same => n,Return

 exten 			=> h,1,NoOp(HangUp)
 exten 			=> t,1,NoOp(Timeout)
 exten 			=> t,2,HangUp
