Make -t <tty> optional in server mode. If not specified use stdin/stdout.

Document this. Do not require channel number in server mode. If not
specified - bind to ''wildcard'' channel zero. Real channel number will
be obtained automatically and registered with local sdpd(8). While I'm
here fix serial port service registration.

Submitted by:	luigi
Tested by:	Helge Oldach <freebsd-bluetooth at oldach dot net>
MFC after:	3 days
This commit is contained in:
Maksim Yevmenkin 2008-05-14 16:47:30 +00:00
parent 48504cc25b
commit aa6985f4f3
2 changed files with 34 additions and 24 deletions

View File

@ -25,7 +25,7 @@
.\" $Id: rfcomm_sppd.1,v 1.3 2003/09/07 18:15:55 max Exp $
.\" $FreeBSD$
.\"
.Dd January 24, 2007
.Dd April 21, 2008
.Dt RFCOMM_SPPD 1
.Os
.Sh NAME
@ -69,14 +69,15 @@ address and advertising a virtual serial port
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 @@ utility will attempt to resolve the name via
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 @@ Slave pseudo tty name.
If not set stdin/stdout will be used.
This option is required if
.Fl b
or
.Fl S
option was specified.
.El
.Sh FILES

View File

@ -1,6 +1,8 @@
/*
* rfcomm_sppd.c
*
*/
/*-
* Copyright (c) 2003 Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
@ -172,7 +174,7 @@ main(int argc, char *argv[])
/* Open TTYs */
if (tty == NULL) {
if (background || doserver)
if (background)
usage();
amaster = STDIN_FILENO;
@ -189,43 +191,46 @@ main(int argc, char *argv[])
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?",
channel);
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(acceptsock, (struct sockaddr *)&ma, &aaddrlen) < 0)
err(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));
@ -505,7 +510,7 @@ usage(void)
"\t-a address Peer address (required in client mode)\n" \
"\t-b Run in background\n" \
"\t-c channel RFCOMM channel to connect to or listen on\n" \
"\t-t tty TTY name (required in background or server mode)\n" \
"\t-t tty TTY name (required in background mode)\n" \
"\t-S Server mode\n" \
"\t-h Display this message\n", SPPD_IDENT);
exit(255);