Diff between 6c5efac68473eddce0624c48aef92af6eca9bac4 and 3b3e88678a5fd117897178c9dc53345781661a60

Changed Files

File Additions Deletions Status
attrib/att.c +4 -0 modified
attrib/att.h +2 -0 modified
attrib/gattrib.c +28 -1 modified

Full Patch

diff --git a/attrib/att.c b/attrib/att.c
index a3a8947..c8e2e1d 100644
--- a/attrib/att.c
+++ b/attrib/att.c
@@ -72,6 +72,10 @@ const char *att_ecode2str(uint8_t status)
 		return "Insufficient Resources to complete the request";
 	case ATT_ECODE_IO:
 		return "Internal application error: I/O";
+	case ATT_ECODE_TIMEOUT:
+		return "A timeout occured";
+	case ATT_ECODE_ABORTED:
+		return "The operation was aborted";
 	default:
 		return "Unexpected error code";
 	}
diff --git a/attrib/att.h b/attrib/att.h
index d12a7f2..8979c95 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -72,6 +72,8 @@
 #define ATT_ECODE_INSUFF_RESOURCES		0x11
 /* Application error */
 #define ATT_ECODE_IO				0xFF
+#define ATT_ECODE_TIMEOUT			0xFE
+#define ATT_ECODE_ABORTED			0xFD
 
 /* Characteristic Property bit field */
 #define ATT_CHAR_PROPER_BROADCAST		0x01
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 9886a92..29c3585 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -53,6 +53,7 @@ struct _GAttrib {
 	guint next_evt_id;
 	GDestroyNotify destroy;
 	gpointer destroy_user_data;
+	gboolean stale;
 };
 
 struct command {
@@ -252,8 +253,25 @@ gboolean g_attrib_set_destroy_function(GAttrib *attrib,
 static gboolean disconnect_timeout(gpointer data)
 {
 	struct _GAttrib *attrib = data;
+	struct command *c;
 
-	attrib_destroy(attrib);
+	c = g_queue_pop_head(attrib->requests);
+	if (c == NULL)
+		goto done;
+
+	if (c->func)
+		c->func(ATT_ECODE_TIMEOUT, NULL, 0, c->user_data);
+
+	command_destroy(c);
+
+	while ((c = g_queue_pop_head(attrib->requests))) {
+		if (c->func)
+			c->func(ATT_ECODE_ABORTED, NULL, 0, c->user_data);
+		command_destroy(c);
+	}
+
+done:
+	attrib->stale = TRUE;
 
 	return FALSE;
 }
@@ -268,6 +286,9 @@ static gboolean can_write_data(GIOChannel *io, GIOCondition cond,
 	GIOStatus iostat;
 	GQueue *queue;
 
+	if (attrib->stale)
+		return FALSE;
+
 	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL))
 		return FALSE;
 
@@ -337,6 +358,9 @@ static gboolean received_data(GIOChannel *io, GIOCondition cond, gpointer data)
 	GIOStatus iostat;
 	gboolean norequests, noresponses;
 
+	if (attrib->stale)
+		return FALSE;
+
 	if (attrib->timeout_watch > 0) {
 		g_source_remove(attrib->timeout_watch);
 		attrib->timeout_watch = 0;
@@ -447,6 +471,9 @@ guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
 	struct command *c;
 	GQueue *queue;
 
+	if (attrib->stale)
+		return 0;
+
 	c = g_try_new0(struct command, 1);
 	if (c == NULL)
 		return 0;