1 /*
2 * Copyright (c) 2020-2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "p2p.h"
10 #include "message/message_router.h"
11 #include "message/sidecar.h"
12 #include "wifi_base.h"
13 #include "wifi_mac80211_ops.h"
14 #include "hdf_wlan_services.h"
15 #include "hdf_wlan_utils.h"
16
17 #define HDF_LOG_TAG HDF_WIFI_CORE
18
19 #ifdef __cplusplus
20 extern "C" {
21 #endif
RemainOnChannel(struct NetDevice * netdev,WifiOnChannel * onChannel)22 static int32_t RemainOnChannel(struct NetDevice *netdev, WifiOnChannel *onChannel)
23 {
24 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
25 if (chipDriver == NULL) {
26 HDF_LOGE("%s:bad net device found!", __func__);
27 return HDF_FAILURE;
28 }
29
30 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, RemainOnChannel);
31 return chipDriver->p2pOps->RemainOnChannel(netdev, onChannel);
32 }
33
WifiCmdRemainOnChannel(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)34 static int32_t WifiCmdRemainOnChannel(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
35 {
36 int32_t ret;
37 struct NetDevice *netdev = NULL;
38 const char *ifName = NULL;
39 WifiOnChannel wifiOnChannel = {0};
40
41 (void)context;
42 if (reqData == NULL || rspData == NULL) {
43 HDF_LOGE("%s: input parameter invalid!", __func__);
44 return HDF_ERR_INVALID_PARAM;
45 }
46 ifName = HdfSbufReadString(reqData);
47 if (ifName == NULL) {
48 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
49 return HDF_FAILURE;
50 }
51 netdev = NetDeviceGetInstByName(ifName);
52 if (netdev == NULL) {
53 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
54 return HDF_FAILURE;
55 }
56 if (!HdfSbufReadUint32(reqData, &(wifiOnChannel.freq))) {
57 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "freq");
58 return HDF_FAILURE;
59 }
60 if (!HdfSbufReadUint32(reqData, &(wifiOnChannel.duration))) {
61 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "duration");
62 return HDF_FAILURE;
63 }
64 ret = RemainOnChannel(netdev, &wifiOnChannel);
65 if (ret != HDF_SUCCESS) {
66 HDF_LOGE("%s: fail to remain on channel,%d", __func__, ret);
67 } else {
68 HDF_LOGD("%s: remain on channel success! freq=%d", __func__, wifiOnChannel.freq);
69 }
70 return ret;
71 }
72
ProbeReqReport(struct NetDevice * netdev,int32_t report)73 static int32_t ProbeReqReport(struct NetDevice *netdev, int32_t report)
74 {
75 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
76 if (chipDriver == NULL) {
77 HDF_LOGE("%s:bad net device found!", __func__);
78 return HDF_FAILURE;
79 }
80
81 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, ProbeReqReport);
82 return chipDriver->p2pOps->ProbeReqReport(netdev, report);
83 }
84
WifiCmdProbeReqReport(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)85 static int32_t WifiCmdProbeReqReport(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
86 {
87 int32_t ret;
88 struct NetDevice *netdev = NULL;
89 const char *ifName = NULL;
90 int32_t report;
91
92 (void)context;
93 if (reqData == NULL || rspData == NULL) {
94 HDF_LOGE("%s: input parameter invalid!", __func__);
95 return HDF_ERR_INVALID_PARAM;
96 }
97 ifName = HdfSbufReadString(reqData);
98 if (ifName == NULL) {
99 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
100 return HDF_FAILURE;
101 }
102 netdev = NetDeviceGetInstByName(ifName);
103 if (netdev == NULL) {
104 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
105 return HDF_FAILURE;
106 }
107 if (!HdfSbufReadInt32(reqData, &(report))) {
108 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "report");
109 return HDF_FAILURE;
110 }
111
112 ret = ProbeReqReport(netdev, report);
113 if (ret != HDF_SUCCESS) {
114 HDF_LOGE("%s: fail to probe req report,%d", __func__, ret);
115 }
116 return ret;
117 }
118
CancelRemainOnChannel(struct NetDevice * netdev)119 static int32_t CancelRemainOnChannel(struct NetDevice *netdev)
120 {
121 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
122 if (chipDriver == NULL) {
123 HDF_LOGE("%s:bad net device found!", __func__);
124 return HDF_FAILURE;
125 }
126
127 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, CancelRemainOnChannel);
128 return chipDriver->p2pOps->CancelRemainOnChannel(netdev);
129 }
130
WifiCmdCancelRemainOnChannel(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)131 static int32_t WifiCmdCancelRemainOnChannel(const RequestContext *context, struct HdfSBuf *reqData,
132 struct HdfSBuf *rspData)
133 {
134 int32_t ret;
135 struct NetDevice *netdev = NULL;
136 const char *ifName = NULL;
137
138 (void)context;
139 if (reqData == NULL || rspData == NULL) {
140 HDF_LOGE("%s: input parameter invalid!", __func__);
141 return HDF_ERR_INVALID_PARAM;
142 }
143 ifName = HdfSbufReadString(reqData);
144 if (ifName == NULL) {
145 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
146 return HDF_FAILURE;
147 }
148 netdev = NetDeviceGetInstByName(ifName);
149 if (netdev == NULL) {
150 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
151 return HDF_FAILURE;
152 }
153
154 ret = CancelRemainOnChannel(netdev);
155 if (ret != HDF_SUCCESS) {
156 HDF_LOGE("%s: fail to cancel remain on channel,%d", __func__, ret);
157 } else {
158 HDF_LOGD("%s: cancel remain on channel success!", __func__);
159 }
160 return ret;
161 }
162
AddIf(struct NetDevice * netdev,WifiIfAdd * ifAdd)163 static int32_t AddIf(struct NetDevice *netdev, WifiIfAdd *ifAdd)
164 {
165 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
166 if (chipDriver == NULL) {
167 HDF_LOGE("%s:bad net device found!", __func__);
168 return HDF_FAILURE;
169 }
170
171 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, AddIf);
172 return chipDriver->p2pOps->AddIf(netdev, ifAdd);
173 }
174
WifiCmdAddIf(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)175 static int32_t WifiCmdAddIf(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
176 {
177 int32_t ret;
178 struct NetDevice *netdev = NULL;
179 const char *ifName = NULL;
180 WifiIfAdd *ifAdd = NULL;
181 uint32_t dataSize = 0;
182
183 (void)context;
184 if (reqData == NULL || rspData == NULL) {
185 HDF_LOGE("%s: input parameter invalid!", __func__);
186 return HDF_ERR_INVALID_PARAM;
187 }
188 ifName = HdfSbufReadString(reqData);
189 if (ifName == NULL) {
190 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
191 return HDF_FAILURE;
192 }
193 netdev = NetDeviceGetInstByName(ifName);
194 if (netdev == NULL) {
195 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
196 return HDF_FAILURE;
197 }
198
199 if (!HdfSbufReadBuffer(reqData, (const void **)&(ifAdd), &dataSize) || dataSize != sizeof(WifiIfAdd)) {
200 HDF_LOGE("%s: %s!ParamName=%s,readSize=%u", __func__, ERROR_DESC_READ_REQ_FAILED, "ifAdd", dataSize);
201 return HDF_FAILURE;
202 }
203
204 ret = AddIf(netdev, ifAdd);
205 if (ret != HDF_SUCCESS) {
206 HDF_LOGE("%s: fail to add p2p device, ret=%d", __func__, ret);
207 } else {
208 HDF_LOGI("%s: add p2p device success! ifAdd->ifName=%s", __func__, ifAdd->ifName);
209 }
210 return ret;
211 }
212
RemoveIf(struct NetDevice * netdev,WifiIfRemove * ifRemove)213 static int32_t RemoveIf(struct NetDevice *netdev, WifiIfRemove *ifRemove)
214 {
215 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
216 if (chipDriver == NULL) {
217 HDF_LOGE("%s:bad net device found!", __func__);
218 return HDF_FAILURE;
219 }
220
221 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, RemoveIf);
222 return chipDriver->p2pOps->RemoveIf(netdev, ifRemove);
223 }
224
WifiCmdRemoveIf(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)225 static int32_t WifiCmdRemoveIf(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
226 {
227 int32_t ret;
228 struct NetDevice *netdev = NULL;
229 const char *ifName = NULL;
230 WifiIfRemove *ifRemove = NULL;
231 uint32_t dataSize;
232 (void)context;
233 if (reqData == NULL || rspData == NULL) {
234 HDF_LOGE("%s: input parameter invalid!", __func__);
235 return HDF_ERR_INVALID_PARAM;
236 }
237 ifName = HdfSbufReadString(reqData);
238 if (ifName == NULL) {
239 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
240 return HDF_FAILURE;
241 }
242 netdev = NetDeviceGetInstByName(ifName);
243 if (netdev == NULL) {
244 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
245 return HDF_FAILURE;
246 }
247
248 dataSize = 0;
249 if (!HdfSbufReadBuffer(reqData, (const void **)&(ifRemove), &dataSize) || dataSize != sizeof(WifiIfRemove)) {
250 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifRemove");
251 return HDF_FAILURE;
252 }
253 ret = RemoveIf(netdev, ifRemove);
254 if (ret != HDF_SUCCESS) {
255 HDF_LOGE("%s: fail to remove interface,%d", __func__, ret);
256 } else {
257 HDF_LOGI("%s: remove p2p device success! remove ifName=%s", __func__, ifRemove->ifName);
258 }
259 return ret;
260 }
261
SetApWpsP2pIe(struct NetDevice * netdev,WifiAppIe * appIe)262 static int32_t SetApWpsP2pIe(struct NetDevice *netdev, WifiAppIe *appIe)
263 {
264 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
265 if (chipDriver == NULL) {
266 HDF_LOGE("%s:bad net device found!", __func__);
267 return HDF_FAILURE;
268 }
269
270 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, SetApWpsP2pIe);
271 return chipDriver->p2pOps->SetApWpsP2pIe(netdev, appIe);
272 }
273
WifiCmdSetApWpsP2pIe(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)274 static int32_t WifiCmdSetApWpsP2pIe(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
275 {
276 int32_t ret;
277 struct NetDevice *netdev = NULL;
278 const char *ifName = NULL;
279 WifiAppIe appIe = {0};
280
281 (void)context;
282 if (reqData == NULL || rspData == NULL) {
283 HDF_LOGE("%s: input parameter invalid!", __func__);
284 return HDF_ERR_INVALID_PARAM;
285 }
286 ifName = HdfSbufReadString(reqData);
287 if (ifName == NULL) {
288 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
289 return HDF_FAILURE;
290 }
291 netdev = NetDeviceGetInstByName(ifName);
292 if (netdev == NULL) {
293 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
294 return HDF_FAILURE;
295 }
296
297 if (!HdfSbufReadUint32(reqData, &(appIe.ieLen))) {
298 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ieLen");
299 return HDF_FAILURE;
300 }
301 if (!HdfSbufReadUint8(reqData, &(appIe.appIeType))) {
302 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "appIeType");
303 return HDF_FAILURE;
304 }
305 if (!HdfSbufReadBuffer(reqData, (const void**)&(appIe.ie), &(appIe.ieLen))) {
306 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "appIe.ie");
307 return HDF_FAILURE;
308 }
309 ret = SetApWpsP2pIe(netdev, &appIe);
310 if (ret != HDF_SUCCESS) {
311 HDF_LOGE("%s: fail to setapwpsp2pie,%d", __func__, ret);
312 } else {
313 HDF_LOGD("%s: SetApWpsP2pIe success! appIeType=%d", __func__, appIe.appIeType);
314 }
315 return ret;
316 }
317
GetDriverFlag(struct NetDevice * netdev,WifiGetDrvFlags ** params)318 int32_t GetDriverFlag(struct NetDevice *netdev, WifiGetDrvFlags **params)
319 {
320 struct HdfChipDriver *chipDriver = GetChipDriver(netdev);
321 if (chipDriver == NULL) {
322 HDF_LOGE("%s:bad net device found!", __func__);
323 return HDF_FAILURE;
324 }
325
326 RETURN_IF_CHIPOPS_NOT_IMPLEMENT(chipDriver->p2pOps, GetDriverFlag);
327 return chipDriver->p2pOps->GetDriverFlag(netdev, params);
328 }
329
WifiCmdGetDriverFlag(const RequestContext * context,struct HdfSBuf * reqData,struct HdfSBuf * rspData)330 static int32_t WifiCmdGetDriverFlag(const RequestContext *context, struct HdfSBuf *reqData, struct HdfSBuf *rspData)
331 {
332 int32_t ret;
333 struct NetDevice *netdev = NULL;
334 const char *ifName = NULL;
335 WifiGetDrvFlags *params = NULL;
336
337 (void)context;
338 if (reqData == NULL || rspData == NULL) {
339 HDF_LOGE("%s: input parameter invalid!", __func__);
340 return HDF_ERR_INVALID_PARAM;
341 }
342 ifName = HdfSbufReadString(reqData);
343 if (ifName == NULL) {
344 HDF_LOGE("%s: %s!ParamName=%s", __func__, ERROR_DESC_READ_REQ_FAILED, "ifName");
345 return HDF_FAILURE;
346 }
347 netdev = NetDeviceGetInstByName(ifName);
348 if (netdev == NULL) {
349 HDF_LOGE("%s: netdev not found!ifName=%s", __func__, ifName);
350 return HDF_FAILURE;
351 }
352
353 ret = GetDriverFlag(netdev, ¶ms);
354 if (ret != HDF_SUCCESS) {
355 HDF_LOGE("%s: fail to getdriverflag,%d", __func__, ret);
356 return HDF_FAILURE;
357 }
358
359 if (!HdfSbufWriteUint64(rspData, params->drvFlags)) {
360 HDF_LOGE("%s:%s!", __func__, ERROR_DESC_WRITE_RSP_FAILED);
361 ret = HDF_ERR_IO;
362 }
363
364 HDF_LOGI("WifiCmdGetDriverFlag:%llx", params->drvFlags);
365 OsalMemFree(params);
366 return ret;
367 }
368
369 static struct MessageDef g_wifiP2pFeatureCmds[] = {
370 DUEMessage(CMD_P2P_PROBE_REQ_REPORT, WifiCmdProbeReqReport, 0),
371 DUEMessage(CMD_P2P_REMAIN_ON_CHANNEL, WifiCmdRemainOnChannel, 0),
372 DUEMessage(CMD_P2P_CANCEL_REMAIN_ON_CHANNEL, WifiCmdCancelRemainOnChannel, 0),
373 DUEMessage(CMD_P2P_ADD_IF, WifiCmdAddIf, 0),
374 DUEMessage(CMD_P2P_REMOVE_IF, WifiCmdRemoveIf, 0),
375 DUEMessage(CMD_P2P_SET_AP_WPS_P2P_IE, WifiCmdSetApWpsP2pIe, 0),
376 DUEMessage(CMD_P2P_GET_DRIVER_FLAGS, WifiCmdGetDriverFlag, 0),
377 };
378 ServiceDefine(P2PService, P2P_SERVICE_ID, g_wifiP2pFeatureCmds);
379
380 static Service *g_p2pService = NULL;
381
P2pInit(struct WifiFeature * feature)382 static int32_t P2pInit(struct WifiFeature *feature)
383 {
384 (void)feature;
385 if (g_p2pService == NULL) {
386 ServiceCfg cfg = {
387 .dispatcherId = DEFAULT_DISPATCHER_ID
388 };
389 g_p2pService = CreateService(P2PService, &cfg);
390 if (g_p2pService == NULL) {
391 return HDF_FAILURE;
392 }
393 }
394 return HDF_SUCCESS;
395 }
396
P2pDeinit(struct WifiFeature * feature)397 static int32_t P2pDeinit(struct WifiFeature *feature)
398 {
399 (void)feature;
400 if (g_p2pService != NULL && g_p2pService->Destroy != NULL) {
401 g_p2pService->Destroy(g_p2pService);
402 g_p2pService = NULL;
403 }
404 return HDF_SUCCESS;
405 }
406
407 struct WifiFeature g_wifiP2PFeature = {
408 .name = "p2p",
409 .init = P2pInit,
410 .deInit = P2pDeinit
411 };
412
GetWifiP2pFeature(void)413 struct WifiFeature *GetWifiP2pFeature(void)
414 {
415 return &g_wifiP2PFeature;
416 }
417
418 #ifdef __cplusplus
419 }
420 #endif
421