⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Bluezan implementation of the Bluetooth&#8482 wireless standards specifications for Linux. The code
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2004  Marcel Holtmann <marcel@holtmann.org> * * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License version 2 as *  published by the Free Software Foundation; * *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. *  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY *  CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *  ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,  *  COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS  *  SOFTWARE IS DISCLAIMED. * * *  $Id: main.c,v 1.14 2005/06/09 01:47:57 holtmann Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <syslog.h>#include <signal.h>#include <errno.h>#include <getopt.h>#include <sys/socket.h>#include <sys/poll.h>#include <sys/types.h>#include <sys/stat.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <bluetooth/l2cap.h>#include <bluetooth/bnep.h>#include "pand.h"static uint16_t role = BNEP_SVC_PANU;	/* Local role (ie service) */static uint16_t service = BNEP_SVC_NAP;	/* Remote service */static int  detach = 1;static int  persist;static int  use_sdp = 1;static int  use_cache;static int  auth;static int  encrypt;static int  secure;static int  master;static int  cleanup;static int  search_duration = 10;static struct {	int      valid;	char     dst[40];	bdaddr_t bdaddr;} cache;static char netdev[16] = "bnep%d";static char *pidfile = NULL;static bdaddr_t src_addr = *BDADDR_ANY;static int src_dev = -1;volatile int terminate;static void do_kill(char *dst);enum {	NONE,	SHOW,	LISTEN,	CONNECT,	KILL} modes;static void run_devup(char *dev, char *dst, int sk, int nsk){	char *argv[4], prog[40];	struct sigaction sa;	sprintf(prog, "%s/%s", PAND_CONFIG_DIR, PAND_DEVUP_CMD);	if (access(prog, R_OK | X_OK))		return;	if (fork())		return;	if (sk >= 0)		close(sk);	if (nsk >= 0)		close(nsk);		memset(&sa, 0, sizeof(sa));	sa.sa_handler = SIG_DFL;	sigaction(SIGCHLD, &sa, NULL);	sigaction(SIGPIPE, &sa, NULL);	argv[0] = prog;	argv[1] = dev;	argv[2] = dst;	argv[3] = NULL;	execv(prog, argv);	exit(1);}static int do_listen(void){	struct l2cap_options l2o;	struct sockaddr_l2 l2a;	int sk, olen, lm;	if (use_sdp)		bnep_sdp_register(role);	/* Create L2CAP socket and bind it to PSM BNEP */	sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);	if (sk < 0) {		syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",				strerror(errno), errno);		return -1;	}	memset(&l2a, 0, sizeof(l2a));	l2a.l2_family = AF_BLUETOOTH;	bacpy(&l2a.l2_bdaddr, &src_addr);	l2a.l2_psm = htobs(BNEP_PSM);	if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) {		syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno);		return -1;	}	/* Setup L2CAP options according to BNEP spec */	memset(&l2o, 0, sizeof(l2o));	olen = sizeof(l2o);	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) {		syslog(LOG_ERR, "Failed to get L2CAP options. %s(%d)",				strerror(errno), errno);		return -1;	}	l2o.imtu = l2o.omtu = BNEP_MTU;	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) {		syslog(LOG_ERR, "Failed to set L2CAP options. %s(%d)",				strerror(errno), errno);		return -1;	}	/* Set link mode */	lm = 0;	if (master)		lm |= L2CAP_LM_MASTER;	if (auth)		lm |= L2CAP_LM_AUTH;	if (encrypt)		lm |= L2CAP_LM_ENCRYPT;	if (secure)		lm |= L2CAP_LM_SECURE;	if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {		syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno);		return -1;	}	listen(sk, 10);	while (!terminate) {		int alen = sizeof(l2a);		int nsk;		nsk = accept(sk, (struct sockaddr *) &l2a, &alen);		if (nsk < 0) {			syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno);			continue;		}		switch (fork()) {		case 0:			break;		case -1:			syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno);		default:			close(nsk);			continue;		}		if (!bnep_accept_connection(nsk, role, netdev)) {			char str[40];			ba2str(&l2a.l2_bdaddr, str);			syslog(LOG_INFO, "New connection from %s %s", str, netdev);			run_devup(netdev, str, sk, nsk);		} else {			syslog(LOG_ERR, "Connection failed. %s(%d)",					strerror(errno), errno);		}		close(nsk);		exit(0);	}	if (use_sdp)		bnep_sdp_unregister();	return 0;}/* Wait for disconnect or error condition on the socket */static int w4_hup(int sk){	struct pollfd pf;	int n;	while (!terminate) {		pf.fd = sk;		pf.events = POLLERR | POLLHUP;		n = poll(&pf, 1, -1);		if (n < 0) {			if (errno == EINTR || errno == EAGAIN)				continue;			syslog(LOG_ERR, "Poll failed. %s(%d)",					strerror(errno), errno);			return 1;		}		if (n) {			int err = 0, olen = sizeof(err);			getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &olen);			syslog(LOG_INFO, "%s disconnected%s%s", netdev,				err ? " : " : "", err ? strerror(err) : "");			close(sk);			return 0;		}	}	return 0;}/* Connect and initiate BNEP session * Returns: *   -1 - critical error (exit persist mode) *   1  - non critical error *   0  - success */static int create_connection(char *dst, bdaddr_t *bdaddr){	struct l2cap_options l2o;	struct sockaddr_l2 l2a;	int sk, olen, r = 0;	syslog(LOG_INFO, "Connecting to %s", dst);	sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);	if (sk < 0) {		syslog(LOG_ERR, "Cannot create L2CAP socket. %s(%d)",				strerror(errno), errno);		return -1;	}	/* Setup L2CAP options according to BNEP spec */	memset(&l2o, 0, sizeof(l2o));	olen = sizeof(l2o);	getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);	l2o.imtu = l2o.omtu = BNEP_MTU;	setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));	memset(&l2a, 0, sizeof(l2a));	l2a.l2_family = AF_BLUETOOTH;	bacpy(&l2a.l2_bdaddr, &src_addr);	if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a)))		syslog(LOG_ERR, "Bind failed. %s(%d)", 				strerror(errno), errno);	memset(&l2a, 0, sizeof(l2a));	l2a.l2_family = AF_BLUETOOTH;	bacpy(&l2a.l2_bdaddr, bdaddr);	l2a.l2_psm = htobs(BNEP_PSM);	if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && 			!bnep_create_connection(sk, role, service, netdev)) {		syslog(LOG_INFO, "%s connected", netdev);		run_devup(netdev, dst, sk, -1);		if (persist) {			w4_hup(sk);			if (terminate && cleanup) {				syslog(LOG_INFO, "Disconnecting from %s.", dst);				do_kill(dst);			}		}		r = 0;	} else {		syslog(LOG_ERR, "Connect to %s failed. %s(%d)",				dst, strerror(errno), errno);		r = 1;	}	close(sk);	if (use_cache) {		if (!r) {			/* Succesesful connection, validate cache */			strcpy(cache.dst, dst);			bacpy(&cache.bdaddr, bdaddr);			cache.valid = use_cache;		} else			cache.valid--;	}	return r;}/* Search and connect * Returns: *   -1 - critical error (exit persist mode) *   1  - non critical error *   0  - success */static int do_connect(void){	inquiry_info *ii;	int reconnect = 0;	int i, n, r = 0;	do {		if (reconnect)			sleep(persist);		reconnect = 1;		if (cache.valid > 0) {			/* Use cached bdaddr */			r = create_connection(cache.dst, &cache.bdaddr);			if (r < 0) {				terminate = 1;				break;			}			continue;		}		syslog(LOG_INFO, "Inquiring");		/* FIXME: Should we use non general LAP here ? */		ii = NULL;		n  = hci_inquiry(src_dev, search_duration, 0, NULL, &ii, 0);		if (n < 0) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -