1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc.  See LICENSE. */
250aadb33SDmitri Tikhonov/*
350aadb33SDmitri Tikhonov * lsquic_sfcw.h -- Stream flow control window functions
450aadb33SDmitri Tikhonov */
550aadb33SDmitri Tikhonov
650aadb33SDmitri Tikhonov#ifndef LSQUIC_SFCW_H
750aadb33SDmitri Tikhonov#define LSQUIC_SFCW_H 1
850aadb33SDmitri Tikhonov
950aadb33SDmitri Tikhonovstruct lsquic_cfcw;
1050aadb33SDmitri Tikhonovstruct lsquic_conn_public;
1150aadb33SDmitri Tikhonov
1250aadb33SDmitri Tikhonovtypedef struct lsquic_sfcw {
1350aadb33SDmitri Tikhonov    struct lsquic_cfcw *sf_cfcw;            /* Connection flow control window,
1450aadb33SDmitri Tikhonov                                             * NULL for streams 1 and 3.
1550aadb33SDmitri Tikhonov                                             */
1650aadb33SDmitri Tikhonov    uint64_t            sf_max_recv_off;    /* Largest offset observed */
1750aadb33SDmitri Tikhonov    uint64_t            sf_recv_off;        /* Flow control receive offset */
1850aadb33SDmitri Tikhonov    uint64_t            sf_read_off;        /* Number of bytes consumed */
1950aadb33SDmitri Tikhonov    lsquic_time_t       sf_last_updated;    /* Last time window was updated */
2050aadb33SDmitri Tikhonov    struct lsquic_conn_public
2150aadb33SDmitri Tikhonov                       *sf_conn_pub;
2250aadb33SDmitri Tikhonov    unsigned            sf_max_recv_win;    /* Maximum receive window */
235392f7a3SLiteSpeed Tech    lsquic_stream_id_t  sf_stream_id;       /* Used for logging */
2450aadb33SDmitri Tikhonov} lsquic_sfcw_t;
2550aadb33SDmitri Tikhonov
2650aadb33SDmitri Tikhonov
2750aadb33SDmitri Tikhonovvoid
2850aadb33SDmitri Tikhonovlsquic_sfcw_init (lsquic_sfcw_t *, unsigned initial_max_recv_window,
2950aadb33SDmitri Tikhonov                  struct lsquic_cfcw *cfcw, struct lsquic_conn_public *,
305392f7a3SLiteSpeed Tech                  lsquic_stream_id_t stream_id);
3150aadb33SDmitri Tikhonov
3250aadb33SDmitri Tikhonov/* If update is to be sent, updates max_recv_off and returns true.  Note
3350aadb33SDmitri Tikhonov * that if you call this function twice, the second call will return false.
3450aadb33SDmitri Tikhonov */
3550aadb33SDmitri Tikhonovint
3650aadb33SDmitri Tikhonovlsquic_sfcw_fc_offsets_changed (lsquic_sfcw_t *);
3750aadb33SDmitri Tikhonov
3850aadb33SDmitri Tikhonov#define lsquic_sfcw_get_fc_recv_off(fc) ((fc)->sf_recv_off)
3950aadb33SDmitri Tikhonov
4050aadb33SDmitri Tikhonov#define lsquic_sfcw_get_max_recv_off(fc) ((fc)->sf_max_recv_off)
4150aadb33SDmitri Tikhonov
4250aadb33SDmitri Tikhonov/* Returns false if flow control violation is encountered */
4350aadb33SDmitri Tikhonovint
4450aadb33SDmitri Tikhonovlsquic_sfcw_set_max_recv_off (lsquic_sfcw_t *, uint64_t);
4550aadb33SDmitri Tikhonov
4650aadb33SDmitri Tikhonov/* Void because we do not expect the caller to make a mistake.
4750aadb33SDmitri Tikhonov */
4850aadb33SDmitri Tikhonovvoid
4950aadb33SDmitri Tikhonovlsquic_sfcw_set_read_off (lsquic_sfcw_t *, uint64_t);
5050aadb33SDmitri Tikhonov
5150aadb33SDmitri Tikhonov#define lsquic_sfcw_consume_rem(sfcw) do {                        \
5250aadb33SDmitri Tikhonov    lsquic_sfcw_set_read_off(sfcw,                                \
5350aadb33SDmitri Tikhonov                    lsquic_sfcw_get_max_recv_off(sfcw));          \
5450aadb33SDmitri Tikhonov} while (0)
5550aadb33SDmitri Tikhonov
5650aadb33SDmitri Tikhonov#endif
57