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 "softbus_conn_common.h"
17 
18 #include "securec.h"
19 #include "conn_log.h"
20 #include "softbus_adapter_mem.h"
21 #include "softbus_adapter_thread.h"
22 #include "softbus_common.h"
23 #include "softbus_def.h"
24 #include "softbus_socket.h"
25 #include "softbus_type_def.h"
26 #include "anonymizer.h"
27 
28 #define HIGH_PRIORITY_DEFAULT_LIMIT   32
29 #define MIDDLE_PRIORITY_DEFAULT_LIMIT 32
30 #define LOW_PRIORITY_DEFAULT_LIMIT    32
31 
32 #define MICROSECONDS 1000000
33 
34 static const int32_t QUEUE_LIMIT[QUEUE_NUM_PER_PID] = {
35     HIGH_PRIORITY_DEFAULT_LIMIT,
36     MIDDLE_PRIORITY_DEFAULT_LIMIT,
37     LOW_PRIORITY_DEFAULT_LIMIT,
38 };
39 
AnonymizeData(char * outAnomize,uint32_t anomizeLen,const char * data)40 static void AnonymizeData(char *outAnomize, uint32_t anomizeLen, const char *data)
41 {
42     char *temp = NULL;
43     Anonymize(data, &temp);
44     if (strcpy_s(outAnomize, anomizeLen, AnonymizeWrapper(temp)) != EOK) {
45         CONN_LOGE(CONN_COMMON, "copy anonymize data fail");
46         AnonymizeFree(temp);
47         return;
48     }
49     AnonymizeFree(temp);
50 }
51 
ConnStartActionAsync(void * arg,void * (* runnable)(void *),const char * taskName)52 int32_t ConnStartActionAsync(void *arg, void *(*runnable)(void *), const char *taskName)
53 {
54     SoftBusThreadAttr attr;
55     SoftBusThreadAttrInit(&attr);
56     attr.detachState = SOFTBUS_THREAD_DETACH;
57     attr.taskName = taskName;
58     SoftBusThread actionAsyncThread;
59     int32_t status = SoftBusThreadCreate(&actionAsyncThread, &attr, runnable, arg);
60     return status;
61 }
62 
ConvertAnonymizeMacAddress(char * outAnomize,uint32_t anomizeLen,const char * mac,uint32_t macLen)63 void ConvertAnonymizeMacAddress(char *outAnomize, uint32_t anomizeLen, const char *mac, uint32_t macLen)
64 {
65     if (anomizeLen < BT_MAC_LEN || macLen != BT_MAC_LEN) {
66         return;
67     }
68     AnonymizeData(outAnomize, anomizeLen, mac);
69 }
70 
ConvertAnonymizeIpAddress(char * outAnomize,uint32_t anomizeLen,const char * ip,uint32_t ipLen)71 void ConvertAnonymizeIpAddress(char *outAnomize, uint32_t anomizeLen, const char *ip, uint32_t ipLen)
72 {
73     if (anomizeLen < IP_LEN || ipLen != IP_LEN) {
74         return;
75     }
76     AnonymizeData(outAnomize, anomizeLen, ip);
77 }
78 
ConvertAnonymizeSensitiveString(char * outAnomize,uint32_t anomizeLen,const char * origin)79 void ConvertAnonymizeSensitiveString(char *outAnomize, uint32_t anomizeLen, const char *origin)
80 {
81     if (outAnomize == NULL || origin == NULL) {
82         return;
83     }
84     AnonymizeData(outAnomize, anomizeLen, origin);
85 }
86 
ConnFreeMessage(SoftBusMessage * msg)87 static void ConnFreeMessage(SoftBusMessage *msg)
88 {
89     CONN_CHECK_AND_RETURN_LOGW(msg != NULL, CONN_COMMON, "ATTENTION UNEXPECTED ERROR, try to free a null msg");
90     if (msg->obj != NULL) {
91         SoftBusFree(msg->obj);
92         msg->obj = NULL;
93     }
94     SoftBusFree(msg);
95 }
96 
ConnPostMsgToLooper(SoftBusHandlerWrapper * wrapper,int32_t what,uint64_t arg1,uint64_t arg2,void * obj,uint64_t delayMillis)97 int32_t ConnPostMsgToLooper(
98     SoftBusHandlerWrapper *wrapper, int32_t what, uint64_t arg1, uint64_t arg2, void *obj, uint64_t delayMillis)
99 {
100     SoftBusMessage *msg = (SoftBusMessage *)SoftBusCalloc(sizeof(SoftBusMessage));
101     CONN_CHECK_AND_RETURN_RET_LOGE(msg != NULL, SOFTBUS_MEM_ERR, CONN_COMMON,
102         "ATTENTION, calloc message object failed: what=%{public}d", what);
103     msg->what = what;
104     msg->arg1 = arg1;
105     msg->arg2 = arg2;
106     msg->handler = &wrapper->handler;
107     msg->FreeMessage = ConnFreeMessage;
108     msg->obj = obj;
109     wrapper->handler.looper->PostMessageDelay(wrapper->handler.looper, msg, delayMillis);
110     return SOFTBUS_OK;
111 }
112 
ConnRemoveMsgFromLooper(const SoftBusHandlerWrapper * wrapper,int32_t what,uint64_t arg1,uint64_t arg2,void * obj)113 void ConnRemoveMsgFromLooper(
114     const SoftBusHandlerWrapper *wrapper, int32_t what, uint64_t arg1, uint64_t arg2, void *obj)
115 {
116     SoftBusMessage ctx = {
117         .what = what,
118         .arg1 = arg1,
119         .arg2 = arg2,
120         .obj = obj,
121     };
122     wrapper->handler.looper->RemoveMessageCustom(
123         wrapper->handler.looper, &wrapper->handler, wrapper->eventCompareFunc, &ctx);
124 }
125 
ConnNewLimitedBuffer(LimitedBuffer ** outLimiteBuffer,uint32_t capacity)126 int32_t ConnNewLimitedBuffer(LimitedBuffer **outLimiteBuffer, uint32_t capacity)
127 {
128     LimitedBuffer *tmpLimiteBuffer = (LimitedBuffer *)SoftBusCalloc(sizeof(LimitedBuffer));
129     uint8_t *tmpByteBuffer = (uint8_t *)SoftBusCalloc(capacity * sizeof(uint8_t));
130     if (tmpLimiteBuffer == NULL || tmpByteBuffer == NULL) {
131         SoftBusFree(tmpLimiteBuffer);
132         SoftBusFree(tmpByteBuffer);
133         return SOFTBUS_MEM_ERR;
134     }
135     tmpLimiteBuffer->buffer = tmpByteBuffer;
136     tmpLimiteBuffer->capacity = capacity;
137     tmpLimiteBuffer->length = 0;
138     *outLimiteBuffer = tmpLimiteBuffer;
139     return SOFTBUS_OK;
140 }
141 
ConnDeleteLimitedBuffer(LimitedBuffer ** limiteBuffer)142 void ConnDeleteLimitedBuffer(LimitedBuffer **limiteBuffer)
143 {
144     LimitedBuffer *tmp = *limiteBuffer;
145     if (tmp == NULL) {
146         return;
147     }
148     if (tmp->buffer != NULL) {
149         SoftBusFree(tmp->buffer);
150         tmp->buffer = NULL;
151     }
152     SoftBusFree(tmp);
153     *limiteBuffer = NULL;
154 }
155 
ConnectSoftBusCondWait(SoftBusCond * cond,SoftBusMutex * mutex,uint32_t timeMillis)156 static int32_t ConnectSoftBusCondWait(SoftBusCond *cond, SoftBusMutex *mutex, uint32_t timeMillis)
157 {
158 #define USECTONSEC 1000LL
159     if (timeMillis == 0) {
160         return SoftBusCondWait(cond, mutex, NULL);
161     }
162     SoftBusSysTime now;
163     if (SoftBusGetTime(&now) != SOFTBUS_OK) {
164         CONN_LOGE(CONN_COMMON, "get time failed");
165         return SOFTBUS_CONN_GET_TIME_FAIL;
166     }
167     now.sec += (now.usec + ((int32_t)timeMillis * USECTONSEC)) / MICROSECONDS;
168     now.usec = (now.usec + ((int32_t)timeMillis * USECTONSEC)) % MICROSECONDS;
169 
170     return SoftBusCondWait(cond, mutex, &now);
171 }
172 
WaitQueueLength(const LockFreeQueue * lockFreeQueue,uint32_t maxLen,uint32_t diffLen,SoftBusCond * cond,SoftBusMutex * mutex)173 int32_t WaitQueueLength(
174     const LockFreeQueue *lockFreeQueue, uint32_t maxLen, uint32_t diffLen, SoftBusCond *cond, SoftBusMutex *mutex)
175 {
176 #define WAIT_QUEUE_DELAY 1000
177     uint32_t queueCount = 0;
178     while (true) {
179         if (QueueCountGet(lockFreeQueue, &queueCount) != 0) {
180             CONN_LOGE(CONN_COMMON, "wait get queue count fail");
181             break;
182         }
183         CONN_LOGD(CONN_COMMON, "queue count=%{public}d", queueCount);
184         if (queueCount < (maxLen - diffLen)) {
185             break;
186         }
187         int32_t status = ConnectSoftBusCondWait(cond, mutex, WAIT_QUEUE_DELAY);
188         if (status != SOFTBUS_OK && status != SOFTBUS_TIMOUT) {
189             CONN_LOGE(CONN_COMMON, "wait queue length cond wait fail");
190             return SOFTBUS_CONN_COND_WAIT_FAIL;
191         }
192     }
193     return SOFTBUS_OK;
194 }
195 
GetMsg(ConnectionQueue * queue,void ** msg,bool * isFull,QueuePriority leastPriority)196 int32_t GetMsg(ConnectionQueue *queue, void **msg, bool *isFull, QueuePriority leastPriority)
197 {
198     uint32_t queueCount;
199     for (uint32_t i = 0; i <= leastPriority; i++) {
200         if (QueueCountGet(queue->queue[i], &queueCount) != 0) {
201             CONN_LOGW(CONN_COMMON, "get queue count fail");
202             continue;
203         }
204         if ((int32_t)queueCount >= (QUEUE_LIMIT[i] - WAIT_QUEUE_BUFFER_PERIOD_LEN)) {
205             (*isFull) = true;
206         } else {
207             (*isFull) = false;
208         }
209         if (QueueSingleConsumerDequeue(queue->queue[i], msg) != 0) {
210             continue;
211         }
212         return SOFTBUS_OK;
213     }
214     return SOFTBUS_CONN_GET_MSG_FAIL;
215 }
216 
GetQueueLimit(int32_t index)217 uint32_t GetQueueLimit(int32_t index)
218 {
219     if (index >= QUEUE_NUM_PER_PID || index < 0) {
220         CONN_LOGE(CONN_COMMON, "invalid parameter");
221         return SOFTBUS_INVALID_PARAM;
222     }
223     return QUEUE_LIMIT[index];
224 }