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

Revision 4259, 36.6 KB (checked in by soohyunc, 6 years ago)

o fixed a lot of RTCP header issues (header size, header fields, ntohs, htons,

etc) currently, RTCP sender side works fine, but receiver side doesn't seem to
send XR packet correctly.

o maybe, this is due to the ntohs, htons kind of issues (need to check)

Todo: RTCP receiver side operation

main TFWC algorithm need to be added

  • 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, 1);
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, 3);
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        //send_xreport(ch, 0);  // this XR report will be driven by timer
629}
630
631/*
632 * Send an RTP extended report packet.
633 */
634void SessionManager::send_xreport(CtrlHandler* ch, int bye, int app)
635{
636        UNUSED(app);
637        int bt = bye;   // XR block type
638
639        SourceManager& sm = SourceManager::instance();
640        Source& s = *sm.localsrc();
641        rtcphdr* rh = (rtcphdr*)pktbuf_;
642        rh->rh_ssrc = s.srcid();
643        int flags = RTP_VERSION << 14;  // RTCP flags
644        int layer = ch - ch_;
645        Source::Layer& sl = s.layer(layer);
646        timeval now = unixtime();
647        sl.lts_ctrl(now);
648
649        int we_sent = 0;
650        rtcp_rr* rr;
651        rtcp_xr_hdr* xrh;   // extended report header
652        rtcp_xr_blk* xrb;   // extended report block
653        Tcl& tcl = Tcl::instance();
654
655        MediaTimer* mt = MediaTimer::instance();
656        if (sl.np() != last_np_ && mt) {
657                last_np_ = sl.np();
658                we_sent = 1;
659                flags |= RTCP_PT_SR;
660                rtcp_sr* sr = (rtcp_sr*)(rh + 1);
661                sr->sr_ntp = ntp64time(now);
662                HTONL(sr->sr_ntp.upper);
663                HTONL(sr->sr_ntp.lower);
664                sr->sr_ts = htonl(mt->ref_ts());
665                sr->sr_np = htonl(sl.np());
666                sr->sr_nb = htonl(sl.nb());
667                rr = (rtcp_rr*)(sr + 1);
668        } else {
669                flags |= RTCP_PT_RR;
670                rr = (rtcp_rr*)(rh + 1);
671        }
672
673        // set RTCP flag to XR packet
674        flags |= RTCP_PT_XR;   
675        // access XR header
676        xrh = (rtcp_xr_hdr*)(rh + 1);
677        xrb = (rtcp_xr_blk*)(xrh + 1);
678
679        int xrlen = 0x03;       // XR packet length
680        int xrssrc = 0; // SSRC of source (currently unused)
681
682        // this block is used for giving seqno and ackofack
683        if(bt == XR_BT_1) {
684                // set XR block flags (block type and length)
685                xrh->xr_flags = htons(XR_BT_1 << 8);
686                xrh->xr_len = htons(xrlen);
687
688                xrb->ssrc = htonl(xrssrc);      // UNUSED
689                xrb->end_seq = htons(tfwc_sndr_get_seqno());
690                xrb->begin_seq = htons(tfwc_sndr_get_aoa());
691                xrb->chunk = NULL;
692                debug_msg("     SeqNo:          %d\n", tfwc_sndr_get_seqno());
693        }
694       
695        // this block is used for giving timestamp
696        else if(bt == XR_BT_3) {
697                // set XR block flags (block type and length)
698                xrh->xr_flags = htons(XR_BT_3 << 8);
699                xrh->xr_len = htons(xrlen);
700
701                xrb->ssrc = htonl(xrssrc);      // UNUSED
702                //xrb->end_seq = NULL;          // UNUSED
703                //xrb->begin_seq = NULL;        // UNUSED
704                xrb->chunk = (u_int32_t *) htonl(tfwc_sndr_get_ts());
705                debug_msg("     TS:             %d\n", tfwc_sndr_get_ts());
706        }
707
708        int nrr = 0;
709        int nsrc = 0;
710
711        u_int inactive = u_int(ch->rint() * (32./1000.));
712        if (inactive < 2)
713                inactive = 2;
714        for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) {
715                ++nsrc;
716                Source::Layer& sl = sp->layer(layer);
717                int received = sl.np() - sl.snp();
718                if (received == 0) {
719                        if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive)
720                                --nsrc;
721                        continue;
722                }
723                sl.snp(sl.np());
724                rr->rr_srcid = sp->srcid();
725                int expected = sl.ns() - sl.sns();
726                sl.sns(sl.ns());
727                u_int32_t v;
728                int lost = expected - received;
729
730                if (lost <= 0)
731                        v = 0;
732                else
733                        /* expected != 0 if lost > 0 */
734                        v = ((lost << 8) / expected) << 24;
735
736                /* XXX should saturate on over/underflow */
737                v |= (sl.ns() - sl.np()) & 0xffffff;
738                rr->rr_loss = htonl(v);
739                rr->rr_ehsr = htonl(sl.ehs());
740                rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0;
741                rr->rr_lsr = htonl(sl.sts_ctrl());
742
743                if (sl.lts_ctrl().tv_sec == 0)
744                        rr->rr_dlsr = 0;
745                else {
746                        u_int32_t ntp_now = ntptime(now);
747                        u_int32_t ntp_then = ntptime(sl.lts_ctrl());
748                        rr->rr_dlsr = htonl(ntp_now - ntp_then);
749                }
750                ++rr;
751                if (++nrr >= 31)
752                        break;
753        }
754
755        flags |= nrr << 8;
756        rh->rh_flags = htons(flags);
757        int len = (u_char*)rr - pktbuf_;
758        rh->rh_len = htons((len >> 2) - 1);
759
760        if (bye)
761                len += build_bye((rtcphdr*)rr, s);
762        else
763                len += build_sdes((rtcphdr*)rr, s);
764       
765        // build "site" app data if specified
766        const char *data = tcl.attr("site");
767        if(data)
768        {
769            rr = (rtcp_rr*)(((u_char*)rh) + len);
770            len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data));
771        }
772
773        // sending XR report packet
774        ch->send(pktbuf_, len);
775}
776
777/*XXX check for buffer overflow*/
778/*
779* Send an RTPv2 report packet.
780*/
781void SessionManager::send_report(CtrlHandler* ch, int bye, int app)
782{
783        UNUSED(app); //SV-XXX: unused
784
785        SourceManager& sm = SourceManager::instance();
786        Source& s = *sm.localsrc();
787        rtcphdr* rh = (rtcphdr*)pktbuf_;
788        rh->rh_ssrc = s.srcid();
789        int flags = RTP_VERSION << 14;
790        int layer = ch - ch_; //LLL
791        Source::Layer& sl = s.layer(layer);
792        timeval now = unixtime();
793        sl.lts_ctrl(now);
794        int we_sent = 0;
795        rtcp_rr* rr;
796        Tcl& tcl = Tcl::instance();
797
798        /*
799         * If we've sent data since our last sender report send a
800         * new report.  The MediaTimer check is to make sure we still
801         * have a grabber -- if not, we won't be able to interpret the
802         * media timestamps so there's no point in sending an SR.
803         */
804        MediaTimer* mt = MediaTimer::instance();
805        if (sl.np() != last_np_ && mt) {
806                last_np_ = sl.np();
807                we_sent = 1;
808                flags |= RTCP_PT_SR;
809                rtcp_sr* sr = (rtcp_sr*)(rh + 1);
810                sr->sr_ntp = ntp64time(now);
811                HTONL(sr->sr_ntp.upper);
812                HTONL(sr->sr_ntp.lower);
813                sr->sr_ts = htonl(mt->ref_ts());
814                sr->sr_np = htonl(sl.np());
815                sr->sr_nb = htonl(sl.nb());
816                rr = (rtcp_rr*)(sr + 1);
817        } else {
818                flags |= RTCP_PT_RR;
819                rr = (rtcp_rr*)(rh + 1);
820        }
821
822        int nrr = 0;
823        int nsrc = 0;
824        /*
825        * we don't want to inflate report interval if user has set
826        * the flag that causes all sources to be 'kept' so we
827        * consider sources 'inactive' if we haven't heard a control
828        * msg from them for ~32 reporting intervals.
829        */
830        //LLL   u_int inactive = u_int(rint_ * (32./1000.));
831        u_int inactive = u_int(ch->rint() * (32./1000.));
832        if (inactive < 2)
833                inactive = 2;
834        for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) {
835                ++nsrc;
836                Source::Layer& sl = sp->layer(layer);
837                //              int received = sp->np() - sp->snp();
838                int received = sl.np() - sl.snp();
839                if (received == 0) {
840                        //              if (u_int(now.tv_sec - sp->lts_ctrl().tv_sec) > inactive)
841                        if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive)
842                                --nsrc;
843                        continue;
844                }
845                //              sp->snp(sp->np());
846                sl.snp(sl.np());
847                rr->rr_srcid = sp->srcid();
848                //              int expected = sp->ns() - sp->sns();
849                int expected = sl.ns() - sl.sns();
850                //              sp->sns(sp->ns());
851                sl.sns(sl.ns());
852                u_int32_t v;
853                int lost = expected - received;
854                if (lost <= 0)
855                        v = 0;
856                else
857                        /* expected != 0 if lost > 0 */
858                        v = ((lost << 8) / expected) << 24;
859                /* XXX should saturate on over/underflow */
860                //              v |= (sp->ns() - sp->np()) & 0xffffff;
861                v |= (sl.ns() - sl.np()) & 0xffffff;
862                rr->rr_loss = htonl(v);
863                //              rr->rr_ehsr = htonl(sp->ehs());
864                rr->rr_ehsr = htonl(sl.ehs());
865                rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0;
866                //              rr->rr_lsr = htonl(sp->sts_ctrl());
867                rr->rr_lsr = htonl(sl.sts_ctrl());
868                //              if (sp->lts_ctrl().tv_sec == 0)
869                if (sl.lts_ctrl().tv_sec == 0)
870                        rr->rr_dlsr = 0;
871                else {
872                        u_int32_t ntp_now = ntptime(now);
873                        //                      u_int32_t ntp_then = ntptime(sp->lts_ctrl());
874                        u_int32_t ntp_then = ntptime(sl.lts_ctrl());
875                        rr->rr_dlsr = htonl(ntp_now - ntp_then);
876                }
877                ++rr;
878                if (++nrr >= 31)
879                        break;
880        }
881        flags |= nrr << 8;
882        rh->rh_flags = htons(flags);
883        int len = (u_char*)rr - pktbuf_;
884        rh->rh_len = htons((len >> 2) - 1);
885
886        if (bye)
887                len += build_bye((rtcphdr*)rr, s);
888        else
889                len += build_sdes((rtcphdr*)rr, s);
890       
891        // build "site" app data if specified
892        const char *data = tcl.attr("site");
893        if(data)
894        {
895            rr = (rtcp_rr*)(((u_char*)rh) + len);
896            len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data));
897        }
898        //LLL   ch_.send(pktbuf_, len);
899        ch->send(pktbuf_, len);
900       
901        /*
902      rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(len + 28) - rtcp_avg_size_);
903         
904          // compute the time to the next report.  we do this here
905          // because we need to know if there were any active sources
906          // during the last report period (nrr above) & if we were
907          // a source.  The bandwidth limit for rtcp traffic was set
908          // on startup from the session bandwidth.  It is the inverse
909          // of bandwidth (ie., ms/byte) to avoid a divide below.
910       
911        //      double ibw = rtcp_inv_bw_;
912        if (nrr) {
913        // there were active sources
914        //              if (we_sent) {
915        ibw *= 1./RTCP_SENDER_BW_FRACTION;
916        nsrc = nrr;
917        } else {
918        ibw *= 1./RTCP_RECEIVER_BW_FRACTION;
919        nsrc -= nrr;
920        }
921        }
922        double rint = rtcp_avg_size_ * double(nsrc) * ibw;
923        if (rint < RTCP_MIN_RPT_TIME * 1000.)
924                rint = RTCP_MIN_RPT_TIME * 1000.;
925        rint_ = rint;
926        rt_.msched(int(fmod(double(random()), rint) + rint * .5 + .5));
927        */
928       
929        // Call timer adaption for each layer
930        ch->adapt(nsrc, nrr, we_sent);
931        ch->sample_size(len);
932       
933        //      sm.CheckActiveSources(rint);
934        if (layer == 0)
935                sm.CheckActiveSources(ch->rint());
936       
937}
938
939int SessionManager::build_bye(rtcphdr* rh, Source& ls)
940{
941        int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_BYE;
942        rh->rh_flags = ntohs(flags);
943        rh->rh_len = htons(1);
944        rh->rh_ssrc = ls.srcid();
945        return (8);
946}
947
948/*
949 * receive an RTP data packet
950 */
951void SessionManager::recv(DataHandler* dh)
952{
953        int layer = dh - dh_;
954        pktbuf* pb = pool_->alloc(layer);
955        Address * addrp;
956        /* leave room in case we need to expand rtpv1 into an rtpv2 header */
957        /* XXX the free mem routine didn't like it ... */
958        //u_char* bp = &pktbuf_[4];
959        //u_char* bp = pktbuf_;
960       
961        int cc = dh->recv(pb->data, sizeof(pb->data), addrp);
962        //int cc = dh->recv(bp, 2 * RTP_MTU - 4, addrp);
963        if (cc <= 0) {
964                pb->release();
965                return;
966        }
967
968    // Ignore loopback packets
969        if (!loopback_) {
970                rtphdr* rh = (rtphdr*)pb->data;
971                SourceManager& sm = SourceManager::instance();
972                if (rh->rh_ssrc == (*sm.localsrc()).srcid()) {
973                        pb->release();  // releasing loopback packet
974                        return;
975                }
976        } // now, loopback packets ignored (if disabled)
977
978        int version = pb->data[0] >> 6;
979        //int version = *(u_char*)rh >> 6;
980        if (version != 2) {
981                ++badversion_;
982                pb->release();
983                return;
984        }
985        if (cc < (int)sizeof(rtphdr)) {
986                ++nrunt_;
987                pb->release();
988                return;
989        }
990        pb->len = cc;
991       
992        //bp += sizeof(*rh);
993        //cc -= sizeof(*rh);
994        demux(pb, *addrp);
995}
996
997void SessionManager::demux(pktbuf* pb, Address & addr)
998{
999        rtphdr* rh = (rtphdr*)pb->data;
1000        u_int32_t srcid = rh->rh_ssrc;
1001        int flags = ntohs(rh->rh_flags);
1002        // for LIP SYNC
1003        //SV-XXX: unused: u_char *pkt = pb->data - sizeof(*rh);
1004
1005        if ((flags & RTP_X) != 0) {
1006        /*
1007        * the minimal-control audio/video profile
1008        * explicitly forbids extensions
1009                */
1010                ++badext_;
1011                pb->release();
1012                return;
1013        }
1014
1015        /*
1016         * Check for illegal payload types.  Most likely this is
1017         * a session packet arriving on the data port.
1018         */
1019        int fmt = flags & 0x7f;
1020        if (!check_format(fmt)) {
1021                ++badfmt_;
1022                pb->release();
1023                return;
1024        }
1025
1026        SourceManager& sm = SourceManager::instance();
1027        u_int16_t seqno = ntohs(rh->rh_seqno);
1028        Source* s = sm.demux(srcid, addr, seqno, pb->layer);
1029        if (s == 0) {
1030        /*
1031        * Takes a pair of validated packets before we will
1032        * believe the source.  This prevents a runaway
1033        * allocation of Source data structures for a
1034        * stream of garbage packets.
1035                */
1036                pb->release();
1037                return;
1038        }
1039        /* inform this source of the mbus */
1040        s->mbus(&mb_);
1041       
1042        Source::Layer& sl = s->layer(pb->layer);
1043        timeval now = unixtime();
1044        //      s->lts_data(now);
1045        sl.lts_data(now);
1046        //      s->sts_data(rh->rh_ts);
1047        sl.sts_data(rh->rh_ts);
1048       
1049        // extract CSRC count (CC field); increment pb->dp data pointer & adjust length accordingly
1050        int cnt = (flags >> 8) & 0xf;
1051        if (cnt > 0) {
1052                //u_char* nh = (u_char*)rh + (cnt << 2);
1053                rtphdr hdr = *rh;
1054                pb->dp += (cnt << 2);
1055                pb->len -= (cnt << 2);
1056                u_int32_t* bp = (u_int32_t*)(rh + 1);
1057                while (--cnt >= 0) {
1058                        u_int32_t csrc = *(u_int32_t*)bp;
1059                        bp += 4;
1060                        Source* cs = sm.lookup(csrc, srcid, addr);
1061                        //                      cs->lts_data(now);
1062                        cs->layer(pb->layer).lts_data(now);
1063                        cs->action();
1064                }
1065                //              rtphdr hdr = *rh;
1066                //              rh = (rtphdr*)nh;
1067                /*XXX move header up so it's contiguous with data*/
1068                rh = (rtphdr*)pb->dp;
1069                *rh = hdr;
1070        } else
1071                s->action();
1072
1073        if (s->sync() && lipSyncEnabled()) { 
1074                /*
1075                 * Synchronisation is enabled on this source;
1076                 * video packets have to
1077                 * be buffered, their playout point scheduled, and the
1078                 * playout delays communicated with the audio tool ...
1079                 */ 
1080
1081                /*
1082                * XXX bit rate doesn't include rtpv1 options;
1083                * but v1 is going away anyway.
1084                */
1085                //              int dup = s->cs(seqno);
1086                //              s->np(1);
1087                //              s->nb(cc + sizeof(*rh));
1088                int dup = sl.cs(seqno, s);
1089                sl.np(1);
1090                sl.nb(pb->len);
1091                if (dup) {
1092                        pb->release();
1093                        return;
1094                }
1095                if (flags & RTP_M) // check if reach frame boundaries
1096                        //                      s->nf(1);
1097                        sl.nf(1);
1098               
1099                //s->recv(pkt, rh, pb, pb->len); // this should invoke Source::recv and buffer
1100                //s->recv(bp); // this should invoke Source::recv and buffer
1101               
1102                pktbuf_ = (u_char*)new_blk();
1103        } /* synced */
1104
1105        else { /* ... playout video packets as they arrive */
1106                /*
1107                 * This is a data packet.  If the source needs activation,
1108                 * or the packet format has changed, deal with this.
1109                 * Then, hand the packet off to the packet handler.
1110                 * XXX might want to be careful about flip-flopping
1111                 * here when format changes due to misordered packets
1112                 * (easy solution -- keep rtp seqno of last fmt change).
1113                 */
1114                PacketHandler* h = s->handler();
1115                if (h == 0)
1116                        h = s->activate(fmt);
1117                else if (s->format() != fmt)
1118                        h = s->change_format(fmt);
1119               
1120                        /*
1121                        * XXX bit rate doesn't include rtpv1 options;
1122                        * but v1 is going away anyway.
1123                */
1124                //              int dup = s->cs(seqno);
1125                //              s->np(1);
1126                //              s->nb(cc + sizeof(*rh));
1127                int dup = sl.cs(seqno, s);
1128                sl.np(1);
1129                sl.nb(pb->len);
1130                if (dup){
1131                        pb->release();
1132                        return;
1133                }
1134                if (flags & RTP_M)
1135                        //                  s->nf(1);
1136                        sl.nf(1);
1137#ifdef notdef
1138        /* This should move to the handler */
1139        /*XXX could get rid of hdrlen and move run check into recv method*/
1140               
1141                int hlen = h->hdrlen();
1142                cc -= hlen;
1143                if (cc < 0) {
1144                        //                  s->runt(1);
1145                        sl.runt(1);
1146                        pb->release();
1147                        return;
1148                }
1149#endif
1150                if (s->mute()) {
1151                        pb->release();
1152                        return;
1153                }
1154                //h->recv(rh, bp + hlen, cc);
1155                h->recv(pb);
1156        } /* not sync-ed */
1157
1158}
1159
1160void SessionManager::parse_rr_records(u_int32_t, rtcp_rr*, int,
1161                                      const u_char*, Address &)
1162{
1163}
1164                                     
1165
1166void SessionManager::parse_sr(rtcphdr* rh, int flags, u_char*ep,
1167                                                          Source* ps, Address & addr, int layer)
1168{
1169        rtcp_sr* sr = (rtcp_sr*)(rh + 1);
1170        Source* s;
1171        u_int32_t ssrc = rh->rh_ssrc;
1172        if (ps->srcid() != ssrc)
1173                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1174        else
1175                s = ps;
1176       
1177        Source::Layer& sl = s->layer(layer);
1178       
1179        timeval now = unixtime();
1180
1181        sl.lts_ctrl(now);
1182        sl.sts_ctrl(ntohl(sr->sr_ntp.upper) << 16 |
1183                ntohl(sr->sr_ntp.lower) >> 16);
1184       
1185        //int cnt = flags >> 8 & 0x1f;
1186        //parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, addr);
1187       
1188        /*s->lts_ctrl(now);
1189        s->sts_ctrl(ntohl(sr->sr_ntp.upper) << 16 |
1190        ntohl(sr->sr_ntp.lower) >> 16);*/
1191       
1192        s->rtp_ctrl(ntohl(sr->sr_ts));
1193        u_int32_t t = ntptime(now);
1194        s->map_ntp_time(t);
1195        s->map_rtp_time(s->convert_time(t));
1196        s->rtp2ntp(1);
1197        //printf("Got SR\n");
1198
1199        int cnt = flags >> 8 & 0x1f;
1200        parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, addr);
1201}
1202
1203void SessionManager::parse_rr(rtcphdr* rh, int flags, u_char* ep,
1204                                                          Source* ps, Address & addr, int layer)
1205{
1206        Source* s;
1207        u_int32_t ssrc = rh->rh_ssrc;
1208        if (ps->srcid() != ssrc)
1209                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1210        else
1211                s = ps;
1212       
1213        s->layer(layer).lts_ctrl(unixtime());
1214        int cnt = flags >> 8 & 0x1f;    // reception report count
1215        parse_rr_records(ssrc, (rtcp_rr*)(rh + 1), cnt, ep, addr);
1216}
1217
1218void SessionManager::parse_xr(rtcphdr* rh, int flags, u_char* ep,
1219                                                          Source* ps, Address & addr, int layer)
1220{
1221        debug_msg("XXX parse_xr() called!\n");
1222        Source* s;
1223        u_int32_t ssrc = rh->rh_ssrc;   // RTCP's ssrc
1224        if (ps->srcid() != ssrc)
1225                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1226        else
1227                s = ps;
1228
1229        s->layer(layer).lts_ctrl(unixtime());
1230        int cnt = flags >> 8 & 0x1f;    // reception report count
1231        parse_xr_records(ssrc, (rtcp_xr_hdr*)(rh + 1), cnt, ep, addr);
1232}
1233
1234void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr_hdr* xrh, int cnt,
1235                                      const u_char* ep, Address & addr)
1236{
1237        UNUSED(cnt);
1238        UNUSED(ep);
1239        UNUSED(addr);
1240
1241        int xrlen = ntohs(xrh->xr_len);
1242        rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1);
1243
1244        // we received seqno/ackofack, so do receiver stuffs here
1245        if (xrb->chunk == NULL) {
1246                printf("RECEIVER RECEIVER!!\n");
1247                // parse seqno, ackofack, and timestamp from XR report block
1248                if(xrh->xr_flags >> 8 == XR_BT_1) {
1249                        ackofack_ = ntohs(xrb->begin_seq);
1250                        seqno_ = ntohs(xrb->end_seq);
1251                }
1252                else if(xrh->xr_flags >> 8 == XR_BT_3) {
1253                        ts_ = ntohl((u_int32_t) &xrb->chunk);
1254                }
1255
1256                // parse seqno, ackofack, and timestamp to TfwcRcvr
1257                tfwc_rcvr_recv(seqno_, ackofack_, ts_);
1258
1259                // send receiver side XR report
1260                ch_[0].send(build_ackv_pkt(xrh, ssrc), xrlen);
1261                ch_[0].send(build_ts_echo_pkt(xrh, ssrc), xrlen);
1262        }
1263        // we received ackvec, so do sender stuffs here
1264        else {
1265                printf("SENDER SENDER!!\n");
1266                // parse seqno, ackvec and timestamp echo from XR report block
1267                if(xrh->xr_flags >> 8 == XR_BT_1) {
1268                        ackvec_ = ntohl((u_int32_t) &xrb->chunk);
1269                }
1270                else if(xrh->xr_flags >> 8 == XR_BT_3) {
1271                        ts_echo_ = ntohl((u_int32_t) &xrb->chunk);
1272                }
1273
1274                // parse ackvec and timestamp echo to TfwcSndr
1275                tfwc_sndr_recv(ackvec_, ts_echo_);
1276        }
1277}
1278
1279// build ackvec packet (RTCP XR packet)
1280u_char* SessionManager::build_ackv_pkt(rtcp_xr_hdr* xrh, u_int32_t ssrc)
1281{
1282        // set XR block type
1283        xrh->xr_flags = XR_BT_1 << 8;
1284
1285        // take XR block contents
1286        rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1);
1287
1288        xrb->ssrc = htons(ssrc);        // UNUSED
1289        xrb->chunk = (u_int32_t *) htonl(tfwc_rcvr_getvec());
1290       
1291        u_char* p = (u_char*) xrh;
1292        return (p);
1293}
1294
1295// build timestamp packet (RTCP XR packet)
1296u_char* SessionManager::build_ts_echo_pkt(rtcp_xr_hdr* xrh, u_int32_t ssrc)
1297{
1298        // set XR block type
1299        xrh->xr_flags = XR_BT_3 << 8;
1300
1301        // take XR block contents
1302        rtcp_xr_blk* xrb = (rtcp_xr_blk*)(xrh + 1);
1303
1304        xrb->ssrc = htons(ssrc);        // UNUSED
1305        xrb->chunk = (u_int32_t *) htonl(tfwc_rcvr_ts_echo());
1306
1307        u_char* p = (u_char*) xrh;
1308        return (p);
1309}
1310
1311int SessionManager::sdesbody(u_int32_t* p, u_char* ep, Source* ps,
1312                                                Address & addr, u_int32_t ssrc, int layer)
1313{
1314        Source* s;
1315        u_int32_t srcid = *p;
1316        if (ps->srcid() != srcid)
1317                s = SourceManager::instance().lookup(srcid, ssrc, addr);
1318        else
1319                s = ps;
1320        if (s == 0)
1321                return (0);
1322                /*
1323                * Note ctrl packet since we will never see any direct ctrl packets
1324                * from a source through a mixer (and we don't want the source to
1325                * time out).
1326        */
1327        s->layer(layer).lts_ctrl(unixtime());
1328       
1329        u_char* cp = (u_char*)(p + 1);
1330        while (cp < ep) {
1331                char buf[256];
1332
1333                u_int type = cp[0];
1334                if (type == 0) {
1335                        /* end of chunk */
1336                        return (((cp - (u_char*)p) >> 2) + 1);
1337                }
1338                u_int len = cp[1];
1339                u_char* eopt = cp + len + 2;
1340                if (eopt > ep)
1341                        return (0);
1342
1343                if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX) {
1344                        memcpy(buf, (char*)&cp[2], len);
1345                        buf[len] = 0;
1346                        s->sdes(type, buf);
1347                } // else
1348                        /*XXX*/;
1349
1350                cp = eopt;
1351        }
1352        return (0);
1353}
1354
1355void SessionManager::parse_sdes(rtcphdr* rh, int flags, u_char* ep, Source* ps,
1356                                                                Address & addr, u_int32_t ssrc, int layer)
1357{
1358        int cnt = flags >> 8 & 0x1f;
1359        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1360        while (--cnt >= 0 && (u_char*)p < ep) {
1361                int n = sdesbody(p, ep, ps, addr, ssrc, layer);
1362                if (n == 0)
1363                        break;
1364                p += n;
1365        }
1366        if (cnt >= 0)
1367                ps->badsdes(1);
1368}
1369
1370void SessionManager::parse_bye(rtcphdr* rh, int flags, u_char* ep, Source* ps)
1371{
1372        int cnt = flags >> 8 & 0x1f;
1373        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1374
1375        while (--cnt >= 0) {
1376                if (p >= (u_int32_t*)ep) {
1377                        ps->badbye(1);
1378                        return;
1379                }
1380                Source* s;
1381                if (ps->srcid() != rh->rh_ssrc)
1382                        s = SourceManager::instance().consult(*p);
1383                else
1384                        s = ps;
1385                if (s != 0)
1386                        s->lts_done(unixtime());
1387                ++p;
1388        }
1389}
1390
1391/*
1392 * Receive an rtcp packet (from the control port).
1393 */
1394void SessionManager::recv(CtrlHandler* ch)
1395{
1396        Address * srcp;
1397        int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);
1398        if (cc <= 0)
1399                return;
1400
1401        rtcphdr* rh = (rtcphdr*)pktbuf_;
1402
1403    // Ignore loopback packets
1404        if (!loopback_) {
1405                SourceManager& sm = SourceManager::instance();
1406                if (rh->rh_ssrc == (*sm.localsrc()).srcid())
1407                        return;
1408        }
1409
1410        if (cc < int(sizeof(*rh))) {
1411                ++nrunt_;
1412                return;
1413        }
1414        /*
1415         * try to filter out junk: first thing in packet must be
1416         * sr, rr or bye & version number must be correct.
1417         */
1418        switch(ntohs(rh->rh_flags) & 0xc0ff) {
1419        case RTP_VERSION << 14 | RTCP_PT_SR:
1420        case RTP_VERSION << 14 | RTCP_PT_RR:
1421        case RTP_VERSION << 14 | RTCP_PT_XR:
1422        case RTP_VERSION << 14 | RTCP_PT_BYE:
1423                break;
1424        default:
1425                /*
1426                 * XXX should further categorize this error -- it is
1427                 * likely that people mis-implement applications that
1428                 * don't put something other than SR,RR,BYE first.
1429                 */
1430                ++badversion_;
1431                return;
1432        }
1433        /*
1434         * at this point we think the packet's valid.  Update our average
1435         * size estimator.  Also, there's valid ssrc so charge errors to it
1436         */
1437        rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(cc + 28) - rtcp_avg_size_);
1438        Address & addr = *srcp;
1439
1440        /*
1441         * First record in compount packet must be the ssrc of the
1442         * sender of the packet.  Pull it out here so we can use
1443         * it in the sdes parsing, since the sdes record doesn't
1444         * contain the ssrc of the sender (in the case of mixers).
1445         */
1446        u_int32_t ssrc = rh->rh_ssrc;
1447        Source* ps = SourceManager::instance().lookup(ssrc, ssrc, addr);
1448        if (ps == 0)
1449                return;
1450       
1451        int layer = ch - ch_;
1452                /*
1453                * Outer loop parses multiple RTCP records of a "compound packet".
1454                * There is no framing between records.  Boundaries are implicit
1455                * and the overall length comes from UDP.
1456        */
1457        u_char* epack = (u_char*)rh + cc;
1458        while ((u_char*)rh < epack) {
1459                u_int len = (ntohs(rh->rh_len) << 2) + 4;
1460                u_char* ep = (u_char*)rh + len;
1461                if (ep > epack) {
1462                        ps->badsesslen(1);
1463                        return;
1464                }
1465                u_int flags = ntohs(rh->rh_flags);
1466                if (flags >> 14 != RTP_VERSION) {
1467                        ps->badsessver(1);
1468                        return;
1469                }
1470                switch (flags & 0xff) {
1471
1472                case RTCP_PT_SR:
1473                        parse_sr(rh, flags, ep, ps, addr, layer);
1474                        break;
1475
1476                case RTCP_PT_RR:
1477                        parse_rr(rh, flags, ep, ps, addr, layer);
1478                        break;
1479
1480                case RTCP_PT_XR:
1481                        parse_xr(rh, flags, ep, ps, addr, layer);
1482                        break;
1483
1484                case RTCP_PT_SDES:
1485                        parse_sdes(rh, flags, ep, ps, addr, ssrc, layer);
1486                        break;
1487
1488                case RTCP_PT_BYE:
1489                        parse_bye(rh, flags, ep, ps);
1490                        break;
1491
1492                default:
1493                        ps->badsessopt(1);
1494                        break;
1495                }
1496                rh = (rtcphdr*)ep;
1497        }
1498        return;
1499}
Note: See TracBrowser for help on using the browser.