Morse Micro IoT SDK  2.11.2
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#include "mmlog.h"
24
25/*
26 * --
27 * Default Network configuration
28 * --
29 */
30
31#ifndef STATIC_LOCAL_IP
33#define STATIC_LOCAL_IP "192.168.1.1"
34#endif
35#ifndef STATIC_GATEWAY
37#define STATIC_GATEWAY "192.168.1.1"
38#endif
39#ifndef STATIC_NETMASK
41#define STATIC_NETMASK "255.255.255.0"
42#endif
43
44/*
45 * --
46 * Default SSID/Security configuration
47 * --
48 */
49
50#ifndef AP_SSID
52#define AP_SSID MorseMicroIoT
53#endif
54
55#ifndef SAE_PASSPHRASE
58#define SAE_PASSPHRASE 12345678
59#endif
60
61/* Default security type */
62#ifndef SECURITY_TYPE
64#define SECURITY_TYPE MMWLAN_SAE
65#endif
66
67/* Default PMF mode */
68#ifndef PMF_MODE
70#define PMF_MODE MMWLAN_PMF_REQUIRED
71#endif
72
73/*
74 * --
75 * Default channel configuration
76 * --
77 */
78
79#ifndef OP_CLASS
84#define OP_CLASS (71) /* US, 8 MHz */
85#endif
86
87#ifndef S1G_CHANNEL
92#define S1G_CHANNEL (44) /* US, 8 MHz */
93#endif
94
95#ifndef PRIMARY_BW_MHZ
104#define PRIMARY_BW_MHZ (0)
105#endif
106
107#ifndef PRIMARY_1MHZ_CHANNEL_INDEX
109#define PRIMARY_1MHZ_CHANNEL_INDEX (3)
110#endif
111
112#ifndef MAX_STAS
117#define MAX_STAS MMWLAN_DEFAULT_AP_MAX_STAS
118#endif
119
121#define _STRINGIFY(x) #x
123#define STRINGIFY(x) _STRINGIFY(x)
124
127
136{
137 switch (state)
138 {
140 return "Unknown (disconnected)";
141
143 return "Authenticated";
144
146 return "Associated";
147
149 return "Authorized";
150 }
151
152 return "Unrecognized";
153}
154
161static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
162{
163 /* Validate that the opaque argument received matches the value passed in. This is just for
164 * testing purposes. */
166
167 MMLOG_APP("AP STA " MM_MAC_ADDR_FMT " State: %s, AID: %u\n",
168 MM_MAC_ADDR_VAL(sta_status->mac_addr),
170 sta_status->aid);
171}
172
185{
186 /* Load default static IP in case we don't find the key */
187 (void)mmosal_safer_strcpy(args->ip_addr, STATIC_LOCAL_IP, sizeof(args->ip_addr));
188 (void)mmconfig_read_string("ip.ip_addr", args->ip_addr, sizeof(args->ip_addr));
189
190 /* Load default netmask in case we don't find the key */
191 (void)mmosal_safer_strcpy(args->netmask, STATIC_NETMASK, sizeof(args->netmask));
192 (void)mmconfig_read_string("ip.netmask", args->netmask, sizeof(args->netmask));
193
194 /* Load default gateway in case we don't find the key */
195 (void)mmosal_safer_strcpy(args->gateway_addr, STATIC_GATEWAY, sizeof(args->gateway_addr));
196 (void)mmconfig_read_string("ip.gateway", args->gateway_addr, sizeof(args->gateway_addr));
197}
198
209{
210 char strval[32];
211 uint32_t uint32val;
212
213 /* Load SSID */
214 (void)mmosal_safer_strcpy((char *)ap_args->ssid, STRINGIFY(AP_SSID), sizeof(ap_args->ssid));
215 (void)mmconfig_read_string("wlan.ap_ssid", (char *)ap_args->ssid, sizeof(ap_args->ssid));
216 ap_args->ssid_len = strlen((char *)ap_args->ssid);
217
218 /* Load password */
219 (void)mmosal_safer_strcpy(ap_args->passphrase,
221 sizeof(ap_args->passphrase));
222 (void)mmconfig_read_string("wlan.ap_password",
223 ap_args->passphrase,
224 sizeof(ap_args->passphrase));
225 ap_args->passphrase_len = strlen(ap_args->passphrase);
226
227 /* Load security type */
228 ap_args->security_type = SECURITY_TYPE;
229 if (mmconfig_read_string("wlan.ap_security", strval, sizeof(strval)) > 0)
230 {
231 if (strncmp("sae", strval, sizeof(strval)) == 0)
232 {
233 ap_args->security_type = MMWLAN_SAE;
234 }
235 else if (strncmp("owe", strval, sizeof(strval)) == 0)
236 {
237 ap_args->security_type = MMWLAN_OWE;
238 }
239 else if (strncmp("open", strval, sizeof(strval)) == 0)
240 {
241 ap_args->security_type = MMWLAN_OPEN;
242 }
243 else
244 {
245 MMLOG_APP("Invalid value of %s read from config store: %s\n",
246 "wlan.ap_security",
247 strval);
248 }
249 }
250
251 /* Load PMF mode */
252 ap_args->pmf_mode = PMF_MODE;
253 if (mmconfig_read_string("wlan.ap_pmf_mode", strval, sizeof(strval)) > 0)
254 {
255 if (strncmp("disabled", strval, sizeof(strval)) == 0)
256 {
257 MMLOG_APP("PMF disabled\n");
258 ap_args->pmf_mode = MMWLAN_PMF_DISABLED;
259 }
260 else if (strncmp("required", strval, sizeof(strval)) == 0)
261 {
262 ap_args->pmf_mode = MMWLAN_PMF_REQUIRED;
263 }
264 else
265 {
266 MMLOG_APP("Invalid value of %s read from config store: %s\n",
267 "wlan.ap_pmf_mode",
268 strval);
269 }
270 }
271
272 /* Load BSSID */
273 if (mmconfig_read_string("wlan.ap_bssid", strval, sizeof(strval)) > 0)
274 {
275 int temp[6];
276 int i;
277
278 int ret = sscanf(strval,
279 "%x:%x:%x:%x:%x:%x",
280 &temp[0],
281 &temp[1],
282 &temp[2],
283 &temp[3],
284 &temp[4],
285 &temp[5]);
286 if (ret == 6)
287 {
288 for (i = 0; i < 6; i++)
289 {
290 if (temp[i] > UINT8_MAX || temp[i] < 0)
291 {
292 /* Invalid value, ignore and reset to default */
293 memset(ap_args->bssid, 0, sizeof(ap_args->bssid));
294 break;
295 }
296
297 ap_args->bssid[i] = (uint8_t)temp[i];
298 }
299 }
300 }
301
302 ap_args->op_class = OP_CLASS;
303 if (mmconfig_read_uint32("wlan.ap_op_class", &uint32val) == MMCONFIG_OK)
304 {
305 if (uint32val <= UINT8_MAX)
306 {
307 ap_args->op_class = uint32val;
308 }
309 else
310 {
311 MMLOG_APP("%s out of range\n", "wlan.ap_op_class");
312 }
313 }
314
315 ap_args->s1g_chan_num = S1G_CHANNEL;
316 if (mmconfig_read_uint32("wlan.ap_s1g_chan_num", &uint32val) == MMCONFIG_OK)
317 {
318 if (uint32val <= UINT8_MAX)
319 {
320 ap_args->s1g_chan_num = uint32val;
321 }
322 else
323 {
324 MMLOG_APP("%s out of range\n", "wlan.ap_s1g_chan_num");
325 }
326 }
327
328 ap_args->pri_bw_mhz = PRIMARY_BW_MHZ;
329 if (mmconfig_read_uint32("wlan.ap_pri_bw_mhz", &uint32val) == MMCONFIG_OK)
330 {
331 if (uint32val <= UINT8_MAX)
332 {
333 ap_args->pri_bw_mhz = uint32val;
334 }
335 else
336 {
337 MMLOG_APP("%s out of range\n", "wlan.ap_pri_bw_mhz");
338 }
339 }
340
342 if (mmconfig_read_uint32("wlan.ap_pri_1mhz_chan_idx", &uint32val) == MMCONFIG_OK)
343 {
344 if (uint32val <= UINT8_MAX)
345 {
346 ap_args->pri_1mhz_chan_idx = uint32val;
347 }
348 else
349 {
350 MMLOG_APP("%s out of range\n", "wlan.ap_pri_1mhz_chan_idx");
351 }
352 }
353}
354
358static void load_mmwlan_settings_ap(void)
359{
360 int intval;
361 uint32_t uintval;
362 bool boolval;
363
364 /* Apply subbands enabled if specified */
365 if (mmconfig_read_bool("wlan.subbands_enabled", &boolval) == MMCONFIG_OK)
366 {
368 }
369
370 /* Apply sgi enabled if specified */
371 if (mmconfig_read_bool("wlan.sgi_enabled", &boolval) == MMCONFIG_OK)
372 {
373 mmwlan_set_sgi_enabled(boolval);
374 }
375
376 /* Apply ampdu enabled if specified */
377 if (mmconfig_read_bool("wlan.ampdu_enabled", &boolval) == MMCONFIG_OK)
378 {
380 }
381
382 /* Apply fragment threshold if specified */
383 if (mmconfig_read_int("wlan.fragment_threshold", &intval) == MMCONFIG_OK)
384 {
386 }
387
388 /* Apply rts threshold if specified */
389 if (mmconfig_read_int("wlan.rts_threshold", &intval) == MMCONFIG_OK)
390 {
392 }
393
394 /* Apply Health check intervals if specified */
395 if (mmconfig_read_uint32("wlan.max_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
396 {
397 /* If not specified, the minimum is 0 */
398 uint32_t health_check_min = 0;
399 mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &health_check_min);
400 mmwlan_set_health_check_interval(health_check_min, uintval);
401 }
402 else if (mmconfig_read_uint32("wlan.min_health_check_intvl_ms", &uintval) == MMCONFIG_OK)
403 {
404 /* If only minimum is specified, then treat the maximum as unbounded */
405 mmwlan_set_health_check_interval(uintval, UINT32_MAX);
406 }
407}
408
414static void link_status_callback(const struct mmipal_link_status *link_status)
415{
416 uint32_t time_ms = mmosal_get_time_ms();
417 if (link_status->link_state == MMIPAL_LINK_UP)
418 {
419 MMLOG_PRINTF("Link is up. Time: %lu ms", time_ms);
420 MMLOG_PRINTF(", IP: %s", link_status->ip_addr);
421 MMLOG_PRINTF(", Netmask: %s", link_status->netmask);
422 MMLOG_PRINTF(", Gateway: %s\n", link_status->gateway);
423 }
424 else
425 {
426 MMLOG_PRINTF("Link is down. Time: %lu ms\n", time_ms);
427 }
428}
429
434void app_init(void)
435{
436 MMLOG_PRINTF("\n\nAP Mode Example (Built " __DATE__ " " __TIME__ ")\n\n");
437 mmwlan_init();
439 mmwlan_boot(NULL);
440
442
443 /* Load IP stack settings from config store, or use defaults if no entry found in
444 * config store. */
449
450 /* Initialize IP stack. */
452 {
453 MMLOG_APP("Error initializing network interface.\n");
454 MMOSAL_ASSERT(false);
455 }
456
458
461
462 struct mmwlan_ap_args ap_args = MMWLAN_AP_ARGS_INIT;
463 load_mmwlan_ap_args(&ap_args);
464
467
468 ap_args.max_stas = MAX_STAS;
469
470 MMLOG_APP("Starting AP mode...\n");
471 enum mmwlan_status status = mmwlan_ap_enable(&ap_args);
472 if (status == MMWLAN_SUCCESS)
473 {
474 MMLOG_APP("AP started successfully\n");
475 }
476 else
477 {
478 MMLOG_APP("Failed to start AP (status %d)\n", status);
479 }
480}
#define PRIMARY_BW_MHZ
Primary Bandwidth to use for AP.
Definition: ap_mode.c:104
#define SECURITY_TYPE
Security type (.
Definition: ap_mode.c:64
#define MAX_STAS
The maximum number of stations that can connect to the AP.
Definition: ap_mode.c:117
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:208
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:184
#define S1G_CHANNEL
S1G Channel to use for AP.
Definition: ap_mode.c:92
#define STATIC_NETMASK
Statically configured netmask.
Definition: ap_mode.c:41
static void load_mmwlan_settings_ap(void)
Loads various WLAN AP specific settings from config store and applies them.
Definition: ap_mode.c:358
#define AP_SSID
SSID of the AP.
Definition: ap_mode.c:52
#define PMF_MODE
Protected Management Frames (PMF) mode (.
Definition: ap_mode.c:70
#define STRINGIFY(x)
Convert the content of the given macro to a string.
Definition: ap_mode.c:123
#define SAE_PASSPHRASE
Passphrase of the AP (ignored if security type is not SAE).
Definition: ap_mode.c:58
static void link_status_callback(const struct mmipal_link_status *link_status)
Link status callback.
Definition: ap_mode.c:414
static char * mmwlan_ap_sta_state_to_str(enum mmwlan_ap_sta_state state)
Function to convert mmwlan_ap_sta_state enumeration to a human readable string.
Definition: ap_mode.c:135
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:161
#define OP_CLASS
Operating Class to use for AP.
Definition: ap_mode.c:84
#define PRIMARY_1MHZ_CHANNEL_INDEX
Primary 1 MHz Channel Index to use for AP.
Definition: ap_mode.c:109
#define STATIC_GATEWAY
Statically configured gateway address.
Definition: ap_mode.c:37
void app_init(void)
Main entry point to the application.
Definition: ap_mode.c:434
uint32_t opaque_argument_value
A throw away variable for checking that the opaque argument is correct.
Definition: ap_mode.c:126
#define STATIC_LOCAL_IP
Statically configured IP address.
Definition: ap_mode.c:33
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:193
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:119
@ MMIPAL_SUCCESS
Completed successfully.
Definition: mmipal.h:45
@ MMIPAL_STATIC
Static IP address.
Definition: mmipal.h:71
#define MMLOG_APP(fmt,...)
Display an APP level log message.
Definition: mmlog.h:238
#define MMLOG_PRINTF(...)
Logging printf definition.
Definition: mmlog.h:233
#define MM_MAC_ADDR_FMT
Macro for format specifier to print MM_MAC_ADDR_VAL.
Definition: mmlog.h:51
#define MM_MAC_ADDR_VAL(value)
Macro for printing a MAC address.
Definition: mmlog.h:47
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:1006
static bool mmosal_safer_strcpy(char *dst, const char *src, size_t size)
A safer version of strncpy.
Definition: mmosal.h:1111
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
mmwlan_ap_sta_state
Enumeration of STA states.
Definition: mmwlan.h:1711
#define MMWLAN_AP_ARGS_INIT
Initializer for mmwlan_ap_args.
Definition: mmwlan.h:1878
enum mmwlan_status mmwlan_ap_enable(const struct mmwlan_ap_args *args)
Enable AP mode.
@ MMWLAN_AP_STA_AUTHORIZED
The STA is fully connected and authorized for data transmission.
Definition: mmwlan.h:1719
@ MMWLAN_AP_STA_ASSOCIATED
The STA is associated but not yet authorized for data transmission.
Definition: mmwlan.h:1717
@ MMWLAN_AP_STA_UNKNOWN
The STA is not known.
Definition: mmwlan.h:1713
@ MMWLAN_AP_STA_AUTHENTICATED
The STA is authenticated but not associated.
Definition: mmwlan.h:1715
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:988
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:134
@ MMWLAN_PMF_REQUIRED
Protected management frames must be used.
Definition: mmwlan.h:132
@ MMWLAN_OPEN
Open (no security)
Definition: mmwlan.h:121
@ MMWLAN_SAE
Simultaneous Authentication of Equals (SAE)
Definition: mmwlan.h:125
@ MMWLAN_OWE
Opportunistic Wireless Encryption (OWE)
Definition: mmwlan.h:123
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:173
enum mmipal_ip6_addr_mode ip6_mode
IPv6 address allocation mode to use.
Definition: mmipal.h:184
mmipal_ip_addr_t gateway_addr
Gateway IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:181
enum mmipal_addr_mode mode
IP address allocation mode to use.
Definition: mmipal.h:175
mmipal_ip_addr_t netmask
Netmask to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:179
mmipal_ip_addr_t ip_addr
IP address to use (if mode is MMIPAL_STATIC).
Definition: mmipal.h:177
Arguments data structure for mmwlan_ap_enable().
Definition: mmwlan.h:1782
void * sta_status_cb_arg
Optional opaque argument to be passed to sta_status_cb.
Definition: mmwlan.h:1856
uint16_t s1g_chan_num
S1G channel number of the channel to use.
Definition: mmwlan.h:1821
uint8_t pri_1mhz_chan_idx
Index of the primary 1 Mhz channel within the operating channel.
Definition: mmwlan.h:1846
enum mmwlan_pmf_mode pmf_mode
Protected Management Frame mode to use (802.11w)
Definition: mmwlan.h:1800
uint16_t op_class
Operating Class to use (S1G or Global).
Definition: mmwlan.h:1813
uint8_t pri_bw_mhz
Bandwidth to use for the primary channel.
Definition: mmwlan.h:1841
uint8_t max_stas
Maximum number of stations that can connect to the AP simultaneously.
Definition: mmwlan.h:1863
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:1786
uint8_t bssid[MMWLAN_MAC_ADDR_LEN]
Optional BSSID of the AP.
Definition: mmwlan.h:1792
uint8_t ssid[MMWLAN_SSID_MAXLEN]
SSID of the AP.
Definition: mmwlan.h:1784
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:1851
char passphrase[MMWLAN_PASSPHRASE_MAXLEN+1]
Passphrase (only used if security_type is MMWLAN_SAE, otherwise ignored.
Definition: mmwlan.h:1796
enum mmwlan_security_type security_type
Type of security to use.
Definition: mmwlan.h:1794
uint16_t passphrase_len
Length of passphrase.
Definition: mmwlan.h:1798
Data structure for communicating STA status information for stations connected to an AP.
Definition: mmwlan.h:1729
uint16_t aid
The AID of the STA.
Definition: mmwlan.h:1733
enum mmwlan_ap_sta_state state
The current state of the STA.
Definition: mmwlan.h:1731
uint8_t mac_addr[MMWLAN_MAC_ADDR_LEN]
The MAC address of the STA.
Definition: mmwlan.h:1735