[svn-commits] mnicholson: trunk r900 - /trunk/channels/chan_mobile.c
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Mon May 4 17:09:00 CDT 2009
Author: mnicholson
Date: Mon May 4 17:08:56 2009
New Revision: 900
URL: http://svn.asterisk.org/svn-view/asterisk-addons?view=rev&rev=900
Log:
Interact with bluetooth audio sockets directly instead of going through an
internal pipe.
(closes issue #14878)
Reported by: jongerenchaos
Tested by: jongerenchaos
Modified:
trunk/channels/chan_mobile.c
Modified: trunk/channels/chan_mobile.c
URL: http://svn.asterisk.org/svn-view/asterisk-addons/trunk/channels/chan_mobile.c?view=diff&rev=900&r1=899&r2=900
==============================================================================
--- trunk/channels/chan_mobile.c (original)
+++ trunk/channels/chan_mobile.c Mon May 4 17:08:56 2009
@@ -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_mutex_lock(&pvt->lock);
ast_channel_set_fd(ast, 0, -1);
-
- ast_mutex_lock(&pvt->lock);
- close(pvt->io_pipe[0]);
- close(pvt->io_pipe[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,15 +1030,16 @@
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,18 +1677,23 @@
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,35 +3543,14 @@
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);
@@ -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))) {
@@ -3719,6 +3638,8 @@
ast_mutex_unlock(&pvt->lock);
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)) {
@@ -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);
More information about the svn-commits
mailing list