Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 103664)
+++ channels/chan_sip.c	(working copy)
@@ -1347,6 +1347,7 @@
 static int sip_poke_peer(struct sip_peer *peer);
 static void sip_poke_all_peers(void);
 static void sip_peer_hold(struct sip_pvt *p, int hold);
+static void sip_audit_subscriptions(void);
 
 /*--- Applications, functions, CLI and manager command helpers */
 static const char *sip_nat_mode(const struct sip_pvt *p);
@@ -7277,6 +7278,10 @@
 	add_line(&req, tmp);
 	p->pendinginvite = p->ocseq;	/* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
 
+	/* Before we actually send out the NOTIFY update the subscription data in the astdb */
+	snprintf(tmp, sizeof(tmp), "%d:%d", (int)time(NULL), p->ocseq);
+	ast_db_put("SIP/Subscription", p->callid, tmp);	
+
 	return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
 }
 
@@ -14798,13 +14803,39 @@
 		return 0;
 	}
 
-	if (!ast_test_flag(req, SIP_PKT_IGNORE) && !resubscribe) {	/* Set up dialog, new subscription */
-		/* Use this as the basis */
-		if (ast_test_flag(req, SIP_PKT_DEBUG))
-			ast_verbose("Creating new subscription\n");
+	if (!ast_test_flag(req, SIP_PKT_IGNORE)) {	/* Set up dialog, new subscription */
+		char data[256];
 
-		copy_request(&p->initreq, req);
-		check_via(p, req);
+		if (!resubscribe) {
+			/* Use this as the basis */
+			if (ast_test_flag(req, SIP_PKT_DEBUG))
+				ast_verbose("Creating new subscription\n");
+			
+			copy_request(&p->initreq, req);
+			check_via(p, req);
+			
+			/* See if we need to reuse a CSeq from a previous subscription */
+			if (!ast_db_get("SIP/Subscription", p->callid, data, sizeof(data))) {
+				char *scan = data, *last_use_time = NULL, *cseq = NULL;
+				
+				/* Parse out the last used time and last actual CSeq of the outgoing NOTIFY packets */
+				last_use_time = strsep(&scan, ":");
+				cseq = scan;
+				
+				if (ast_test_flag(req, SIP_PKT_DEBUG))
+					ast_verbose("Using previous outgoing CSeq of %s\n", cseq);
+				
+				/* Update our subscription's dialog structure to use this CSeq.. once done the remote device should be happy */
+				p->ocseq = atoi(cseq);
+			}
+		} else {
+			/* This is just a resubscription, but in order to keep the astdb up to date we want to update the time */
+			if (ast_test_flag(req, SIP_PKT_DEBUG))
+				ast_verbose("Updating subscription\n");
+
+			snprintf(data, sizeof(data), "%d:%d", (int)time(NULL), p->ocseq);
+			ast_db_put("SIP/Subscription", p->callid, data);
+		}
 	} else if (ast_test_flag(req, SIP_PKT_DEBUG) && ast_test_flag(req, SIP_PKT_IGNORE))
 		ast_verbose("Ignoring this SUBSCRIBE request\n");
 
@@ -17742,6 +17773,38 @@
 	);
 }
 
+/*! \brief Audit stored subscriptions in astdb and remove old ones */
+static void sip_audit_subscriptions(void)
+{
+	struct ast_db_entry *db_tree = NULL, *entry = NULL;
+
+	/* If no subscriptions exist just bail out */
+	if (!(db_tree = ast_db_gettree("SIP/Subscription", NULL)))
+		return;
+
+	/* Iterate through each stored subscription seeing if the time in the entry exceeds our maximum allowed */
+	for (entry = db_tree; entry; entry = entry->next) {
+		char *callid = entry->key + 18, data[256], *scan = data, *lut = NULL;
+		time_t last_used_time;
+
+		/* Try to grab the actual entry from astdb based on the given callid */
+		if (ast_db_get("SIP/Subscription", callid, data, sizeof(data)))
+			continue;
+
+		/* We only need the first part, not the CSeq */
+		lut = strsep(&scan, ":");
+		last_used_time = atoi(lut);
+
+		/* See if the time between last used time and current time exceeds our maximum of 1 hour */
+		if ((time(NULL) - last_used_time) >= 3600) {
+			/* Drop entry from astdb, it's old and stale */
+			ast_db_del("SIP/Subscription", callid);
+		}
+	}
+
+	return;
+}
+
 /*! \brief Send all known registrations */
 static void sip_send_all_registers(void)
 {
@@ -17938,6 +18001,9 @@
 
 	sip_reloadreason = CHANNEL_MODULE_LOAD;
 
+	/* Perform an audit of subscriptions stored in the astdb */
+	sip_audit_subscriptions();
+
 	if(reload_config(sip_reloadreason))	/* Load the configuration from sip.conf */
 		return AST_MODULE_LOAD_DECLINE;
 
