RTCP statistics via radius patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




Patch to send RTCP statistic in radius accounting packets in cisco vsa attributes if rtp proxy enabled and rtcp packets is present.

example of radius vsa attributes in stop accounting packet:

Cisco-AVPair = "RTP_source_IP=192.168.168.6" Cisco-AVPair = "RTP_destination_IP=193.58.235.18" Cisco-AVPair = "RTCP_source_packet_count=172914" Cisco-AVPair = "RTCP_source_packet_lost=32" Cisco-AVPair = "RTCP_source_jitter=72|109|288" Cisco-AVPair = "RTCP_source_sdes_cname=0.0.0@xxxxxxxxxxxxx" Cisco-AVPair = "RTCP_source_sdes_name=Cisco IOS, VoIP Gateway" Cisco-AVPair = "RTCP_source_sdes_tool=Cisco IOS, VoIP Gateway" Cisco-AVPair = "RTCP_destination_packet_count=172926" Cisco-AVPair = "RTCP_destination_packet_lost=25" Cisco-AVPair = "RTCP_destination_jitter=16|69|168" Cisco-AVPair = "RTCP_destination_sdes_cname=0.0.0@xxxxxxxxxxxxx" Cisco-AVPair = "RTCP_destination_sdes_name=Cisco IOS, VoIP Gateway" Cisco-AVPair = "RTCP_destination_sdes_tool=Cisco IOS, VoIP Gateway"

jitter values in order min/average/max and not in millisecondss, to calculate ms use formula X*(1/8000)*1000 where X is value from RTCP jitter attribute.



diff -c openh323gk_cvs/ProxyChannel.cxx openh323gk_cvs_p/ProxyChannel.cxx
*** openh323gk_cvs/ProxyChannel.cxx	Mon May 25 00:48:26 2009
--- openh323gk_cvs_p/ProxyChannel.cxx	Thu Jun  4 16:06:22 2009
***************
*** 287,296 ****

  	UDPProxySocket(const char *);

! 	void SetDestination(H245_UnicastAddress_iPAddress &);
! 	void SetForwardDestination(const Address &, WORD, const H245_UnicastAddress_iPAddress &);
! 	void SetReverseDestination(const Address &, WORD, const H245_UnicastAddress_iPAddress &);
! 	typedef void (UDPProxySocket::*pMem)(const Address &, WORD, const H245_UnicastAddress_iPAddress &);

  	bool Bind(WORD pt);
  	bool Bind(const Address &localAddr, WORD pt);
--- 287,296 ----

  	UDPProxySocket(const char *);

! 	void SetDestination(H245_UnicastAddress_iPAddress &,callptr &);
! 	void SetForwardDestination(const Address &, WORD, const H245_UnicastAddress_iPAddress &, callptr &);
! 	void SetReverseDestination(const Address &, WORD, const H245_UnicastAddress_iPAddress &, callptr &);
! 	typedef void (UDPProxySocket::*pMem)(const Address &, WORD, const H245_UnicastAddress_iPAddress &, callptr &);

  	bool Bind(WORD pt);
  	bool Bind(const Address &localAddr, WORD pt);
***************
*** 310,315 ****
--- 310,319 ----
  	virtual bool Flush();
  	virtual bool ErrorHandler(PSocket::ErrorGroup);

+ 	//RTCP handler
+ 	void BuildReceiverReport(const RTP_ControlFrame & frame, PINDEX offset, bool direct);
+ + callptr * m_call;
  private:
  	UDPProxySocket();
  	UDPProxySocket(const UDPProxySocket&);
***************
*** 362,368 ****
  	WORD GetChannelNumber() const { return channelNumber; }
  	void SetChannelNumber(WORD cn) { channelNumber = cn; }

! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *) = 0;
  	virtual void StartReading(ProxyHandler *) = 0;
  	virtual void SetRTPMute(bool toMute) = 0;

--- 366,372 ----
  	WORD GetChannelNumber() const { return channelNumber; }
  	void SetChannelNumber(WORD cn) { channelNumber = cn; }

! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *,callptr &) = 0;
  	virtual void StartReading(ProxyHandler *) = 0;
  	virtual void SetRTPMute(bool toMute) = 0;

***************
*** 381,391 ****
  	void SetMediaChannelSource(const H245_UnicastAddress_iPAddress &);
  	void SetMediaControlChannelSource(const H245_UnicastAddress_iPAddress &);
  	PIPSocket::Address GetSourceIP() const;
! 	void HandleMediaChannel(H245_UnicastAddress_iPAddress *, H245_UnicastAddress_iPAddress *, const PIPSocket::Address &, bool);
! 	bool OnLogicalChannelParameters(H245_H2250LogicalChannelParameters &, const PIPSocket::Address &, bool);

  	// override from class LogicalChannel
! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *);
  	virtual void StartReading(ProxyHandler *);
  	virtual void SetRTPMute(bool toMute);

--- 385,395 ----
  	void SetMediaChannelSource(const H245_UnicastAddress_iPAddress &);
  	void SetMediaControlChannelSource(const H245_UnicastAddress_iPAddress &);
  	PIPSocket::Address GetSourceIP() const;
! 	void HandleMediaChannel(H245_UnicastAddress_iPAddress *, H245_UnicastAddress_iPAddress *, const PIPSocket::Address &, bool, callptr &);
! 	bool OnLogicalChannelParameters(H245_H2250LogicalChannelParameters &, const PIPSocket::Address &, bool, callptr &);

  	// override from class LogicalChannel
! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *,callptr &);
  	virtual void StartReading(ProxyHandler *);
  	virtual void SetRTPMute(bool toMute);

***************
*** 413,419 ****
  	virtual ~T120LogicalChannel();

  	// override from class LogicalChannel
! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *);
  	virtual void StartReading(ProxyHandler *);
  	virtual void SetRTPMute(bool /*toMute*/) {};   /// We do not Mute T.120 Channels

--- 417,423 ----
  	virtual ~T120LogicalChannel();

  	// override from class LogicalChannel
! 	virtual bool SetDestination(H245_OpenLogicalChannelAck &, H245Handler *,callptr &);
  	virtual void StartReading(ProxyHandler *);
  	virtual void SetRTPMute(bool /*toMute*/) {};   /// We do not Mute T.120 Channels

***************
*** 463,472 ****
  	virtual ~H245Handler();

  	virtual void OnH245Address(H225_TransportAddress &);
! 	virtual bool HandleMesg(H245_MultimediaSystemControlMessage &, bool & suppress);
! 	virtual bool HandleFastStartSetup(H245_OpenLogicalChannel &);
! 	virtual bool HandleFastStartResponse(H245_OpenLogicalChannel &);
! 	typedef bool (H245Handler::*pMem)(H245_OpenLogicalChannel &);

  	PIPSocket::Address GetLocalAddr() const { return localAddr; }
      PIPSocket::Address GetRemoteAddr() const { return remoteAddr; }
--- 467,476 ----
  	virtual ~H245Handler();

  	virtual void OnH245Address(H225_TransportAddress &);
! 	virtual bool HandleMesg(H245_MultimediaSystemControlMessage &, bool & suppress, callptr & mcall);
! 	virtual bool HandleFastStartSetup(H245_OpenLogicalChannel &, callptr &);
! 	virtual bool HandleFastStartResponse(H245_OpenLogicalChannel &, callptr &);
! 	typedef bool (H245Handler::*pMem)(H245_OpenLogicalChannel &,callptr &);

  	PIPSocket::Address GetLocalAddr() const { return localAddr; }
      PIPSocket::Address GetRemoteAddr() const { return remoteAddr; }
***************
*** 477,483 ****

  protected:
  	virtual bool HandleRequest(H245_RequestMessage &);
! 	virtual bool HandleResponse(H245_ResponseMessage &);
  	virtual bool HandleCommand(H245_CommandMessage &);
  	virtual bool HandleIndication(H245_IndicationMessage &, bool & suppress);

--- 481,487 ----

  protected:
  	virtual bool HandleRequest(H245_RequestMessage &);
! 	virtual bool HandleResponse(H245_ResponseMessage &,callptr &);
  	virtual bool HandleCommand(H245_CommandMessage &);
  	virtual bool HandleIndication(H245_IndicationMessage &, bool & suppress);

***************
*** 499,506 ****
  	virtual ~H245ProxyHandler();

  	// override from class H245Handler
! 	virtual bool HandleFastStartSetup(H245_OpenLogicalChannel &);
! 	virtual bool HandleFastStartResponse(H245_OpenLogicalChannel &);

  	void SetHandler(ProxyHandler *);
  	LogicalChannel *FindLogicalChannel(WORD);
--- 503,510 ----
  	virtual ~H245ProxyHandler();

  	// override from class H245Handler
! 	virtual bool HandleFastStartSetup(H245_OpenLogicalChannel &,callptr &);
! 	virtual bool HandleFastStartResponse(H245_OpenLogicalChannel &,callptr &);

  	void SetHandler(ProxyHandler *);
  	LogicalChannel *FindLogicalChannel(WORD);
***************
*** 511,522 ****
  private:
  	// override from class H245Handler
  	virtual bool HandleRequest(H245_RequestMessage &);
! 	virtual bool HandleResponse(H245_ResponseMessage &);
  	virtual bool HandleIndication(H245_IndicationMessage &, bool & suppress);

  	bool OnLogicalChannelParameters(H245_H2250LogicalChannelParameters *, WORD);
  	bool HandleOpenLogicalChannel(H245_OpenLogicalChannel &);
! 	bool HandleOpenLogicalChannelAck(H245_OpenLogicalChannelAck &);
  	bool HandleOpenLogicalChannelReject(H245_OpenLogicalChannelReject &);
  	bool HandleCloseLogicalChannel(H245_CloseLogicalChannel &);
  	void HandleMuteRTPChannel();
--- 515,526 ----
  private:
  	// override from class H245Handler
  	virtual bool HandleRequest(H245_RequestMessage &);
! 	virtual bool HandleResponse(H245_ResponseMessage &, callptr &);
  	virtual bool HandleIndication(H245_IndicationMessage &, bool & suppress);

  	bool OnLogicalChannelParameters(H245_H2250LogicalChannelParameters *, WORD);
  	bool HandleOpenLogicalChannel(H245_OpenLogicalChannel &);
! 	bool HandleOpenLogicalChannelAck(H245_OpenLogicalChannelAck &, callptr &);
  	bool HandleOpenLogicalChannelReject(H245_OpenLogicalChannelReject &);
  	bool HandleCloseLogicalChannel(H245_CloseLogicalChannel &);
  	void HandleMuteRTPChannel();
***************
*** 1277,1283 ****
  		}
  	}

! 	if ((!m_h245handler || !m_h245handler->HandleMesg(h245msg, suppress)) && !changed)
  		return false;

  	strm.BeginEncoding();
--- 1281,1287 ----
  		}
  	}

! 	if ((!m_h245handler || !m_h245handler->HandleMesg(h245msg, suppress, m_call)) && !changed)
  		return false;

  	strm.BeginEncoding();
***************
*** 3004,3013 ****
  		} else
  			PTRACE(5, "Q931\tFailover inactive for call " << m_call->GetCallNumber() << ", Q931 cause " << cause);
  	}
!
  	if (m_call)
  		CallTable::Instance()->RemoveCall(m_call);
-
  	m_result = Closing;
  }

--- 3008,3016 ----
  		} else
  			PTRACE(5, "Q931\tFailover inactive for call " << m_call->GetCallNumber() << ", Q931 cause " << cause);
  	}
!
  	if (m_call)
  		CallTable::Instance()->RemoveCall(m_call);
  	m_result = Closing;
  }

***************
*** 3342,3348 ****
  		}

  		H245Handler::pMem handlefs = (fromCaller) ? &H245Handler::HandleFastStartSetup : &H245Handler::HandleFastStartResponse;
! 		if ((m_h245handler->*handlefs)(olc)) {
  			PPER_Stream wtstrm;
  			olc.Encode(wtstrm);
  			wtstrm.CompleteEncoding();
--- 3345,3351 ----
  		}

  		H245Handler::pMem handlefs = (fromCaller) ? &H245Handler::HandleFastStartSetup : &H245Handler::HandleFastStartResponse;
! 		if ((m_h245handler->*handlefs)(olc, m_call)) {
  			PPER_Stream wtstrm;
  			olc.Encode(wtstrm);
  			wtstrm.CompleteEncoding();
***************
*** 4092,4098 ****
  		hnat->TranslateH245Address(addr);
  }

! bool H245Handler::HandleMesg(H245_MultimediaSystemControlMessage & h245msg, bool & suppress)
  {
  	bool changed = false;

--- 4095,4101 ----
  		hnat->TranslateH245Address(addr);
  }

! bool H245Handler::HandleMesg(H245_MultimediaSystemControlMessage & h245msg, bool & suppress, callptr & mcall)
  {
  	bool changed = false;

***************
*** 4102,4108 ****
  			changed = HandleRequest(h245msg);
  			break;
  		case H245_MultimediaSystemControlMessage::e_response:
! 			changed = HandleResponse(h245msg);
  			break;
  		case H245_MultimediaSystemControlMessage::e_command:
  			changed = HandleCommand(h245msg);
--- 4105,4111 ----
  			changed = HandleRequest(h245msg);
  			break;
  		case H245_MultimediaSystemControlMessage::e_response:
! 			changed = HandleResponse(h245msg, mcall);
  			break;
  		case H245_MultimediaSystemControlMessage::e_command:
  			changed = HandleCommand(h245msg);
***************
*** 4117,4128 ****
  	return changed;
  }

! bool H245Handler::HandleFastStartSetup(H245_OpenLogicalChannel & olc)
  {
  	return hnat ? hnat->HandleOpenLogicalChannel(olc) : false;
  }

! bool H245Handler::HandleFastStartResponse(H245_OpenLogicalChannel & olc)
  {
  	return hnat ? hnat->HandleOpenLogicalChannel(olc) : false;
  }
--- 4120,4131 ----
  	return changed;
  }

! bool H245Handler::HandleFastStartSetup(H245_OpenLogicalChannel & olc,callptr & mcall)
  {
  	return hnat ? hnat->HandleOpenLogicalChannel(olc) : false;
  }

! bool H245Handler::HandleFastStartResponse(H245_OpenLogicalChannel & olc, callptr & mcall)
  {
  	return hnat ? hnat->HandleOpenLogicalChannel(olc) : false;
  }
***************
*** 4139,4145 ****
  	}
  }

! bool H245Handler::HandleResponse(H245_ResponseMessage & Response)
  {
  	PTRACE(4, "H245\tResponse: " << Response.GetTagName());
  	if (hnat && Response.GetTag() == H245_ResponseMessage::e_openLogicalChannelAck)
--- 4142,4148 ----
  	}
  }

! bool H245Handler::HandleResponse(H245_ResponseMessage & Response, callptr & mcall)
  {
  	PTRACE(4, "H245\tResponse: " << Response.GetTagName());
  	if (hnat && Response.GetTag() == H245_ResponseMessage::e_openLogicalChannelAck)
***************
*** 4557,4563 ****
  	PTRACE(5, Type() << "\tfnat=" << fnat << " rnat=" << rnat);
  }

! void UDPProxySocket::SetForwardDestination(const Address & srcIP, WORD srcPort, const H245_UnicastAddress_iPAddress & addr)
  {
  	if ((DWORD)srcIP != 0)
  		fSrcIP = srcIP, fSrcPort = srcPort;
--- 4560,4566 ----
  	PTRACE(5, Type() << "\tfnat=" << fnat << " rnat=" << rnat);
  }

! void UDPProxySocket::SetForwardDestination(const Address & srcIP, WORD srcPort, const H245_UnicastAddress_iPAddress & addr, callptr & mcall)
  {
  	if ((DWORD)srcIP != 0)
  		fSrcIP = srcIP, fSrcPort = srcPort;
***************
*** 4574,4590 ****
  		<< " to " << fDestIP << ':' << fDestPort
  		);
  	SetConnected(true);
  }

! void UDPProxySocket::SetReverseDestination(const Address & srcIP, WORD srcPort, const H245_UnicastAddress_iPAddress & addr)
  {
  	if( (DWORD)srcIP != 0 )
  		rSrcIP = srcIP, rSrcPort = srcPort;

  	addr >> rDestIP >> rDestPort;
!
  	PTRACE(5, Type() << "\tReverse " << srcIP << ':' << srcPort << " to " << rDestIP << ':' << rDestPort);
  	SetConnected(true);
  }

  ProxySocket::Result UDPProxySocket::ReceiveData()
--- 4577,4614 ----
  		<< " to " << fDestIP << ':' << fDestPort
  		);
  	SetConnected(true);
+ + if (Type() == "RTCP"){
+ 	    mcall->SetSRC_media_control_IP(fDestIP.AsString());
+ 	    mcall->SetDST_media_control_IP(srcIP.AsString());
+ 	}
+ 	if (Type() == "RTP"){
+ 	    mcall->SetSRC_media_IP(fDestIP.AsString());
+ 	    mcall->SetDST_media_IP(srcIP.AsString());
+ 	}
+ + m_call = &mcall;
  }

! void UDPProxySocket::SetReverseDestination(const Address & srcIP, WORD srcPort, const H245_UnicastAddress_iPAddress & addr, callptr & mcall)
  {
  	if( (DWORD)srcIP != 0 )
  		rSrcIP = srcIP, rSrcPort = srcPort;

  	addr >> rDestIP >> rDestPort;
!
  	PTRACE(5, Type() << "\tReverse " << srcIP << ':' << srcPort << " to " << rDestIP << ':' << rDestPort);
  	SetConnected(true);
+ 	if (Type() == "RTCP"){
+ 	    mcall->SetSRC_media_control_IP(srcIP.AsString());
+ 	    mcall->SetDST_media_control_IP(rDestIP.AsString());
+ 	}
+ 	if (Type() == "RTP"){
+ 	    mcall->SetSRC_media_IP(srcIP.AsString());
+ 	    mcall->SetDST_media_IP(rDestIP.AsString());
+ 	}
+ 	m_call = &mcall;
+
  }

  ProxySocket::Result UDPProxySocket::ReceiveData()
***************
*** 4662,4670 ****
--- 4686,4853 ----
  		if (fnat)
  			fDestIP = fromIP, fDestPort = fromPort;
  	}
+ 	if (Type() == "RTCP"){
+ 	bool direct = true;
+ + if ((*m_call)->GetSRC_media_control_IP() == fromIP.AsString()){
+ 	    direct = true;
+ 	}else {
+ 	    direct = false;
+ 	}
+ + PIPSocket::Address addr = (DWORD)0; + (*m_call)->GetMediaOriginatingIp(addr); + + RTP_ControlFrame frame(2048);
+ 	frame.Attach(wbuffer,buflen);
+ 	do {
+ 	    BYTE * payload = frame.GetPayloadPtr();
+ unsigned size = frame.GetPayloadSize(); + if ((payload == NULL) || (size == 0) || ((payload + size) > (frame.GetPointer() + frame.GetSize()))){
+ 		/* TODO: 1.shall we test for a maximum size ? Indeed but what's the value ? *
+ 			 2. what's the correct exit status ? */
+ //		PTRACE(2, "RTCP\tSession invalid frame");
+ + break;
+ 	    }
+ 	    switch (frame.GetPayloadType()) {
+ 		case RTP_ControlFrame::e_SenderReport :
+ 		    PTRACE(5, "RTCP\tSession SenderReport packet");
+ 		    if (size >= sizeof(RTP_ControlFrame::SenderReport)) {
+ 			const RTP_ControlFrame::SenderReport & sr = *(const RTP_ControlFrame::SenderReport *)(payload);
+ 			if (direct){
+ 			    (*m_call)->SetRTCP_DST_packet_count(sr.psent);
+ 			    PTRACE(5, "RTCP\tSession SetRTCP_DST_packet_count:"<<sr.psent);
+ 			}else{
+ 			    (*m_call)->SetRTCP_SRC_packet_count(sr.psent);
+ 			    PTRACE(5, "RTCP\tSession SetRTCP_SRC_packet_count:"<<sr.psent);
+ } + BuildReceiverReport(frame, sizeof(RTP_ControlFrame::SenderReport),direct);
+ 		    }else {
+ 			PTRACE(5, "RTCP\tSession  SenderReport packet truncated");
+ 		    }
+ 		    break;
+ 		case RTP_ControlFrame::e_ReceiverReport :
+ 		    PTRACE(5, "RTCP\tSession ReceiverReport packet");
+ 		    if (size >= 4)
+ 			BuildReceiverReport(frame, sizeof(PUInt32b),direct);
+     		    else {
+ 			PTRACE(5, "RTP\tSession ReceiverReport packet truncated");
+ 		    }
+ 		    break;
+ 		case RTP_ControlFrame::e_SourceDescription :
+ PTRACE(5, "RTCP\tSession SourceDescription packet"); + if ((!(*m_call)->GetRTCP_SRC_sdes_flag()&&direct)||(!(*m_call)->GetRTCP_DST_sdes_flag()&&!direct))
+ 		    if (size >= frame.GetCount()*sizeof(RTP_ControlFrame::SourceDescription)) {
+ 			const RTP_ControlFrame::SourceDescription * sdes = (const RTP_ControlFrame::SourceDescription *)payload;
+ 			PINDEX srcIdx;
+ 			for (srcIdx = 0; srcIdx < (PINDEX)frame.GetCount(); srcIdx++){
+ 			    const RTP_ControlFrame::SourceDescription::Item * item = sdes->item;
+ 			    while ((item != NULL) && (item->type != RTP_ControlFrame::e_END)){
+ 				if (item->length != NULL && item->length != 0){
+ 				    switch (item->type){
+ 					case RTP_ControlFrame::e_CNAME:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("cname="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("cname="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_NAME:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("name="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("name="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_EMAIL:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("email="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("email="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_PHONE:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("phone="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("phone="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_LOC:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("loc="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("loc="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_TOOL:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("tool="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("tool="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					case RTP_ControlFrame::e_NOTE:
+ 					    if (!direct){
+ 						(*m_call)->SetRTCP_DST_sdes("note="+((PString)(item->data)).Left(item->length));
+ 					    }else{
+ 						(*m_call)->SetRTCP_SRC_sdes("note="+((PString)(item->data)).Left(item->length));
+ 					    }
+ 					    break;
+ 					default :
+ 					    PTRACE(5,"RTCP\tSession  SourceDescription bad item");
+ 					    break;
+ 				    }
+ } + item = item->GetNextItem();
+ 			    }
+ 			    /* RTP_ControlFrame::e_END doesn't have a length field, so do NOT call item->GetNextItem()
+ 				otherwise it reads over the buffer */
+ if((item == NULL) || + (item->type == RTP_ControlFrame::e_END) || + ((sdes = (const RTP_ControlFrame::SourceDescription *)item->GetNextItem()) == NULL)){
+ 				break;
+ 			    }
+ 			}
+ 		    }
+ 		    break;
+ 		case RTP_ControlFrame::e_Goodbye :
+ 		    PTRACE(5, "RTCP\tSession Goodbye packet");
+ 		    break;
+ 		case RTP_ControlFrame::e_ApplDefined :
+ 		    PTRACE(5, "RTCP\tSession ApplDefined packet");
+ 		    break;
+ 		default :
+ 		    PTRACE(5, "RTCP\tSession  Unknown control payload type: " << frame.GetPayloadType());
+ 		    break;
+ 	    }
+ 	} while (frame.ReadNextCompound());
+ 	}
  	return Forwarding;
  }

+ void UDPProxySocket::BuildReceiverReport(const RTP_ControlFrame & frame, PINDEX offset, bool direct)
+ {
+   const RTP_ControlFrame::ReceiverReport * rr = (const RTP_ControlFrame::ReceiverReport *)(frame.GetPayloadPtr()+offset);
+   for (PINDEX repIdx = 0; repIdx < (PINDEX)frame.GetCount(); repIdx++) {
+     RTP_Session::ReceiverReport * report = new RTP_Session::ReceiverReport;
+     if (direct){
+ 	(*m_call)->SetRTCP_DST_packet_lost(report->totalLost = rr->GetLostPackets());
+ 	(*m_call)->SetRTCP_DST_jitter(rr->jitter);
+ 	PTRACE(5, "RTCP\tSession SetRTCP_DST_packet_lost:"<<rr->GetLostPackets());
+ 	PTRACE(5, "RTCP\tSession SetRTCP_DST_jitter:"<<rr->jitter);
+     } else{
+ 	(*m_call)->SetRTCP_SRC_packet_lost(report->totalLost = rr->GetLostPackets());
+ 	(*m_call)->SetRTCP_SRC_jitter(rr->jitter);
+ 	PTRACE(5, "RTCP\tSession SetRTCP_SRC_packet_lost:"<<rr->GetLostPackets());
+ 	PTRACE(5, "RTCP\tSession SetRTCP_SRC_jitter:"<<rr->jitter);
+     }
+     rr++;
+   }
+ }
+ +
  bool UDPProxySocket::WriteData(const BYTE *buffer, int len)
  {
  	if (!IsSocketOpen())
***************
*** 4889,4895 ****
  	addr >> SrcIP >> SrcPort;
  }

! void RTPLogicalChannel::HandleMediaChannel(H245_UnicastAddress_iPAddress *mediaControlChannel, H245_UnicastAddress_iPAddress *mediaChannel, const PIPSocket::Address & local, bool rev)
  {
  	// mediaControlChannel should be non-zero.
  	H245_UnicastAddress_iPAddress tmp, tmpmedia, tmpmediacontrol, *dest = mediaControlChannel;
--- 5072,5078 ----
  	addr >> SrcIP >> SrcPort;
  }

! void RTPLogicalChannel::HandleMediaChannel(H245_UnicastAddress_iPAddress *mediaControlChannel, H245_UnicastAddress_iPAddress *mediaChannel, const PIPSocket::Address & local, bool rev, callptr & mcall)
  {
  	// mediaControlChannel should be non-zero.
  	H245_UnicastAddress_iPAddress tmp, tmpmedia, tmpmediacontrol, *dest = mediaControlChannel;
***************
*** 4918,4924 ****
  		}
  	}
  	UDPProxySocket::pMem SetDest = (reversed) ? &UDPProxySocket::SetReverseDestination : &UDPProxySocket::SetForwardDestination;
! 	(rtcp->*SetDest)(tmpSrcIP, tmpSrcPort, *dest);
  	*mediaControlChannel << local << (port + 1);

  	if (mediaChannel) {
--- 5101,5107 ----
  		}
  	}
  	UDPProxySocket::pMem SetDest = (reversed) ? &UDPProxySocket::SetReverseDestination : &UDPProxySocket::SetForwardDestination;
! 	(rtcp->*SetDest)(tmpSrcIP, tmpSrcPort, *dest, mcall);
  	*mediaControlChannel << local << (port + 1);

  	if (mediaChannel) {
***************
*** 4927,4933 ****
  		} else {
  			dest = mediaChannel;
  		}
! 		(rtp->*SetDest)(tmpSrcIP, tmpSrcPort - 1, *dest);
  		*mediaChannel << local << port;
  	}
  }
--- 5110,5116 ----
  		} else {
  			dest = mediaChannel;
  		}
! 		(rtp->*SetDest)(tmpSrcIP, tmpSrcPort - 1, *dest, mcall);
  		*mediaChannel << local << port;
  	}
  }
***************
*** 4938,4961 ****
  		rtp->SetMute(toMute);
  }

! bool RTPLogicalChannel::OnLogicalChannelParameters(H245_H2250LogicalChannelParameters & h225Params, const PIPSocket::Address & local, bool rev)
  {
  	if (!h225Params.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaControlChannel))
  		return false;
  	H245_UnicastAddress_iPAddress *mediaControlChannel = GetH245UnicastAddress(h225Params.m_mediaControlChannel);
  	H245_UnicastAddress_iPAddress *mediaChannel = h225Params.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaChannel) ? GetH245UnicastAddress(h225Params.m_mediaChannel) : 0;
! 	HandleMediaChannel(mediaControlChannel, mediaChannel, local, rev);
  	return true;
  }

! bool RTPLogicalChannel::SetDestination(H245_OpenLogicalChannelAck & olca, H245Handler *handler)
  {
  	H245_UnicastAddress_iPAddress *mediaControlChannel, *mediaChannel;
  	GetChannelsFromOLCA(olca, mediaControlChannel, mediaChannel);
  	if (mediaControlChannel == NULL && mediaChannel == NULL) {
  		return false;
  	}
! 	HandleMediaChannel(mediaControlChannel, mediaChannel, handler->GetMasqAddr(), false);
  	return true;
  }

--- 5121,5144 ----
  		rtp->SetMute(toMute);
  }

! bool RTPLogicalChannel::OnLogicalChannelParameters(H245_H2250LogicalChannelParameters & h225Params, const PIPSocket::Address & local, bool rev, callptr & mcall)
  {
  	if (!h225Params.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaControlChannel))
  		return false;
  	H245_UnicastAddress_iPAddress *mediaControlChannel = GetH245UnicastAddress(h225Params.m_mediaControlChannel);
  	H245_UnicastAddress_iPAddress *mediaChannel = h225Params.HasOptionalField(H245_H2250LogicalChannelParameters::e_mediaChannel) ? GetH245UnicastAddress(h225Params.m_mediaChannel) : 0;
! 	HandleMediaChannel(mediaControlChannel, mediaChannel, local, rev,mcall);
  	return true;
  }

! bool RTPLogicalChannel::SetDestination(H245_OpenLogicalChannelAck & olca, H245Handler *handler, callptr & mcall)
  {
  	H245_UnicastAddress_iPAddress *mediaControlChannel, *mediaChannel;
  	GetChannelsFromOLCA(olca, mediaControlChannel, mediaChannel);
  	if (mediaControlChannel == NULL && mediaChannel == NULL) {
  		return false;
  	}
! 	HandleMediaChannel(mediaControlChannel, mediaChannel, handler->GetMasqAddr(), false,mcall);
  	return true;
  }

***************
*** 5016,5022 ****
  	PTRACE(4, "T120\tDelete logical channel " << channelNumber);
  }

! bool T120LogicalChannel::SetDestination(H245_OpenLogicalChannelAck & olca, H245Handler * _handler)
  {
  	return (olca.HasOptionalField(H245_OpenLogicalChannelAck::e_separateStack)) ?
  		OnSeparateStack(olca.m_separateStack, _handler) : false;
--- 5199,5205 ----
  	PTRACE(4, "T120\tDelete logical channel " << channelNumber);
  }

! bool T120LogicalChannel::SetDestination(H245_OpenLogicalChannelAck & olca, H245Handler * _handler, callptr & mcall)
  {
  	return (olca.HasOptionalField(H245_OpenLogicalChannelAck::e_separateStack)) ?
  		OnSeparateStack(olca.m_separateStack, _handler) : false;
***************
*** 5148,5161 ****
  	return false;
  }

! bool H245ProxyHandler::HandleResponse(H245_ResponseMessage & Response)
  {
  	PTRACE(4, "H245\tResponse: " << Response.GetTagName());
  	if (peer)
  		switch (Response.GetTag())
  		{
  			case H245_ResponseMessage::e_openLogicalChannelAck:
! 				return HandleOpenLogicalChannelAck(Response);
  			case H245_ResponseMessage::e_openLogicalChannelReject:
  				return HandleOpenLogicalChannelReject(Response);
  			default:
--- 5331,5344 ----
  	return false;
  }

! bool H245ProxyHandler::HandleResponse(H245_ResponseMessage & Response, callptr & mcall)
  {
  	PTRACE(4, "H245\tResponse: " << Response.GetTagName());
  	if (peer)
  		switch (Response.GetTag())
  		{
  			case H245_ResponseMessage::e_openLogicalChannelAck:
! 				return HandleOpenLogicalChannelAck(Response, mcall);
  			case H245_ResponseMessage::e_openLogicalChannelReject:
  				return HandleOpenLogicalChannelReject(Response);
  			default:
***************
*** 5274,5280 ****
  	return false; // nothing changed :)
  }

! bool H245ProxyHandler::HandleOpenLogicalChannelAck(H245_OpenLogicalChannelAck & olca)
  {
  	if (hnat)
  		hnat->HandleOpenLogicalChannelAck(olca);
--- 5457,5463 ----
  	return false; // nothing changed :)
  }

! bool H245ProxyHandler::HandleOpenLogicalChannelAck(H245_OpenLogicalChannelAck & olca, callptr & mcall)
  {
  	if (hnat)
  		hnat->HandleOpenLogicalChannelAck(olca);
***************
*** 5326,5332 ****
  	}
  #endif

! 	bool result = lc->SetDestination(olca, this);
  	if (result)
  		lc->StartReading(handler);
  	return result;
--- 5509,5515 ----
  	}
  #endif

! 	bool result = lc->SetDestination(olca, this, mcall);
  	if (result)
  		lc->StartReading(handler);
  	return result;
***************
*** 5402,5408 ****
  	return false; // nothing changed :)
  }

! bool H245ProxyHandler::HandleFastStartSetup(H245_OpenLogicalChannel & olc)
  {
  	if (!peer)
  		return false;
--- 5585,5591 ----
  	return false; // nothing changed :)
  }

! bool H245ProxyHandler::HandleFastStartSetup(H245_OpenLogicalChannel & olc,callptr & mcall)
  {
  	if (!peer)
  		return false;
***************
*** 5428,5434 ****
  	return ((h225Params) ? OnLogicalChannelParameters(h225Params, 0) : false) || changed;
  }

! bool H245ProxyHandler::HandleFastStartResponse(H245_OpenLogicalChannel & olc)
  {
  	if (!peer)
  		return false;
--- 5611,5617 ----
  	return ((h225Params) ? OnLogicalChannelParameters(h225Params, 0) : false) || changed;
  }

! bool H245ProxyHandler::HandleFastStartResponse(H245_OpenLogicalChannel & olc,callptr & mcall)
  {
  	if (!peer)
  		return false;
***************
*** 5476,5482 ****
  				peer->logicalChannels[flcn] = peer->sessionIDs[id] = lc = new RTPLogicalChannel(lc, flcn, hnat != 0);
  		}
  	}
! 	if (lc && (changed = lc->OnLogicalChannelParameters(*h225Params, GetMasqAddr(), isReverseLC)))
  		lc->StartReading(handler);
  	return changed;
  }
--- 5659,5665 ----
  				peer->logicalChannels[flcn] = peer->sessionIDs[id] = lc = new RTPLogicalChannel(lc, flcn, hnat != 0);
  		}
  	}
! 	if (lc && (changed = lc->OnLogicalChannelParameters(*h225Params, GetMasqAddr(), isReverseLC, mcall)))
  		lc->StartReading(handler);
  	return changed;
  }
diff -c openh323gk_cvs/RasTbl.cxx openh323gk_cvs_p/RasTbl.cxx
*** openh323gk_cvs/RasTbl.cxx	Tue Jun  2 18:23:30 2009
--- openh323gk_cvs_p/RasTbl.cxx	Thu Jun  4 16:06:22 2009
***************
*** 2347,2352 ****
--- 2347,2480 ----
  	m_disabledcodecs = codecs.Trim();
  }

+ void CallRec::SetSRC_media_control_IP(PString IP)
+ {
+     m_src_media_control_IP = IP;
+ }
+ + + void CallRec::SetDST_media_control_IP(PString IP)
+ {
+     m_dst_media_control_IP = IP;
+ }
+ + void CallRec::SetSRC_media_IP(PString IP)
+ {
+     m_src_media_IP = IP;
+ }
+ + + void CallRec::SetDST_media_IP(PString IP)
+ {
+     m_dst_media_IP = IP;
+ }
+ + + void CallRec::InitRTCP_report(){
+     m_rtcp_source_packet_count = 0;
+     m_rtcp_destination_packet_count = 0;
+     m_rtcp_source_packet_lost = 0;
+     m_rtcp_destination_packet_lost = 0;
+ + m_rtcp_source_jitter_max = 0;
+     m_rtcp_source_jitter_min = 0;
+     m_rtcp_source_jitter_avg = 0;
+     m_rtcp_source_jitter_avg_count = 0;
+     m_rtcp_source_jitter_avg_sum = 0;
+ + m_rtcp_destination_jitter_max = 0;
+     m_rtcp_destination_jitter_min = 0;
+     m_rtcp_destination_jitter_avg = 0;
+     m_rtcp_destination_jitter_avg_count = 0;
+     m_rtcp_destination_jitter_avg_sum = 0;
+ + m_src_media_IP = "0.0.0.0";
+     m_dst_media_IP = "0.0.0.0";
+ + m_src_media_control_IP = "0.0.0.0";
+     m_dst_media_control_IP = "0.0.0.0";
+ + m_rtcp_source_sdes_flag = false;
+     m_rtcp_destination_sdes_flag = false;
+ }
+ + + void CallRec::SetRTCP_SRC_sdes(PString val)
+ {
+     m_rtcp_source_sdes.AppendString(val);
+     m_rtcp_source_sdes_flag = true;
+ }
+ + void CallRec::SetRTCP_DST_sdes(PString val) + { + m_rtcp_destination_sdes.AppendString(val); + m_rtcp_destination_sdes_flag = true; + } + + + void CallRec::SetRTCP_SRC_packet_count(long val)
+ {
+     m_rtcp_source_packet_count = val;
+ }
+ + void CallRec::SetRTCP_DST_packet_count(long val)
+ {
+     m_rtcp_destination_packet_count = val;
+ }
+ + void CallRec::SetRTCP_SRC_packet_lost(long val)
+ {
+     m_rtcp_source_packet_lost = val;
+ }
+ + void CallRec::SetRTCP_DST_packet_lost(long val)
+ {
+     m_rtcp_destination_packet_lost = val;
+ }
+ + void CallRec::SetRTCP_SRC_jitter(int val) + { + if (val > 0){
+         if (m_rtcp_source_jitter_min == 0) {
+ 	    m_rtcp_source_jitter_min = val;
+ 	}else if (m_rtcp_source_jitter_min > val) {
+ 	     m_rtcp_source_jitter_min = val;
+ 	}
+ 	if (m_rtcp_source_jitter_max == 0){
+ 	    m_rtcp_source_jitter_max = val;
+ 	}else if (m_rtcp_source_jitter_max < val){
+ 	    m_rtcp_source_jitter_max =val;
+ 	}
+ 	m_rtcp_source_jitter_avg_count ++;
+ 	m_rtcp_source_jitter_avg_sum +=val;
+ 	m_rtcp_source_jitter_avg = (int)(m_rtcp_source_jitter_avg_sum/m_rtcp_source_jitter_avg_count);
+     }else{
+ 	m_rtcp_source_jitter_avg = 0;
+     }
+ }
+ + void CallRec::SetRTCP_DST_jitter(int val)
+ {
+     if (val > 0){
+         if (m_rtcp_destination_jitter_min == 0){
+ 	    m_rtcp_destination_jitter_min = val;
+ 	}else if (m_rtcp_destination_jitter_min > val){
+ 	    m_rtcp_destination_jitter_min =val;
+ 	}
+ 	if (m_rtcp_destination_jitter_max == 0){
+ 	    m_rtcp_destination_jitter_max = val;
+ 	}else if (m_rtcp_destination_jitter_max < val){
+ 	    m_rtcp_destination_jitter_max =val;
+ 	}
+ 	m_rtcp_destination_jitter_avg_count ++;
+ 	m_rtcp_destination_jitter_avg_sum +=val;
+ 	m_rtcp_destination_jitter_avg = (int)(m_rtcp_destination_jitter_avg_sum/m_rtcp_destination_jitter_avg_count);
+     }else{
+ 	m_rtcp_destination_jitter_avg = 0;
+     }
+ }
+ +
  void CallRec::InternalSetEP(endptr & ep, const endptr & nep)
  {
  	if (ep != nep) {
***************
*** 3127,3132 ****
--- 3255,3261 ----
  	}
  	CallList.push_back(NewRec);
  	++m_activeCall;
+ 	NewRec->InitRTCP_report();
  	PTRACE(2, "CallTable::Insert(CALL) Call No. " << NewRec->GetCallNumber() << ", total sessions : " << m_activeCall);
  }

diff -c openh323gk_cvs/RasTbl.h openh323gk_cvs_p/RasTbl.h
*** openh323gk_cvs/RasTbl.h	Tue Jun  2 18:23:31 2009
--- openh323gk_cvs_p/RasTbl.h	Thu Jun  4 16:28:31 2009
***************
*** 756,761 ****
--- 756,819 ----
  		has not been yet received.
  		Meaningful only in GK routed mode.
  	*/
+ + PString GetSRC_media_control_IP() const;
+         PString GetDST_media_control_IP() const;
+ + void SetSRC_media_control_IP(PString IP);
+         void SetDST_media_control_IP(PString IP);
+ + PString GetSRC_media_IP() const; + PString GetDST_media_IP() const; + + void SetSRC_media_IP(PString IP);
+         void SetDST_media_IP(PString IP);
+ + void SetRTCP_SRC_sdes(PString val);
+         void SetRTCP_DST_sdes(PString val);
+ + PStringList GetRTCP_SRC_sdes() const;
+         PStringList GetRTCP_DST_sdes() const;
+ + bool GetRTCP_SRC_sdes_flag() const;
+         bool GetRTCP_DST_sdes_flag() const;
+ + void InitRTCP_report(); + + void SetRTCP_SRC_packet_count(long val);
+         void SetRTCP_DST_packet_count(long val);
+ + void SetRTCP_SRC_packet_lost(long val);
+         void SetRTCP_DST_packet_lost(long val);
+ + void SetRTCP_SRC_jitter(int val); + + void SetRTCP_DST_jitter(int val); + + // Get RTCP source packet count
+         long GetRTCP_SRC_packet_count() const;
+         // Get RTCP destination packet count
+         long GetRTCP_DST_packet_count() const;
+ + // Get RTCP source packet lost
+         long GetRTCP_SRC_packet_lost() const;
+         // Get RTCP destination packet lost
+         long GetRTCP_DST_packet_lost() const;
+ + // Get RTCP source jitter max
+         int GetRTCP_SRC_jitter_max() const;
+         // Get RTCP source jitter min
+         int GetRTCP_SRC_jitter_min() const;
+         // Get RTCP source jitter avg
+         int GetRTCP_SRC_jitter_avg() const;
+ + //Get RTCP destinaton jitter max
+         int GetRTCP_DST_jitter_max() const;
+         //Get RTCP destinaton jitter in
+         int GetRTCP_DST_jitter_min() const;
+         //Get RTCP destinaton jitter avg
+         int GetRTCP_DST_jitter_avg() const;
+
  	time_t GetSetupTime() const;

  	/** Set timestamp for a Setup message associated with this call. */
***************
*** 1078,1086 ****

  	/// list of disabled codes
  	PString m_disabledcodecs;

  	/// current timeout (or duration limit) for the call
! 	time_t m_timeout;
  	/// timestamp for call timeout measuring
  	time_t m_timer;
  	/// timestamp (seconds since 1st January, 1970) for the call creation
--- 1136,1180 ----

  	/// list of disabled codes
  	PString m_disabledcodecs;
+ + PString m_src_media_control_IP, m_dst_media_control_IP;
+         PString m_src_media_IP, m_dst_media_IP;
+ + PStringList m_rtcp_source_sdes;
+         bool m_rtcp_source_sdes_flag;
+ + PStringList m_rtcp_destination_sdes; + bool m_rtcp_destination_sdes_flag; + + // RTCP_source_packet_count
+         long m_rtcp_source_packet_count;
+ // RTCP_destination_packet_count + long m_rtcp_destination_packet_count; + + // RTCP_source_packet_lost
+         long m_rtcp_source_packet_lost;
+         // RTCP_destination_packet_lost
+         long m_rtcp_destination_packet_lost;
+ + // RTCP_source_jitter
+         int m_rtcp_source_jitter_min;
+         int m_rtcp_source_jitter_max;
+         int m_rtcp_source_jitter_avg;
+ + // RTCP_destination_jitter
+         int m_rtcp_destination_jitter_min;
+         int m_rtcp_destination_jitter_max;
+         int m_rtcp_destination_jitter_avg;
+ + + int m_rtcp_source_jitter_avg_count;
+         long m_rtcp_source_jitter_avg_sum;
+ + int m_rtcp_destination_jitter_avg_count;
+         long m_rtcp_destination_jitter_avg_sum;

  	/// current timeout (or duration limit) for the call
! 	time_t m_timeout;
  	/// timestamp for call timeout measuring
  	time_t m_timer;
  	/// timestamp (seconds since 1st January, 1970) for the call creation
***************
*** 1558,1563 ****
--- 1652,1749 ----
  		(m_Called && m_Called->GetCallSignalAddress() == *adr);
  }

+ inline PString CallRec::GetSRC_media_control_IP() const
+ {
+     return m_src_media_control_IP;
+ }
+ + inline PString CallRec::GetDST_media_control_IP() const
+ {
+     return m_dst_media_control_IP;
+ }
+ + inline PString CallRec::GetSRC_media_IP() const
+ {
+     return m_src_media_IP;
+ }
+ + inline PString CallRec::GetDST_media_IP() const
+ {
+     return m_dst_media_IP;
+ }
+ + inline bool CallRec::GetRTCP_SRC_sdes_flag() const
+ {
+     return m_rtcp_source_sdes_flag;
+ }
+ + inline bool CallRec::GetRTCP_DST_sdes_flag() const
+ {
+     return m_rtcp_destination_sdes_flag;
+ }
+ + inline PStringList CallRec::GetRTCP_SRC_sdes() const
+ {
+     return m_rtcp_source_sdes;
+ }
+ + inline PStringList CallRec::GetRTCP_DST_sdes() const
+ {
+     return m_rtcp_destination_sdes;
+ }
+ + + + inline long CallRec::GetRTCP_SRC_packet_count() const
+ {
+     return m_rtcp_source_packet_count;
+ }
+ + inline long CallRec::GetRTCP_DST_packet_count() const
+ {
+     return m_rtcp_destination_packet_count;
+ }
+ + inline long CallRec::GetRTCP_SRC_packet_lost() const
+ {
+     return m_rtcp_source_packet_lost;
+ }
+ + inline long CallRec::GetRTCP_DST_packet_lost() const
+ {
+     return m_rtcp_destination_packet_lost;
+ }
+ + inline int CallRec::GetRTCP_SRC_jitter_max() const
+ {
+     return m_rtcp_source_jitter_max;
+ }
+ + inline int CallRec::GetRTCP_SRC_jitter_min() const
+ {
+     return m_rtcp_source_jitter_min;
+ }
+ + inline int CallRec::GetRTCP_SRC_jitter_avg() const
+ {
+     return m_rtcp_source_jitter_avg;
+ }
+ + inline int CallRec::GetRTCP_DST_jitter_max() const
+ {
+     return m_rtcp_destination_jitter_max;
+ }
+ + inline int CallRec::GetRTCP_DST_jitter_min() const
+ {
+     return m_rtcp_destination_jitter_min;
+ }
+ + inline int CallRec::GetRTCP_DST_jitter_avg() const
+ {
+     return m_rtcp_destination_jitter_avg;
+ }
+
  inline time_t CallRec::GetSetupTime() const
  {
  	return m_setupTime;
diff -c openh323gk_cvs/radacct.cxx openh323gk_cvs_p/radacct.cxx
*** openh323gk_cvs/radacct.cxx	Mon May 25 02:38:51 2009
--- openh323gk_cvs_p/radacct.cxx	Thu Jun  4 16:06:22 2009
***************
*** 320,325 ****
--- 320,381 ----
  				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_release_source,call->GetReleaseSource());
  				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_preferred_codec,call->GetCodec());
  				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_rewritten_e164_num,call->GetCalledStationId());
+ 				//RTCP SOURCE REPORT
+ + pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTP_source_IP=")+call->GetSRC_media_IP(),
+     				    true
+ 				);
+ + pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTP_destination_IP=")+call->GetDST_media_IP(),
+     				    true
+ 				);
+ + pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_source_packet_count=")+PString(PString::Unsigned,call->GetRTCP_SRC_packet_count()),
+     				    true
+ 				);
+ 				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_source_packet_lost=")+PString(PString::Unsigned,call->GetRTCP_SRC_packet_lost()),
+ 				    true
+ 				);
+ 				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_source_jitter=")+PString(PString::Unsigned,call->GetRTCP_SRC_jitter_min())+PString("|")+PString(PString::Unsigned,call->GetRTCP_SRC_jitter_avg())+PString("|")+PString(PString::Unsigned,call->GetRTCP_SRC_jitter_max()),
+ 				    true
+ 				);
+ + PINDEX i_sdes = 0;
+ 				PStringList sdes = call->GetRTCP_SRC_sdes();
+ 				while (i_sdes < sdes.GetSize()) {
+ 				    pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 					PString("RTCP_source_sdes_")+sdes[i_sdes],
+ 					true
+ 				    );
+ 				    i_sdes ++;
+ 				}
+ 				//RTCP DESTINATION REPORT
+ 				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_destination_packet_count=")+PString(PString::Unsigned,call->GetRTCP_DST_packet_count()),
+ 				    true
+ 				);
+ 				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_destination_packet_lost=")+PString(PString::Unsigned,call->GetRTCP_DST_packet_lost()),
+ 				    true
+ 				);
+ 				pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 				    PString("RTCP_destination_jitter=")+PString(PString::Unsigned,call->GetRTCP_DST_jitter_min())+PString("|")+PString(PString::Unsigned,call->GetRTCP_DST_jitter_avg())+PString("|")+PString(PString::Unsigned,call->GetRTCP_DST_jitter_max()),
+ 				    true
+ 				);
+ 				i_sdes = 0;
+ 				sdes = call->GetRTCP_DST_sdes();
+ 				while (i_sdes < sdes.GetSize()) {
+ 				    pdu->AppendCiscoAttr(RadiusAttr::CiscoVSA_AV_Pair,
+ 					PString("RTCP_destination_sdes_")+sdes[i_sdes],
+ 					true
+ 				    );
+ 				    i_sdes ++;
+ 				}
  			}

  			if (call->GetDestSignalAddr(addr,port))
***************
*** 332,337 ****
--- 388,394 ----
  					+ GetGUIDString(call->GetCallIdentifier().m_guid),
  				true
  				);
+
  		}

  		pdu->AppendAttr(RadiusAttr::AcctDelayTime, 0);


C уважением                       With Best Regards
Георгиевский Юрий.                Georgiewskiy Yuriy
+7 4872 711666                    +7 4872 711666
факс +7 4872 711143               fax +7 4872 711143
Компания ООО "Ай Ти Сервис"       IT Service Ltd
http://nkoort.ru                  http://nkoort.ru
JID: GHhost@xxxxxxxxxxxxxxxxxxxxx JID: GHhost@xxxxxxxxxxxxxxxxxxxxx
YG129-RIPE                        YG129-RIPE
------------------------------------------------------------------------------
Crystal Reports - New Free Runtime and 30 Day Trial
Check out the new simplified licensing option that enables unlimited
royalty-free distribution of the report engine for externally facing 
server and web deployment.
http://p.sf.net/sfu/businessobjects
_______________________________________________________

Posting: mailto:Openh323gk-users@xxxxxxxxxxxxxxxxxxxxx
Archive: http://sourceforge.net/mailarchive/forum.php?forum_name=openh323gk-users
Unsubscribe: http://lists.sourceforge.net/lists/listinfo/openh323gk-users
Homepage: http://www.gnugk.org/

[Index of Archives]     [SIP]     [Open H.323]     [Gnu Gatekeeper]     [Asterisk PBX]     [ISDN Cause Codes]     [Yosemite News]

  Powered by Linux