Morse Micro IoT SDK  2.10.4
ap_mode.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 * Default Network configuration
27 * --
28 */
29
30#ifndef STATIC_LOCAL_IP
32#define STATIC_LOCAL_IP "192.168.1.1"
33#endif
34#ifndef STATIC_GATEWAY
36#define STATIC_GATEWAY "192.168.1.1"
37#endif
38#ifndef STATIC_NETMASK
40#define STATIC_NETMASK "255.255.255.0"
41#endif
42
43/*
44 * --
45 * Default SSID/Security configuration
46 * --
47 */
48
49#ifndef AP_SSID
51#define AP_SSID MorseMicroIoT
52#endif
53
54#ifndef SAE_PASSPHRASE
57#define SAE_PASSPHRASE 12345678
58#endif
59
60/* Default security type */
61#ifndef SECURITY_TYPE
63#define SECURITY_TYPE MMWLAN_SAE
64#endif
65
66/* Default PMF mode */
67#ifndef PMF_MODE
69#define PMF_MODE MMWLAN_PMF_REQUIRED
70#endif
71
72/*
73 * --
74 * Default channel configuration
75 * --
76 */
77
78#ifndef OP_CLASS
83#define OP_CLASS (71) /* US, 8 MHz */
84#endif
85
86#ifndef S1G_CHANNEL
91#define S1G_CHANNEL (44) /* US, 8 MHz */
92#endif
93
94#ifndef PRIMARY_BW_MHZ
103#define PRIMARY_BW_MHZ (0)
104#endif
105
106#ifndef PRIMARY_1MHZ_CHANNEL_INDEX
108#define PRIMARY_1MHZ_CHANNEL_INDEX (0)
109#endif
110
111#ifndef MAX_STAS
116#define MAX_STAS MMWLAN_DEFAULT_AP_MAX_STAS
117#endif
118
120#define _STRINGIFY(x) #x
122#define STRINGIFY(x) _STRINGIFY(x)
123
126
133static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
134{
135 MM_UNUSED(sta_status);
136
137 /* Validate that the opaque argument received matches the value passed in. This is just for
138 * testing purposes. */
140
141 printf("STA status updated\n");
142}
143
156{
157 /* Load default static IP in case we don't find the key */
158 (void)mmosal_safer_strcpy(args->ip_addr, STATIC_LOCAL_IP, sizeof(args->ip_addr));
159 (void)mmconfig_read_string("ip.ip_addr", args->ip_addr, sizeof(args->ip_addr));
160
161 /* Load default netmask in case we don't find the key */
162 (void)mmosal_safer_strcpy(args->netmask, STATIC_NETMASK, sizeof(args->netmask));
163 (void)mmconfig_read_string("ip.netmask", args->netmask, sizeof(args->netmask));
164
165 /* Load default gateway in case we don't find the key */
166 (void)mmosal_safer_strcpy(args->gateway_addr, STATIC_GATEWAY, sizeof(args->gateway_addr));
167 (void)mmconfig_read_string("ip.gateway", args->gateway_addr, sizeof(args->gateway_addr));
168}
169
180{
181 char strval[32];
182 uint32_t uint32val;
183
184 /* Load SSID */
185 (void)mmosal_safer_strcpy((char *)ap_args->ssid, STRINGIFY(AP_SSID), sizeof(ap_args->ssid));
186 (void)mmconfig_read_string("wlan.ssid", (char *)ap_args->ssid, sizeof(ap_args->ssid));
187 ap_args->ssid_len = strlen((char *)ap_args->ssid);
188
189 /* Load password */
190 (void)mmosal_safer_strcpy(ap_args->passphrase,
192 sizeof(ap_args->passphrase));
193 (void)mmconfig_read_string("wlan.password", ap_args->passphrase, sizeof(ap_args->passphrase));
194 ap_args->passphrase_len = strlen(ap_args->passphrase);
195
196 /* Load security type */
197 ap_args->security_type = SECURITY_TYPE;
198 if (mmconfig_read_string("wlan.security", strval, sizeof(strval)) > 0)
199 {
200 if (strncmp("sae", strval, sizeof(strval)) == 0)
201 {
202 ap_args->security_type = MMWLAN_SAE;
203 }
204 else if (strncmp("owe", strval, sizeof(strval)) == 0)
205 {
206 ap_args->security_type = MMWLAN_OWE;
207 }
208 else if (strncmp("open", strval, sizeof(strval)) == 0)
209 {
210 ap_args->security_type = MMWLAN_OPEN;
211 }
212 else
213 {
214 printf("Invalid value of %s read from config store: %s\n", "wlan.security", strval);
215 }
216 }
217
218 /* Load PMF mode */
219 ap_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 ap_args->pmf_mode = MMWLAN_PMF_DISABLED;
226 }
227 else if (strncmp("required", strval, sizeof(strval)) == 0)
228 {
229 ap_args->pmf_mode = MMWLAN_PMF_REQUIRED;
230 }
231 else
232 {
233 printf("Invalid value of %s read from config store: %s\n", "wlan.pmf_mode", strval);
234 }
235 }
236
237 /* Load BSSID */
238 if (mmconfig_read_string("wlan.bssid", strval, sizeof(strval)) > 0)
239 {
240 int temp[6];
241 int i;
242
243 int ret = sscanf(strval,
244 "%x:%x:%x:%x:%x:%x",
245 &temp[0],
246 &temp[1],
247 &temp[2],
248 &temp[3],
249 &temp[4],
250 &temp[5]);
251 if (ret == 6)
252 {
253 for (i = 0; i < 6; i++)
254 {
255 if (temp[i] > UINT8_MAX || temp[i] < 0)
256 {
257 /* Invalid value, ignore and reset to default */
258 memset(ap_args->bssid, 0, sizeof(ap_args->bssid));
259 break;
260 }
261
262 ap_args->bssid[i] = (uint8_t)temp[i];
263 }
264 }
265 }
266
267 ap_args->op_class = OP_CLASS;
268 if (mmconfig_read_uint32("wlan.op_class", &uint32val) == MMCONFIG_OK)
269 {
270 if (uint32val <= UINT8_MAX)
271 {
272 ap_args->op_class = uint32val;
273 }
274 else
275 {
276 printf("%s out of range\n", "wlan.op_class");
277 }
278 }
279
280 ap_args->s1g_chan_num = S1G_CHANNEL;
281 if (mmconfig_read_uint32("wlan.s1g_chan_num", &uint32val) == MMCONFIG_OK)
282 {
283 if (uint32val <= UINT8_MAX)
284 {
285 ap_args->s1g_chan_num = uint32val;
286 }
287 else
288 {
289 printf("%s out of range\n", "wlan.s1g_chan_num");
290 }
291 }
292
293 ap_args->pri_bw_mhz = PRIMARY_BW_MHZ;
294 if (mmconfig_read_uint32("wlan.pri_bw_mhz", &uint32val) == MMCONFIG_OK)
295 {
296 if (uint32val <= UINT8_MAX)
297 {
298 ap_args->pri_bw_mhz = uint32val;
299 }
300 else
301 {
302 printf("%s out of range\n", "wlan.pri_bw_mhz");
303 }
304 }
305
307 if (mmconfig_read_uint32("wlan.pri_1mhz_chan_idx", &uint32val) == MMCONFIG_OK)
308 {
309 if (uint32val <= UINT8_MAX)
310 {
311 ap_args->pri_1mhz_chan_idx = uint32val;
312 }
313 else
314 {
315 printf("%s out of range\n", "wlan.pri_1mhz_chan_idx");
316 }
317 }
318}
319
323static void load_mmwlan_settings_ap(void)
324{
325 int intval;
326 uint32_t uintval;
327 bool boolval;
328
329 /* Apply subbands enabled if specified */
330 if (mmconfig_read_bool("wlan.subbands_enabled", &boolval) == MMCONFIG_OK)
331 {
333 }
334
335 /* Apply sgi enabled if specified */
336 if (mmconfig_read_bool("wlan.sgi_enabled", &boolval) == MMCONFIG_OK)
337 {
338 mmwlan_set_sgi_enabled(boolval);
339 }
340
341 /* Apply ampdu enabled if specified */
342 if (mmconfig_read_bool("wlan.ampdu_enabled", &boolval) == MMCONFIG_OK)
343 {
345 }
346
347 /* Apply fragment threshold if specified */
348 if (mmconfig_read_int("wlan.fragment_threshold", &intval) == MMCONFIG_OK)
349 {
351 }
352
353 /* Apply rts threshold if specified */
354 if (mmconfig_read_int("wlan.rts_threshold", &intval) == MMCONFIG_OK)
355 {
357 }
358
359 /* Apply Health check intervals if specified */
360 if (mmconfig_read_uint32("wlan.max_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
361 {
362 /* If not specified, the minimum is 0 */
363 uint32_t health_check_min = 0;
364 mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &health_check_min);
365 mmwlan_set_health_check_interval(health_check_min, uintval);
366 }
367 else if (mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
368 {
369 /* If only minimum is specified, then treat the maximum as unbounded */
370 mmwlan_set_health_check_interval(uintval, UINT32_MAX);
371 }
372}
373
379static void link_status_callback(const struct mmipal_link_status *link_status)
380{
381 uint32_t time_ms = mmosal_get_time_ms();
382 if (link_status->link_state == MMIPAL_LINK_UP)
383 {
384 printf("Link is up. Time: %lu ms", time_ms);
385 printf(", IP: %s", link_status->ip_addr);
386 printf(", Netmask: %s", link_status->netmask);
387 printf(", Gateway: %s\n", link_status->gateway);
388 }
389 else
390 {
391 printf("Link is down. Time: %lu ms\n", time_ms);
392 }
393}
394
399void app_init(void)
400{
401 printf("\n\nAP Mode Example (Built " __DATE__ " " __TIME__ ")\n\n");
402 mmwlan_init();
404 mmwlan_boot(NULL);
405
407
408 /* Load IP stack settings from config store, or use defaults if no entry found in
409 * config store. */
414
415 /* Initialize IP stack. */
417 {
418 printf("Error initializing network interface.\n");
419 MMOSAL_ASSERT(false);
420 }
421
423
426
427 struct mmwlan_ap_args ap_args = MMWLAN_AP_ARGS_INIT;
428 load_mmwlan_ap_args(&ap_args);
429
432
433 ap_args.max_stas = MAX_STAS;
434
435 enum mmwlan_status status = mmwlan_ap_enable(&ap_args);
436 if (status == MMWLAN_SUCCESS)
437 {
438 printf("AP started successfully\n");
439 }
440 else
441 {
442 printf("Failed to start AP (status %d)\n", status);
443 }
444}
#define PRIMARY_BW_MHZ
Primary Bandwidth to use for AP.
Definition: ap_mode.c:103
#define SECURITY_TYPE
Security type (.
Definition: ap_mode.c:63
#define MAX_STAS
The maximum number of stations that can connect to the AP.
Definition: ap_mode.c:116
void load_mmwlan_ap_args(struct mmwlan_ap_args *ap_args)
Loads the provided structure with initialization parameters read from config store.
Definition: ap_mode.c:179
static void load_ap_mmipal_init_args(struct mmipal_init_args *args)
Loads the provided structure with initialization parameters read from config store.
Definition: ap_mode.c:155
#define S1G_CHANNEL
S1G Channel to use for AP.
Definition: ap_mode.c:91
#define STATIC_NETMASK
Statically configured netmask.
Definition: ap_mode.c:40
static void load_mmwlan_settings_ap(void)
Loads various WLAN AP specific settings from config store and applies them.
Definition: ap_mode.c:323
#define AP_SSID
SSID of the AP.
Definition: ap_mode.c:51
#define PMF_MODE
Protected Management Frames (PMF) mode (.
Definition: ap_mode.c:69
#define STRINGIFY(x)
Convert the content of the given macro to a string.
Definition: ap_mode.c:122
#define SAE_PASSPHRASE
Passphrase of the AP (ignored if security type is not SAE).
Definition: ap_mode.c:57
static void link_status_callback(const struct mmipal_link_status *link_status)
Link status callback.
Definition: ap_mode.c:379
static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
Handler for AP STA Status callback.
Definition: ap_mode.c:133
#define OP_CLASS
Operating Class to use for AP.
Definition: ap_mode.c:83
#define PRIMARY_1MHZ_CHANNEL_INDEX
Primary 1 MHz Channel Index to use for AP.
Definition: ap_mode.c:108
#define STATIC_GATEWAY
Statically configured gateway address.
Definition: ap_mode.c:36
void app_init(void)
Main entry point to the application.
Definition: ap_mode.c:399
uint32_t opaque_argument_value
A throw away variable for checking that the opaque argument is correct.
Definition: ap_mode.c:125
#define STATIC_LOCAL_IP
Statically configured IP address.
Definition: ap_mode.c:32
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:222
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:199
void mmipal_set_link_status_callback(mmipal_link_status_cb_fn_t fn)
Sets the callback function to be invoked on link status changes.
@ MMIPAL_LINK_UP
Link is up.
Definition: mmipal.h:62
@ MMIPAL_IP6_DISABLED
Disabled.
Definition: mmipal.h:121
@ MMIPAL_SUCCESS
Completed successfully.
Definition: mmipal.h:45
@ MMIPAL_STATIC
Static IP address.
Definition: mmipal.h:71
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:934
static bool mmosal_safer_strcpy(char *dst, const char *src, size_t size)
A safer version of strncpy.
Definition: mmosal.h:1039
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
#define MM_UNUSED(_x)
Casts the given expression to void to avoid "unused" warnings from the compiler.
Definition: mmutils.h:70
#define MMWLAN_AP_ARGS_INIT
Initializer for mmwlan_ap_args.
Definition: mmwlan.h:2409
enum mmwlan_status mmwlan_ap_enable(const struct mmwlan_ap_args *args)
Enable AP mode.
enum mmwlan_status mmwlan_boot(const struct mmwlan_boot_args *args)
Boot the Morse Micro transceiver and leave it in an idle state.
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_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.
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.
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.
enum mmwlan_status mmwlan_set_power_save_mode(enum mmwlan_ps_mode mode)
Sets whether or not the 802.11 power save is enabled.
@ MMWLAN_PS_DISABLED
Power save disabled.
Definition: mmwlan.h:981
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:51
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:53
@ MMWLAN_PMF_DISABLED
No protected management frames.
Definition: mmwlan.h:130
@ MMWLAN_PMF_REQUIRED
Protected management frames must be used.
Definition: mmwlan.h:128
@ MMWLAN_OPEN
Open (no security)
Definition: mmwlan.h:117
@ MMWLAN_SAE
Simultaneous Authentication of Equals (SAE)
Definition: mmwlan.h:121
@ MMWLAN_OWE
Opportunistic Wireless Encryption (OWE)
Definition: mmwlan.h:119
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.
Initialize arguments structure.
Definition: mmipal.h:175
enum mmipal_ip6_addr_mode ip6_mode
IPv6 address allocation mode to use.
Definition: mmipal.h:186
mmipal_ip_addr_t gateway_addr
Gateway IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:183
enum mmipal_addr_mode mode
IP address allocation mode to use.
Definition: mmipal.h:177
mmipal_ip_addr_t netmask
Netmask to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:181
mmipal_ip_addr_t ip_addr
IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:179
Arguments data structure for mmwlan_ap_enable().
Definition: mmwlan.h:2320
void * sta_status_cb_arg
Optional opaque argument to be passed to sta_status_cb.
Definition: mmwlan.h:2394
uint16_t s1g_chan_num
S1G channel number of the channel to use.
Definition: mmwlan.h:2359
uint8_t pri_1mhz_chan_idx
Index of the primary 1 Mhz channel within the operating channel.
Definition: mmwlan.h:2384
enum mmwlan_pmf_mode pmf_mode
Protected Management Frame mode to use (802.11w)
Definition: mmwlan.h:2338
uint16_t op_class
Operating Class to use (S1G or Global).
Definition: mmwlan.h:2351
uint8_t pri_bw_mhz
Bandwidth to use for the primary channel.
Definition: mmwlan.h:2379
uint8_t max_stas
Maximum number of stations that can connect to the AP simultaneously.
Definition: mmwlan.h:2401
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:2324
uint8_t bssid[MMWLAN_MAC_ADDR_LEN]
Optional BSSID of the AP.
Definition: mmwlan.h:2330
uint8_t ssid[MMWLAN_SSID_MAXLEN]
SSID of the AP.
Definition: mmwlan.h:2322
mmwlan_ap_sta_status_cb_t sta_status_cb
Optional callback to be invoked when the status of a connected STA changes.
Definition: mmwlan.h:2389
char passphrase[MMWLAN_PASSPHRASE_MAXLEN+1]
Passphrase (only used if security_type is MMWLAN_SAE, otherwise ignored.
Definition: mmwlan.h:2334
enum mmwlan_security_type security_type
Type of security to use.
Definition: mmwlan.h:2332
uint16_t passphrase_len
Length of passphrase.
Definition: mmwlan.h:2336
Data structure for communicating STA status information for stations connected to an AP.
Definition: mmwlan.h:2267