[RFC 19/34] NAN: Support synchronized SDF transmissions
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Aug 13 10:39:03 PDT 2025
Handle DW notification and trigger transmission of multicast unsolicited
publish or active subscribe frames.
Skip USD specific logic for synchronized services.
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/common/nan_de.c | 104 +++++++++++++++++++++++++++++---
src/common/nan_de.h | 7 +++
wpa_supplicant/nan_supplicant.c | 7 ++-
3 files changed, 107 insertions(+), 11 deletions(-)
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index c45725a392..c21164b463 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -64,6 +64,7 @@ struct nan_de_service {
struct os_reltime next_publish_chan;
unsigned int next_publish_duration;
bool is_p2p;
+ bool sync;
};
struct nan_de {
@@ -84,6 +85,8 @@ struct nan_de {
unsigned int listen_freq;
unsigned int tx_wait_status_freq;
unsigned int tx_wait_end_freq;
+
+ int dw_freq;
};
@@ -365,11 +368,14 @@ static void nan_de_tx_multicast(struct nan_de *de, struct nan_de_service *srv,
type = NAN_SRV_CTRL_PUBLISH;
- nan_de_check_chan_change(srv);
- ms = nan_de_time_to_next_chan_change(srv);
- if (ms < 100)
- ms = 100;
- wait_time = ms;
+ if (!srv->sync) {
+ nan_de_check_chan_change(srv);
+ ms = nan_de_time_to_next_chan_change(srv);
+ if (ms < 100)
+ ms = 100;
+
+ wait_time = ms;
+ }
} else if (srv->type == NAN_DE_SUBSCRIBE) {
type = NAN_SRV_CTRL_SUBSCRIBE;
} else {
@@ -384,6 +390,17 @@ static void nan_de_tx_multicast(struct nan_de *de, struct nan_de_service *srv,
bssid = nan_network_id;
}
+ if (srv->sync) {
+ if (!de->cluster_id_set || !de->dw_freq) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Cluster ID or DW frequency are not set. Skip sync TX");
+ return;
+ }
+
+ wait_time = 0;
+ bssid = de->cluster_id;
+ }
+
nan_de_tx_sdf(de, srv, wait_time, type, network_id, bssid,
req_instance_id, srv->ssi);
os_get_reltime(&srv->last_multicast);
@@ -553,6 +570,9 @@ static void nan_de_start_new_publish_state(struct nan_de_service *srv,
{
unsigned int n;
+ if (srv->sync)
+ return;
+
if (force_single || !srv->freq_list || srv->freq_list[0] == 0)
srv->in_multi_chan = false;
else
@@ -617,6 +637,9 @@ static void nan_de_timer(void *eloop_ctx, void *timeout_ctx)
continue;
}
+ if (srv->sync)
+ continue;
+
if (os_reltime_initialized(&srv->next_publish_state) &&
os_reltime_before(&srv->next_publish_state, &now))
nan_de_start_new_publish_state(srv, false);
@@ -876,6 +899,10 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
enum nan_service_protocol_type srv_proto_type,
const u8 *ssi, size_t ssi_len)
{
+ /* Skip USD logic */
+ if (srv->sync)
+ goto send_event;
+
/* Subscribe function processing of a receive Publish message */
if (!os_reltime_initialized(&srv->first_discovered)) {
os_get_reltime(&srv->first_discovered);
@@ -897,6 +924,7 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
instance_id);
}
+send_event:
if (de->cb.discovery_result)
de->cb.discovery_result(
de->cb.ctx, srv->id, srv_proto_type,
@@ -1040,12 +1068,12 @@ static void nan_de_rx_subscribe(struct nan_de *de, struct nan_de_service *srv,
else if (srv->is_p2p)
a3 = de->nmi;
- nan_de_tx(de, srv->freq, 100,
+ nan_de_tx(de, srv->sync ? 0 : srv->freq, srv->sync ? 0 : 100,
srv->publish.solicited_multicast ? network_id : peer_addr,
de->nmi, a3, buf);
wpabuf_free(buf);
- if (!srv->is_p2p)
+ if (!srv->is_p2p && !srv->sync)
nan_de_pause_state(srv, peer_addr, instance_id);
offload:
@@ -1072,7 +1100,7 @@ static void nan_de_rx_follow_up(struct nan_de *de, struct nan_de_service *srv,
return;
}
- if (srv->type == NAN_DE_PUBLISH && !ssi)
+ if (srv->type == NAN_DE_PUBLISH && !ssi && !srv->sync)
nan_de_pause_state(srv, peer_addr, instance_id);
os_memcpy(srv->a3, a3, ETH_ALEN);
@@ -1341,6 +1369,18 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
return -1;
}
+ if (params->sync && !de->cluster_id_set) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Publish() - can't publish sync, cluster id is not set");
+ return -1;
+ }
+
+ if (p2p && params->sync) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Publish() - P2P is not supported with sync");
+ return -1;
+ }
+
publish_id = nan_de_get_handle(de);
if (publish_id < 1)
return -1;
@@ -1379,6 +1419,8 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
goto fail;
}
+ srv->sync = params->sync;
+
/* Prepare for single and multi-channel states; starting with
* single channel */
srv->first_multi_chan = true;
@@ -1475,6 +1517,18 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
return -1;
}
+ if (params->sync && !de->cluster_id_set) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Subscribe() - can't publish sync, cluster id is not set");
+ return -1;
+ }
+
+ if (p2p && params->sync) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Subscribe() - P2P is not supported with sync");
+ return -1;
+ }
+
subscribe_id = nan_de_get_handle(de);
if (subscribe_id < 1)
return -1;
@@ -1517,6 +1571,7 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
subscribe_id, service_name);
srv->id = subscribe_id;
srv->is_p2p = p2p;
+ srv->sync = params->sync;
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return subscribe_id;
@@ -1570,6 +1625,39 @@ int nan_de_transmit(struct nan_de *de, int handle,
}
+void nan_de_dw_trigger(struct nan_de *de, int freq)
+{
+ int i;
+ struct os_reltime now;
+
+ de->dw_freq = freq;
+
+ if (!de->cluster_id_set) {
+ wpa_printf(MSG_DEBUG, "NAN: Skip DW, cluster ID not set");
+ return;
+ }
+
+ os_get_reltime(&now);
+ for (i = 0; i < NAN_DE_MAX_SERVICE; i++) {
+ struct nan_de_service *srv = de->service[i];
+
+ if (!srv || !srv->sync)
+ continue;
+
+ if (nan_de_srv_expired(srv, &now)) {
+ nan_de_del_srv(de, srv, NAN_DE_REASON_TIMEOUT);
+ continue;
+ }
+
+ if ((srv->type == NAN_DE_PUBLISH &&
+ srv->publish.unsolicited) ||
+ (srv->type == NAN_DE_SUBSCRIBE && srv->subscribe.active)) {
+ nan_de_tx_multicast(de, srv, 0);
+ }
+ }
+}
+
+
void nan_de_set_cluster_id(struct nan_de *de, const u8 *cluster_id)
{
if (cluster_id) {
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index 8c81deb326..78bc9348fe 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -110,6 +110,9 @@ struct nan_publish_params {
/* Announcement period in ms; 0 = use default */
unsigned int announcement_period;
+
+ /* Synchronized discovery */
+ bool sync;
};
/* Returns -1 on failure or >0 publish_id */
@@ -143,6 +146,9 @@ struct nan_subscribe_params {
/* Query period in ms; 0 = use default */
unsigned int query_period;
+
+ /* Synchronized discovery */
+ bool sync;
};
/* Returns -1 on failure or >0 subscribe_id */
@@ -158,6 +164,7 @@ void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id);
int nan_de_transmit(struct nan_de *de, int handle,
const struct wpabuf *ssi, const struct wpabuf *elems,
const u8 *peer_addr, u8 req_instance_id);
+void nan_de_dw_trigger(struct nan_de *de, int freq);
void nan_de_set_cluster_id(struct nan_de *de, const u8 *cluster_id);
#endif /* NAN_DE_H */
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index a3b9bf6c20..b2b70bb6d8 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -135,8 +135,9 @@ void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
void wpas_nan_next_dw(struct wpa_supplicant *wpa_s, u32 freq)
{
if (!wpas_nan_ready(wpa_s))
- return;
+ return;
- /* TODO: Handle DW notification */
wpa_printf(MSG_DEBUG, "NAN: Next DW notification freq=%d", freq);
-}
\ No newline at end of file
+ nan_de_dw_trigger(wpa_s->nan_de, freq);
+}
+
--
2.49.0
More information about the Hostap
mailing list