[Gateway] Initial Patch

Alok <[email protected]>
Newsgroups gmane.linux.bluez.devel
Message-ID <1208256550.28663.5.camel@greatbear>
Johan, 

Here is the initial patch for gateway. 
This patch includes: 

Removal of "Enabled" option checking. 
Name changed for hs_server/hf_server.
Initial gateway framework.

Let me know.

-Alok.

-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference 
Don't miss this year's exciting event. There's still time to save $100. 
Use priority code J8TL2D2. 
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone

_______________________________________________
Bluez-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bluez-devel
patch (text/x-patch, 10.8 KB)
Index: manager.c
===================================================================
RCS file: /cvsroot/bluez/utils/audio/manager.c,v
retrieving revision 1.96
diff -u -5 -p -r1.96 manager.c
--- manager.c	27 Mar 2008 23:07:19 -0000	1.96
+++ manager.c	15 Apr 2008 10:47:16 -0000
@@ -100,15 +100,19 @@ static DBusConnection *connection = NULL
 static struct device *default_hs = NULL;
 static struct device *default_dev = NULL;
 
 static GSList *devices = NULL;
 
-static uint32_t hs_record_id = 0;
-static uint32_t hf_record_id = 0;
+static uint32_t hsp_ag_record_id = 0;
+static uint32_t hfp_ag_record_id = 0;
 
-static GIOChannel *hs_server = NULL;
-static GIOChannel *hf_server = NULL;
+static uint32_t hsp_hs_record_id = 0;
+
+static GIOChannel *hsp_ag_server = NULL; /*Headset Gateway server*/
+static GIOChannel *hfp_ag_server = NULL; /*Hands-free Gateway server*/
+
+static GIOChannel *hsp_hs_server = NULL;
 
 static struct enabled_interfaces enabled = {
 	.headset	= TRUE,
 	.gateway	= FALSE,
 	.sink		= TRUE,
@@ -224,14 +228,14 @@ gboolean server_is_enabled(uint16_t svc)
 {
 	gboolean ret;
 
 	switch (svc) {
 	case HEADSET_SVCLASS_ID:
-		ret = (hs_server != NULL);
+		ret = (hsp_ag_server != NULL);
 		break;
 	case HANDSFREE_SVCLASS_ID:
-		ret = (hf_server != NULL);
+		ret = (hfp_ag_server != NULL);
 		break;
 	case AUDIO_SINK_SVCLASS_ID:
 		return enabled.sink;
 	case AV_REMOTE_TARGET_SVCLASS_ID:
 	case AV_REMOTE_SVCLASS_ID:
@@ -1180,12 +1184,12 @@ static sdp_record_t *hsp_ag_record(uint8
 		return NULL;
 
 	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
 	root = sdp_list_append(0, &root_uuid);
 	sdp_set_browse_groups(record, root);
-
 	sdp_uuid16_create(&svclass_uuid, HEADSET_AGW_SVCLASS_ID);
+
 	svclass_id = sdp_list_append(0, &svclass_uuid);
 	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
 	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
 	sdp_set_service_classes(record, svclass_id);
 
@@ -1204,11 +1208,10 @@ static sdp_record_t *hsp_ag_record(uint8
 	proto[1] = sdp_list_append(proto[1], channel);
 	apseq = sdp_list_append(apseq, proto[1]);
 
 	aproto = sdp_list_append(0, apseq);
 	sdp_set_access_protos(record, aproto);
-
 	sdp_set_info_attr(record, "Headset Audio Gateway", 0, 0);
 
 	sdp_data_free(channel);
 	sdp_list_free(proto[0], 0);
 	sdp_list_free(proto[1], 0);
@@ -1219,10 +1222,65 @@ static sdp_record_t *hsp_ag_record(uint8
 	sdp_list_free(svclass_id, 0);
 
 	return record;
 }
 
+static sdp_record_t *hsp_hs_record(uint8_t ch)
+{
+	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
+	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
+	uuid_t l2cap_uuid, rfcomm_uuid;
+	sdp_profile_desc_t profile;
+	sdp_record_t *record;
+	sdp_list_t *aproto, *proto[2];
+	sdp_data_t *channel;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
+	root = sdp_list_append(0, &root_uuid);
+	sdp_set_browse_groups(record, root);
+	sdp_uuid16_create(&svclass_uuid, HEADSET_SVCLASS_ID);
+
+	svclass_id = sdp_list_append(0, &svclass_uuid);
+	sdp_uuid16_create(&ga_svclass_uuid, GENERIC_AUDIO_SVCLASS_ID);
+	svclass_id = sdp_list_append(svclass_id, &ga_svclass_uuid);
+	sdp_set_service_classes(record, svclass_id);
+
+	sdp_uuid16_create(&profile.uuid, HEADSET_PROFILE_ID);
+	profile.version = 0x0100;
+	pfseq = sdp_list_append(0, &profile);
+	sdp_set_profile_descs(record, pfseq);
+
+	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
+	proto[0] = sdp_list_append(0, &l2cap_uuid);
+	apseq = sdp_list_append(0, proto[0]);
+
+	sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
+	proto[1] = sdp_list_append(0, &rfcomm_uuid);
+	channel = sdp_data_alloc(SDP_UINT8, &ch);
+	proto[1] = sdp_list_append(proto[1], channel);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(0, apseq);
+	sdp_set_access_protos(record, aproto);
+	sdp_set_info_attr(record, "Headset", 0, 0);
+
+	sdp_data_free(channel);
+	sdp_list_free(proto[0], 0);
+	sdp_list_free(proto[1], 0);
+	sdp_list_free(apseq, 0);
+	sdp_list_free(pfseq, 0);
+	sdp_list_free(aproto, 0);
+	sdp_list_free(root, 0);
+	sdp_list_free(svclass_id, 0);
+
+	return record;
+}
+
 static sdp_record_t *hfp_ag_record(uint8_t ch, uint32_t feat)
 {
 	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
 	uuid_t root_uuid, svclass_uuid, ga_svclass_uuid;
 	uuid_t l2cap_uuid, rfcomm_uuid;
@@ -1348,11 +1406,11 @@ static gboolean ag_io_cb(GIOChannel *cha
 	if (cli_sk < 0) {
 		error("accept: %s (%d)", strerror(errno), errno);
 		return TRUE;
 	}
 
-	if (chan == hs_server) {
+	if (chan == hsp_ag_server) {
 		hfp_active = FALSE;
 		uuid = HSP_AG_UUID;
 	} else {
 		hfp_active = TRUE;
 		uuid = HFP_AG_UUID;
@@ -1389,10 +1447,16 @@ failed:
 	headset_close_rfcomm(device);
 
 	return TRUE;
 }
 
+static gboolean hs_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+{
+	/*Stub*/
+	return TRUE;
+}
+
 static GIOChannel *server_socket(uint8_t *channel, gboolean master)
 {
 	int sock, lm;
 	struct sockaddr_rc addr;
 	socklen_t sa_len;
@@ -1452,11 +1516,11 @@ static int headset_server_init(DBusConne
 	sdp_record_t *record;
 	gboolean hfp = TRUE, master = TRUE;
 	GError *err = NULL;
 	uint32_t features;
 
-	if (!(enabled.headset || enabled.gateway))
+	if (!enabled.headset)
 		return 0;
 
 	if (config) {
 		gboolean tmp;
 
@@ -1477,12 +1541,12 @@ static int headset_server_init(DBusConne
 			err = NULL;
 		} else
 			hfp = tmp;
 	}
 
-	hs_server = server_socket(&chan, master);
-	if (!hs_server)
+	hsp_ag_server = server_socket(&chan, master);
+	if (!hsp_ag_server)
 		return -1;
 
 	record = hsp_ag_record(chan);
 	if (!record) {
 		error("Unable to allocate new service record");
@@ -1490,28 +1554,28 @@ static int headset_server_init(DBusConne
 	}
 
 	if (add_record_to_server(BDADDR_ANY, record) < 0) {
 		error("Unable to register HS AG service record");
 		sdp_record_free(record);
-		g_io_channel_unref(hs_server);
-		hs_server = NULL;
+		g_io_channel_unref(hsp_ag_server);
+		hsp_ag_server = NULL;
 		return -1;
 	}
-	hs_record_id = record->handle;
+	hsp_ag_record_id = record->handle;
 
-	g_io_add_watch(hs_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	g_io_add_watch(hsp_ag_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 				(GIOFunc) ag_io_cb, NULL);
 
 	features = headset_config_init(config);
 
 	if (!hfp)
 		return 0;
 
 	chan = DEFAULT_HF_AG_CHANNEL;
 
-	hf_server = server_socket(&chan, master);
-	if (!hf_server)
+	hfp_ag_server = server_socket(&chan, master);
+	if (!hfp_ag_server)
 		return -1;
 
 	record = hfp_ag_record(chan, features);
 	if (!record) {
 		error("Unable to allocate new service record");
@@ -1519,42 +1583,100 @@ static int headset_server_init(DBusConne
 	}
 
 	if (add_record_to_server(BDADDR_ANY, record) < 0) {
 		error("Unable to register HF AG service record");
 		sdp_record_free(record);
-		g_io_channel_unref(hf_server);
-		hf_server = NULL;
+		g_io_channel_unref(hfp_ag_server);
+		hfp_ag_server = NULL;
 		return -1;
 	}
-	hf_record_id = record->handle;
+	hfp_ag_record_id = record->handle;
 
-	g_io_add_watch(hf_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+	g_io_add_watch(hfp_ag_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
 			(GIOFunc) ag_io_cb, NULL);
 
 	return 0;
 }
 
+static int gateway_server_init(DBusConnection *conn, GKeyFile *config)
+{
+	uint8_t chan = DEFAULT_HSP_HS_CHANNEL;
+	sdp_record_t *record;
+	gboolean master = TRUE;
+	GError *err = NULL;
+
+	if (!enabled.gateway)
+		return 0;
+
+	if (config) {
+		gboolean tmp;
+
+		tmp = g_key_file_get_boolean(config, "General", "Master",
+						&err);
+		if (err) {
+			debug("audio.conf: %s", err->message);
+			g_error_free(err);
+			err = NULL;
+		} else
+			master = tmp;
+	}
+
+	hsp_hs_server = server_socket(&chan, master);
+	if (!hsp_hs_server)
+		return -1;
+
+	record = hsp_hs_record(chan);
+	if (!record) {
+		error("Unable to allocate new service record");
+		return -1;
+	}
+
+	if (add_record_to_server(BDADDR_ANY, record) < 0) {
+		error("Unable to register HSP HS service record");
+		sdp_record_free(record);
+		g_io_channel_unref(hsp_hs_server);
+		hsp_hs_server = NULL;
+		return -1;
+	}
+	hsp_hs_record_id = record->handle;
+
+	g_io_add_watch(hsp_hs_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				(GIOFunc) hs_io_cb, NULL);
+	debug("ALOK:Gateway");
+	return 0;
+}
+
 static void server_exit(void)
 {
-	if (hs_record_id) {
-		remove_record_from_server(hs_record_id);
-		hs_record_id = 0;
+	if (hsp_ag_record_id) {
+		remove_record_from_server(hsp_ag_record_id);
+		hsp_ag_record_id = 0;
 	}
 
-	if (hs_server) {
-		g_io_channel_unref(hs_server);
-		hs_server = NULL;
+	if (hsp_ag_server) {
+		g_io_channel_unref(hsp_ag_server);
+		hsp_ag_server = NULL;
 	}
 
-	if (hf_record_id) {
-		remove_record_from_server(hf_record_id);
-		hf_record_id = 0;
+	if (hsp_hs_record_id) {
+		remove_record_from_server(hsp_hs_record_id);
+		hsp_hs_record_id = 0;
 	}
 
-	if (hf_server) {
-		g_io_channel_unref(hf_server);
-		hf_server = NULL;
+	if (hsp_hs_server) {
+		g_io_channel_unref(hsp_hs_server);
+		hsp_hs_server = NULL;
+	}
+
+	if (hfp_ag_record_id) {
+		remove_record_from_server(hfp_ag_record_id);
+		hfp_ag_record_id = 0;
+	}
+
+	if (hfp_ag_server) {
+		g_io_channel_unref(hfp_ag_server);
+		hfp_ag_server = NULL;
 	}
 }
 
 int audio_manager_init(DBusConnection *conn, GKeyFile *config)
 {
@@ -1562,30 +1684,10 @@ int audio_manager_init(DBusConnection *c
 	GError *err = NULL;
 
 	connection = dbus_connection_ref(conn);
 
 	if (config) {
-		str = g_key_file_get_string(config, "General", "Enable", &err);
-
-		if (err) {
-			debug("audio.conf: %s", 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;
-			g_free(str);
-		}
-
 		str = g_key_file_get_string(config, "General", "Disable", &err);
 
 		if (err) {
 			debug("audio.conf: %s", err->message);
 			g_error_free(err);
@@ -1614,10 +1716,15 @@ int audio_manager_init(DBusConnection *c
 	if (enabled.headset) {
 		if (headset_server_init(conn, config) < 0)
 			goto failed;
 	}
 
+	if (enabled.gateway) {
+		if (gateway_server_init(conn, config) < 0)
+			goto failed;
+	}
+
 	if (enabled.source || enabled.sink) {
 		if (a2dp_init(conn, config) < 0)
 			goto failed;
 	}
 
Index: gateway.h
===================================================================
RCS file: /cvsroot/bluez/utils/audio/gateway.h,v
retrieving revision 1.8
diff -u -5 -p -r1.8 gateway.h
--- gateway.h	2 Feb 2008 03:37:05 -0000	1.8
+++ gateway.h	15 Apr 2008 10:47:16 -0000
@@ -22,10 +22,13 @@
  *
  */
 
 #define AUDIO_GATEWAY_INTERFACE "org.bluez.audio.Gateway"
 
+#define DEFAULT_HSP_HS_CHANNEL 6
+#define DEFAULT_HFP_HS_CHANNEL 7
+
 int gateway_init(DBusConnection *conn, gboolean disable_hfp, gboolean sco_hci);
 
 void gateway_exit(void);
 
 gboolean gateway_is_enabled(uint16_t svc);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.