[PATCH 47/60] Random generation of first mdlid used as based to create data channels

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

 



From: José Antonio Santos-Cadenas <santoscadenas@xxxxxxxxx>

Add random mdlid generation to avoid mdlid collisions when
two instances create a data channel at the same time.
---
 mcap/mcap.c          |   53 ++++++++++++++++++++++++++-----------------------
 mcap/mcap_internal.h |    1 +
 2 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/mcap/mcap.c b/mcap/mcap.c
index 3f3268b..f164e76 100644
--- a/mcap/mcap.c
+++ b/mcap/mcap.c
@@ -28,6 +28,7 @@
 #include "error.h"
 
 #include <netinet/in.h>
+#include <stdlib.h>
 
 #include "mcap.h"
 #include "mcap_lib.h"
@@ -358,24 +359,37 @@ static int send5B_cmd(struct mcap_mcl *mcl, uint8_t oc, uint8_t rc,
 	return sent;
 }
 
-static uint16_t generate_mdlid(struct mcap_mcl *mcl)
+static struct mcap_mdl *get_mdl(struct mcap_mcl *mcl, uint16_t mdlid)
 {
-	uint16_t mdlid = MCAP_MDLID_INITIAL;
-	struct mcap_mdl *mdl;
 	GSList *l;
+	struct mcap_mdl *mdl;
 
 	for (l = mcl->mdls; l; l = l->next) {
 		mdl = l->data;
-		if (mdlid < mdl->mdlid)
-			break;
-		else
-			mdlid = mdl->mdlid + 1;
+		if (mdlid == mdl->mdlid)
+			return mdl;
 	}
 
-	if (mdlid > MCAP_MDLID_FINAL)
-		return 0;
+	return NULL;
+}
+
+static uint16_t generate_mdlid(struct mcap_mcl *mcl)
+{
+	uint16_t mdlid = mcl->next_mdl;
+	struct mcap_mdl *mdl;
 
-	return mdlid;
+	do {
+		DBG("Testing %d", mdlid);
+		mdl = get_mdl(mcl, mdlid);
+		if (!mdl) {
+			mcl->next_mdl = (mdlid % MCAP_MDLID_FINAL) + 1;
+			return mdlid;
+		} else
+			mdlid = (mdlid % MCAP_MDLID_FINAL) + 1;
+	} while (mdlid != mcl->next_mdl);
+
+	/* No more mdlids availables */
+	return 0;
 }
 
 static uint8_t *create_req(uint8_t op, uint16_t mdl_id)
@@ -949,20 +963,6 @@ static void error_cmd_rsp(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
 	}
 }
 
-static struct mcap_mdl *get_mdl(struct mcap_mcl *mcl, uint16_t mdlid)
-{
-	GSList *l;
-	struct mcap_mdl *mdl;
-
-	for (l = mcl->mdls; l; l = l->next) {
-		mdl = l->data;
-		if (mdlid == mdl->mdlid)
-			return mdl;
-	}
-
-	return NULL;
-}
-
 static void mcap_delete_mdl(gpointer elem, gpointer user_data)
 {
 	struct mcap_mdl *mdl = elem;
@@ -1764,6 +1764,7 @@ void mcap_create_mcl(struct mcap_instance *ms,
 		mcl->state = MCL_IDLE;
 		bacpy(&mcl->addr, addr);
 		set_default_cb(mcl);
+		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
 		mcl = mcap_mcl_ref(mcl);
 	} else
 		mcl->ctrl |= MCAP_CTRL_CONN;
@@ -1899,6 +1900,7 @@ static void confirm_mcl_event_cb(GIOChannel *chan, gpointer user_data)
 		mcl->ms = ms;
 		bacpy(&mcl->addr, &dst);
 		set_default_cb(mcl);
+		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
 		mcl = mcap_mcl_ref(mcl);
 	}
 
@@ -1983,7 +1985,8 @@ struct mcap_instance *mcap_create_instance(struct btd_adapter *btd_adapter,
 		g_free(ms);
 		return NULL;
 	}
-
+	/* Initialize random seed to generate mdlids for this instance */
+	srand(time(NULL));
 	return ms;
 }
 
diff --git a/mcap/mcap_internal.h b/mcap/mcap_internal.h
index 3aaeed5..9dacc12 100644
--- a/mcap/mcap_internal.h
+++ b/mcap/mcap_internal.h
@@ -94,6 +94,7 @@ struct mcap_mcl {
 	uint8_t			*lcmd;		/* Last command sent */
 	guint			ref;		/* References counter */
 	uint8_t			ctrl;		/* MCL control flag */
+	uint16_t		next_mdl;	/* id used to create next MDL */
 };
 
 #define	MCAP_CTRL_CACHED	0x01	/* MCL is cached */
-- 
1.6.3.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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