lin
2025-08-21 57113df3a0e2be01232281fad9a5f2c060567981
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <netlink/genl/genl.h>
 
#include "wifi_command.h"
 
static int ackHandler(struct nl_msg *msg, void *arg)
{
   *((int *)arg) = 0;
 
   return NL_STOP;
}
 
static int finishHandler(struct nl_msg *msg, void *arg)
{
   *((int *)arg) = 0;
 
   return NL_SKIP;
}
 
static int errorHandler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg)
{
   *((int *)arg) = 0;
 
   return NL_SKIP;
}
 
static int msgHandler(struct nl_msg *msg, void *arg)
{
   struct nlattr *attr[NL80211_ATTR_MAX + 1];
   WifiCommand *cmd = (WifiCommand *)arg;
   struct genlmsghdr *gnlh = (struct genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
 
   nla_parse(attr, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
           genlmsg_attrlen(gnlh, 0), NULL);
 
   cmd->parser(attr);
 
   return NL_SKIP;
}
 
wifi_error sendMsg(struct nl_sock *sk, struct nl_msg *msg, void *arg)
{
   int err;
   struct nl_cb *cb;
 
           cb = nl_cb_alloc(NL_CB_DEFAULT);
   if (cb == NULL) {
       ALOGE("%s: alloc cb failed");
       return WIFI_ERROR_OUT_OF_MEMORY;
   }
 
   nl_cb_err(cb, NL_CB_CUSTOM, errorHandler, &err);
   nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finishHandler, &err);
   nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ackHandler, &err);
   nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, msgHandler, arg);
 
   err = nl_send_auto_complete(sk, msg);
   while (err > 0) {
       int res = nl_recvmsgs(sk, cb);
       if (res < 0)
           ALOGE("%s: recv msg failed: %d", res);
   }
 
   nl_cb_put(cb);
 
   return err ? WIFI_ERROR_UNKNOWN : WIFI_SUCCESS;
}
 
wifi_error WifiCommand::send()
{
   return sendMsg(sock, nlmsg(), (void *)this);
}
 
WifiCommand::~WifiCommand()
{
   nlmsg_free(msg);
}
 
WifiCommand::WifiCommand(struct nl_sock *sk, int family_id, int flags, int nl80211_cmd)
{
   sock = sk;
 
   msg = nlmsg_alloc();
   if (msg)
       genlmsg_put(msg, 0, 0, family_id, 0, flags, nl80211_cmd, 0);
   else
       ALOGE("nlmsg alloc failed, nl80211 cmd: %d", nl80211_cmd);
}