From: "suche.org" <admin@suche.org>
To: bluez-devel@lists.sourceforge.net
Subject: [Bluez-devel] btsco2 Patch
Date: Wed, 01 Dec 2004 16:51:17 +0100 [thread overview]
Message-ID: <41ADE875.5050405@suche.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 487 bytes --]
Hi,
this patch fix some problems:
1. use nonblocking socket on rfcomm connect this allow to wait for more
than one headset
2. Before seting the SCO filedescriptor to the kernel ir send -1 for
closing the actual one.
+ If an SCO connection is lost from last time it become close and with
the next try is available again
3. Move the SCO loopback testroutine to poll informations
4. Handle Headset disconnect (power off)
Cu Thomas
p.s. I hope this tine the patch is in correct format
[-- Attachment #2: btsco2.c.diff --]
[-- Type: text/plain, Size: 4164 bytes --]
--- btsco2.c.orig 2004-12-01 15:06:13.000000000 +0100
+++ btsco2.c 2004-12-01 16:41:34.698979692 +0100
@@ -91,6 +91,7 @@
{
struct sockaddr_rc addr;
int sk;
+ int opt;
sk = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
if (sk < 0)
@@ -105,12 +106,18 @@
return -1;
}
+ /* Try to use non blocking IO */
+ opt = 1;
+ ioctl (sk, FIONBIO , &opt);
+
memset(&addr, 0, sizeof(addr));
addr.rc_family = AF_BLUETOOTH;
bacpy(&addr.rc_bdaddr, dst);
addr.rc_channel = channel;
if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ if (errno == EAGAIN)
+ return sk;
close(sk);
return -1;
}
@@ -300,10 +307,10 @@
if (headset == NULL)
return 0;
+ /* disconnect SCO stream */
+ bt_sco_set_fd(headset->handle, -1);
if (headset->sco_fd != -1) {
/* close bt_sco audio handle */
- bt_sco_set_fd(headset->handle, -1);
- /* disconnect SCO stream */
close(headset->sco_fd);
headset->sco_fd = -1;
fprintf(stderr, "disconnected SCO channel\n");
@@ -401,16 +408,13 @@
return 1;
}
-static void headset_destroy(struct s_headset *headset)
+static void headset_close(struct s_headset *headset)
{
if (headset == NULL)
return;
- if (headset->sco_fd != -1) {
bt_sco_set_fd(headset->handle, -1);
+ if (headset->sco_fd != -1)
close(headset->sco_fd);
- }
-
- sleep(1);
if (headset->rfcomm_fd != -1)
close(headset->rfcomm_fd);
if (headset->handle != NULL)
@@ -418,6 +422,7 @@
headset->sco_fd = -1;
headset->rfcomm_fd = -1;
headset->handle = NULL;
+ sleep(1);
}
static void cleanup(void)
@@ -426,7 +431,8 @@
akt_headset = first;
while (akt_headset != NULL) {
struct s_headset *next = akt_headset->next;
- headset_destroy(akt_headset);
+ headset_close(akt_headset);
+ free(akt_headset);
akt_headset = next;
}
}
@@ -513,10 +519,6 @@
str2ba(argv[1], &akt_headset->bdaddr);
akt_headset->channel = atoi(argv[2]);
/* open hwdep on audio device */
- if ((err = snd_hwdep_open(&akt_headset->handle, hwdep_name, O_RDWR)) < 0) {
- fprintf(stderr, "btsco open (%i-%i): %s\n", card, dev, snd_strerror(err));
- return -1;
- }
break;
default:
usage();
@@ -548,13 +550,26 @@
&akt_headset->bdaddr,
akt_headset->channel)) < 0)
fprintf(stderr, "Can't connect RFCOMM channel");
- else
+ else {
fprintf(stderr, "RFCOMM channel %i connected\n", akt_headset->channel);
+ if ((err = snd_hwdep_open(&akt_headset->handle, hwdep_name, O_RDWR)) < 0) {
+ fprintf(stderr, "Can not open soudncard %s for Headset\n", hwdep_name);
+ close(akt_headset->rfcomm_fd);
+ akt_headset->rfcomm_fd = -1;
+ }
+ }
}
if (akt_headset->rfcomm_fd != -1) {
pfds[nfds].fd = akt_headset->rfcomm_fd;
+ pfds[nfds].events = POLLIN|POLLERR;
+ nfds++;
+ }
+#ifdef TEST
+ if (akt_headset->sco_fd != -1) {
+ pfds[nfds].fd = akt_headset->sco_fd;
pfds[nfds++].events = POLLIN;
}
+#endif
if (akt_headset->handle != NULL) {
/* polling data from hwdep interface */
nfds += snd_hwdep_poll_descriptors(akt_headset->handle, &pfds[nfds], 1);
@@ -574,16 +589,16 @@
if (pfds[j].fd == akt_headset->rfcomm_fd) {
if (pfds[j].revents & POLLIN)
headset_from_bt(akt_headset);
+ if (pfds[j].revents & POLLERR)
+ headset_close(akt_headset);
continue;
}
#ifdef TEST
if (pfds[j].fd == akt_headset->sco_fd) {
/* Just for testing; handled by kernel driver */
- fd_set rfds;
- if (0 && FD_ISSET(akt_headset->sco_fd, &rfds)) {
+ if (0 && pfds[j].revents & POLLIN) {
int i;
unsigned char buf[2048];
-
memset(buf, 0, sizeof(buf));
rlen = read(akt_headset->sco_fd, buf, sizeof(buf));
write(akt_headset->sco_fd, buf, rlen);
@@ -594,7 +609,9 @@
}
#endif
/* Volume polling (sound card) */
- if (!snd_hwdep_poll_descriptors_revents (akt_headset->handle, &pfds[j], 1, &revents) && revents & POLLIN)
+ if (akt_headset->handle != NULL)
+ if (!snd_hwdep_poll_descriptors_revents ( akt_headset->handle, &pfds[j], 1, &revents) &&
+ revents & POLLIN)
headset_volume_fromcard (akt_headset);
}
}
reply other threads:[~2004-12-01 15:51 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=41ADE875.5050405@suche.org \
--to=admin@suche.org \
--cc=bluez-devel@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox