[RFC PATCH BlueZ v2 7/7] mesh: gatt-proxy: propagate beacons

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



MshPRT_v1.1, section 6.7 requires that:
1. Upon connection of a GATT proxy client to a GATT proxy server, the
   server sends a beacon for each known subnet to the client.
2. Upon processing a SNB or MPB with a new IV index or flags value, the
   GATT proxy server shall propagate the beacon to the client.
3. When the GATT proxy server is added to a new subnet, a beacon for
   that subnet shall be sent to the client.
---
 mesh/gatt-proxy-svc.c | 20 +++++++++++++++++++-
 mesh/gatt-proxy-svc.h |  1 +
 mesh/net-keys.c       | 25 +++++++++++++++++++++++++
 mesh/net-keys.h       |  1 +
 mesh/net.c            | 23 +++++++++++++++++++++++
 mesh/net.h            |  1 +
 6 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/mesh/gatt-proxy-svc.c b/mesh/gatt-proxy-svc.c
index 4100578a9f0a..020555bbfdb2 100644
--- a/mesh/gatt-proxy-svc.c
+++ b/mesh/gatt-proxy-svc.c
@@ -25,7 +25,8 @@
 #include "mesh/net.h"			// PROXY_FILTER_ACCEPT_LIST,
 					// PROXY_FILTER_REJECT_LIST
 					// mesh_net_attach_gatt(),
-					// mesh_net_detach_gatt()
+					// mesh_net_detach_gatt(),
+					// mesh_net_send_all_beacons_gatt()
 #include "mesh/net-keys.h"		// net_key_fill_adv_service_data(),
 					// net_key_get_next_id()
 #include "mesh/util.h"			// print_packet()
@@ -281,6 +282,11 @@ static void gatt_proxy_svc_send(enum proxy_msg_type msg_type, const void *data,
 	}
 }
 
+void gatt_proxy_svc_send_beacon(const void *data, uint8_t len)
+{
+	gatt_proxy_svc_send(PROXY_MSG_TYPE_MESH_BEACON, data, len);
+}
+
 void gatt_proxy_svc_send_net(uint16_t dst, const void *data, uint8_t len)
 {
 	int i;
@@ -331,6 +337,18 @@ static void gatt_service_notify_acquired(void *user_data)
 	 */
 	gatt_proxy->filter_type = PROXY_FILTER_ACCEPT_LIST;
 	gatt_proxy->filter_count = 0;
+
+	/*
+	 * MshPRT_v1.1, section 6.7 - Proxy Server behavior
+	 * Upon connection, [...] The Proxy Server shall send a mesh
+	 * beacon for each known subnet to the Proxy Client, [...]
+	 *
+	 * MshPRT_v1.1, section 7.2.3.2.1 - Characteristic behavior
+	 * [...] the client will enable notifications [...] to the
+	 * Mesh Proxy Data Out Client Characteristic Configuration
+	 * Descriptor after a connection is established.
+	 */
+	mesh_net_send_all_beacons_gatt();
 }
 
 static void gatt_service_notify_stopped(void *user_data)
diff --git a/mesh/gatt-proxy-svc.h b/mesh/gatt-proxy-svc.h
index 0abb85d7109f..2784602160bb 100644
--- a/mesh/gatt-proxy-svc.h
+++ b/mesh/gatt-proxy-svc.h
@@ -36,5 +36,6 @@ unsigned gatt_proxy_svc_filter_count(struct gatt_proxy_svc *gatt_proxy,
 void gatt_proxy_svc_filter_pdu_rcvd(struct gatt_proxy_svc *gatt_proxy,
 								uint16_t src);
 
+void gatt_proxy_svc_send_beacon(const void *data, uint8_t len);
 void gatt_proxy_svc_send_net(uint16_t dst, const void *data, uint8_t len);
 void gatt_proxy_svc_send_proxy_cfg(const void *data, uint8_t len);
diff --git a/mesh/net-keys.c b/mesh/net-keys.c
index 1a2cd39421c1..918455b2200f 100644
--- a/mesh/net-keys.c
+++ b/mesh/net-keys.c
@@ -732,6 +732,18 @@ bool net_key_beacon_refresh(uint32_t id, uint32_t ivi, bool kr, bool ivu,
 
 		print_packet("Set SNB to", key->snb, BEACON_LEN_SNB);
 		gatt_proxy_svc_set_current_adv_key(key->id);
+
+		/*
+		 * MshPRT_v1.1, section 6.7 - Proxy Server behavior
+		 * Upon successfully processing a Secure Network Beacon or
+		 * a Mesh Private beacon with a new value for the IV Index
+		 * field or the Flags field, the Proxy Server shall send a
+		 * mesh beacon to the Proxy Client, ...
+		 * When the Proxy Server is added to a new subnet, the server
+		 * shall send a mesh beacon for that subnet to the Proxy Client,
+		 * ...
+		 */
+		gatt_proxy_svc_send_beacon(key->snb + 1, BEACON_LEN_SNB - 1);
 	}
 
 	l_debug("Set Beacon: IVI: %8.8x, IVU: %d, KR: %d", ivi, ivu, kr);
@@ -850,6 +862,19 @@ void net_key_beacon_disable(uint32_t id, bool mpb)
 	key->observe.timeout = NULL;
 }
 
+void net_key_beacon_send_gatt(uint32_t id)
+{
+	struct net_key *key = l_queue_find(keys, match_id, L_UINT_TO_PTR(id));
+
+	if (!key)
+		return;
+
+	/* FIXME: How to determine that key actually contains a valid SNB? */
+	if (key->snb && key->snb[0] == BT_AD_MESH_BEACON &&
+			key->snb[1] == BEACON_TYPE_SNB && key->snb[2] == 0)
+		gatt_proxy_svc_send_beacon(key->snb + 1, BEACON_LEN_SNB - 1);
+}
+
 static void free_key(void *data)
 {
 	struct net_key *key = data;
diff --git a/mesh/net-keys.h b/mesh/net-keys.h
index b43157df29bc..0d292ee41606 100644
--- a/mesh/net-keys.h
+++ b/mesh/net-keys.h
@@ -40,6 +40,7 @@ bool net_key_beacon_refresh(uint32_t id, uint32_t iv_index, bool kr, bool ivu,
 								bool force);
 void net_key_beacon_enable(uint32_t id, bool mpb, uint8_t refresh_count);
 void net_key_beacon_disable(uint32_t id, bool mpb);
+void net_key_beacon_send_gatt(uint32_t id);
 uint32_t net_key_beacon_last_seen(uint32_t id);
 
 bool net_key_fill_adv_service_data(uint32_t id,
diff --git a/mesh/net.c b/mesh/net.c
index 97591a5323d1..e4998a0924f6 100644
--- a/mesh/net.c
+++ b/mesh/net.c
@@ -2997,6 +2997,29 @@ void net_local_beacon(uint32_t net_key_id, uint32_t ivi, bool ivu, bool kr)
 	l_queue_foreach(nets, process_beacon, &beacon_data);
 }
 
+static void send_beacon_gatt(void *a, void *b)
+{
+	struct mesh_subnet *subnet = a;
+
+	net_key_beacon_send_gatt(subnet->net_key_tx);
+}
+
+static void send_all_beacons_gatt(void *a, void *b)
+{
+	struct mesh_net *net = a;
+
+	l_queue_foreach(net->subnets, send_beacon_gatt, NULL);
+}
+
+void mesh_net_send_all_beacons_gatt(void)
+{
+	/*
+	 * Upon connection, [...] The Proxy Server shall send a mesh beacon
+	 * for each known subnet to the Proxy Client, [...]
+	 */
+	l_queue_foreach(nets, send_all_beacons_gatt, NULL);
+}
+
 bool mesh_net_set_snb_mode(struct mesh_net *net, bool enable)
 {
 	if (!net)
diff --git a/mesh/net.h b/mesh/net.h
index af581478412c..bf537e20a57c 100644
--- a/mesh/net.h
+++ b/mesh/net.h
@@ -229,6 +229,7 @@ uint16_t mesh_net_get_address(struct mesh_net *net);
 bool mesh_net_register_unicast(struct mesh_net *net,
 					uint16_t unicast, uint8_t num_ele);
 void net_local_beacon(uint32_t key_id, uint32_t ivi, bool ivu, bool kr);
+void mesh_net_send_all_beacons_gatt(void);
 bool mesh_net_set_snb_mode(struct mesh_net *net, bool enable);
 bool mesh_net_set_mpb_mode(struct mesh_net *net, bool enabla, uint8_t period,
 								bool init);
-- 
2.43.0





[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux