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

Revision 4910, 49.0 KB (checked in by piers, 2 years ago)

Updated VIC so that Soo-Hyun's TFRC support works with ECN. Fixes a number of bugs - new and old.

video/grabber.h
- Corrected description of frametime_ variable - as it is derived from fps_

video/grabber-still.cpp
- reverted to original jpeg still grabber

video/grabber-file.cpp
- Renamed from orig grabber-still and updated it
- Added correct return(TCL_OK) for file_load command
- Added #ifdef SUSPEND_GRAB around H261Encoder::suspend_grab() call
- Converted all fprintf(stderr...) to debug_msg(...)

video/grabber.cpp
- in tick(): renamed frametime to bpsframetime to better reflect its usage

tcl/ui-main.tcl
- Shrunk UI size by putting buttons below address in main GUI
- Added code to create filedev grabber obj early so decoder can be informed of it for PSNR calculation

tcl/ui-resource.tcl
- changed defaults for stillgrabber so it is enabled as default
- Created new stillFile resource to allow for setting of the filename
- Created new fileGrabberFile resource to allow for setting of the filename for fileGrabber

tcl/ui-ctrlmenu.tcl
- Added support setting StillGrabber? filename from new stillGrabber resource
- Added support setting FileGrabber? filename from new fileGrabberFile resource
- Removed still grabber disabling of controls
- Inform sessionmanager of grabber so it can control grabber bps
- Corrected bandwidth indicator units to be Kbps

tcl/ui-grabber.tcl
- Updated build.still with correct name and setting filename from resource
- Updated build.filegrab with correct name and setting filename from resource
- Both of the above use renamed proc set.file.frame to set the file name

cc/tfwc_sndr.h
- Added x_rate variable and xrate() return func - derived in the same way as TFRC - used for setting VIC send rate
- Converted all fprintf(stderr...) to debug_msg(...)
- Increased prev_history_[] size to HSZ+1 to match history[] size

cc/tfwc_sndr.cpp
- Added xrate calculation from TFRC sender code into window_in_packets()
- Corrected BUG in pseudo_history(): bzero history_ loop was exceeding array bounds by 1
- Corrected possible BUG: history revert was not copying entire array contents

cc/tfrc_sndr.cpp
- Corrected BUG in pseudo_history(): bzero history_ loop was exceeding array bounds by 1

codec/decoder.cpp
- Replace fprintf() with debug_msg()

codec/encoder-h261.cpp
- Added #ifdef ADJUST_QUANT around call to H261Encoder::adjust_quantizer() method in consume()
- Added bounds checking to adjust_quantizer()
- Corrected BUG in avg_packets_per_frame(): loop didn't cycle thru history values
- Converted all fprintf(stderr...) to debug_msg(...)

rtp/source.h
- Added associated access functions for ECN variables

rtp/transmitter.cpp
- Added associated code for setting Congestion Control (cc_type_) via command line
- txtime(): Commented out old tfrc block as VIC's own rate (kbps_) is used (which is now set to the CC algo's rate in SessionManager::parse_xr_records())
- tx_buf_size(): Fixed BUG in buffer traversal
- send(): commented out case RBCC as it doesn't appear to work. Instead TFRC mode just operates using VIC's normal rate control (which is controlled by TFRC algo's rate)
- send()/timeout(): Fixed OLD VIC BUG: 1e-3 used to convert secs to millisecs - should be 1e3 - meant that transmit scheduling was broken. Tho with TFRC there are few timeouts (but that probably depends on path characteristics).
- tfwc_output(_pb,ack_clock): corrected output so that packet buffer is emptied from the head of the list (as opposed to the tail - so only one packet was usually sent).
- tfwc_output(_pb,ack_clock): Moved b_magic() into while loop as it may change as loop progresses(?).
- tfrc_output() - Added comment saying that these routines are no longer used as the packet output in TFRC should be controlled via timers - in the normal vic output routines.

rtp/transmitter.h
- Added ECN defines
- Corrected bps() return value

rtp/session.cpp
- Added ecn-mode setting command
- Added grabber command for linking of grabber and session rate control
- Added control code for use of ecn-mode: Treat ECN as Loss(default) or Ignore
- parse_fb(): Added AVPF Feed Back(FB) packet parser for ECN for RTP support
- parse_xr_records(): Added sender rate control for grabber and session controller based on received Acks and TFRC algo.
- Removed some old cruft

rtp/session.h
- Added grabber connection member variable
- Added parse_fb() declaration
- Converted all fprintf(stderr...) to debug_msg(...)

module.cpp
- Added safety check when sending that tx_ object exists before attempting send

net/mbus_handler.cpp
- Added safety check when before scheduling heartbeat that mbusp_ object exists

net/confbus.cpp
- Added debug_msg() call.

  • 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
54/* added to support the mbus
55#include "mbus_handler.h"*/
56
57
58static class SessionMatcher : public Matcher {
59    public:
60                SessionMatcher() : Matcher("session") {}
61                TclObject* match(const char* id) {
62                        if (strcmp(id, "audio/rtp") == 0)
63                                return (new AudioSessionManager);
64                        else if (strcmp(id, "video/rtp") == 0)
65                                return (new VideoSessionManager);
66                        return (0);
67                }
68} session_matcher;
69
70int VideoSessionManager::check_format(int fmt) const
71{
72        switch(fmt) {
73                case RTP_PT_RAW:
74                case RTP_PT_CELLB:
75                case RTP_PT_JPEG:
76                case RTP_PT_CUSEEME:
77                case RTP_PT_NV:
78                case RTP_PT_CPV:
79                case RTP_PT_H261:
80                case RTP_PT_BVC:
81                case RTP_PT_H261_COMPAT:/*XXX*/
82                case RTP_PT_H263:
83                case RTP_PT_MPEG4:
84                case RTP_PT_H264:
85                case RTP_PT_H263P:
86                case RTP_PT_LDCT:
87                case RTP_PT_PVH:
88                case RTP_PT_DV:
89#ifdef USE_H261AS
90                case RTP_PT_H261AS:
91#endif 
92                return (1);
93        }
94        return (0);
95}
96
97int AudioSessionManager::check_format(int fmt) const
98{
99        switch (fmt) {
100        case RTP_PT_PCMU:
101        case RTP_PT_CELP:
102        case RTP_PT_GSM:
103        case RTP_PT_DVI:
104        case RTP_PT_LPC:
105                return (1);
106        }
107        return (0);
108}
109
110
111static SessionManager* manager;
112
113void
114adios()
115{
116        if (SourceManager::instance().localsrc() != 0)
117                manager->send_bye();
118        exit(0);
119}
120
121/*void ReportTimer::timeout()
122{
123sm_.send_report();
124}*/
125
126void DataHandler::dispatch(int)
127{
128        sm_->recv(this);
129}
130
131void CtrlHandler::dispatch(int)
132{
133        int i = 0; int cc = 0;
134        while((cc = sm_->recv(this)) > 0) {
135        i++; //dispatch_info(sm_->tx_get_now(), cc, i);
136        }
137}
138
139CtrlHandler::CtrlHandler()
140: ctrl_inv_bw_(0.),
141ctrl_avg_size_(128.),
142rint_(0.0) //SV-XXX: Debian
143{
144}
145
146inline void CtrlHandler::schedule_timer()
147{
148        msched(int(fmod(double(random()), rint_) + rint_ * .5 + .5));
149}
150
151void CtrlHandler::net(Network* n)
152{
153        DataHandler::net(n);
154        cancel();
155        if (n != 0) {
156        /*
157        * schedule a timer for our first report using half the
158        * min ctrl interval.  This gives us some time before
159        * our first report to learn about other sources so our
160        * next report interval will account for them.  The avg
161        * ctrl size was initialized to 128 bytes which is
162        * conservative (it assumes everyone else is generating
163        * SRs instead of RRs).
164                */
165                double rint = ctrl_avg_size_ * ctrl_inv_bw_;
166                if (rint < CTRL_MIN_RPT_TIME / 2. * 1000.)
167                        rint = CTRL_MIN_RPT_TIME / 2. * 1000.;
168                rint_ = rint;
169                schedule_timer();
170        }
171}
172
173void CtrlHandler::sample_size(int cc)
174{
175        ctrl_avg_size_ += CTRL_SIZE_GAIN * (double(cc + 28) - ctrl_avg_size_);
176}
177
178void CtrlHandler::adapt(int nsrc, int nrr, int we_sent)
179{
180        /*
181         * compute the time to the next report.  we do this here
182         * because we need to know if there were any active sources
183         * during the last report period (nrr above) & if we were
184         * a source.  The bandwidth limit for ctrl traffic was set
185         * on startup from the session bandwidth.  It is the inverse
186         * of bandwidth (ie., ms/byte) to avoid a divide below.
187         */
188        double ibw = ctrl_inv_bw_;
189        if (nrr) {
190                /* there were active sources */
191                if (we_sent) {
192                        ibw *= 1./CTRL_SENDER_BW_FRACTION;
193                        nsrc = nrr;
194                } else {
195                        ibw *= 1./CTRL_RECEIVER_BW_FRACTION;
196                        nsrc -= nrr;
197                }
198        }
199        double rint = ctrl_avg_size_ * double(nsrc) * ibw;
200        if (rint < CTRL_MIN_RPT_TIME * 1000.)
201                rint = CTRL_MIN_RPT_TIME * 1000.;
202        rint_ = rint;
203}
204
205void CtrlHandler::timeout()
206{
207        sm_->announce(this);
208        schedule_timer();
209}
210
211//SV-XXX: rearranged initialization order to shut up gcc4
212SessionManager::SessionManager()
213//      : dh_(*this), ch_(*this), rt_(*this),
214: mb_(mbus_handler_engine, NULL),
215lipSyncEnabled_(0),
216badversion_(0),
217badoptions_(0),
218badfmt_(0),
219badext_(0),
220nrunt_(0),
221last_np_(0),
222sdes_seq_(0),
223rtcp_inv_bw_(0.),
224rtcp_avg_size_(128.),
225confid_(-1),
226seqno_(0),              // RTP data packet seqno (from RTP header)
227lastseq_(0),    // last received packet's seqno
228ackvec_(0),             // bit vector (AckVec)
229grabber_(0)
230{
231        /*XXX For adios() to send bye*/
232        manager = this;
233       
234        for (int i = 0; i < NLAYER; ++i) {
235                dh_[i].manager(this);
236                ch_[i].manager(this);
237        }
238       
239        /*XXX*/
240        pktbuf_ = new u_char[2 * RTP_MTU];
241        pool_ = new BufferPool;
242       
243        /*
244         * schedule a timer for our first report using half the
245         * min rtcp interval.  This gives us some time before
246         * our first report to learn about other sources so our
247         * next report interval will account for them.  The avg
248         * rtcp size was initialized to 128 bytes which is
249         * conservative (it assumes everyone else is generating
250         * SRs instead of RRs).
251         */
252        double rint = rtcp_avg_size_ * rtcp_inv_bw_;
253        if (rint < RTCP_MIN_RPT_TIME / 2. * 1000.)
254                rint = RTCP_MIN_RPT_TIME / 2. * 1000.;
255        rint_ = rint;
256        //rt_.msched(int(fmod(double(random()), rint) + rint * .5 + .5));
257}
258
259SessionManager::~SessionManager()
260{
261        if (pktbuf_)
262                delete[] pktbuf_;
263       
264        delete pool_;
265}
266
267u_int32_t SessionManager::alloc_srcid(Address & addr) const
268{
269        timeval tv;
270        ::gettimeofday(&tv, 0);
271        u_int32_t srcid = u_int32_t(tv.tv_sec + tv.tv_usec);
272        srcid += (u_int32_t)getuid();
273        srcid += (u_int32_t)getpid();
274/* __IPv6 changed srcid computation */
275        for(unsigned int i = 0; i < (addr.length() % sizeof(u_int32_t)); i++) {
276                srcid += ((u_int32_t*)((const void*)addr))[i];
277        }
278        return (srcid);
279}
280
281extern char* onestat(char* cp, const char* name, u_long v);
282
283char* SessionManager::stats(char* cp) const
284{
285        cp = onestat(cp, "Bad-RTP-version", badversion_);
286        cp = onestat(cp, "Bad-RTPv1-options", badoptions_);
287        cp = onestat(cp, "Bad-Payload-Format", badfmt_);
288        cp = onestat(cp, "Bad-RTP-Extension", badext_);
289        cp = onestat(cp, "Runts", nrunt_);
290        Crypt* p = dh_[0].net()->crypt();
291        if (p != 0) {
292                cp = onestat(cp, "Crypt-Bad-Length", p->badpktlen());
293                cp = onestat(cp, "Crypt-Bad-P-Bit", p->badpbit());
294        }
295        /*XXX*/
296        if (ch_[0].net() != 0) {
297                Crypt* p = ch_[0].net()->crypt();
298                if (p != 0) {
299                        cp = onestat(cp, "Crypt-Ctrl-Bad-Length", p->badpktlen());
300                        cp = onestat(cp, "Crypt-Ctrl-Bad-P-Bit", p->badpbit());
301                }
302        }
303        *--cp = 0;
304        return (cp);
305}
306
307int SessionManager::command(int argc, const char*const* argv)
308{
309        Tcl& tcl = Tcl::instance();
310        char* cp = tcl.buffer();
311        if (argc == 2) {
312                if (strcmp(argv[1], "active") == 0) {
313                        SourceManager::instance().sortactive(cp);
314                        tcl.result(cp);
315                        return (TCL_OK);
316                }
317                if (strcmp(argv[1], "local-addr-heuristic") == 0) {
318                        strcpy(cp, intoa(LookupLocalAddr()));
319                        tcl.result(cp);
320                        return (TCL_OK);
321                }
322                if (strcmp(argv[1], "stats") == 0) {
323                        stats(cp);
324                        tcl.result(cp);
325                        return (TCL_OK);
326                }
327                if (strcmp(argv[1], "nb") == 0) {
328                        sprintf(cp, "%u", 8 * nb_);
329                        tcl.result(cp);
330                        return (TCL_OK);
331                }
332                if (strcmp(argv[1], "nf") == 0) {
333                        sprintf(cp, "%u", nf_);
334                        tcl.result(cp);
335                        return (TCL_OK);
336                }
337                if (strcmp(argv[1], "np") == 0 ||
338                    strcmp(argv[1], "ns") == 0) {
339                        sprintf(cp, "%u", np_);
340                        tcl.result(cp);
341                        return (TCL_OK);
342                }
343                if (strcmp(argv[1], "lip-sync") == 0) {
344                        sprintf(cp, "%u", lipSyncEnabled_);
345                        tcl.result(cp);
346                        return (TCL_OK);
347                }
348
349        } else if (argc == 3) {
350                if (strcmp(argv[1], "sm") == 0) {
351                        sm_ = (SourceManager*)TclObject::lookup(argv[2]);
352                        return (TCL_OK);
353                }
354                if (strcmp(argv[1], "name") == 0) {
355                        Source* s = SourceManager::instance().localsrc();
356                        s->sdes(RTCP_SDES_NAME, argv[2]);
357                        return (TCL_OK);
358                }
359                if (strcmp(argv[1], "email") == 0) {
360                        Source* s = SourceManager::instance().localsrc();
361                        s->sdes(RTCP_SDES_EMAIL, argv[2]);
362                        return (TCL_OK);
363                }
364                if (strcmp(argv[1], "random-srcid") == 0) {
365                        Address * addrp;
366                        if ((addrp = (dh_[0].net())->alloc(argv[2])) !=0 ) { //SV-XXX: placed ()'s against truth check == NULL
367                          sprintf(cp, "%u", alloc_srcid(*addrp));
368                          delete addrp;
369                        }
370                        tcl.result(cp);
371                        return (TCL_OK);
372                }
373                if (strcmp(argv[1], "data-net") == 0) {
374                        dh_[0].net((Network*)TclObject::lookup(argv[2]));
375                        return (TCL_OK);
376                }
377                if (strcmp(argv[1], "ctrl-net") == 0) {
378                        ch_[0].net((Network*)TclObject::lookup(argv[2]));
379                        return (TCL_OK);
380                }
381                if (strcmp(argv[1], "max-bandwidth") == 0) {
382                        double bw = atof(argv[2]) / 8.;
383                        rtcp_inv_bw_ = 1. / (bw * RTCP_SESSION_BW_FRACTION);
384                        return (TCL_OK);
385                }
386                if (strcmp(argv[1], "confid") == 0) {
387                        confid_ = atoi(argv[2]);
388                        return (TCL_OK);
389                }
390                if (strcmp(argv[1], "data-bandwidth") == 0) {
391                        /*XXX assume value in range */
392                        bps(atoi(argv[2]));
393                        return (TCL_OK);
394                }
395                if (strcmp(argv[1], "mtu") == 0) {
396                        mtu_ = atoi(argv[2]);
397                        return (TCL_OK);
398                }
399                if (strcmp(argv[1], "loopback") == 0) {
400                        loopback_ = atoi(argv[2]);
401                        return (TCL_OK);
402                }
403                if (strcmp(argv[1], "ecn-mode") == 0) {
404                        ecn_mode_ = atoi(argv[2]);
405                        return (TCL_OK);
406                }
407                if (strcmp(argv[1], "lip-sync") == 0) {
408                        lipSyncEnabled_ = atoi(argv[2]);
409                        return (TCL_OK);
410                }
411                if (strcmp(argv[1], "grabber") == 0) {
412                        grabber_ = (Grabber*)TclObject::lookup(argv[2]);
413                        fprintf(stderr,"Session:Setting this %d grabber_:%d\n", (int)this, (int)grabber_);
414                        return (TCL_OK);
415                }
416
417        }  else if (argc == 4) {
418                if (strcmp(argv[1], "data-net") == 0) {
419                        u_int layer = atoi(argv[3]);
420                        if (layer >= NLAYER)
421                                abort();
422                        if (*argv[2] == 0) {
423                                dh_[layer].net(0);
424                                return (TCL_OK);
425                        }
426                        Network* net = (Network*)TclObject::lookup(argv[2]);
427                        if (net == 0) {
428                                tcl.resultf("no network %s", argv[2]);
429                                return (TCL_ERROR);
430                        }
431                        if (net->rchannel() < 0) {
432                                tcl.resultf("network not open");
433                                return (TCL_ERROR);
434                        }
435                        dh_[layer].net(net);
436                        return (TCL_OK);
437                }
438                if (strcmp(argv[1], "ctrl-net") == 0) {
439                        u_int layer = atoi(argv[3]);
440                        if (layer >= NLAYER)
441                                abort();
442                        if (*argv[2] == 0) {
443                                ch_[layer].net(0);
444                                return (TCL_OK);
445                        }
446                        Network* net = (Network*)TclObject::lookup(argv[2]);
447                        if (net == 0) {
448                                tcl.resultf("no network %s", argv[2]);
449                                return (TCL_ERROR);
450                        }
451                        if (net->rchannel() < 0) {
452                                tcl.resultf("network not open");
453                                return (TCL_ERROR);
454                        }
455                        ch_[layer].net(net);
456                        return (TCL_OK);
457                }
458                return (Transmitter::command(argc, argv));
459        }
460        //should not be reached
461        return (TCL_ERROR);
462}
463
464// Transmit RTP and DO send AoA
465void SessionManager::transmit(pktbuf* pb, bool ack_clock)
466{
467        // mh_.msg_iov = pb->iov;
468        // dh_[.net()->send(mh_);
469        // debug_msg("L %d,",pb->layer);
470
471        // receive XR before sending
472        tot_num_acked_ = check_xr_arrival(pb, 1);
473        // print RTP seqno
474        print_rtp_seqno(pb);
475
476        // record seqno and timestamp at CC sender
477        switch (cc_type_) {
478          case WBCC:
479            tfwc_sndr_.send(pb, tx_get_now());
480            break;
481          case RBCC:
482            tfrc_sndr_.send(pb, tx_get_now());
483            break;
484        }
485
486        // Using loop_layer for now to restrict transmission as well
487        if (pb->layer < loop_layer_) {
488          Network* n = dh_[pb->layer].net();
489          if (n != 0)
490                n->send(pb);
491
492          // send an RTCP XR (aoa) packet
493          switch (cc_type_) {
494                case WBCC:
495                  ch_->send_aoa();
496                  break;
497                case RBCC:
498                  ch_->send_aoa();
499                  break;
500          }
501        }
502}
503
504// Transmit RTP but DO NOT send AoA
505void SessionManager::tx_data_only(pktbuf* pb, bool ack_clock)
506{
507        // receive XR before sending
508        tot_num_acked_ = check_xr_arrival(pb, 1);
509        // print RTP seqno
510        print_rtp_seqno(pb);
511
512        // record seqno and timestamp at CC sender
513        switch (cc_type_) {
514          case WBCC:
515            tfwc_sndr_.send(pb, tx_get_now());
516            break;
517          case RBCC:
518            tfrc_sndr_.send(pb, tx_get_now());
519            break;
520        }
521
522        if (pb->layer < loop_layer_) {
523                Network* n = dh_[pb->layer].net();
524                if (n != 0)
525                        n->send(pb);
526        }
527}
528
529// sending ack of ack packet (RTCP XR report packet)
530void CtrlHandler::send_aoa()
531{
532        i_am_sender();
533        sm_->build_aoa_pkt(this);
534}
535
536// sending time stamp packet (RTCP XR report packet)
537void CtrlHandler::send_ts()
538{
539        i_am_sender();
540        sm_->build_ts_pkt(this);
541}
542
543void SessionManager::build_aoa_pkt(CtrlHandler* ch)
544{
545        // RTCP XR (Loss RLE Report Block)
546        // (it is XR_BT_1 defined in rtp/rtp.h)
547        build_xreport(ch, XR_BT_1);
548}
549
550void SessionManager::build_ts_pkt(CtrlHandler* ch)
551{
552        // RTCP XR (Packet Receipt Times Report Block)
553        // (it is XR_BT_3 defined in rtp/rtp.h)
554        build_xreport(ch, XR_BT_3);
555}
556
557u_char* SessionManager::build_sdes_item(u_char* p, int code, Source& s)
558{
559        const char* value = s.sdes(code);
560        if (value != 0) {
561                int len = strlen(value);
562                *p++ = code;
563                *p++ = len;
564                memcpy(p, value, len);
565                p += len;
566        }
567        return (p);
568}
569
570int SessionManager::build_sdes(rtcphdr* rh, Source& ls)
571{
572        int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_SDES;
573        rh->rh_flags = htons(flags);
574        rh->rh_ssrc = ls.srcid();
575        u_char* p = (u_char*)(rh + 1);
576        p = build_sdes_item(p, RTCP_SDES_CNAME, ls);
577
578        /*
579         * We always send a cname plus one other sdes
580         * There's a schedule for what we send sequenced by sdes_seq_:
581         *   - send 'email' every 0th & 4th packet
582         *   - send 'note' every 2nd packet
583         *   - send 'tool' every 6th packet
584         *   - send 'name' in all the odd slots
585         * (if 'note' is not the empty string, we switch the roles
586         *  of name & note)
587         */
588        int nameslot, noteslot;
589        const char* note = ls.sdes(RTCP_SDES_NOTE);
590        if (note) {
591                if (*note) {
592                        nameslot = RTCP_SDES_NOTE;
593                        noteslot = RTCP_SDES_NAME;
594                } else {
595                        nameslot = RTCP_SDES_NAME;
596                        noteslot = RTCP_SDES_NOTE;
597                }
598        } else {
599                nameslot = RTCP_SDES_NAME;
600                noteslot = RTCP_SDES_NAME;
601        }
602        u_int seq = (++sdes_seq_) & 0x7;
603        switch (seq) {
604
605        case 0case 4:
606                p = build_sdes_item(p, RTCP_SDES_EMAIL, ls);
607                break;
608
609        case 2:
610                p = build_sdes_item(p, noteslot, ls);
611                break;
612        case 6:
613                p = build_sdes_item(p, RTCP_SDES_TOOL, ls);
614                break;
615        default:
616                p = build_sdes_item(p, nameslot, ls);
617        }
618        int len = p - (u_char*)rh;
619        int pad = 4 - (len & 3);
620        len += pad;
621        rh->rh_len = htons((len >> 2) - 1);
622        while (--pad >= 0)
623                *p++ = 0;
624
625        return (len);
626}
627
628int SessionManager::build_app(rtcphdr* rh, Source& ls, const char *name,
629                void *data, int datalen)
630{
631  int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_APP;
632  rh->rh_flags = htons(flags);
633  rh->rh_ssrc = ls.srcid();
634  u_char* p = (u_char*)(rh + 1);
635    int len;
636   
637    // write the name field
638    len = strlen(name);
639    if( len < 4 ) {
640        memcpy(p,name,len);
641        p += len;
642       
643        // pad short names
644        while( p - (u_char*)(rh+1) < 4 )
645            *p++ = 0;
646    }
647    else {
648        // use first four chars of given name
649        memcpy(p,name,4);
650        p += 4;
651    }
652   
653    // write the app data
654    memcpy(p,data,datalen);
655    p += datalen;
656   
657    // pad as needed
658    len = p - (u_char*)rh;
659    int pad = 4 - (len & 3);
660    while( --pad >= 0 )
661        *p++ = 0;
662        len = p - (u_char*)rh;
663
664    // set the length now that it's known
665        rh->rh_len = htons((len >> 2) - 1);
666
667  return (len);
668}
669
670/*void SessionManager::send_ECN_XR(CtrlHandler* ch,
671                                        u_int8_t tos, u_int16_t begin_seq)
672{
673        u_int16_t chunk = (tos & 0x03) << 14;
674        send_xreport(ch, XR_BT_1, XR_BT_ECN, 0,
675                                 begin_seq, begin_seq, &chunk, 1, 0);
676}*/
677
678/*
679void SessionManager::send_report()
680{
681        send_report(0);
682}
683
684  void SessionManager::send_bye()
685  {
686  send_report(1);
687}
688*/
689
690// SessionManager is no longer used as Timer - Each
691// CtrlHandler has its own Timer which calls this;
692void SessionManager::announce(CtrlHandler* ch)
693{
694        send_report(ch, 0);
695}
696
697/*
698 * Send an RTP extended report packet.
699 */
700void SessionManager::build_xreport(CtrlHandler* ch, int bt)
701{
702        //fprintf(stderr, "\tentering build_xreport()..................  %s +%d\n",
703        //              __FILE__,__LINE__);
704
705        // declare chunks
706        u_int16_t *chunks = NULL;
707        u_int16_t num_chunks = 0;
708        // begin and end
709        u_int16_t b = 0;
710        u_int16_t e = 0;
711
712        // -----------------------------------------------------------------*
713        // i am an RTP data sender                                          *
714        // -----------------------------------------------------------------*
715        if (am_i_sender()) {
716                if(bt == XR_BT_1) {
717                num_chunks = 1;
718                chunks = (u_int16_t *) malloc(num_chunks * sizeof(u_int16_t));
719
720                switch (cc_type_) {
721                  case WBCC:
722                        // this block is used for giving ackofack
723                        chunks[num_chunks-1] = tfwc_sndr_.get_aoa();
724                    break;
725                  case RBCC:
726                        // this block is used for giving ackofack
727                        chunks[num_chunks-1] = tfrc_sndr_.get_aoa();
728                        break;
729                  } // switch (cc_type_)
730
731                  // send_xreport (sender's report)
732                  // - just sending ackofack information
733                  send_xreport(ch, XR_BT_1, 0, 0, 0, 0, chunks, num_chunks, 0);
734                }
735                else if (bt == XR_BT_3) {
736                        /*XXX*/
737                }
738        }
739        // -----------------------------------------------------------------*
740        // i am an RTP data receiver                                        *
741        // -----------------------------------------------------------------*
742        else {
743                // this block is used for giving ackvec
744                if (bt == XR_BT_1) {
745                  switch (cc_type_) {
746                  case WBCC:
747                    // get the number of required chunks for giving AckVec
748                    num_chunks = tfwc_rcvr_.numvec();
749                    chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t));
750                       
751                    // set/printing chunks
752                    //fprintf(stderr, "\t   printing chunks: ");
753                    for (int i = 0; i < num_chunks; i++) {
754                        chunks[i] = tfwc_rcvr_.getvec(i);
755                        //      fprintf(stderr, "[%d:%x] ", i, chunks[i]);
756                    }
757                    //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
758                    b = tfwc_rcvr_.begins();
759                    e = tfwc_rcvr_.ends();
760                    break;
761
762                  case RBCC:
763                    // get the number of required chunks for giving AckVec
764                    num_chunks = tfrc_rcvr_.numvec();
765                    chunks = (u_int16_t *)malloc(num_chunks * sizeof(u_int16_t));
766
767                    // set/printing chunks
768                    //fprintf(stderr, "\t   printing chunks: ");
769                    for (int i = 0; i < num_chunks; i++) {
770                        chunks[i] = tfrc_rcvr_.getvec(i);
771                        //      fprintf(stderr, "[%d:%x] ", i, chunks[i]);
772                    }
773                    //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
774                    b = tfrc_rcvr_.begins();
775                    e = tfrc_rcvr_.ends();
776                    break;
777                  } // switch (cc_type_)
778
779                  // send_xreport (receiver's report)
780                  // - sending AckVec
781                  send_xreport(ch,XR_BT_1,0,0,b,e,chunks,num_chunks,0);
782                }
783
784                // XR block type 3 - TBD
785                else if (bt == XR_BT_3) {
786                        /*XXX*/
787                }
788        } // end of if (am_i_sender())
789        // -----------------------------------------------------------------*
790}
791
792// New version
793void SessionManager::send_xreport(CtrlHandler* ch, u_int8_t bt,
794                u_int8_t rsvd, u_int8_t thin,
795                u_int16_t begin_seq, u_int16_t end_seq,
796                u_int16_t *chunks, u_int16_t num_chunks,
797                u_int32_t xrssrc)
798{
799        SourceManager& sm = SourceManager::instance();
800        Source& s = *sm.localsrc();
801        rtcphdr* rh = (rtcphdr*)pktbuf_;
802        rh->rh_ssrc = s.srcid();
803        int flags = RTP_VERSION << 14;  // RTCP flags
804        //int layer = ch - ch_; //LLL
805        //Source::Layer& sl = s.layer(layer);
806        //timeval now = unixtime();
807        //sl.lts_ctrl(now);
808        int i;
809
810        // set RTCP flag to XR packet
811        flags |= RTCP_PT_XR;
812
813        // check XR block type
814        switch (bt) {
815                case XR_BT_1:
816                case XR_BT_3:
817                case XR_BT_ECN:
818                        break;
819                default:
820                        debug_msg("ERROR: Unknown XR packet type: %d\n", bt);
821                        return;
822        }
823
824        // set xr pointer to XR packet
825        rtcp_xr_BT_1_hdr* xr = (rtcp_xr_BT_1_hdr*)(rh + 1);
826
827        // set XR block type and flags (block type and length)
828        xr->BT = bt;
829        xr->xr_flags.rsvd = rsvd;
830        xr->xr_flags.T = thin;
831        xr->ssrc = htonl(xrssrc);
832
833        // get current RTP data packet seqno
834        xr->begin_seq = htons(begin_seq);
835        xr->end_seq = htons(end_seq);
836
837        //fprintf(stderr, "\t>> sending RTCP XR: BT:%d, begin:%d, end:%d\n",
838        //              bt, ntohs(xr->begin_seq), ntohs(xr->end_seq));
839
840        // declare XR report chunks
841        u_int16_t *xrchunks = (u_int16_t *) (xr + 1);
842
843        // copy XR chunks and printing
844        //fprintf(stderr, "\t   printing chunks: ");
845        for (i = 0; i < num_chunks; i++) {
846        //      fprintf(stderr, "[%d:%x] ", i, chunks[i]);
847                xrchunks[i] = htons(chunks[i]);
848        } //fprintf(stderr, "...........%s +%d\n",__FILE__,__LINE__);
849
850        // if num_chunks is odd then increment it by one as packet size is
851        // measured in 32-bits pieces. And add Null chunk onto the end.
852        if (num_chunks % 2) {
853                num_chunks++;
854                xrchunks[i] = 0;
855        }
856
857        // XR report block length in bytes
858        int xrlen = sizeof(rtcp_xr_BT_1_hdr) + (num_chunks * 2);
859
860        // Convert XR report block length to multiples of 32 bit-words minus 1
861        xr->xr_len = htons((xrlen >> 2) - 1);
862
863        // RTCP header flags (this is not the XR header flags)
864        rh->rh_flags = htons(flags);
865
866        // RTCP packet length
867        int len = (u_char *) ++xr + (num_chunks * 2) - pktbuf_;
868        //fprintf(stderr, "\t   RTCP XR: len: %d, xrlen: %d\n", len, xrlen);
869        len = sizeof(rtcphdr) + sizeof(rtcp_xr_BT_1_hdr) + (num_chunks * 2);
870        rh->rh_len = htons((len >> 2) - 1);
871
872    // send XR report block
873    if(am_i_sender())
874      send_xr_info(bt, begin_seq, end_seq);
875    ch->send(pktbuf_, len);
876}
877
878// ECN FB
879void SessionManager::send_fb_ecn(CtrlHandler* ch, Source::Layer& sl, u_int32_t seqno, u_int32_t media_ssrc)
880{
881        SourceManager& sm = SourceManager::instance();
882        Source& s = *sm.localsrc();
883        rtcphdr* rh = (rtcphdr*)pktbuf_;
884        rh->rh_ssrc = s.srcid();
885        int flags = RTP_VERSION << 14;  // RTCP flags
886        //int layer = ch - ch_; //LLL
887        //Source::Layer& sl = s.layer(layer);
888        //timeval now = unixtime();
889        //sl.lts_ctrl(now);
890
891        // set RTCP PT to RTPFB packet and FMT to RTPFB_FMT_ECN
892        flags |= RTCP_PT_RTPFB | RTPFB_FMT_ECN << 8;
893
894        //Set fb_ecn pointer to FB packet
895        struct rtcp_fb_ecn *fb_ecn = (rtcp_fb_ecn*)(rh + 1);
896
897        fb_ecn->media_ssrc = htonl(media_ssrc);
898        // loss is the lower portion but not including that yet
899        fb_ecn->seq_n_loss = htonl(seqno << 12);
900        fb_ecn->ecn_ce = htons(sl.ecn_ce());
901        fb_ecn->not_ect = htons(sl.not_ect());
902        fb_ecn->ect0 = htons(sl.ect0());
903        fb_ecn->ect1 = htons(sl.ect1());
904
905        fprintf(stderr, "\t>> sending RTCP FB: seq_n_loss:%d(seq=%d), ecn_ecn:%d, not_ect:%d, ect0:%d,ect1:%d\n", ntohl(fb_ecn->seq_n_loss), seqno,ntohs(fb_ecn->ecn_ce), ntohs(fb_ecn->not_ect), ntohs(fb_ecn->ect0), ntohs(fb_ecn->ect1));
906
907        // FB packet length in bytes
908        int len = sizeof(rtcp_fb_ecn) + sizeof(rtcphdr);
909
910        // Convert FB length to multiples of 32 bit-words minus 1
911        rh->rh_len = htons((len >> 2) - 1);
912
913        // Set RTCP header flags
914        rh->rh_flags = htons(flags);
915
916    //if(am_i_sender())
917      //send_xr_info(bt, begin_seq, end_seq);
918    ch->send(pktbuf_, len);
919}
920
921/*XXX check for buffer overflow*/
922/*
923* Send an RTPv2 report packet.
924*/
925void SessionManager::send_report(CtrlHandler* ch, int bye, int app)
926{
927        UNUSED(app); //SV-XXX: unused
928
929        SourceManager& sm = SourceManager::instance();
930        Source& s = *sm.localsrc();
931        rtcphdr* rh = (rtcphdr*)pktbuf_;
932        rh->rh_ssrc = s.srcid();
933        int flags = RTP_VERSION << 14;
934        int layer = ch - ch_; //LLL
935        Source::Layer& sl = s.layer(layer);
936        timeval now = unixtime();
937        sl.lts_ctrl(now);
938        int we_sent = 0;
939        rtcp_rr* rr;
940        Tcl& tcl = Tcl::instance();
941
942        /*
943         * If we've sent data since our last sender report send a
944         * new report.  The MediaTimer check is to make sure we still
945         * have a grabber -- if not, we won't be able to interpret the
946         * media timestamps so there's no point in sending an SR.
947         */
948        MediaTimer* mt = MediaTimer::instance();
949        if (sl.np() != last_np_ && mt) {
950                last_np_ = sl.np();
951                we_sent = 1;
952                flags |= RTCP_PT_SR;
953                rtcp_sr* sr = (rtcp_sr*)(rh + 1);
954                sr->sr_ntp = ntp64time(now);
955                HTONL(sr->sr_ntp.upper);
956                HTONL(sr->sr_ntp.lower);
957                sr->sr_ts = htonl(mt->ref_ts());
958                sr->sr_np = htonl(sl.np());
959                sr->sr_nb = htonl(sl.nb());
960                rr = (rtcp_rr*)(sr + 1);
961        } else {
962                flags |= RTCP_PT_RR;
963                rr = (rtcp_rr*)(rh + 1);
964        }
965
966        int nrr = 0;
967        int nsrc = 0;
968        /*
969        * we don't want to inflate report interval if user has set
970        * the flag that causes all sources to be 'kept' so we
971        * consider sources 'inactive' if we haven't heard a control
972        * msg from them for ~32 reporting intervals.
973        */
974        u_int inactive = u_int(ch->rint() * (32./1000.));
975        if (inactive < 2)
976                inactive = 2;
977        for (Source* sp = sm.sources(); sp != 0; sp = sp->next_) {
978                ++nsrc;
979                Source::Layer& sl = sp->layer(layer);
980                int received = sl.np() - sl.snp();
981                if (received == 0) {
982                        if (u_int(now.tv_sec - sl.lts_ctrl().tv_sec) > inactive)
983                                --nsrc;
984                        continue;
985                }
986                sl.snp(sl.np());
987                rr->rr_srcid = sp->srcid();
988                int expected = sl.ns() - sl.sns();
989                sl.sns(sl.ns());
990                u_int32_t v;
991                int lost = expected - received;
992                if (lost <= 0)
993                        v = 0;
994                else
995                        /* expected != 0 if lost > 0 */
996                        v = ((lost << 8) / expected) << 24;
997                /* XXX should saturate on over/underflow */
998                v |= (sl.ns() - sl.np()) & 0xffffff;
999                rr->rr_loss = htonl(v);
1000                rr->rr_ehsr = htonl(sl.ehs());
1001                rr->rr_dv = (sp->handler() != 0) ? sp->handler()->delvar() : 0;
1002                rr->rr_lsr = htonl(sl.sts_ctrl());
1003                if (sl.lts_ctrl().tv_sec == 0)
1004                        rr->rr_dlsr = 0;
1005                else {
1006                        u_int32_t ntp_now = ntptime(now);
1007                        u_int32_t ntp_then = ntptime(sl.lts_ctrl());
1008                        rr->rr_dlsr = htonl(ntp_now - ntp_then);
1009                }
1010                ++rr;
1011                if (++nrr >= 31)
1012                        break;
1013        }
1014        flags |= nrr << 8;
1015        rh->rh_flags = htons(flags);
1016        int len = (u_char*)rr - pktbuf_;
1017        rh->rh_len = htons((len >> 2) - 1);
1018
1019        if (bye)
1020                len += build_bye((rtcphdr*)rr, s);
1021        else
1022                len += build_sdes((rtcphdr*)rr, s);
1023       
1024        // build "site" app data if specified
1025        const char *data = tcl.attr("site");
1026        if(data)
1027        {
1028            rr = (rtcp_rr*)(((u_char*)rh) + len);
1029            len += build_app((rtcphdr*)rr, s, "site", (void *)data, strlen(data));
1030        }
1031        //LLL   ch_.send(pktbuf_, len);
1032        ch->send(pktbuf_, len);
1033       
1034        /*
1035      rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(len + 28) - rtcp_avg_size_);
1036         
1037          // compute the time to the next report.  we do this here
1038          // because we need to know if there were any active sources
1039          // during the last report period (nrr above) & if we were
1040          // a source.  The bandwidth limit for rtcp traffic was set
1041          // on startup from the session bandwidth.  It is the inverse
1042          // of bandwidth (ie., ms/byte) to avoid a divide below.
1043       
1044        //      double ibw = rtcp_inv_bw_;
1045        if (nrr) {
1046        // there were active sources
1047        //              if (we_sent) {
1048        ibw *= 1./RTCP_SENDER_BW_FRACTION;
1049        nsrc = nrr;
1050        } else {
1051        ibw *= 1./RTCP_RECEIVER_BW_FRACTION;
1052        nsrc -= nrr;
1053        }
1054        }
1055        double rint = rtcp_avg_size_ * double(nsrc) * ibw;
1056        if (rint < RTCP_MIN_RPT_TIME * 1000.)
1057                rint = RTCP_MIN_RPT_TIME * 1000.;
1058        rint_ = rint;
1059        rt_.msched(int(fmod(double(random()), rint) + rint * .5 + .5));
1060        */
1061       
1062        // Call timer adaption for each layer
1063        ch->adapt(nsrc, nrr, we_sent);
1064        ch->sample_size(len);
1065       
1066        //      sm.CheckActiveSources(rint);
1067        if (layer == 0)
1068                sm.CheckActiveSources(ch->rint());
1069       
1070}
1071
1072int SessionManager::build_bye(rtcphdr* rh, Source& ls)
1073{
1074        int flags = RTP_VERSION << 14 | 1 << 8 | RTCP_PT_BYE;
1075        rh->rh_flags = ntohs(flags);
1076        rh->rh_len = htons(1);
1077        rh->rh_ssrc = ls.srcid();
1078        return (8);
1079}
1080
1081/*
1082 * receive an RTP data packet
1083 */
1084void SessionManager::recv(DataHandler* dh)
1085{
1086        int layer = dh - dh_;
1087        pktbuf* pb = pool_->alloc(layer);
1088        Address * addrp;
1089        /* leave room in case we need to expand rtpv1 into an rtpv2 header */
1090        /* XXX the free mem routine didn't like it ... */
1091        //u_char* bp = &pktbuf_[4];
1092        //u_char* bp = pktbuf_;
1093       
1094        int cc = dh->recv(pb->data, sizeof(pb->data), addrp);
1095        //int cc = dh->recv(bp, 2 * RTP_MTU - 4, addrp);
1096        if (cc <= 0) {
1097                pb->release();
1098                return;
1099        }
1100
1101    // Ignore loopback packets
1102        if (!loopback_) {
1103                rtphdr* rh = (rtphdr*)pb->data;
1104                SourceManager& sm = SourceManager::instance();
1105                if (rh->rh_ssrc == (*sm.localsrc()).srcid()) {
1106                        pb->release();  // releasing loopback packet
1107                        return;
1108                }
1109        } // now, loopback packets ignored (if disabled)
1110
1111        int version = pb->data[0] >> 6;
1112        //int version = *(u_char*)rh >> 6;
1113        if (version != 2) {
1114                ++badversion_;
1115                pb->release();
1116                return;
1117        }
1118        if (cc < (int)sizeof(rtphdr)) {
1119                ++nrunt_;
1120                pb->release();
1121                return;
1122        }
1123        pb->len = cc;
1124
1125        //bp += sizeof(*rh);
1126        //cc -= sizeof(*rh);
1127        demux(pb, *addrp);
1128}
1129
1130void SessionManager::demux(pktbuf* pb, Address & addr)
1131{
1132        rtphdr* rh = (rtphdr*)pb->data;
1133        u_int32_t srcid = rh->rh_ssrc;
1134        int flags = ntohs(rh->rh_flags);
1135        // for LIP SYNC
1136        //SV-XXX: unused: u_char *pkt = pb->data - sizeof(*rh);
1137
1138        if ((flags & RTP_X) != 0) {
1139        /*
1140        * the minimal-control audio/video profile
1141        * explicitly forbids extensions
1142                */
1143                ++badext_;
1144                pb->release();
1145                return;
1146        }
1147
1148        /*
1149         * Check for illegal payload types.  Most likely this is
1150         * a session packet arriving on the data port.
1151         */
1152        int fmt = flags & 0x7f;
1153        if (!check_format(fmt)) {
1154                ++badfmt_;
1155                pb->release();
1156                return;
1157        }
1158
1159        SourceManager& sm = SourceManager::instance();
1160        u_int16_t seqno = ntohs(rh->rh_seqno);
1161        Source* s = sm.demux(srcid, addr, seqno, pb->layer);
1162        if (s == 0) {
1163        /*
1164        * Takes a pair of validated packets before we will
1165        * believe the source.  This prevents a runaway
1166        * allocation of Source data structures for a
1167        * stream of garbage packets.
1168        *
1169        * NOTE: This check is disabled for now in demux as it interferes
1170        * with the congestion control - e.g. 1st packet always missing
1171                */
1172                pb->release();
1173                return;
1174        }
1175
1176        Source::Layer& sl = s->layer(pb->layer);
1177        timeval now = unixtime();
1178        int ecn = dh_[0].net()->recvd_tos() & 0x03;
1179        debug_msg("TOS byte:%d\n",dh_[0].net()->recvd_tos());
1180        switch (ecn) {
1181          case NOT_ECT:
1182                sl.not_ect(1);
1183                break;
1184          case ECT0:
1185                sl.ect0(1);
1186                break;
1187          case ECT1:
1188                sl.ect1(1);
1189                break;
1190          case ECN_CE:
1191                sl.ecn_ce(1);
1192                break;
1193          default:
1194                debug_msg("Bizarre TOS byte:%d\n",dh_[0].net()->recvd_tos());
1195        }
1196        // RTP data receiver need to extract seqno
1197        // and send XR report back to the sender.
1198        if (!am_i_sender()) {
1199                // retrieve RTP seqno
1200                extern int ecn_mode__;
1201                seqno = ntohs(rh->rh_seqno);
1202
1203                // if ECN_CE & ECN_AS_LOSS then act like packet is lost
1204                if (!(ecn == ECN_CE && ecn_mode__ == ECN_AS_LOSS) ) {
1205                    switch (cc_type_) {
1206                    case WBCC:
1207                      // pass seqno to tfwc receiver to build up AckVec
1208                      fprintf(stderr, "\n\treceived seqno: %d", seqno);
1209                      tfwc_rcvr_.recv_seqno(seqno);
1210                      break;
1211                    case RBCC:
1212                      // pass seqno to tfrc receiver to build up AckVec
1213                      fprintf(stderr, "\n\treceived seqno: %d", seqno);
1214                      tfrc_rcvr_.recv_seqno(seqno);
1215                      break;
1216                    }
1217                    // Only send receiver side XR report (AckVec) when pkt not 'lost'
1218                    ch_->send_ackv();
1219                    debug_msg("NOT Treating ECN as LOSS (ecn:%d, mode:%d)\n",ecn,ecn_mode__);
1220                } else
1221                    debug_msg("Treating ECN as LOSS (ecn:%d, mode:%d)\n",ecn,ecn_mode__);
1222                send_fb_ecn(ch_, sl, seqno, ntohl(rh->rh_ssrc));
1223        }
1224       
1225        fprintf(stderr, "\n\treceived frame_no: %d\n\n", rh->frame_no);
1226
1227        /* inform this source of the mbus */
1228        s->mbus(&mb_);
1229       
1230        sl.lts_data(now);
1231        sl.sts_data(rh->rh_ts);
1232       
1233        // extract CSRC count (CC field); increment pb->dp data pointer & adjust length accordingly
1234        int cnt = (flags >> 8) & 0xf;
1235        if (cnt > 0) {
1236                //u_char* nh = (u_char*)rh + (cnt << 2);
1237                rtphdr hdr = *rh;
1238                pb->dp += (cnt << 2);
1239                pb->len -= (cnt << 2);
1240                u_int32_t* bp = (u_int32_t*)(rh + 1);
1241                while (--cnt >= 0) {
1242                        u_int32_t csrc = *(u_int32_t*)bp;
1243                        bp += 4;
1244                        Source* cs = sm.lookup(csrc, srcid, addr);
1245                        cs->layer(pb->layer).lts_data(now);
1246                        cs->action();
1247                }
1248                //              rtphdr hdr = *rh;
1249                //              rh = (rtphdr*)nh;
1250                /*XXX move header up so it's contiguous with data*/
1251                rh = (rtphdr*)pb->dp;
1252                *rh = hdr;
1253        } else
1254                s->action();
1255
1256        if (s->sync() && lipSyncEnabled()) { 
1257                /*
1258                 * Synchronisation is enabled on this source;
1259                 * video packets have to
1260                 * be buffered, their playout point scheduled, and the
1261                 * playout delays communicated with the audio tool ...
1262                 */ 
1263
1264                /*
1265                * XXX bit rate doesn't include rtpv1 options;
1266                * but v1 is going away anyway.
1267                */
1268                //              int dup = s->cs(seqno);
1269                //              s->np(1);
1270                //              s->nb(cc + sizeof(*rh));
1271                int dup = sl.cs(seqno, s);
1272                sl.np(1);
1273                sl.nb(pb->len);
1274                if (dup) {
1275                        pb->release();
1276                        return;
1277                }
1278                if (flags & RTP_M) // check if reach frame boundaries
1279                        sl.nf(1);
1280               
1281                //s->recv(pkt, rh, pb, pb->len); // this should invoke Source::recv and buffer
1282                //s->recv(bp); // this should invoke Source::recv and buffer
1283               
1284                pktbuf_ = (u_char*)new_blk();
1285        } /* synced */
1286
1287        else { /* ... playout video packets as they arrive */
1288                /*
1289                 * This is a data packet.  If the source needs activation,
1290                 * or the packet format has changed, deal with this.
1291                 * Then, hand the packet off to the packet handler.
1292                 * XXX might want to be careful about flip-flopping
1293                 * here when format changes due to misordered packets
1294                 * (easy solution -- keep rtp seqno of last fmt change).
1295                 */
1296                PacketHandler* h = s->handler();
1297                if (h == 0)
1298                        h = s->activate(fmt);
1299                else if (s->format() != fmt)
1300                        h = s->change_format(fmt);
1301               
1302                        /*
1303                        * XXX bit rate doesn't include rtpv1 options;
1304                        * but v1 is going away anyway.
1305                */
1306                //              int dup = s->cs(seqno);
1307                //              s->np(1);
1308                //              s->nb(cc + sizeof(*rh));
1309                int dup = sl.cs(seqno, s);
1310                sl.np(1);
1311                sl.nb(pb->len);
1312                if (dup){
1313                        pb->release();
1314                        return;
1315                }
1316                if (flags & RTP_M)
1317                        sl.nf(1);
1318#ifdef notdef
1319        /* This should move to the handler */
1320        /*XXX could get rid of hdrlen and move run check into recv method*/
1321               
1322                int hlen = h->hdrlen();
1323                cc -= hlen;
1324                if (cc < 0) {
1325                        sl.runt(1);
1326                        pb->release();
1327                        return;
1328                }
1329#endif
1330                if (s->mute()) {
1331                        pb->release();
1332                        return;
1333                }
1334                //h->recv(rh, bp + hlen, cc);
1335                h->recv(pb);
1336        } /* not sync-ed */
1337
1338}
1339
1340void SessionManager::parse_rr_records(u_int32_t, rtcp_rr*, int,
1341                                      const u_char*, Address &)
1342{
1343}
1344                                     
1345
1346void SessionManager::parse_sr(rtcphdr* rh, int flags, u_char*ep,
1347                                                          Source* ps, Address & addr, int layer)
1348{
1349        rtcp_sr* sr = (rtcp_sr*)(rh + 1);
1350        Source* s;
1351        u_int32_t ssrc = rh->rh_ssrc;
1352        if (ps->srcid() != ssrc)
1353                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1354        else
1355                s = ps;
1356       
1357        Source::Layer& sl = s->layer(layer);
1358       
1359        timeval now = unixtime();
1360
1361        sl.lts_ctrl(now);
1362        sl.sts_ctrl(ntohl(sr->sr_ntp.upper) << 16 |
1363                ntohl(sr->sr_ntp.lower) >> 16);
1364       
1365        s->rtp_ctrl(ntohl(sr->sr_ts));
1366        u_int32_t t = ntptime(now);
1367        s->map_ntp_time(t);
1368        s->map_rtp_time(s->convert_time(t));
1369        s->rtp2ntp(1);
1370
1371        int cnt = flags >> 8 & 0x1f;
1372        parse_rr_records(ssrc, (rtcp_rr*)(sr + 1), cnt, ep, addr);
1373}
1374
1375void SessionManager::parse_rr(rtcphdr* rh, int flags, u_char* ep,
1376                                                          Source* ps, Address & addr, int layer)
1377{
1378        Source* s;
1379        u_int32_t ssrc = rh->rh_ssrc;
1380        if (ps->srcid() != ssrc)
1381                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1382        else
1383                s = ps;
1384       
1385        s->layer(layer).lts_ctrl(unixtime());
1386        int cnt = flags >> 8 & 0x1f;    // reception report count
1387        parse_rr_records(ssrc, (rtcp_rr*)(rh + 1), cnt, ep, addr);
1388}
1389
1390void SessionManager::parse_fb(rtcphdr* rh, int flags, u_char* ep,
1391                                                          Source* ps, Address & addr, int layer)
1392{
1393        Source* s;
1394        u_int32_t ssrc = rh->rh_ssrc;
1395        int fb_fmt = flags >>8 & 0x1f;  // FB Format(FMT)
1396
1397        if (ps->srcid() != ssrc)
1398                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1399        else
1400                s = ps;
1401       
1402        Source::Layer& sl = s->layer(layer);
1403       
1404        switch (fb_fmt) {
1405         case RTPFB_FMT_ECN: {
1406                struct rtcp_fb_ecn *fb_ecn = (rtcp_fb_ecn*)(rh + 1);
1407                sl.lts_ctrl(unixtime());
1408                sl.set_ecn_ce(ntohs(fb_ecn->ecn_ce));
1409                sl.set_ect0(ntohs(fb_ecn->ect0));
1410                sl.set_ect1(ntohs(fb_ecn->ect1));
1411                sl.set_not_ect(ntohs(fb_ecn->not_ect));
1412                debug_msg("Received RTCP ECN FB: seq_n_loss:%d, ecn_ecn:%d, not_ect:%d, ect0:%d, ect1:%d\n", ntohl(fb_ecn->seq_n_loss),ntohs(fb_ecn->ecn_ce), ntohs(fb_ecn->not_ect), ntohs(fb_ecn->ect0), ntohs(fb_ecn->ect1));
1413                break;
1414                             }
1415         default:
1416                fprintf(stderr, "\t>> Received  UNRECOGNISED RTCP FB packet FMT: %d\n", fb_fmt);
1417                break;
1418        }
1419}
1420
1421void SessionManager::parse_xr(rtcphdr* rh, int flags, u_char* ep,
1422                Source* ps, Address & addr, int layer, bool ack_clock, pktbuf* pb)
1423{
1424        Source* s;
1425        u_int32_t ssrc = rh->rh_ssrc;   // RTCP's ssrc
1426        if (ps->srcid() != ssrc)
1427                s = SourceManager::instance().lookup(ssrc, ssrc, addr);
1428        else
1429                s = ps;
1430
1431        s->layer(layer).lts_ctrl(unixtime());
1432        int cnt = flags >> 8 & 0x1f;    // reception report count
1433        parse_xr_records(ssrc, (rtcp_xr*)(rh + 1), cnt, ep, addr, ack_clock, pb);
1434}
1435
1436void SessionManager::parse_xr_records(u_int32_t ssrc, rtcp_xr* xr, int cnt,
1437                const u_char* ep, Address & addr, bool ack_clock, pktbuf* pb)
1438{
1439        parse_xr_banner_top();
1440        UNUSED(ssrc);
1441        UNUSED(cnt);
1442        UNUSED(ep);
1443        UNUSED(addr);
1444
1445        // XR repport block
1446        rtcp_xr_BT_1_hdr *xr1;
1447
1448        // so_timestamp
1449        double so_rtime = 0.;
1450
1451        if ( xr->BT == XR_BT_1 && xr->xr_flag == 0 ) {
1452                // XR block type 1
1453                xr1 = (rtcp_xr_BT_1_hdr *) xr;
1454
1455                // parse XR information (xrssrc, begin, end)
1456                u_int32_t xrssrc = ntohl(xr1->ssrc); UNUSED(xrssrc);
1457                u_int16_t begin  = ntohs(xr1->begin_seq);
1458                u_int16_t end    = ntohs(xr1->end_seq);
1459
1460                // parse XR chunks
1461                u_int16_t *chunk = (u_int16_t *) ++xr1;
1462
1463                // -----------------------------------------------------------------*
1464                // i am an RTP data sender (receive ackvec)                         *
1465                // -----------------------------------------------------------------*
1466                if (am_i_sender()) {
1467                  // get SO_TIMESTAMP
1468                  so_rtime = ch_->net()->recvd_so_time() - tx_ts_offset();
1469                  //sender_xr_ts_info(so_rtime);
1470                  int xrate;
1471
1472                  fprintf(stderr, ">>> parse_xr - i_am_sender\n");
1473                  fprintf(stderr, "\tincomingXR\tnow: %f\n", so_rtime);
1474                  //sender_xr_info(__FILE__,__LINE__,begin, end, xr1, xrlen);
1475
1476                  switch (cc_type_) {
1477                        case WBCC:
1478                        // TFWC sender (getting AckVec)
1479                        tfwc_sndr_.recv(xr->BT,begin,end,chunk,so_rtime,ack_clock,pb);
1480                        // we need to call Transmitter::output(pb) to make Ack driven
1481                        xrate=(tfwc_sndr_.xrate()*8)/1000;
1482                        if (!xrate) xrate = 1;
1483                        bps(xrate);
1484                        if (grabber_) grabber_->bps(xrate);
1485                        debug_msg("now: %f Setting kbps: %d\n",so_rtime, kbps_);
1486                        if(ack_clock)
1487                                tfwc_output(ack_clock);
1488                        break;
1489
1490                        case RBCC:
1491                        // TFRC sender (getting AckVec)
1492                        tfrc_sndr_.recv(xr->BT,begin,end,chunk,so_rtime,ack_clock,pb);
1493                        xrate=(tfrc_sndr_.xrate()*8)/1000;
1494                        if (!xrate) xrate = 1;
1495                        bps(xrate);
1496                        if (grabber_) grabber_->bps(xrate);
1497                        debug_msg("now: %f Setting kbps: %d\n",so_rtime, kbps_);
1498                        // XXX
1499                        if(ack_clock)
1500                                tfrc_output(ack_clock);
1501                        break;
1502                  } // switch (cc_type_)
1503                }
1504                // -----------------------------------------------------------------*
1505                // i am an RTP data receiver (receive ackofack)                     *
1506                // -----------------------------------------------------------------*
1507                else {
1508                        fprintf(stderr, ">>> parse_xr - i_am_receiver\n");
1509                        receiver_xr_info(__FILE__,__LINE__,chunk);
1510                        switch (cc_type_) {
1511                        // TFWC receiver (getting ackofack)
1512                        case WBCC:
1513                          tfwc_rcvr_.recv_aoa(xr->BT, chunk);
1514                          break;
1515                        // TFRC receiver
1516                        case RBCC:
1517                          tfrc_rcvr_.recv_aoa(xr->BT, chunk);
1518                          break;
1519                        }
1520                } // end of XR block type 1
1521                // -----------------------------------------------------------------*
1522        } else {
1523                // XXX
1524                debug_msg("UNKNOWN RTCP XR Packet: BT:%d\n", xr->BT);
1525        }
1526        parse_xr_banner_bottom();
1527}
1528
1529/*
1530 * check if XR has arrived
1531 * @pb: RTP data packet
1532 * @ack_clock: this SHOULD be always set to 1,
1533 *             although it is not an ack-clocking actually
1534 *             (i.e., check XR reception ONLY)
1535 * return: total number of bytes that the retrieved Acks have given
1536 */
1537int SessionManager::check_xr_arrival(pktbuf* pb, bool ack_clock){
1538        int i = 0; int cc = 0;
1539        // receive XR before sending
1540        while (recv_xreport(ch_, pb, ack_clock) > 0) {
1541        cc += tfwc_sndr_.b_jacked(); i++;
1542        //      xr_arrival_info(cc, i);
1543        }
1544        return (cc);
1545}
1546
1547// receive XR (AckVec)
1548int SessionManager::recv_xreport(CtrlHandler *ch, pktbuf* pb, bool ack_clock) {
1549        // timestamp for XR reception
1550        recv_ts_ = tx_get_now();
1551
1552        Address * srcp;
1553        int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);
1554
1555        // return when no RTCP arrived in the socket buffer
1556        if (cc <= 0)
1557                return cc;
1558
1559        rtcphdr* rh = (rtcphdr *)pktbuf_;
1560        // ignore loopback packets
1561        if (!loopback_) {
1562                SourceManager& sm = SourceManager::instance();
1563                if (rh->rh_ssrc == (*sm.localsrc()).srcid())
1564                return 0;
1565        }
1566        if (cc < int(sizeof(*rh))) {
1567                ++nrunt_;
1568                return 0;
1569        }
1570
1571        // filter out junk report and other types of RTCP packet.
1572        // here, we expect it to be XR only.
1573        switch(ntohs(rh->rh_flags) & 0xc0ff) {
1574        case RTP_VERSION << 14 | RTCP_PT_XR:
1575        case RTP_VERSION << 14 | RTCP_PT_RTPFB:
1576                break;
1577        case RTP_VERSION << 14 | RTCP_PT_SR:
1578        case RTP_VERSION << 14 | RTCP_PT_RR:
1579        case RTP_VERSION << 14 | RTCP_PT_BYE:
1580                debug_msg("warning: detected wrong RTCP packet types!\n");
1581                return 0;
1582        default:
1583                ++badversion_;
1584                return 0;
1585        }
1586
1587        // we're safe to assume that this is XR packet.
1588        // -- compute average size estimator.
1589        rtcp_avg_size_ += RTCP_SIZE_GAIN * (double (cc + 28) - rtcp_avg_size_);
1590        Address & addr = *srcp;
1591
1592        // XXX sdes related stuffs (do we need it here?)
1593        // -- first record in compound packet must be the ssrc of the sender of this
1594        // packet. pull it out for the use in sdes parsing.
1595        // -- note: sdes record does not contain the ssrc of the sender.
1596        u_int32_t ssrc = rh->rh_ssrc;
1597        Source* ps = SourceManager::instance().lookup(ssrc, ssrc, addr);
1598        if (ps == 0) return 0;
1599
1600        int layer = ch - ch_;
1601        int rtcp_pkt_id;
1602
1603        // parse RTCP records (while loop enables to parse "compound packet")
1604        // -- we expect it to be XR.
1605        u_char* epack = (u_char *)rh + cc;
1606        while ((u_char *)rh < epack) {
1607                u_int len = (ntohs(rh->rh_len) << 2) + 4;
1608                u_char* ep = (u_char *)rh + len;
1609                // bad length
1610                if (ep > epack) {
1611                        ps->badsesslen(1);
1612                        return 0;
1613                }
1614                // bad version
1615                u_int flags = ntohs(rh->rh_flags);
1616                if (flags >> 14 != RTP_VERSION) {
1617                        ps->badsessver(1);
1618                        return 0;
1619                }
1620
1621                switch (flags & 0xff) {
1622                case RTCP_PT_XR:
1623                        rtcp_pkt_id = RTCP_PT_XR;
1624                        parse_xr(rh, flags, ep, ps, addr, layer, !(ack_clock), pb);
1625                        debug_msg("SessionManager::recv_xreport: parsed RTCP XR packet %d\n", rtcp_pkt_id);
1626                        break;
1627                case RTCP_PT_SR:
1628                        rtcp_pkt_id = RTCP_PT_SR;
1629                case RTCP_PT_RR:
1630                        rtcp_pkt_id = RTCP_PT_RR;
1631                case RTCP_PT_BYE:
1632                        rtcp_pkt_id = RTCP_PT_BYE;
1633                case RTCP_PT_SDES:
1634                        rtcp_pkt_id = RTCP_PT_SDES;
1635                        debug_msg("warning: wrong RTCP packet type! %d\n", rtcp_pkt_id);
1636                        return 0;
1637                case RTCP_PT_RTPFB:
1638                        debug_msg("Received: RTCP FB packet type %d\n", flags & 0xff);
1639                        parse_fb(rh, flags, ep, ps, addr, layer);
1640                        break;
1641
1642                default:
1643                        debug_msg("warning: Unrecognised RTCP packet type! %d\n", flags & 0xff);
1644                        ps->badsessopt(1);
1645                        break;
1646                }
1647                rh = (rtcphdr *)ep;
1648        }
1649        return (cc);
1650}
1651
1652// send AckVec
1653// (TFWC data receiver side)
1654void CtrlHandler::send_ackv()
1655{
1656        i_am_receiver();
1657        sm_->build_ackv_pkt(this);
1658}
1659
1660// send loss event rate
1661// (TFRC data receiver side)
1662void CtrlHandler::send_p() {
1663        i_am_receiver();
1664        sm_->build_p_pkt(this);
1665}
1666
1667// send timestamp echo
1668void CtrlHandler::send_ts_echo()
1669{
1670        i_am_receiver();
1671        sm_->build_ts_echo_pkt(this);
1672}
1673
1674// build AckVec packet
1675// (TFWC data receiver side)
1676void SessionManager::build_ackv_pkt(CtrlHandler* ch)
1677{
1678        // RTCP XR (block type 1)
1679        // this block contains ackvec
1680        build_xreport(ch, XR_BT_1);
1681}
1682
1683// build loss event rate report packet
1684// (TFRC data receiver side)
1685void SessionManager::build_p_pkt(CtrlHandler* ch)
1686{
1687        // this block conveys loss event rate
1688        build_xreport (ch, XR_BT_1);
1689}
1690
1691void SessionManager::build_ts_echo_pkt(CtrlHandler* ch)
1692{
1693        // RTCP XR (block type 3)
1694        // this block contains timestamp echo
1695        build_xreport(ch, XR_BT_3);
1696}
1697
1698int SessionManager::sdesbody(u_int32_t* p, u_char* ep, Source* ps,
1699                                                Address & addr, u_int32_t ssrc, int layer)
1700{
1701        Source* s;
1702        u_int32_t srcid = *p;
1703        if (ps->srcid() != srcid)
1704                s = SourceManager::instance().lookup(srcid, ssrc, addr);
1705        else
1706                s = ps;
1707        if (s == 0)
1708                return (0);
1709                /*
1710                * Note ctrl packet since we will never see any direct ctrl packets
1711                * from a source through a mixer (and we don't want the source to
1712                * time out).
1713        */
1714        s->layer(layer).lts_ctrl(unixtime());
1715       
1716        u_char* cp = (u_char*)(p + 1);
1717        while (cp < ep) {
1718                char buf[256];
1719
1720                u_int type = cp[0];
1721                if (type == 0) {
1722                        /* end of chunk */
1723                        return (((cp - (u_char*)p) >> 2) + 1);
1724                }
1725                u_int len = cp[1];
1726                u_char* eopt = cp + len + 2;
1727                if (eopt > ep)
1728                        return (0);
1729
1730                if (type >= RTCP_SDES_MIN && type <= RTCP_SDES_MAX) {
1731                        memcpy(buf, (char*)&cp[2], len);
1732                        buf[len] = 0;
1733                        s->sdes(type, buf);
1734                } // else
1735                        /*XXX*/;
1736
1737                cp = eopt;
1738        }
1739        return (0);
1740}
1741
1742void SessionManager::parse_sdes(rtcphdr* rh, int flags, u_char* ep, Source* ps,
1743                                                                Address & addr, u_int32_t ssrc, int layer)
1744{
1745        int cnt = flags >> 8 & 0x1f;
1746        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1747        while (--cnt >= 0 && (u_char*)p < ep) {
1748                int n = sdesbody(p, ep, ps, addr, ssrc, layer);
1749                if (n == 0)
1750                        break;
1751                p += n;
1752        }
1753        if (cnt >= 0)
1754                ps->badsdes(1);
1755}
1756
1757void SessionManager::parse_bye(rtcphdr* rh, int flags, u_char* ep, Source* ps)
1758{
1759        int cnt = flags >> 8 & 0x1f;
1760        u_int32_t* p = (u_int32_t*)&rh->rh_ssrc;
1761
1762        while (--cnt >= 0) {
1763                if (p >= (u_int32_t*)ep) {
1764                        ps->badbye(1);
1765                        return;
1766                }
1767                Source* s;
1768                if (ps->srcid() != rh->rh_ssrc)
1769                        s = SourceManager::instance().consult(*p);
1770                else
1771                        s = ps;
1772                if (s != 0)
1773                        s->lts_done(unixtime());
1774                ++p;
1775        }
1776}
1777
1778/*
1779 * Receive an rtcp packet (from the control port).
1780 */
1781int SessionManager::recv(CtrlHandler* ch)
1782{
1783        // timestamp for XR reception
1784        recv_ts_ = tx_get_now();
1785
1786        Address * srcp;
1787        int cc = ch->recv(pktbuf_, 2 * RTP_MTU, srcp);
1788        if (cc <= 0)
1789                return (cc);
1790
1791        rtcphdr* rh = (rtcphdr*)pktbuf_;
1792
1793    // Ignore loopback packets
1794        if (!loopback_) {
1795                SourceManager& sm = SourceManager::instance();
1796                if (rh->rh_ssrc == (*sm.localsrc()).srcid())
1797                        return 0;
1798        }
1799
1800        if (cc < int(sizeof(*rh))) {
1801                ++nrunt_;
1802                return 0;
1803        }
1804
1805        /*
1806         * try to filter out junk: first thing in packet must be
1807         * sr, rr, xr or bye & version number must be correct.
1808         */
1809        switch(ntohs(rh->rh_flags) & 0xc0ff) {
1810        case RTP_VERSION << 14 | RTCP_PT_SR:
1811        case RTP_VERSION << 14 | RTCP_PT_RR:
1812        case RTP_VERSION << 14 | RTCP_PT_XR:
1813        case RTP_VERSION << 14 | RTCP_PT_RTPFB:
1814        case RTP_VERSION << 14 | RTCP_PT_BYE:
1815                break;
1816        default:
1817                /*
1818                 * XXX should further categorize this error -- it is
1819                 * likely that people mis-implement applications that
1820                 * don't put something other than SR,RR,XR,BYE first.
1821                 */
1822                ++badversion_;
1823                return 0;
1824        }
1825        /*
1826         * at this point we think the packet's valid.  Update our average
1827         * size estimator.  Also, there's valid ssrc so charge errors to it
1828         */
1829        rtcp_avg_size_ += RTCP_SIZE_GAIN * (double(cc + 28) - rtcp_avg_size_);
1830        Address & addr = *srcp;
1831
1832        /*
1833         * First record in compound packet must be the ssrc of the
1834         * sender of the packet.  Pull it out here so we can use
1835         * it in the sdes parsing, since the sdes record doesn't
1836         * contain the ssrc of the sender (in the case of mixers).
1837         */
1838        u_int32_t ssrc = rh->rh_ssrc;
1839        Source* ps = SourceManager::instance().lookup(ssrc, ssrc, addr);
1840        if (ps == 0)
1841                return 0;
1842       
1843        int layer = ch - ch_;
1844        /*
1845         * Outer loop parses multiple RTCP records of a "compound packet".
1846         * There is no framing between records.  Boundaries are implicit
1847         * and the overall length comes from UDP.
1848         */
1849        u_char* epack = (u_char*)rh + cc;
1850        while ((u_char*)rh < epack) {
1851                u_int len = (ntohs(rh->rh_len) << 2) + 4;
1852                u_char* ep = (u_char*)rh + len;
1853                if (ep > epack) {
1854                        ps->badsesslen(1);
1855                        return 0;
1856                }
1857                u_int flags = ntohs(rh->rh_flags);
1858                if (flags >> 14 != RTP_VERSION) {
1859                        ps->badsessver(1);
1860                        return 0;
1861                }
1862                switch (flags & 0xff) {
1863
1864                case RTCP_PT_SR:
1865                        debug_msg("Received: RTCP SR packet type %d\n", flags & 0xff);
1866                        parse_sr(rh, flags, ep, ps, addr, layer);
1867                        break;
1868
1869                case RTCP_PT_RR:
1870                        debug_msg("Received: RTCP RR packet type %d\n", flags & 0xff);
1871                        parse_rr(rh, flags, ep, ps, addr, layer);
1872                        break;
1873
1874                case RTCP_PT_XR:
1875                        debug_msg("Received: RTCP XR packet type %d\n", flags & 0xff);
1876                        parse_xr(rh, flags, ep, ps, addr, layer, 1);
1877                        break;
1878
1879                case RTCP_PT_RTPFB:
1880                        debug_msg("Received: RTCP FB packet type %d\n", flags & 0xff);
1881                        parse_fb(rh, flags, ep, ps, addr, layer);
1882                        break;
1883
1884                case RTCP_PT_SDES:
1885                        parse_sdes(rh, flags, ep, ps, addr, ssrc, layer);
1886                        break;
1887
1888                case RTCP_PT_BYE:
1889                        parse_bye(rh, flags, ep, ps);
1890                        break;
1891
1892                default:
1893                        ps->badsessopt(1);
1894                        break;
1895                }
1896                rh = (rtcphdr*)ep;
1897        }
1898        return (cc);
1899}
Note: See TracBrowser for help on using the browser.