From b9192f4232bd24394a0d22180d6a9e5900d2ea98 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jun 2007 09:38:05 +0000 Subject: Add support for linger timeout --- rfcomm/main.c | 38 +++++++++++++++++++++++++++++++------- rfcomm/rfcomm.1 | 5 ++++- 2 files changed, 35 insertions(+), 8 deletions(-) (limited to 'rfcomm') 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 " " Specify alternate config file. .TP .BI -i " | " @@ -78,6 +78,9 @@ Secure connection .TP .BI -M Become the master of a piconet +.TP +.BI -L " " +Set linger timeout .SH COMMANDS .TP .BI show " " -- cgit