Morse Micro IoT SDK  2.11.2
relay_mode.c
Go to the documentation of this file.
1/*
2 * Copyright 2026 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 "mmwlan.h"
19#include "mmconfig.h"
20#include "mmosal.h"
21#include "mmutils.h"
22#include "mm_app_common.h"
23#include "mm_app_loadconfig.h"
24#include "mmlog.h"
25
26/*
27 * --
28 * Default SSID/Security configuration
29 * --
30 */
31
32#ifndef AP_SSID
34#define AP_SSID MorseMicroIoT
35#endif
36
37#ifndef SAE_PASSPHRASE
40#define SAE_PASSPHRASE 12345678
41#endif
42
43/* Default security type */
44#ifndef SECURITY_TYPE
46#define SECURITY_TYPE MMWLAN_SAE
47#endif
48
49/* Default PMF mode */
50#ifndef PMF_MODE
52#define PMF_MODE MMWLAN_PMF_REQUIRED
53#endif
54
55#ifndef MAX_STAS
60#define MAX_STAS MMWLAN_DEFAULT_AP_MAX_STAS
61#endif
62
64#define _STRINGIFY(x) #x
66#define STRINGIFY(x) _STRINGIFY(x)
67
70
79{
80 switch (state)
81 {
83 return "Unknown (disconnected)";
84
86 return "Authenticated";
87
89 return "Associated";
90
92 return "Authorized";
93 }
94
95 return "Unrecognized";
96}
97
104static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
105{
106 /* Validate that the opaque argument received matches the value passed in. This is just for
107 * testing purposes. */
109
110 printf("AP STA " MM_MAC_ADDR_FMT " State: %s, AID: %u, Time: %lu ms\n",
111 MM_MAC_ADDR_VAL(sta_status->mac_addr),
113 sta_status->aid,
115}
116
127{
128 char strval[32];
129
130 /* Load SSID */
131 (void)mmosal_safer_strcpy((char *)ap_args->ssid, STRINGIFY(AP_SSID), sizeof(ap_args->ssid));
132 (void)mmconfig_read_string("wlan.ap_ssid", (char *)ap_args->ssid, sizeof(ap_args->ssid));
133 ap_args->ssid_len = strlen((char *)ap_args->ssid);
134
135 /* Load password */
136 (void)mmosal_safer_strcpy(ap_args->passphrase,
138 sizeof(ap_args->passphrase));
139 (void)mmconfig_read_string("wlan.ap_password",
140 ap_args->passphrase,
141 sizeof(ap_args->passphrase));
142 ap_args->passphrase_len = strlen(ap_args->passphrase);
143
144 /* Load security type */
145 ap_args->security_type = SECURITY_TYPE;
146 if (mmconfig_read_string("wlan.ap_security", strval, sizeof(strval)) > 0)
147 {
148 if (strncmp("sae", strval, sizeof(strval)) == 0)
149 {
150 ap_args->security_type = MMWLAN_SAE;
151 }
152 else if (strncmp("owe", strval, sizeof(strval)) == 0)
153 {
154 ap_args->security_type = MMWLAN_OWE;
155 }
156 else if (strncmp("open", strval, sizeof(strval)) == 0)
157 {
158 ap_args->security_type = MMWLAN_OPEN;
159 }
160 else
161 {
162 printf("Invalid value of %s read from config store: %s\n", "wlan.ap_security", strval);
163 }
164 }
165
166 /* Load PMF mode */
167 ap_args->pmf_mode = PMF_MODE;
168 if (mmconfig_read_string("wlan.ap_pmf_mode", strval, sizeof(strval)) > 0)
169 {
170 if (strncmp("disabled", strval, sizeof(strval)) == 0)
171 {
172 printf("PMF disabled\n");
173 ap_args->pmf_mode = MMWLAN_PMF_DISABLED;
174 }
175 else if (strncmp("required", strval, sizeof(strval)) == 0)
176 {
177 ap_args->pmf_mode = MMWLAN_PMF_REQUIRED;
178 }
179 else
180 {
181 printf("Invalid value of %s read from config store: %s\n", "wlan.ap_pmf_mode", strval);
182 }
183 }
184
185 /* Load BSSID */
186 if (mmconfig_read_string("wlan.ap_bssid", strval, sizeof(strval)) > 0)
187 {
188 int temp[6];
189 int i;
190
191 int ret = sscanf(strval,
192 "%x:%x:%x:%x:%x:%x",
193 &temp[0],
194 &temp[1],
195 &temp[2],
196 &temp[3],
197 &temp[4],
198 &temp[5]);
199 if (ret == 6)
200 {
201 for (i = 0; i < 6; i++)
202 {
203 if (temp[i] > UINT8_MAX || temp[i] < 0)
204 {
205 /* Invalid value, ignore and reset to default */
206 memset(ap_args->bssid, 0, sizeof(ap_args->bssid));
207 break;
208 }
209
210 ap_args->bssid[i] = (uint8_t)temp[i];
211 }
212 }
213 }
214}
215
220void app_init(void)
221{
222 MMLOG_PRINTF("\n\nRelay Mode Example (Built " __DATE__ " " __TIME__ ")\n\n");
223
224 /* Initialize and connect to Wi-Fi, blocks till connected */
227
228 /* Query STA channel info to configure the AP interface. */
229 struct mmwlan_vif_channel_info channel_info = {};
230 enum mmwlan_status status = mmwlan_get_vif_channel_info(MMWLAN_VIF_STA, &channel_info);
231 if (status != MMWLAN_SUCCESS)
232 {
233 MMLOG_ERR("Failed to retrieve STA channel info\n", status);
234 MMOSAL_ASSERT(0);
235 }
236
237 /* Bring up the relay subsystem. */
239 status = mmwlan_relay_enable(&args);
240 if (status != MMWLAN_SUCCESS)
241 {
242 MMLOG_ERR("Failed to start relay (status %d)\n", status);
243 MMOSAL_ASSERT(0);
244 }
245
246 /* Configure the AP args. */
247 struct mmwlan_ap_args ap_args = MMWLAN_AP_ARGS_INIT;
248 load_mmwlan_ap_args(&ap_args);
250
251 ap_args.op_class = channel_info.op_class;
252 ap_args.s1g_chan_num = channel_info.s1g_chan_num;
253 ap_args.pri_bw_mhz = channel_info.pri_bw_mhz;
254 ap_args.pri_1mhz_chan_idx = channel_info.pri_1mhz_chan_idx;
255
258
259 ap_args.max_stas = MAX_STAS;
260
261 status = mmwlan_ap_enable(&ap_args);
262 if (status == MMWLAN_SUCCESS)
263 {
264 MMLOG_PRINTF("AP started with SSID: %s ", ap_args.ssid);
265 if (ap_args.security_type == MMWLAN_SAE)
266 {
267 MMLOG_PRINTF("with passphrase %s", ap_args.passphrase);
268 }
269 MMLOG_PRINTF("\n");
270 }
271 else
272 {
273 MMLOG_PRINTF("Failed to start AP (status %d)\n", status);
274 }
275}
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
#define MMLOG_PRINTF(...)
Logging printf definition.
Definition: mmlog.h:233
#define MMLOG_ERR(fmt,...)
Display an ERROR level log message.
Definition: mmlog.h:266
#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_get_vif_channel_info(enum mmwlan_vif vif, struct mmwlan_vif_channel_info *info)
Gets the channel information for the specified VIF.
#define MMWLAN_RELAY_ARGS_INIT
Initializer for mmwlan_relay_args.
Definition: mmwlan.h:2001
enum mmwlan_status mmwlan_relay_enable(const struct mmwlan_relay_args *args)
Enable S1G Relay mode.
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
@ MMWLAN_VIF_STA
STA VIF.
Definition: mmwlan.h:112
Morse Micro application helper routines for initializing/de-initializing the Wireless LAN interface a...
void app_wlan_init(void)
Initializes the WLAN interface (and dependencies) using settings specified in the config store.
void app_wlan_start(void)
Starts the WLAN interface and connects to Wi-Fi using settings specified in the config store.
#define SECURITY_TYPE
Security type (.
Definition: relay_mode.c:46
#define MAX_STAS
The maximum number of stations that can connect to the AP.
Definition: relay_mode.c:60
void load_mmwlan_ap_args(struct mmwlan_ap_args *ap_args)
Loads the provided structure with initialization parameters read from config store.
Definition: relay_mode.c:126
#define AP_SSID
SSID of the AP.
Definition: relay_mode.c:34
#define PMF_MODE
Protected Management Frames (PMF) mode (.
Definition: relay_mode.c:52
#define STRINGIFY(x)
Convert the content of the given macro to a string.
Definition: relay_mode.c:66
#define SAE_PASSPHRASE
Passphrase of the AP (ignored if security type is not SAE).
Definition: relay_mode.c:40
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: relay_mode.c:78
static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
Handler for AP STA Status callback.
Definition: relay_mode.c:104
void app_init(void)
Main entry point to the application.
Definition: relay_mode.c:220
uint32_t opaque_argument_value
A throw away variable for checking that the opaque argument is correct.
Definition: relay_mode.c:69
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
Arguments data structure for mmwlan_relay_enable().
Definition: mmwlan.h:1984
Channel information for a VIF.
Definition: mmwlan.h:2221
uint8_t pri_bw_mhz
Bandwidth of the primary channel.
Definition: mmwlan.h:2227
uint16_t op_class
Operating class for the BSS.
Definition: mmwlan.h:2223
uint16_t s1g_chan_num
S1G operating channel number.
Definition: mmwlan.h:2225
uint8_t pri_1mhz_chan_idx
Index of the primary 1 MHz channel within the operating channel.
Definition: mmwlan.h:2229