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

📄 common.c

📁 Linux的蓝牙操作工具。配合bluez-lib使用
💻 C
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2004-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 <unistd.h>#include <stdlib.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/stat.h>#include <sys/wait.h>#include <net/if.h>#include <bluetooth/bluetooth.h>#include <bluetooth/l2cap.h>#include <bluetooth/bnep.h>#include <glib.h>#include "logging.h"#include "common.h"#include "textfile.h"static int ctl;static GSList *pids;#define PANU_UUID	"00001115-0000-1000-8000-00805f9b34fb"#define NAP_UUID	"00001116-0000-1000-8000-00805f9b34fb"#define GN_UUID		"00001117-0000-1000-8000-00805f9b34fb"static struct {	const char	*name;		/* Friendly name */	const char	*uuid128;	/* UUID 128 */	uint16_t	id;		/* Service class identifier */} __svc[] = {	{ "panu",	PANU_UUID,	BNEP_SVC_PANU	},	{ "gn",		GN_UUID,	BNEP_SVC_GN	},	{ "nap",	NAP_UUID,	BNEP_SVC_NAP	},	{ NULL }};static const char *panu = NULL;static const char *gn = NULL;static const char *nap = NULL;struct bnep_data {	char *devname;	char *script;	int pid;};static gint find_devname(gconstpointer a, gconstpointer b){	struct bnep_data *data = (struct bnep_data *) a;	const char *devname = b;	return strcmp(data->devname, devname);}static void script_exited(GPid pid, gint status, gpointer data){	if (WIFEXITED(status))		debug("%d exited with status %d", pid, WEXITSTATUS(status));	else		debug("%d was killed by signal %d", pid, WTERMSIG(status));	g_spawn_close_pid(pid);}uint16_t bnep_service_id(const char *svc){	int i;	uint16_t id;	/* Friendly service name */	for (i = 0; __svc[i].name; i++)		if (!strcasecmp(svc, __svc[i].name)) {			return __svc[i].id;		}	/* UUID 128 string */	for (i = 0; __svc[i].uuid128; i++)		if (!strcasecmp(svc, __svc[i].uuid128)) {			return __svc[i].id;		}	/* Try convert to HEX */	id = strtol(svc, NULL, 16);	if ((id < BNEP_SVC_PANU) || (id > BNEP_SVC_GN))		return 0;	return id;}const char *bnep_uuid(uint16_t id){	int i;	for (i = 0; __svc[i].uuid128; i++)		if (__svc[i].id == id)			return __svc[i].uuid128;	return NULL;}const char *bnep_name(uint16_t id){	int i;	for (i = 0; __svc[i].name; i++)		if (__svc[i].id == id)			return __svc[i].name;	return NULL;}int bnep_init(const char *panu_script, const char *gn_script,		const char *nap_script){	ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP);	if (ctl < 0) {		int err = errno;		error("Failed to open control socket: %s (%d)",						strerror(err), err);		return -err;	}	panu = panu_script;	gn = gn_script;	nap = nap_script;	return 0;}int bnep_cleanup(void){	close(ctl);	return 0;}int bnep_kill_connection(bdaddr_t *dst){	struct bnep_conndel_req req;	baswap((bdaddr_t *)&req.dst, dst);	req.flags = 0;	if (ioctl(ctl, BNEPCONNDEL, &req)) {		int err = errno;		error("Failed to kill connection: %s (%d)",						strerror(err), err);		return -err;	}	return 0;}int bnep_kill_all_connections(void){	struct bnep_connlist_req req;	struct bnep_conninfo ci[7];	int i, err;	memset(&req, 0, sizeof(req));	req.cnum = 7;	req.ci   = ci;	if (ioctl(ctl, BNEPGETCONNLIST, &req)) {		err = errno;		error("Failed to get connection list: %s (%d)",						strerror(err), err);		return -err;	}	for (i=0; i < req.cnum; i++) {		struct bnep_conndel_req req;		memcpy(req.dst, ci[i].dst, ETH_ALEN);		req.flags = 0;		ioctl(ctl, BNEPCONNDEL, &req);	}	return 0;}int bnep_connadd(int sk, uint16_t role, char *dev){	struct bnep_connadd_req req;	strncpy(req.device, dev, 16);	req.device[15] = '\0';	req.sock = sk;	req.role = role;	if (ioctl(ctl, BNEPCONNADD, &req) < 0) {		int err = errno;		error("Failed to add device %s: %s(%d)",				dev, strerror(err), err);		return -err;	}	strncpy(dev, req.device, 16);	return 0;}static void bnep_setup(gpointer data){}int bnep_if_up(const char *devname, uint16_t id){	int sd, err, pid;	struct ifreq ifr;	const char *argv[5];	struct bnep_data *bnep;	GSpawnFlags flags;	GSList *l;	/* Check if a script is running */	if ((l = g_slist_find_custom(pids, devname, find_devname))) {		bnep = l->data;		if (bnep->script && !strcmp(bnep->script, "avahi-autoipd")) {			argv[0] = bnep->script;			argv[1] = devname;			argv[2] = "--refresh";			argv[3] = NULL;			flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH;			g_spawn_async(NULL, (char **) argv, NULL, flags,					bnep_setup, (gpointer) devname, &pid,					NULL);		}		return bnep->pid;	}	sd = socket(AF_INET6, SOCK_DGRAM, 0);	memset(&ifr, 0, sizeof(ifr));	strcpy(ifr.ifr_name, devname);	ifr.ifr_flags |= IFF_UP;	ifr.ifr_flags |= IFF_MULTICAST;	if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) {		err = errno;		error("Could not bring up %s. %s(%d)", devname, strerror(err),			err);		return -err;	}	bnep = g_new0(struct bnep_data, 1);	bnep->devname = g_strdup(devname);	if (!id)		goto done;	if (id == BNEP_SVC_PANU)		bnep->script = g_strdup(panu);	else if (id == BNEP_SVC_GN)		bnep->script = g_strdup(gn);	else		bnep->script = g_strdup(nap);	if (!bnep->script)		goto done;	argv[0] = bnep->script;	argv[1] = devname;	if (!strcmp(bnep->script, "avahi-autoipd")) {		argv[2] = "--no-drop-root";		argv[3] = "--no-chroot";		argv[4] = NULL;	} else		argv[2] = NULL;	flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH;	if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup,				(gpointer) devname, &pid, NULL)) {		error("Unable to execute %s", argv[0]);		return -EINVAL;	}	bnep->pid = pid;	g_child_watch_add(pid, script_exited, bnep);done:	pids = g_slist_append(pids, bnep);	return bnep->pid;}int bnep_if_down(const char *devname){	int sd, err, pid;	struct ifreq ifr;	struct bnep_data *bnep;	GSList *l;	GSpawnFlags flags;	const char *argv[4];	l = g_slist_find_custom(pids, devname, find_devname);	if (!l)		return 0;	bnep = l->data;	if (!bnep->pid)		goto done;	if (bnep->script && !strcmp (bnep->script, "avahi-autoipd")) {		argv[0] = bnep->script;		argv[1] = devname;		argv[2] = "--kill";		argv[3] = NULL;		flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH;		g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup,				(gpointer) devname, &pid, NULL);		goto done;	}	/* Kill script */	err = kill(bnep->pid, SIGTERM);	if (err < 0)		error("kill(%d, SIGTERM): %s (%d)", bnep->pid,			strerror(errno), errno);done:	sd = socket(AF_INET6, SOCK_DGRAM, 0);	memset(&ifr, 0, sizeof(ifr));	strcpy(ifr.ifr_name, devname);	ifr.ifr_flags &= ~IFF_UP;	/* Bring down the interface */	if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) {		err = errno;		error("Could not bring down %d. %s(%d)", devname, strerror(err),			err);		return -err;	}	pids = g_slist_remove(pids, bnep);	if (bnep->devname)		g_free(bnep->devname);	if (bnep->script)		g_free(bnep->script);	g_free(bnep);	return 0;}int read_remote_name(bdaddr_t *src, bdaddr_t *dst, char *buf, size_t size){	char filename[PATH_MAX + 1], addr[18], *str;	ba2str(src, addr);	create_name(filename, PATH_MAX, STORAGEDIR, addr, "names");	ba2str(dst, addr);	str = textfile_get(filename, addr);	if (!str)		return -ENOENT;	snprintf(buf, size, "%s", str);	free(str);	return 0;}

⌨️ 快捷键说明

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