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

📄 main.c

📁 这是Linux环境下的蓝牙源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2003-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/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include <gdbus.h>#include "cups.h"#include "sdp-xml.h"extern int sdp_search_spp(sdp_session_t *sdp, uint8_t *channel);extern int sdp_search_hcrp(sdp_session_t *sdp, unsigned short *ctrl_psm, unsigned short *data_psm);extern int spp_print(bdaddr_t *src, bdaddr_t *dst, uint8_t channel, int fd, int copies, const char *cups_class);extern int hcrp_print(bdaddr_t *src, bdaddr_t *dst, unsigned short ctrl_psm, unsigned short data_psm, int fd, int copies, const char *cups_class);#define PRINTER_SERVICE_CLASS_NAME "printer"struct cups_device {	char *bdaddr;	char *name;	char *id;};static GSList *device_list = NULL;static GMainLoop *loop = NULL;static DBusConnection *conn = NULL;#define ATTRID_1284ID 0x0300static char *parse_xml_sdp(const char *xml){	sdp_record_t *sdp_record;	sdp_list_t *l;	char *str = NULL;	sdp_record = sdp_xml_parse_record(xml, strlen(xml));	if (sdp_record == NULL)		return NULL;	for (l = sdp_record->attrlist; l != NULL; l = l->next) {		sdp_data_t *data;		data = (sdp_data_t *) l->data;		if (data->attrId != ATTRID_1284ID)			continue;		/* Ignore the length, it's null terminated */		str = g_strdup(data->val.str + 2);		break;	}	sdp_record_free(sdp_record);	return str;}static char *device_get_ieee1284_id(const char *adapter, const char *bdaddr){	guint service_handle;	DBusMessage *message, *reply;	DBusMessageIter iter, reply_iter, iter_array;	const char *hcr_print = "00001126-0000-1000-8000-00805f9b34fb";	char *xml, *id;	/* Look for the service handle of the HCRP service */	message = dbus_message_new_method_call("org.bluez", adapter,						"org.bluez.Adapter",						"GetRemoteServiceHandles");	dbus_message_iter_init_append(message, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &hcr_print);	reply = dbus_connection_send_with_reply_and_block(conn,							message, -1, NULL);	dbus_message_unref(message);	if (!reply)		return NULL;	dbus_message_iter_init(reply, &reply_iter);	if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) {		dbus_message_unref(reply);		return NULL;	}	/* Hopefully we only get one handle, or take a punt */	dbus_message_iter_recurse(&reply_iter, &iter_array);	while (dbus_message_iter_get_arg_type(&iter_array) == DBUS_TYPE_UINT32) {		dbus_message_iter_get_basic(&iter_array, &service_handle);		dbus_message_iter_next(&iter_array);	}	dbus_message_unref(reply);	/* Now get the XML for the HCRP service record */	message = dbus_message_new_method_call("org.bluez", adapter,						"org.bluez.Adapter",						"GetRemoteServiceRecordAsXML");	dbus_message_iter_init_append(message, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &service_handle);	reply = dbus_connection_send_with_reply_and_block(conn,							message, -1, NULL);	dbus_message_unref(message);	if (!reply)		return NULL;	dbus_message_iter_init(reply, &reply_iter);	dbus_message_iter_get_basic(&reply_iter, &xml);	id = parse_xml_sdp(xml);	dbus_message_unref(reply);	return id;}static void add_device_to_list(const char *name, const char *bdaddr, const char *id){	struct cups_device *device;	GSList *l;	/* Look for the device in the list */	for (l = device_list; l != NULL; l = l->next) {		device = (struct cups_device *) l->data;		if (strcmp(device->bdaddr, bdaddr) == 0) {			g_free(device->name);			device->name = g_strdup(name);			return;		}	}	/* Or add it to the list if it's not there */	device = g_new0(struct cups_device, 1);	device->bdaddr = g_strdup(bdaddr);	device->name = g_strdup(name);	device->id = g_strdup(id);	device_list = g_slist_prepend(device_list, device);}static char *escape_name(const char *str, char orig, char dest){	char *ret, *s;	ret = g_strdup(str);	while ((s = strchr(ret, orig)) != NULL)		s[0] = dest;	return ret;}static void print_printer_details(const char *name, const char *bdaddr, const char *id){	char *uri, *escaped;	guint len;	escaped = escape_name(name, '\"', '\'');	len = strlen("bluetooth://") + 12 + 1;	uri = g_malloc(len);	snprintf(uri, len, "bluetooth://%c%c%c%c%c%c%c%c%c%c%c%c",		 bdaddr[0], bdaddr[1],		 bdaddr[3], bdaddr[4],		 bdaddr[6], bdaddr[7],		 bdaddr[9], bdaddr[10],		 bdaddr[12], bdaddr[13],		 bdaddr[15], bdaddr[16]);	printf("network %s \"Unknown\" \"%s (Bluetooth)\"", uri, escaped);	if (id != NULL)		printf(" \"%s\"\n", id);	else		printf ("\n");	g_free(escaped);	g_free(uri);}static gboolean device_is_printer(const char *adapter, const char *bdaddr){	char *class;	DBusMessage *message, *reply;	DBusMessageIter iter, reply_iter;	message = dbus_message_new_method_call("org.bluez", adapter,					       "org.bluez.Adapter",					       "GetRemoteMinorClass");	dbus_message_iter_init_append(message, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);	reply = dbus_connection_send_with_reply_and_block(conn,							message, -1, NULL);	dbus_message_unref(message);	if (!reply)		return FALSE;	dbus_message_iter_init(reply, &reply_iter);	dbus_message_iter_get_basic(&reply_iter, &class);	if (class != NULL && strcmp(class, PRINTER_SERVICE_CLASS_NAME) == 0) {		dbus_message_unref(reply);		return TRUE;	}	return FALSE;}static char *device_get_name(const char *adapter, const char *bdaddr){	DBusMessage *message, *reply;	DBusMessageIter iter, reply_iter;	char *name;	message = dbus_message_new_method_call("org.bluez", adapter,						"org.bluez.Adapter",						"GetRemoteName");	dbus_message_iter_init_append(message, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &bdaddr);	reply = dbus_connection_send_with_reply_and_block(conn,							message, -1, NULL);	dbus_message_unref(message);	if (!reply)		return NULL;	dbus_message_iter_init(reply, &reply_iter);	dbus_message_iter_get_basic(&reply_iter, &name);	name = g_strdup(name);	dbus_message_unref(reply);	return name;}static void remote_device_found(const char *adapter, const char *bdaddr, guint class, int rssi){	uint8_t major_index = (class >> 8) & 0x1F;	uint8_t minor_index;	uint8_t shift_minor = 0;	gboolean found = FALSE;	char *name, *id;	/* Check if we have a printer	 * From hcid/dbus-adapter.c minor_class_str() */	if (major_index != 6)		return;	minor_index = (class >> 4) & 0x0F;	while (shift_minor < 4) {		if (((minor_index >> shift_minor) & 0x01) == 0x01) {			if (shift_minor == 3) {				found = TRUE;				break;			}		}		shift_minor++;	}	if (!found)		return;	name = device_get_name(adapter, bdaddr);	id = device_get_ieee1284_id(adapter, bdaddr);	add_device_to_list(name, bdaddr, id);	g_free(name);	g_free(id);}static void remote_name_updated(const char *bdaddr, const char *name){	add_device_to_list(name, bdaddr, NULL);}static void discovery_completed(void){	GSList *l;	for (l = device_list; l != NULL; l = l->next) {		struct cups_device *device = (struct cups_device *) l->data;		if (device->name == NULL)			device->name = escape_name(device->bdaddr, ':', '-');		print_printer_details(device->name, device->bdaddr, device->id);		g_free(device->name);		g_free(device->bdaddr);		g_free(device->id);		g_free(device);	}	g_slist_free(device_list);	device_list = NULL;	g_main_loop_quit(loop);}static void remote_device_disappeared(const char *bdaddr){	GSList *l;	for (l = device_list; l != NULL; l = l->next) {		struct cups_device *device = (struct cups_device *) l->data;		if (strcmp(device->bdaddr, bdaddr) == 0) {			g_free(device->name);			g_free(device->bdaddr);			g_free(device);			device_list = g_slist_delete_link(device_list, l);			return;		}	}}static gboolean list_known_printers(const char *adapter){	DBusMessageIter reply_iter, iter_array;	DBusError error;	DBusMessage *message, *reply;

⌨️ 快捷键说明

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