📄 connectionmanagerctrl.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include "av_upnp.h"
#include "av_upnp_ctrl_internal.h"
using namespace av_upnp;
using namespace av_upnp::details;
/////////////////////////////////////////////////////////////////////////////
// ConnectionManagerCtrl
//
// Init
//
bool ConnectionManagerCtrl::Init(/* [in] */ IUPnPDevice* pDevice)
{
HRESULT hr;
CComPtr<IUPnPServices> pServices;
CComPtr<IUPnPService> pConnectionManager, pAVTransport, pRenderingControl;
if(!pDevice)
{
DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("pDevice is NULL")));
return false;
}
// Get collection of UPnP services
if(FAILED(hr = pDevice->get_Services(&pServices)))
{
DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("get_Serivces failed 0x%08x"), hr));
return false;
}
// Get ConnectionManager service
if(!GetService(pServices, L"urn:upnp-org:serviceId:ConnectionManager", L"urn:schemas-upnp-org:service:ConnectionManager:1", &pConnectionManager))
return false;
ce::auto_bstr bstrServiceID;
pConnectionManager->get_Id(&bstrServiceID);
m_strServiceID = bstrServiceID;
if(!ServiceCtrl<IConnectionManager>::Init(pConnectionManager, pDevice))
return false;
m_proxyConnectionManager.init(pConnectionManager);
// Get [optional] AVTransport service
if(GetService(pServices, L"urn:upnp-org:serviceId:AVTransport", L"urn:schemas-upnp-org:service:AVTransport:1", &pAVTransport))
{
m_AVTransport.Init(pAVTransport, pDevice);
}
#ifdef DEBUG
else
{
ce::auto_bstr bstrName;
pDevice->get_FriendlyName(&bstrName);
DEBUGMSG(ZONE_AV_TRACE, (AV_TEXT("Device %s doesn't implement optional service AVTransport"), static_cast<BSTR>(bstrName)));
}
#endif
// Get [optional] RenderingControl service
if(GetService(pServices, L"urn:upnp-org:serviceId:RenderingControl", L"urn:schemas-upnp-org:service:RenderingControl:1", &pRenderingControl))
{
m_RenderingControl.Init(pRenderingControl, pDevice);
}
#ifdef DEBUG
else
{
ce::auto_bstr bstrName;
pDevice->get_FriendlyName(&bstrName);
DEBUGMSG(ZONE_AV_TRACE, (AV_TEXT("Device %s doesn't implement optional service RenderingControl"), static_cast<BSTR>(bstrName)));
}
#endif
return true;
}
//
// GetProtocolInfo
//
DWORD ConnectionManagerCtrl::GetProtocolInfo(
/* [in, out] */ wstring* pstrSourceProtocolInfo,
/* [in, out] */ wstring* pstrSinkProtocolInfo)
{
HRESULT hr;
hr = m_proxyConnectionManager.call(L"GetProtocolInfo");
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
if(!m_proxyConnectionManager.get_results(pstrSourceProtocolInfo,
pstrSinkProtocolInfo))
{
return ERROR_AV_INVALID_OUT_ARGUMENTS;
}
return SUCCESS_AV;
}
//
// PrepareForConnection
//
DWORD ConnectionManagerCtrl::PrepareForConnection(
/* [in] */ LPCWSTR pszRemoteProtocolInfo,
/* [in] */ LPCWSTR pszPeerConnectionManager,
/* [in] */ long PeerConnectionID,
/* [in] */ DIRECTION Direction,
/* [in, out] */ long* pConnectionID,
/* [in, out] */ IAVTransport** ppAVTransport,
/* [in, out] */ IRenderingControl** ppRenderingControl)
{
HRESULT hr;
hr = m_proxyConnectionManager.call(L"PrepareForConnection",
pszRemoteProtocolInfo,
pszPeerConnectionManager,
PeerConnectionID,
Direction == INPUT ? details::Direction::Input : details::Direction::Output);
if(hr == UPNP_E_INVALID_ACTION)
{
DEBUGMSG(ZONE_AV_WARN, (AV_TEXT("PrepareForConnection not implemented. Using IDs = 0")));
*pConnectionID = 0;
m_AVTransport.GetInstance(0, ppAVTransport);
m_RenderingControl.GetInstance(0, ppRenderingControl);
}
else
{
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
long RcsID, AVTransportID;
if(!m_proxyConnectionManager.get_results(pConnectionID,
&AVTransportID,
&RcsID))
{
return ERROR_AV_INVALID_OUT_ARGUMENTS;
}
m_AVTransport.GetInstance(AVTransportID, ppAVTransport);
m_RenderingControl.GetInstance(RcsID, ppRenderingControl);
}
return SUCCESS_AV;
}
//
// ConnectionComplete
//
DWORD ConnectionManagerCtrl::ConnectionComplete(
/* [in] */ long ConnectionID)
{
HRESULT hr;
hr = m_proxyConnectionManager.call(L"ConnectionComplete", ConnectionID);
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
return SUCCESS_AV;
}
//
// GetFirstConnectionID
//
DWORD ConnectionManagerCtrl::GetFirstConnectionID(
/* [in, out] */ long* pConnectionID)
{
HRESULT hr;
hr = m_proxyConnectionManager.call(L"GetCurrentConnectionIDs");
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
if(!m_proxyConnectionManager.get_results(&m_strConnectionIDs))
{
return ERROR_AV_INVALID_OUT_ARGUMENTS;
}
if(m_strConnectionIDs.empty())
return ERROR_AV_NO_MORE_ITEMS;
// append extra ',' to make parsing easier
m_strConnectionIDs += L",";
return GetNextConnectionID(pConnectionID);
}
//
// GetNextConnectionID
//
DWORD ConnectionManagerCtrl::GetNextConnectionID(
/* [in, out] */ long* pConnectionID)
{
if(!pConnectionID)
return ERROR_AV_POINTER;
if(m_strConnectionIDs.empty())
return ERROR_AV_NO_MORE_ITEMS;
*pConnectionID = _wtoi(m_strConnectionIDs);
m_strConnectionIDs.erase(0, m_strConnectionIDs.find(L",") + 1);
return SUCCESS_AV;
}
//
// GetCurrentConnectionInfo
//
DWORD ConnectionManagerCtrl::GetCurrentConnectionInfo(
/* [in] */ long ConnectionID,
/* [in, out] */ ConnectionInfo* pConnectionInfo)
{
if(!pConnectionInfo)
return ERROR_AV_POINTER;
HRESULT hr;
hr = m_proxyConnectionManager.call(L"GetCurrentConnectionInfo", ConnectionID);
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
ce::wstring strDirection;
long RcsID, AVTransportID;
if(!m_proxyConnectionManager.get_results(&RcsID,
&AVTransportID,
&pConnectionInfo->strRemoteProtocolInfo,
&pConnectionInfo->strPeerConnectionManager,
&pConnectionInfo->nPeerConnectionID,
&strDirection,
&pConnectionInfo->strStatus))
{
return ERROR_AV_INVALID_OUT_ARGUMENTS;
}
// Direction
if(Direction::Input == strDirection)
pConnectionInfo->Direction = INPUT;
else
if(Direction::Output == strDirection)
pConnectionInfo->Direction = OUTPUT;
else
{
DEBUGMSG(ZONE_AV_ERROR, (AV_TEXT("GetCurrentConnectionInfo returned invalid Direction: %s"), static_cast<LPCWSTR>(strDirection)));
return ERROR_AV_INVALID_OUT_ARGUMENTS;
}
m_AVTransport.GetInstance(AVTransportID, &pConnectionInfo->pAVTransport);
m_RenderingControl.GetInstance(RcsID, &pConnectionInfo->pRenderingControl);
return SUCCESS_AV;
}
//
// InvokeVendorAction
//
DWORD ConnectionManagerCtrl::InvokeVendorAction(
/* [in] */ LPCWSTR pszActionName,
/* [in] */ DISPPARAMS* pdispparams,
/* [in, out] */ VARIANT* pvarResult)
{
HRESULT hr;
hr = m_proxyConnectionManager.invoke(pszActionName, pdispparams, pvarResult);
if(FAILED(hr))
{
return AVErrorFromUPnPError(hr);
}
return SUCCESS_AV;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -