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

📄 btsrv.c

📁 Affix - Bluetooth Protocol Stack for Linux has been developed at Nokia Research Center in Helsinki
💻 C
📖 第 1 页 / 共 2 页
字号:
		err = HCI_LinkKeyRequestReply(fd, &evt->bda, btdev->link_key);	} else {		err = HCI_LinkKeyRequestNegativeReply(fd, &evt->bda);	}	if (err) {		BTERROR("unable to set link key: %d", err);	}	btdev_cache_unlock(&btdevs);	hci_close(fd);	return err;}int event_link_key_notification(struct Link_Key_Notification_Event *evt, int devnum){	btdev_struct	*btdev;	if (!managekey)		return 0;	btdev_cache_reload(&btdevs);	btdev = btdev_cache_add(&btdevs, &evt->bda);	if (btdev == NULL)		return -1;	btdev->key_type = evt->Key_Type;	memcpy(btdev->link_key, evt->Link_Key, 16);	btdev->flags |= BTDEV_KEY;	btdev_cache_save(&btdevs);		return 0;}int event_handler(int fd){	__u8	buf[HCI_MAX_EVENT_SIZE];	int	devnum;	HCI_Event_Packet_Header	*hdr = (void*)buf;	hci_recv_event_any(fd, &devnum, buf, sizeof(buf));	DBPRT("got event: %#x, from: %d", hdr->EventCode, devnum);	switch (hdr->EventCode) {		case HCI_E_LINK_KEY_REQUEST:			event_link_key_request((void*)hdr, devnum);			break;		case HCI_E_LINK_KEY_NOTIFICATION:			event_link_key_notification((void*)hdr, devnum);			break;		case HCI_E_PIN_CODE_REQUEST:			event_pin_code_request((void*)hdr, devnum);			break;		default:			break;	}	return 0;}int message_handler(int fd){	__u8			buf[HCI_MAX_MSG_SIZE];	struct hci_msg_hdr	*msg = (void*)(buf+1);	int			err;	recv(fd, buf, sizeof(buf), 0);	DBPRT("got message: %x", msg->opcode);	if (msg->opcode == HCICTL_STATE_CHANGE) {		struct hci_state_change	*cmd = (void*)msg;		if (cmd->event == HCIDEV_UP) {			DBPRT("device is up\n");			err = btsrv_devconf(cmd->devnum);			if (err) {				BTERROR("Unable to configure device: %d", cmd->devnum);				return err;			}		}	}	return 0;}int handle_input(void){	int	i, err = 0;	int	fd_cnt;	fd_set	fds_read;	int	max_fd;	for(;;) {		FD_ZERO(&fds_read);		max_fd = -1;		/* set service fd */		for (i = 0; i < svcnums; i++) {			if (services[i].running && services[i].srv_fd != -1) {				FD_SET(services[i].srv_fd, &fds_read);				if (max_fd < services[i].srv_fd)					max_fd = services[i].srv_fd;			}		}		/* set event fd */		FD_SET(efd, &fds_read);		if (max_fd < efd)			max_fd = efd;		FD_SET(mfd, &fds_read);		if (max_fd < mfd)			max_fd = mfd;		/* poll data */		fd_cnt = select(max_fd + 1, &fds_read, NULL, NULL, NULL);		if (fd_cnt <= 0) {			BTERROR("Select error");			err = -1;			goto exit;		}		if (FD_ISSET(efd, &fds_read)) {			event_handler(efd);		}		if (FD_ISSET(mfd, &fds_read)) {			message_handler(mfd);		}		for (i = 0; fd_cnt && (i < svcnums); i++) {			if (services[i].running && services[i].srv_fd != -1 && 					FD_ISSET(services[i].srv_fd, &fds_read)) {				int 			newsock;				struct sockaddr_affix	caddr;				socklen_t		calen = sizeof(caddr);				int			pid;				newsock = accept(services[i].srv_fd, (struct sockaddr*)&caddr, &calen);				if (newsock == -1) {					BTERROR("Accept error");					continue;				}				BTINFO("Connection from %s\nchannel %d (%s Profile)",						bda2str(&caddr.bda), caddr.port, services[i].name);				if (services[i].cmd[0] != '\0') {					pid = fork();					if (pid < 0) {						BTERROR("Fork error");						continue;					}					if (pid == 0) {						int res, j;						for (j = 0; j < svcnums; j++)							close(services[j].srv_fd);						res = execute_cmd(services[i].cmd, newsock,								caddr.port, &caddr.bda, 								services[i].flags);						/*  In case of error.. */						exit(res);					}				}				close(newsock);				fd_cnt--;			}		}	}exit:	return err;}/* * read HCI events and kernel messages */int start_event_handler(void){	__u64		mask = 0;	efd = hci_open_event();	if (efd < 0) {		BTERROR("Unable to open hci(NULL)");		return efd;			}	mfd = hci_open_mgr();	if (mfd < 0) {		BTERROR("Unable to open mgr");		close(efd);		return mfd;	}	if (managepin) {		hci_set_mode(mfd, AFFIX_MODE_PIN);		mask |= PIN_CODE_REQUEST_MASK;	}	if (managekey) {		hci_set_mode(mfd, AFFIX_MODE_KEY);		mask |= LINK_KEY_NOTIFICATION_MASK | LINK_KEY_REQUEST_MASK;	}	if (mask)		hci_event_mask(efd, mask);	return 0;}void stop_event_handler(void){	close(mfd);	close(efd);}int btsrv_setdev(int fd, device_t *dev){	int	err;	err = HCI_WriteSecurityMode(fd, dev->security);	if (err < 0) {		BTERROR("hci_set_secmode() failed\n");		return err;	}	err = hci_set_role(fd, dev->role);	if (err < 0) {		BTERROR("hci_set_role() failed\n");		return err;	}	err = hci_set_pkttype(fd, dev->pkt_type);	if (err < 0) {		BTERROR("hci_set_pkttype() failed\n");		return err;	}	err = HCI_WriteClassOfDevice(fd, dev->cod);	if (err) {		BTERROR("WriteScanEnable error\n");		return err;	}	if (dev->btname) {		err = HCI_ChangeLocalName(fd, dev->btname);		if (err) {			BTERROR("WriteScanEnable error\n");			return err;		}	}	err = HCI_WriteScanEnable(fd, dev->scan);	if (err) {		BTERROR("WriteScanEnable error\n");		return err;	}	return 0;}int btsrv_devconf(int devnum){	int			err = 0, i, fd;	device_t		*dev;	struct hci_dev_attr	da;	if (!initdev)		return 0;	err = hci_get_attr_id(devnum, &da);	if (err)		return err;	fd = hci_open(da.name);	if (fd < 0) {		BTERROR("hci_open_id() failed: %s\n", da.name);		return fd;	}	for (i = 0; i < devnums; i++) {		dev = &devices[i];		if ((i == 0 && dev->name[0] == '*') ||				(strcasecmp(dev->name, da.name) == 0)) {			err = btsrv_setdev(fd, dev);			if (err)				break;		}	}	close(fd);	return err;}int btsrv_devinit(void){	int			i, err, num;	int			devs[HCI_MAX_DEVS];	struct hci_dev_attr	da;	num = hci_get_devs(devs);	if (num < 0) {		BTERROR("Unable to get device info\n");						return num;	}	for (i = 0; i < num; i++) {		err = hci_get_attr_id(devs[i], &da);		if (err < 0) {			BTERROR("hci_get_attr() failed: %d\n", devs[i]);			continue;		}		if (!(da.flags & HCI_FLAGS_UP))			continue;		err = btsrv_devconf(da.devnum);		if (err)			return err;	}	return 0;}int btsrv_cleanup(void){	int		i;	device_t	*dev;	stop_event_handler();	stop_all_services();	BTINFO("Terminating ..");#if defined(CONFIG_AFFIX_SDP)	sdpreg_cleanup();#endif	free(config_file);	for (i = 0; i < svcnums; i++) {		if (services[i].name)			free(services[i].name);		if (services[i].prov)			free(services[i].prov);		if (services[i].desc)			free(services[i].prov);	}	for (i = 0; i < devnums; i++) {		dev = &devices[i];		if (dev->btname)			free(dev->btname);	}	return 0;}void signal_handler(int sig){	BTINFO("Sig handler : %d", sig);	btsrv_cleanup();	exit(0);}void get_cmd_opts(int argc, char **argv){	int	c, lind = 0;	struct option	opts[] = {		{"help", 0, 0, 'h'},		{"daemon", 0, 0, 'd'},		{"config", 1, 0, 'C'},		{"debug", 0, 0, 'v'},		{"initdev", 0, 0, 'i'},		{"noinitdev", 0, 0, 'I'},		{"startsvc", 0, 0, 's'},		{"nostartsvc", 0, 0, 'S'},		{"managepin", 0, 0, 'p'},		{"nomanagepin", 0, 0, 'P'},		{"managekey", 0, 0, 'k'},		{"nomanagekey", 0, 0, 'K'},		{"expression", 0, 0, 'e'},		{0, 0, 0, 0}	};	optind = 0;	for (;;) {		c = getopt_long(argc, argv, "hdpskvC:e:", opts, &lind);		if (c == -1)			break;		switch (c) {			case 'h':				printusage();				exit(0);				break;			case 'd':					_daemon = 1;				break;			case 'C':				config_file = strdup(optarg);				break;			case 'v':				affix_logmask = BTDEBUG_MODULE;				break;			case 'p':				managepin = 1;				break;			case 'P':				managepin = 0;				break;			case 'k':				managekey = 1;				break;			case 'K':				managekey = 0;				break;			case 'i':				initdev = 1;				break;			case 'I':				initdev = 0;				break;			case 's':				startsvc = 1;				break;			case 'S':				startsvc = 0;				break;			case 'e':				config_expr = strdup(optarg);				break;			case '?':				fprintf(stderr, "Unknown option: %c\n", optopt);				exit(1);				break;		}	}}int main(int argc, char **argv){	int	err;	char	cachefile[80];	openlog(NULL/*argv[0]*/, LOG_PERROR, LOG_DAEMON);	BTINFO("%s started [%s].", argv[0], affix_version);		if (affix_init()) {		BTERROR("Affix initialization failed\n");		return 1;	}	affix_logmask = BTDEBUG_MODULE;		// read first to get config_file	get_cmd_opts(argc, argv);	if (config_expr) {		// use command line configuration		if (btsrv_read_config_buf(config_expr, &svcnums, &devnums)) {			BTERROR("Invalid config expr: %s", config_expr);			return -1;		}		startsvc = 1;	// default action for this	} else {		if (!config_file)			config_file = strdup(DEF_CONFIG_FILE);		// read config_file		if (btsrv_read_config(config_file, &svcnums, &devnums)) {			BTERROR("Invalid config file: %s", config_file);			return -1;		}	}	// read to overwride config file setting by command line	get_cmd_opts(argc, argv);		if (getuid() == 0) {		/* root -> put the stuff to /var/spool/affix */		sprintf(confdir, "/var/spool/affix");	} else		sprintf(confdir, "%s/.bluetooth", getenv("HOME"));	err = rmkdir(confdir, 0700);	if (err < 0) {		BTERROR("Unable to create dir [%s]: %s", confdir, strerror(errno));		return 1;	}	/* load device list from the cache */	sprintf(cachefile, "%s/%s", confdir, "devcache");	btdev_cache_load(cachefile, &btdevs);	/* test X access */	if (managepin) {		err = system("/etc/affix/btsrv-gui try 2>/dev/null");		if (err) {			BTERROR("Unable to launch to /etc/affix/btsrv-gui\n"				"-> maybe unable to connect to X-server or python-gtk problems\n"				"-> Disable options requiring btsrv-gui (e.g. give --nomanagepin)\n");			return 1;		}	}	if (startsvc && svcnums < 1)		BTINFO("No services found in %s", config_file);#if defined(CONFIG_AFFIX_SDP)	if (sdpreg_init() != 0) {		BTERROR("SDP initialization failed");		return -1;	}#endif	/* initialize devices */	err = btsrv_devinit();	if (err) {		BTERROR("Unable to initialize devices\n");		return -1;	}	signal(SIGCHLD, SIG_IGN);	if (start_event_handler() < 0) {		BTERROR("Cannot start event handler");		return -1;	}	if (start_all_services() < 0) {		BTERROR("Cannot start services");		return -1;	}	/* Exit the parent process if run as a daemon */	if (_daemon && become_daemon(1))		return 0;	/* install signal handlers to unregister services from SDP */	signal(SIGINT, signal_handler);	signal(SIGTERM, signal_handler);	signal(SIGABRT, signal_handler);	signal(SIGQUIT, signal_handler);	if (handle_input() < 0) {		BTERROR("Unable to listen to incoming connections");	}	btsrv_cleanup();	return 0;}

⌨️ 快捷键说明

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