1  /*
2   * Copyright (c) 2021-2023 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 <net/if.h>
17  #include <arpa/inet.h>
18  #include <dirent.h>
19  #include <netlink-private/types.h>
20  #include <netlink/genl/ctrl.h>
21  #include <netlink/genl/genl.h>
22  #include <netlink/handlers.h>
23  #include <securec.h>
24  #include <stdbool.h>
25  #include <stdio.h>
26  #include <sys/ioctl.h>
27  #include <sys/socket.h>
28  #include <sys/time.h>
29  #include <sys/types.h>
30  #include <unistd.h>
31  #include <linux/ethtool.h>
32  #include <linux/if_arp.h>
33  #include <linux/netlink.h>
34  #include <linux/nl80211.h>
35  #include <linux/sockios.h>
36  #include <linux/wireless.h>
37  #include <linux/version.h>
38  #include <osal_mem.h>
39  
40  #include "../wifi_common_cmd.h"
41  #include "hilog/log.h"
42  #include "netlink_adapter.h"
43  #include "hdf_dlist.h"
44  #include "parameter.h"
45  
46  #define VENDOR_ID 0x001A11
47  
48  // vendor subcmd
49  #define WIFI_SUBCMD_SET_COUNTRY_CODE   0x100E
50  #define WIFI_SUBCMD_SET_RANDOM_MAC_OUI 0x100C
51  
52  #define WAITFORMUTEX  100000
53  #define WAITFORTHREAD 100000
54  #define WAITFORSEND   5000
55  #define RETRIES       30
56  
57  #define STR_WLAN0     "wlan0"
58  #define STR_WLAN1     "wlan1"
59  #define STR_P2P0      "p2p0"
60  #define STR_P2P0_X    "p2p0-"
61  #define STR_CHBA      "chba0"
62  #define NET_DEVICE_INFO_PATH "/sys/class/net"
63  
64  #define PRIMARY_ID_POWER_MODE   0x8bfd
65  #define SECONDARY_ID_POWER_MODE 0x101
66  #define SET_POWER_MODE_SLEEP     "pow_mode sleep"
67  #define SET_POWER_MODE_INIT      "pow_mode init"
68  #define SET_POWER_MODE_THIRD     "pow_mode third"
69  #define GET_POWER_MODE           "get_pow_mode"
70  
71  #define CMD_SET_CLOSE_GO_CAC      "SET_CLOSE_GO_CAC"
72  #define CMD_SET_CHANGE_GO_CHANNEL "CMD_SET_CHANGE_GO_CHANNEL"
73  #define CMD_SET_GO_DETECT_RADAR   "CMD_SET_GO_DETECT_RADAR"
74  #define CMD_SET_DYNAMIC_DBAC_MODE "SET_DYNAMIC_DBAC_MODE"
75  #define CMD_SET_P2P_SCENES        "CMD_SET_P2P_SCENES"
76  #define CMD_GET_AP_BANDWIDTH      "GET_AP_BANDWIDTH"
77  #define CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL "RX_MGMT_REMAIN_ON_CHANNEL"
78  #define CMD_SET_STA_PM_ON        "SET_STA_PM_ON"
79  
80  #define P2P_BUF_SIZE              64
81  #define MAX_PRIV_CMD_SIZE         4096
82  #define LOW_LITMIT_FREQ_2_4G      2400
83  #define HIGH_LIMIT_FREQ_2_4G      2500
84  #define LOW_LIMIT_FREQ_5G         5100
85  #define HIGH_LIMIT_FREQ_5G        5900
86  #define INTERFACE_UP              0x1 /* interface is up */
87  #define MAX_INTERFACE_NAME_SIZE   16
88  #define MAX_CMD_LEN               64
89  #define DPI_MSG_LEN               4
90  #define NETLINK_HW_DPI            25
91  #define TP_TYPE_TCP               6
92  #define TP_TYPE_UDP               17
93  #define WZRY_MARK_NUM             0x5a
94  
95  #define INSTALL_WLAN_HEAD_LEN 2
96  #define SUITE_INDEX_1 1
97  #define SUITE_INDEX_2 2
98  #define SUITE_INDEX_3 3
99  #define SUITE_LEFT_LEN_24 24
100  #define SUITE_LEFT_LEN_16 16
101  #define SUITE_LEFT_LEN_8 8
102  
BIT(uint8_t x)103  static inline uint32_t BIT(uint8_t x)
104  {
105      return 1U << x;
106  }
107  #define STA_DRV_DATA_TX_MCS BIT(0)
108  #define STA_DRV_DATA_RX_MCS BIT(1)
109  #define STA_DRV_DATA_TX_VHT_MCS BIT(2)
110  #define STA_DRV_DATA_RX_VHT_MCS BIT(3)
111  #define STA_DRV_DATA_TX_VHT_NSS BIT(4)
112  #define STA_DRV_DATA_RX_VHT_NSS BIT(5)
113  #define STA_DRV_DATA_TX_SHORT_GI BIT(6)
114  #define STA_DRV_DATA_RX_SHORT_GI BIT(7)
115  #define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
116  
117  #define WLAN_IFACE_LENGTH 4
118  #define P2P_IFACE_LENGTH 3
119  #define CHBA_IFACE_LENGTH 4
120  #ifndef KERNEL_VERSION
121  #define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + ((c) > 255 ? 255 : (c)))
122  #endif
123  
124  #define SUBCHIP_WIFI_PROP "ohos.boot.odm.conn.schiptype"
125  #define SUPPORT_COEXCHIP ""
126  #define SUBCHIP_WIFI_PROP_LEN 10
127  #define SUPPORT_COEXCHIP_LEN 7
128  
129  #define NETLINK_CAP_ACK 10
130  #define NETLINK_EXT_ACK 11
131  #define SOL_NETLINK 270
132  #define RECV_MAX_COUNT 100
133  #define NETLINK_BUFF_LENGTH 262144
134  
135  // vendor attr
136  enum AndrWifiAttr {
137  #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
138      WIFI_ATTRIBUTE_INVALID,
139  #endif
140      WIFI_ATTRIBUTE_NUM_FEATURE_SET,
141      WIFI_ATTRIBUTE_FEATURE_SET,
142      WIFI_ATTRIBUTE_RANDOM_MAC_OUI,
143      WIFI_ATTRIBUTE_NODFS_SET,
144      WIFI_ATTRIBUTE_COUNTRY
145  };
146  
147  struct FamilyData {
148      const char *group;
149      int32_t id;
150  };
151  
152  struct WifiHalInfo {
153      struct nl_sock *cmdSock;
154      struct nl_sock *eventSock;
155      struct nl_sock *ctrlSock;
156      int32_t familyId;
157  
158      // thread controller info
159      pthread_t thread;
160      enum ThreadStatus status;
161      pthread_mutex_t mutex;
162  };
163  
164  typedef struct {
165      void *buf;
166      uint16_t length;
167      uint16_t flags;
168  } DataPoint;
169  
170  union HwprivReqData {
171      char name[IFNAMSIZ];
172      int32_t mode;
173      DataPoint point;
174  };
175  
176  typedef struct {
177      char interfaceName[IFNAMSIZ];
178      union HwprivReqData data;
179  } HwprivIoctlData;
180  
181  typedef struct {
182  #if (defined(LINUX_VERSION_CODE) && LINUX_VERSION_CODE >= KERNEL_VERSION(5, 4, 0))
183      uint8_t *buf;
184      uint32_t size;
185      uint32_t len;
186  #else
187      uint32_t size;
188      uint32_t len;
189      uint8_t *buf;
190  #endif
191  } WifiPrivCmd;
192  
193  #define SLOW_SCAN_INTERVAL_MULTIPLIER 3
194  #define FAST_SCAN_ITERATIONS 3
195  #define BITNUMS_OF_ONE_BYTE 8
196  #define SCHED_SCAN_PLANS_ATTR_INDEX1 1
197  #define SCHED_SCAN_PLANS_ATTR_INDEX2 2
198  #define MS_PER_SECOND 1000
199  
200  typedef struct {
201      uint8_t maxNumScanSsids;
202      uint8_t maxNumSchedScanSsids;
203      uint8_t maxMatchSets;
204      uint32_t maxNumScanPlans;
205      uint32_t maxScanPlanInterval;
206      uint32_t maxScanPlanIterations;
207  } ScanCapabilities;
208  
209  typedef struct {
210      bool supportsRandomMacSchedScan;
211      bool supportsLowPowerOneshotScan;
212      bool supportsExtSchedScanRelativeRssi;
213  } WiphyFeatures;
214  
215  typedef struct {
216      ScanCapabilities scanCapabilities;
217      WiphyFeatures wiphyFeatures;
218  } WiphyInfo;
219  
220  struct SsidListNode {
221      WifiDriverScanSsid ssidInfo;
222      struct DListHead entry;
223  };
224  
225  struct FreqListNode {
226      int32_t freq;
227      struct DListHead entry;
228  };
229  
230  struct HwCommMsgT {
231      struct nlmsghdr hdr;
232      int opt;
233      char data[1];
234  };
235  
236  typedef enum {
237      DMR_MT_BEGIN = 0,
238      DMR_MT_TP, /* matching transport protocol */
239      DMR_MT_END,
240  }DmrMatchTypeT;
241  
242  /* DPI rule format */
243  typedef struct {
244      DmrMatchTypeT ruleType;
245      /* ruleBody varies according to ruleType */
246      union {
247          uint8_t matchTpVal;
248      } ruleBody;
249      uint32_t markNum;
250  } DpiRuleT;
251  
252  typedef struct {
253      uint32_t dmrAppUid;
254      uint32_t dmrMplkNetid;
255      uint32_t dmrMplkStrategy;
256      DpiRuleT dmrRule;
257  } DpiMarkRuleT;
258  
259  typedef enum {
260      NETLINK_REG_TO_KERNEL = 0,
261      NETLINK_UNREG_TO_KERNEL,
262      NETLINK_CMD_TO_KERNEL,
263      NETLINK_SET_RULE_TO_KERNEL,
264      NETLINK_STOP_MARK,
265      NETLINK_START_MARK,
266      NETLINK_MPLK_BIND_NETWORK,
267      NETLINK_MPLK_UNBIND_NETWORK,
268      NETLINK_MPLK_RESET_SOCKET,
269      NETLINK_MPLK_CLOSE_SOCKET,
270      NETLINK_HID2D_TYPE,
271      NETLINK_DEL_RULE_TO_KERNEL,
272      NETLINK_SET_RULE_TO_KERNEL_EX,
273      NETLINK_SET_TCP_RECOVER_TO_KERNEL,
274  } NtlCmdTypeT;
275  
276  static struct WifiHalInfo g_wifiHalInfo = {0};
277  
278  static int32_t GetWiphyInfo(const uint32_t wiphyIndex, WiphyInfo *wiphyInfo);
279  static int32_t GetWiphyIndex(const char *ifName, uint32_t *wiphyIndex);
280  
281  static uint32_t g_cookieStart = 0;
282  static uint32_t g_cookieSucess = 0;
283  
OpenNetlinkSocket(void)284  static struct nl_sock *OpenNetlinkSocket(void)
285  {
286      struct nl_sock *sock = NULL;
287  
288      sock = nl_socket_alloc();
289      if (sock == NULL) {
290          HILOG_ERROR(LOG_CORE, "%s: fail to alloc socket", __FUNCTION__);
291          return NULL;
292      }
293  
294      if (nl_connect(sock, NETLINK_GENERIC) != 0) {
295          HILOG_ERROR(LOG_CORE, "%s: fail to connect socket", __FUNCTION__);
296          nl_socket_free(sock);
297          return NULL;
298      }
299  
300      return sock;
301  }
302  
CloseNetlinkSocket(struct nl_sock * sock)303  static void CloseNetlinkSocket(struct nl_sock *sock)
304  {
305      if (sock != NULL) {
306          nl_socket_free(sock);
307      }
308  }
309  
ConnectCmdSocket(void)310  static int32_t ConnectCmdSocket(void)
311  {
312      g_wifiHalInfo.cmdSock = OpenNetlinkSocket();
313      if (g_wifiHalInfo.cmdSock == NULL) {
314          HILOG_ERROR(LOG_CORE, "%s: fail to open cmd socket", __FUNCTION__);
315          return RET_CODE_FAILURE;
316      }
317  
318      nl_socket_disable_seq_check(g_wifiHalInfo.cmdSock);
319      // send find familyId result to Controller
320      g_wifiHalInfo.familyId = genl_ctrl_resolve(g_wifiHalInfo.cmdSock, NL80211_GENL_NAME);
321      if (g_wifiHalInfo.familyId < 0) {
322          HILOG_ERROR(LOG_CORE, "%s: fail to resolve family", __FUNCTION__);
323          CloseNetlinkSocket(g_wifiHalInfo.cmdSock);
324          g_wifiHalInfo.cmdSock = NULL;
325          return RET_CODE_FAILURE;
326      }
327      HILOG_INFO(LOG_CORE, "%s: family id: %d", __FUNCTION__, g_wifiHalInfo.familyId);
328      return RET_CODE_SUCCESS;
329  }
330  
DisconnectCmdSocket(void)331  static void DisconnectCmdSocket(void)
332  {
333      CloseNetlinkSocket(g_wifiHalInfo.cmdSock);
334      g_wifiHalInfo.cmdSock = NULL;
335  }
336  
ConnectCtrlSocket(void)337  static int32_t ConnectCtrlSocket(void)
338  {
339      g_wifiHalInfo.ctrlSock = OpenNetlinkSocket();
340      if (g_wifiHalInfo.ctrlSock == NULL) {
341          HILOG_ERROR(LOG_CORE, "%s: fail to open ctrl socket", __FUNCTION__);
342          return RET_CODE_FAILURE;
343      }
344  
345      if (nl_socket_set_buffer_size(g_wifiHalInfo.ctrlSock, NETLINK_BUFF_LENGTH, 0) < 0) {
346          HILOG_ERROR(LOG_CORE, "%s: fail to set buffer size", __FUNCTION__);
347      }
348  
349      if (nl_socket_set_nonblocking(g_wifiHalInfo.ctrlSock) != 0) {
350          HILOG_ERROR(LOG_CORE, "%s: fail to set nonblocking socket", __FUNCTION__);
351          CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
352          g_wifiHalInfo.ctrlSock = NULL;
353          return RET_CODE_FAILURE;
354      }
355  
356      // send find familyId result to Controller
357      g_wifiHalInfo.familyId = genl_ctrl_resolve(g_wifiHalInfo.ctrlSock, NL80211_GENL_NAME);
358      if (g_wifiHalInfo.familyId < 0) {
359          HILOG_ERROR(LOG_CORE, "%s: fail to resolve family", __FUNCTION__);
360          CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
361          g_wifiHalInfo.ctrlSock = NULL;
362          return RET_CODE_FAILURE;
363      }
364      HILOG_INFO(LOG_CORE, "%s: family id: %d", __FUNCTION__, g_wifiHalInfo.familyId);
365      return RET_CODE_SUCCESS;
366  }
367  
DisconnectCtrlSocket(void)368  static void DisconnectCtrlSocket(void)
369  {
370      CloseNetlinkSocket(g_wifiHalInfo.ctrlSock);
371      g_wifiHalInfo.ctrlSock = NULL;
372  }
373  
CmdSocketErrorHandler(struct sockaddr_nl * nla,struct nlmsgerr * err,void * arg)374  static int32_t CmdSocketErrorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
375  {
376      int32_t *ret = (int32_t *)arg;
377  
378      *ret = err->error;
379      return NL_SKIP;
380  }
381  
CmdSocketFinishHandler(struct nl_msg * msg,void * arg)382  static int32_t CmdSocketFinishHandler(struct nl_msg *msg, void *arg)
383  {
384      int32_t *ret = (int32_t *)arg;
385  
386      *ret = 0;
387      return NL_SKIP;
388  }
389  
CmdSocketAckHandler(struct nl_msg * msg,void * arg)390  static int32_t CmdSocketAckHandler(struct nl_msg *msg, void *arg)
391  {
392      int32_t *err = (int32_t *)arg;
393  
394      *err = 0;
395      return NL_STOP;
396  }
397  
NetlinkSetCallback(const RespHandler handler,int32_t * error,void * data)398  static struct nl_cb *NetlinkSetCallback(const RespHandler handler, int32_t *error, void *data)
399  {
400      struct nl_cb *cb = NULL;
401  
402      cb = nl_cb_alloc(NL_CB_DEFAULT);
403      if (cb == NULL) {
404          HILOG_ERROR(LOG_CORE, "%s: nl_cb_alloc failed", __FUNCTION__);
405          return NULL;
406      }
407      nl_cb_err(cb, NL_CB_CUSTOM, CmdSocketErrorHandler, error);
408      nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, CmdSocketFinishHandler, error);
409      nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, CmdSocketAckHandler, error);
410      if (handler != NULL) {
411          nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, handler, data);
412      }
413      return cb;
414  }
415  
PthreadMutexLock(void)416  static int32_t PthreadMutexLock(void)
417  {
418      int32_t rc;
419      int32_t count = 0;
420  
421      while ((rc = pthread_mutex_trylock(&g_wifiHalInfo.mutex)) == EBUSY) {
422          if (count < RETRIES) {
423              HILOG_ERROR(LOG_CORE, "%s: pthread b trylock", __FUNCTION__);
424              count++;
425              usleep(WAITFORMUTEX);
426          } else {
427              HILOG_ERROR(LOG_CORE, "%s: pthread trylock timeout", __FUNCTION__);
428              return RET_CODE_FAILURE;
429          }
430      }
431      return rc;
432  }
433  
WaitStartActionLock(void)434  static int32_t WaitStartActionLock(void)
435  {
436      int32_t count = 0;
437      while (g_cookieStart == 0) {
438          if (count < RETRIES) {
439              HILOG_DEBUG(LOG_CORE, "%{public}s: wait g_cookieStart %{public}d 5ms",
440                  __FUNCTION__, count);
441              count++;
442              usleep(WAITFORSEND);
443          } else {
444              HILOG_ERROR(LOG_CORE, "%{public}s: wait g_cookieStart timeout", __FUNCTION__);
445              return RET_CODE_FAILURE;
446          }
447      }
448      if (count > 0) {
449          HILOG_DEBUG(LOG_CORE, "%{public}s: Guaranteed Send Return", __FUNCTION__);
450          usleep(WAITFORSEND);
451      }
452      return count;
453  }
454  
NetlinkSendCmdSync(struct nl_msg * msg,const RespHandler handler,void * data)455  int32_t NetlinkSendCmdSync(struct nl_msg *msg, const RespHandler handler, void *data)
456  {
457      HILOG_DEBUG(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
458      int32_t rc = RET_CODE_FAILURE;
459      struct nl_cb *cb = NULL;
460  
461      if (g_wifiHalInfo.cmdSock == NULL) {
462          HILOG_ERROR(LOG_CORE, "%s: sock is null", __FUNCTION__);
463          return RET_CODE_INVALID_PARAM;
464      }
465  
466      if (PthreadMutexLock() != RET_CODE_SUCCESS) {
467          HILOG_ERROR(LOG_CORE, "%s: pthread trylock failed", __FUNCTION__);
468          return RET_CODE_FAILURE;
469      }
470  
471      /* try to set NETLINK_EXT_ACK to 1, ignoring errors */
472      int32_t opt = 1;
473      if (setsockopt(nl_socket_get_fd(g_wifiHalInfo.cmdSock), SOL_NETLINK, NETLINK_EXT_ACK, &opt, sizeof(opt)) < 0) {
474          HILOG_ERROR(LOG_CORE, "%s: setsockopt one failed", __FUNCTION__);
475      }
476  
477      /* try to set NETLINK_CAP_ACK to 1, ignoring errors */
478      opt = 1;
479      if (setsockopt(nl_socket_get_fd(g_wifiHalInfo.cmdSock), SOL_NETLINK, NETLINK_CAP_ACK, &opt, sizeof(opt)) < 0) {
480          HILOG_ERROR(LOG_CORE, "%s: setsockopt two failed", __FUNCTION__);
481      }
482  
483      do {
484          rc = nl_send_auto(g_wifiHalInfo.cmdSock, msg);
485          HILOG_DEBUG(LOG_CORE, "nl_send_auto cmdSock, rc=%{public}d", rc);
486          if (rc < 0) {
487              HILOG_ERROR(LOG_CORE, "%s: nl_send_auto failed", __FUNCTION__);
488              break;
489          }
490  
491          int32_t error = 1;
492          cb = NetlinkSetCallback(handler, &error, data);
493          if (cb == NULL) {
494              HILOG_ERROR(LOG_CORE, "%s: nl_cb_alloc failed", __FUNCTION__);
495              rc = RET_CODE_FAILURE;
496              break;
497          }
498  
499          /* wait for reply */
500          int32_t recv_count = 0;
501          while (error > 0) {
502              rc = nl_recvmsgs(g_wifiHalInfo.cmdSock, cb);
503              if (rc == -NLE_DUMP_INTR) {
504                  HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed: rc=%{public}d, errno=%{public}d, (%{public}s)", rc, errno,
505                      strerror(errno));
506                  error = -NLE_AGAIN;
507                  rc = RET_CODE_NOT_AVAILABLE;
508              } else if (rc < 0) {
509                  HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed: rc=%{public}d, errno=%{public}d, (%{public}s)", rc, errno,
510                      strerror(errno));
511              }
512  
513              if (rc == -NLE_NOMEM || recv_count != 0) {
514                  recv_count++;
515              }
516  
517              if (recv_count >= RECV_MAX_COUNT) {
518                  HILOG_ERROR(LOG_CORE, "nl_recvmsgs failed times overs max count!");
519                  error = -NLE_NOMEM;
520                  rc = RET_CODE_NOMEM;
521              }
522              HILOG_INFO(LOG_CORE, "nl_recvmsgs cmdSock, rc=%{public}d error=%{public}d", rc, error);
523          }
524  
525          if (error == -1) {
526              HILOG_ERROR(LOG_CORE, "%s: Netlink error", __FUNCTION__);
527              rc = RET_CODE_UNKNOW;
528          }
529          if (error == -NLE_MSGTYPE_NOSUPPORT) {
530              HILOG_ERROR(LOG_CORE, "%s: Netlink message type is not supported", __FUNCTION__);
531              rc = RET_CODE_NOT_SUPPORT;
532          }
533          if (error == -EBUSY) {
534              HILOG_ERROR(LOG_CORE, "%s: Device is busy.", __FUNCTION__);
535              rc = RET_CODE_DEVICE_BUSY;
536          }
537          nl_cb_put(cb);
538      } while (0);
539  
540      pthread_mutex_unlock(&g_wifiHalInfo.mutex);
541      HILOG_DEBUG(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
542      return rc;
543  }
544  
ParseFamilyId(struct nlattr * attr,struct FamilyData * familyData)545  static void ParseFamilyId(struct nlattr *attr, struct FamilyData *familyData)
546  {
547      struct nlattr *tmp = NULL;
548      void *data = NULL;
549      int32_t len;
550      int32_t i;
551  
552      nla_for_each_nested(tmp, attr, i) {
553          struct nlattr *attrMcastGrp[CTRL_ATTR_MCAST_GRP_MAX + 1];
554          data = nla_data(tmp);
555          len = nla_len(tmp);
556          nla_parse(attrMcastGrp, CTRL_ATTR_MCAST_GRP_MAX, data, len, NULL);
557          data = nla_data(attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME]);
558          len = nla_len(attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME]);
559          if (attrMcastGrp[CTRL_ATTR_MCAST_GRP_NAME] && attrMcastGrp[CTRL_ATTR_MCAST_GRP_ID] &&
560              strncmp((char *)data, familyData->group, len) == 0) {
561              familyData->id = (int32_t)nla_get_u32(attrMcastGrp[CTRL_ATTR_MCAST_GRP_ID]);
562          }
563      }
564  }
565  
FamilyIdHandler(struct nl_msg * msg,void * arg)566  static int32_t FamilyIdHandler(struct nl_msg *msg, void *arg)
567  {
568      struct FamilyData *familyData = (struct FamilyData *)arg;
569      struct genlmsghdr *hdr = NULL;
570      struct nlattr *attr[CTRL_ATTR_MAX + 1];
571      void *data = NULL;
572      int32_t len;
573  
574      hdr = nlmsg_data(nlmsg_hdr(msg));
575      if (hdr == NULL) {
576          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
577          return NL_SKIP;
578      }
579  
580      data = genlmsg_attrdata(hdr, 0);
581      len = genlmsg_attrlen(hdr, 0);
582      nla_parse(attr, CTRL_ATTR_MAX, data, len, NULL);
583      if (!attr[CTRL_ATTR_MCAST_GROUPS]) {
584          return NL_SKIP;
585      }
586  
587      ParseFamilyId(attr[CTRL_ATTR_MCAST_GROUPS], familyData);
588  
589      return NL_SKIP;
590  }
591  
GetMulticastId(const char * family,const char * group)592  static int32_t GetMulticastId(const char *family, const char *group)
593  {
594      struct nl_msg *msg = NULL;
595      int32_t ret;
596      static struct FamilyData familyData;
597      int32_t familyId = genl_ctrl_resolve(g_wifiHalInfo.cmdSock, "nlctrl");
598  
599      familyData.group = group;
600      familyData.id = -ENOENT;
601  
602      msg = nlmsg_alloc();
603      if (msg == NULL) {
604          HILOG_ERROR(LOG_CORE, "%s: nlmsg_alloc failed", __FUNCTION__);
605          return RET_CODE_NOMEM;
606      }
607  
608      if (!genlmsg_put(msg, 0, 0, familyId, 0, 0, CTRL_CMD_GETFAMILY, 0) ||
609          nla_put_string(msg, CTRL_ATTR_FAMILY_NAME, family)) {
610          HILOG_ERROR(LOG_CORE, "%s: put msg failed", __FUNCTION__);
611          nlmsg_free(msg);
612          return RET_CODE_FAILURE;
613      }
614  
615      ret = NetlinkSendCmdSync(msg, FamilyIdHandler, &familyData);
616      if (ret == 0) {
617          ret = familyData.id;
618      }
619      nlmsg_free(msg);
620      return ret;
621  }
622  
NlsockAddMembership(struct nl_sock * sock,const char * group)623  static int32_t NlsockAddMembership(struct nl_sock *sock, const char *group)
624  {
625      int32_t id;
626      int32_t ret;
627  
628      id = GetMulticastId(NL80211_GENL_NAME, group);
629      if (id < 0) {
630          HILOG_ERROR(LOG_CORE, "%s: get multicast id failed", __FUNCTION__);
631          return id;
632      }
633  
634      ret = nl_socket_add_membership(sock, id);
635      if (ret < 0) {
636          HILOG_ERROR(LOG_CORE, "%s: Could not add multicast membership for %d: %d (%s)", __FUNCTION__, id, ret,
637              strerror(-ret));
638          return RET_CODE_FAILURE;
639      }
640  
641      return RET_CODE_SUCCESS;
642  }
643  
ConnectEventSocket(void)644  static int32_t ConnectEventSocket(void)
645  {
646      int32_t ret;
647  
648      g_wifiHalInfo.eventSock = OpenNetlinkSocket();
649      if (g_wifiHalInfo.eventSock == NULL) {
650          HILOG_ERROR(LOG_CORE, "%s: fail to open event socket", __FUNCTION__);
651          return RET_CODE_FAILURE;
652      }
653  
654      if (nl_socket_set_nonblocking(g_wifiHalInfo.eventSock) != 0) {
655          HILOG_ERROR(LOG_CORE, "%s: fail to set nonblocking socket", __FUNCTION__);
656          CloseNetlinkSocket(g_wifiHalInfo.eventSock);
657          g_wifiHalInfo.eventSock = NULL;
658          return RET_CODE_FAILURE;
659      }
660  
661      do {
662          ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_SCAN);
663          if (ret != RET_CODE_SUCCESS) {
664              HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for scan event failed.", __FUNCTION__);
665              break;
666          }
667          ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_MLME);
668          if (ret != RET_CODE_SUCCESS) {
669              HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for mlme failed.", __FUNCTION__);
670              break;
671          }
672          ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_REG);
673          if (ret != RET_CODE_SUCCESS) {
674              HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for regulatory failed.", __FUNCTION__);
675              break;
676          }
677          ret = NlsockAddMembership(g_wifiHalInfo.eventSock, NL80211_MULTICAST_GROUP_VENDOR);
678          if (ret != RET_CODE_SUCCESS) {
679              HILOG_ERROR(LOG_CORE, "%s: nlsock add membership for vendor failed.", __FUNCTION__);
680              break;
681          }
682          return RET_CODE_SUCCESS;
683      } while (0);
684      CloseNetlinkSocket(g_wifiHalInfo.eventSock);
685      g_wifiHalInfo.eventSock = NULL;
686      return ret;
687  }
688  
DisconnectEventSocket(void)689  void DisconnectEventSocket(void)
690  {
691      CloseNetlinkSocket(g_wifiHalInfo.eventSock);
692      g_wifiHalInfo.eventSock = NULL;
693  }
694  
WifiMsgRegisterEventListener(void)695  static int32_t WifiMsgRegisterEventListener(void)
696  {
697      HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
698      int32_t rc;
699      int32_t count = 0;
700      struct WifiThreadParam threadParam;
701  
702      threadParam.eventSock = g_wifiHalInfo.eventSock;
703      threadParam.ctrlSock = g_wifiHalInfo.ctrlSock;
704      threadParam.familyId = g_wifiHalInfo.familyId;
705      threadParam.status = &g_wifiHalInfo.status;
706  
707      g_wifiHalInfo.status = THREAD_STARTING;
708      rc = pthread_create(&(g_wifiHalInfo.thread), NULL, EventThread, &threadParam);
709      if (rc != 0) {
710          HILOG_ERROR(LOG_CORE, "%s: failed create event thread", __FUNCTION__);
711          g_wifiHalInfo.status = THREAD_STOP;
712          return RET_CODE_FAILURE;
713      }
714  
715      // waiting for thread start running
716      while (g_wifiHalInfo.status != THREAD_RUN) {
717          HILOG_INFO(LOG_CORE, "%s: waiting for thread start running.", __FUNCTION__);
718          if (count < RETRIES) {
719              count++;
720              usleep(WAITFORTHREAD);
721          } else {
722              HILOG_ERROR(LOG_CORE, "%s: warit for thread running timeout", __FUNCTION__);
723              if (g_wifiHalInfo.status != THREAD_STOP) {
724                  g_wifiHalInfo.status = THREAD_STOP;
725                  pthread_join(g_wifiHalInfo.thread, NULL);
726              }
727              return RET_CODE_FAILURE;
728          }
729      }
730      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
731      return RET_CODE_SUCCESS;
732  }
733  
WifiMsgUnregisterEventListener(void)734  static void WifiMsgUnregisterEventListener(void)
735  {
736      HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
737      g_wifiHalInfo.status = THREAD_STOPPING;
738      pthread_join(g_wifiHalInfo.thread, NULL);
739      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
740  }
741  
WifiDriverClientInit(void)742  int32_t WifiDriverClientInit(void)
743  {
744      HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
745      if (g_wifiHalInfo.cmdSock != NULL) {
746          HILOG_ERROR(LOG_CORE, "%s: already create cmd socket", __FUNCTION__);
747          return RET_CODE_FAILURE;
748      }
749  
750      if (InitEventcallbackMutex() != RET_CODE_SUCCESS) {
751          HILOG_ERROR(LOG_CORE, "%s: init callbackmutex failed.", __FUNCTION__);
752          return RET_CODE_FAILURE;
753      }
754  
755      if (pthread_mutex_init(&g_wifiHalInfo.mutex, NULL) != RET_CODE_SUCCESS) {
756          HILOG_ERROR(LOG_CORE, "%s: init mutex failed.", __FUNCTION__);
757          goto err_mutex;
758      }
759  
760      if (ConnectCmdSocket() != RET_CODE_SUCCESS) {
761          HILOG_ERROR(LOG_CORE, "%s: connect cmd socket failed.", __FUNCTION__);
762          goto err_cmd;
763      }
764  
765      if (ConnectCtrlSocket() != RET_CODE_SUCCESS) {
766          HILOG_ERROR(LOG_CORE, "%s: connect ctrl socket failed", __FUNCTION__);
767          goto err_ctrl;
768      }
769  
770      if (ConnectEventSocket() != RET_CODE_SUCCESS) {
771          HILOG_ERROR(LOG_CORE, "%s: connect event socket failed", __FUNCTION__);
772          goto err_event;
773      }
774  
775      if (WifiMsgRegisterEventListener() != RET_CODE_SUCCESS) {
776          HILOG_ERROR(LOG_CORE, "%s: WifiMsgRegisterEventListener failed", __FUNCTION__);
777          goto err_reg;
778      }
779      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
780      return RET_CODE_SUCCESS;
781  err_reg:
782      DisconnectEventSocket();
783  err_event:
784      DisconnectCtrlSocket();
785  err_ctrl:
786      DisconnectCmdSocket();
787  err_cmd:
788      pthread_mutex_destroy(&g_wifiHalInfo.mutex);
789  err_mutex:
790      DeinitEventcallbackMutex();
791      return RET_CODE_FAILURE;
792  }
793  
WifiDriverClientDeinit(void)794  void WifiDriverClientDeinit(void)
795  {
796      HILOG_INFO(LOG_CORE, "hal enter %{public}s", __FUNCTION__);
797      WifiMsgUnregisterEventListener();
798  
799      if (g_wifiHalInfo.cmdSock == NULL) {
800          HILOG_ERROR(LOG_CORE, "%s: cmd socket not inited", __FUNCTION__);
801      } else {
802          DisconnectCmdSocket();
803      }
804  
805      if (g_wifiHalInfo.ctrlSock == NULL) {
806          HILOG_ERROR(LOG_CORE, "%s: ctrl socket not inited", __FUNCTION__);
807      } else {
808          DisconnectCtrlSocket();
809      }
810  
811      if (g_wifiHalInfo.eventSock == NULL) {
812          HILOG_ERROR(LOG_CORE, "%s: event socket not inited", __FUNCTION__);
813      } else {
814          DisconnectEventSocket();
815      }
816  
817      pthread_mutex_destroy(&g_wifiHalInfo.mutex);
818      DeinitEventcallbackMutex();
819      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
820  }
821  
ParserIsSupportCombo(struct nl_msg * msg,void * arg)822  static int32_t ParserIsSupportCombo(struct nl_msg *msg, void *arg)
823  {
824      struct nlattr *attr[NL80211_ATTR_MAX + 1];
825      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
826      struct nlattr *nlComb = NULL;
827      struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
828      uint8_t *isSupportCombo = (uint8_t *)arg;
829      int32_t ret, i;
830      static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
831      ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
832      ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
833      ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
834  
835      // parse all enum nl80211_attrs type
836      ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
837      if (ret != 0) {
838          HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
839          return NL_SKIP;
840      }
841  
842      if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
843          nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
844              // parse all enum nl80211_if_combination_attrs type
845              ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
846              if (ret != 0) {
847                  HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
848                  return NL_SKIP;
849              }
850              if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
851                  !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
852                  *isSupportCombo = 0;
853              } else {
854                  *isSupportCombo = 1;
855              }
856          }
857      }
858      HILOG_INFO(LOG_CORE, "%s: isSupportCombo is %hhu", __FUNCTION__, *isSupportCombo);
859      return NL_SKIP;
860  }
861  
ParserSupportComboInfo(struct nl_msg * msg,void * arg)862  static int32_t ParserSupportComboInfo(struct nl_msg *msg, void *arg)
863  {
864      (void)arg;
865      struct nlattr *attr[NL80211_ATTR_MAX + 1];
866      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
867      struct nlattr *nlComb = NULL, *nlLimit = NULL, *nlMode = NULL;
868      struct nlattr *attrComb[NUM_NL80211_IFACE_COMB];
869      struct nlattr *attrLimit[NUM_NL80211_IFACE_LIMIT];
870      int32_t ret, i, j, k, type;
871      static struct nla_policy ifaceCombPolicy[NUM_NL80211_IFACE_COMB];
872      ifaceCombPolicy[NL80211_IFACE_COMB_LIMITS].type = NLA_NESTED;
873      ifaceCombPolicy[NL80211_IFACE_COMB_MAXNUM].type = NLA_U32;
874      ifaceCombPolicy[NL80211_IFACE_COMB_NUM_CHANNELS].type = NLA_U32;
875  
876      static struct nla_policy ifaceLimitPolicy[NUM_NL80211_IFACE_LIMIT];
877      ifaceLimitPolicy[NL80211_IFACE_LIMIT_MAX].type = NLA_U32;
878      ifaceLimitPolicy[NL80211_IFACE_LIMIT_TYPES].type = NLA_NESTED;
879  
880      ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
881      if (ret != 0) {
882          HILOG_ERROR(LOG_CORE, "%s: nla_parse tb failed", __FUNCTION__);
883          return NL_SKIP;
884      }
885  
886      if (attr[NL80211_ATTR_INTERFACE_COMBINATIONS] != NULL) {
887          // get each ieee80211_iface_combination
888          nla_for_each_nested(nlComb, attr[NL80211_ATTR_INTERFACE_COMBINATIONS], i) {
889              ret = nla_parse_nested(attrComb, MAX_NL80211_IFACE_COMB, nlComb, ifaceCombPolicy);
890              if (ret != 0) {
891                  HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested nlComb failed", __FUNCTION__);
892                  return NL_SKIP;
893              }
894              if (!attrComb[NL80211_IFACE_COMB_LIMITS] || !attrComb[NL80211_IFACE_COMB_MAXNUM] ||
895                  !attrComb[NL80211_IFACE_COMB_NUM_CHANNELS]) {
896                  return RET_CODE_NOT_SUPPORT;
897              }
898              // parse each ieee80211_iface_limit
899              nla_for_each_nested(nlLimit, attrComb[NL80211_IFACE_COMB_LIMITS], j) {
900                  ret = nla_parse_nested(attrLimit, MAX_NL80211_IFACE_LIMIT, nlLimit, ifaceLimitPolicy);
901                  if (ret || !attrLimit[NL80211_IFACE_LIMIT_TYPES]) {
902                      HILOG_ERROR(LOG_CORE, "%s: iface limit types not supported", __FUNCTION__);
903                      return RET_CODE_NOT_SUPPORT; /* broken combination */
904                  }
905                  // parse each ieee80211_iface_limit's types
906                  nla_for_each_nested(nlMode, attrLimit[NL80211_IFACE_LIMIT_TYPES], k) {
907                      type = nla_type(nlMode);
908                      if (type > WIFI_IFTYPE_UNSPECIFIED && type < WIFI_IFTYPE_MAX) {
909                          HILOG_INFO(LOG_CORE, "%s: mode: %d", __FUNCTION__, type);
910                      }
911                  }
912                  HILOG_INFO(LOG_CORE, "%s: has parse a attrLimit", __FUNCTION__);
913              }
914          }
915      }
916      return NL_SKIP;
917  }
918  
GetWiphyBands(struct genlmsghdr * hdr)919  static struct nlattr *GetWiphyBands(struct genlmsghdr *hdr)
920  {
921      struct nlattr *attrMsg[NL80211_ATTR_MAX + 1];
922      void *data = genlmsg_attrdata(hdr, 0);
923      int32_t len = genlmsg_attrlen(hdr, 0);
924      nla_parse(attrMsg, NL80211_ATTR_MAX, data, len, NULL);
925      if (!attrMsg[NL80211_ATTR_WIPHY_BANDS]) {
926          HILOG_ERROR(LOG_CORE, "%s: no wiphy bands", __FUNCTION__);
927      }
928      return attrMsg[NL80211_ATTR_WIPHY_BANDS];
929  }
930  
GetCenterFreq(struct nlattr * bands,struct FreqInfoResult * result)931  static void GetCenterFreq(struct nlattr *bands, struct FreqInfoResult *result)
932  {
933      struct nlattr *attrFreq[NL80211_FREQUENCY_ATTR_MAX + 1];
934      struct nlattr *nlFreq = NULL;
935      void *data = NULL;
936      int32_t len;
937      int32_t i;
938      uint32_t freq;
939      static struct nla_policy freqPolicy[NL80211_FREQUENCY_ATTR_MAX + 1];
940      freqPolicy[NL80211_FREQUENCY_ATTR_FREQ].type = NLA_U32;
941      freqPolicy[NL80211_FREQUENCY_ATTR_MAX_TX_POWER].type = NLA_U32;
942  
943      // get each ieee80211_channel
944      nla_for_each_nested(nlFreq, bands, i) {
945          data = nla_data(nlFreq);
946          len = nla_len(nlFreq);
947          nla_parse(attrFreq, NL80211_FREQUENCY_ATTR_MAX, data, len, freqPolicy);
948          // get center freq
949          if (attrFreq[NL80211_FREQUENCY_ATTR_FREQ] == NULL) {
950              continue;
951          }
952          freq = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_FREQ]);
953          switch (result->band) {
954              case NL80211_BAND_2GHZ:
955                  if (attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]) {
956                      if (freq > LOW_LITMIT_FREQ_2_4G && freq < HIGH_LIMIT_FREQ_2_4G) {
957                          result->freqs[result->nums] = freq;
958                          result->txPower[result->nums] = nla_get_u32(attrFreq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER]);
959                          result->nums++;
960                      }
961                  }
962                  break;
963              case NL80211_BAND_5GHZ:
964                  if (freq > LOW_LIMIT_FREQ_5G && freq < HIGH_LIMIT_FREQ_5G) {
965                      result->freqs[result->nums] = freq;
966                      result->nums++;
967                  }
968                  break;
969              default:
970                  break;
971          }
972      }
973  }
974  
ParserValidFreq(struct nl_msg * msg,void * arg)975  static int32_t ParserValidFreq(struct nl_msg *msg, void *arg)
976  {
977      struct FreqInfoResult *result = (struct FreqInfoResult *)arg;
978      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
979      struct nlattr *attrWiphyBands = NULL;
980      struct nlattr *attrBand[NL80211_BAND_ATTR_MAX + 1];
981      struct nlattr *nlBand = NULL;
982      int32_t i;
983      void *data = NULL;
984      int32_t len;
985  
986      attrWiphyBands = GetWiphyBands(hdr);
987      if (attrWiphyBands == NULL) {
988          return NL_SKIP;
989      }
990  
991      // get each ieee80211_supported_band
992      nla_for_each_nested(nlBand, attrWiphyBands, i) {
993          data = nla_data(nlBand);
994          len = nla_len(nlBand);
995          nla_parse(attrBand, NL80211_BAND_ATTR_MAX, data, len, NULL);
996          if (attrBand[NL80211_BAND_ATTR_FREQS] == NULL) {
997              continue;
998          }
999          GetCenterFreq(attrBand[NL80211_BAND_ATTR_FREQS], result);
1000      }
1001      return NL_SKIP;
1002  }
1003  
IsWifiIface(const char * name)1004  static bool IsWifiIface(const char *name)
1005  {
1006      if (strncmp(name, "wlan", WLAN_IFACE_LENGTH) != 0 && strncmp(name, "p2p", P2P_IFACE_LENGTH) != 0 &&
1007          strncmp(name, "chba", CHBA_IFACE_LENGTH) != 0) {
1008          /* not a wifi interface; ignore it */
1009          return false;
1010      } else {
1011          return true;
1012      }
1013  }
1014  
GetAllIfaceInfo(struct NetworkInfoResult * infoResult)1015  static int32_t GetAllIfaceInfo(struct NetworkInfoResult *infoResult)
1016  {
1017      struct dirent **namelist = NULL;
1018      char *ifName = NULL;
1019      int32_t num;
1020      int32_t i;
1021      int32_t ret = RET_CODE_SUCCESS;
1022  
1023      num = scandir(NET_DEVICE_INFO_PATH, &namelist, NULL, alphasort);
1024      if (num < 0) {
1025          HILOG_ERROR(LOG_CORE, "%s: scandir failed, errno = %d, %s", __FUNCTION__, errno, strerror(errno));
1026          return RET_CODE_FAILURE;
1027      }
1028      infoResult->nums = 0;
1029      for (i = 0; i < num; i++) {
1030          if (infoResult->nums < MAX_IFACE_NUM && IsWifiIface(namelist[i]->d_name)) {
1031              ifName = infoResult->infos[infoResult->nums].name;
1032              if (strncpy_s(ifName, IFNAMSIZ, namelist[i]->d_name, strlen(namelist[i]->d_name)) != EOK) {
1033                  HILOG_ERROR(LOG_CORE, "%s: strncpy_s infoResult->infos failed", __FUNCTION__);
1034                  ret = RET_CODE_FAILURE;
1035              }
1036              HILOG_DEBUG(LOG_CORE, "%{public}s: ifName = %{public}s", __FUNCTION__, ifName);
1037              infoResult->nums++;
1038          }
1039          free(namelist[i]);
1040      }
1041      free(namelist);
1042      return ret;
1043  }
1044  
NetLinkGetChipProp(void)1045  static bool NetLinkGetChipProp(void)
1046  {
1047      char preValue[SUBCHIP_WIFI_PROP_LEN] = { 0 };
1048      int errCode = GetParameter(SUBCHIP_WIFI_PROP, 0, preValue, SUBCHIP_WIFI_PROP_LEN);
1049      if (errCode > 0) {
1050          if (strncmp(preValue, SUPPORT_COEXCHIP, SUPPORT_COEXCHIP_LEN) == 0) {
1051              return true;
1052          }
1053      }
1054  
1055      return false;
1056  }
1057  
GetUsableNetworkInfo(struct NetworkInfoResult * result)1058  int32_t GetUsableNetworkInfo(struct NetworkInfoResult *result)
1059  {
1060      int32_t ret;
1061      uint32_t i;
1062  
1063      ret = GetAllIfaceInfo(result);
1064      if (ret != RET_CODE_SUCCESS) {
1065          HILOG_ERROR(LOG_CORE, "%s: GetAllIfaceInfo failed", __FUNCTION__);
1066          return ret;
1067      }
1068  
1069      HILOG_INFO(LOG_CORE, "%{public}s: wifi iface num %{public}d", __FUNCTION__, result->nums);
1070      for (i = 0; i < result->nums; ++i) {
1071          ret = memset_s(result->infos[i].supportMode, sizeof(result->infos[i].supportMode), 0,
1072              sizeof(result->infos[i].supportMode));
1073          if (ret != EOK) {
1074              HILOG_ERROR(LOG_CORE, "%s: memset_s esult->infos failed", __FUNCTION__);
1075              return RET_CODE_FAILURE;
1076          }
1077          if (strncmp(result->infos[i].name, STR_WLAN0, strlen(STR_WLAN0)) == 0) {
1078              result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
1079              result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 0 : 1;
1080          } else if (strncmp(result->infos[i].name, STR_WLAN1, strlen(STR_WLAN1)) == 0) {
1081              result->infos[i].supportMode[WIFI_IFTYPE_STATION] = 1;
1082              result->infos[i].supportMode[WIFI_IFTYPE_AP] = NetLinkGetChipProp() ? 1 : 0;
1083          } else if (strncmp(result->infos[i].name, STR_P2P0, strlen(STR_P2P0)) == 0) {
1084              result->infos[i].supportMode[WIFI_IFTYPE_P2P_DEVICE] = 1;
1085          } else if (strncmp(result->infos[i].name, STR_P2P0_X, strlen(STR_P2P0_X)) == 0) {
1086              result->infos[i].supportMode[WIFI_IFTYPE_P2P_CLIENT] = 1;
1087              result->infos[i].supportMode[WIFI_IFTYPE_P2P_GO] = 1;
1088          } else if (strncmp(result->infos[i].name, STR_CHBA, strlen(STR_CHBA)) == 0) {
1089              result->infos[i].supportMode[WIFI_IFTYPE_CHBA] = 1;
1090          }
1091      }
1092      return RET_CODE_SUCCESS;
1093  }
1094  
IsSupportCombo(uint8_t * isSupportCombo)1095  int32_t IsSupportCombo(uint8_t *isSupportCombo)
1096  {
1097      uint32_t ifaceId;
1098      struct nl_msg *msg = NULL;
1099      struct NetworkInfoResult networkInfo;
1100      int32_t ret;
1101  
1102      ret = GetUsableNetworkInfo(&networkInfo);
1103      if (ret != RET_CODE_SUCCESS) {
1104          HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1105          return ret;
1106      }
1107  
1108      ifaceId = if_nametoindex(networkInfo.infos[0].name);
1109      if (ifaceId == 0) {
1110          HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1111          return RET_CODE_FAILURE;
1112      }
1113  
1114      msg = nlmsg_alloc();
1115      if (msg == NULL) {
1116          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1117          return RET_CODE_NOMEM;
1118      }
1119  
1120      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1121      nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1122      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1123      ret = NetlinkSendCmdSync(msg, ParserIsSupportCombo, isSupportCombo);
1124      if (ret != RET_CODE_SUCCESS) {
1125          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1126      }
1127      nlmsg_free(msg);
1128      return ret;
1129  }
1130  
GetComboInfo(uint64_t * comboInfo,uint32_t size)1131  int32_t GetComboInfo(uint64_t *comboInfo, uint32_t size)
1132  {
1133      (void)size;
1134      uint32_t ifaceId;
1135      struct nl_msg *msg = NULL;
1136      struct NetworkInfoResult networkInfo;
1137      int32_t ret;
1138  
1139      ret = GetUsableNetworkInfo(&networkInfo);
1140      if (ret != RET_CODE_SUCCESS) {
1141          HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1142          return ret;
1143      }
1144  
1145      ifaceId = if_nametoindex(networkInfo.infos[0].name);
1146      if (ifaceId == 0) {
1147          HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1148          return RET_CODE_FAILURE;
1149      }
1150  
1151      msg = nlmsg_alloc();
1152      if (msg == NULL) {
1153          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1154          return RET_CODE_NOMEM;
1155      }
1156      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1157      nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1158      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1159      ret = NetlinkSendCmdSync(msg, ParserSupportComboInfo, comboInfo);
1160      if (ret != RET_CODE_SUCCESS) {
1161          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1162      }
1163      nlmsg_free(msg);
1164      return ret;
1165  }
1166  
SetMacAddr(const char * ifName,unsigned char * mac,uint8_t len)1167  int32_t SetMacAddr(const char *ifName, unsigned char *mac, uint8_t len)
1168  {
1169      int32_t fd;
1170      int32_t ret;
1171      struct ifreq req;
1172  
1173      if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1174          HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1175          return RET_CODE_FAILURE;
1176      }
1177      fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1178      if (fd < 0) {
1179          HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1180          return RET_CODE_FAILURE;
1181      }
1182      if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1183          HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1184          close(fd);
1185          return RET_CODE_FAILURE;
1186      }
1187      req.ifr_addr.sa_family = ARPHRD_ETHER;
1188      if (memcpy_s(req.ifr_hwaddr.sa_data, len, mac, len) != EOK) {
1189          HILOG_ERROR(LOG_CORE, "%s: memcpy_s req.ifr_hwaddr.sa_data failed", __FUNCTION__);
1190          close(fd);
1191          return RET_CODE_FAILURE;
1192      }
1193      ret = ioctl(fd, SIOCSIFHWADDR, &req);
1194      if (ret != RET_CODE_SUCCESS) {
1195          HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1196          if (errno == EPERM) {
1197              ret = RET_CODE_NOT_SUPPORT;
1198          } else if (errno == EBUSY) {
1199              ret = RET_CODE_DEVICE_BUSY;
1200          } else {
1201              ret = RET_CODE_FAILURE;
1202          }
1203      }
1204      close(fd);
1205      return ret;
1206  }
1207  
ParserChipId(struct nl_msg * msg,void * arg)1208  static int32_t ParserChipId(struct nl_msg *msg, void *arg)
1209  {
1210      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
1211      struct nlattr *attr[NL80211_ATTR_MAX + 1];
1212      uint8_t *chipId = (uint8_t *)arg;
1213      uint8_t *getChipId = NULL;
1214      int32_t ret;
1215  
1216      ret = nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
1217      if (ret != 0) {
1218          HILOG_ERROR(LOG_CORE, "%s: nla_parse failed", __FUNCTION__);
1219          return NL_SKIP;
1220      }
1221  
1222      if (attr[NL80211_ATTR_MAX]) {
1223          getChipId = nla_data(attr[NL80211_ATTR_MAX]);
1224          *chipId = *getChipId;
1225      }
1226  
1227      return NL_SKIP;
1228  }
1229  
GetDevMacAddr(const char * ifName,int32_t type,uint8_t * mac,uint8_t len)1230  int32_t GetDevMacAddr(const char *ifName, int32_t type, uint8_t *mac, uint8_t len)
1231  {
1232      (void)type;
1233      int32_t fd;
1234      int32_t ret;
1235      struct ifreq req;
1236  
1237      if (memset_s(&req, sizeof(req), 0, sizeof(req)) != EOK) {
1238          HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1239          return RET_CODE_FAILURE;
1240      }
1241      fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1242      if (fd < 0) {
1243          HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1244          return RET_CODE_FAILURE;
1245      }
1246  
1247      if (strncpy_s(req.ifr_name, IFNAMSIZ, ifName, strlen(ifName)) != EOK) {
1248          HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1249          close(fd);
1250          return RET_CODE_FAILURE;
1251      }
1252      struct ethtool_perm_addr *epaddr =
1253          (struct ethtool_perm_addr *)malloc(sizeof(struct ethtool_perm_addr) + ETH_ADDR_LEN);
1254      if (epaddr == NULL) {
1255          HILOG_ERROR(LOG_CORE, "%s: malloc failed", __FUNCTION__);
1256          close(fd);
1257          return RET_CODE_FAILURE;
1258      }
1259      epaddr->cmd = ETHTOOL_GPERMADDR;
1260      epaddr->size = ETH_ADDR_LEN;
1261      req.ifr_data = (char*)epaddr;
1262      ret = ioctl(fd, SIOCETHTOOL, &req);
1263      if (ret != 0) {
1264          HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1265          free(epaddr);
1266          close(fd);
1267          return RET_CODE_FAILURE;
1268      }
1269  
1270      if (memcpy_s(mac, len, (unsigned char *)epaddr->data, ETH_ADDR_LEN) != EOK) {
1271          HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac failed", __FUNCTION__);
1272          ret = RET_CODE_FAILURE;
1273      }
1274      free(epaddr);
1275      close(fd);
1276      return ret;
1277  }
1278  
GetValidFreqByBand(const char * ifName,int32_t band,struct FreqInfoResult * result,uint32_t size)1279  int32_t GetValidFreqByBand(const char *ifName, int32_t band, struct FreqInfoResult *result, uint32_t size)
1280  {
1281      uint32_t ifaceId;
1282      struct nl_msg *msg = NULL;
1283      int32_t ret;
1284  
1285      if (result == NULL || result->freqs == NULL || result->txPower == NULL) {
1286          HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter", __FUNCTION__);
1287          return RET_CODE_INVALID_PARAM;
1288      }
1289  
1290      if (band >= IEEE80211_NUM_BANDS) {
1291          HILOG_ERROR(LOG_CORE, "%s:  Invalid input parameter, band = %d", __FUNCTION__, band);
1292          return RET_CODE_INVALID_PARAM;
1293      }
1294  
1295      ifaceId = if_nametoindex(ifName);
1296      if (ifaceId == 0) {
1297          HILOG_ERROR(LOG_CORE, "%s: get iface id(%u) failed", __FUNCTION__, ifaceId);
1298          return RET_CODE_INVALID_PARAM;
1299      }
1300  
1301      msg = nlmsg_alloc();
1302      if (msg == NULL) {
1303          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1304          return RET_CODE_NOMEM;
1305      }
1306  
1307      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1308      nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1309      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1310      ret = memset_s(result->freqs, size * sizeof(uint32_t), 0, size * sizeof(uint32_t));
1311      if (ret != EOK) {
1312          HILOG_ERROR(LOG_CORE, "%s: memset_s result->freqs  failed", __FUNCTION__);
1313          nlmsg_free(msg);
1314          return RET_CODE_FAILURE;
1315      }
1316      result->nums = 0;
1317      result->band = band;
1318      ret = NetlinkSendCmdSync(msg, ParserValidFreq, result);
1319      if (ret != RET_CODE_SUCCESS) {
1320          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1321      }
1322      nlmsg_free(msg);
1323      return ret;
1324  }
1325  
SetTxPower(const char * ifName,int32_t power)1326  int32_t SetTxPower(const char *ifName, int32_t power)
1327  {
1328      uint32_t ifaceId;
1329      struct nl_msg *msg = NULL;
1330      int32_t ret;
1331  
1332      ifaceId = if_nametoindex(ifName);
1333      if (ifaceId == 0) {
1334          HILOG_ERROR(LOG_CORE, "%s: get iface id(%d) failed", __FUNCTION__, ifaceId);
1335          return RET_CODE_INVALID_PARAM;
1336      }
1337  
1338      msg = nlmsg_alloc();
1339      if (msg == NULL) {
1340          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1341          return RET_CODE_NOMEM;
1342      }
1343  
1344      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_SET_WIPHY, 0);
1345      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1346      nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, NL80211_TX_POWER_LIMITED);
1347      nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, 100 * power);
1348      ret = NetlinkSendCmdSync(msg, NULL, NULL);
1349      if (ret != RET_CODE_SUCCESS) {
1350          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1351      } else {
1352          HILOG_INFO(LOG_CORE, "%s: send end success", __FUNCTION__);
1353      }
1354      nlmsg_free(msg);
1355      return ret;
1356  }
1357  
GetAssociatedStas(const char * ifName,struct AssocStaInfoResult * result)1358  int32_t GetAssociatedStas(const char *ifName, struct AssocStaInfoResult *result)
1359  {
1360      (void)ifName;
1361      if (memset_s(result, sizeof(struct AssocStaInfoResult), 0, sizeof(struct AssocStaInfoResult)) != EOK) {
1362          HILOG_ERROR(LOG_CORE, "%s: memset_s result failed", __FUNCTION__);
1363          return RET_CODE_FAILURE;
1364      }
1365      return RET_CODE_SUCCESS;
1366  }
1367  
WifiSetCountryCode(const char * ifName,const char * code,uint32_t len)1368  int32_t WifiSetCountryCode(const char *ifName, const char *code, uint32_t len)
1369  {
1370      uint32_t ifaceId = if_nametoindex(ifName);
1371      struct nl_msg *msg = NULL;
1372      struct nlattr *data = NULL;
1373      int32_t ret;
1374  
1375      if (ifaceId == 0) {
1376          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1377          return RET_CODE_FAILURE;
1378      }
1379  
1380      msg = nlmsg_alloc();
1381      if (msg == NULL) {
1382          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1383          return RET_CODE_NOMEM;
1384      }
1385  
1386      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1387      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1388      nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1389      nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_COUNTRY_CODE);
1390      data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1391      if (data == NULL) {
1392          HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1393          nlmsg_free(msg);
1394          return RET_CODE_FAILURE;
1395      }
1396      if (nla_put(msg, WIFI_ATTRIBUTE_COUNTRY, len, code) != RET_CODE_SUCCESS) {
1397          HILOG_ERROR(LOG_CORE, "%s: nla_put code failed", __FUNCTION__);
1398          nlmsg_free(msg);
1399          return RET_CODE_FAILURE;
1400      }
1401      nla_nest_end(msg, data);
1402  
1403      ret = NetlinkSendCmdSync(msg, NULL, NULL);
1404      if (ret != RET_CODE_SUCCESS) {
1405          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1406      }
1407      nlmsg_free(msg);
1408      return ret;
1409  }
1410  
SetScanMacAddr(const char * ifName,uint8_t * scanMac,uint8_t len)1411  int32_t SetScanMacAddr(const char *ifName, uint8_t *scanMac, uint8_t len)
1412  {
1413      int32_t ret;
1414      uint32_t ifaceId = if_nametoindex(ifName);
1415      struct nl_msg *msg = nlmsg_alloc();
1416      struct nlattr *data = NULL;
1417  
1418      if (msg == NULL) {
1419          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1420          return RET_CODE_NOMEM;
1421      }
1422      if (ifaceId == 0) {
1423          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1424          nlmsg_free(msg);
1425          return RET_CODE_FAILURE;
1426      }
1427      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_VENDOR, 0);
1428      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1429      nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, VENDOR_ID);
1430      nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, WIFI_SUBCMD_SET_RANDOM_MAC_OUI);
1431      data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
1432      if (data == NULL) {
1433          HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1434          nlmsg_free(msg);
1435          return RET_CODE_FAILURE;
1436      }
1437      if (nla_put(msg, WIFI_ATTRIBUTE_RANDOM_MAC_OUI, len, scanMac) !=RET_CODE_SUCCESS) {
1438          HILOG_ERROR(LOG_CORE, "%s: nla_put scanMac failed", __FUNCTION__);
1439          nlmsg_free(msg);
1440          return RET_CODE_FAILURE;
1441      }
1442      nla_nest_end(msg, data);
1443      ret = NetlinkSendCmdSync(msg, NULL, NULL);
1444      if (ret != RET_CODE_SUCCESS) {
1445          HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1446      }
1447      nlmsg_free(msg);
1448      return ret;
1449  }
1450  
AcquireChipId(const char * ifName,uint8_t * chipId)1451  int32_t AcquireChipId(const char *ifName, uint8_t *chipId)
1452  {
1453      struct nl_msg *msg = NULL;
1454      uint32_t ifaceId;
1455      int32_t ret;
1456  
1457      if (ifName == NULL || chipId == NULL) {
1458          HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1459          return RET_CODE_INVALID_PARAM;
1460      }
1461  
1462      ifaceId = if_nametoindex(ifName);
1463      if (ifaceId == 0) {
1464          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1465          return RET_CODE_FAILURE;
1466      }
1467  
1468      msg = nlmsg_alloc();
1469      if (msg == NULL) {
1470          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1471          return RET_CODE_NOMEM;
1472      }
1473  
1474      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0);
1475      nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP);
1476      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1477  
1478      ret = NetlinkSendCmdSync(msg, ParserChipId, chipId);
1479      if (ret != RET_CODE_SUCCESS) {
1480          HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1481      }
1482      nlmsg_free(msg);
1483      return ret;
1484  }
1485  
GetIfNamesByChipId(const uint8_t chipId,char ** ifNames,uint32_t * num)1486  int32_t GetIfNamesByChipId(const uint8_t chipId, char **ifNames, uint32_t *num)
1487  {
1488      if (ifNames == NULL || num == NULL) {
1489          HILOG_ERROR(LOG_CORE, "%s params is NULL", __FUNCTION__);
1490          return RET_CODE_INVALID_PARAM;
1491      }
1492  
1493      if (chipId >= MAX_WLAN_DEVICE) {
1494          HILOG_ERROR(LOG_CORE, "%s: chipId = %u", __FUNCTION__, chipId);
1495          return RET_CODE_INVALID_PARAM;
1496      }
1497      *num = 1;
1498      *ifNames = (char *)calloc(*num, IFNAMSIZ);
1499      if (*ifNames == NULL) {
1500          HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1501          return RET_CODE_FAILURE;
1502      }
1503      if (memcpy_s(*ifNames, IFNAMSIZ, "wlan0", IFNAMSIZ) != EOK) {
1504          HILOG_ERROR(LOG_CORE, "%s: memcpy failed", __FUNCTION__);
1505          free(*ifNames);
1506          *ifNames = NULL;
1507          return RET_CODE_FAILURE;
1508      }
1509      return RET_CODE_SUCCESS;
1510  }
1511  
SetResetDriver(const uint8_t chipId,const char * ifName)1512  int32_t SetResetDriver(const uint8_t chipId, const char *ifName)
1513  {
1514      (void)chipId;
1515      (void)ifName;
1516      return RET_CODE_SUCCESS;
1517  }
1518  
NetDeviceInfoHandler(struct nl_msg * msg,void * arg)1519  static int32_t NetDeviceInfoHandler(struct nl_msg *msg, void *arg)
1520  {
1521      struct NetDeviceInfo *info = (struct NetDeviceInfo *)arg;
1522      struct nlattr *attr[NL80211_ATTR_MAX + 1];
1523      struct genlmsghdr *hdr = NULL;
1524      void *data = NULL;
1525      int32_t len;
1526  
1527      hdr = nlmsg_data(nlmsg_hdr(msg));
1528      if (hdr == NULL) {
1529          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
1530          return NL_SKIP;
1531      }
1532      data = genlmsg_attrdata(hdr, 0);
1533      len = genlmsg_attrlen(hdr, 0);
1534      nla_parse(attr, NL80211_ATTR_MAX, data, len, NULL);
1535      if (attr[NL80211_ATTR_IFTYPE]) {
1536          info->iftype = nla_get_u32(attr[NL80211_ATTR_IFTYPE]);
1537          HILOG_ERROR(LOG_CORE, "%s: %s iftype is %hhu", __FUNCTION__, info->ifName, info->iftype);
1538      }
1539      if (attr[NL80211_ATTR_MAC]) {
1540          if (memcpy_s(info->mac, ETH_ADDR_LEN, nla_data(attr[NL80211_ATTR_MAC]), ETH_ADDR_LEN) != EOK) {
1541              HILOG_ERROR(LOG_CORE, "%s: memcpy_s mac address fail", __FUNCTION__);
1542          }
1543      }
1544  
1545      return NL_SKIP;
1546  }
1547  
GetIftypeAndMac(struct NetDeviceInfo * info)1548  static int32_t GetIftypeAndMac(struct NetDeviceInfo *info)
1549  {
1550      struct nl_msg *msg = nlmsg_alloc();
1551      int32_t ret;
1552  
1553      if (msg == NULL) {
1554          HILOG_ERROR(LOG_CORE, "%s: nlmsg_alloc failed.", __FUNCTION__);
1555          return RET_CODE_FAILURE;
1556      }
1557  
1558      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_INTERFACE, 0);
1559      nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(info->ifName));
1560  
1561      ret = NetlinkSendCmdSync(msg, NetDeviceInfoHandler, info);
1562      if (ret != RET_CODE_SUCCESS) {
1563          HILOG_ERROR(LOG_CORE, "%s: NetlinkSendCmdSync failed.", __FUNCTION__);
1564      }
1565      nlmsg_free(msg);
1566      return ret;
1567  }
1568  
GetNetDeviceInfo(struct NetDeviceInfoResult * netDeviceInfoResult)1569  int32_t GetNetDeviceInfo(struct NetDeviceInfoResult *netDeviceInfoResult)
1570  {
1571      struct NetworkInfoResult networkInfo;
1572      uint32_t i;
1573      int32_t ret;
1574  
1575      ret = GetUsableNetworkInfo(&networkInfo);
1576      if (ret != RET_CODE_SUCCESS) {
1577          HILOG_ERROR(LOG_CORE, "%s: get network info failed", __FUNCTION__);
1578          return ret;
1579      }
1580  
1581      for (i = 0; i < networkInfo.nums && i < MAX_NETDEVICE_COUNT; i++) {
1582          if (memset_s(&netDeviceInfoResult->deviceInfos[i], sizeof(struct NetDeviceInfo), 0,
1583              sizeof(struct NetDeviceInfo)) != EOK) {
1584              HILOG_ERROR(LOG_CORE, "%s: memset_s fail", __FUNCTION__);
1585              return RET_CODE_FAILURE;
1586          }
1587          netDeviceInfoResult->deviceInfos[i].index = i + 1;
1588          if (strncpy_s(netDeviceInfoResult->deviceInfos[i].ifName, IFNAMSIZ,
1589              networkInfo.infos[i].name, IFNAMSIZ) != EOK) {
1590              HILOG_ERROR(LOG_CORE, "%s: strncpy_s fail", __FUNCTION__);
1591              return RET_CODE_FAILURE;
1592          }
1593          ret = GetIftypeAndMac(&netDeviceInfoResult->deviceInfos[i]);
1594          if (ret != RET_CODE_SUCCESS) {
1595              HILOG_ERROR(LOG_CORE, "%s: get iftype and mac failed", __FUNCTION__);
1596              return ret;
1597          }
1598      }
1599  
1600      return RET_CODE_SUCCESS;
1601  }
1602  
CmdScanPutSsidsMsg(struct nl_msg * msg,const WifiScan * scan,const WiphyInfo * wiphyInfo)1603  static int32_t CmdScanPutSsidsMsg(struct nl_msg *msg, const WifiScan *scan, const WiphyInfo *wiphyInfo)
1604  {
1605      struct nlattr *nest = NULL;
1606      int32_t i;
1607  
1608      if (scan->ssids) {
1609          nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
1610          if (nest == NULL) {
1611              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1612              return RET_CODE_FAILURE;
1613          }
1614          int attrtype = 1;
1615          /*add an empty ssid for a wildcard scan*/
1616          if (nla_put(msg, attrtype, 0, NULL) != RET_CODE_SUCCESS) {
1617              HILOG_ERROR(LOG_CORE, "%s: nla_put NULL failed", __FUNCTION__);
1618              return RET_CODE_FAILURE;
1619          }
1620          for (i = 0; i < scan->numSsids; i++) {
1621              if (attrtype >= wiphyInfo->scanCapabilities.maxNumScanSsids) {
1622                  HILOG_INFO(LOG_CORE, "%s: Skip the excess hidden ssids for scan,current:%{public}d,max:%{public}d",
1623                      __FUNCTION__, attrtype, wiphyInfo->scanCapabilities.maxNumScanSsids);
1624                  break;
1625              }
1626              if (strlen((const char *)scan->ssids[i].ssid) == 0 || scan->ssids[i].ssidLen == 0) {
1627                  HILOG_ERROR(LOG_CORE, "%s: nla_put ssid is empty", __FUNCTION__);
1628                  continue;
1629              }
1630              attrtype++;
1631              if (nla_put(msg, attrtype, scan->ssids[i].ssidLen, scan->ssids[i].ssid) != RET_CODE_SUCCESS) {
1632                  HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed", __FUNCTION__);
1633                  return RET_CODE_FAILURE;
1634              }
1635          }
1636          nla_nest_end(msg, nest);
1637          HILOG_INFO(LOG_CORE, "%{public}s numSsids:%{public}d", __FUNCTION__, attrtype);
1638      }
1639      return RET_CODE_SUCCESS;
1640  }
1641  
CmdScanPutFreqsMsg(struct nl_msg * msg,const WifiScan * scan)1642  static int32_t CmdScanPutFreqsMsg(struct nl_msg *msg, const WifiScan *scan)
1643  {
1644      struct nlattr *nest = NULL;
1645      int32_t i;
1646  
1647      if (scan->freqs) {
1648          nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
1649          if (nest == NULL) {
1650              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed", __FUNCTION__);
1651              return RET_CODE_FAILURE;
1652          }
1653          for (i = 0; i < scan->numFreqs; i++) {
1654              nla_put_u32(msg, i + 1, scan->freqs[i]);
1655          }
1656          nla_nest_end(msg, nest);
1657      }
1658      return RET_CODE_SUCCESS;
1659  }
1660  
CmdScanPutMsg(const char * ifName,struct nl_msg * msg,const WifiScan * scan)1661  static int32_t CmdScanPutMsg(const char *ifName, struct nl_msg *msg, const WifiScan *scan)
1662  {
1663      uint32_t wiphyIndex;
1664      WiphyInfo wiphyInfo;
1665  
1666      if (memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo)) != EOK) {
1667          HILOG_ERROR(LOG_CORE, "%s: memset_s wiphyInfo failed", __FUNCTION__);
1668          return RET_CODE_FAILURE;
1669      }
1670      if (GetWiphyIndex(ifName, &wiphyIndex) != RET_CODE_SUCCESS) {
1671          HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
1672          return RET_CODE_FAILURE;
1673      }
1674      if (GetWiphyInfo(wiphyIndex, &wiphyInfo) != RET_CODE_SUCCESS) {
1675          HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
1676          return RET_CODE_FAILURE;
1677      }
1678  
1679      if (CmdScanPutSsidsMsg(msg, scan, &wiphyInfo) != RET_CODE_SUCCESS) {
1680          return RET_CODE_FAILURE;
1681      }
1682  
1683      if (CmdScanPutFreqsMsg(msg, scan) != RET_CODE_SUCCESS) {
1684          return RET_CODE_FAILURE;
1685      }
1686  
1687      if (scan->extraIes) {
1688          if (nla_put(msg, NL80211_ATTR_IE, scan->extraIesLen, scan->extraIes) != RET_CODE_SUCCESS) {
1689              HILOG_ERROR(LOG_CORE, "%s: nla_put extraIes failed", __FUNCTION__);
1690              return RET_CODE_FAILURE;
1691          }
1692      }
1693  
1694      if (scan->bssid) {
1695          if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, scan->bssid) != RET_CODE_SUCCESS) {
1696              HILOG_ERROR(LOG_CORE, "%s: nla_put bssid failed", __FUNCTION__);
1697              return RET_CODE_FAILURE;
1698          }
1699      }
1700  
1701      return RET_CODE_SUCCESS;
1702  }
1703  
WifiCmdScan(const char * ifName,WifiScan * scan)1704  int32_t WifiCmdScan(const char *ifName, WifiScan *scan)
1705  {
1706      uint32_t ifaceId = if_nametoindex(ifName);
1707      struct nl_msg *msg = NULL;
1708      int32_t ret;
1709  
1710      if (ifaceId == 0) {
1711          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
1712          return RET_CODE_FAILURE;
1713      }
1714  
1715      msg = nlmsg_alloc();
1716      if (msg == NULL) {
1717          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
1718          return RET_CODE_NOMEM;
1719      }
1720  
1721      genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_TRIGGER_SCAN, 0);
1722      nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId);
1723      do {
1724          ret = CmdScanPutMsg(ifName, msg, scan);
1725          if (ret != RET_CODE_SUCCESS) {
1726              HILOG_ERROR(LOG_CORE, "%s: put msg failed", __FUNCTION__);
1727              break;
1728          }
1729          ret = NetlinkSendCmdSync(msg, NULL, NULL);
1730          if (ret != RET_CODE_SUCCESS) {
1731              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
1732          }
1733      } while (0);
1734      nlmsg_free(msg);
1735      return ret;
1736  }
1737  
ParsePowerMode(const char * buf,uint16_t len,uint8_t * mode)1738  static int32_t ParsePowerMode(const char *buf, uint16_t len, uint8_t *mode)
1739  {
1740      char *key[WIFI_POWER_MODE_NUM] = {"sleep\n", "third\n", "init\n"};
1741      char *str = "pow_mode = ";
1742      if (buf == NULL || mode == NULL) {
1743          return RET_CODE_INVALID_PARAM;
1744      }
1745      char *pos = strstr(buf, str);
1746      if (pos == NULL) {
1747          HILOG_ERROR(LOG_CORE, "%s: no power mode", __FUNCTION__);
1748          return RET_CODE_FAILURE;
1749      }
1750      pos += strlen(str);
1751      if (!strncmp(pos, key[WIFI_POWER_MODE_SLEEPING], strlen(key[WIFI_POWER_MODE_SLEEPING]))) {
1752          *mode = WIFI_POWER_MODE_SLEEPING;
1753      } else if (!strncmp(pos, key[WIFI_POWER_MODE_GENERAL], strlen(key[WIFI_POWER_MODE_GENERAL]))) {
1754          *mode = WIFI_POWER_MODE_GENERAL;
1755      } else if (!strncmp(pos, key[WIFI_POWER_MODE_THROUGH_WALL], strlen(key[WIFI_POWER_MODE_THROUGH_WALL]))) {
1756          *mode = WIFI_POWER_MODE_THROUGH_WALL;
1757      } else {
1758          HILOG_ERROR(LOG_CORE, "%s: no invalid power mode", __FUNCTION__);
1759          return RET_CODE_FAILURE;
1760      }
1761      return RET_CODE_SUCCESS;
1762  }
1763  
GetCurrentPowerMode(const char * ifName,uint8_t * mode)1764  int32_t GetCurrentPowerMode(const char *ifName, uint8_t *mode)
1765  {
1766      int32_t fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1767      int32_t ret;
1768      HwprivIoctlData ioctlData;
1769  
1770      (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1771      if (fd < 0) {
1772          HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1773          return RET_CODE_FAILURE;
1774      }
1775      do {
1776          if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1777              HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1778              ret = RET_CODE_FAILURE;
1779              break;
1780          }
1781          ioctlData.data.point.flags = SECONDARY_ID_POWER_MODE;
1782          ioctlData.data.point.length = strlen(GET_POWER_MODE) + 1;
1783          ioctlData.data.point.buf = calloc(ioctlData.data.point.length, sizeof(char));
1784          if (ioctlData.data.point.buf == NULL) {
1785              HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1786              ret = RET_CODE_NOMEM;
1787              break;
1788          }
1789          if (memcpy_s(ioctlData.data.point.buf, ioctlData.data.point.length,
1790              GET_POWER_MODE, strlen(GET_POWER_MODE)) != EOK) {
1791              HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed", __FUNCTION__);
1792              ret = RET_CODE_FAILURE;
1793              break;
1794          }
1795          ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1796          if (ret != RET_CODE_SUCCESS) {
1797              HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1798              if (errno == EOPNOTSUPP) {
1799                  ret = RET_CODE_NOT_SUPPORT;
1800              } else {
1801                  ret = RET_CODE_FAILURE;
1802              }
1803              break;
1804          }
1805          ret = ParsePowerMode(ioctlData.data.point.buf, ioctlData.data.point.length, mode);
1806          if (ret != RET_CODE_SUCCESS) {
1807              HILOG_ERROR(LOG_CORE, "%s: ParsePowerMode failed", __FUNCTION__);
1808              break;
1809          }
1810      } while (0);
1811      if (ioctlData.data.point.buf != NULL) {
1812          free(ioctlData.data.point.buf);
1813          ioctlData.data.point.buf = NULL;
1814      }
1815      close(fd);
1816      return ret;
1817  }
1818  
FillHwprivIoctlData(HwprivIoctlData * ioctlData,uint8_t mode)1819  static int32_t FillHwprivIoctlData(HwprivIoctlData *ioctlData, uint8_t mode)
1820  {
1821      const char *strTable[WIFI_POWER_MODE_NUM] = {SET_POWER_MODE_SLEEP, SET_POWER_MODE_THIRD, SET_POWER_MODE_INIT};
1822      const char *modeStr = strTable[mode];
1823  
1824      ioctlData->data.point.length = strlen(strTable[mode]) + 1;
1825      ioctlData->data.point.buf = calloc(ioctlData->data.point.length, sizeof(char));
1826      if (ioctlData->data.point.buf == NULL) {
1827          HILOG_ERROR(LOG_CORE, "%s: calloc failed", __FUNCTION__);
1828          return RET_CODE_NOMEM;
1829      }
1830      ioctlData->data.point.flags = SECONDARY_ID_POWER_MODE;
1831      if (strncpy_s(ioctlData->data.point.buf, ioctlData->data.point.length, modeStr, strlen(modeStr)) != EOK) {
1832          HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1833          free(ioctlData->data.point.buf);
1834          ioctlData->data.point.buf = NULL;
1835          return RET_CODE_FAILURE;
1836      }
1837  
1838      return RET_CODE_SUCCESS;
1839  }
1840  
SetPowerMode(const char * ifName,uint8_t mode)1841  int32_t SetPowerMode(const char *ifName, uint8_t mode)
1842  {
1843      int32_t fd;
1844      int32_t ret;
1845      HwprivIoctlData ioctlData;
1846  
1847      if (ifName == NULL || mode >= WIFI_POWER_MODE_NUM) {
1848          HILOG_ERROR(LOG_CORE, "%s: Invalid parameter", __FUNCTION__);
1849          return RET_CODE_FAILURE;
1850      }
1851      (void)memset_s(&ioctlData, sizeof(ioctlData), 0, sizeof(ioctlData));
1852      fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1853      if (fd < 0) {
1854          HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1855          return RET_CODE_FAILURE;
1856      }
1857  
1858      do {
1859          if (strcpy_s(ioctlData.interfaceName, IFNAMSIZ, ifName) != EOK) {
1860              HILOG_ERROR(LOG_CORE, "%s: strcpy_s failed", __FUNCTION__);
1861              ret = RET_CODE_FAILURE;
1862              break;
1863          }
1864          ret = FillHwprivIoctlData(&ioctlData, mode);
1865          if (ret != RET_CODE_SUCCESS) {
1866              break;
1867          }
1868          ret = ioctl(fd, PRIMARY_ID_POWER_MODE, &ioctlData);
1869          if (ret != RET_CODE_SUCCESS) {
1870              HILOG_ERROR(LOG_CORE, "%s: ioctl failed, errno = %d, (%s)", __FUNCTION__, errno, strerror(errno));
1871              if (errno == EOPNOTSUPP) {
1872                  ret = RET_CODE_NOT_SUPPORT;
1873              } else {
1874                  ret = RET_CODE_FAILURE;
1875              }
1876          }
1877      } while (0);
1878  
1879      if (ioctlData.data.point.buf != NULL) {
1880          free(ioctlData.data.point.buf);
1881          ioctlData.data.point.buf = NULL;
1882      }
1883      close(fd);
1884      return ret;
1885  }
1886  
StartChannelMeas(const char * ifName,const struct MeasParam * measParam)1887  int32_t StartChannelMeas(const char *ifName, const struct MeasParam *measParam)
1888  {
1889      (void)ifName;
1890      (void)measParam;
1891      return RET_CODE_NOT_SUPPORT;
1892  }
1893  
GetChannelMeasResult(const char * ifName,struct MeasResult * measResult)1894  int32_t GetChannelMeasResult(const char *ifName, struct MeasResult *measResult)
1895  {
1896      (void)ifName;
1897      (void)measResult;
1898      return RET_CODE_NOT_SUPPORT;
1899  }
1900  
SendCommandToDriver(const char * cmd,uint32_t len,const char * ifName,WifiPrivCmd * out)1901  static int32_t SendCommandToDriver(const char *cmd, uint32_t len, const char *ifName, WifiPrivCmd *out)
1902  {
1903      struct ifreq ifr;
1904      int32_t ret = RET_CODE_FAILURE;
1905  
1906      if (cmd == NULL || out == NULL) {
1907          HILOG_ERROR(LOG_CORE, "%{public}s: cmd or out is null", __FUNCTION__);
1908          return RET_CODE_INVALID_PARAM;
1909      }
1910      if (len > out->size) {
1911          HILOG_ERROR(LOG_CORE, "%{public}s: Size of command is too large", __FUNCTION__);
1912          return RET_CODE_INVALID_PARAM;
1913      }
1914      if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1915          HILOG_ERROR(LOG_CORE, "%s: memset_s ifr failed", __FUNCTION__);
1916          return RET_CODE_FAILURE;
1917      }
1918      if (memcpy_s(out->buf, out->size, cmd, len) != EOK) {
1919          HILOG_ERROR(LOG_CORE, "%{public}s: memcpy_s error", __FUNCTION__);
1920          return RET_CODE_FAILURE;
1921      }
1922      out->len = len;
1923      ifr.ifr_data = (void *)out;
1924      if (strcpy_s(ifr.ifr_name, IFNAMSIZ, ifName) != EOK) {
1925          HILOG_ERROR(LOG_CORE, "%s: strcpy_s error", __FUNCTION__);
1926          return RET_CODE_FAILURE;
1927      }
1928      int32_t sock = socket(AF_INET, SOCK_DGRAM, 0);
1929      if (sock < 0) {
1930          HILOG_ERROR(LOG_CORE, "%{public}s: socket failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1931              strerror(errno));
1932          return ret;
1933      }
1934      do {
1935          ret = ioctl(sock, SIOCDEVPRIVATE + 1, &ifr);
1936          if (ret < 0) {
1937              HILOG_ERROR(LOG_CORE, "%{public}s: ioctl failed, errno = %{public}d, (%{public}s)", __FUNCTION__, errno,
1938                  strerror(errno));
1939              ret = (errno == EOPNOTSUPP) ? RET_CODE_NOT_SUPPORT : RET_CODE_FAILURE;
1940              break;
1941          }
1942      } while (0);
1943  
1944      close(sock);
1945      return ret;
1946  }
1947  
GetInterfaceState(const char * interfaceName,uint16_t * state)1948  static int32_t GetInterfaceState(const char *interfaceName, uint16_t *state)
1949  {
1950      int32_t ret = RET_CODE_FAILURE;
1951      struct ifreq ifr;
1952      int32_t fd;
1953  
1954      if (memset_s(&ifr, sizeof(ifr), 0, sizeof(ifr)) != EOK) {
1955          HILOG_ERROR(LOG_CORE, "%s: memset_s req failed", __FUNCTION__);
1956          return RET_CODE_FAILURE;
1957      }
1958  
1959      fd = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
1960      if (fd < 0) {
1961          HILOG_ERROR(LOG_CORE, "%s: open socket failed", __FUNCTION__);
1962          return RET_CODE_FAILURE;
1963      }
1964      do {
1965          if (strncpy_s(ifr.ifr_name, MAX_INTERFACE_NAME_SIZE, interfaceName, strlen(interfaceName)) != EOK) {
1966              HILOG_ERROR(LOG_CORE, "%s: strncpy_s failed", __FUNCTION__);
1967              break;
1968          }
1969          ret = ioctl(fd, SIOCGIFFLAGS, &ifr);
1970          if (ret < 0) {
1971              HILOG_ERROR(LOG_CORE, "%s:could not read interface state for %s, errno = %d, (%s)", __FUNCTION__,
1972                  interfaceName, errno, strerror(errno));
1973              ret = RET_CODE_FAILURE;
1974              break;
1975          }
1976          *state = ifr.ifr_flags;
1977      } while (0);
1978  
1979      close(fd);
1980      return ret;
1981  }
1982  
DisableNextCacOnce(const char * ifName)1983  static int32_t DisableNextCacOnce(const char *ifName)
1984  {
1985      char cmdBuf[P2P_BUF_SIZE] = {CMD_SET_CLOSE_GO_CAC};
1986  
1987      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
1988      WifiPrivCmd out = {0};
1989      out.buf = buf;
1990      out.size = MAX_PRIV_CMD_SIZE;
1991      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
1992  }
1993  
SetGoChannel(const char * ifName,const int8_t * data,uint32_t len)1994  static int32_t SetGoChannel(const char *ifName, const int8_t *data, uint32_t len)
1995  {
1996      int32_t ret = RET_CODE_FAILURE;
1997      char cmdBuf[P2P_BUF_SIZE] = {0};
1998      uint32_t cmdLen;
1999      uint16_t state;
2000  
2001      cmdLen = strlen(CMD_SET_CHANGE_GO_CHANNEL);
2002      if ((cmdLen + len) >= P2P_BUF_SIZE) {
2003          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2004          return ret;
2005      }
2006      ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_CHANGE_GO_CHANNEL, *data);
2007      if (ret < RET_CODE_SUCCESS) {
2008          HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2009          return RET_CODE_FAILURE;
2010      }
2011      if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2012          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2013          return RET_CODE_NETDOWN;
2014      }
2015  
2016      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2017      WifiPrivCmd out = {0};
2018      out.buf = buf;
2019      out.size = MAX_PRIV_CMD_SIZE;
2020      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2021  }
2022  
SetGoDetectRadar(const char * ifName,const int8_t * data,uint32_t len)2023  static int32_t SetGoDetectRadar(const char *ifName, const int8_t *data, uint32_t len)
2024  {
2025      int32_t ret = RET_CODE_FAILURE;
2026      char cmdBuf[P2P_BUF_SIZE] = {0};
2027      uint32_t cmdLen;
2028      uint16_t state;
2029  
2030      cmdLen = strlen(CMD_SET_GO_DETECT_RADAR);
2031      if ((cmdLen + len) >= P2P_BUF_SIZE) {
2032          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2033          return ret;
2034      }
2035      ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_GO_DETECT_RADAR, *data);
2036      if (ret < RET_CODE_SUCCESS) {
2037          HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2038          return RET_CODE_FAILURE;
2039      }
2040      if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2041          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2042          return RET_CODE_NETDOWN;
2043      }
2044  
2045      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2046      WifiPrivCmd out = {0};
2047      out.buf = buf;
2048      out.size = MAX_PRIV_CMD_SIZE;
2049      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2050  }
2051  
SetP2pScenes(const char * ifName,const int8_t * data,uint32_t len)2052  static int32_t SetP2pScenes(const char *ifName, const int8_t *data, uint32_t len)
2053  {
2054      int32_t ret = RET_CODE_FAILURE;
2055      char cmdBuf[P2P_BUF_SIZE] = {0};
2056      uint32_t cmdLen;
2057      uint16_t state;
2058  
2059      cmdLen = strlen(CMD_SET_P2P_SCENES);
2060      if ((cmdLen + len) >= P2P_BUF_SIZE) {
2061          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2062          return ret;
2063      }
2064      ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_P2P_SCENES, *data);
2065      if (ret < RET_CODE_SUCCESS) {
2066          HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2067          return RET_CODE_FAILURE;
2068      }
2069      if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2070          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2071          return RET_CODE_NETDOWN;
2072      }
2073  
2074      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2075      WifiPrivCmd out = {0};
2076      out.buf = buf;
2077      out.size = MAX_PRIV_CMD_SIZE;
2078      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2079  }
2080  
SetDynamicDbacMode(const char * ifName,const int8_t * data,uint32_t len)2081  static int32_t SetDynamicDbacMode(const char *ifName, const int8_t *data, uint32_t len)
2082  {
2083      int32_t ret = RET_CODE_FAILURE;
2084      char cmdBuf[P2P_BUF_SIZE] = {0};
2085      uint32_t cmdLen;
2086      uint16_t state;
2087  
2088      cmdLen = strlen(CMD_SET_DYNAMIC_DBAC_MODE);
2089      if ((cmdLen + len) >= P2P_BUF_SIZE) {
2090          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2091          return ret;
2092      }
2093      ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s %d", CMD_SET_DYNAMIC_DBAC_MODE, *data);
2094      if (ret < RET_CODE_SUCCESS) {
2095          HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
2096          return RET_CODE_FAILURE;
2097      }
2098      if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2099          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2100          return RET_CODE_NETDOWN;
2101      }
2102  
2103      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2104      WifiPrivCmd out = {0};
2105      out.buf = buf;
2106      out.size = MAX_PRIV_CMD_SIZE;
2107      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2108  }
2109  
SetRxRemainOnChannel(const char * ifName,const int8_t * data,uint32_t len)2110  static int32_t SetRxRemainOnChannel(const char *ifName, const int8_t *data, uint32_t len)
2111  {
2112      int32_t ret = RET_CODE_FAILURE;
2113      char cmdBuf[P2P_BUF_SIZE] = {0};
2114      uint32_t cmdLen;
2115      uint16_t state;
2116  
2117      cmdLen = strlen(CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
2118      if ((cmdLen + len) >= P2P_BUF_SIZE) {
2119          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large", __FUNCTION__);
2120          return ret;
2121      }
2122      ret = snprintf_s(cmdBuf, P2P_BUF_SIZE, P2P_BUF_SIZE - 1, "%s", CMD_SET_RX_MGMT_REMAIN_ON_CHANNEL);
2123      if (ret < RET_CODE_SUCCESS) {
2124          HILOG_ERROR(LOG_CORE, "%{public}s: snprintf failed!, ret = %{public}d", __FUNCTION__, ret);
2125          return RET_CODE_FAILURE;
2126      }
2127      cmdLen = (uint32_t)ret;
2128      ret = memcpy_s(cmdBuf + cmdLen + 1, P2P_BUF_SIZE - cmdLen - 1, data, len);
2129      if (ret < RET_CODE_SUCCESS) {
2130          HILOG_ERROR(LOG_CORE, "%{public}s: memcpy failed!, ret = %{public}d", __FUNCTION__, ret);
2131          return RET_CODE_FAILURE;
2132      }
2133      if ((GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS) || (state & INTERFACE_UP) == 0) {
2134          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
2135          return RET_CODE_NETDOWN;
2136      }
2137  
2138      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
2139      WifiPrivCmd out = {0};
2140      out.buf = buf;
2141      out.size = MAX_PRIV_CMD_SIZE;
2142      return SendCommandToDriver(cmdBuf, P2P_BUF_SIZE, ifName, &out);
2143  }
2144  
InitInstallWlanParam(const char * ifName,uint32_t interfaceId,struct nl_msg ** msg,struct nl_msg ** keyMsg)2145  static int32_t InitInstallWlanParam(const char *ifName, uint32_t interfaceId,
2146      struct nl_msg **msg, struct nl_msg **keyMsg)
2147  {
2148      if (interfaceId == 0) {
2149          HILOG_ERROR(LOG_CORE, "%{public}s: if_nametoindex failed", __FUNCTION__);
2150          return RET_CODE_FAILURE;
2151      }
2152  
2153      *msg = nlmsg_alloc();
2154      if (*msg == NULL) {
2155          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2156          return RET_CODE_NOMEM;
2157      }
2158  
2159      *keyMsg = nlmsg_alloc();
2160      if (*keyMsg == NULL) {
2161          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2162          nlmsg_free(*msg);
2163          return RET_CODE_NOMEM;
2164      }
2165      return RET_CODE_SUCCESS;
2166  }
2167  
InstallParam(struct nl_msg * msg,struct nl_msg * keyMsg)2168  static int32_t InstallParam(struct nl_msg *msg, struct nl_msg *keyMsg)
2169  {
2170      HILOG_INFO(LOG_CORE, "enter %{public}s", __FUNCTION__);
2171      if (msg == NULL || keyMsg == NULL) {
2172          HILOG_ERROR(LOG_CORE, "%s: param is NULL ", __FUNCTION__);
2173          return RET_CODE_FAILURE;
2174      }
2175      struct nlmsghdr *hdr = nlmsg_hdr(keyMsg);
2176      void *data = nlmsg_data(hdr);
2177      int len = (int)hdr->nlmsg_len - NLMSG_HDRLEN;
2178      if (memset_s(data, len, 0, len) != 0) {
2179          HILOG_ERROR(LOG_CORE, "%s: memset_s failed", __FUNCTION__);
2180          return RET_CODE_FAILURE;
2181      }
2182  
2183      return NetlinkSendCmdSync(msg, NULL, NULL);
2184  }
2185  
FreeMsg(struct nl_msg * msg,struct nl_msg * keyMsg)2186  static void FreeMsg(struct nl_msg *msg, struct nl_msg *keyMsg)
2187  {
2188      if (msg != NULL) {
2189          nlmsg_free(msg);
2190      }
2191      if (keyMsg != NULL) {
2192          nlmsg_free(keyMsg);
2193      }
2194  }
2195  
WifiInstallWlanExtParam(const char * ifName,const InstallWlanParam * param)2196  int32_t WifiInstallWlanExtParam(const char *ifName, const InstallWlanParam *param)
2197  {
2198      HILOG_INFO(LOG_CORE, "enter %{public}s", __FUNCTION__);
2199      int32_t ret = RET_CODE_FAILURE;
2200      if (ifName == NULL || param == NULL) {
2201          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2202          return RET_CODE_FAILURE;
2203      }
2204  
2205      uint32_t interfaceId = if_nametoindex(ifName);
2206      struct nl_msg *msg = NULL;
2207      struct nl_msg *keyMsg = NULL;
2208      ret = InitInstallWlanParam(ifName, interfaceId, &msg, &keyMsg);
2209      if (ret != RET_CODE_SUCCESS) {
2210          goto err;
2211      }
2212      do {
2213          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_NEW_KEY, 0)) {
2214              break;
2215          }
2216          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2217              break;
2218          }
2219          if (nla_put(keyMsg, NL80211_KEY_DATA, param->len, param->buf)  != RET_CODE_SUCCESS) {
2220              break;
2221          }
2222  
2223          if (nla_put_u32(keyMsg, NL80211_KEY_CIPHER, param->suite)  != RET_CODE_SUCCESS) {
2224              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 suite failed", __FUNCTION__);
2225              break;
2226          }
2227          if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, param->addr)  != RET_CODE_SUCCESS) {
2228              HILOG_ERROR(LOG_CORE, "%s: nla_put addr failed", __FUNCTION__);
2229              break;
2230          }
2231          if (nla_put_u8(keyMsg, NL80211_KEY_IDX, param->id) != RET_CODE_SUCCESS) {
2232              HILOG_ERROR(LOG_CORE, "%s: nla_put_u8 index failed", __FUNCTION__);
2233              break;
2234          }
2235          if (nla_put_nested(msg, NL80211_ATTR_KEY, keyMsg) != RET_CODE_SUCCESS) {
2236              HILOG_ERROR(LOG_CORE, "%s: nla_put_nested failed", __FUNCTION__);
2237              break;
2238          }
2239          ret = InstallParam(msg, keyMsg);
2240          if (ret != RET_CODE_SUCCESS) {
2241              HILOG_ERROR(LOG_CORE, "%s: install wlan ext param failed", __FUNCTION__);
2242              break;
2243          }
2244      } while (0);
2245  err:
2246      FreeMsg(msg, keyMsg);
2247      return ret;
2248  }
2249  
InstallWlanExtParam(const char * ifName,const int8_t * data,uint32_t dataLen)2250  static int32_t InstallWlanExtParam(const char *ifName, const int8_t *data, uint32_t dataLen)
2251  {
2252      if (dataLen > sizeof(InstallWlanParam) || dataLen < sizeof(InstallWlanParam) - MAX_BUF_LEN) {
2253          HILOG_ERROR(LOG_CORE, "%s: dataLen error", __FUNCTION__);
2254          return HDF_FAILURE;
2255      }
2256      uint8_t newData[dataLen];
2257      int32_t ret = memset_s(newData, dataLen, 0, dataLen);
2258      if (ret != EOK) {
2259          HILOG_ERROR(LOG_CORE, "%s: memset_s failed", __FUNCTION__);
2260          return HDF_FAILURE;
2261      }
2262      for (uint32_t i = 0; i < dataLen; i++) {
2263          newData[i] = (uint8_t)(data[i]);
2264      }
2265  
2266      uint8_t id = newData[0];
2267      uint8_t len = newData[1];
2268      const uint8_t *buf = newData + INSTALL_WLAN_HEAD_LEN;
2269      const uint8_t *suite = buf + len;
2270      const uint8_t *mac = buf + len + sizeof(uint32_t);
2271      InstallWlanParam param;
2272      param.id = id;
2273      param.len = len;
2274      param.suite = ((suite[0] << SUITE_LEFT_LEN_24) | (suite[SUITE_INDEX_1] << SUITE_LEFT_LEN_16) |
2275          (suite[SUITE_INDEX_2] << SUITE_LEFT_LEN_8) | suite[SUITE_INDEX_3]);
2276      if (memcpy_s(param.buf, MAX_BUF_LEN, buf, len) != EOK ||
2277          memcpy_s(param.addr, ETH_ADDR_LEN, mac, ETH_ADDR_LEN) != EOK) {
2278          HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed", __FUNCTION__);
2279          return HDF_FAILURE;
2280      }
2281      return WifiInstallWlanExtParam(ifName, &param);
2282  }
2283  
SetProjectionScreenParam(const char * ifName,const ProjectionScreenParam * param)2284  int32_t SetProjectionScreenParam(const char *ifName, const ProjectionScreenParam *param)
2285  {
2286      int32_t ret;
2287      switch (param->cmdId) {
2288          case CMD_CLOSE_GO_CAC:
2289              ret = DisableNextCacOnce(ifName);
2290              break;
2291          case CMD_SET_GO_CSA_CHANNEL:
2292              ret = SetGoChannel(ifName, param->buf, param->bufLen);
2293              break;
2294          case CMD_SET_GO_RADAR_DETECT:
2295              ret = SetGoDetectRadar(ifName, param->buf, param->bufLen);
2296              break;
2297          case CMD_ID_MCC_STA_P2P_QUOTA_TIME:
2298              ret = SetDynamicDbacMode(ifName, param->buf, param->bufLen);
2299              break;
2300          case CMD_ID_CTRL_ROAM_CHANNEL:
2301              ret = SetP2pScenes(ifName, param->buf, param->bufLen);
2302              break;
2303          case CMD_ID_RX_REMAIN_ON_CHANNEL:
2304              ret = SetRxRemainOnChannel(ifName, param->buf, param->bufLen);
2305              break;
2306          case CMD_ID_INSTALL_WLAN_KEY:
2307              ret = InstallWlanExtParam(ifName, param->buf, param->bufLen);
2308              break;
2309          default:
2310              HILOG_ERROR(LOG_CORE, "%{public}s: Invalid command id", __FUNCTION__);
2311              return RET_CODE_NOT_SUPPORT;
2312      }
2313      if (ret != RET_CODE_SUCCESS) {
2314          HILOG_ERROR(LOG_CORE, "%{public}s: Config projection screen fail, ret = %{public}d", __FUNCTION__, ret);
2315      }
2316      return ret;
2317  }
2318  
SendCmdIoctl(const char * ifName,int32_t cmdId,const int8_t * paramBuf,uint32_t paramBufLen)2319  int32_t SendCmdIoctl(const char *ifName, int32_t cmdId, const int8_t *paramBuf, uint32_t paramBufLen)
2320  {
2321      (void)ifName;
2322      (void)cmdId;
2323      (void)paramBuf;
2324      (void)paramBufLen;
2325      return RET_CODE_NOT_SUPPORT;
2326  }
2327  
ParseStaTxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2328  static void ParseStaTxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2329  {
2330      struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2331      static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2332  
2333      if (size < NL80211_STA_INFO_MAX + 1) {
2334          HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2335          return;
2336      }
2337      ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2338      ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2339      ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2340      ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2341      ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2342      ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2343      if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
2344          nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
2345          if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2346              info->txRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2347          } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2348              info->txRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2349          }
2350          if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2351              info->txMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2352              info->flags |= STA_DRV_DATA_TX_MCS;
2353          }
2354          if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2355              info->txVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2356              info->flags |= STA_DRV_DATA_TX_VHT_MCS;
2357          }
2358          if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2359              info->flags |= STA_DRV_DATA_TX_SHORT_GI;
2360          }
2361          if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2362              info->txVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2363              info->flags |= STA_DRV_DATA_TX_VHT_NSS;
2364          }
2365      }
2366  }
2367  
ParseStaRxRate(struct nlattr ** stats,uint32_t size,StationInfo * info)2368  static void ParseStaRxRate(struct nlattr **stats, uint32_t size, StationInfo *info)
2369  {
2370      struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
2371      static struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
2372  
2373      if (size < NL80211_STA_INFO_MAX + 1) {
2374          HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
2375          return;
2376      }
2377      ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
2378      ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
2379      ratePolicy[NL80211_RATE_INFO_MCS].type = NLA_U8;
2380      ratePolicy[NL80211_RATE_INFO_VHT_MCS].type = NLA_U8;
2381      ratePolicy[NL80211_RATE_INFO_SHORT_GI].type = NLA_FLAG;
2382      ratePolicy[NL80211_RATE_INFO_VHT_NSS].type = NLA_U8;
2383      if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
2384          nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
2385          if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
2386              info->rxRate = nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
2387          } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
2388              info->rxRate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
2389          }
2390          if (rate[NL80211_RATE_INFO_MCS] != NULL) {
2391              info->rxMcs = nla_get_u8(rate[NL80211_RATE_INFO_MCS]);
2392              info->flags |= STA_DRV_DATA_RX_MCS;
2393          }
2394          if (rate[NL80211_RATE_INFO_VHT_MCS] != NULL) {
2395              info->rxVhtmcs = nla_get_u8(rate[NL80211_RATE_INFO_VHT_MCS]);
2396              info->flags |= STA_DRV_DATA_RX_VHT_MCS;
2397          }
2398          if (rate[NL80211_RATE_INFO_SHORT_GI] != NULL) {
2399              info->flags |= STA_DRV_DATA_RX_SHORT_GI;
2400          }
2401          if (rate[NL80211_RATE_INFO_VHT_NSS] != NULL) {
2402              info->rxVhtNss = nla_get_u8(rate[NL80211_RATE_INFO_VHT_NSS]);
2403              info->flags |= STA_DRV_DATA_RX_VHT_NSS;
2404          }
2405      }
2406  }
2407  
ParseStaInfo(struct nlattr ** stats,uint32_t size,StationInfo * info)2408  static void ParseStaInfo(struct nlattr **stats, uint32_t size, StationInfo *info)
2409  {
2410      ParseStaTxRate(stats, size, info);
2411      ParseStaRxRate(stats, size, info);
2412  }
2413  
StationInfoHandler(struct nl_msg * msg,void * arg)2414  static int32_t StationInfoHandler(struct nl_msg *msg, void *arg)
2415  {
2416      StationInfo *info = (StationInfo *)arg;
2417      struct genlmsghdr *hdr = NULL;
2418      struct nlattr *attr[NL80211_ATTR_MAX + 1];
2419      struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
2420      static struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
2421  
2422      statsPolicy[NL80211_STA_INFO_INACTIVE_TIME].type = NLA_U32;
2423      statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
2424      statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
2425      statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
2426      statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
2427      statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
2428      statsPolicy[NL80211_STA_INFO_RX_BYTES64].type = NLA_U64;
2429      statsPolicy[NL80211_STA_INFO_TX_BYTES64].type = NLA_U64;
2430      statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_U8;
2431      statsPolicy[NL80211_STA_INFO_ACK_SIGNAL].type = NLA_U8;
2432      statsPolicy[NL80211_STA_INFO_RX_DURATION].type = NLA_U64;
2433  
2434      hdr = nlmsg_data(nlmsg_hdr(msg));
2435      if (hdr == NULL) {
2436          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2437          return NL_SKIP;
2438      }
2439  
2440      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2441      if (!attr[NL80211_ATTR_STA_INFO]) {
2442          HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
2443          return NL_SKIP;
2444      }
2445  
2446      if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy)) {
2447          HILOG_ERROR(LOG_CORE, "%s: failed to parse nested attributes!", __FUNCTION__);
2448          return NL_SKIP;
2449      }
2450  
2451      ParseStaInfo(stats, NL80211_STA_INFO_MAX + 1, info);
2452      return NL_SKIP;
2453  }
2454  
GetStationInfo(const char * ifName,StationInfo * info,const uint8_t * mac,uint32_t macLen)2455  int32_t GetStationInfo(const char *ifName, StationInfo *info, const uint8_t *mac, uint32_t macLen)
2456  {
2457      uint32_t ifaceId = if_nametoindex(ifName);
2458      struct nl_msg *msg = NULL;
2459      int32_t ret = RET_CODE_FAILURE;
2460  
2461      if (ifaceId == 0) {
2462          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2463          return RET_CODE_FAILURE;
2464      }
2465  
2466      msg = nlmsg_alloc();
2467      if (msg == NULL) {
2468          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2469          return RET_CODE_NOMEM;
2470      }
2471      do {
2472          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
2473              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2474              break;
2475          }
2476          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifaceId) != RET_CODE_SUCCESS) {
2477              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 ifaceId faile", __FUNCTION__);
2478              break;
2479          }
2480          if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, mac) != RET_CODE_SUCCESS) {
2481              HILOG_ERROR(LOG_CORE, "%s: nla_put mac address faile", __FUNCTION__);
2482              break;
2483          }
2484  
2485          ret = NetlinkSendCmdSync(msg, StationInfoHandler, info);
2486          if (ret != RET_CODE_SUCCESS) {
2487              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2488          }
2489      } while (0);
2490      nlmsg_free(msg);
2491      return ret;
2492  }
2493  
SetExtFeatureFlag(const uint8_t * extFeatureFlagsBytes,uint32_t extFeatureFlagsLen,uint32_t extFeatureFlag)2494  static bool SetExtFeatureFlag(const uint8_t *extFeatureFlagsBytes, uint32_t extFeatureFlagsLen, uint32_t extFeatureFlag)
2495  {
2496      uint32_t extFeatureFlagBytePos;
2497      uint32_t extFeatureFlagBitPos;
2498  
2499      if (extFeatureFlagsBytes == NULL || extFeatureFlagsLen == 0) {
2500          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2501          return false;
2502      }
2503      extFeatureFlagBytePos = extFeatureFlag / BITNUMS_OF_ONE_BYTE;
2504      extFeatureFlagBitPos = extFeatureFlag % BITNUMS_OF_ONE_BYTE;
2505      if (extFeatureFlagBytePos >= extFeatureFlagsLen) {
2506          return false;
2507      }
2508      return extFeatureFlagsBytes[extFeatureFlagBytePos] & (1U << extFeatureFlagBitPos);
2509  }
2510  
GetWiphyInfoHandler(struct nl_msg * msg,void * arg)2511  static int32_t GetWiphyInfoHandler(struct nl_msg *msg, void *arg)
2512  {
2513      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2514      struct nlattr *attr[NL80211_ATTR_MAX + 1];
2515      WiphyInfo *wiphyInfo = (WiphyInfo *)arg;
2516      uint32_t featureFlags = 0;
2517      uint8_t *extFeatureFlagsBytes = NULL;
2518      uint32_t extFeatureFlagsLen = 0;
2519  
2520      if (hdr == NULL) {
2521          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2522          return NL_SKIP;
2523      }
2524      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2525      if (attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS] != NULL) {
2526          wiphyInfo->scanCapabilities.maxNumScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]);
2527      }
2528      if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS] != NULL) {
2529          wiphyInfo->scanCapabilities.maxNumSchedScanSsids = nla_get_u8(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]);
2530      }
2531      if (attr[NL80211_ATTR_MAX_MATCH_SETS] != NULL) {
2532          wiphyInfo->scanCapabilities.maxMatchSets = nla_get_u8(attr[NL80211_ATTR_MAX_MATCH_SETS]);
2533      }
2534      if (attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS] != NULL) {
2535          wiphyInfo->scanCapabilities.maxNumScanPlans = nla_get_u32(attr[NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS]);
2536      }
2537      if (attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL] != NULL) {
2538          wiphyInfo->scanCapabilities.maxScanPlanInterval = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL]);
2539      }
2540      if (attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS] != NULL) {
2541          wiphyInfo->scanCapabilities.maxScanPlanIterations = nla_get_u32(attr[NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS]);
2542      }
2543      if (attr[NL80211_ATTR_FEATURE_FLAGS] != NULL) {
2544          featureFlags = nla_get_u32(attr[NL80211_ATTR_FEATURE_FLAGS]);
2545      }
2546      wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan = featureFlags & NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
2547      if (attr[NL80211_ATTR_EXT_FEATURES] != NULL) {
2548          extFeatureFlagsBytes = nla_data(attr[NL80211_ATTR_EXT_FEATURES]);
2549          extFeatureFlagsLen = (uint32_t)nla_len(attr[NL80211_ATTR_EXT_FEATURES]);
2550          wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan =
2551              SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_LOW_POWER_SCAN);
2552          wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi =
2553              SetExtFeatureFlag(extFeatureFlagsBytes, extFeatureFlagsLen, NL80211_EXT_FEATURE_SCHED_SCAN_RELATIVE_RSSI);
2554      }
2555      return NL_SKIP;
2556  }
2557  
GetWiphyInfo(const uint32_t wiphyIndex,WiphyInfo * wiphyInfo)2558  static int32_t GetWiphyInfo(const uint32_t wiphyIndex, WiphyInfo *wiphyInfo)
2559  {
2560      struct nl_msg *msg = NULL;
2561      int32_t ret = RET_CODE_FAILURE;
2562  
2563      if (wiphyInfo == NULL) {
2564          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2565          return RET_CODE_INVALID_PARAM;
2566      }
2567      msg = nlmsg_alloc();
2568      if (msg == NULL) {
2569          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2570          return RET_CODE_NOMEM;
2571      }
2572      do {
2573          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_WIPHY, 0)) {
2574              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2575              break;
2576          }
2577          if (nla_put_u32(msg, NL80211_ATTR_WIPHY, wiphyIndex) != RET_CODE_SUCCESS) {
2578              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 wiphyIndex failed.", __FUNCTION__);
2579              break;
2580          }
2581          ret = NetlinkSendCmdSync(msg, GetWiphyInfoHandler, wiphyInfo);
2582          if (ret != RET_CODE_SUCCESS) {
2583              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2584          }
2585      } while (0);
2586      nlmsg_free(msg);
2587      return ret;
2588  }
2589  
GetWiphyIndexHandler(struct nl_msg * msg,void * arg)2590  static int32_t GetWiphyIndexHandler(struct nl_msg *msg, void *arg)
2591  {
2592      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
2593      struct nlattr *attr[NL80211_ATTR_MAX + 1];
2594      uint32_t *wiphyIndex = (uint32_t *)arg;
2595  
2596      if (hdr == NULL) {
2597          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
2598          return NL_SKIP;
2599      }
2600      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
2601      if (!attr[NL80211_ATTR_WIPHY]) {
2602          HILOG_ERROR(LOG_CORE, "%s: wiphy info missing!", __FUNCTION__);
2603          return NL_SKIP;
2604      }
2605      *wiphyIndex = nla_get_u32(attr[NL80211_ATTR_WIPHY]);
2606      return NL_SKIP;
2607  }
2608  
GetWiphyIndex(const char * ifName,uint32_t * wiphyIndex)2609  static int32_t GetWiphyIndex(const char *ifName, uint32_t *wiphyIndex)
2610  {
2611      struct nl_msg *msg = NULL;
2612      uint32_t interfaceId;
2613      int32_t ret = RET_CODE_FAILURE;
2614  
2615      if (ifName == NULL || wiphyIndex == NULL) {
2616          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
2617          return RET_CODE_INVALID_PARAM;
2618      }
2619      interfaceId = if_nametoindex(ifName);
2620      if (interfaceId == 0) {
2621          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2622          return RET_CODE_FAILURE;
2623      }
2624      msg = nlmsg_alloc();
2625      if (msg == NULL) {
2626          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2627          return RET_CODE_NOMEM;
2628      }
2629      do {
2630          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_WIPHY, 0)) {
2631              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2632              break;
2633          }
2634          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2635              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2636              break;
2637          }
2638          ret = NetlinkSendCmdSync(msg, GetWiphyIndexHandler, wiphyIndex);
2639          if (ret != RET_CODE_SUCCESS) {
2640              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2641          }
2642      } while (0);
2643      nlmsg_free(msg);
2644      return ret;
2645  }
2646  
ProcessMatchSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2647  static int32_t ProcessMatchSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2648  {
2649      struct nlattr *nestedMatchSsid = NULL;
2650      struct nlattr *nest = NULL;
2651      uint8_t matchSsidsCount = 0;
2652  
2653      nestedMatchSsid = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
2654      if (nestedMatchSsid == NULL) {
2655          HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2656          return RET_CODE_FAILURE;
2657      }
2658      for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2659          if (matchSsidsCount + 1 > wiphyInfo->scanCapabilities.maxMatchSets) {
2660              break;
2661          }
2662          nest = nla_nest_start(msg, i);
2663          if (nest == NULL) {
2664              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2665              return RET_CODE_FAILURE;
2666          }
2667          if (nla_put(msg, NL80211_SCHED_SCAN_MATCH_ATTR_SSID, pnoSettings->pnoNetworks[i].ssid.ssidLen,
2668              pnoSettings->pnoNetworks[i].ssid.ssid) != RET_CODE_SUCCESS) {
2669              HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed.", __FUNCTION__);
2670              return RET_CODE_FAILURE;
2671          }
2672          nla_put_u32(msg, NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, pnoSettings->min5gRssi);
2673          nla_nest_end(msg, nest);
2674          matchSsidsCount++;
2675      }
2676      nla_nest_end(msg, nestedMatchSsid);
2677      return RET_CODE_SUCCESS;
2678  }
2679  
ClearSsidsList(struct DListHead * ssidsList)2680  static void ClearSsidsList(struct DListHead *ssidsList)
2681  {
2682      struct SsidListNode *ssidListNode = NULL;
2683      struct SsidListNode *tmp = NULL;
2684  
2685      DLIST_FOR_EACH_ENTRY_SAFE(ssidListNode, tmp, ssidsList, struct SsidListNode, entry) {
2686          DListRemove(&ssidListNode->entry);
2687          free(ssidListNode);
2688          ssidListNode = NULL;
2689      }
2690      DListHeadInit(ssidsList);
2691  }
2692  
SsidToMsg(struct nl_msg * msg,struct DListHead * scanSsids)2693  static int32_t SsidToMsg(struct nl_msg *msg, struct DListHead *scanSsids)
2694  {
2695      struct SsidListNode *ssidListNode = NULL;
2696      uint32_t index = 0;
2697      struct nlattr *nestedSsid = NULL;
2698  
2699      if (!scanSsids) {
2700          HILOG_ERROR(LOG_CORE, "%s: scanSsids is null.", __FUNCTION__);
2701          ClearSsidsList(scanSsids);
2702          return RET_CODE_FAILURE;
2703      }
2704      if (!DListIsEmpty(scanSsids)) {
2705          nestedSsid = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
2706          if (nestedSsid == NULL) {
2707              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2708              ClearSsidsList(scanSsids);
2709              return RET_CODE_FAILURE;
2710          }
2711          DLIST_FOR_EACH_ENTRY(ssidListNode, scanSsids, struct SsidListNode, entry) {
2712              if (nla_put(msg, index, ssidListNode->ssidInfo.ssidLen, ssidListNode->ssidInfo.ssid) != RET_CODE_SUCCESS) {
2713                  HILOG_ERROR(LOG_CORE, "%s: nla_put ssid failed.", __FUNCTION__);
2714                  ClearSsidsList(scanSsids);
2715                  return RET_CODE_FAILURE;
2716              }
2717              index++;
2718          }
2719          nla_nest_end(msg, nestedSsid);
2720      }
2721      ClearSsidsList(scanSsids);
2722      return RET_CODE_SUCCESS;
2723  }
2724  
ProcessSsidToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2725  static int32_t ProcessSsidToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2726  {
2727      uint8_t scanSsidsCount = 0;
2728      struct DListHead scanSsids = {0};
2729  
2730      DListHeadInit(&scanSsids);
2731      for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2732          if (!(pnoSettings->pnoNetworks[i].isHidden)) {
2733              continue;
2734          }
2735          if (scanSsidsCount + 1 > wiphyInfo->scanCapabilities.maxNumSchedScanSsids) {
2736              break;
2737          }
2738          struct SsidListNode *ssidNode = (struct SsidListNode *)malloc(sizeof(struct SsidListNode));
2739          if (ssidNode == NULL) {
2740              HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2741              ClearSsidsList(&scanSsids);
2742              return RET_CODE_FAILURE;
2743          }
2744          (void)memset_s(ssidNode, sizeof(struct SsidListNode), 0, sizeof(struct SsidListNode));
2745          ssidNode->ssidInfo.ssidLen = pnoSettings->pnoNetworks[i].ssid.ssidLen;
2746          if (memcpy_s(ssidNode->ssidInfo.ssid, MAX_SSID_LEN, pnoSettings->pnoNetworks[i].ssid.ssid,
2747                  pnoSettings->pnoNetworks[i].ssid.ssidLen) != EOK) {
2748              HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed.", __FUNCTION__);
2749              free(ssidNode);
2750              ssidNode = NULL;
2751              ClearSsidsList(&scanSsids);
2752              return RET_CODE_FAILURE;
2753          }
2754          DListInsertTail(&ssidNode->entry, &scanSsids);
2755          scanSsidsCount++;
2756      }
2757      return SsidToMsg(msg, &scanSsids);
2758  }
2759  
ProcessScanPlanToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2760  static int32_t ProcessScanPlanToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2761  {
2762      struct nlattr *nestedPlan = NULL;
2763      struct nlattr *plan = NULL;
2764  
2765      bool supportNumScanPlans = (wiphyInfo->scanCapabilities.maxNumScanPlans >= 2);
2766      bool supportScanPlanInterval = (wiphyInfo->scanCapabilities.maxScanPlanInterval * MS_PER_SECOND >=
2767          (uint32_t)pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2768      bool supportScanPlanIterations = (wiphyInfo->scanCapabilities.maxScanPlanIterations >= FAST_SCAN_ITERATIONS);
2769  
2770      if (supportNumScanPlans && supportScanPlanInterval && supportScanPlanIterations) {
2771          nestedPlan = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_PLANS);
2772          if (nestedPlan == NULL) {
2773              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2774              return RET_CODE_FAILURE;
2775          }
2776          plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX1);
2777          nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs);
2778          nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_ITERATIONS, pnoSettings->scanIterations);
2779          nla_nest_end(msg, plan);
2780          plan = nla_nest_start(msg, SCHED_SCAN_PLANS_ATTR_INDEX2);
2781          nla_put_u32(msg, NL80211_SCHED_SCAN_PLAN_INTERVAL, pnoSettings->scanIntervalMs * SLOW_SCAN_INTERVAL_MULTIPLIER);
2782          nla_nest_end(msg, plan);
2783          nla_nest_end(msg, nestedPlan);
2784      } else {
2785          nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, pnoSettings->scanIntervalMs * MS_PER_SECOND);
2786      }
2787      return RET_CODE_SUCCESS;
2788  }
2789  
ClearFreqsList(struct DListHead * freqsList)2790  static void ClearFreqsList(struct DListHead *freqsList)
2791  {
2792      struct FreqListNode *freqListNode = NULL;
2793      struct FreqListNode *tmp = NULL;
2794  
2795      DLIST_FOR_EACH_ENTRY_SAFE(freqListNode, tmp, freqsList, struct FreqListNode, entry) {
2796          DListRemove(&freqListNode->entry);
2797          free(freqListNode);
2798          freqListNode = NULL;
2799      }
2800      DListHeadInit(freqsList);
2801  }
2802  
InsertFreqToList(int32_t freq,struct DListHead * scanFreqs)2803  static int32_t InsertFreqToList(int32_t freq, struct DListHead *scanFreqs)
2804  {
2805      bool isFreqExist = false;
2806      struct FreqListNode *freqListNode = NULL;
2807  
2808      DLIST_FOR_EACH_ENTRY(freqListNode, scanFreqs, struct FreqListNode, entry) {
2809          if (freqListNode == NULL) {
2810              HILOG_ERROR(LOG_CORE, "%s: freqListNode is NULL.", __FUNCTION__);
2811              return RET_CODE_FAILURE;
2812          }
2813          if (freqListNode->freq == freq) {
2814              isFreqExist = true;
2815              break;
2816          }
2817      }
2818      if (!isFreqExist) {
2819          struct FreqListNode *freqNode = (struct FreqListNode *)malloc(sizeof(struct FreqListNode));
2820          if (freqNode == NULL) {
2821              HILOG_ERROR(LOG_CORE, "%s: malloc failed.", __FUNCTION__);
2822              return RET_CODE_FAILURE;
2823          }
2824          (void)memset_s(freqNode, sizeof(struct FreqListNode), 0, sizeof(struct FreqListNode));
2825          freqNode->freq = freq;
2826          DListInsertTail(&freqNode->entry, scanFreqs);
2827      }
2828      return RET_CODE_SUCCESS;
2829  }
2830  
ProcessFreqToMsg(struct nl_msg * msg,const WifiPnoSettings * pnoSettings)2831  static int32_t ProcessFreqToMsg(struct nl_msg *msg, const WifiPnoSettings *pnoSettings)
2832  {
2833      struct FreqListNode *freqListNode = NULL;
2834      struct DListHead scanFreqs = {0};
2835      struct nlattr *nestedFreq = NULL;
2836      uint32_t index = 0;
2837  
2838      DListHeadInit(&scanFreqs);
2839      for (uint32_t i = 0; i < pnoSettings->pnoNetworksLen; i++) {
2840          for (uint32_t j = 0; j < pnoSettings->pnoNetworks[i].freqsLen; j++) {
2841              if (InsertFreqToList(pnoSettings->pnoNetworks[i].freqs[j], &scanFreqs) != RET_CODE_SUCCESS) {
2842                  HILOG_ERROR(LOG_CORE, "%s: InsertFreqToList failed.", __FUNCTION__);
2843                  ClearFreqsList(&scanFreqs);
2844                  return RET_CODE_FAILURE;
2845              }
2846          }
2847      }
2848      if (!DListIsEmpty(&scanFreqs)) {
2849          nestedFreq = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
2850          if (nestedFreq == NULL) {
2851              HILOG_ERROR(LOG_CORE, "%s: nla_nest_start failed.", __FUNCTION__);
2852              ClearFreqsList(&scanFreqs);
2853              return RET_CODE_FAILURE;
2854          }
2855          DLIST_FOR_EACH_ENTRY(freqListNode, &scanFreqs, struct FreqListNode, entry) {
2856              nla_put_s32(msg, index, freqListNode->freq);
2857              index++;
2858          }
2859          nla_nest_end(msg, nestedFreq);
2860      }
2861      ClearFreqsList(&scanFreqs);
2862      return RET_CODE_SUCCESS;
2863  }
2864  
ProcessReqflagsToMsg(struct nl_msg * msg,const WiphyInfo * wiphyInfo,const WifiPnoSettings * pnoSettings)2865  static int32_t ProcessReqflagsToMsg(struct nl_msg *msg, const WiphyInfo *wiphyInfo, const WifiPnoSettings *pnoSettings)
2866  {
2867      uint32_t scanFlag = 0;
2868  
2869      if (wiphyInfo->wiphyFeatures.supportsExtSchedScanRelativeRssi) {
2870          struct nl80211_bss_select_rssi_adjust rssiAdjust;
2871          (void)memset_s(&rssiAdjust, sizeof(rssiAdjust), 0, sizeof(rssiAdjust));
2872          rssiAdjust.band = NL80211_BAND_2GHZ;
2873          rssiAdjust.delta = pnoSettings->min2gRssi - pnoSettings->min5gRssi;
2874          if (nla_put(msg, NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, sizeof(rssiAdjust), &rssiAdjust) != RET_CODE_SUCCESS) {
2875              HILOG_ERROR(LOG_CORE, "%s: nla_put rssiAdjust failed.", __FUNCTION__);
2876              return RET_CODE_FAILURE;
2877          }
2878      }
2879      if (wiphyInfo->wiphyFeatures.supportsRandomMacSchedScan) {
2880          scanFlag |= NL80211_SCAN_FLAG_RANDOM_ADDR;
2881      }
2882      if (wiphyInfo->wiphyFeatures.supportsLowPowerOneshotScan) {
2883          scanFlag |= NL80211_SCAN_FLAG_LOW_POWER;
2884      }
2885      if (scanFlag != 0) {
2886          nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, scanFlag);
2887      }
2888      return RET_CODE_SUCCESS;
2889  }
2890  
ConvertSetsToNetlinkmsg(struct nl_msg * msg,const char * ifName,const WifiPnoSettings * pnoSettings)2891  static int32_t ConvertSetsToNetlinkmsg(struct nl_msg *msg, const char *ifName, const WifiPnoSettings *pnoSettings)
2892  {
2893      int32_t ret;
2894      uint32_t wiphyIndex;
2895      WiphyInfo wiphyInfo;
2896  
2897      (void)memset_s(&wiphyInfo, sizeof(wiphyInfo), 0, sizeof(wiphyInfo));
2898      ret = GetWiphyIndex(ifName, &wiphyIndex);
2899      if (ret != RET_CODE_SUCCESS) {
2900          HILOG_ERROR(LOG_CORE, "%s: GetWiphyIndex failed", __FUNCTION__);
2901          return RET_CODE_FAILURE;
2902      }
2903      ret = GetWiphyInfo(wiphyIndex, &wiphyInfo);
2904      if (ret != RET_CODE_SUCCESS) {
2905          HILOG_ERROR(LOG_CORE, "%s: GetWiphyInfo failed", __FUNCTION__);
2906          return RET_CODE_FAILURE;
2907      }
2908      if (ProcessMatchSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2909          ProcessSsidToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2910          ProcessScanPlanToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2911          ProcessReqflagsToMsg(msg, &wiphyInfo, pnoSettings) != RET_CODE_SUCCESS ||
2912          ProcessFreqToMsg(msg, pnoSettings) != RET_CODE_SUCCESS) {
2913          HILOG_ERROR(LOG_CORE, "%s: Fill parameters to netlink failed.", __FUNCTION__);
2914          return RET_CODE_FAILURE;
2915      }
2916      return RET_CODE_SUCCESS;
2917  }
2918  
WifiStartPnoScan(const char * ifName,const WifiPnoSettings * pnoSettings)2919  int32_t WifiStartPnoScan(const char *ifName, const WifiPnoSettings *pnoSettings)
2920  {
2921      HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2922      uint32_t interfaceId;
2923      struct nl_msg *msg = NULL;
2924      int32_t ret = RET_CODE_FAILURE;
2925  
2926      interfaceId = if_nametoindex(ifName);
2927      if (interfaceId == 0) {
2928          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2929          return RET_CODE_FAILURE;
2930      }
2931      msg = nlmsg_alloc();
2932      if (msg == NULL) {
2933          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2934          return RET_CODE_NOMEM;
2935      }
2936      do {
2937          HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_START_SCHED_SCAN");
2938          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_START_SCHED_SCAN, 0)) {
2939              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2940              break;
2941          }
2942          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2943              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2944              break;
2945          }
2946          if (ConvertSetsToNetlinkmsg(msg, ifName, pnoSettings) != RET_CODE_SUCCESS) {
2947              HILOG_ERROR(LOG_CORE, "%s: ConvertSetsToNetlinkmsg failed.", __FUNCTION__);
2948              break;
2949          }
2950          ret = NetlinkSendCmdSync(msg, NULL, NULL);
2951          if (ret != RET_CODE_SUCCESS) {
2952              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2953          }
2954      } while (0);
2955      nlmsg_free(msg);
2956      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2957      return ret;
2958  }
2959  
WifiStopPnoScan(const char * ifName)2960  int32_t WifiStopPnoScan(const char *ifName)
2961  {
2962      HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
2963      uint32_t interfaceId;
2964      struct nl_msg *msg = NULL;
2965      int32_t ret = RET_CODE_FAILURE;
2966  
2967      interfaceId = if_nametoindex(ifName);
2968      if (interfaceId == 0) {
2969          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
2970          return RET_CODE_FAILURE;
2971      }
2972      msg = nlmsg_alloc();
2973      if (msg == NULL) {
2974          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
2975          return RET_CODE_NOMEM;
2976      }
2977      do {
2978          HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_STOP_SCHED_SCAN");
2979          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_ACK, NL80211_CMD_STOP_SCHED_SCAN, 0)) {
2980              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
2981              break;
2982          }
2983          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
2984              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed.", __FUNCTION__);
2985              break;
2986          }
2987          ret = NetlinkSendCmdSync(msg, NULL, NULL);
2988          if (ret != RET_CODE_SUCCESS) {
2989              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
2990          }
2991      } while (0);
2992      nlmsg_free(msg);
2993      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
2994      return ret;
2995  }
2996  
GetAssociatedInfoHandler(struct nl_msg * msg,void * arg)2997  static int32_t GetAssociatedInfoHandler(struct nl_msg *msg, void *arg)
2998  {
2999      struct nlattr *attr[NL80211_ATTR_MAX + 1];
3000      struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3001      struct nlattr *bss[NL80211_BSS_MAX + 1];
3002      uint32_t status;
3003      AssociatedInfo *associatedInfo = (AssociatedInfo *)arg;
3004      struct nla_policy bssPolicy[NL80211_BSS_MAX + 1];
3005      bssPolicy[NL80211_BSS_BSSID].type = NLA_UNSPEC;
3006      bssPolicy[NL80211_BSS_FREQUENCY].type = NLA_U32;
3007      bssPolicy[NL80211_BSS_STATUS].type = NLA_U32;
3008  
3009      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
3010      if (!attr[NL80211_ATTR_BSS]) {
3011          HILOG_ERROR(LOG_CORE, "%s: BSS info missing!", __FUNCTION__);
3012          return NL_SKIP;
3013      }
3014      if (nla_parse_nested(bss, NL80211_BSS_MAX, attr[NL80211_ATTR_BSS], bssPolicy) < 0 ||
3015          bss[NL80211_BSS_STATUS] == NULL) {
3016          HILOG_INFO(LOG_CORE, "%s: BSS attr or status missing!", __FUNCTION__);
3017          return NL_SKIP;
3018      }
3019      status = nla_get_u32(bss[NL80211_BSS_STATUS]);
3020      if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_FREQUENCY]) {
3021          associatedInfo->associatedFreq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]);
3022      }
3023      if (status == BSS_STATUS_ASSOCIATED && bss[NL80211_BSS_BSSID]) {
3024          if (memcpy_s(associatedInfo->associatedBssid, ETH_ADDR_LEN,
3025              nla_data(bss[NL80211_BSS_BSSID]), ETH_ADDR_LEN) != EOK) {
3026              HILOG_ERROR(LOG_CORE, "%s: memcpy_s failed!", __FUNCTION__);
3027              return NL_SKIP;
3028          }
3029      }
3030      return NL_SKIP;
3031  }
3032  
WifiGetAssociatedInfo(const char * ifName,AssociatedInfo * associatedInfo)3033  static int32_t WifiGetAssociatedInfo(const char *ifName, AssociatedInfo *associatedInfo)
3034  {
3035      HILOG_INFO(LOG_CORE, "hal enter %{public}s ifName:%{public}s", __FUNCTION__, ifName);
3036      struct nl_msg *msg = NULL;
3037      uint32_t interfaceId;
3038      int32_t ret = RET_CODE_FAILURE;
3039  
3040      interfaceId = if_nametoindex(ifName);
3041      if (interfaceId == 0) {
3042          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3043          return RET_CODE_FAILURE;
3044      }
3045      msg = nlmsg_alloc();
3046      if (msg == NULL) {
3047          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3048          return RET_CODE_NOMEM;
3049      }
3050      do {
3051          HILOG_INFO(LOG_CORE, "genlmsg_put NL80211_CMD_GET_SCAN");
3052          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, NLM_F_DUMP, NL80211_CMD_GET_SCAN, 0)) {
3053              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3054              break;
3055          }
3056          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3057              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3058              break;
3059          }
3060          ret = NetlinkSendCmdSync(msg, GetAssociatedInfoHandler, associatedInfo);
3061          if (ret != RET_CODE_SUCCESS) {
3062              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
3063          }
3064      } while (0);
3065      nlmsg_free(msg);
3066      HILOG_INFO(LOG_CORE, "hal exit %{public}s", __FUNCTION__);
3067      return ret;
3068  }
3069  
FillSignalExt(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)3070  static void FillSignalExt(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
3071  {
3072      if (size < NL80211_STA_INFO_MAX + 1) {
3073          HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
3074          return;
3075      }
3076  
3077      if (stats[NL80211_STA_INFO_NOISE] != NULL) {
3078          signalResult->currentNoise = nla_get_s32(stats[NL80211_STA_INFO_NOISE]);
3079      }
3080      if (stats[NL80211_STA_INFO_SNR] != NULL) {
3081          signalResult->currentSnr = nla_get_s32(stats[NL80211_STA_INFO_SNR]);
3082      }
3083      if (stats[NL80211_STA_INFO_CNAHLOAD] != NULL) {
3084          signalResult->currentChload = nla_get_s32(stats[NL80211_STA_INFO_CNAHLOAD]);
3085      }
3086      if (stats[NL80211_STA_INFO_UL_DELAY] != NULL) {
3087          signalResult->currentUlDelay = nla_get_s32(stats[NL80211_STA_INFO_UL_DELAY]);
3088      }
3089  }
3090  
FillSignalRate(struct nlattr ** stats,uint32_t size,struct SignalResult * signalResult)3091  static void FillSignalRate(struct nlattr **stats, uint32_t size, struct SignalResult *signalResult)
3092  {
3093      struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
3094      struct nla_policy ratePolicy[NL80211_RATE_INFO_MAX + 1];
3095      ratePolicy[NL80211_RATE_INFO_BITRATE].type = NLA_U16;
3096      ratePolicy[NL80211_RATE_INFO_BITRATE32].type = NLA_U32;
3097  
3098      if (size < NL80211_STA_INFO_MAX + 1) {
3099          HILOG_ERROR(LOG_CORE, "%{public}s: size of stats is not enough", __FUNCTION__);
3100          return;
3101      }
3102      if (stats[NL80211_STA_INFO_RX_BITRATE] != NULL &&
3103          nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_RX_BITRATE], ratePolicy) == 0) {
3104          if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
3105              signalResult->rxBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
3106          } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
3107              signalResult->rxBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
3108          }
3109      }
3110      if (stats[NL80211_STA_INFO_TX_BITRATE] != NULL &&
3111          nla_parse_nested(rate, NL80211_RATE_INFO_MAX, stats[NL80211_STA_INFO_TX_BITRATE], ratePolicy) == 0) {
3112          if (rate[NL80211_RATE_INFO_BITRATE32] != NULL) {
3113              signalResult->txBitrate = (int32_t)nla_get_u32(rate[NL80211_RATE_INFO_BITRATE32]);
3114          } else if (rate[NL80211_RATE_INFO_BITRATE] != NULL) {
3115              signalResult->txBitrate = nla_get_u16(rate[NL80211_RATE_INFO_BITRATE]);
3116          }
3117      }
3118  }
3119  
SignalInfoHandler(struct nl_msg * msg,void * arg)3120  static int32_t SignalInfoHandler(struct nl_msg *msg, void *arg)
3121  {
3122      struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3123      struct nlattr *attr[NL80211_ATTR_MAX + 1];
3124      struct nlattr *stats[NL80211_STA_INFO_MAX + 1];
3125      struct nla_policy statsPolicy[NL80211_STA_INFO_MAX + 1];
3126      struct SignalResult *signalResult = (struct SignalResult *)arg;
3127      statsPolicy[NL80211_STA_INFO_SIGNAL].type = NLA_S8;
3128      statsPolicy[NL80211_STA_INFO_RX_BYTES].type = NLA_U32;
3129      statsPolicy[NL80211_STA_INFO_TX_BYTES].type = NLA_U32;
3130      statsPolicy[NL80211_STA_INFO_RX_PACKETS].type = NLA_U32;
3131      statsPolicy[NL80211_STA_INFO_TX_PACKETS].type = NLA_U32;
3132      statsPolicy[NL80211_STA_INFO_TX_FAILED].type = NLA_U32;
3133      statsPolicy[NL80211_STA_INFO_NOISE].type = NLA_S32;
3134      statsPolicy[NL80211_STA_INFO_SNR].type = NLA_S32;
3135      statsPolicy[NL80211_STA_INFO_CNAHLOAD].type = NLA_S32;
3136      statsPolicy[NL80211_STA_INFO_UL_DELAY].type = NLA_S32;
3137  
3138      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
3139      if (!attr[NL80211_ATTR_STA_INFO]) {
3140          HILOG_ERROR(LOG_CORE, "%s: sta stats missing!", __FUNCTION__);
3141          return NL_SKIP;
3142      }
3143      if (nla_parse_nested(stats, NL80211_STA_INFO_MAX, attr[NL80211_ATTR_STA_INFO], statsPolicy) < 0) {
3144          HILOG_ERROR(LOG_CORE, "%s: nla_parse_nested NL80211_ATTR_STA_INFO failed!", __FUNCTION__);
3145          return NL_SKIP;
3146      }
3147      if (stats[NL80211_STA_INFO_SIGNAL] != NULL) {
3148          signalResult->currentRssi = nla_get_s8(stats[NL80211_STA_INFO_SIGNAL]);
3149      }
3150      if (stats[NL80211_STA_INFO_TX_BYTES] != NULL) {
3151          signalResult->currentTxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_BYTES]);
3152      }
3153      if (stats[NL80211_STA_INFO_RX_BYTES] != NULL) {
3154          signalResult->currentRxBytes = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_BYTES]);
3155      }
3156      if (stats[NL80211_STA_INFO_TX_PACKETS] != NULL) {
3157          signalResult->currentTxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_PACKETS]);
3158      }
3159      if (stats[NL80211_STA_INFO_RX_PACKETS] != NULL) {
3160          signalResult->currentRxPackets = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_RX_PACKETS]);
3161      }
3162      if (stats[NL80211_STA_INFO_TX_FAILED] != NULL) {
3163          signalResult->currentTxFailed = (int32_t)nla_get_u32(stats[NL80211_STA_INFO_TX_FAILED]);
3164      }
3165      FillSignalExt(stats, NL80211_STA_INFO_MAX + 1, signalResult);
3166      FillSignalRate(stats, NL80211_STA_INFO_MAX + 1, signalResult);
3167  
3168      return NL_SKIP;
3169  }
3170  
ClientGetApBandwidth(const char * ifName,uint8_t * bandwidth)3171  int32_t ClientGetApBandwidth(const char *ifName, uint8_t *bandwidth)
3172  {
3173      if (ifName == NULL || bandwidth == NULL) {
3174          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3175          return RET_CODE_FAILURE;
3176      }
3177  
3178      const char *cmd = CMD_GET_AP_BANDWIDTH;
3179      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
3180      WifiPrivCmd out = {0};
3181      out.buf = buf;
3182      out.size = MAX_PRIV_CMD_SIZE;
3183      int32_t ret = SendCommandToDriver(cmd, strlen(cmd), ifName, &out);
3184      if (ret != RET_CODE_SUCCESS) {
3185          HILOG_ERROR(LOG_CORE, "%s: send command to driver failed, code=%d", __FUNCTION__, ret);
3186          return ret;
3187      }
3188      *bandwidth = *out.buf;
3189  
3190      HILOG_INFO(LOG_CORE, "%s: AP bandwidth: %d", __FUNCTION__, *bandwidth);
3191      return RET_CODE_SUCCESS;
3192  }
3193  
WifiGetSignalPollInfo(const char * ifName,struct SignalResult * signalResult)3194  int32_t WifiGetSignalPollInfo(const char *ifName, struct SignalResult *signalResult)
3195  {
3196      struct nl_msg *msg = NULL;
3197      uint32_t interfaceId;
3198      int32_t ret = RET_CODE_FAILURE;
3199      AssociatedInfo associatedInfo;
3200      (void)memset_s(&associatedInfo, sizeof(associatedInfo), 0, sizeof(associatedInfo));
3201  
3202      if (ifName == NULL || signalResult == NULL) {
3203          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3204          return RET_CODE_FAILURE;
3205      }
3206      interfaceId = if_nametoindex(ifName);
3207      if (interfaceId == 0) {
3208          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3209          return RET_CODE_FAILURE;
3210      }
3211      if (WifiGetAssociatedInfo(ifName, &associatedInfo) != RET_CODE_SUCCESS) {
3212          HILOG_ERROR(LOG_CORE, "%s: WifiGetAssociatedInfo failed", __FUNCTION__);
3213          return RET_CODE_FAILURE;
3214      }
3215      signalResult->associatedFreq = (int32_t)(associatedInfo.associatedFreq);
3216      msg = nlmsg_alloc();
3217      if (msg == NULL) {
3218          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3219          return RET_CODE_NOMEM;
3220      }
3221      do {
3222          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_GET_STATION, 0)) {
3223              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3224              break;
3225          }
3226          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3227              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3228              break;
3229          }
3230          if (nla_put(msg, NL80211_ATTR_MAC, ETH_ADDR_LEN, associatedInfo.associatedBssid) != RET_CODE_SUCCESS) {
3231              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId faile", __FUNCTION__);
3232              break;
3233          }
3234          ret = NetlinkSendCmdSync(msg, SignalInfoHandler, signalResult);
3235          if (ret != RET_CODE_SUCCESS) {
3236              HILOG_ERROR(LOG_CORE, "%s: send cmd failed", __FUNCTION__);
3237          }
3238      } while (0);
3239      nlmsg_free(msg);
3240      return ret;
3241  }
3242  
WifiEventTxStatus(const char * ifName,struct nlattr ** attr)3243  void WifiEventTxStatus(const char *ifName, struct nlattr **attr)
3244  {
3245      if (ifName == NULL || attr == NULL) {
3246          HILOG_ERROR(LOG_CORE, "%{public}s: is null", __FUNCTION__);
3247          return;
3248      }
3249      if (WaitStartActionLock() == RET_CODE_FAILURE) {
3250          HILOG_ERROR(LOG_CORE, "%{public}s: WaitStartActionLock error", __FUNCTION__);
3251          return;
3252      }
3253      g_cookieSucess = (uint32_t)nla_get_u64(attr[NL80211_ATTR_COOKIE]);
3254      HILOG_DEBUG(LOG_CORE, "%{public}s: g_cookieStart = %{public}u g_cookieSucess = %{public}u "
3255          "ack = %{public}d", __FUNCTION__, g_cookieStart, g_cookieSucess,
3256          attr[NL80211_ATTR_ACK] != NULL);
3257  
3258      if (g_cookieStart != g_cookieSucess) {
3259          HILOG_ERROR(LOG_CORE, "%{public}s: ignore cookie", __FUNCTION__);
3260          return;
3261      }
3262      WifiActionData actionData;
3263      uint8_t action[MAX_INDEX] = { 0 };
3264      for (int i = 0; i < ACK_INDEX; i++) {
3265          action[i] = (uint8_t)((g_cookieSucess >> (i * BYTE_UNIT_8)) & 0xFF);
3266      }
3267      if (attr[NL80211_ATTR_ACK] == NULL) {
3268          action[ACK_INDEX] = NO_ACK;
3269      } else {
3270          action[ACK_INDEX] = ACK;
3271      }
3272      actionData.data = action;
3273      actionData.dataLen = MAX_INDEX;
3274      WifiEventReport("p2p0", WIFI_EVENT_ACTION_RECEIVED, &actionData);
3275  }
3276  
WifiSendActionFrameHandler(struct nl_msg * msg,void * arg)3277  static int32_t WifiSendActionFrameHandler(struct nl_msg *msg, void *arg)
3278  {
3279      struct nlattr *attr[NL80211_ATTR_MAX + 1];
3280      struct genlmsghdr *hdr = nlmsg_data(nlmsg_hdr(msg));
3281      if (hdr == NULL) {
3282          HILOG_ERROR(LOG_CORE, "%s: get nlmsg header fail", __FUNCTION__);
3283          return NL_SKIP;
3284      }
3285      nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(hdr, 0), genlmsg_attrlen(hdr, 0), NULL);
3286      if (!attr[NL80211_ATTR_COOKIE]) {
3287          HILOG_ERROR(LOG_CORE, "%{public}s: no attr cookie", __FUNCTION__);
3288          return NL_SKIP;
3289      }
3290      g_cookieStart = (uint32_t)nla_get_u64(attr[NL80211_ATTR_COOKIE]);
3291      HILOG_DEBUG(LOG_CORE, "%{public}s: g_cookieStart = %{public}u", __FUNCTION__, g_cookieStart);
3292      return NL_SKIP;
3293  }
3294  
WifiSendActionFrame(const char * ifName,uint32_t freq,const uint8_t * frameData,uint32_t frameDataLen)3295  int32_t WifiSendActionFrame(const char *ifName, uint32_t freq, const uint8_t *frameData, uint32_t frameDataLen)
3296  {
3297      int32_t ret = RET_CODE_FAILURE;
3298      struct nl_msg *msg = NULL;
3299      uint32_t interfaceId;
3300      if (ifName == NULL || freq == 0 || frameData == NULL || frameDataLen == 0) {
3301          HILOG_ERROR(LOG_CORE, "%{public}s: param is NULL.", __FUNCTION__);
3302          return RET_CODE_FAILURE;
3303      }
3304      interfaceId = if_nametoindex(ifName);
3305      if (interfaceId == 0) {
3306          HILOG_ERROR(LOG_CORE, "%{public}s: if_nametoindex failed", __FUNCTION__);
3307          return RET_CODE_FAILURE;
3308      }
3309      msg = nlmsg_alloc();
3310      if (msg == NULL) {
3311          HILOG_ERROR(LOG_CORE, "%{public}s: nlmsg alloc failed", __FUNCTION__);
3312          return RET_CODE_NOMEM;
3313      }
3314      do {
3315          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_FRAME, 0)) {
3316              HILOG_ERROR(LOG_CORE, "%{public}s: genlmsg_put faile", __FUNCTION__);
3317              break;
3318          }
3319          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3320              HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 interfaceId failed", __FUNCTION__);
3321              break;
3322          }
3323          if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) != RET_CODE_SUCCESS) {
3324              HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 freq failed", __FUNCTION__);
3325              break;
3326          }
3327          if (strncmp(ifName, STR_CHBA, strlen(STR_CHBA)) != 0 &&
3328              nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK) != RET_CODE_SUCCESS) {
3329              HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 offchannel failed", __FUNCTION__);
3330              break;
3331          }
3332          if (nla_put(msg, NL80211_ATTR_FRAME, frameDataLen, frameData) != RET_CODE_SUCCESS) {
3333              HILOG_ERROR(LOG_CORE, "%{public}s: nla_put_u32 frameData failed", __FUNCTION__);
3334              break;
3335          }
3336          g_cookieStart = 0;
3337          ret = NetlinkSendCmdSync(msg, WifiSendActionFrameHandler, NULL);
3338          if (ret != RET_CODE_SUCCESS) {
3339              HILOG_ERROR(LOG_CORE, "%{public}s: send action failed", __FUNCTION__);
3340          }
3341      } while (0);
3342      nlmsg_free(msg);
3343      return ret;
3344  }
3345  
WifiRegisterActionFrameReceiver(const char * ifName,const uint8_t * match,uint32_t matchLen)3346  int32_t WifiRegisterActionFrameReceiver(const char *ifName, const uint8_t *match, uint32_t matchLen)
3347  {
3348      int32_t ret = RET_CODE_FAILURE;
3349      struct nl_msg *msg = NULL;
3350      uint32_t interfaceId;
3351      if (ifName == NULL || match == NULL || matchLen == 0) {
3352          HILOG_ERROR(LOG_CORE, "%s: param is NULL.", __FUNCTION__);
3353          return RET_CODE_FAILURE;
3354      }
3355      interfaceId = if_nametoindex(ifName);
3356      if (interfaceId == 0) {
3357          HILOG_ERROR(LOG_CORE, "%s: if_nametoindex failed", __FUNCTION__);
3358          return RET_CODE_FAILURE;
3359      }
3360      msg = nlmsg_alloc();
3361      if (msg == NULL) {
3362          HILOG_ERROR(LOG_CORE, "%s: nlmsg alloc failed", __FUNCTION__);
3363          return RET_CODE_NOMEM;
3364      }
3365      do {
3366          if (!genlmsg_put(msg, 0, 0, g_wifiHalInfo.familyId, 0, 0, NL80211_CMD_REGISTER_FRAME, 0)) {
3367              HILOG_ERROR(LOG_CORE, "%s: genlmsg_put faile", __FUNCTION__);
3368              break;
3369          }
3370          if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, interfaceId) != RET_CODE_SUCCESS) {
3371              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 interfaceId failed", __FUNCTION__);
3372              break;
3373          }
3374          if (nla_put(msg, NL80211_ATTR_FRAME_MATCH, matchLen, match) != RET_CODE_SUCCESS) {
3375              HILOG_ERROR(LOG_CORE, "%s: nla_put_u32 frameData failed", __FUNCTION__);
3376              break;
3377          }
3378          if (g_wifiHalInfo.ctrlSock == NULL) {
3379              HILOG_ERROR(LOG_CORE, "%s: ctrlSock is NULL", __FUNCTION__);
3380              break;
3381          }
3382          ret = nl_send_auto(g_wifiHalInfo.ctrlSock, msg);
3383          if (ret < 0) {
3384              HILOG_ERROR(LOG_CORE, "%s: register ctrl sock failed", __FUNCTION__);
3385              break;
3386          }
3387          ret = RET_CODE_SUCCESS;
3388      } while (0);
3389      nlmsg_free(msg);
3390      return ret;
3391  }
3392  
WifiSetPowerSaveMode(const char * ifName,int32_t frequency,int32_t mode)3393  int32_t WifiSetPowerSaveMode(const char *ifName, int32_t frequency, int32_t mode)
3394  {
3395      int32_t ret = RET_CODE_FAILURE;
3396      char cmdBuf[MAX_CMD_LEN] = {0};
3397      uint32_t cmdLen;
3398      uint16_t state;
3399      cmdLen = strlen(CMD_SET_STA_PM_ON);
3400      if (cmdLen >= MAX_CMD_LEN - 1) {
3401          HILOG_ERROR(LOG_CORE, "%{public}s: the length of input data is too large.", __FUNCTION__);
3402          return ret;
3403      }
3404  
3405      ret = snprintf_s(cmdBuf, MAX_CMD_LEN, MAX_CMD_LEN - 1, "%s %d", CMD_SET_STA_PM_ON, mode);
3406      if (ret < RET_CODE_SUCCESS) {
3407          HILOG_ERROR(LOG_CORE, "%{public}s: ifName: %{public}s, ret = %{public}d", __FUNCTION__, ifName, ret);
3408          return RET_CODE_FAILURE;
3409      }
3410  
3411      if (GetInterfaceState(ifName, &state) != RET_CODE_SUCCESS || (state & INTERFACE_UP) == 0) {
3412          HILOG_ERROR(LOG_CORE, "%{public}s: interface state is not OK.", __FUNCTION__);
3413          return RET_CODE_NETDOWN;
3414      }
3415      uint8_t buf[MAX_PRIV_CMD_SIZE] = {0};
3416      WifiPrivCmd out = {0};
3417      out.buf = buf;
3418      out.size = MAX_PRIV_CMD_SIZE;
3419      return SendCommandToDriver(cmdBuf, MAX_CMD_LEN, ifName, &out);
3420  }
3421  
3422  int g_dpiNtlFd = -1;
3423  
NtlLinkInit()3424  static int32_t NtlLinkInit()
3425  {
3426      struct sockaddr_nl ntlAddr;
3427      int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_HW_DPI);
3428      if (fd < 0) {
3429          HILOG_ERROR(LOG_CORE, "Cant create netlink socket, err: %{public}s", strerror(errno));
3430          return RET_CODE_FAILURE;
3431      }
3432  
3433      memset_s(&ntlAddr, sizeof(ntlAddr), 0, sizeof(ntlAddr));
3434      ntlAddr.nl_family = AF_NETLINK;
3435      ntlAddr.nl_pid = getpid();
3436      ntlAddr.nl_groups = 0;
3437  
3438      if (bind(fd, (struct sockaddr*)&ntlAddr, sizeof(ntlAddr)) != 0) {
3439          HILOG_ERROR(LOG_CORE, "Cant bind netlink socket.");
3440          close(fd);
3441          return RET_CODE_FAILURE;
3442      }
3443  
3444      return fd;
3445  }
3446  
SendMsgToKernel(unsigned short nlmsgType,int opt,char * data,int datalen,int skfd)3447  static int32_t SendMsgToKernel(unsigned short nlmsgType, int opt, char *data, int datalen, int skfd)
3448  {
3449      struct sockaddr_nl ntlAddr;
3450      struct HwCommMsgT *ntlMsg = NULL;
3451      unsigned int len = datalen + sizeof(struct HwCommMsgT);
3452      int ret = -1;
3453      if (len <= 0) {
3454          return RET_CODE_FAILURE;
3455      }
3456  
3457      ntlMsg = (struct HwCommMsgT *)OsalMemAlloc(len);
3458      if (ntlMsg == NULL) {
3459          return RET_CODE_FAILURE;
3460      }
3461  
3462      if (memset_s(&ntlAddr, sizeof(ntlAddr), 0, sizeof(ntlAddr)) != EOK) {
3463          HILOG_ERROR(LOG_CORE, "ntlAddr memset_s is failed");
3464          OsalMemFree(ntlMsg);
3465          ntlMsg = NULL;
3466          return RET_CODE_FAILURE;
3467      }
3468      ntlAddr.nl_family = AF_NETLINK;
3469      ntlAddr.nl_pid = 0;
3470      ntlAddr.nl_groups = 0;
3471  
3472      if (memset_s(ntlMsg, len, 0, len) != EOK) {
3473          HILOG_ERROR(LOG_CORE, "ntlMsg memset_s is failed");
3474          OsalMemFree(ntlMsg);
3475          ntlMsg = NULL;
3476          return RET_CODE_FAILURE;
3477      }
3478      ntlMsg->hdr.nlmsg_len = NLMSG_LENGTH(DPI_MSG_LEN + datalen + 1);
3479      ntlMsg->hdr.nlmsg_flags = 0;
3480      ntlMsg->hdr.nlmsg_type = nlmsgType;
3481      ntlMsg->hdr.nlmsg_pid = (unsigned int)(getpid());
3482      ntlMsg->opt = opt;
3483  
3484      if (data != NULL && datalen != 0) {
3485          if (memcpy_s(ntlMsg->data, datalen, data, datalen) != EOK) {
3486              HILOG_ERROR(LOG_CORE, "memcpy_s is failed");
3487              OsalMemFree(ntlMsg);
3488              ntlMsg = NULL;
3489              return RET_CODE_FAILURE;
3490          }
3491      }
3492      ret = sendto(skfd, ntlMsg, ntlMsg->hdr.nlmsg_len, 0, (struct sockaddr*)&ntlAddr, sizeof(ntlAddr));
3493      OsalMemFree(ntlMsg);
3494      ntlMsg = NULL;
3495      return ret;
3496  }
3497  
WifiSetDpiMarkRule(int32_t uid,int32_t protocol,int32_t enable)3498  int32_t WifiSetDpiMarkRule(int32_t uid, int32_t protocol, int32_t enable)
3499  {
3500      DpiMarkRuleT dmr;
3501      if (g_dpiNtlFd < 0) {
3502          g_dpiNtlFd = NtlLinkInit();
3503          if (g_dpiNtlFd < 0) {
3504              HILOG_ERROR(LOG_CORE, "Failed to initialize netlink socket.");
3505              return RET_CODE_FAILURE;
3506          }
3507  
3508          HILOG_INFO(LOG_CORE, "Netlink socket created OK.");
3509          if (SendMsgToKernel(NETLINK_REG_TO_KERNEL, 0, NULL, 0, g_dpiNtlFd) < 0) {
3510              close(g_dpiNtlFd);
3511              g_dpiNtlFd = -1;
3512              HILOG_ERROR(LOG_CORE, "Failed to register to kernel.");
3513              return RET_CODE_FAILURE;
3514          }
3515      }
3516  
3517      if (enable == 0) {
3518          if (SendMsgToKernel(NETLINK_STOP_MARK, 0, NULL, 0, g_dpiNtlFd) < 0) {
3519              close(g_dpiNtlFd);
3520              g_dpiNtlFd = -1;
3521              HILOG_ERROR(LOG_CORE, "Failed to send msg to kernel.");
3522              return RET_CODE_FAILURE;
3523          }
3524          HILOG_INFO(LOG_CORE, "Disable Dpi.");
3525          return RET_CODE_SUCCESS;
3526      } else {
3527          if (SendMsgToKernel(NETLINK_START_MARK, 0, NULL, 0, g_dpiNtlFd) < 0) {
3528              close(g_dpiNtlFd);
3529              g_dpiNtlFd = -1;
3530              HILOG_ERROR(LOG_CORE, "Failed to send msg to kernel.");
3531              return RET_CODE_FAILURE;
3532          }
3533      }
3534  
3535      dmr.dmrAppUid = (unsigned int)uid;
3536      dmr.dmrRule.ruleType = DMR_MT_TP;
3537      dmr.dmrRule.ruleBody.matchTpVal = protocol;
3538      dmr.dmrRule.markNum = WZRY_MARK_NUM;
3539  
3540      if (SendMsgToKernel(NETLINK_SET_RULE_TO_KERNEL, 0, (char *)&dmr, sizeof(dmr), g_dpiNtlFd) < 0) {
3541          close(g_dpiNtlFd);
3542          g_dpiNtlFd = -1;
3543          HILOG_ERROR(LOG_CORE, "Failed to add rule.");
3544          return RET_CODE_FAILURE;
3545      }
3546  
3547      HILOG_INFO(LOG_CORE, "SetDpiMarkRule OK.");
3548      return RET_CODE_SUCCESS;
3549  }
3550