any reason to require -t dev in rfcomm_sppd -S ?

Maksim Yevmenkin maksim.yevmenkin at gmail.com
Mon Apr 21 18:51:58 UTC 2008


On Thu, Apr 17, 2008 at 11:06 AM, Luigi Rizzo <rizzo at iet.unipi.it> wrote:
>
> On Thu, Apr 17, 2008 at 10:39:16AM -0700, Maksim Yevmenkin wrote:
>  > On Thu, Apr 17, 2008 at 4:56 AM, Luigi Rizzo <rizzo at iet.unipi.it> wrote:
>  > > hi, is there any compelling reason to require
>  > >  the '-t device' option in rfcomm_sppd when used in server mode ?
>  >
>  > technically, no. just need to be careful who is going to setup tty
>  > properly, for example make it 'raw' as rfcomm_sppd(1) does with pty.
>  > rfcomm_sppd(1) already can be used inside ppp(8), i.e. one can do
>  > something like
>  >
>  > set device '!/usr/bin/rfcomm_sppd -a mobile -c sp'
>  >
>  > in /etc/ppp.conf and it will work just fine. rfcomm_sppd(1) does not
>  > do anything to tty when running using stdin/stdout in client mode. the
>  > assumption here is that whatever calls rfcomm_sppd(1) will setup
>  > tty/fd properly.
>  >
>  > >  I tried to disable the one-line that checks it in the code, and
>  > >  things seem to work - and this makes the program very convenient
>  > >  to use in a pipeline, e.g.  to receive data from a remote bluetooth
>  > >  device.
>  >
>  > right. can you please provide usage example? i certainly would not
>  > object to making the change you are requesting.
>
>  sure - i need to listen to a portable ElectroCardioGram (ECG) device
>  which talks to the external world through bluetooth. The device
>  must have some kind of modem inside - its console port says it is
>  issuing commands such as
>
>         AT+ZV SPPConnect XXX
>         ...
>
>  where XXX is the (manually configured) address of the bluetooth
>  dongle on the PC. On the FreeBSD side, running
>  "rfcom_sppd -a YYY" (without the -S option, YYY is the ECG address)
>  sometimes connects, but most of the times doesnt.
>
>  With a patched rfcomm_sppp i can just do
>
>         rfcomm_sppd -S -a YYY | my_data_logger
>
>  rather than having to manually select an available tty/pty pair
>
>  Don't know how many devices behave in this way, but a
>  search for "AT+ZV SPPConnect" gives several matches with
>  documentation for embedded hardware.

ok, please try the attached patch and see if it works for you. i
basically removed the check for tty name in server mode, bind to
"wildcard" channel instead of generating one based on pid (if channel
was not specified) and fixed a possible problem with service
registration in server mode (i.e. always register serial port
service).

thanks,
max



>
>         cheers
>         luigi
>
-------------- next part --------------
Index: rfcomm_sppd.1
===================================================================
RCS file: /usr/local/cvs/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1,v
retrieving revision 1.10
diff -u -r1.10 rfcomm_sppd.1
--- rfcomm_sppd.1	21 Apr 2008 18:13:23 -0000	1.10
+++ rfcomm_sppd.1	21 Apr 2008 18:37:09 -0000
@@ -25,7 +25,7 @@
 .\" $Id: rfcomm_sppd.1,v 1.10 2008/04/21 18:13:23 max Exp $
 .\" $FreeBSD: src/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.1,v 1.10 2007/01/25 20:54:59 emax Exp $
 .\"
-.Dd January 24, 2007
+.Dd April 21, 2008
 .Dt RFCOMM_SPPD 1
 .Os
 .Sh NAME
@@ -69,14 +69,15 @@
 via the
 .Xr sdpd 8
 daemon.
-The
+If
 .Fl t
-option must be specified;
+options was specified,
 the server side of the virtual serial port is attached to the pseudo-terminal
 .Ar tty .
+Otherwise the virtual serial port is attached to the stdin/stdout.
 .Nm
 should be run as root in order to communicate with
-.Xr sdp 8
+.Xr sdpd 8
 in this case.
 .Pp
 The
@@ -113,12 +114,18 @@
 Detach from the controlling terminal, i.e., run in background.
 .It Fl c Ar channel
 In both client and server mode,
-this required option specifies the RFCOMM channel to connect to or listen on.
+this option specifies the RFCOMM channel to connect to or listen on.
 In server mode,
 the channel should be a number between 1 and 30.
 If not specified,
 .Nm
-will try to allocate RFCOMM channel number based on process ID.
+will try to bind to
+.Dq wildcard
+RFCOMM channel number.
+The actual RFCOMM channel will be obtained via
+.Xr getsockname 2
+call and will be used to register Serial Port service with
+.Xr sdpd 8 .
 In client mode,
 the channel could either be a number between 1 and 30 or a service name.
 Supported service names are:
@@ -144,8 +151,6 @@
 If not set stdin/stdout will be used.
 This option is required if
 .Fl b
-or
-.Fl S
 option was specified.
 .El
 .Sh FILES
Index: rfcomm_sppd.c
===================================================================
RCS file: /usr/local/cvs/usr.bin/bluetooth/rfcomm_sppd/rfcomm_sppd.c,v
retrieving revision 1.11
diff -u -r1.11 rfcomm_sppd.c
--- rfcomm_sppd.c	21 Apr 2008 18:13:23 -0000	1.11
+++ rfcomm_sppd.c	21 Apr 2008 18:39:26 -0000
@@ -1,6 +1,8 @@
 /*
  * rfcomm_sppd.c
- *
+ */
+
+/*-
  * Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin at yahoo.com>
  * All rights reserved.
  *
@@ -172,7 +174,7 @@
 
 	/* Open TTYs */
 	if (tty == NULL) {
-		if (background || doserver)
+		if (background)
 			usage();
 
 		amaster = STDIN_FILENO;
@@ -189,43 +191,47 @@
 	if (doserver) {
 		struct sockaddr_rfcomm	 ma;
 		bdaddr_t		 bt_addr_any;
-		sdp_lan_profile_t	 lan;
+		sdp_sp_profile_t	 sp;
 		void			*ss;
 		uint32_t		 sdp_handle;
 		int			 acceptsock, aaddrlen;
 
-		if (channel == 0) {
-			/* XXX: should check if selected channel is unused */
-			channel = (getpid() % 30) + 1;
-		}
 		acceptsock = socket(PF_BLUETOOTH, SOCK_STREAM,
-		    BLUETOOTH_PROTO_RFCOMM);
+					BLUETOOTH_PROTO_RFCOMM);
 		if (acceptsock < 0)
 			err(1, "Could not create socket");
 
+		memcpy(&bt_addr_any, NG_HCI_BDADDR_ANY, sizeof(bt_addr_any));
+
 		memset(&ma, 0, sizeof(ma));
 		ma.rfcomm_len = sizeof(ma);
 		ma.rfcomm_family = AF_BLUETOOTH;
+		memcpy(&ma.rfcomm_bdaddr, &bt_addr_any, sizeof(bt_addr_any));
 		ma.rfcomm_channel = channel;
 
 		if (bind(acceptsock, (struct sockaddr *)&ma, sizeof(ma)) < 0)
-			err(1, "Could not bind socket -- channel %d in use?",
+			err(1, "Could not bind socket on channel %d",
 			    channel);
 		if (listen(acceptsock, 10) != 0)
 			err(1, "Could not listen on socket");
 
+		aaddrlen = sizeof(ma);
+		if (getsockname(s, (struct sockaddr *)&ma, &aaddrlen) < 0)
+			errx(1, "Could not get socket name");
+		channel = ma.rfcomm_channel;
+
 		ss = sdp_open_local(NULL);
 		if (ss == NULL)
 			errx(1, "Unable to create local SDP session");
 		if (sdp_error(ss) != 0)
 			errx(1, "Unable to open local SDP session. %s (%d)",
 			    strerror(sdp_error(ss)), sdp_error(ss));
-		memset(&lan, 0, sizeof(lan));
-		lan.server_channel = channel;
+		memset(&sp, 0, sizeof(sp));
+		sp.server_channel = channel;
 
-		memcpy(&bt_addr_any, NG_HCI_BDADDR_ANY, sizeof(bt_addr_any));
-		if (sdp_register_service(ss, service, &bt_addr_any,
-		    (void *)&lan, sizeof(lan), &sdp_handle) != 0) {
+		if (sdp_register_service(ss, SDP_SERVICE_CLASS_SERIAL_PORT,
+				&bt_addr_any, (void *)&sp, sizeof(sp),
+				&sdp_handle) != 0) {
 			errx(1, "Unable to register LAN service with "
 			    "local SDP daemon. %s (%d)",
 			    strerror(sdp_error(ss)), sdp_error(ss));


More information about the freebsd-bluetooth mailing list