summaryrefslogtreecommitdiffstats
path: root/rfcomm
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2007-06-05 09:38:05 +0000
committerMarcel Holtmann <marcel@holtmann.org>2007-06-05 09:38:05 +0000
commitb9192f4232bd24394a0d22180d6a9e5900d2ea98 (patch)
tree1ee2949d5317994eb54b16120b437fede6f20c42 /rfcomm
parent6e1999d1ddf223e3a0fc173a8dc6fc2342ab9da3 (diff)
Add support for linger timeout
Diffstat (limited to 'rfcomm')
-rw-r--r--rfcomm/main.c38
-rw-r--r--rfcomm/rfcomm.15
2 files changed, 35 insertions, 8 deletions
diff --git a/rfcomm/main.c b/rfcomm/main.c
index 80eaab56..e648c2d1 100644
--- a/rfcomm/main.c
+++ b/rfcomm/main.c
@@ -59,6 +59,7 @@ static int auth = 0;
static int encryption = 0;
static int secure = 0;
static int master = 0;
+static int linger = 0;
static char *rfcomm_state[] = {
"unknown",
@@ -100,7 +101,7 @@ static char *rfcomm_flagstostr(uint32_t flags)
if (flags & (1 << RFCOMM_TTY_ATTACHED))
strcat(str, "tty-attached");
-
+
strcat(str, "]");
return str;
}
@@ -170,7 +171,6 @@ static int create_dev(int ctl, int dev, uint32_t flags, bdaddr_t *bdaddr, int ar
fprintf(stderr, "Can't find a config entry for rfcomm%d\n", dev);
return -EFAULT;
}
-
} else {
str2ba(argv[1], &req.dst);
@@ -265,7 +265,7 @@ static void run_cmdline(struct pollfd *p, sigset_t* sigs, char *devname,
int i;
pid_t pid;
char **cmdargv;
-
+
cmdargv = malloc((argc + 1) * sizeof(char*));
if (!cmdargv)
return;
@@ -357,13 +357,22 @@ static void cmd_connect(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **arg
return;
}
- if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
+ if (linger) {
+ struct linger l = { .l_onoff = 1, .l_linger = linger };
+
+ if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
+ perror("Can't set linger option");
+ return;
+ }
+ }
+
+ if (bind(sk, (struct sockaddr *) &laddr, sizeof(laddr)) < 0) {
perror("Can't bind RFCOMM socket");
close(sk);
return;
}
- if (connect(sk, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
+ if (connect(sk, (struct sockaddr *) &raddr, sizeof(raddr)) < 0) {
perror("Can't connect RFCOMM socket");
close(sk);
return;
@@ -524,6 +533,16 @@ static void cmd_listen(int ctl, int dev, bdaddr_t *bdaddr, int argc, char **argv
return;
}
+ if (linger) {
+ struct linger l = { .l_onoff = 1, .l_linger = linger };
+
+ if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
+ perror("Can't set linger option");
+ close(nsk);
+ return;
+ }
+ }
+
memset(&req, 0, sizeof(req));
req.dev_id = dev;
req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP);
@@ -708,7 +727,6 @@ static void usage(void)
printf("\n");
}
-
static struct option main_options[] = {
{ "help", 0, 0, 'h' },
{ "device", 1, 0, 'i' },
@@ -718,6 +736,7 @@ static struct option main_options[] = {
{ "encrypt", 0, 0, 'E' },
{ "secure", 0, 0, 'S' },
{ "master", 0, 0, 'M' },
+ { "linger", 1, 0, 'L' },
{ 0, 0, 0, 0 }
};
@@ -728,7 +747,7 @@ int main(int argc, char *argv[])
bacpy(&bdaddr, BDADDR_ANY);
- while ((opt = getopt_long(argc, argv, "+i:f:rahAESM", main_options, NULL)) != -1) {
+ while ((opt = getopt_long(argc, argv, "+i:f:rahAESML:", main_options, NULL)) != -1) {
switch(opt) {
case 'i':
if (strncmp(optarg, "hci", 3) == 0)
@@ -740,6 +759,7 @@ int main(int argc, char *argv[])
case 'f':
rfcomm_config_file = strdup(optarg);
break;
+
case 'r':
rfcomm_raw_tty = 1;
break;
@@ -768,6 +788,10 @@ int main(int argc, char *argv[])
master = 1;
break;
+ case 'L':
+ linger = atoi(optarg);
+ break;
+
default:
exit(0);
}
diff --git a/rfcomm/rfcomm.1 b/rfcomm/rfcomm.1
index 47c98857..eaec05df 100644
--- a/rfcomm/rfcomm.1
+++ b/rfcomm/rfcomm.1
@@ -48,7 +48,7 @@ Prints information about all configured RFCOMM devices.
.BI -r
Switch TTY into raw mode (doesn't work with "bind").
.TP
-.BI -f " [file]"
+.BI -f " <file>"
Specify alternate config file.
.TP
.BI -i " <hciX> | <bdaddr>"
@@ -78,6 +78,9 @@ Secure connection
.TP
.BI -M
Become the master of a piconet
+.TP
+.BI -L " <seconds>"
+Set linger timeout
.SH COMMANDS
.TP
.BI show " <dev>"