/*
 * ccid2.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 _CCID2_H_
#define _CCID2_H_

#define DCTPCCID2_INITCWND     4
#define DCTPCCID2_INITSSTHRESH 0xffffffff
#define DCTPCCID2_INITRTO      3000000  /* 3 seconds */
#define DCTPCCID2_CLOCKGRAN    1000000  /* 1 ms */

#ifdef NEVER
#define xmtInfoGetDataPkt(xi)    ((xi)->seqno & 0x0100000000000000)
#define xmtInfoSetDataPkt(xi)    ((xi)->seqno |= 0x0100000000000000)
#define xmtInfoGetAckPkt(xi)     ((xi)->seqno & 0x0200000000000000)
#define xmtInfoSetAckPkt(xi)     ((xi)->seqno |= 0x0200000000000000)
#define xmtInfoGetDupAcks(xi)    (((xi)->seqno >> 48) & 0xff)
#define xmtInfoSetDupAcks(xi, d) ((xi)->seqno = (((xi)->seqno & 0xff00ffffffffffff) | \
                                   ((uint64_t)((d) & 0xff)) << 48))
#define xmtInfoGetSeqno(xi)      ((xi)->seqno & DCTP_48BITMASK)
#define xmtInfoGetState(xi)      ((uint8_t)(((xi)->seqno >> 56) & 0xc0))
#define xmtInfoSetState(xi, st)  ((xi)->seqno = ((xi)->seqno & 0x3fffffffffffffff) | \
				  ((uint64_t)(((uint8_t)(st)) & 0xc0)) << 56)
#endif

#define DCTPCCID2_ACKVECTORRCVD      0x00
#define DCTPCCID2_ACKVECTORMARKED    0x40
#define DCTPCCID2_ACKVECTORNOTRCVD   0xc0
#define DCTPCCID2_NUMDUPACKS         3
#define DCTPCCID2_ACKVECTORCOUNT     0x3f
#define DCTPCCID2_ACKVECTORSTATEMASK 0xe0

typedef struct _ccid2XmtInfo {
#ifdef DEBUG
    uint32_t mgc;
#endif
    struct _ccid2XmtInfo *next;
    struct _ccid2XmtInfo *prev;
    uint64_t seqno;  /* High order bit set for data packet */
    uint64_t xtime;
} ccid2XmtInfo;

#define DCTPCCID2_MAXXMTINFOBUFS     4096

typedef struct _ccid2SenderInfo {
    uint32_t cwnd;
    uint32_t pipe;
    uint32_t ssthresh;
    uint32_t srtt;
    uint32_t rttvar;
    uint32_t rto;
    uint32_t pktsSinceLastRttEst;
    uint32_t pktsSinceLastAckRatio;
    uint32_t dataRcvdOK;
    uint32_t ackMarked;
    uint32_t maxpipe;
    uint32_t xmtInfoCount;
    uint8_t dataDropped;
    uint8_t slowReceiver;
    uint8_t stopData;
    dctpTimer rtoTimer;
    dctpTimer slowRcvrTimer;
    dctpTimer idleTimer;
    struct _ccid2XmtInfo *xmtInfoBufs;
    struct _ccid2XmtInfo *xmtHistory;
} ccid2SenderInfo;

#define DCTPCCID2_ACKBUFSIZEINC            32
#define DCTPCCID2_ACKBUFSIZEBITSINC        (DCTPCCID2_ACKBUFSIZEINC*8)
#define DCTPCCID2_ACKBUFMAXSIZE            4096
#define DCTPCCID2_ACKBUFRCVD               0
#define DCTPCCID2_ACKBUFMARKED             1
#define DCTPCCID2_ACKBUFNOTRCVD            3
#define DCTPCCID2_ACKBUFSTATEPERBYTE       4
#define DCTPCCID2_ACKBUFSTATEBITSIZE       2
#define DCTPCCID2_ACKBUFSTATEMASK          3
#define DCTPCCID2_ACKBUF2VECTORSTATESHIFT  6

#define DCTPCCID2_MAXACKVECS               1024

typedef struct _ccid2AckVectorInfo {
    uint64_t ackSeqno;
    uint16_t ackPtr;
    uint16_t nonce;
    struct _ccid2AckVectorInfo *next;
} ccid2AckVectorInfo;

typedef struct _ccid2RcvrInfo {
    uint16_t ackBufHead;
    uint16_t ackBufTail;
    uint16_t ackBufNonce;
    uint16_t ackBufSize;
    uint8_t *ackBuf;
    uint64_t ackBufAckno;
    uint32_t ackPktsWaitingAck;
    uint32_t pktsWaitingAck;
    uint32_t ackVecCount;
    uint8_t nonce;
    struct _ccid2AckVectorInfo *ackVecHist;
    struct _ccid2AckVectorInfo *ackVecFreeList;
} ccid2RcvrInfo;

#endif  /* _CCID_H_ */

