linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [Bluez-devel] rfcomm utility patch to loop and startup executable when connection received
@ 2006-08-09 10:19 Frédéric DALLEAU
  2006-08-09 21:50 ` Marcel Holtmann
  0 siblings, 1 reply; 4+ messages in thread
From: Frédéric DALLEAU @ 2006-08-09 10:19 UTC (permalink / raw)
  To: BlueZ development

[-- Attachment #1: Type: text/plain, Size: 655 bytes --]

Hi,

I came accross the need to startup an executable when rfcomm receives a 
connection. I also added an option called watch that allows rfcomm not 
to exit when the rfcomm connection is closed. It simply loops and calls 
listen.

listen   <dev> [channel [cmd]]          Listen
watch    <dev> [channel [cmd]]          Watch

rfcomm --raw watch 0 1 "cat {}"
rfcomm --raw listen 0 1 "cat {}"

Not specifying the cmd parameter will simply wait for [control-c] as before.

the {} will be replaced by the address of the rfcomm device created. In 
the example the command run will be 'cat /dev/rfcomm0'.

Attached is the patch.
Frédéric.


[-- Attachment #2: patch_rfcomm --]
[-- Type: text/plain, Size: 4908 bytes --]

? Makefile
? Makefile.in
? aclocal.m4
? autom4te.cache
? config.guess
? config.h
? config.h.in
? config.log
? config.status
? config.sub
? configure
? depcomp
? install-sh
? libtool
? ltmain.sh
? missing
? mkinstalldirs
? stamp-h.in
? stamp-h1
? alsa/.deps
? alsa/Makefile
? alsa/Makefile.in
? common/.deps
? common/Makefile
? common/Makefile.in
? cups/.deps
? cups/Makefile
? cups/Makefile.in
? daemon/.deps
? daemon/Makefile
? daemon/Makefile.in
? dund/.deps
? dund/Makefile
? dund/Makefile.in
? extra/.deps
? extra/Makefile
? extra/Makefile.in
? fuse/.deps
? fuse/Makefile
? fuse/Makefile.in
? hcid/.deps
? hcid/Makefile
? hcid/Makefile.in
? hidd/.deps
? hidd/Makefile
? hidd/Makefile.in
? pand/.deps
? pand/Makefile
? pand/Makefile.in
? rfcomm/.deps
? rfcomm/.libs
? rfcomm/Makefile
? rfcomm/Makefile.in
? rfcomm/lexer.c
? rfcomm/main.c.modified
? rfcomm/main.patch
? rfcomm/parser.c
? rfcomm/parser.h
? rfcomm/rfcomm
? scripts/Makefile
? scripts/Makefile.in
? sdpd/.deps
? sdpd/Makefile
? sdpd/Makefile.in
? test/.deps
? test/Makefile
? test/Makefile.in
? tools/.deps
? tools/Makefile
? tools/Makefile.in
Index: rfcomm/main.c
===================================================================
RCS file: /cvsroot/bluez/utils/rfcomm/main.c,v
retrieving revision 1.19
diff -u -r1.19 main.c
--- rfcomm/main.c	6 Jul 2006 09:31:03 -0000	1.19
+++ rfcomm/main.c	9 Aug 2006 10:06:15 -0000
@@ -39,6 +39,7 @@
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
+#include <sys/wait.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -252,6 +253,67 @@
 	return 0;
 }
 
+static void run_command_line(struct pollfd* p, char* command_line, char* device_name)
+{
+	int i=0;
+	pid_t pid, child;
+	char command[256] = "";
+#define NBARGVS 8
+	char * argv_table[NBARGVS+1];
+	char* cur_arg=NULL;
+	char* next_arg=NULL;
+	int status = 0;
+
+	memset(argv_table, 0, sizeof(argv_table));
+	strncpy(command, command_line, sizeof(command));
+	command[sizeof(command)-1]=0;
+	cur_arg = command;
+			
+	// Create params table, end with NULL hence +1 in declaration
+	i=0;
+	while(i<NBARGVS) {
+		argv_table[i] = cur_arg;
+		next_arg = strchr(cur_arg, ' ');
+		if(next_arg) { *next_arg=0; cur_arg = next_arg+1; }
+		else break;
+		i++;
+	}
+	for(i=0; i<NBARGVS && argv_table[i]; i++) {
+		if(strcmp(argv_table[i], "{}")==0) {
+			argv_table[i] = device_name;
+		}
+	}
+
+	pid = fork();
+
+	switch(pid) {
+		case 0:
+			// Replace children with new process
+			i = execv(command, argv_table);
+			fprintf(stderr, "execv failed %s=%d (errno=%d:%s)\n", command, i, errno, strerror(errno));
+			break;
+		case -1:
+			// failed
+			fprintf(stderr, "fork %s failed\n", command);
+			break;
+		default:
+			// Parent, Wait for children and also watch fd for errors
+			while (1) {
+				child = waitpid(-1, &status, WNOHANG);
+				if (child == pid || (child < 0 && errno != EAGAIN))
+					break;
+
+				p->revents = 0;
+				if (poll(p, 1, 200) || __io_canceled) {
+					kill(pid, SIGTERM);
+					waitpid(pid, &status, 0);
+					break;
+				}
+			}
+			break;
+	}
+}
+
 static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	struct sockaddr_rc laddr, raddr;
@@ -402,6 +464,7 @@
 	socklen_t alen;
 	char dst[18], devname[MAXPATHLEN];
 	int sk, nsk, fd, try = 30;
+	char* command_line = (argc < 3) ? NULL : argv[2];
 
 	laddr.rc_family = AF_BLUETOOTH;
 	bacpy(&laddr.rc_bdaddr, bdaddr);
@@ -499,10 +562,14 @@
 	p.fd = fd;
 	p.events = POLLERR | POLLHUP;
 
-	while (!__io_canceled) {
-		p.revents = 0;
-		if (poll(&p, 1, 100))
-			break;
+	if(!command_line) {
+		while (!__io_canceled) {
+			p.revents = 0;
+			if (poll(&p, 1, 100))
+				break;
+		}
+	} else {
+		run_command_line(&p, command_line, devname);
 	}
 
 	printf("Disconnected\n");
@@ -510,6 +577,22 @@
 	close(fd);
 }
 
+static void cmd_watch(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
+{
+	struct sigaction sa;
+
+	sa.sa_handler = sig_term;
+	sigaction(SIGTERM, &sa, NULL);
+	sigaction(SIGINT,  &sa, NULL);
+
+        // While process not killed
+        while(!__io_canceled)
+        {
+                cmd_listen(ctl, dev, bdaddr, argc, argv);
+                usleep(100*1000);
+        }
+}
+
 static void cmd_create(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv)
 {
 	if (strcmp(argv[0], "all") == 0)
@@ -552,7 +635,8 @@
 	{ "release", "unbind", cmd_release, "<dev>",                    "Release device" },
 	{ "show",    "info",   cmd_show,    "<dev>",                    "Show device"    },
 	{ "connect", "conn",   cmd_connect, "<dev> <bdaddr> [channel]", "Connect device" },
-	{ "listen",  "server", cmd_listen,  "<dev> [channel]",          "Listen"         },
+	{ "listen",  "server", cmd_listen,  "<dev> [channel [cmd]]",    "Listen"         },
+	{ "watch",   "watch",  cmd_watch,   "<dev> [channel [cmd]]",    "Watch"          },
 	{ NULL, NULL, NULL, 0, 0 }
 };
 

[-- Attachment #3: Type: text/plain, Size: 373 bytes --]

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642

[-- Attachment #4: Type: text/plain, Size: 164 bytes --]

_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-08-10 15:17 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-09 10:19 [Bluez-devel] rfcomm utility patch to loop and startup executable when connection received Frédéric DALLEAU
2006-08-09 21:50 ` Marcel Holtmann
2006-08-10 13:36   ` Frédéric DALLEAU
2006-08-10 15:17     ` [Bluez-devel] rfcomm utility patch to loop and startup executable when connection received [REPOST] Frédéric DALLEAU

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).