/* * Copyright 2007 Sun Microsystems, Inc. * * This file is part of jVoiceBridge. * * jVoiceBridge is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation and distributed hereunder * to you. * * jVoiceBridge is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the License file that accompanied this * code. */ package com.sun.voip; import java.io.IOException; import java.net.DatagramPacket; /* * From RFC1889 * * SR: Sender report RTCP packet * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |V=2|P| RC | PT=SR=200 | length | header * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | SSRC of sender | * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * | NTP timestamp, most significant word | sender * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ info * | NTP timestamp, least significant word | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | RTP timestamp | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | sender's packet count | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | sender's octet count | * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * | SSRC_1 (SSRC of first source) | report * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block * | fraction lost | cumulative number of packets lost | 1 * -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | extended highest sequence number received | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | interarrival jitter | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | last SR (LSR) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | delay since last SR (DLSR) | * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * | SSRC_2 (SSRC of second source) | report * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block * : ... : 2 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ * | profile-specific extensions | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ public class RtcpSenderPacket extends RtcpPacket { /* * This constructor is used for a packet which has been received. */ public RtcpSenderPacket(DatagramPacket packet) { super(packet); } /* * This constructor is used to create a packet to send */ public RtcpSenderPacket(int SSRC) { super(SSRC, true); setSSRC_1(SSRC); } public void setNTPTimestamp(long ts) { rtcpData[8] = (byte) ((ts >> 56) & 0xff); rtcpData[9] = (byte) ((ts >> 48) & 0xff); rtcpData[10] = (byte) ((ts >> 40) & 0xff); rtcpData[11] = (byte) ((ts >> 32) & 0xff); rtcpData[12] = (byte) ((ts >> 24) & 0xff); rtcpData[13] = (byte) ((ts >> 16) & 0xff); rtcpData[14] = (byte) ((ts >> 8) & 0xff); rtcpData[15] = (byte) (ts & 0xff); } public void setRTPTimestamp(int ts) { rtcpData[16] = (byte) ((ts >> 24) & 0xff); rtcpData[17] = (byte) ((ts >> 16) & 0xff); rtcpData[18] = (byte) ((ts >> 8) & 0xff); rtcpData[19] = (byte) (ts & 0xff); } public int getRTPTimestamp() { return ((((int)rtcpData[16]) << 24) & 0xff000000) | ((((int)rtcpData[17]) << 16) & 0x00ff0000) | ((((int)rtcpData[18]) << 8) & 0x0000ff00) | (rtcpData[19] & 0xff); } public void setPacketCount(int packetCount) { rtcpData[20] = (byte) ((packetCount >> 24) & 0xff); rtcpData[21] = (byte) ((packetCount >> 16) & 0xff); rtcpData[22] = (byte) ((packetCount >> 8) & 0xff); rtcpData[23] = (byte) (packetCount & 0xff); } public int getPacketCount() { return ((((int)rtcpData[20]) << 24) & 0xff000000) | ((((int)rtcpData[21]) << 16) & 0x00ff0000) | ((((int)rtcpData[22]) << 8) & 0x0000ff00) | (rtcpData[23] & 0xff); } public void setOctetCount(int octetCount) { rtcpData[24] = (byte) ((octetCount >> 24) & 0xff); rtcpData[25] = (byte) ((octetCount >> 16) & 0xff); rtcpData[26] = (byte) ((octetCount >> 8) & 0xff); rtcpData[27] = (byte) (octetCount >> 0xff); } public int getOctetCount() { return ((((int)rtcpData[24]) << 24) & 0xff000000) | ((((int)rtcpData[25]) << 16) & 0x00ff0000) | ((((int)rtcpData[26]) << 8) & 0x0000ff00) | (rtcpData[27] & 0xff); } public void setSSRC_1(int SSRC) { rtcpData[28] = (byte) ((SSRC >> 24) & 0xff); rtcpData[29] = (byte) ((SSRC >> 16) & 0xff); rtcpData[30] = (byte) ((SSRC >> 8) & 0xff); rtcpData[31] = (byte) (SSRC & 0xff); } public void setFractionLost(byte fractionLost) { rtcpData[32] = fractionLost; } public byte getFractionLost() { return rtcpData[32]; } public void setCumulativeLost(int cumulativeLost) { rtcpData[33] = (byte) ((cumulativeLost >> 16) & 0xff); rtcpData[34] = (byte) ((cumulativeLost >> 8) & 0xff); rtcpData[35] = (byte) (cumulativeLost & 0xff); } public int getCumulativeLost() { int cumulativeLost = ((((int)rtcpData[33]) << 16) & 0x00ff0000) | ((((int)rtcpData[34]) << 8) & 0x0000ff00) | (rtcpData[35] & 0xff); if ((rtcpData[33] & 0x80) != 0) { cumulativeLost |= 0xff000000; // it's negative } return cumulativeLost; } public void setHighestSeqReceived(int seq) { rtcpData[36] = (byte) ((seq >> 24) & 0xff); rtcpData[37] = (byte) ((seq >> 16) & 0xff); rtcpData[38] = (byte) ((seq >> 8) & 0xff); rtcpData[39] = (byte) (seq & 0xff); } public int getHighestSeqReceived() { return ((((int)rtcpData[36]) << 24) & 0xff000000) | ((((int)rtcpData[37]) << 16) & 0x00ff0000) | ((((int)rtcpData[38]) << 8) & 0x0000ff00) | (rtcpData[39] & 0xff); } public void setInterArrivalJitter(int interArrivalJitter) { rtcpData[40] = (byte) ((interArrivalJitter >> 24) & 0xff); rtcpData[41] = (byte) ((interArrivalJitter >> 16) & 0xff); rtcpData[42] = (byte) ((interArrivalJitter >> 8) & 0xff); rtcpData[43] = (byte) (interArrivalJitter & 0xff); } public int getInterArrivalJitter() { return ((((int)rtcpData[40]) << 24) & 0xff000000) | ((((int)rtcpData[41]) << 16) & 0x00ff0000) | ((((int)rtcpData[42]) << 8) & 0x0000ff00) | (rtcpData[43] & 0xff); } public void setLSR(int LSR) { rtcpData[44] = (byte) ((LSR >> 24) & 0xff); rtcpData[45] = (byte) ((LSR >> 16) & 0xff); rtcpData[46] = (byte) ((LSR >> 8) & 0xff); rtcpData[47] = (byte) (LSR & 0xff); } public int getLSR() { return ((((int)rtcpData[44]) << 24) & 0xff000000) | ((((int)rtcpData[45]) << 16) & 0x00ff0000) | ((((int)rtcpData[46]) << 8) & 0x0000ff00) | (rtcpData[47] & 0xff); } public void setDLSR(int DLSR) { rtcpData[48] = (byte) ((DLSR >> 24) & 0xff); rtcpData[49] = (byte) ((DLSR >> 16) & 0xff); rtcpData[50] = (byte) ((DLSR >> 8) & 0xff); rtcpData[51] = (byte) (DLSR & 0xff); } public void printReport() { if (Logger.logLevel >= Logger.LOG_INFO) { Logger.writeFile(" RTCP Sender report: from " + from + ", RTP Timestamp " + Integer.toHexString(getRTPTimestamp()) + ", packets " + getPacketCount() + ", octets " + getOctetCount() + ", fractionLost " + getFractionLost() + ", cumulativeLost " + getCumulativeLost() + ", highest seq " + Integer.toHexString(getHighestSeqReceived()) + ", jitter " + getInterArrivalJitter()); } } }