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

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

?? headset.c

?? 這是Linux環境下的藍牙源代碼
?? C
?? 第 1 頁 / 共 3 頁
字號:
/* * *  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 <errno.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <stdarg.h>#include <signal.h>#include <string.h>#include <getopt.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <bluetooth/bluetooth.h>#include <bluetooth/hci.h>#include <bluetooth/hci_lib.h>#include <bluetooth/sco.h>#include <bluetooth/rfcomm.h>#include <bluetooth/sdp.h>#include <bluetooth/sdp_lib.h>#include <glib.h>#include <dbus/dbus.h>#include <gdbus.h>#include "logging.h"#include "device.h"#include "manager.h"#include "error.h"#include "headset.h"#include "glib-helper.h"#define DC_TIMEOUT 3000#define RING_INTERVAL 3000#define BUF_SIZE 1024#define HEADSET_GAIN_SPEAKER 'S'#define HEADSET_GAIN_MICROPHONE 'M'#define AG_FEATURE_THREE_WAY_CALLING             0x0001#define AG_FEATURE_EC_ANDOR_NR                   0x0002#define AG_FEATURE_VOICE_RECOGNITION             0x0004#define AG_FEATURE_INBAND_RINGTONE               0x0008#define AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG     0x0010#define AG_FEATURE_REJECT_A_CALL                 0x0020#define AG_FEATURE_ENHANCES_CALL_STATUS          0x0040#define AG_FEATURE_ENHANCES_CALL_CONTROL         0x0080#define AG_FEATURE_EXTENDED_ERROR_RESULT_CODES   0x0100static uint32_t ag_features = 0;static gboolean sco_hci = TRUE;static char *str_state[] = {	"HEADSET_STATE_DISCONNECTED",	"HEADSET_STATE_CONNECT_IN_PROGRESS",	"HEADSET_STATE_CONNECTED",	"HEADSET_STATE_PLAY_IN_PROGRESS",	"HEADSET_STATE_PLAYING",};struct connect_cb {	unsigned int id;	headset_stream_cb_t cb;	void *cb_data;};struct pending_connect {	DBusMessage *msg;	DBusPendingCall *call;	GIOChannel *io;	int err;	headset_state_t target_state;	GSList *callbacks;};struct headset {	uint32_t hsp_handle;	uint32_t hfp_handle;	int rfcomm_ch;	GIOChannel *rfcomm;	GIOChannel *tmp_rfcomm;	GIOChannel *sco;	guint sco_id;	gboolean auto_dc;	guint ring_timer;	guint dc_timer;	char buf[BUF_SIZE];	int data_start;	int data_length;	gboolean hfp_active;	gboolean search_hfp;	gboolean cli_active;	char *ph_number;	int type;	headset_state_t state;	struct pending_connect *pending;	int sp_gain;	int mic_gain;	unsigned int hfp_features;	headset_lock_t lock;};struct event {	const char *cmd;	int (*callback) (struct audio_device *device, const char *buf);};static DBusHandlerResult error_not_supported(DBusConnection *conn,							DBusMessage *msg){	return error_common_reply(conn, msg, ERROR_INTERFACE ".NotSupported",							"Not supported");}static DBusHandlerResult error_connection_attempt_failed(DBusConnection *conn,						DBusMessage *msg, int err){	return error_common_reply(conn, msg,			ERROR_INTERFACE ".ConnectionAttemptFailed",			err > 0 ? strerror(err) : "Connection attempt failed");}static int rfcomm_connect(struct audio_device *device, headset_stream_cb_t cb,				void *user_data, unsigned int *cb_id);static int get_records(struct audio_device *device, headset_stream_cb_t cb,			void *user_data, unsigned int *cb_id);static int headset_send(struct headset *hs, char *format, ...){	char rsp[BUF_SIZE];	va_list ap;	ssize_t total_written, written, count;	int fd;	va_start(ap, format);	count = vsnprintf(rsp, sizeof(rsp), format, ap);	va_end(ap);	if (count < 0)		return -EINVAL;	if (!hs->rfcomm) {		error("headset_send: the headset is not connected");		return -EIO;	}	written = total_written = 0;	fd = g_io_channel_unix_get_fd(hs->rfcomm);	while (total_written < count) {		written = write(fd, rsp + total_written, count - total_written);		if (written < 0)			return -errno;		total_written += written;	}	return 0;}static int supported_features(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	int err;	if (strlen(buf) < 9)		return -EINVAL;	hs->hfp_features = strtoul(&buf[8], NULL, 10);	err = headset_send(hs, "\r\n+BRSF=%u\r\n", ag_features);	if (err < 0)		return err;	return headset_send(hs, "\r\nOK\r\n");}static int report_indicators(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	int err;	if (buf[7] == '=')		err = headset_send(hs, "\r\n+CIND:(\"service\",(0,1)),"				"(\"call\",(0,1)),(\"callsetup\",(0-3))\r\n");	else		err = headset_send(hs, "\r\n+CIND:1,0,0\r\n");	if (err < 0)		return err;	return headset_send(hs, "\r\nOK\r\n");}static void pending_connect_complete(struct connect_cb *cb, struct audio_device *dev){	struct headset *hs = dev->headset;	if (hs->pending->err)		cb->cb(NULL, cb->cb_data);	else		cb->cb(dev, cb->cb_data);}static void pending_connect_finalize(struct audio_device *dev){	struct headset *hs = dev->headset;	struct pending_connect *p = hs->pending;	g_slist_foreach(p->callbacks, (GFunc) pending_connect_complete, dev);	g_slist_foreach(p->callbacks, (GFunc) g_free, NULL);	g_slist_free(p->callbacks);	if (p->io) {		g_io_channel_close(p->io);		g_io_channel_unref(p->io);	}	if (p->msg)		dbus_message_unref(p->msg);	if (p->call) {		dbus_pending_call_cancel(p->call);		dbus_pending_call_unref(p->call);	}	g_free(p);	hs->pending = NULL;}static void pending_connect_init(struct headset *hs, headset_state_t target_state){	if (hs->pending) {		if (hs->pending->target_state < target_state)			hs->pending->target_state = target_state;		return;	}	hs->pending = g_new0(struct pending_connect, 1);	hs->pending->target_state = target_state;}static unsigned int connect_cb_new(struct headset *hs,					headset_state_t target_state,					headset_stream_cb_t func,					void *user_data){	struct connect_cb *cb;	unsigned int free_cb_id = 1;	pending_connect_init(hs, target_state);	cb = g_new(struct connect_cb, 1);	cb->cb = func;	cb->cb_data = user_data;	cb->id = free_cb_id++;	hs->pending->callbacks = g_slist_append(hs->pending->callbacks,						cb);	return cb->id;}static void sco_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,			const bdaddr_t *dst, gpointer user_data){	int sk;	struct audio_device *dev = user_data;	struct headset *hs = dev->headset;	struct pending_connect *p = hs->pending;	if (err < 0) {		error("connect(): %s (%d)", strerror(-err), -err);		if (p->msg)			error_connection_attempt_failed(dev->conn, p->msg, p->err);		pending_connect_finalize(dev);		if (hs->rfcomm)			headset_set_state(dev, HEADSET_STATE_CONNECTED);		else			headset_set_state(dev, HEADSET_STATE_DISCONNECTED);		return;	}	debug("SCO socket opened for headset %s", dev->path);	sk = g_io_channel_unix_get_fd(chan);	info("SCO fd=%d", sk);	hs->sco = chan;	p->io = NULL;	if (p->msg) {		DBusMessage *reply = dbus_message_new_method_return(p->msg);		dbus_connection_send(dev->conn, reply, NULL);		dbus_message_unref(reply);	}	pending_connect_finalize(dev);	fcntl(sk, F_SETFL, 0);	headset_set_state(dev, HEADSET_STATE_PLAYING);}static int sco_connect(struct audio_device *dev, headset_stream_cb_t cb,			void *user_data, unsigned int *cb_id){	struct headset *hs = dev->headset;	int err;	if (hs->state != HEADSET_STATE_CONNECTED)		return -EINVAL;	err = bt_sco_connect(&dev->src, &dev->dst, sco_connect_cb, dev);	if (err < 0) {		error("connect: %s (%d)", strerror(-err), -err);		return -err;	}	headset_set_state(dev, HEADSET_STATE_PLAY_IN_PROGRESS);	pending_connect_init(hs, HEADSET_STATE_PLAYING);	if (cb) {		unsigned int id = connect_cb_new(hs, HEADSET_STATE_PLAYING,							cb, user_data);		if (cb_id)			*cb_id = id;	}	return 0;}static void hfp_slc_complete(struct audio_device *dev){	struct headset *hs = dev->headset;	struct pending_connect *p = hs->pending;	debug("HFP Service Level Connection established");	headset_set_state(dev, HEADSET_STATE_CONNECTED);	if (p == NULL)		return;	if (p->msg) {		DBusMessage *reply = dbus_message_new_method_return(p->msg);		dbus_connection_send(dev->conn, reply, NULL);		dbus_message_unref(reply);	}	if (p->target_state == HEADSET_STATE_CONNECTED) {		pending_connect_finalize(dev);		return;	}	p->err = sco_connect(dev, NULL, NULL, NULL);	if (p->err < 0)		pending_connect_finalize(dev);}static int event_reporting(struct audio_device *dev, const char *buf){	struct headset *hs = dev->headset;	int ret;	ret = headset_send(hs, "\r\nOK\r\n");	if (ret < 0)		return ret;	if (hs->state != HEADSET_STATE_CONNECT_IN_PROGRESS)		return 0;	if (ag_features & AG_FEATURE_THREE_WAY_CALLING)		return 0;	hfp_slc_complete(dev);	return 0;}static int call_hold(struct audio_device *dev, const char *buf){	struct headset *hs = dev->headset;	int err;	err = headset_send(hs, "\r\n+CHLD:(0,1,1x,2,2x,3,4)\r\n");	if (err < 0)		return err;	err = headset_send(hs, "\r\nOK\r\n");	if (err < 0)		return err;	if (hs->state != HEADSET_STATE_CONNECT_IN_PROGRESS)		return 0;	hfp_slc_complete(dev);	return 0;}static int answer_call(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	int err;	g_dbus_emit_signal(device->conn, device->path,			AUDIO_HEADSET_INTERFACE, "AnswerRequested",			DBUS_TYPE_INVALID);	if (hs->ring_timer) {		g_source_remove(hs->ring_timer);		hs->ring_timer = 0;	}	if (!hs->hfp_active)		return headset_send(hs, "\r\nOK\r\n");	if (hs->ph_number) {		g_free(hs->ph_number);		hs->ph_number = NULL;	}	err = headset_send(hs, "\r\nOK\r\n");	if (err < 0)		return err;	/*+CIEV: (call = 1)*/	err = headset_send(hs, "\r\n+CIEV:2,1\r\n");	if (err < 0)		return err;	/*+CIEV: (callsetup = 0)*/	return headset_send(hs, "\r\n+CIEV:3,0\r\n");}static int terminate_call(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	int err;	g_dbus_emit_signal(device->conn, device->path,			AUDIO_HEADSET_INTERFACE, "CallTerminated",			DBUS_TYPE_INVALID);	err = headset_send(hs, "\r\nOK\r\n");	if (err < 0)		return err;	if (hs->ph_number) {		g_free(hs->ph_number);		hs->ph_number = NULL;	}	if (hs->ring_timer) {		g_source_remove(hs->ring_timer);		hs->ring_timer = 0;		/*+CIEV: (callsetup = 0)*/		return headset_send(hs, "\r\n+CIEV:3,0\r\n");	}	/*+CIEV: (call = 0)*/	return headset_send(hs, "\r\n+CIEV:2,0\r\n");}static int cli_notification(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	if (strlen(buf) < 9)		return -EINVAL;	hs->cli_active = buf[8] == '1' ? TRUE : FALSE;	return headset_send(hs, "\r\nOK\r\n");}static int signal_gain_setting(struct audio_device *device, const char *buf){	struct headset *hs = device->headset;	const char *name;	dbus_uint16_t gain;	if (strlen(buf) < 8) {		error("Too short string for Gain setting");		return -EINVAL;	}	gain = (dbus_uint16_t) strtol(&buf[7], NULL, 10);	if (gain > 15) {		error("Invalid gain value received: %u", gain);		return -EINVAL;	}	switch (buf[5]) {	case HEADSET_GAIN_SPEAKER:		if (hs->sp_gain == gain)			goto ok;		name = "SpeakerGainChanged";		hs->sp_gain = gain;		break;	case HEADSET_GAIN_MICROPHONE:		if (hs->mic_gain == gain)			goto ok;		name = "MicrophoneGainChanged";		hs->mic_gain = gain;		break;	default:		error("Unknown gain setting");		return -EINVAL;	}	g_dbus_emit_signal(device->conn, device->path,				    AUDIO_HEADSET_INTERFACE, name,				    DBUS_TYPE_UINT16, &gain,				    DBUS_TYPE_INVALID);ok:	return headset_send(hs, "\r\nOK\r\n");}static struct event event_callbacks[] = {	{ "ATA", answer_call },	{ "AT+VG", signal_gain_setting },	{ "AT+BRSF", supported_features },	{ "AT+CIND", report_indicators },	{ "AT+CMER", event_reporting },	{ "AT+CHLD", call_hold },	{ "AT+CHUP", terminate_call },	{ "AT+CKPD", answer_call },	{ "AT+CLIP", cli_notification },	{ 0 }};static int handle_event(struct audio_device *device, const char *buf){	struct event *ev;	debug("Received %s", buf);	for (ev = event_callbacks; ev->cmd; ev++) {		if (!strncmp(buf, ev->cmd, strlen(ev->cmd)))			return ev->callback(device, buf);	}	return -EINVAL;}static void close_sco(struct audio_device *device){	struct headset *hs = device->headset;	if (hs->sco) {		g_source_remove(hs->sco_id);		hs->sco_id = 0;		g_io_channel_close(hs->sco);		g_io_channel_unref(hs->sco);		hs->sco = NULL;	}}static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,				struct audio_device *device){	struct headset *hs;	unsigned char buf[BUF_SIZE];	char *cr;	gsize bytes_read = 0;	gsize free_space;	int err;	off_t cmd_len;	if (cond & G_IO_NVAL)		return FALSE;	hs = device->headset;	if (cond & (G_IO_ERR | G_IO_HUP))		goto failed;	if (g_io_channel_read(chan, (gchar *) buf, sizeof(buf) - 1,				&bytes_read) != G_IO_ERROR_NONE)		return TRUE;	free_space = sizeof(hs->buf) - hs->data_start - hs->data_length - 1;	if (free_space < bytes_read) {		/* Very likely that the HS is sending us garbage so		 * just ignore the data and disconnect */		error("Too much data to fit incomming buffer");		goto failed;	}	memcpy(&hs->buf[hs->data_start], buf, bytes_read);	hs->data_length += bytes_read;	/* Make sure the data is null terminated so we can use string	 * functions */	hs->buf[hs->data_start + hs->data_length] = '\0';	cr = strchr(&hs->buf[hs->data_start], '\r');	if (!cr)		return TRUE;	cmd_len = 1 + (off_t) cr - (off_t) &hs->buf[hs->data_start];	*cr = '\0';

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲精品视频免费看| 欧美日韩国产精品成人| 26uuu国产日韩综合| 午夜免费欧美电影| 欧美最新大片在线看| 亚洲欧美日韩一区二区| 99re在线视频这里只有精品| 国产精品色哟哟| 99视频超级精品| 亚洲特级片在线| 97国产一区二区| ...中文天堂在线一区| 99久久久久免费精品国产| 欧美激情一区在线观看| 日韩中文字幕1| 91黄色激情网站| 亚洲第一综合色| 777久久久精品| 久久激情五月婷婷| 久久精品日产第一区二区三区高清版| 国产一区二区成人久久免费影院| 久久久久久免费| 成人黄色在线看| 一区二区三区四区蜜桃| 成人激情小说网站| 国产精品无码永久免费888| 国产一区二区美女诱惑| 国产精品美日韩| 成人av影视在线观看| 欧美极品xxx| 91免费小视频| 亚洲女同一区二区| 欧美精选午夜久久久乱码6080| 免费视频最近日韩| 国产色综合一区| 91久久精品国产91性色tv| 午夜精彩视频在线观看不卡| 日韩欧美一级在线播放| 国产福利91精品| 一区二区三区毛片| 欧美成人乱码一区二区三区| 成人一级黄色片| 香港成人在线视频| 久久嫩草精品久久久精品一| 91老司机福利 在线| 日韩av二区在线播放| 国产人成亚洲第一网站在线播放 | 在线观看91精品国产入口| 免费高清视频精品| 国产区在线观看成人精品| 欧美色欧美亚洲另类二区| 狠狠网亚洲精品| 亚洲综合一二三区| 久久美女高清视频| 欧美私人免费视频| 日本中文字幕一区| 亚洲欧美偷拍卡通变态| 日韩你懂的在线播放| 色视频一区二区| 久久国产欧美日韩精品| 亚洲精品视频在线看| 精品国产一区二区三区av性色| 91女神在线视频| 国产精品1区2区3区| 亚洲福利视频三区| 国产精品国产三级国产三级人妇| 日韩视频免费直播| 在线视频你懂得一区二区三区| 激情五月婷婷综合网| 国产精品网站一区| 欧美日韩一区二区不卡| 成人免费视频网站在线观看| 经典三级视频一区| 日韩成人av影视| 亚洲一区在线免费观看| 中文字幕欧美一| 欧美极品xxx| 久久久久九九视频| 精品入口麻豆88视频| 制服.丝袜.亚洲.另类.中文| 色一情一乱一乱一91av| 成人听书哪个软件好| 国产精品影音先锋| 国内久久婷婷综合| 久久不见久久见免费视频1| 日本特黄久久久高潮| 日韩在线观看一区二区| 香蕉久久夜色精品国产使用方法 | 美女脱光内衣内裤视频久久网站| 一区二区在线看| 亚洲欧美日本韩国| 亚洲情趣在线观看| 亚洲图片激情小说| 亚洲丝袜自拍清纯另类| 中文字幕亚洲欧美在线不卡| 国产精品电影一区二区| 国产精品视频yy9299一区| 国产午夜精品福利| 国产午夜精品福利| 国产精品美女久久久久久| 国产欧美日韩精品在线| 国产精品护士白丝一区av| 国产精品美女久久久久av爽李琼 | 美日韩黄色大片| 精品一区二区三区在线观看国产 | 久久久一区二区三区捆绑**| 精品日韩成人av| 日韩精品一区二区三区老鸭窝 | 99re热这里只有精品免费视频| 国产九色精品成人porny | 99国产精品久| 91黄视频在线| 日韩一二在线观看| 久久免费精品国产久精品久久久久| 国产欧美精品一区| 亚洲精品成人少妇| 日本不卡一区二区三区| 国产精品亚洲成人| 色综合久久久久网| 这里只有精品电影| 久久免费视频一区| 亚洲柠檬福利资源导航| 性做久久久久久免费观看| 蜜桃av一区二区在线观看| 成人一级片在线观看| 91国产免费观看| 69堂成人精品免费视频| 精品久久一二三区| 国产亚洲污的网站| 亚洲香肠在线观看| 国产露脸91国语对白| 91国在线观看| 亚洲精品在线网站| 亚洲精品国久久99热| 久久精品国产77777蜜臀| 不卡电影一区二区三区| 9191成人精品久久| 中文字幕一区二区不卡| 免费高清在线一区| 97精品久久久午夜一区二区三区 | 91色婷婷久久久久合中文| 欧美丰满嫩嫩电影| 中文字幕乱码一区二区免费| 亚洲第一搞黄网站| 精品一区二区三区免费毛片爱| 97se狠狠狠综合亚洲狠狠| 欧美日韩精品一区二区三区| 欧美精品一区二区三区蜜臀| 一区二区三区欧美亚洲| 韩国v欧美v亚洲v日本v| 欧美色综合天天久久综合精品| 欧美v亚洲v综合ⅴ国产v| 一区二区三区小说| 国产麻豆日韩欧美久久| 欧美老女人第四色| 中文字幕欧美一区| 国产精品一区二区免费不卡| 欧美性videosxxxxx| 国产精品久久福利| 国产综合久久久久久鬼色| 欧美日本乱大交xxxxx| 亚洲日韩欧美一区二区在线| 狠狠色综合色综合网络| 欧美一区日韩一区| 亚洲综合一区二区精品导航| 成人午夜精品在线| 国产日韩欧美a| 国产精品原创巨作av| 欧美成va人片在线观看| 日韩精品一二三| 国产盗摄视频一区二区三区| 欧美精品电影在线播放| 亚洲欧洲av色图| 国产精品亚洲人在线观看| 欧美福利视频导航| 国产精品国产三级国产普通话蜜臀 | 久久精品在线免费观看| 亚洲综合免费观看高清完整版| 国产成人欧美日韩在线电影| 日韩精品一区二区三区视频播放| 午夜视频久久久久久| 欧美中文字幕一二三区视频| 国产精品福利在线播放| 成人激情小说网站| 国产精品免费丝袜| www.亚洲免费av| 国产精品国产自产拍在线| 成人精品一区二区三区四区| 中文在线免费一区三区高中清不卡| 激情六月婷婷综合| 久久久久国产免费免费| 国产成人在线视频网站| 欧美国产激情二区三区| 成人av影视在线观看| 欧美国产在线观看| 成人激情文学综合网| 亚洲四区在线观看| 欧美天堂一区二区三区| 香蕉久久夜色精品国产使用方法 | 亚洲天堂中文字幕|