[RFC PATCH 6/6] tests: add a proxy publishing and discovery test

Benjamin Berg benjamin at sipsolutions.net
Thu Feb 19 07:55:53 PST 2026


From: Benjamin Berg <benjamin.berg at intel.com>

Add a test where a service is published by a proxy, it is discovered and
a followup message is sent to the original device.

Signed-off-by: Benjamin Berg <benjamin.berg at intel.com>
---
 tests/hwsim/test_nan.py | 45 +++++++++++++++++++++++++++++++++++------
 1 file changed, 39 insertions(+), 6 deletions(-)

diff --git a/tests/hwsim/test_nan.py b/tests/hwsim/test_nan.py
index f7a212f7f8..28414b4eaa 100644
--- a/tests/hwsim/test_nan.py
+++ b/tests/hwsim/test_nan.py
@@ -83,6 +83,7 @@ class NanDevice:
         logger.info(f"NAN device stopped on {self.ifname}")
 
     def publish(self, service_name, ssi=None, unsolicited=1, solicited=1,
+                origin_nmi=None, origin_id=0,
                 sync=1, match_filter_rx=None, match_filter_tx=None,
                 close_proximity=0):
 
@@ -94,6 +95,9 @@ class NanDevice:
         if unsolicited == 0:
             cmd += " unsolicited=0"
 
+        if origin_nmi is not None:
+            cmd += f" origin_nmi={origin_nmi} origin_id={origin_id}"
+
         if ssi is not None:
             cmd += f" ssi={ssi}"
 
@@ -179,7 +183,7 @@ def split_nan_event(ev):
         vals[name] = val
     return vals
 
-def nan_sync_verify_event(ev, addr, pid, sid, ssi):
+def nan_sync_verify_event(ev, addr, pid, sid, ssi, proxied_by=None):
     data = split_nan_event(ev)
 
     if data['srv_proto_type'] != '2':
@@ -197,15 +201,28 @@ def nan_sync_verify_event(ev, addr, pid, sid, ssi):
     if data['address'] != addr:
         raise Exception("Unexpected peer_addr: " + ev)
 
+    if proxied_by is not None and data['proxied_by'] != proxied_by:
+        raise Exception("Unexpected proxied_by address: " + ev)
+
+    if proxied_by is None and 'proxied_by' in data:
+        raise Exception("Unexpected proxied_by information")
+
 def nan_sync_discovery(pub, sub, service_name, pssi, sssi,
-                       unsolicited=1, solicited=1, active=1,
+                       unsolicited=1, solicited=1, proxy=None, active=1,
                        expect_discovery=True,
                        timeout=2):
     paddr = pub.wpas.own_addr()
     saddr = sub.wpas.own_addr()
+    proxied_by = proxy.wpas.own_addr() if proxy else None
+
+    if proxy is None:
+        pid = pub.publish(service_name, ssi=pssi, unsolicited=unsolicited, solicited=solicited)
+    else:
+        pid = pub.publish(service_name, ssi=pssi, unsolicited=0, solicited=0)
+        ppid = proxy.publish(service_name, ssi=pssi, unsolicited=unsolicited, solicited=solicited,
+                             origin_nmi=paddr, origin_id=pid)
+        logger.info(f"Proxy internal Publish ID: {ppid}")
 
-    pid = pub.publish(service_name, ssi=pssi, unsolicited=unsolicited,
-                      solicited=solicited)
     sid = sub.subscribe(service_name, ssi=sssi, active=active)
 
     logger.info(f"Publish ID: {pid}, Subscribe ID: {sid}")
@@ -214,13 +231,13 @@ def nan_sync_discovery(pub, sub, service_name, pssi, sssi,
     if expect_discovery:
         if ev is None:
             raise Exception("NAN-DISCOVERY-RESULT event not seen")
-        nan_sync_verify_event(ev, paddr, pid, sid, pssi)
+        nan_sync_verify_event(ev, paddr, pid, sid, pssi, proxied_by)
     else:
         if ev is not None:
             raise Exception("Unexpected NAN-DISCOVERY-RESULT event")
 
     ev = pub.wpas.wait_event(["NAN-REPLIED"], timeout=timeout)
-    if active and solicited:
+    if proxy is None and active and solicited:
         if ev is None:
             raise Exception("NAN-REPLIED event not seen")
         nan_sync_verify_event(ev, saddr, pid, sid, sssi)
@@ -252,6 +269,22 @@ def test_nan_sync_followup(dev, apdev, params):
         if ev is None or f"id={pid}" not in ev or f"peer_instance_id={sid}" not in ev or "ssi=11223344" not in ev:
             raise Exception("NAN-RECEIVE followup event not seen or invalid format")
 
+def test_nan_sync_proxy_followup(dev, apdev, params):
+    """NAN synchronized active subscribe and solicited publish via proxy"""
+    with hwsim_nan_radios(count=3) as [wpas1, wpas2, wpas3], \
+        NanDevice(wpas1, "nan0") as pub, NanDevice(wpas2, "nan1") as sub, \
+        NanDevice(wpas3, "nan3") as proxy:
+
+        pid, sid, paddr, _ = nan_sync_discovery(pub, sub, "test_service",
+                                                pssi="aabbccdd", sssi="ddbbccaa",
+                                                unsolicited=0, proxy=proxy,
+                                                timeout=2)
+
+        sub.transmit(handle=sid, req_instance_id=pid, address=paddr, ssi="11223344")
+        ev = pub.wpas.wait_event(["NAN-RECEIVE"], timeout=2)
+        if ev is None or f"id={pid}" not in ev or f"peer_instance_id={sid}" not in ev or "ssi=11223344" not in ev:
+            raise Exception("NAN-RECEIVE followup event not seen or invalid format")
+
 def test_nan_sync_active_subscribe_two_publishers(dev, apdev, params):
     """NAN synchronized active subscribe and 2 publishers"""
     with hwsim_nan_radios(count=3) as [wpas1, wpas2, wpas3], \
-- 
2.53.0




More information about the Hostap mailing list