* [Bluez-devel] btsco2 Patch
@ 2004-12-01 15:51 suche.org
0 siblings, 0 replies; only message in thread
From: suche.org @ 2004-12-01 15:51 UTC (permalink / raw)
To: bluez-devel
[-- 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);
}
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2004-12-01 15:51 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-01 15:51 [Bluez-devel] btsco2 Patch suche.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox