Re: [Ekiga-list] Trouble with ekiga + snd-bt-sco



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Okay, I fixed the problem. I added options to btsco to make the SCO
stream persistant, so it doesn't close the stream, even if the audio
device is closed. Patch to btsco 0.42 is attached, I will submit it
upstream to bluetooth-alsa once I have done some cleanup and testing.
It was supposed to be a workaround but works quite well, considering the
little understanding I have of the btsco code.

(I had to mess with btsco's signal handling and add a pid-file. instead
of sending SIGUSR1/2 to ring the headset/reconnect the sco stream, this
is now done with the btsco -a ring and btsco -a reconnect options).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFDvp1Eda5KzHP/VARAkubAJ9DISXnRTYl/ZaOy1EZS+uIT+OQMwCgsIqQ
nto21lGa42SOMH90wj+z0T8=
=DCzF
-----END PGP SIGNATURE-----
--- /dev/shm/btsco-0.42/btsco.c	2006-05-04 16:30:34.000000000 +0200
+++ btsco.c	2006-09-18 21:47:09.000000000 +0200
@@ -42,6 +42,8 @@
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/poll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -71,6 +73,15 @@
 #define NOT_CONNECTED 0
 #define CONNECTED 1
 
+/* sigusr1 constants */
+#define BTSCO_SIG_UNKNOWN 0
+#define BTSCO_SIG_RECONNECT 1
+#define BTSCO_SIG_RING 2
+#define BTSCO_SIG_PERSISTANT_ENABLE 3
+#define BTSCO_SIG_PERSISTANT_DISABLE 4
+
+#define PIDFILE ".btsco-pid"
+
 typedef struct snd_card_bt_sco_info {
 	int mixer_volume[2];
 	int playback_count, capture_count;
@@ -82,7 +93,7 @@
 	char *cmd;
 };
 
-static volatile int terminate = 0, ring = 0, hupped = 0, reconnect = 0, rfreconnect = 0;
+static volatile int terminate = 0, ring = 0, hupped = 0, reconnect = 0, rfreconnect = 0, persistant = 0;
 static int verbose = 0, auto_reconn = 0, conn_status = 0;
 
 static void sig_term(int sig)
@@ -90,19 +101,41 @@
 	terminate = 1;
 }
 
-static void sig_ring(int sig)
-{
-	ring = 1;
-}
-
 static void sig_hup(int sig)
 {
 	hupped = 1;
 }
 
-static void sig_usr(int sig)
+static void sig_usr(int sig, siginfo_t *si, void *u)
 {
-	reconnect = 1;
+	switch(si->si_value.sival_int)
+	{
+		case BTSCO_SIG_RECONNECT:
+			reconnect = 1;
+			break;
+		case BTSCO_SIG_RING:
+			ring = 1;
+			break;
+		case BTSCO_SIG_PERSISTANT_ENABLE:
+			persistant = 1;
+			if(verbose) {
+				printf("Persistant mode enabled\n");
+				fflush(stdout);
+			}
+			break;
+		case BTSCO_SIG_PERSISTANT_DISABLE:
+			persistant = 0;
+			if(verbose) {
+				printf("Persistant mode disabled\n");
+				fflush(stdout);
+			}
+			break;
+		default:
+			if(verbose) {
+				printf("Unknown signal received\n");
+				fflush(stdout);
+			}
+	}
 }
 
 static int rfcomm_connect(bdaddr_t * src, bdaddr_t * dst, uint8_t channel)
@@ -285,7 +318,13 @@
 	printf(" -f fork and run as a daemon\n");
 	printf(" -c clear filehandle and exit\n");
 	printf(" -s indicate status by creating the file %s\n", HEADSET_AVAIL_FILE);
-	printf(" -i hciX : use interface hciX\n");	
+	printf(" -i hciX : use interface hciX\n");
+	printf(" -p file : specify path to the pid file (default: ~/.btsco-pid)\n");
+	printf(" -a action : send a signal to a running btsco. action can be one of the following:\n");
+	printf("     ring - let the headset ring\n");
+	printf("     reconnect - reconnect sco channel\n");
+	printf("     persistant-enable - let sco channel stay open even when the audio device is closed\n");
+	printf("     persistant-disable - disconnect sco channel when audio device is closed\n");
 	printf(" -h print this usage and exit\n");
 	printf("\nThe headset channel will be automatically detected if not specified\n\n");
 }
@@ -460,8 +499,12 @@
 	int ret;
 	int fork, clear;
         int hci_if;
-	char *hci_opt = NULL;
-	 
+	int send_signal=0, fd;
+	pid_t fpid=0;
+	char *hci_opt = NULL, *pid_file=NULL, *send_action=NULL;
+	sigval_t sv;
+
+	struct stat st;
 	struct sigaction sa;
 
 	//struct timeval timeout;
@@ -500,7 +543,7 @@
 
 	fork = 0;
 	clear = 0;
-	while((i = getopt(argc, argv, "fcvhrsi:")) >= 0) {
+	while((i = getopt(argc, argv, "fcvhrsi:a:p:")) >= 0) {
 		switch(i) {
 		case 'v':
 			verbose++;
@@ -520,6 +563,13 @@
 		case 'i':
 			hci_opt = optarg;
 			break;
+		case 'p':
+			pid_file = strdup(optarg);
+			break;
+		case 'a':
+			send_signal = 1;
+			send_action = optarg;
+			break;
 		case 'h':
 		case '?':
 		case ':':
@@ -533,6 +583,69 @@
 		printf("btsco v0.42\n");
 		fflush(stdout);
 	}
+	
+	if(pid_file == NULL)
+	{
+		pid_file = malloc(strlen(getenv("HOME"))+strlen(PIDFILE)+2);
+		strcpy(pid_file, getenv("HOME"));
+		strcat(pid_file, "/");
+		strcat(pid_file, PIDFILE);
+	}
+	if(!stat(pid_file, &st))
+	{
+		fd = open(pid_file, O_RDONLY);
+		memset(buf, 0, sizeof(buf));
+		rlen = read(fd, buf, sizeof(buf) - 1);
+		close(fd);
+		fpid = atoi(buf);
+	}
+	
+	if(kill(fpid,0)==-1 && errno==ESRCH)
+		fpid = 0;
+
+	if(send_signal && fpid)
+	{
+		if(!strcmp(send_action, "ring"))
+			sv.sival_int = BTSCO_SIG_RING;
+		else if(!strcmp(send_action, "reconnect"))
+			sv.sival_int = BTSCO_SIG_RECONNECT;
+		else if(!strcmp(send_action, "persistant-enable"))
+			sv.sival_int = BTSCO_SIG_PERSISTANT_ENABLE;
+		else if(!strcmp(send_action, "persistant-disable"))
+			sv.sival_int = BTSCO_SIG_PERSISTANT_DISABLE;
+		else
+		{
+			printf("Unknown signal specified.\n");
+			exit(-1);
+		}
+		if(verbose)
+			printf("Sending %s signal.\n", send_action);
+		if(sigqueue(fpid, SIGUSR1, sv) == -1)
+		{
+			if(errno==EPERM)
+				printf("Permission denied when trying to send signal.\n");
+			else
+				printf("Error when sending signal: %s\n", strerror(errno));
+			exit(1);
+		}
+		exit(0);
+	}
+	else if(send_signal && !fpid)
+	{
+		printf("%s is not running.\n", argv[0]);
+		exit(-1);
+	}
+	else if(!send_signal && fpid)
+	{
+		printf("%s is already running at PID %d.\n", argv[0], fpid);
+		exit(-1);
+	}
+	
+	fd = open(pid_file, O_WRONLY | O_CREAT, 0600);
+	sprintf(buf, "%d\n", getpid());
+	write(fd, buf, sizeof(buf));
+	close(fd);
+	
 
 	actions = read_actions();
 	
@@ -617,18 +730,18 @@
 	sigaction(SIGTERM, &sa, NULL);
 	sigaction(SIGINT, &sa, NULL);
 	
-	sa.sa_handler = sig_ring;
-	sigaction(SIGUSR1, &sa, NULL);
-
-	sa.sa_handler = sig_usr;
-	sigaction(SIGUSR2, &sa, NULL);
-
 	sa.sa_handler = sig_hup;
 	sigaction(SIGHUP, &sa, NULL);
 
 	sa.sa_handler = SIG_IGN;
 	sigaction(SIGCHLD, &sa, NULL);
 	sigaction(SIGPIPE, &sa, NULL);
+	
+	/* set up SIGUSR1 */
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_sigaction = sig_usr;
+	sa.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
+	sigaction(SIGUSR1, &sa, NULL);
 
 	do {
         
@@ -874,7 +987,7 @@
 				force_sco = 0;
 			} else reconnect = 0;
 			
-			if(((!dr_usage && (force_sco != 1)) || (force_sco == 0)) && (sco_mode == CONNECTED)) {
+			if(!persistant && (((!dr_usage && (force_sco != 1)) || (force_sco == 0)) && (sco_mode == CONNECTED))) {
 				if(verbose) {
 					printf("driver is not in use\n");
 					fflush(stdout);
@@ -956,6 +1069,8 @@
 	close(rd);
 
 	snd_hwdep_close(handle);
+	unlink(pid_file);
+	free(pid_file);
 
 	return 0;
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]