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

📄 dbus.c

📁 bluetooth 开发应用bluez-utils-2.23
💻 C
📖 第 1 页 / 共 5 页
字号:
	char path[MAX_PATH_LENGTH];	char *pptr = path;	gboolean ret;	DBusMessage *message = NULL;	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);	message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE,							BLUEZ_MGR_DEV_ADDED);	if (message == NULL) {		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");		goto failed;	}	dbus_message_append_args(message,					DBUS_TYPE_STRING, &pptr,					DBUS_TYPE_INVALID);	if (!dbus_connection_send(connection, message, NULL)) {		syslog(LOG_ERR, "Can't send D-BUS added device message");		goto failed;	}	dbus_connection_flush(connection);failed:	dbus_message_unref(message);	ret = register_dbus_path(path, DEVICE_PATH_ID, id, &obj_dev_vtable, FALSE);	if (ret && default_dev < 0)		default_dev = id;	return ret;}gboolean hcid_dbus_unregister_device(uint16_t id){	gboolean ret;	DBusMessage *message = NULL;	char path[MAX_PATH_LENGTH];	char *pptr = path;	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);	message = dbus_message_new_signal(MANAGER_PATH, MANAGER_INTERFACE,							BLUEZ_MGR_DEV_REMOVED);	if (message == NULL) {		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");		goto failed;	}	dbus_message_append_args(message,					DBUS_TYPE_STRING, &pptr,					DBUS_TYPE_INVALID);	if (!dbus_connection_send(connection, message, NULL)) {		syslog(LOG_ERR, "Can't send D-BUS added device message");		goto failed;	}	dbus_connection_flush(connection);failed:	dbus_message_unref(message);	ret = unregister_device_path(path);	/* FIXME: If there are any devices left after this removal the default	 * device should be changed to one of them */	if (ret && default_dev == id)		default_dev = -1;	return ret;}gboolean hcid_dbus_dev_up(uint16_t id){	char path[MAX_PATH_LENGTH];	struct profile_obj_path_data *ptr = obj_path_table;	DBusMessage *message = NULL;	if (!connection)		return FALSE;	for (; ptr->id != INVALID_PATH_ID; ptr++) {		if (ptr->reg_func(connection, id) < 0)			goto failed;	}	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);	message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_UP);	if (message == NULL) {		syslog(LOG_ERR, "Can't allocate D-BUS remote name message");		goto failed;	}	if (dbus_connection_send(connection, message, NULL) == FALSE) {		syslog(LOG_ERR, "Can't send D-BUS added device message");		goto failed;	}	dbus_connection_flush(connection);failed:	/* if the signal can't be sent ignore the error */	dbus_message_unref(message);	return TRUE;}gboolean hcid_dbus_dev_down(uint16_t id){	char path[MAX_PATH_LENGTH];	struct profile_obj_path_data *ptr = obj_path_table;	DBusMessage *message = NULL;	if (!connection)		return FALSE;	for (; ptr->id != INVALID_PATH_ID; ptr++) {		if (ptr->unreg_func(connection, id) < 0)			syslog(LOG_ERR, "Unregistering profile id 0x%04x failed", ptr->id);	}	snprintf(path, sizeof(path), "%s/hci%d", DEVICE_PATH, id);	message = dbus_message_new_signal(path, DEVICE_INTERFACE, DEV_DOWN);	if (message == NULL) {		syslog(LOG_ERR, "Can't allocate D-BUS device removed  message");		goto failed;	}	if (dbus_connection_send(connection, message, NULL) == FALSE) {		syslog(LOG_ERR, "Can't send D-BUS removed device message");		goto failed;	}	dbus_connection_flush(connection);failed:	/* if the signal can't be sent ignore the error */	dbus_message_unref(message);	return TRUE;}/* * @brief HCI object path register function * Detailed description: function responsible for register a new hci  * D-Bus path. If necessary the default path must be registered too. * @param conn D-Bus connection * @param id hci device identification * @return (0-Success/-1 failure) */static int hci_dbus_reg_obj_path(DBusConnection *conn, uint16_t id){	char path[MAX_PATH_LENGTH];	/* register the default path*/	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);	if (!register_dbus_path(path, HCI_PATH_ID, id, &obj_dev_vtable, FALSE))		return -1;	return 0;}/* * @brief HCI object path unregister function * Detailed description: function responsible for unregister HCI D-Bus * path for a detached hci device. If necessary the default path must  * be registered too. * @param conn D-Bus connection * @param unreg_dft register the default path(0 or !0) * @param id hci device identification * @return (0-Success/-1 failure) */static int hci_dbus_unreg_obj_path(DBusConnection *conn, uint16_t id) {	char path[MAX_PATH_LENGTH];	snprintf(path, sizeof(path), "%s/hci%d/%s", DEVICE_PATH, id, BLUEZ_HCI);	if (!unregister_dbus_path(path))		return -1;	return 0;}const struct service_data *get_hci_table(void){	return device_hci_services;}/***************************************************************** * *  Section reserved to re-connection timer * *****************************************************************/static void reconnect_timer_handler(int signum){	struct hci_dev_list_req *dl = NULL;	struct hci_dev_req *dr;	int sk;	int i;	if (hcid_dbus_init() == FALSE)		return;	/* stop the timer */	sigaction(SIGALRM, NULL, NULL);	setitimer(ITIMER_REAL, NULL, NULL);	/* register the device based paths */	/* Create and bind HCI socket */	sk = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);	if (sk < 0) {		syslog(LOG_ERR, "Can't open HCI socket: %s (%d)",							strerror(errno), errno);		return;	}	dl = malloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl));	if (!dl) {		syslog(LOG_ERR, "Can't allocate memory");		goto failed;	}	dl->dev_num = HCI_MAX_DEV;	dr = dl->dev_req;	if (ioctl(sk, HCIGETDEVLIST, (void *) dl) < 0) {		syslog(LOG_INFO, "Can't get device list: %s (%d)",							strerror(errno), errno);		goto failed;	}	/* reset the default device */	default_dev = -1;	for (i = 0; i < dl->dev_num; i++, dr++) {		hcid_dbus_register_device(dr->dev_id);		if (hci_test_bit(HCI_UP, &dr->dev_opt))			hcid_dbus_dev_up(dr->dev_id);	}failed:	if (sk >= 0)		close(sk);	if (dl)		free(dl);}static void reconnect_timer_start(void){	struct sigaction sa;	struct itimerval timer;	memset (&sa, 0, sizeof (sa));	sa.sa_handler = &reconnect_timer_handler;	sigaction(SIGALRM, &sa, NULL);	/* expire after X  msec... */	timer.it_value.tv_sec = 0;	timer.it_value.tv_usec = DBUS_RECONNECT_TIMER;	/* ... and every x msec after that. */	timer.it_interval.tv_sec = 0;	timer.it_interval.tv_usec = DBUS_RECONNECT_TIMER;	setitimer(ITIMER_REAL, &timer, NULL);}/***************************************************************** *   *  Section reserved to HCI D-Bus services  *   *****************************************************************/static DBusHandlerResult hci_signal_filter (DBusConnection *conn, DBusMessage *msg, void *data){	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;	const char *iface;	const char *method;	if (!msg || !conn)		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;	if (dbus_message_get_type (msg) != DBUS_MESSAGE_TYPE_SIGNAL)		return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;	iface = dbus_message_get_interface(msg);	method = dbus_message_get_member(msg);	if ((strcmp(iface, DBUS_INTERFACE_LOCAL) == 0) &&			(strcmp(method, "Disconnected") == 0)) {		syslog(LOG_ERR, "Got disconnected from the system message bus");		dbus_connection_dispatch(conn);		dbus_connection_close(conn);		dbus_connection_unref(conn);		reconnect_timer_start();		ret = DBUS_HANDLER_RESULT_HANDLED;	} else if (strcmp(iface, DBUS_INTERFACE_DBUS) == 0) {		if (strcmp(method, "NameOwnerChanged") == 0)			ret = DBUS_HANDLER_RESULT_HANDLED;		else if (strcmp(method, "NameAcquired") == 0)			ret = DBUS_HANDLER_RESULT_HANDLED;	}	return ret;}static DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data){	const struct service_data *handlers = NULL;	DBusMessage *reply = NULL;	struct hci_dbus_data *dbus_data = data;	const char *method;	const char *signature;	const char *path;	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD;	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;	path = dbus_message_get_path(msg);	method = dbus_message_get_member(msg);	signature = dbus_message_get_signature(msg);	if (dbus_data->path_id == DEVICE_ROOT_ID) {		/* Device is down(path unregistered) or the path is wrong */		ret = DBUS_HANDLER_RESULT_HANDLED;		error = BLUEZ_EDBUS_UNKNOWN_PATH;		goto failed;	}	if (dbus_data->path_id == DEVICE_PATH_ID)		handlers = device_services;	else {		struct profile_obj_path_data *profile;		for (profile = obj_path_table; profile->id != INVALID_PATH_ID; profile++) {			if (profile->id == dbus_data->path_id) {				handlers = profile->get_svc_table();				break;			}		}	}	if (!handlers)		goto failed;	for (; handlers->name != NULL; handlers++) {		if (strcmp(handlers->name, method))			continue;		ret = DBUS_HANDLER_RESULT_HANDLED;		if (!strcmp(handlers->signature, signature)) {			reply = handlers->handler_func(msg, data);			error = 0;			break;		} else {			/* Set the error, but continue looping incase there is			 * another method with the same name but a different			 * signature */			error = BLUEZ_EDBUS_WRONG_SIGNATURE;			continue;		}	}failed:	if (error)		reply = bluez_new_failure_msg(msg, error);	if (reply) {		if (!dbus_connection_send (conn, reply, NULL))			syslog(LOG_ERR, "Can't send reply message!");		dbus_message_unref(reply);	}	return ret;}static DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data){	const struct service_data *handlers;	DBusMessage *reply = NULL;	const char *iface;	const char *method;	const char *signature;	const char *path;	uint32_t error = BLUEZ_EDBUS_UNKNOWN_METHOD;	DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;	path = dbus_message_get_path(msg);	iface = dbus_message_get_interface(msg);	method = dbus_message_get_member(msg);	signature = dbus_message_get_signature(msg);	if (strcmp(iface, MANAGER_INTERFACE) != 0)		return ret;	for (handlers = manager_services; handlers->name != NULL; handlers++) {		if (strcmp(handlers->name, method))			continue;		if (strcmp(handlers->signature, signature) != 0)			error = BLUEZ_EDBUS_WRONG_SIGNATURE;		else {			reply = handlers->handler_func(msg, data);			error = 0;		}		ret = DBUS_HANDLER_RESULT_HANDLED;	}	if (error)		reply = bluez_new_failure_msg(msg, error);	if (reply) {		if (!dbus_connection_send (conn, reply, NULL))			syslog(LOG_ERR, "Can't send reply message!");		dbus_message_unref(reply);	}	return ret;}static DBusMessage* handle_periodic_inq_req(DBusMessage *msg, void *data){	periodic_inquiry_cp inq_param;	struct hci_request rq;	uint8_t status;	DBusMessage *reply = NULL;	struct hci_dbus_data *dbus_data = data;	uint8_t length, num_rsp = 0;	uint16_t max_period;	uint16_t min_period;	uint32_t lap = 0x9e8b33;	int dd = -1;	dd = hci_open_dev(dbus_data->dev_id);	if (dd < 0) {		syslog(LOG_ERR, "HCI device open failed");		reply = bluez_new_failure_msg(msg, BLUEZ_ESYSTEM_ENODEV);		goto failed;	}	if (dbus_message_has_signature(msg, HCI_PERIODIC_INQ_EXT_SIGNATURE))		dbus_message_get_args(msg, NULL,						DBUS_TYPE_BYTE, &length,						DBUS_TYPE_UINT16, &min_period,						DBUS_TYPE_UINT16, &max_period,						DBUS_TYPE_UINT32, &lap,						DBUS_TYPE_INVALID);	else		dbus_message_get_args(msg, NULL,						DBUS_TYPE_BYTE, &length,						DBUS_TYPE_UINT16, &min_period,						DBUS_TYPE_UINT16, &max_period,						DBUS_TYPE_INVALID);

⌨️ 快捷键说明

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