• 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 "hdi_wpa_hal.h"
17 
18 #include <poll.h>
19 #include <unistd.h>
20 #include <hdf_log.h>
21 #include <pthread.h>
22 
23 #include "wpa_common_cmd.h"
24 #include "ethernet_eap_client.h"
25 #include "common/wpa_ctrl.h"
26 #include "securec.h"
27 
28 #ifdef LOG_TAG
29 #undef LOG_TAG
30 #endif
31 #define LOG_TAG "EthHdiWpaHal"
32 #ifdef LOG_DOMAIN
33 #undef LOG_DOMAIN
34 #endif
35 #define LOG_DOMAIN 0xD0015b0
36 
37 #define WPA_TRY_CONNECT_TIMES 20
38 #define WPA_TRY_CONNECT_SLEEP_TIME (100 * 1000) /* 100ms */
39 #define WPA_CMD_BUF_LEN 256
40 #define WPA_CMD_REPLY_BUF_LEN 64
41 #define CMD_BUFFER_SIZE 2148
42 #define MAX_NAME_LEN 12
43 #define REPLY_BUF_LENGTH (4096 * 10)
44 #define REPLY_BUF_SMALL_LENGTH 64
45 #define REPLY_BUF_STA_INFO_LENGTH 2048
46 #define CMD_BUFFER_MIN_SIZE 15
47 
48 static EthWpaInstance *g_wpaInstance = NULL;
49 
GetEthWpaInsCtrl(void)50 static WpaCtrl *GetEthWpaInsCtrl(void)
51 {
52     if (g_wpaInstance == NULL) {
53         HDF_LOGE("GetEthWpaInsCtrl g_wpaInstance = NULL!");
54         return NULL;
55     }
56     return &g_wpaInstance->staCtrl;
57 }
58 
InitWpaCtrl(WpaCtrl * pCtrl,const char * ctrlPath)59 int InitWpaCtrl(WpaCtrl *pCtrl, const char *ctrlPath)
60 {
61     if (pCtrl == NULL || ctrlPath == NULL) {
62         return -1;
63     }
64     pCtrl->pSend = wpa_ctrl_open(ctrlPath);
65     if (pCtrl->pSend == NULL) {
66         HDF_LOGE("open wpa control send interface failed!");
67         ReleaseWpaCtrl(pCtrl);
68         return -1;
69     }
70     return 0;
71 }
72 
ReleaseWpaCtrl(WpaCtrl * pCtrl)73 void ReleaseWpaCtrl(WpaCtrl *pCtrl)
74 {
75     if (pCtrl == NULL) {
76         return;
77     }
78     if (pCtrl->pSend != NULL) {
79         wpa_ctrl_close(pCtrl->pSend);
80         pCtrl->pSend = NULL;
81     }
82     if (pCtrl->pRecv != NULL) {
83         wpa_ctrl_close(pCtrl->pRecv);
84         pCtrl->pRecv = NULL;
85     }
86 }
87 
StaCliCmd(WpaCtrl * ctrl,const char * cmd,char * buf,size_t bufLen)88 static int StaCliCmd(WpaCtrl *ctrl, const char *cmd, char *buf, size_t bufLen)
89 {
90     HDF_LOGI("enter StaCliCmd");
91     if (ctrl == NULL || ctrl->pSend == NULL || cmd == NULL || buf == NULL || bufLen == 0) {
92         HDF_LOGE("StaCliCmd, invalid param");
93         return -1;
94     }
95     size_t len = bufLen - 1;
96     HDF_LOGI("wpa_ctrl_request -> cmd: %{public}s", cmd);
97     int ret = wpa_ctrl_request(ctrl->pSend, cmd, strlen(cmd), buf, &len, NULL);
98     if (ret < 0) {
99         HDF_LOGE("[%{public}s] command failed.", cmd);
100         return -1;
101     }
102     buf[len] = '\0';
103     HDF_LOGI("wpa_ctrl_request -> buf: %{public}s", buf);
104     if (strncmp(buf, "FAIL\n", strlen("FAIL\n")) == 0 ||
105         strncmp(buf, "UNKNOWN COMMAND\n", strlen("UNKNOWN COMMAND\n")) == 0) {
106         HDF_LOGE("%{public}s request success, but response %{public}s", cmd, buf);
107         return -1;
108     }
109     return 0;
110 }
111 
WpaCliCmd(const char * cmd,char * buf,size_t bufLen)112 int WpaCliCmd(const char *cmd, char *buf, size_t bufLen)
113 {
114     int ret = -1;
115     HDF_LOGI("enter WpaCliCmd");
116     if (cmd == NULL || buf == NULL || bufLen == 0) {
117         HDF_LOGE("WpaCliCmd, invalid parameters!");
118         return ret;
119     }
120     ret = StaCliCmd(GetEthWpaInsCtrl(), cmd, buf, bufLen);
121     return ret;
122 }
123 
WpaCliConnect(EthWpaInstance * p)124 static int WpaCliConnect(EthWpaInstance *p)
125 {
126     HDF_LOGI("Wpa connect start.");
127     if (p == NULL) {
128         HDF_LOGE("Wpa connect parameter error.");
129         return -1;
130     }
131     if (p->staCtrl.pSend != NULL) {
132         HDF_LOGE("Wpa is already connected.");
133         return 0;
134     }
135     int count = WPA_TRY_CONNECT_TIMES;
136     char *ctrlPath = WPA_CTRL_OPEN_IFNAME;
137     while (count-- > 0) {
138         if (!InitWpaCtrl(&p->staCtrl, ctrlPath)) {
139             HDF_LOGI("Global wpa interface connect successfully!");
140             break;
141         } else {
142             HDF_LOGE("Init wpaCtrl failed.");
143         }
144         usleep(WPA_TRY_CONNECT_SLEEP_TIME);
145     }
146     if (count <= 0) {
147         return -1;
148     }
149     HDF_LOGI("Wpa connect finish.");
150     return 0;
151 }
152 
WpaCliClose(EthWpaInstance * p)153 static void WpaCliClose(EthWpaInstance *p)
154 {
155     HDF_LOGI("Wpa connect close.");
156     if (p->tid != 0) {
157         pthread_join(p->tid, NULL);
158         p->tid = 0;
159     }
160     ReleaseWpaCtrl(&p->staCtrl);
161     return;
162 }
163 
WpaCliTerminate(void)164 static int WpaCliTerminate(void)
165 {
166     HDF_LOGI("enter WpaCliTerminate.");
167     char cmd[WPA_CMD_BUF_LEN] = {0};
168     char buf[WPA_CMD_REPLY_BUF_LEN] = {0};
169     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "TERMINATE") < 0) {
170         HDF_LOGE("WpaCliTerminate, snprintf err");
171         return -1;
172     }
173     return WpaCliCmd(cmd, buf, sizeof(buf));
174 }
175 
WpaCliCmdSetNetwork(EthWpaInstance * p,const char * ifName,const char * name,const char * value)176 static int WpaCliCmdSetNetwork(EthWpaInstance *p, const char *ifName, const char *name, const char *value)
177 {
178     char cmd[CMD_BUFFER_SIZE] = {0};
179     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
180     int res = snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s SET_NETWORK %d %s %s", ifName,
181         0, name, value);
182     HDF_LOGI("%{public}s cmd= %{private}s", __func__, cmd);
183     if (res < 0) {
184         HDF_LOGE("%{public}s Internal error, set request message failed!", __func__);
185         return -1;
186     }
187     return WpaCliCmd(cmd, buf, sizeof(buf));
188 }
189 
WpaCliCmdStaShellCmd(EthWpaInstance * p,const char * ifName,const char * params)190 static int WpaCliCmdStaShellCmd(EthWpaInstance *p, const char *ifName, const char *params)
191 {
192     if (params == NULL) {
193         return -1;
194     }
195     char cmd[CMD_BUFFER_SIZE] = {0};
196     char buf[REPLY_BUF_SMALL_LENGTH] = {0};
197     if (snprintf_s(cmd, sizeof(cmd), sizeof(cmd) - 1, "IFNAME=%s STA_SHELL %s", ifName, params) < 0) {
198         HDF_LOGE("WpaCliCmdStaShellCmd, snprintf_s err");
199         return -1;
200     }
201     return WpaCliCmd(cmd, buf, sizeof(buf));
202 }
203 
InitEthWpaGlobalInstance(void)204 void InitEthWpaGlobalInstance(void)
205 {
206     HDF_LOGI("enter InitEthWpaGlobalInstance.");
207     if (g_wpaInstance != NULL) {
208         return;
209     }
210     g_wpaInstance = (EthWpaInstance *)calloc(1, sizeof(EthWpaInstance));
211     if (g_wpaInstance == NULL) {
212         HDF_LOGE("Failed to create wpa interface!");
213         return;
214     }
215     g_wpaInstance->wpaCliConnect = WpaCliConnect;
216     g_wpaInstance->wpaCliClose = WpaCliClose;
217     g_wpaInstance->wpaCliTerminate = WpaCliTerminate;
218     g_wpaInstance->wpaCliCmdSetNetwork = WpaCliCmdSetNetwork;
219     g_wpaInstance->wpaCliCmdStaShellCmd = WpaCliCmdStaShellCmd;
220 }
221 
GetEthWpaGlobalInstance(void)222 EthWpaInstance *GetEthWpaGlobalInstance(void)
223 {
224     return g_wpaInstance;
225 }
226 
ReleaseEthWpaGlobalInstance(void)227 void ReleaseEthWpaGlobalInstance(void)
228 {
229     HDF_LOGI("enter ReleaseEthWpaGlobalInstance.");
230     if (g_wpaInstance == NULL) {
231         return;
232     }
233     WpaCliClose(g_wpaInstance);
234     free(g_wpaInstance);
235     g_wpaInstance = NULL;
236 }
237