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