root/vic/branches/cc/cc/tfwc_rcvr.cpp @ 4502

Revision 4502, 7.3 KB (checked in by soohyunc, 5 years ago)

further improvement on AckVec? (receiver side)

-- resolved a weird artifact on handling multiple AckVec? chunks

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Rev URL
Line 
1/*
2 * Copyright (c) 2008 University College London
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 MASH Research
16 *  Group at the University of California Berkeley.
17 * 4. Neither the name of the University nor of the Research Group may be
18 *    used to endorse or promote products derived from this software without
19 *    specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $Id$
34 */
35
36#include "assert.h"
37#include "config.h"
38#include "timer.h"
39#include "rtp.h"
40#include "inet.h"
41#include "pktbuf-rtp.h"
42#include "vic_tcl.h"
43#include "module.h"
44#include "transmitter.h"
45#include "tfwc_rcvr.h"
46
47TfwcRcvr::TfwcRcvr() :
48        currseq_(0),
49        prevseq_(0),
50        ackofack_(0),
51        begins_(0),
52        ends_(0),
53        currNumElm_(1),
54        prevNumElm_(1),
55        currNumVec_(1),
56        prevNumVec_(1)
57{
58        // declare/initialize tfwcAV
59        tfwcAV = (u_int16_t *) malloc(AVSZ * sizeof(u_int16_t));
60        bzero(tfwcAV, AVSZ);
61}
62
63void TfwcRcvr::tfwc_rcvr_recv(u_int16_t type, u_int16_t seqno,
64                                u_int16_t *chunk, int num_chunks)
65{
66        // variables
67        int numLoss             = 0;    // number of packet loss count
68        int diffNumElm  = 0;    // difference of AckVec elements (curr vs. prev)
69        int diffNumVec  = 0;    // difference of AckVec array (curr vs. prev)
70        int addiNumVec  = 0;    // additional AckVec array required
71
72        // parse the received seqno and ackofack
73        if (type == XR_BT_1) {
74                // received data packet seqno
75                currseq_ = seqno;
76                // XXX received ackofack (currently only one chunk)
77                ackofack_ = ntohs(chunk[num_chunks-1]);
78
79                // number of AckVec element
80                currNumElm_     = currseq_ - ackofack_;
81                diffNumElm      = currNumElm_ - prevNumElm_;
82                int x = currNumElm_%BITLEN;
83                int y = prevNumElm_%BITLEN;
84
85                // number of chunks for building tfwcAV
86                currNumVec_     = getNumVec(currNumElm_);
87                diffNumVec      = currNumVec_ - prevNumVec_;
88
89                // for debugging purpose
90                printf("    [%s +%d] seqno:%d, ackofack:%d\n",
91                        __FILE__,__LINE__,currseq_,ackofack_);
92                printf("    [%s +%d] currNumElm:%d, prevNumElm:%d\n",
93                        __FILE__,__LINE__,currNumElm_,prevNumElm_);
94                printf("    [%s +%d] currNumVec:%d, prevNumVec:%d\n",
95                        __FILE__,__LINE__,currNumVec_,prevNumVec_);
96
97                // there is no packet loss (or reordering)
98                if (currseq_ == prevseq_ + 1) {
99                        // we just need the same number of AckVec elements,
100                        // hence just left shift by one and clear the top bit
101                        if (diffNumElm == 0) {
102                                // set next bit to 1
103                                SET_BIT_VEC(tfwcAV[currNumVec_-1], 1);
104
105                                // and clear the top bit which we don't need it anymore
106                                if (x != 0)
107                                        CLR_BIT_AT(tfwcAV[currNumVec_-1], x+1);
108                        }
109                        // we just need less number of AckVec elements,
110                        // hence first free unnecessary AckVec chunk(s) and set bit.
111                        else if (diffNumElm < 0) {
112                                // firstly, freeing unnecessary AcvVec chunk(s)
113                                if (currNumVec_ != prevNumVec_) {
114                                        for (int i = prevNumVec_; i > currNumVec_; i--) {
115                                                for (int j = 1; j <= BITLEN; j++)
116                                                        SET_BIT_VEC(tfwcAV[i-1], 0);
117                                        }
118                                }
119                                // set next bit to 1
120                                SET_BIT_VEC(tfwcAV[currNumVec_-1], 1);
121                                // and clear the bit(s) that we don't need it anymore
122                                int k = (x == 0) ? BITLEN: x;
123                                for (int i = BITLEN; i > k; i--)
124                                        CLR_BIT_AT(tfwcAV[currNumVec_-1], i);
125                        }
126                        // otherwise, just set next bit to 1
127                        // (i.e., we need more AckVec elements)
128                        else
129                                SET_BIT_VEC(tfwcAV[currNumVec_-1], 1);
130                }
131                // we have one or more packet losses (or reordering)
132                else {
133                        // number of packet loss
134                        numLoss = currseq_ - prevseq_ - 1;
135                        int z = numLoss%BITLEN;
136
137                        // we need more AckVec chunks (maybe one or more)
138                        if (currNumVec_ != prevNumVec_) {
139                                // currently available spaces in the previous tfwcAV array
140                                int numAvail = BITLEN - y;
141
142                                // first, fill up zeros into those available spaces
143                                for (int i = 0; i < numAvail; i++) {
144                                        SET_BIT_VEC(tfwcAV[prevNumVec_-1], 0);
145                                        numLoss--;
146                                }
147
148                                // then, calculate "additional" AckVec chunks required
149                                addiNumVec = getNumVec(numLoss);
150
151                                // fill up zeros accordingly if addiNumVec is greater than 1
152                                for (int i = 0; i < (addiNumVec - 1); i++) {
153                                        for (int j = 0; j < BITLEN; j++) {
154                                                SET_BIT_VEC(tfwcAV[prevNumVec_+i], 0);
155                                                numLoss--;
156                                        }
157                                }
158
159                                // finally, fill up zeros at the latest AckVec chunk
160                                for (int i = 0; i < z; i++) {
161                                        SET_BIT_VEC(tfwcAV[prevNumVec_+addiNumVec-1], 0);
162                                }
163                        }
164                        // current AckVeck chunk can cope with the elements
165                        else {
166                                // set next bit 0 into AckVec (# of packet loss)
167                                for (int i = 0; i < numLoss; i++)
168                                        SET_BIT_VEC(tfwcAV[currNumVec_-1], 0);
169                        }
170
171                        // then, set this packet as received (this is important)
172                        SET_BIT_VEC(tfwcAV[currNumVec_-1], 1);
173
174                        // and clear the top two bits which we don't need
175                        // (because we have pushed '0' and '1' at the end of this AckVec)
176                        // it doesn't really matter if diffNumElm is greater than 0.
177                        if ( (diffNumElm <= 0) && (x != 0) ) {
178                                int b = abs(diffNumElm) + x + z;
179                                for (int i = x + 1; i <= b; i++)
180                                        CLR_BIT_AT(tfwcAV[currNumVec_-1], i);
181                        }
182                }
183
184                // print ackvec
185                print_ackvec(tfwcAV);
186
187                // start seqno that this AckVec is reporting
188                if (ackofack_ != 0)
189                        begins_ = ackofack_ + 1;
190                else
191                        begins_ = 1;
192
193                // end seqno is current seqno plus one (according to RFC 3611)
194                ends_ = currseq_ + 1;
195
196                // store seqno, num of AckVec elem, and num of AckVec array
197                prevseq_ = currseq_;
198                prevNumElm_ = currNumElm_;
199                prevNumVec_ = currNumVec_;
200        }
201        else if (type == XR_BT_2) {
202                // set timestamp echo
203                ts_echo_ = chunk[num_chunks-1];
204        }
205}
206
207void TfwcRcvr::print_ackvec(u_int16_t *ackv) {
208        // start sequence number
209        int seqno = ackofack_+1;
210        int x = currNumElm_%BITLEN;
211
212        // printing...
213        printf("\t>> AckVec: ");
214        for (int i = 0; i < currNumVec_-1; i++) {
215                printf("[%d] ( ", ackv[i]);
216                for (int j = 0; j < BITLEN; j++) {
217                        if ( CHECK_BIT_AT(ackv[i], (j+1)) )
218                                printf("%d ", seqno);
219                        seqno++;
220                }
221        } printf (") ");
222
223        int k = (x == 0) ? BITLEN: x;
224        printf("[%d] ( ", ackv[currNumVec_-1]);
225        for (int i = k; i > 0; i--) {
226                if (CHECK_BIT_AT(ackv[currNumVec_-1], i))
227                        printf("%d ", seqno);
228                seqno++;
229        } printf(")...... %s +%d\n",__FILE__,__LINE__);
230}
Note: See TracBrowser for help on using the browser.