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