root/vic/branches/cc/rtp/session.cpp @ 4260

Revision 4260, 34.6 KB (checked in by soohyunc, 6 years ago)

o XR header modified (simplified than before for the simplicity).

o fixed some header leength calculation part.

o basic control loop works, but due to the header length calculation problem,

the conveyed information over RTCP XR seems to be corrupted (or incorrect).
for example, the seqno and/or timestamp from the data sender does not reach
to the data receiver through XR channel correctly.

o first, we need to see "send_xreport()" method and check if XR packet length

was calculated (or assigned) correctly.

o second, we may need to change "parse_xr_records()" method such that when we

send the XR report back to the data sender, it needs to send the whole RTCP
packet (i.e., including RTCP packet header). However, current implementatiaon
does not include the RTCP hearder. maybe, this is the reason why the
information conveyed through RTCP XR is displayed incorrectly on console.

To-do:
(1) resolve the two issues above.
(2) TfwcSndr? still cannot handle if multiple packets passed to it from

Transmitter module.

(3) main TFWC algorithm still missing (once, the XR control loop works, it

would be just a matter of time to imeplement it.)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*-
2 * Copyright (c) 1993-1994 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *      This product includes software developed by the University of
16 *      California, Berkeley and the Network Research Group at
17 *      Lawrence Berkeley Laboratory.
18 * 4. Neither the name of the University nor of the Laboratory may be used
19 *    to endorse or promote products derived from this software without
20 *    specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * $Id$
35 */
36static const char rcsid[] =
37    "@(#) $Header$ (LBL)";
38
39#include "config.h"
40#include <math.h>
41#include <errno.h>
42#include <string.h>
43#ifdef WIN32
44extern "C" int getpid();
45#endif
46#include "source.h"
47#include "vic_tcl.h"
48#include "media-timer.h"
49#include "crypt.h"
50#include "timer.h"
51#include "ntp-time.h"
52#include "session.h"
53#include "cc/tfwc_sndr.h"
54#include "cc/tfwc_rcvr.h"
55
56/* added to support the mbus
57#include "mbus_handler.h"*/
58
59
60static class SessionMatcher : public Matcher {
61    public:
62                SessionMatcher() : Matcher("session") {}
63                TclObject* match(const char* id) {
64                        if (strcmp(id, "audio/rtp") == 0)
65                                return (new AudioSessionManager);
66                        else if (strcmp(id, "video/rtp") == 0)
67                                return (new VideoSessionManager);
68                        return (0);
69                }
70} session_matcher;
71
72int VideoSessionManager::check_format(int fmt) const
73{
74        switch(fmt) {
75                case RTP_PT_RAW:
76                case RTP_PT_CELLB:
77                case RTP_PT_JPEG:
78                case RTP_PT_CUSEEME:
79                case RTP_PT_NV:
80                case RTP_PT_CPV:
81                case RTP_PT_H261:
82                case RTP_PT_BVC:
83                case RTP_PT_H261_COMPAT:/*XXX*/
84                case RTP_PT_H263:
85                case RTP_PT_MPEG4:
86                case RTP_PT_H264:
87                case RTP_PT_H263P:
88                case RTP_PT_LDCT:
89                case RTP_PT_PVH:
90                case RTP_PT_DV:
91#ifdef USE_H261AS
92                case RTP_PT_H261AS:
93#endif 
94                return (1);
95        }
96        return (0);
97}
98
99int AudioSessionManager::check_format(int fmt) const
100{
101        switch (fmt) {
102        case RTP_PT_PCMU:
103        case RTP_PT_CELP:
104        case RTP_PT_GSM:
105        case RTP_PT_DVI:
106        case RTP_PT_LPC:
107                return (1);
108        }
109        return (0);
110}
111
112
113static SessionManager* manager;
114
115void
116adios()
117{
118        if (SourceManager::instance().localsrc() != 0)
119                manager->send_bye();
120        exit(0);
121}
122
123/*void ReportTimer::timeout()
124{
125sm_.send_report();
126}*/
127
128void DataHandler::dispatch(int)
129{
130        sm_->recv(this);
131}
132
133void CtrlHandler::dispatch(int)
134{
135        sm_->recv(this);
136}
137
138CtrlHandler::CtrlHandler()
139: ctrl_inv_bw_(0.),
140ctrl_avg_size_(128.),
141rint_(0.0) //SV-XXX: Debian
142{
143}
144
145inline void CtrlHandler::schedule_timer()
146{
147        msched(int(fmod(double(random()), rint_) + rint_ * .5 + .5));
148}
149
150void CtrlHandler::net(Network* n)
151{
152        DataHandler::net(n);
153        cancel();
154        if (n != 0) {
155        /*
156        * schedule a timer for our first report using half the
157        * min ctrl interval.  This gives us some time before
158        * our first report to learn about other sources so our
159        * next report interval will account for them.  The avg
160        * ctrl size was initialized to 128 bytes which is
161        * conservative (it assumes everyone else is generating
162        * SRs instead of RRs).
163                */
164                double rint = ctrl_avg_size_ * ctrl_inv_bw_;
165                if (rint < CTRL_MIN_RPT_TIME / 2. * 1000.)
166                        rint = CTRL_MIN_RPT_TIME / 2. * 1000.;
167                rint_ = rint;
168                schedule_timer();
169        }
170}
171
172void CtrlHandler::sample_size(int cc)
173{
174        ctrl_avg_size_ += CTRL_SIZE_GAIN * (double(cc + 28) - ctrl_avg_size_);
175}
176
177void CtrlHandler::adapt(int nsrc, int nrr, int we_sent)
178{
179/*
180* compute the time to the next report.  we do this here
181* because we need to know if there were any active sources
182* during the last report period (nrr above) & if we were
183* a source.  The bandwidth limit for ctrl traffic was set
184* on startup from the session bandwidth.  It is the inverse
185* of bandwidth (ie., ms/byte) to avoid a divide below.
186        */
187        double ibw = ctrl_inv_bw_;
188        if (nrr) {
189                /* there were active sources */
190                if (we_sent) {
191                        ibw *= 1./CTRL_SENDER_BW_FRACTION;
192                        nsrc = nrr;
193                } else {
194                        ibw *= 1./CTRL_RECEIVER_BW_FRACTION;
195                        nsrc -= nrr;
196                }
197        }
198        double rint = ctrl_avg_size_ * double(nsrc) * ibw;
199        if (rint < CTRL_MIN_RPT_TIME * 1000.)
200                rint = CTRL_MIN_RPT_TIME * 1000.;
201        rint_ = rint;
202}
203
204void CtrlHandler::timeout()
205{
206        sm_->announce(this);
207        schedule_timer();
208}
209
210//SV-XXX: rearranged initialization order to shut up gcc4
211SessionManager::SessionManager()
212//      : dh_(*this), ch_(*this), rt_(*this),
213: mb_(mbus_handler_engine, NULL),
214lipSyncEnabled_(0),
215badversion_(0),
216badoptions_(0),
217badfmt_(0),
218badext_(0),
219nrunt_(0),
220last_np_(0),
221sdes_seq_(0),
222rtcp_inv_bw_(0.),
223rtcp_avg_size_(128.),
224confid_(-1),
225seqno_(0),              // RTP packet sequence number (from RTP header)
226lastseq_(0),    // last received packet's seqno
227ackvec_(0)              // bit vector (AckVec)
228{
229        /*XXX For adios() to send bye*/
230        manager = this;
231       
232        for (int i = 0; i < NLAYER; ++i) {
233                dh_[i].manager(this);
234                ch_[i].manager(this);
235        }
236       
237        /*XXX*/
238        pktbuf_ = new u_char[2 * RTP_MTU];
239        pool_ = new BufferPool;
240       
241        /*
242        * schedule a timer for our first report using half the
243        * min rtcp interval.  This gives us some time before
244        * our first report to learn about other sources so our
245        * next report interval will account for them.  The avg
246        * rtcp size was initialized to 128 bytes which is
247        * conservative (it assumes everyone else is generating
248        * SRs instead of RRs).
249        */
250        double rint = rtcp_avg_size_ * rtcp_inv_bw_;
251        if (rint < RTCP_MIN_RPT_TIME / 2. * 1000.)
252                rint = RTCP_MIN_RPT_TIME / 2. * 1000.;
253        rint_ = rint;
254        //rt_.msched(int(fmod(double(random()), rint) + rint * .5 + .5));
255}
256
257SessionManager::~SessionManager()
258{
259        if (pktbuf_)
260                delete[] pktbuf_;
261       
262        delete pool_;
263}
264
265u_int32_t SessionManager::alloc_srcid(Address & addr) const
266{
267        timeval tv;
268        ::gettimeofday(&tv, 0);
269        u_int32_t srcid = u_int32_t(tv.tv_sec + tv.tv_usec);
270        srcid += (u_int32_t)getuid();
271        srcid += (u_int32_t)getpid();
272/* __IPv6 changed srcid computation */
273        for(unsigned int i = 0; i < (addr.length() % sizeof(u_int32_t)); i++) {
274                srcid += ((u_int32_t*)((const void*)addr))[i];
275        }
276        return (srcid);
277}
278
279extern char* onestat(char* cp, const char* name, u_long v);
280
281char* SessionManager::stats(char* cp) const
282{
283        cp = onestat(cp, "Bad-RTP-version", badversion_);
284        cp = onestat(cp, "Bad-RTPv1-options", badoptions_);
285        cp = onestat(cp, "Bad-Payload-Format", badfmt_);
286        cp = onestat(cp, "Bad-RTP-Extension", badext_);
287        cp = onestat(cp, "Runts", nrunt_);
288        Crypt* p = dh_[0].net()->crypt();
289        if (p != 0) {
290                cp = onestat(cp, "Crypt-Bad-Length", p->badpktlen());
291                cp = onestat(cp, "Crypt-Bad-P-Bit", p->badpbit());
292        }
293        /*XXX*/
294        if (ch_[0].net() != 0) {
295                Crypt* p = ch_[0].net()->crypt();
296                if (p != 0) {
297                        cp = onestat(cp, "Crypt-Ctrl-Bad-Length", p->badpktlen());
298                        cp = onestat(cp, "Crypt-Ctrl-Bad-P-Bit", p->badpbit());
299                }
300        }
301        *--cp = 0;
302        return (cp);
303}
304
305int SessionManager::command(int argc, const char*const* argv)
306{
307        Tcl& tcl = Tcl::instance();
308        char* cp = tcl.buffer();
309        if (argc == 2) {
310                if (strcmp(argv[1], "active") == 0) {
311                        SourceManager::instance().sortactive(cp);
312                        tcl.result(cp);
313                        return (TCL_OK);
314                }
315                if (strcmp(argv[1], "local-addr-heuristic") == 0) {
316                        strcpy(cp, intoa(LookupLocalAddr()));
317                        tcl.result(cp);
318                        return (TCL_OK);
319                }
320                if (strcmp(argv[1], "stats") == 0) {
321                        stats(cp);
322                        tcl.result(cp);
323                        return (TCL_OK);
324                }
325                if (strcmp(argv[1], "nb") == 0) {
326                        sprintf(cp, "%u", 8 * nb_);
327                        tcl.result(cp);
328                        return (TCL_OK);
329                }
330                if (strcmp(argv[1], "nf") == 0) {
331                        sprintf(cp, "%u", nf_);
332                        tcl.result(cp);
333                        return (TCL_OK);
334                }
335                if (strcmp(argv[1], "np") == 0 ||
336                    strcmp(argv[1], "ns") == 0) {
337                        sprintf(cp, "%u", np_);
338                        tcl.result(cp);
339                        return (TCL_OK);
340                }
341                if (strcmp(argv[1], "lip-sync") == 0) {
342                        sprintf(cp, "%u", lipSyncEnabled_);
343                        tcl.result(cp);
344                        return (TCL_OK);
345                }
346
347        } else if (argc == 3) {
348                if (strcmp(argv[1], "sm") == 0) {
349                        sm_ = (SourceManager*)TclObject::lookup(argv[2]);
350                        return (TCL_OK);
351                }
352                if (strcmp(argv[1], "name") == 0) {
353                        Source* s = SourceManager::instance().localsrc();
354                        s->sdes(RTCP_SDES_NAME, argv[2]);
355                        return (TCL_OK);
356                }
357                if (strcmp(argv[1], "email") == 0) {
358                        Source* s = SourceManager::instance().localsrc();
359                        s->sdes(RTCP_SDES_EMAIL, argv[2]);
360                        return (TCL_OK);
361                }
362                if (strcmp(argv[1], "random-srcid") == 0) {
363                        Address * addrp;
364                        if ((addrp = (dh_[0].net())->alloc(argv[2])) !=0 ) { //SV-XXX: placed ()'s against truth check == NULL
365                          sprintf(cp, "%u", alloc_srcid(*addrp));
366                          delete addrp;
367                        }
368                        tcl.result(cp);
369                        return (TCL_OK);
370                }
371                if (strcmp(argv[1], "data-net") == 0) {
372                        dh_[0].net((Network*)TclObject::lookup(argv[2]));
373                        return (TCL_OK);
374                }
375                if (strcmp(argv[1], "ctrl-net") == 0) {
376                        ch_[0].net((Network*)TclObject::lookup(argv[2]));
377                        return (TCL_OK);
378                }
379                if (strcmp(argv[1], "max-bandwidth") == 0) {
380                        double bw = atof(argv[2]) / 8.;
381                        rtcp_inv_bw_ = 1. / (bw * RTCP_SESSION_BW_FRACTION);
382                        return (TCL_OK);
383                }
384                if (strcmp(argv[1], "confid") == 0) {
385                        confid_ = atoi(argv[2]);
386                        return (TCL_OK);
387                }
388                if (strcmp(argv[1], "data-bandwidth") == 0) {
389                        /*XXX assume value in range */
390                        bps(atoi(argv[2]));
391                        return (TCL_OK);
392                }
393                if (strcmp(argv[1], "mtu") == 0) {
394                        mtu_ = atoi(argv[2]);
395                        return (TCL_OK);
396                }
397                if (strcmp(argv[1], "loopback") == 0) {
398                        loopback_ = atoi(argv[2]);
399                        return (TCL_OK);
400                }
401                if (strcmp(argv[1], "lip-sync") == 0) {
402                        lipSyncEnabled_ = atoi(argv[2]);
403                        return (TCL_OK);
404                }
405
406        }  else if (argc == 4) {
407                if (strcmp(argv[1], "data-net") == 0) {
408                        u_int layer = atoi(argv[3]);
409                        if (layer >= NLAYER)
410                                abort();
411                        if (*argv[2] == 0) {
412                                dh_[layer].net(0);
413                                return (TCL_OK);
414                        }
415                        Network* net = (Network*)TclObject::lookup(argv[2]);
416                        if (net == 0) {
417                                tcl.resultf("no network %s", argv[2]);
418                                return (TCL_ERROR);
419                        }
420                        if (net->rchannel() < 0) {
421                                tcl.resultf("network not open");
422                                return (TCL_ERROR);
423                        }
424                        dh_[layer].net(net);
425                        return (TCL_OK);
426                }
427                if (strcmp(argv[1], "ctrl-net") == 0) {
428                        u_int layer = atoi(argv[3]);
429                        if (layer >= NLAYER)
430                                abort();
431                        if (*argv[2] == 0) {
432                                ch_[layer].net(0);
433                                return (TCL_OK);
434                        }
435                        Network* net = (Network*)TclObject::lookup(argv[2]);
436                        if (net == 0) {
437                                tcl.resultf("no network %s", argv[2]);
438                                return (TCL_ERROR);
439                        }
440                        if (net->rchannel() < 0) {
441                                tcl.resultf("network not open");
442                                return (TCL_ERROR);
443                        }
444                        ch_[layer].net(net);
445                        return (TCL_OK);
446                }
447                return (Transmitter::command(argc, argv));
448        }
449        //should not be reached
450        return (TCL_ERROR);
451}
452
453void SessionManager::transmit(pktbuf* pb)
454{
455        //mh_.msg_iov = pb->iov;
456        //      dh_[.net()->send(mh_);
457                //debug_msg("L %d,",pb->layer);
458        // Using loop_layer for now to restrict transmission as well
459        if (pb->layer < loop_layer_) {
460        //      if ( pb->layer <0 ) exit(1);
461                Network* n = dh_[pb->layer].net();
462                if (n != 0)
463                        n->send(pb);
464
465                // if CC is on, send an RTCP XR (aoa) packet
466                // upon every RTP data packet transmission.
467                if(is_cc_on()) {
468                        ch_[0].send_aoa();      // send ack of ack
469                        ch_[0].send_ts();       // send time stamp
470                }
471        }
472}
473
474// sending ack of ack packet (RTCP XR report packet)
475void CtrlHandler::send_aoa()
476{
477        sm_->build_aoa_pkt(this);
478}
479
480// sending time stamp packet (RTCP XR report packet)
481void CtrlHandler::send_ts()
482{
483        sm_->build_ts_pkt(this);
484}
485
486void SessionManager::build_aoa_pkt(CtrlHandler* ch)
487{
488        // RTCP XR (Loss RLE Report Block)
489        // (it is XR_BT_1 defined in rtp/rtp.h)
490        send_xreport(ch, XR_BT_1, 0);
491}
492
493void SessionManager::build_ts_pkt(CtrlHandler* ch)
494{
495        // RTCP XR (Packet Receipt Times Report Block)
496        // (it is XR_BT_3 defined in rtp/rtp.h)
497        send_xreport(ch, XR_BT_3, 0);
498}
499
500u_char* SessionManager::build_sdes_item(u_char* p, int code, Source& s)
501{
502        const char* value = s.sdes(code);
503        if (value != 0) {
504                int len = strlen(value);
505                *p++ = code;
506                *p++ = len;
507                memcpy(p, value, len);
508                p += len;
509        }
510        return (p);
511}
512
513int SessionManager::build_sdes(rtcphdr* rh, Source& ls)
514{
515        int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_SDES;
516        rh->rh_flags = htons(flags);
517        rh->rh_ssrc = ls.srcid();
518        u_char* p = (u_char*)(rh + 1);
519        p = build_sdes_item(p, RTCP_SDES_CNAME, ls);
520
521        /*
522         * We always send a cname plus one other sdes
523         * There's a schedule for what we send sequenced by sdes_seq_:
524         *   - send 'email' every 0th & 4th packet
525         *   - send 'note' every 2nd packet
526         *   - send 'tool' every 6th packet
527         *   - send 'name' in all the odd slots
528         * (if 'note' is not the empty string, we switch the roles
529         *  of name & note)
530         */
531        int nameslot, noteslot;
532        const char* note = ls.sdes(RTCP_SDES_NOTE);
533        if (note) {
534                if (*note) {
535                        nameslot = RTCP_SDES_NOTE;
536                        noteslot = RTCP_SDES_NAME;
537                } else {
538                        nameslot = RTCP_SDES_NAME;
539                        noteslot = RTCP_SDES_NOTE;
540                }
541        } else {
542                nameslot = RTCP_SDES_NAME;
543                noteslot = RTCP_SDES_NAME;
544        }
545        u_int seq = (++sdes_seq_) & 0x7;
546        switch (seq) {
547
548        case 0case 4:
549                p = build_sdes_item(p, RTCP_SDES_EMAIL, ls);
550                break;
551
552        case 2:
553                p = build_sdes_item(p, noteslot, ls);
554                break;
555        case 6:
556                p = build_sdes_item(p, RTCP_SDES_TOOL, ls);
557                break;
558        default:
559                p = build_sdes_item(p, nameslot, ls);
560        }
561        int len = p - (u_char*)rh;
562        int pad = 4 - (len & 3);
563        len += pad;
564        rh->rh_len = htons((len >> 2) - 1);
565        while (--pad >= 0)
566                *p++ = 0;
567
568        return (len);
569}
570
571int SessionManager::build_app(rtcphdr* rh, Source& ls, const char *name,
572                void *data, int datalen)
573{
574  int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_APP;
575  rh->rh_flags = htons(flags);
576  rh->rh_ssrc = ls.srcid();
577  u_char* p = (u_char*)(rh + 1);
578    int len;
579   
580    // write the name field
581    len = strlen(name);
582    if( len < 4 ) {
583        memcpy(p,name,len);
584        p += len;
585       
586        // pad short names
587        while( p - (u_char*)(rh+1) < 4 )
588            *p++ = 0;
589    }
590    else {
591        // use first four chars of given name
592        memcpy(p,name,4);
593        p += 4;
594    }
595   
596    // write the app data
597    memcpy(p,data,datalen);
598    p += datalen;
599   
600    // pad as needed
601    len = p - (u_char*)rh;
602    int pad = 4 - (len & 3);
603    while( --pad >= 0 )
604        *p++ = 0;
605  len = p - (u_char*)rh;
606
607    // set the length now that it's known
608  rh->rh_len = htons((len >> 2) - 1);
609
610  return (len);
611}
612
613/*void SessionManager::send_report()
614{
615        send_report(0);
616}
617
618  void SessionManager::send_bye()
619  {
620  send_report(1);
621}*/
622
623// SessionManager is no longer used as Timer - Each
624// CtrlHandler has its own Timer which calls this;
625void SessionManager::announce(CtrlHandler* ch)
626{
627        send_report(ch, 0);
628}
629
630/*
631 * Send an RTP extended report packet.
632 */
633void SessionManager::send_xreport(CtrlHandler* ch, int bt, int bye)
634{
635        UNUSED(bye);
636
637        SourceManager& sm = SourceManager::instance();
638        Source& s = *sm.localsrc();
639        rtcphdr* rh = (rtcphdr*)pktbuf_;
640        rh->rh_ssrc = s.srcid();
641        int flags = RTP_VERSION << 14;  // RTCP flags
642        int layer = ch - ch_; //LLL
643        Source::Layer& sl = s.layer(layer);
644        timeval now = unixtime();
645        sl.lts_ctrl(now);
646
647        // set RTCP flag to XR packet
648        flags |= RTCP_PT_XR;
649
650        // declare XR packet
651        rtcp_xr* xr;
652        xr = (rtcp_xr*)(rh + 1);
653
654        // ssrc of XR source (currently unused)
655        int xrssrc = 0;
656        xr->ssrc = htonl(xrssrc);       // UNUSED
657
658        // this block is used for giving seqno and ackofack
659        if(bt == XR_BT_1) {
660                // set XR block flags (block type and length)
661                xr->xr_flags = htons(XR_BT_1 << 8);
662
663                // get current RTP data packet seqno from TfwcSndr
664                xr->end_seq = htons(tfwc_sndr_get_seqno());
665
666                // get ackofack from TfwcSndr
667                xr->begin_seq = htons(tfwc_sndr_get_aoa());
668
669                debug_msg("     SeqNo:          %d\n", tfwc_sndr_get_seqno());
670        }
671        // this block is used for giving timestamp
672        else if(bt == XR_BT_3) {
673                // set XR block flags (block type and length)
674                xr->xr_flags = htons(XR_BT_3 << 8);
675
676                // get timestamp from TfwcSndr
677                xr->chunk = (u_int32_t *) htonl(tfwc_sndr_get_ts());
678
679                debug_msg("     TS:             %d\n", tfwc_sndr_get_ts());
680        }
681
682        // XR report block length
683        int xrlen = (u_char*)xr - pktbuf_;
684        xr->xr_len = htons((xrlen >> 2) - 1);
685
686        // RTCP header flags (this is not the XR header flags)
687        rh->rh_flags = htons(flags);
688
689        // RTCP packet length
690        int len = (u_char *) xr - pktbuf_;     
691        rh->rh_len = htons((len >> 2) - 1);
692
693        // send XR report block
694        ch->send(pktbuf_, len);
695}
696
697/*XXX check for buffer overflow*/
698/*
699* Send an RTPv2 report packet.
700*/
701void SessionManager::send_report(CtrlHandler* ch, int bye, int app)
702{
703        UNUSED(app); //SV-XXX: unused
704
705        SourceManager& sm = SourceManager::instance();
706        Source& s = *sm.localsrc();
707        rtcphdr* rh = (rtcphdr*)pktbuf_;
708        rh->rh_ssrc = s.srcid();
709        int flags = RTP_VERSION << 14;
710        int layer = ch - ch_; //LLL
711        Source::Layer& sl = s.layer(layer);
712        timeval now = unixtime();
713        sl.lts_ctrl(now);
714        int we_sent = 0;
715        rtcp_rr* rr;
716        Tcl& tcl = Tcl::instance();
717
718        /*
719         * If we've sent data since our last sender report send a
720         * new report.  The MediaTimer check is to make sure we still
721         * have a grabber -- if not, we won't be able to interpret the
722         * media timestamps so there's no point in sending an SR.
723         */
724        MediaTimer* mt = MediaTimer::instance();
725        if (sl.np() != last_np_ && mt) {
726                last_np_ = sl.np();
727                we_sent = 1;
728                flags |= RTCP_PT_SR;
729                rtcp_sr* sr = (rtcp_sr*)(rh + 1);
730                sr->sr_ntp = ntp64time(now);
731                HTONL(sr->sr_ntp.upper);
732                HTONL(sr->sr_ntp.lower);
733                sr->sr_ts = htonl(mt->ref_ts());
734                sr->sr_np = htonl(sl.np());
735                sr->sr_nb = htonl(sl.nb());
736                rr = (rtcp_rr*)(sr + 1);
737        } else {
738                flags |= RTCP_PT_RR;
739                rr = (rtcp_rr*)(rh + 1);
740        }
741
742        int nrr = 0;
743        int nsrc = 0;
744        /*
745        * we don't want to inflate report interval if user has set
746        * the flag that causes all sources to be 'kept' so we
747        * consider sources 'inactive' if we haven't heard a control
748        * msg from them for ~32 reporting intervals.
749        */
750        //LLL   u_int inactive = u_int(rint_ * (32./1000.));
751        u_int inactive = u_int(ch->rint() * (32./1000.));
752        if (inactive < 2)
753                inactive = 2;
754        for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) {
755                ++nsrc;
756                Source::Layer& sl = sp->layer(layer);
757                //              int received = sp->np() - sp->snp();
758                int received = sl.np() - sl.snp();
759                if (received == 0) {
760                        //              if (u_int(now.tv_sec - sp->lts_ctrl().tv_sec) > inactive)
761                        if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive)
762                                --nsrc;
763                        continue;
764                }
765                //              sp->snp(sp->np());
766                sl.snp(sl.np());
767                rr->rr_srcid = sp->srcid();
768                //              int expected = sp->ns() - sp->sns();
769                int expected = sl.ns() - sl.sns();
770                //              sp->sns(sp->ns());
771                sl.sns(sl.ns());
772                u_int32_t v;
773                int lost = expected - received;
774                if (lost <= 0)
775                        v = 0;
776                else
777                        /* expected != 0 if lost > 0 */
778                        v = ((lost << 8) / expected) << 24;
779                /* XXX should saturate on over/underflow */
780                //              v |= (sp->ns() - sp->np()) & 0xffffff;
781                v |= (sl.ns() - sl.np()) & 0xffffff;
782                rr->rr_loss = htonl(v);
783                //              rr->rr_ehsr = htonl(sp->ehs());
784                rr->rr_ehsr = htonl(sl.ehs());
785                rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0;
786                //              rr->rr_lsr = htonl(sp->sts_ctrl());
787                rr->rr_lsr = htonl(sl.sts_ctrl());
788                //              if (sp->lts_ctrl().tv_sec == 0)
789                if (sl.lts_ctrl().tv_sec == 0)
790                        rr->rr_dlsr = 0;
791                else {
792                        u_int32_t ntp_now = ntptime(now);
793                        //                      u_int32_t ntp_then = ntptime(sp->lts_ctrl());
794                        u_int32_t ntp_then = ntptime(sl.lts_ctrl());
795                        rr->rr_dlsr = htonl(ntp_now - ntp_then);
796                }
797                ++rr;
798                if (++nrr >= 31)
799                        break;
800        }
801        flags |= nrr << 8;
802        rh->rh_flags = htons(flags);
803        int len = (u_char*)rr - pktbuf_;
804        rh->rh_len = htons((len >> 2) - 1);
805
806        if (bye)
807                len += build_bye((rtcphdr*)rr, s);
808        else
809                len += build_sdes((rtcphdr*)rr, s);
810       
811        // build "site" app data if specified
812        const char *data = tcl.attr("site");
813        if(data)
814        {
815            rr = (rtcp_rr*)(((u_char*)rh) + len);
816            len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data));
817        }
818        //LLL   ch_.send(pktbuf_, len);
819        ch->send(pktbuf_, len);
820       
821        /*
822      rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(len + 28) - rtcp_avg_size_);
823         
824          // compute the time to the next report.  we do this here
825          // because we need to know if there were any active sources
826          // during the last report period (nrr above) & if we were
827          // a source.  The bandwidth limit for rtcp traffic was set
828          // on startup from the session bandwidth.  It is the inverse
829          // of bandwidth (ie., ms/byte) to avoid a divide below.
830       
831        //      double ibw = rtcp_inv_bw_;
832        if (nrr) {
833        // there were active sources
834        //              if (we_sent) {
835        ibw *= 1./RTCP_SENDER_BW_FRACTION;
836        nsrc = nrr;
837        } else {
838        ibw *= 1./RTCP_RECEIVER_BW_FRACTION;
839        nsrc -= nrr;
840        }
841        }
842        double rint = rtcp_avg_size_ * double(nsrc) * ibw;
843        if (rint < RTCP_MIN_RPT_TIME * 1000.)
844                rint = RTCP_MIN_RPT_TIME * 1000.;
845        rint_ = rint;
846        rt_.msched(int(fmod(double(random()), rint) + rint * .5 + .5));
847        */
848       
849        // Call timer adaption for each layer
850        ch->adapt(nsrc, nrr, we_sent);
851        ch->sample_size(len);
852       
853        //      sm.CheckActiveSources(rint);
854        if (layer == 0)
855                sm.CheckActiveSources(ch->rint());
856       
857}
858
859int SessionManager::build_bye(rtcphdr* rh, Source& ls)
860{
861        int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_BYE;
862        rh->rh_flags = ntohs(flags);
863        rh->rh_len = htons(1);
864        rh->rh_ssrc = ls.srcid();
865        return (8);
866}
867
868/*
869 * receive an RTP data packet
870 */
871void SessionManager::recv(DataHandler* dh)
872{
873        int layer = dh - dh_;
874        pktbuf* pb = pool_->alloc(layer);
875        Address * addrp;
876        /* leave room in case we need to expand rtpv1 into an rtpv2 header */
877        /* XXX the free mem routine didn't like it ... */
878        //u_char* bp = &pktbuf_[4];
879        //u_char* bp = pktbuf_;
880       
881        int cc = dh->recv(pb->data, sizeof(pb->data), addrp);
882        //int cc = dh->recv(bp, 2 * RTP_MTU - 4, addrp);
883        if (cc <= 0) {
884                pb->release();
885                return;
886        }
887
888    // Ignore loopback packets
889        if (!loopback_) {
890                rtphdr* rh = (rtphdr*)pb->data;
891                SourceManager& sm = SourceManager::instance();
892                if (rh->rh_ssrc == (*sm.localsrc()).srcid()) {
893                        pb->release();  // releasing loopback packet
894                        return;
895                }
896        } // now, loopback packets ignored (if disabled)
897
898        int version = pb->data[0] >> 6;
899        //int version = *(u_char*)rh >> 6;
900        if (version != 2) {
901                ++badversion_;
902                pb->release();
903                return;
904        }
905        if (cc < (int)sizeof(rtphdr)) {
906                ++nrunt_;
907                pb->release();
908                return;
909        }
910        pb->len = cc;
911       
912        //bp += sizeof(*rh);
913        //cc -= sizeof(*rh);
914        demux(pb, *addrp);
915}
916
917void SessionManager::demux(pktbuf* pb, Address & addr)
918{
919        rtphdr* rh = (rtphdr*)pb->data;
920        u_int32_t srcid = rh->rh_ssrc;
921        int flags = ntohs(rh->rh_flags);
922        // for LIP SYNC
923        //SV-XXX: unused: u_char *pkt = pb->data - sizeof(*rh);
924
925        if ((flags & RTP_X) != 0) {
926        /*
927        * the minimal-control audio/video profile
928        * explicitly forbids extensions
929                */
930                ++badext_;
931                pb->release();
932                return;
933        }
934
935        /*
936         * Check for illegal payload types.  Most likely this is
937         * a session packet arriving on the data port.
938         */
939        int fmt = flags & 0x7f;
940        if (!check_format(fmt)) {
941                ++badfmt_;
942                pb->release();
943                return;
944        }
945
946        SourceManager& sm = SourceManager::instance();
947        u_int16_t seqno = ntohs(rh->rh_seqno);
948        Source* s = sm.demux(srcid, addr, seqno, pb->layer);
949        if (s == 0) {
950        /*
951        * Takes a pair of validated packets before we will
952        * believe the source.  This prevents a runaway
953        * allocation of Source data structures for a
954        * stream of garbage packets.
955                */
956                pb->release();
957                return;
958        }
959        /* inform this source of the mbus */
960        s->mbus(&mb_);
961       
962        Source::Layer& sl = s->layer(pb->layer);
963        timeval now = unixtime();
964        //      s->lts_data(now);
965        sl.lts_data(now);
966        //      s->sts_data(rh->rh_ts);
967        sl.sts_data(rh->rh_ts);
968       
969        // extract CSRC count (CC field); increment pb->dp data pointer & adjust length accordingly
970        int cnt = (flags >> 8) & 0xf;
971        if (cnt > 0) {
972                //u_char* nh = (u_char*)rh + (cnt << 2);
973                rtphdr hdr = *rh;
974                pb->dp += (cnt << 2);
975                pb->len -= (cnt << 2);
976                u_int32_t* bp = (u_int32_t*)(rh + 1);
977                while (--cnt >= 0) {
978                        u_int32_t csrc = *(u_int32_t*)bp;
979                        bp += 4;
980                        Source* cs = sm.lookup(csrc, srcid, addr);
981                        //                      cs->lts_data(now);
982                        cs->layer(pb->layer).lts_data(now);
983                        cs->action();
984                }
985                //              rtphdr hdr = *rh;
986                //              rh = (rtphdr*)nh;
987                /*XXX move header up so it's contiguous with data*/
988                rh = (rtphdr*)pb->dp;
989                *rh = hdr;
990        } else
991                s->action();
992
993        if (s->sync() && lipSyncEnabled()) { 
994                /*
995                 * Synchronisation is enabled on this source;
996                 * video packets have to
997                 * be buffered, their playout point scheduled, and the
998                 * playout delays communicated with the audio tool ...
999                 */ 
1000
1001                /*
1002                * XXX bit rate doesn't include rtpv1 options;
1003                * but v1 is going away anyway.
1004                */
1005                //              int dup = s->cs(seqno);
1006                //              s->np(1);
1007                //              s->nb(cc + sizeof(*rh));
1008                int dup = sl.cs(seqno, s);
1009                sl.np(1);
1010                sl.nb(pb->len);
1011                if (dup) {
1012                        pb->release();
1013                        return;
1014                }
1015                if (flags & RTP_M) // check if reach frame boundaries
1016                        //                      s->nf(1);
1017                        sl.nf(1);
1018               
1019                //s->recv(pkt, rh, pb, pb->len); // this should invoke Source::recv and buffer
1020                //s->recv(bp); // this should invoke Source::recv and buffer
1021               
1022                pktbuf_ = (u_char*)new_blk();
1023        } /* synced */
1024
1025        else { /* ... playout video packets as they arrive */
1026                /*
1027                 * This is a data packet.  If the source needs activation,
1028                 * or the packet format has changed, deal with this.
1029                 * Then, hand the packet off to the packet handler.
1030                 * XXX might want to be careful about flip-flopping
1031                 * here when format changes due to misordered packets
1032                 * (easy solution -- keep rtp seqno of last fmt change).
1033                 */
1034                PacketHandler* h = s->handler();
1035                if (h == 0)
1036                        h = s->activate(fmt);
1037                else if (s->format() != fmt)
1038                        h = s->change_format(fmt);
1039               
1040                        /*
1041                        * XXX bit rate doesn't include rtpv1 options;
1042                        * but v1 is going away anyway.
1043                */
1044                //              int dup = s->cs(seqno);
1045                //              s->np(1);
1046                //              s->nb(cc + sizeof(*rh));
1047                int dup = sl.cs(seqno, s);
1048                sl.np(1);
1049                sl.nb(pb->len);
1050                if (dup){
1051                        pb->release();
1052                        return;
1053                }
1054                if (flags & RTP_M)
1055                        //                  s->nf(1);
1056                        sl.nf(1);
1057#ifdef notdef
1058        /* This should move to the handler */
1059        /*XXX could get rid of hdrlen and move run check into recv method*/
1060               
1061                int hlen = h->hdrlen();
1062                cc -= hlen;
1063                if (cc < 0) {
1064                        //                  s->runt(1);
1065                        sl.runt(1);
1066                        pb->release();
1067                        return;
1068                }
1069#endif
1070                if (s->mute()) {
1071                        pb->release();
1072                        return;
1073                }
1074                //h->recv(rh, bp + hlen, cc);
1075                h->recv(pb);
1076        } /* not sync-ed */
1077
1078}
1079
1080void SessionManager::parse_rr_records(u_int32_t, rtcp_rr*, int,
1081                                      const u_char*, Address &)
1082{
1083}
1084                                     
1085
1086void SessionManager::parse_sr(rtcphdr* rh, int flags, u_char*ep,
1087                                                          Source* ps, Address & addr, int layer)
1088{
1089        rtcp_sr* sr = (rtcp_sr*)(rh + 1);
1090        Source* s;
1091        u_int32_t ssrc = rh->rh_ssrc;
1092        if (ps->srcid() != ssrc)
1093                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1094        else
1095                s = ps;
1096       
1097        Source::Layer& sl = s->layer(layer);
1098       
1099        timeval now = unixtime();
1100
1101        sl.lts_ctrl(now);
1102        sl.sts_ctrl(ntohl(sr->sr_ntp.upper) << 16 |
1103                ntohl(sr->sr_ntp.lower) >> 16);
1104       
1105        //int cnt = flags >> 8 & 0x1f;
1106        //parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, addr);
1107       
1108        /*s->lts_ctrl(now);
1109        s->sts_ctrl(ntohl(sr->sr_ntp.upper) << 16 |
1110        ntohl(sr->sr_ntp.lower) >> 16);*/
1111       
1112        s->rtp_ctrl(ntohl(sr->sr_ts));
1113        u_int32_t t = ntptime(now);
1114        s->map_ntp_time(t);
1115        s->map_rtp_time(s->convert_time(t));
1116        s->rtp2ntp(1);
1117        //printf("Got SR\n");
1118
1119        int cnt = flags >> 8 & 0x1f;
1120        parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, addr);
1121}
1122
1123void SessionManager::parse_rr(rtcphdr* rh, int flags, u_char* ep,
1124                                                          Source* ps, Address & addr, int layer)
1125{
1126        Source* s;
1127        u_int32_t ssrc = rh->rh_ssrc;
1128        if (ps->srcid() != ssrc)
1129                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1130        else
1131                s = ps;
1132       
1133        s->layer(layer).lts_ctrl(unixtime());
1134        int cnt = flags >> 8 & 0x1f;    // reception report count
1135        parse_rr_records(ssrc, (rtcp_rr*)(rh + 1), cnt, ep, addr);
1136}
1137
1138void SessionManager::parse_xr(rtcphdr* rh, int flags, u_char* ep,
1139                                                          Source* ps, Address & addr, int layer)
1140{
1141        debug_msg("XXX parse_xr() called!\n");
1142        Source* s;
1143        u_int32_t ssrc = rh->rh_ssrc;   // RTCP's ssrc
1144        if (ps->srcid() != ssrc)
1145                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1146        else
1147                s = ps;
1148
1149        s->layer(layer).lts_ctrl(unixtime());
1150        int cnt = flags >> 8 & 0x1f;    // reception report count
1151        parse_xr_records(ssrc, (rtcp_xr*)(rh + 1), cnt, ep, addr);
1152}
1153
1154void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
1155                                      const u_char* ep, Address & addr)
1156{
1157        UNUSED(cnt);
1158        UNUSED(ep);
1159        UNUSED(addr);
1160
1161        int xrlen = ntohs(xr->xr_len) << 2;
1162        u_int16_t ackofack = ntohs(xr->begin_seq);
1163        u_int16_t seqno = ntohs(xr->end_seq);
1164        debug_msg("AoA: %d, SEQNO:      %d\n", ackofack, seqno);
1165
1166        // we received seqno/ackofack, so do receiver stuffs here
1167        if (seqno != ackofack) {
1168                printf("RECEIVER RECEIVER!!\n");
1169                // parse seqno, ackofack, and timestamp from XR report block
1170                if(xr->xr_flags >> 8 == XR_BT_1) {
1171                        ackofack_ = ackofack;
1172                        seqno_ = seqno;
1173                }
1174                else if(xr->xr_flags >> 8 == XR_BT_3) {
1175                        ts_ = ntohl((u_int32_t) &xr->chunk);
1176                }
1177
1178                // parse seqno, ackofack, and timestamp to TfwcRcvr
1179                tfwc_rcvr_recv(seqno_, ackofack_, ts_);
1180
1181                // send receiver side XR report
1182                ch_[0].send(build_ackv_pkt(xr, ssrc), xrlen);
1183                ch_[0].send(build_ts_echo_pkt(xr, ssrc), xrlen);
1184        }
1185        // we received ackvec, so do sender stuffs here
1186        else {
1187                printf("SENDER SENDER!!\n");
1188                // parse seqno, ackvec and timestamp echo from XR report block
1189                if(xr->xr_flags >> 8 == XR_BT_1) {
1190                        ackvec_ = ntohl((u_int32_t) &xr->chunk);
1191                }
1192                else if(xr->xr_flags >> 8 == XR_BT_3) {
1193                        ts_echo_ = ntohl((u_int32_t) &xr->chunk);
1194                }
1195
1196                // parse ackvec and timestamp echo to TfwcSndr
1197                tfwc_sndr_recv(ackvec_, ts_echo_);
1198        }
1199}
1200
1201// build ackvec packet (RTCP XR packet)
1202u_char* SessionManager::build_ackv_pkt(rtcp_xr* xr, u_int32_t ssrc)
1203{
1204        xr->ssrc = htons(ssrc);         // UNUSED
1205
1206        // set XR block type
1207        xr->xr_flags = XR_BT_1 << 8;
1208
1209        // make 'begin_seq' equal to 'end_seq'
1210        xr->begin_seq = xr->end_seq;
1211
1212        // get ackvec from TfwcRcvr
1213        xr->chunk = (u_int32_t *) htonl(tfwc_rcvr_getvec());
1214       
1215        u_char* p = (u_char*) xr;
1216        return (p);
1217}
1218
1219// build timestamp packet (RTCP XR packet)
1220u_char* SessionManager::build_ts_echo_pkt(rtcp_xr* xr, u_int32_t ssrc)
1221{
1222        xr->ssrc = htons(ssrc);         // UNUSED
1223
1224        // set XR block type
1225        xr->xr_flags = XR_BT_3 << 8;
1226
1227        // get timestamp echo from TfwcRcvr
1228        xr->chunk = (u_int32_t *) htonl(tfwc_rcvr_ts_echo());
1229
1230        u_char* p = (u_char*) xr;
1231        return (p);
1232}
1233
1234int SessionManager::sdesbody(u_int32_t* p, u_char* ep, Source* ps,
1235                                                Address & addr, u_int32_t ssrc, int layer)
1236{
1237        Source* s;
1238        u_int32_t srcid = *p;
1239        if (ps->srcid() != srcid)
1240                s = SourceManager::instance().lookup(srcid, ssrc, addr);
1241        else
1242                s = ps;
1243        if (s == 0)
1244                return (0);
1245                /*
1246                * Note ctrl packet since we will never see any direct ctrl packets
1247                * from a source through a mixer (and we don't want the source to
1248                * time out).
1249        */
1250        s->layer(layer).lts_ctrl(unixtime());
1251       
1252        u_char* cp = (u_char*)(p + 1);
1253        while (cp < ep) {
1254                char buf[256];
1255
1256                u_int type = cp[0];
1257                if (type == 0) {
1258                        /* end of chunk */
1259                        return (((cp - (u_char*)p) >> 2) + 1);
1260                }
1261                u_int len = cp[1];
1262                u_char* eopt = cp + len + 2;
1263                if (eopt > ep)
1264                        return (0);
1265
1266                if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX) {
1267                        memcpy(buf, (char*)&cp[2], len);
1268                        buf[len] = 0;
1269                        s->sdes(type, buf);
1270                } // else
1271                        /*XXX*/;
1272
1273                cp = eopt;
1274        }
1275        return (0);
1276}
1277
1278void SessionManager::parse_sdes(rtcphdr* rh, int flags, u_char* ep, Source* ps,
1279                                                                Address & addr, u_int32_t ssrc, int layer)
1280{
1281        int cnt = flags >> 8 & 0x1f;
1282        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1283        while (--cnt >= 0 && (u_char*)p < ep) {
1284                int n = sdesbody(p, ep, ps, addr, ssrc, layer);
1285                if (n == 0)
1286                        break;
1287                p += n;
1288        }
1289        if (cnt >= 0)
1290                ps->badsdes(1);
1291}
1292
1293void SessionManager::parse_bye(rtcphdr* rh, int flags, u_char* ep, Source* ps)
1294{
1295        int cnt = flags >> 8 & 0x1f;
1296        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1297
1298        while (--cnt >= 0) {
1299                if (p >= (u_int32_t*)ep) {
1300                        ps->badbye(1);
1301                        return;
1302                }
1303                Source* s;
1304                if (ps->srcid() != rh->rh_ssrc)
1305                        s = SourceManager::instance().consult(*p);
1306                else
1307                        s = ps;
1308                if (s != 0)
1309                        s->lts_done(unixtime());
1310                ++p;
1311        }
1312}
1313
1314/*
1315 * Receive an rtcp packet (from the control port).
1316 */
1317void SessionManager::recv(CtrlHandler* ch)
1318{
1319        Address * srcp;
1320        int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);
1321        if (cc <= 0)
1322                return;
1323
1324        rtcphdr* rh = (rtcphdr*)pktbuf_;
1325
1326    // Ignore loopback packets
1327        if (!loopback_) {
1328                SourceManager& sm = SourceManager::instance();
1329                if (rh->rh_ssrc == (*sm.localsrc()).srcid())
1330                        return;
1331        }
1332
1333        if (cc < int(sizeof(*rh))) {
1334                ++nrunt_;
1335                return;
1336        }
1337        /*
1338         * try to filter out junk: first thing in packet must be
1339         * sr, rr or bye & version number must be correct.
1340         */
1341        switch(ntohs(rh->rh_flags) & 0xc0ff) {
1342        case RTP_VERSION << 14 | RTCP_PT_SR:
1343        case RTP_VERSION << 14 | RTCP_PT_RR:
1344        case RTP_VERSION << 14 | RTCP_PT_XR:
1345        case RTP_VERSION << 14 | RTCP_PT_BYE:
1346                break;
1347        default:
1348                /*
1349                 * XXX should further categorize this error -- it is
1350                 * likely that people mis-implement applications that
1351                 * don't put something other than SR,RR,BYE first.
1352                 */
1353                ++badversion_;
1354                return;
1355        }
1356        /*
1357         * at this point we think the packet's valid.  Update our average
1358         * size estimator.  Also, there's valid ssrc so charge errors to it
1359         */
1360        rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(cc + 28) - rtcp_avg_size_);
1361        Address & addr = *srcp;
1362
1363        /*
1364         * First record in compount packet must be the ssrc of the
1365         * sender of the packet.  Pull it out here so we can use
1366         * it in the sdes parsing, since the sdes record doesn't
1367         * contain the ssrc of the sender (in the case of mixers).
1368         */
1369        u_int32_t ssrc = rh->rh_ssrc;
1370        Source* ps = SourceManager::instance().lookup(ssrc, ssrc, addr);
1371        if (ps == 0)
1372                return;
1373       
1374        int layer = ch - ch_;
1375                /*
1376                * Outer loop parses multiple RTCP records of a "compound packet".
1377                * There is no framing between records.  Boundaries are implicit
1378                * and the overall length comes from UDP.
1379        */
1380        u_char* epack = (u_char*)rh + cc;
1381        while ((u_char*)rh < epack) {
1382                u_int len = (ntohs(rh->rh_len) << 2) + 4;
1383                u_char* ep = (u_char*)rh + len;
1384                if (ep > epack) {
1385                        ps->badsesslen(1);
1386                        return;
1387                }
1388                u_int flags = ntohs(rh->rh_flags);
1389                if (flags >> 14 != RTP_VERSION) {
1390                        ps->badsessver(1);
1391                        return;
1392                }
1393                switch (flags & 0xff) {
1394
1395                case RTCP_PT_SR:
1396                        parse_sr(rh, flags, ep, ps, addr, layer);
1397                        break;
1398
1399                case RTCP_PT_RR:
1400                        parse_rr(rh, flags, ep, ps, addr, layer);
1401                        break;
1402
1403                case RTCP_PT_XR:
1404                        parse_xr(rh, flags, ep, ps, addr, layer);
1405                        break;
1406
1407                case RTCP_PT_SDES:
1408                        parse_sdes(rh, flags, ep, ps, addr, ssrc, layer);
1409                        break;
1410
1411                case RTCP_PT_BYE:
1412                        parse_bye(rh, flags, ep, ps);
1413                        break;
1414
1415                default:
1416                        ps->badsessopt(1);
1417                        break;
1418                }
1419                rh = (rtcphdr*)ep;
1420        }
1421        return;
1422}
Note: See TracBrowser for help on using the browser.