* [Bluez-devel] plugin tries
@ 2007-12-13 14:14 Frédéric Dalleau
2007-12-13 14:16 ` Frédéric Dalleau
2007-12-14 0:10 ` [Bluez-devel] [PATCH] HFP - Audio Gateway Features Alok
0 siblings, 2 replies; 3+ messages in thread
From: Frédéric Dalleau @ 2007-12-13 14:14 UTC (permalink / raw)
To: BlueZ development
[-- Attachment #1: Type: text/plain, Size: 425 bytes --]
alok,
This is my first try to implement a plugin that would handle hfp the ALP
way.
Makefile.am is modified to build a library from hf_plugin_alp.*.
main.c reads a string containing the path of the library.
device.h is modified to keep a pointer to a plugin instance.
hf_plugin.c|h wraps plugin loading and calls (see the init func).
hf_plugin_alp.c|h are the plugin itself.
all this probably won't build...
Frederic
[-- Attachment #2: hf_plugin_alp.c --]
[-- Type: text/x-csrc, Size: 4743 bytes --]
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2007 Access Systems Inc. <http://www.access-company.com>
* Copyright (C) 2004-2007 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 <fcntl.h>
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include "device.h"
#include "manager.h"
#include "headset.h"
#include "hf_plugin.h"
#include "hf_plugin_alp.h"
/***********************************************************************
*
* Methods implementation
*
***********************************************************************/
/***********************************************************************
*
* DBUS Method Handler
*
***********************************************************************/
///////////////////////////////////////////////////////////////////////////////
static DBusHandlerResult dbus_handler_HSHF_func(DBusConnection * connection, DBusMessage * message, void *user_data)
///////////////////////////////////////////////////////////////////////////////
{
UNUSED_PARAMETER(user_data);
if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
dbus_connection_unref(connection);
connection = NULL;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int hf_plugin_alp_init(void** pag)
{
int result;
DBusError error;
*pag = NULL;
dbus_error_init(&error);
g_message("%s [%s %s] starting ...", __FUNCTION__, __DATE__, __TIME__);
connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (connection == NULL)
{
g_critical("hshfgd: *** Failed to open connection to activating message bus: %s", error.message);
goto failed;
}
g_message("hshfgd: Register object path");
if (!dbus_connection_register_object_path(connection, hshfserver_object_path, &dbus_vtable_hshfserver, NULL))
{
g_critical("hshfgd: *** Failed to register object path");
goto failed;
}
g_message("hshfgd: Acquire service: " HSHF_SERVICE_NAME);
result = dbus_bus_request_name(connection, HSHF_SERVICE_NAME, 0, &error);
if (dbus_error_is_set(&error))
{
g_critical("hshfgd: *** Failed to acquire service: %s", error.message);
goto failed;
}
dbus_error_free(&error);
return 0;
failed:
dbus_error_free(&error);
return -ENOTCONN;
}
void hf_plugin_alp_exit(void* ag)
{
g_message("%s [%s %s] exiting ...", __FUNCTION__, __DATE__, __TIME__);
}
void hf_plugin_alp_state_changed(int state, int type)
{
gchar *stateP = NULL;
gchar *profileP;
g_message("%s", __FUNCTION__);
switch (state)
{
case HEADSET_STATE_DISCONNECTED:
stateP = HSHF_DISCONNECTED;
break;
case HEADSET_STATE_CONNECT_IN_PROGRESS:
stateP = HSHF_CONNECTING;
break;
case HEADSET_STATE_CONNECTED:
stateP = HSHF_CONNECTED;
break;
case HEADSET_STATE_PLAY_IN_PROGRESS:
stateP = HSHF_AUDIO_CONNECTING;
break;
case HEADSET_STATE_PLAYING:
stateP = HSHF_AUDIO_CONNECTED;
break;
default:
stateP = HSHF_DISCONNECTED;
}
switch (type)
{
case SVC_HEADSET:
profileP = HEADSET_PROFILE;
break;
case SVC_HANDSFREE:
profileP = HANDSFREE_PROFILE;
break;
default:
profileP = NO_PROFILE;
}
if(connection && hshfclient_name && hshfclient_object_path)
{
g_message("%s", __FUNCTION__);
DBusMessage* msg = dbus_message_new_method_call(hshfclient_name, hshfclient_object_path, HSHFCLIENT_INTERFACE_NAME, "StateChange");
if(msg) {
if (dbus_message_append_args (msg,
G_TYPE_STRING, stateP,
G_TYPE_STRING, profileP,
G_TYPE_UCHAR, 0,
DBUS_TYPE_INVALID)) {
// In case this gets fired off after we've disconnected.
if (dbus_connection_get_is_connected (connection)) {
dbus_connection_send (connection, msg, NULL);
}
}
dbus_message_unref(msg);
}
}
}
[-- Attachment #3: hf_plugin_alp.h --]
[-- Type: text/x-chdr, Size: 991 bytes --]
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2007 Access Systems Inc. <http://www.access-company.com>
* Copyright (C) 2004-2007 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
[-- Attachment #4: hf_plugin.c --]
[-- Type: text/x-csrc, Size: 3297 bytes --]
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2007 Access Systems Inc. <http://www.access-company.com>
* Copyright (C) 2004-2007 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 <dlfcn.h>
#include <errno.h>
#include <string.h>
#include "hf_plugin.h"
#include "logging.h"
struct hf_service {
int (*ag_state_changed_cb)(int state);
int (*ag_indicate_call_cb)(int incoming);
int (*ag_set_indicator_cb)(hf_indicator_t indicator, int value);
int (*ag_cancel_call_cb)();
int (*ag_event_cb)(int event, void *param);
};
struct hf_ag {
struct hf_service service;
void *handle;
void *data;
int (* init)(void **plg);
void (* exit)(void *plg);
void (* state_changed)(int state, int type);
};
void* hf_plugin_init(char* filename)
{
struct hf_ag *plg;
char funcname[512];
char *basename, *dot;
if(!filename || !*filename)
return NULL;
plg = malloc(sizeof(struct hf_ag));
if(!plg)
return NULL;
memset(plg, 0, sizeof(struct hf_ag));
info("%s(%s)", __FUNCTION__, filename);
plg->handle = dlopen (filename, RTLD_NOW);
if(!plg->handle)
goto failed;
basename = strrchr(filename, '/');
if(basename)
basename++;
else
basename = filename;
if(strncmp(basename, "lib", 3)==0)
basename += 3;
dot = strrchr(basename, '.');
if(dot)
*dot = '\0';
sprintf(funcname, "%s_exit", basename);
debug("loading func %s", funcname);
plg->exit = dlsym(plg->handle, funcname);
if(!plg->exit)
goto failed;
sprintf(funcname, "%s_init", basename);
debug("loading func %s", funcname);
plg->init = dlsym(plg->handle, funcname);
if(!plg->init)
goto failed;
sprintf(funcname, "%s_state_changed", basename);
debug("loading func %s", funcname);
plg->state_changed = dlsym(plg->handle, funcname);
if(!plg->state_changed)
goto failed;
if(plg->init(&plg->data)<0)
goto failed;
debug("%s successful", funcname);
return plg;
failed:
error("plugin load failed (error:%s, dlerror:%s)", strerror(errno), dlerror());
hf_plugin_exit(plg);
return NULL;
}
void hf_plugin_exit(void *plugin)
{
struct hf_ag *plg = (struct hf_ag*)plugin;
info("%s", __FUNCTION__);
if(!plg)
return;
if(plg->exit)
plg->exit(plg->data);
if(plg->handle)
dlclose (plg->handle);
free(plg);
}
void hf_plugin_state_changed(void *plugin, int state, int type)
{
struct hf_ag *plg = (struct hf_ag*)plugin;
info("%s(%d, %d)", __FUNCTION__, state, type);
if(plg->state_changed)
plg->state_changed(state, type);
}
[-- Attachment #5: hf_plugin.h --]
[-- Type: text/x-chdr, Size: 1103 bytes --]
/*
*
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2007 Access Systems Inc. <http://www.access-company.com>
* Copyright (C) 2004-2007 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
*
*/
#include <stdint.h>
void *hf_plugin_init(char *filename);
void hf_plugin_exit(void *plugin);
void hf_plugin_state_changed(void *plugin, int state, int type);
[-- Attachment #6: hfp_plugin.patch --]
[-- Type: text/x-patch, Size: 14380 bytes --]
Index: headset.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/headset.c,v
retrieving revision 1.143
diff -u -r1.143 headset.c
--- headset.c 23 Oct 2007 17:17:47 -0000 1.143
+++ headset.c 13 Dec 2007 11:14:47 -0000
@@ -56,6 +56,7 @@
#include "manager.h"
#include "error.h"
#include "headset.h"
+#include "hf_plugin.h"
#define RING_INTERVAL 3000
@@ -172,15 +173,23 @@
static headset_event_t parse_headset_event(const char *buf, char *rsp,
int rsp_len)
{
- printf("Received: %s\n", buf);
+ debug("Received: %s", buf);
- /* Return an error if this is not a proper AT command */
- if (strncmp(buf, "AT", 2)) {
- snprintf(rsp, rsp_len, "\r\nERROR\r\n");
- return HEADSET_EVENT_INVALID;
+ if (!strncmp(buf, "+", 1)) {
+ buf += 1;
+ goto parse_at_event;
+ }
+
+ if (!strncmp(buf, "AT", 2)) {
+ buf += 2;
+ goto parse_at_command;
}
- buf += 2;
+ /* Return an error if this is not a proper AT command */
+ snprintf(rsp, rsp_len, "\r\nERROR\r\n");
+ return HEADSET_EVENT_INVALID;
+
+parse_at_command:
if (!strncmp(buf, "+CKPD", 5)) {
snprintf(rsp, rsp_len, "\r\nOK\r\n");
@@ -188,10 +197,52 @@
} else if (!strncmp(buf, "+VG", 3)) {
snprintf(rsp, rsp_len, "\r\nOK\r\n");
return HEADSET_EVENT_GAIN;
- } else {
- snprintf(rsp, rsp_len, "\r\nERROR\r\n");
- return HEADSET_EVENT_UNKNOWN;
+ } else if (!strncmp(buf, "A", 1)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_CALL_ANSWERED;
+ } else if (!strncmp(buf, "D", 1)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_DIAL_NUMBER;
+ } else if (!strncmp(buf, "H", 1)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_CALL_HANGUP;
+ } else if (!strncmp(buf, "+BRSF=", 6)) {
+ snprintf(rsp, rsp_len, "\r\n+BRSF:127\r\n");
+ snprintf(rsp+strlen(rsp), rsp_len-strlen(rsp), "\r\nOK\r\n");
+ return HEADSET_EVENT_BRSF;
+ } else if (!strncmp(buf, "+CIND=?", 7)) {
+ snprintf(rsp, rsp_len, "\r\n+CIND:\r\n");
+ snprintf(rsp+strlen(rsp), rsp_len-strlen(rsp), "\r\nOK\r\n");
+ return HEADSET_EVENT_CIND_TEST;
+ } else if (!strncmp(buf, "+CIND", 5)) {
+ snprintf(rsp, rsp_len, "\r\n+CIND:\r\n");
+ snprintf(rsp+strlen(rsp), rsp_len-strlen(rsp), "\r\nOK\r\n");
+ return HEADSET_EVENT_CIND_READ;
+ } else if (!strncmp(buf, "+CMER=", 6)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_CMER;
+ } else if (!strncmp(buf, "+CHLD=?", 7)) {
+ snprintf(rsp, rsp_len, "\r\n+CHLD: 1,2,3,4,1x,2\r\n");
+ snprintf(rsp+strlen(rsp), rsp_len-strlen(rsp), "\r\nOK\r\n");
+ return HEADSET_EVENT_CHLD_TEST;
+ }
+
+ return HEADSET_EVENT_UNKNOWN;
+
+parse_at_event:
+
+ if (!strncmp(buf, "VGS", 3)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_SPEAKER_VOLUME;
}
+
+ if (!strncmp(buf, "VGM", 3)) {
+ snprintf(rsp, rsp_len, "\r\nOK\r\n");
+ return HEADSET_EVENT_MICROPHONE_VOLUME;
+ }
+
+ /* Just ignore, no error */
+ return HEADSET_EVENT_INVALID;
}
static void close_sco(struct device *device)
@@ -261,7 +312,6 @@
case HEADSET_EVENT_GAIN:
hs_signal_gain_setting(device, &hs->buf[hs->data_start] + 2);
break;
-
case HEADSET_EVENT_KEYPRESS:
if (hs->ring_timer) {
g_source_remove(hs->ring_timer);
@@ -274,6 +324,79 @@
DBUS_TYPE_INVALID);
break;
+ case HEADSET_EVENT_STATE_CHANGE:
+ debug("HEADSET_EVENT_STATE_CHANGE");
+ hf_plugin_state_changed(device->plugin, device->headset->state, device->headset->type);
+ break;
+ case HEADSET_EVENT_REMOTE_VOLUME:
+ debug("HEADSET_EVENT_REMOTE_VOLUME");
+ break;
+ case HEADSET_EVENT_SUPPORTED_FEATURES:
+ debug("HEADSET_EVENT_SUPPORTED_FEATURES");
+ break;
+ case HEADSET_EVENT_SPEAKER_VOLUME:
+ hs_signal_gain_setting(device, &hs->buf[hs->data_start] + 0);
+ break;
+ case HEADSET_EVENT_MICROPHONE_VOLUME:
+ hs_signal_gain_setting(device, &hs->buf[hs->data_start] + 0);
+ break;
+ case HEADSET_EVENT_CALL_ANSWERED:
+ debug("HEADSET_EVENT_CALL_ANSWERED");
+ break;
+ case HEADSET_EVENT_CALL_HANGUP:
+ debug("HEADSET_EVENT_CALL_HANGUP");
+ break;
+ case HEADSET_EVENT_DIAL_NUMBER:
+ debug("HEADSET_EVENT_DIAL_NUMBER");
+ break;
+ case HEADSET_EVENT_DIAL_MEMORY:
+ debug("HEADSET_EVENT_DIAL_MEMORY");
+ break;
+ case HEADSET_EVENT_CALL_HOLD:
+ debug("HEADSET_EVENT_CALL_HOLD");
+ break;
+ case HEADSET_EVENT_DTMF:
+ debug("HEADSET_EVENT_DTMF");
+ break;
+ case HEADSET_EVENT_GET_PHONE_NUMBER:
+ debug("HEADSET_EVENT_GET_PHONE_NUMBER");
+ break;
+ case HEADSET_EVENT_DIAL_LAST_NUMBER:
+ debug("HEADSET_EVENT_DIAL_LAST_NUMBER");
+ break;
+ case HEADSET_EVENT_VOICE_RECOGNITION:
+ debug("HEADSET_EVENT_VOICE_RECOGNITION");
+ break;
+ case HEADSET_EVENT_ECNR:
+ debug("HEADSET_EVENT_ECNR");
+ break;
+ case HEADSET_EVENT_RESPONSE_HOLD:
+ debug("HEADSET_EVENT_RESPONSE_HOLD");
+ break;
+ case HEADSET_EVENT_LIST_CURRENT_CALLS:
+ debug("HEADSET_EVENT_LIST_CURRENT_CALLS");
+ break;
+ case HEADSET_EVENT_COMMAND:
+ debug("HEADSET_EVENT_COMMAND");
+ break;
+ case HEADSET_EVENT_BRSF:
+ debug("HEADSET_EVENT_BRSF");
+ break;
+ case HEADSET_EVENT_CIND_TEST:
+ debug("HEADSET_EVENT_CIND_TEST");
+ break;
+ case HEADSET_EVENT_CIND_READ:
+ debug("HEADSET_EVENT_CIND_READ");
+ break;
+ case HEADSET_EVENT_CMER:
+ debug("HEADSET_EVENT_CMER");
+ if(device->headset->type == SVC_HEADSET)
+ headset_set_state(device, HEADSET_STATE_CONNECTED);
+ break;
+ case HEADSET_EVENT_CHLD_TEST:
+ debug("HEADSET_EVENT_CHLD_TEST");
+ break;
+
case HEADSET_EVENT_INVALID:
case HEADSET_EVENT_UNKNOWN:
default:
@@ -546,7 +669,8 @@
hs->rfcomm = chan;
c->io = NULL;
- headset_set_state(device, HEADSET_STATE_CONNECTED);
+ if(device->headset->type == SVC_HEADSET)
+ headset_set_state(device, HEADSET_STATE_CONNECTED);
debug("%s: Connected to %s", device->path, hs_address);
@@ -571,9 +695,10 @@
g_slist_foreach(hs->pending, (GFunc) pending_connect_failed, device);
g_slist_free(hs->pending);
hs->pending = NULL;
- if (hs->rfcomm)
- headset_set_state(device, HEADSET_STATE_CONNECTED);
- else
+ if (hs->rfcomm) {
+ if(device->headset->type == SVC_HEADSET)
+ headset_set_state(device, HEADSET_STATE_CONNECTED);
+ } else
headset_set_state(device, HEADSET_STATE_DISCONNECTED);
return FALSE;
@@ -1593,6 +1718,8 @@
break;
}
+ hf_plugin_state_changed(dev->plugin, dev->headset->state, dev->headset->type);
+
debug("State changed %s: %s -> %s", dev->path, str_state[hs->state],
str_state[state]);
hs->state = state;
Index: headset.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/headset.h,v
retrieving revision 1.31
diff -u -r1.31 headset.h
--- headset.h 23 Oct 2007 17:17:47 -0000 1.31
+++ headset.h 13 Dec 2007 11:14:47 -0000
@@ -31,7 +31,33 @@
HEADSET_EVENT_KEYPRESS,
HEADSET_EVENT_GAIN,
HEADSET_EVENT_UNKNOWN,
- HEADSET_EVENT_INVALID
+ HEADSET_EVENT_INVALID,
+
+
+ HEADSET_EVENT_BRSF,
+ HEADSET_EVENT_CIND_READ,
+ HEADSET_EVENT_CIND_TEST,
+ HEADSET_EVENT_CMER,
+ HEADSET_EVENT_CHLD_TEST,
+ HEADSET_EVENT_CHLD,
+ HEADSET_EVENT_STATE_CHANGE,
+ HEADSET_EVENT_REMOTE_VOLUME,
+ HEADSET_EVENT_SUPPORTED_FEATURES,
+ HEADSET_EVENT_SPEAKER_VOLUME,
+ HEADSET_EVENT_MICROPHONE_VOLUME,
+ HEADSET_EVENT_CALL_ANSWERED,
+ HEADSET_EVENT_CALL_HANGUP,
+ HEADSET_EVENT_DIAL_NUMBER,
+ HEADSET_EVENT_DIAL_MEMORY,
+ HEADSET_EVENT_CALL_HOLD,
+ HEADSET_EVENT_DTMF,
+ HEADSET_EVENT_GET_PHONE_NUMBER,
+ HEADSET_EVENT_DIAL_LAST_NUMBER,
+ HEADSET_EVENT_VOICE_RECOGNITION,
+ HEADSET_EVENT_ECNR,
+ HEADSET_EVENT_RESPONSE_HOLD,
+ HEADSET_EVENT_LIST_CURRENT_CALLS,
+ HEADSET_EVENT_COMMAND,
} headset_event_t;
typedef enum {
Index: manager.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/manager.c,v
retrieving revision 1.80
diff -u -r1.80 manager.c
--- manager.c 24 Oct 2007 21:22:40 -0000 1.80
+++ manager.c 13 Dec 2007 11:14:47 -0000
@@ -62,6 +62,7 @@
#include "sink.h"
#include "control.h"
#include "manager.h"
+#include "hf_plugin.h"
typedef enum {
HEADSET = 1 << 0,
@@ -94,6 +95,8 @@
void *cb_data;
};
+static void* plugin = NULL;
+
static DBusConnection *connection = NULL;
static struct device *default_hs = NULL;
@@ -121,7 +124,7 @@
snprintf(path, sizeof(path) - 1,
"%s/device%d", AUDIO_MANAGER_PATH, device_id++);
- return device_register(connection, path, bda);
+ return device_register(connection, path, bda, plugin);
}
static void destroy_device(struct device *device)
@@ -1531,10 +1534,13 @@
uint8_t chan = DEFAULT_HS_AG_CHANNEL;
sdp_buf_t buf;
+ info("Enabling headset server (hs=%d,hf=%d)", enabled->headset, enabled->gateway);
+
if (!(enabled->headset || enabled->gateway))
return 0;
hs_server = server_socket(&chan);
+
if (!hs_server)
return -1;
@@ -1558,6 +1564,8 @@
if (no_hfp)
return 0;
+ info("Enabling handsfree server");
+
chan = DEFAULT_HF_AG_CHANNEL;
hf_server = server_socket(&chan);
@@ -1581,6 +1589,7 @@
g_io_add_watch(hf_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
(GIOFunc) ag_io_cb, NULL);
+ info("servers enabled");
return 0;
}
@@ -1608,10 +1617,12 @@
}
int audio_init(DBusConnection *conn, struct enabled_interfaces *enable,
- gboolean no_hfp, gboolean sco_hci, int source_count)
+ gboolean no_hfp, gboolean sco_hci, int source_count, char* plugin_path)
{
int sinks, sources;
+ plugin = hf_plugin_init(plugin_path);
+
connection = dbus_connection_ref(conn);
enabled = enable;
@@ -1662,6 +1673,7 @@
void audio_exit(void)
{
+
server_exit();
dbus_connection_destroy_object_path(connection, AUDIO_MANAGER_PATH);
@@ -1669,6 +1681,8 @@
dbus_connection_unref(connection);
connection = NULL;
+
+ hf_plugin_exit(plugin);
}
struct device *manager_default_device(void)
Index: manager.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/manager.h,v
retrieving revision 1.30
diff -u -r1.30 manager.h
--- manager.h 23 Oct 2007 17:17:47 -0000 1.30
+++ manager.h 13 Dec 2007 11:14:47 -0000
@@ -38,7 +38,7 @@
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);
+ gboolean no_hfp, gboolean sco_hci, int source_count, char* plugin_path);
void audio_exit(void);
Index: main.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/main.c,v
retrieving revision 1.28
diff -u -r1.28 main.c
--- main.c 24 Oct 2007 20:02:53 -0000 1.28
+++ main.c 13 Dec 2007 11:14:47 -0000
@@ -45,15 +45,16 @@
static gboolean disable_hfp = TRUE;
static gboolean sco_hci = TRUE;
static int source_count = 1;
+static char plugin_path[256] = {0};
static GMainLoop *main_loop = NULL;
static struct enabled_interfaces enabled = {
- .headset = TRUE,
+ .headset = FALSE,
.gateway = FALSE,
.sink = TRUE,
.source = FALSE,
- .control = FALSE,
+ .control = TRUE,
.target = FALSE,
};
@@ -144,6 +145,16 @@
} else
disable_hfp = no_hfp;
+ str = g_key_file_get_string(keyfile, "Headset", "HFPPluginPath", &err);
+ if (err) {
+ debug("%s: %s", file, err->message);
+ g_error_free(err);
+ err = NULL;
+ } else {
+ strncpy(plugin_path, str, sizeof(plugin_path)-1);
+ g_free(str);
+ }
+
str = g_key_file_get_string(keyfile, "A2DP", "SourceCount", &err);
if (err) {
debug("%s: %s", file, err->message);
@@ -154,8 +165,9 @@
g_free(str);
}
- debug("Config options: DisableHFP=%s, SCORouting=%s, SourceCount=%d",
+ debug("Config options: DisableHFP=%s, HFPPluginPath=%s, SCORouting=%s, SourceCount=%d",
disable_hfp ? "true" : "false",
+ plugin_path,
sco_hci ? "HCI" : "PCM", source_count);
g_key_file_free(keyfile);
@@ -196,7 +208,7 @@
}
if (audio_init(conn, &enabled, disable_hfp, sco_hci,
- source_count) < 0) {
+ source_count, plugin_path) < 0) {
error("Audio init failed!");
exit(1);
}
Index: Makefile.am
===================================================================
RCS file: /cvsroot/bluez/utils/audio/Makefile.am,v
retrieving revision 1.40
diff -u -r1.40 Makefile.am
--- Makefile.am 25 Oct 2007 10:33:03 -0000 1.40
+++ Makefile.am 13 Dec 2007 11:14:47 -0000
@@ -13,10 +13,18 @@
bluetoothd_service_audio_SOURCES = main.c \
manager.h manager.c headset.h headset.c ipc.h unix.h unix.c \
error.h error.c device.h device.c gateway.h gateway.c \
+ hf_plugin.c \
sink.c sink.h avdtp.c avdtp.h a2dp.c a2dp.h control.c control.h
bluetoothd_service_audio_LDADD = $(top_builddir)/common/libhelper.a \
- @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
+ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ -ldl
+
+hf_plugin_alpdir = $(libdir)
+hf_plugin_alp_LTLIBRARIES = libhf_plugin_alp.la
+libhf_plugin_alp_la_SOURCES = hf_plugin_alp.c
+libhf_plugin_alp_la_LDFLAGS = -module -avoid-version -export-dynamic
+libhf_plugin_alp_la_LIBADD = @GLIB_LIBS@ @DBUS_LIBS@ @DBUS_GLIB_LIBS@
+libhf_plugin_alp_la_CFLAGS = @GLIB_CFLAGS@ @DBUS_CFLAGS@ @DBUS_GLIB_CFLAGS@
if ALSA
alsadir = $(libdir)/alsa-lib
Index: device.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/device.c,v
retrieving revision 1.24
diff -u -r1.24 device.c
--- device.c 25 Oct 2007 10:38:47 -0000 1.24
+++ device.c 13 Dec 2007 11:14:47 -0000
@@ -273,7 +273,7 @@
}
struct device *device_register(DBusConnection *conn,
- const char *path, bdaddr_t *bda)
+ const char *path, bdaddr_t *bda, void* plugin)
{
struct device *dev;
bdaddr_t src;
@@ -310,6 +310,7 @@
return NULL;
}
+ dev->plugin = plugin;
dev->name = get_dev_name(conn, dev->adapter_path, bda);
dev->path = g_strdup(path);
bacpy(&dev->dst, bda);
Index: device.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/device.h,v
retrieving revision 1.15
diff -u -r1.15 device.h
--- device.h 25 Oct 2007 10:38:47 -0000 1.15
+++ device.h 13 Dec 2007 11:14:47 -0000
@@ -60,6 +60,7 @@
bdaddr_t store;
bdaddr_t src;
bdaddr_t dst;
+ void* plugin;
struct headset *headset;
struct gateway *gateway;
@@ -70,7 +71,7 @@
};
struct device *device_register(DBusConnection *conn,
- const char *path, bdaddr_t *bda);
+ const char *path, bdaddr_t *bda, void* plugin);
int device_store(struct device *device, gboolean is_default);
[-- Attachment #7: Type: text/plain, Size: 308 bytes --]
-------------------------------------------------------------------------
SF.Net email is sponsored by:
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 #8: 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] 3+ messages in thread
* Re: [Bluez-devel] plugin tries
2007-12-13 14:14 [Bluez-devel] plugin tries Frédéric Dalleau
@ 2007-12-13 14:16 ` Frédéric Dalleau
2007-12-14 0:10 ` [Bluez-devel] [PATCH] HFP - Audio Gateway Features Alok
1 sibling, 0 replies; 3+ messages in thread
From: Frédéric Dalleau @ 2007-12-13 14:16 UTC (permalink / raw)
To: BlueZ development
Well,
This wasn't meant for the list,
anyway, let me know if anything is interesting ;D
Frederic
-------------------------------------------------------------------------
SF.Net email is sponsored by:
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
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bluez-devel] [PATCH] HFP - Audio Gateway Features
2007-12-13 14:14 [Bluez-devel] plugin tries Frédéric Dalleau
2007-12-13 14:16 ` Frédéric Dalleau
@ 2007-12-14 0:10 ` Alok
1 sibling, 0 replies; 3+ messages in thread
From: Alok @ 2007-12-14 0:10 UTC (permalink / raw)
To: BlueZ development
[-- Attachment #1: Type: text/plain, Size: 212 bytes --]
Hello,
Sending a patch for the following :
1. Added AG's Feature definitions + BRSF response.
2. Modified headset_send() for variable args.
Let me know if anything needs to be fixed.
-Alok Barsode.
[-- Attachment #2: patch --]
[-- Type: text/x-patch, Size: 5192 bytes --]
diff --git a/audio/headset.c b/audio/headset.c
index e7425d5..ee9a57f 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -31,6 +31,7 @@
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <signal.h>
#include <string.h>
#include <getopt.h>
@@ -64,6 +65,17 @@
#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
+/*Audio Gateway features.Default is In-band Ringtone*/
+static unsigned int ag_features = AG_FEATURE_INBAND_RINGTONE;
+
static char *str_state[] = {
"HEADSET_STATE_DISCONNECTED",
"HEADSET_STATE_CONNECT_IN_PROGRESS",
@@ -120,21 +132,31 @@ struct event {
static int rfcomm_connect(struct device *device, struct pending_connect *c);
static int get_handles(struct device *device, struct pending_connect *c);
-static int headset_send(struct headset *hs, const char *str)
+static int headset_send(struct headset *hs, char *format, ...)
{
+ char rsp[BUF_SIZE];
+ va_list ap;
GIOError err;
gsize total_written, written, count;
+ int er;
+
+ va_start(ap, hs);
+ er = vsnprintf(rsp, sizeof(rsp), format, ap);
+ va_end(ap);
+
+ if (er < 0)
+ return -EINVAL;
if (hs->state < HEADSET_STATE_CONNECTED || !hs->rfcomm) {
error("headset_send: the headset is not connected");
return -EIO;
}
- count = strlen(str);
+ count = strlen(rsp);
written = total_written = 0;
while (total_written < count) {
- err = g_io_channel_write(hs->rfcomm, str + total_written,
+ err = g_io_channel_write(hs->rfcomm, rsp + total_written,
count - total_written, &written);
if (err != G_IO_ERROR_NONE)
return -errno;
@@ -150,8 +172,7 @@ static int supported_features(struct device *device, const char *buf)
int err;
hs->hfp_features = strtoul(&buf[8], NULL, 10);
-
- err = headset_send(hs, "\r\n+BRSF:0\r\n");
+ err = headset_send(hs, "\r\n+BRSF=%u\r\n", ag_features);
if (err < 0)
return err;
@@ -355,7 +376,7 @@ static gboolean rfcomm_io_cb(GIOChannel *chan, GIOCondition cond,
err = handle_event(device, &hs->buf[hs->data_start]);
if (err < 0)
error("Error handling command %s: %s (%d)", &hs->buf[hs->data_start],
- strerror(-err), -err);
+ strerror(-err), -err);
hs->data_start += cmd_len;
hs->data_length -= cmd_len;
@@ -1103,8 +1124,11 @@ error:
static gboolean ring_timer_cb(gpointer data)
{
struct device *device = data;
+ int err;
+
+ err = headset_send(device->headset, "\r\nRING\r\n");
- if (headset_send(device->headset, "\r\nRING\r\n") != G_IO_ERROR_NONE)
+ if (err)
error("Sending RING failed");
return TRUE;
@@ -1116,6 +1140,7 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg,
struct device *device = data;
struct headset *hs = device->headset;
DBusMessage *reply = NULL;
+ int err;
if (hs->state < HEADSET_STATE_CONNECTED)
return error_not_connected(conn, msg);
@@ -1129,7 +1154,8 @@ static DBusHandlerResult hs_ring(DBusConnection *conn, DBusMessage *msg,
goto done;
}
- if (headset_send(device->headset, "\r\nRING\r\n") != G_IO_ERROR_NONE) {
+ err = headset_send(device->headset, "\r\nRING\r\n");
+ if (err) {
dbus_message_unref(reply);
return error_failed(conn, msg, "Failed");
}
@@ -1261,7 +1287,7 @@ static DBusHandlerResult hs_set_gain(DBusConnection *conn,
DBusMessage *reply;
DBusError derr;
dbus_uint16_t gain;
- char str[13];
+ int err;
if (hs->state < HEADSET_STATE_CONNECTED)
return error_not_connected(conn, msg);
@@ -1286,10 +1312,8 @@ static DBusHandlerResult hs_set_gain(DBusConnection *conn,
if (hs->state != HEADSET_STATE_PLAYING)
goto done;
-
- snprintf(str, sizeof(str) - 1, "\r\n+VG%c=%u\r\n", type, gain);
-
- if (headset_send(device->headset, str) != G_IO_ERROR_NONE) {
+ err = headset_send(device->headset, "\r\n+VG%c=%u\r\n", type, gain);
+ if (err) {
dbus_message_unref(reply);
return error_failed(conn, msg, "Unable to send to headset");
}
@@ -1584,7 +1608,6 @@ int headset_close_rfcomm(struct device *dev)
void headset_set_state(struct device *dev, headset_state_t state)
{
struct headset *hs = dev->headset;
- char str[13];
if (hs->state == state)
return;
@@ -1629,17 +1652,11 @@ void headset_set_state(struct device *dev, headset_state_t state)
AUDIO_HEADSET_INTERFACE,
"Playing", DBUS_TYPE_INVALID);
- if (hs->sp_gain >= 0) {
- snprintf(str, sizeof(str) - 1, "\r\n+VGS=%u\r\n",
- hs->sp_gain);
- headset_send(hs, str);
- }
+ if (hs->sp_gain >= 0)
+ headset_send(hs, "\r\n+VGS=%u\r\n", hs->sp_gain);
- if (hs->mic_gain >= 0) {
- snprintf(str, sizeof(str) - 1, "\r\n+VGM=%u\r\n",
- hs->sp_gain);
- headset_send(hs, str);
- }
+ if (hs->mic_gain >= 0)
+ headset_send(hs, "\r\n+VGM=%u\r\n", hs->mic_gain);
break;
}
[-- Attachment #3: Type: text/plain, Size: 308 bytes --]
-------------------------------------------------------------------------
SF.Net email is sponsored by:
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 #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 related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2007-12-14 0:10 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-12-13 14:14 [Bluez-devel] plugin tries Frédéric Dalleau
2007-12-13 14:16 ` Frédéric Dalleau
2007-12-14 0:10 ` [Bluez-devel] [PATCH] HFP - Audio Gateway Features Alok
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).