int CStreamCgcProxy::avsRequestP2PUser(const tstring & sRequestUser, long nP2PType, long nP2PParam)
{
	if (!avsIsOpenSession()) return -1;
	if (m_sCurrentUser.empty()) return -1;

	char buffer[30];
	sprintf(buffer, ":%d-%d", nP2PType, nP2PParam);
	tstring sP2PKey(sRequestUser);
	sP2PKey.append(buffer);
	CDoP2PClientHandler::pointer pP2PClient;
	if (!m_p2pProxy.find(sP2PKey, pP2PClient, false))
	{
		DoSotpClientHandler::pointer pDoHandler = m_sotpClient.startClient(nP2PType == CDoP2PClientHandler::P2P_AUDIO || nP2PType == CDoP2PClientHandler::P2P_VIDEO ? m_rtpAddr : m_udpAddr);
		if (pDoHandler.get() == NULL) return -1;
		pDoHandler->doSetAppName(const_Avs_AppName);

		pP2PClient = P2PClient::create(pDoHandler);
		m_p2pProxy.insert(sP2PKey, pP2PClient);
	}else if (pP2PClient->getLocalP2PStatus() && pP2PClient->getRemoteP2PStatus())
	{
		return 1;	// is already P2P state
	}

	pP2PClient->setP2PInfo(sRequestUser, nP2PType);
	pP2PClient->clearP2PStatus();

	DoSotpClientHandler::pointer pDoHandler = pP2PClient->dohandler();
	BOOST_ASSERT(pDoHandler.get() != NULL);

	pDoHandler->doSetResponseHandler(this);
	pDoHandler->doSetRemoteAddr(nP2PType == CDoP2PClientHandler::P2P_AUDIO || nP2PType == CDoP2PClientHandler::P2P_VIDEO
		? m_rtpAddr.address() : m_udpAddr.address());
	pDoHandler->doSetMediaType(const_CGCMediaType);

	if (nP2PType == CDoP2PClientHandler::P2P_AUDIO || nP2PType == CDoP2PClientHandler::P2P_VIDEO)
	{
		for (int i=0; i<=2; i++)
		{
			pDoHandler->doBeginCallLock();
			pDoHandler->doSendAppCall(0, const_Avs_Api_RequestP2PUser);
		}
	}

	pDoHandler->doSetDisableSotpParser(false);
	pDoHandler->doBeginCallLock();
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("FromUser"), m_sCurrentUser));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("ToUser"), sRequestUser));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("P2PType"), (long)nP2PType));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("P2PParam"), nP2PParam));
	pDoHandler->doSendAppCall(const_CallSign_RequestP2PUser, const_Avs_Api_RequestP2PUser);

	return 0;
}
bool CStreamCgcProxy::sendP2PAck(CDoP2PClientHandler::pointer pP2PClient, long nP2PType, long nP2PParam, bool bAckAck)
{
	BOOST_ASSERT (pP2PClient.get() != NULL);

	if (!avsIsOpenSession()) return false;
	if (m_sCurrentUser.empty()) return false;
	if (pP2PClient == NULL) return false;

	DoSotpClientHandler::pointer pDoHandler = pP2PClient->dohandler();
	BOOST_ASSERT(pDoHandler.get() != NULL);

	pDoHandler->doBeginCallLock();
	if (bAckAck)
		pDoHandler->doAddParameter(CGC_PARAMETER(_T("P2PACKACK"), tstring(_T("1"))));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("FromUser"), m_sCurrentUser));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("P2PType"), nP2PType));
	pDoHandler->doAddParameter(CGC_PARAMETER(_T("P2PParam"), nP2PParam));
	pDoHandler->doSendAppCall(const_CallSign_P2PAck, const_Avs_Api_P2PAck);
	return true;
}