1 /*
2  * Copyright (C) 2021 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 #ifndef NSTACKX_DFILE_TRANSFER_H
17 #define NSTACKX_DFILE_TRANSFER_H
18 
19 #include <stdint.h>
20 #include <stdio.h>
21 #include "nstackx_list.h"
22 #include "nstackx_dfile.h"
23 #include "nstackx_util.h"
24 #include "nstackx_file_list.h"
25 #include "nstackx_dfile_frame.h"
26 #include "nstackx_file_manager.h"
27 #include "nstackx_dfile_config.h"
28 #include "nstackx_timer.h"
29 #include "nstackx_dev.h"
30 
31 #define DFILE_SHOW_RECEIVE_TIME 1
32 #define NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE   6
33 #define INTEGRAL_TIME 2
34 
35 typedef enum {
36     DFILE_TRANS_MSG_FILE_SEND_DATA,
37     DFILE_TRANS_MSG_FILE_LIST_RECEIVED,
38     DFILE_TRANS_MSG_FILE_RECEIVED, /* Receiver receive all the file data */
39     DFILE_TRANS_MSG_FILE_RECEIVE_FAIL,
40     DFILE_TRANS_MSG_FILE_RECEIVED_TO_FAIL,
41     DFILE_TRANS_MSG_FILE_SENT, /* Sender send TRANSFER DONE ACK frame and come to end */
42     DFILE_TRANS_MSG_FILE_SEND_FAIL,
43     DFILE_TRANS_MSG_IN_PROGRESS,
44     DFILE_TRANS_MSG_FILE_SEND_ACK,
45     DFILE_TRANS_MSG_END,
46 } DFileTransMsgType;
47 
48 typedef enum {
49     DFILE_TRANS_NO_ERROR = 0,
50     DFILE_TRANS_SOCKET_ERROR, /* Socket IO error */
51     DFILE_TRANS_INTERNAL_ERROR, /* Internal error, such as no memory. */
52     /* For sender */
53     DFILE_TRANS_FILE_HEADER_CONFIRM_TIMEOUT, /* Wait for HEADER CONFIRM frame timeout */
54     DFILE_TRANS_FILE_DATA_ACK_TIMEOUT, /* Heart beat (DATA ACK frame) timeout */
55     DFILE_TRANS_TRANSFER_DONE_TIMEOUT, /* Wait for TRANSFER DONE frame timeout */
56     /* For receiver */
57     DFILE_TRANS_FILE_HEADER_TIMEOUT, /* Receive HEADER frame timeout (partially received) */
58     DFILE_TRANS_FILE_DATA_TIMEOUT, /* Receive file data timeout (partially received) */
59     /* Receiver wait for TRANSFER DONE ACK frame timeout, for debug purpose, won't report to user */
60     DFILE_TRANS_TRANSFER_DONE_ACK_TIMEOUT,
61     DFILE_TRANS_FILE_SEND_TASK_ERROR, /* Send task error */
62     DFILE_TRANS_FILE_RECEIVE_TASK_ERROR, /* Receive task error */
63     DFILE_TRANS_FILE_WRITE_FAIL, /* Write file list fail */
64     DFILE_TRANS_FILE_RENAME_FAIL, /* Rename file fail */
65 } DFileTransErrorCode;
66 
67 typedef enum {
68     STATE_SEND_FILE_INIT = 0,
69     STATE_SEND_FILE_HEADER_ONGOING,
70     STATE_WAIT_FOR_FILE_HEADER_CONFIRM,
71     STATE_SEND_FILE_DATA_ONGOING,
72     STATE_WAIT_FOR_FILE_TRANSFER_DONE_FRAME,
73     STATE_SEND_FILE_TRANSFER_DONE_ACK,
74     STATE_SEND_FILE_DONE,
75     STATE_SEND_FILE_FAIL,
76 } DFileSendState;
77 
78 typedef enum {
79     STATE_RECEIVE_FILE_INIT = 0,
80     STATE_RECEIVE_FILE_HEADER_ONGOING,
81     STATE_SEND_FILE_HEADER_CONFIRM,
82     STATE_RECEIVE_FILE_DATA_ONGOING,
83     STATE_SEND_FILE_DATA_ACK,
84     STATE_SEND_FILE_TRANSFER_DONE,
85     STATE_WAIT_FOR_FILE_TRANSFER_DONE_ACK,
86     STATE_RECEIVE_FILE_DONE,
87     STATE_RECEIVE_FILE_FAIL,
88 } DFileReceiveState;
89 
90 struct DFileTrans;
91 /* Reuse DFileMsg for ease use */
92 typedef DFileMsg DFileTransMsg;
93 
94 typedef int32_t (*DFileTransWriteHandle)(const uint8_t *frame, size_t len, void *context);
95 typedef void (*DFileTransMsgReceiver)(struct DFileTrans *dFileTrans, DFileTransMsgType msgType, DFileTransMsg *msg);
96 
97 typedef struct {
98     uint16_t lastRetranFileId;
99     uint32_t lastRetranFileSequence;
100     uint32_t sameRetraLostBlocks;
101     uint8_t lastRetranLevel;
102 } RetranFileRecord;
103 
104 typedef struct DFileTrans {
105     List list;
106     uint16_t transId;
107     uint8_t isSender;
108     DFileSendState sendState;
109     DFileReceiveState recvState;
110     /* members for sending file */
111     int32_t lastSentHeaderFileId;
112     uint8_t headerRetryCnt;
113     uint8_t lostAckCnt;
114     uint8_t fileTransferReqReceived; /* Flag: Receive File Transfer REQ frame */
115     uint8_t fileTransferDoneReceived; /* Flag: Receive File Transfer Done frame */
116     uint8_t *remainDataFrame;
117 
118     /* members for receiving file */
119     uint16_t lastAckedHeaderFileId;
120     uint16_t lastFileDataRecvFileId;
121     uint32_t lastFileDataSequence;
122     uint16_t prefileId;
123     uint32_t preSequence;
124     uint16_t haveRetransFilefileId;
125     uint32_t haveRetransFilepreSequence;
126     struct timespec retryAllPacketTs;
127     struct timespec heartBeatTs;
128     uint8_t headerAckRetryCnt;
129     uint8_t idleTimeoutCnt;
130     uint8_t allFileNameReceived;
131     uint8_t dupFileName;
132     uint8_t allFileDataReceived;
133     uint8_t fileTransferDoneAcked;
134     uint8_t transferDoneRetryCnt;
135     uint8_t recvPacketFlag;
136     uint8_t retransFileFlag;
137     /* members for data lost and retry */
138     List retryList;
139     List *retryPointer;
140     uint32_t retryCount;
141     uint32_t allRetryCount;
142     uint32_t allRetrySendCount;
143     uint32_t shouldSendAck;
144     uint32_t shouldSendAckDividor;
145 #if DFILE_SHOW_RECEIVE_TIME
146     struct timespec startTs;
147 #endif
148 
149     uint64_t totalDataFrameCnt;
150     uint64_t receivedDataFrameCnt;
151     uint64_t adjustAckIntervalLimit;
152     uint32_t ackInterval;
153     uint32_t transRetryCount;
154     uint32_t notInsertCount;
155 
156     uint16_t connType;
157     DFileTransConfig config;
158     DFileTransErrorCode errorCode;
159     struct timespec ts;
160     uint32_t timeout;
161     uint8_t fileManagerTaskStarted;
162     uint8_t sendBuffer[NSTACKX_MAX_FRAME_SIZE];
163     size_t sendBufferLength;
164     uint16_t mtu;
165     FileList *fileList;
166     FileManager *fileManager;
167     DFileTransWriteHandle writeHandle;
168     DFileTransMsgReceiver msgReceiver;
169     void *context;
170     DFileSession *session;
171     uint8_t isRecvSucMsgNotified;
172     uint64_t bytesTransferredLastRecord; /* just usefully for receiver */
173     uint64_t bytesTransferred; /* just usefully for receiver */
174     uint64_t totalBytes;  /* just usefully for receiver */
175     uint8_t isAckSend;
176     uint8_t recvLastFramePrint;
177     uint8_t adjustAckIntervalLimitPrint;
178     uint64_t recvBlockListFullTimes;
179     uint8_t adjustToLastFrameAckInterval;
180     OnDFileRenameFile onRenameFile;
181     uint32_t recvCount;
182     uint8_t sendRetransFileCount;
183     uint8_t ioWriteFinishFlag;
184     uint32_t backPressureBypassCnt;
185 } DFileTrans;
186 
187 typedef struct {
188     uint8_t isSender;
189     uint16_t transId;
190     FileManager *fileManager;
191     ConnectType connType;
192     DFileTransWriteHandle writeHandle;
193     DFileTransMsgReceiver msgReceiver;
194     void *context;
195     DFileSession *session;
196     OnDFileRenameFile onRenameFile;
197 } DFileTransPara;
198 
199 typedef enum SettingState {
200     SETTING_NEGOTIATING = 0,
201     SETTING_NEGOTIATED
202 } SettingState;
203 
204 typedef struct PeerInfo {
205     List list;
206     struct sockaddr_in dstAddr;
207     char localInterfaceName[IFNAMSIZ];
208     uint16_t localMtu;
209     uint16_t mtu;
210     uint16_t mtuInuse;
211     uint16_t dataFrameSize;
212     uint16_t connType;
213     SettingState state;
214     DFileSession *session;
215     Timer *settingTimer;
216     uint8_t settingTimeoutCnt;
217     uint8_t socketIndex;
218     int32_t remoteSessionId;
219     uint64_t overRun;
220     struct PeerInfo *brotherPeer;
221 
222     /* congestion control info */
223     WifiStationInfo rxWifiStationInfo; /* save the bitrate of the server endian to calculate the sendrate */
224     int8_t rxWifiStationInfoStatus;
225     double integralLossRate[INTEGRAL_TIME];
226     uint32_t fastStartCounter;
227     /* qdisc info */
228     uint16_t qdiscMaxLeft;
229     uint16_t qdiscMinLeft;
230     uint32_t qdiscSearchNum;
231     uint32_t qdiscAveLeft;
232 
233     FlowCtrlInfo flowCtrlInfo; /* flow control info */
234 
235     struct timespec startTime;
236     uint32_t sendCount;
237     uint32_t sendCountRateMB;
238     uint16_t sendRate;
239     uint16_t maxSendRate;
240     uint32_t sendFrameRate;
241     uint32_t intervalSendCount;
242     int32_t amendSendRate;
243     uint8_t decreaseStatus;
244 
245     uint32_t eAgainCount;
246     struct timespec measureBefore;
247     struct timespec ackDropTimer;
248     uint32_t maxRetryCountPerSec;
249     uint32_t maxRetryCountLastSec;
250 
251     uint32_t recvCount;
252     uint32_t recvFrameRate;
253     uint32_t recvCountRateMB;
254     uint32_t allDtransRetryCount;
255 
256     uint32_t retryCountHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
257     uint16_t sendRateHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
258     uint16_t recvRateHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
259     uint16_t locationHistoryData;
260     uint16_t ackInterval;
261     uint32_t rateStateInterval;
262     uint16_t sendAckNum;
263     uint32_t remoteDFileVersion;
264     uint8_t gotWifiRate;
265     uint32_t linkSequence;
266     uint32_t lastMaxSeq;
267     uint32_t lastTimes;
268     uint32_t duplicateCount;
269     uint32_t currentTransCount;
270 } PeerInfo;
271 
ClearPeerinfoStats(PeerInfo * peerInfo)272 static inline void ClearPeerinfoStats(PeerInfo *peerInfo)
273 {
274     peerInfo->sendCount = 0;
275     peerInfo->qdiscMinLeft = 0;
276     peerInfo->qdiscMaxLeft = 0;
277     peerInfo->qdiscAveLeft = 0;
278     peerInfo->qdiscSearchNum = 0;
279 }
280 
281 int32_t DFileTransSendFiles(DFileTrans *trans, FileListInfo *fileListInfo);
282 int32_t DFileTransAddExtraInfo(DFileTrans *trans, uint16_t pathType, uint8_t noticeFileNameType, char *userData);
283 int32_t HandleDFileFrame(DFileTrans *dFileTrans, DFileFrame *dFileFrame);
284 void DFileTransProcess(DFileTrans *dFileTrans);
285 int64_t DFileTransGetTimeout(DFileTrans *dFileTrans);
286 int32_t DFileTransSetMtu(DFileTrans *dFileTrans, uint16_t mtu);
287 
288 DFileTrans *DFileTransCreate(const DFileTransPara *para);
289 void DFileTransDestroy(DFileTrans *dFileTrans);
290 void DFileTransDestroyInner(DFileTrans *dFileTrans);
291 uint64_t DFileTransGetTotalBytes(const DFileTrans *dFileTrans);
292 void FileManagerReceiverMsgHandler(uint16_t fileId, FileManagerMsgType msgType, FileManagerMsg *msg,
293                                    DFileTrans *dFileTrans);
294 void FileManagerSenderMsgHandler(uint16_t fileId, FileManagerMsgType msgType, FileManagerMsg *msg,
295                                  DFileTrans *dFileTrans);
296 int32_t SendFrame(DFileTrans *dFileTrans, uint8_t *frame, size_t frameLength, DFileSendState *nextSend,
297                   DFileReceiveState *nextRecv);
298 void ReviewSuccessMsg(const DFileTrans *dFileTrans, DFileTransMsgType *msgType,
299     DFileTransMsg *msg, char *files[]);
300 #endif /* NSTACKX_DFILE_TRANSFER_H */
301