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

📄 dbus.c

📁 蓝牙bluez-utils-2.25.tar.gz网上很少找到这个版本的了
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2004-2006  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 <signal.h>#include <string.h>#include <syslog.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/time.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <dbus/dbus.h>#include "glib-ectomy.h"#include "hcid.h"#include "dbus.h"#ifndef DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT#define DBUS_NAME_FLAG_PROHIBIT_REPLACEMENT	0x00#endifstatic DBusConnection *connection;static int default_dev = -1;#define TIMEOUT				(30 * 1000)		/* 30 seconds */#define DBUS_RECONNECT_TIMER		(5 * 1000 * 1000)	/* 5 sec */#define MAX_PATH_LENGTH			64#define MAX_CONN_NUMBER			10#define PINAGENT_SERVICE_NAME BASE_INTERFACE ".PinAgent"#define PINAGENT_INTERFACE PINAGENT_SERVICE_NAME#define PIN_REQUEST "PinRequest"#define PINAGENT_PATH BASE_PATH "/PinAgent"struct pin_request {	int dev;	bdaddr_t bda;};typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *);struct service_data {	const char		*name;	service_handler_func_t	*handler_func;	const char		*signature;};struct hci_dbus_data {	uint16_t dev_id;	uint16_t path_id;	uint32_t path_data;};typedef int register_function_t(DBusConnection *conn, uint16_t id);typedef int unregister_function_t(DBusConnection *conn, uint16_t id);const struct service_data *get_hci_table(void);static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id);static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id);typedef const struct service_data *get_svc_table_func_t(void);struct profile_obj_path_data {	uint16_t		id;	register_function_t	*reg_func;	unregister_function_t	*unreg_func;	get_svc_table_func_t	*get_svc_table;	/* return the service table */};/* * D-Bus error messages functions and declarations. * This section should be moved to a common file  * in the future * */typedef struct  {	uint32_t code;	const char *str;} bluez_error_t;typedef struct {	char *str;	unsigned int val;} hci_map;static hci_map dev_flags_map[] = {	{ "INIT",	HCI_INIT	},	{ "RUNNING",	HCI_RUNNING	},	{ "RAW",	HCI_RAW		},	{ "PSCAN",	HCI_PSCAN	},	{ "ISCAN",	HCI_ISCAN	},	{ "INQUIRY",	HCI_INQUIRY	},	{ "AUTH",	HCI_AUTH	},	{ "ENCRYPT",	HCI_ENCRYPT	},	{ "SECMGR",	HCI_SECMGR	},	{ NULL }};static const bluez_error_t dbus_error_array[] = {	{ BLUEZ_EDBUS_UNKNOWN_METHOD,	"Method not found"		},	{ BLUEZ_EDBUS_WRONG_SIGNATURE,	"Wrong method signature"	},	{ BLUEZ_EDBUS_WRONG_PARAM,	"Invalid parameters"		},	{ BLUEZ_EDBUS_RECORD_NOT_FOUND,	"No record found"		},	{ BLUEZ_EDBUS_NO_MEM,		"No memory"			},	{ BLUEZ_EDBUS_CONN_NOT_FOUND,	"Connection not found"		},	{ BLUEZ_EDBUS_UNKNOWN_PATH,	"Unknown D-BUS path"		},	{ BLUEZ_EDBUS_NOT_IMPLEMENTED,	"Method not implemented"	},	{ 0, NULL }};static const bluez_error_t hci_error_array[] = {	{ HCI_UNKNOWN_COMMAND,			"Unknown HCI Command"						},	{ HCI_NO_CONNECTION,			"Unknown Connection Identifier"					},	{ HCI_HARDWARE_FAILURE,			"Hardware Failure"						},	{ HCI_PAGE_TIMEOUT,			"Page Timeout"							},	{ HCI_AUTHENTICATION_FAILURE,		"Authentication Failure"					},	{ HCI_PIN_OR_KEY_MISSING,		"PIN Missing"							},	{ HCI_MEMORY_FULL,			"Memory Capacity Exceeded"					},	{ HCI_CONNECTION_TIMEOUT,		"Connection Timeout"						},	{ HCI_MAX_NUMBER_OF_CONNECTIONS,	"Connection Limit Exceeded"					},	{ HCI_MAX_NUMBER_OF_SCO_CONNECTIONS,	"Synchronous Connection Limit To A Device Exceeded"		},	{ HCI_ACL_CONNECTION_EXISTS,		"ACL Connection Already Exists"					},	{ HCI_COMMAND_DISALLOWED,		"Command Disallowed"						},	{ HCI_REJECTED_LIMITED_RESOURCES,	"Connection Rejected due to Limited Resources"			},	{ HCI_REJECTED_SECURITY,		"Connection Rejected Due To Security Reasons"			},	{ HCI_REJECTED_PERSONAL,		"Connection Rejected due to Unacceptable BD_ADDR"		},	{ HCI_HOST_TIMEOUT,			"Connection Accept Timeout Exceeded"				},	{ HCI_UNSUPPORTED_FEATURE,		"Unsupported Feature or Parameter Value"			},	{ HCI_INVALID_PARAMETERS,		"Invalid HCI Command Parameters"				},	{ HCI_OE_USER_ENDED_CONNECTION,		"Remote User Terminated Connection"				},	{ HCI_OE_LOW_RESOURCES,			"Remote Device Terminated Connection due to Low Resources"	},	{ HCI_OE_POWER_OFF,			"Remote Device Terminated Connection due to Power Off"		},	{ HCI_CONNECTION_TERMINATED,		"Connection Terminated By Local Host"				},	{ HCI_REPEATED_ATTEMPTS,		"Repeated Attempts"						},	{ HCI_PAIRING_NOT_ALLOWED,		"Pairing Not Allowed"						},	{ HCI_UNKNOWN_LMP_PDU,			"Unknown LMP PDU"						},	{ HCI_UNSUPPORTED_REMOTE_FEATURE,	"Unsupported Remote Feature"					},	{ HCI_SCO_OFFSET_REJECTED,		"SCO Offset Rejected"						},	{ HCI_SCO_INTERVAL_REJECTED,		"SCO Interval Rejected"						},	{ HCI_AIR_MODE_REJECTED,		"SCO Air Mode Rejected"						},	{ HCI_INVALID_LMP_PARAMETERS,		"Invalid LMP Parameters"					},	{ HCI_UNSPECIFIED_ERROR,		"Unspecified Error"						},	{ HCI_UNSUPPORTED_LMP_PARAMETER_VALUE,	"Unsupported LMP Parameter Value"				},	{ HCI_ROLE_CHANGE_NOT_ALLOWED,		"Role Change Not Allowed"					},	{ HCI_LMP_RESPONSE_TIMEOUT,		"LMP Response Timeout"						},	{ HCI_LMP_ERROR_TRANSACTION_COLLISION,	"LMP Error Transaction Collision"				},	{ HCI_LMP_PDU_NOT_ALLOWED,		"LMP PDU Not Allowed"						},	{ HCI_ENCRYPTION_MODE_NOT_ACCEPTED,	"Encryption Mode Not Acceptable"				},	{ HCI_UNIT_LINK_KEY_USED,		"Link Key Can Not be Changed"					},	{ HCI_QOS_NOT_SUPPORTED,		"Requested QoS Not Supported"					},	{ HCI_INSTANT_PASSED,			"Instant Passed"						},	{ HCI_PAIRING_NOT_SUPPORTED,		"Pairing With Unit Key Not Supported"				},	{ HCI_TRANSACTION_COLLISION,		"Different Transaction Collision"				},	{ HCI_QOS_UNACCEPTABLE_PARAMETER,	"QoS Unacceptable Parameter"					},	{ HCI_QOS_REJECTED,			"QoS Rejected"							},	{ HCI_CLASSIFICATION_NOT_SUPPORTED,	"Channel Classification Not Supported"				},	{ HCI_INSUFFICIENT_SECURITY,		"Insufficient Security"						},	{ HCI_PARAMETER_OUT_OF_RANGE,		"Parameter Out Of Mandatory Range"				},	{ HCI_ROLE_SWITCH_PENDING,		"Role Switch Pending"						},	{ HCI_SLOT_VIOLATION,			"Reserved Slot Violation"					},	{ HCI_ROLE_SWITCH_FAILED,		"Role Switch Failed"						},	{ 0, NULL },};static const char *bluez_dbus_error_to_str(const uint32_t ecode) {	const bluez_error_t *ptr;	uint32_t raw_code = 0;	if (ecode & BLUEZ_ESYSTEM_OFFSET) {		/* System error */		raw_code = (~BLUEZ_ESYSTEM_OFFSET) & ecode;		syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, strerror(raw_code));		return strerror(raw_code);	} else if (ecode & BLUEZ_EDBUS_OFFSET) {		/* D-Bus error */		for (ptr = dbus_error_array; ptr->code; ptr++) {			if (ptr->code == ecode) {				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str);				return ptr->str;			}		}	} else {		/* BLUEZ_EBT_OFFSET - Bluetooth HCI errors */		for (ptr = hci_error_array; ptr->code; ptr++) {			if (ptr->code == ecode) {				syslog(LOG_INFO, "%s - msg:%s", __PRETTY_FUNCTION__, ptr->str);				return ptr->str;			}		}	}	return NULL;}static DBusMessage *bluez_new_failure_msg(DBusMessage *msg, const uint32_t ecode){	DBusMessageIter iter;	DBusMessage *reply;	const char *error_msg;	error_msg = bluez_dbus_error_to_str(ecode);	if (!error_msg)		return NULL;	reply = dbus_message_new_error(msg, ERROR_INTERFACE, error_msg);	dbus_message_iter_init_append(reply, &iter);	dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32 ,&ecode);	return reply;}/* * Object path register/unregister functions  * */static struct profile_obj_path_data obj_path_table[] = {	{ HCI_PATH_ID, hci_dbus_reg_obj_path, hci_dbus_unreg_obj_path, get_hci_table },	/* add other profiles here */	{ INVALID_PATH_ID, NULL, NULL, NULL }};/* * Virtual table that handle the object path hierarchy */static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data);static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data);static DBusMessage* handle_not_implemented_req(DBusMessage *msg, void *data);static const DBusObjectPathVTable obj_dev_vtable = {	.message_function	= &msg_func_device,	.unregister_function	= NULL};static const DBusObjectPathVTable obj_mgr_vtable = {	.message_function	= &msg_func_manager,	.unregister_function	= NULL};/* * Services provided under the path DEVICE_PATH */static DBusMessage* handle_device_up_req(DBusMessage *msg, void *data);static DBusMessage* handle_device_down_req(DBusMessage *msg, void *data);static DBusMessage* handle_device_set_property_req(DBusMessage *msg, void *data);static DBusMessage* handle_device_get_property_req(DBusMessage *msg, void *data);static DBusMessage* handle_device_set_property_req_name(DBusMessage *msg, void *data);static DBusMessage* handle_device_get_property_req_name(DBusMessage *msg, void *data);static DBusMessage* handle_device_set_property_req_pscan(DBusMessage *msg, void *data);static DBusMessage* handle_device_set_property_req_iscan(DBusMessage *msg, void *data);static const struct service_data device_services[] = {	{ DEV_UP,		handle_device_up_req,		DEV_UP_SIGNATURE		},	{ DEV_DOWN,		handle_device_down_req,		DEV_DOWN_SIGNATURE		},	{ DEV_SET_PROPERTY,	handle_device_set_property_req,	DEV_SET_PROPERTY_SIGNATURE_BOOL	},	{ DEV_SET_PROPERTY,	handle_device_set_property_req,	DEV_SET_PROPERTY_SIGNATURE_STR	},	{ DEV_SET_PROPERTY,	handle_device_set_property_req,	DEV_SET_PROPERTY_SIGNATURE_BYTE	},	{ DEV_GET_PROPERTY,	handle_device_get_property_req,	DEV_GET_PROPERTY_SIGNATURE	},	{ NULL, NULL, NULL}};static const struct service_data set_property_services[] = {	{ DEV_PROPERTY_AUTH,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},	{ DEV_PROPERTY_ENCRYPT,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BOOL		},	{ DEV_PROPERTY_PSCAN,		handle_device_set_property_req_pscan,	DEV_SET_PROPERTY_SIGNATURE_BOOL		},	{ DEV_PROPERTY_ISCAN,		handle_device_set_property_req_iscan,	DEV_SET_PROPERTY_SIGNATURE_BOOL		},	{ DEV_PROPERTY_NAME,		handle_device_set_property_req_name,	DEV_SET_PROPERTY_SIGNATURE_STR		},	{ DEV_PROPERTY_INCMODE,		handle_not_implemented_req,		DEV_SET_PROPERTY_SIGNATURE_BYTE		},	{ NULL, NULL, NULL}};static const struct service_data get_property_services[] = {	{ DEV_PROPERTY_DEV_INFO,	handle_not_implemented_req,		DEV_GET_PROPERTY_SIGNATURE 	},	{ DEV_PROPERTY_NAME,		handle_device_get_property_req_name,	DEV_GET_PROPERTY_SIGNATURE 	},	{ DEV_PROPERTY_INCMODE,		handle_not_implemented_req,		DEV_GET_PROPERTY_SIGNATURE 	},	{ NULL, NULL, NULL}};/* * Services provided under the path MANAGER_PATH */static DBusMessage* handle_device_list_req(DBusMessage *msg, void *data);static DBusMessage* handle_default_device_req(DBusMessage *msg, void *data);static const struct service_data manager_services[] = {	{ MGR_DEVICE_LIST,	handle_device_list_req,		MGR_GET_DEV_SIGNATURE		},	{ MGR_DEFAULT_DEVICE,	handle_default_device_req,	MGR_DEFAULT_DEV_SIGNATURE	},	{ MGR_INIT,		handle_not_implemented_req,	NULL				},	{ MGR_ENABLE,		handle_not_implemented_req,	NULL				},	{ MGR_DISABLE,		handle_not_implemented_req,	NULL				},	{ NULL, NULL, NULL }};/* * HCI D-Bus services */static DBusHandlerResult hci_signal_filter(DBusConnection *conn, DBusMessage *msg, void *data);static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data);static DBusMessage* handle_cancel_periodic_inq_req(DBusMessage *msg, void *data);static DBusMessage* handle_inq_req(DBusMessage *msg, void *data);static DBusMessage* handle_cancel_inq_req(DBusMessage *msg, void *data);static DBusMessage* handle_role_switch_req(DBusMessage *msg, void *data);static DBusMessage* handle_remote_name_req(DBusMessage *msg, void *data);static DBusMessage* handle_display_conn_req(DBusMessage *msg, void *data);static DBusMessage* handle_auth_req(DBusMessage *msg, void *data);static const struct service_data device_hci_services[] = {	{ HCI_PERIODIC_INQ,		handle_periodic_inq_req,	HCI_PERIODIC_INQ_SIGNATURE		},	{ HCI_PERIODIC_INQ,		handle_periodic_inq_req,	HCI_PERIODIC_INQ_EXT_SIGNATURE		},	{ HCI_CANCEL_PERIODIC_INQ,	handle_cancel_periodic_inq_req,	HCI_CANCEL_PERIODIC_INQ_SIGNATURE	},	{ HCI_ROLE_SWITCH,		handle_role_switch_req,		HCI_ROLE_SWITCH_SIGNATURE		},	{ HCI_INQ,			handle_inq_req,			HCI_INQ_SIGNATURE			},	{ HCI_INQ,			handle_inq_req,			HCI_INQ_EXT_SIGNATURE			},	{ HCI_CANCEL_INQ,		handle_cancel_inq_req,		HCI_CANCEL_INQ_SIGNATURE		},	{ HCI_REMOTE_NAME,		handle_remote_name_req,		HCI_REMOTE_NAME_SIGNATURE		},	{ HCI_CONNECTIONS,		handle_display_conn_req,	HCI_CONNECTIONS_SIGNATURE		},	{ HCI_AUTHENTICATE,		handle_auth_req,		HCI_AUTHENTICATE_SIGNATURE		},	{ NULL, NULL, NULL }};static void reply_handler_function(DBusPendingCall *call, void *user_data){	struct pin_request *req = (struct pin_request *) user_data;	pin_code_reply_cp pr;	DBusMessage *message;	DBusMessageIter iter;	int arg_type;	int msg_type;	size_t len;	char *pin;	const char *error_msg;	message = dbus_pending_call_steal_reply(call);	if (!message)		goto done;	msg_type = dbus_message_get_type(message);	dbus_message_iter_init(message, &iter);	if (msg_type == DBUS_MESSAGE_TYPE_ERROR) {		dbus_message_iter_get_basic(&iter, &error_msg);		/* handling WRONG_ARGS_ERROR, DBUS_ERROR_NO_REPLY, DBUS_ERROR_SERVICE_UNKNOWN */		syslog(LOG_ERR, "%s: %s", dbus_message_get_error_name(message), error_msg);		hci_send_cmd(req->dev, OGF_LINK_CTL,					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);		goto done;	}	/* check signature */	arg_type = dbus_message_iter_get_arg_type(&iter);	if (arg_type != DBUS_TYPE_STRING) {		syslog(LOG_ERR, "Wrong reply signature: expected PIN");		hci_send_cmd(req->dev, OGF_LINK_CTL,					OCF_PIN_CODE_NEG_REPLY, 6, &req->bda);	} else {		dbus_message_iter_get_basic(&iter, &pin);		len = strlen(pin);		memset(&pr, 0, sizeof(pr));		bacpy(&pr.bdaddr, &req->bda);		memcpy(pr.pin_code, pin, len);		pr.pin_len = len;		hci_send_cmd(req->dev, OGF_LINK_CTL,			OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr);	}done:	if (message)		dbus_message_unref(message);	dbus_pending_call_unref(call);}static void free_pin_req(void *req){	free(req);}static gboolean register_dbus_path(const char *path, uint16_t path_id, uint16_t dev_id,				const DBusObjectPathVTable *pvtable, gboolean fallback){	gboolean ret = FALSE;	struct hci_dbus_data *data = NULL;	data = malloc(sizeof(struct hci_dbus_data));	if (data == NULL) {		syslog(LOG_ERR, "Failed to alloc memory to DBUS path register data (%s)", path);		goto failed;	}	data->path_id = path_id;	data->dev_id = dev_id;	if (fallback) {		if (!dbus_connection_register_fallback(connection, path, pvtable, data)) {			syslog(LOG_ERR, "DBUS failed to register %s fallback", path);			goto failed;		}	} else {		if (!dbus_connection_register_object_path(connection, path, pvtable, data)) {			syslog(LOG_ERR, "DBUS failed to register %s object", path);			goto failed;		}	}	ret = TRUE;failed:	if (!ret && data)		free(data);	return ret;}static gboolean unregister_dbus_path(const char *path){	void *data;	if (dbus_connection_get_object_path_data(connection, path, &data) && data)		free(data);	if (!dbus_connection_unregister_object_path (connection, path)) {		syslog(LOG_ERR, "DBUS failed to unregister %s object", path);		return FALSE;	}	return TRUE;}void hcid_dbus_request_pin(int dev, struct hci_conn_info *ci){	DBusMessage *message = NULL;	DBusPendingCall *pending = NULL;	struct pin_request *req;	uint8_t *addr = (uint8_t *) &ci->bdaddr;	dbus_bool_t out = ci->out;	if (!connection) {		if (!hcid_dbus_init())			goto failed;	}	message = dbus_message_new_method_call(PINAGENT_SERVICE_NAME, PINAGENT_PATH,						PINAGENT_INTERFACE, PIN_REQUEST);	if (message == NULL) {		syslog(LOG_ERR, "Couldn't allocate D-BUS message");		goto failed;	}	req = malloc(sizeof(*req));	req->dev = dev;	bacpy(&req->bda, &ci->bdaddr);

⌨️ 快捷键说明

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