• 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 #include "trans_pending_pkt.h"
17 
18 #include <sys/time.h>
19 #include <unistd.h>
20 
21 #include "softbus_adapter_mem.h"
22 #include "softbus_adapter_thread.h"
23 #include "softbus_errcode.h"
24 #include "softbus_log.h"
25 #include "softbus_utils.h"
26 
27 #define TIME_OUT 20
28 
29 typedef struct {
30     ListNode node;
31     SoftBusCond cond;
32     SoftBusMutex lock;
33     int32_t channelId;
34     int32_t seq;
35     uint8_t status;
36 } PendingPktInfo;
37 
38 enum PackageStatus {
39     PACKAGE_STATUS_PENDING = 0,
40     PACKAGE_STATUS_FINISHED,
41     PACKAGE_STATUS_CANCELED
42 };
43 
44 static SoftBusList *g_pendingList[PENDING_TYPE_BUTT] = {NULL, NULL};
45 
PendingInit(int type)46 int32_t PendingInit(int type)
47 {
48     if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) {
49         return SOFTBUS_ERR;
50     }
51 
52     g_pendingList[type] = CreateSoftBusList();
53     if (g_pendingList[type] == NULL) {
54         return SOFTBUS_ERR;
55     }
56     return SOFTBUS_OK;
57 }
58 
PendingDeinit(int type)59 void PendingDeinit(int type)
60 {
61     if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) {
62         return;
63     }
64 
65     if (g_pendingList[type] != NULL) {
66         DestroySoftBusList(g_pendingList[type]);
67         g_pendingList[type] = NULL;
68     }
69     SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_INFO, "PendigPackManagerDeinit init ok");
70 }
71 
TimeBefore(const SoftBusSysTime * inputTime)72 static inline bool TimeBefore(const SoftBusSysTime *inputTime)
73 {
74     SoftBusSysTime now;
75     SoftBusGetTime(&now);
76     return (now.sec < inputTime->sec || (now.sec == inputTime->sec && now.usec < inputTime->usec));
77 }
78 
CreatePendingItem(int32_t channelId,int32_t seqNum)79 static PendingPktInfo *CreatePendingItem(int32_t channelId, int32_t seqNum)
80 {
81     PendingPktInfo *item = (PendingPktInfo *)SoftBusCalloc(sizeof(PendingPktInfo));
82     if (item == NULL) {
83         return NULL;
84     }
85 
86     SoftBusMutexInit(&item->lock, NULL);
87     SoftBusCondInit(&item->cond);
88     item->channelId = channelId;
89     item->seq = seqNum;
90     item->status = PACKAGE_STATUS_PENDING;
91     return item;
92 }
93 
ReleasePendingItem(PendingPktInfo * item)94 static void ReleasePendingItem(PendingPktInfo *item)
95 {
96     if (item == NULL) {
97         return;
98     }
99     (void)SoftBusMutexDestroy(&item->lock);
100     (void)SoftBusCondDestroy(&item->cond);
101     SoftBusFree(item);
102 }
103 
ProcPendingPacket(int32_t channelId,int32_t seqNum,int type)104 int32_t ProcPendingPacket(int32_t channelId, int32_t seqNum, int type)
105 {
106     if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) {
107         return SOFTBUS_ERR;
108     }
109 
110     PendingPktInfo *item = NULL;
111     SoftBusList *pendingList = g_pendingList[type];
112     if (pendingList == NULL) {
113         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pending[%d] list not inited.", type);
114         return SOFTBUS_TRANS_TDC_PENDINGLIST_NOT_FOUND;
115     }
116 
117     SoftBusMutexLock(&pendingList->lock);
118     LIST_FOR_EACH_ENTRY(item, &pendingList->list, PendingPktInfo, node)
119     {
120         if (item->seq == seqNum && item->channelId == channelId) {
121             SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "PendingPacket already Created");
122             SoftBusMutexUnlock(&pendingList->lock);
123             return SOFTBUS_TRANS_TDC_CHANNEL_ALREADY_PENDING;
124         }
125     }
126 
127     item = CreatePendingItem(channelId, seqNum);
128     if (item == NULL) {
129         SoftBusMutexUnlock(&pendingList->lock);
130         return SOFTBUS_MALLOC_ERR;
131     }
132     ListAdd(&pendingList->list, &item->node);
133     pendingList->cnt++;
134     SoftBusMutexUnlock(&pendingList->lock);
135 
136     SoftBusSysTime outtime;
137     SoftBusSysTime now;
138     SoftBusGetTime(&now);
139     outtime.sec = now.sec + TIME_OUT;
140     outtime.usec = now.usec;
141     SoftBusMutexLock(&item->lock);
142     while (item->status == PACKAGE_STATUS_PENDING && TimeBefore(&outtime)) {
143         SoftBusCondWait(&item->cond, &item->lock, &outtime);
144     }
145 
146     int32_t ret = SOFTBUS_OK;
147     if (item->status != PACKAGE_STATUS_FINISHED) {
148         ret = SOFTBUS_TIMOUT;
149     }
150     SoftBusMutexUnlock(&item->lock);
151 
152     SoftBusMutexLock(&pendingList->lock);
153     ListDelete(&item->node);
154     pendingList->cnt--;
155     SoftBusMutexUnlock(&pendingList->lock);
156     ReleasePendingItem(item);
157     return ret;
158 }
159 
SetPendingPacket(int32_t channelId,int32_t seqNum,int type)160 int32_t SetPendingPacket(int32_t channelId, int32_t seqNum, int type)
161 {
162     if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) {
163         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "type[%d] illegal.", type);
164         return SOFTBUS_ERR;
165     }
166 
167     SoftBusList *pendingList = g_pendingList[type];
168     if (pendingList == NULL) {
169         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "pendind list not exist");
170         return SOFTBUS_ERR;
171     }
172     if (SoftBusMutexLock(&pendingList->lock) != SOFTBUS_OK) {
173         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "set pendind lock failed.");
174         return SOFTBUS_ERR;
175     }
176     PendingPktInfo *item = NULL;
177     LIST_FOR_EACH_ENTRY(item, &pendingList->list, PendingPktInfo, node) {
178         if (item->seq == seqNum && item->channelId == channelId) {
179             item->status = PACKAGE_STATUS_FINISHED;
180             SoftBusCondSignal(&item->cond);
181             SoftBusMutexUnlock(&pendingList->lock);
182             return SOFTBUS_OK;
183         }
184     }
185     SoftBusMutexUnlock(&pendingList->lock);
186     return SOFTBUS_ERR;
187 }
188 
DelPendingPacket(int32_t channelId,int type)189 int32_t DelPendingPacket(int32_t channelId, int type)
190 {
191     if (type < PENDING_TYPE_PROXY || type >= PENDING_TYPE_BUTT) {
192         return SOFTBUS_ERR;
193     }
194 
195     SoftBusList *pendingList = g_pendingList[type];
196     if (pendingList == NULL) {
197         return SOFTBUS_ERR;
198     }
199     if (SoftBusMutexLock(&pendingList->lock) != SOFTBUS_OK) {
200         SoftBusLog(SOFTBUS_LOG_TRAN, SOFTBUS_LOG_ERROR, "del pendind lock failed.");
201         return SOFTBUS_ERR;
202     }
203     PendingPktInfo *item = NULL;
204     LIST_FOR_EACH_ENTRY(item, &pendingList->list, PendingPktInfo, node) {
205         if (item->channelId == channelId) {
206             item->status = PACKAGE_STATUS_CANCELED;
207             SoftBusCondSignal(&item->cond);
208             SoftBusMutexUnlock(&pendingList->lock);
209             return SOFTBUS_OK;
210         }
211     }
212     SoftBusMutexUnlock(&pendingList->lock);
213     return SOFTBUS_OK;
214 }
215 
216