/*
 * ccid3.h -- definitions for CCID2 code
 *
 * Copyright (C) 2008 Tom Phelan
 *
 * This file is part of dccp-tp.
 *
 * Dccp-tp is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * Dccp-tp is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with dccp-tp.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Documentation and source code for dccp-tp is available at
 * http://www.phelan-4.com/dccp-tp/.
 */

#ifndef _CCID3_H_
#define _CCID3_H_

#include "fixedPointMath.h"

#define DCTPCCID3_TMBI                  fptpDiv(info->segSize, FPTP_CONST(64, 0))
#define DCTPCCID3_MAXLOSSINTERVALS      8
#define DCTPCCID3_FDBKINTERVALS         1
#define DCTPCCID3_FDBKRCVRATE           2
#define DCTPCCID3_FDBKELAPTIME          4
#define DCTPCCID3_FDBKTSECHO            8
#define DCTPCCID3_REQFDBKOPTIONS        \
    (DCTPCCID3_FDBKINTERVALS | DCTPCCID3_FDBKRCVRATE | DCTPCCID3_FDBKELAPTIME)
#define DCTPCCID3_MAXRTT                FPTP_CONST(64, 0)
#define DCTPCCID3_INITSEGSIZE           FPTP_CONST(1422, 0)
#define DCTPCCID3_INITIALRATE           FPTP_CONST(4380, 0)
#define DCTPCCID3_RECOVERRATE           DCTPCCID3_INITIALRATE
#define DCTPCCID3_INITRTO               FPTP_CONST(2, 0)
#define DCTPCCID3_WINITMAX              FPTP_CONST(4380, 0)
#define DCTPCCID3_LOSSINTERVALOPMINLEN  12
#define DCTPCCID3_LOSSEVENTRATEOP       192
#define DCTPCCID3_LOSSINTERVALSOP       193
#define DCTPCCID3_RECEIVERATEOP         194
#define DCTPCCID3_RCVRATEOPLEN          6

typedef struct _ccid3LossInterval {
    uint64_t start;
    uint64_t end;
    uint32_t dataLen;
} ccid3LossInterval;

typedef struct _ccid3SenderInfo {
    fixedp rtt;              /* R */
    fixedp xRcv;             /* X_recv */
    fixedp xInRcv;           /* X_inrecv */
    fixedp dataDropped;      /* Count of data dropped options rcvd */
    fixedp lossEventRate;    /* p */
    fixedp xBps;             /* X_Bps */
    fixedp xAllowed;         /* X */
    fixedp rttSqmean;        /* R_sqmean */
    fixedp xInst;            /* X_inst */
    fixedp tIpi;             /* t_ipi */
    fixedp rto;              /* RTO */
    fixedp rttSamp;          /* R_sample */
    fixedp nextPktTime;      /* Next time a packet may be transmitted */
    fixedp lastWcTime;       /* Last time window counter was changed */
    fixedp xRcvSet[3];       /* X_recv_set X_recv values */
    fixedp xRcvSetTs[3];     /* X_recv_set timestamp values */
    fixedp tld;              /* Time of last doubling during slow-start */
    fixedp rtoTime;          /* Time no feedback timer expires */
    fixedp tsEcho;           /* Last rtt computed from timestamp echo */
    fixedp elapsedTime;      /* Last elapsed time option rcvd */
    fixedp tsElapsedTime;    /* Last elapsed time rcvd in a timestamp echo */
    fixedp segSize;          /* segsize (s) */
    fixedp timestampBase;    /* Base of timestamp echo times */
    uint64_t lossIntervalContinue;
    ccid3LossInterval lossIntervals[DCTPCCID3_MAXLOSSINTERVALS];
    uint8_t lossIntNum;
    uint_t ccval:4;
    uint_t isFeedbackPkt:4;
    uint_t dataLimited:1;
    uint_t newLoss:1;
    uint_t gotFdbk:1;
    uint_t rttSampled:1;
    uint_t idle:1;
    uint_t stopData:1;       /* Set when app not listening option rcvd */
    uint_t timestampWrapped:1;
    uint_t slowRcvr:1;       /* Set when slow receiver option rcvd */
    dctpTimer rttTimer;
    dctpTimer fdelay;
#ifdef DEBUG
    dctpSocket *sock;
#endif  /* DEBUG */
} ccid3SenderInfo;

#define DCTPCCID3_PKTRECEIVED      1
#define DCTPCCID3_PKTMARKED        2
#define DCTPCCID3_PKTMISSING       3
#define DCTPCCID3_LOSSINTERVALOPT  193
#define DCTPCCID3_RCVRATEOPT       194
#define DCTPCCID3_LOSSLENGTHMAX    0x007fffff
#define DCTPCCID3_LLESSLENGTHMAX   0x00ffffff
#define DCTPCCID3_DATALENGTHMAX    0x00ffffff

typedef struct _ccid3RcvrPktHistory {
    uint8_t ccval;
    uint8_t status;
} ccid3RcvrPktHistory;

typedef struct _ccid3RcvrLossInterval {
    uint32_t llessLength;
    uint32_t lossLength;
    uint32_t dataLength;
    uint8_t startCcval;
    uint8_t nonce;
} ccid3RcvrLossInterval;

typedef struct _ccid3RcvrInfo {
    uint64_t pktHistTop;          /* Seqno of 1st packet in history */
    ccid3RcvrPktHistory pktHist[3];
    ccid3RcvrLossInterval *currLossInt;
    ccid3RcvrLossInterval lossIntervals[DCTPCCID3_MAXLOSSINTERVALS];
    uint32_t xRcv;
    uint32_t lastXRcv;
    uint8_t lossIntIndex;
    uint8_t lastCcval;
    uint8_t rcvdCcval;
    uint8_t ccvalDiff;
    uint_t pktRcvd:1;
} ccid3RcvrInfo;

#endif  /* _CCID3_H_ */

