Morse Micro IoT SDK  2.9.7
softap.c
Go to the documentation of this file.
1/*
2 * Copyright 2025 Morse Micro
3 *
4 * This file is licensed under terms that can be found in the LICENSE.md file in the root
5 * directory of the Morse Micro IoT SDK software package.
6 */
7
17#include <string.h>
18#include "mmconfig.h"
19#include "mmosal.h"
20#include "mmutils.h"
21#include "mm_app_common.h"
22#include "mm_app_loadconfig.h"
23
24
25
26/*
27 * --
28 * Default Network configuration
29 * --
30 */
31
32#ifndef STATIC_LOCAL_IP
34#define STATIC_LOCAL_IP "192.168.1.1"
35#endif
36#ifndef STATIC_GATEWAY
38#define STATIC_GATEWAY "192.168.1.1"
39#endif
40#ifndef STATIC_NETMASK
42#define STATIC_NETMASK "255.255.255.0"
43#endif
44
45
46/*
47 * --
48 * Default SSID/Security configuration
49 * --
50 */
51
52#ifndef SOFTAP_SSID
54#define SOFTAP_SSID SoftAP
55#endif
56
57#ifndef SAE_PASSPHRASE
60#define SAE_PASSPHRASE 12345678
61#endif
62
63/* Default security type */
64#ifndef SECURITY_TYPE
66#define SECURITY_TYPE MMWLAN_SAE
67#endif
68
69/* Default PMF mode */
70#ifndef PMF_MODE
72#define PMF_MODE MMWLAN_PMF_REQUIRED
73#endif
74
75
76/*
77 * --
78 * Default channel configuration
79 * --
80 */
81
82#ifndef OP_CLASS
87#define OP_CLASS (25)
88#endif
89
90#ifndef S1G_CHANNEL
95#define S1G_CHANNEL (44)
96#endif
97
98#ifndef PRIMARY_BW_MHZ
107#define PRIMARY_BW_MHZ (0)
108#endif
109
110#ifndef PRIMARY_1MHZ_CHANNEL_INDEX
112#define PRIMARY_1MHZ_CHANNEL_INDEX (0)
113#endif
114
115
117#define _STRINGIFY(x) #x
119#define STRINGIFY(x) _STRINGIFY(x)
120
121
124
131static void handle_softap_sta_status(const struct mmwlan_softap_sta_status *sta_status, void *arg)
132{
133 MM_UNUSED(sta_status);
134
135 /* Validate that the opaque argument received matches the value passed in. This is just for
136 * testing purposes. */
138
139 printf("STA status updated\n");
140}
141
154{
155 /* Load default static IP in case we don't find the key */
156 (void)mmosal_safer_strcpy(args->ip_addr, STATIC_LOCAL_IP, sizeof(args->ip_addr));
157 (void)mmconfig_read_string("ip.ip_addr", args->ip_addr, sizeof(args->ip_addr));
158
159 /* Load default netmask in case we don't find the key */
160 (void)mmosal_safer_strcpy(args->netmask, STATIC_NETMASK, sizeof(args->netmask));
161 (void)mmconfig_read_string("ip.netmask", args->netmask, sizeof(args->netmask));
162
163 /* Load default gateway in case we don't find the key */
164 (void)mmosal_safer_strcpy(args->gateway_addr, STATIC_GATEWAY, sizeof(args->gateway_addr));
165 (void)mmconfig_read_string("ip.gateway", args->gateway_addr, sizeof(args->gateway_addr));
166}
167
178{
179 char strval[32];
180 uint32_t uint32val;
181
182 /* Load SSID */
183 (void)mmosal_safer_strcpy((char*)softap_args->ssid, STRINGIFY(SOFTAP_SSID),
184 sizeof(softap_args->ssid));
185 (void)mmconfig_read_string("wlan.ssid", (char*) softap_args->ssid, sizeof(softap_args->ssid));
186 softap_args->ssid_len = strlen((char*)softap_args->ssid);
187
188 /* Load password */
190 sizeof(softap_args->passphrase));
191 (void)mmconfig_read_string("wlan.password", softap_args->passphrase,
192 sizeof(softap_args->passphrase));
193 softap_args->passphrase_len = strlen(softap_args->passphrase);
194
195 /* Load security type */
196 softap_args->security_type = SECURITY_TYPE;
197 if (mmconfig_read_string("wlan.security", strval, sizeof(strval)) > 0)
198 {
199 if (strncmp("sae", strval, sizeof(strval)) == 0)
200 {
201 softap_args->security_type = MMWLAN_SAE;
202 }
203 else if (strncmp("owe", strval, sizeof(strval)) == 0)
204 {
205 softap_args->security_type = MMWLAN_OWE;
206 }
207 else if (strncmp("open", strval, sizeof(strval)) == 0)
208 {
209 softap_args->security_type = MMWLAN_OPEN;
210 }
211 else
212 {
213 printf("Invalid value of %s read from config store: %s\n",
214 "wlan.security", strval);
215 }
216 }
217
218 /* Load PMF mode */
219 softap_args->pmf_mode = PMF_MODE;
220 if (mmconfig_read_string("wlan.pmf_mode", strval, sizeof(strval)) > 0)
221 {
222 if (strncmp("disabled", strval, sizeof(strval)) == 0)
223 {
224 printf("PMF disabled\n");
225 softap_args->pmf_mode = MMWLAN_PMF_DISABLED;
226 }
227 else if (strncmp("required", strval, sizeof(strval)) == 0)
228 {
229 softap_args->pmf_mode = MMWLAN_PMF_REQUIRED;
230 }
231 else
232 {
233 printf("Invalid value of %s read from config store: %s\n",
234 "wlan.pmf_mode", strval);
235 }
236 }
237
238 /* Load BSSID */
239 if (mmconfig_read_string("wlan.bssid", strval, sizeof(strval)) > 0)
240 {
241 int temp[6];
242 int i;
243
244 int ret = sscanf(strval, "%x:%x:%x:%x:%x:%x",
245 &temp[0], &temp[1], &temp[2],
246 &temp[3], &temp[4], &temp[5]);
247 if (ret == 6)
248 {
249 for (i = 0; i < 6; i++)
250 {
251 if (temp[i] > UINT8_MAX || temp[i] < 0)
252 {
253 /* Invalid value, ignore and reset to default */
254 memset(softap_args->bssid, 0, sizeof(softap_args->bssid));
255 break;
256 }
257
258 softap_args->bssid[i] = (uint8_t)temp[i];
259 }
260 }
261 }
262
263 softap_args->op_class = OP_CLASS;
264 if (mmconfig_read_uint32("wlan.op_class", &uint32val) == MMCONFIG_OK)
265 {
266 if (uint32val <= UINT8_MAX)
267 {
268 softap_args->op_class = uint32val;
269 }
270 else
271 {
272 printf("%s out of range\n", "wlan.op_class");
273 }
274 }
275
276 softap_args->s1g_chan_num = S1G_CHANNEL;
277 if (mmconfig_read_uint32("wlan.s1g_chan_num", &uint32val) == MMCONFIG_OK)
278 {
279 if (uint32val <= UINT8_MAX)
280 {
281 softap_args->s1g_chan_num = uint32val;
282 }
283 else
284 {
285 printf("%s out of range\n", "wlan.s1g_chan_num");
286 }
287 }
288
289 softap_args->pri_bw_mhz = PRIMARY_BW_MHZ;
290 if (mmconfig_read_uint32("wlan.pri_bw_mhz", &uint32val) == MMCONFIG_OK)
291 {
292 if (uint32val <= UINT8_MAX)
293 {
294 softap_args->pri_bw_mhz = uint32val;
295 }
296 else
297 {
298 printf("%s out of range\n", "wlan.pri_bw_mhz");
299 }
300 }
301
303 if (mmconfig_read_uint32("wlan.pri_1mhz_chan_idx", &uint32val) == MMCONFIG_OK)
304 {
305 if (uint32val <= UINT8_MAX)
306 {
307 softap_args->pri_1mhz_chan_idx = uint32val;
308 }
309 else
310 {
311 printf("%s out of range\n", "wlan.pri_1mhz_chan_idx");
312 }
313 }
314}
315
320{
321 int intval;
322 uint32_t uintval;
323 bool boolval;
324
325 /* Apply subbands enabled if specified */
326 if (mmconfig_read_bool("wlan.subbands_enabled", &boolval) == MMCONFIG_OK)
327 {
329 }
330
331 /* Apply sgi enabled if specified */
332 if (mmconfig_read_bool("wlan.sgi_enabled", &boolval) == MMCONFIG_OK)
333 {
334 mmwlan_set_sgi_enabled(boolval);
335 }
336
337 /* Apply ampdu enabled if specified */
338 if (mmconfig_read_bool("wlan.ampdu_enabled", &boolval) == MMCONFIG_OK)
339 {
341 }
342
343 /* Apply fragment threshold if specified */
344 if (mmconfig_read_int("wlan.fragment_threshold", &intval) == MMCONFIG_OK)
345 {
347 }
348
349 /* Apply rts threshold if specified */
350 if (mmconfig_read_int("wlan.rts_threshold", &intval) == MMCONFIG_OK)
351 {
353 }
354
355 /* Apply Health check intervals if specified */
356 if (mmconfig_read_uint32("wlan.max_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
357 {
358 /* If not specified, the minimum is 0 */
359 uint32_t health_check_min = 0;
360 mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &health_check_min);
361 mmwlan_set_health_check_interval(health_check_min, uintval);
362 }
363 else if (mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
364 {
365 /* If only minimum is specified, then treat the maximum as unbounded */
366 mmwlan_set_health_check_interval(uintval, UINT32_MAX);
367 }
368}
369
374void app_init(void)
375{
376 printf("\n\nSoftAP Example (Built " __DATE__ " " __TIME__ ")\n\n");
377 mmwlan_init();
379 mmwlan_boot(NULL);
380
382
383 /* Load IP stack settings from config store, or use defaults if no entry found in
384 * config store. */
389
390 /* Initialize IP stack. */
392 {
393 printf("Error initializing network interface.\n");
394 MMOSAL_ASSERT(false);
395 }
396
399
400 struct mmwlan_softap_args softap_args = MMWLAN_SOFTAP_ARGS_INIT;
401 load_mmwlan_softap_args(&softap_args);
402
405
406 enum mmwlan_status status = mmwlan_softap_enable(&softap_args);
407 if (status == MMWLAN_SUCCESS)
408 {
409 printf("Soft AP started successfully\n");
410 }
411 else
412 {
413 printf("Failed to start Soft AP (status %d)\n", status);
414 }
415}
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
int mmconfig_read_int(const char *key, int *value)
Returns the integer stored in persistent store identified by the key.
int mmconfig_read_bool(const char *key, bool *value)
Returns the boolean value stored in persistent store identified by the key.
int mmconfig_read_uint32(const char *key, uint32_t *value)
Returns the unsigned integer stored in persistent store identified by the key.
@ MMCONFIG_OK
Operation completed successfully.
Definition: mmconfig.h:221
enum mmipal_status mmipal_init(const struct mmipal_init_args *args)
Initialize the IP stack and enable the MMWLAN interface.
#define MMIPAL_INIT_ARGS_DEFAULT
Default values for mmipal_init_args.
Definition: mmipal.h:173
@ MMIPAL_IP6_DISABLED
Disabled.
Definition: mmipal.h:106
@ MMIPAL_SUCCESS
Completed successfully.
Definition: mmipal.h:39
@ MMIPAL_STATIC
Static IP address.
Definition: mmipal.h:65
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:927
static bool mmosal_safer_strcpy(char *dst, const char *src, size_t size)
A safer version of strncpy.
Definition: mmosal.h:1030
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
Definition: mmutils.h:69
enum mmwlan_status mmwlan_boot(const struct mmwlan_boot_args *args)
Boot the Morse Micro transceiver and leave it in an idle state.
#define MMWLAN_SOFTAP_ARGS_INIT
Initializer for mmwlan_softap_args.
Definition: mmwlan.h:1405
enum mmwlan_status mmwlan_set_ampdu_enabled(bool ampdu_enabled)
Sets whether or not Aggregated MAC Protocol Data Unit (A-MPDU) support is enabled.
enum mmwlan_status mmwlan_set_sgi_enabled(bool sgi_enabled)
Sets whether or not Short Guard Interval (SGI) support is enabled.
enum mmwlan_status mmwlan_set_power_save_mode(enum mmwlan_ps_mode mode)
Sets whether or not the 802.11 power save is enabled.
enum mmwlan_status mmwlan_softap_enable(const struct mmwlan_softap_args *args)
Enable Soft AP mode.
enum mmwlan_status mmwlan_set_subbands_enabled(bool subbands_enabled)
Sets whether or not sub-band support is enabled for transmit.
enum mmwlan_status mmwlan_set_fragment_threshold(unsigned fragment_threshold)
Set the Fragmentation threshold.
enum mmwlan_status mmwlan_set_rts_threshold(unsigned rts_threshold)
Set the RTS threshold.
enum mmwlan_status mmwlan_set_health_check_interval(uint32_t min_interval_ms, uint32_t max_interval_ms)
Specify the upper and lower bound for the periodic health check interval.
void mmwlan_init(void)
Initialize the MMWLAN subsystem.
enum mmwlan_status mmwlan_set_channel_list(const struct mmwlan_s1g_channel_list *channel_list)
Set the list of channels that are supported by the regulatory domain in which the device resides.
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:52
@ MMWLAN_PMF_DISABLED
No protected management frames.
Definition: mmwlan.h:161
@ MMWLAN_PMF_REQUIRED
Protected management frames must be used.
Definition: mmwlan.h:159
@ MMWLAN_OPEN
Open (no security)
Definition: mmwlan.h:139
@ MMWLAN_SAE
Simultaneous Authentication of Equals (SAE)
Definition: mmwlan.h:143
@ MMWLAN_OWE
Opportunistic Wireless Encryption (OWE)
Definition: mmwlan.h:141
@ MMWLAN_PS_DISABLED
Power save disabled.
Definition: mmwlan.h:150
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_print_version_info(void)
Prints various version information.
const struct mmwlan_s1g_channel_list * load_channel_list(void)
Looks up country code and returns appropriate channel list.
#define PRIMARY_BW_MHZ
Primary Bandwidth to use for Soft AP.
Definition: softap.c:107
#define SECURITY_TYPE
Security type (.
Definition: softap.c:66
static void load_softap_mmipal_init_args(struct mmipal_init_args *args)
Loads the provided structure with initialization parameters read from config store.
Definition: softap.c:153
#define S1G_CHANNEL
S1G Channel to use for Soft AP.
Definition: softap.c:95
#define STATIC_NETMASK
Statically configured netmask.
Definition: softap.c:42
static void handle_softap_sta_status(const struct mmwlan_softap_sta_status *sta_status, void *arg)
Handler for Soft AP STA Status callback.
Definition: softap.c:131
#define PMF_MODE
Protected Management Frames (PMF) mode (.
Definition: softap.c:72
#define STRINGIFY(x)
Convert the content of the given macro to a string.
Definition: softap.c:119
#define SAE_PASSPHRASE
Passphrase of the AP (ignored if security type is not SAE).
Definition: softap.c:60
#define SOFTAP_SSID
SSID of the AP.
Definition: softap.c:54
#define OP_CLASS
Operating Class to use for Soft AP.
Definition: softap.c:87
#define PRIMARY_1MHZ_CHANNEL_INDEX
Primary 1 MHz Channel Index to use for Soft AP.
Definition: softap.c:112
#define STATIC_GATEWAY
Statically configured gateway address.
Definition: softap.c:38
void app_init(void)
Main entry point to the application.
Definition: softap.c:374
uint32_t opaque_argument_value
A throw away variable for checking that the opaque argument is correct.
Definition: softap.c:123
#define STATIC_LOCAL_IP
Statically configured IP address.
Definition: softap.c:34
static void load_mmwlan_settings_softap(void)
Loads various WLAN Soft AP specific settings from config store and applies them.
Definition: softap.c:319
void load_mmwlan_softap_args(struct mmwlan_softap_args *softap_args)
Loads the provided structure with initialization parameters read from config store.
Definition: softap.c:177
Initialize arguments structure.
Definition: mmipal.h:149
enum mmipal_ip6_addr_mode ip6_mode
IPv6 address allocation mode to use.
Definition: mmipal.h:160
mmipal_ip_addr_t gateway_addr
Gateway IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:157
enum mmipal_addr_mode mode
IP address allocation mode to use.
Definition: mmipal.h:151
mmipal_ip_addr_t netmask
Netmask to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:155
mmipal_ip_addr_t ip_addr
IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:153
Arguments data structure for mmwlan_softap_enable().
Definition: mmwlan.h:1324
char passphrase[MMWLAN_PASSPHRASE_MAXLEN+1]
Passphrase (only used if security_type is MMWLAN_SAE, otherwise ignored.
Definition: mmwlan.h:1338
uint8_t bssid[MMWLAN_MAC_ADDR_LEN]
Optional BSSID of the AP.
Definition: mmwlan.h:1334
uint16_t passphrase_len
Length of passphrase.
Definition: mmwlan.h:1340
uint16_t op_class
Operating Class to use (S1G or Global).
Definition: mmwlan.h:1355
uint8_t pri_1mhz_chan_idx
Index of the primary 1 Mhz channel within the operating channel.
Definition: mmwlan.h:1387
mmwlan_softap_sta_status_cb_t sta_status_cb
Optional callback to be invoked when the status of a connected STA changes.
Definition: mmwlan.h:1392
uint8_t pri_bw_mhz
Bandwidth to use for the primary channel.
Definition: mmwlan.h:1382
uint16_t s1g_chan_num
S1G channel number of the channel to use.
Definition: mmwlan.h:1363
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:1328
enum mmwlan_pmf_mode pmf_mode
Protected Management Frame mode to use (802.11w)
Definition: mmwlan.h:1342
void * sta_status_cb_arg
Optional opaque argument to be passed to sta_status_cb.
Definition: mmwlan.h:1397
uint8_t ssid[MMWLAN_SSID_MAXLEN]
SSID of the AP.
Definition: mmwlan.h:1326
enum mmwlan_security_type security_type
Type of security to use.
Definition: mmwlan.h:1336
Data structure for communicating STA status information for stations connected to a Soft AP.
Definition: mmwlan.h:1289