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 "lnn_event_monitor_impl.h"
17 
18 #include <securec.h>
19 
20 #include "bus_center_event.h"
21 #include "common_event_data.h"
22 #include "common_event_manager.h"
23 #include "common_event_subscriber.h"
24 #include "common_event_support.h"
25 #include "lnn_async_callback_utils.h"
26 #include "lnn_log.h"
27 #include "want.h"
28 #include "wifi_msg.h"
29 #include "softbus_adapter_mem.h"
30 #include "softbus_errcode.h"
31 #include "kits/c/wifi_p2p.h"
32 #include "wifi_ap_msg.h"
33 #include "softbus_wifi_api_adapter.h"
34 
35 static const int32_t DELAY_LEN = 1000;
36 static const int32_t RETRY_MAX = 20;
37 static const std::string COMMON_EVENT_WIFI_SEMI_STATE = "usual.event.wifi.SEMI_STATE";
38 static const int32_t WIFI_UID = 1010;
39 
40 namespace OHOS {
41 namespace EventFwk {
42 class WifiServiceMonitor : public CommonEventSubscriber {
43 public:
44     explicit WifiServiceMonitor(const CommonEventSubscribeInfo &subscriberInfo);
~WifiServiceMonitor()45     virtual ~WifiServiceMonitor() {}
46     virtual void OnReceiveEvent(const CommonEventData &data);
47 };
48 
WifiServiceMonitor(const CommonEventSubscribeInfo & subscriberInfo)49 WifiServiceMonitor::WifiServiceMonitor(const CommonEventSubscribeInfo &subscriberInfo)
50     :CommonEventSubscriber(subscriberInfo)
51 {
52 }
53 
SetSoftBusWifiConnState(const int code,SoftBusWifiState * state)54 static void SetSoftBusWifiConnState(const int code, SoftBusWifiState *state)
55 {
56     switch (code) {
57         case int(OHOS::Wifi::ConnState::OBTAINING_IPADDR):
58             *state = SOFTBUS_WIFI_OBTAINING_IPADDR;
59             break;
60         case int(OHOS::Wifi::ConnState::CONNECTED):
61             *state = SOFTBUS_WIFI_CONNECTED;
62             break;
63         case int(OHOS::Wifi::ConnState::DISCONNECTED):
64             *state = SOFTBUS_WIFI_DISCONNECTED;
65             break;
66         default: {
67             break;
68         }
69     }
70 }
71 
SetSoftBusWifiUseState(const int code,SoftBusWifiState * state)72 static void SetSoftBusWifiUseState(const int code, SoftBusWifiState *state)
73 {
74     switch (code) {
75         case int(OHOS::Wifi::WifiState::DISABLED):
76             *state = SOFTBUS_WIFI_DISABLED;
77             break;
78         case int(OHOS::Wifi::WifiState::ENABLED):
79             *state = SOFTBUS_WIFI_ENABLED;
80             break;
81         default: {
82             break;
83         }
84     }
85 }
86 
SetSoftBusWifiHotSpotState(const int code,SoftBusWifiState * state)87 static void SetSoftBusWifiHotSpotState(const int code, SoftBusWifiState *state)
88 {
89     switch (code) {
90         case int(OHOS::Wifi::ApState::AP_STATE_STARTED):
91             *state = SOFTBUS_AP_ENABLED;
92             break;
93         case int(OHOS::Wifi::ApState::AP_STATE_CLOSED):
94             *state = SOFTBUS_AP_DISABLED;
95             break;
96         default: {
97             break;
98         }
99     }
100 }
101 
SetSoftBusWifiSemiState(const int code,SoftBusWifiState * state)102 static void SetSoftBusWifiSemiState(const int code, SoftBusWifiState *state)
103 {
104     switch (code) {
105         case int(OHOS::Wifi::WifiDetailState::STATE_SEMI_ACTIVE):
106             *state = SOFTBUS_WIFI_SEMI_ACTIVE;
107             break;
108         default: {
109             break;
110         }
111     }
112 }
113 
OnReceiveEvent(const CommonEventData & data)114 void WifiServiceMonitor::OnReceiveEvent(const CommonEventData &data)
115 {
116     int code = data.GetCode();
117     std::string action = data.GetWant().GetAction();
118     SoftBusWifiState state = SOFTBUS_WIFI_UNKNOWN;
119     LNN_LOGI(LNN_BUILDER, "notify wifiservice event=%{public}s, code=%{public}d", action.c_str(), code);
120     if (action == CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE) {
121         SetSoftBusWifiConnState(code, &state);
122     }
123     if (action == CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE) {
124         SetSoftBusWifiUseState(code, &state);
125     }
126     if (action == CommonEventSupport::COMMON_EVENT_WIFI_HOTSPOT_STATE) {
127         SetSoftBusWifiHotSpotState(code, &state);
128     }
129     if (action == COMMON_EVENT_WIFI_SEMI_STATE) {
130         SetSoftBusWifiSemiState(code, &state);
131     }
132     if (state != SOFTBUS_WIFI_UNKNOWN) {
133         SoftBusWifiState *notifyState = (SoftBusWifiState *)SoftBusMalloc(sizeof(SoftBusWifiState));
134         if (notifyState == NULL) {
135             LNN_LOGE(LNN_BUILDER, "notifyState malloc err");
136             return;
137         }
138         *notifyState = state;
139         int32_t ret = LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnNotifyWlanStateChangeEvent,
140             (void *)notifyState);
141         if (ret != SOFTBUS_OK) {
142             LNN_LOGE(LNN_BUILDER, "async notify wifi state err, ret=%{public}d", ret);
143             SoftBusFree(notifyState);
144         }
145     }
146 }
147 
148 class SubscribeEvent {
149 public:
150     int32_t SubscribeWifiConnStateEvent();
151     int32_t SubscribeWifiPowerStateEvent();
152     int32_t SubscribeAPConnStateEvent();
153     int32_t SubscribeWifiSemiStateEvent();
154 };
155 
SubscribeAPConnStateEvent()156 int32_t SubscribeEvent::SubscribeAPConnStateEvent()
157 {
158     MatchingSkills matchingSkills;
159     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_WIFI_HOTSPOT_STATE);
160     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
161     std::shared_ptr<WifiServiceMonitor> subscriberPtr = std::make_shared<WifiServiceMonitor>(subscriberInfo);
162     if (!CommonEventManager::SubscribeCommonEvent(subscriberPtr)) {
163         return SOFTBUS_ERR;
164     }
165     return SOFTBUS_OK;
166 }
167 
SubscribeWifiConnStateEvent()168 int32_t SubscribeEvent::SubscribeWifiConnStateEvent()
169 {
170     MatchingSkills matchingSkills;
171     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_WIFI_CONN_STATE);
172     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
173     std::shared_ptr<WifiServiceMonitor> subscriberPtr = std::make_shared<WifiServiceMonitor>(subscriberInfo);
174     if (!CommonEventManager::SubscribeCommonEvent(subscriberPtr)) {
175         return SOFTBUS_ERR;
176     }
177     return SOFTBUS_OK;
178 }
179 
SubscribeWifiPowerStateEvent()180 int32_t SubscribeEvent::SubscribeWifiPowerStateEvent()
181 {
182     MatchingSkills matchingSkills;
183     matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_WIFI_POWER_STATE);
184     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
185     std::shared_ptr<WifiServiceMonitor> subscriberPtr = std::make_shared<WifiServiceMonitor>(subscriberInfo);
186     if (!CommonEventManager::SubscribeCommonEvent(subscriberPtr)) {
187         return SOFTBUS_ERR;
188     }
189     return SOFTBUS_OK;
190 }
191 
SubscribeWifiSemiStateEvent()192 int32_t SubscribeEvent::SubscribeWifiSemiStateEvent()
193 {
194     MatchingSkills matchingSkills;
195     matchingSkills.AddEvent(COMMON_EVENT_WIFI_SEMI_STATE);
196     CommonEventSubscribeInfo subscriberInfo(matchingSkills);
197     subscriberInfo.SetPublisherUid(WIFI_UID);
198     std::shared_ptr<WifiServiceMonitor> subscriberPtr = std::make_shared<WifiServiceMonitor>(subscriberInfo);
199     if (!CommonEventManager::SubscribeCommonEvent(subscriberPtr)) {
200         return SOFTBUS_ERR;
201     }
202     return SOFTBUS_OK;
203 }
204 } // namespace EventFwk
205 } // namespace OHOS
206 
UpdateLocalWifiActiveCapability(void)207 static void UpdateLocalWifiActiveCapability(void)
208 {
209     SoftBusWifiState *notifyState = (SoftBusWifiState *)SoftBusMalloc(sizeof(SoftBusWifiState));
210     if (notifyState == NULL) {
211         LNN_LOGE(LNN_BUILDER, "notifyState malloc err");
212         return;
213     }
214     bool isWifiActive = SoftBusIsWifiActive();
215     if (!isWifiActive) {
216         *notifyState = SOFTBUS_WIFI_DISABLED;
217     } else {
218         *notifyState = SOFTBUS_WIFI_ENABLED;
219     }
220     int32_t ret = LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnNotifyWlanStateChangeEvent,
221         (void *)notifyState);
222     if (ret != SOFTBUS_OK) {
223         LNN_LOGE(LNN_BUILDER, "async notify wifi state err, ret=%{public}d", ret);
224         SoftBusFree(notifyState);
225     }
226 }
227 
UpdateLocalWifiConnCapability(void)228 static void UpdateLocalWifiConnCapability(void)
229 {
230     SoftBusWifiState *notifyState = (SoftBusWifiState *)SoftBusMalloc(sizeof(SoftBusWifiState));
231     if (notifyState == NULL) {
232         LNN_LOGE(LNN_BUILDER, "notifyState malloc err");
233         return;
234     }
235     SoftBusWifiLinkedInfo info;
236     (void)memset_s(&info, sizeof(SoftBusWifiLinkedInfo), 0, sizeof(SoftBusWifiLinkedInfo));
237     if (SoftBusGetLinkedInfo(&info) != SOFTBUS_OK) {
238         LNN_LOGE(LNN_BUILDER, "get link info failed");
239         SoftBusFree(notifyState);
240         return;
241     }
242     if (info.connState == SOFTBUS_API_WIFI_DISCONNECTED) {
243         *notifyState = SOFTBUS_WIFI_DISCONNECTED;
244     } else {
245         *notifyState = SOFTBUS_WIFI_CONNECTED;
246     }
247     int32_t ret = LnnAsyncCallbackHelper(GetLooper(LOOP_TYPE_DEFAULT), LnnNotifyWlanStateChangeEvent,
248         (void *)notifyState);
249     if (ret != SOFTBUS_OK) {
250         LNN_LOGE(LNN_BUILDER, "async notify wifi state err, ret=%{public}d", ret);
251         SoftBusFree(notifyState);
252     }
253 }
254 
LnnSubscribeWifiService(void * para)255 static void LnnSubscribeWifiService(void *para)
256 {
257     (void)para;
258     static int32_t retry = 0;
259     if (retry > RETRY_MAX) {
260         LNN_LOGE(LNN_BUILDER, "try subscribe wifiservice event max times");
261         return;
262     }
263     OHOS::EventFwk::SubscribeEvent *subscriberPtr = new OHOS::EventFwk::SubscribeEvent();
264     if (subscriberPtr == nullptr) {
265         LNN_LOGE(LNN_BUILDER, "SubscribeEvent init fail");
266         return;
267     }
268     if (subscriberPtr->SubscribeWifiConnStateEvent() == SOFTBUS_OK &&
269         subscriberPtr->SubscribeWifiPowerStateEvent() == SOFTBUS_OK &&
270         subscriberPtr->SubscribeAPConnStateEvent() == SOFTBUS_OK &&
271         subscriberPtr->SubscribeWifiSemiStateEvent() == SOFTBUS_OK) {
272         LNN_LOGI(LNN_BUILDER, "subscribe wifiservice conn and power state success");
273         UpdateLocalWifiActiveCapability();
274         UpdateLocalWifiConnCapability();
275     } else {
276         LNN_LOGE(LNN_BUILDER, "subscribe wifiservice event fail");
277         retry++;
278         SoftBusLooper *looper = GetLooper(LOOP_TYPE_DEFAULT);
279         if (LnnAsyncCallbackDelayHelper(looper, LnnSubscribeWifiService, NULL, DELAY_LEN) != SOFTBUS_OK) {
280             LNN_LOGE(LNN_BUILDER, "LnnAsyncCallbackDelayHelper fail");
281         }
282     }
283     delete subscriberPtr;
284 }
285 
LnnInitWifiServiceMonitorImpl(void)286 int32_t LnnInitWifiServiceMonitorImpl(void)
287 {
288     SoftBusLooper *looper = GetLooper(LOOP_TYPE_DEFAULT);
289     int32_t ret = LnnAsyncCallbackDelayHelper(looper, LnnSubscribeWifiService, NULL, DELAY_LEN);
290     if (ret != SOFTBUS_OK) {
291         LNN_LOGE(LNN_INIT, "LnnAsyncCallbackDelayHelper fail");
292     }
293     return ret;
294 }
295