300 likes | 454 Views
Introduction of VOTEL API. Arlene Chen Sam Chang 2002/9/12. Agenda. Overview of VONTEL API How to write a client application—Initial How to write a client application—PickupCall How to write a client application—CampCall. Overview of VONTEL API (1/7). VONTEL API 架構圖.
E N D
Introduction of VOTEL API Arlene Chen Sam Chang 2002/9/12
Agenda • Overview of VONTEL API • How to write a client application—Initial • How to write a client application—PickupCall • How to write a client application—CampCall CCL Confidential
Overview of VONTEL API (1/7) • VONTEL API架構圖 CCL Confidential
Overview of VONTEL API(2/7) • VONTEL API包含以下物件 • ServiceAdmin物件 • 提供IVServiceAdmin介面,用來設定VONTEL Service Application • MegacoProtocolAdmin物件 • 提供IVProtocolAdmin介面,用來設定Megaco Protocol Adapter • SIPProtocolAdmin物件 • 提供IVProtocolAdmin介面,用來設定SIP Protocol Adapter CCL Confidential
Overview of VONTEL API(3/7) • H323ProtocolAdmin物件 • 提供IVProtocolAdmin介面,用來設定H.323 Protocol Adapter • CallServer物件 • 提供IVCallServer介面,用來設定Device、Group、Routing Table以及其他電話行為。並透過IVCallServerEvent或IVCallServerEventDisp發出event通知client端的應用程式 CCL Confidential
Overview of VONTEL API(4/7) • VONTEL包含下列介面 • IVServiceAdmin • 提供對service application設定的新增刪除和查詢 • IVServiceApp • 提供對一個service application的設定管理 • IVProtocolAdmin • 提供對protocol adapter的設定管理 • IVCallServer • 提供對call model中各種物件和設定的新增刪除和查詢,以及對系統整體執行參數的設定管理 • IVDevice • 提供對一個call model device物件的設定管理與操作控制 CCL Confidential
Overview of VONTEL API(5/7) • IVPhysicalDevice • 提供對一個實體的device物件的設定管理 • IVVirtualDevice • 提供對一個虛擬的device物件的設定管理 • IVStationDevice • 提供對一個分機類型的device物件的設定管理 • IVTrunkDevice • 提供對一個PSTN外線device物件的設定管理 • IVDeviceGroup • 提供對一個device群組物件的設定管理 CCL Confidential
Overview of VONTEL API(6/7) • IVTrunkGroup • 提供對一個PSTN外線群組物件的設定管理 • IVRoutingTable • 提供對一個routing table的設定管理 • IVRoutingTableEntry • 提供對routing table中單一routing規則的設定管理 • IVCallServerEvent • Client應用程式接收Call Server物件所發出的事件的介面 • IVCallServerEventDisp • Client應用程式接收Call Server物件所發出的事件的介面。介面規格與IVCallServerEvent完全相同,但宣告為dispinterface的型式,與VB或其他無型別語言相容 CCL Confidential
Overview of VONTEL API(7/7) • IVCall • 提供對一個call model中call物件的狀態存取 • IVConnection • 提供對一個call model中connection物件的狀態存取 • IVStrings • 提供對一個字串陣列內容的存取 • IVNumbers • 提供對一個數字陣列內容的存取 CCL Confidential
How to write a client application--Initial(1/4) • 呼叫CoCreateInstance取得IVCallServer物件 • 使用IVCallServer的method--GetDeivce(), 指定device ID,取得有興趣IVDevice物件 • 如果這個device不存在,使用AddDevice建立 hr = m_spCallServer.CoCreateInstance( CLSID_CallServer); // get virtual device CComBSTR bstrDeviceID = "device:"; bstrDeviceID += m_bstrDeviceAlias; hr = m_spCallServer->GetDevice( bstrDeviceID, &m_spDevice); if ( hr == VAPI_E_INVALID_DEVICE) { // device not exist, create it hr = m_spCallServer->AddDevice( NULL, m_bstrDeviceAlias, VAPI_VIRTUAL_STATION, &m_spDevice); } CCL Confidential
How to write a client application--Initial(2/4) • 使用CallServer的method--RegisterMonitor(), 要求CallServer將event發送給指定的物件 • 接著呼叫AddMonitorFilter指定接收event的等級與類別 • 可以指定要收全部的event或是針對某個device產生的event • VAPI_MONITOR_TYPE_DEVICE • VAPI_MONITOR_TYPE_GLOBAL hr = m_spCallServer->RegisterMonitor( this, &m_nMonitorHandle); hr = m_spCallServer->AddMonitorFilter( m_nMonitorHandle, VAPI_MONITOR_TYPE_DEVICE, bstrDeviceID, VAPI_MONITOR_EVENT_CALLCONTROL, &nFilterHandle); CCL Confidential
How to write a client application--Initial(3/4) • 可以指定收取的event類別 • VAPI_MONITOR_EVENT_CALLMODEL • 當call mode狀態改變時發出的event • OnNewCall • OnDeleteCall • OnNewConnection • OnConnectionChanged • OnDeleteConnection • OnMoveConnection • VAPI_MONITOR_EVENT_CALLCONTROL • 呼叫call相關的命令之後發出的event • OnMakeCall • OnDropCall CCL Confidential
How to write a client application--Initial(4/4) • VAPI_MONITOR_EVENT_CONFIG • 與device設定修改或是發生新增,刪除時發出的event • OnNewDevice • OnDeleteDevice • OnDeviceChanged • VAPI_MONITOR_EVENT_MEDIA • 與device完成media I/O時發出的event • OnPlayCompleted • OnRecordCompleted • OnGetDTMFCompleted • OnSendFaxCompleted • OnReceiveFaxCompleted • VAPI_MONITOR_EVENT_ALL • 所有的event CCL Confidential
使用virtual device提供pickup call服務 使用者發現有其他話機正在振鈴,可以直接透過位置上的話機進行代接。使用者可以撥號到Pickup call的virtual device代接正在震鈴的電話 Example: device:vontel-pickup-call;target=12312 digit:#112312 How to write a client application--PickupCall(1/8) CCL Confidential
執行到OnMakeCall時 檢查callee device是否為該virtual device 根據傳入的參數取得要代接的對象 How to write a client application--PickupCall(2/8) virtual device caller device a c URL = device:vontel-pickup-call;target=12312 HRESULT CPickupCallDevice::OnMakeCall( /*[in]*/ BSTR bstrCallerDevice, /*[in]*/ BSTR bstrCalleeDevice, /*[in]*/ BSTR bstrCallID, /*[in]*/ BSTR bstrOriginalDialAddress, /*[in]*/ BSTR bstrTargetDialAddress, /*[in]*/ VAPI_EEventCause eCause) { if ( !_IsThisDevice(bstrCalleeDevice)) return S_OK; ….. // process dial-address CComPtr<IVURLAddress> spURL; hr = spURL.CoCreateInstance( CLSID_URLAddress); spURL->Init( bstrTargetDialAddress); // get target device CComBSTR bstrTarget; spURL->GetParam( CComBSTR("target"), &bstrTarget); CCL Confidential
進行Pickup call 檢查代接對象是否為station device 取得代接對象上第一個狀態為alerting的call How to write a client application--PickupCall(3/8) virtual device caller device a c target device device a c // target device must be a station device CComQIPtr<IVStationDevice> spPickupStation = spPickupDevice; if ( !spPickupStation) throw E_INVALIDARG; ……………………………………….. // get first alerting connection on target device CComBSTR bstrAlertingCall; hr = spPickupDevice->GetCallIDByState( VAPI_CONNECTION_ALERTING, &bstrAlertingCall); if ( FAILED(hr)) throw hr; CCL Confidential
使用DirectTransferCall將這個altering call轉接到virtual device How to write a client application--PickupCall(4/8) virtual device caller device a c target device device a c // direct transfer alerting call to virtual device CComBSTR bstrThisDevice = "device:"; bstrThisDevice += m_bstrDeviceAlias; hr = spPickupDevice->DirectTransferCall( bstrAlertingCall, bstrThisDevice, 0); virtual device device a c caller device a c CCL Confidential
virtual device先接起從代接對象轉接來的電話 How to write a client application--PickupCall(5/8) virtual device device a c caller device a c hr = m_spDevice->AnswerCall( bstrAlertingCall, 0); virtual device device c c caller device a c CCL Confidential
接著保留這通電話 How to write a client application--PickupCall(6/8) virtual device device c c caller device a c hr = m_spDevice->HoldCall( bstrAlertingCall, 0); virtual device device h c caller device a c CCL Confidential
接起另外一通正在震鈴的電話 How to write a client application--PickupCall(7/8) virtual device device h c caller device a c hr = m_spDevice->AnswerCall( bstrCallID, 0); virtual device device h c caller device c c CCL Confidential
針對被保留的電話進行轉接 完成pickup call服務 How to write a client application--PickupCall(8/8) virtual device device h c caller device c c hr = m_spDevice->TransferCall( bstrAlertingCall, bstrCallID, 0); device c caller device c CCL Confidential
使用virtual device提供camp call服務 使用者進行撥號,當對方忙線或是未接電話時,使用者可以要求camp call服務,進行自動撥號。Camp call服務會持續撥號給使用者的上一個外撥對象,直到對方接起電話後,再回振使用者的設備。 Example: 要求camp最後撥出的電話 device:vontel-camp-call digit:#2# Example: 取消之前的camp call要求 device:vontel-camp-call;cancel digit:#2* How to write a client application--CampCall(1/8) CCL Confidential
使用者要求進行camp call服務 使用者撥號給提供camp call服務的virtual device 執行到OnMakeCall 檢查callee device是否為該virtual device How to write a client application--CampCall(2/8) virtual device caller device a c HRESULT CCampCallDevice::OnMakeCall( /*[in]*/ BSTR bstrCallerDevice, /*[in]*/ BSTR bstrCalleeDevice, /*[in]*/ BSTR bstrCallID, /*[in]*/ BSTR bstrOriginalDialAddress, /*[in]*/ BSTR bstrTargetDialAddress, /*[in]*/ VAPI_EEventCause eCause) { // process incoming call only if ( !_IsThisDevice(bstrCalleeDevice)) return S_OK; CCL Confidential
接著檢查參數中是否出現“cancel” 出現“cancel”表示caller要求停止前一次camp call服務 若參數中沒有“cancel”,表示caller要求進行camp call服務。 How to write a client application--CampCall(3/8) CComPtr<IVDevice> spCaller; CComBSTR bstrCaller = "device:"; bstrCaller += bstrCallerDevice; hr = m_spCallServer->GetDevice( bstrCaller, &spCaller); // process dial-address CComPtr<IVURLAddress> spURL; hr = spURL.CoCreateInstance( CLSID_URLAddress); spURL->Init( bstrTargetDialAddress); BOOL bExist = false; spURL->IsParamExist( CComBSTR("cancel"), &bExist); if ( bExist) { // do cancel camp call return DoUnregisterCallBack( spCaller, bstrCallID); } else { // get caller last dial address CComBSTR bstrLastDial; spCaller->GetProperty( CComBSTR("vontel:last-dial2"), &bstrLastDial); // do register camp call return DoRegisterCallBack( spCaller, bstrCallID, bstrLastDial); } URL = device:vontel-camp-call;cancel URL = device:vontel-camp-call CCL Confidential
收取caller device的VAPI_MONITOR_EVENT_CALLMODEL事件 收取target device的VAPI_MONITOR_EVENT_CALLMODEL事件 How to write a client application--CampCall(4/8) // monitor target device long nTargetEventHandle; hr = m_spCallServer->AddMonitorFilter( m_nMonitorHandle, VAPI_MONITOR_TYPE_DEVICE, bstrTargetDevice, VAPI_MONITOR_EVENT_CALLMODEL, &nTargetEventHandle); // monitor caller device long nCallerEventHandle; hr = m_spCallServer->AddMonitorFilter( m_nMonitorHandle, VAPI_MONITOR_TYPE_DEVICE, bstrCallerDevice, VAPI_MONITOR_EVENT_CALLCONTROL, &nCallerEventHandle); CCL Confidential
接起該通電話 撥放語音(目前尚未提供virtual device語音資源) 掛上該通電話 完成camp call註冊 How to write a client application--CampCall(5/8) virtual device caller device c c virtual device caller device // answer call m_spDevice->AnswerCall( bstrCallID, 0); // pause for 0.5 second Sleep(500); // drop call m_spDevice->DropCall( bstrCallID, 0); CCL Confidential
進行camp call 執行到OnDeviceStateChanged時,檢查target device的狀態是否已經回復為idle target device回復為idle後,virtual device撥號給target device How to write a client application--CampCall(6/8) virtual device target device c a // when target device state changed to IDLE state, make a call-back call HRESULT CCampCallDevice::OnDeviceStateChanged( /*[in]*/ BSTR bstrDeviceID, /*[in]*/ VAPI_EDeviceState eDeviceOldState, /*[in]*/ VAPI_EDeviceState eDeviceNewState, /*[in]*/ VAPI_EEventCause eEventCause) { // for device back to idle state if ( eDeviceNewState != VAPI_DEVICE_IDLE) return S_FALSE; ………… hr = m_spDevice->MakeCall( bstrCallerDevice, 0, &spCB->bstrCallerCallID); CCL Confidential
執行到OnAnswerCall時,檢查ringback device是否為virtual device 接著檢查altering device是否為caller device How to write a client application--CampCall(7/8) virtual device target device c c HRESULT CCampCallDevice::OnAnswerCall( /*[in]*/ BSTR bstrAlertingDevice, /*[in]*/ BSTR bstrRingbackDevice, /*[in]*/ BSTR bstrCallID, /*[in]*/ VAPI_EEventCause eCause) { HRESULT hr = S_OK; // only interest call from this device if ( !(m_bstrDeviceGUID == bstrRingbackDevice)) return S_FALSE; ……………….. if ( spCB->bstrCallerGUID == bstrAlertingDevice) CCL Confidential
使用DirectTransferCall將建立的call轉接給caller device 完成camp call服務 How to write a client application--CampCall(8/8) virtual device caller device target device a c // direct transfer to target device CComBSTR bstrTargetDevice = "device:"; bstrTargetDevice += spCB->bstrTargetGUID; hr = m_spDevice->DirectTransferCall( spCB->bstrCallerCallID, bstrTargetDevice, 0); if ( FAILED(hr)) throw hr; CCL Confidential