From 2de470601f0f20240818d576b5981c2b9415d648 Mon Sep 17 00:00:00 2001 From: jiazhenyu Date: Sun, 19 Nov 2023 19:10:50 +0800 Subject: [PATCH] Implement blocking and restoring WiFi scanning function Signed-off-by: jiazhenyu --- .../feature_config/mini/config.gni | 2 + .../feature_config/small/config.gni | 2 + .../feature_config/standard/config.gni | 2 + bundle.json | 3 +- .../include/softbus_scenario_manager.h | 63 ++ .../session/src/softbus_scenario_manager.c | 688 ++++++++++++++++++ .../src/softbus_scenario_manager_virtual.c | 46 ++ .../session/src/trans_session_service.c | 6 + core/transmission/trans.gni | 8 + .../src/trans_udp_negotiation.c | 30 + 10 files changed, 849 insertions(+), 1 deletion(-) create mode 100755 core/transmission/session/include/softbus_scenario_manager.h create mode 100755 core/transmission/session/src/softbus_scenario_manager.c create mode 100755 core/transmission/session/src/softbus_scenario_manager_virtual.c diff --git a/adapter/default_config/feature_config/mini/config.gni b/adapter/default_config/feature_config/mini/config.gni index 5680888e1..509b24dca 100644 --- a/adapter/default_config/feature_config/mini/config.gni +++ b/adapter/default_config/feature_config/mini/config.gni @@ -44,4 +44,6 @@ declare_args() { dsoftbus_feature_ex_kits = false dsoftbus_feature_proxy_file = false + + dsoftbus_feature_wifi_notify = true } diff --git a/adapter/default_config/feature_config/small/config.gni b/adapter/default_config/feature_config/small/config.gni index ebd2b2543..3cd08d35a 100644 --- a/adapter/default_config/feature_config/small/config.gni +++ b/adapter/default_config/feature_config/small/config.gni @@ -44,4 +44,6 @@ declare_args() { dsoftbus_feature_ex_kits = false dsoftbus_feature_proxy_file = true + + dsoftbus_feature_wifi_notify = true } diff --git a/adapter/default_config/feature_config/standard/config.gni b/adapter/default_config/feature_config/standard/config.gni index 9efec0e6c..36c72a221 100644 --- a/adapter/default_config/feature_config/standard/config.gni +++ b/adapter/default_config/feature_config/standard/config.gni @@ -44,4 +44,6 @@ declare_args() { dsoftbus_feature_ex_kits = false dsoftbus_feature_proxy_file = true + + dsoftbus_feature_wifi_notify = true } diff --git a/bundle.json b/bundle.json index cf74a7b5e..5e8c511f7 100644 --- a/bundle.json +++ b/bundle.json @@ -39,7 +39,8 @@ "dsoftbus_feature_lnn_wifiservice_dependence", "dsoftbus_standard_feature_dfinder_support_multi_nif", "dsoftbus_feature_protocol_newip", - "dsoftbus_feature_ex_kits" + "dsoftbus_feature_ex_kits", + "dsoftbus_feature_wifi_notify" ], "rom": "3000KB", "ram": "40MB", diff --git a/core/transmission/session/include/softbus_scenario_manager.h b/core/transmission/session/include/softbus_scenario_manager.h new file mode 100755 index 000000000..d40b04aff --- /dev/null +++ b/core/transmission/session/include/softbus_scenario_manager.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOFTBUS_SCENARIO_MANAGER_H +#define SOFTBUS_SCENARIO_MANAGER_H + +#include "softbus_def.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +typedef enum { + SM_ERROR_INNER = -1, + SM_ERROR_INVALID_PARAM = -2, + SM_ERROR_TYPE_NOT_SUPPORT = -3, + SM_ERROR_INVALID_LOCAL_MAC = -4, + SM_ERROR_OUT_OF_MEMORY = -5, + SM_ERROR_OPT_NOT_SUPPORT = -6, +} ScenarioManagerError; + +typedef enum { + SM_MESSAGE_TYPE = 1, + SM_BYTE_TYPE = 2, + SM_FILE_TYPE = 3, + SM_VIDEO_TYPE = 4, + SM_AUDIO_TYPE = 5, + SM_RAW_TYPE = 6, +} ScenarioManagerBusinessType; + +typedef struct ScenarioManager ScenarioManager; + +ScenarioManager *ScenarioManagerGetInstance(void); + +// update scenarios based on the command and determine whether to deliver the driver. +int32_t AddScenario(const char *localMac, const char *peerMac, int localPid, int businessType); + +int32_t DelScenario(const char *localMac, const char *peerMac, int localPid, int businessType); + +// clear all scenarios +void ScenarioManagerdestroyInstance(); + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ + +#endif // SOFTBUS_SCENARIO_MANAGER_H diff --git a/core/transmission/session/src/softbus_scenario_manager.c b/core/transmission/session/src/softbus_scenario_manager.c new file mode 100755 index 000000000..990bc82a2 --- /dev/null +++ b/core/transmission/session/src/softbus_scenario_manager.c @@ -0,0 +1,688 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_scenario_manager.h" + +#include "common_list.h" +#include "softbus_adapter_mem.h" +#include "softbus_adapter_thread.h" +#include "softbus_bitmap.h" +#include "softbus_errcode.h" +#include "softbus_utils.h" +#include "trans_log.h" +#include "wifi_hid2d.h" +#include "securec.h" + +#include +#include +#include + +#define MAC_STR_LEN 18 +#define IFACE_LEN_MAX 32 + +#define VIDEO_BIT_POS 0 +#define AUDIO_BIT_POS 1 +#define FILE_BIT_POS 2 + +#define VALID_TYPE_MIN 3 +#define VALID_TYPE_MAX 5 + +typedef struct ScenarioManager { + // mac to iface name map + SoftBusList* macIfacePairList; + // mac to final map + SoftBusList* scenarioItemList; +} ScenarioManager; + +typedef struct MacIfacePair { + ListNode node; + char mac[MAC_STR_LEN]; + char iface[IFACE_LEN_MAX]; +} MacIfacePair; + +typedef struct ScenarioItem { + ListNode node; + char localMac[MAC_STR_LEN]; + char peerMac[MAC_STR_LEN]; + uint32_t finalType; + int totalFileCount; + int totalAudioCount; + int totalVideoCount; + ListNode businessCounterList; +} ScenarioItem; + +typedef struct BusinessCounter { + ListNode node; + int localPid; + int totalCount; + int fileCount; + int audioCount; + int videoCount; +} BusinessCounter; + +typedef struct OriginalScenario { + char localMac[MAC_STR_LEN]; + char peerMac[MAC_STR_LEN]; + int localPid; + int businessType; +} OriginalScenario; + +typedef struct LocalScenarioCount { + int allMacVideoCount; + int allMacAudioCount; + int allMacFileCount; + int allMacTotalCount; +} LocalScenarioCount; + +static ScenarioManager *g_manager = NULL; + + +static void NotifyWifi(const char *ifName, const char *localMac, + const char *peerMac, int finalType, int businessType) +{ + (void)peerMac; + TRANS_LOGI(TRANS_CTRL, "ifName=%s, localMac=%s, peerMac=%s, finalType=%d, businessType=%d", + ifName, localMac, peerMac, finalType, businessType); + Hid2dUpperScene *scene = NULL; + scene = (Hid2dUpperScene *)SoftBusCalloc(sizeof(Hid2dUpperScene)); + if (scene == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, out of memory"); + return; + } + if (strcpy_s((char *)scene->mac, sizeof(scene->mac), localMac) != EOK) { + TRANS_LOGE(TRANS_CTRL, "set scene Mac err"); + SoftBusFree(scene); + return; + } + scene->scene = finalType; + if (businessType != SM_VIDEO_TYPE) { + scene->fps = -1; + } + if (Hid2dSetUpperScene(ifName, scene) != 0) { + TRANS_LOGE(TRANS_CTRL, "notify wifi err"); + } else { + TRANS_LOGI(TRANS_CTRL, "notify wifi success"); + } + SoftBusFree(scene); +} + +static void OriginalScenarioInit(OriginalScenario *scenarioInfo, + const char *localMac, const char *peerMac, int localPid, int businessType) +{ + if (strcpy_s(scenarioInfo->localMac, sizeof(scenarioInfo->localMac), localMac) != EOK) { + TRANS_LOGE(TRANS_CTRL, "set scenarioInfo localMac err"); + return; + } + if (strcpy_s(scenarioInfo->peerMac, sizeof(scenarioInfo->peerMac), peerMac) != EOK) { + TRANS_LOGE(TRANS_CTRL, "set scenarioInfo peerMac err"); + return; + } + scenarioInfo->localPid = localPid; + scenarioInfo->businessType = businessType; +} + +static ScenarioItem *ScenarioManagerGetOrAddScenarioItem(ScenarioManager *manager, + OriginalScenario *scenarioInfo, bool create) +{ + ScenarioItem *scenarioItem = NULL; + ScenarioItem *tmp = NULL; + LIST_FOR_EACH_ENTRY(tmp, &(manager->scenarioItemList->list), ScenarioItem, node) { + if (strcmp(tmp->localMac, scenarioInfo->localMac) == 0 && + strcmp(tmp->peerMac, scenarioInfo->peerMac) == 0) { + scenarioItem = tmp; + break; + } + } + if (scenarioItem == NULL) { + if (!create) { + TRANS_LOGI(TRANS_CTRL, "scenario item of this mac pair not exist!"); + return NULL; + } + TRANS_LOGI(TRANS_CTRL, "scenario item of this mac pair not exist, create it"); + scenarioItem = (ScenarioItem *)SoftBusCalloc(sizeof(ScenarioItem)); + if (scenarioItem == NULL) { + return NULL; + } + if (strcpy_s(scenarioItem->localMac, sizeof(scenarioItem->localMac), scenarioInfo->localMac) != EOK) { + SoftBusFree(scenarioItem); + return NULL; + } + if (strcpy_s(scenarioItem->peerMac, sizeof(scenarioItem->peerMac), scenarioInfo->peerMac) != EOK) { + SoftBusFree(scenarioItem); + return NULL; + } + ListInit(&scenarioItem->businessCounterList); + ListAdd(&(manager->scenarioItemList->list), &scenarioItem->node); + manager->scenarioItemList->cnt++; + } + return scenarioItem; +} + +static void ScenarioManagerDelScenarioItem(ScenarioManager *manager, ScenarioItem *scenarioItem) +{ + ScenarioItem *item = NULL; + ScenarioItem *tmp = NULL; + LIST_FOR_EACH_ENTRY(tmp, &(manager->scenarioItemList->list), ScenarioItem, node) { + if (strcmp(tmp->localMac, scenarioItem->localMac) == 0 && + strcmp(tmp->peerMac, scenarioItem->peerMac) == 0) { + item = tmp; + break; + } + } + if (item == NULL) { + TRANS_LOGE(TRANS_CTRL, "pair of the peer mac not found!"); + return; + } + if (IsListEmpty(&scenarioItem->businessCounterList)) { + TRANS_LOGE(TRANS_CTRL, "remove empty list pair on put!"); + ListDelete(&scenarioItem->node); + manager->scenarioItemList->cnt--; + SoftBusFree(scenarioItem); + } +} + +static char *ScenarioManagerGetIfaceNameByMac(ScenarioManager *manager, const char *localMac) +{ + if (manager->macIfacePairList == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenarioItemList hasn't initialized"); + return NULL; + } + MacIfacePair *pair = NULL; + LIST_FOR_EACH_ENTRY(pair, &(manager->macIfacePairList->list), MacIfacePair, node) { + if (strcmp(localMac, pair->mac) == 0) { + return pair->iface; + } + } + return NULL; +} + +static bool ScenarioManagerAddIfaceNameByLocalMac(ScenarioManager *manager, + const char *localMac, const char *ifaceName) +{ + if (manager->macIfacePairList == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenarioItemList hasn't initialized"); + return false; + } + MacIfacePair *pair = (MacIfacePair *)SoftBusCalloc(sizeof(MacIfacePair)); + if (pair == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, out of memory"); + return false; + } + if (strcpy_s(pair->mac, sizeof(pair->mac), localMac) != EOK) { + TRANS_LOGE(TRANS_CTRL, "copy MacIfacePair localMac err"); + SoftBusFree(pair); + return false; + } + if (strcpy_s(pair->iface, sizeof(pair->iface), ifaceName) != EOK) { + TRANS_LOGE(TRANS_CTRL, "set MacIfacePair ifaceName err"); + SoftBusFree(pair); + return false; + } + ListAdd(&manager->macIfacePairList->list, &pair->node); + manager->macIfacePairList->cnt++; + return true; +} + +static char *ScenarioManagerFindIfaceNameByLocalMac(const char *localMac) +{ + // it's fake, gona replaced by wifi interface + static char *LOCAL_MAC_1 = "18:65"; + static char *LOCAL_MAC_2 = "82:13"; + if (strcmp(localMac, LOCAL_MAC_1) == 0) { + return "en0"; + } else if (strcmp(localMac, LOCAL_MAC_2) == 0) { + return "en1"; + } + return NULL; +} + +static bool ScenarioManagerCheckAndUpdateIfaceName(ScenarioManager *manager, const char *localMac) +{ + if (manager == NULL || manager->macIfacePairList == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenarioItemList hasn't initialized"); + return false; + } + if (SoftBusMutexLock(&(manager->macIfacePairList->lock)) != 0) { + TRANS_LOGE(TRANS_CTRL, "lock mutex failed!"); + return false; + } + const char *ifaceName = ScenarioManagerGetIfaceNameByMac(manager, localMac); + if (ifaceName != NULL) { + (void)SoftBusMutexUnlock(&(manager->macIfacePairList->lock)); + return true; + } + ifaceName = ScenarioManagerFindIfaceNameByLocalMac(localMac); + if (ifaceName == NULL) { + TRANS_LOGE(TRANS_CTRL, "inteface name not found!"); + (void)SoftBusMutexUnlock(&(manager->macIfacePairList->lock)); + return false; + } + bool result = ScenarioManagerAddIfaceNameByLocalMac(manager, localMac, ifaceName); + (void)SoftBusMutexUnlock(&(manager->macIfacePairList->lock)); + return result; +} + +static void ScenarioManagerAddBusinessType(ScenarioManager *manager, + ScenarioItem *scenarioItem, BusinessCounter *counter, int businessType) +{ + switch (businessType) { + case SM_FILE_TYPE: + counter->fileCount++; + counter->totalCount++; + scenarioItem->totalFileCount++; + break; + case SM_AUDIO_TYPE: + counter->audioCount++; + counter->totalCount++; + scenarioItem->totalAudioCount++; + break; + case SM_VIDEO_TYPE: + counter->videoCount++; + counter->totalCount++; + scenarioItem->totalVideoCount++; + break; + default: + TRANS_LOGE(TRANS_CTRL, "business type not supported!"); + return; + } + TRANS_LOGI(TRANS_CTRL, + "same mac pair: businessType:%d, totalFileCount:%d, totalAudioCount=%d, totalVideoCount=%d!", + businessType, scenarioItem->totalFileCount, scenarioItem->totalAudioCount, + scenarioItem->totalVideoCount); +} + +static void ScenarioManagerDelBusinessType(ScenarioManager *manager, + ScenarioItem *scenarioItem, BusinessCounter *counter, int businessType) +{ + int *singleCount = NULL; + int *itemCount = NULL; + switch (businessType) { + case SM_FILE_TYPE: + singleCount = &counter->fileCount; + itemCount = &scenarioItem->totalFileCount; + break; + case SM_AUDIO_TYPE: + singleCount = &counter->audioCount; + itemCount = &scenarioItem->totalAudioCount; + break; + case SM_VIDEO_TYPE: + singleCount = &counter->videoCount; + itemCount = &scenarioItem->totalVideoCount; + break; + default: + break; + } + if (singleCount == NULL) { + TRANS_LOGE(TRANS_CTRL, "business type not supported!"); + return; + } + if (*singleCount <= 0 || counter->totalCount <= 0 || *itemCount <= 0) { + TRANS_LOGE(TRANS_CTRL, "error, count of the type wrong!"); + return; + } + (void)(*singleCount)--; + counter->totalCount--; + (void)(*itemCount)--; + TRANS_LOGI(TRANS_CTRL, + "businessType:%d, filecount:%d, audiocuont=%d, videocount=%d!", + businessType, scenarioItem->totalFileCount, scenarioItem->totalAudioCount, + scenarioItem->totalVideoCount); +} + +static int32_t ScenarioManagerGetBitPosByBusinessType(int businessType) +{ + int32_t bitPos = 0; + switch (businessType) { + case SM_FILE_TYPE: + bitPos = FILE_BIT_POS; + break; + case SM_AUDIO_TYPE: + bitPos = AUDIO_BIT_POS; + break; + case SM_VIDEO_TYPE: + bitPos = VIDEO_BIT_POS; + break; + default: + TRANS_LOGI(TRANS_CTRL, "business type not supported!"); + return -1; + } + return bitPos; +} + +static bool ScenarioManagerIsBusinesExisted(ScenarioManager *manager, + ScenarioItem *item, int businessType) +{ + TRANS_LOGI(TRANS_CTRL, + "businessType:%d, filecount:%d, audiocuont=%d, videocount=%d!", + businessType, item->totalFileCount, item->totalAudioCount, item->totalVideoCount); + switch (businessType) { + case SM_FILE_TYPE: + return item->totalFileCount > 0; + case SM_AUDIO_TYPE: + return item->totalAudioCount > 0; + case SM_VIDEO_TYPE: + return item->totalVideoCount > 0; + default: + return false; + } +} + +static LocalScenarioCount *GetScenarioCount(ScenarioManager *manager) +{ + LocalScenarioCount *localScenarioCount = NULL; + ScenarioItem *tmp = NULL; + localScenarioCount = (LocalScenarioCount *)SoftBusCalloc(sizeof(LocalScenarioCount)); + if (localScenarioCount == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, out of memory"); + return NULL; + } + LIST_FOR_EACH_ENTRY(tmp, &(manager->scenarioItemList->list), ScenarioItem, node) { + localScenarioCount->allMacVideoCount += tmp->totalVideoCount; + localScenarioCount->allMacAudioCount += tmp->totalAudioCount; + localScenarioCount->allMacFileCount += tmp->totalFileCount; + } + localScenarioCount->allMacTotalCount = + localScenarioCount->allMacVideoCount + localScenarioCount->allMacAudioCount + + localScenarioCount->allMacFileCount; + return localScenarioCount; +} + +static void ScenarioManagerDoNotifyIfNeed(ScenarioManager *manager, + OriginalScenario *info, bool isAdd) +{ + bool notify = false; + ScenarioItem *item = ScenarioManagerGetOrAddScenarioItem(manager, info, false); + LocalScenarioCount *localScenarioCount = GetScenarioCount(manager); + if (item == NULL || localScenarioCount == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenario item not found!"); + return; + } + uint32_t finalType = item->finalType; + int bitPos = ScenarioManagerGetBitPosByBusinessType(info->businessType); + if (bitPos < 0) { + TRANS_LOGE(TRANS_CTRL, "error, invalid business type!"); + return; + } + if (isAdd) { + TRANS_LOGI(TRANS_CTRL, "finalType:%d, bitPos%d", finalType, bitPos); + if (!SoftbusIsBitmapSet(&finalType, bitPos)) { + SoftbusBitmapSet(&finalType, bitPos); + item->finalType = finalType; + TRANS_LOGI(TRANS_CTRL, "finalType:%d, bitPos%d", finalType, bitPos); + } + if (localScenarioCount->allMacTotalCount == 0) { + notify = true; + } + } else { + TRANS_LOGI(TRANS_CTRL, "finalType:%d, bitPos%d", finalType, bitPos); + if (SoftbusIsBitmapSet(&finalType, bitPos) && + !ScenarioManagerIsBusinesExisted(manager, item, info->businessType)) { + SoftbusBitmapClr(&finalType, bitPos); + item->finalType = finalType; + TRANS_LOGI(TRANS_CTRL, "finalType:%d, bitPos%d", finalType, bitPos); + } + if (localScenarioCount->allMacTotalCount == 0) { + notify = true; + } + } + if (notify) { + TRANS_LOGI(TRANS_CTRL, + "current businessType of finalType is %d", item->finalType); + const char* ifaceName = ScenarioManagerFindIfaceNameByLocalMac(item->localMac); + // do notify here + NotifyWifi(ifaceName, item->localMac, item->peerMac, item->finalType, info->businessType); + } + SoftBusFree(localScenarioCount); +} + +static int32_t AddOriginalScenario(ScenarioManager *manager, OriginalScenario *info) +{ + if (manager == NULL || manager->scenarioItemList == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenarioItemList hasn't initialized"); + return SOFTBUS_ERR; + } + if (info == NULL) { + TRANS_LOGE(TRANS_CTRL, "OriginalScenario is null"); + return SOFTBUS_ERR; + } + if (SoftBusMutexLock(&(manager->scenarioItemList->lock)) != 0) { + TRANS_LOGE(TRANS_CTRL, "lock mutex failed!"); + return SOFTBUS_ERR; + } + ScenarioItem *scenarioItem = ScenarioManagerGetOrAddScenarioItem(manager, info, true); + if (scenarioItem == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, get scenario item failed"); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return SOFTBUS_ERR; + } + BusinessCounter *counter = NULL; + BusinessCounter *tmp = NULL; + LIST_FOR_EACH_ENTRY(tmp, &scenarioItem->businessCounterList, BusinessCounter, node) { + if (tmp->localPid == info->localPid) { + counter = tmp; + break; + } + } + if (counter == NULL) { + counter = (BusinessCounter *)SoftBusCalloc(sizeof(BusinessCounter)); + if (counter == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, out of memory"); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return SOFTBUS_MALLOC_ERR; + } + counter->localPid = info->localPid; + ListAdd(&scenarioItem->businessCounterList, &counter->node); + } else { + TRANS_LOGI(TRANS_CTRL, "businessCounter already exist"); + } + ScenarioManagerDoNotifyIfNeed(manager, info, true); + ScenarioManagerAddBusinessType(manager, scenarioItem, counter, info->businessType); + LocalScenarioCount *localScenarioCount = GetScenarioCount(manager); + TRANS_LOGI(TRANS_CTRL, + "allMacTotalCount:%d, allMacVideoCount:%d, allMacAudioCount:%d, allMacFileCount:%d", + localScenarioCount->allMacTotalCount, localScenarioCount->allMacVideoCount, + localScenarioCount->allMacAudioCount, localScenarioCount->allMacFileCount); + SoftBusFree(localScenarioCount); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return 0; +} + +static int32_t DelOriginalScenario(ScenarioManager *manager, OriginalScenario *info) +{ + if (manager == NULL || manager->scenarioItemList == NULL) { + TRANS_LOGE(TRANS_CTRL, "scenarioItemList hasn't initialized"); + return SOFTBUS_ERR; + } + if (info == NULL) { + TRANS_LOGE(TRANS_CTRL, "OriginalScenario is null"); + return SOFTBUS_ERR; + } + if (SoftBusMutexLock(&(manager->scenarioItemList->lock)) != 0) { + TRANS_LOGE(TRANS_CTRL, "lock mutex failed!"); + return SOFTBUS_ERR; + } + ScenarioItem *scenarioItem = ScenarioManagerGetOrAddScenarioItem(manager, info, false); + if (scenarioItem == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, get scenario item failed"); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return SOFTBUS_NOT_FIND; + } + BusinessCounter *counter = NULL; + BusinessCounter *tmp = NULL; + LIST_FOR_EACH_ENTRY(tmp, &scenarioItem->businessCounterList, BusinessCounter, node) { + if (tmp->localPid == info->localPid) { + counter = tmp; + break; + } + } + if (counter == NULL) { + TRANS_LOGE(TRANS_CTRL, "error, counter of the pid not found!"); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return SOFTBUS_NOT_FIND; + } + ScenarioManagerDelBusinessType(manager, scenarioItem, counter, info->businessType); + if (counter->totalCount <= 0) { + TRANS_LOGE(TRANS_CTRL, "error, delete a counter form list!"); + ListDelete(&counter->node); + SoftBusFree(counter); + } + ScenarioManagerDoNotifyIfNeed(manager, info, false); + ScenarioManagerDelScenarioItem(manager, scenarioItem); + LocalScenarioCount *localScenarioCount = GetScenarioCount(manager); + TRANS_LOGI(TRANS_CTRL, + "allMacTotalCount:%d, allMacVideoCount:%d, allMacAudioCount:%d, allMacFileCount:%d", + localScenarioCount->allMacTotalCount, localScenarioCount->allMacVideoCount, + localScenarioCount->allMacAudioCount, localScenarioCount->allMacFileCount); + SoftBusFree(localScenarioCount); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); + return SOFTBUS_OK; +} + +static int32_t UpdateOriginalScenario(ScenarioManager *manager, OriginalScenario *info, bool isAdd) +{ + if (strlen(info->localMac) == 0 || strlen(info->peerMac) == 0 || info->localPid < 0) { + TRANS_LOGE(TRANS_CTRL, "invalid parameters!"); + return SOFTBUS_INVALID_PARAM; + } + if (info->businessType < VALID_TYPE_MIN || info->businessType > VALID_TYPE_MAX) { + TRANS_LOGE(TRANS_CTRL, "type not supportted!"); + return SOFTBUS_INVALID_NUM; + } + if (!ScenarioManagerCheckAndUpdateIfaceName(manager, info->localMac)) { + TRANS_LOGE(TRANS_CTRL, "invalid local mac!"); + return SOFTBUS_INVALID_NUM; + } + TRANS_LOGI(TRANS_CTRL, + "UpdateOriginalScenario : localMac=%s, peerMac=%s, localPid=%d, businessType=%d, isAdd=%d", + info->localMac, info->peerMac, info->localPid, info->businessType, isAdd); + + int ret = isAdd ? AddOriginalScenario(manager, info) : DelOriginalScenario(manager, info); + if (ret != 0) { + TRANS_LOGE(TRANS_CTRL, "update scenario info failed: %d", ret); + return ret; + } + return ret; +} + +static void ScenarioManagerClearMacIfacePairList(ScenarioManager *manager) +{ + TRANS_LOGI(TRANS_CTRL, "before clean : macIfacePairList numer is :%d", manager->macIfacePairList->cnt); + MacIfacePair *pair = NULL; + MacIfacePair *nextPair = NULL; + if (SoftBusMutexLock(&(manager->macIfacePairList->lock)) != 0) { + TRANS_LOGE(TRANS_CTRL, "lock mutex failed!"); + return; + } + LIST_FOR_EACH_ENTRY_SAFE(pair, nextPair, &manager->macIfacePairList->list, MacIfacePair, node) { + ListDelete(&pair->node); + SoftBusFree(pair); + manager->macIfacePairList->cnt--; + } + TRANS_LOGI(TRANS_CTRL, "before clean : macIfacePairList numer is :%d", manager->macIfacePairList->cnt); + (void)SoftBusMutexUnlock(&(manager->macIfacePairList->lock)); +} + +static void ScenarioManagerClearBusinessCounterList(ListNode *list) +{ + BusinessCounter *counter = NULL; + BusinessCounter *tmp = NULL; + LIST_FOR_EACH_ENTRY_SAFE(counter, tmp, list, BusinessCounter, node) { + ListDelete(&counter->node); + SoftBusFree(counter); + } +} + +static void ScenarioManagerClearScenarioItemList(ScenarioManager *manager) +{ + TRANS_LOGI(TRANS_CTRL, "before clean:scenarioItemList numer is :%d", manager->scenarioItemList->cnt); + ScenarioItem *item = NULL; + ScenarioItem *tmp = NULL; + if (SoftBusMutexLock(&(manager->scenarioItemList->lock)) != 0) { + TRANS_LOGE(TRANS_CTRL, "lock mutex failed!"); + return; + } + LIST_FOR_EACH_ENTRY_SAFE(item, tmp, &manager->scenarioItemList->list, ScenarioItem, node) { + ScenarioManagerClearBusinessCounterList(&item->businessCounterList); + ListDelete(&item->node); + SoftBusFree(item); + manager->scenarioItemList->cnt--; + } + TRANS_LOGI(TRANS_CTRL, "after clean:scenarioItemList numer is :%d", manager->scenarioItemList->cnt); + (void)SoftBusMutexUnlock(&(manager->scenarioItemList->lock)); +} + +static int32_t ScenarioManagerAddScenario(ScenarioManager *manager, const char *localMac, + const char *peerMac, int localPid, int businessType) +{ + OriginalScenario scenarioInfo; + OriginalScenarioInit(&scenarioInfo, localMac, peerMac, localPid, businessType); + int ret = UpdateOriginalScenario(manager, &scenarioInfo, true); + if (ret != 0) { + TRANS_LOGE(TRANS_CTRL, "add scenario info failed!"); + return ret; + } + return SOFTBUS_OK; +} + +static int32_t ScenarioManagerDelScenario(ScenarioManager *manager, const char *localMac, + const char *peerMac, int localPid, int businessType) +{ + OriginalScenario scenarioInfo; + OriginalScenarioInit(&scenarioInfo, localMac, peerMac, localPid, businessType); + int ret = UpdateOriginalScenario(manager, &scenarioInfo, false); + if (ret != 0) { + TRANS_LOGE(TRANS_CTRL, "delete scenario info failed!"); + return ret; + } + return SOFTBUS_OK; +} + +int32_t AddScenario(const char *localMac, const char *peerMac, int localPid, int businessType) +{ + return ScenarioManagerAddScenario(g_manager, localMac, peerMac, localPid, businessType); +} + +int32_t DelScenario(const char *localMac, const char *peerMac, int localPid, int businessType) +{ + return ScenarioManagerDelScenario(g_manager, localMac, peerMac, localPid, businessType); +} + + +ScenarioManager *ScenarioManagerGetInstance() +{ + static ScenarioManager manager; + if (g_manager == NULL) { + manager.macIfacePairList = CreateSoftBusList(); + manager.scenarioItemList = CreateSoftBusList(); + g_manager = &manager; + } + TRANS_LOGI(TRANS_CTRL, "creat g_manager success!"); + return g_manager; +} + +void ScenarioManagerdestroyInstance() +{ + if (g_manager == NULL) { + TRANS_LOGE(TRANS_CTRL, "manager is null!"); + return; + } + ScenarioManagerClearMacIfacePairList(g_manager); + ScenarioManagerClearScenarioItemList(g_manager); + DestroySoftBusList(g_manager->macIfacePairList); + g_manager->macIfacePairList = NULL; + DestroySoftBusList(g_manager->scenarioItemList); + g_manager->scenarioItemList = NULL; + g_manager = NULL; +} diff --git a/core/transmission/session/src/softbus_scenario_manager_virtual.c b/core/transmission/session/src/softbus_scenario_manager_virtual.c new file mode 100755 index 000000000..26692b834 --- /dev/null +++ b/core/transmission/session/src/softbus_scenario_manager_virtual.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "softbus_scenario_manager.h" + +ScenarioManager *ScenarioManagerGetInstance(void) +{ + return NULL; +} + +// update scenarios based on the command and determine whether to deliver the driver. +int32_t AddScenario(const char *localMac, const char *peerMac, int localPid, int businessType) +{ + (void)localMac; + (void)peerMac; + (void)localPid; + (void)businessType; + return 0; +} + +int32_t DelScenario(const char *localMac, const char *peerMac, int localPid, int businessType) +{ + (void)localMac; + (void)peerMac; + (void)localPid; + (void)businessType; + return 0; +} + +// clear all scenarios +void ScenarioManagerdestroyInstance() +{ + return; +} diff --git a/core/transmission/session/src/trans_session_service.c b/core/transmission/session/src/trans_session_service.c index cddef27e0..451da378e 100644 --- a/core/transmission/session/src/trans_session_service.c +++ b/core/transmission/session/src/trans_session_service.c @@ -21,6 +21,7 @@ #include "softbus_errcode.h" #include "softbus_permission.h" #include "softbus_qos.h" +#include "softbus_scenario_manager.h" #include "softbus_utils.h" #include "trans_channel_manager.h" #include "trans_log.h" @@ -49,6 +50,10 @@ int32_t TransServerInit(void) TRANS_LOGE(TRANS_INIT, "QosInit Failed"); return SOFTBUS_ERR; } + if (ScenarioManagerGetInstance() == NULL) { + TRANS_LOGE(TRANS_INIT, "ScenarioManager init Failed"); + return SOFTBUS_ERR; + } g_transSessionInitFlag = true; TRANS_LOGI(TRANS_INIT, "trans session server list init succ"); return SOFTBUS_OK; @@ -63,6 +68,7 @@ void TransServerDeinit(void) TransSessionMgrDeinit(); TransChannelDeinit(); TransPermissionDeinit(); + ScenarioManagerdestroyInstance(); g_transSessionInitFlag = false; } diff --git a/core/transmission/trans.gni b/core/transmission/trans.gni index c4189d8e9..b20b7d654 100644 --- a/core/transmission/trans.gni +++ b/core/transmission/trans.gni @@ -85,3 +85,11 @@ if (defined(ohos_lite)) { [ "//third_party/bounds_checking_function:libsec_shared" ] trans_session_external_deps += [ "c_utils:utils" ] } + +if (dsoftbus_feature_wifi_notify == true && + softbus_communication_wifi_feature == true) { + trans_session_src += [ "$dsoftbus_root_path/core/transmission/session/src/softbus_scenario_manager.c" ] + trans_session_external_deps += [ "wifi:wifi_sdk" ] +} else { + trans_session_src += [ "$dsoftbus_root_path/core/transmission/session/src/softbus_scenario_manager_virtual.c" ] +} diff --git a/core/transmission/trans_channel/udp_negotiation/src/trans_udp_negotiation.c b/core/transmission/trans_channel/udp_negotiation/src/trans_udp_negotiation.c index bd129c3fc..4ae63fe1c 100644 --- a/core/transmission/trans_channel/udp_negotiation/src/trans_udp_negotiation.c +++ b/core/transmission/trans_channel/udp_negotiation/src/trans_udp_negotiation.c @@ -28,6 +28,7 @@ #include "softbus_def.h" #include "softbus_errcode.h" #include "softbus_hisysevt_transreporter.h" +#include "softbus_scenario_manager.h" #include "trans_lane_pending_ctl.h" #include "trans_log.h" #include "trans_udp_channel_manager.h" @@ -50,6 +51,10 @@ static IServerChannelCallBack *g_channelCb = NULL; static SoftBusMutex g_udpNegLock; static uint32_t g_idMark = 0; +// it's fake, gona replaced by wifi interface +const char *LOCAL_MAC_1 = "18:65"; +const char *PEER_MAC_1 = "de:4f"; + static int32_t GenerateUdpChannelId(void) { if (SoftBusMutexLock(&g_udpNegLock) != 0) { @@ -266,11 +271,34 @@ static int32_t CloseUdpChannel(AppInfo *appInfo) return SOFTBUS_OK; } +static void NotifyWifiByAddScenario(StreamType streamType, int pid) +{ + if (streamType == COMMON_AUDIO_STREAM || streamType == COMMON_VIDEO_STREAM) { + if (AddScenario(LOCAL_MAC_1, PEER_MAC_1, pid, SM_AUDIO_TYPE) !=0) { + TRANS_LOGE(TRANS_CTRL, "notify wifi scan failed!"); + } else { + TRANS_LOGI(TRANS_CTRL, "notify wifi scan success!"); + } + } +} + +static void NotifyWifiByDelScenario(StreamType streamType, int pid) +{ + if (streamType == COMMON_AUDIO_STREAM || streamType == COMMON_VIDEO_STREAM) { + if (DelScenario(LOCAL_MAC_1, PEER_MAC_1, pid, SM_AUDIO_TYPE) !=0) { + TRANS_LOGE(TRANS_CTRL, "recover wifi scan failed"); + } else { + TRANS_LOGI(TRANS_CTRL, "recover wifi scan success!"); + } + } +} + static int32_t ProcessUdpChannelState(AppInfo *appInfo, bool isServerSide) { int32_t ret = SOFTBUS_OK; switch (appInfo->udpChannelOptType) { case TYPE_UDP_CHANNEL_OPEN: + NotifyWifiByAddScenario(appInfo->streamType, appInfo->myData.pid); if (isServerSide) { ret = AcceptUdpChannelAsServer(appInfo); } else { @@ -278,6 +306,7 @@ static int32_t ProcessUdpChannelState(AppInfo *appInfo, bool isServerSide) } return ret; case TYPE_UDP_CHANNEL_CLOSE: + NotifyWifiByDelScenario(appInfo->streamType, appInfo->myData.pid); ret = CloseUdpChannel(appInfo); break; default: @@ -793,6 +822,7 @@ int32_t TransCloseUdpChannel(int32_t channelId) TRANS_LOGE(TRANS_CTRL, "get udp channel by channel id failed. channelId=%d", channelId); return SOFTBUS_ERR; } + NotifyWifiByDelScenario(channel.info.streamType, channel.info.myData.pid); if (OpenAuthConnForUdpNegotiation(&channel) != SOFTBUS_OK) { TRANS_LOGE(TRANS_CTRL, "open udp negotiation failed."); return SOFTBUS_ERR;