55#define TFRC_MAGIC 0xbaef03b7
57#define MAX_HISTORY 1000
59#define MAX_DROPOUT 100
60#define RTP_SEQ_MOD 0x10000
61#define MAX_MISORDER 100
110static double transfer_rate(
double p)
112 double t, t1, t2, t3, t4, rtt, tRTO;
118 rtt = ((double)
RTT) / 1000000.0;
121 t1 = rtt * sqrt(2 * p / 3);
122 t2 = (1 + 32 * p * p);
123 t3 = 3 * sqrt(3 * p / 8);
124 t4 = t1 + tRTO * t3 * p * t2;
125 t = ((double)s) / t4;
130static void compute_transfer_rate(
void)
135 t1 = transfer_rate(p);
153 for (i =
first + 1; i < last; i++) {
164 for (i = 0; i < last; i++) {
170 assert(
count == (u - 1));
187 for (i =
first; i <= last; i++) {
196 for (i = 0; i <= last; i++) {
212 uint32_t
seq = s1 + 1;
214 est = ts1 + (ts2 - ts1) * ((
seq - s1) / (s2 -
seq));
217 if (
state->ii <= -1) {
229 state->interval_count++;
230 if (
state->ii > (
N + 1)) {
231 printf(
"how did this happen?\n");
234 if (
state->ii >= (
N + 1)) {
235 for (i = 0; i < (
N + 1); i++) {
250 int kk, inc, last_jj;
254 static uint16_t last_seq;
255 static uint32_t ext_last_ack;
256 static int last_ack_jj = 0;
259 now = (curr_time -
state->start_time) / 1000;
261 if (
state->jj == -1) {
272 udelta =
seq - last_seq;
274 state->total_pckts++;
277 if (
seq < last_seq) {
289 state->gap[udelta - 1]++;
291 if ((ext_seq - ext_last_ack) == 1) {
293 ext_last_ack = ext_seq;
294 last_ack_jj =
state->jj;
300 ext_last_ack = ext_seq;
301 last_ack_jj =
state->jj;
311 if (ext_seq > ext_last_ack) {
320 && last_ack_jj < state->jj) {
323 ext_last_ack =
arrival[last_ack_jj].seq;
332 uint32_t temp, I_tot0 = 0, I_tot1 = 0, I_tot = 0;
339 for (i =
state->ii -
N; i < state->ii; i++) {
340 temp =
loss[i + 1].seq -
loss[i].seq;
341 I_tot0 = I_tot0 + temp *
state->weight[i];
342 if (i >= (
state->ii -
N + 1)) {
343 I_tot1 = I_tot1 + temp *
state->weight[i - 1];
350 I_tot = (I_tot1 > I_tot0) ? I_tot1 : I_tot0;
351 I_mean = I_tot /
state->W_tot;
373 state->total_pckts = 0;
377 state->feedback_timer = curr_time;
381 state->start_time = curr_time;
382 state->loss_count = 0;
383 state->interval_count = 0;
387 state->weight[0] = 0.2;
388 state->weight[1] = 0.4;
389 state->weight[2] = 0.6;
390 state->weight[3] = 0.8;
391 state->weight[4] = 1.0;
392 state->weight[5] = 1.0;
393 state->weight[6] = 1.0;
394 state->weight[7] = 1.0;
395 state->weight[8] = 1.0;
397 for (i = 0; i < 20; i++) {
401 for (i = 0; i <
N; i++) {
422 for (i = 0; i < 10; i++) {
423 printf(
"\n%2d %8d", i,
state->gap[i]);
426 printf(
"\nLost: %8d",
state->loss_count);
427 printf(
"\nIntervals: %8d",
state->interval_count);
428 printf(
"\nTotal: %8d",
state->total_pckts);
429 printf(
"\nooo: %8d -- %7.5f\n\n",
state->ooo,
430 (
state->ooo * 100) / (
double)
state->total_pckts);
444 if (
state->RTT > 0) {
449 if (
state->p -
state->p_prev > 0.00000000001) {
450 gettimeofday(&(
state->feedback_timer), NULL);
452 (
unsigned int)
state->RTT);
453 compute_transfer_rate();
468 if (
state->RTT == 0) {
479 if ((
state->RTT == 0) ||
state->feedback_timer > curr_time) {
struct __attribute__((packed))
struct tfrc * tfrc_init(time_ns_t curr_time)
double tfrc_feedback_txrate(struct tfrc *state, time_ns_t curr_time)
static struct @50 arrival[MAX_HISTORY]
void tfrc_recv_rtt(struct tfrc *state, time_ns_t curr_time, uint32_t rtt)
static int set_zero(int first, int last, uint16_t u)
void tfrc_recv_data(struct tfrc *state, time_ns_t curr_time, uint16_t seqnum, unsigned length)
static void record_loss(struct tfrc *state, uint32_t s1, uint32_t s2, uint32_t ts1, uint32_t ts2)
static struct @51 loss[MAX_HISTORY]
void tfrc_done(struct tfrc *state)
static int arrived(int first, int last)
static double compute_loss_event(struct tfrc *state)
int tfrc_feedback_is_due(struct tfrc *state, time_ns_t curr_time)
static void validate_tfrc_state(struct tfrc *state)
static void save_arrival(struct tfrc *state, time_ns_t curr_time, uint16_t seq)
void tv_add(struct timeval *ts, double offset_secs)
static time_ns_t get_time_in_ns()