• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     uint8_t lastRetranLevel;
100     uint32_t sameRetraLostBlocks;
101     uint32_t lastRetranFileSequence;
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     uint8_t headerRetryCnt;
112     uint8_t lostAckCnt;
113     uint8_t fileTransferReqReceived; /* Flag: Receive File Transfer REQ frame */
114     uint8_t fileTransferDoneReceived; /* Flag: Receive File Transfer Done frame */
115     int32_t lastSentHeaderFileId;
116     uint8_t *remainDataFrame;
117     /* members for receiving file */
118     struct timespec retryAllPacketTs;
119     struct timespec heartBeatTs;
120     uint16_t lastAckedHeaderFileId;
121     uint16_t lastFileDataRecvFileId;
122     uint32_t lastFileDataSequence;
123     uint16_t prefileId;
124     uint16_t haveRetransFilefileId;
125     uint32_t preSequence;
126     uint32_t haveRetransFilepreSequence;
127     uint8_t headerAckRetryCnt;
128     uint8_t idleTimeoutCnt;
129     uint8_t allFileNameReceived;
130     uint8_t dupFileName;
131     uint8_t allFileDataReceived;
132     uint8_t fileTransferDoneAcked;
133     uint8_t transferDoneRetryCnt;
134     uint8_t recvPacketFlag;
135     uint8_t retransFileFlag;
136     /* members for data lost and retry */
137     List retryList;
138     List *retryPointer;
139     uint32_t retryCount;
140     uint32_t allRetryCount;
141     uint32_t allRetrySendCount;
142     uint32_t shouldSendAck;
143     uint32_t shouldSendAckDividor;
144 
145     uint32_t ackInterval;
146     uint32_t transRetryCount;
147     uint32_t notInsertCount;
148 #if DFILE_SHOW_RECEIVE_TIME
149     struct timespec startTs;
150 #endif
151     uint64_t totalDataFrameCnt;
152     uint64_t receivedDataFrameCnt;
153     uint64_t adjustAckIntervalLimit;
154     uint8_t fileManagerTaskStarted;
155     uint8_t isRecvSucMsgNotified;
156     uint8_t isAckSend;
157     uint8_t recvLastFramePrint;
158     uint8_t adjustAckIntervalLimitPrint;
159     uint8_t adjustToLastFrameAckInterval;
160     uint8_t sendRetransFileCount;
161     uint8_t ioWriteFinishFlag;
162 
163     uint16_t connType;
164     uint16_t mtu;
165     DFileTransConfig config;
166     DFileTransErrorCode errorCode;
167     uint32_t timeout;
168     struct timespec ts;
169     uint8_t sendBuffer[NSTACKX_MAX_FRAME_SIZE];
170     size_t sendBufferLength;
171     FileList *fileList;
172     FileManager *fileManager;
173     DFileTransWriteHandle writeHandle;
174     DFileTransMsgReceiver msgReceiver;
175     void *context;
176     DFileSession *session;
177 
178     uint64_t bytesTransferredLastRecord; /* just usefully for receiver */
179     uint64_t bytesTransferred; /* just usefully for receiver */
180     uint64_t totalBytes;  /* just usefully for receiver */
181     uint64_t recvBlockListFullTimes;
182     OnDFileRenameFile onRenameFile;
183     uint32_t recvCount;
184     uint32_t backPressureBypassCnt;
185 } DFileTrans;
186 
187 typedef struct {
188     uint8_t isSender;
189     uint16_t transId;
190     ConnectType connType;
191     FileManager *fileManager;
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     DFileSession *session;
209     Timer *settingTimer;
210     struct PeerInfo *brotherPeer;
211     uint64_t overRun;
212     uint16_t localMtu;
213     uint16_t mtu;
214     uint16_t mtuInuse;
215     uint16_t dataFrameSize;
216     uint16_t connType;
217     uint8_t settingTimeoutCnt;
218     uint8_t socketIndex;
219     int32_t remoteSessionId;
220     SettingState state;
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     uint8_t gotWifiRate;
245     uint16_t sendAckNum;
246     uint32_t eAgainCount;
247     struct timespec measureBefore;
248     struct timespec ackDropTimer;
249     uint32_t maxRetryCountPerSec;
250     uint32_t maxRetryCountLastSec;
251 
252     uint32_t recvCount;
253     uint32_t recvFrameRate;
254     uint32_t recvCountRateMB;
255     uint32_t allDtransRetryCount;
256 
257     uint32_t retryCountHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
258     uint16_t sendRateHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
259     uint16_t recvRateHistoryData[NSTACKX_RETRY_HISTORY_DATA_ARRAY_SIZE];
260     uint16_t locationHistoryData;
261     uint16_t ackInterval;
262     uint32_t rateStateInterval;
263     uint32_t remoteDFileVersion;
264     uint32_t linkSequence;
265     uint32_t lastMaxSeq;
266     uint32_t lastTimes;
267     uint32_t duplicateCount;
268     uint32_t currentTransCount;
269 } PeerInfo;
270 
ClearPeerinfoStats(PeerInfo * peerInfo)271 static inline void ClearPeerinfoStats(PeerInfo *peerInfo)
272 {
273     peerInfo->sendCount = 0;
274     peerInfo->qdiscMinLeft = 0;
275     peerInfo->qdiscMaxLeft = 0;
276     peerInfo->qdiscAveLeft = 0;
277     peerInfo->qdiscSearchNum = 0;
278 }
279 
280 int32_t DFileTransSendFiles(DFileTrans *trans, FileListInfo *fileListInfo);
281 int32_t DFileTransAddExtraInfo(DFileTrans *trans, uint16_t pathType, uint8_t noticeFileNameType, char *userData);
282 int32_t HandleDFileFrame(DFileTrans *dFileTrans, DFileFrame *dFileFrame);
283 void DFileTransProcess(DFileTrans *dFileTrans);
284 int64_t DFileTransGetTimeout(DFileTrans *dFileTrans);
285 int32_t DFileTransSetMtu(DFileTrans *dFileTrans, uint16_t mtu);
286 
287 DFileTrans *DFileTransCreate(const DFileTransPara *para);
288 void DFileTransDestroy(DFileTrans *dFileTrans);
289 void DFileTransDestroyInner(DFileTrans *dFileTrans);
290 uint64_t DFileTransGetTotalBytes(const DFileTrans *dFileTrans);
291 void FileManagerReceiverMsgHandler(uint16_t fileId, FileManagerMsgType msgType, FileManagerMsg *msg,
292                                    DFileTrans *dFileTrans);
293 void FileManagerSenderMsgHandler(uint16_t fileId, FileManagerMsgType msgType, FileManagerMsg *msg,
294                                  DFileTrans *dFileTrans);
295 int32_t SendFrame(DFileTrans *dFileTrans, uint8_t *frame, size_t frameLength, DFileSendState *nextSend,
296                   DFileReceiveState *nextRecv);
297 void ReviewSuccessMsg(const DFileTrans *dFileTrans, DFileTransMsgType *msgType,
298     DFileTransMsg *msg, char *files[]);
299 #endif /* NSTACKX_DFILE_TRANSFER_H */
300