1
--- txw.c 2011-03-12 10:37:12.000000000 +0800
2
+++ txw.c89.c 2011-03-12 11:15:05.000000000 +0800
5
pgm_debug ("create (tsi:%s max-tpdu:%" PRIu16 " sqns:%" PRIu32 " secs %u max-rte %" PRIzd " use-fec:%s rs(n):%u rs(k):%u)",
7
- tpdu_size, sqns, secs, max_rte,
8
+ tpdu_size, sqns, secs, (long)max_rte,
9
use_fec ? "YES" : "NO",
12
/* calculate transmit window parameters */
13
pgm_assert (sqns || (tpdu_size && secs && max_rte));
15
const unsigned alloc_sqns = sqns ? sqns : (unsigned)( (secs * max_rte) / tpdu_size );
16
window = pgm_malloc0 (sizeof(pgm_txw_t) + ( alloc_sqns * sizeof(struct pgm_sk_buff_t*) ));
19
pgm_assert (!pgm_txw_retransmit_can_peek (window));
25
/* destructor for transmit window. must not be called more than once for same window.
27
skb->sequence = window->lead;
29
/* add skb to window */
31
const uint_fast32_t index_ = skb->sequence % pgm_txw_max_length (window);
32
window->pdata[index_] = skb;
36
window->size += skb->len;
38
pgm_assert (NULL != window);
39
pgm_assert_cmpuint (tg_sqn_shift, <, 8 * sizeof(uint32_t));
42
const uint32_t tg_sqn_mask = 0xffffffff << tg_sqn_shift;
43
const uint32_t nak_tg_sqn = sequence & tg_sqn_mask; /* left unshifted */
44
const uint32_t nak_pkt_cnt = sequence & ~tg_sqn_mask;
46
pgm_assert (!pgm_queue_is_empty (&window->retransmit_queue));
47
state->waiting_retransmit = 1;
56
/* generate parity packet to satisify request */
58
const uint8_t rs_h = state->pkt_cnt_sent % (window->rs.n - window->rs.k);
59
const uint32_t tg_sqn_mask = 0xffffffff << window->tg_sqn_shift;
60
const uint32_t tg_sqn = skb->sequence & tg_sqn_mask;
61
- for (uint_fast8_t i = 0; i < window->rs.k; i++)
64
+ for (i = 0; i < window->rs.k; i++)
66
const struct pgm_sk_buff_t* odata_skb = pgm_txw_peek (window, tg_sqn + i);
67
const uint16_t odata_tsdu_length = ntohs (odata_skb->pgm_header->pgm_tsdu_length);
74
/* construct basic PGM header to be completed by send_rdata() */
75
skb = window->parity_buffer;
78
skb->pgm_header->pgm_options |= PGM_OPT_VAR_PKTLEN;
80
- for (uint_fast8_t i = 0; i < window->rs.k; i++)
83
+ for (i = 0; i < window->rs.k; i++)
85
struct pgm_sk_buff_t* odata_skb = pgm_txw_peek (window, tg_sqn + i);
86
const uint16_t odata_tsdu_length = ntohs (odata_skb->pgm_header->pgm_tsdu_length);
88
odata_skb->zero_padded = 1;
99
- struct pgm_opt_header *opt_header;
100
- struct pgm_opt_length *opt_len;
101
- struct pgm_opt_fragment *opt_fragment, null_opt_fragment;
102
- const pgm_gf8_t *opt_src[ window->rs.k ];
103
+ struct pgm_opt_header *opt_header;
104
+ struct pgm_opt_length *opt_len;
105
+ struct pgm_opt_fragment *opt_fragment, null_opt_fragment;
106
+ const pgm_gf8_t **opt_src;
108
skb->pgm_header->pgm_options |= PGM_OPT_PRESENT;
110
memset (&null_opt_fragment, 0, sizeof(null_opt_fragment));
111
*(uint8_t*)&null_opt_fragment |= PGM_OP_ENCODED_NULL;
113
- for (uint_fast8_t i = 0; i < window->rs.k; i++)
114
+ opt_src = pgm_newa (pgm_gf8_t*, window->rs.k);
118
+ for (i = 0; i < window->rs.k; i++)
120
const struct pgm_sk_buff_t* odata_skb = pgm_txw_peek (window, tg_sqn + i);
123
opt_src[i] = (pgm_gf8_t*)&null_opt_fragment;
128
/* add options to this rdata packet */
130
const uint16_t opt_total_length = sizeof(struct pgm_opt_length) +
131
sizeof(struct pgm_opt_header) +
132
sizeof(struct pgm_opt_fragment);
134
opt_len->opt_type = PGM_OPT_LENGTH;
135
opt_len->opt_length = sizeof(struct pgm_opt_length);
136
opt_len->opt_total_length = htons ( opt_total_length );
138
opt_header = (struct pgm_opt_header*)(opt_len + 1);
139
opt_header->opt_type = PGM_OPT_FRAGMENT | PGM_OPT_END;
140
opt_header->opt_length = sizeof(struct pgm_opt_header) + sizeof(struct pgm_opt_fragment);
144
/* calculate partial checksum */
146
const uint16_t tsdu_length = ntohs (skb->pgm_header->pgm_tsdu_length);
147
state->unfolded_checksum = pgm_csum_partial ((char*)skb->tail - tsdu_length, tsdu_length, 0);
153
/* remove head entry from retransmit queue, will fail on assertion if queue is empty.