2021 lines
60 KiB
HTML
2021 lines
60 KiB
HTML
|
<!-- This page allow the user to originate a call from a given address and using the selected address type
|
||
|
This sample is also able to accept incoming calls.
|
||
|
|
||
|
What is covered by this sample:
|
||
|
1. Address enumerations and registering on address in order to receive call notifications
|
||
|
2. Call operations: create, connect, answer, disconnect
|
||
|
3. Setting application priority (which application will receive notifications about incoming calls)
|
||
|
4. Processing of TAPI events.
|
||
|
5. QOS usage.
|
||
|
6. Call forwarding setup (minimal)
|
||
|
|
||
|
What is not covered:
|
||
|
This page does not manage the positioning of video windows.
|
||
|
(In order to do this, you can change the sample to use an ActiveX control that is able
|
||
|
to set properties in IVideoWindow. This requires window handle values - HWND - which
|
||
|
are not available in vbscripting).
|
||
|
|
||
|
-->
|
||
|
|
||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD W3 HTML//EN">
|
||
|
|
||
|
<html>
|
||
|
<head>
|
||
|
</head>
|
||
|
<meta content="text/html; charset=unicode" http-equiv="Content-Type">
|
||
|
<title>Call operations</title>
|
||
|
|
||
|
<SCRIPT LANGUAGE="JavaScript"><!--
|
||
|
|
||
|
var ua = navigator.userAgent;
|
||
|
var an = navigator.appName;
|
||
|
|
||
|
// Is it IE?
|
||
|
bMSIE = (ua.indexOf("MSIE")>=1);
|
||
|
if (! bMSIE)
|
||
|
{
|
||
|
alert("You need to use IE to run this page");
|
||
|
window.close;
|
||
|
}
|
||
|
//-->
|
||
|
</SCRIPT>
|
||
|
|
||
|
|
||
|
<script LANGUAGE="VbScript">
|
||
|
|
||
|
Const CallerName ="name1"
|
||
|
|
||
|
'Constants section
|
||
|
'These constants are copied from tapi3if.idl
|
||
|
Const TAPIMEDIAMODE_AUDIO = &H08&
|
||
|
Const TAPIMEDIAMODE_VIDEO = &H8000&
|
||
|
Const S_MEDIA_AUDIOVIDEO = &H8008&
|
||
|
Const TD_CAPTURE = 0
|
||
|
Const TD_RENDER = 1
|
||
|
Const QSL_NEEDED = 1
|
||
|
Const AS_INSERVICE = 0
|
||
|
Const DC_NORMAL = 0
|
||
|
Const TE_CALLSTATE = 8
|
||
|
Const TE_CALLNOTIFICATION = 4
|
||
|
Const TE_DIGITEVENT = &H00008000&
|
||
|
Const CS_DISCONNECTED = 3
|
||
|
Const CS_IDLE = 0
|
||
|
Const CS_OFFERING = 4
|
||
|
Const CS_CONNECTED = 2
|
||
|
Const CNE_OWNER = 0
|
||
|
Const CIS_CALLERIDNAME = 0
|
||
|
Const CIS_CALLERIDNUMBER = 1
|
||
|
Const CIS_REDIRECTINGIDNAME = 8
|
||
|
Const CIS_REDIRECTINGIDNUMBER = 9
|
||
|
|
||
|
Const CIS_DISPLAYABLEADDRESS = 12
|
||
|
Const CIS_COMMENT = 11
|
||
|
Const CIS_CALLINGPARTYID = 13
|
||
|
Const CIS_CALLEDPARTYFRIENDLYNAME = 10
|
||
|
|
||
|
Const CIL_REASON = 8
|
||
|
Const LINEDIGITMODE_DTMF = 2
|
||
|
|
||
|
'Interface IDs for casting
|
||
|
'Note: you can find the following IID-s in tapi3.idl, tapi3if.idl or rend.idl
|
||
|
|
||
|
Const IID_String_ITMediaSupport = "{B1EFC384-9355-11D0-835C-00AA003CCABD}"
|
||
|
Const IID_String_ITTerminalSupport="{B1EFC385-9355-11D0-835C-00AA003CCABD}"
|
||
|
|
||
|
Const IID_String_ITBasicCallControl = "{B1EFC389-9355-11D0-835C-00AA003CCABD}"
|
||
|
|
||
|
'Const IID_String_ITCallInfo = "{B1EFC390-9355-11d0-835C-00AA003CCABD}"
|
||
|
'New interface
|
||
|
Const IID_String_ITCallInfo = "{350F85D1-1227-11D3-83D4-00C04FB6809F}"
|
||
|
Const IID_String_ITStreamControl= "{EE3BD604-3868-11D2-A045-00C04FB6809F}"
|
||
|
Const IID_String_ITDirectoryObjectConference= "{F1029E5D-CB5B-11D0-8D59-00C04FD91AC0}"
|
||
|
Const IID_String_ITCallStateEvent = "{62F47097-95C9-11d0-835D-00AA003CCABD}"
|
||
|
Const IID_String_ITCallNotificationEvent = "{895801DF-3DD6-11d1-8F30-00C04FB6809F}"
|
||
|
|
||
|
Const IID_String_ITDigitDetectionEvent = "{80D3BFAC-57D9-11d2-A04A-00C04FB6809F}"
|
||
|
|
||
|
|
||
|
' IID of IVideoWindow
|
||
|
' Note: you can find this IID defined in control.h (from your sdk\inc directory),
|
||
|
' which contains the interface to type library QuartzTypeLib for quartz.dll;
|
||
|
' (search for the interface IVideoWindow)
|
||
|
Const IID_String_IVideoWindow = "{56A868B4-0AD4-11CE-B03A-0020AF0BA770}"
|
||
|
|
||
|
' The following CLSID is defined in tapi3.h
|
||
|
'(and it's used for creating a terminal of class "video window terminal")
|
||
|
Const CLSID_String_VideoWindowTerm = "{F7438990-D6EB-11d0-82A6-00AA00B5CA1B}"
|
||
|
|
||
|
|
||
|
'****************************************************************************
|
||
|
'Global variable section
|
||
|
'****************************************************************************
|
||
|
|
||
|
DIM spITAddress
|
||
|
|
||
|
spITAddress = Empty
|
||
|
|
||
|
'Set on True when we are unable to complete the connecting phase, to skip rest of processing
|
||
|
DIM sUnableToComplete
|
||
|
DIM sbNeedToExit
|
||
|
sUnableToComplete = False
|
||
|
sbNeedToExit = False
|
||
|
|
||
|
' If we want to receive incoming calls, we have to register on the corresponding addresses.
|
||
|
'We don't really use the values returned by registration (they are supposed to be used
|
||
|
'for unregistration), because Unregistration is performed automatically when we shutdown the TAPI object
|
||
|
|
||
|
'The variable pRegisteredCallNotification is an array that contains cookies returned by RegisterCallNotifications;
|
||
|
'these would normally be used to call UnregisterNotifications.
|
||
|
|
||
|
'The variable pRegisteredName holds correspondent AddressName
|
||
|
|
||
|
DIM pRegisteredCallNotification(50)
|
||
|
DIM pRegisteredName(50)
|
||
|
DIM iQtaRegistered
|
||
|
iQtaRegistered = 0
|
||
|
|
||
|
|
||
|
'Set by radio button "Select Address Type"
|
||
|
DIM sCurrentAddressType
|
||
|
sCurrentAddressType = -1
|
||
|
|
||
|
' This variable will hold a references to the currently established calls
|
||
|
Const MaxCallNumber = 20
|
||
|
DIM spITCall(20)
|
||
|
DIM spCallState(20)
|
||
|
DIM spCallerCallee(20)
|
||
|
DIM spTerminalState(20)
|
||
|
DIM spDtmfDetected(20)
|
||
|
DIM spCallOnHold(20)
|
||
|
|
||
|
spTerminalsNumber = 0
|
||
|
|
||
|
DIm pVideoWindow1
|
||
|
DIm pVideoWindow2
|
||
|
|
||
|
DIM FwdType
|
||
|
FwdType = 0
|
||
|
|
||
|
</script>
|
||
|
|
||
|
|
||
|
<script ID="clientEventHandlersVBS" LANGUAGE="vbscript">
|
||
|
|
||
|
'Simplest error processing
|
||
|
Sub CheckError(strMsg)
|
||
|
if not Err.number = 0 Then
|
||
|
MsgBox strMsg & ":" & Err.number & ";"&Err.description
|
||
|
sbNeedToExit = True
|
||
|
Err.Clear
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
' Enumerate addresses, register for incoming calls and fill listbox
|
||
|
Sub window_onload
|
||
|
On Error Resume Next
|
||
|
|
||
|
' If TAPI object is not initialized, we can't do anything, so exit.
|
||
|
If sUnableToComplete = True Then
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
radioFType.value = ""
|
||
|
|
||
|
'Listen on ALL available addresses
|
||
|
DIM intTmp
|
||
|
intTmp = Find_Address_And_Register()
|
||
|
|
||
|
If sbNeedToExit Then
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
If intTmp = 0 Then
|
||
|
MsgBox "Unable to find any valid address. Try to reload page.",0,"Initializing"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
' Select first address option
|
||
|
selAddress.options(0).selected = True
|
||
|
|
||
|
call changeOptionsState()
|
||
|
|
||
|
Call PopulateFwdRules
|
||
|
window.status = "Done."
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
' Find all addresses that have state "in service" and have at least audio capabilities.
|
||
|
' Register the app as "owner" on all these addresses
|
||
|
' Return number of addresses for which we registered...
|
||
|
Function Find_Address_And_Register()
|
||
|
On Error Resume Next
|
||
|
DIM bUsefulAddress
|
||
|
DIM bSupportVideoOrAudio
|
||
|
DIM bSupportVideo
|
||
|
|
||
|
Find_Address_And_Register = 0
|
||
|
For Each pITAddress in TAPIOBJ.Addresses
|
||
|
|
||
|
bUsefulAddress = False
|
||
|
|
||
|
if pITAddress.State = AS_INSERVICE Then
|
||
|
'Check if this address supports Audio or Video
|
||
|
'Obtain ITMediaSupport
|
||
|
DIM pITMediaSupport
|
||
|
|
||
|
Set pITMediaSupport = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITMediaSupport,pITAddress)
|
||
|
|
||
|
'If this address does not support streaming
|
||
|
'(such as the addresses exposed by RemoteSP, data modems, etc,)
|
||
|
'skip it
|
||
|
if not Err.number = 0 Then
|
||
|
Err.Clear
|
||
|
Else
|
||
|
|
||
|
'Check if audio or video are supported
|
||
|
|
||
|
bSupportVideo = pITMediaSupport.QueryMediaType(TAPIMEDIAMODE_VIDEO)
|
||
|
|
||
|
bSupportVideoOrAudio = _
|
||
|
pITMediaSupport.QueryMediaType(TAPIMEDIAMODE_AUDIO) or bSupportVideo
|
||
|
|
||
|
call CheckError("Find_Address_And_Register:ITMediaSupport.QueryMediaType" )
|
||
|
|
||
|
bUsefulAddress = bSupportVideoOrAudio
|
||
|
End If
|
||
|
End If
|
||
|
|
||
|
if bUsefulAddress and pITAddress.AddressName="H323 Line" Then
|
||
|
' This address should be used:
|
||
|
' register the application to receive notifications on this address
|
||
|
iQtaRegistered = iQtaRegistered + 1
|
||
|
|
||
|
Set spITAddress = pITAddress
|
||
|
|
||
|
if bSupportVideo Then
|
||
|
modes = S_MEDIA_AUDIOVIDEO
|
||
|
Else
|
||
|
modes = TAPIMEDIAMODE_AUDIO
|
||
|
End If
|
||
|
|
||
|
'Register as Owner of any incoming call
|
||
|
pRegisteredCallNotification(iQtaRegistered) = TAPIOBJ.RegisterCallNotifications(pITAddress,True,True,modes,0)
|
||
|
pRegisteredName(iQtaRegistered) = pITAddress.AddressName
|
||
|
|
||
|
if not Err.number = 0 Then 'Probably this address does not support incoming calls
|
||
|
iQtaRegistered = iQtaRegistered - 1
|
||
|
Err.Clear
|
||
|
Else
|
||
|
Find_Address_And_Register = Find_Address_And_Register + 1
|
||
|
End If
|
||
|
|
||
|
|
||
|
'Fill address list
|
||
|
DIM oOption
|
||
|
Set oOption = document.createElement("OPTION")
|
||
|
oOption.text = pITAddress.AddressName
|
||
|
oOption.value = pITAddress.AddressName
|
||
|
selAddress.add(oOption)
|
||
|
|
||
|
Set oOption = Nothing
|
||
|
End IF
|
||
|
Next
|
||
|
|
||
|
|
||
|
'This section shows how to override Application Priority:
|
||
|
'after the execution of the following lines, our app will always receive incoming calls
|
||
|
'even if there are other running tapi apps that had registered for receiving calls before our app.
|
||
|
|
||
|
call TAPIOBJ.SetApplicationPriority("IEXPLORE.EXE",TAPIMEDIAMODE_AUDIO,TRUE)
|
||
|
call TAPIOBJ.SetApplicationPriority("IEXPLORE.EXE",TAPIMEDIAMODE_VIDEO,TRUE)
|
||
|
|
||
|
End Function
|
||
|
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'fired when user changes selected outgoing address radio button
|
||
|
Sub changeOptionsState
|
||
|
On Error Resume Next
|
||
|
|
||
|
'Find address selected
|
||
|
Selstr = ""
|
||
|
|
||
|
bSupportVideo = false
|
||
|
For i = 0 to selAddress.length - 1
|
||
|
If selAddress.options(i).selected = True Then
|
||
|
selstr = selAddress.options(i).value
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
'Find this address and check if video is supported
|
||
|
For Each pITAddress in TAPIOBJ.Addresses
|
||
|
|
||
|
if pITAddress.AddressName =SelStr Then
|
||
|
'Obtain ITMediaSupport
|
||
|
DIM pITMediaSupport
|
||
|
|
||
|
Set pITMediaSupport = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITMediaSupport,pITAddress)
|
||
|
|
||
|
call CheckError("changeOptionsState:Query ITAddress for ITMediaSupport" )
|
||
|
|
||
|
'Check if video is supported
|
||
|
bSupportVideo = _
|
||
|
pITMediaSupport.QueryMediaType(TAPIMEDIAMODE_VIDEO)
|
||
|
|
||
|
call CheckError("changeOptionsState:ITMediaSupport.QueryMediaType" )
|
||
|
Set pITMediaSupport = Nothing
|
||
|
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
call CheckError("changeOptionsState:After enumerating the Addresses")
|
||
|
checkAOnly.disabled = not bSupportVideo
|
||
|
checkNoOutgoingVideo.disabled = not bSupportVideo
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Check parameters of a call before connecting it
|
||
|
Sub PressConnect
|
||
|
On Error Resume Next
|
||
|
DIM iAddressType
|
||
|
DIM pConnectTo
|
||
|
DIM addressFrom
|
||
|
DIM selStr
|
||
|
|
||
|
' Find new entry in call array
|
||
|
DIM CallNumber
|
||
|
CallNumber = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if IsEmpty(spITCall(i)) Then
|
||
|
CallNumber = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
If CallNumber = 0 Then
|
||
|
MsgBox "Maximum number of calls reached. Disconnect call first",0,"connect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
|
||
|
If txtAddress.value = "" Then
|
||
|
MsgBox "You have not entered a destination address",0,"connect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
'Check if type is supplied
|
||
|
if sCurrentAddressType < 0 Then
|
||
|
MsgBox "You have not selected addres type",0,"connect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
' Address type. This app uses only type = 1 ("Phone") and type = 16 ("ip address")
|
||
|
iAddressType = CInt(sCurrentAddressType)
|
||
|
|
||
|
pConnectTo = txtAddress.value
|
||
|
|
||
|
'Find selected originating address
|
||
|
For i = 0 to selAddress.length - 1
|
||
|
If selAddress.options(i).selected = True Then
|
||
|
addressFrom = selAddress.options(i).value
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
If addressFrom = "" Then
|
||
|
MsgBox "Originating Address is not selected or doesn't exist at all: uable to connect",0,"COnnect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
Call Connect(CallNumber, pConnectTo,iAddressType,addressFrom,checkAOnly.value="on" or checkAOnly.disabled,checkNoOutgoingVideo.value="on" or checkNoOutgoingVideo.disabled)
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Create Call object, setup terminals, connect call
|
||
|
Sub Connect(CallNumber, pConnectTo,iAddressType,addressFrom,blnAOnly,blnNoOutVideo)
|
||
|
On Error resume Next
|
||
|
|
||
|
sUnableToComplete = False
|
||
|
|
||
|
window.status = "Connecting to " & pConnectTo & "..."
|
||
|
|
||
|
|
||
|
'Create new internal call representation
|
||
|
|
||
|
'Find address selected
|
||
|
DIM pITAddress_Connect
|
||
|
DIM blnFoundAddress
|
||
|
blnFoundAddress = False
|
||
|
DIM pITAddress
|
||
|
|
||
|
For Each pITAddress in TAPIOBJ.Addresses
|
||
|
if pITAddress.AddressName = addressFrom Then
|
||
|
'Obtain ITMediaSupport
|
||
|
DIM pITMediaSupport
|
||
|
Set pITMediaSupport = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITMediaSupport,pITAddress)
|
||
|
|
||
|
call CheckError("connect:Query ITAddress for ITMediaSupport" )
|
||
|
|
||
|
'Check what is supported
|
||
|
bSupportVideo = _
|
||
|
pITMediaSupport.QueryMediaType(TAPIMEDIAMODE_VIDEO)
|
||
|
|
||
|
call CheckError("connect:ITMediaSupport.QueryMediaType" )
|
||
|
blnFoundAddress = True
|
||
|
Set pITAddress_Connect = pITAddress
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
Set pITAddress = Nothing
|
||
|
|
||
|
if not blnFoundAddress Then
|
||
|
MsgBox "Sorry, outgoing address " & addressFrom & "does not exist",0,"Connect"
|
||
|
window.status = "Call to "& pConnectTo & " failed."
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
Call UnselectTerminals
|
||
|
|
||
|
Call CheckError("Connect: before CreateCallWindow")
|
||
|
Call CreateCallWindow(pITAddress_Connect,blnAOnly or not bSupportVideo,blnNoOutVideo or not bSupportVideo)
|
||
|
Call CheckError("Connect: after CreateCallWindow")
|
||
|
|
||
|
'Obtain Terminal support
|
||
|
DIM pITTerminalSupport
|
||
|
|
||
|
'Set pITTerminalSupport = MAPPER.QueryDispatchInterface(_
|
||
|
'IID_String_ITTerminalSupport,pITAddress_Connect)
|
||
|
Set pITTerminalSupport = pITAddress_Connect
|
||
|
call CheckError("connect:Query ITAddress for ITTerminalSuport" )
|
||
|
|
||
|
'Create a Call
|
||
|
DIM MediaTypes
|
||
|
|
||
|
If not bSupportVideo or blnAOnly Then
|
||
|
MediaTypes = TAPIMEDIAMODE_AUDIO
|
||
|
Else
|
||
|
MediaTypes = S_MEDIA_AUDIOVIDEO
|
||
|
End If
|
||
|
|
||
|
Set pCall = pITAddress_Connect.CreateCall(pConnectTo,iAddressType,MediaTypes)
|
||
|
|
||
|
call CheckError("connect:CreateCall" )
|
||
|
|
||
|
|
||
|
window.status = "Configure terminals..."
|
||
|
Call AssignTerminals(CallNumber,pCall,blnAOnly,blnNoOutVideo,True, False)
|
||
|
call CheckError("connect:after AssignTerminals" )
|
||
|
|
||
|
if sUnableToComplete Then
|
||
|
Call DisconnectCall(CallNumber,1)
|
||
|
window.status = "Call to "& pConnectTo & " failed."
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
DIM pITCallInfo
|
||
|
Set pITCallInfo = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITCallInfo, pCall)
|
||
|
|
||
|
call CheckError("connect:get CalllInfo from Call" )
|
||
|
|
||
|
'XXXX-XX
|
||
|
pITCallInfo.CallInfoString(CIS_CALLINGPARTYID) = CallerName
|
||
|
|
||
|
call CheckError("connect:Set caller name" )
|
||
|
|
||
|
|
||
|
|
||
|
window.status = "Connecting..."
|
||
|
|
||
|
|
||
|
|
||
|
Call pCall.Connect(false)
|
||
|
|
||
|
' Check for error "invalid address" (see in tapi3err.h TAPI_E_INVALADDRESS=(HRESULT)0x8004000C)
|
||
|
if Err.Number = &H8004000C Then
|
||
|
Err.Clear
|
||
|
Call DisconnectCall(CallNumber,1)
|
||
|
window.status = "Call to "& pConnectTo & " failed: Address is invalid"
|
||
|
Set pCall = Nothing
|
||
|
|
||
|
Else
|
||
|
if not Err.Number = 0 Then
|
||
|
Err.Clear
|
||
|
Call DisconnectCall(CallNumber,1)
|
||
|
window.status = "Call to "& pConnectTo & " failed: error " & Hex(Err.number)
|
||
|
Set pCall = Nothing
|
||
|
Else
|
||
|
Set spITCall(CallNumber) = pCall
|
||
|
spCallState(CallNumber) = "Connecting..."
|
||
|
spCallerCallee(CallNumber) = "To " & pConnectTo
|
||
|
spDtmfDetected(CallNumber) = ""
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
|
||
|
End if
|
||
|
|
||
|
End If
|
||
|
|
||
|
call CheckError("connect:main connect" )
|
||
|
|
||
|
Set pCall = Nothing
|
||
|
|
||
|
End Sub
|
||
|
'
|
||
|
'
|
||
|
' Refreshing Call Table
|
||
|
'
|
||
|
'
|
||
|
Sub RefreshCallTable
|
||
|
On error Resume Next
|
||
|
' Delete all entries
|
||
|
|
||
|
For i = 0 to selectCalls.options.length
|
||
|
selectCalls.remove(0)
|
||
|
Next
|
||
|
|
||
|
For i = 1 to MaxCallNumber
|
||
|
|
||
|
if Not IsEmpty(spITCall(i)) Then
|
||
|
if Not spCallerCallee(i) = "" Then
|
||
|
CallString = spCallerCallee(i) & " " & spCallState(i)
|
||
|
|
||
|
if spCallOnHold(i) Then
|
||
|
CallString = CallString & "(On Hold)"
|
||
|
End If
|
||
|
|
||
|
if spTerminalState(i) Then
|
||
|
CallString = "==>" & CallString
|
||
|
End IF
|
||
|
|
||
|
if Not spDtmfDetected(i) = "" Then
|
||
|
CallString = CallString & " DTMF:" & spDtmfDetected(i)
|
||
|
End If
|
||
|
Set oOption = document.createElement("OPTION")
|
||
|
oOption.text = CallString
|
||
|
oOption.value = i
|
||
|
selectCalls.add(oOption)
|
||
|
End If
|
||
|
End if
|
||
|
|
||
|
Next
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
|
||
|
'*
|
||
|
'* Unselect terminals from the call which has them
|
||
|
'*
|
||
|
'*
|
||
|
Sub UnselectTerminals
|
||
|
On Error Resume Next
|
||
|
'Find call which have terminals selected
|
||
|
ActiveCall = 0
|
||
|
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if spTerminalState(i) = TRUE Then
|
||
|
ActiveCall = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
if ActiveCall = 0 Then
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
DIM pITStreamControl
|
||
|
'Set pITStreamControl = MAPPER.QueryDispatchInterface(_
|
||
|
'IID_String_ITStreamControl, spITCall(ActiveCall))
|
||
|
|
||
|
Set pITStreamControl = spITCall(ActiveCall)
|
||
|
if Not Err.Number = 0 Then
|
||
|
Err.Clear
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
|
||
|
DIM pITStream
|
||
|
DIM lMediaType
|
||
|
DIM lDirection
|
||
|
DIM pITTerminal
|
||
|
|
||
|
Set pVideoWindow1 = Nothing
|
||
|
Set pVideoWindow2 = Nothing
|
||
|
spTerminalsNumber = 0
|
||
|
|
||
|
spTerminalState(ActiveCall) = FALSE
|
||
|
|
||
|
'Unselect all audio terms...
|
||
|
For Each pITStream in pITStreamControl.Streams
|
||
|
pITStream.StopStream
|
||
|
If Not Err.Number = 0 Then ' most likely call is already closed
|
||
|
Err.Clear
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
For Each pITTerminal in pITStream.Terminals
|
||
|
pITStream.UnselectTerminal(pITTerminal)
|
||
|
If Not Err.Number = 0 Then ' most likely call is already closed
|
||
|
Err.Clear
|
||
|
End If
|
||
|
Next
|
||
|
Set pITTerminal = Nothing
|
||
|
|
||
|
Next
|
||
|
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' For static terminals: get default static terminal, select it on stream and start the stream
|
||
|
Sub AssignTerminals(CallNumber,pCall, is_no_video, is_no_render,bSetQOS, StartStreams)
|
||
|
On Error Resume Next
|
||
|
|
||
|
' Terminals may already selected somewhere
|
||
|
'Find call which have terminals selected
|
||
|
ActiveCall = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if spTerminalState(i) = TRUE Then
|
||
|
ActiveCall = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
if Not ActiveCall = 0 Then
|
||
|
'Exit Sub
|
||
|
End If
|
||
|
|
||
|
DIM pITCallInfo
|
||
|
Set pITCallInfo = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITCallInfo, pCall)
|
||
|
|
||
|
|
||
|
Call CheckError("AssignTerminals:query for pITCallInfo")
|
||
|
|
||
|
DIM pITAddress
|
||
|
Set pITAddress = pITCallInfo.Address
|
||
|
|
||
|
Call CheckError("AssignTerminals:pITCallInfo.Address")
|
||
|
|
||
|
DIM pITTerminalSupport
|
||
|
|
||
|
'Set pITTerminalSupport = MAPPER.QueryDispatchInterface(_
|
||
|
' IID_String_ITTerminalSupport,pITAddress)
|
||
|
Set pITTerminalSupport = pITAddress
|
||
|
Call CheckError("AssignTerminals:query for pITTerminalSupport")
|
||
|
|
||
|
|
||
|
DIM pITStreamControl
|
||
|
'Set pITStreamControl = MAPPER.QueryDispatchInterface(_
|
||
|
'IID_String_ITStreamControl,pCall)
|
||
|
Set pITStreamControl = pCall
|
||
|
call CheckError("AssignTerminals:Query ITCall for ITStreamControl" )
|
||
|
|
||
|
DIM pITStream
|
||
|
DIM lMediaType
|
||
|
DIM lDirection
|
||
|
|
||
|
'Setup all static terminals: video capture,
|
||
|
' and both audio terminals (microphone and speakers)
|
||
|
|
||
|
For Each pITStream in pITStreamControl.Streams
|
||
|
lMediaType = pITStream.MediaType
|
||
|
lDirection = pITStream.Direction
|
||
|
'Try to find correspondent terminal (if we need one ;))
|
||
|
|
||
|
if not ((is_no_video and lMediaType = TAPIMEDIAMODE_VIDEO) or _
|
||
|
(is_no_render and lMediaType = TAPIMEDIAMODE_VIDEO and lDirection=TD_CAPTURE) ) Then
|
||
|
|
||
|
if (lMediaType = TAPIMEDIAMODE_VIDEO) and (lDirection=TD_RENDER) Then
|
||
|
is_error = false
|
||
|
Else
|
||
|
|
||
|
Set pITTerminal = pITTerminalSupport.GetDefaultStaticTerminal(lMediaType,lDirection)
|
||
|
|
||
|
if not (Err.number = 0) Then 'No such terminal?
|
||
|
is_error = True
|
||
|
Err.Clear
|
||
|
Else
|
||
|
is_error = False
|
||
|
pITStream.SelectTerminal(pITTerminal)
|
||
|
End if
|
||
|
|
||
|
call CheckError("AssignTerminals:SelectTerminal" )
|
||
|
End If
|
||
|
|
||
|
|
||
|
if is_error Then 'Maybe unnecessary
|
||
|
' Maybe join audio only - special case
|
||
|
if (lMediaType = TAPIMEDIAMODE_VIDEO and lDirection=TD_CAPTURE) Then
|
||
|
'MsgBox "Unable to find video capture device: attach video receive only"
|
||
|
Else
|
||
|
if (lMediaType = TAPIMEDIAMODE_AUDIO and lDirection=TD_CAPTURE) Then
|
||
|
'MsgBox "Unable to find audio recording device: attach audio receive only"
|
||
|
Else
|
||
|
MsgBox "Unable to find audio playback device."
|
||
|
Err.Clear
|
||
|
sUnableToComplete = True
|
||
|
Exit Sub
|
||
|
End If
|
||
|
End if
|
||
|
|
||
|
Else 'No errors, start this stream!
|
||
|
|
||
|
|
||
|
'call CheckError("AssignTerminals:StartStream" )
|
||
|
'And now setup specific devices: video windows...
|
||
|
|
||
|
if (lMediaType = TAPIMEDIAMODE_VIDEO ) Then
|
||
|
'for Video Capture we will create a "Preview Window"terminal
|
||
|
'for Video Render we will create a "Video Window" Terminal
|
||
|
|
||
|
if lDirection = 0 Then 'see TD_CAPTURE = 0 in tapi3if.idl
|
||
|
|
||
|
'Preview window
|
||
|
pITStream.SelectTerminal(pVideoWindow2)
|
||
|
call CheckError("AssignTerminals: SelectTerminalStream")
|
||
|
|
||
|
'Show preview window (this will show the video stream sent by our app to the other party)
|
||
|
Dim pIVideoWindow2
|
||
|
Set pIVideoWindow2 = MAPPER.QueryDispatchInterface(IID_String_IVideoWindow, pVideoWindow2)
|
||
|
call CheckError("AssignTerminals: query for IVideoWindow")
|
||
|
pIVideoWindow2.AutoShow = True
|
||
|
'pIVideoWindow2.Visible = TRUE
|
||
|
|
||
|
call CheckError("AssignTerminals: set visibility")
|
||
|
|
||
|
|
||
|
End If
|
||
|
|
||
|
if lDirection = 1 Then 'see TD_RENDER = 1 in tapi3if.idl
|
||
|
|
||
|
pITStream.SelectTerminal(pVideoWindow1)
|
||
|
|
||
|
call CheckError("AssignTerminals: SelectTerminalStream")
|
||
|
|
||
|
'Show window (this will show us the video stream received by our app from the other party)
|
||
|
Dim pIVideoWindow1
|
||
|
Set pIVideoWindow1 = MAPPER.QueryDispatchInterface(IID_String_IVideoWindow, pVideoWindow1)
|
||
|
call CheckError("AssignTerminals: query for IVideoWindow")
|
||
|
pIVideoWindow1.AutoShow = True
|
||
|
'pIVideoWindow1.Visible = TRUE
|
||
|
call CheckError("AssignTerminals: set visibility")
|
||
|
|
||
|
|
||
|
End If
|
||
|
|
||
|
call CheckError("AssignTerminals: SelectTerminalStream")
|
||
|
|
||
|
End If 'Create Preview
|
||
|
End if 'have error
|
||
|
|
||
|
End if 'our Stream
|
||
|
|
||
|
call CheckError("AssignTerminals:GeneralChecking1" )
|
||
|
|
||
|
if StartStreams Then
|
||
|
Call pITStream.StartStream
|
||
|
Err.Clear
|
||
|
End If
|
||
|
|
||
|
|
||
|
Next ' End cycle for ITStreams
|
||
|
|
||
|
|
||
|
spTerminalState(CallNumber) = TRUE
|
||
|
|
||
|
|
||
|
call CheckError("AssignTerminals:Streams cycle problems" )
|
||
|
|
||
|
|
||
|
if bSetQOS Then
|
||
|
'Let's try to setup QoS level for video and audio
|
||
|
if not is_no_video Then
|
||
|
call pCall.SetQOS(TAPIMEDIAMODE_VIDEO,QSL_NEEDED)
|
||
|
call CheckError("AssignTerminals:set QOS_REQUIRED for Video" )
|
||
|
End If
|
||
|
|
||
|
call pCall.SetQOS(TAPIMEDIAMODE_AUDIO,QSL_NEEDED)
|
||
|
call CheckError("AssignTerminals:set QOS_REQUIRED for Audio" )
|
||
|
End IF
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Create two new Video Window terminals
|
||
|
Sub CreateCallWindow(pITAddress, AOnly,NoOutgoingVideo)
|
||
|
On Error Resume Next
|
||
|
|
||
|
'Obtain Terminal support
|
||
|
DIM pITTerminalSupport
|
||
|
|
||
|
'Set pITTerminalSupport = MAPPER.QueryDispatchInterface(_
|
||
|
'IID_String_ITTerminalSupport,pITAddress)
|
||
|
Set pITTerminalSupport = pITAddress
|
||
|
call CheckError("CreateCallWindow:Query ITAddress for ITTerminalSuport" )
|
||
|
|
||
|
if not AOnly Then 'create window for your party
|
||
|
|
||
|
Set pVideoWindow1 = pITTerminalSupport.CreateTerminal(CLSID_String_VideoWindowTerm,TAPIMEDIAMODE_VIDEO,TD_RENDER)
|
||
|
End If
|
||
|
|
||
|
if not AOnly and not NoOutgoingVideo Then
|
||
|
|
||
|
Set pVideoWindow2 = pITTerminalSupport.CreateTerminal(CLSID_String_VideoWindowTerm,TAPIMEDIAMODE_VIDEO,TD_RENDER)
|
||
|
End If 'Create window for preview
|
||
|
|
||
|
call CheckError("CreateCallWindow:GeneralChecking1" )
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Tapi events processing:
|
||
|
' - call state events ("connected", "disconnected")
|
||
|
' - and call notification events (these calls will be in "offering" state)
|
||
|
Sub TAPIOBJ_Event(event_type, tapi_event)
|
||
|
On Error Resume Next
|
||
|
DIM pITCallInfo
|
||
|
DIM pITCall
|
||
|
|
||
|
'MsgBox CStr(event_type)
|
||
|
|
||
|
if event_type = 2 Then
|
||
|
Call PopulateFwdRules
|
||
|
End if
|
||
|
|
||
|
'Check For disconnected call
|
||
|
if event_type = TE_CALLSTATE Then
|
||
|
|
||
|
DIM pITCallStateEvent
|
||
|
|
||
|
Set pITCallStateEvent = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITCallStateEvent,tapi_event)
|
||
|
|
||
|
call CheckError("TAPIOBJ_Event:unable to map" )
|
||
|
|
||
|
iCallState = pITCallStateEvent.State
|
||
|
'MsgBox "Call state" &Cstr(iCallState)
|
||
|
call CheckError("TAPIOBJ_Event:get CallState" )
|
||
|
|
||
|
Set pITCallInfo = pITCallStateEvent.Call
|
||
|
call CheckError("TAPIOBJ_Event:get CallInfo" )
|
||
|
|
||
|
Set pITCall = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITBasicCallControl, pITCallInfo)
|
||
|
call CheckError("TAPIOBJ_Event:get Call from CallInfo" )
|
||
|
|
||
|
if iCallState= CS_DISCONNECTED or iCallState= CS_IDLE Then
|
||
|
|
||
|
|
||
|
cause = pITCallStateEvent.Cause
|
||
|
|
||
|
strinnerHTML = ""
|
||
|
Select Case cause
|
||
|
Case 1 ' CEC_DISCONNECT_NORMAL
|
||
|
' Normal disconnect
|
||
|
Case 2 ' CEC_DISCONNECT_BUSY
|
||
|
strinnerHTML = "Your Party is busy.Try Later."
|
||
|
Case 3 ' CEC_DISCONNECT_BADADDRESS
|
||
|
strinnerHTML = "Address is invalid"
|
||
|
case 4 ' CEC_DISCONNECT_NOANSWER
|
||
|
strinnerHTML = "No answer from your party."
|
||
|
case 0 'CEC_NONE
|
||
|
strinnerHTML = "No answer from your party."
|
||
|
Case Else
|
||
|
strinnerHTML = "Your call is cancelled, rejected or failed"
|
||
|
End Select
|
||
|
|
||
|
window.status = "Done."
|
||
|
|
||
|
'Find call entry
|
||
|
ActiveCall = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if spITCall(i) Is pITCall Then
|
||
|
ActiveCall = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
if ActiveCall = 0 Then
|
||
|
'Bogus call : no such call
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
if strinnerHTML= "" Then
|
||
|
window.status = "Disconnected"
|
||
|
Else
|
||
|
window.status = strinnerHTML
|
||
|
End if
|
||
|
|
||
|
spCallState(ActiveCall) = window.status
|
||
|
Call UnselectTerminals
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
|
||
|
End If 'Call is disconnected
|
||
|
|
||
|
if iCallState = CS_CONNECTED Then 'Call is connected
|
||
|
window.status = "Call is connected."
|
||
|
|
||
|
'Find call entry
|
||
|
ActiveCall = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if spITCall(i) Is pITCall Then
|
||
|
ActiveCall = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
if ActiveCall = 0 Then
|
||
|
'Bogus call : no such call
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
|
||
|
spCallState(ActiveCall) = "Connected"
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
|
||
|
' Set digit detection
|
||
|
|
||
|
spITCall(ActiveCall).DetectDigits LINEDIGITMODE_DTMF
|
||
|
|
||
|
call CheckError("connect:Detect digits" )
|
||
|
|
||
|
End If 'Call is connected
|
||
|
End If ' event: call state
|
||
|
|
||
|
|
||
|
'Check only for incoming calls
|
||
|
if event_type = TE_CALLNOTIFICATION Then ' We have an incoming call (an "offering" call)
|
||
|
|
||
|
DIM pITCallNotificationEvent
|
||
|
Set pITCallNotificationEvent = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITCallNotificationEvent,tapi_event)
|
||
|
|
||
|
Call CheckError("TAPIOBJ_Event:query for pITDirectoryObjectUser")
|
||
|
|
||
|
CallOwnership = pITCallNotificationEvent.Event
|
||
|
|
||
|
|
||
|
Set pITCallInfo = pITCallNotificationEvent.Call
|
||
|
|
||
|
Call CheckError("TAPIOBJ_Event:get pITCallInfo")
|
||
|
|
||
|
if not blnShowOnlyOnce and pITCallInfo.CallState = CS_OFFERING and not ( CallOwnership = CNE_OWNER) Then
|
||
|
MsgBox "Unable to accept incoming calls: is other instance of this app running?",0,"Info"
|
||
|
blnShowOnlyOnce = True
|
||
|
Exit Sub
|
||
|
End IF
|
||
|
|
||
|
if CallOwnership = CNE_OWNER Then 'We are the owner!
|
||
|
|
||
|
'Create new call entry
|
||
|
|
||
|
' Find new entry in call array
|
||
|
DIM CallNumber
|
||
|
CallNumber = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if IsEmpty(spITCall(i)) Then
|
||
|
CallNumber = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
If CallNumber = 0 Then
|
||
|
MsgBox "Maximum number of calls reached. Disconnect call first",0,"connect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
if pITCallInfo.CallState = CS_OFFERING Then 'Offering
|
||
|
|
||
|
sCalleeName = pITCallInfo.CallInfoString(CIS_CALLERIDNAME)
|
||
|
|
||
|
|
||
|
if not Err.number = 0 then ' Caller ID name is not supported
|
||
|
sCalleeName = "Unknown"
|
||
|
Err.Clear
|
||
|
End if
|
||
|
|
||
|
sCallerNumber = pITCallInfo.CallInfoString(CIS_CALLERIDNUMBER)
|
||
|
|
||
|
if not Err.number = 0 then ' Caller ID number is not supported
|
||
|
sCallerNumber = ""
|
||
|
Err.Clear
|
||
|
Else
|
||
|
sCallerNumber = " {" & sCallerNumber & "}"
|
||
|
End If
|
||
|
|
||
|
sCalleeName = sCalleeName & sCallerNumber
|
||
|
|
||
|
sRName2 = pITCallInfo.CallInfoString(CIS_REDIRECTINGIDNAME)
|
||
|
|
||
|
if not Err.number = 0 then
|
||
|
sRName2 = ""
|
||
|
Err.Clear
|
||
|
End If
|
||
|
|
||
|
sRNumber = pITCallInfo.CallInfoString(CIS_REDIRECTINGIDNUMBER)
|
||
|
|
||
|
if not Err.number = 0 then ' Caller ID number is not supported
|
||
|
sRNumber = ""
|
||
|
Err.Clear
|
||
|
Else
|
||
|
sRNumber = " {" & sRNumber & "}"
|
||
|
End If
|
||
|
|
||
|
sRName2 = sRName2 & sRNumber
|
||
|
|
||
|
|
||
|
if not sRName2 = "" Then
|
||
|
' Trying to get forwarding reason
|
||
|
dueTo = ""
|
||
|
reason = pITCallInfo.CallInfoLong( CIL_REASON)
|
||
|
if not Err.number = 0 then ' non che
|
||
|
Err.Clear
|
||
|
Else
|
||
|
'tapi.h:#define LINECALLREASON_FWDBUSY 0x00000002
|
||
|
'tapi.h:#define LINECALLREASON_FWDNOANSWER 0x00000004
|
||
|
'tapi.h:#define LINECALLREASON_FWDUNCOND 0x00000008
|
||
|
if reason = 2 Then
|
||
|
dueTo = " since original caller was busy"
|
||
|
Else
|
||
|
if reason = 4 Then
|
||
|
dueTo = " since original caller does not answer"
|
||
|
End If
|
||
|
End If
|
||
|
End if
|
||
|
|
||
|
sRName2 = " ( Forwarded from " & sRName2 & dueTo &" )"
|
||
|
|
||
|
End if
|
||
|
|
||
|
|
||
|
DIM pITCallOffer
|
||
|
Set pITCallOffer = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITBasicCallControl, pITCallInfo)
|
||
|
|
||
|
Call CheckError("TAPIOBJ_Event:query for pITCall")
|
||
|
|
||
|
|
||
|
Set spITCall(CallNumber) = pITCallOffer
|
||
|
spCallState(CallNumber) = "Offering..."
|
||
|
spCallerCallee(CallNumber) = "Incoming " & sCalleeName &" " & sRName2
|
||
|
spTerminalState(CallNumber) = FALSE
|
||
|
spDtmfDetected(CallNumber) = ""
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
if AutoAnswer.value ="on" Then
|
||
|
Call AcceptIncomingCall(CallNumber,pITCallOffer, pITCallInfo)
|
||
|
End If
|
||
|
End If 'Call is offering
|
||
|
End If 'We are owner
|
||
|
|
||
|
End If 'Call Notification has arrived
|
||
|
|
||
|
'DTMF detection
|
||
|
if event_type = TE_DIGITEVENT Then
|
||
|
|
||
|
DIM pITDigitDetectionEvent
|
||
|
Set pITDigitDetectionEvent = MAPPER.QueryDispatchInterface(_
|
||
|
IID_String_ITDigitDetectionEvent,tapi_event)
|
||
|
|
||
|
Call CheckError("TAPIOBJ_Event:query for pITDigitDetectionEvent")
|
||
|
|
||
|
digit = pITDigitDetectionEvent.Digit
|
||
|
|
||
|
Set pITCallInfo = pITDigitDetectionEvent.Call
|
||
|
call CheckError("TAPIOBJ_Event:get CallInfo" )
|
||
|
|
||
|
Set pITCall = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITBasicCallControl, pITCallInfo)
|
||
|
call CheckError("TAPIOBJ_Event:get Call from CallInfo" )
|
||
|
|
||
|
'Find call entry
|
||
|
ActiveCall = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if spITCall(i) Is pITCall Then
|
||
|
ActiveCall = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
if ActiveCall = 0 Then
|
||
|
'Bogus call : no such call
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
spDtmfDetected(ActiveCall) = spDtmfDetected(ActiveCall) & Chr(digit)
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
End if
|
||
|
|
||
|
|
||
|
End Sub
|
||
|
'*
|
||
|
'*
|
||
|
'*
|
||
|
'*
|
||
|
Sub AnswerCall
|
||
|
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
|
||
|
DIM pITCallInfo
|
||
|
Set pITCallInfo = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITCallInfo,spITCall(ActiveCall))
|
||
|
|
||
|
Call CheckError("Get CallInfo from Call in AnswerCall")
|
||
|
|
||
|
Call AcceptIncomingCall(ActiveCall,spITCall(ActiveCall), pITCallInfo)
|
||
|
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Sub for incoming calls processing
|
||
|
Sub AcceptIncomingCall(CallNumber,pITCallIncoming,pITCallInfoIncoming)
|
||
|
On Error Resume Next
|
||
|
'Get address
|
||
|
|
||
|
sUnableToComplete = False
|
||
|
DIM pITAddress
|
||
|
Set pITAddress = pITCallInfoIncoming.Address
|
||
|
Call CheckError("AcceptIncomingCall:pITCallInfo.Address")
|
||
|
|
||
|
|
||
|
sname1 = pITCallInfoIncoming.CallerIDName
|
||
|
if not Err.number = 0 Then
|
||
|
sname1 = "Unknown"
|
||
|
Err.Clear
|
||
|
End If
|
||
|
|
||
|
|
||
|
Call CheckError("AcceptIncomingCall:sFriendltName")
|
||
|
|
||
|
Call UnselectTerminals
|
||
|
|
||
|
|
||
|
|
||
|
'sAddressName = pITAddress.AddressName
|
||
|
Call CheckError("AcceptIncomingCall:AddressName")
|
||
|
|
||
|
Call CreateCallWindow(pITAddress,False,False)
|
||
|
|
||
|
Call CheckError("AcceptIncomingCall: after CreateCallWindow")
|
||
|
|
||
|
|
||
|
window.status = "Configure terminals."
|
||
|
|
||
|
Call AssignTerminals(CallNumber,pITCallIncoming,False,False,False, False)
|
||
|
call CheckError("AcceptIncomingCall:after AssignTerminals" )
|
||
|
|
||
|
if sUnableToComplete or sbNeedToExit Then
|
||
|
window.status = ""
|
||
|
pITCallIncoming.Disconnect 6 'rejected
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
window.status = "Answering..."
|
||
|
|
||
|
Call pITCallIncoming.Answer()
|
||
|
window.status = "Connected."
|
||
|
|
||
|
call CheckError("AcceptIncomingCall:main connect" )
|
||
|
|
||
|
|
||
|
window.status = "Done."
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Disconnect current call
|
||
|
Sub DisconnectCall(CallNumber,callDisc)
|
||
|
On Error resume Next
|
||
|
|
||
|
if not IsEmpty(spITCall(CallNumber)) Then
|
||
|
|
||
|
if not callDisc = 8 and not callDisc = 0 Then
|
||
|
' We need some kind of message pump here. The following call to MsgBox does exactly this:
|
||
|
MsgBox "A call is disconnected",0,"Disconnect"
|
||
|
End If
|
||
|
|
||
|
Set pVideoWindow1 = Nothing
|
||
|
Set pVideoWindow2 = Nothing
|
||
|
|
||
|
window.status = "You are disconnected"
|
||
|
|
||
|
if callDisc=0 Then
|
||
|
spITCall(CallNumber).Disconnect(DC_NORMAL)
|
||
|
End If
|
||
|
spITCallTransferred(ActiveCall) = Empty
|
||
|
|
||
|
End If
|
||
|
Call RefreshCallTable
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Disconnect call if we have one and shutdown TAPI object on exit from page
|
||
|
Sub window_onunload
|
||
|
On Error Resume Next
|
||
|
|
||
|
Call DisconnectCall(0)
|
||
|
|
||
|
TAPIOBJ.Shutdown
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Used by radio button: address type
|
||
|
Sub change_type
|
||
|
sCurrentAddressType = CInt(window.event.srcElement.value )
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'small function to change value of checkboxes in a more appropriate
|
||
|
' manner.
|
||
|
Sub togglechk()
|
||
|
'Toggle state of checkbox
|
||
|
If (window.event.srcElement.value = "off") Then
|
||
|
window.event.srcElement.value ="on"
|
||
|
Else
|
||
|
window.event.srcElement.value ="off"
|
||
|
End IF
|
||
|
End Sub
|
||
|
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
Sub PressCreateRule
|
||
|
buttFCreate.disabled = True
|
||
|
editDestination.value = ""
|
||
|
editCaller.value = ""
|
||
|
FwdInfo.style.visibility = "visible"
|
||
|
End Sub
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
' Used by radio button: forward type
|
||
|
Sub changeF_type
|
||
|
On Error resume Next
|
||
|
FwdType = CInt(window.event.srcElement.value )
|
||
|
End Sub
|
||
|
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
Sub FRuleCancel
|
||
|
On Error resume Next
|
||
|
buttFCreate.disabled = False
|
||
|
FwdInfo.style.visibility = "hidden"
|
||
|
End Sub
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
|
||
|
Sub FRuleCreate
|
||
|
On Error resume Next
|
||
|
|
||
|
if FwdType = 0 Then
|
||
|
MsgBox "Forwarding type is not selected"
|
||
|
Exit Sub
|
||
|
End if
|
||
|
|
||
|
'Find address selected
|
||
|
DIM pITAddress_Connect
|
||
|
|
||
|
Set pITAddress_Connect = spITAddress
|
||
|
|
||
|
call CheckError("Before create" )
|
||
|
|
||
|
Set pCall = pITAddress_Connect.CreateCall("",1,S_MEDIA_AUDIOVIDEO)
|
||
|
|
||
|
call CheckError("CreateCall" )
|
||
|
|
||
|
|
||
|
Set pForwarding = pITAddress_Connect.CreateForwardInfoObject
|
||
|
|
||
|
call CheckError("CreateForwardInfoObject" )
|
||
|
|
||
|
pForwarding.NumRingsNoAnswer = 2
|
||
|
|
||
|
call CheckError("NumRingsNoAnswer" )
|
||
|
|
||
|
if editCaller.value = "" Then
|
||
|
if FwdType = 1 Then
|
||
|
FwdT = 1
|
||
|
elseif FwdType = 2 Then
|
||
|
FwdT = 16
|
||
|
elseif FwdType = 3 Then
|
||
|
FwdT = 256
|
||
|
else
|
||
|
FwdT = 4096
|
||
|
end if
|
||
|
|
||
|
else
|
||
|
if FwdType = 1 Then
|
||
|
FwdT = 8
|
||
|
elseif FwdType = 2 Then
|
||
|
FwdT = 128
|
||
|
elseif FwdType = 3 Then
|
||
|
FwdT = 2048
|
||
|
else
|
||
|
FwdT = 32768
|
||
|
end if
|
||
|
end if
|
||
|
|
||
|
pForwarding.SetForwardType FwdT, editDestination.value, editCaller.value
|
||
|
|
||
|
call CheckError("An error occured while preparing forward information" )
|
||
|
|
||
|
|
||
|
pITAddress_Connect.Forward pForwarding, pCall
|
||
|
|
||
|
|
||
|
call CheckError("An error occured while setting forward information" )
|
||
|
|
||
|
Call FRuleCancel
|
||
|
|
||
|
Call PopulateFwdRules
|
||
|
|
||
|
End Sub
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
'********************************************************************
|
||
|
Sub PopulateFwdRules
|
||
|
On Error resume Next
|
||
|
' clear select
|
||
|
'Remove all from list
|
||
|
'For i = 0 to selectRules.options.length
|
||
|
' selectRules.remove(0)
|
||
|
'Next
|
||
|
|
||
|
'get forward info
|
||
|
Set CurrentFwd = spITAddress.CurrentForwardInfo
|
||
|
call CheckError("CurrentForwardInfo" )
|
||
|
|
||
|
'now lets find all about it...
|
||
|
|
||
|
FwdT = 1
|
||
|
|
||
|
fRule.innerHTML = ""
|
||
|
|
||
|
For i = 1 to 18
|
||
|
s1 =""
|
||
|
s2 =""
|
||
|
s2 = CurrentFwd.ForwardTypeCaller(FwdT)
|
||
|
call CheckError("GetForwardType" )
|
||
|
s1 = CurrentFwd.ForwardTypeDestination(FwdT)
|
||
|
call CheckError("GetForwardType1" )
|
||
|
if Not (s1 ="") Then
|
||
|
|
||
|
|
||
|
|
||
|
if FwdT = 1 or FwdT = 8 Then
|
||
|
s4 = "always"
|
||
|
elseif FwdT = 16 or FwdT = 128 Then
|
||
|
s4 = "when we are busy"
|
||
|
elseif FwdT = 256 or FwdT = 2048 Then
|
||
|
s4 = "on no answer"
|
||
|
else
|
||
|
s4 = "on no answer or busy"
|
||
|
end if
|
||
|
|
||
|
if Not (Asc(s1) = 63) Then
|
||
|
s5 = "from "& s1 & " "
|
||
|
else
|
||
|
s5 = " "
|
||
|
end if
|
||
|
|
||
|
s3 = "Forward calls "& s5 & s4 & " to "& s2
|
||
|
|
||
|
'Set oOption = document.createElement("OPTION")
|
||
|
'oOption.text = s3
|
||
|
'oOption.value = s3
|
||
|
'selectRules.add(oOption)
|
||
|
fRule.innerHTML = fRule.innerHTML & s3 & "<BR>"
|
||
|
End if
|
||
|
|
||
|
FwdT = FwdT * 2
|
||
|
Next
|
||
|
|
||
|
if fRule.innerHTML = "" Then
|
||
|
fRule.innerHTML = "No rules are active"
|
||
|
End if
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'
|
||
|
''
|
||
|
''
|
||
|
''
|
||
|
'
|
||
|
'********************************************************************
|
||
|
Function check_call
|
||
|
On Error Resume Next
|
||
|
check_call = True
|
||
|
if selectCalls.value = "" or IsEmpty(selectCalls.value) Then
|
||
|
MsgBox "You need to select call first",0,"Operations"
|
||
|
check_call= False
|
||
|
End if
|
||
|
End Function
|
||
|
'
|
||
|
''
|
||
|
''
|
||
|
''
|
||
|
Sub DeleteCall
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
Set spITCall(ActiveCall) = Nothing
|
||
|
spITCall(ActiveCall) = Empty
|
||
|
spCallerCallee(ActiveCall) = ""
|
||
|
Call RefreshCallTable
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub DisconnectThisCall
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
Call DisconnectCall(ActiveCall, 0)
|
||
|
Call RefreshCallTable
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub HoldCall
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
|
||
|
if ISEmpty(spCallOnHold(ActiveCall)) Or spCallOnHold(ActiveCall) = FALSE Then
|
||
|
spCallOnHold(ActiveCall) = TRUE
|
||
|
Else
|
||
|
spCallOnHold(ActiveCall) = FALSE
|
||
|
End If
|
||
|
|
||
|
spITCall(ActiveCall).Hold(spCallOnHold(ActiveCall))
|
||
|
|
||
|
Call CheckError("HoldCall: ITBAsicCallControl.Hold")
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub BlindTransferCall
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
sDestinationAddress= InputBox("Enter destination for call transfer", "Blind Transfer")
|
||
|
|
||
|
spITCall(ActiveCall).BlindTransfer(sDestinationAddress)
|
||
|
spCallerCallee(ActiveCall) = spCallerCallee(ActiveCall) & "(BTRNSF:"&sDestinationAddress& ")"
|
||
|
|
||
|
CheckError("Call BlindTransfer")
|
||
|
End If
|
||
|
End Sub
|
||
|
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub RedirectCall
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
sDestinationAddress= InputBox("Enter new destination for call", "Call Redirection")
|
||
|
|
||
|
spITCall(ActiveCall).BlindTransfer(sDestinationAddress)
|
||
|
spCallerCallee(ActiveCall) = spCallerCallee(ActiveCall) & "(Blind TRSFR:"&sDestinationAddress& ")"
|
||
|
CheckError("Call BlindTransfer")
|
||
|
End If
|
||
|
End Sub
|
||
|
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub SelectTerminals
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
Call UnselectTerminals
|
||
|
|
||
|
DIM pITCallInfo
|
||
|
Set pITCallInfo = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITCallInfo, spITCall(ActiveCall))
|
||
|
|
||
|
Set pITAddress = pITCallInfo.Address
|
||
|
call CheckError("connect:get CalllInfo from Call" )
|
||
|
Call CreateCallWindow(pITAddress,False,False)
|
||
|
|
||
|
Call CheckError("SelectTerminals: after CreateCallWindow")
|
||
|
|
||
|
Call AssignTerminals(ActiveCall,spITCall(ActiveCall),False,False,False, True)
|
||
|
Call RefreshCallTable
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
Sub TransferCall
|
||
|
'Not yet fully implemented, workaroud for now..
|
||
|
On Error Resume Next
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
sDestinationAddress= InputBox("Enter destination for call transfer", "Transfer")
|
||
|
|
||
|
spCallerCallee(ActiveCall) = spCallerCallee(ActiveCall) & "(TRNSFR:"&sDestinationAddress& ")"
|
||
|
|
||
|
DIM pITCallInfo
|
||
|
Set pITCallInfo = MAPPER.QueryDispatchInterface( _
|
||
|
IID_String_ITCallInfo, spITCall(ActiveCall))
|
||
|
|
||
|
|
||
|
Set pITAddress = pITCallInfo.Address
|
||
|
|
||
|
Set pCall = pITAddress.CreateCall(sDestinationAddress,16, S_MEDIA_AUDIOVIDEO)
|
||
|
CheckError("Call Transfer: Create Call")
|
||
|
|
||
|
Set Call1= spITCall(ActiveCall)
|
||
|
|
||
|
'Unselect Terminals from previous call
|
||
|
'if Not spCallOnHold(ActiveCall) Then
|
||
|
' Call1.Hold(TRUE)
|
||
|
' CheckError("Call Transfer: Hold Call")
|
||
|
' spCallOnHold(ActiveCall) = TRUE
|
||
|
'End If
|
||
|
Call UnselectTerminals
|
||
|
|
||
|
'Set spITCallTransferred(ActiveCall) = pCall
|
||
|
|
||
|
'do not make Call UnselectTerminals
|
||
|
|
||
|
' Find new entry in call array
|
||
|
DIM CallNumber
|
||
|
CallNumber = 0
|
||
|
For i = 1 to MaxCallNumber
|
||
|
if IsEmpty(spITCall(i)) Then
|
||
|
CallNumber = i
|
||
|
Exit For
|
||
|
End If
|
||
|
Next
|
||
|
|
||
|
If CallNumber = 0 Then
|
||
|
MsgBox "Maximum number of calls reached. Disconnect call first",0,"connect"
|
||
|
Exit Sub
|
||
|
End If
|
||
|
|
||
|
Set spITCall(CallNumber) = pCall
|
||
|
spCallState(CallNumber) = "Initiating transfer..."
|
||
|
spCallerCallee(CallNumber) = "To " & pConnectTo
|
||
|
spDtmfDetected(CallNumber) = ""
|
||
|
'Select Terminals
|
||
|
Call CreateCallWindow(pITAddress,False,False)
|
||
|
|
||
|
Call CheckError("Call Transfer: after CreateCallWindow")
|
||
|
|
||
|
window.status = "Configure terminals."
|
||
|
|
||
|
Call AssignTerminals(CallNumber,pCall,False,False,False,False)
|
||
|
call CheckError("Call Transfer:after AssignTerminals" )
|
||
|
|
||
|
Call1.Transfer pCall , FALSE
|
||
|
|
||
|
Call CheckError("CreateTransfer: Transfer")
|
||
|
End If
|
||
|
|
||
|
|
||
|
Call RefreshCallTable
|
||
|
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
Sub FinishTransferCall
|
||
|
On Error Resume Next
|
||
|
|
||
|
if check_call() Then
|
||
|
|
||
|
ActiveCall = selectCalls.value
|
||
|
Set Call1= spITCall(ActiveCall)
|
||
|
'if IsEmpty(spITCallTransferred(ActiveCall)) Then
|
||
|
' MsgBox "Wrong call to finish transfer"
|
||
|
' Exit Sub
|
||
|
' End If
|
||
|
|
||
|
Call1.Finish 0
|
||
|
Call CheckError("FinishTransferCall: Finish")
|
||
|
|
||
|
spITCallTransferred(ActiveCall) = Empty
|
||
|
|
||
|
End If
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
'
|
||
|
DIM sKeypadCall
|
||
|
Sub SendDTMF
|
||
|
if check_call() Then
|
||
|
ActiveCall = selectCalls.value
|
||
|
sKeypadCall = ActiveCall
|
||
|
divKeypad.style.visibility = "visible"
|
||
|
End If
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
Sub CancelDtmf
|
||
|
divKeypad.style.visibility = "hidden"
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
'******************************************************************
|
||
|
|
||
|
Sub DoClick
|
||
|
On Error Resume Next
|
||
|
window.event.cancelBubble = True
|
||
|
'1. Determine element that is clicked
|
||
|
Set sCurrentlyClickedButton = window.event.srcElement
|
||
|
|
||
|
'2. Change background to blue
|
||
|
sCurrentlyClickedButton.style.background = "blue"
|
||
|
|
||
|
'Send DTMF code
|
||
|
spITCall(sKeypadCall).GenerateDigits sCurrentlyClickedButton.value,2 'DTMF mode
|
||
|
Call CheckError("DoClick:pITLegacyCallMediaControl.GenerateDigits")
|
||
|
sCurrentlyClickedButton.style.background = "gray"
|
||
|
|
||
|
|
||
|
End Sub
|
||
|
|
||
|
|
||
|
|
||
|
</script>
|
||
|
|
||
|
<div id="AllElementsNonSimple" style="position:absolute;top:5px" >
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 0px;width:400px;background:blue;LEFT:0px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Dialing center
|
||
|
</p>
|
||
|
|
||
|
<div id="UserSelectionSection" style="position:absolute;Width:300px">
|
||
|
|
||
|
<p style="HEIGHT: 20px; background:#000080;POSITION: absolute; TOP: 20px;width:200px;LEFT:20px;FONT-SIZE:16px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Address to call
|
||
|
</p>
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; background:#000080;TOP: 75px;width:200px;LEFT:20px;FONT-SIZE:16px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Address type
|
||
|
</p>
|
||
|
|
||
|
<input id="txtAddress" style="HEIGHT: 30px; POSITION: absolute; TOP: 40px;LEFT:20px;FONT-SIZE:16px;COLOR:black;WIdth:200px">
|
||
|
|
||
|
<div id="divRadioGroup" style="BORDER-BOTTOM: black 2px solid; BORDER-LEFT: black 2px solid; BORDER-RIGHT: black 2px solid; BORDER-TOP: black 2px solid; HEIGHT: 80px; LEFT: 20px; POSITION: absolute; TOP: 100px; WIDTH: 200px">
|
||
|
<font style="COLOR: black; FONT-SIZE: 12px;font-style:oblique">
|
||
|
|
||
|
|
||
|
<input id="radioAddressType" name="radioAddressType" onclick="change_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 10px;LEFT:10px" type="radio" value="16" title="IP Address">
|
||
|
|
||
|
<input id="radioAddressType" name="radioAddressType" onclick="change_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 40px; LEFT:10px" type="radio" value="1" title="Phone Number">
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 10px;LEFT:40px">
|
||
|
IP Address
|
||
|
</p>
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 40px;LEFT:40px">
|
||
|
Phone Number
|
||
|
</p>
|
||
|
|
||
|
</font>
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<div id="Separator3" style="position:absolute;BORDER-BOTTOM: blue 2px solid; BORDER-LEFT: blue 2px solid; BORDER-RIGHT: blue 2px solid; BORDER-TOP: blue 2px solid; HEIGHT: 305px; LEFT:405px; POSITION: absolute; TOP: 0px; WIDTH: 0px">
|
||
|
</div>
|
||
|
|
||
|
<div id="PropertiesSelectionSection" style="LEFT:0px;ALIGN:CENTER;position:absolute;top:190px;Width:400px">
|
||
|
<p style="HEIGHT: 10px; POSITION: absolute; TOP: 0px;background:#808080;width:100%;LEFT:0px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Originating address and call properties
|
||
|
</p>
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute;background:#000080; TOP: 20px;width:200px;LEFT:0px;FONT-SIZE:16px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Address
|
||
|
</p>
|
||
|
<select id="selAddress" name="selAddress" onchange="changeOptionsState()" style="position:absolute;width:200px;Left:0px;FONT-SIZE:16px;COLOR:black;top:40px">
|
||
|
</select>
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 20px;width:150px;LEFT:200px;FONT-SIZE:16px;COLOR:black;TEXT-ALIGN:center">
|
||
|
Setup audio only
|
||
|
</p>
|
||
|
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 40px;width:150px;LEFT:200px;FONT-SIZE:16px;COLOR:black;TEXT-ALIGN:center">
|
||
|
Setup no video-out
|
||
|
</p>
|
||
|
|
||
|
<input type="checkbox" id="checkAOnly" name="checkAROnly" value="off" onclick="togglechk()" style="HEIGHT: 20px; LEFT: 350px; POSITION: absolute; TOP: 20px; WIDTH: 20px" title="Connect Audio Only">
|
||
|
|
||
|
<input type="checkbox" id="checkNoOutgoingVideo" value="off" onclick="togglechk()" style="HEIGHT: 20px; LEFT: 350px; POSITION: absolute; TOP: 40px; WIDTH: 20px" title="Do not send outgoing video">
|
||
|
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<INPUT type=button id="buttConnect" style="cursor:hand;LEFt:40px; HEIGHT: 30px; POSITION: absolute; WIDTH: 300px; top:270px" onclick="PressConnect()" value="Create new call" title="Create new call">
|
||
|
|
||
|
|
||
|
|
||
|
<!--p id=ConnANN style="HEIGHT: 20px; POSITION: absolute; TOP: 305px;width:100%;background:blue;LEFT:3px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center">
|
||
|
</p-->
|
||
|
<hr id=secHr1243 size=1 ALIGN=RIGHT style="color:blue;position:absolute;Top:310px;Left:0px;width:100%">
|
||
|
|
||
|
|
||
|
<div style="HEIGHT: 150px; POSITION: absolute; TOP: 315px;width:100%;LEFT:10px;FONT-SIZE:18px;COLOR:black">
|
||
|
<p style="POSITION: absolute; background:blue; TOP: 10px;width:400px;LEFT:0px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Forwarding information
|
||
|
</p>
|
||
|
|
||
|
<P id=FRule style="FONT-SIZE: 16px;color:blue;z-index:10; HEIGHT: 100px; LEFT: 20px; POSITION: absolute; TOP: 35px; WIDTH: 350px;BORDER-BOTTOM: blue 1px solid; BORDER-LEFT: blue 1px solid; BORDER-RIGHT: blue 1px solid; BORDER-TOP: blue 1px solid">
|
||
|
</P>
|
||
|
|
||
|
<INPUT type=button id="buttFCreate" style="cursor:hand;LEFt:20px; HEIGHT: 30px; POSITION: absolute; WIDTH: 350px; top:140px" onclick="PressCreateRule()" value="Create New Forward rule" title="Create New Forward rule">
|
||
|
|
||
|
<!--INPUT type=button id="buttFClear" style="visibility:hidden;cursor:hand;LEFt:20px; HEIGHT: 30px; POSITION: absolute; WIDTH: 200px; top:100px" onclick="PressClearForward()" value="Clear Forwarding" title="Clear Forwarding"-->
|
||
|
|
||
|
<!--hr id=secHr1 size=1 ALIGN=RIGHT style="color:blue;position:absolute;Top:135px;Left:0px;width:300px"-->
|
||
|
|
||
|
<!--p style="POSITION: absolute; TOP: 140px;width:100%;LEFT:50px;FONT-SIZE:18px;COLOR:black">
|
||
|
Current forward rules
|
||
|
</p-->
|
||
|
|
||
|
<!--SELECT size=2 id=selectRules name=selectRules
|
||
|
style="FONT-SIZE: 12px;z-index:10; HEIGHT: 150px; LEFT: 20px; POSITION: absolute; TOP: 160px; WIDTH: 200px">
|
||
|
</SELECT-->
|
||
|
<!--INPUT type=button style="cursor:hand;LEFt:30px; HEIGHT: 20px; POSITION: absolute; WIDTH: 180px; top:320px" onclick="PopulateFwdRules()" value="refresh" title="Refresh Rules"-->
|
||
|
<hr id=secHr1 size=2 ALIGN=RIGHT style="color:blue;position:absolute;Top:180px;Left:0px;width:405px">
|
||
|
|
||
|
<div id="Separator3" style="position:absolute;BORDER-BOTTOM: blue 2px solid; BORDER-LEFT: blue 2px solid; BORDER-RIGHT: blue 2px solid; BORDER-TOP: blue 2px solid; HEIGHT: 250px; LEFT:405px; POSITION: absolute; TOP: -10px; WIDTH: 0px">
|
||
|
</div>
|
||
|
<p style="POSITION: absolute; background:blue; TOP: 190px;width:400px;LEFT:0px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center">
|
||
|
Application features
|
||
|
</p>
|
||
|
|
||
|
<input disabled type="checkbox" id="AutoAnswer" name="AutoAnswer" value="off" onclick="togglechk()" style="HEIGHT: 20px; LEFT: 140px; POSITION: absolute; TOP: 220px; WIDTH: 20px" title="Auto Answer">
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 220px;LEFT:20px">
|
||
|
Auto Answer
|
||
|
</p>
|
||
|
|
||
|
<!--p style="POSITION: absolute; TOP: 250px;width:100%;LEFT:50px;FONT-SIZE:18px;COLOR:black">
|
||
|
DTMF digits detected
|
||
|
</p>
|
||
|
|
||
|
<P id=DTMFD style="FONT-SIZE: 16px;color:blue;z-index:10; HEIGHT: 100px; LEFT: 20px; POSITION: absolute; TOP: 280px; WIDTH: 200px">
|
||
|
</P-->
|
||
|
<div id=TransfInfo style="visibility:hidden;POSITION: absolute; TOP: 0px;width:350;LEFT:420px;FONT-SIZE:22px;COLOR:black;background-color:grey">
|
||
|
<p style="POSITION: absolute; TOP: 10px;width:350px;LEFT:20px;FONT-SIZE:22px;COLOR:white;background:blue">
|
||
|
Call Transfer
|
||
|
</p>
|
||
|
|
||
|
<p id=transp style="POSITION: absolute; TOP: 50px;width:350px;LEFT:20px;FONT-SIZE:22px;COLOR:black">
|
||
|
</p>
|
||
|
|
||
|
<INPUT type=button style="cursor:hand;LEFt:10px; HEIGHT: 30px; POSITION: absolute; WIDTH: 150px; top:200px" onclick="CreateTransfer()" value="Make Transfer" title="Make Transfer">
|
||
|
<INPUT type=button style="cursor:hand;LEFt:180px; HEIGHT: 30px; POSITION: absolute; WIDTH: 150px; top:200px" onclick="CancelTransfer()" value="Cancel Transfer" title="Cancel Transfer">
|
||
|
|
||
|
</div>
|
||
|
|
||
|
<div id=FwdInfo style="visibility:hidden;POSITION: absolute; TOP: 0px;width:350;LEFT:420px;FONT-SIZE:22px;COLOR:black;background-color:grey">
|
||
|
<p style="POSITION: absolute; TOP: 10px;width:100%;LEFT:20px;FONT-SIZE:22px;COLOR:black">
|
||
|
New Forward Rule
|
||
|
</p>
|
||
|
|
||
|
<p style="POSITION: absolute; TOP: 50px;width:100%;LEFT:20px;FONT-SIZE:18px;COLOR:black">
|
||
|
Forward to
|
||
|
</p>
|
||
|
|
||
|
<INPUT id="editDestination" style="LEFt:20px; HEIGHT: 25px; POSITION: absolute; WIDTH: 120px; top:70px" >
|
||
|
|
||
|
<p style="POSITION: absolute; TOP: 100px;width:100%;LEFT:20px;FONT-SIZE:18px;COLOR:black">
|
||
|
When
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<div style="HEIGHT: 200px; LEFT: 20px; POSITION: absolute; TOP: 110px; WIDTH: 300px">
|
||
|
<font style="COLOR: black; FONT-SIZE: 12px;font-style:oblique">
|
||
|
|
||
|
<input id="radioFType" name="radioFType" onclick="changeF_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 10px;LEFT:10px" type="radio" value="1" title="Unconditional forward">
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 10px;LEFT:40px">
|
||
|
Always
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<input id="radioFType" name="radioFType" onclick="changeF_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 30px;LEFT:10px" type="radio" value="2" title="Forward when we are busy">
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 30px;LEFT:30px">
|
||
|
Forward when we are busy
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<input id="radioFType" name="radioFType" onclick="changeF_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 50px;LEFT:10px" type="radio" value="3" title="Forward on no answer">
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 50px;LEFT:30px">
|
||
|
Forward on no answer
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<input id="radioFType" name="radioFType" onclick="changeF_type()" style="HEIGHT: 20px; POSITION: absolute; TOP: 70px;LEFT:10px" type="radio" value="4" title="Forward on no answer or busy">
|
||
|
<p style="HEIGHT: 20px; POSITION: absolute; TOP: 70px;LEFT:30px">
|
||
|
Forward on no answer or busy
|
||
|
</p>
|
||
|
|
||
|
</font>
|
||
|
|
||
|
</div>
|
||
|
<p style="POSITION: absolute; TOP: 200px;width:100%;LEFT:20px;FONT-SIZE:18px;COLOR:black">
|
||
|
Forward only this caller:
|
||
|
</p>
|
||
|
|
||
|
<INPUT id="editCaller" style="LEFt:20px; HEIGHT: 25px; POSITION: absolute; WIDTH: 120px; top:220px" >
|
||
|
|
||
|
<INPUT type=button id="buttFRule" style="cursor:hand;LEFt:20px; HEIGHT: 30px; POSITION: absolute; WIDTH: 100px; top:250px" onclick="FRuleCreate()" value="Create" title="Create Rule">
|
||
|
<INPUT type=button id="buttFRule" style="cursor:hand;LEFt:140px; HEIGHT: 30px; POSITION: absolute; WIDTH: 100px; top:250px" onclick="FRuleCancel()" value="Cancel" title="Cancel Rule Creation">
|
||
|
|
||
|
</div>
|
||
|
</div>
|
||
|
|
||
|
<div style="position:absolute;top:0px;left:410px">
|
||
|
<p style="POSITION: absolute; TOP: 5px;width:580px;background:blue;LEFT:0px;FONT-SIZE:18px;COLOR:white;TEXT-ALIGN:center;LEFT:20px;FONT-SIZE:18px;COLOR:white">
|
||
|
Call Table
|
||
|
</p>
|
||
|
|
||
|
<SELECT size=2 id=selectCalls name=selectCalls
|
||
|
style="FONT-SIZE: 10px;z-index:10; HEIGHT: 262px; LEFT: 20px; POSITION: absolute; TOP: 40px; WIDTH: 380px">
|
||
|
</SELECT>
|
||
|
|
||
|
<INPUT type=button id="buttAnswer" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:35px" onclick="AnswerCall()" value="Answer Call" title="Answer Call">
|
||
|
<INPUT type=button id="buttRedirect" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:60px" onclick="RedirectCall()" value="Redirect Call" title="Redirect Call">
|
||
|
<INPUT type=button id="buttBlindTransfer" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:85px" onclick="BlindTransferCall()" value="Blind Transfer" title="Blind Transfer">
|
||
|
<INPUT type=button id="buttTransfer" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:110px" onclick="TransferCall()" value="Start Transfer" title="StartTransfer">
|
||
|
<INPUT type=button id="buttDisconnect" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:135px" onclick="FinishTransferCall()" value="Finish Transfer" title="Finish Transfer">
|
||
|
|
||
|
<INPUT type=button id="buttDisconnect" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:160px" onclick="DisconnectThisCall()" value="Disconnect" title="Disconnect">
|
||
|
<INPUT type=button id="buttHold" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:185px" onclick="HoldCall()" value="Hold/UnHold" title="Hold/UnHold">
|
||
|
<INPUT type=button id="buttUnselect" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:210px" onclick="SelectTerminals()" value="SelectTerminals" title="SelectTerminals">
|
||
|
<INPUT type=button id="buttDelete" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:235px" onclick="DeleteCall()" value="Delete Call" title="Delete Call">
|
||
|
<INPUT type=button id="buttDTMF" style="cursor:hand;LEFt:405px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:260px" onclick="SendDTMF()" value="Send DTMF" title="Send DTMF">
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<div id=divKeypad style="visibility:hidden;HEIGHT: 200px; LEFT: 460px; POSITION: absolute; TOP: 305px; WIDTH: 150px">
|
||
|
|
||
|
<div style="BORDER-BOTTOM: black 2px solid; BORDER-LEFT: black 2px solid;
|
||
|
BORDER-RIGHT: black 2px solid; BORDER-TOP: black 2px solid;
|
||
|
HEIGHT: 180px; LEFT: 0px; POSITION: absolute; TOP: 20px; WIDTH: 150px;background:#000080;">
|
||
|
|
||
|
<INPUT id=butt1 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:10px;left:20px;width:30px"
|
||
|
value="1">
|
||
|
<INPUT id=butt2 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:10px;left:60px;width:30px"
|
||
|
value="2">
|
||
|
<INPUT id=butt3 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:10px;left:100px;width:30px"
|
||
|
value="3">
|
||
|
<INPUT id=butt4 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:50px;left:20px;width:30px"
|
||
|
value="4">
|
||
|
<INPUT id=butt5 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:50px;left:60px;width:30px"
|
||
|
value="5">
|
||
|
<INPUT id=butt6 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:50px;left:100px;width:30px"
|
||
|
value="6">
|
||
|
<INPUT id=butt7 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:90px;left:20px;width:30px"
|
||
|
value="7">
|
||
|
<INPUT id=butt8 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:90px;left:60px;width:30px"
|
||
|
value="8">
|
||
|
<INPUT id=butt9 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:90px;left:100px;width:30px"
|
||
|
value="9">
|
||
|
<INPUT id=buttA onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:130px;left:20px;width:30px"
|
||
|
value="*">
|
||
|
<INPUT id=butt0 onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:130px;left:60px;width:30px"
|
||
|
value="0">
|
||
|
<INPUT id=buttD onclick="DoClick()" type=button style="color:white;background:gray;position:absolute;height:30px;top:130px;left:100px;width:30px"
|
||
|
value="#">
|
||
|
|
||
|
<INPUT type=button style="cursor:hand;LEFt:0px; HEIGHT: 25px; POSITION: absolute; WIDTH: 150px; top:200px" onclick="CancelDTMF()" value="Cancel" title="Cancel">
|
||
|
|
||
|
</div>
|
||
|
|
||
|
|
||
|
|
||
|
<!-- Listed objects : TAPI(tapi3.idl), DispatchMapper(tapi3.idl) -->
|
||
|
<object classid="clsid:21D6D48E-A88B-11D0-83DD-00AA003CCABD" id="TAPIOBJ"></object>
|
||
|
|
||
|
<object classid="clsid:E9225296-C759-11d1-A02B-00C04FB6809F" id="MAPPER"></object>
|
||
|
|
||
|
<script LANGUAGE="vbscript">
|
||
|
|
||
|
' Be shure that you call TAPIOBJ.Initialize before window_onload, otherwise you'll
|
||
|
' never receive events from tapi...
|
||
|
On Error Resume Next
|
||
|
window.status = "Initialization phase started..."
|
||
|
|
||
|
call TAPIOBJ.Initialize
|
||
|
sUnableToComplete = False
|
||
|
TAPIOBJ.EventFilter = &H1FFFF&
|
||
|
|
||
|
|
||
|
if Not Err.number = 0 Then
|
||
|
MsgBox "Unable to perform Tapi3 initialization",0,"Init"
|
||
|
sUnableToComplete = True
|
||
|
End If
|
||
|
|
||
|
|
||
|
</script>
|
||
|
|
||
|
</body></html>
|