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