亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? manager.c

字號:
/* * *  BlueZ - Bluetooth protocol stack for Linux * *  Copyright (C) 2006-2007  Nokia Corporation *  Copyright (C) 2004-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 <stdlib.h>#include <stdarg.h>#include <errno.h>#include <unistd.h>#include <stdint.h>#include <sys/stat.h>#include <dirent.h>#include <ctype.h>#include <signal.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <bluetooth/rfcomm.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include <glib.h>#include <dbus/dbus.h>#include "dbus-helper.h"#include "dbus.h"#include "logging.h"#include "textfile.h"#include "ipc.h"#include "device.h"#include "error.h"#include "avdtp.h"#include "a2dp.h"#include "headset.h"#include "gateway.h"#include "sink.h"#include "control.h"#include "manager.h"typedef enum {	HEADSET	= 1 << 0,	GATEWAY	= 1 << 1,	SINK	= 1 << 2,	SOURCE	= 1 << 3,	CONTROL	= 1 << 4,	TARGET	= 1 << 5,	INVALID	= 1 << 6} audio_service_type;typedef enum {		GENERIC_AUDIO = 0,		ADVANCED_AUDIO,		AV_REMOTE,		GET_RECORDS} audio_sdp_state_t;struct audio_sdp_data {	struct device *device;	DBusMessage *msg;	/* Method call or NULL */	GSList *handles;	/* uint32_t * */	GSList *records;	/* sdp_record_t * */	audio_sdp_state_t state;	create_dev_cb_t cb;	void *cb_data;};static DBusConnection *connection = NULL;static struct device *default_hs = NULL;static struct device *default_dev = NULL;static GSList *devices = NULL;static uint32_t hs_record_id = 0;static uint32_t hf_record_id = 0;static GIOChannel *hs_server = NULL;static GIOChannel *hf_server = NULL;static struct enabled_interfaces enabled = {	.headset	= TRUE,	.gateway	= FALSE,	.sink		= TRUE,	.source		= FALSE,	.control	= TRUE,};static void get_next_record(struct audio_sdp_data *data);static DBusHandlerResult get_handles(const char *uuid,					struct audio_sdp_data *data);static struct device *create_device(bdaddr_t *bda){	static int device_id = 0;	char path[128];	snprintf(path, sizeof(path) - 1,			"%s/device%d", AUDIO_MANAGER_PATH, device_id++);	return device_register(connection, path, bda);}static void destroy_device(struct device *device){	dbus_connection_destroy_object_path(connection, device->path);}static void remove_device(struct device *device){	if (device == default_dev) {		debug("Removing default device");		default_dev = NULL;	}	if (device == default_hs) {		debug("Removing default headset");		default_hs = NULL;	}	devices = g_slist_remove(devices, device);	destroy_device(device);}static gboolean add_device(struct device *device, gboolean send_signals){	if (!send_signals)		goto add;	dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,					AUDIO_MANAGER_INTERFACE,					"DeviceCreated",					DBUS_TYPE_STRING, &device->path,					DBUS_TYPE_INVALID);	if (device->headset)		dbus_connection_emit_signal(connection,				AUDIO_MANAGER_PATH,				AUDIO_MANAGER_INTERFACE,				"HeadsetCreated",				DBUS_TYPE_STRING, &device->path,				DBUS_TYPE_INVALID);add:	if (default_dev == NULL && g_slist_length(devices) == 0) {		debug("Selecting default device");		default_dev = device;	}	if (!default_hs && device->headset && !devices)		default_hs = device;	devices = g_slist_append(devices, device);	return TRUE;}static uint16_t get_service_uuid(const sdp_record_t *record){	sdp_list_t *classes;	uuid_t uuid;	uint16_t uuid16 = 0;	if (sdp_get_service_classes(record, &classes) < 0) {		error("Unable to get service classes from record");		return 0;	}	memcpy(&uuid, classes->data, sizeof(uuid));	if (!sdp_uuid128_to_uuid(&uuid)) {		error("Not a 16 bit UUID");		sdp_list_free(classes, free);		return 0;	}	if (uuid.type == SDP_UUID32) {		if (uuid.value.uuid32 > 0xFFFF) {			error("Not a 16 bit UUID");			goto done;		}		uuid16 = (uint16_t) uuid.value.uuid32;	} else		uuid16 = uuid.value.uuid16;done:	sdp_list_free(classes, free);	return uuid16;}gboolean server_is_enabled(uint16_t svc){	gboolean ret;	switch (svc) {	case HEADSET_SVCLASS_ID:		ret = (hs_server != NULL);		break;	case HANDSFREE_SVCLASS_ID:		ret = (hf_server != NULL);		break;	case AUDIO_SINK_SVCLASS_ID:		return enabled.sink;	case AV_REMOTE_TARGET_SVCLASS_ID:	case AV_REMOTE_SVCLASS_ID:		return enabled.control;	default:		ret = FALSE;		break;	}	return ret;}static void handle_record(sdp_record_t *record, struct device *device){	gboolean is_default;	uint16_t uuid16;	uuid16 = get_service_uuid(record);	if (!server_is_enabled(uuid16))		return;	switch (uuid16) {	case HEADSET_SVCLASS_ID:		debug("Found Headset record");		if (device->headset)			headset_update(device, record, uuid16);		else			device->headset = headset_init(device,							record, uuid16);		break;	case HEADSET_AGW_SVCLASS_ID:		debug("Found Headset AG record");		break;	case HANDSFREE_SVCLASS_ID:		debug("Found Hansfree record");		if (device->headset)			headset_update(device, record, uuid16);		else			device->headset = headset_init(device,							record, uuid16);		break;	case HANDSFREE_AGW_SVCLASS_ID:		debug("Found Handsfree AG record");		break;	case AUDIO_SINK_SVCLASS_ID:		debug("Found Audio Sink");		if (device->sink == NULL)			device->sink = sink_init(device);		break;	case AUDIO_SOURCE_SVCLASS_ID:		debug("Found Audio Source");		break;	case AV_REMOTE_SVCLASS_ID:		debug("Found AV Remote");		if (device->control == NULL)			device->control = control_init(device);		if (device->sink && sink_is_active(device))			avrcp_connect(device);		break;	case AV_REMOTE_TARGET_SVCLASS_ID:		debug("Found AV Target");		if (device->control == NULL)			device->control = control_init(device);		if (device->sink && sink_is_active(device))			avrcp_connect(device);		break;	default:		debug("Unrecognized UUID: 0x%04X", uuid16);		break;	}	is_default = (default_dev == device) ? TRUE : FALSE;	device_store(device, is_default);}static void finish_sdp(struct audio_sdp_data *data, gboolean success){	const char *addr;	DBusMessage *reply = NULL;	DBusError derr;	debug("Audio service discovery completed with %s",			success ? "success" : "failure");	device_finish_sdp_transaction(data->device);	if (!success)		goto done;	if (!data->msg)		goto update;	dbus_error_init(&derr);	dbus_message_get_args(data->msg, &derr,				DBUS_TYPE_STRING, &addr,				DBUS_TYPE_INVALID);	if (dbus_error_is_set(&derr)) {		error("Unable to get message args");		success = FALSE;		error_failed(connection, data->msg, derr.message);		dbus_error_free(&derr);		goto done;	}	/* Return error if no audio related service records were found */	if (!data->records) {		debug("No audio audio related service records were found");		success = FALSE;		error_not_supported(connection, data->msg);		goto done;	}	reply = dbus_message_new_method_return(data->msg);	if (!reply) {		success = FALSE;		error_failed(connection, data->msg, "Out of memory");		goto done;	}update:	g_slist_foreach(data->records, (GFunc) handle_record, data->device);	if (!g_slist_find(devices, data->device))		add_device(data->device, TRUE);	if (reply) {		dbus_message_append_args(reply, DBUS_TYPE_STRING,					&data->device->path,					DBUS_TYPE_INVALID);		send_message_and_unref(connection, reply);	}done:	if (success) {		if (data->cb)			data->cb(data->device, data->cb_data);	} else {		if (data->cb)			data->cb(NULL, data->cb_data);		if (!g_slist_find(devices, data->device))			destroy_device(data->device);	}	if (data->msg)		dbus_message_unref(data->msg);	g_slist_foreach(data->handles, (GFunc) g_free, NULL);	g_slist_free(data->handles);	g_slist_foreach(data->records, (GFunc) sdp_record_free, NULL);	g_slist_free(data->records);	g_free(data);}static void get_record_reply(DBusPendingCall *call,				struct audio_sdp_data *data){	DBusMessage *reply;	DBusError derr;	uint8_t *array;	int array_len, record_len;	sdp_record_t *record;	reply = dbus_pending_call_steal_reply(call);	dbus_error_init(&derr);	if (dbus_set_error_from_message(&derr, reply)) {		/* FIXME : forward error message as is */		error("GetRemoteServiceRecord failed: %s", derr.message);		if (dbus_error_has_name(&derr,					"org.bluez.Error.ConnectionAttemptFailed"))			error_connection_attempt_failed(connection, data->msg,				EHOSTDOWN);		else			error_failed(connection, data->msg, derr.message);		dbus_error_free(&derr);		goto failed;	}	if (!dbus_message_get_args(reply, NULL,				DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &array, &array_len,				DBUS_TYPE_INVALID)) {		error_failed(connection, data->msg,				"Unable to get args from GetRecordReply");		goto failed;	}	record = sdp_extract_pdu(array, &record_len);	if (!record) {		error("Unable to extract service record from reply");		goto done;	}	if (record_len != array_len)		debug("warning: array len (%d) != record len (%d)",				array_len, record_len);	data->records = g_slist_append(data->records, record);done:	dbus_message_unref(reply);	if (data->handles)		get_next_record(data);	else		finish_sdp(data, TRUE);	return;failed:	if (reply)		dbus_message_unref(reply);	finish_sdp(data, FALSE);}static void get_next_record(struct audio_sdp_data *data){	DBusMessage *msg;	DBusPendingCall *pending;	char address[18], *ptr = address;	dbus_uint32_t *handle;	msg = dbus_message_new_method_call("org.bluez",						data->device->adapter_path,						"org.bluez.Adapter",						"GetRemoteServiceRecord");	if (!msg) {		error("Unable to allocate new method call");		error_out_of_memory(connection, data->msg);		finish_sdp(data, FALSE);		return;	}	handle = data->handles->data;	data->handles = g_slist_remove(data->handles, data->handles->data);	ba2str(&data->device->dst, address);	dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr,					DBUS_TYPE_UINT32, handle,					DBUS_TYPE_INVALID);	g_free(handle);	if (!dbus_connection_send_with_reply(connection, msg, &pending, -1)) {		error("Sending GetRemoteServiceRecord failed");		error_connection_attempt_failed(connection, data->msg, EIO);		finish_sdp(data, FALSE);		return;	}	dbus_pending_call_set_notify(pending,			(DBusPendingCallNotifyFunction) get_record_reply,			data, NULL);	dbus_pending_call_unref(pending);	dbus_message_unref(msg);}static GSList *find_handle(GSList *handles, dbus_uint32_t handle){	while (handles) {		if (*(dbus_uint32_t *) handles->data == handle)			return handles;		handles = handles->next;	}	return NULL;}static void get_handles_reply(DBusPendingCall *call,				struct audio_sdp_data *data){	DBusMessage *reply;	DBusError derr;	dbus_uint32_t *array = NULL;	int array_len, i;	reply = dbus_pending_call_steal_reply(call);	dbus_error_init(&derr);	if (dbus_set_error_from_message(&derr, reply)) {		/* FIXME : forward error message as is */		error("GetRemoteServiceHandles failed: %s", derr.message);		if (dbus_error_has_name(&derr,					"org.bluez.Error.ConnectionAttemptFailed"))			error_connection_attempt_failed(connection, data->msg,							EHOSTDOWN);		else			error_failed(connection, data->msg, derr.message);		dbus_error_free(&derr);		goto failed;	}	if (!dbus_message_get_args(reply, NULL,				DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,				&array, &array_len,				DBUS_TYPE_INVALID)) {		error_failed(connection, data->msg,				"Unable to get args from reply");		goto failed;	}	for (i = 0; i < array_len; i++) {		if (!find_handle(data->handles, array[i])) {			dbus_uint32_t *handle = g_new(dbus_uint32_t, 1);			*handle = array[i];			data->handles = g_slist_append(data->handles, handle);		}	}	data->state++;	switch (data->state) {	case ADVANCED_AUDIO:		get_handles(ADVANCED_AUDIO_UUID, data);		break;	case AV_REMOTE:		get_handles(AVRCP_REMOTE_UUID, data);		break;	default:		if (data->handles)			get_next_record(data);		else			finish_sdp(data, TRUE);	}	dbus_message_unref(reply);	return;failed:	dbus_message_unref(reply);	finish_sdp(data, FALSE);}static DBusHandlerResult get_handles(const char *uuid,					struct audio_sdp_data *data){	DBusPendingCall *pending;	char address[18];	const char *ptr = address;	DBusMessage *msg;	msg = dbus_message_new_method_call("org.bluez",						data->device->adapter_path,						"org.bluez.Adapter",						"GetRemoteServiceHandles");	if (!msg) {		error_failed(connection, data->msg,				"Could not create a new dbus message");		goto failed;	}	ba2str(&data->device->dst, address);	dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr,					DBUS_TYPE_STRING, &uuid,					DBUS_TYPE_INVALID);	if (!dbus_connection_send_with_reply(connection, msg, &pending, -1)) {		error_failed(connection, data->msg,				"Sending GetRemoteServiceHandles failed");		goto failed;	}	dbus_pending_call_set_notify(pending,			(DBusPendingCallNotifyFunction) get_handles_reply,			data, NULL);	dbus_pending_call_unref(pending);	dbus_message_unref(msg);	return DBUS_HANDLER_RESULT_HANDLED;failed:	if (msg)		dbus_message_unref(msg);	finish_sdp(data, FALSE);	return DBUS_HANDLER_RESULT_HANDLED;}static DBusHandlerResult resolve_services(DBusMessage *msg,						struct device *device,						create_dev_cb_t cb,						void *user_data){	struct audio_sdp_data *sdp_data;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
中文字幕一区二区三区蜜月| 亚洲免费视频成人| 91精品国产91热久久久做人人| www.欧美日韩| 成人黄色一级视频| 国产真实乱偷精品视频免| 日韩高清一区二区| 婷婷开心激情综合| 亚洲成年人影院| 精油按摩中文字幕久久| 青椒成人免费视频| 日韩电影在线观看电影| 日韩福利电影在线| 日产欧产美韩系列久久99| 视频一区二区中文字幕| 日韩精品一二三区| 麻豆成人久久精品二区三区红| 丝瓜av网站精品一区二区| 人人爽香蕉精品| 麻豆精品在线播放| 国产ts人妖一区二区| 成人爽a毛片一区二区免费| 成人激情av网| 欧美私模裸体表演在线观看| 欧美一级xxx| 久久理论电影网| 亚洲欧美在线视频观看| 亚洲国产日韩综合久久精品| 五月婷婷综合网| 93久久精品日日躁夜夜躁欧美| av资源站一区| 欧美日韩视频在线观看一区二区三区| 欧美日本国产一区| 欧美精品一区二区三| 亚洲日本在线a| 日本不卡一区二区三区| 国产高清亚洲一区| 激情综合色综合久久综合| 亚洲一二三四区不卡| 日韩激情一二三区| 美女性感视频久久| 色偷偷一区二区三区| 欧美一区二区三区四区五区| 国产欧美一区二区精品婷婷| 亚洲综合久久久| 国产精品一区二区三区网站| 欧美日韩www| 国产精品欧美极品| 麻豆精品一二三| 色综合色狠狠综合色| 久久麻豆一区二区| 舔着乳尖日韩一区| 成人激情动漫在线观看| 精品国产成人系列| 日韩av一区二| 欧美精品第1页| 一区二区三区日韩| 精品三级av在线| 午夜欧美电影在线观看| 一本色道a无线码一区v| 欧美国产禁国产网站cc| 国产一区二区三区最好精华液| 欧美精品自拍偷拍动漫精品| 亚洲精品视频在线观看免费| 成人精品在线视频观看| 久久欧美一区二区| 国产精品1区2区| 久久精品一区二区| 成人听书哪个软件好| 日本一区二区三区高清不卡| 懂色av一区二区三区免费看| 国产婷婷色一区二区三区| 狠狠色丁香婷婷综合| 久久久电影一区二区三区| 韩国三级中文字幕hd久久精品| 日韩欧美中文字幕制服| 国产麻豆一精品一av一免费 | 粉嫩av亚洲一区二区图片| 国产欧美综合在线| 欧美日韩精品一区二区天天拍小说 | 欧美在线观看一区| 久久精品免费看| 欧美激情中文字幕| 欧美性色欧美a在线播放| 日韩精品电影在线观看| 久久久久久久综合| 91亚洲精品久久久蜜桃网站| 亚洲国产中文字幕在线视频综合| 欧美精品久久一区| 国产精品亚洲专一区二区三区| 亚洲视频你懂的| 日韩一区二区三区在线视频| 高清不卡一二三区| 午夜久久久久久久久久一区二区| 久久奇米777| 欧美日韩免费一区二区三区 | 91精品综合久久久久久| a在线播放不卡| 亚洲第一会所有码转帖| 欧美精品1区2区3区| 国产99精品在线观看| 久久国产精品色| 天天综合天天做天天综合| 国产精品美女久久久久久久网站| 在线播放91灌醉迷j高跟美女 | 一本大道久久a久久精品综合| 老司机精品视频线观看86| 免费观看在线综合| 亚洲午夜电影网| 亚洲男同1069视频| 亚洲色欲色欲www在线观看| 久久综合色播五月| 717成人午夜免费福利电影| 色婷婷久久综合| 波多野结衣视频一区| 国产jizzjizz一区二区| 国产大陆亚洲精品国产| 国产一区二区三区综合| 久久不见久久见免费视频7| 免费成人性网站| 蜜桃久久久久久久| 极品少妇xxxx偷拍精品少妇| 六月丁香婷婷色狠狠久久| 免费观看成人av| 国产一区久久久| 成人av电影观看| 97精品国产97久久久久久久久久久久| 99精品国产热久久91蜜凸| 91免费视频观看| 欧美偷拍一区二区| 日韩欧美成人激情| 国产精品免费av| 亚洲亚洲精品在线观看| 久久国产精品露脸对白| 成人自拍视频在线观看| 色婷婷久久综合| 日韩三级精品电影久久久| 日本一区二区久久| 午夜影视日本亚洲欧洲精品| 国产一区二区视频在线播放| 99热这里都是精品| 欧美成人伊人久久综合网| 中文字幕亚洲一区二区av在线| 亚洲一区日韩精品中文字幕| 麻豆精品一区二区三区| 99久久国产综合精品麻豆| 7799精品视频| 国产精品成人免费在线| 九九**精品视频免费播放| 91福利精品视频| 久久久精品免费免费| 亚洲va欧美va人人爽午夜| 欧美性生活久久| 国产精品久久久久久亚洲伦| 美洲天堂一区二卡三卡四卡视频| 色欧美片视频在线观看在线视频| 日韩一级在线观看| 午夜欧美电影在线观看| 91丨porny丨最新| 国产精品色眯眯| 国产成人综合视频| 久久免费的精品国产v∧| 三级欧美韩日大片在线看| 国产精品免费看片| 国产精品性做久久久久久| 欧美大白屁股肥臀xxxxxx| 亚洲成av人片一区二区三区 | 色偷偷一区二区三区| 亚洲视频在线一区二区| 99视频一区二区| 亚洲欧美日韩一区二区 | 亚洲综合成人在线| 日本韩国精品在线| 亚洲国产毛片aaaaa无费看| 在线免费观看日韩欧美| 韩国一区二区三区| 久久色在线观看| 国产成a人无v码亚洲福利| 国产精品九色蝌蚪自拍| a级高清视频欧美日韩| 亚洲欧美日韩电影| 欧美浪妇xxxx高跟鞋交| 日韩电影免费一区| 国产亚洲欧洲一区高清在线观看| 国产福利电影一区二区三区| 国产精品电影一区二区三区| 欧洲一区在线观看| 免费不卡在线观看| 亚洲视频一区二区免费在线观看| 欧美午夜片在线看| 国内精品视频一区二区三区八戒| 久久久一区二区三区捆绑**| 成人动漫精品一区二区| 亚洲国产精品一区二区久久恐怖片| 欧美丰满少妇xxxbbb| 国产91对白在线观看九色| 亚洲午夜精品一区二区三区他趣| 91精品国产麻豆| 91精品国产全国免费观看| 成人爱爱电影网址|