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_response_list.h"
16 #include "wifi_logger.h"
17 
18 DEFINE_WIFILOG_P2P_LABEL("WifiP2pServiceResponseList");
19 
20 namespace OHOS {
21 namespace Wifi {
WifiP2pServiceResponseList()22 WifiP2pServiceResponseList::WifiP2pServiceResponseList() : updateIndic(0), frequency(0), dialogToken(-1), p2pDevice(), srvRespList()
23 {}
24 
WifiP2pServiceResponseList(const WifiP2pDevice & device,const std::vector<WifiP2pServiceResponse> & respList)25 WifiP2pServiceResponseList::WifiP2pServiceResponseList(
26     const WifiP2pDevice &device, const std::vector<WifiP2pServiceResponse> &respList)
27     : updateIndic(0), frequency(0), dialogToken(-1), p2pDevice(device), srvRespList(respList)
28 {}
29 
AddServiceResponse(const WifiP2pServiceResponse & resp)30 bool WifiP2pServiceResponseList::AddServiceResponse(const WifiP2pServiceResponse &resp)
31 {
32     for (auto it = srvRespList.begin(); it != srvRespList.end(); ++it) {
33         if (*it == resp) {
34             return true;
35         }
36     }
37     srvRespList.push_back(resp);
38     return true;
39 }
RemoveServiceResponse(const WifiP2pServiceResponse & resp)40 bool WifiP2pServiceResponseList::RemoveServiceResponse(const WifiP2pServiceResponse &resp)
41 {
42     for (auto it = srvRespList.begin(); it != srvRespList.end(); ++it) {
43         if (*it == resp) {
44             srvRespList.erase(it);
45             return true;
46         }
47     }
48     return false;
49 }
50 
GetServiceResponseList() const51 const std::vector<WifiP2pServiceResponse> &WifiP2pServiceResponseList::GetServiceResponseList() const
52 {
53     return srvRespList;
54 }
55 
FilterSerivceResponse(P2pServiceStatus status) const56 WifiP2pServiceResponseList WifiP2pServiceResponseList::FilterSerivceResponse(P2pServiceStatus status) const
57 {
58     std::vector<WifiP2pServiceResponse> pushSrvRespList;
59     for (auto it = srvRespList.begin(); it != srvRespList.end(); ++it) {
60         if (it->GetServiceStatus() == status) {
61             pushSrvRespList.push_back(*it);
62         }
63     }
64     return WifiP2pServiceResponseList(p2pDevice, pushSrvRespList);
65 }
ReverseFilterSerivceResponse(P2pServiceStatus status) const66 WifiP2pServiceResponseList WifiP2pServiceResponseList::ReverseFilterSerivceResponse(P2pServiceStatus status) const
67 {
68     std::vector<WifiP2pServiceResponse> pushSrvRespList;
69     for (auto it = srvRespList.begin(); it != srvRespList.end(); ++it) {
70         if (it->GetServiceStatus() != status) {
71             pushSrvRespList.push_back(*it);
72         }
73     }
74     return WifiP2pServiceResponseList(p2pDevice, pushSrvRespList);
75 }
MergerAndDeduplicate(const WifiP2pServiceResponseList & respList)76 bool WifiP2pServiceResponseList::MergerAndDeduplicate(const WifiP2pServiceResponseList &respList)
77 {
78     if (p2pDevice.GetDeviceAddress() != respList.GetDevice().GetDeviceAddress()) {
79         WIFI_LOGE("Different device!");
80         return false;
81     }
82 
83     for (auto mergerRespIter = respList.GetServiceResponseList().begin();
84          mergerRespIter != respList.GetServiceResponseList().end();
85          ++mergerRespIter) {
86         bool findSameResp = false;
87         for (auto iter = srvRespList.begin(); iter != srvRespList.end(); ++iter) {
88             if (mergerRespIter->GetProtocolType() == iter->GetProtocolType() &&
89                 mergerRespIter->GetData() == iter->GetData()) {
90                 findSameResp = true;
91                 break;
92             }
93         }
94         if (!findSameResp) {
95             srvRespList.push_back(*mergerRespIter);
96         }
97     }
98     return true;
99 }
GetTlvs()100 std::vector<unsigned char> WifiP2pServiceResponseList::GetTlvs()
101 {
102     std::vector<unsigned char> ret;
103 
104     for (auto tlvsIter = srvRespList.begin(); tlvsIter != srvRespList.end(); ++tlvsIter) {
105         std::vector<unsigned char> buf = tlvsIter->GetTlv();
106         for (auto dataIter = buf.begin(); dataIter != buf.end(); ++dataIter) {
107             ret.push_back(*dataIter);
108         }
109     }
110 
111     return ret;
112 }
SetUpdateIndic(unsigned short setUpdateIndic)113 void WifiP2pServiceResponseList::SetUpdateIndic(unsigned short setUpdateIndic)
114 {
115     updateIndic = setUpdateIndic;
116 }
GetUpdateIndic() const117 unsigned short WifiP2pServiceResponseList::GetUpdateIndic() const
118 {
119     return updateIndic;
120 }
SetFrequency(int setFrequency)121 void WifiP2pServiceResponseList::SetFrequency(int setFrequency)
122 {
123     frequency = setFrequency;
124 }
GetFrequency() const125 int WifiP2pServiceResponseList::GetFrequency() const
126 {
127     return frequency;
128 }
SetDialogToken(int setDialogToken)129 void WifiP2pServiceResponseList::SetDialogToken(int setDialogToken)
130 {
131     dialogToken = setDialogToken;
132 }
GetDialogToken() const133 int WifiP2pServiceResponseList::GetDialogToken() const
134 {
135     return dialogToken;
136 }
SetDevice(const WifiP2pDevice & device)137 void WifiP2pServiceResponseList::SetDevice(const WifiP2pDevice &device)
138 {
139     p2pDevice = device;
140 }
GetDevice() const141 const WifiP2pDevice &WifiP2pServiceResponseList::GetDevice() const
142 {
143     return p2pDevice;
144 }
145 
ParseTlvs2RespList(const std::vector<unsigned char> & tlvList)146 bool WifiP2pServiceResponseList::ParseTlvs2RespList(const std::vector<unsigned char> &tlvList)
147 {
148     if (tlvList.empty()) {
149         WIFI_LOGW("No Response Tlvs");
150         return false;
151     }
152     std::size_t leftLength = tlvList.size();
153     std::size_t headLength = SERVICE_TLV_LENGTH_SIZE + PROTOCOL_SIZE + TRANSACTION_ID_SIZE + SERVICE_STATUS_SIZE;
154     std::size_t pos = 0;
155     while (leftLength > 0) {
156         unsigned short length = tlvList[pos] + (tlvList[pos + 1] << CHAR_BIT);
157         unsigned short dataLength = length - PROTOCOL_SIZE - TRANSACTION_ID_SIZE - SERVICE_STATUS_SIZE;
158         int type = tlvList[pos + SERVICE_TLV_LENGTH_SIZE];
159         unsigned char transId = tlvList[pos + SERVICE_TLV_LENGTH_SIZE + PROTOCOL_SIZE];
160         int status = tlvList[pos + SERVICE_TLV_LENGTH_SIZE + PROTOCOL_SIZE + TRANSACTION_ID_SIZE];
161 
162         if (dataLength > leftLength - headLength || dataLength < 0) {
163             WIFI_LOGW("A tlv packet error!");
164             return false;
165         }
166 
167         pos += headLength;
168         if (dataLength <= MAX_BUF_SIZE) {
169             std::vector<unsigned char> data;
170             for (unsigned short i = 0; i < dataLength; ++i) {
171                 data.push_back(tlvList[pos + i]);
172             }
173             WifiP2pServiceResponse buf(
174                 static_cast<P2pServicerProtocolType>(type), static_cast<P2pServiceStatus>(status), transId, data);
175             srvRespList.push_back(buf);
176         }
177         pos += dataLength;
178         leftLength = leftLength - headLength - dataLength;
179     }
180     return true;
181 }
182 }  // namespace Wifi
183 }  // namespace OHOS
184