Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Commit

Permalink
[nrf noup] Monitor supplicant state and inform applications
Browse files Browse the repository at this point in the history
Add a control connection handler for monitoring the
supplicant state at real time and notify interested
applications.

Signed-off-by: Ravi Dondaputi <[email protected]>
  • Loading branch information
rado17 authored and krish2718 committed Sep 7, 2023
1 parent 8b0abe8 commit db9f97f
Show file tree
Hide file tree
Showing 5 changed files with 222 additions and 3 deletions.
148 changes: 147 additions & 1 deletion wpa_supplicant/ctrl_iface_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,114 @@

#include "ctrl_iface_zephyr.h"


static int wpa_supplicant_ctrl_mon_iface_attach(struct wpa_ctrl_mon **head, int sock)
{
struct wpa_ctrl_mon *dst;

dst = os_zalloc(sizeof(*dst));
if (dst == NULL)
return -1;

dst->sock = sock;
dst->debug_level = MSG_INFO;
dst->next = *head;
*head = dst;
return 0;
}


static int wpa_supplicant_ctrl_mon_iface_detach(struct wpa_ctrl_mon **head, int sock)
{
struct wpa_ctrl_mon *dst, *prev = NULL;

dst = *head;
while (dst) {
if (dst->sock == sock) {
if (prev == NULL) {
*head = dst->next;
} else {
prev->next = dst->next;
}
os_free(dst);
return 0;
}
prev = dst;
dst = dst->next;
}
return -1;
}

static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
const char *ifname, int sock,
struct wpa_ctrl_mon **head,
int level, const char *buf,
size_t len)
{
struct wpa_ctrl_mon *dst, *next;
char levelstr[64];
int idx;
struct conn_msg msg;

dst = *head;
if (sock < 0 || dst == NULL)
return;

if (ifname)
os_snprintf(levelstr, sizeof(levelstr), "IFNAME=%s <%d>",
ifname, level);
else
os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);

idx = 0;
while (dst) {
next = dst->next;
if (level >= dst->debug_level) {
memcpy(&msg.msg, buf, len);
msg.msg_len = len;
if (send(dst->sock, &msg, sizeof(msg), 0) < 0) {
wpa_printf(MSG_ERROR,
"sendto(CTRL_IFACE monitor): %s",
strerror(errno));
dst->errors++;
} else {
dst->errors = 0;
}
}
idx++;
dst = next;
}
}

static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
enum wpa_msg_type type,
const char *txt, size_t len)
{
struct wpa_supplicant *wpa_s = ctx;

if (!wpa_s)
return;

if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) {
struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;

if (priv->ctrl_dst) {
wpa_supplicant_ctrl_iface_send(wpa_s, type != WPA_MSG_PER_INTERFACE ?
NULL : wpa_s->ifname,
priv->sock_pair[0],
&priv->ctrl_dst, level, txt, len);
}
}

if (type == WPA_MSG_ONLY_GLOBAL || !wpa_s->ctrl_iface)
return;

wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock_pair[0],
&wpa_s->ctrl_iface->ctrl_dst,
level, txt, len);
}


static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
Expand Down Expand Up @@ -39,8 +147,26 @@ static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
while (*pos == ' ')
pos++;

reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos,
if (os_strcmp(pos, "ATTACH") == 0) {
if (wpa_supplicant_ctrl_mon_iface_attach(&wpa_s->ctrl_iface->ctrl_dst,
wpa_s->ctrl_iface->mon_sock_pair[1])){
reply_len = 1;
}
else {
reply_len = 2;
}
} else if (os_strcmp(pos, "DETACH") == 0) {
if (wpa_supplicant_ctrl_mon_iface_detach(&wpa_s->ctrl_iface->ctrl_dst,
wpa_s->ctrl_iface->mon_sock_pair[1])) {
reply_len = 1;
}
else {
reply_len = 2;
}
} else {
reply = wpa_supplicant_ctrl_iface_process(wpa_s, pos,
&reply_len);
}

if (reply) {
send(sock, reply, reply_len, 0);
Expand Down Expand Up @@ -86,6 +212,8 @@ wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
eloop_register_read_sock(priv->sock_pair[1], wpa_supplicant_ctrl_iface_receive,
wpa_s, priv);

wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);

return priv;

fail:
Expand Down Expand Up @@ -154,8 +282,26 @@ static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
while (*pos == ' ')
pos++;

if (os_strcmp(pos, "ATTACH") == 0) {
if (wpa_supplicant_ctrl_mon_iface_attach(&global->ctrl_iface->ctrl_dst,
global->ctrl_iface->mon_sock_pair[1])) {
reply_len = 1;
}
else {
reply_len = 2;
}
} else if (os_strcmp(pos, "DETACH") == 0) {
if (wpa_supplicant_ctrl_mon_iface_detach(&global->ctrl_iface->ctrl_dst,
global->ctrl_iface->mon_sock_pair[1])) {
reply_len = 1;
}
else {
reply_len = 2;
}
} else {
reply = wpa_supplicant_global_ctrl_iface_process(global, pos,
&reply_len);
}

if (reply) {
send(sock, reply, reply_len, 0);
Expand Down
22 changes: 22 additions & 0 deletions wpa_supplicant/ctrl_iface_zephyr.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,37 @@
#include "ctrl_iface.h"
#include "common/wpa_ctrl.h"

#define MAX_CTRL_MSG_LEN 256
/**
* struct wpa_ctrl_mon - Data structure of control interface monitors
*
* This structure is used to store information about registered control
* interface monitors into struct wpa_supplicant.
*/
struct wpa_ctrl_mon {
struct wpa_ctrl_mon *next;
int sock;
int debug_level;
int errors;
};

struct ctrl_iface_priv {
struct wpa_supplicant *wpa_s;
/* 0 - wpa_cli, 1 - ctrl_iface */
int sock_pair[2];
int mon_sock_pair[2];
struct wpa_ctrl_mon *ctrl_dst;
};

struct ctrl_iface_global_priv {
struct wpa_global *global;
/* 0 - wpa_cli, 1 - ctrl_iface */
int sock_pair[2];
int mon_sock_pair[2];
struct wpa_ctrl_mon *ctrl_dst;
};

struct conn_msg {
char msg[MAX_CTRL_MSG_LEN];
int msg_len;
};
3 changes: 2 additions & 1 deletion wpa_supplicant/events.c
Original file line number Diff line number Diff line change
Expand Up @@ -3589,7 +3589,8 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
MAC2STR(bssid), reason_code,
locally_generated ? " locally_generated=1" : "");
#ifdef CONFIG_ZEPHYR
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_DISCONNECT_RESULT, 0);
int status = 0;
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_DISCONNECT_RESULT, (void *)&status, sizeof(int));
#endif /* CONFIG_ZEPHYR */
}
}
Expand Down
49 changes: 49 additions & 0 deletions wpa_supplicant/wpa_cli_zephyr.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "common/ieee802_11_defs.h"

#include "supp_main.h"
#include "supp_events.h"
#include "wpa_cli_zephyr.h"
#include "ctrl_iface_zephyr.h"

Expand All @@ -30,6 +31,7 @@
#define MAX_ARGS 32

struct wpa_ctrl *ctrl_conn;
struct wpa_ctrl *mon_conn;
struct wpa_ctrl *global_ctrl_conn;
char *ifname_prefix = NULL;
extern struct wpa_global *global;
Expand Down Expand Up @@ -92,16 +94,63 @@ static void wpa_cli_close_connection(void)
ctrl_conn = NULL;
}

static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl)
{
while (wpa_ctrl_pending(ctrl) > 0) {
char buf[MAX_CTRL_MSG_LEN];
size_t len = sizeof(buf) - 1;

if (wpa_ctrl_recv(ctrl, buf, &len) == 0) {
buf[len] = '\0';
if (strlen(buf) > 0) {
/* Only interested in CTRL-EVENTs */
if (strncmp(buf, "CTRL-EVENT", 10) == 0) {
wpa_printf(MSG_DEBUG, "Received event: %s\n", buf);
send_wifi_mgmt_event("wlan0", NET_EVENT_WPA_SUPP_CMD_INT_EVENT,
(void *)&buf[0], strlen(buf));
}
}
} else {
wpa_printf(MSG_INFO, "Could not read pending message.\n");
}
}
}

static void wpa_cli_mon_receive(int sock, void *eloop_ctx,
void *sock_ctx)
{
wpa_cli_recv_pending(mon_conn);
}

static int wpa_cli_open_connection(struct wpa_supplicant *wpa_s)
{
int ret;

ctrl_conn = wpa_ctrl_open(wpa_s->ctrl_iface->sock_pair[0]);
if (ctrl_conn == NULL) {
wpa_printf(MSG_ERROR, "Failed to open control connection to %d",
wpa_s->ctrl_iface->sock_pair[0]);
return -1;
}

ret = socketpair(AF_UNIX, SOCK_STREAM, 0, wpa_s->ctrl_iface->mon_sock_pair);
if (ret != 0) {
wpa_printf(MSG_ERROR, "Failed to open monitor connection: %s",
strerror(errno));
goto fail;
}
mon_conn = wpa_ctrl_open(wpa_s->ctrl_iface->mon_sock_pair[0]);
if (mon_conn) {
if (wpa_ctrl_attach(ctrl_conn) == 0) {
eloop_register_read_sock(wpa_s->ctrl_iface->mon_sock_pair[0],
wpa_cli_mon_receive, NULL, NULL);
}
}

return 0;
fail:
wpa_ctrl_close(ctrl_conn);
return -1;
}

static int wpa_cli_open_global_ctrl(void)
Expand Down
3 changes: 2 additions & 1 deletion wpa_supplicant/wpa_supplicant.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,8 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
sme_sched_obss_scan(wpa_s, 1);

#ifdef CONFIG_ZEPHYR
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_CONNECT_RESULT, 0);
int status = 0;
send_wifi_mgmt_event(wpa_s->ifname, NET_EVENT_WIFI_CMD_CONNECT_RESULT, (void *)&status, sizeof(int));
#endif /* CONFIG_ZEPHYR */
#if defined(CONFIG_FILS) && defined(IEEE8021X_EAPOL)
if (!fils_hlp_sent && ssid && ssid->eap.erp)
Expand Down

0 comments on commit db9f97f

Please sign in to comment.