diff options
Diffstat (limited to 'toxav/bwcontroller.c')
-rw-r--r-- | toxav/bwcontroller.c | 99 |
1 files changed, 37 insertions, 62 deletions
diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c index 9d1ad9ce..defb3fde 100644 --- a/toxav/bwcontroller.c +++ b/toxav/bwcontroller.c | |||
@@ -32,9 +32,10 @@ | |||
32 | #include <errno.h> | 32 | #include <errno.h> |
33 | 33 | ||
34 | #define BWC_PACKET_ID 196 | 34 | #define BWC_PACKET_ID 196 |
35 | #define BWC_SEND_INTERVAL_MS 1000 | 35 | #define BWC_SEND_INTERVAL_MS 950 /* 0.95s */ |
36 | #define BWC_REFRESH_INTERVAL_MS 10000 | 36 | #define BWC_REFRESH_INTERVAL_MS 2000 /* 2.00s */ |
37 | #define BWC_AVG_PKT_COUNT 20 | 37 | #define BWC_AVG_PKT_COUNT 20 |
38 | #define BWC_AVG_LOSS_OVER_CYCLES_COUNT 30 | ||
38 | 39 | ||
39 | struct BWController_s { | 40 | struct BWController_s { |
40 | void (*mcb)(BWController *, uint32_t, float, void *); | 41 | void (*mcb)(BWController *, uint32_t, float, void *); |
@@ -56,6 +57,8 @@ struct BWController_s { | |||
56 | uint32_t packet_length_array[BWC_AVG_PKT_COUNT]; | 57 | uint32_t packet_length_array[BWC_AVG_PKT_COUNT]; |
57 | RingBuffer *rb; | 58 | RingBuffer *rb; |
58 | } rcvpkt; /* To calculate average received packet (this means split parts, not the full message!) */ | 59 | } rcvpkt; /* To calculate average received packet (this means split parts, not the full message!) */ |
60 | |||
61 | uint32_t packet_loss_counted_cycles; | ||
59 | }; | 62 | }; |
60 | 63 | ||
61 | struct BWCMessage { | 64 | struct BWCMessage { |
@@ -71,23 +74,23 @@ BWController *bwc_new(Messenger *m, uint32_t friendnumber, | |||
71 | void *udata) | 74 | void *udata) |
72 | { | 75 | { |
73 | BWController *retu = (BWController *)calloc(sizeof(struct BWController_s), 1); | 76 | BWController *retu = (BWController *)calloc(sizeof(struct BWController_s), 1); |
74 | 77 | LOGGER_DEBUG(m->log, "Creating bandwidth controller"); | |
75 | retu->mcb = mcb; | 78 | retu->mcb = mcb; |
76 | retu->mcb_data = udata; | 79 | retu->mcb_data = udata; |
77 | retu->m = m; | 80 | retu->m = m; |
78 | retu->friend_number = friendnumber; | 81 | retu->friend_number = friendnumber; |
79 | retu->cycle.last_sent_timestamp = retu->cycle.last_refresh_timestamp = current_time_monotonic(); | 82 | retu->cycle.last_sent_timestamp = retu->cycle.last_refresh_timestamp = current_time_monotonic(); |
80 | retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT); | 83 | retu->rcvpkt.rb = rb_new(BWC_AVG_PKT_COUNT); |
84 | retu->cycle.lost = 0; | ||
85 | retu->cycle.recv = 0; | ||
86 | retu->packet_loss_counted_cycles = 0; | ||
81 | 87 | ||
82 | /* Fill with zeros */ | 88 | /* Fill with zeros */ |
83 | int i = 0; | 89 | for (int i = 0; i < BWC_AVG_PKT_COUNT; i++) { |
84 | 90 | rb_write(retu->rcvpkt.rb, &retu->rcvpkt.packet_length_array[i]); | |
85 | for (; i < BWC_AVG_PKT_COUNT; i ++) { | ||
86 | rb_write(retu->rcvpkt.rb, retu->rcvpkt.packet_length_array + i); | ||
87 | } | 91 | } |
88 | 92 | ||
89 | m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu); | 93 | m_callback_rtp_packet(m, friendnumber, BWC_PACKET_ID, bwc_handle_data, retu); |
90 | |||
91 | return retu; | 94 | return retu; |
92 | } | 95 | } |
93 | 96 | ||
@@ -98,47 +101,21 @@ void bwc_kill(BWController *bwc) | |||
98 | } | 101 | } |
99 | 102 | ||
100 | m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr); | 103 | m_callback_rtp_packet(bwc->m, bwc->friend_number, BWC_PACKET_ID, nullptr, nullptr); |
101 | |||
102 | rb_kill(bwc->rcvpkt.rb); | 104 | rb_kill(bwc->rcvpkt.rb); |
103 | free(bwc); | 105 | free(bwc); |
104 | } | 106 | } |
105 | 107 | ||
106 | void bwc_feed_avg(BWController *bwc, uint32_t bytes) | ||
107 | { | ||
108 | uint32_t *p; | ||
109 | |||
110 | rb_read(bwc->rcvpkt.rb, (void **) &p); | ||
111 | rb_write(bwc->rcvpkt.rb, p); | ||
112 | |||
113 | *p = bytes; | ||
114 | } | ||
115 | |||
116 | void bwc_add_lost(BWController *bwc, uint32_t bytes_lost) | 108 | void bwc_add_lost(BWController *bwc, uint32_t bytes_lost) |
117 | { | 109 | { |
118 | if (!bwc) { | 110 | if (!bwc) { |
119 | return; | 111 | return; |
120 | } | 112 | } |
121 | 113 | ||
122 | if (!bytes_lost) { | 114 | if (bytes_lost > 0) { |
123 | uint32_t *t_avg[BWC_AVG_PKT_COUNT], c = 1; | 115 | LOGGER_DEBUG(bwc->m->log, "BWC lost(1): %d", (int)bytes_lost); |
124 | 116 | bwc->cycle.lost += bytes_lost; | |
125 | rb_data(bwc->rcvpkt.rb, (void **) t_avg); | 117 | send_update(bwc); |
126 | |||
127 | int i = 0; | ||
128 | |||
129 | for (; i < BWC_AVG_PKT_COUNT; i ++) { | ||
130 | bytes_lost += *(t_avg[i]); | ||
131 | |||
132 | if (*(t_avg[i])) { | ||
133 | c++; | ||
134 | } | ||
135 | } | ||
136 | |||
137 | bytes_lost /= c; | ||
138 | } | 118 | } |
139 | |||
140 | bwc->cycle.lost += bytes_lost; | ||
141 | send_update(bwc); | ||
142 | } | 119 | } |
143 | 120 | ||
144 | void bwc_add_recv(BWController *bwc, uint32_t recv_bytes) | 121 | void bwc_add_recv(BWController *bwc, uint32_t recv_bytes) |
@@ -147,37 +124,35 @@ void bwc_add_recv(BWController *bwc, uint32_t recv_bytes) | |||
147 | return; | 124 | return; |
148 | } | 125 | } |
149 | 126 | ||
127 | bwc->packet_loss_counted_cycles++; | ||
150 | bwc->cycle.recv += recv_bytes; | 128 | bwc->cycle.recv += recv_bytes; |
151 | send_update(bwc); | 129 | send_update(bwc); |
152 | } | 130 | } |
153 | 131 | ||
154 | |||
155 | void send_update(BWController *bwc) | 132 | void send_update(BWController *bwc) |
156 | { | 133 | { |
157 | if (current_time_monotonic() - bwc->cycle.last_refresh_timestamp > BWC_REFRESH_INTERVAL_MS) { | 134 | if (bwc->packet_loss_counted_cycles > BWC_AVG_LOSS_OVER_CYCLES_COUNT && |
158 | 135 | current_time_monotonic() - bwc->cycle.last_sent_timestamp > BWC_SEND_INTERVAL_MS) { | |
159 | bwc->cycle.lost /= 10; | 136 | bwc->packet_loss_counted_cycles = 0; |
160 | bwc->cycle.recv /= 10; | ||
161 | bwc->cycle.last_refresh_timestamp = current_time_monotonic(); | ||
162 | } else if (current_time_monotonic() - bwc->cycle.last_sent_timestamp > BWC_SEND_INTERVAL_MS) { | ||
163 | 137 | ||
164 | if (bwc->cycle.lost) { | 138 | if (bwc->cycle.lost) { |
165 | LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u", | 139 | LOGGER_DEBUG(bwc->m->log, "%p Sent update rcv: %u lost: %u percent: %f %%", |
166 | bwc, bwc->cycle.recv, bwc->cycle.lost); | 140 | bwc, bwc->cycle.recv, bwc->cycle.lost, |
167 | 141 | (((float) bwc->cycle.lost / (bwc->cycle.recv + bwc->cycle.lost)) * 100.0f)); | |
168 | uint8_t p_msg[sizeof(struct BWCMessage) + 1]; | 142 | uint8_t bwc_packet[sizeof(struct BWCMessage) + 1]; |
169 | struct BWCMessage *b_msg = (struct BWCMessage *)(p_msg + 1); | 143 | struct BWCMessage *msg = (struct BWCMessage *)(bwc_packet + 1); |
170 | 144 | bwc_packet[0] = BWC_PACKET_ID; // set packet ID | |
171 | p_msg[0] = BWC_PACKET_ID; | 145 | msg->lost = net_htonl(bwc->cycle.lost); |
172 | b_msg->lost = net_htonl(bwc->cycle.lost); | 146 | msg->recv = net_htonl(bwc->cycle.recv); |
173 | b_msg->recv = net_htonl(bwc->cycle.recv); | 147 | |
174 | 148 | if (-1 == m_send_custom_lossy_packet(bwc->m, bwc->friend_number, bwc_packet, sizeof(bwc_packet))) { | |
175 | if (-1 == m_send_custom_lossy_packet(bwc->m, bwc->friend_number, p_msg, sizeof(p_msg))) { | 149 | LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %d)! std error: %s", sizeof(bwc_packet), strerror(errno)); |
176 | LOGGER_WARNING(bwc->m->log, "BWC send failed (len: %d)! std error: %s", sizeof(p_msg), strerror(errno)); | ||
177 | } | 150 | } |
178 | } | 151 | } |
179 | 152 | ||
180 | bwc->cycle.last_sent_timestamp = current_time_monotonic(); | 153 | bwc->cycle.last_sent_timestamp = current_time_monotonic(); |
154 | bwc->cycle.lost = 0; | ||
155 | bwc->cycle.recv = 0; | ||
181 | } | 156 | } |
182 | } | 157 | } |
183 | 158 | ||
@@ -185,9 +160,9 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg) | |||
185 | { | 160 | { |
186 | LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc); | 161 | LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc); |
187 | 162 | ||
188 | /* Peer must respect time boundary */ | 163 | /* Peers sent update too soon */ |
189 | if (current_time_monotonic() < bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS) { | 164 | if (bwc->cycle.last_recv_timestamp + BWC_SEND_INTERVAL_MS > current_time_monotonic()) { |
190 | LOGGER_DEBUG(bwc->m->log, "%p Rejecting extra update", bwc); | 165 | LOGGER_INFO(bwc->m->log, "%p Rejecting extra update", bwc); |
191 | return -1; | 166 | return -1; |
192 | } | 167 | } |
193 | 168 | ||
@@ -196,9 +171,9 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg) | |||
196 | uint32_t recv = net_ntohl(msg->recv); | 171 | uint32_t recv = net_ntohl(msg->recv); |
197 | uint32_t lost = net_ntohl(msg->lost); | 172 | uint32_t lost = net_ntohl(msg->lost); |
198 | 173 | ||
199 | LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u", recv, lost); | ||
200 | |||
201 | if (lost && bwc->mcb) { | 174 | if (lost && bwc->mcb) { |
175 | LOGGER_DEBUG(bwc->m->log, "recved: %u lost: %u percentage: %f %%", recv, lost, | ||
176 | (((float) lost / (recv + lost)) * 100.0f)); | ||
202 | bwc->mcb(bwc, bwc->friend_number, | 177 | bwc->mcb(bwc, bwc->friend_number, |
203 | ((float) lost / (recv + lost)), | 178 | ((float) lost / (recv + lost)), |
204 | bwc->mcb_data); | 179 | bwc->mcb_data); |