windows-nt/Source/XPSP1/NT/net/tapi/skywalker/tapi3/phone.h
2020-09-26 16:20:57 +08:00

743 lines
20 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
phone.h
Abstract:
Declaration of the CPhone class
Notes:
Revision History:
--*/
#ifndef __PHONE_H_
#define __PHONE_H_
#include "resource.h" // main symbols
#include "address.h"
#include "ObjectSafeImpl.h"
class CTAPI;
extern CHashTable * gpPhoneHashTable;
/////////////////////////////////////////////////////////////////
// Intermediate classes used for DISPID encoding
template <class T>
class ITPhoneVtbl : public ITPhone
{
DECLARE_TRACELOG_CLASS(ITPhoneVtbl)
};
template <class T>
class ITAutomatedPhoneControlVtbl : public ITAutomatedPhoneControl
{
DECLARE_TRACELOG_CLASS(ITAutomatedPhoneControlVtbl)
};
/////////////////////////////////////////////////////////////////
// Constants defining default values for certain properties.
const DWORD APC_DEFAULT_AEONT = 3000;
const DWORD APC_DEFAULT_AKTMD = 100;
const DWORD APC_DEFAULT_VCS = 4096;
const DWORD APC_DEFAULT_VCRD = 500;
const DWORD APC_DEFAULT_VCRP = 100;
const DWORD APC_MAX_NUMBERS_GATHERED = 100;
/////////////////////////////////////////////////////////////////
// Types
typedef enum AUTOMATED_PHONE_STATE
{
APS_ONHOOK_IDLE,
APS_OFFHOOK_DIALTONE,
APS_OFFHOOK_WARNING,
APS_ONHOOK_RINGING_IN,
APS_OFFHOOK_DIALING,
APS_OFFHOOK_DEAD_LINE,
APS_OFFHOOK_CALL_INIT,
APS_OFFHOOK_CONNECTED,
APS_ONHOOK_CONNECTED,
APS_OFFHOOK_BUSY_TONE,
APS_OFFHOOK_RINGING_OUT,
APS_ONHOOK_RINGING_OUT
} AUTOMATED_PHONE_STATE;
/////////////////////////////////////////////////////////////////////////////
// CPhone
class CPhone :
public CTAPIComObjectRoot<CPhone>,
public IDispatchImpl<ITPhoneVtbl<CPhone>, &IID_ITPhone, &LIBID_TAPI3Lib>,
public IDispatchImpl<ITAutomatedPhoneControlVtbl<CPhone>,
&IID_ITAutomatedPhoneControl, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
CPhone() : m_pTAPI(NULL),
m_hPhoneApp(NULL),
m_dwAPIVersion(0),
m_dwDeviceID(0),
m_hPhone(NULL),
m_dwPrivilege(0),
m_pPhoneCaps(NULL),
m_pdwLineDeviceIDs(NULL),
m_dwNumLineDeviceIDs(0),
m_Tone(PT_SILENCE),
m_fRinger(FALSE),
m_fPhoneHandlingEnabled(FALSE),
m_dwAutoEndOfNumberTimeout(APC_DEFAULT_AEONT),
m_fAutoDialtone(TRUE),
m_fAutoStopTonesOnOnHook(TRUE),
m_fAutoStopRingOnOffHook(TRUE),
m_fAutoKeypadTones(TRUE),
m_dwAutoKeypadTonesMinimumDuration(APC_DEFAULT_AKTMD),
m_pCall(NULL),
m_hTimerQueue(NULL),
m_hTimerEvent(NULL),
m_hToneTimer(NULL),
m_hDTMFTimer(NULL),
m_hRingTimer(NULL),
m_hVolumeTimer(NULL),
m_hAutoEndOfNumberTimer(NULL),
m_fUseWaveForRinger(FALSE),
m_wszNumbersGathered(NULL),
m_AutomatedPhoneState(APS_ONHOOK_IDLE),
m_fAutoVolumeControl(TRUE),
m_dwAutoVolumeControlStep(APC_DEFAULT_VCS),
m_dwAutoVolumeControlRepeatDelay(APC_DEFAULT_VCRD),
m_dwAutoVolumeControlRepeatPeriod(APC_DEFAULT_VCRP),
m_dwOffHookCount(0),
m_fInitialized(FALSE)
{
LOG((TL_TRACE, "CPhone[%p] - enter", this ));
LOG((TL_TRACE, "CPhone - finished" ));
}
~CPhone()
{
LOG((TL_TRACE, "~CPhone[%p] - enter", this ));
LOG((TL_TRACE, "~CPhone - finished" ));
}
DECLARE_DEBUG_ADDREF_RELEASE(CPhone)
DECLARE_QI()
DECLARE_MARSHALQI(CPhone)
DECLARE_TRACELOG_CLASS(CPhone)
BEGIN_COM_MAP(CPhone)
COM_INTERFACE_ENTRY2(IDispatch, ITPhone)
COM_INTERFACE_ENTRY(ITPhone)
// ITAutomatedPhoneControlQI will fall thru on SUCCESS, so we need to keep COM_INTERFACE_ENTRY(ITAutomatedPhoneControl)
COM_INTERFACE_ENTRY_FUNC(IID_ITAutomatedPhoneControl, 0, CPhone::ITAutomatedPhoneControlQI)
COM_INTERFACE_ENTRY(ITAutomatedPhoneControl)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
void FinalRelease();
private:
ITTAPI * m_pTAPI;
HPHONEAPP m_hPhoneApp;
DWORD m_dwAPIVersion;
DWORD m_dwDeviceID;
HPHONE m_hPhone;
DWORD m_dwPrivilege;
LPPHONECAPS m_pPhoneCaps;
DWORD * m_pdwLineDeviceIDs;
DWORD m_dwNumLineDeviceIDs;
BOOL m_fInitialized;
// AutomatedPhoneControl Variables
CWavePlayer m_WavePlayer;
BOOL m_fUseWaveForRinger;
BOOL m_fRinger;
BOOL m_fPhoneHandlingEnabled;
DWORD m_dwAutoEndOfNumberTimeout;
BOOL m_fAutoDialtone;
BOOL m_fAutoStopTonesOnOnHook;
BOOL m_fAutoStopRingOnOffHook;
BOOL m_fAutoKeypadTones;
DWORD m_dwAutoKeypadTonesMinimumDuration;
BOOL m_fAutoVolumeControl;
DWORD m_dwAutoVolumeControlStep;
DWORD m_dwAutoVolumeControlRepeatDelay;
DWORD m_dwAutoVolumeControlRepeatPeriod;
DWORD m_dwOffHookCount;
ITCallInfo * m_pCall;
LPWSTR m_wszNumbersGathered;
PHONE_TONE m_Tone;
DWORD m_dwToneDuration;
DWORD m_dwTonePeriodOn;
DWORD m_dwTonePeriodOff;
PHONE_TONE m_DTMF;
DWORD m_dwDTMFStart;
DWORD m_dwRingDuration;
DWORD m_dwRingPeriod;
BOOL m_fVolumeUp;
AUTOMATED_PHONE_STATE m_AutomatedPhoneState;
BOOL m_fDefaultTerminalsSelected;
// Timer Handles
HANDLE m_hTimerQueue;
HANDLE m_hTimerEvent;
HANDLE m_hToneTimer;
HANDLE m_hDTMFTimer;
HANDLE m_hRingTimer;
HANDLE m_hVolumeTimer;
HANDLE m_hAutoEndOfNumberTimer;
// Critical Sections
CRITICAL_SECTION m_csAutomatedPhoneState;
CRITICAL_SECTION m_csToneTimer;
CRITICAL_SECTION m_csRingTimer;
public:
static HRESULT WINAPI ITAutomatedPhoneControlQI(void* pv, REFIID riid, LPVOID* ppv, DWORD_PTR dw);
DWORD GetDeviceID(){ return m_dwDeviceID; }
DWORD GetAPIVersion(){ return m_dwAPIVersion; }
HPHONEAPP GetHPhoneApp(){ return m_hPhoneApp; }
HRESULT Initialize(
ITTAPI * pTAPI,
HPHONEAPP hPhoneApp,
DWORD dwAPIVersion,
DWORD dwDeviceID
);
void SetPhoneCapBuffer( LPVOID pBuf );
HRESULT UpdatePhoneCaps();
HRESULT InvalidatePhoneCaps();
BOOL IsPhoneOnAddress(ITAddress * pAddress);
BOOL IsPhoneOnPreferredAddress(ITAddress *pAddress);
BOOL IsPhoneUsingWaveID(DWORD dwWaveID, TERMINAL_DIRECTION nDir);
CTAPI * GetTapi();
void ForceClose();
void Automation_CallState( ITCallInfo * pCall, CALL_STATE cs, CALL_STATE_EVENT_CAUSE cause );
void Automation_ButtonDown( DWORD dwButtonId );
void Automation_ButtonUp( DWORD dwButtonId );
void Automation_OnHook( PHONE_HOOK_SWITCH_DEVICE phsd );
void Automation_OffHook( PHONE_HOOK_SWITCH_DEVICE phsd );
void Automation_EndOfNumberTimeout();
//
// IDispatch
//
STDMETHOD(GetIDsOfNames)(REFIID riid,
LPOLESTR* rgszNames,
UINT cNames,
LCID lcid,
DISPID* rgdispid
);
STDMETHOD(Invoke)(DISPID dispidMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS* pdispparams,
VARIANT* pvarResult,
EXCEPINFO* pexcepinfo,
UINT* puArgErr
);
STDMETHOD_(ULONG, InternalAddRef)();
STDMETHOD_(ULONG, InternalRelease)();
//
// ITPhone
//
STDMETHOD(Open)(
IN PHONE_PRIVILEGE Privilege
);
STDMETHOD(Close)();
STDMETHOD(get_Addresses)(
OUT VARIANT * pAddresses
);
STDMETHOD(EnumerateAddresses)(
OUT IEnumAddress ** ppEnumAddress
);
STDMETHOD(get_PreferredAddresses)(
OUT VARIANT * pAddresses
);
STDMETHOD(EnumeratePreferredAddresses)(
OUT IEnumAddress ** ppEnumAddress
);
STDMETHOD(get_PhoneCapsLong)(
IN PHONECAPS_LONG pclCap,
OUT long * plCapability
);
STDMETHOD(get_PhoneCapsString)(
IN PHONECAPS_STRING pcsCap,
OUT BSTR * ppCapability
);
STDMETHOD(GetPhoneCapsBuffer)(
IN PHONECAPS_BUFFER pcbCaps,
OUT DWORD *pdwSize,
OUT BYTE **ppPhoneCapsBuffer
);
STDMETHOD(get_PhoneCapsBuffer)(
IN PHONECAPS_BUFFER pcbCaps,
OUT VARIANT *pVarBuffer
);
STDMETHOD(get_Terminals)(
IN ITAddress * pAddress,
OUT VARIANT * pTerminals
);
STDMETHOD(EnumerateTerminals)(
IN ITAddress * pAddress,
OUT IEnumTerminal ** ppEnumTerminal
);
STDMETHOD(get_ButtonMode)(
IN long lButtonID,
OUT PHONE_BUTTON_MODE * pButtonMode
);
STDMETHOD(put_ButtonMode)(
IN long lButtonID,
IN PHONE_BUTTON_MODE ButtonMode
);
STDMETHOD(get_LampMode)(
IN long lLampID,
OUT PHONE_LAMP_MODE* pLampMode
);
STDMETHOD(put_LampMode)(
IN long lLampID,
IN PHONE_LAMP_MODE pLampMode
);
STDMETHOD(get_ButtonFunction)(
IN long lButtonID,
OUT PHONE_BUTTON_FUNCTION * pButtonFunction
);
STDMETHOD(put_ButtonFunction)(
IN long lButtonID,
IN PHONE_BUTTON_FUNCTION ButtonFunction
);
STDMETHOD(get_ButtonText)(
IN long lButtonID,
OUT BSTR * ppButtonText
);
STDMETHOD(put_ButtonText)(
IN long lButtonID,
IN BSTR bstrButtonText
);
STDMETHOD(get_ButtonState)(
IN long lButtonID,
OUT PHONE_BUTTON_STATE * pButtonState
);
STDMETHOD(get_HookSwitchState)(
IN PHONE_HOOK_SWITCH_DEVICE HookSwitchDevice,
OUT PHONE_HOOK_SWITCH_STATE * pHookSwitchState
);
STDMETHOD(put_HookSwitchState)(
IN PHONE_HOOK_SWITCH_DEVICE HookSwitchDevice,
OUT PHONE_HOOK_SWITCH_STATE HookSwitchState
);
STDMETHOD(put_RingMode)(
IN long lRingMode
);
STDMETHOD(get_RingMode)(
OUT long * plRingMode
);
STDMETHOD(put_RingVolume)(
IN long lRingVolume
);
STDMETHOD(get_RingVolume)(
OUT long * plRingVolume
);
STDMETHOD(get_Privilege)(
OUT PHONE_PRIVILEGE * pPrivilege
);
STDMETHOD(get_Display)(
BSTR *pbstrDisplay
);
//
// put display string at a specified location
//
STDMETHOD(SetDisplay)(
IN long lRow,
IN long lColumn,
IN BSTR bstrDisplay
);
STDMETHOD(DeviceSpecific)(
IN BYTE *pParams,
IN DWORD dwSize
);
STDMETHOD(DeviceSpecificVariant)(
IN VARIANT varDevSpecificByteArray
);
STDMETHOD(NegotiateExtVersion)(
IN long lLowVersion,
IN long lHighVersion,
IN long *plExtVersion
);
//
// ITAutomatedPhoneControl
//
public:
STDMETHOD (StartTone)(
IN PHONE_TONE Tone,
IN long lDuration
);
STDMETHOD (StopTone)();
STDMETHOD (get_Tone)(
OUT PHONE_TONE * pTone
);
STDMETHOD (StartRinger)(
IN long lRingMode,
IN long lDuration
);
STDMETHOD (StopRinger)();
STDMETHOD (get_Ringer)(
OUT VARIANT_BOOL * pfRinging
);
STDMETHOD (put_PhoneHandlingEnabled)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_PhoneHandlingEnabled)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoEndOfNumberTimeout)(
IN long lTimeout
);
STDMETHOD (get_AutoEndOfNumberTimeout)(
OUT long * plTimeout
);
STDMETHOD (put_AutoDialtone)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_AutoDialtone)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoStopTonesOnOnHook)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_AutoStopTonesOnOnHook)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoStopRingOnOffHook)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_AutoStopRingOnOffHook)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoKeypadTones)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_AutoKeypadTones)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoKeypadTonesMinimumDuration)(
IN long lDuration
);
STDMETHOD (get_AutoKeypadTonesMinimumDuration)(
OUT long * plDuration
);
STDMETHOD (put_AutoVolumeControl)(
IN VARIANT_BOOL fEnabled
);
STDMETHOD (get_AutoVolumeControl)(
OUT VARIANT_BOOL * pfEnabled
);
STDMETHOD (put_AutoVolumeControlStep)(
IN long lStepSize
);
STDMETHOD (get_AutoVolumeControlStep)(
OUT long * plStepSize
);
STDMETHOD (put_AutoVolumeControlRepeatDelay)(
IN long lDelay
);
STDMETHOD (get_AutoVolumeControlRepeatDelay)(
OUT long * plDelay
);
STDMETHOD (put_AutoVolumeControlRepeatPeriod)(
IN long lPeriod
);
STDMETHOD (get_AutoVolumeControlRepeatPeriod)(
OUT long * plPeriod
);
STDMETHOD (SelectCall)(
IN ITCallInfo * pCall,
IN VARIANT_BOOL fSelectDefaultTerminals
);
STDMETHOD (UnselectCall)(
IN ITCallInfo * pCall
);
STDMETHOD (EnumerateSelectedCalls)(
OUT IEnumCall ** ppCallEnum
);
STDMETHOD (get_SelectedCalls)(
OUT VARIANT * pVariant
);
// Private helper methods for ITAutomatedPhoneControl implementation
private:
void UnselectAllPreviouslySelectedTerminals(
IN ITBasicCallControl2 * pCall,
IN ITTerminal * pTerminalThatFailed,
IN IEnumTerminal * pEnum
);
HRESULT InternalUnselectCall(
IN ITCallInfo * pCall
);
HRESULT SelectDefaultTerminalsOnCall(
IN ITCallInfo * pCall
);
HRESULT UnselectDefaultTerminalsOnCall(
IN ITCallInfo * pCall
);
HRESULT GetPhoneWaveRenderID(
IN DWORD * pdwWaveID
);
void OpenWaveDevice(
);
void CloseWaveDevice(
);
static VOID CALLBACK ToneTimerCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired
);
static VOID CALLBACK DTMFTimerCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired
);
static VOID CALLBACK RingTimerCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired
);
static VOID CALLBACK VolumeTimerCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired
);
static VOID CALLBACK AutoEndOfNumberTimerCallback(
PVOID lpParameter,
BOOLEAN TimerOrWaitFired
);
};
class CPhoneEvent :
public CTAPIComObjectRoot<CPhoneEvent, CComMultiThreadModelNoCS>, // no need to have a cs
public CComDualImpl<ITPhoneEvent, &IID_ITPhoneEvent, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CPhoneEvent)
DECLARE_TRACELOG_CLASS(CPhoneEvent)
BEGIN_COM_MAP(CPhoneEvent)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITPhoneEvent)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
static HRESULT FireEvent(
CPhone * pCPhone,
PHONE_EVENT Event,
PHONE_BUTTON_STATE ButtonState,
PHONE_HOOK_SWITCH_STATE HookSwitchState,
PHONE_HOOK_SWITCH_DEVICE HookSwitchDevice,
DWORD dwRingMode,
DWORD dwButtonLampId,
PWSTR pNumber,
ITCallInfo * pCallInfo
);
void FinalRelease();
protected:
ITPhone * m_pPhone;
PHONE_EVENT m_Event;
PHONE_BUTTON_STATE m_ButtonState;
PHONE_HOOK_SWITCH_STATE m_HookSwitchState;
PHONE_HOOK_SWITCH_DEVICE m_HookSwitchDevice;
DWORD m_dwRingMode;
DWORD m_dwButtonLampId;
BSTR m_pNumber;
ITCallInfo * m_pCallInfo;
#if DBG
PWSTR m_pDebug;
#endif
public:
STDMETHOD(get_Phone)( ITPhone ** ppPhone );
STDMETHOD(get_Event)( PHONE_EVENT * pEvent );
STDMETHOD(get_ButtonState)( PHONE_BUTTON_STATE * pState );
STDMETHOD(get_HookSwitchState)( PHONE_HOOK_SWITCH_STATE * pState );
STDMETHOD(get_HookSwitchDevice)( PHONE_HOOK_SWITCH_DEVICE * pDevice );
STDMETHOD(get_RingMode)( long * plRingMode );
STDMETHOD(get_ButtonLampId)( LONG * plButtonLampId );
STDMETHOD(get_NumberGathered)( BSTR * ppNumber );
STDMETHOD(get_Call)( ITCallInfo ** ppCallInfo );
};
class CPhoneDevSpecificEvent :
public CTAPIComObjectRoot<CPhoneDevSpecificEvent, CComMultiThreadModelNoCS>, // no need to have a cs
public CComDualImpl<ITPhoneDeviceSpecificEvent, &IID_ITPhoneDeviceSpecificEvent, &LIBID_TAPI3Lib>,
public CObjectSafeImpl
{
public:
DECLARE_MARSHALQI(CPhoneDevSpecificEvent)
DECLARE_TRACELOG_CLASS(CPhoneDevSpecificEvent)
BEGIN_COM_MAP(CPhoneDevSpecificEvent)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(ITPhoneDeviceSpecificEvent)
COM_INTERFACE_ENTRY(IObjectSafety)
COM_INTERFACE_ENTRY_FUNC(IID_IMarshal, 0, IMarshalQI)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pFTM)
END_COM_MAP()
static HRESULT FireEvent(
CPhone *pPhone,
long lParam1,
long lParam2,
long lParam3
);
void FinalRelease();
CPhoneDevSpecificEvent();
protected:
//
// phone for which the event was fired
//
ITPhone *m_pPhone;
//
// data received from the TSP
//
long m_l1;
long m_l2;
long m_l3;
#if DBG
PWSTR m_pDebug;
#endif
public:
STDMETHOD(get_Phone)( ITPhone **ppPhone );
STDMETHOD(get_lParam1)( long *plParam1 );
STDMETHOD(get_lParam2)( long *plParam2 );
STDMETHOD(get_lParam3)( long *plParam3 );
};
#endif //__PHONE_H_