EMMA Coverage Report (generated Tue Dec 18 20:38:46 CET 2007)
[all classes][cz.vutbr.feec.session.rtprtcp.internal]

COVERAGE SUMMARY FOR SOURCE FILE [Session3550.java]

nameclass, %method, %block, %line, %
Session3550.java0%   (0/1)0%   (0/64)0%   (0/1324)0%   (0/349)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Session35500%   (0/1)0%   (0/64)0%   (0/1324)0%   (0/349)
<static initializer> 0%   (0/1)0%   (0/12)0%   (0/3)
Session3550 (Socket, DatagramSocket, SessionType, double, int, int, InetAddre... 0%   (0/1)0%   (0/43)0%   (0/15)
Session3550 (Socket, DatagramSocket, SessionType, double, int, int, MemberTab... 0%   (0/1)0%   (0/43)0%   (0/15)
Session3550 (Socket, Socket, DatagramSocket, SessionType, double, int, int, I... 0%   (0/1)0%   (0/41)0%   (0/14)
Session3550 (Socket, Socket, DatagramSocket, SessionType, double, int, int, M... 0%   (0/1)0%   (0/41)0%   (0/14)
addMemberTableChangeListener (MemberTableChangeListener): void 0%   (0/1)0%   (0/6)0%   (0/2)
addPacketSentOrRetreiveListener (PacketSentOrRetreiveListener): void 0%   (0/1)0%   (0/6)0%   (0/2)
computeInterval (): double 0%   (0/1)0%   (0/89)0%   (0/24)
expireSender (): void 0%   (0/1)0%   (0/6)0%   (0/2)
getCNAME (): String 0%   (0/1)0%   (0/4)0%   (0/1)
getEMAIL (): String 0%   (0/1)0%   (0/4)0%   (0/1)
getM_RTPHandler (): RTPThreadHandler 0%   (0/1)0%   (0/3)0%   (0/1)
getMirrorPacketDestPort (): int 0%   (0/1)0%   (0/4)0%   (0/1)
getName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getOwnSource (): Source 0%   (0/1)0%   (0/3)0%   (0/1)
getSSRC (): long 0%   (0/1)0%   (0/4)0%   (0/1)
init (Socket, Socket, DatagramSocket, SessionType, double, int, int, InetAddr... 0%   (0/1)0%   (0/98)0%   (0/24)
isActiveSender (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
isByeRequested (): boolean 0%   (0/1)0%   (0/4)0%   (0/1)
isByeSent (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isFeedbackTarget (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
isReceiver (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
isRunning (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isSSM (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
isSender (): boolean 0%   (0/1)0%   (0/5)0%   (0/1)
mirrorPacketToMcastGroup (byte [], int): void 0%   (0/1)0%   (0/6)0%   (0/2)
onBYEReceive (ByePacket): void 0%   (0/1)0%   (0/34)0%   (0/8)
onBYESent (ByePacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onBye (): void 0%   (0/1)0%   (0/15)0%   (0/5)
onExpireInvalid (Source): void 0%   (0/1)0%   (0/16)0%   (0/5)
onExpireMember (Source): void 0%   (0/1)0%   (0/16)0%   (0/5)
onExpireSender (Source): void 0%   (0/1)0%   (0/22)0%   (0/7)
onInit (Source): void 0%   (0/1)0%   (0/16)0%   (0/5)
onNewInvalid (Source): void 0%   (0/1)0%   (0/16)0%   (0/5)
onNewSender (Source): void 0%   (0/1)0%   (0/19)0%   (0/6)
onRRReceive (ReportPacket): void 0%   (0/1)0%   (0/19)0%   (0/6)
onRRSent (ReportPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onRSIReceive (RSIPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onRSISent (RSIPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onRTPReceive (RTPPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onRTPSent (RTPPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onReportReceived (GeneralRTCPHeader): void 0%   (0/1)0%   (0/26)0%   (0/7)
onSDESReceive (SDESPacket): void 0%   (0/1)0%   (0/88)0%   (0/27)
onSDESSent (SDESPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onSRReceive (SenderReportPacket): void 0%   (0/1)0%   (0/19)0%   (0/6)
onSRSent (SenderReportPacket): void 0%   (0/1)0%   (0/16)0%   (0/5)
onSchedule (double, Session3550): void 0%   (0/1)0%   (0/17)0%   (0/5)
onValidated (Source): void 0%   (0/1)0%   (0/16)0%   (0/5)
prepareForByeTransmit (int): void 0%   (0/1)0%   (0/32)0%   (0/10)
refresh (): void 0%   (0/1)0%   (0/231)0%   (0/44)
removeAllMembers (): void 0%   (0/1)0%   (0/21)0%   (0/6)
sendRTPPacket (byte [], int): void 0%   (0/1)0%   (0/9)0%   (0/3)
sendRTPPacket (byte [], int, boolean): void 0%   (0/1)0%   (0/24)0%   (0/5)
setByeRequested (boolean): void 0%   (0/1)0%   (0/5)0%   (0/2)
setByeSent (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setCNAME (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
setEMAIL (String): void 0%   (0/1)0%   (0/5)0%   (0/2)
setM_RTCPHandler (RTCPThreadHandler): void 0%   (0/1)0%   (0/4)0%   (0/2)
setM_RTPHandler (RTPThreadHandler): void 0%   (0/1)0%   (0/4)0%   (0/2)
setName (String): void 0%   (0/1)0%   (0/4)0%   (0/2)
startRTPReceiverThread (): void 0%   (0/1)0%   (0/4)0%   (0/2)
startSession (): void 0%   (0/1)0%   (0/16)0%   (0/6)
stopSession (): void 0%   (0/1)0%   (0/7)0%   (0/3)
updateAvgPktLength (int): void 0%   (0/1)0%   (0/34)0%   (0/6)

1package cz.vutbr.feec.session.rtprtcp.internal;
2 
3import java.net.DatagramSocket;
4import java.net.InetAddress;
5import java.util.Enumeration;
6import java.util.Iterator;
7import java.util.Vector;
8 
9import net.java.dev.jssm.Socket;
10 
11import org.apache.commons.lang.math.RandomUtils;
12import org.apache.log4j.Logger;
13 
14import cz.vutbr.feec.packets.PacketGenerateException;
15import cz.vutbr.feec.packets.rsi.RSIPacket;
16import cz.vutbr.feec.packets.rtcp.ByePacket;
17import cz.vutbr.feec.packets.rtcp.GeneralRTCPHeader;
18import cz.vutbr.feec.packets.rtcp.ReportPacket;
19import cz.vutbr.feec.packets.rtcp.SenderReportPacket;
20import cz.vutbr.feec.packets.rtcp.SDESChunk;
21import cz.vutbr.feec.packets.rtcp.SDESItem;
22import cz.vutbr.feec.packets.rtcp.SDESPacket;
23import cz.vutbr.feec.packets.rtp.RTPPacket;
24import cz.vutbr.feec.session.Constants;
25import cz.vutbr.feec.session.ISession;
26 
27/**
28 * This class maintains session related information and provides startup
29 * functions.
30 */
31 
32public class Session3550 extends Session implements MemberTableChangeListener,
33                PacketSentOrRetreiveListener, ISession {
34 
35        /** The logger. */
36        private static Logger logger = Logger
37                        .getLogger(Session3550.class.getName());
38 
39        /** The is created as sender. */
40        private SessionType sessionType  = null;
41 
42        /** The is SSM. */
43        private boolean isSSM;
44 
45        /** The member table change listener. */
46        private Vector<MemberTableChangeListener> memberTableChangeListeners = new Vector<MemberTableChangeListener>();
47 
48        /** The packet sent or retreive listener. */
49        private Vector<PacketSentOrRetreiveListener> packetSentOrRetreiveListeners =  
50                new Vector<PacketSentOrRetreiveListener>();
51 
52        private String name = "";
53 
54        /**
55         * Sets the packet sent or retreive listener.
56         * 
57         * @param packetSentOrRetreiveListener
58         *            the packet sent or retreive listener
59         */
60        public void addPacketSentOrRetreiveListener(
61                        PacketSentOrRetreiveListener packetSentOrRetreiveListener) {
62                this.packetSentOrRetreiveListeners.add(packetSentOrRetreiveListener);
63        }
64 
65        /**
66         * Gets the mirror packet dest port.
67         * 
68         * @return the mirror packet dest port
69         */
70        public int getMirrorPacketDestPort() {
71                return m_RTCPHandler.getDestRTCPPort();
72        }
73 
74        /**
75         * Mirror packet to mcast group.
76         * 
77         * @param packet
78         *            the packet
79         */
80        protected void mirrorPacketToMcastGroup(byte[] packet, int length) {
81                m_RTCPHandler.mirrorPacket(packet, length);
82        }
83 
84        /** Initialize the Random Number Generator. */
85        private RTPThreadHandler m_RTPHandler;
86 
87        /** The m_ RTCP handler. */
88        private RTCPThreadHandler m_RTCPHandler;
89 
90        /** The own source. */
91        private Source ownSource;
92 
93        private boolean byeSent = false;
94 
95        private boolean running = false;
96 
97        /**
98         * Create receiver Session Create Source-specific multicast session. Sets
99         * action listener.
100         * 
101         * @param multicastRTPSocket
102         *            the multicast RTP socket
103         * @param unicastSendToPort
104         *            the unicast send to port
105         * @param bandwidth
106         *            the bandwidth
107         * @param isCreatedAsSender
108         *            the is created as sender
109         * @param multicastRTCPSocket
110         *            the multicast RTCP socket
111         * @param targetFeedbackAddr
112         *            the target feedback addr
113         * @param listener
114         *            the listener
115         * @param ssmSendToPort
116         *            the ssm send to port
117         * @param unicastSocket
118         *            the unicast socket
119         */
120        public Session3550(Socket multicastRTPSocket, Socket multicastRTCPSocket,
121                        DatagramSocket unicastSocket, SessionType sessionType,
122                        double bandwidth, int ssmSendToPort, int unicastSendToPort,
123                        MemberTableChangeListener listener, InetAddress targetFeedbackAddr) {
124                addMemberTableChangeListener(listener);
125                init(multicastRTPSocket, multicastRTCPSocket, unicastSocket,
126                                sessionType, bandwidth, ssmSendToPort, unicastSendToPort,
127                                targetFeedbackAddr);
128        }
129 
130        /**
131         * Create Sender Session Create Source-specific multicast session. Sets
132         * action listener.
133         * 
134         * @param multicastRTPSocket
135         *            the multicast RTP socket
136         * @param unicastSendToPort
137         *            the unicast send to port
138         * @param bandwidth
139         *            the bandwidth
140         * @param isCreatedAsSender
141         *            the is created as sender
142         * @param targetFeedbackAddr
143         *            the target feedback addr
144         * @param listener
145         *            the listener
146         * @param ssmSendToPort
147         *            the ssm send to port
148         * @param unicastSocket
149         *            the unicast socket
150         */
151        public Session3550(Socket multicastRTPSocket, DatagramSocket unicastSocket,
152                        SessionType sessionType, double bandwidth, int ssmSendToPort,
153                        int unicastSendToPort, MemberTableChangeListener listener,
154                        InetAddress targetFeedbackAddr) {
155                addMemberTableChangeListener(listener);
156                Socket multicastRTCPSocket = null;
157                init(multicastRTPSocket, multicastRTCPSocket, unicastSocket,
158                                sessionType, bandwidth, ssmSendToPort, unicastSendToPort,
159                                targetFeedbackAddr);
160        }
161 
162        /**
163         * Receiver session. Create Source-specific multicast session.
164         * 
165         * @param multicastRTPSocket
166         *            the multicast RTP socket
167         * @param unicastSendToPort
168         *            the unicast send to port
169         * @param bandwidth
170         *            the bandwidth
171         * @param isCreatedAsSender
172         *            the is created as sender
173         * @param multicastRTCPSocket
174         *            the multicast RTCP socket
175         * @param targetFeedbackAddr
176         *            the target feedback addr
177         * @param ssmSendToPort
178         *            the ssm send to port
179         * @param unicastSocket
180         *            the unicast socket
181         */
182        public Session3550(Socket multicastRTPSocket, Socket multicastRTCPSocket,
183                        DatagramSocket unicastSocket, SessionType sessionType,
184                        double bandwidth, int ssmSendToPort, int unicastSendToPort,
185                        InetAddress targetFeedbackAddr, String name) {
186                this.name = name;
187                init(multicastRTPSocket, multicastRTCPSocket, unicastSocket,
188                                sessionType, bandwidth, ssmSendToPort, unicastSendToPort,
189                                targetFeedbackAddr);
190        }
191 
192        /**
193         * Sender session. Create Source-specific multicast session.
194         * 
195         * @param multicastRTPSocket
196         *            the multicast RTP socket
197         * @param unicastSendToPort
198         *            the unicast send to port
199         * @param bandwidth
200         *            the bandwidth
201         * @param isCreatedAsSender
202         *            the is created as sender
203         * @param targetFeedbackAddr
204         *            the target feedback addr
205         * @param ssmSendToPort
206         *            the ssm send to port
207         * @param unicastSocket
208         *            the unicast socket
209         */
210        public Session3550(Socket multicastRTPSocket, DatagramSocket unicastSocket,
211                        SessionType sessionType, double bandwidth, int ssmSendToPort,
212                        int unicastSendToPort, InetAddress targetFeedbackAddr, String name) {
213                Socket multicastRTCPSocket = null;
214                this.name = name;
215                init(multicastRTPSocket, multicastRTCPSocket, unicastSocket,
216                                sessionType, bandwidth, ssmSendToPort, unicastSendToPort,
217                                targetFeedbackAddr);
218        }
219 
220        /**
221         * Init.
222         * 
223         * @param multicastRTPSocket
224         *            the multicast RTP socket
225         * @param unicastSendToPort
226         *            the unicast send to port
227         * @param bandwidth
228         *            the bandwidth
229         * @param isCreatedAsSender
230         *            the is created as sender
231         * @param multicastRTCPSocket
232         *            the multicast RTCP socket
233         * @param targetFeedbackAddr
234         *            the target feedback addr
235         * @param ssmSendToPort
236         *            the ssm send to port
237         * @param unicastSocket
238         *            the unicast socket
239         */
240        private void init(Socket multicastRTPSocket, Socket multicastRTCPSocket,
241                        DatagramSocket unicastSocket, SessionType sessionType,
242                        double bandwidth, int ssmSendToPort, int unicastSendToPort,
243                        InetAddress targetFeedbackAddr) {
244                this.sessionType = sessionType; 
245                        
246                assert isReceiver() && targetFeedbackAddr != null : "Not initialized properly!!";
247                this.isSSM = true;
248 
249                this.rtcp_bw = bandwidth;
250 
251                // Create SSRC
252                long ssrc = RandomUtils.nextInt();
253                int seq = Math.abs(RandomUtils.nextInt());
254 
255                ownSource = addMember(ssrc, seq);
256                ownSource.setSender(isSender());
257                validate(ssrc);
258 
259                onInit(ownSource);
260 
261                if (isSender()) {
262                        addSender(ssrc, 0);
263                }
264 
265                // Create a new RTP Handler thread (but do not start it yet)
266                m_RTPHandler = new RTPThreadHandler(this, multicastRTPSocket,
267                                ssmSendToPort);
268                m_RTPHandler.setPriority(Thread.MAX_PRIORITY);
269 
270                // Create a new RTCP Handler thread (but do not start it yet)
271                // Set the sendto and recvfrom ports
272                if (isSender()) {
273                        multicastRTCPSocket = multicastRTPSocket;
274                        m_RTCPHandler = new RTCPThreadHandlerSender(this, unicastSocket,
275                                        multicastRTCPSocket, unicastSendToPort);
276                } else if(isReceiver()){
277                        m_RTCPHandler = new RTCPThreadHandlerReceiver(this, unicastSocket,
278                                        multicastRTCPSocket, unicastSendToPort, targetFeedbackAddr);
279                } else if(isFeedbackTarget()) {
280//                        TODO: pridat podporu pro feedback target
281                }
282        } 
283 
284        /**
285         * Starts the RTP Receiver thread.
286         */
287        public synchronized void startRTPReceiverThread() {
288                m_RTPHandler.start();
289        }
290 
291        /**
292         * Checks if is bye requested.
293         * 
294         * @return Returns the isByeRequested.
295         */
296        public boolean isByeRequested() {
297                return getOwnSource().byeRequested;
298        }
299 
300        /**
301         * Sets the bye requested.
302         * 
303         * @param isByeRequested
304         *            The isByeRequested to set.
305         */
306        public void setByeRequested(boolean isByeRequested) {
307                getOwnSource().byeRequested = isByeRequested;
308        }
309 
310        /**
311         * Sets the m_ RTCP handler.
312         * 
313         * @param handler
314         *            The m_RTCPHandler to set.
315         */
316        public void setM_RTCPHandler(RTCPThreadHandler handler) {
317                m_RTCPHandler = handler;
318        }
319 
320        /**
321         * Sets the m_ RTP handler.
322         * 
323         * @param handler
324         *            The m_RTPHandler to set.
325         */
326        public void setM_RTPHandler(RTPThreadHandler handler) {
327                m_RTPHandler = handler;
328        }
329 
330        /**
331         * Sends an RTP Packet.
332         * 
333         * @param length
334         *            the length
335         * @param data
336         *            The RTP payload.
337         * @throws PacketGenerateException 
338         */
339        public void sendRTPPacket(byte[] data, int length) throws PacketGenerateException {
340                logger.fatal("sendRTPPacket");
341                sendRTPPacket(data, length, false);
342        }
343 
344        /**
345         * Sends an RTP Packet.
346         * 
347         * @param marker
348         *            the marker
349         * @param length
350         *            the length
351         * @param data
352         *            The RTP payload.
353         * @throws PacketGenerateException 
354         */
355        public void sendRTPPacket(byte[] data, int length, boolean marker) throws PacketGenerateException {
356                logger.debug("sendRTPPacket + marker:"+marker);
357                if (m_RTPHandler != null) {
358                        m_RTPHandler.sendPacket(data, length, marker);
359                } else {
360                        logger.error("ERROR: Cannot send RTP data if RTPHandler not instantiated.");
361                }
362        }
363 
364        /**
365         * Starts the threads. Starts the RTCP sender and receiver threads and the
366         * RTP receiver thread. This function calls the thread startup functions
367         * which could also be called manually if needed. This function is an
368         * alternative for calling the following StartRTCPSenderThread();
369         * StartRTCPReceiverThread(); StartRTPReceiverThread();
370         * 
371         * @see Session3550#StartRTCPSenderThread
372         * @see Session3550#StartRTCPReceiverThread
373         * @see Session3550#StartRTPReceiverThread
374         */
375        public void startSession() {
376                running  = true;
377                onInit(ownSource);
378                // RTCP
379                m_RTCPHandler.startRTCPReceiverThread();
380                m_RTCPHandler.startRTCPSenderThread();
381                // RTP
382                startRTPReceiverThread();
383        }
384 
385        /**
386         * Vraci casovou konstantu T, ktere je odvozeno od deterministickeho Td. T
387         * reprezentuje cas, kdy ma nastat vyslani RTCP packetu.
388         * 
389         * @return nondeterministic time interval
390         */
391        protected double computeInterval() {
392 
393                double rtcp_bw = this.rtcp_bw;
394                /*
395                 * Minimum average time between RTCP packets from this site (in mili
396                 * seconds). This time prevents the reports from `clumping' when
397                 * sessions are small and the law of large numbers isn't helping to
398                 * smooth out the traffic. It also keeps the report interval from
399                 * becoming ridiculously small during transient outages like a network
400                 * partition.
401                 */
402                final double RTCP_MIN_TIME = 5000; // 5000 mSec = 5 seconds
403                /*
404                 * Fraction of the RTCP bandwidth to be shared among active senders.
405                 * (This fraction was chosen so that in a typical session with one or
406                 * two active senders, the computed report time would be roughly equal
407                 * to the minimum report time so that we don't unnecessarily slow down
408                 * receiver reports.) The receiver fraction must be 1 - the sender
409                 * fraction.
410                 */
411                final double RTCP_SENDER_BW_FRACTION = 0.25;
412                final double RTCP_RCVR_BW_FRACTION = (1 - RTCP_SENDER_BW_FRACTION);
413                /*
414                 * /* To compensate for "timer reconsideration" converging to a value
415                 * below the intended average.
416                 */
417                final double COMPENSATION = 2.71828 - 1.5;
418                // final double COMPENSATION = 2718.28 - 1500.0;
419 
420                double t; /* interval */
421                double rtcp_min_time = RTCP_MIN_TIME;
422                int n; /* no. of members for computation */
423 
424                /*
425                 * Very first call at application start-up uses half the min delay for
426                 * quicker notification while still allowing some time before reporting
427                 * for randomization and to learn about other sources so the report
428                 * interval will converge to the correct interval more quickly.
429                 */
430                if (this.initial) {
431                        rtcp_min_time /= 2;
432                }
433                /*
434                 * Dedicate a fraction of the RTCP bandwidth to senders unless the
435                 * number of senders is large enough that their share is more than that
436                 * fraction.
437                 */
438                int senders = getSendersCount();
439                members = getMembersCount();
440                n = getMembersCount();
441                if (senders <= members * RTCP_SENDER_BW_FRACTION) {
442                        if (this.isActiveSender()) {
443                                rtcp_bw *= RTCP_SENDER_BW_FRACTION;
444                                n = senders;
445                        } else {
446                                rtcp_bw *= RTCP_RCVR_BW_FRACTION;
447                                n -= senders;
448                        }
449                }
450 
451                /*
452                 * The effective number of sites times the average packet size is the
453                 * total number of octets sent when each site sends a report. Dividing
454                 * this by the effective bandwidth gives the time interval over which
455                 * those packets must be sent in order to meet the bandwidth target,
456                 * with a minimum enforced. In that time interval we send one report so
457                 * this time is also our average time between reports.
458                 */
459                t = avg_rtcp_size * n / rtcp_bw;
460                if (t < rtcp_min_time)
461                        t = rtcp_min_time;
462 
463                this.T = (long) (t / COMPENSATION);
464                /*
465                 * To avoid traffic bursts from unintended synchronization with other
466                 * sites, we then pick our actual next report interval as a random
467                 * number uniformly distributed between 0.5*t and 1.5*t.
468                 */
469                t = t * (RandomUtils.nextDouble() + 0.5);
470                t = t / COMPENSATION;
471 
472                if (ConfigDebug.RTCP_GENERATOR_INTERVAL) {
473                        System.out.println("###################################");
474                        System.out.println("## isSender:" + this.isActiveSender());
475                        System.out.println("## rtcp_bw:" + rtcp_bw);
476                        System.out.println("## SESSION:" + this);
477                        System.out.println("## initial:" + initial);
478                        System.out.println("## invalids:" + getInvalidCount());
479                        System.out.println("## members:" + members);
480                        System.out.println("## senders:" + senders);
481                        System.out.println("## AVG_RTCP_SIZE:" + avg_rtcp_size);
482                        System.out.println("## INTERVAL (DETERMIN): "
483                                        + ConfigDebug.toString(T) + " miliSec");
484                        System.out.println("## INTERVAL (NONDETER): "
485                                        + ConfigDebug.toString(t) + " miliSec");
486                        System.out.println("###################################");
487                }
488                return t;
489        }
490 
491        /**
492         * Update average packet length.
493         * 
494         * @param length
495         *            the length of RTP packet (IP and UDP header is added).
496         */
497        public void updateAvgPktLength(int length) {
498                double last = avg_rtcp_size;
499                // IPv4
500                length += Constants.IP_UDP_HEADER_SIZE;
501                avg_rtcp_size = ((1d / 16d) * length) + (15d / 16d) * (avg_rtcp_size);
502                logger.info("Updating AVRG packet length, Prev.Length:" + last
503                                + " NewLength:" + avg_rtcp_size + " PacketLength:" + (length));
504        }
505 
506        /**
507         * Stops the session and terminates the RTCP sending loop by forcing a bye
508         * packet.
509         * 
510         * @see Session3550#StopRTCPSenderThread
511         */
512        public void stopSession() {
513                // RTCP
514                m_RTCPHandler.stopThreads();
515                // RTP sender
516                m_RTPHandler.stopThread();
517        }
518 
519        /**
520         * Gets the own source.
521         * 
522         * @return the own source
523         */
524        public Source getOwnSource() {
525                return ownSource;
526        }
527 
528        /**
529         * Gets the SSRC.
530         * 
531         * @return the SSRC
532         */
533        public long getSSRC() {
534                return getOwnSource().getSSRC();
535        }
536 
537        /**
538         * Expire sender.
539         */
540        public synchronized void expireSender() {
541                expireSender(getOwnSource().getSSRC());
542        }
543 
544        /**
545         * Checks if is active sender.
546         * 
547         * @return true, if is active sender
548         */
549        public synchronized boolean isActiveSender() {
550                return getOwnSource().isSender();
551        }
552 
553        /**
554         * Sets the CNAME.
555         * 
556         * @param str
557         *            the CNAME
558         */
559        public void setCNAME(String str) {
560                getOwnSource().CNAME = str;
561        }
562 
563        /**
564         * Sets the EMAIL.
565         * 
566         * @param str
567         *            the EMAIL
568         */
569        public void setEMAIL(String str) {
570                getOwnSource().EMAIL = str;
571        }
572 
573        /**
574         * Gets the CNAME.
575         * 
576         * @return the CNAME
577         */
578        public String getCNAME() {
579                return getOwnSource().CNAME;
580        }
581 
582        /**
583         * Gets the EMAIL.
584         * 
585         * @return the EMAIL
586         */
587        public String getEMAIL() {
588                return getOwnSource().EMAIL;
589        }
590 
591        /**
592         * Gets the m_ RTP handler.
593         * 
594         * @return the m_ RTP handler
595         */
596        public RTPThreadHandler getM_RTPHandler() {
597                return m_RTPHandler;
598        }
599 
600        /**
601         * Check for expired members.
602         */
603        protected synchronized void refresh() {
604 
605                long curTime = System.currentTimeMillis();
606                // OWN SOURCE !!!
607                Source src = getOwnSource();
608                // long Tnext = (long) this.tp + 2 * this.T;
609                if (src.timeOfLastRTPSent + 2 * T < curTime) {
610                        if (src.isSender()) {
611                                logger.info("EXPIRED OWN SENDER SSRC:" + src.ssrc);
612                                expireSender(src.ssrc);
613                                src.setSender(false);
614                                onExpireSender(src);
615 
616                        }
617                } else {
618                        // last sent -> check if it is sender already
619 
620                        if (!src.isSender()) {
621                                logger.info("OWN SSRC is SENDER:" + src.ssrc);
622 
623                                addSender(src.ssrc, 0);
624                                src.setSender(true);
625                                onNewSender(src);
626                        }
627                }
628 
629                // FOREIGN SOURCES
630                Enumeration<Source> senders = sendersMap.elements();
631                while (senders.hasMoreElements()) {
632                        src = senders.nextElement();
633                        if (src.ssrc != getSSRC()) {
634                                src.refreshSender();
635                                // not validate own source
636                                if (src.ssrc != getOwnSource().ssrc) {
637                                        // has member expired from senders?
638                                        if (src.timeOfLastRTPArrival + 2 * this.T < curTime) {
639 
640                                                logger.info("EXPIRED SENDER SSRC:" + src.ssrc);
641 
642                                                src.setSender(false);
643                                                expireSender(src.ssrc);
644                                                onExpireSender(src);
645                                        }
646                                }
647                        }
648                }
649 
650                // checks for expired members
651                Enumeration<Source> members = membersMap.elements();
652                while (members.hasMoreElements()) {
653                        src = members.nextElement();
654                        // not validate own source
655                        if (src.ssrc != getOwnSource().ssrc) {
656                                // has member expired from members?
657                                if (src.timeOfLastRTCPArrival + 5 * this.T < curTime
658                                                && src.timeOfLastRTPArrival + 5 * this.T < curTime) {
659 
660                                        // For expiration of invalid member need to set current time
661                                        // as
662                                        // the last echo from this source
663                                        src.timeOfLastRTPArrival = System.currentTimeMillis();
664 
665                                        logger.info("EXPIRED MEMBER SSRC:" + src.ssrc);
666                                        expireMember(src.ssrc);
667                                        onExpireMember(src);
668                                }
669                        }
670                }
671                // check for expired invalids
672                Enumeration<Source> invalids = invalidMap.elements();
673                while (invalids.hasMoreElements()) {
674                        src = invalids.nextElement();
675                        // not validate own source
676                        if (src.ssrc != getOwnSource().ssrc) {
677                                // has member expired from senders?
678                                if (src.timeOfLastRTPArrival + 2 * this.T < curTime
679                                                && src.timeOfLastRTCPArrival + 2 * this.T < curTime) {
680                                        // 2T elapsed from last echo
681                                        if (ConfigDebug.MEMBERS_TABLE_ACTIONS) {
682                                                logger.info("EXPIRED INVALID SSRC:" + src.ssrc);
683                                        }
684                                        expireInvalid(src.ssrc);
685                                        onExpireInvalid(src);
686 
687                                        // BYErequested will be also removed
688 
689                                }
690                        }
691                }
692                logger.debug(printMembersInfo());
693        }
694 
695        /**
696         * Removes all senders and all members. Removes all members excepts own.
697         */
698        public synchronized void removeAllMembers() {
699                // store
700                Source src = getOwnSource();
701 
702                sendersMap.clear();
703                membersMap.clear();
704                invalidMap.clear();
705 
706                // reinsert own source
707                membersMap.put(Long.valueOf(src.ssrc), src);
708        }
709 
710        /**
711         * according to rfc3550, 6.4.7 prepares session to transmit RTCP compound
712         * packet
713         */
714        public void prepareForByeTransmit(int compoundPacketLength) {
715                Source src = getOwnSource();
716 
717                tp = tc = System.currentTimeMillis();
718                pmembers = 1;
719                // delete each members senders or invalids (members = 1)
720                removeAllMembers(); // except own src
721                // senders = 0;
722                sendersMap.clear();
723                initial = true;
724                // not sender
725                src.timeOfLastRTPArrival = 0;
726                src.setSender(false);
727 
728                // size of compound BYE packet
729                avg_rtcp_size = compoundPacketLength;
730        }
731 
732        /*
733         * (non-Javadoc)
734         * 
735         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onBYEReceive(cz.vutbr.feec.utko.rtp.packets.ByePacket)
736         */
737        public void onBYEReceive(ByePacket packet) {
738                for (int i = 0; i < packet.getSSRCCount(); ++i) {
739                        // if sending BYE there is probability a packet will arrive
740                        // so if no SSRC exists, it will be created
741                        Source src = getMemberOrCreateMember(packet.getSSRC(i));
742                        src.byeRequested = true;
743                }
744 
745                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
746                                .iterator(); iterator.hasNext();) {
747                        PacketSentOrRetreiveListener name = iterator.next();
748                        name.onBYEReceive(packet);
749                }
750                
751        }
752 
753        /*
754         * (non-Javadoc)
755         * 
756         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onBYESent(cz.vutbr.feec.utko.rtp.packets.ByePacket)
757         */
758        public void onBYESent(ByePacket packet) {
759 
760                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
761                                .iterator(); iterator.hasNext();) {
762                        PacketSentOrRetreiveListener name = iterator.next();
763                        name.onBYESent(packet);
764                }
765        }
766 
767        /*
768         * (non-Javadoc)
769         * 
770         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onRRReceive(cz.vutbr.feec.utko.rtp.packets.RTCPReceiverReportPacket)
771         */
772        public void onRRReceive(ReportPacket packet) {
773                onReportReceived(packet);
774 
775                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
776                                .iterator(); iterator.hasNext();) {
777                        PacketSentOrRetreiveListener name = iterator.next();
778                        name.onRRReceive(packet);
779                }
780        }
781 
782        /*
783         * (non-Javadoc)
784         * 
785         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onRRSent(cz.vutbr.feec.utko.rtp.packets.RTCPReceiverReportPacket)
786         */
787        public void onRRSent(ReportPacket packet) {
788                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
789                                .iterator(); iterator.hasNext();) {
790                        PacketSentOrRetreiveListener name = iterator.next();
791                        name.onRRSent(packet);
792                }
793        }
794 
795        /*
796         * (non-Javadoc)
797         * 
798         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onRTPReceive(cz.vutbr.feec.utko.rtp.packets.RTPPacket)
799         */
800        public void onRTPReceive(RTPPacket packet) {
801                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
802                                .iterator(); iterator.hasNext();) {
803                        PacketSentOrRetreiveListener name = iterator.next();
804                        name.onRTPReceive(packet);
805                }
806        }
807 
808        /*
809         * (non-Javadoc)
810         * 
811         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onRTPSent(cz.vutbr.feec.utko.rtp.packets.RTPPacket)
812         */
813        public void onRTPSent(RTPPacket packet) {
814                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
815                                .iterator(); iterator.hasNext();) {
816                        PacketSentOrRetreiveListener name = iterator.next();
817                        name.onRTPSent(packet);
818                }
819        }
820 
821        /*
822         * (non-Javadoc)
823         * 
824         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onSDESReceive(cz.vutbr.feec.utko.rtp.packets.SDESPacket)
825         */
826        public void onSDESReceive(SDESPacket packet) {
827                for (int i = 0; i < packet.getChunkCount(); ++i) {
828                        SDESChunk chunk = packet.getChunkBlock(i);
829 
830                        // Validated on SR or RR packet
831                        Source src = getMemberOrInvalid(chunk.getSSRC_CSRC());
832 
833                        for (int j = 0; j < chunk.getNumberofItems(); ++j) {
834                                SDESItem item = chunk.getItem(j);
835                                switch (item.getType()) {
836                                case SDESItem.CNAME:
837                                        // Validated on RR/SR received
838                                        src.CNAME = item.getText();
839                                        break;
840                                case SDESItem.EMAIL:
841                                        src.EMAIL = item.getText();
842                                        break;
843                                case SDESItem.LOC:
844                                        src.LOC = item.getText();
845                                        break;
846                                case SDESItem.NAME:
847                                        src.NAME = item.getText();
848                                        break;
849                                case SDESItem.NOTE:
850                                        src.NOTE = item.getText();
851                                        break;
852                                case SDESItem.PHONE:
853                                        src.PRIV = item.getText();
854                                        break;
855                                case SDESItem.PRIV:
856                                        src.PRIV = item.getText();
857                                        break;
858                                case SDESItem.TOOL:
859                                        src.TOOL = item.getText();
860                                        break;
861                                default:
862                                        break;
863                                }
864                        }
865                }
866 
867                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
868                                .iterator(); iterator.hasNext();) {
869                        PacketSentOrRetreiveListener name = iterator.next();
870                        name.onSDESReceive(packet);
871                }
872        }
873 
874        /*
875         * (non-Javadoc)
876         * 
877         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onSDESSent(cz.vutbr.feec.utko.rtp.packets.SDESPacket)
878         */
879        public void onSDESSent(SDESPacket packet) {
880 
881                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
882                                .iterator(); iterator.hasNext();) {
883                        PacketSentOrRetreiveListener name = iterator.next();
884                        name.onSDESSent(packet);
885                }
886        }
887 
888        /**
889         * On report received.
890         * 
891         * @param packet
892         *            the packet
893         */
894        public synchronized void onReportReceived(GeneralRTCPHeader packet) {
895                Source src;
896                if (!existMember(packet.getSSRC())) {
897                        src = getMemberOrCreateMember(packet.getSSRC());
898                        validate(packet.getSSRC());
899                        onValidated(src);
900                }
901                src = getMember(packet.getSSRC());
902                src.timeOfLastRTCPArrival = System.currentTimeMillis();
903        }
904 
905        /*
906         * (non-Javadoc)
907         * 
908         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onSRReceive(cz.vutbr.feec.utko.rtp.packets.RTCPSenderReportPacket)
909         */
910        public void onSRReceive(SenderReportPacket packet) {
911                onReportReceived(packet);
912                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
913                                .iterator(); iterator.hasNext();) {
914                        PacketSentOrRetreiveListener name = iterator.next();
915                        name.onSRReceive(packet);
916                }
917        }
918 
919        /*
920         * (non-Javadoc)
921         * 
922         * @see cz.vutbr.feec.utko.iptv.net.rtp.PacketSentOrRetreiveListener#onSRSent(cz.vutbr.feec.utko.rtp.packets.RTCPSenderReportPacket)
923         */
924        public void onSRSent(SenderReportPacket packet) {
925                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
926                                .iterator(); iterator.hasNext();) {
927                        PacketSentOrRetreiveListener name = iterator.next();
928                        name.onSRSent(packet);
929                }
930        }
931 
932        /*
933         * (non-Javadoc)
934         * 
935         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onExpireInvalid(cz.vutbr.feec.utko.iptv.net.rtp.Source)
936         */
937        public void onExpireInvalid(Source src) {
938                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
939                                .iterator(); iterator.hasNext();) {
940                        MemberTableChangeListener name = iterator.next();
941                        name.onExpireInvalid(src);
942                }
943 
944        }
945 
946        /*
947         * (non-Javadoc)
948         * 
949         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onExpireMember(cz.vutbr.feec.utko.iptv.net.rtp.Source)
950         */
951        public void onExpireMember(Source src) {
952                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
953                                .iterator(); iterator.hasNext();) {
954                        MemberTableChangeListener name = iterator.next();
955                        name.onExpireMember(src);
956                }
957        }
958 
959        /*
960         * (non-Javadoc)
961         * 
962         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onExpireSender(cz.vutbr.feec.utko.iptv.net.rtp.Source)
963         */
964        public void onExpireSender(Source src) {
965                src.probation = Source.MIN_SEQUENTIAL;
966                src.setSender(false);
967 
968                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
969                                .iterator(); iterator.hasNext();) {
970                        MemberTableChangeListener name = iterator.next();
971                        name.onExpireSender(src);
972                }
973        }
974 
975        /*
976         * (non-Javadoc)
977         * 
978         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onNewInvalid(cz.vutbr.feec.utko.iptv.net.rtp.Source)
979         */
980        public void onNewInvalid(Source src) {
981                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
982                                .iterator(); iterator.hasNext();) {
983                        MemberTableChangeListener name = iterator.next();
984                        name.onNewInvalid(src);
985                }
986        }
987 
988        /*
989         * (non-Javadoc)
990         * 
991         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onNewSender(cz.vutbr.feec.utko.iptv.net.rtp.Source)
992         */
993        public void onNewSender(Source src) {
994                src.setSender(true);
995                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
996                                .iterator(); iterator.hasNext();) {
997                        MemberTableChangeListener name = iterator.next();
998                        name.onNewSender(src);
999                }
1000        }
1001 
1002        /*
1003         * (non-Javadoc)
1004         * 
1005         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onValidated(cz.vutbr.feec.utko.iptv.net.rtp.Source)
1006         */
1007        public void onValidated(Source src) {
1008                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
1009                                .iterator(); iterator.hasNext();) {
1010                        MemberTableChangeListener name = iterator.next();
1011                        name.onValidated(src);
1012                }
1013        }
1014 
1015        /*
1016         * (non-Javadoc)
1017         * 
1018         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onSchedule(double,
1019         *      cz.vutbr.feec.utko.iptv.net.rtp.Session3550)
1020         */
1021        public void onSchedule(double delay, Session3550 session) {
1022                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
1023                                .iterator(); iterator.hasNext();) {
1024                        MemberTableChangeListener name = iterator.next();
1025                        name.onSchedule(delay, session);
1026                }
1027        }
1028 
1029        /*
1030         * (non-Javadoc)
1031         * 
1032         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onInit(cz.vutbr.feec.utko.iptv.net.rtp.Source)
1033         */
1034        public void onInit(Source src) {
1035                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
1036                                .iterator(); iterator.hasNext();) {
1037                        MemberTableChangeListener name = iterator.next();
1038                        name.onInit(src);
1039                }
1040        }
1041 
1042        /*
1043         * (non-Javadoc)
1044         * 
1045         * @see cz.vutbr.feec.utko.iptv.net.rtp.MemberTableChangeListener#onBye()
1046         */
1047        public void onBye() {
1048                for (Iterator<MemberTableChangeListener> iterator = memberTableChangeListeners
1049                                .iterator(); iterator.hasNext();) {
1050                        MemberTableChangeListener name = iterator.next();
1051                        name.onBye();
1052                }
1053        }
1054 
1055        public void onRSIReceive(RSIPacket packet) {
1056                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
1057                                .iterator(); iterator.hasNext();) {
1058                        PacketSentOrRetreiveListener name = iterator.next();
1059                        name.onRSIReceive(packet);
1060                }
1061        }
1062 
1063        public void onRSISent(RSIPacket packet) {
1064                for (Iterator<PacketSentOrRetreiveListener> iterator = packetSentOrRetreiveListeners
1065                                .iterator(); iterator.hasNext();) {
1066                        PacketSentOrRetreiveListener name = iterator.next();
1067                        name.onRSISent(packet);
1068                }
1069        }
1070 
1071        /** The Constant multicastType_SSM. */
1072        public final static String multicastType_SSM = "SSM";
1073 
1074        /** The Constant multicastType_ASM. */
1075        public final static String multicastType_ASM = "ASM";
1076 
1077        /** The multicast type. */
1078        public String multicastType = multicastType_ASM;
1079 
1080        /**
1081         * Checks is a sender.
1082         * 
1083         * @return true, if is created as sender
1084         */
1085        public boolean isSender() {
1086                return sessionType.equals(SessionType.SENDER);
1087        }
1088        /**
1089         * Checks if member is a receiver.
1090         * 
1091         * @return true, if is a receiver
1092         */
1093        public boolean isReceiver() {
1094                return sessionType.equals(SessionType.RECEIVER);
1095        }
1096        /**
1097         * Checks if member is s feedback target.
1098         * 
1099         * @return true, if is feedback target
1100         */
1101        public boolean isFeedbackTarget() {
1102                return sessionType.equals(SessionType.FEEDBACK_TARGET);
1103        }
1104 
1105        /**
1106         * Checks if is SSM.
1107         * 
1108         * @return true, if is SSM
1109         */
1110        public boolean isSSM() {
1111                return isSSM;
1112        }
1113 
1114        /**
1115         * Sets the member table change listener.
1116         * 
1117         * @param memberTableChangeListener
1118         *            the member table change listener
1119         */
1120        public void addMemberTableChangeListener(
1121                        MemberTableChangeListener memberTableChangeListener) {
1122                this.memberTableChangeListeners.add(memberTableChangeListener);
1123        }
1124 
1125        /**
1126         * For idetification of threads (e.g. AUDIO or VIDEO)
1127         * 
1128         * @return
1129         */
1130        public String getName() {
1131                return name;
1132        }
1133 
1134        /**
1135         * For idetification of threads (e.g. AUDIO or VIDEO)
1136         * 
1137         * @param name
1138         */
1139        public void setName(String name) {
1140                this.name = name;
1141        }
1142 
1143        public boolean isByeSent() {
1144                return byeSent;
1145        }
1146 
1147        public void setByeSent(boolean byeSent) {
1148                this.byeSent = byeSent;
1149        }
1150 
1151        @Override
1152        public boolean isRunning() {
1153                return running;
1154        }
1155}

[all classes][cz.vutbr.feec.session.rtprtcp.internal]
EMMA 2.0.5312 EclEmma Fix 1 (C) Vladimir Roubtsov