Morse Micro IoT SDK  2.9.7
beacon_stuffing.c
Go to the documentation of this file.
1/*
2 * Copyright 2024 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
78#include <string.h>
79#include <endian.h>
80#include "mmhal.h"
81#include "mmosal.h"
82#include "mmwlan.h"
83#include "mmconfig.h"
84#include "mmutils.h"
85
86#include "mm_app_common.h"
87
88/* Application default configurations. */
95#define DEFAULT_OUI {0x4D, 0x4D, 0x42};
98#define DEFAULT_LOG_LEN_BYTES 30
100#define DEFAULT_STATS_UPDATE_PERIOD_MS 1000
101
102
104#define FILTER_INDEX 0
106#define RGB_DATA_LENGTH_BYTES 3
107
111
114{
116 uint32_t occurrences;
118 uint8_t *ie_data;
120 uint32_t ie_len;
121};
122
136static void beacon_vendor_ie_callback(const uint8_t *ies, uint32_t ies_len, void *arg)
137{
138 int offset;
139 uint8_t length;
140 struct beacon_vendor_ie_stat *stat = (struct beacon_vendor_ie_stat *)arg;
141
143 if (offset > 0)
144 {
145 stat->occurrences++;
146 /* Note that we rely on mm_find_vendor_specific_ie() to validate that the IE does not
147 * extend past the end of the given buffer. */
148 length = ies[offset + 1];
149 offset += 2;
150
151 if (stat->ie_data && (stat->ie_len != length))
152 {
153 mmosal_free(stat->ie_data);
154 stat->ie_data = NULL;
155 stat->ie_len = 0;
156 }
157
158 if (!stat->ie_data)
159 {
160 stat->ie_data = (uint8_t *)mmosal_malloc(length);
161 if (!stat->ie_data)
162 {
163 /* Generally we would want to avoid operations that might take an extended amount of
164 * time (i.e printf()). This has just been put in to try and make it as clear as
165 * possible what the error might be for the purposes of the example application. */
166 printf("Failed to alloc memory for ie data.");
167 return;
168 }
169 stat->ie_len = length;
170 }
171
172 memcpy(stat->ie_data, (ies + offset), length);
173
175 {
176 const uint8_t *rgb_data = stat->ie_data + MMWLAN_OUI_SIZE;
177 mmhal_set_led(LED_RED, rgb_data[0]);
178 mmhal_set_led(LED_GREEN, rgb_data[1]);
179 mmhal_set_led(LED_BLUE, rgb_data[2]);
180 }
181 }
182}
183
191static void beacon_vendor_ie_stat_log(struct beacon_vendor_ie_stat *stat, uint32_t max_data_log_len)
192{
193 uint32_t ii;
194 printf("%11lu | %14lu | ", stat->occurrences, stat->ie_len);
195 if (stat->ie_data)
196 {
197 for (ii = 0; (ii < stat->ie_len) && (ii < max_data_log_len); ii++)
198 {
199 printf("%02x", stat->ie_data[ii]);
200 }
201
202 printf("%s\n", (stat->ie_len >= max_data_log_len) ? "..." : "");
203 }
204 else
205 {
206 printf("N/A \n");
207 }
208}
209
214void app_init(void)
215{
216 enum mmwlan_status status;
217 struct beacon_vendor_ie_stat stat = {0};
218 uint8_t mmconfig_oui[MMWLAN_OUI_SIZE];
219
220 uint8_t oui[MMWLAN_OUI_SIZE] = DEFAULT_OUI;
221 uint32_t log_length_bytes = DEFAULT_LOG_LEN_BYTES;
222 uint32_t update_period_ms = DEFAULT_STATS_UPDATE_PERIOD_MS;
223
224 /* Read out any params from configstore if they exist. If they don't the variables will retain
225 * their current values. */
226 mmconfig_read_uint32("beacon_stuffing.log_len_bytes", &log_length_bytes);
227 mmconfig_read_uint32("beacon_stuffing.log_period_ms", &update_period_ms);
228
229 int mmconfig_oui_len = mmconfig_read_bytes("beacon_stuffing.oui", &mmconfig_oui,
230 MMWLAN_OUI_SIZE, 0);
231 if (mmconfig_oui_len >= MMWLAN_OUI_SIZE)
232 {
233 memcpy(&oui, &mmconfig_oui, MMWLAN_OUI_SIZE);
234 }
235
236 printf("\n\nMorse Beacon Stuffing Demo (Built " __DATE__ " " __TIME__ ")\n\n");
237
238 /* Initialize and connect to Wi-Fi, blocks till connected */
241
242 memcpy(filter.ouis[FILTER_INDEX], &oui, MMWLAN_OUI_SIZE);
243 filter.n_ouis = 1;
245 filter.cb_arg = (void *)&stat;
246
248 if (status != MMWLAN_SUCCESS)
249 {
250 printf("Failed to register beacon vendor ie filter.\n");
251 return;
252 }
253
254 printf("\nFiltering for Vendor Specific IE with OUI: 0x%02x%02x%02x\n", oui[0], oui[1], oui[2]);
255
256 printf("Occurrences | Length (bytes) | Data (hex)\n");
257 while (1)
258 {
259 mmosal_task_sleep(update_period_ms);
260 beacon_vendor_ie_stat_log(&stat, log_length_bytes);
261 }
262}
#define DEFAULT_STATS_UPDATE_PERIOD_MS
How often the contents for the stat struct is logged.
struct mmwlan_beacon_vendor_ie_filter filter
Filter structure used when calling mmwlan_update_beacon_vendor_ie_filter().
#define DEFAULT_LOG_LEN_BYTES
Length of the data to print when logging the stat struct.
#define DEFAULT_OUI
OUI to look for in the Vendor Specific IE.
#define FILTER_INDEX
Filter index to install the OUI.
#define RGB_DATA_LENGTH_BYTES
Length of data required for updating the LED state.
void app_init(void)
Main entry point to the application.
static void beacon_vendor_ie_stat_log(struct beacon_vendor_ie_stat *stat, uint32_t max_data_log_len)
Print the contents of the given stat struct using printf().
static void beacon_vendor_ie_callback(const uint8_t *ies, uint32_t ies_len, void *arg)
Callback function that gets executed every time a beacon containing a matching Vendor Specific IE is ...
int mmconfig_read_bytes(const char *key, void *buffer, uint32_t buffsize, uint32_t offset)
Returns the persistent store data 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.
void mmhal_set_led(uint8_t led, uint8_t level)
Set the specified LED to the requested level.
#define mmosal_malloc(size)
Allocate memory of the given size and return a pointer to it (malloc).
Definition: mmosal.h:137
void mmosal_free(void *p)
Free the given memory allocation.
void mmosal_task_sleep(uint32_t duration_ms)
Sleep for a period of time, yielding during that time.
static int mm_find_vendor_specific_ie(const uint8_t *ies, uint32_t ies_len, const uint8_t *id, size_t id_len)
Search through the given list of Information Elements (IEs) to find the first Vendor Specific IE that...
Definition: mmutils.h:309
enum mmwlan_status mmwlan_update_beacon_vendor_ie_filter(const struct mmwlan_beacon_vendor_ie_filter *filter)
Function to update the filter used to pass beacon back.
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
#define MMWLAN_OUI_SIZE
Size of an 802.11 OUI element in octets.
Definition: mmwlan.h:94
@ MMWLAN_SUCCESS
The operation was successful.
Definition: mmwlan.h:52
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.
Structure to store some basic statistics for the beacon Vendor Specific IE reception.
uint32_t occurrences
Number of times the Vendor Specific IE in the beacon was seen.
uint8_t * ie_data
If not NULL, the most recent IE data received.
uint32_t ie_len
The length in bytes of ie_data.
Structure for storing beacon vendor ie filter parameter.
Definition: mmwlan.h:2160
void * cb_arg
Opaque argument to be passed to the callbacks.
Definition: mmwlan.h:2171
mmwlan_beacon_vendor_ie_filter_cb_t cb
Callback that will be executed upon reception of a beacon containing a Vendor Specific information el...
Definition: mmwlan.h:2169
mmwlan_oui_t ouis[MMWLAN_BEACON_VENDOR_IE_MAX_OUI_FILTERS]
List of OUIs to filter on.
Definition: mmwlan.h:2176
uint8_t n_ouis
Number of OUIs contained within ouis.
Definition: mmwlan.h:2174