• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "wifi_p2p_service_manager.h"
16 #include "wifi_logger.h"
17 
18 DEFINE_WIFILOG_P2P_LABEL("WifiP2pServiceManager");
19 
20 namespace OHOS {
21 namespace Wifi {
WifiP2pServiceManager()22 WifiP2pServiceManager::WifiP2pServiceManager() : transId(0), queryId(""), requestRecord(),
23     deviceService(), serviceRespons(), localServicesInfo(), serviceMutex()
24 {}
25 
Init()26 void WifiP2pServiceManager::Init()
27 {
28 }
29 
ClearAll()30 void WifiP2pServiceManager::ClearAll()
31 {
32     ClearAllServiceResponse();
33     ClearAllDeviceService();
34     ClearLocalService();
35 }
36 
SetQueryId(const std::string & setQueryId)37 void WifiP2pServiceManager::SetQueryId(const std::string &setQueryId)
38 {
39     queryId = setQueryId;
40 }
41 
GetQueryId() const42 const std::string &WifiP2pServiceManager::GetQueryId() const
43 {
44     return queryId;
45 }
46 
GetTransId()47 unsigned char WifiP2pServiceManager::GetTransId()
48 {
49     std::unique_lock<std::mutex> lock(serviceMutex);
50     transId++;
51     if (transId == 0) {
52         transId++;
53     }
54     return transId;
55 }
56 
AddLocalService(const WifiP2pServiceInfo & p2pSvrInfo)57 bool WifiP2pServiceManager::AddLocalService(const WifiP2pServiceInfo &p2pSvrInfo)
58 {
59     std::unique_lock<std::mutex> lock(serviceMutex);
60     for (auto iter = localServicesInfo.begin(); iter != localServicesInfo.end(); ++iter) {
61         if (iter->GetServicerProtocolType() == p2pSvrInfo.GetServicerProtocolType() &&
62             iter->GetQueryList() == p2pSvrInfo.GetQueryList() &&
63             iter->GetDeviceAddress() == p2pSvrInfo.GetDeviceAddress()) {
64             WIFI_LOGD("WifiP2pServiceInfo has been added when AddLocalService.");
65             return false;
66         }
67     }
68     localServicesInfo.push_back(p2pSvrInfo);
69     return true;
70 }
71 
RemoveLocalService(const WifiP2pServiceInfo & p2pSvrInfo)72 bool WifiP2pServiceManager::RemoveLocalService(const WifiP2pServiceInfo &p2pSvrInfo)
73 {
74     std::unique_lock<std::mutex> lock(serviceMutex);
75     for (auto iter = localServicesInfo.begin(); iter != localServicesInfo.end(); ++iter) {
76         if (iter->GetServicerProtocolType() == p2pSvrInfo.GetServicerProtocolType() &&
77             iter->GetQueryList() == p2pSvrInfo.GetQueryList() &&
78             iter->GetDeviceAddress() == p2pSvrInfo.GetDeviceAddress()) {
79             localServicesInfo.erase(iter);
80             return true;
81         }
82     }
83     WIFI_LOGD("Cannot find p2pSvrInfo when RemoveLocalService.");
84     return false;
85 }
ClearLocalService()86 void WifiP2pServiceManager::ClearLocalService()
87 {
88     std::unique_lock<std::mutex> lock(serviceMutex);
89     localServicesInfo.clear();
90 }
GetLocalServiceList()91 const std::vector<WifiP2pServiceInfo> &WifiP2pServiceManager::GetLocalServiceList()
92 {
93     return localServicesInfo;
94 }
95 
AddDeviceResponses(const WifiP2pServiceResponseList & rspList)96 bool WifiP2pServiceManager::AddDeviceResponses(const WifiP2pServiceResponseList &rspList)
97 {
98     const WifiP2pServiceResponseList responseList = rspList.FilterSerivceResponse(P2pServiceStatus::PSRS_SUCCESS);
99     const WifiP2pDevice &device = responseList.GetDevice();
100 
101     auto iter = serviceRespons.find(device.GetDeviceAddress());
102     if (iter != serviceRespons.end()) {
103         WifiP2pServiceResponseList &deviceRespList = iter->second;
104         if (!deviceRespList.MergerAndDeduplicate(responseList)) {
105             WIFI_LOGE("Merge response error.");
106             return false;
107         }
108     } else {
109         serviceRespons.insert(
110             std::pair<std::string, WifiP2pServiceResponseList>(device.GetDeviceAddress(), responseList));
111     }
112     return true;
113 }
114 
AddDeviceService(const WifiP2pServiceResponse & rsp,const WifiP2pDevice & dev)115 bool WifiP2pServiceManager::AddDeviceService(const WifiP2pServiceResponse &rsp, const WifiP2pDevice &dev)
116 {
117     if (rsp.GetServiceStatus() == P2pServiceStatus::PSRS_SERVICE_PROTOCOL_NOT_AVAILABLE) {
118         return false;
119     }
120 
121     WifiP2pServiceInfo service;
122     service.SetServicerProtocolType(rsp.GetProtocolType());
123     service.SetDeviceAddress(dev.GetDeviceAddress());
124     std::vector<std::string> queryList;
125     std::string query;
126     for (auto itRsp = rsp.GetData().begin(); itRsp != rsp.GetData().end(); ++itRsp) {
127         query += *itRsp;
128     }
129     queryList.push_back(query);
130     service.SetQueryList(queryList);
131 
132     std::unique_lock<std::mutex> lock(serviceMutex);
133     auto iter = deviceService.find(dev.GetDeviceAddress());
134     if (iter == deviceService.end()) {
135         std::vector<WifiP2pServiceInfo> services;
136         services.push_back(service);
137         deviceService.insert(
138             std::pair<std::string, std::vector<WifiP2pServiceInfo>>(dev.GetDeviceAddress(), services));
139         return true;
140     }
141 
142     std::vector<WifiP2pServiceInfo> &deviceServices = iter->second;
143     for (auto devService = deviceServices.begin(); devService != deviceServices.end(); ++devService) {
144         if (*devService == service) {
145             return false;
146         }
147     }
148     deviceServices.push_back(service);
149 
150     return true;
151 }
152 
DelServicesFormAddress(const std::string & devAddr)153 bool WifiP2pServiceManager::DelServicesFormAddress(const std::string &devAddr)
154 {
155     std::unique_lock<std::mutex> lock(serviceMutex);
156     auto it = deviceService.find(devAddr);
157     if (it == deviceService.end()) {
158         WIFI_LOGD("no svr to del.");
159         return false;
160     }
161     deviceService.erase(it);
162     return true;
163 }
164 
ClearAllDeviceService()165 bool WifiP2pServiceManager::ClearAllDeviceService()
166 {
167     std::unique_lock<std::mutex> lock(serviceMutex);
168     deviceService.clear();
169     return true;
170 }
171 
GetDeviceServices(std::vector<WifiP2pServiceInfo> & services)172 void WifiP2pServiceManager::GetDeviceServices(std::vector<WifiP2pServiceInfo> &services)
173 {
174     std::unique_lock<std::mutex> lock(serviceMutex);
175     for (auto mapIter = deviceService.begin(); mapIter != deviceService.end(); ++mapIter) {
176         for (auto svrInfoIter = mapIter->second.begin(); svrInfoIter != mapIter->second.end(); ++svrInfoIter) {
177             WifiP2pServiceInfo buf;
178             buf.SetDeviceAddress(svrInfoIter->GetDeviceAddress());
179             buf.SetServicerProtocolType(svrInfoIter->GetServicerProtocolType());
180             buf.SetServiceName(svrInfoIter->GetServiceName());
181             buf.SetQueryList(svrInfoIter->GetQueryList());
182             services.push_back(buf);
183         }
184     }
185 }
186 
AddServiceResponse(const WifiP2pServiceResponseList & p2pSvrRespList)187 bool WifiP2pServiceManager::AddServiceResponse(const WifiP2pServiceResponseList &p2pSvrRespList)
188 {
189     auto findIter = serviceRespons.find(p2pSvrRespList.GetDevice().GetDeviceAddress());
190     if (findIter == serviceRespons.end()) {
191         serviceRespons.emplace(std::make_pair(p2pSvrRespList.GetDevice().GetDeviceAddress(), p2pSvrRespList));
192         return true;
193     }
194 
195     bool bUpdate = false;
196     for (auto addedRespIter = p2pSvrRespList.GetServiceResponseList().begin();
197          addedRespIter != p2pSvrRespList.GetServiceResponseList().end(); ++addedRespIter) {
198         bool equal = false;
199         for (auto foundRespIter = findIter->second.GetServiceResponseList().begin();
200              foundRespIter != findIter->second.GetServiceResponseList().end(); ++foundRespIter) {
201             if (*addedRespIter == *foundRespIter) {
202                 equal = true;
203                 break;
204             }
205         }
206         if (!equal) {
207             findIter->second.AddServiceResponse(*addedRespIter);
208             bUpdate = true;
209         }
210     }
211     return bUpdate;
212 }
213 
RemoveServiceResponse(const WifiP2pServiceResponseList & p2pSvrRespList)214 bool WifiP2pServiceManager::RemoveServiceResponse(const WifiP2pServiceResponseList &p2pSvrRespList)
215 {
216     auto findIter = serviceRespons.find(p2pSvrRespList.GetDevice().GetDeviceAddress());
217     if (findIter == serviceRespons.end()) {
218         WIFI_LOGE("Cannot find %{private}s respList", p2pSvrRespList.GetDevice().GetDeviceAddress().c_str());
219         return false;
220     }
221 
222     for (auto delRespIter = p2pSvrRespList.GetServiceResponseList().begin();
223          delRespIter != p2pSvrRespList.GetServiceResponseList().end(); ++delRespIter) {
224         bool found = false;
225         for (auto foundRespIter = findIter->second.GetServiceResponseList().begin();
226              foundRespIter != findIter->second.GetServiceResponseList().end(); ++foundRespIter) {
227             if (*delRespIter == *foundRespIter) {
228                 found = true;
229                 findIter->second.RemoveServiceResponse(*delRespIter);
230                 break;
231             }
232         }
233         if (!found) {
234             WIFI_LOGE("No %{public}d resp in stored %{private}s",
235                 delRespIter->GetTransactionId(),
236                 p2pSvrRespList.GetDevice().GetDeviceAddress().c_str());
237         }
238     }
239     return true;
240 }
241 
RemoveServiceResponse(const std::string & deviceAddress)242 bool WifiP2pServiceManager::RemoveServiceResponse(const std::string &deviceAddress)
243 {
244     auto findIter = serviceRespons.find(deviceAddress);
245     if (findIter == serviceRespons.end()) {
246         return false;
247     } else {
248         serviceRespons.erase(findIter);
249         return true;
250     }
251 }
252 
ClearAllServiceResponse()253 bool WifiP2pServiceManager::ClearAllServiceResponse()
254 {
255     serviceRespons.clear();
256     return true;
257 }
258 
GetServiceResponseList(std::vector<WifiP2pServiceResponseList> & respList)259 bool WifiP2pServiceManager::GetServiceResponseList(std::vector<WifiP2pServiceResponseList> &respList)
260 {
261     for (auto respListIter = respList.begin(); respListIter != respList.end(); ++respListIter) {
262         auto findIter = serviceRespons.find(respListIter->GetDevice().GetDeviceAddress());
263         if (findIter != serviceRespons.end()) {
264             *respListIter = findIter->second;
265         } else {
266             WIFI_LOGE("Cannot get %{private}s responseList", respListIter->GetDevice().GetDeviceAddress().c_str());
267         }
268     }
269     return true;
270 }
271 
ProcessServiceRequestList(const WifiP2pServiceRequestList & reqList)272 WifiP2pServiceResponseList WifiP2pServiceManager::ProcessServiceRequestList(const WifiP2pServiceRequestList &reqList)
273 {
274     WifiP2pServiceResponseList responseList;
275     responseList.SetDevice(reqList.GetDevice());
276     responseList.SetFrequency(reqList.GetFrequency());
277     responseList.SetDialogToken(reqList.GetDialogToken());
278     const std::vector<WifiP2pServiceRequest> &list = reqList.GetServiceRequestList();
279 
280     std::unique_lock<std::mutex> lock(serviceMutex);
281     for (const auto &request : list) {
282         bool isFind = false;
283         WifiP2pServiceResponse response;
284         response.SetTransactionId(request.GetTransactionId());
285 
286         for (const auto &service : localServicesInfo) {
287             if (request.GetProtocolType() == service.GetServicerProtocolType() ||
288                 request.GetProtocolType() == P2pServicerProtocolType::SERVICE_TYPE_ALL) {
289                 isFind = true;
290                 response.SetProtocolType(service.GetServicerProtocolType());
291                 std::vector<unsigned char> data;
292                 P2pServiceStatus status = service.ProcessServiceRequest(request.GetQuery(), data);
293                 response.SetServiceStatus(status);
294                 response.SetData(data);
295                 responseList.AddServiceResponse(response);
296             }
297         }
298 
299         if (!isFind) {
300             response.SetProtocolType(request.GetProtocolType());
301             response.SetServiceStatus(P2pServiceStatus::PSRS_SERVICE_PROTOCOL_NOT_AVAILABLE);
302             responseList.AddServiceResponse(response);
303         }
304     }
305 
306     return responseList;
307 }
308 
ProcessServiceResponseList(const WifiP2pServiceResponseList & rspList) const309 void WifiP2pServiceManager::ProcessServiceResponseList(const WifiP2pServiceResponseList &rspList) const
310 {
311     const std::vector<WifiP2pServiceResponse> &list = rspList.GetServiceResponseList();
312 
313     for (const auto &response : list) {
314         for (const auto &service : localServicesInfo) {
315             if (response.GetProtocolType() == service.GetServicerProtocolType()) {
316                 service.ProcessServiceResponse(response.GetData());
317             }
318         }
319     }
320 }
321 
IsRecordedRequest(const std::string & deviceAddress,int dialogToken)322 bool WifiP2pServiceManager::IsRecordedRequest(const std::string &deviceAddress, int dialogToken)
323 {
324     auto findIter = requestRecord.find(deviceAddress);
325     if (findIter == requestRecord.end()) {
326         return false;
327     }
328     for (auto diaIter = findIter->second.begin(); diaIter != findIter->second.end(); ++diaIter) {
329         if (*diaIter == dialogToken) {
330             return true;
331         }
332     }
333     return false;
334 }
335 
AddRequestRecord(const std::string & deviceAddress,int dialogToken)336 void WifiP2pServiceManager::AddRequestRecord(const std::string &deviceAddress, int dialogToken)
337 {
338     auto findIter = requestRecord.find(deviceAddress);
339     if (findIter == requestRecord.end()) {
340         std::vector<int> dias;
341         dias.push_back(dialogToken);
342         requestRecord.emplace(std::make_pair(deviceAddress, dias));
343         return;
344     }
345     for (auto diaIter = findIter->second.begin(); diaIter != findIter->second.end(); ++diaIter) {
346         if (*diaIter == dialogToken) {
347             return;
348         }
349     }
350     findIter->second.push_back(dialogToken);
351     return;
352 }
353 
RemoveRequestRecord(const std::string & deviceAddress,int dialogToken)354 void WifiP2pServiceManager::RemoveRequestRecord(const std::string &deviceAddress, int dialogToken)
355 {
356     auto findIter = requestRecord.find(deviceAddress);
357     if (findIter != requestRecord.end()) {
358         for (auto diaIter = findIter->second.begin(); diaIter != findIter->second.end(); ++diaIter) {
359             if (*diaIter == dialogToken) {
360                 findIter->second.erase(diaIter);
361                 return;
362             }
363         }
364     }
365     return;
366 }
367 
ClearAllRequestRecord()368 void WifiP2pServiceManager::ClearAllRequestRecord()
369 {
370     requestRecord.clear();
371 }
372 
UpdateServiceName(const std::string & devAddr,const WifiP2pServiceResponse & svrInfo)373 bool WifiP2pServiceManager::UpdateServiceName(const std::string &devAddr, const WifiP2pServiceResponse &svrInfo)
374 {
375     std::unique_lock<std::mutex> lock(serviceMutex);
376     auto iter = deviceService.find(devAddr);
377     if (iter == deviceService.end()) {
378         WIFI_LOGE("Cannot find %{private}s, update service name failed!", devAddr.c_str());
379         return false;
380     }
381 
382     std::string tlvString(svrInfo.GetData().begin(), svrInfo.GetData().end());
383     std::vector<WifiP2pServiceInfo> &svrInfos = iter->second;
384     for (auto iterSvrInfo = svrInfos.begin(); iterSvrInfo != svrInfos.end(); ++iterSvrInfo) {
385         if (iterSvrInfo->GetServicerProtocolType() == svrInfo.GetProtocolType() &&
386             iterSvrInfo->GetDeviceAddress() == devAddr && iterSvrInfo->GetQueryList().at(0) == tlvString) {
387             iterSvrInfo->SetServiceName(svrInfo.GetServiceName());
388             return true;
389         }
390     }
391 
392     WIFI_LOGE("Cannot find same service info, update service name failed!");
393     return false;
394 }
395 } // namespace Wifi
396 } // namespace OHOS
397