1 /*
2 * Copyright (C) 2025 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 "wifi_sensor_scene.h"
17
18 #include <functional>
19 #include "net_all_capabilities.h"
20 #include "net_supplier_info.h"
21 #include "wifi_logger.h"
22 #include "wifi_service_manager.h"
23 #include "wifi_hisysevent.h"
24 #include "wifi_settings.h"
25 #include "wifi_config_center.h"
26
27 namespace OHOS {
28 namespace Wifi {
29 DEFINE_WIFILOG_LABEL("WifiSensorScene");
30
31 constexpr int SCENARIO_UNKNOWN = -1;
32 constexpr int SCENARIO_OUTDOOR = 1;
33
34 constexpr int MIN_5GHZ_BAND_FREQUENCY = 5000;
35
36 constexpr int MIN_RSSI_VALUE_24G = -80;
37 constexpr int MIN_RSSI_VALUE_5G = -77;
38 constexpr int MIN_RSSI_VALUE_OUTDOOR_24G = -75;
39 constexpr int MIN_RSSI_VALUE_OUTDOOR_5G = -72;
40 constexpr int CONN_RSSI_CNT = 10;
41
WifiSensorScene()42 WifiSensorScene::WifiSensorScene() : scenario_(SCENARIO_UNKNOWN),
43 minRssi24G_(MIN_RSSI_VALUE_24G), minRssi5G_(MIN_RSSI_VALUE_5G), isCallbackReg_(false)
44 {
45 InitCallback();
46 }
47
GetInstance()48 WifiSensorScene &WifiSensorScene::GetInstance()
49 {
50 static WifiSensorScene gWifiSensorScene;
51 return gWifiSensorScene;
52 }
53
InitCallback()54 void WifiSensorScene::InitCallback()
55 {
56 using namespace std::placeholders;
57 WIFI_LOGI("Enter InitCallback");
58 staCallback_.callbackModuleName = "WifiSensorScene";
59 staCallback_.OnStaConnChanged = [this](OperateResState state, const WifiLinkedInfo &linkedInfo, int32_t instId) {
60 this->DealStaConnChanged(state, linkedInfo, instId);
61 };
62 staCallback_.OnWifiHalSignalInfoChange = [this](const WifiSignalPollInfo &wifiSignalPollInfo) {
63 this->HandleSignalInfoChange(wifiSignalPollInfo);
64 };
65 }
66
DealStaConnChanged(OperateResState state,const WifiLinkedInfo & info,int instId)67 void WifiSensorScene::DealStaConnChanged(OperateResState state, const WifiLinkedInfo &info, int instId)
68 {
69 std::lock_guard<std::mutex> lock(staCbMutex_);
70 if (instId != INSTID_WLAN0 || info.networkId == INVALID_NETWORK_ID || info.bssid.empty() ||
71 (state != OperateResState::DISCONNECT_DISCONNECTED && state != OperateResState::CONNECT_AP_CONNECTED)) {
72 return;
73 }
74 if (state == OperateResState::DISCONNECT_DISCONNECTED) {
75 if (rssiCnt_ < CONN_RSSI_CNT) {
76 ReportLinkedQuality(0);
77 }
78 connScene_ = UNKNOW_SCENE;
79 rssiCnt_ = 0;
80 reportRssi_ = 0;
81 return;
82 }
83 IsOutdoorScene() ? connScene_ = OUTDOOR_SCENE : connScene_ = INDOOR_SCENE;
84 }
85
HandleSignalInfoChange(const WifiSignalPollInfo & wifiSignalPollInfo)86 void WifiSensorScene::HandleSignalInfoChange(const WifiSignalPollInfo &wifiSignalPollInfo)
87 {
88 WIFI_LOGD("Enter HandleSignalInfoChange");
89 std::lock_guard<std::mutex> lock(staCbMutex_);
90 if (rssiCnt_ == CONN_RSSI_CNT) {
91 ReportLinkedQuality(reportRssi_);
92 }
93 if (rssiCnt_ > CONN_RSSI_CNT) {
94 WIFI_LOGD("Current link has collected rssi data");
95 return;
96 }
97 rssiCnt_++;
98 reportRssi_ = wifiSignalPollInfo.signal < reportRssi_ ? wifiSignalPollInfo.signal : reportRssi_;
99 }
100
GetStaCallback() const101 StaServiceCallback WifiSensorScene::GetStaCallback() const
102 {
103 return staCallback_;
104 }
105
ReportLinkedQuality(int32_t rssi,int32_t instId)106 void WifiSensorScene::ReportLinkedQuality(int32_t rssi, int32_t instId)
107 {
108 IodStatisticInfo iodStatisticInfo;
109 if (rssi == 0) {
110 WIFI_LOGI("Connection duration is short, connScene_: %{public}d", connScene_);
111 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnShortTime++ : iodStatisticInfo.indoorConnShortTime++;
112 return;
113 }
114 WifiLinkedInfo linkedInfo;
115 WifiConfigCenter::GetInstance().GetLinkedInfo(linkedInfo);
116 int32_t signalLevel = WifiSettings::GetInstance().GetSignalLevel(rssi, linkedInfo.band, instId);
117 WIFI_LOGI("ReportLinkedQuality, connScene_: %{public}d, signalLevel: %{public}d", connScene_, signalLevel);
118 switch (signalLevel) {
119 case SIG_LEVEL_0:
120 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnLevel0++ : iodStatisticInfo.indoorConnLevel0++;
121 break;
122 case SIG_LEVEL_1:
123 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnLevel1++ : iodStatisticInfo.indoorConnLevel1++;
124 break;
125 case SIG_LEVEL_2:
126 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnLevel2++ : iodStatisticInfo.indoorConnLevel2++;
127 break;
128 case SIG_LEVEL_3:
129 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnLevel3++ : iodStatisticInfo.indoorConnLevel3++;
130 break;
131 case SIG_LEVEL_4:
132 connScene_ == OUTDOOR_SCENE ? iodStatisticInfo.outdoorConnLevel4++ : iodStatisticInfo.indoorConnLevel4++;
133 break;
134 default:
135 WIFI_LOGE("Invalid signal level");
136 break;
137 }
138 WriteIodHiSysEvent(iodStatisticInfo);
139 }
140
GetMinRssiThres(int frequency)141 int WifiSensorScene::GetMinRssiThres(int frequency)
142 {
143 std::lock_guard<std::mutex> lock(mutex_);
144
145 if (scenario_ == SCENARIO_OUTDOOR) {
146 minRssi24G_ = MIN_RSSI_VALUE_OUTDOOR_24G;
147 minRssi5G_ = MIN_RSSI_VALUE_OUTDOOR_5G;
148 } else {
149 minRssi24G_ = MIN_RSSI_VALUE_24G;
150 minRssi5G_ = MIN_RSSI_VALUE_5G;
151 }
152 int minRssi = frequency < MIN_5GHZ_BAND_FREQUENCY ? minRssi24G_ : minRssi5G_;
153 return minRssi;
154 }
155
SensorEnhCallback(int scenario)156 void WifiSensorScene::SensorEnhCallback(int scenario)
157 {
158 WIFI_LOGI("%{public}s scene %{public}d", __FUNCTION__, scenario);
159 std::lock_guard<std::mutex> lock(mutex_);
160 if (scenario_ != scenario) {
161 IodStatisticInfo iodStatisticInfo;
162 if (scenario == SCENARIO_OUTDOOR) {
163 iodStatisticInfo.in2OutCnt++;
164 } else {
165 iodStatisticInfo.out2InCnt++;
166 }
167 WriteIodHiSysEvent(iodStatisticInfo);
168 scenario_ = scenario;
169 }
170 }
171
RegisterSensorEnhCallback()172 void WifiSensorScene::RegisterSensorEnhCallback()
173 {
174 std::lock_guard<std::mutex> lock(mutex_);
175 if (isCallbackReg_) {
176 return;
177 }
178
179 IEnhanceService *pEnhanceService = WifiServiceManager::GetInstance().GetEnhanceServiceInst();
180 if (pEnhanceService == nullptr) {
181 WIFI_LOGE("%{public}s get pEnhance service failed!", __FUNCTION__);
182 return;
183 }
184 std::function<void(int)> callback = [this](int scenario) {
185 SensorEnhCallback(scenario);
186 };
187 ErrCode ret = pEnhanceService->RegisterSensorEnhanceCallback(callback);
188 if (ret == WIFI_OPT_SUCCESS) {
189 isCallbackReg_ = true;
190 }
191 WIFI_LOGI("%{public}s ret %{public}d", __FUNCTION__, ret);
192 }
193
IsOutdoorScene()194 bool WifiSensorScene::IsOutdoorScene()
195 {
196 std::lock_guard<std::mutex> lock(mutex_);
197 return scenario_ == SCENARIO_OUTDOOR;
198 }
199
OnConnectivityChanged(int32_t bearType,int32_t code)200 void WifiSensorScene::OnConnectivityChanged(int32_t bearType, int32_t code)
201 {
202 if ((bearType == NetManagerStandard::NetBearType::BEARER_WIFI ||
203 bearType == NetManagerStandard::NetBearType::BEARER_CELLULAR) &&
204 code == NetManagerStandard::NetConnState::NET_CONN_STATE_CONNECTED) {
205 RegisterSensorEnhCallback();
206 }
207 }
208
209 } // namespace Wifi
210 } // namespace OHOS