nl80211: clean up netlink code
This is a port of commit cafe38cae0
from Johannes Berg <johannes@sipsolutions.net> for hostapd to
wpa_supplicant driver_nl80211.c.
This commit is contained in:
parent
cafe38cae0
commit
6241fcb165
1 changed files with 108 additions and 120 deletions
|
@ -93,6 +93,62 @@ static void
|
||||||
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
|
wpa_driver_nl80211_finish_drv_init(struct wpa_driver_nl80211_data *drv);
|
||||||
|
|
||||||
|
|
||||||
|
/* nl80211 code */
|
||||||
|
static int ack_handler(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
int *err = arg;
|
||||||
|
*err = 0;
|
||||||
|
return NL_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int finish_handler(struct nl_msg *msg, void *arg)
|
||||||
|
{
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
int *ret = arg;
|
||||||
|
*ret = err->error;
|
||||||
|
return NL_SKIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int send_and_recv_msgs(struct wpa_driver_nl80211_data *drv,
|
||||||
|
struct nl_msg *msg,
|
||||||
|
int (*valid_handler)(struct nl_msg *, void *),
|
||||||
|
void *valid_data)
|
||||||
|
{
|
||||||
|
struct nl_cb *cb;
|
||||||
|
int err = -ENOMEM;
|
||||||
|
|
||||||
|
cb = nl_cb_clone(drv->nl_cb);
|
||||||
|
if (!cb)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = nl_send_auto_complete(drv->nl_handle, msg);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = 1;
|
||||||
|
|
||||||
|
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
|
||||||
|
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, NULL);
|
||||||
|
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
|
||||||
|
|
||||||
|
if (valid_handler)
|
||||||
|
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
|
||||||
|
valid_handler, valid_data);
|
||||||
|
|
||||||
|
while (err > 0)
|
||||||
|
nl_recvmsgs(drv->nl_handle, cb);
|
||||||
|
out:
|
||||||
|
nl_cb_put(cb);
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_driver_nl80211_send_oper_ifla(
|
static int wpa_driver_nl80211_send_oper_ifla(
|
||||||
struct wpa_driver_nl80211_data *drv,
|
struct wpa_driver_nl80211_data *drv,
|
||||||
int linkmode, int operstate)
|
int linkmode, int operstate)
|
||||||
|
@ -911,7 +967,7 @@ static int nl80211_set_vif(struct wpa_driver_nl80211_data *drv,
|
||||||
|
|
||||||
msg = nlmsg_alloc();
|
msg = nlmsg_alloc();
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto out;
|
return -ENOMEM;
|
||||||
|
|
||||||
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
|
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0, 0,
|
||||||
NL80211_CMD_SET_VIF, 0);
|
NL80211_CMD_SET_VIF, 0);
|
||||||
|
@ -927,16 +983,11 @@ static int nl80211_set_vif(struct wpa_driver_nl80211_data *drv,
|
||||||
|
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
||||||
|
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
nl_wait_for_ack(drv->nl_handle) < 0) {
|
return ret;
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_free(msg);
|
return -ENOBUFS;
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
#else /* NL80211_CMD_SET_VIF */
|
#else /* NL80211_CMD_SET_VIF */
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* NL80211_CMD_SET_VIF */
|
#endif /* NL80211_CMD_SET_VIF */
|
||||||
|
@ -962,13 +1013,11 @@ static void nl80211_remove_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
||||||
0, NL80211_CMD_DEL_INTERFACE, 0);
|
0, NL80211_CMD_DEL_INTERFACE, 0);
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifidx);
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
if (send_and_recv_msgs(drv, msg, NULL, NULL) == 0)
|
||||||
nl_wait_for_ack(drv->nl_handle) < 0) {
|
return;
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
wpa_printf(MSG_ERROR, "nl80211: Failed to remove interface.");
|
wpa_printf(MSG_ERROR, "nl80211: Failed to remove interface.");
|
||||||
}
|
}
|
||||||
nlmsg_free(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
|
@ -976,6 +1025,7 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
{
|
{
|
||||||
struct nl_msg *msg, *flags = NULL;
|
struct nl_msg *msg, *flags = NULL;
|
||||||
int ifidx, err;
|
int ifidx, err;
|
||||||
|
int ret = -ENOBUFS;
|
||||||
|
|
||||||
msg = nlmsg_alloc();
|
msg = nlmsg_alloc();
|
||||||
if (!msg)
|
if (!msg)
|
||||||
|
@ -1002,26 +1052,14 @@ static int nl80211_create_iface(struct wpa_driver_nl80211_data *drv,
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nl_send_auto_complete(drv->nl_handle, msg);
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
if (err < 0)
|
if (ret) {
|
||||||
wpa_printf(MSG_ERROR, "nl80211: nl_send_auto_complete failed: "
|
|
||||||
"%d (create_iface)", err);
|
|
||||||
else {
|
|
||||||
err = nl_wait_for_ack(drv->nl_handle);
|
|
||||||
if (err < 0)
|
|
||||||
wpa_printf(MSG_ERROR, "nl80211: nl_wait_for_ack "
|
|
||||||
"failed: %d (create_iface)", err);
|
|
||||||
}
|
|
||||||
if (err < 0) {
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
wpa_printf(MSG_ERROR, "nl80211: Failed to create interface "
|
wpa_printf(MSG_ERROR, "nl80211: Failed to create interface %d",
|
||||||
"%s.", ifname);
|
ret);
|
||||||
nlmsg_free(msg);
|
return ret;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nlmsg_free(msg);
|
|
||||||
|
|
||||||
ifidx = if_nametoindex(ifname);
|
ifidx = if_nametoindex(ifname);
|
||||||
if (ifidx <= 0)
|
if (ifidx <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1953,7 +1991,7 @@ static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
|
||||||
const u8 *key, size_t key_len)
|
const u8 *key, size_t key_len)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = priv;
|
struct wpa_driver_nl80211_data *drv = priv;
|
||||||
int ret = -1, err;
|
int err;
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
|
wpa_printf(MSG_DEBUG, "%s: alg=%d addr=%p key_idx=%d set_tx=%d "
|
||||||
|
@ -2001,16 +2039,13 @@ static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
|
||||||
NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
|
NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
||||||
|
|
||||||
err = 0;
|
err = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
if (err) {
|
||||||
(err = nl_wait_for_ack(drv->nl_handle)) < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err);
|
wpa_printf(MSG_DEBUG, "nl80211: set_key failed; err=%d", err);
|
||||||
nlmsg_free(msg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set_tx && alg != WPA_ALG_NONE) {
|
if (set_tx && alg != WPA_ALG_NONE) {
|
||||||
nlmsg_free(msg);
|
|
||||||
msg = nlmsg_alloc();
|
msg = nlmsg_alloc();
|
||||||
if (msg == NULL)
|
if (msg == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2021,21 +2056,18 @@ static int wpa_driver_nl80211_set_key(void *priv, wpa_alg alg,
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
||||||
NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
|
NLA_PUT_FLAG(msg, NL80211_ATTR_KEY_DEFAULT);
|
||||||
|
|
||||||
err = 0;
|
err = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
if (err) {
|
||||||
(err = nl_wait_for_ack(drv->nl_handle)) < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "nl80211: set default key "
|
wpa_printf(MSG_DEBUG, "nl80211: set default key "
|
||||||
"failed; err=%d", err);
|
"failed; err=%d", err);
|
||||||
nlmsg_free(msg);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
return 0;
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_free(msg);
|
return -ENOBUFS;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2331,15 +2363,14 @@ static int wpa_driver_nl80211_set_mode(void *priv, int mode)
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE,
|
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE,
|
||||||
mode ? NL80211_IFTYPE_ADHOC : NL80211_IFTYPE_STATION);
|
mode ? NL80211_IFTYPE_ADHOC : NL80211_IFTYPE_STATION);
|
||||||
|
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
nl_wait_for_ack(drv->nl_handle) < 0)
|
if (!ret)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
goto try_again;
|
goto try_again;
|
||||||
|
|
||||||
nlmsg_free(msg);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_free(msg);
|
wpa_printf(MSG_ERROR, "nl80211: Failed to set interface mode");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
try_again:
|
try_again:
|
||||||
|
@ -2351,12 +2382,21 @@ try_again:
|
||||||
(void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
|
(void) wpa_driver_nl80211_set_ifflags(drv, flags & ~IFF_UP);
|
||||||
|
|
||||||
/* Try to set the mode again while the interface is down */
|
/* Try to set the mode again while the interface is down */
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
msg = nlmsg_alloc();
|
||||||
nl_wait_for_ack(drv->nl_handle) < 0) {
|
if (!msg)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
||||||
|
0, NL80211_CMD_SET_INTERFACE, 0);
|
||||||
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
||||||
|
NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE,
|
||||||
|
mode ? NL80211_IFTYPE_ADHOC :
|
||||||
|
NL80211_IFTYPE_STATION);
|
||||||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
|
if (ret) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to set interface %s "
|
wpa_printf(MSG_ERROR, "Failed to set interface %s "
|
||||||
"mode", drv->ifname);
|
"mode", drv->ifname);
|
||||||
} else
|
}
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
/* Ignore return value of get_ifflags to ensure that the device
|
/* Ignore return value of get_ifflags to ensure that the device
|
||||||
* is always up like it was before this function was called.
|
* is always up like it was before this function was called.
|
||||||
|
@ -2365,7 +2405,6 @@ try_again:
|
||||||
(void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP);
|
(void) wpa_driver_nl80211_set_ifflags(drv, flags | IFF_UP);
|
||||||
}
|
}
|
||||||
|
|
||||||
nlmsg_free(msg);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2488,19 +2527,9 @@ static int wpa_driver_nl80211_set_param(void *priv, const char *param)
|
||||||
|
|
||||||
#ifdef CONFIG_CLIENT_MLME
|
#ifdef CONFIG_CLIENT_MLME
|
||||||
|
|
||||||
static int ack_wait_handler(struct nl_msg *msg, void *arg)
|
|
||||||
{
|
|
||||||
int *finished = arg;
|
|
||||||
|
|
||||||
*finished = 1;
|
|
||||||
return NL_STOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct phy_info_arg {
|
struct phy_info_arg {
|
||||||
u16 *num_modes;
|
u16 *num_modes;
|
||||||
struct wpa_hw_modes *modes;
|
struct wpa_hw_modes *modes;
|
||||||
int error;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -2660,8 +2689,6 @@ static int phy_info_handler(struct nl_msg *msg, void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
phy_info->error = 0;
|
|
||||||
|
|
||||||
return NL_SKIP;
|
return NL_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2671,13 +2698,9 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
|
||||||
{
|
{
|
||||||
struct wpa_driver_nl80211_data *drv = priv;
|
struct wpa_driver_nl80211_data *drv = priv;
|
||||||
struct nl_msg *msg;
|
struct nl_msg *msg;
|
||||||
int err = -1;
|
|
||||||
struct nl_cb *cb = NULL;
|
|
||||||
int finished = 0;
|
|
||||||
struct phy_info_arg result = {
|
struct phy_info_arg result = {
|
||||||
.num_modes = num_modes,
|
.num_modes = num_modes,
|
||||||
.modes = NULL,
|
.modes = NULL,
|
||||||
.error = 1,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
*num_modes = 0;
|
*num_modes = 0;
|
||||||
|
@ -2692,33 +2715,10 @@ wpa_driver_nl80211_get_hw_feature_data(void *priv, u16 *num_modes, u16 *flags)
|
||||||
|
|
||||||
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, drv->ifindex);
|
||||||
|
|
||||||
cb = nl_cb_clone(drv->nl_cb);
|
if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0)
|
||||||
if (!cb)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, phy_info_handler, &result);
|
|
||||||
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
|
|
||||||
|
|
||||||
err = nl_recvmsgs(drv->nl_handle, cb);
|
|
||||||
|
|
||||||
if (!finished)
|
|
||||||
err = nl_wait_for_ack(drv->nl_handle);
|
|
||||||
|
|
||||||
if (err < 0 || result.error) {
|
|
||||||
wpa_supplicant_sta_free_hw_features(result.modes, *num_modes);
|
|
||||||
result.modes = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
nl_cb_put(cb);
|
|
||||||
nla_put_failure:
|
|
||||||
if (err)
|
|
||||||
fprintf(stderr, "failed to get information: %d\n", err);
|
|
||||||
nlmsg_free(msg);
|
|
||||||
return result.modes;
|
return result.modes;
|
||||||
|
nla_put_failure:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2781,7 +2781,7 @@ static int wpa_driver_nl80211_mlme_add_sta(void *priv, const u8 *addr,
|
||||||
|
|
||||||
msg = nlmsg_alloc();
|
msg = nlmsg_alloc();
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto out;
|
return -ENOMEM;
|
||||||
|
|
||||||
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
||||||
0, NL80211_CMD_NEW_STATION, 0);
|
0, NL80211_CMD_NEW_STATION, 0);
|
||||||
|
@ -2794,19 +2794,12 @@ static int wpa_driver_nl80211_mlme_add_sta(void *priv, const u8 *addr,
|
||||||
supp_rates);
|
supp_rates);
|
||||||
NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 1);
|
NLA_PUT_U16(msg, NL80211_ATTR_STA_LISTEN_INTERVAL, 1);
|
||||||
|
|
||||||
ret = nl_send_auto_complete(drv->nl_handle, msg);
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
if (ret < 0)
|
|
||||||
goto nla_put_failure;
|
|
||||||
|
|
||||||
ret = nl_wait_for_ack(drv->nl_handle);
|
|
||||||
/* ignore EEXIST, this happens if a STA associates while associated */
|
/* ignore EEXIST, this happens if a STA associates while associated */
|
||||||
if (ret == -EEXIST || ret >= 0)
|
if (ret == -EEXIST || ret >= 0)
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_free(msg);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2819,7 +2812,7 @@ static int wpa_driver_nl80211_mlme_remove_sta(void *priv, const u8 *addr)
|
||||||
|
|
||||||
msg = nlmsg_alloc();
|
msg = nlmsg_alloc();
|
||||||
if (!msg)
|
if (!msg)
|
||||||
goto out;
|
return -ENOMEM;
|
||||||
|
|
||||||
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
genlmsg_put(msg, 0, 0, genl_family_get_id(drv->nl80211), 0,
|
||||||
0, NL80211_CMD_DEL_STATION, 0);
|
0, NL80211_CMD_DEL_STATION, 0);
|
||||||
|
@ -2829,16 +2822,11 @@ static int wpa_driver_nl80211_mlme_remove_sta(void *priv, const u8 *addr)
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
if (nl_send_auto_complete(drv->nl_handle, msg) < 0 ||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
nl_wait_for_ack(drv->nl_handle) < 0) {
|
return ret;
|
||||||
ret = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
nla_put_failure:
|
nla_put_failure:
|
||||||
nlmsg_free(msg);
|
return -ENOBUFS;
|
||||||
|
|
||||||
out:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_CLIENT_MLME */
|
#endif /* CONFIG_CLIENT_MLME */
|
||||||
|
|
Loading…
Reference in a new issue