Index: channels/chan_mobile.c
===================================================================
--- channels/chan_mobile.c	(revision 885)
+++ channels/chan_mobile.c	(working copy)
@@ -129,7 +129,6 @@
 	int rfcomm_socket;				/* rfcomm socket descriptor */
 	char rfcomm_buf[256];
 	char io_buf[CHANNEL_FRAME_SIZE + AST_FRIENDLY_OFFSET];
-	int io_pipe[2];
 	struct ast_smoother *smoother;			/* our smoother, for making 48 byte frames */
 	int sco_socket;					/* sco socket descriptor */
 	pthread_t monitor_thread;			/* monitor thread handle */
@@ -223,7 +222,6 @@
 
 static int sco_connect(bdaddr_t src, bdaddr_t dst);
 static int sco_write(int s, char *buf, int len);
-static int sco_read(int *id, int fd, short events, void *data);
 static int sco_accept(int *id, int fd, short events, void *data);
 static int sco_bind(struct adapter_pvt *adapter);
 
@@ -769,11 +767,6 @@
 
 	struct ast_channel *chn;
 
-	if (pipe(pvt->io_pipe) == -1) {
-		ast_log(LOG_ERROR, "[%s] failed to create io_pipe for audio data\n", pvt->id);
-		goto e_return;
-	}
-
 	pvt->answered = 0;
 	pvt->alignment_count = 0;
 	pvt->alignment_detection_triggered = 0;
@@ -787,7 +780,7 @@
 
 	chn = ast_channel_alloc(1, state, cid_num, pvt->id, 0, 0, pvt->context, 0, "Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
 	if (!chn) {
-		goto e_close_pipe;
+		goto e_return;
 	}
 
 	chn->tech = &mbl_tech;
@@ -797,7 +790,6 @@
 	chn->writeformat = prefformat;
 	chn->readformat = prefformat;
 	chn->tech_pvt = pvt;
-	ast_channel_set_fd(chn, 0, pvt->io_pipe[0]);
 
 	if (state == AST_STATE_RING)
 		chn->rings = 1;
@@ -807,9 +799,6 @@
 
 	return chn;
 
-e_close_pipe:
-	close(pvt->io_pipe[0]);
-	close(pvt->io_pipe[1]);
 e_return:
 	return NULL;
 }
@@ -953,12 +942,8 @@
 
 	ast_debug(1, "[%s] hanging up device\n", pvt->id);
 
-	ast_channel_set_fd(ast, 0, -1);
-
 	ast_mutex_lock(&pvt->lock);
-	close(pvt->io_pipe[0]);
-	close(pvt->io_pipe[1]);
-
+	ast_channel_set_fd(chan, 0, -1);
 	close(pvt->sco_socket);
 	pvt->sco_socket = -1;
 
@@ -1038,8 +1023,6 @@
 	memset(&pvt->fr, 0x00, sizeof(struct ast_frame));
 	pvt->fr.frametype = AST_FRAME_VOICE;
 	pvt->fr.subclass = DEVICE_FRAME_FORMAT;
-	pvt->fr.datalen = CHANNEL_FRAME_SIZE;
-	pvt->fr.samples = CHANNEL_FRAME_SIZE / 2;
 	pvt->fr.src = "Mobile";
 	pvt->fr.offset = AST_FRIENDLY_OFFSET;
 	pvt->fr.mallocd = 0;
@@ -1047,16 +1030,17 @@
 	pvt->fr.delivery.tv_usec = 0;
 	pvt->fr.data.ptr = pvt->io_buf + AST_FRIENDLY_OFFSET;
 
-	if ((r = read(pvt->io_pipe[0], pvt->fr.data.ptr, CHANNEL_FRAME_SIZE)) != CHANNEL_FRAME_SIZE) {
-		if (r == -1) {
-			ast_log(LOG_ERROR, "read error %d\n", errno);
-			return &ast_null_frame;
-		} else {
-			pvt->fr.datalen = r;
-			pvt->fr.samples = r / 2;
-		}
+	if ((r = read(pvt->sco_socket, pvt->fr.data.ptr, DEVICE_FRAME_SIZE)) == -1) {
+		ast_log(LOG_ERROR, "read error %d\n", errno);
+		return &ast_null_frame;
 	}
 
+	pvt->fr.datalen = r;
+	pvt->fr.samples = r / 2;
+
+	if (pvt->do_alignment_detection)
+		do_alignment_detection(pvt, pvt->fr.data.ptr, r);
+
 	return ast_dsp_process(ast, pvt->dsp, &pvt->fr);
 
 }
@@ -1652,39 +1636,6 @@
 }
 
 /*!
- * \brief Read data from the given sco connection.
- * This function is an ast_io callback function that will read data from the
- * given sco socket and write it to the corrisponding pvt io_pipe.
- */
-static int sco_read(int *id, int fd, short events, void *data)
-{
-	struct mbl_pvt *pvt = (struct mbl_pvt *) data;
-	int res;
-	char buf[DEVICE_FRAME_SIZE];
-
-	ast_debug(3, "sco_read()\n");
-
-	if ((res = read(fd, buf, DEVICE_FRAME_SIZE)) <= 0) {
-		ast_debug(3, "error reading sco audio data\n");
-		close(fd);
-		/* don't set pvt->sco_sock = -1 here, there may already be a
-		 * new pvt->sco_sock */
-		return 0;
-	}
-
-	if (pvt->do_alignment_detection)
-		do_alignment_detection(pvt, buf, res);
-
-	if (pvt->owner && pvt->owner->_state == AST_STATE_UP) {
-		if (write(pvt->io_pipe[1], buf, res) == -1) {
-			ast_debug(1, "[%s] failed to queue sco data: %s", pvt->id, strerror_r(errno, buf, sizeof(buf)));
-		}
-	}
-
-	return 1;
-}
-
-/*!
  * \brief Accept SCO connections.
  * This function is an ast_io callback function used to accept incoming sco
  * audio connections.
@@ -1726,19 +1677,24 @@
 		return 1;
 	}
 
+	ast_mutex_lock(&pvt->lock);
+	if (!pvt->owner) {
+		ast_mutex_unlock(&pvt->lock);
+		ast_log(LOG_ERROR, "incoming audio connection for pvt without owner\n");
+		close(sock);
+		return 1;
+	}
+
 	if (pvt->sco_socket != -1) {
 		close(pvt->sco_socket);
 		pvt->sco_socket = -1;
 	}
 
 	pvt->sco_socket = sock;
-	if (!ast_io_add(adapter->io, sock, sco_read, AST_IO_IN, pvt)) {
-		ast_log(LOG_ERROR, "error monitoring new incoming audio connection\n");
-		close(pvt->sco_socket);
-		pvt->sco_socket = -1;
-		return 1;
-	}
+	ast_channel_set_fd(pvt->owner, 0, sock);
 
+	ast_mutex_unlock(&pvt->lock);
+
 	return 1;
 }
 
@@ -3587,36 +3543,15 @@
 	return 1;
 }
 
-/*!
- * \brief Handle rfcomm data.
- * Currently this function does nothing, it is merely used to interrupt
- * ast_io_wait().
- */
-static int headset_handle_rfcomm(int *id, int fd, short events, void *data)
-{
-	return 1;
-}
-
 static void *do_monitor_headset(void *data)
 {
 
 	struct mbl_pvt *pvt = (struct mbl_pvt *)data;
 	char buf[256];
-	int t, zero = 0;
+	int t;
 	at_message_t at_msg;
-	struct io_context *io = NULL;
 	struct ast_channel *chan = NULL;
 
-	if (!(io = io_context_create())) {
-		ast_log(LOG_ERROR, "Unable to create I/O context for headset audio connections\n");
-		goto e_cleanup;
-	}
-
-	if (!ast_io_add(io, pvt->rfcomm_socket, headset_handle_rfcomm, AST_IO_IN, pvt)) {
-		ast_log(LOG_ERROR, "[%s] error moitoring rfcomm connection\n", pvt->id);
-		goto e_cleanup;
-	}
-
 	ast_verb(3, "Bluetooth Device %s initialised and ready.\n", pvt->id);
 
 	while (!check_unloading()) {
@@ -3626,14 +3561,9 @@
 			t = 6000;
 		}
 
-		if (ast_io_wait(io, t) == -1) {
-			ast_debug(1, "[%s] error when waiting for audio from device\n", pvt->id);
-			goto e_cleanup;
-		}
-
 		ast_sched_runq(pvt->sched);
 
-		if (rfcomm_wait(pvt->rfcomm_socket, &zero) == 0)
+		if (rfcomm_wait(pvt->rfcomm_socket, &t) == 0)
 			continue;
 
 		if ((at_msg = at_read_full(pvt->rfcomm_socket, buf, sizeof(buf))) < 0) {
@@ -3675,12 +3605,7 @@
 						goto e_cleanup;
 					}
 
-					if (!ast_io_add(io, pvt->sco_socket, sco_read, AST_IO_IN, pvt)) {
-						ast_log(LOG_ERROR, "[%s] error servicing audio connection\n", pvt->id);
-						mbl_queue_hangup(pvt);
-						ast_mutex_unlock(&pvt->lock);
-						goto e_cleanup;
-					}
+					ast_channel_set_fd(pvt->owner, 0, pvt->sco_socket);
 
 					mbl_queue_control(pvt, AST_CONTROL_ANSWER);
 					pvt->answered = 1;
@@ -3706,12 +3631,6 @@
 					goto e_cleanup;
 				}
 
-				if (!ast_io_add(io, pvt->sco_socket, sco_read, AST_IO_IN, pvt)) {
-					ast_log(LOG_ERROR, "[%s] error servicing audio connection\n", pvt->id);
-					ast_mutex_unlock(&pvt->lock);
-					goto e_cleanup;
-				}
-
 				pvt->incoming = 1;
 
 				if (!(chan = mbl_new(AST_STATE_UP, pvt, NULL))) {
@@ -3720,6 +3639,8 @@
 					goto e_cleanup;
 				}
 
+				ast_channel_set_fd(chan, 0, pvt->sco_socket);
+
 				ast_copy_string(chan->exten, "s", AST_MAX_EXTENSION);
 				if (ast_pbx_start(chan)) {
 					ast_log(LOG_ERROR, "[%s] unable to start pbx on incoming call\n", pvt->id);
@@ -3741,9 +3662,6 @@
 	}
 
 e_cleanup:
-	if (io)
-		io_context_destroy(io);
-
 	ast_mutex_lock(&pvt->lock);
 	if (pvt->owner) {
 		ast_debug(1, "[%s] device disconnected, hanging up owner\n", pvt->id);
@@ -4235,8 +4153,6 @@
 		}
 
 		close(pvt->sco_socket);
-		close(pvt->io_pipe[0]);
-		close(pvt->io_pipe[1]);
 		close(pvt->rfcomm_socket);
 
 		msg_queue_flush(pvt);
