* [Bluez-devel] [PATCH] Resubmission of Fixes in rfcomm tty
@ 2008-01-15 2:20 Denis KENZIOR
2008-01-15 20:34 ` [Bluez-devel] [HFP][PATCH] HFP options in audio.conf Alok
0 siblings, 1 reply; 2+ messages in thread
From: Denis KENZIOR @ 2008-01-15 2:20 UTC (permalink / raw)
To: bluez-devel
[-- Attachment #1: Type: text/plain, Size: 696 bytes --]
Marcel,
Previous patch broken up into two:
rfcomm-tty-keep-socket-data:
If the TTY socket receives data before TTY is created, or the TTY is not
opened (e.g. on devfs) then the data is discarded. This makes it impossible
to support some protocols which send data right away, e.g. DUN and HFP
This one should be applied first.
rfcomm-tty-echo-overflow:
The serial core sends us lots of 1 byte requests when dealing with
canonical ttys (e.g. ones that echo). This attempts to fix this issue by
tweaking how the wfree is handled and also tries to be intelligent in the
handling these 1 byte requests by appending them to the pending packet if
there is room.
-Denis
[-- Attachment #2: rfcomm-tty-keep-socket-data.patch --]
[-- Type: text/x-diff, Size: 5695 bytes --]
diff -r -U5 a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
--- a/net/bluetooth/rfcomm/core.c 2007-08-23 09:23:54.000000000 +1000
+++ b/net/bluetooth/rfcomm/core.c 2007-12-14 11:08:54.000000000 +1000
@@ -457,11 +457,10 @@
BT_DBG("dlc %p mtu %d len %d", d, d->mtu, len);
if (len > d->mtu)
return -EINVAL;
- rfcomm_make_uih(skb, d->addr);
skb_queue_tail(&d->tx_queue, skb);
if (!test_bit(RFCOMM_TX_THROTTLED, &d->flags))
rfcomm_schedule(RFCOMM_SCHED_TX);
return len;
@@ -1021,10 +1020,11 @@
put_unaligned(htobs(__len16(len)), (__le16 *) &hdr->len);
} else {
hdr = (void *) skb_push(skb, 3);
hdr->len = __len8(len);
}
+
hdr->addr = addr;
hdr->ctrl = __ctrl(RFCOMM_UIH, 0);
crc = skb_put(skb, 1);
*crc = __fcs((void *) hdr);
@@ -1673,19 +1673,23 @@
}
if (test_bit(RFCOMM_TX_THROTTLED, &d->flags))
return skb_queue_len(&d->tx_queue);
+ /* Need to lock this in case the tty driver might be messing with the tx queue */
+ rfcomm_dlc_lock(d);
while (d->tx_credits && (skb = skb_dequeue(&d->tx_queue))) {
+ rfcomm_make_uih(skb, d->addr);
err = rfcomm_send_frame(d->session, skb->data, skb->len);
if (err < 0) {
skb_queue_head(&d->tx_queue, skb);
break;
}
kfree_skb(skb);
d->tx_credits--;
}
+ rfcomm_dlc_unlock(d);
if (d->cfc && !d->tx_credits) {
/* We're out of TX credits.
* Set TX_THROTTLED flag to avoid unnesary wakeups by dlc_send. */
set_bit(RFCOMM_TX_THROTTLED, &d->flags);
diff -r -U5 a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c 2007-08-23 09:23:54.000000000 +1000
+++ b/net/bluetooth/rfcomm/tty.c 2007-12-14 11:13:23.000000000 +1000
@@ -75,20 +75,25 @@
struct tasklet_struct wakeup_task;
struct device *tty_dev;
atomic_t wmem_alloc;
+
+ struct tasklet_struct copy_task;
+ struct sk_buff_head rx_queue;
+ atomic_t rxq_mem_alloc;
};
static LIST_HEAD(rfcomm_dev_list);
static DEFINE_RWLOCK(rfcomm_dev_lock);
static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb);
static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err);
static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig);
static void rfcomm_tty_wakeup(unsigned long arg);
+static void rfcomm_tty_copy_buffered(unsigned long arg);
/* ---- Device functions ---- */
static void rfcomm_dev_destruct(struct rfcomm_dev *dev)
{
struct rfcomm_dlc *dlc = dev->dlc;
@@ -192,10 +197,12 @@
static int rfcomm_dev_add(struct rfcomm_dev_req *req, struct rfcomm_dlc *dlc)
{
struct rfcomm_dev *dev;
struct list_head *head = &rfcomm_dev_list, *p;
int err = 0;
+ struct sock *sk;
+ struct sk_buff *skb;
BT_DBG("id %d channel %d", req->dev_id, req->channel);
dev = kzalloc(sizeof(struct rfcomm_dev), GFP_KERNEL);
if (!dev)
@@ -248,12 +255,24 @@
dev->flags = req->flags &
((1 << RFCOMM_RELEASE_ONHUP) | (1 << RFCOMM_REUSE_DLC));
init_waitqueue_head(&dev->wait);
tasklet_init(&dev->wakeup_task, rfcomm_tty_wakeup, (unsigned long) dev);
+ skb_queue_head_init(&dev->rx_queue);
+ tasklet_init(&dev->copy_task, rfcomm_tty_copy_buffered, (unsigned long) dev);
rfcomm_dlc_lock(dlc);
+ if (req->flags & (1 << RFCOMM_REUSE_DLC)) {
+ sk = dlc->owner;
+ atomic_set(&dev->rxq_mem_alloc, 0);
+ while (sk && (skb = skb_dequeue(&sk->sk_receive_queue))) {
+ atomic_sub(skb->len, &sk->sk_rmem_alloc);
+ atomic_add(skb->len, &dev->rxq_mem_alloc);
+ skb_queue_tail(&dev->rx_queue, skb);
+ }
+ }
+
dlc->data_ready = rfcomm_dev_data_ready;
dlc->state_change = rfcomm_dev_state_change;
dlc->modem_status = rfcomm_dev_modem_status;
dlc->owner = dev;
@@ -506,15 +524,24 @@
static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
{
struct rfcomm_dev *dev = dlc->owner;
struct tty_struct *tty;
- if (!dev || !(tty = dev->tty)) {
+ if (!dev) {
kfree_skb(skb);
return;
}
+ if (!(tty = dev->tty) || !skb_queue_empty(&dev->rx_queue)) {
+ atomic_add(skb->len, &dev->rxq_mem_alloc);
+ skb_queue_tail(&dev->rx_queue, skb);
+
+ if (atomic_read(&dev->rxq_mem_alloc) >= RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10)
+ rfcomm_dlc_throttle(dlc);
+ return;
+ }
+
BT_DBG("dlc %p tty %p len %d", dlc, tty, skb->len);
tty_insert_flip_string(tty, skb->data, skb->len);
tty_flip_buffer_push(tty);
@@ -588,10 +615,35 @@
#ifdef SERIAL_HAVE_POLL_WAIT
wake_up_interruptible(&tty->poll_wait);
#endif
}
+static void rfcomm_tty_copy_buffered(unsigned long arg)
+{
+ struct rfcomm_dev *dev = (void *) arg;
+ struct tty_struct *tty = dev->tty;
+ struct sk_buff *skb;
+
+ if (!tty)
+ return;
+
+ rfcomm_dlc_lock(dev->dlc);
+
+ while ((skb = skb_dequeue(&dev->rx_queue))) {
+ int inserted;
+ inserted = tty_insert_flip_string(tty, skb->data, skb->len);
+
+ kfree_skb(skb);
+ }
+
+ tty_flip_buffer_push(tty);
+
+ rfcomm_dlc_unthrottle(dev->dlc);
+ rfcomm_dlc_unlock(dev->dlc);
+ tasklet_disable(&dev->copy_task);
+}
+
static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
{
DECLARE_WAITQUEUE(wait, current);
struct rfcomm_dev *dev;
struct rfcomm_dlc *dlc;
@@ -649,10 +701,12 @@
schedule();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&dev->wait, &wait);
+ tasklet_schedule(&dev->copy_task);
+
if (err == 0)
device_move(dev->tty_dev, rfcomm_get_device(dev));
return err;
}
@@ -671,10 +725,11 @@
/* Close DLC and dettach TTY */
rfcomm_dlc_close(dev->dlc, 0);
clear_bit(RFCOMM_TTY_ATTACHED, &dev->flags);
tasklet_kill(&dev->wakeup_task);
+ tasklet_kill(&dev->copy_task);
rfcomm_dlc_lock(dev->dlc);
tty->driver_data = NULL;
dev->tty = NULL;
rfcomm_dlc_unlock(dev->dlc);
[-- Attachment #3: rfcomm-tty-echo-overflow.patch --]
[-- Type: text/x-diff, Size: 1938 bytes --]
diff -r -U5 a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
--- a/net/bluetooth/rfcomm/tty.c 2007-08-23 09:23:54.000000000 +1000
+++ b/net/bluetooth/rfcomm/tty.c 2007-12-14 11:13:23.000000000 +1000
@@ -292,18 +311,17 @@
}
/* ---- Send buffer ---- */
static inline unsigned int rfcomm_room(struct rfcomm_dlc *dlc)
{
- /* We can't let it be zero, because we don't get a callback
- when tx_credits becomes nonzero, hence we'd never wake up */
- return dlc->mtu * (dlc->tx_credits?:1);
+ return RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10;
}
static void rfcomm_wfree(struct sk_buff *skb)
{
struct rfcomm_dev *dev = (void *) skb->sk;
+
atomic_sub(skb->truesize, &dev->wmem_alloc);
if (test_bit(RFCOMM_TTY_ATTACHED, &dev->flags))
tasklet_schedule(&dev->wakeup_task);
rfcomm_dev_put(dev);
}
@@ -690,14 +745,30 @@
struct sk_buff *skb;
int err = 0, sent = 0, size;
BT_DBG("tty %p count %d", tty, count);
+ /* We get lots of 1 byte requests in canonical mode */
+ /* So we just put them on the tail of our tx queue */
+ /* if possible */
+
+ rfcomm_dlc_lock(dlc);
+ skb = skb_peek_tail(&dlc->tx_queue);
+ if (skb) {
+ size = min_t(uint, count, dlc->mtu - skb->len);
+ memcpy(skb_put(skb, size), buf + sent, size);
+
+ sent += size;
+ count -= size;
+ }
+ rfcomm_dlc_unlock(dlc);
+ skb = 0;
+
while (count) {
size = min_t(uint, count, dlc->mtu);
- skb = rfcomm_wmalloc(dev, size + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
+ skb = rfcomm_wmalloc(dev, dlc->mtu + RFCOMM_SKB_RESERVE, GFP_ATOMIC);
if (!skb)
break;
skb_reserve(skb, RFCOMM_SKB_HEAD_RESERVE);
@@ -964,12 +1035,10 @@
BT_DBG("tty %p dev %p", tty, dev);
if (!dev || !dev->dlc)
return;
- skb_queue_purge(&dev->dlc->tx_queue);
-
if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
tty->ldisc.write_wakeup(tty);
}
static void rfcomm_tty_send_xchar(struct tty_struct *tty, char ch)
[-- Attachment #4: Type: text/plain, Size: 278 bytes --]
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
[-- Attachment #5: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
* [Bluez-devel] [HFP][PATCH] HFP options in audio.conf
2008-01-15 2:20 [Bluez-devel] [PATCH] Resubmission of Fixes in rfcomm tty Denis KENZIOR
@ 2008-01-15 20:34 ` Alok
0 siblings, 0 replies; 2+ messages in thread
From: Alok @ 2008-01-15 20:34 UTC (permalink / raw)
To: BlueZ development
[-- Attachment #1: Type: text/plain, Size: 194 bytes --]
Hi Johan/Fredric,
Attaching a patch for HFP AG feature options in audio.conf and the other
changes we discussed on #bluez yesterday.
Let me know if something needs to be changed.
-Alok.
[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 16746 bytes --]
Index: audio/audio.conf
===================================================================
RCS file: /cvsroot/bluez/utils/audio/audio.conf,v
retrieving revision 1.3
diff -u -5 -p -r1.3 audio.conf
--- audio/audio.conf 28 Aug 2007 11:49:37 -0000 1.3
+++ audio/audio.conf 15 Jan 2008 20:22:38 -0000
@@ -18,8 +18,20 @@
# Set to true to only support HSP
# Defaults to false
DisableHFP=true
+# HFP Gateway features
+# Defaults to false
+3WayCalling=false
+EchoCancelNoiseCancel=false
+VoiceRecognition=false
+InBandRingtone=false
+VoiceTags=false
+RejectingCalls=false
+EnhancedCallStatus=false
+EnhancedCallControl=false
+ExtendedErrorResultCodes=false
+
# Just an example of potential config options for the other interfaces
#[A2DP]
#SourceCount=2
Index: audio/manager.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/manager.h,v
retrieving revision 1.31
diff -u -5 -p -r1.31 manager.h
--- audio/manager.h 8 Jan 2008 08:58:14 -0000 1.31
+++ audio/manager.h 15 Jan 2008 20:22:38 -0000
@@ -24,10 +24,12 @@
#define MAX_PATH_LENGTH 64 /* D-Bus path */
#define AUDIO_MANAGER_PATH "/org/bluez/audio"
#define AUDIO_MANAGER_INTERFACE "org.bluez.audio.Manager"
+#define configfile CONFIGDIR"/audio.conf"
+
struct enabled_interfaces {
gboolean headset;
gboolean gateway;
gboolean sink;
gboolean source;
@@ -35,13 +37,11 @@ struct enabled_interfaces {
gboolean target;
};
typedef void (*create_dev_cb_t) (struct device *dev, void *user_data);
-int audio_init(DBusConnection *conn, struct enabled_interfaces *enabled,
- gboolean no_hfp, gboolean sco_hci, int source_count);
-
+int audio_init(DBusConnection *conn, GKeyFile *config);
void audio_exit(void);
uint32_t add_service_record(DBusConnection *conn, sdp_buf_t *buf);
int remove_service_record(DBusConnection *conn, uint32_t rec_id);
gboolean server_is_enabled(uint16_t svc);
Index: audio/manager.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/manager.c,v
retrieving revision 1.85
diff -u -5 -p -r1.85 manager.c
--- audio/manager.c 8 Jan 2008 08:58:14 -0000 1.85
+++ audio/manager.c 15 Jan 2008 20:22:39 -0000
@@ -105,11 +105,18 @@ 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 const struct enabled_interfaces *enabled;
+static struct enabled_interfaces enabled = {
+ .headset = TRUE,
+ .gateway = FALSE,
+ .sink = TRUE,
+ .source = FALSE,
+ .control = TRUE,
+ .target = FALSE,
+};
static void get_next_record(struct audio_sdp_data *data);
static DBusHandlerResult get_handles(const char *uuid,
struct audio_sdp_data *data);
@@ -223,14 +230,14 @@ gboolean server_is_enabled(uint16_t svc)
break;
case HANDSFREE_SVCLASS_ID:
ret = (hf_server != NULL);
break;
case AUDIO_SINK_SVCLASS_ID:
- return enabled->sink;
+ return enabled.sink;
case AV_REMOTE_TARGET_SVCLASS_ID:
case AV_REMOTE_SVCLASS_ID:
- return enabled->control;
+ return enabled.control;
default:
ret = FALSE;
break;
}
@@ -1067,15 +1074,15 @@ static void parse_stored_devices(char *k
return;
/* Change storage to source adapter */
bacpy(&device->store, src);
- if (enabled->headset && strstr(value, "headset"))
+ if (enabled.headset && strstr(value, "headset"))
device->headset = headset_init(device, NULL, 0);
- if (enabled->sink && strstr(value, "sink"))
+ if (enabled.sink && strstr(value, "sink"))
device->sink = sink_init(device);
- if (enabled->control && strstr(value, "control"))
+ if (enabled.control && strstr(value, "control"))
device->control = control_init(device);
add_device(device, FALSE);
}
static void register_devices_stored(const char *adapter)
@@ -1527,16 +1534,18 @@ static GIOChannel *server_socket(uint8_t
}
return io;
}
-static int headset_server_init(DBusConnection *conn, gboolean no_hfp)
+static int headset_server_init(DBusConnection *conn, GKeyFile *config)
{
uint8_t chan = DEFAULT_HS_AG_CHANNEL;
sdp_buf_t buf;
+ gboolean no_hfp = TRUE;
+ GError *err = NULL;
- if (!(enabled->headset || enabled->gateway))
+ if (!(enabled.headset || enabled.gateway))
return 0;
hs_server = server_socket(&chan);
if (!hs_server)
return -1;
@@ -1555,10 +1564,19 @@ static int headset_server_init(DBusConne
return -1;
}
g_io_add_watch(hs_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
(GIOFunc) ag_io_cb, NULL);
+ if (config) {
+ no_hfp = g_key_file_get_boolean(config, "Headset", "DisableHFP",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ }
+ }
if (no_hfp)
return 0;
chan = DEFAULT_HF_AG_CHANNEL;
@@ -1608,42 +1626,97 @@ static void server_exit(void)
g_io_channel_unref(hf_server);
hf_server = NULL;
}
}
-int audio_init(DBusConnection *conn, struct enabled_interfaces *enable,
- gboolean no_hfp, gboolean sco_hci, int source_count)
+int audio_init(DBusConnection *conn, GKeyFile *config)
{
- int sinks, sources;
-
+ static int sinks, sources;
+ char *str;
+ GError *err = NULL;
connection = dbus_connection_ref(conn);
+ debug("config is %x",config);
+ if (config) {
+ str = g_key_file_get_string(config, "General", "Enable", &err);
+
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (strstr(str, "Headset"))
+ enabled.headset = TRUE;
+ if (strstr(str, "Gateway"))
+ enabled.gateway = TRUE;
+ if (strstr(str, "Sink"))
+ enabled.sink = TRUE;
+ if (strstr(str, "Source"))
+ enabled.source = TRUE;
+ if (strstr(str, "Control"))
+ enabled.control = TRUE;
+ if (strstr(str, "Target"))
+ enabled.target = TRUE;
+ g_free(str);
+ }
- enabled = enable;
+ str = g_key_file_get_string(config, "General", "Disable", &err);
+
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (strstr(str, "Headset"))
+ enabled.headset = FALSE;
+ if (strstr(str, "Gateway"))
+ enabled.gateway = FALSE;
+ if (strstr(str, "Sink"))
+ enabled.sink = FALSE;
+ if (strstr(str, "Source"))
+ enabled.source = FALSE;
+ if (strstr(str, "Control"))
+ enabled.control = FALSE;
+ if (strstr(str, "Target"))
+ enabled.target = FALSE;
+ g_free(str);
+ }
+ }
if (!dbus_connection_create_object_path(conn, AUDIO_MANAGER_PATH,
NULL, manager_unregister)) {
error("D-Bus failed to register %s path", AUDIO_MANAGER_PATH);
goto failed;
}
- if (headset_server_init(conn, no_hfp) < 0)
+ if (enabled.headset && headset_config_init(config) &&
+ headset_server_init(conn, config) < 0)
goto failed;
- if (enable->sink)
- sources = source_count;
- else
+ if (enabled.sink) {
+ if (config) {
+ str = g_key_file_get_string(config, "A2DP", "SourceCount", &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ sources = atoi(str);
+ g_free(str);
+ }
+ }
+ } else
sources = 0;
- if (enable->source)
+ if (enabled.source)
sinks = 1;
else
sinks = 0;
if (a2dp_init(conn, sources, sinks) < 0)
goto failed;
- if (enable->control && avrcp_init(conn) < 0)
+ if (enabled.control && avrcp_init(conn) < 0)
goto failed;
if (!dbus_connection_register_interface(conn, AUDIO_MANAGER_PATH,
AUDIO_MANAGER_INTERFACE,
manager_methods,
Index: audio/headset.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/headset.h,v
retrieving revision 1.34
diff -u -5 -p -r1.34 headset.h
--- audio/headset.h 8 Jan 2008 08:58:14 -0000 1.34
+++ audio/headset.h 15 Jan 2008 20:22:40 -0000
@@ -45,10 +45,12 @@ typedef void (*headset_stream_cb_t) (str
struct headset *headset_init(struct device *dev, sdp_record_t *record,
uint16_t svc);
void headset_free(struct device *dev);
+int headset_config_init(GKeyFile *config);
+
void headset_update(struct device *dev, sdp_record_t *record, uint16_t svc);
unsigned int headset_request_stream(struct device *dev, headset_stream_cb_t cb,
void *user_data);
gboolean headset_cancel_stream(struct device *dev, unsigned int id);
Index: audio/headset.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/headset.c,v
retrieving revision 1.157
diff -u -5 -p -r1.157 headset.c
--- audio/headset.c 11 Jan 2008 11:19:00 -0000 1.157
+++ audio/headset.c 15 Jan 2008 20:22:40 -0000
@@ -71,12 +71,14 @@
#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 0x0100
/*Audio Gateway features.Default is In-band Ringtone*/
-static unsigned int ag_features = AG_FEATURE_INBAND_RINGTONE;
+static unsigned int ag_features;
+static gboolean sco_hci = TRUE;
static char *str_state[] = {
"HEADSET_STATE_DISCONNECTED",
"HEADSET_STATE_CONNECT_IN_PROGRESS",
"HEADSET_STATE_CONNECTED",
@@ -1584,10 +1586,138 @@ register_iface:
}
return hs;
}
+int headset_config_init(GKeyFile *config)
+{
+ GError *err = NULL;
+ gboolean value;
+ char *str;
+
+ /*Use the default values if there is no config file*/
+ if (config == NULL)
+ return 1;
+
+ str = g_key_file_get_string(config, "General", "SCORouting",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (strcmp(str, "PCM") == 0)
+ sco_hci = FALSE;
+ else if (strcmp(str, "HCI") == 0)
+ sco_hci = TRUE;
+ else
+ error("Invalid Headset Routing value: %s", str);
+ g_free(str);
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "3WayCalling",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_THREE_WAY_CALLING;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "EchoCancelNoiseCancel",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_EC_ANDOR_NR;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "VoiceRecognition",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_VOICE_RECOGNITION;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "InBandRingtone",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_INBAND_RINGTONE;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "VoiceTags",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "RejectingCalls",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_REJECT_A_CALL;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "EnhancedCallStatus",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_ENHANCES_CALL_STATUS;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "EnhancedCallControl",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_ENHANCES_CALL_CONTROL;
+ }
+
+ value = g_key_file_get_boolean(config, "Headset", "ExtendedErrorResultCodes",
+ &err);
+ if (err) {
+ debug("%s: %s", configfile, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ if (value)
+ ag_features |= AG_FEATURE_EXTENDED_ERROR_RESULT_CODES;
+ }
+
+ return 1;
+}
+
void headset_free(struct device *dev)
{
struct headset *hs = dev->headset;
if (hs->sco) {
Index: audio/main.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/main.c,v
retrieving revision 1.29
diff -u -5 -p -r1.29 main.c
--- audio/main.c 27 Nov 2007 09:15:54 -0000 1.29
+++ audio/main.c 15 Jan 2008 20:22:40 -0000
@@ -40,133 +40,38 @@
#include "logging.h"
#include "unix.h"
#include "device.h"
#include "manager.h"
-static gboolean disable_hfp = TRUE;
-static gboolean sco_hci = TRUE;
-static int source_count = 1;
-
static GMainLoop *main_loop = NULL;
-static struct enabled_interfaces enabled = {
- .headset = TRUE,
- .gateway = FALSE,
- .sink = TRUE,
- .source = FALSE,
- .control = TRUE,
- .target = FALSE,
-};
-
static void sig_term(int sig)
{
g_main_loop_quit(main_loop);
}
-static void read_config(const char *file)
+static GKeyFile *load_config_file(const char *file)
{
- GKeyFile *keyfile;
GError *err = NULL;
- gboolean no_hfp;
- char *str;
+ GKeyFile *keyfile;
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, file, 0, &err)) {
error("Parsing %s failed: %s", file, err->message);
g_error_free(err);
g_key_file_free(keyfile);
- return;
- }
-
- str = g_key_file_get_string(keyfile, "General", "SCORouting", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else {
- if (strcmp(str, "PCM") == 0)
- sco_hci = FALSE;
- else if (strcmp(str, "HCI") == 0)
- sco_hci = TRUE;
- else
- error("Invalid Headset Routing value: %s", str);
- g_free(str);
- }
-
- str = g_key_file_get_string(keyfile, "General", "Enable", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else {
- if (strstr(str, "Headset"))
- enabled.headset = TRUE;
- if (strstr(str, "Gateway"))
- enabled.gateway = TRUE;
- if (strstr(str, "Sink"))
- enabled.sink = TRUE;
- if (strstr(str, "Source"))
- enabled.source = TRUE;
- if (strstr(str, "Control"))
- enabled.control = TRUE;
- if (strstr(str, "Target"))
- enabled.target = TRUE;
- g_free(str);
+ return NULL;
}
-
- str = g_key_file_get_string(keyfile, "General", "Disable", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else {
- if (strstr(str, "Headset"))
- enabled.headset = FALSE;
- if (strstr(str, "Gateway"))
- enabled.gateway = FALSE;
- if (strstr(str, "Sink"))
- enabled.sink = FALSE;
- if (strstr(str, "Source"))
- enabled.source = FALSE;
- if (strstr(str, "Control"))
- enabled.control = FALSE;
- if (strstr(str, "Target"))
- enabled.target = FALSE;
- g_free(str);
- }
-
- no_hfp = g_key_file_get_boolean(keyfile, "Headset", "DisableHFP",
- &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else
- disable_hfp = no_hfp;
-
- str = g_key_file_get_string(keyfile, "A2DP", "SourceCount", &err);
- if (err) {
- debug("%s: %s", file, err->message);
- g_error_free(err);
- err = NULL;
- } else {
- source_count = atoi(str);
- g_free(str);
- }
-
- debug("Config options: DisableHFP=%s, SCORouting=%s, SourceCount=%d",
- disable_hfp ? "true" : "false",
- sco_hci ? "HCI" : "PCM", source_count);
-
- g_key_file_free(keyfile);
+ return keyfile;
}
int main(int argc, char *argv[])
{
DBusConnection *conn;
struct sigaction sa;
+ GKeyFile *config;
start_logging("audio", "Bluetooth Audio daemon");
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_NOCLDSTOP;
@@ -178,11 +83,11 @@ int main(int argc, char *argv[])
sigaction(SIGCHLD, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
enable_debug();
- read_config(CONFIGDIR "/audio.conf");
+ config = load_config_file(CONFIGDIR "/audio.conf");
main_loop = g_main_loop_new(NULL, FALSE);
conn = dbus_bus_system_setup_with_main_loop(NULL, NULL, NULL);
if (!conn) {
@@ -193,18 +98,19 @@ int main(int argc, char *argv[])
if (unix_init() < 0) {
error("Unable to setup unix socket");
exit(1);
}
- if (audio_init(conn, &enabled, disable_hfp, sco_hci,
- source_count) < 0) {
+ if (audio_init(conn, config) < 0) {
error("Audio init failed!");
exit(1);
}
if (argc > 1 && !strcmp(argv[1], "-s"))
register_external_service(conn, "audio", "Audio service", "");
+ if (config)
+ g_key_file_free(config);
g_main_loop_run(main_loop);
audio_exit();
[-- Attachment #3: Type: text/plain, Size: 228 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
[-- Attachment #4: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-01-15 20:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-15 2:20 [Bluez-devel] [PATCH] Resubmission of Fixes in rfcomm tty Denis KENZIOR
2008-01-15 20:34 ` [Bluez-devel] [HFP][PATCH] HFP options in audio.conf Alok
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox