diff --git a/autoservice.c b/autoservice.c
new file mode 100755
index 0000000000000000000000000000000000000000..5f15c244c8fdca2a7fb554304987433ca73237b4
--- /dev/null
+++ b/autoservice.c
@@ -0,0 +1,152 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Automatic channel service routines
+ * 
+ * Copyright (C) 1999, Mark Spencer
+ *
+ * Mark Spencer <markster@linux-support.net>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <string.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <math.h>			/* For PI */
+#include <asterisk/pbx.h>
+#include <asterisk/frame.h>
+#include <asterisk/sched.h>
+#include <asterisk/options.h>
+#include <asterisk/channel.h>
+#include <asterisk/channel_pvt.h>
+#include <asterisk/logger.h>
+#include <asterisk/file.h>
+#include <asterisk/translate.h>
+#include <asterisk/manager.h>
+#include <asterisk/chanvars.h>
+#include <asterisk/linkedlists.h>
+#include <asterisk/indications.h>
+
+#define MAX_AUTOMONS 256
+
+static pthread_mutex_t autolock = AST_MUTEX_INITIALIZER;
+
+struct asent {
+	struct ast_channel *chan;
+	struct asent *next;
+};
+
+static struct asent *aslist = NULL;
+static pthread_t asthread = -1;
+
+static void *autoservice_run(void *ign)
+{
+	struct ast_channel *mons[MAX_AUTOMONS];
+	int x;
+	int ms;
+	struct ast_channel *chan;
+	struct asent *as;
+	struct ast_frame *f;
+	for(;;) {
+		x = 0;
+		ast_pthread_mutex_lock(&autolock);
+		as = aslist;
+		while(as) {
+			if (!as->chan->_softhangup) {
+				if (x < MAX_AUTOMONS)
+					mons[x++] = as->chan;
+				else
+					ast_log(LOG_WARNING, "Exceeded maximum number of automatic monitoring events.  Fix autoservice.c\n");
+			}
+			as = as->next;
+		}
+		ast_pthread_mutex_unlock(&autolock);
+
+/* 		if (!aslist)
+			break; */
+		ms = 500;
+		chan = ast_waitfor_n(mons, x, &ms);
+		if (chan) {
+			/* Read and ignore anything that occurs */
+			f = ast_read(chan);
+			if (f)
+				ast_frfree(f);
+		}
+	}
+	asthread = -1;
+	return NULL;
+}
+
+int ast_autoservice_start(struct ast_channel *chan)
+{
+	int res = -1;
+	struct asent *as;
+	int needstart;
+	ast_pthread_mutex_lock(&autolock);
+	needstart = (asthread == -1) ? 1 : 0 /* aslist ? 0 : 1 */;
+	as = aslist;
+	while(as) {
+		if (as->chan == chan)
+			break;
+		as = as->next;
+	}
+	if (!as) {
+		as = malloc(sizeof(struct asent));
+		if (as) {
+			memset(as, 0, sizeof(struct asent));
+			as->chan = chan;
+			as->next = aslist;
+			aslist = as;
+			res = 0;
+			if (needstart) {
+				if (pthread_create(&asthread, NULL, autoservice_run, NULL)) {
+					ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
+					free(aslist);
+					aslist = NULL;
+					res = -1;
+				} else
+					pthread_kill(asthread, SIGURG);
+			}
+		}
+	}
+	ast_pthread_mutex_unlock(&autolock);
+	return res;
+}
+
+int ast_autoservice_stop(struct ast_channel *chan)
+{
+	int res = -1;
+	struct asent *as, *prev;
+	ast_pthread_mutex_lock(&autolock);
+	as = aslist;
+	prev = NULL;
+	while(as) {
+		if (as->chan == chan)
+			break;
+		prev = as;
+		as = as->next;
+	}
+	if (as) {
+		if (prev)
+			prev->next = as->next;
+		else
+			aslist = as->next;
+		free(as);
+		if (!chan->_softhangup)
+			res = 0;
+	}
+	if (asthread != -1) 
+		pthread_kill(asthread, SIGURG);
+	ast_pthread_mutex_unlock(&autolock);
+	/* Wait for it to un-block */
+	while(chan->blocking)
+		usleep(1000);
+	return res;
+}