1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "fillp_common.h"
17 #include "fillp_output.h"
18 #include "opt.h"
19
20 #define FILLP_FRAME_INTVL_MIN_INDEX(len) ((FILLP_UINT16)((((FILLP_UINT32)(len)) * 5) / 100))
21 #define FILLP_FRAME_INTVL_MAX_INDEX(len) ((FILLP_UINT16)((((FILLP_UINT32)(len)) * 95) / 100))
22 #define FILLP_UNLIMIT_SEND_INTERVAL 100 /* try to send every 100us */
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
FillpEnablePackTimerInCb(struct FillpPcb * pcb,FILLP_BOOL enNormalPackTimer)28 static void FillpEnablePackTimerInCb(struct FillpPcb *pcb, FILLP_BOOL enNormalPackTimer)
29 {
30 (void)enNormalPackTimer;
31 FillpEnablePackTimer(pcb);
32 }
33
LogFcFcAppStastics(const struct FillpPcb * pcb,const struct FillAppFcStastics * appFcStastics)34 static void LogFcFcAppStastics(const struct FillpPcb *pcb, const struct FillAppFcStastics *appFcStastics)
35 {
36 FILLP_LOGDBG("fillp_sock_id:%d periodRtt:<%u>, periodRecvRate: <%u, %llu>, periodRecvPktLoss: <%u, %u>, "
37 "periodSendRate: <%llu>, period_send_pkt_loss: %u",
38 FILLP_GET_SOCKET(pcb)->index, appFcStastics->periodRtt, appFcStastics->periodRecvRate,
39 appFcStastics->periodRecvRateBps, appFcStastics->periodRecvPktLoss,
40 appFcStastics->periodRecvPktLossHighPrecision, appFcStastics->periodSendRateBps,
41 appFcStastics->periodSendPktLossHighPrecision);
42 }
43
FillpCalFcAppStastics(struct FillpPcb * pcb)44 static void FillpCalFcAppStastics(struct FillpPcb *pcb)
45 {
46 struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
47 struct FillpPackStastics *packStastics = &pcb->statistics.pack;
48 struct FillAppFcStastics *appFcStastics = &pcb->statistics.appFcStastics;
49
50 appFcStastics->periodTimePassed += packStastics->packTimePassed;
51 appFcStastics->periodRecvBits += (FILLP_LLONG)packStastics->periodRecvBits;
52 appFcStastics->periodRecvPkts += packStastics->periodRecvedOnes;
53
54 if (appFcStastics->periodTimePassed < (FILLP_LLONG)(sock->resConf.common.fcStasticsInterval)) {
55 return;
56 }
57
58 FILLP_UINT32 pktData = pcb->recv.pktNum - appFcStastics->pktNum;
59 if (pktData == 0) {
60 appFcStastics->periodRecvPktLossHighPrecision = 0;
61 } else if (pktData >= appFcStastics->periodRecvPkts) {
62 appFcStastics->periodRecvPktLossHighPrecision = (pktData - appFcStastics->periodRecvPkts) *
63 FILLP_RECV_PKT_LOSS_H_PERCISION * FILLP_RECV_PKT_LOSS_MAX / pktData;
64 } else {
65 appFcStastics->periodRecvPktLossHighPrecision = 0;
66 FILLP_LOGINF("fillp_sock_id:%d, recv_pkt_num:%u, pre_pkt_num:%u, periodRecvPkts:%u",
67 FILLP_GET_SOCKET(pcb)->index, pcb->recv.pktNum, appFcStastics->pktNum,
68 appFcStastics->periodRecvPkts);
69 }
70 appFcStastics->periodRecvPktLoss =
71 appFcStastics->periodRecvPktLossHighPrecision / (FILLP_UINT32)FILLP_RECV_PKT_LOSS_H_PERCISION;
72
73 /* bits num / (us / 1,000,000) equal to (bits num * 1,000,000) / us */
74 appFcStastics->periodRecvRateBps =
75 (FILLP_ULLONG)(((FILLP_ULLONG)appFcStastics->periodRecvBits * FILLP_UTILS_MS2US(FILLP_ONE_SECOND)) /
76 (FILLP_ULLONG)appFcStastics->periodTimePassed);
77 appFcStastics->periodRecvRate = (FILLP_UINT32)FILLP_UTILS_BPS2KBPS(appFcStastics->periodRecvRateBps);
78
79 if ((appFcStastics->periodSendPkts == 0) ||
80 (appFcStastics->periodSendPkts < appFcStastics->periodSendLostPkts)) {
81 appFcStastics->periodSendPktLossHighPrecision = 0;
82 } else {
83 appFcStastics->periodSendPktLossHighPrecision = appFcStastics->periodSendLostPkts *
84 FILLP_RECV_PKT_LOSS_H_PERCISION * FILLP_RECV_PKT_LOSS_MAX / appFcStastics->periodSendPkts;
85 }
86
87 appFcStastics->periodSendRateBps =
88 (FILLP_ULLONG)((appFcStastics->periodSendBits * FILLP_UTILS_MS2US(FILLP_ONE_SECOND)) /
89 (FILLP_ULLONG)appFcStastics->periodTimePassed);
90
91 appFcStastics->periodTimePassed = 0;
92 appFcStastics->periodRecvBits = 0;
93 appFcStastics->periodRecvPkts = 0;
94 appFcStastics->pktNum = pcb->recv.pktNum;
95 appFcStastics->periodSendLostPkts = 0;
96 appFcStastics->periodSendPkts = 0;
97 appFcStastics->periodSendBits = 0;
98 LogFcFcAppStastics(pcb, appFcStastics);
99 }
100
FillpCalRecvRate(struct FillpPcb * pcb)101 static void FillpCalRecvRate(struct FillpPcb *pcb)
102 {
103 struct FillpPackStastics *packStastics = &pcb->statistics.pack;
104 FILLP_UINT32 recvRate;
105
106 /* Cal Pkt loss and rate */
107 FILLP_UINT32 pktData = pcb->recv.pktNum - packStastics->packPktNum;
108 if (pktData == 0) {
109 packStastics->periodRecvPktLoss = 0;
110 } else {
111 if (pktData <= packStastics->periodRecvedOnes) {
112 packStastics->periodRecvPktLoss = 0;
113 } else {
114 packStastics->periodRecvPktLoss = (FILLP_UINT16)(
115 (FILLP_ULLONG)(pktData - packStastics->periodRecvedOnes) * FILLP_RECV_PKT_LOSS_MAX / pktData);
116 }
117 }
118 /* kbps */
119 recvRate = (FILLP_UINT32)((packStastics->periodRecvBits * FILLP_ONE_SECOND) /
120 (FILLP_ULLONG)packStastics->packTimePassed);
121 packStastics->periodRecvRate = (packStastics->lastPackRecvRate + recvRate) >> 1;
122 packStastics->lastPackRecvRate = recvRate;
123
124 if (packStastics->maxRecvRate < packStastics->periodRecvRate) {
125 packStastics->maxRecvRate = packStastics->periodRecvRate;
126 }
127 FILLP_LOGDBG("fillp_sock_id:%d nackSend: %u nackFailed: %u nackRcv: %u "
128 "packSend: %u packFailed: %u packRcv: %u nackPktNum: %u "
129 "totalSendBytes: %u packIntervalSendPkt: %u "
130 "total_recvd_count: %u recv rate: %u pack input interval: %lld",
131 FILLP_GET_SOCKET(pcb)->index, pcb->statistics.debugPcb.nackSend,
132 pcb->statistics.debugPcb.nackFailed, pcb->statistics.debugPcb.nackRcv,
133 pcb->statistics.debugPcb.packSend, pcb->statistics.debugPcb.packFailed,
134 pcb->statistics.debugPcb.packRcv, pcb->statistics.debugPcb.nackPktNum,
135 pcb->statistics.traffic.totalSendBytes, pcb->statistics.debugPcb.packIntervalSendPkt,
136 pcb->statistics.traffic.totalRecved, pcb->statistics.pack.periodRecvRate,
137 pcb->statistics.debugPcb.packRecvedTimeInterval);
138
139 FILLP_LOGDBG("fillp_sock_id:%d periodRecvRate: %u, maxRecvRate: %u \n", FILLP_GET_SOCKET(pcb)->index,
140 packStastics->periodRecvRate, packStastics->maxRecvRate);
141
142 pcb->recv.prePackPktNum = packStastics->packPktNum;
143 packStastics->packPktNum = pcb->recv.pktNum;
144 packStastics->periodRecvBits = 0;
145 packStastics->periodRecvedOnes = 0;
146 }
147
FillpPackTimerCb(void * argPcb)148 void FillpPackTimerCb(void *argPcb)
149 {
150 struct FillpPcb *pcb = (struct FillpPcb *)argPcb;
151 struct FtSocket *sock = FILLP_GET_SOCKET(pcb);
152 struct FillpPackStastics *pack = &pcb->statistics.pack;
153 FILLP_BOOL enableNormalTimer;
154 FILLP_LLONG curTime = SYS_ARCH_GET_CUR_TIME_LONGLONG();
155
156 pack->packTimePassed = curTime - pack->packSendTime;
157 pack->packSendTime = curTime;
158
159 FILLP_LOGDBG("pack fire time =%lld", pcb->pcbInst->curTime);
160 FillpCalFcAppStastics(pcb);
161 FillpCalRecvRate(pcb);
162 FillpUploadRecvBox(pcb);
163
164 if (pcb->algFuncs.packTimer != FILLP_NULL_PTR) {
165 pcb->algFuncs.packTimer(pcb);
166 }
167
168 enableNormalTimer = FillpSendPackWithPcbBuffer(pcb);
169 if (enableNormalTimer &&
170 (curTime - pack->packRttDetectTime) > (FILLP_LLONG)(sock->resConf.common.fcStasticsInterval)) {
171 FillpSendAdhocpackToDetectRtt(pcb);
172 pack->packRttDetectTime = curTime;
173 }
174
175 pack->packSendTime = pcb->pcbInst->curTime;
176 FillpEnablePackTimerInCb(pcb, enableNormalTimer);
177 }
178
FillpSendTimerCb(void * argPcb)179 void FillpSendTimerCb(void *argPcb)
180 {
181 struct FillpPcb *pcb = (struct FillpPcb *)argPcb;
182 struct FillpFlowControl *flowControl = &pcb->send.flowControl;
183 FILLP_LLONG detaTime = (FILLP_LLONG)(pcb->pcbInst->curTime - flowControl->sendTime);
184 FILLP_LLONG realDetaTime = (FILLP_LLONG)((FILLP_ULLONG)detaTime << FILLP_TIME_PRECISION);
185
186 FILLP_LOGDBG("cur %lld, deta_time:%lld, send_interval:%lld",
187 pcb->pcbInst->curTime, realDetaTime, flowControl->sendInterval);
188 if (realDetaTime >= flowControl->sendInterval) {
189 SpungeDoSendCycle((struct SpungePcb *)pcb->spcb, pcb->pcbInst, realDetaTime);
190 } else {
191 FillpEnableSendTimer(pcb);
192 }
193 }
194
FillpEnableSendTimer(struct FillpPcb * pcb)195 void FillpEnableSendTimer(struct FillpPcb *pcb)
196 {
197 if (pcb->send.flowControl.sendInterval < pcb->pcbInst->minSendInterval) {
198 pcb->pcbInst->minSendInterval = pcb->send.flowControl.sendInterval;
199 }
200 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->sendTimerNode)) {
201 return;
202 }
203 FILLP_LOGDBG("enable, pcb->send.flowControl.sendTime:%lld, interval:%u", pcb->send.flowControl.sendTime,
204 pcb->sendTimerNode.interval);
205 if (pcb->send.flowControl.sendTime == 0) {
206 pcb->send.flowControl.remainBytes = 0;
207 pcb->send.flowControl.sendTime = pcb->pcbInst->curTime;
208 }
209 FILLP_LOGDBG("enable time =%lld\t next expire timer=%lld", pcb->pcbInst->curTime,
210 pcb->send.flowControl.sendTime + pcb->sendTimerNode.interval);
211 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
212 pcb->send.flowControl.sendTime + pcb->sendTimerNode.interval, &pcb->sendTimerNode);
213 }
214
FillpDisableSendTimer(struct FillpPcb * pcb)215 void FillpDisableSendTimer(struct FillpPcb *pcb)
216 {
217 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->sendTimerNode)) {
218 FillpTimingWheelDelTimer(pcb->sendTimerNode.wheel, &pcb->sendTimerNode);
219 }
220 }
221
FillpEnablePackTimer(struct FillpPcb * pcb)222 void FillpEnablePackTimer(struct FillpPcb *pcb)
223 {
224 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->packTimerNode)) {
225 FILLP_LOGDBG("enable time =%lld\t next expire timer=%u", pcb->pcbInst->curTime,
226 pcb->packTimerNode.interval);
227 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
228 pcb->packTimerNode.interval + pcb->pcbInst->curTime, &pcb->packTimerNode);
229 }
230 }
231
FillpDisablePackTimer(struct FillpPcb * pcb)232 void FillpDisablePackTimer(struct FillpPcb *pcb)
233 {
234 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->packTimerNode)) {
235 FillpTimingWheelDelTimer(pcb->packTimerNode.wheel, &pcb->packTimerNode);
236 }
237 }
238
FillpEnableFcTimer(struct FillpPcb * pcb)239 void FillpEnableFcTimer(struct FillpPcb *pcb)
240 {
241 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->FcTimerNode)) {
242 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
243 pcb->FcTimerNode.interval + pcb->pcbInst->curTime, &pcb->FcTimerNode);
244 }
245 }
FillpDisableFcTimer(struct FillpPcb * pcb)246 void FillpDisableFcTimer(struct FillpPcb *pcb)
247 {
248 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->FcTimerNode)) {
249 FillpTimingWheelDelTimer(pcb->FcTimerNode.wheel, &pcb->FcTimerNode);
250 }
251 }
252
FillpEnableKeepAliveTimer(struct FillpPcb * pcb)253 void FillpEnableKeepAliveTimer(struct FillpPcb *pcb)
254 {
255 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->keepAliveTimerNode)) {
256 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
257 pcb->keepAliveTimerNode.interval + pcb->pcbInst->curTime, &pcb->keepAliveTimerNode);
258 }
259 }
260
FillpDisableKeepAliveTimer(struct FillpPcb * pcb)261 void FillpDisableKeepAliveTimer(struct FillpPcb *pcb)
262 {
263 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->keepAliveTimerNode)) {
264 FillpTimingWheelDelTimer(pcb->keepAliveTimerNode.wheel, &pcb->keepAliveTimerNode);
265 }
266 }
267
FillpEnableDelayNackTimer(struct FillpPcb * pcb)268 void FillpEnableDelayNackTimer(struct FillpPcb *pcb)
269 {
270 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->delayNackTimerNode)) {
271 FILLP_LOGDBG("Delay NACK Timer Enable: curTime:%lld, interval:%u", pcb->pcbInst->curTime,
272 pcb->delayNackTimerNode.interval);
273 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
274 pcb->pcbInst->curTime + pcb->delayNackTimerNode.interval, &pcb->delayNackTimerNode);
275 }
276 }
277
FillpDisableDelayNackTimer(struct FillpPcb * pcb)278 void FillpDisableDelayNackTimer(struct FillpPcb *pcb)
279 {
280 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->delayNackTimerNode)) {
281 FillpTimingWheelDelTimer(pcb->delayNackTimerNode.wheel, &pcb->delayNackTimerNode);
282 }
283 }
284
FillpEnableDataBurstTimer(struct FillpPcb * pcb)285 void FillpEnableDataBurstTimer(struct FillpPcb *pcb)
286 {
287 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->dataBurstTimerNode)) {
288 FILLP_LOGDBG("Data Burst Timer Enable: curTime:%lld, interval:%u", pcb->pcbInst->curTime,
289 pcb->dataBurstTimerNode.interval);
290 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
291 pcb->pcbInst->curTime + pcb->dataBurstTimerNode.interval, &pcb->dataBurstTimerNode);
292 }
293 }
FillpDisableDataBurstTimer(struct FillpPcb * pcb)294 void FillpDisableDataBurstTimer(struct FillpPcb *pcb)
295 {
296 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->dataBurstTimerNode)) {
297 FillpTimingWheelDelTimer(pcb->dataBurstTimerNode.wheel, &pcb->dataBurstTimerNode);
298 }
299 }
300
FillpEnableConnRetryCheckTimer(struct FillpPcb * pcb)301 void FillpEnableConnRetryCheckTimer(struct FillpPcb *pcb)
302 {
303 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->connRetryTimeoutTimerNode)) {
304 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
305 pcb->pcbInst->curTime + pcb->connRetryTimeoutTimerNode.interval, &pcb->connRetryTimeoutTimerNode);
306 }
307 }
FillpDisableConnRetryCheckTimer(struct FillpPcb * pcb)308 void FillpDisableConnRetryCheckTimer(struct FillpPcb *pcb)
309 {
310 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->connRetryTimeoutTimerNode)) {
311 FillpTimingWheelDelTimer(pcb->connRetryTimeoutTimerNode.wheel, &pcb->connRetryTimeoutTimerNode);
312 }
313 }
314
FillpEnableFinCheckTimer(struct FillpPcb * pcb)315 void FillpEnableFinCheckTimer(struct FillpPcb *pcb)
316 {
317 if (!FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->finCheckTimer)) {
318 FillpTimingWheelAddTimer(&pcb->pcbInst->timingWheel,
319 pcb->pcbInst->curTime + pcb->finCheckTimer.interval, &pcb->finCheckTimer);
320 }
321 }
322
FillpDisableFinCheckTimer(struct FillpPcb * pcb)323 void FillpDisableFinCheckTimer(struct FillpPcb *pcb)
324 {
325 if (FILLP_TIMING_WHEEL_IS_NODE_ENABLED(&pcb->finCheckTimer)) {
326 FillpTimingWheelDelTimer(pcb->finCheckTimer.wheel, &pcb->finCheckTimer);
327 }
328 }
329
FillpFcTimerCb(void * argPcb)330 void FillpFcTimerCb(void *argPcb)
331 {
332 struct FillpPcb *pcb = (struct FillpPcb *)argPcb;
333
334 if (pcb->algFuncs.fcTime != FILLP_NULL_PTR) {
335 pcb->algFuncs.fcTime(pcb);
336 FillpEnableFcTimer(pcb);
337 }
338 }
339
340 #ifdef __cplusplus
341 }
342 #endif
343