All of lore.kernel.org
 help / color / mirror / Atom feed
* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.