• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <algorithm>
17 #include "napi/native_node_api.h"
18 #include "eap_event_mgr.h"
19 namespace OHOS {
20 namespace NetManagerStandard {
21 
22 static constexpr int32_t REGISTERINFO_MAX_NUM = 16;
23 static constexpr int32_t WIFI_DEVICE_SA_ID = 1120;
24 static constexpr int32_t COMM_ETHERNET_MANAGER_SYS_ABILITY_ID = 1157;
25 static constexpr uint32_t INVALID_REF_COUNT = 0xff;
26 static constexpr const char *EAP_BUFFER = "eapBuffer";
27 static constexpr const char *EAP_BUFFERLEN = "bufferLen";
28 static constexpr const char *EAP_MSGID = "msgId";
29 static std::shared_mutex g_regInfoMutex;
30 
OnEapSupplicantPostback(NetType netType,const sptr<EapData> & eapData)31 int32_t NetEapPostBackCallback::OnEapSupplicantPostback(NetType netType, const sptr<EapData> &eapData)
32 {
33     if (eapData == nullptr) {
34         NETMANAGER_EXT_LOGE("%{public}s eapData is nullptr.", __func__);
35         return NETMANAGER_ERR_LOCAL_PTR_NULL;
36     }
37     if (eapData->eapCode < EAP_CODE_MIN || eapData->eapCode > EAP_CODE_MAX) {
38         NETMANAGER_EXT_LOGE("eapCode %{public}d invalid.", eapData->eapCode);
39         return NETMANAGER_ERR_PARAMETER_ERROR;
40     }
41     if (eapData->eapBuffer.size() == 0) {
42         NETMANAGER_EXT_LOGE("%{public}s eapBuffer size is 0. %{public}s", __func__, eapData->PrintLogInfo().c_str());
43         return NETMANAGER_ERR_PARAMETER_ERROR;
44     }
45     NETMANAGER_EXT_LOGI("%{public}s: eapCode:%{public}d, eapType:%{public}d, buffsize:%{public}zu", __func__,
46         eapData->eapCode, eapData->eapType, eapData->eapBuffer.size());
47     uint32_t composeParam =  (eapData->eapCode << 8) | eapData->eapType;
48     return CheckAndNotifyApp(netType, composeParam, eapData);
49 }
50 
CreateResult(const napi_env & env,const sptr<EapData> & eapData)51 napi_value NetEapPostBackCallback::CreateResult(const napi_env& env, const sptr<EapData> &eapData)
52 {
53     napi_value obj = NapiUtils::CreateObject(env);
54     if (NapiUtils::GetValueType(env, obj) != napi_object) {
55         return NapiUtils::GetUndefined(env);
56     }
57 
58     NapiUtils::SetVectorUint8Property(env, obj, EAP_BUFFER, eapData->eapBuffer);
59     NapiUtils::SetUint32Property(env, obj, EAP_BUFFERLEN, eapData->bufferLen);
60     NapiUtils::SetUint32Property(env, obj, EAP_MSGID, eapData->msgId);
61     return obj;
62 }
63 
CheckAndNotifyApp(NetType netType,const int32_t key,const sptr<EapData> & eapData)64 bool NetEapPostBackCallback::CheckAndNotifyApp(NetType netType, const int32_t key, const sptr<EapData> &eapData)
65 {
66     std::shared_lock<std::shared_mutex> lock(g_regInfoMutex);
67     auto regInfo = EapEventMgr::GetInstance().GetRegisterInfoMap();
68     auto netTypeIter = regInfo.find(netType);
69     if (netTypeIter == regInfo.end()) {
70         NETMANAGER_EXT_LOGE("%{public}s, netType %{public}d not find register info.", __func__, netType);
71         return false;
72     }
73     auto it = netTypeIter->second.find(key);
74     if (it == netTypeIter->second.end()) {
75         NETMANAGER_EXT_LOGE("%{public}s, not find register info.", __func__);
76         return false;
77     }
78     for (auto& each : it->second) {
79         auto func = [this, env = each.m_regEnv, eapData] () -> napi_value { return this->CreateResult(env, eapData); };
80         std::shared_ptr<AsyncEventData> asyncEvent =
81             std::make_shared<AsyncEventData>(each.m_regEnv, each.m_regHandlerRef, func);
82         asyncEvent->Init(key, netType, eapData->msgId);
83         EventNotify(asyncEvent);
84     }
85     return true;
86 }
87 
SendTask(const std::shared_ptr<AsyncEventData> & asyncEvent)88 void NetEapPostBackCallback::SendTask(const std::shared_ptr<AsyncEventData> &asyncEvent)
89 {
90     napi_value handler = nullptr;
91     napi_value jsEvent = nullptr;
92     napi_value undefine;
93     uint32_t refCount = INVALID_REF_COUNT;
94     napi_status res;
95     bool unrefRef = false;
96     bool find = false;
97     InitScope(asyncEvent);
98     auto regInfo = EapEventMgr::GetInstance().GetRegisterInfoMap();
99     auto it = regInfo[asyncEvent->netType_].find(asyncEvent->key_);
100     if (it == regInfo[asyncEvent->netType_].end()) {
101         NETMANAGER_EXT_LOGE("%{public}s, event has been unregistered.", __func__);
102         EndSendTask(asyncEvent, unrefRef, refCount);
103         return;
104     }
105     for (auto& each : it->second) {
106         if (each.m_regEnv == asyncEvent->env_ && each.m_regHandlerRef == asyncEvent->callbackRef_) {
107             find = true;
108             break;
109         }
110     }
111     if (find == false) {
112         NETMANAGER_EXT_LOGE("%{public}s, NOT find the event.", __func__);
113         EndSendTask(asyncEvent, unrefRef, refCount);
114         return;
115     }
116     res = napi_reference_ref(asyncEvent->env_, asyncEvent->callbackRef_, &refCount);
117     NETMANAGER_EXT_LOGI("%{public}s, res: %{public}d, callbackRef: %{private}p, refCount: %{public}d",
118         __func__, res, asyncEvent->callbackRef_, refCount);
119     if (res != napi_ok || refCount <= 1) {
120         EndSendTask(asyncEvent, unrefRef, refCount);
121         return;
122     }
123     unrefRef = true;
124     res = napi_get_reference_value(asyncEvent->env_, asyncEvent->callbackRef_, &handler);
125     if (res != napi_ok || handler == nullptr) {
126         NETMANAGER_EXT_LOGE("%{public}s, handler is nullptr or res: %{public}d!", __func__, res);
127         EndSendTask(asyncEvent, unrefRef, refCount);
128         return;
129     }
130     napi_get_undefined(asyncEvent->env_, &undefine);
131     jsEvent = asyncEvent->packResult_();
132     if (napi_call_function(asyncEvent->env_, nullptr, handler, 1, &jsEvent, &undefine) != napi_ok) {
133         NETMANAGER_EXT_LOGE("%{public}s, Report event to Js failed", __func__);
134         EndSendTask(asyncEvent, unrefRef, refCount);
135         return;
136     }
137 }
138 
InitScope(const std::shared_ptr<AsyncEventData> & asyncEvent)139 void NetEapPostBackCallback::InitScope(const std::shared_ptr<AsyncEventData> &asyncEvent)
140 {
141     napi_open_handle_scope(asyncEvent->env_, &scope_);
142     if (scope_ == nullptr) {
143         NETMANAGER_EXT_LOGE("napi_send_event, scope is nullptr");
144         EndSendTask(asyncEvent, false, INVALID_REF_COUNT);
145     }
146 }
147 
EndSendTask(const std::shared_ptr<AsyncEventData> & asyncEvent,bool unrefRef,uint32_t refCount)148 void NetEapPostBackCallback::EndSendTask(const std::shared_ptr<AsyncEventData> &asyncEvent,
149     bool unrefRef, uint32_t refCount)
150 {
151     napi_close_handle_scope(asyncEvent->env_, scope_);
152     if (unrefRef) {
153         napi_reference_unref(asyncEvent->env_, asyncEvent->callbackRef_, &refCount);
154     }
155 }
156 
EventNotify(const std::shared_ptr<AsyncEventData> & asyncEvent)157 void NetEapPostBackCallback::EventNotify(const std::shared_ptr<AsyncEventData> &asyncEvent)
158 {
159     if (asyncEvent == nullptr) {
160         NETMANAGER_EXT_LOGE("asyncEvent is null!");
161         return;
162     }
163     NETMANAGER_EXT_LOGI("Enter eap postback event notify, msgId: %{public}d", asyncEvent->msgId_);
164     auto sendTask = std::bind(&NetEapPostBackCallback::SendTask, this, asyncEvent);
165     if (napi_status::napi_ok != napi_send_event(asyncEvent->env_, sendTask, napi_eprio_immediate)) {
166         NETMANAGER_EXT_LOGE("%{public}s, Failed to SendEvent", __func__);
167     }
168 }
169 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)170 void NetManagerNapiAbilityStatusChange::OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
171 {
172     NETMANAGER_EXT_LOGI("NetManagerNapiAbilityStatusChange OnAddSystemAbility systemAbilityId:%{public}d",
173         systemAbilityId);
174     std::vector<std::string> event;
175     switch (systemAbilityId) {
176         case WIFI_DEVICE_SA_ID:
177         case COMM_ETHERNET_MANAGER_SYS_ABILITY_ID: {
178             EapEventMgr::GetInstance().RegCustomEapHandler(NetType::WLAN0, RegTriggerMode::SA_LAUNCH);
179             break;
180         }
181         default:
182             NETMANAGER_EXT_LOGI("OnAddSystemAbility unhandled sysabilityId:%{public}d", systemAbilityId);
183             return;
184     }
185 }
186 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)187 void NetManagerNapiAbilityStatusChange::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId)
188 {
189     NETMANAGER_EXT_LOGI("NetManagerNapiAbilityStatusChange OnRemoveSystemAbility systemAbilityId:%{public}d",
190         systemAbilityId);
191 }
192 
GetInstance()193 EapEventMgr &EapEventMgr::GetInstance()
194 {
195     static EapEventMgr instance;
196     return instance;
197 }
198 
EapEventMgr()199 EapEventMgr::EapEventMgr():eapPostBackCallback_(sptr<NetEapPostBackCallback>::MakeSptr())
200 {
201         auto samgrProxy = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
202         if (samgrProxy == nullptr) {
203             NETMANAGER_EXT_LOGE("samgrProxy is nullptr!");
204             return;
205         }
206         sptr<NetManagerNapiAbilityStatusChange> mSaStatusListener = sptr<NetManagerNapiAbilityStatusChange>::MakeSptr();
207 
208         int32_t retWifiSa = samgrProxy->SubscribeSystemAbility((int32_t)WIFI_DEVICE_SA_ID, mSaStatusListener);
209         int32_t retNetManagerSa = samgrProxy->SubscribeSystemAbility(
210             (int32_t)COMM_ETHERNET_MANAGER_SYS_ABILITY_ID, mSaStatusListener);
211         NETMANAGER_EXT_LOGI("EventRegister, SubscribeSystemAbility return retWifiSa:%{public}d, \
212             retNetManagerSa:%{public}d!", retWifiSa, retNetManagerSa);
213 }
214 
RegCustomEapHandler(napi_env env,NetType netType,uint32_t eapCode,uint32_t eapType,napi_value handler)215 int32_t EapEventMgr::RegCustomEapHandler(napi_env env, NetType netType, uint32_t eapCode, uint32_t eapType,
216     napi_value handler)
217 {
218     NETMANAGER_EXT_LOGI("%{public}s enter, netType:%{public}d, eapCode:%{public}d, eapType:%{public}d", __func__,
219         static_cast<int>(netType), eapCode, eapType);
220     uint32_t composeParam =  (eapCode << 8) | eapType;
221     napi_ref handlerRef = nullptr;
222     napi_create_reference(env, handler, 1, &handlerRef);
223     RegObj regObj(env, handlerRef);
224 
225     std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
226     auto netTypeMapIter = eventRegisterInfo_.find(netType);
227     if (netTypeMapIter == eventRegisterInfo_.end()) {
228         NETMANAGER_EXT_LOGI("%{public}s, new netType!", __func__);
229         TypeMapRegObj mapObj;
230         mapObj[composeParam] = std::vector<RegObj>{regObj};
231         eventRegisterInfo_[netType] = mapObj;
232     } else {
233         NETMANAGER_EXT_LOGI("%{public}s, exist netType!", __func__);
234         TypeMapRegObj mapObj = netTypeMapIter->second;
235         auto iter = mapObj.find(composeParam);
236         if (iter == mapObj.end()) {
237             NETMANAGER_EXT_LOGI("%{public}s, new eapCode:%{public}d, eapType:%{public}d!", __func__,
238                 eapCode, eapType);
239             if (mapObj.size() > REGISTERINFO_MAX_NUM) {
240                 NETMANAGER_EXT_LOGE("%{public}s, RegisterInfo Exceeding the maximum value!", __func__);
241                 return EAP_ERRCODE_INTERNAL_ERROR;
242             }
243             mapObj[composeParam] = std::vector<RegObj>{regObj};
244             eventRegisterInfo_[netType] = mapObj;
245         } else {
246             auto vecIter = std::find_if(iter->second.begin(), iter->second.end(),
247                 [&regObj] (const RegObj &obj) { return regObj.m_regEnv == obj.m_regEnv;});
248             if (vecIter != iter->second.end()) {
249                 NETMANAGER_EXT_LOGE("%{public}s, eapCode:%{public}d, eapType:%{public}d callback is registered!",
250                     __func__, eapCode, eapType);
251                 return EAP_ERRCODE_SUCCESS;
252             }
253             iter->second.emplace_back(regObj);
254             NETMANAGER_EXT_LOGI("%{public}s, eapCode:%{public}d, eapType:%{public}d callback size:%{public}zu!",
255                 __func__, eapCode, eapType, iter->second.size());
256         }
257     }
258     guard.unlock();
259     return RegCustomEapHandler(netType, RegTriggerMode::USER_REGISTER);
260 }
261 
RegCustomEapHandler(NetType netType,RegTriggerMode triggerMode)262 int32_t EapEventMgr::RegCustomEapHandler(NetType netType, RegTriggerMode triggerMode)
263 {
264     std::string regCmd;
265     {
266         std::shared_lock<std::shared_mutex> guard(g_regInfoMutex);
267         auto mNetTypeValueIter = eventRegisterInfo_.find(netType);
268         if (mNetTypeValueIter == eventRegisterInfo_.end()) {
269             NETMANAGER_EXT_LOGE("%{public}s eventRegisterInfo_ not have eapType:%{public}d", __func__, netType);
270             return EAP_ERRCODE_INTERNAL_ERROR;
271         }
272         regCmd += std::to_string(static_cast<int>(netType));
273         regCmd += ":";
274         regCmd += std::to_string(mNetTypeValueIter->second.size());
275         for (auto &iter : mNetTypeValueIter->second) {
276             regCmd += ":";
277             regCmd += std::to_string(iter.first);
278         }
279     }
280     NETMANAGER_EXT_LOGI("%{public}s enter, triggreMode:%{public}d, netType:%{public}d, regCmd:%{public}s", __func__,
281         static_cast<int>(triggerMode), static_cast<int>(netType), regCmd.c_str());
282     return DelayedSingleton<EthernetClient>::GetInstance()->RegCustomEapHandler(netType, regCmd,
283         eapPostBackCallback_);
284 }
285 
UnRegCustomEapHandler(napi_env env,NetType netType,uint32_t eapCode,uint32_t eapType,napi_value handler)286 int32_t EapEventMgr::UnRegCustomEapHandler(napi_env env, NetType netType, uint32_t eapCode, uint32_t eapType,
287     napi_value handler)
288 {
289     NETMANAGER_EXT_LOGI("%{public}s enter, netType:%{public}d, eapCode:%{public}d, eapType:%{public}d", __func__,
290         static_cast<int>(netType), eapCode, eapType);
291     uint32_t composeParam =  (eapCode << 8) | eapType;
292     napi_ref handlerRef = nullptr;
293     napi_create_reference(env, handler, 1, &handlerRef);
294     RegObj regObj(env, handlerRef);
295     bool needUnregister = false;
296     {
297         std::unique_lock<std::shared_mutex> guard(g_regInfoMutex);
298         auto netTypeMapIter = eventRegisterInfo_.find(netType);
299         if (netTypeMapIter == eventRegisterInfo_.end()) {
300             NETMANAGER_EXT_LOGE("%{public}s, not netType %{public}d handler", __func__, netType);
301             return EAP_ERRCODE_INTERNAL_ERROR;
302         }
303         TypeMapRegObj& mapObj = netTypeMapIter->second;
304         auto mapObjIter = mapObj.find(composeParam);
305         if (mapObjIter == mapObj.end()) {
306             NETMANAGER_EXT_LOGE("%{public}s, not composeParam %{public}d handler", __func__, composeParam);
307             return EAP_ERRCODE_INTERNAL_ERROR;
308         }
309         auto new_end = std::remove_if(mapObjIter->second.begin(), mapObjIter->second.end(),
310             [env](const RegObj& obj) { return obj.m_regEnv == env; });
311         mapObjIter->second.erase(new_end, mapObjIter->second.end());
312     // if have no callbacks, supplicant unregister this eap code and type
313         if (mapObjIter->second.size() == 0) {
314             mapObj.erase(mapObjIter);
315             needUnregister = true;
316         }
317     }
318     if (needUnregister) {
319         NETMANAGER_EXT_LOGI("%{public}s, eapCode:%{public}d, eapType:%{public}d", __func__, eapCode, eapType);
320         return UnRegCustomEapHandler(netType);
321     }
322     return true;
323 }
324 
UnRegCustomEapHandler(NetType netType)325 int32_t EapEventMgr::UnRegCustomEapHandler(NetType netType)
326 {
327     return RegCustomEapHandler(netType, RegTriggerMode::UNREGISTER);
328 }
329 
ReplyCustomEapData(CustomResult result,const sptr<EapData> & eapData)330 int32_t EapEventMgr::ReplyCustomEapData(CustomResult result, const sptr<EapData> &eapData)
331 {
332     return DelayedSingleton<EthernetClient>::GetInstance()->ReplyCustomEapData(static_cast<int>(result),
333         eapData);
334 }
335 
GetRegisterInfoMap()336 std::map<NetType, TypeMapRegObj> EapEventMgr::GetRegisterInfoMap()
337 {
338     return eventRegisterInfo_;
339 }
340 } // namespace NetManagerStandard
341 } // namespace OHOS