Morse Micro IoT SDK  2.13.1
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#include "relay_mode_led.h"
26
27#ifndef MAX_STAS
32#define MAX_STAS MMWLAN_DEFAULT_AP_MAX_STAS
33#endif
34
37
46{
47 switch (state)
48 {
50 return "Unknown (disconnected)";
51
53 return "Authenticated";
54
56 return "Associated";
57
59 return "Authorized";
60 }
61
62 return "Unrecognized";
63}
64
71static void handle_ap_sta_status(const struct mmwlan_ap_sta_status *sta_status, void *arg)
72{
73 /* Validate that the opaque argument received matches the value passed in. This is just for
74 * testing purposes. */
76
77 printf("AP STA " MM_MAC_ADDR_FMT " State: %s, AID: %u, Time: %lu ms\n",
78 MM_MAC_ADDR_VAL(sta_status->mac_addr),
80 sta_status->aid,
82}
83
90static void handle_relay_depth_change(uint8_t new_depth, void *arg)
91{
92 /* Validate that the opaque argument received matches the value passed in. This is just for
93 * testing purposes. */
95
96 if (new_depth == MMWLAN_RELAY_DEPTH_UNKNOWN)
97 {
98 MMLOG_APP("Relay depth unknown (no path to root)\n");
99 }
100 else
101 {
102 MMLOG_APP("Relay depth changed to %u\n", new_depth);
103 }
104
105 relay_led_set_depth(new_depth);
106}
107
115static void load_relay_mmwlan_ap_args(struct mmwlan_ap_args *ap_args)
116{
117 char strval[32];
118 uint32_t uint32val;
119
120 /* Load BSSID */
121 if (mmconfig_read_string("wlan.ap_bssid", strval, sizeof(strval)) > 0)
122 {
123 int temp[6];
124 int i;
125
126 int ret = sscanf(strval,
127 "%x:%x:%x:%x:%x:%x",
128 &temp[0],
129 &temp[1],
130 &temp[2],
131 &temp[3],
132 &temp[4],
133 &temp[5]);
134 if (ret == 6)
135 {
136 for (i = 0; i < 6; i++)
137 {
138 if (temp[i] > UINT8_MAX || temp[i] < 0)
139 {
140 /* Invalid value, ignore and reset to default */
141 memset(ap_args->bssid, 0, sizeof(ap_args->bssid));
142 break;
143 }
144
145 ap_args->bssid[i] = (uint8_t)temp[i];
146 }
147 }
148 }
149
150 /* Load DTIM period */
151 if (mmconfig_read_uint32("wlan.ap_dtim_period", &uint32val) == MMCONFIG_OK)
152 {
153 if (uint32val <= UINT16_MAX)
154 {
155 ap_args->dtim_period = uint32val;
156 }
157 else
158 {
159 printf("%s out of range\n", "wlan.ap_dtim_period");
160 }
161 }
162
163 /* Load Beacon Interval */
164 if (mmconfig_read_uint32("wlan.ap_beacon_interval_tus", &uint32val) == MMCONFIG_OK)
165 {
166 if (uint32val <= UINT16_MAX)
167 {
168 ap_args->beacon_interval_tus = uint32val;
169 }
170 else
171 {
172 printf("%s out of range\n", "wlan.ap_beacon_interval_tus");
173 }
174 }
175}
176
181{
182 /* Optionally override the relay depth. Only valid while STA and AP are both disabled, so it
183 * must be applied before connecting to the network. */
184 uint32_t relay_depth_override;
185 if (mmconfig_read_uint32("wlan.relay_depth_override", &relay_depth_override) == MMCONFIG_OK)
186 {
187 if (relay_depth_override <= MMWLAN_RELAY_MAX_DEPTH)
188 {
189 enum mmwlan_status status =
190 mmwlan_relay_set_depth_override((uint8_t)relay_depth_override);
191 if (status != MMWLAN_SUCCESS)
192 {
193 MMLOG_ERR("Failed to set relay depth override (status %d)\n", status);
194 }
195 }
196 else
197 {
198 printf("%s out of range\n", "wlan.relay_depth_override");
199 }
200 }
201}
202
207void app_init(void)
208{
209 enum mmwlan_status status;
210
211 MMLOG_PRINTF("\n\nRelay Mode Example (Built " __DATE__ " " __TIME__ ")\n\n");
212
214
215 /* Initialise the Wi-Fi system and boot the chip. */
217
219
220 /* Bring up the relay subsystem. */
221 struct mmwlan_relay_args relay_args = MMWLAN_RELAY_ARGS_INIT;
222 status = mmwlan_relay_enable(&relay_args);
223 if (status != MMWLAN_SUCCESS)
224 {
225 MMLOG_ERR("Failed to start relay (status %d)\n", status);
227 MMOSAL_ASSERT(0);
228 }
229
231 if (status != MMWLAN_SUCCESS)
232 {
233 MMLOG_ERR("Failed to register depth change callback (status %d)\n", status);
234 }
235
236 /* Connect to Wi-Fi network, block till connected. */
239 if (mmwlan_get_sta_state() == MMWLAN_STA_CONNECTED)
240 {
242 }
243 else
244 {
246 }
248
249 /* Load the sta args shared by the whole relay tree. */
250 struct mmwlan_sta_args sta_args = MMWLAN_STA_ARGS_INIT;
251 load_mmwlan_sta_args(&sta_args);
252
253 /* Bring up the AP interface. */
254 struct mmwlan_ap_args ap_args = MMWLAN_AP_ARGS_INIT;
256
257 /* The AP re-advertises the STA credentials so the whole tree shares one SSID. */
258 memcpy(ap_args.ssid, sta_args.ssid, sizeof(ap_args.ssid));
259 ap_args.ssid_len = sta_args.ssid_len;
260 ap_args.security_type = sta_args.security_type;
261 memcpy(ap_args.passphrase, sta_args.passphrase, sizeof(ap_args.passphrase));
262 ap_args.passphrase_len = sta_args.passphrase_len;
263 ap_args.pmf_mode = sta_args.pmf_mode;
264
267
268 ap_args.max_stas = MAX_STAS;
269
270 status = mmwlan_ap_enable(&ap_args);
271 if (status == MMWLAN_SUCCESS)
272 {
273 MMLOG_PRINTF("AP started with SSID: %s ", ap_args.ssid);
274 if (ap_args.security_type == MMWLAN_SAE)
275 {
276 MMLOG_PRINTF("with passphrase %s", ap_args.passphrase);
277 }
278 MMLOG_PRINTF("\n");
279 }
280 else
281 {
282 MMLOG_PRINTF("Failed to start AP (status %d)\n", status);
284 }
285}
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value 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:224
#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 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
uint32_t mmosal_get_time_ms(void)
Get the system time in milliseconds.
mmwlan_ap_sta_state
Enumeration of STA states.
Definition: mmwlan.h:1988
#define MMWLAN_AP_ARGS_INIT
Initializer for mmwlan_ap_args.
Definition: mmwlan.h:2171
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:1996
@ MMWLAN_AP_STA_ASSOCIATED
The STA is associated but not yet authorized for data transmission.
Definition: mmwlan.h:1994
@ MMWLAN_AP_STA_UNKNOWN
The STA is not known.
Definition: mmwlan.h:1990
@ MMWLAN_AP_STA_AUTHENTICATED
The STA is authenticated but not associated.
Definition: mmwlan.h:1992
#define MMWLAN_RELAY_ARGS_INIT
Initializer for mmwlan_relay_args.
Definition: mmwlan.h:2324
#define MMWLAN_RELAY_MAX_DEPTH
Maximum valid relay depth.
Definition: mmwlan.h:2348
enum mmwlan_status mmwlan_relay_enable(const struct mmwlan_relay_args *args)
Enable S1G Relay mode.
#define MMWLAN_RELAY_DEPTH_UNKNOWN
Relay depth value returned when the depth is unknown.
Definition: mmwlan.h:2406
enum mmwlan_status mmwlan_relay_set_depth_override(uint8_t depth)
Set the S1G Relay depth override.
enum mmwlan_status mmwlan_register_depth_change_cb(mmwlan_relay_depth_change_cb_t callback, void *arg)
Register a relay depth change callback for use in relay mode.
enum mmwlan_sta_state mmwlan_get_sta_state(void)
Gets the current WLAN STA state.
enum mmwlan_status mmwlan_set_power_save_mode(enum mmwlan_ps_mode mode)
Sets whether or not the 802.11 power save is enabled.
#define MMWLAN_STA_ARGS_INIT
Initializer for mmwlan_sta_args.
Definition: mmwlan.h:1258
@ MMWLAN_PS_DISABLED
Power save disabled.
Definition: mmwlan.h:1046
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:52
@ MMWLAN_SAE
Simultaneous Authentication of Equals (SAE)
Definition: mmwlan.h:125
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.
void load_mmwlan_sta_args(struct mmwlan_sta_args *sta_config)
Loads the provided structure with initialization parameters read from config store.
#define MAX_STAS
The maximum number of stations that can connect to the AP.
Definition: relay_mode.c:32
static void handle_relay_depth_change(uint8_t new_depth, void *arg)
Handler for relay depth change callback.
Definition: relay_mode.c:90
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:45
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:71
static void load_mmwlan_relay_settings(void)
Apply any relay mode specific settings from the config store.
Definition: relay_mode.c:180
static void load_relay_mmwlan_ap_args(struct mmwlan_ap_args *ap_args)
Loads the provided structure, with the subset of AP initialization parameters that are applicable to ...
Definition: relay_mode.c:115
void app_init(void)
Main entry point to the application.
Definition: relay_mode.c:207
uint32_t opaque_argument_value
A throwaway variable for checking that the opaque argument is correct.
Definition: relay_mode.c:36
Optional LED status indication for the Relay Mode Example Application.
void relay_led_set_connected(void)
Indicates that the app has connected to Wi-Fi.
void relay_led_set_failed(void)
Indicates that the app has failed to connect.
void relay_led_set_depth(uint8_t depth)
Indicates the current relay depth by pulsing the green LED depth times.
void relay_led_init(void)
Initializes the LED status module and starts its background task.
void relay_led_set_connecting(void)
Indicates that the app is attempting to connect to Wi-Fi.
Arguments data structure for mmwlan_ap_enable().
Definition: mmwlan.h:2059
uint16_t beacon_interval_tus
The Beacon period in units of TUs.
Definition: mmwlan.h:2113
void * sta_status_cb_arg
Optional opaque argument to be passed to sta_status_cb.
Definition: mmwlan.h:2149
enum mmwlan_pmf_mode pmf_mode
Protected Management Frame mode to use (802.11w)
Definition: mmwlan.h:2077
uint8_t max_stas
Maximum number of stations that can connect to the AP simultaneously.
Definition: mmwlan.h:2156
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:2063
uint8_t bssid[MMWLAN_MAC_ADDR_LEN]
Optional BSSID of the AP.
Definition: mmwlan.h:2069
uint8_t ssid[MMWLAN_SSID_MAXLEN]
SSID of the AP.
Definition: mmwlan.h:2061
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:2144
char passphrase[MMWLAN_PASSPHRASE_MAXLEN+1]
Passphrase (only used if security_type is MMWLAN_SAE, otherwise ignored.
Definition: mmwlan.h:2073
enum mmwlan_security_type security_type
Type of security to use.
Definition: mmwlan.h:2071
uint16_t passphrase_len
Length of passphrase.
Definition: mmwlan.h:2075
uint16_t dtim_period
The Delivery Traffic Indication Map (DTIM) interval in beacons.
Definition: mmwlan.h:2119
Data structure for communicating STA status information for stations connected to an AP.
Definition: mmwlan.h:2006
uint16_t aid
The AID of the STA.
Definition: mmwlan.h:2010
enum mmwlan_ap_sta_state state
The current state of the STA.
Definition: mmwlan.h:2008
uint8_t mac_addr[MMWLAN_MAC_ADDR_LEN]
The MAC address of the STA.
Definition: mmwlan.h:2012
Arguments data structure for mmwlan_relay_enable().
Definition: mmwlan.h:2307
Arguments data structure for mmwlan_sta_enable().
Definition: mmwlan.h:1132
uint8_t ssid[MMWLAN_SSID_MAXLEN]
SSID of the AP to connect to.
Definition: mmwlan.h:1134
char passphrase[MMWLAN_PASSPHRASE_MAXLEN+1]
Passphrase (only used if security_type is MMWLAN_SAE, otherwise ignored.
Definition: mmwlan.h:1145
enum mmwlan_pmf_mode pmf_mode
Protected Management Frame mode to use (802.11w)
Definition: mmwlan.h:1149
enum mmwlan_security_type security_type
Type of security to use.
Definition: mmwlan.h:1143
uint16_t passphrase_len
Length of passphrase.
Definition: mmwlan.h:1147
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:1136