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

📄 main.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 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-2007  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 "notify.h"#include "hcid.h"#include "sdpd.h"#include "server.h"#include "adapter.h"#include "dbus-common.h"#include "dbus-service.h"#include "dbus-database.h"#include "dbus-hci.h"struct hcid_opts hcid;struct device_opts default_device;struct device_opts *parser_device;static struct device_list *device_list = NULL;static int child_pipe[2];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 (get_device_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);		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)))		device_opts->discovto = HCID_DEFAULT_DISCOVERABLE_TIMEOUT;	/* Set scan mode */	if (read_device_mode(&di.bdaddr, mode, sizeof(mode)) == 0) {		if (!strcmp(mode, "off") && hcid.offmode == HCID_OFFMODE_NOSCAN) {			device_opts->mode = MODE_OFF;			device_opts->scan = SCAN_DISABLED;		} else if (!strcmp(mode, "connectable")) {			device_opts->mode = MODE_CONNECTABLE;			device_opts->scan = SCAN_PAGE;		} else if (!strcmp(mode, "discoverable")) {			/* Set discoverable only if timeout is 0 */			if (!get_discoverable_timeout(dev_id)) {				device_opts->scan = SCAN_PAGE | SCAN_INQUIRY;				device_opts->mode = MODE_DISCOVERABLE;			} else {				device_opts->scan = SCAN_PAGE;				device_opts->mode = MODE_CONNECTABLE;			}		} else if (!strcmp(mode, "limited")) {			/* Set discoverable only if timeout is 0 */			if (!get_discoverable_timeout(dev_id)) {				device_opts->scan = SCAN_PAGE | SCAN_INQUIRY;				device_opts->mode = MODE_LIMITED;			} else {				device_opts->scan = SCAN_PAGE;				device_opts->mode = MODE_CONNECTABLE;			}		}	}	/* Do configuration in the separate process */	switch (fork()) {		case 0:			atexit(at_child_exit);			break;		case -1:			error("Fork failed. Can't init device hci%d: %s (%d)",						dev_id, strerror(errno), errno);		default:			return;	}	dd = hci_open_dev(dev_id);	if (dd < 0) {		error("Can't open device hci%d: %s (%d)",						dev_id, strerror(errno), errno);		exit(1);	}	memset(&dr, 0, sizeof(dr));	dr.dev_id = dev_id;	/* Set packet type */	if ((device_opts->flags & (1 << HCID_SET_PTYPE))) {		dr.dev_opt = device_opts->pkt_type;		if (ioctl(dd, HCISETPTYPE, (unsigned long) &dr) < 0) {			error("Can't set packet type on hci%d: %s (%d)",					dev_id, strerror(errno), errno);		}	}	/* Set link mode */	if ((device_opts->flags & (1 << HCID_SET_LM))) {		dr.dev_opt = device_opts->link_mode;		if (ioctl(dd, HCISETLINKMODE, (unsigned long) &dr) < 0) {			error("Can't set link mode on hci%d: %s (%d)",					dev_id, strerror(errno), errno);		}	}	/* Set link policy */	if ((device_opts->flags & (1 << HCID_SET_LP))) {		dr.dev_opt = device_opts->link_policy;		if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0) {			error("Can't set link policy on hci%d: %s (%d)",

⌨️ 快捷键说明

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