Skip to content

Commit db9f97f

Browse files
rado17krish2718
authored andcommitted
[nrf noup] Monitor supplicant state and inform applications
Add a control connection handler for monitoring the supplicant state at real time and notify interested applications. Signed-off-by: Ravi Dondaputi <[email protected]>
1 parent 8b0abe8 commit db9f97f

File tree

5 files changed

+222
-3
lines changed

5 files changed

+222
-3
lines changed

wpa_supplicant/ctrl_iface_zephyr.c

Lines changed: 147 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,114 @@
88

99
#include "ctrl_iface_zephyr.h"
1010

11+
12+
static int wpa_supplicant_ctrl_mon_iface_attach(struct wpa_ctrl_mon **head, int sock)
13+
{
14+
struct wpa_ctrl_mon *dst;
15+
16+
dst = os_zalloc(sizeof(*dst));
17+
if (dst == NULL)
18+
return -1;
19+
20+
dst->sock = sock;
21+
dst->debug_level = MSG_INFO;
22+
dst->next = *head;
23+
*head = dst;
24+
return 0;
25+
}
26+
27+
28+
static int wpa_supplicant_ctrl_mon_iface_detach(struct wpa_ctrl_mon **head, int sock)
29+
{
30+
struct wpa_ctrl_mon *dst, *prev = NULL;
31+
32+
dst = *head;
33+
while (dst) {
34+
if (dst->sock == sock) {
35+
if (prev == NULL) {
36+
*head = dst->next;
37+
} else {
38+
prev->next = dst->next;
39+
}
40+
os_free(dst);
41+
return 0;
42+
}
43+
prev = dst;
44+
dst = dst->next;
45+
}
46+
return -1;
47+
}
48+
49+
static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
50+
const char *ifname, int sock,
51+
struct wpa_ctrl_mon **head,
52+
int level, const char *buf,
53+
size_t len)
54+
{
55+
struct wpa_ctrl_mon *dst, *next;
56+
char levelstr[64];
57+
int idx;
58+
struct conn_msg msg;
59+
60+
dst = *head;
61+
if (sock < 0 || dst == NULL)
62+
return;
63+
64+
if (ifname)
65+
os_snprintf(levelstr, sizeof(levelstr), "IFNAME=%s <%d>",
66+
ifname, level);
67+
else
68+
os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
69+
70+
idx = 0;
71+
while (dst) {
72+
next = dst->next;
73+
if (level >= dst->debug_level) {
74+
memcpy(&msg.msg, buf, len);
75+
msg.msg_len = len;
76+
if (send(dst->sock, &msg, sizeof(msg), 0) < 0) {
77+
wpa_printf(MSG_ERROR,
78+
"sendto(CTRL_IFACE monitor): %s",
79+
strerror(errno));
80+
dst->errors++;
81+
} else {
82+
dst->errors = 0;
83+
}
84+
}
85+
idx++;
86+
dst = next;
87+
}
88+
}
89+
90+
static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
91+
enum wpa_msg_type type,
92+
const char *txt, size_t len)
93+
{
94+
struct wpa_supplicant *wpa_s = ctx;
95+
96+
if (!wpa_s)
97+
return;
98+
99+
if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) {
100+
struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;
101+
102+
if (priv->ctrl_dst) {
103+
wpa_supplicant_ctrl_iface_send(wpa_s, type != WPA_MSG_PER_INTERFACE ?
104+
NULL : wpa_s->ifname,
105+
priv->sock_pair[0],
106+
&priv->ctrl_dst, level, txt, len);
107+
}
108+
}
109+
110+
if (type == WPA_MSG_ONLY_GLOBAL || !wpa_s->ctrl_iface)
111+
return;
112+
113+
wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock_pair[0],
114+
&wpa_s->ctrl_iface->ctrl_dst,
115+
level, txt, len);
116+
}
117+
118+
11119
static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
12120
void *sock_ctx)
13121
{
@@ -39,8 +147,26 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
39147
while (*pos == ' ')
40148
pos++;
41149

42-
reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos,
150+
if (os_strcmp(pos, "ATTACH") == 0) {
151+
if (wpa_supplicant_ctrl_mon_iface_attach(&wpa_s->ctrl_iface->ctrl_dst,
152+
wpa_s->ctrl_iface->mon_sock_pair[1])){
153+
reply_len = 1;
154+
}
155+
else {
156+
reply_len = 2;
157+
}
158+
} else if (os_strcmp(pos, "DETACH") == 0) {
159+
if (wpa_supplicant_ctrl_mon_iface_detach(&wpa_s->ctrl_iface->ctrl_dst,
160+
wpa_s->ctrl_iface->mon_sock_pair[1])) {
161+
reply_len = 1;
162+
}
163+
else {
164+
reply_len = 2;
165+
}
166+
} else {
167+
reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos,
43168
&reply_len);
169+
}
44170

45171
if (reply) {
46172
send(sock, reply, reply_len, 0);
@@ -86,6 +212,8 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
86212
eloop_register_read_sock(priv->sock_pair[1], wpa_supplicant_ctrl_iface_receive,
87213
wpa_s, priv);
88214

215+
wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
216+
89217
return priv;
90218

91219
fail:
@@ -154,8 +282,26 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
154282
while (*pos == ' ')
155283
pos++;
156284

285+
if (os_strcmp(pos, "ATTACH") == 0) {
286+
if (wpa_supplicant_ctrl_mon_iface_attach(&global->ctrl_iface->ctrl_dst,
287+
global->ctrl_iface->mon_sock_pair[1])) {
288+
reply_len = 1;
289+
}
290+
else {
291+
reply_len = 2;
292+
}
293+
} else if (os_strcmp(pos, "DETACH") == 0) {
294+
if (wpa_supplicant_ctrl_mon_iface_detach(&global->ctrl_iface->ctrl_dst,
295+
global->ctrl_iface->mon_sock_pair[1])) {
296+
reply_len = 1;
297+
}
298+
else {
299+
reply_len = 2;
300+
}
301+
} else {
157302
reply = wpa_supplicant_global_ctrl_iface_process(global, pos,
158303
&reply_len);
304+
}
159305

160306
if (reply) {
161307
send(sock, reply, reply_len, 0);

wpa_supplicant/ctrl_iface_zephyr.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,37 @@
1616
#include "ctrl_iface.h"
1717
#include "common/wpa_ctrl.h"
1818

19+
#define MAX_CTRL_MSG_LEN 256
20+
/**
21+
* struct wpa_ctrl_mon - Data structure of control interface monitors
22+
*
23+
* This structure is used to store information about registered control
24+
* interface monitors into struct wpa_supplicant.
25+
*/
26+
struct wpa_ctrl_mon {
27+
struct wpa_ctrl_mon *next;
28+
int sock;
29+
int debug_level;
30+
int errors;
31+
};
32+
1933
struct ctrl_iface_priv {
2034
struct wpa_supplicant *wpa_s;
2135
/* 0 - wpa_cli, 1 - ctrl_iface */
2236
int sock_pair[2];
37+
int mon_sock_pair[2];
38+
struct wpa_ctrl_mon *ctrl_dst;
2339
};
2440

2541
struct ctrl_iface_global_priv {
2642
struct wpa_global *global;
2743
/* 0 - wpa_cli, 1 - ctrl_iface */
2844
int sock_pair[2];
45+
int mon_sock_pair[2];
46+
struct wpa_ctrl_mon *ctrl_dst;
2947
};
3048

49+
struct conn_msg {
50+
char msg[MAX_CTRL_MSG_LEN];
51+
int msg_len;
52+
};

wpa_supplicant/events.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3589,7 +3589,8 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
35893589
MAC2STR(bssid), reason_code,
35903590
locally_generated ? " locally_generated=1" : "");
35913591
#ifdef CONFIG_ZEPHYR
3592-
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_DISCONNECT_RESULT, 0);
3592+
int status = 0;
3593+
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_DISCONNECT_RESULT, (void *)&status, sizeof(int));
35933594
#endif /* CONFIG_ZEPHYR */
35943595
}
35953596
}

wpa_supplicant/wpa_cli_zephyr.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "common/ieee802_11_defs.h"
2121

2222
#include "supp_main.h"
23+
#include "supp_events.h"
2324
#include "wpa_cli_zephyr.h"
2425
#include "ctrl_iface_zephyr.h"
2526

@@ -30,6 +31,7 @@
3031
#define MAX_ARGS 32
3132

3233
struct wpa_ctrl *ctrl_conn;
34+
struct wpa_ctrl *mon_conn;
3335
struct wpa_ctrl *global_ctrl_conn;
3436
char *ifname_prefix = NULL;
3537
extern struct wpa_global *global;
@@ -92,16 +94,63 @@ static void wpa_cli_close_connection(void)
9294
ctrl_conn = NULL;
9395
}
9496

97+
static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl)
98+
{
99+
while (wpa_ctrl_pending(ctrl) > 0) {
100+
char buf[MAX_CTRL_MSG_LEN];
101+
size_t len = sizeof(buf) - 1;
102+
103+
if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
104+
buf[len] = '\0';
105+
if (strlen(buf) > 0) {
106+
/* Only interested in CTRL-EVENTs */
107+
if (strncmp(buf, "CTRL-EVENT", 10) == 0) {
108+
wpa_printf(MSG_DEBUG, "Received event: %s\n", buf);
109+
send_wifi_mgmt_event("wlan0", NET_EVENT_WPA_SUPP_CMD_INT_EVENT,
110+
(void *)&buf[0], strlen(buf));
111+
}
112+
}
113+
} else {
114+
wpa_printf(MSG_INFO, "Could not read pending message.\n");
115+
}
116+
}
117+
}
118+
119+
static void wpa_cli_mon_receive(int sock, void *eloop_ctx,
120+
void *sock_ctx)
121+
{
122+
wpa_cli_recv_pending(mon_conn);
123+
}
124+
95125
static int wpa_cli_open_connection(struct wpa_supplicant *wpa_s)
96126
{
127+
int ret;
128+
97129
ctrl_conn = wpa_ctrl_open(wpa_s->ctrl_iface->sock_pair[0]);
98130
if (ctrl_conn == NULL) {
99131
wpa_printf(MSG_ERROR, "Failed to open control connection to %d",
100132
wpa_s->ctrl_iface->sock_pair[0]);
101133
return -1;
102134
}
103135

136+
ret = socketpair(AF_UNIX, SOCK_STREAM, 0, wpa_s->ctrl_iface->mon_sock_pair);
137+
if (ret != 0) {
138+
wpa_printf(MSG_ERROR, "Failed to open monitor connection: %s",
139+
strerror(errno));
140+
goto fail;
141+
}
142+
mon_conn = wpa_ctrl_open(wpa_s->ctrl_iface->mon_sock_pair[0]);
143+
if (mon_conn) {
144+
if (wpa_ctrl_attach(ctrl_conn) == 0) {
145+
eloop_register_read_sock(wpa_s->ctrl_iface->mon_sock_pair[0],
146+
wpa_cli_mon_receive, NULL, NULL);
147+
}
148+
}
149+
104150
return 0;
151+
fail:
152+
wpa_ctrl_close(ctrl_conn);
153+
return -1;
105154
}
106155

107156
static int wpa_cli_open_global_ctrl(void)

wpa_supplicant/wpa_supplicant.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1042,7 +1042,8 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
10421042
sme_sched_obss_scan(wpa_s, 1);
10431043

10441044
#ifdef CONFIG_ZEPHYR
1045-
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_CONNECT_RESULT, 0);
1045+
int status = 0;
1046+
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_CONNECT_RESULT, (void *)&status, sizeof(int));
10461047
#endif /* CONFIG_ZEPHYR */
10471048
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
10481049
if (!fils_hlp_sent && ssid && ssid->eap.erp)

0 commit comments

Comments
 (0)