summaryrefslogtreecommitdiff
path: root/toxav/bwcontroller.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/bwcontroller.c')
-rw-r--r--toxav/bwcontroller.c99
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
39struct BWController_s { 40struct 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
61struct BWCMessage { 64struct 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
106void 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
116void bwc_add_lost(BWController *bwc, uint32_t bytes_lost) 108void 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
144void bwc_add_recv(BWController *bwc, uint32_t recv_bytes) 121void 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
155void send_update(BWController *bwc) 132void 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);