Skip to content

Commit c76652e

Browse files
maxd-nordickrish2718
authored andcommitted
[nrf fromtree] net: lib: wifi_credentials: add connect-stored feature
This patch adds a feature to directly connect to stored Wi-Fi credentials without having to compose the NET_MGMT commands yourself. Signed-off-by: Maximilian Deubel <[email protected]> (cherry picked from commit e7ce0f5)
1 parent f54fa7d commit c76652e

File tree

4 files changed

+301
-16
lines changed

4 files changed

+301
-16
lines changed

include/zephyr/net/wifi_mgmt.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) 2017 Intel Corporation.
33
* Copyright 2024 NXP
4+
* Copyright (c) 2024 Nordic Semiconductor ASA
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -108,9 +109,13 @@ enum net_request_wifi_cmd {
108109
NET_REQUEST_WIFI_CMD_RTS_THRESHOLD_CONFIG,
109110
/** WPS config */
110111
NET_REQUEST_WIFI_CMD_WPS_CONFIG,
112+
#ifdef CONFIG_WIFI_CREDENTIALS_CONNECT_STORED
113+
/** Connect to APs stored using wifi_credentials library. */
114+
NET_REQUEST_WIFI_CMD_CONNECT_STORED,
115+
#endif
111116
/** @cond INTERNAL_HIDDEN */
112117
NET_REQUEST_WIFI_CMD_MAX
113-
/** @endcond */
118+
/** @endcond */
114119
};
115120

116121
/** Request a Wi-Fi scan */
@@ -257,6 +262,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_RTS_THRESHOLD_CONFIG);
257262
#define NET_REQUEST_WIFI_WPS_CONFIG (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_WPS_CONFIG)
258263

259264
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_WPS_CONFIG);
265+
#ifdef CONFIG_WIFI_CREDENTIALS_CONNECT_STORED
266+
#define NET_REQUEST_WIFI_CONNECT_STORED (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_CONNECT_STORED)
267+
268+
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT_STORED);
269+
#endif
260270

261271
/** @brief Wi-Fi management events */
262272
enum net_event_wifi_cmd {

subsys/net/l2/wifi/wifi_mgmt.c

Lines changed: 239 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8+
#undef _POSIX_C_SOURCE
9+
#define _POSIX_C_SOURCE 200809L /* For strnlen() */
10+
811
#include <zephyr/logging/log.h>
912
LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL);
1013

1114
#include <errno.h>
1215
#include <string.h>
13-
16+
#include <stdio.h>
1417
#include <zephyr/net/net_core.h>
1518
#include <zephyr/net/net_if.h>
1619
#include <zephyr/net/wifi_mgmt.h>
@@ -1009,3 +1012,238 @@ void wifi_mgmt_raise_ap_sta_disconnected_event(struct net_if *iface,
10091012
iface, sta_info,
10101013
sizeof(struct wifi_ap_sta_info));
10111014
}
1015+
1016+
#ifdef CONFIG_WIFI_CREDENTIALS_CONNECT_STORED
1017+
1018+
#include <zephyr/net/wifi_credentials.h>
1019+
1020+
#if defined(CONFIG_WIFI_CREDENTIALS_STATIC)
1021+
BUILD_ASSERT(sizeof(CONFIG_WIFI_CREDENTIALS_STATIC_SSID) != 1,
1022+
"CONFIG_WIFI_CREDENTIALS_STATIC_SSID required");
1023+
#endif /* defined(CONFIG_WIFI_CREDENTIALS_STATIC) */
1024+
1025+
static int __stored_creds_to_params(struct wifi_credentials_personal *creds,
1026+
struct wifi_connect_req_params *params)
1027+
{
1028+
char *ssid = NULL;
1029+
char *psk = NULL;
1030+
int ret;
1031+
1032+
/* SSID */
1033+
ssid = (char *)k_malloc(creds->header.ssid_len + 1);
1034+
if (!ssid) {
1035+
LOG_ERR("Failed to allocate memory for SSID\n");
1036+
ret = -ENOMEM;
1037+
goto err_out;
1038+
}
1039+
1040+
memset(ssid, 0, creds->header.ssid_len + 1);
1041+
ret = snprintf(ssid, creds->header.ssid_len + 1, "%s", creds->header.ssid);
1042+
if (ret > creds->header.ssid_len) {
1043+
LOG_ERR("SSID string truncated\n");
1044+
ret = -EINVAL;
1045+
goto err_out;
1046+
}
1047+
1048+
params->ssid = ssid;
1049+
params->ssid_length = creds->header.ssid_len;
1050+
1051+
/* PSK (optional) */
1052+
if (creds->password_len > 0) {
1053+
psk = (char *)k_malloc(creds->password_len + 1);
1054+
if (!psk) {
1055+
LOG_ERR("Failed to allocate memory for PSK\n");
1056+
ret = -ENOMEM;
1057+
goto err_out;
1058+
}
1059+
1060+
memset(psk, 0, creds->password_len + 1);
1061+
ret = snprintf(psk, creds->password_len + 1, "%s", creds->password);
1062+
if (ret > creds->password_len) {
1063+
LOG_ERR("PSK string truncated\n");
1064+
ret = -EINVAL;
1065+
goto err_out;
1066+
}
1067+
1068+
params->psk = psk;
1069+
params->psk_length = creds->password_len;
1070+
}
1071+
1072+
/* Defaults */
1073+
params->security = creds->header.type;
1074+
1075+
/* If channel is set to 0 we default to ANY. 0 is not a valid Wi-Fi channel. */
1076+
params->channel = (creds->header.channel != 0) ? creds->header.channel : WIFI_CHANNEL_ANY;
1077+
params->timeout = (creds->header.timeout != 0)
1078+
? creds->header.timeout
1079+
: CONFIG_WIFI_CREDENTIALS_CONNECT_STORED_CONNECTION_TIMEOUT;
1080+
1081+
/* Security type (optional) */
1082+
if (creds->header.type > WIFI_SECURITY_TYPE_MAX) {
1083+
params->security = WIFI_SECURITY_TYPE_NONE;
1084+
}
1085+
1086+
if (creds->header.flags & WIFI_CREDENTIALS_FLAG_2_4GHz) {
1087+
params->band = WIFI_FREQ_BAND_2_4_GHZ;
1088+
} else if (creds->header.flags & WIFI_CREDENTIALS_FLAG_5GHz) {
1089+
params->band = WIFI_FREQ_BAND_5_GHZ;
1090+
} else {
1091+
params->band = WIFI_FREQ_BAND_UNKNOWN;
1092+
}
1093+
1094+
/* MFP setting (default: optional) */
1095+
if (creds->header.flags & WIFI_CREDENTIALS_FLAG_MFP_DISABLED) {
1096+
params->mfp = WIFI_MFP_DISABLE;
1097+
} else if (creds->header.flags & WIFI_CREDENTIALS_FLAG_MFP_REQUIRED) {
1098+
params->mfp = WIFI_MFP_REQUIRED;
1099+
} else {
1100+
params->mfp = WIFI_MFP_OPTIONAL;
1101+
}
1102+
1103+
return 0;
1104+
err_out:
1105+
if (ssid) {
1106+
k_free(ssid);
1107+
ssid = NULL;
1108+
}
1109+
1110+
if (psk) {
1111+
k_free(psk);
1112+
psk = NULL;
1113+
}
1114+
1115+
return ret;
1116+
}
1117+
1118+
static inline const char *wpa_supp_security_txt(enum wifi_security_type security)
1119+
{
1120+
switch (security) {
1121+
case WIFI_SECURITY_TYPE_NONE:
1122+
return "NONE";
1123+
case WIFI_SECURITY_TYPE_PSK:
1124+
return "WPA-PSK";
1125+
case WIFI_SECURITY_TYPE_PSK_SHA256:
1126+
return "WPA-PSK-SHA256";
1127+
case WIFI_SECURITY_TYPE_SAE:
1128+
return "SAE";
1129+
case WIFI_SECURITY_TYPE_UNKNOWN:
1130+
default:
1131+
return "UNKNOWN";
1132+
}
1133+
}
1134+
1135+
static int add_network_from_credentials_struct_personal(struct wifi_credentials_personal *creds,
1136+
struct net_if *iface)
1137+
{
1138+
int ret = 0;
1139+
struct wifi_connect_req_params cnx_params = {0};
1140+
1141+
if (__stored_creds_to_params(creds, &cnx_params)) {
1142+
ret = -ENOEXEC;
1143+
goto out;
1144+
}
1145+
1146+
if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &cnx_params,
1147+
sizeof(struct wifi_connect_req_params))) {
1148+
LOG_ERR("Connection request failed\n");
1149+
1150+
return -ENOEXEC;
1151+
}
1152+
1153+
LOG_INF("Connection requested");
1154+
1155+
out:
1156+
if (cnx_params.psk) {
1157+
k_free((void *)cnx_params.psk);
1158+
}
1159+
1160+
if (cnx_params.ssid) {
1161+
k_free((void *)cnx_params.ssid);
1162+
}
1163+
1164+
return ret;
1165+
}
1166+
1167+
static void add_stored_network(void *cb_arg, const char *ssid, size_t ssid_len)
1168+
{
1169+
int ret = 0;
1170+
struct wifi_credentials_personal creds;
1171+
1172+
/* load stored data */
1173+
ret = wifi_credentials_get_by_ssid_personal_struct(ssid, ssid_len, &creds);
1174+
1175+
if (ret) {
1176+
LOG_ERR("Loading WiFi credentials failed for SSID [%.*s], len: %d, err: %d",
1177+
ssid_len, ssid, ssid_len, ret);
1178+
return;
1179+
}
1180+
1181+
add_network_from_credentials_struct_personal(&creds, (struct net_if *)cb_arg);
1182+
}
1183+
1184+
static int add_static_network_config(struct net_if *iface)
1185+
{
1186+
#if defined(CONFIG_WIFI_CREDENTIALS_STATIC)
1187+
1188+
struct wifi_credentials_personal creds = {
1189+
.header = {
1190+
.ssid_len = strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID),
1191+
},
1192+
.password_len = strlen(CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD),
1193+
};
1194+
1195+
int ret = wifi_credentials_get_by_ssid_personal_struct(
1196+
CONFIG_WIFI_CREDENTIALS_STATIC_SSID, strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID),
1197+
&creds);
1198+
1199+
if (!ret) {
1200+
LOG_WRN("Statically configured WiFi network was overridden by storage.");
1201+
return 0;
1202+
}
1203+
1204+
#if defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_OPEN)
1205+
creds.header.type = WIFI_SECURITY_TYPE_NONE;
1206+
#elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_PSK)
1207+
creds.header.type = WIFI_SECURITY_TYPE_PSK;
1208+
#elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_PSK_SHA256)
1209+
creds.header.type = WIFI_SECURITY_TYPE_PSK_SHA256;
1210+
#elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_SAE)
1211+
creds.header.type = WIFI_SECURITY_TYPE_SAE;
1212+
#elif defined(CONFIG_WIFI_CREDENTIALS_STATIC_TYPE_WPA_PSK)
1213+
creds.header.type = WIFI_SECURITY_TYPE_WPA_PSK;
1214+
#else
1215+
#error "invalid CONFIG_WIFI_CREDENTIALS_STATIC_TYPE"
1216+
#endif
1217+
1218+
memcpy(creds.header.ssid, CONFIG_WIFI_CREDENTIALS_STATIC_SSID,
1219+
strlen(CONFIG_WIFI_CREDENTIALS_STATIC_SSID));
1220+
memcpy(creds.password, CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD,
1221+
strlen(CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD));
1222+
1223+
LOG_DBG("Adding statically configured WiFi network [%s] to internal list.",
1224+
creds.header.ssid);
1225+
1226+
return add_network_from_credentials_struct_personal(&creds, iface);
1227+
#else
1228+
return 0;
1229+
#endif /* defined(CONFIG_WIFI_CREDENTIALS_STATIC) */
1230+
}
1231+
1232+
static int connect_stored_command(uint32_t mgmt_request, struct net_if *iface, void *data,
1233+
size_t len)
1234+
{
1235+
int ret = 0;
1236+
1237+
ret = add_static_network_config(iface);
1238+
if (ret) {
1239+
return ret;
1240+
}
1241+
1242+
wifi_credentials_for_each_ssid(add_stored_network, iface);
1243+
1244+
return ret;
1245+
};
1246+
1247+
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT_STORED, connect_stored_command);
1248+
1249+
#endif /* CONFIG_WIFI_CREDENTIALS_CONNECT_STORED */

subsys/net/lib/wifi_credentials/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ config WIFI_CREDENTIALS_SHELL
5959
depends on SHELL
6060
depends on !WIFI_CREDENTIALS_BACKEND_NONE
6161

62+
config WIFI_CREDENTIALS_CONNECT_STORED
63+
bool "Add command to connect to stored networks directly."
64+
default y
65+
66+
if WIFI_CREDENTIALS_CONNECT_STORED
67+
68+
config WIFI_CREDENTIALS_CONNECT_STORED_CONNECTION_TIMEOUT
69+
int "Connection timeout"
70+
default 30
71+
help
72+
Wait period before falling back to the next entry in the list of stored SSIDs.
73+
74+
endif # WIFI_CREDENTIALS_CONNECT_STORED
75+
6276
endif # WIFI_CREDENTIALS
6377

6478
if WIFI_CREDENTIALS_BACKEND_PSA

0 commit comments

Comments
 (0)