--- 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);
}
}