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

📄 main.c

📁 这是Linux环境下的蓝牙源代码
💻 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 "hcid.h"#include "sdpd.h"#include "adapter.h"#include "dbus-common.h"#include "dbus-database.h"#include "dbus-hci.h"#include "device.h"#include "agent.h"#include "manager.h"struct hcid_opts hcid;struct device_opts default_device;static struct device_list *device_list = NULL;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_error_free(err);		err = NULL;	} else {		debug("offmode=%s", str);		if (g_str_equal(str, "DevDown"))			hcid.offmode = HCID_OFFMODE_DEVDOWN;		g_free(str);	}	val = g_key_file_get_integer(config, "General",					"DiscoverableTimeout",					&err);	if (err) {		debug("%s", err->message);		g_error_free(err);		err = NULL;	} else {		debug("discovto=%d", val);		default_device.discovto = val;		default_device.flags |= 1 << HCID_SET_DISCOVTO;	}	val = g_key_file_get_integer(config, "General",					"PageTimeout",					&err);	if (err) {		debug("%s", err->message);		g_error_free(err);		err = NULL;	} else {		debug("pageto=%d", val);		default_device.pageto = val;		default_device.flags |= 1 << HCID_SET_PAGETO;	}	str = g_key_file_get_string(config, "General",					"Name", &err);	if (err) {		debug("%s", err->message);		g_error_free(err);		err = NULL;	} else {		debug("name=%s", str);		g_free(default_device.name);		default_device.name = g_strdup(str);		default_device.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_error_free(err);		err = NULL;	} else {		debug("class=%s", str);		default_device.class = strtol(str, NULL, 16);		default_device.flags |= 1 << HCID_SET_CLASS;		g_free(str);	}	default_device.link_mode = HCI_LM_ACCEPT;	default_device.flags |= (1 << HCID_SET_LM);	default_device.link_policy = HCI_LP_RSWITCH | HCI_LP_SNIFF |						HCI_LP_HOLD | HCI_LP_PARK;	default_device.flags |= (1 << HCID_SET_LP);}static inline void init_device_defaults(struct device_opts *device_opts){	memset(device_opts, 0, sizeof(*device_opts));	device_opts->scan = SCAN_PAGE;	device_opts->mode = MODE_CONNECTABLE;	device_opts->name = g_strdup("BlueZ");	device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT;}struct device_opts *alloc_device_opts(char *ref){	struct device_list *device;	device = g_try_new(struct device_list, 1);	if (!device) {		info("Can't allocate devlist opts buffer: %s (%d)",							strerror(errno), errno);		exit(1);	}	device->ref = g_strdup(ref);	device->next = device_list;	device_list = device;	memcpy(&device->opts, &default_device, sizeof(struct device_opts));	device->opts.name = g_strdup(default_device.name);	return &device->opts;}static void free_device_opts(void){	struct device_list *device, *next;	g_free(default_device.name);	for (device = device_list; device; device = next) {		g_free(device->ref);		g_free(device->opts.name);		next = device->next;		g_free(device);	}	device_list = NULL;}static inline struct device_opts *find_device_opts(char *ref){	struct device_list *device;	for (device = device_list; device; device = device->next)		if (!strcmp(ref, device->ref))			return &device->opts;	return NULL;}static struct device_opts *get_device_opts(int hdev){	struct device_opts *device_opts = NULL;	struct hci_dev_info di;	/* First try to get BD_ADDR based settings ... */	if (hci_devinfo(hdev, &di) == 0) {		char addr[18];		ba2str(&di.bdaddr, addr);		device_opts = find_device_opts(addr);	}	/* ... then try HCI based settings ... */	if (!device_opts) {		char ref[8];		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);		device_opts = find_device_opts(ref);	}	/* ... and last use the default settings. */	if (!device_opts)		device_opts = &default_device;	return device_opts;}static struct device_opts *get_opts(int hdev){	struct device_opts *device_opts = NULL;	struct hci_dev_info di;	char addr[18];	int sock;	if (hdev < 0)		return NULL;	sock = hci_open_dev(hdev);	if (sock < 0)		goto no_address;	if (hci_devinfo(hdev, &di) < 0) {		close(sock);		goto no_address;	}	close(sock);	ba2str(&di.bdaddr, addr);	device_opts = find_device_opts(addr);no_address:	if (!device_opts) {		char ref[8];		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);		device_opts = find_device_opts(ref);	}	if (!device_opts)		device_opts = &default_device;	return device_opts;}uint8_t get_startup_scan(int hdev){	struct device_opts *device_opts = get_opts(hdev);	if (!device_opts)		return SCAN_DISABLED;	return device_opts->scan;}uint8_t get_startup_mode(int hdev){	struct device_opts *device_opts = get_opts(hdev);	if (!device_opts)		return MODE_OFF;	return device_opts->mode;}int get_discoverable_timeout(int hdev){	struct device_opts *device_opts = NULL;	struct hci_dev_info di;	char addr[18];	int sock, timeout;	if (hdev < 0)		return HCID_DEFAULT_DISCOVERABLE_TIMEOUT;	sock = hci_open_dev(hdev);	if (sock < 0)		goto no_address;	if (hci_devinfo(hdev, &di) < 0) {		close(sock);		goto no_address;	}	close(sock);	if (read_discoverable_timeout(&di.bdaddr, &timeout) == 0)		return timeout;	ba2str(&di.bdaddr, addr);	device_opts = find_device_opts(addr);no_address:	if (!device_opts) {		char ref[8];		snprintf(ref, sizeof(ref) - 1, "hci%d", hdev);		device_opts = find_device_opts(ref);	}	if (!device_opts)		device_opts = &default_device;	return device_opts->discovto;}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 = hcid.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 device_opts *device_opts;	struct hci_dev_req dr;	struct hci_dev_info di;	char mode[14];	int dd;	device_opts = get_device_opts(dev_id);	if (hci_devinfo(dev_id, &di) < 0)		return;	if (hci_test_bit(HCI_RAW, &di.flags))		return;	/* Set default discoverable timeout if not set */	if (!(device_opts->flags & (1 << HCID_SET_DISCOVTO)))

⌨️ 快捷键说明

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