Morse Micro IoT SDK  2.12.3
dpp.c
Go to the documentation of this file.
1/*
2 * Copyright 2025-2026 Morse Micro
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
26#include <stdio.h>
27#include <string.h>
28#include "mmutils.h"
29#include "mmosal.h"
30#include "mmwlan.h"
31#include "mmconfig.h"
32#include "mm_app_common.h"
33
35#define DPP_TIMEOUT_MS (200 * 1000)
36
38#define DPP_URI_MAX_LEN 256
39
49{
50 switch (result)
51 {
53 return "Success";
55 return "Error";
57 return "Session Overlap";
58 default:
59 return "Unknown Result";
60 }
61}
62
74{
75 switch (reason)
76 {
78 return "No Response";
80 return "No Confirm";
82 return "Init Failed";
83 default:
84 return "Unknown";
85 }
86}
87
99{
100 switch (reason)
101 {
103 return "Response Error";
105 return "Timeout";
107 return "Result Timeout";
108 default:
109 return "Unknown";
110 }
111}
112
119static void dpp_store_credentials(const struct mmwlan_dpp_cb_args *dpp_event,
120 struct mmosal_semb *semb)
121{
123
124 if ((dpp_event->args.conf_received.ssid == NULL) ||
125 (dpp_event->args.conf_received.passphrase == NULL) ||
127 {
128 mmosal_printf("Invalid/incomplete credentials provided\n");
129 return;
130 }
131
132 mmosal_printf("SSID %*s, PWD %s\n",
133 dpp_event->args.conf_received.ssid_len,
134 dpp_event->args.conf_received.ssid,
135 dpp_event->args.conf_received.passphrase);
136
137 char ssid[MMWLAN_SSID_MAXLEN];
138 memcpy(ssid, dpp_event->args.conf_received.ssid, dpp_event->args.conf_received.ssid_len);
139 ssid[dpp_event->args.conf_received.ssid_len] = '\0';
140 mmconfig_write_string("wlan.ssid", ssid);
141 mmconfig_write_string("wlan.password", dpp_event->args.conf_received.passphrase);
142
143 (void)mmosal_semb_give(semb);
144}
145
152static void dpp_event_handler(const struct mmwlan_dpp_cb_args *dpp_event, void *arg)
153{
154 struct mmosal_semb *semb = (struct mmosal_semb *)arg;
155
156 switch (dpp_event->event)
157 {
159 mmosal_printf("DPP QR: chirp started\n");
160 break;
161
163 mmosal_printf("DPP QR: chirp stopped\n");
164 break;
165
167 mmosal_printf("DPP PB: started\n");
168 break;
169
171 mmosal_printf("DPP PB: configurator found\n");
172 break;
173
175 mmosal_printf("DPP PB Result: %s\n",
178 {
179 (void)mmosal_semb_give(semb);
180 }
181 break;
182
184 mmosal_printf("DPP: auth request received\n");
185 break;
186
188 mmosal_printf("DPP: auth response sent\n");
189 break;
190
192 mmosal_printf("DPP: auth succeeded\n");
193 break;
194
197 "DPP: auth failed (%s)\n",
199 (void)mmosal_semb_give(semb);
200 break;
201
203 mmosal_printf("DPP: config request sent\n");
204 break;
205
207 mmosal_printf("DPP: config received\n");
208 dpp_store_credentials(dpp_event, semb);
209 break;
210
212 mmosal_printf("DPP: config result sent\n");
213 break;
214
217 "DPP: config failed (%s)\n",
219 (void)mmosal_semb_give(semb);
220 break;
221
222 default:
223 break;
224 }
225}
226
231void app_init(void)
232{
233 printf("\n\nSTA DPP Connect Example (Built " __DATE__ " " __TIME__ ")\n\n");
234
235 struct mmosal_semb *semb = mmosal_semb_create("dpp");
236 MMOSAL_ASSERT(semb);
237
239
240 struct mmwlan_dpp_args dpp_args = MMWLAN_DPP_ARGS_INIT;
241
242 dpp_args.dpp_event_cb_arg = semb;
243
244 char mode[8] = "pb";
245 mmconfig_read_string("dpp.mode", mode, sizeof(mode));
246
247 if (strcasecmp(mode, "qr") == 0)
248 {
251 dpp_args.qr.chirp_iterations = 1000;
252
253 /* Read DER-encoded bootstrap key if configured; otherwise hostap generates a fresh
254 * key pair. Key can be generated with:
255 * openssl ecparam -name prime256v1 -genkey -noout -outform DER -out bootstrap.der */
256 uint8_t bootstrap_key_buf[MMWLAN_DPP_BOOTSTRAP_KEY_MAX_LEN];
257 int key_len = mmconfig_read_bytes("dpp.bootstrap_key",
258 bootstrap_key_buf,
259 sizeof(bootstrap_key_buf),
260 0);
261 if (key_len > 0)
262 {
263 dpp_args.qr.bootstrap_private_key = bootstrap_key_buf;
264 dpp_args.qr.bootstrap_private_key_len = (uint16_t)key_len;
265 }
266 else
267 {
268 mmosal_printf("DPP QR: no bootstrap key configured, generating ephemeral key\n");
269 }
270
271 mmosal_printf("DPP QR Enrollee Start\n");
272 enum mmwlan_status status = mmwlan_dpp_start(&dpp_args);
273 if (status != MMWLAN_SUCCESS)
274 {
275 mmosal_printf("DPP Start Failed: %u\n", status);
276 goto exit;
277 }
278
279 char uri[DPP_URI_MAX_LEN];
280 status = mmwlan_dpp_get_uri(uri, sizeof(uri));
281 if (status != MMWLAN_SUCCESS)
282 {
283 mmosal_printf("Failed to get DPP URI: %u\n", status);
284 }
285 else
286 {
287 mmosal_printf("DPP URI: %s\n", uri);
288 }
289 }
290 else
291 {
293
294 mmosal_printf("DPP Push Button Start\n");
295 enum mmwlan_status status = mmwlan_dpp_start(&dpp_args);
296 if (status != MMWLAN_SUCCESS)
297 {
298 mmosal_printf("DPP Start Failed: %u\n", status);
299 goto exit;
300 }
301 }
302
303 bool ok = mmosal_semb_wait(semb, DPP_TIMEOUT_MS);
304 if (!ok)
305 {
306 mmosal_printf("DPP timed out\n");
307 }
308
309exit:
311
313}
#define DPP_TIMEOUT_MS
Timeout in milliseconds to wait for DPP provisioning to complete.
Definition: dpp.c:35
static const char * mmwlan_dpp_conf_failure_reason_to_string(enum mmwlan_dpp_conf_failure_reason reason)
Convert a DPP configuration failure reason to its string representation.
Definition: dpp.c:97
static const char * mmwlan_dpp_pb_result_to_string(enum mmwlan_dpp_pb_result result)
Convert a DPP push button result code to its string representation.
Definition: dpp.c:48
#define DPP_URI_MAX_LEN
Maximum length of the DPP URI string.
Definition: dpp.c:38
static void dpp_event_handler(const struct mmwlan_dpp_cb_args *dpp_event, void *arg)
DPP event handler.
Definition: dpp.c:152
static const char * mmwlan_dpp_auth_failure_reason_to_string(enum mmwlan_dpp_auth_failure_reason reason)
Convert a DPP authentication failure reason to its string representation.
Definition: dpp.c:72
void app_init(void)
Main entry point to the application.
Definition: dpp.c:231
static void dpp_store_credentials(const struct mmwlan_dpp_cb_args *dpp_event, struct mmosal_semb *semb)
Store received DPP credentials to mmconfig and signal completion.
Definition: dpp.c:119
int mmconfig_read_string(const char *key, char *buffer, int bufsize)
Returns the persistent store string value identified by the key.
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_write_string(const char *key, const char *value)
Writes the null terminated string to persistent store location identified by key.
#define MMOSAL_ASSERT(expr)
Assert that the given expression evaluates to true and abort execution if not.
Definition: mmosal.h:1006
#define MMOSAL_DEV_ASSERT(x)
Assertions that are only enabled for debug builds.
Definition: mmosal.h:1054
int mmosal_printf(const char *format,...)
OS abstracted version of printf used by morselib.
bool mmosal_semb_wait(struct mmosal_semb *semb, uint32_t timeout_ms)
Wait for a counting semaphore.
struct mmosal_semb * mmosal_semb_create(const char *name)
Create a new binary semaphore.
bool mmosal_semb_give(struct mmosal_semb *semb)
Give a binary semaphore.
mmwlan_dpp_auth_failure_reason
Reason codes for MMWLAN_DPP_EVT_AUTH_FAILURE.
Definition: mmwlan.h:1655
enum mmwlan_status mmwlan_dpp_get_uri(char *uri_buf, size_t buf_len)
Retrieve the DPP bootstrap URI for the current QR enrollee session.
#define MMWLAN_DPP_BOOTSTRAP_KEY_MAX_LEN
Maximum length (in bytes) of a DER-encoded bootstrap private key.
Definition: mmwlan.h:1752
mmwlan_dpp_conf_failure_reason
Reason codes for MMWLAN_DPP_EVT_CONF_FAILED.
Definition: mmwlan.h:1671
#define MMWLAN_DPP_ARGS_INIT
Initializer for mmwlan_dpp_args.
Definition: mmwlan.h:1824
enum mmwlan_status mmwlan_dpp_stop(void)
Function to stop the DPP process.
mmwlan_dpp_pb_result
Enumeration of results for MMWLAN_DPP_EVT_PB_RESULT.
Definition: mmwlan.h:1639
enum mmwlan_status mmwlan_dpp_start(const struct mmwlan_dpp_args *args)
Function to start the Device Provisioning Protocol (DPP) process.
@ MMWLAN_DPP_AUTH_FAILURE_INIT_FAILED
Exhausted all retry attempts without a response.
Definition: mmwlan.h:1661
@ MMWLAN_DPP_AUTH_FAILURE_NO_CONFIRM
Authentication confirmation was not received in time.
Definition: mmwlan.h:1659
@ MMWLAN_DPP_AUTH_FAILURE_NO_RESPONSE
Responder never replied to the Authentication Request.
Definition: mmwlan.h:1657
@ MMWLAN_DPP_MODE_QR_ENROLLEE
DPP QR Code Enrollee mode.
Definition: mmwlan.h:1586
@ MMWLAN_DPP_CONF_FAILURE_RESPONSE_ERROR
Config response contained an error status.
Definition: mmwlan.h:1673
@ MMWLAN_DPP_CONF_FAILURE_RESULT_TIMEOUT
Timed out waiting for the DPP2 Configuration Result.
Definition: mmwlan.h:1677
@ MMWLAN_DPP_CONF_FAILURE_TIMEOUT
Timed out waiting for the config response.
Definition: mmwlan.h:1675
@ MMWLAN_DPP_PB_RESULT_SUCCESS
DPP push button process was successful.
Definition: mmwlan.h:1641
@ MMWLAN_DPP_PB_RESULT_SESSION_OVERLAP
A session overlap occurred during the DPP push button process.
Definition: mmwlan.h:1645
@ MMWLAN_DPP_PB_RESULT_ERROR
An error occurred during the DPP push button process.
Definition: mmwlan.h:1643
@ MMWLAN_DPP_EVT_CONF_FAILED
Configuration exchange failed after authentication succeeded.
Definition: mmwlan.h:1629
@ MMWLAN_DPP_EVT_AUTH_FAILURE
DPP authentication could not complete.
Definition: mmwlan.h:1619
@ MMWLAN_DPP_EVT_AUTH_REQ_RX
Enrollee received and validated a DPP Authentication Request.
Definition: mmwlan.h:1613
@ MMWLAN_DPP_EVT_CHIRP_STARTED
QR enrollee began broadcasting presence announcements.
Definition: mmwlan.h:1599
@ MMWLAN_DPP_EVT_CONF_REQ_TX
Enrollee sent a DPP Configuration Request.
Definition: mmwlan.h:1623
@ MMWLAN_DPP_EVT_AUTH_SUCCESS
DPP authentication phase succeeded (both PB and QR flows).
Definition: mmwlan.h:1617
@ MMWLAN_DPP_EVT_CONF_RESULT_TX
Enrollee sent a DPP Configuration Result (DPP2+).
Definition: mmwlan.h:1627
@ MMWLAN_DPP_EVT_PB_DISCOVERY
Push Button configurator discovered.
Definition: mmwlan.h:1607
@ MMWLAN_DPP_EVT_AUTH_RESP_TX
Enrollee sent a DPP Authentication Response.
Definition: mmwlan.h:1615
@ MMWLAN_DPP_EVT_CONF_RECEIVED
DPP configuration received (any DPP mode).
Definition: mmwlan.h:1625
@ MMWLAN_DPP_EVT_CHIRP_STOPPED
QR enrollee presence announcement process has stopped.
Definition: mmwlan.h:1601
@ MMWLAN_DPP_EVT_PB_STARTED
Push Button enrollment started (enrollee).
Definition: mmwlan.h:1605
@ MMWLAN_DPP_EVT_PB_RESULT
DPP push button result.
Definition: mmwlan.h:1609
mmwlan_status
Enumeration of status return codes.
Definition: mmwlan.h:50
#define MMWLAN_SSID_MAXLEN
Maximum allowable length of an SSID.
Definition: mmwlan.h:90
@ 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 hold the arguments used for the DPP process.
Definition: mmwlan.h:1808
void(* dpp_event_cb)(const struct mmwlan_dpp_cb_args *dpp_event, void *arg)
DPP event callback prototype.
Definition: mmwlan.h:1810
void * dpp_event_cb_arg
Optional user argument that will be passed back to the DPP event callback.
Definition: mmwlan.h:1812
enum mmwlan_dpp_mode mode
DPP mode to use.
Definition: mmwlan.h:1814
struct mmwlan_dpp_qr_args qr
QR enrollee specific arguments.
Definition: mmwlan.h:1816
Structure passed back when a DPP event occurs.
Definition: mmwlan.h:1687
union mmwlan_dpp_cb_args::@2 args
Union of arguments for DPP events.
const uint8_t * ssid
SSID of the AP to connect to.
Definition: mmwlan.h:1705
struct mmwlan_dpp_cb_args::@2::@4 conf_received
Argument for MMWLAN_DPP_EVT_CONF_RECEIVED event.
struct mmwlan_dpp_cb_args::@2::@8 auth_failure
Argument for MMWLAN_DPP_EVT_AUTH_FAILURE event.
struct mmwlan_dpp_cb_args::@2::@9 conf_failed
Argument for MMWLAN_DPP_EVT_CONF_FAILED event.
uint16_t ssid_len
Length of the SSID.
Definition: mmwlan.h:1707
enum mmwlan_dpp_auth_failure_reason reason
Reason for the authentication failure.
Definition: mmwlan.h:1739
const char * passphrase
Passphrase, NULL terminated.
Definition: mmwlan.h:1709
enum mmwlan_dpp_pb_result result
Result of DPP push button.
Definition: mmwlan.h:1698
struct mmwlan_dpp_cb_args::@2::@3 pb_result
Argument for MMWLAN_DPP_EVT_PB_RESULT event.
enum mmwlan_dpp_event event
The DPP event that has occurred.
Definition: mmwlan.h:1689
uint16_t bootstrap_private_key_len
Length of bootstrap_private_key in bytes.
Definition: mmwlan.h:1780
const uint8_t * bootstrap_private_key
DER-encoded EC private key for the DPP bootstrap identity (P-256 / prime256v1).
Definition: mmwlan.h:1778
uint16_t chirp_iterations
Number of chirp iterations (0 = default of 1).
Definition: mmwlan.h:1798