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

📄 main.c

📁 BlueZ源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2000-2001  Qualcomm Incorporated *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com> *  Copyright (C) 2002-2008  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 as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA * */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <signal.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/types.h>#include <sys/wait.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <glib.h>#include <dbus/dbus.h>#include "logging.h"#include "hcid.h"#include "sdpd.h"#include "adapter.h"#include "dbus-hci.h"#include "dbus-common.h"#include "agent.h"#include "manager.h"#include "storage.h"#define HCID_DEFAULT_DISCOVERABLE_TIMEOUT 180 /* 3 minutes */enum {	HCID_SET_NAME,	HCID_SET_CLASS,	HCID_SET_PAGETO,	HCID_SET_DISCOVTO,};struct main_opts main_opts;static int child_pipe[2];static GKeyFile *load_config(const char *file){	GError *err = NULL;	GKeyFile *keyfile;	keyfile = g_key_file_new();	g_key_file_set_list_separator(keyfile, ',');	if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {		error("Parsing %s failed: %s", file, err->message);		g_error_free(err);		g_key_file_free(keyfile);		return NULL;	}	return keyfile;}static void parse_config(GKeyFile *config){	GError *err = NULL;	char *str;	int val;	if (!config)		return;	debug("parsing main.conf");	str = g_key_file_get_string(config, "General",					"OffMode", &err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("offmode=%s", str);		if (g_str_equal(str, "DevDown"))			main_opts.offmode = HCID_OFFMODE_DEVDOWN;		g_free(str);	}	val = g_key_file_get_integer(config, "General",					"DiscoverableTimeout",					&err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("discovto=%d", val);		main_opts.discovto = val;		main_opts.flags |= 1 << HCID_SET_DISCOVTO;	}	val = g_key_file_get_integer(config, "General",					"PairableTimeout",					&err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("pairto=%d", val);		main_opts.pairto = val;	}	val = g_key_file_get_integer(config, "General",					"PageTimeout",					&err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("pageto=%d", val);		main_opts.pageto = val;		main_opts.flags |= 1 << HCID_SET_PAGETO;	}	str = g_key_file_get_string(config, "General",					"Name", &err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("name=%s", str);		g_free(main_opts.name);		main_opts.name = g_strdup(str);		main_opts.flags |= 1 << HCID_SET_NAME;		g_free(str);	}	str = g_key_file_get_string(config, "General",					"Class", &err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("class=%s", str);		main_opts.class = strtol(str, NULL, 16);		main_opts.flags |= 1 << HCID_SET_CLASS;		g_free(str);	}	val = g_key_file_get_integer(config, "General",					"DiscoverSchedulerInterval",					&err);	if (err) {		debug("%s", err->message);		g_clear_error(&err);	} else {		debug("inqmode=%d", val);		main_opts.inqmode = val;	}	main_opts.link_mode = HCI_LM_ACCEPT;	main_opts.link_policy = HCI_LP_RSWITCH | HCI_LP_SNIFF |						HCI_LP_HOLD | HCI_LP_PARK;}static void update_service_classes(const bdaddr_t *bdaddr, uint8_t value){	struct hci_dev_list_req *dl;	struct hci_dev_req *dr;	int i, sk;	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);	if (sk < 0)		return;	dl = g_malloc0(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));	dl->dev_num = HCI_MAX_DEV;	dr = dl->dev_req;	if (ioctl(sk, HCIGETDEVLIST, dl) < 0) {		close(sk);		g_free(dl);		return;	}	dr = dl->dev_req;	for (i = 0; i < dl->dev_num; i++, dr++) {		struct hci_dev_info di;		uint8_t cls[3];		int dd;		if (hci_devinfo(dr->dev_id, &di) < 0)			continue;		if (hci_test_bit(HCI_RAW, &di.flags))			continue;		if (!hci_test_bit(HCI_UP, &di.flags))			continue;		if (manager_get_adapter_class(di.dev_id, cls) < 0)			continue;		dd = hci_open_dev(di.dev_id);		if (dd < 0)			continue;		set_service_classes(dd, cls, value);		hci_close_dev(dd);		manager_update_adapter(di.dev_id);	}	g_free(dl);	close(sk);}/* * Device name expansion *   %d - device id */static char *expand_name(char *dst, int size, char *str, int dev_id){	register int sp, np, olen;	char *opt, buf[10];	if (!str && !dst)		return NULL;	sp = np = 0;	while (np < size - 1 && str[sp]) {		switch (str[sp]) {		case '%':			opt = NULL;			switch (str[sp+1]) {			case 'd':				sprintf(buf, "%d", dev_id);				opt = buf;				break;			case 'h':				opt = main_opts.host_name;				break;			case '%':				dst[np++] = str[sp++];				/* fall through */			default:				sp++;				continue;			}			if (opt) {				/* substitute */				olen = strlen(opt);				if (np + olen < size - 1)					memcpy(dst + np, opt, olen);				np += olen;			}			sp += 2;			continue;		case '\\':			sp++;			/* fall through */		default:			dst[np++] = str[sp++];			break;		}	}	dst[np] = '\0';	return dst;}static gboolean child_exit(GIOChannel *io, GIOCondition cond, void *user_data){	int status, fd = g_io_channel_unix_get_fd(io);	pid_t child_pid;	if (read(fd, &child_pid, sizeof(child_pid)) != sizeof(child_pid)) {		error("child_exit: unable to read child pid from pipe");		return TRUE;	}	if (waitpid(child_pid, &status, 0) != child_pid)		error("waitpid(%d) failed", child_pid);	else		debug("child %d exited", child_pid);	return TRUE;}static void at_child_exit(void){	pid_t pid = getpid();	if (write(child_pipe[1], &pid, sizeof(pid)) != sizeof(pid))		error("unable to write to child pipe");}static void configure_device(int dev_id){	struct hci_dev_info di;	uint16_t policy;	int dd;	if (hci_devinfo(dev_id, &di) < 0)		return;	if (hci_test_bit(HCI_RAW, &di.flags))		return;	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("Can't open device hci%d: %s (%d)",						dev_id, strerror(errno), errno);		return;	}	/* Set device name */	if ((main_opts.flags & (1 << HCID_SET_NAME)) && main_opts.name) {		change_local_name_cp cp;		memset(cp.name, 0, sizeof(cp.name));		expand_name((char *) cp.name, sizeof(cp.name),						main_opts.name, dev_id);		hci_send_cmd(dd, OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME,					CHANGE_LOCAL_NAME_CP_SIZE, &cp);	}	/* Set device class */	if ((main_opts.flags & (1 << HCID_SET_CLASS))) {		write_class_of_dev_cp cp;		uint32_t class;		uint8_t cls[3];		if (read_local_class(&di.bdaddr, cls) < 0) {			class = htobl(main_opts.class);			cls[2] = get_service_classes(&di.bdaddr);			memcpy(cp.dev_class, &class, 3);		} else {			if (!(main_opts.scan & SCAN_INQUIRY))				cls[1] &= 0xdf; /* Clear discoverable bit */			cls[2] = get_service_classes(&di.bdaddr);			memcpy(cp.dev_class, cls, 3);		}		hci_send_cmd(dd, OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV,					WRITE_CLASS_OF_DEV_CP_SIZE, &cp);	}	/* Set page timeout */	if ((main_opts.flags & (1 << HCID_SET_PAGETO))) {		write_page_timeout_cp cp;

⌨️ 快捷键说明

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