public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [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