Linux bluetooth development
 help / color / mirror / Atom feed
* Re: SCO Socket input.
From: Johan Hedberg @ 2010-10-06  9:59 UTC (permalink / raw)
  To: Pepe Aracil; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikqpge1KU4w4aQhtxz21097iQjWTKekdgg_+JeX@mail.gmail.com>

Hi,

On Wed, Oct 06, 2010, Pepe Aracil wrote:
> I have compiled bluez without audio support to avoid SCO socket be
> blocked by bluetoothd. Without positive results.
> 
> ¿Some idea?

Just to be sure you could add DisablePlugins=audio to
/etc/bluetooth/main.conf.

Johan

^ permalink raw reply

* SCO Socket input.
From: Pepe Aracil @ 2010-10-06  9:53 UTC (permalink / raw)
  To: linux-bluetooth

Hello.

If I create SCO socket listening input connections it not works if
bluetoothd is running but if I kill bluetoothd SCO input connections
works fine.

I need bluetoothd running for (mobile rfcomm connection) keys exchange
purposes but I must kill bluetoothd after rfcomm connection if i want
SCO input socket connections works well.

I have compiled bluez without audio support to avoid SCO socket be
blocked by bluetoothd. Without positive results.

¿Some idea?

Thanks

^ permalink raw reply

* RE: Sim Access profile server implementation
From: Waldemar.Rymarkiewicz @ 2010-10-06  9:32 UTC (permalink / raw)
  To: marcel
  Cc: suraj, linux-bluetooth, Jothikumar.Mothilal, joakim.xj.ceder,
	arunkr.singh
In-Reply-To: <99B09243E1A5DA4898CDD8B700111448097D01B6CF@EXMB04.eu.tieto.com>

[-- Attachment #1: Type: text/plain, Size: 516 bytes --]


Hi Marcel,

>>
>>Can you share that code with us. And also hardware if you. We 
>are still 
>>having hard time to find proper hardware to test this on.
>
>Will send a patch soon. I use 
>http://www.stericsson.com/platforms/U8500.jsp hw, but need to 
>check if I can share one with you.
>

Here you are the patch. Just note that it is based on an old bluez 4.4x
If you consider to accept the design I will update the patch upon the latest release. 

Will appreciate any comments.

Thanks,
/Waldek 

[-- Attachment #2: 0001-Add-Sim-Access-plugin.patch --]
[-- Type: application/octet-stream, Size: 95321 bytes --]

From 12f560c28fd3fe926d10639156e10d089dd26506 Mon Sep 17 00:00:00 2001
From: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
Date: Tue, 28 Sep 2010 17:24:19 +0200
Subject: [PATCH] Add Sim Access plugin

Sim Access plugin implements Sim Access Profile server role
according to the Bluetooth Sim Access Profile v1.1 specification.

Change-Id: I55e86dda969ae18339a134686ebf0b31a74ff335
---
 Makefile.am     |    2 +-
 acinclude.m4    |   13 +
 configure.ac    |    1 +
 sap/Android.mk  |   33 ++
 sap/Makefile.am |   25 +
 sap/main.c      |   57 +++
 sap/manager.c   |   98 ++++
 sap/manager.h   |   23 +
 sap/sap-dummy.c |   76 +++
 sap/sap-ste.c   | 1309 +++++++++++++++++++++++++++++++++++++++++++++++++
 sap/sap.h       |  200 ++++++++
 sap/server.c    | 1459 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sap/server.h    |   25 +
 13 files changed, 3320 insertions(+), 1 deletions(-)
 mode change 100644 => 100755 Makefile.am
 mode change 100644 => 100755 acinclude.m4
 mode change 100644 => 100755 configure.ac
 create mode 100644 sap/Android.mk
 create mode 100644 sap/Makefile.am
 create mode 100644 sap/main.c
 create mode 100644 sap/manager.c
 create mode 100644 sap/manager.h
 create mode 100644 sap/sap-dummy.c
 create mode 100644 sap/sap-ste.c
 create mode 100644 sap/sap.h
 create mode 100644 sap/server.c
 create mode 100644 sap/server.h

diff --git a/Makefile.am b/Makefile.am
old mode 100644
new mode 100755
index c4c6322..acea6bb
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
 
 SUBDIRS = include lib sbc gdbus common plugins src client\
-			network serial input audio tools \
+			network serial input audio tools sap\
 			rfcomm compat cups test scripts doc
 
 EXTRA_DIST = bluez.m4
diff --git a/acinclude.m4 b/acinclude.m4
old mode 100644
new mode 100755
index 248fed3..68962bc
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -197,6 +197,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	input_enable=yes
 	serial_enable=yes
 	network_enable=yes
+	sap_enable=yes
 	service_enable=yes
 	tools_enable=yes
 	hidd_enable=no
@@ -212,6 +213,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	udevrules_enable=yes
 	configfiles_enable=yes
 	telephony_driver=dummy
+	sap_driver=dummy
 
 	AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
 		optimization_enable=${enableval}
@@ -241,6 +243,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 		audio_enable=${enableval}
 	])
 
+	AC_ARG_ENABLE(sap, AC_HELP_STRING([--disable-sap], [disable sap plugin]), [
+		sap_enable=${enableval}
+	])
+
 	AC_ARG_ENABLE(service, AC_HELP_STRING([--disable-service], [disable service plugin]), [
 		service_enable=${enableval}
 	])
@@ -323,6 +329,12 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 
 	AC_SUBST([TELEPHONY_DRIVER], [telephony-${telephony_driver}.c])
 
+	AC_ARG_WITH(sap, AC_HELP_STRING([--with-sap=DRIVER], [select SIM Access driver]), [
+		sap_driver=${withval}
+	])
+
+	AC_SUBST([SAP_DRIVER], [sap-${sap_driver}.c])
+
 	if (test "${fortify_enable}" = "yes"); then
 		CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2"
 	fi
@@ -363,6 +375,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
 	AM_CONDITIONAL(INPUTPLUGIN, test "${input_enable}" = "yes")
 	AM_CONDITIONAL(SERIALPLUGIN, test "${serial_enable}" = "yes")
 	AM_CONDITIONAL(NETWORKPLUGIN, test "${network_enable}" = "yes")
+	AM_CONDITIONAL(SAPPLUGIN, test "${sap_enable}" = "yes")
 	AM_CONDITIONAL(SERVICEPLUGIN, test "${service_enable}" = "yes")
 	AM_CONDITIONAL(HIDD, test "${hidd_enable}" = "yes")
 	AM_CONDITIONAL(PAND, test "${pand_enable}" = "yes")
diff --git a/configure.ac b/configure.ac
old mode 100644
new mode 100755
index 85e1dae..512d032
--- a/configure.ac
+++ b/configure.ac
@@ -71,4 +71,5 @@ AC_OUTPUT([
 	src/bluetoothd.8
 	src/hcid.conf.5
 	bluez.pc
+	sap/Makefile
 ])
diff --git a/sap/Android.mk b/sap/Android.mk
new file mode 100644
index 0000000..d46837a
--- /dev/null
+++ b/sap/Android.mk
@@ -0,0 +1,33 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	manager.c \
+	server.c \
+	main.c \
+	sap-ste.c
+
+LOCAL_CFLAGS:= \
+	-DVERSION=\"4.47\"
+
+LOCAL_C_INCLUDES:= \
+	$(LOCAL_PATH)/../include \
+	$(LOCAL_PATH)/../common \
+	$(LOCAL_PATH)/../gdbus \
+	$(LOCAL_PATH)/../src \
+	$(call include-path-for, glib) \
+	$(call include-path-for, dbus)
+
+LOCAL_SHARED_LIBRARIES := \
+	libbluetoothd \
+	libbluetooth \
+	libdbus
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/bluez-plugin
+LOCAL_UNSTRIPPED_PATH := $(TARGET_OUT_SHARED_LIBRARIES_UNSTRIPPED)/bluez-plugin
+LOCAL_MODULE := sap
+LOCAL_PRELINK_MODULE := false
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/sap/Makefile.am b/sap/Makefile.am
new file mode 100644
index 0000000..2166cfc
--- /dev/null
+++ b/sap/Makefile.am
@@ -0,0 +1,25 @@
+if SAPPLUGIN
+plugindir = $(libdir)/bluetooth/plugins
+
+plugin_LTLIBRARIES = sap.la
+
+sap_la_SOURCES = server.c manager.h sap.c \
+		server.h manager.c \
+		sap.h main.c
+
+LDADD = $(top_builddir)/common/libhelper.a \
+		@GDBUS_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@
+endif
+
+AM_LDFLAGS = -module -avoid-version -no-undefined
+
+AM_CFLAGS = -fvisibility=hidden \
+		@BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ @GDBUS_CFLAGS@
+
+INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/src
+
+MAINTAINERCLEANFILES = Makefile.in
+
+sap.c: @SAP_DRIVER@
+	@if [ ! -e $@ ] ; then $(LN_S) $< $@ ; fi
+
diff --git a/sap/main.c b/sap/main.c
new file mode 100644
index 0000000..541951b
--- /dev/null
+++ b/sap/main.c
@@ -0,0 +1,57 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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 <errno.h>
+
+#include <gdbus.h>
+
+#include "plugin.h"
+#include "manager.h"
+
+static DBusConnection *connection;
+
+static int sap_init(void)
+{
+	connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+	if (connection == NULL)
+		return -EIO;
+
+	if (sap_manager_init(connection) < 0) {
+		dbus_connection_unref(connection);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void sap_exit(void)
+{
+	sap_manager_exit();
+
+	dbus_connection_unref(connection);
+}
+
+BLUETOOTH_PLUGIN_DEFINE(sap, VERSION,
+		BLUETOOTH_PLUGIN_PRIORITY_DEFAULT, sap_init, sap_exit)
+
diff --git a/sap/manager.c b/sap/manager.c
new file mode 100644
index 0000000..4a249a9
--- /dev/null
+++ b/sap/manager.c
@@ -0,0 +1,98 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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 <errno.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include <gdbus.h>
+
+#include "logging.h"
+#include "adapter.h"
+#include "device.h"
+
+#include "manager.h"
+
+#include "server.h"
+
+#define SAP_UUID_STR		"0000112D-0000-1000-8000-00805F9B34FB"
+
+static DBusConnection *connection = NULL;
+
+
+static int sap_server_probe(struct btd_adapter *adapter)
+{
+	const gchar *path = adapter_get_path(adapter);
+	bdaddr_t src;
+
+	DBG("path %s", path);
+
+	adapter_get_address(adapter, &src);
+
+	return sap_server_register(path, &src);
+}
+
+static void sap_server_remove(struct btd_adapter *adapter)
+{
+	const gchar *path = adapter_get_path(adapter);
+
+	DBG("path %s", path);
+
+	sap_server_unregister(path);
+}
+
+static struct btd_adapter_driver sap_server_driver = {
+	.name	= "sap-server",
+	.probe	= sap_server_probe,
+	.remove	= sap_server_remove,
+};
+
+int sap_manager_init(DBusConnection *conn)
+{
+	connection = dbus_connection_ref(conn);
+
+	if (sap_server_init(connection) < 0) {
+		error("Can't init SAP server");
+		dbus_connection_unref(conn);
+		return -1;
+	}
+
+	btd_register_adapter_driver(&sap_server_driver);
+
+	return 0;
+}
+
+void sap_manager_exit(void)
+{
+	btd_unregister_adapter_driver(&sap_server_driver);
+
+	dbus_connection_unref(connection);
+	connection = NULL;
+
+	sap_server_exit();
+}
+
diff --git a/sap/manager.h b/sap/manager.h
new file mode 100644
index 0000000..5c1c02a
--- /dev/null
+++ b/sap/manager.h
@@ -0,0 +1,23 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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
+ */
+
+int sap_manager_init(DBusConnection *conn);
+void sap_manager_exit(void);
+
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c
new file mode 100644
index 0000000..6a93900
--- /dev/null
+++ b/sap/sap-dummy.c
@@ -0,0 +1,76 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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 <unistd.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "sap.h"
+
+void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
+{
+	sap_connect_rsp(sap_device, SAP_STATUS_OK, maxmsgsize);
+	sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+}
+
+void sap_disconnect_req(void *sap_device)
+{
+	sap_disconnect_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_transfer_apdu_req(void *sap_device, sap_parameter *param)
+{
+	sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+}
+
+void sap_transfer_atr_req(void * sap_device)
+{
+	uint8_t atr[] = {0x3b, 0x9a, 0x96, 0x00, 0x92, 0x01, 0x98, 0x93, 0x17, 0x00, 0x02, 0x28, 0x03, 0x00};
+	sap_transfer_atr_rsp(sap_device, SAP_RESULT_OK, atr, 0x0E);
+}
+
+void sap_power_sim_off_req(void *sap_device)
+{
+	sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_power_sim_on_req(void *sap_device)
+{
+	sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_reset_sim_req(void *sap_device)
+{
+	sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
+}
+
+void sap_transfer_card_reader_status_req(void * sap_device)
+{
+	sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK, 0xF1);
+}
+
+void sap_set_transport_protocol_req(void * sap_device,sap_parameter * param)
+{
+
+}
diff --git a/sap/sap-ste.c b/sap/sap-ste.c
new file mode 100644
index 0000000..2298e61
--- /dev/null
+++ b/sap/sap-ste.c
@@ -0,0 +1,1309 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *
+ *  Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for
+ *  ST-Ericsson.
+ *
+ *  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.
+ *
+ *  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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include <glib.h>
+#include <assert.h>
+#include "logging.h"
+
+#include "sap.h"
+
+/** STE_SIM_MAX_MSG_SIZE - Maximum size of Sim Access Profile message
+ * supported by the server.
+ */
+#define STE_SIM_MAX_MSG_SIZE 	1024
+
+/** STE_SIM_MIN_MSG_SIZE - Minimal size of  Sim Access Profile message
+ * supported by the server.
+ */
+#define STE_SIM_MIN_MSG_SIZE 	512
+
+/** STE_SIM_UNIX_SOCKET_NAME - Unix socket name used to communicate with
+ * SIM daemon.
+ */
+#define STE_SIM_UNIX_SOCKET_NAME "/dev/socket/catd_a"
+
+/*Sizes of SIM message fields.*/
+#define STE_SIM_MSG_LEN_SIZE 		0x0002
+#define STE_SIM_MSG_TYPE_SIZE 		0x0002
+#define STE_SIM_MSG_CLIENT_TAG_SIZE 	0x0004
+#define STE_SIM_MSG_STATUS_SIZE 	0x0004
+
+/*Header size of SIM message */
+#define STE_SIM_MSG_HEADER_SIZE ((STE_SIM_MSG_LEN_SIZE) + \
+		(STE_SIM_MSG_TYPE_SIZE) + (STE_SIM_MSG_CLIENT_TAG_SIZE))
+
+#define STE_SIM_CLIENT_TAG 0x0000
+
+#define STE_UICC_RANGE_REQ_SAP	(0x2D00)
+#define STE_UICC_RANGE_RSP_SAP  (0x2E00)
+#define STE_UICC_RANGE_IND_SAP  (0x2F00)
+
+/** ste_sim_protocol_t - protocol used in communication with SIM daemon.*/
+typedef enum {
+	STE_SIM_START_SAP_REQ 	= (STE_UICC_RANGE_REQ_SAP | 0x0001),
+	STE_SIM_START_SAP_RSP 	= (STE_UICC_RANGE_RSP_SAP | 0x0001),
+
+	STE_SIM_END_SAP_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0002),
+	STE_SIM_END_SAP_RSP 	= (STE_UICC_RANGE_RSP_SAP | 0x0002),
+
+	STE_SIM_POWER_ON_REQ 	= (STE_UICC_RANGE_REQ_SAP | 0x0004),
+	STE_SIM_POWER_ON_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0004),
+
+	STE_SIM_POWER_OFF_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0003),
+	STE_SIM_POWER_OFF_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0003),
+
+	STE_SIM_RESET_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0005),
+	STE_SIM_RESET_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0005),
+
+	STE_SIM_GET_ATR_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0007),
+	STE_SIM_GET_ATR_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0007),
+
+	STE_SIM_SEND_APDU_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0006),
+	STE_SIM_SEND_APDU_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0006),
+
+	STE_SIM_GET_STATUS_REQ	= (STE_UICC_RANGE_REQ_SAP | 0x0008),
+	STE_SIM_GET_STATUS_RSP	= (STE_UICC_RANGE_RSP_SAP | 0x0008),
+
+	STE_SIM_STATUS_IND	= (STE_UICC_RANGE_IND_SAP | 0x0002)
+} ste_sim_protocol_t;
+
+/** ste_sim_msg_t - Type of SIM message.*/
+typedef enum {
+	STE_SIM_SEND_APDU_MSG = 0,
+	STE_SIM_GET_ATR_MSG,
+	STE_SIM_POWER_OFF_MSG,
+	STE_SIM_POWER_ON_MSG,
+	STE_SIM_RESET_MSG,
+	STE_SIM_GET_STATUS_MSG,
+	STE_SIM_MSG_MAX,
+} ste_sim_msg_t;
+
+/** ste_sim_status_t - Status of a request.*/
+typedef enum {
+	STE_SIM_STATUS_OK 			= 0x00000000,
+	STE_SIM_STATUS_UNDEFINED_FAILURE 	= 0xFFFFFFFF,
+} ste_sim_status_t;
+
+/** ste_sim_card_status_t - Sim card status.*/
+typedef enum {
+	STE_SIM_CARD_STATUS_UNKNOWN = 0x00,
+	STE_SIM_CARD_STATUS_READY = 0x01,
+	STE_SIM_CARD_STATUS_NOT_READY = 0x02,
+	STE_SIM_CARD_STATUS_MISSING = 0x03,
+	STE_SIM_CARD_STATUS_INVALID = 0x04
+} ste_sim_card_status_t;
+
+/** ste_sim_reader_status_t - Sim card reader status.*/
+typedef enum {
+	STE_SIM_READER_UNSPECIFIED_ERROR 	= 0x0000,
+	STE_SIM_READER_NOT_PRESENT		= 0x0001,
+	STE_SIM_READER_BUSY			= 0x0002,
+	STE_SIM_READER_CARD_POWERED_ON		= 0x0003,
+	STE_SIM_READER_DEACTIVATED		= 0x0004,
+	STE_SIM_READER_CARD_POWERED_OFF		= 0x0005,
+	STE_SIM_READER_NO_CARD			= 0x0006
+}ste_sim_reader_status_t;
+
+/** ste_sim_state_t - Sim connection state.*/
+typedef enum {
+		STE_SIM_DISABLED,	/* Reader not presend or removed */
+		STE_SIM_POWERED_OFF,	/* Card in the reader but powered off */
+		STE_SIM_NO_CARD,	/* No card in the reader */
+		STE_SIM_ENABLED,	/* Card in the reader and powered on */
+		STE_SIM_STATE_MAX
+} ste_sim_state_t;
+
+/** ste_sim_message - Sim message format.
+ * @len;	Length of the message minus sizeof(len).
+ * @id;		Request type id.
+ * @client_tag;	SAP server cleint id.
+ * @payload;	Data.
+ */
+typedef struct {
+	uint16_t len;
+	uint16_t id;
+	uint32_t client_tag;
+	uint8_t payload[0];
+} __attribute__ ((packed)) ste_sim_message;
+
+/** ste_sim_connection - main admin structure that keeps data about connection
+ * with Sim daemon.
+ */
+struct ste_sim_connection {
+	GIOChannel  *io;
+	ste_sim_state_t state;
+	void *sap_data;
+};
+
+static struct ste_sim_connection *simd_conn = NULL;
+
+/** sim2sap_result - Conversion table of sap result which varies with
+ * connection state and the message type.
+ */
+static sap_result_t sim2sap_result[STE_SIM_MSG_MAX][STE_SIM_STATE_MAX] = {
+	/* SAP results for SEND APDU message */
+	{SAP_RESULT_ERROR_NOT_ACCESSIBLE,/*for STE_SIM_DISABLED state */
+	 SAP_RESULT_ERROR_POWERED_OFF,	/*for STE_SIM_POWERED_OFF state */
+	 SAP_RESULT_ERROR_CARD_REMOVED,	/*for STE_SIM_NO_CARD state */
+	 SAP_RESULT_ERROR_NO_REASON},	/*for STE_SIM_ENABLED state */
+	 /* SAP results for GET_ATR message */
+	{SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_POWERED_OFF,
+	 SAP_RESULT_ERROR_CARD_REMOVED,
+	 SAP_RESULT_ERROR_NO_REASON},
+	 /* SAP results POWER OFF message */
+	{SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_POWERED_OFF,
+	 SAP_RESULT_ERROR_CARD_REMOVED,
+	 SAP_RESULT_ERROR_NO_REASON},
+	 /* SAP results POWER ON message */
+	{SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_NOT_ACCESSIBLE,
+	 SAP_RESULT_ERROR_CARD_REMOVED,
+	 SAP_RESULT_ERROR_POWERED_ON},
+	 /* SAP results SIM RESET message */
+	{SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_POWERED_OFF,
+	 SAP_RESULT_ERROR_CARD_REMOVED,
+	 SAP_RESULT_ERROR_NOT_ACCESSIBLE},
+	 /* SAP results GET STATUS message */
+	{SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_NO_REASON,
+	 SAP_RESULT_ERROR_NO_REASON}
+	};
+
+static void simd_conn_uninit(struct ste_sim_connection *c);
+static int simd_conn_watch(int sock, void *sap_data);
+
+/**
+ * get_sap_result - Convert STE sim status to sap result.
+ * @c;		Connection info structure.
+ * @msg;	Sim message type.
+ * @status;	Sim status.
+ *
+ * Returns:
+ *	SAP result.
+ */
+static sap_result_t get_sap_result(struct ste_sim_connection *c,
+				ste_sim_msg_t msg, ste_sim_status_t status)
+{
+	if (!c)
+		return SAP_RESULT_ERROR_NO_REASON;
+
+	switch (status){
+		case STE_SIM_STATUS_OK:
+			return SAP_RESULT_OK;
+
+		case STE_SIM_STATUS_UNDEFINED_FAILURE:
+			return sim2sap_result[msg][c->state];
+
+		default:
+			error("Cannot convert ste_sim_status [status: %d] \
+						to sap_result.", status);
+			return SAP_RESULT_ERROR_NO_REASON;
+	}
+}
+
+/**
+ * get_sap_reader_status - Convert STE sim reader status to sap reader result.
+ * @status;	Sim card reader status.
+ *
+ * Returns:
+ *	SAP reader status.
+ */
+static icc_reader_status_t get_sap_reader_status(ste_sim_reader_status_t status)
+{
+	switch (status){
+		case STE_SIM_READER_UNSPECIFIED_ERROR:
+			return ICC_READER_UNSPECIFIED_ERROR;
+
+		case STE_SIM_READER_NOT_PRESENT:
+			return ICC_READER_NOT_PRESENT;
+
+		case STE_SIM_READER_BUSY:
+			return ICC_READER_BUSY;
+
+		case STE_SIM_READER_CARD_POWERED_ON:
+			return ICC_READER_CARD_POWERED_ON;
+
+		case STE_SIM_READER_DEACTIVATED:
+			return ICC_READER_DEACTIVATED;
+
+		case STE_SIM_READER_CARD_POWERED_OFF:
+			return ICC_READER_CARD_POWERED_OFF;
+
+		case STE_SIM_READER_NO_CARD:
+			return ICC_READER_NO_CARD;
+
+		default:
+			error("Cannot convert ste_sim_reader_status [status: %d]\
+					to icc_sap_reader_status.", status);
+			return ICC_READER_UNSPECIFIED_ERROR;
+	}
+}
+
+/**
+ * sap_status_change - Convert STE sim card status to sap change event.
+ * @c;		Connection info structure.
+ * @status;	Sim card status.
+ *
+ * This also updates Sim connection state.
+ *
+ * Returns:
+ *	SAP change event.
+ */
+static sap_status_change_t sap_status_change(struct ste_sim_connection *c,
+					ste_sim_card_status_t status)
+{
+	if (!c)
+		return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
+
+	switch (status){
+		case STE_SIM_CARD_STATUS_UNKNOWN:
+			return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
+
+		case STE_SIM_CARD_STATUS_READY:
+			c->state = STE_SIM_ENABLED;
+			return SAP_STATUS_CHANGE_CARD_RESET;
+
+		case STE_SIM_CARD_STATUS_NOT_READY:
+			c->state = STE_SIM_DISABLED;
+			return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
+
+		case STE_SIM_CARD_STATUS_MISSING:
+			c->state = STE_SIM_DISABLED;
+			return SAP_STATUS_CHANGE_CARD_REMOVED;
+
+		case STE_SIM_CARD_STATUS_INVALID:
+			c->state = STE_SIM_DISABLED;
+			return SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE;
+
+		default:
+			error("Cannot convert ste_sim_status_change to \
+							sap_status_change.");
+			return SAP_STATUS_CHANGE_UNKNOWN_ERROR;
+	}
+}
+/**
+ * send_message - Send Sim message to Sim daemon.
+ * @c;		Connection info structure.
+ * @buf;	Sim message.
+ * @size;	Size of Sim message
+ *
+ * Returns:
+ *	O if success or negaive integer if error occured.
+ */
+static int send_message(struct ste_sim_connection *c,
+					ste_sim_message *buf, gsize size)
+{
+	gsize written = 0;
+	GIOError gerr;
+
+	debug("[STE_DRV] send_message: c %p, buf %p size %d", c, buf,
+								(int) size);
+
+	gerr = g_io_channel_write(c->io, (const gchar *) buf, size, &written);
+
+	if (written != size) {
+		error("[STE_DRV] send_message: written only %d bytes out of %d"
+						, (int)written, (int)size);
+		return -1;
+	}
+
+	if (gerr != G_IO_ERROR_NONE) {
+		int err = errno;
+		error("write error: %s(%d)", strerror(err), err);
+		return -err;
+	}
+
+	return 0;
+}
+
+/**
+ * ste_sim_start_sap_req - Create and send start SAP request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_start_sap_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_start_sap_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_START_SAP_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_end_sap_req - Create and send end SAP request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_end_sap_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_end_sap_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_END_SAP_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_end_sap_req - Create and send transfer apdu request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_send_apdu_req(struct ste_sim_connection *c,
+						sap_parameter *param)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE + param->len;
+
+	debug("[STE_DRV] ste_sim_send_apdu_req: c %p param %p len %d",
+							c, param, param->len);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_SEND_APDU_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+	memcpy(msg->payload, param->val, param->len);
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_get_atr_req - Create and send get ATR request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_get_atr_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_get_atr_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_GET_ATR_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_power_off_req - Create and send power off request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_power_off_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_power_off_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_POWER_OFF_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_power_on_req - Create and send power on request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_power_on_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_power_on_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_POWER_ON_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_reset_req - Create and send card reset request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_reset_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_reset_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_RESET_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_get_status_req - Create and send card status request message.
+ * @c;	Connection info structure.
+ *
+ * Returns:
+ *	O if success or negaive integer in case of error.
+ */
+static int ste_sim_get_status_req(struct ste_sim_connection *c)
+{
+	int err;
+	ste_sim_message *msg = NULL;
+	gsize msg_size = STE_SIM_MSG_HEADER_SIZE;
+
+	debug("[STE_DRV] ste_sim_get_status_req: c %p", c);
+
+	msg = (ste_sim_message *)g_malloc0(msg_size);
+	if (msg == NULL)
+		return -1;
+
+	msg->len = msg_size - STE_SIM_MSG_LEN_SIZE;
+	msg->id = STE_SIM_GET_STATUS_REQ;
+	msg->client_tag = STE_SIM_CLIENT_TAG;
+
+	err = send_message(c, msg, msg_size);
+	if (err < 0)
+		return err;
+
+	g_free(msg);
+	return 0;
+}
+
+/**
+ * ste_sim_start_sap_rsp - Handle start SAP response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_start_sap_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_status_t ss;
+	sap_status_change_t sc;
+
+	assert(msg && c);
+
+	debug("[STE_DRV] ste_sim_start_sap_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	status = (uint32_t*) msg->payload;
+	if (*status == STE_SIM_STATUS_OK)
+		sap_connect_rsp(c->sap_data, SAP_STATUS_OK, 0);
+	else {
+		sap_connect_rsp(c->sap_data, SAP_STATUS_CONNECTION_FAILED, 0);
+		simd_conn_uninit(c);
+	}
+}
+
+/**
+ * ste_sim_end_sap_rsp - Handle end SAP response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_end_sap_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	debug("[STE_DRV] ste_sim_end_sap_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+	assert(msg && c);
+
+	sap_disconnect_rsp(c->sap_data);
+	simd_conn_uninit(c);
+}
+
+/**
+ * ste_sim_send_apdu_rsp - Handle transfer apdu response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void  ste_sim_send_apdu_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_result_t sr;
+	uint8_t *apdu = NULL;
+	uint16_t len = 0;
+
+	debug("[STE_DRV] ste_sim_send_apdu_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	status = (uint32_t*) msg->payload;
+	if (*status == STE_SIM_STATUS_OK) {
+		apdu = (uint8_t *)(msg->payload + STE_SIM_MSG_STATUS_SIZE);
+		len = msg->len - (STE_SIM_MSG_HEADER_SIZE) +
+				STE_SIM_MSG_LEN_SIZE - STE_SIM_MSG_STATUS_SIZE;
+	}
+
+	sr = get_sap_result(c, STE_SIM_SEND_APDU_MSG, *status);
+	sap_transfer_apdu_rsp(c->sap_data, sr, apdu, len);
+}
+
+/**
+ * ste_sim_get_atr_rsp - Handle get ATR response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_get_atr_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_result_t sr;
+	uint8_t *atr = NULL;
+	uint16_t len = 0;
+
+	debug("[STE_DRV] ste_sim_get_atr_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	status = (uint32_t*) msg->payload;
+	if (*status == STE_SIM_STATUS_OK) {
+		atr = (uint8_t *)(msg->payload + STE_SIM_MSG_STATUS_SIZE);
+		len = msg->len - (STE_SIM_MSG_HEADER_SIZE) +
+						STE_SIM_MSG_LEN_SIZE;
+	}
+
+	sr = get_sap_result(c, STE_SIM_GET_ATR_MSG, *status);
+	sap_transfer_atr_rsp(c->sap_data, sr, atr, len);
+}
+
+/**
+ * ste_sim_power_off_rsp - Handle power off response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_power_off_rsp(struct ste_sim_connection *c,
+							ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_result_t sr;
+
+	debug("[STE_DRV] ste_sim_power_off_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	status = (uint32_t *) msg->payload;
+	if (*status == STE_SIM_STATUS_OK)
+		c->state = STE_SIM_POWERED_OFF;
+
+	sr = get_sap_result(c, STE_SIM_POWER_OFF_MSG, *status);
+	sap_power_sim_off_rsp(c->sap_data, sr);
+}
+
+/**
+ * ste_sim_power_on_rsp - Handle power on response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_power_on_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_result_t sr;
+
+	debug("[STE_DRV] ste_sim_power_on_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	status = (uint32_t *) msg->payload;
+	if (*status == STE_SIM_STATUS_OK)
+		c->state = STE_SIM_ENABLED;
+
+	sr = get_sap_result(c, STE_SIM_POWER_ON_MSG, *status);
+	sap_power_sim_on_rsp(c->sap_data, sr);
+}
+
+/**
+ * ste_sim_reset_rsp - Handle reset response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_reset_rsp(struct ste_sim_connection *c,
+					ste_sim_message * msg)
+{
+	uint32_t *status;
+	sap_result_t sr;
+
+	debug("[STE_DRV] ste_sim_reset_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	status = (uint32_t *) msg->payload;
+	if (*status == STE_SIM_STATUS_OK)
+		c->state = STE_SIM_ENABLED;
+
+	sr = get_sap_result(c, STE_SIM_RESET_MSG, *status);
+	sap_reset_sim_rsp(c->sap_data, sr);
+}
+
+/**
+ * ste_sim_get_status_rsp - Handle card status response message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_get_status_rsp(struct ste_sim_connection *c,
+						ste_sim_message * msg)
+{
+	uint8_t *p = NULL;
+	uint32_t *status;
+	sap_result_t sr;
+	ste_sim_reader_status_t rs;
+	icc_reader_status_t iccrs;
+
+	debug("[STE_DRV] ste_sim_get_status_rsp: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	p = msg->payload;
+
+	status = (uint32_t *)p; p += sizeof(uint32_t);
+	rs = *((uint16_t *)p);
+
+	iccrs = get_sap_reader_status(rs);
+	sr = get_sap_result(c, STE_SIM_GET_STATUS_MSG, *status);
+	sap_transfer_card_reader_status_rsp(c->sap_data, sr, iccrs);
+}
+
+/**
+ * ste_sim_status_ind - Handle status indication message.
+ * @c;		Connection info structure.
+ * @msg;	Response message.
+ */
+static void ste_sim_status_ind(struct ste_sim_connection *c,
+							ste_sim_message * msg)
+{
+	sap_status_change_t sc;
+	ste_sim_card_status_t cs;
+
+	debug("[STE_DRV] ste_sim_status_ind: c %p (conn %p) msg %p",
+							c, simd_conn, msg );
+
+	assert(msg && c);
+
+	cs = *((uint32_t *) msg->payload);
+	sc = sap_status_change(c, cs);
+
+	sap_status_ind(c->sap_data, sc);
+}
+
+/**
+ * handle_msg - Handle messages from Sim daemon.
+ * @c;		Connection info structure.
+ * @buf;	Data buffer.
+ * @size;	Size of data buffer.
+ *
+ * Returns:
+ *    0 if success or EBADMSG in case of bad message format.
+ */
+static int handle_msg(struct ste_sim_connection *c, unsigned char *buf,
+								gsize size)
+{
+	unsigned char *iter = buf;
+	ste_sim_message * msg = (ste_sim_message *) buf;
+	gsize msize = size;
+
+	assert(c);
+
+	do {
+		debug("[STE_DRV] handle_msg: msize %d msg->len %d.",
+							(int)msize, msg->len);
+
+		/* Message must be at least size of header len */
+		if (msize < STE_SIM_MSG_HEADER_SIZE) {
+			error("[STE_DRV] Invalid message size.");
+			return -EBADMSG;
+		}
+
+		/* Message must be completed. */
+		if (msize < (STE_SIM_MSG_LEN_SIZE + msg->len)) {
+			error("[STE_DRV] Not complete message.");
+			return -EBADMSG;
+		}
+
+		switch (msg->id){
+			case STE_SIM_START_SAP_RSP:
+				ste_sim_start_sap_rsp(c, msg);
+				break;
+
+			case STE_SIM_END_SAP_RSP:
+				ste_sim_end_sap_rsp(c, msg);
+				break;
+
+			case STE_SIM_SEND_APDU_RSP:
+				ste_sim_send_apdu_rsp(c, msg);
+				break;
+
+			case STE_SIM_GET_ATR_RSP:
+				ste_sim_get_atr_rsp(c, msg);
+				break;
+
+			case STE_SIM_POWER_OFF_RSP:
+				ste_sim_power_off_rsp(c, msg);
+				break;
+
+			case STE_SIM_POWER_ON_RSP:
+				ste_sim_power_on_rsp(c, msg);
+				break;
+
+			case STE_SIM_RESET_RSP:
+				ste_sim_reset_rsp(c, msg);
+				break;
+
+			case STE_SIM_GET_STATUS_RSP:
+				ste_sim_get_status_rsp(c, msg);
+				break;
+
+			case STE_SIM_STATUS_IND:
+				ste_sim_status_ind(c, msg);
+				break;
+
+			default:
+				error("[STE_DRV] Invalid or not supported \
+						frame [0x%02x].", msg->id);
+		}
+
+		/* Reduce total buffer size of just handled frame size*/
+		msize -= (STE_SIM_MSG_HEADER_SIZE +
+				(msg->len - (STE_SIM_MSG_HEADER_SIZE) +
+				 STE_SIM_MSG_LEN_SIZE));
+
+		/* Move msg ponter to then next message if any */
+		iter += (msg->len + STE_SIM_MSG_LEN_SIZE);
+		msg = (ste_sim_message *)iter;
+
+	} while (msg && (msize > 0));
+
+	return 0;
+}
+
+/**
+ * simd_io_data_cb - Handle data on socket to Sim daemon.
+ * @io;		Connection info structure.
+ * @cond;	Conndition that triggered this callback.
+ * @data;	Data buffor.
+ *
+ * Returns:
+ *    True if @data was handled, False otherwise.
+ */
+static gboolean simd_io_data_cb(GIOChannel *io, GIOCondition cond,
+							gpointer data)
+{
+	GIOError err = G_IO_ERROR_NONE;
+	unsigned char buf[STE_SIM_MAX_MSG_SIZE];
+	gsize read_bytes = 0;
+
+	if (cond & G_IO_NVAL) {
+		debug("[STE_DRV] NVAL on sim socket");
+		return FALSE;
+	}
+
+	if (cond & G_IO_HUP) {
+		debug("[STE_DRV] HUP on sim socket");
+		return FALSE;
+	}
+
+	if (cond & G_IO_ERR) {
+		debug("[STE_DRV] ERR on sim socket");
+		return FALSE;
+	}
+
+	/* TODO: consider to read bytes in a while loop just in case if one read
+			operation won't read all data. while(read_data!=0)
+	*/
+
+	err = g_io_channel_read(io, (gchar *)buf, sizeof(buf), &read_bytes);
+	if (err != G_IO_ERROR_NONE) {
+		error("[STE_DRV] Error while reading from channel \
+						[err 0x%x io %p].", err, io);
+		return FALSE;
+	}
+
+	if (handle_msg(data, buf, read_bytes) < 0)
+		error("[STE_DRV] Invalid STE Sim message.");
+
+	return TRUE;
+}
+
+/**
+ * simd_io_destroy_cb - Clean up the SAP serer in case of socket closure.
+ * @data;	Private data.
+ *
+ * The callback is run if the connection with Sim daemon has been lost.
+ */
+static void simd_io_destroy_cb(void *data)
+{
+	struct ste_sim_connection *c = (struct ste_sim_connection *)data;
+
+	debug("[STE_DRV] simd_io_destroy_cb: c %p conn %p io %p", c,
+							simd_conn, c->io);
+
+	if (c && simd_conn) {
+		g_io_channel_unref(c->io);
+		g_io_channel_shutdown(c->io, TRUE, NULL);
+		g_free(c);
+		simd_conn = NULL;
+	}
+}
+
+/**
+ * simd_conn_init - Initialize connection with Sim Daemon.
+ * @sap_data;	Private data of SAP Server.
+ *
+ * Returns:
+ *    0 if success, negative number in case of an error.
+ */
+static int simd_conn_init(void * sap_data)
+{
+	int sock;
+	int len = 0;
+	struct sockaddr_un addr;
+	ssize_t addr_len;
+
+	/* Create a socket to communicate with SIMD*/
+	sock = socket(PF_UNIX, SOCK_STREAM, 0);
+	if (sock < 0) {
+		error("[STE_DRV] Create socket failed: %s", strerror(errno));
+		return -errno;
+	}
+
+	/*Connect to SIMD*/
+	memset(&addr, 0, sizeof(addr));
+	addr.sun_family = AF_UNIX;
+	len = sprintf(addr.sun_path, STE_SIM_UNIX_SOCKET_NAME);
+	addr_len = sizeof(addr.sun_family) + len;
+	if (connect(sock, (struct sockaddr *) &addr, addr_len) < 0) {
+		error("[STE_DRV] Connect to the socket failed:  %s",
+							strerror(errno));
+		goto drop;
+	}
+
+	if (fcntl(sock, F_SETFL, O_NONBLOCK) > 0) {
+		error("[STE_DRV] fcntl() failed: %s", strerror(errno));
+		goto drop;
+	}
+
+	debug("[STE_DRV] simd_conn_init: sock %d ",sock);
+
+	/* Start watching incoming data */
+	if (simd_conn_watch(sock, sap_data) < 0)
+		goto drop;
+
+	return 0;
+
+drop:
+	debug("[STE_DRV] simd_conn_init: drop!");
+	close(sock);
+	return -errno;
+}
+
+/**
+ * simd_conn_uninit - Disconnect from Sim daemon.
+ * @c;	Connection info structure.
+ */
+static void simd_conn_uninit(struct ste_sim_connection *c)
+{
+	debug("[STE_DRV] simd_conn_uninit: c %p simd_conn %p", c, simd_conn);
+
+	if (!c)
+		return;
+
+	g_io_channel_shutdown(c->io, TRUE, NULL);
+	g_io_channel_unref(c->io);
+	g_free(c);
+
+	simd_conn = NULL;
+}
+
+
+/**
+ * simd_conn_watch - Start watching Sim daemon connection.
+ * @sap_data;	Private data of SAP Server.
+ *
+ * Returns:
+ *    0 if success, negative number in case of an error.
+ */
+static int simd_conn_watch(int sock, void *sap_data)
+{
+	GIOChannel *io = NULL;
+
+	debug("[STE_DRV] simd_conn_watch: sock %d, sap_data %p ", sock,
+								sap_data);
+
+	if (sock < 0)
+		return -1;
+
+	io = g_io_channel_unix_new(sock);
+	g_io_channel_set_close_on_unref(io, TRUE);
+
+
+	simd_conn = g_new0(struct ste_sim_connection, 1);
+	if (!simd_conn) {
+		error("[STE_DRV] simd_conn_watch: simd_conn %p io %p",
+								simd_conn, io);
+		g_io_channel_shutdown(io, TRUE, NULL);
+		g_io_channel_unref(io);
+		return -1;
+	}
+
+	simd_conn->io = io;
+	simd_conn->sap_data = sap_data;
+	simd_conn->state = STE_SIM_DISABLED;
+
+	g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
+			G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
+			simd_io_data_cb, simd_conn, simd_io_destroy_cb);
+
+	return 0;
+}
+
+/**
+ * sap_connect_req - Handle SAP connect request.
+ * @sap_data;	Private data of SAP Server.
+ * @maxmsgsize;	Message size supported by the SAP client.
+ */
+void sap_connect_req(void *sap_device, uint16_t maxmsgsize)
+{
+
+	debug("[STE_DRV] sap_connect_req: conn %p sap_device %p maxmsgsize %d",
+			simd_conn, sap_device, maxmsgsize);
+
+	if (maxmsgsize < STE_SIM_MIN_MSG_SIZE) {
+		sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL,
+							STE_SIM_MAX_MSG_SIZE);
+		return;
+	}
+
+	if (maxmsgsize > STE_SIM_MAX_MSG_SIZE) {
+		sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED,
+							STE_SIM_MAX_MSG_SIZE);
+		return;
+	}
+
+	if (simd_conn_init(sap_device) < 0) {
+		debug("[STE_DRV] simd_conn_init: failed!");
+		sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED, 0);
+		return;
+	}
+
+	if (simd_conn && simd_conn->state == STE_SIM_DISABLED) {
+		if (ste_sim_start_sap_req(simd_conn) < 0) {
+			sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED,
+							STE_SIM_MAX_MSG_SIZE);
+			simd_conn_uninit(simd_conn);
+		}
+	} else {
+		debug("[STE_DRV] Connection failed! (simd_conn %p) ", simd_conn);
+		sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED, 0);
+	}
+}
+
+/**
+ * sap_disconnect_req - Handle SAP disconnect request.
+ * @sap_data;	Private data of SAP Server.
+ * @linkloss;	Indicates thet link is being disconnected due to link loss.
+ */
+void sap_disconnect_req(void *sap_device, uint8_t linkloss)
+{
+	debug("[STE_DRV] sap_disconnect_req: conn %p sap_device %p linkloss %d",
+					simd_conn, sap_device, linkloss);
+	if (simd_conn && linkloss) {
+		simd_conn_uninit(simd_conn);
+		return;
+	}
+
+	if (simd_conn && simd_conn->state != STE_SIM_DISABLED) {
+		if (ste_sim_end_sap_req(simd_conn) < 0) {
+			sap_disconnect_rsp(sap_device);
+		}
+	} else {
+		sap_disconnect_rsp(sap_device);
+	}
+}
+
+/**
+ * sap_transfer_apdu_req - Handle SAP transfer apdu request.
+ * @sap_data;	Private data of SAP Server.
+ * @param;	SAP parameter of the request.
+ */
+void sap_transfer_apdu_req(void *sap_device, sap_parameter *param)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_transfer_apdu_req: conn %p sap_device %p param %p\
+		param len %d", simd_conn, sap_device, param, param->len);
+
+	if (simd_conn && simd_conn->state == STE_SIM_ENABLED) {
+		if (ste_sim_send_apdu_req(simd_conn, param) < 0)
+			sap_transfer_apdu_rsp(sap_device,
+					SAP_RESULT_ERROR_NO_REASON, NULL, 0);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_SEND_APDU_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_transfer_apdu_rsp(sap_device, sr, NULL, 0);
+	}
+}
+
+/**
+ * sap_transfer_atr_req - Handle SAP ATR request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_transfer_atr_req(void * sap_device)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_transfer_atr_req: conn %p, sap_device %p",
+							simd_conn, sap_device);
+
+	if (simd_conn && simd_conn->state == STE_SIM_ENABLED) {
+		if (ste_sim_get_atr_req(simd_conn) < 0)
+			sap_transfer_atr_rsp(sap_device,
+				SAP_RESULT_ERROR_NO_DATA, NULL, 0);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_GET_ATR_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_transfer_atr_rsp(sap_device, sr, NULL, 0);
+	}
+}
+
+/**
+ * sap_power_sim_off_req - Handle SAP power off request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_power_sim_off_req(void *sap_device)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_power_sim_off_req: conn %p, sap_device %p",
+							simd_conn, sap_device);
+
+	if (simd_conn && simd_conn->state == STE_SIM_ENABLED) {
+		if (ste_sim_power_off_req(simd_conn) < 0)
+			sap_power_sim_off_rsp(sap_device,
+					SAP_RESULT_ERROR_NO_REASON);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_POWER_OFF_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_power_sim_off_rsp(sap_device, sr);
+	}
+}
+
+/**
+ * sap_power_sim_on_req - Handle SAP power on request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_power_sim_on_req(void *sap_device)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_power_sim_on_req: conn %p, sap_device %p",
+							simd_conn, sap_device);
+
+	if (simd_conn && simd_conn->state == STE_SIM_POWERED_OFF) {
+		if (ste_sim_power_on_req(simd_conn) < 0)
+			sap_power_sim_on_rsp(sap_device,
+					SAP_RESULT_ERROR_NO_REASON);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_POWER_ON_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_power_sim_on_rsp(sap_device, sr);
+	}
+}
+
+/**
+ * sap_reset_sim_req - Handle SAP reset request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_reset_sim_req(void *sap_device)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_reset_sim_req: conn %p, sap_device %p",
+							simd_conn, sap_device);
+
+	if (simd_conn && simd_conn->state == STE_SIM_ENABLED) {
+		if (ste_sim_reset_req(simd_conn) < 0)
+			sap_reset_sim_rsp(sap_device,
+						SAP_RESULT_ERROR_NO_REASON);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_RESET_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_reset_sim_rsp(sap_device, sr);
+	}
+}
+
+/**
+ * sap_transfer_card_reader_status_req - Handle get card reader status request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_transfer_card_reader_status_req(void * sap_device)
+{
+	sap_result_t sr;
+
+	debug("[STE_DRV] sap_transfer_card_reader_status_req: conn %p, \
+					sap_device %p", simd_conn, sap_device);
+
+	if (simd_conn && simd_conn->state != STE_SIM_DISABLED) {
+		if (ste_sim_get_status_req(simd_conn) < 0)
+			sap_transfer_card_reader_status_rsp(sap_device,
+						SAP_RESULT_ERROR_NO_DATA,
+						ICC_READER_UNSPECIFIED_ERROR);
+	} else {
+		sr = get_sap_result(simd_conn, STE_SIM_GET_STATUS_MSG,
+					STE_SIM_STATUS_UNDEFINED_FAILURE);
+		sap_transfer_card_reader_status_rsp(sap_device, sr,
+						ICC_READER_UNSPECIFIED_ERROR);
+	}
+}
+
+/**
+ * sap_set_transport_protocol_req - Handle set transport protocol request.
+ * @sap_data;	Private data of SAP Server.
+ */
+void sap_set_transport_protocol_req(void * sap_device,sap_parameter * param)
+{
+	debug("[STE_DRV] Not supported.");
+}
+
diff --git a/sap/sap.h b/sap/sap.h
new file mode 100644
index 0000000..d0a1b99
--- /dev/null
+++ b/sap/sap.h
@@ -0,0 +1,200 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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
+ */
+
+/* SAP 1.1 section 5.2.2 */
+typedef enum {
+	SAP_STATUS_OK 				= 0x00,
+	SAP_STATUS_CONNECTION_FAILED		= 0x01,
+	SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED	= 0x02,
+	SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL	= 0x03,
+	SAP_STATUS_OK_ONGOING_CALL		= 0x04
+} sap_status_t;
+
+/* SAP 1.1 section 5.2.3 */
+typedef enum {
+	SAP_DISCONNECTION_TYPE_GRACEFUL  = 0x00,
+	SAP_DISCONNECTION_TYPE_IMMEDIATE = 0x01,
+	SAP_DISCONNECTION_TYPE_CLIENT    = 0xFF
+} sap_disconnection_type_t;
+
+/* SAP 1.1 section 5.2.4 */
+typedef enum {
+	SAP_RESULT_OK 			= 0x00,
+	SAP_RESULT_ERROR_NO_REASON	= 0x01,
+	SAP_RESULT_ERROR_NOT_ACCESSIBLE	= 0x02,
+	SAP_RESULT_ERROR_POWERED_OFF	= 0x03,
+	SAP_RESULT_ERROR_CARD_REMOVED	= 0x04,
+	SAP_RESULT_ERROR_POWERED_ON	= 0x05,
+	SAP_RESULT_ERROR_NO_DATA	= 0x06,
+	SAP_RESULT_NOT_SUPPORTED	= 0x07
+} sap_result_t;
+
+/* SAP 1.1 section 5.2.8 Status Change */
+typedef enum {
+	SAP_STATUS_CHANGE_UNKNOWN_ERROR       = 0x00,
+	SAP_STATUS_CHANGE_CARD_RESET          = 0x01,
+	SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE = 0x02,
+	SAP_STATUS_CHANGE_CARD_REMOVED        = 0x03,
+	SAP_STATUS_CHANGE_CARD_INSERTED       = 0x04,
+	SAP_STATUS_CHANGE_CARD_RECOVERED      = 0x05
+} sap_status_change_t;
+
+
+/* SAP 1.1 section 5.1 Message formats */
+typedef struct {
+	uint8_t id;
+	uint8_t reserved;
+	uint16_t len;
+	uint8_t val[0];
+	/*
+	 * Padding bytes 0-3 bytes
+	 */
+} __attribute__ ((packed)) sap_parameter;
+
+typedef struct {
+	uint8_t id;
+	uint8_t nparam;
+	uint16_t reserved;
+	sap_parameter param[0];
+} __attribute__ ((packed)) sap_message;
+
+
+typedef enum {
+	ICC_READER_UNSPECIFIED_ERROR, /* No further information available */
+	ICC_READER_NOT_PRESENT,       /* Card Reader removed or not present */
+	ICC_READER_BUSY,              /* Card Reader in use */
+	ICC_READER_CARD_POWERED_ON,   /* Card in reader and is powered on */
+	ICC_READER_DEACTIVATED,       /* Card Reader deactivated */
+	ICC_READER_CARD_POWERED_OFF,  /* Card in reader, but powered off */
+	ICC_READER_NO_CARD,           /* No card in reader */
+	ICC_READER_LAST
+} icc_reader_status_t;
+
+
+#define SAP_BUF_SIZE		512
+
+#define SAP_MSG_HEADER_SIZE	4
+
+typedef enum {
+	SAP_CONNECT_REQ                        = 0x00,	/* Client -> Server */
+	SAP_CONNECT_RESP                       = 0x01,	/* Server -> Client */
+
+	SAP_DISCONNECT_REQ                     = 0x02,	/* Client -> Server */
+	SAP_DISCONNECT_RESP                    = 0x03,	/* Server -> Client */
+	SAP_DISCONNECT_IND                     = 0x04,	/* Server -> Client */
+
+	SAP_TRANSFER_APDU_REQ                  = 0x05,	/* Client -> Server */
+	SAP_TRANSFER_APDU_RESP                 = 0x06,	/* Server -> Client */
+
+	SAP_TRANSFER_ATR_REQ                   = 0x07,	/* Client -> Server */
+	SAP_TRANSFER_ATR_RESP                  = 0x08,	/* Server -> Client */
+
+	SAP_POWER_SIM_OFF_REQ                  = 0x09,	/* Client -> Server */
+	SAP_POWER_SIM_OFF_RESP                 = 0x0A,	/* Server -> Client */
+
+	SAP_POWER_SIM_ON_REQ                   = 0x0B,	/* Client -> Server */
+	SAP_POWER_SIM_ON_RESP                  = 0x0C,	/* Server -> Client */
+
+	SAP_RESET_SIM_REQ                      = 0x0D,	/* Client -> Server */
+	SAP_RESET_SIM_RESP                     = 0x0E,	/* Server -> Client */
+
+	SAP_TRANSFER_CARD_READER_STATUS_REQ    = 0x0F,	/* Client -> Server */
+	SAP_TRANSFER_CARD_READER_STATUS_RESP   = 0x10,	/* Server -> Client */
+
+	SAP_STATUS_IND                         = 0x11,	/* Server -> Client */
+	SAP_ERROR_RESP                         = 0x12,	/* Server -> Client */
+
+	SAP_SET_TRANSPORT_PROTOCOL_REQ         = 0x13,	/* Client -> Server */
+	SAP_SET_TRANSPORT_PROTOCOL_RESP        = 0x14,	/* Server -> Client */
+} sap_protocol;
+
+/* SAP 1.1 section 5.2 Parameters IDs and Coding */
+#define SAP_PARAM_ID_MAXMSGSIZE             0x00
+#define SAP_PARAM_ID_MAXMSGSIZE_LEN         0x02
+
+#define SAP_PARAM_ID_CONN_STATUS            0x01
+#define SAP_PARAM_ID_CONN_STATUS_LEN        0x01
+
+#define SAP_PARAM_ID_RESULT_CODE            0x02
+#define SAP_PARAM_ID_RESULT_CODE_LEN        0x01
+
+#define SAP_PARAM_ID_DISCONNECT_IND         0x03
+#define SAP_PARAM_ID_DISCONNECT_IND_LEN     0x01
+
+#define SAP_PARAM_ID_COMMAND_APDU           0x04
+
+#define SAP_PARAM_ID_RESPONSE_APDU          0x05
+
+#define SAP_PARAM_ID_ATR                    0x06
+
+#define SAP_PARAM_ID_CARD_READER_STATUS     0x07
+#define SAP_PARAM_ID_CARD_READER_STATUS_LEN 0x01
+
+#define SAP_PARAM_ID_STATUS_CHANGE          0x08
+#define SAP_PARAM_ID_STATUS_CHANGE_LEN      0x01
+
+#define SAP_PARAM_ID_TRANSPORT_PROTOCOL     0x09
+#define SAP_PARAM_ID_TRANSPORT_PROTOCOL_LEN 0x01
+
+#define SAP_PARAM_ID_COMMAND_APDU7816       0x10
+
+/* SAP 1.1 section 5.2.9 Possible Values for TransportProtocol */
+#define SAP_TRANSPORT_PROTOCOL_T0           0x00
+#define SAP_TRANSPORT_PROTOCOL_T1           0x01
+
+
+/*
+ * Drivers must implement the following functions.
+ * Blocking operations are not allowed, results must be
+ * reported using the functions defined in the next section.
+ * Functions implemented on sap.c
+ */
+void sap_connect_req(void *sap_device, uint16_t maxmsgsize);
+void sap_disconnect_req(void *sap_device, uint8_t linkloss);
+void sap_transfer_apdu_req(void *sap_device, sap_parameter *param);
+void sap_transfer_atr_req(void *sap_device);
+void sap_power_sim_off_req(void *sap_device);
+void sap_power_sim_on_req(void *sap_device);
+void sap_reset_sim_req(void *sap_device);
+void sap_transfer_card_reader_status_req(void *sap_device);
+void sap_set_transport_protocol_req(void *sap_device, sap_parameter *param);
+
+
+/*
+ * Drivers must use the following functions to report operation results.
+ * Functions implemented on server.c
+ */
+int sap_connect_rsp(void *sap_device, sap_status_t status, uint16_t maxmsgsize);
+int sap_disconnect_rsp(void *sap_device);
+int sap_transfer_apdu_rsp(void *sap_device, sap_result_t result, uint8_t *sap_apdu_resp, uint16_t length);
+int sap_transfer_atr_rsp(void *sap_device, sap_result_t result, uint8_t *sap_atr, uint16_t length);
+int sap_power_sim_off_rsp(void *sap_device, sap_result_t result);
+int sap_power_sim_on_rsp(void *sap_device, sap_result_t result);
+int sap_reset_sim_rsp(void *sap_device, sap_result_t result);
+int sap_transfer_card_reader_status_rsp(void *sap_device, sap_result_t result, icc_reader_status_t status);
+int sap_error_rsp(void *sap_device);
+int sap_transport_protocol_resp(void *sap_device, sap_result_t resul);
+
+/*
+ * Asynchronous Driver events notification.
+ * Functions implemented on server.c
+ */
+int sap_status_ind(void *sap_device, sap_status_change_t status_change);
+
diff --git a/sap/server.c b/sap/server.c
new file mode 100644
index 0000000..a8d098a
--- /dev/null
+++ b/sap/server.c
@@ -0,0 +1,1459 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.org>
+ *
+ *  Author: Marek Skowron <marek.skowron@tieto.com> for ST-Ericsson.
+ *
+ *  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.
+ *
+ *  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 <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+#include <assert.h>
+#include <glib.h>
+#include <gdbus.h>
+
+#include "adapter.h"
+#include "dbus-common.h"
+#include "btio.h"
+#include "sdpd.h"
+
+#include "logging.h"
+#include "error.h"
+
+#include "sap.h"
+#include "server.h"
+
+#define SAP_PROFILE_VERSION 0x0101
+
+#define SAP_SERVER_INTERFACE		"org.bluez.SimAccess"
+#define SAP_SERVER_CHANNEL		8
+#define SAP_UUID			"0000112D-0000-1000-8000-00805F9B34FB"
+#define SAP_BUF_SIZE			512
+#define PADDING4(x) (4 - (x & 0x03))
+#define PARAMETER_SIZE(x) (sizeof(sap_parameter) + x + PADDING4(x))
+
+#define SAP_NO_REQ 0xFF
+
+#define SAP_TIMER_GRACEFUL_DISCONNECT 30
+#define SAP_TIMER_NO_ACTIVITY 30
+
+typedef enum {
+	SAP_STATE_DISCONNECTED,
+	SAP_STATE_CONNECT_IN_PROGRESS,
+	SAP_STATE_CONNECTED,
+	SAP_STATE_GRACEFUL_DISCONNECT,
+	SAP_STATE_IMMEDIATE_DISCONNECT,
+	SAP_STATE_CLIENT_DISCONNECT
+} sap_state_t;
+
+struct sap_server {
+	bdaddr_t	src;
+	char		*path;
+	gboolean	enable;		/* Enable flag */
+	uint32_t	record_id;	/* Service record id */
+	GIOChannel	*listen_io;
+	GIOChannel	*io;		/* Active client channel */
+	sap_state_t	state;		/* State of the SAP server */
+	uint8_t		processing_req; /* Processing request in Connected state */
+	guint timer_id;			/* Guard timer */
+};
+
+static DBusConnection *connection = NULL;
+
+static void connect_req(void *data, sap_parameter *param);
+static int disconnect_req(void *data, sap_disconnection_type_t disc_type);
+static void transfer_apdu_req(void *data, sap_parameter *param);
+static void transfer_atr_req(void *data);
+static void power_sim_off_req(void *data);
+static void power_sim_on_req(void *data);
+static void reset_sim_req(void *data);
+static void transfer_card_reader_status_req(void *data);
+static void set_transport_protocol_req(void *data, sap_parameter *param);
+static int disconnect_ind(void *sap_device, sap_disconnection_type_t type);
+
+static gsize add_result_parameter(sap_result_t result, sap_parameter *param);
+
+static int is_power_sim_off_req_allowed(uint8_t processing_req);
+static int is_reset_sim_req_allowed(uint8_t processing_req);
+
+static int check_msg(sap_message *msg);
+
+static void start_guard_timer(struct sap_server *ss, guint interval);
+static void stop_guard_timer(struct sap_server *ss);
+static gboolean guard_timeout(gpointer data);
+
+static gsize add_result_parameter(sap_result_t result, sap_parameter *param)
+{
+	param->id = SAP_PARAM_ID_RESULT_CODE;
+	param->len = htons(SAP_PARAM_ID_RESULT_CODE_LEN);
+	*param->val = (uint8_t) result;
+	return PARAMETER_SIZE(SAP_PARAM_ID_RESULT_CODE_LEN);
+}
+
+
+static inline int is_power_sim_off_req_allowed(uint8_t processing_req)
+{
+	switch(processing_req) {
+	case SAP_NO_REQ:
+	case SAP_TRANSFER_APDU_REQ:
+	case SAP_TRANSFER_ATR_REQ:
+	case SAP_POWER_SIM_ON_REQ:
+	case SAP_RESET_SIM_REQ:
+	case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static inline int is_reset_sim_req_allowed(uint8_t processing_req)
+{
+	switch(processing_req) {
+	case SAP_NO_REQ:
+	case SAP_TRANSFER_APDU_REQ:
+	case SAP_TRANSFER_ATR_REQ:
+	case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+		return 1;
+	default:
+		return 0;
+	}
+}
+
+static int check_msg(sap_message *msg)
+{
+	assert(msg);
+
+	switch(msg->id) {
+	case SAP_CONNECT_REQ:
+		if (msg->nparam == 0x01 &&
+				msg->param->id == SAP_PARAM_ID_MAXMSGSIZE &&
+				ntohs(msg->param->len) == SAP_PARAM_ID_MAXMSGSIZE_LEN)
+			return 0;
+		break;
+	case SAP_TRANSFER_APDU_REQ:
+		if (msg->nparam == 0x01 &&
+				(msg->param->id == SAP_PARAM_ID_COMMAND_APDU ||
+				msg->param->id == SAP_PARAM_ID_COMMAND_APDU7816) &&
+				msg->param->len != 0x00)
+			return 0;
+		break;
+	case SAP_SET_TRANSPORT_PROTOCOL_REQ:
+		if (msg->nparam == 0x01 &&
+				msg->param->id == SAP_PARAM_ID_TRANSPORT_PROTOCOL &&
+				ntohs(msg->param->len) == SAP_PARAM_ID_TRANSPORT_PROTOCOL_LEN &&
+				(*msg->param->val  == SAP_TRANSPORT_PROTOCOL_T0 ||
+				*msg->param->val == SAP_TRANSPORT_PROTOCOL_T1))
+			return 0;
+		break;
+	case SAP_DISCONNECT_REQ:
+	case SAP_TRANSFER_ATR_REQ:
+	case SAP_POWER_SIM_OFF_REQ:
+	case SAP_POWER_SIM_ON_REQ:
+	case SAP_RESET_SIM_REQ:
+	case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+		if (msg->nparam == 0x00)
+			return 0;
+		break;
+	}
+
+	error("Invalid message");
+	return -EBADMSG;
+}
+
+
+static void start_guard_timer(struct sap_server *ss, guint interval)
+{
+	assert(ss);
+
+	if (!ss->timer_id)
+		ss->timer_id = g_timeout_add_seconds(interval, guard_timeout, ss);
+	else
+		error("[%s::%s] Timer is already active", __FILE__, __FUNCTION__);
+}
+
+static void stop_guard_timer(struct sap_server *ss)
+{
+	if (ss && ss->timer_id) {
+		g_source_remove(ss->timer_id);
+		ss->timer_id = 0x00;
+	}
+}
+
+static gboolean guard_timeout(gpointer data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+		__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	/* Set timer ID to zero because timer will be destroyed. */
+	ss->timer_id = 0;
+
+	switch(ss->state) {
+	case SAP_STATE_DISCONNECTED:
+		/* Client opened RFCOMM channel but didn't send CONNECT_REQ, in fixed time
+		 * or client disconnected SAP connection but didn't closed
+		 * RFCOMM channel in fixed time. Shutdown RFCOMM channel immediately. */
+		if (ss->io)
+			g_io_channel_shutdown(ss->io, TRUE, NULL);
+		break;
+	case SAP_STATE_GRACEFUL_DISCONNECT:
+		/* Client didn't disconnect SAP connection in fixed time,
+		 * so close SAP connection immediately. */
+		disconnect_req(ss, SAP_DISCONNECTION_TYPE_IMMEDIATE);
+		break;
+	default:
+		error("[%s::%s] Unexpected state: %#x processing_req: %#x",
+					__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+		break;
+	}
+
+	return FALSE;
+}
+
+static void server_free(struct sap_server *ss)
+{
+	if (!ss)
+		return;
+
+	g_free(ss->path);
+	g_free(ss);
+	debug("[%s::%s]", __FILE__, __FUNCTION__);
+}
+
+static sdp_record_t *sap_record(uint8_t channel)
+{
+	sdp_list_t *apseq, *aproto, *profiles, *proto[2], *root, *svclass_id;
+	uuid_t sap_uuid, gt_uuid, root_uuid, l2cap, rfcomm;
+	sdp_profile_desc_t profile;
+	sdp_record_t *record;
+	sdp_data_t *ch;
+
+	record = sdp_record_alloc();
+	if (!record)
+		return NULL;
+
+	root = sdp_list_append(NULL, &root_uuid);
+	sdp_set_browse_groups(record, root);
+	sdp_list_free(root, NULL);
+
+	sdp_uuid16_create(&sap_uuid, SAP_SVCLASS_ID);
+	svclass_id = sdp_list_append(NULL, &sap_uuid);
+	sdp_uuid16_create(&gt_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
+	svclass_id = sdp_list_append(svclass_id, &gt_uuid);
+
+	sdp_set_service_classes(record, svclass_id);
+	sdp_list_free(svclass_id, NULL);
+
+	sdp_uuid16_create(&profile.uuid, SAP_PROFILE_ID);
+	profile.version = SAP_PROFILE_VERSION;
+	profiles = sdp_list_append(NULL, &profile);
+	sdp_set_profile_descs(record, profiles);
+	sdp_list_free(profiles, NULL);
+
+	sdp_uuid16_create(&l2cap, L2CAP_UUID);
+	proto[0] = sdp_list_append(NULL, &l2cap);
+	apseq = sdp_list_append(NULL, proto[0]);
+
+	sdp_uuid16_create(&rfcomm, RFCOMM_UUID);
+	proto[1] = sdp_list_append(NULL, &rfcomm);
+	ch = sdp_data_alloc(SDP_UINT8, &channel);
+	proto[1] = sdp_list_append(proto[1], ch);
+	apseq = sdp_list_append(apseq, proto[1]);
+
+	aproto = sdp_list_append(NULL, apseq);
+	sdp_set_access_protos(record, aproto);
+
+	sdp_set_info_attr(record, "SIM Access Server",
+			NULL, NULL);
+
+	sdp_data_free(ch);
+	sdp_list_free(proto[0], NULL);
+	sdp_list_free(proto[1], NULL);
+	sdp_list_free(apseq, NULL);
+	sdp_list_free(aproto, NULL);
+
+	return record;
+}
+
+static int send_message(struct sap_server *ss,
+						unsigned char *buf, gsize size)
+{
+	gsize written = 0;
+	GIOError gerr;
+
+	assert(ss && buf);
+
+	debug("[%s::%s] size=%#x", __FILE__, __FUNCTION__, (unsigned int)size);
+	gerr = g_io_channel_write(ss->io, (const gchar *) buf, size, &written);
+	debug("[%s::%s] written=%#x", __FILE__, __FUNCTION__, (unsigned int)written);
+	if (gerr != G_IO_ERROR_NONE) {
+		int err = errno;
+		error("write error: %s(%d)", strerror(err), err);
+		return -err;
+	}
+
+	return 0;
+}
+
+static void connect_req(void *data, sap_parameter *param)
+{
+	struct sap_server *ss = data;
+	uint16_t maxmsgsize, *val;
+
+	assert(ss && param);
+
+	if (ss->state != SAP_STATE_DISCONNECTED)
+		goto error_rsp;
+
+	stop_guard_timer(ss);
+
+	val = (uint16_t *) &param->val;
+	maxmsgsize = ntohs(*val);
+
+	debug("Connect MaxMsgSize: 0x%04X(%d)", maxmsgsize, maxmsgsize);
+
+	ss->state = SAP_STATE_CONNECT_IN_PROGRESS;
+
+	if (maxmsgsize <= SAP_BUF_SIZE){
+		ss->processing_req = SAP_CONNECT_REQ;
+		sap_connect_req(ss, maxmsgsize);
+	}else{
+		sap_connect_rsp(ss, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED, htons(SAP_BUF_SIZE));
+	}
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(data);
+}
+
+static int disconnect_req(void *data, sap_disconnection_type_t disc_type)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("disconnect_req: type 0x%x state %d", disc_type, ss->state);
+
+	switch(disc_type) {
+	case SAP_DISCONNECTION_TYPE_GRACEFUL:
+
+		if (ss->state == SAP_STATE_DISCONNECTED || ss->state == SAP_STATE_CONNECT_IN_PROGRESS)
+			goto error_req;
+
+		if (ss->state == SAP_STATE_CONNECTED) {
+			ss->state = SAP_STATE_GRACEFUL_DISCONNECT;
+			ss->processing_req = SAP_NO_REQ;
+			disconnect_ind(ss, disc_type);
+
+			/* Start guard timer - timer will disconnect connection if client doesn't do it. */
+			start_guard_timer(ss, SAP_TIMER_GRACEFUL_DISCONNECT);
+
+			return 0;
+		}
+
+		/* Disconnection is ongoing - do nothing. */
+		return 0;
+
+	case SAP_DISCONNECTION_TYPE_IMMEDIATE:
+
+		if (ss->state == SAP_STATE_DISCONNECTED || ss->state == SAP_STATE_CONNECT_IN_PROGRESS)
+			goto error_req;
+
+		if (ss->state == SAP_STATE_CONNECTED ||
+				ss->state == SAP_STATE_GRACEFUL_DISCONNECT) {
+			ss->state = SAP_STATE_IMMEDIATE_DISCONNECT;
+			ss->processing_req = SAP_NO_REQ;
+
+			/* Stop timer if it is run. */
+			stop_guard_timer(ss);
+
+			disconnect_ind(ss, disc_type);
+			sap_disconnect_req(ss, 0);
+
+			return 0;
+		}
+
+		/* Disconnection is ongoing - do nothing. */
+		return 0;
+
+	case SAP_DISCONNECTION_TYPE_CLIENT:
+
+		if (ss->state != SAP_STATE_CONNECTED && ss->state != SAP_STATE_GRACEFUL_DISCONNECT)
+			goto error_rsp;
+
+		ss->state = SAP_STATE_CLIENT_DISCONNECT;
+		ss->processing_req = SAP_NO_REQ;
+
+		/* Stop timer if it is run. */
+		stop_guard_timer(ss);
+
+		sap_disconnect_req(ss, 0);
+
+		return 0;
+
+	default:
+		error("Unexpected disconnection type: %#x", disc_type);
+		return -EINVAL;
+	}
+
+error_rsp:
+	sap_error_rsp(ss);
+error_req:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	return -EPERM;
+}
+
+static void transfer_apdu_req(void * data, sap_parameter * param)
+{
+	struct sap_server *ss = data;
+
+	assert(ss && param);
+	param->len = ntohs(param->len);
+
+	debug("transfer_apdu_req: data %p state %d", data, ss->state);
+	debug("transfer_apdu_req: apdu param id %d  val %s len %d ", param->id, param->val, param->len);
+
+	if (ss->state != SAP_STATE_CONNECTED && ss->state != SAP_STATE_GRACEFUL_DISCONNECT)
+		goto error_rsp;
+
+	if (ss->processing_req != SAP_NO_REQ)
+		goto error_rsp;
+
+	ss->processing_req = SAP_TRANSFER_APDU_REQ;
+	sap_transfer_apdu_req(ss, param);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+
+static void transfer_atr_req(void * data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("transfer_atr_req: data %p state %d", data, ss->state);
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (ss->processing_req != SAP_NO_REQ)
+		goto error_rsp;
+
+	ss->processing_req = SAP_TRANSFER_ATR_REQ;
+	sap_transfer_atr_req(ss);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+
+static void power_sim_off_req(void *data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("power_sim_off_req: data %p state %d", data, ss->state);
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (!is_power_sim_off_req_allowed(ss->processing_req))
+		goto error_rsp;
+
+	ss->processing_req = SAP_POWER_SIM_OFF_REQ;
+	sap_power_sim_off_req(ss);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+static void power_sim_on_req(void *data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("power_sim_on_req: data %p state %d", data, ss->state);
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (ss->processing_req != SAP_NO_REQ)
+		goto error_rsp;
+
+	ss->processing_req = SAP_POWER_SIM_ON_REQ;
+	sap_power_sim_on_req(ss);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+static void reset_sim_req(void *data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("reset_sim_req: data %p state %d", data, ss->state);
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (!is_reset_sim_req_allowed(ss->processing_req))
+		goto error_rsp;
+
+	ss->processing_req = SAP_RESET_SIM_REQ;
+	sap_reset_sim_req(ss);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+static void transfer_card_reader_status_req(void * data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+	debug("transfer_card_reader_status_req: data %p state %d", data, ss->state);
+
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (ss->processing_req != SAP_NO_REQ)
+		goto error_rsp;
+
+	ss->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
+	sap_transfer_card_reader_status_req(ss);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+static void set_transport_protocol_req(void *data, sap_parameter *param)
+{
+	struct sap_server *ss = data;
+
+	assert(ss && param);
+	debug("set_transport_protocol_req: data %p state %d param %p", data, ss->state, param);
+
+	if (ss->state != SAP_STATE_CONNECTED)
+		goto error_rsp;
+
+	if (ss->processing_req != SAP_NO_REQ)
+		goto error_rsp;
+
+	ss->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
+	sap_set_transport_protocol_req(ss, param);
+
+	return;
+
+error_rsp:
+	error("Unexpected request state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	sap_error_rsp(ss);
+}
+
+static int disconnect_ind(void *sap_device, sap_disconnection_type_t type)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE];
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+	debug("disconnect_ind: data %p state %d disc_type %d", ss, ss->state, type);
+
+
+	if (ss->state != SAP_STATE_CONNECTED && ss->state != SAP_STATE_GRACEFUL_DISCONNECT)
+		goto error_ind;
+
+	if (ss->state == SAP_STATE_GRACEFUL_DISCONNECT && type == SAP_DISCONNECTION_TYPE_GRACEFUL)
+		goto error_ind;
+
+	memset(buf, 0, sizeof(buf));
+	msg->id = SAP_DISCONNECT_IND;
+	msg->nparam = 0x01;
+
+	/* Adding disconnection type. */
+	param->id  = SAP_PARAM_ID_DISCONNECT_IND;
+	param->len = htons(SAP_PARAM_ID_DISCONNECT_IND_LEN);
+	*param->val = (uint8_t) type;
+	size += PARAMETER_SIZE(SAP_PARAM_ID_DISCONNECT_IND_LEN);
+
+	debug("[%s::%s] buf=%s size=%#x", __FILE__, __FUNCTION__, buf, (unsigned int)size);
+	return send_message(sap_device, buf, size);
+
+error_ind:
+	error("Unexpected indication state: %#x processing_req: %#x", ss->state, ss->processing_req);
+	return -EPERM;
+}
+
+static int handle_cmd(void *data, unsigned char *buf, gsize size)
+{
+	sap_message *msg = (sap_message *) buf;
+
+	/* Avoiding invalid memory access */
+	if (size < sizeof(sap_message))
+		goto error_rsp;
+
+	/* When number of parameters != 0 make sure that it has the min size */
+	if (msg->nparam != 0 &&
+			size < (sizeof(sap_message) + sizeof(sap_parameter) + 4))
+		goto error_rsp;
+
+	if (check_msg(msg) < 0)
+		goto error_rsp;
+
+	switch(msg->id) {
+	case SAP_CONNECT_REQ:
+		debug("SAP Connect");
+		connect_req(data, msg->param);
+		return 0;
+	case SAP_DISCONNECT_REQ:
+		debug("SAP Disconnect");
+		disconnect_req(data, SAP_DISCONNECTION_TYPE_CLIENT);
+		return 0;
+	case SAP_TRANSFER_APDU_REQ:
+		debug("SAP Transfer APDU");
+		transfer_apdu_req(data, msg->param);
+		return 0;
+	case SAP_TRANSFER_ATR_REQ:
+		debug("SAP Transfer ATR");
+		transfer_atr_req(data);
+		return 0;
+	case SAP_POWER_SIM_OFF_REQ:
+		debug("SAP SIM off");
+		power_sim_off_req(data);
+		return 0;
+	case SAP_POWER_SIM_ON_REQ:
+		debug("SAP SIM on");
+		power_sim_on_req(data);
+		return 0;
+	case SAP_RESET_SIM_REQ:
+		debug("SAP SIM reset");
+		reset_sim_req(data);
+		return 0;
+	case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+		debug("SAP reader status");
+		transfer_card_reader_status_req(data);
+		return 0;
+	case SAP_SET_TRANSPORT_PROTOCOL_REQ:
+		debug("SAP set proto request");
+		set_transport_protocol_req(data, msg->param);
+		return 0;
+	}
+
+error_rsp:
+	debug("SAP ERROR RSP");
+	sap_error_rsp(data);
+	return -EBADMSG;
+}
+
+static gboolean sap_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+{
+	unsigned char buf[SAP_BUF_SIZE];
+	gsize bytes_read = 0;
+
+	debug("[%s::%s]", __FILE__, __FUNCTION__);
+
+	if (cond & G_IO_NVAL)
+		return FALSE;
+
+	if (cond & G_IO_ERR) {
+		debug("ERR on RFCOMM socket");
+		goto failed;
+	}
+
+	if (cond & G_IO_HUP ) {
+		debug("HUP on RFCOMM socket");
+		goto failed;
+	}
+
+	if (g_io_channel_read(chan, (gchar *) buf, sizeof(buf) - 1,
+				&bytes_read) != G_IO_ERROR_NONE)
+		return TRUE;
+
+	if (handle_cmd(data, buf, bytes_read) < 0) {
+		debug("Invalid SAP message");
+	}
+
+	return TRUE;
+
+failed:
+	return FALSE;
+}
+
+static void sap_io_destroy(void *data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+
+	if (ss && ss->io) {
+		gboolean connected = FALSE;
+
+		/* Stop timer if it is run. */
+		stop_guard_timer(ss);
+
+		g_io_channel_shutdown(ss->io, TRUE, NULL);
+		g_io_channel_unref(ss->io);
+
+		ss->io = NULL;
+
+		if (ss->state != SAP_STATE_CONNECT_IN_PROGRESS)
+			emit_property_changed(connection, ss->path, SAP_SERVER_INTERFACE,
+									"Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+		if (ss->state == SAP_STATE_CONNECT_IN_PROGRESS ||
+					ss->state == SAP_STATE_CONNECTED ||
+					ss->state == SAP_STATE_GRACEFUL_DISCONNECT ){
+				sap_disconnect_req(NULL, 1);
+			}
+
+		ss->state = SAP_STATE_DISCONNECTED;
+	}
+
+	debug("[%s::%s]", __FILE__, __FUNCTION__);
+}
+
+static void sap_connect_cb(GIOChannel *chan, GError *gerr, gpointer data)
+{
+	struct sap_server *ss = data;
+
+	assert(ss);
+
+	debug("[%s::%s]", __FILE__, __FUNCTION__);
+
+	/* Start timer which will shutdown channel if client doesn't send CONNECT_REQ. */
+	start_guard_timer(ss, SAP_TIMER_NO_ACTIVITY);
+
+	g_io_add_watch_full(chan, G_PRIORITY_DEFAULT,
+			G_IO_IN | G_IO_ERR | G_IO_HUP| G_IO_NVAL,
+			(GIOFunc) sap_io_cb, ss, sap_io_destroy);
+}
+
+static void sap_auth_cb(DBusError *derr, void *data)
+{
+	GError *gerr = NULL;
+	struct sap_server *ss = data;
+
+	assert(ss && ss->io);
+
+	debug("[%s::%s]", __FILE__, __FUNCTION__);
+
+	if (derr && dbus_error_is_set(derr)) {
+		error("Access denied: %s", derr->message);
+		goto drop;
+	}
+
+	if (!bt_io_accept(ss->io, sap_connect_cb, ss, NULL, &gerr)) {
+		error("bt_io_accept: %s", gerr->message);
+		g_error_free(gerr);
+		goto drop;
+	}
+	return;
+
+drop:
+	g_io_channel_shutdown(ss->io, TRUE, NULL);
+	g_io_channel_unref(ss->io);
+	ss->io = NULL;
+}
+
+static void connect_confirm(GIOChannel *chan, gpointer data)
+{
+	GError *gerr = NULL;
+	bdaddr_t src, dst;
+	int err;
+	struct sap_server *ss = data;
+
+	assert(chan && ss);
+
+	if (ss->io)
+		goto drop;
+
+	bt_io_get(chan, BT_IO_RFCOMM, &gerr,
+			BT_IO_OPT_SOURCE_BDADDR, &src,
+			BT_IO_OPT_DEST_BDADDR, &dst,
+			BT_IO_OPT_INVALID);
+	if (gerr) {
+		error("%s", gerr->message);
+		g_error_free(gerr);
+		goto drop;
+	}
+
+	ss->io = g_io_channel_ref(chan);
+
+	err = btd_request_authorization(&src, &dst, SAP_UUID, sap_auth_cb, ss);
+
+	if (err < 0) {
+		debug("Authorization denied: %s", strerror(-err));
+		goto drop;
+	}
+
+	debug("[%s::%s] RFCOMM SAP accept socket fd: %#x", __FILE__, __FUNCTION__, g_io_channel_unix_get_fd(chan));
+
+	return;
+
+drop:
+	g_io_channel_shutdown(chan, TRUE, NULL);
+	if (ss->io && ss->io == chan) {
+		g_io_channel_unref(ss->io);
+		ss->io = NULL;
+	}
+}
+
+static void path_unregister(void *data)
+{
+	struct sap_server *ss = data;
+
+	debug("Unregistered interface %s on path %s",
+			SAP_SERVER_INTERFACE, ss->path);
+
+	server_free(ss);
+}
+
+int sap_server_init(DBusConnection *conn)
+{
+	connection = dbus_connection_ref(conn);
+
+	return 0;
+}
+
+void sap_server_exit(void)
+{
+	dbus_connection_unref(connection);
+	connection = NULL;
+}
+
+static inline DBusMessage *invalid_arguments(DBusMessage *msg,
+					const char *description)
+{
+	return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
+				description);
+}
+
+static DBusMessage *enable(DBusConnection *conn,
+			DBusMessage *msg, void *data)
+{
+	struct sap_server *ss = data;
+	sdp_record_t *record;
+	GIOChannel *io;
+	GError *gerr = NULL;
+	gboolean master = TRUE;
+	uint8_t chan = SAP_SERVER_CHANNEL;
+
+	if (ss->enable == TRUE)
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"Server already enabled");
+
+	record = sap_record(SAP_SERVER_CHANNEL);
+	if (add_record_to_server(&ss->src, record) < 0) {
+		error("Failed to register service record");
+		sdp_record_free(record);
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"Record registration failed");
+	}
+
+	io = bt_io_listen(BT_IO_RFCOMM, NULL, connect_confirm,
+			ss, NULL, &gerr,
+			BT_IO_OPT_SOURCE_BDADDR, &ss->src,
+			BT_IO_OPT_CHANNEL, chan,
+			BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
+			BT_IO_OPT_MASTER, master,
+			BT_IO_OPT_INVALID);
+
+	if (!io) {
+		error("bt_io_listen: %s", gerr->message);
+		g_error_free(gerr);
+		sdp_record_free(record);
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"RFCOMM SAP channel listen failed");
+	}
+
+	debug("RFCOMM SAP listen socket fd %#x", g_io_channel_unix_get_fd(io));
+
+	ss->enable = TRUE;
+	ss->record_id = record->handle;
+
+	emit_property_changed(connection, ss->path, SAP_SERVER_INTERFACE,
+				"Enabled", DBUS_TYPE_BOOLEAN, &ss->enable);
+
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disable(DBusConnection *conn,
+				DBusMessage *msg, void *data)
+{
+	struct sap_server *ss = data;
+	DBusMessage *reply;
+
+	if (ss->enable == FALSE)
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"Server already disabled");
+
+	if (ss->state != SAP_STATE_DISCONNECTED)
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"There is ongoing connection");
+
+	reply = dbus_message_new_method_return(msg);
+	if (!reply)
+		return NULL;
+
+	ss->enable = FALSE;
+	remove_record_from_server(ss->record_id);
+
+	if (ss->listen_io) {
+		debug("[%s::%s] Stopping RFCOMM SAP listen socket fd: %#x", __FILE__, __FUNCTION__, g_io_channel_unix_get_fd(ss->listen_io));
+		g_io_channel_shutdown(ss->listen_io, TRUE, NULL);
+		g_io_channel_unref(ss->listen_io);
+		ss->listen_io = NULL;
+	}
+
+	emit_property_changed(connection, ss->path, SAP_SERVER_INTERFACE,
+				"Enabled", DBUS_TYPE_BOOLEAN, &ss->enable);
+
+	return reply;
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+				DBusMessage *msg, void *data)
+{
+	struct sap_server *ss = data;
+	DBusMessage *reply;
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	dbus_bool_t connected;
+
+	assert(ss && conn && msg);
+
+	reply = dbus_message_new_method_return(msg);
+	if (!reply)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	/* Enabled */
+	dict_append_entry(&dict, "Enabled", DBUS_TYPE_BOOLEAN, &ss->enable);
+
+	/* Connected */
+	connected = (ss->state == SAP_STATE_CONNECTED || ss->state == SAP_STATE_GRACEFUL_DISCONNECT);
+	dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	return reply;
+}
+
+static DBusMessage *set_property(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	DBusMessageIter iter;
+	DBusMessageIter sub;
+	const char *property;
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return invalid_arguments(msg, "Not a dict");
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return invalid_arguments(msg, "Key not a string");
+
+	dbus_message_iter_get_basic(&iter, &property);
+	dbus_message_iter_next(&iter);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+		return invalid_arguments(msg, "Value not a variant");
+	dbus_message_iter_recurse(&iter, &sub);
+
+	if (g_str_equal("Enabled", property)) {
+		gboolean enabled;
+
+		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
+			return invalid_arguments(msg, "Value not boolean");
+		dbus_message_iter_get_basic(&sub, &enabled);
+
+		return enabled ? enable(conn, msg, data) :
+				disable(conn, msg, data);
+	}
+
+	return invalid_arguments(msg, "Property does not exist");
+}
+
+
+static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+	struct sap_server *ss = data;
+	dbus_bool_t disc_type;
+	const char *sender;
+	sap_disconnection_type_t sap_disc_type;
+
+	assert(ss);
+
+	if (!ss->enable)
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"Server already disabled");
+
+	if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &disc_type, DBUS_TYPE_INVALID) == FALSE)
+		return NULL;
+
+	sap_disc_type = disc_type ? SAP_DISCONNECTION_TYPE_GRACEFUL : SAP_DISCONNECTION_TYPE_IMMEDIATE;
+	if (disconnect_req(ss, sap_disc_type) < 0)
+		return g_dbus_create_error(msg, ERROR_INTERFACE
+				".Failed",
+				"There is no active connection");
+
+	return dbus_message_new_method_return(msg);
+}
+
+static GDBusMethodTable server_methods[] = {
+	{ "SetProperty",	"sv",	"",	set_property },
+	{ "GetProperties",	"",	"a{sv}",get_properties },
+	{ "Disconnect",	"b",	"", disconnect },
+	{ }
+};
+
+static GDBusSignalTable server_signals[] = {
+	{ "PropertyChanged",		"sv"		},
+	{ }
+};
+
+int sap_server_register(const char *path, bdaddr_t *src)
+{
+	struct sap_server *ss;
+
+	ss = g_new0(struct sap_server, 1);
+	if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE,
+				server_methods, server_signals, NULL,
+				ss, path_unregister)) {
+		error("D-Bus failed to register %s interface", SAP_SERVER_INTERFACE);
+		server_free(ss);
+		return -1;
+	}
+
+	ss->path = g_strdup(path);
+	bacpy(&ss->src, src);
+
+	return 0;
+}
+
+int sap_server_unregister(const char *path)
+{
+	g_dbus_unregister_interface(connection, path, SAP_SERVER_INTERFACE);
+
+	return 0;
+}
+
+int sap_connect_rsp(void *sap_device, sap_status_t status, uint16_t maxmsgsize)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE];
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x status 0%x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req, status);
+
+	if (ss->state != SAP_STATE_CONNECT_IN_PROGRESS)
+		goto failed;
+
+	memset(buf, 0, sizeof(buf));
+	msg->id = SAP_CONNECT_RESP;
+	msg->nparam = 0x01;
+
+	/* Adding connection status */
+	param->id = SAP_PARAM_ID_CONN_STATUS;
+	param->len = htons(SAP_PARAM_ID_CONN_STATUS_LEN);
+	*param->val = (uint8_t)status;
+	size += PARAMETER_SIZE(SAP_PARAM_ID_CONN_STATUS_LEN);
+
+	/* Adding MaxMsgSize */
+	if (maxmsgsize && (status == SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED ||
+			status == SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL)) {
+		uint16_t *len;
+		msg->nparam++;
+		/* Skipping the first param */
+		param = (sap_parameter *) &buf[size];
+		param->id = SAP_PARAM_ID_MAXMSGSIZE;
+		param->len = htons(SAP_PARAM_ID_MAXMSGSIZE_LEN);
+		len = (uint16_t *) &param->val;
+		*len = htons(maxmsgsize);
+		size += PARAMETER_SIZE(SAP_PARAM_ID_MAXMSGSIZE_LEN);
+	}
+
+	if (status == SAP_STATUS_OK) {
+		gboolean connected = TRUE;
+		emit_property_changed(connection, ss->path, SAP_SERVER_INTERFACE,
+			"Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+		ss->state = SAP_STATE_CONNECTED;
+	}
+	else {
+		ss->state = SAP_STATE_DISCONNECTED;
+
+		/* Start timer which will shutdown channel if client
+		 * doesn't send CONNECT_REQ or doesn't shutdown channel itself. */
+		start_guard_timer(ss, SAP_TIMER_NO_ACTIVITY);
+	}
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+
+failed:
+	error("Unexpected response");
+	return -EPERM;
+}
+
+int sap_disconnect_rsp(void *sap_device)
+{
+	struct sap_server *ss = sap_device;
+	sap_message msg = {0};
+
+	assert(ss);
+	debug("sap_disconnect_rsp: sap_device %p", sap_device);
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	switch(ss->state) {
+	case SAP_STATE_CLIENT_DISCONNECT:
+		msg.id = SAP_DISCONNECT_RESP;
+
+		ss->state = SAP_STATE_DISCONNECTED;
+		ss->processing_req = SAP_NO_REQ;
+
+		/* Start timer which will close channel if client doesn't do it. */
+		start_guard_timer(ss, SAP_TIMER_NO_ACTIVITY);
+
+		return send_message(sap_device, (unsigned char *) &msg, sizeof(msg));
+
+	case SAP_STATE_IMMEDIATE_DISCONNECT:
+		ss->state = SAP_STATE_DISCONNECTED;
+		ss->processing_req = SAP_NO_REQ;
+
+		if (ss->io)
+			g_io_channel_shutdown(ss->io, TRUE, NULL);
+		return 0;
+	default:
+		break;
+	}
+
+failed:
+	error("Unexpected response");
+	return -EPERM;
+}
+
+int sap_transfer_apdu_rsp(void *sap_device, sap_result_t result, uint8_t *apdu, uint16_t length)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_TRANSFER_APDU_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request.*/
+		return 0;
+
+	if (result == SAP_RESULT_OK && (!apdu || (apdu && length == 0x00)))
+		return -EINVAL;
+
+	msg->id = SAP_TRANSFER_APDU_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, param);
+
+	/* Adding APDU response. */
+	if (result == SAP_RESULT_OK) {
+		msg->nparam++;
+		/* Skipping the first param. */
+		param = (sap_parameter *) &buf[size];
+		param->id = SAP_PARAM_ID_RESPONSE_APDU;
+		param->len = htons(length);
+
+		size += PARAMETER_SIZE(length);
+		if (size > SAP_BUF_SIZE)
+			return -EOVERFLOW;
+
+		memcpy(param->val, apdu, length);
+	}
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_transfer_atr_rsp(void *sap_device, sap_result_t result, uint8_t *atr, uint16_t length)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE]= {0};
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_TRANSFER_ATR_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request.*/
+		return 0;
+
+	if (result == SAP_RESULT_OK && (!atr || (atr && length == 0x00)))
+		return -EINVAL;
+
+	msg->id = SAP_TRANSFER_ATR_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, param);
+
+	/* Adding ATR response */
+	if (result == SAP_RESULT_OK) {
+		msg->nparam++;
+		/* Skipping the first param */
+		param = (sap_parameter *) &buf[size];
+		param->id = SAP_PARAM_ID_ATR;
+		param->len = htons(length);
+
+		size += PARAMETER_SIZE(length);
+		if (size > SAP_BUF_SIZE)
+			return -EOVERFLOW;
+
+		memcpy(param->val, atr, length);
+	}
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_power_sim_off_rsp(void *sap_device, sap_result_t result)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_POWER_SIM_OFF_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request. */
+		return 0;
+
+	msg->id = SAP_POWER_SIM_OFF_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, msg->param);
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_power_sim_on_rsp(void *sap_device, sap_result_t result)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_POWER_SIM_ON_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request. */
+		return 0;
+
+	msg->id = SAP_POWER_SIM_ON_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, msg->param);
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_reset_sim_rsp(void *sap_device, sap_result_t result)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_RESET_SIM_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request. */
+		return 0;
+
+	msg->id = SAP_RESET_SIM_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, msg->param);
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_transfer_card_reader_status_rsp(void *sap_device, sap_result_t result, icc_reader_status_t status)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+				__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->processing_req != SAP_TRANSFER_CARD_READER_STATUS_REQ)
+		/* Ignore this response because processing (state) request has been changed.
+		 * This situation can happen e.g. when client sends disconnect request
+		 * while server is processing another request. */
+		return 0;
+
+	msg->id = SAP_TRANSFER_CARD_READER_STATUS_RESP;
+
+	/* Adding result code */
+	msg->nparam = 0x01;
+	size += add_result_parameter(result, param);
+
+	/* Adding card reader status. */
+	if (result == SAP_RESULT_OK) {
+		msg->nparam++;
+		/* Skipping the first param. */
+		param = (sap_parameter *) &buf[size];
+		param->id = SAP_PARAM_ID_CARD_READER_STATUS;
+		param->len = htons(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
+		*param->val = (uint8_t) status;
+		size += PARAMETER_SIZE(SAP_PARAM_ID_CARD_READER_STATUS_LEN);
+	}
+
+	ss->processing_req = SAP_NO_REQ;
+	return send_message(sap_device, buf, size);
+}
+
+int sap_error_rsp(void *sap_device)
+{
+	sap_message msg;
+
+	memset(&msg, 0, sizeof(msg));
+	msg.id = SAP_ERROR_RESP;
+
+	return send_message(sap_device, (unsigned char *) &msg, sizeof(msg));
+}
+
+int sap_status_ind(void *sap_device, sap_status_change_t status_change)
+{
+	struct sap_server *ss = sap_device;
+	unsigned char buf[SAP_BUF_SIZE] = {0};
+	sap_message *msg = (sap_message *) buf;
+	sap_parameter *param = (sap_parameter *) msg->param;
+	gsize size = sizeof(sap_message);
+
+	assert(ss);
+
+	debug("[%s::%s] state: %#x processing_req: %#x",
+					__FILE__, __FUNCTION__, ss->state, ss->processing_req);
+
+	if (ss->state != SAP_STATE_CONNECTED && ss->state != SAP_STATE_GRACEFUL_DISCONNECT)
+		/* Ignore this indication when server is not connected. */
+		return 0;
+
+	msg->id = SAP_STATUS_IND;
+	msg->nparam = 0x01;
+
+	/* Adding status change. */
+	param->id  = SAP_PARAM_ID_STATUS_CHANGE;
+	param->len = htons(SAP_PARAM_ID_STATUS_CHANGE_LEN);
+	*param->val = (uint8_t) status_change;
+	size += PARAMETER_SIZE(SAP_PARAM_ID_STATUS_CHANGE_LEN);
+
+	return send_message(sap_device, buf, size);
+}
diff --git a/sap/server.h b/sap/server.h
new file mode 100644
index 0000000..4dca525
--- /dev/null
+++ b/sap/server.h
@@ -0,0 +1,25 @@
+/*
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2010 ST-Ericsson SA
+ *  Copyright (C) 2010 Claudio Takahasi<claudio.takahasi@openbossa.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.
+ *
+ *  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
+ */
+
+int sap_server_init(DBusConnection *conn);
+void sap_server_exit(void);
+int sap_server_register(const char *path, bdaddr_t *src);
+int sap_server_unregister(const char *path);
+
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH v2] Bluetooth: Latest firmware support for ath3k USB device
From: Marcel Holtmann @ 2010-10-06  8:48 UTC (permalink / raw)
  To: Suraj Sumangala; +Cc: linux-bluetooth, Jothikumar.Mothilal
In-Reply-To: <1286353896-8811-1-git-send-email-suraj@atheros.com>

Hi Suraj,

> This patch add support for latest ath3k USB Bluetooth device firmare.
> The firmware implements shared antenna support and
> fixes few critical bugs.
> 
> Signed-off-by: Suraj Sumangala <suraj@atheros.com>
> ---
>  drivers/bluetooth/ath3k.c |   11 ++++++++---
>  1 files changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
> index 128cae4..6eb4bcf 100644
> --- a/drivers/bluetooth/ath3k.c
> +++ b/drivers/bluetooth/ath3k.c
> @@ -103,6 +103,8 @@ error:
>  	return err;
>  }
>  
> +#define ATH3K_FW	"ath3k-fw.fw"
> +#define ATH3K_FW_LEGACY	"ath3k-1.fw"
>  static int ath3k_probe(struct usb_interface *intf,
>  			const struct usb_device_id *id)
>  {
> @@ -122,9 +124,12 @@ static int ath3k_probe(struct usb_interface *intf,
>  
>  	data->udev = udev;
>  
> -	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
> -		kfree(data);
> -		return -EIO;
> +	if (request_firmware(&firmware, ATH3K_FW, &udev->dev) < 0) {
> +		if (request_firmware(&firmware, ATH3K_FW_LEGACY,
> +							&udev->dev) < 0) {
> +			kfree(data);
> +			return -EIO;
> +		}
>  	}
>  
>  	size = max_t(uint, firmware->size, 4096);

if this change is enough and the firmware is API compatible, then why do
you bother with this change. Just copy the new firmware over ath3k.fw
file.

I was under the assumption that the firmware is somehow API incompatible
with the current driver, but if it is not, then we don't need this at
all.

So I would propose to just send a patch against linux-firmware tree to
replace the current ath3k.fw with a newer file. Since only in API
incompatible changes should be reflected with a new name.

Regards

Marcel



^ permalink raw reply

* [PATCH v2] Bluetooth: Latest firmware support for ath3k USB device
From: Suraj Sumangala @ 2010-10-06  8:31 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jothikumar.Mothilal, Suraj Sumangala

This patch add support for latest ath3k USB Bluetooth device firmare.
The firmware implements shared antenna support and
fixes few critical bugs.

Signed-off-by: Suraj Sumangala <suraj@atheros.com>
---
 drivers/bluetooth/ath3k.c |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index 128cae4..6eb4bcf 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -103,6 +103,8 @@ error:
 	return err;
 }
 
+#define ATH3K_FW	"ath3k-fw.fw"
+#define ATH3K_FW_LEGACY	"ath3k-1.fw"
 static int ath3k_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
 {
@@ -122,9 +124,12 @@ static int ath3k_probe(struct usb_interface *intf,
 
 	data->udev = udev;
 
-	if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) {
-		kfree(data);
-		return -EIO;
+	if (request_firmware(&firmware, ATH3K_FW, &udev->dev) < 0) {
+		if (request_firmware(&firmware, ATH3K_FW_LEGACY,
+							&udev->dev) < 0) {
+			kfree(data);
+			return -EIO;
+		}
 	}
 
 	size = max_t(uint, firmware->size, 4096);
-- 
1.7.0.4


^ permalink raw reply related

* RE: Sim Access profile server implementation
From: Waldemar.Rymarkiewicz @ 2010-10-06  7:28 UTC (permalink / raw)
  To: marcel; +Cc: suraj, linux-bluetooth, Jothikumar.Mothilal, joakim.xj.ceder
In-Reply-To: <1286280767.17473.89.camel@aeonflux>

Marcel,

>
>please no top posting on this mailing list.
>

Sorry, didn't know that.  Thanks for pointing this out.

>> I understand you concerns about dbus reliability and I agree=20
>with you , but I guess we should find a compromise solution as=20
>ofono is not used widely in Linux mobile platforms nowadays.
>>=20
>> I my view, combination of a bluez plugin for sap and a=20
>platform dependend sim driver is a reliable and most available=20
>solution so far. The SAP plugin implements BT SAP spec and=20
>require simple API (connect, disconnect, apdu, atr, status)=20
>which is implemented in SIM driver for a certain platform.=20
>This way it's relatively easy to support SAP in different=20
>platforms. Ofono can have its own driver as well.
>>=20
>> What's you view on such design?
>> Can we also have a double solution one in ofono for ofono=20
>aware platforms and the second as a plugin for others?=20
>
>I am fine with starting this in BlueZ and see how far we get.=20
>And yes, plugin based is a must from my point of view. It is=20
>most likely similar to our different telephony drivers for=20
>Handsfree support.

It's nice to here that.

>We will move strongly in the direction of oFono being the main=20
>telephony stack. So I do care mostly that this work in=20
>conjunction with oFono.
>Everything else is just a nice benefit if it doesn't clutter=20
>the overhaul implementation and requires pointless abstraction=20
>everywhere.
>> BTW, I already have this implemented and tested with real hardware=20
>> (STEricsson). Bluez SAP works fine with Nokia 616 carkit :)
>
>Can you share that code with us. And also hardware if you. We=20
>are still having hard time to find proper hardware to test this on.

Will send a patch soon. I use http://www.stericsson.com/platforms/U8500.jsp=
 hw, but need to check if I can share one with you.

Regards,
/Waldek=

^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Marcel Holtmann @ 2010-10-06  7:19 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Luis Rodriguez, linux-bluetooth, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org, Deepak Dhamdhere, Sree Durbha
In-Reply-To: <AANLkTimz7U52_qHaTutQDOFQde+GrWJRA0WpqY__FPgi@mail.gmail.com>

Hi Luis,

> > most likely via a separate firmware loading driver.
> 
> Like the fwload patch ? Or something different?

something clean of course and not this hacking around, but in general
along that.

> > Your ath3k driver is such a driver. Same as the bcm203x driver.
> 
> Right -- so ath3k depends on some atheros USB device IDs, and its a
> stupid driver that just loads firmware. The problem with this new
> device is that it requires two phases. One to load some sort of
> firmware onto it to get it to read as an ath3k device, and then ath3k
> will load the right firmware to it. So the hardware device is already
> claiming a btusb vendor:device ID, we can't change that I believe. Of
> course for future devices we can, and we've addressed this and its
> been fixed.

So your current loading procedure is this:

	1) btusb with hacked firmware loading
	2) ath3k
	3) btusb with HCI

Who thought that this is a good idea in the first place? And more
important that I would accept this upstream? This is even worse than I
thought it is.

Please get this craziness fixed.

> > They don't do anything than claiming that USB device, loading the firmware, and then let it reset.
> 
> Right but if the SFLASH configurations hardware is already shipping
> and without firmware is claiming to be a BT USB device which matches
> the USB vendor:device ID of the btusb driver. Unfortunately it does
> not accept HCI commands which as you indicates breaks some
> specification. We can and have fixed this in future chipsets but this
> one cannot be addressed. So what do we do?
> 
> > And after the reset the btusb can claim the one where the firmware has
> > been loaded and which behaves like a proper USB dongle.
> 
> Right, that's what the fwload patch from our BT team does, no?

Yes, but not inside the btusb driver. Stop hacking a generic driver with
crazy firmware loading only because the USB Bluetooth class descriptors
got screwed up in the first place.

> > The part that I don't understand is that you have the ath3k driver doing
> > it exactly how it should be done, why now started to make nasty hacks in
> > the btusb driver.
> 
> Yeah that seems to have been a shortcoming, its something you should
> expect from us moving forward. I've been told AR3012 and future
> Atheros chipsets will not have behave this way, and this issue is only
> present for the AR3011 devices with SFLASH configuration.

Most likely including the flashing into ath3k firmware loading driver
and that being called bound twice might be a good idea. However we are
not doing the firmware loading in btusb. Then a patch to blacklist this
broken device. And then ensure that the firmware changes the USB PIDs
after success.

And if I understand you correct, then it does this anyway right now
already. Otherwise the ath3k driver would not bind to it.

Now I am failing to understand why this was done wrong in the first
place. Especially if the loading procedure happens as you say it
happens.

This is the example for the Broadcom 203x devices:

static struct usb_device_id blacklist_table[] = {
        /* Broadcom BCM2033 without firmware */
        { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE },

The btusb driver clearly blacklists them. And then bcm203x can take over
loading the firmware:

static const struct usb_device_id bcm203x_table[] = {
        /* Broadcom Blutonium (BCM2033) */
        { USB_DEVICE(0x0a5c, 0x2033) },

So there is a working example of this already in the kernel tree since
forever.

Regards

Marcel



^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Marcel Holtmann @ 2010-10-06  7:09 UTC (permalink / raw)
  To: Matthew Garrett
  Cc: Luis R. Rodriguez, Luis Rodriguez, linux-bluetooth,
	linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
	Deepak Dhamdhere, Sree Durbha
In-Reply-To: <20101005215008.GA11117@srcf.ucam.org>

Hi Matthew,

> > Right -- so ath3k depends on some atheros USB device IDs, and its a
> > stupid driver that just loads firmware. The problem with this new
> > device is that it requires two phases. One to load some sort of
> > firmware onto it to get it to read as an ath3k device, and then ath3k
> > will load the right firmware to it. So the hardware device is already
> > claiming a btusb vendor:device ID, we can't change that I believe. Of
> > course for future devices we can, and we've addressed this and its
> > been fixed.
> 
> If the device IDs can be changed when the firmware is loaded, then 
> simply provide a driver that binds to the original IDs and uploads the 
> firmware. The original IDs can be blacklisted from btusb so it won't 
> interfere. The device will then boot the firmware, detach and reattach 
> with new IDs - btusb will then bind. Repeat for every cold reset.
> 
> If you can't change the IDs from firmware then an alternative would be 
> to blacklist it from btusb and provide a userspace application triggered 
> by a udev rule. Have it load the firmware and then poke 
> /sys/bus/usb/drivers/btusb/new_id .

exactly, we just blacklist the original USB IDs in the btusb driver. It
already has a blacklist table and you just use BTUSB_IGNORE in there.

Regards

Marcel



^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Matthew Garrett @ 2010-10-05 21:50 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Marcel Holtmann, Luis Rodriguez, linux-bluetooth,
	linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
	Deepak Dhamdhere, Sree Durbha
In-Reply-To: <AANLkTimz7U52_qHaTutQDOFQde+GrWJRA0WpqY__FPgi@mail.gmail.com>

On Tue, Oct 05, 2010 at 01:28:53PM -0700, Luis R. Rodriguez wrote:

> Right -- so ath3k depends on some atheros USB device IDs, and its a
> stupid driver that just loads firmware. The problem with this new
> device is that it requires two phases. One to load some sort of
> firmware onto it to get it to read as an ath3k device, and then ath3k
> will load the right firmware to it. So the hardware device is already
> claiming a btusb vendor:device ID, we can't change that I believe. Of
> course for future devices we can, and we've addressed this and its
> been fixed.

If the device IDs can be changed when the firmware is loaded, then 
simply provide a driver that binds to the original IDs and uploads the 
firmware. The original IDs can be blacklisted from btusb so it won't 
interfere. The device will then boot the firmware, detach and reattach 
with new IDs - btusb will then bind. Repeat for every cold reset.

If you can't change the IDs from firmware then an alternative would be 
to blacklist it from btusb and provide a userspace application triggered 
by a udev rule. Have it load the firmware and then poke 
/sys/bus/usb/drivers/btusb/new_id .

-- 
Matthew Garrett | mjg59@srcf.ucam.org

^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Luis R. Rodriguez @ 2010-10-05 20:28 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis Rodriguez, linux-bluetooth, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org, Deepak Dhamdhere, Sree Durbha
In-Reply-To: <1286308731.2588.13.camel@aeonflux>

On Tue, Oct 5, 2010 at 12:58 PM, Marcel Holtmann
<holtmann@linux.intel.com> wrote:
> Hi Luis,
>
>> > > Marcel, I was just poked about this thread:
>> > >
>> > > http://www.spinics.net/lists/linux-bluetooth/msg06087.html
>> > >
>> > > The hack is required because our BT hardware does not accept HCI commands
>> > > when the device is plugged in. If I understood your position you did not
>> > > want to accept the patch because our BT USB devices are violating the
>> > > specification by not acceping HCI commands and yet claiming to be BT
>> > > devices, is that right?
>> >
>> > you don't have to accept HCI commands when your device has no firmware
>> > loaded. That is just fine. However at that point you should not claim to
>> > be a Bluetooth H:2 device with USB Bluetooth descriptors.
>> >
>> > Just having different USB PIDs for without firmware and with firmware
>> > stages would have been fine. The ancient Broadcom 203x devices even got
>> > that part right.
>>
>> Ah I see.
>>
>> > So what about sticking with the current VID:PID for the device without
>> > firmware and we blacklist it in btusb driver. And then the firmware
>> > loading ensures that after reset it uses a different PID for the device
>> > with valid HCI firmware.
>>
>> How would firmware be uploaded to the device if no module
>> is claiming it?
>
> most likely via a separate firmware loading driver.

Like the fwload patch ? Or something different?

> Your ath3k driver is such a driver. Same as the bcm203x driver.

Right -- so ath3k depends on some atheros USB device IDs, and its a
stupid driver that just loads firmware. The problem with this new
device is that it requires two phases. One to load some sort of
firmware onto it to get it to read as an ath3k device, and then ath3k
will load the right firmware to it. So the hardware device is already
claiming a btusb vendor:device ID, we can't change that I believe. Of
course for future devices we can, and we've addressed this and its
been fixed.

> They don't do anything than claiming that USB device, loading the firmware, and then let it reset.

Right but if the SFLASH configurations hardware is already shipping
and without firmware is claiming to be a BT USB device which matches
the USB vendor:device ID of the btusb driver. Unfortunately it does
not accept HCI commands which as you indicates breaks some
specification. We can and have fixed this in future chipsets but this
one cannot be addressed. So what do we do?

> And after the reset the btusb can claim the one where the firmware has
> been loaded and which behaves like a proper USB dongle.

Right, that's what the fwload patch from our BT team does, no?

> The part that I don't understand is that you have the ath3k driver doing
> it exactly how it should be done, why now started to make nasty hacks in
> the btusb driver.

Yeah that seems to have been a shortcoming, its something you should
expect from us moving forward. I've been told AR3012 and future
Atheros chipsets will not have behave this way, and this issue is only
present for the AR3011 devices with SFLASH configuration.

  Luis

^ permalink raw reply

* Re: [PATCH] TODO: Automatic server indication/notification owner
From: Johan Hedberg @ 2010-10-05 20:27 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1286299418-21862-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Tue, Oct 05, 2010, Claudio Takahasi wrote:
> ---
>  TODO |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)

This one is now also upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Add PSM option for GATT/ATT over BR/EDR on gatttool
From: Johan Hedberg @ 2010-10-05 20:27 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1286298958-21494-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Tue, Oct 05, 2010, Claudio Takahasi wrote:
> ---
>  TODO              |    6 ------
>  attrib/gatttool.c |    6 ++++--
>  2 files changed, 4 insertions(+), 8 deletions(-)

The patch has been pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Marcel Holtmann @ 2010-10-05 19:58 UTC (permalink / raw)
  To: Luis R. Rodriguez
  Cc: Luis Rodriguez, linux-bluetooth, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org, Deepak Dhamdhere, Sree Durbha
In-Reply-To: <20101005192814.GB11831@tux>

Hi Luis,

> > > Marcel, I was just poked about this thread:
> > > 
> > > http://www.spinics.net/lists/linux-bluetooth/msg06087.html
> > > 
> > > The hack is required because our BT hardware does not accept HCI commands
> > > when the device is plugged in. If I understood your position you did not
> > > want to accept the patch because our BT USB devices are violating the
> > > specification by not acceping HCI commands and yet claiming to be BT
> > > devices, is that right?
> > 
> > you don't have to accept HCI commands when your device has no firmware
> > loaded. That is just fine. However at that point you should not claim to
> > be a Bluetooth H:2 device with USB Bluetooth descriptors.
> > 
> > Just having different USB PIDs for without firmware and with firmware
> > stages would have been fine. The ancient Broadcom 203x devices even got
> > that part right.
> 
> Ah I see.
> 
> > So what about sticking with the current VID:PID for the device without
> > firmware and we blacklist it in btusb driver. And then the firmware
> > loading ensures that after reset it uses a different PID for the device
> > with valid HCI firmware.
> 
> How would firmware be uploaded to the device if no module
> is claiming it?

most likely via a separate firmware loading driver. Your ath3k driver is
such a driver. Same as the bcm203x driver. They don't do anything than
claiming that USB device, loading the firmware, and then let it reset.

And after the reset the btusb can claim the one where the firmware has
been loaded and which behaves like a proper USB dongle.

The part that I don't understand is that you have the ath3k driver doing
it exactly how it should be done, why now started to make nasty hacks in
the btusb driver.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] Bluetooth: clean up rfcomm code
From: Gustavo F. Padovan @ 2010-10-05 19:42 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Emeltchenko Andrei, linux-bluetooth
In-Reply-To: <1286265236.17473.26.camel@aeonflux>

Hi Andrei,

* Marcel Holtmann <marcel@holtmann.org> [2010-10-05 09:53:56 +0200]:

> Hi Andrei,
> 
> > Remove dead code and unused rfcomm thread events
> > 
> > Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> > ---
> >  include/net/bluetooth/rfcomm.h |    5 -----
> >  net/bluetooth/rfcomm/core.c    |   29 ++++++++++++++---------------
> >  2 files changed, 14 insertions(+), 20 deletions(-)
> > 
> > diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
> > index a140847..71047bc 100644
> > --- a/include/net/bluetooth/rfcomm.h
> > +++ b/include/net/bluetooth/rfcomm.h
> > @@ -213,11 +213,6 @@ struct rfcomm_dlc {
> >  #define RFCOMM_DEFER_SETUP  8
> >  
> >  /* Scheduling flags and events */
> > -#define RFCOMM_SCHED_STATE  0
> > -#define RFCOMM_SCHED_RX     1
> > -#define RFCOMM_SCHED_TX     2
> > -#define RFCOMM_SCHED_TIMEO  3
> > -#define RFCOMM_SCHED_AUTH   4
> >  #define RFCOMM_SCHED_WAKEUP 31
> 
> we had some big ambition to use these, but never did in the end or
> realized that they are not needed. So I am fine with removing these.
> 
> Acked-by: Marcel Holtmann <marcel@holtmann.org>

Patch has been applied. Thanks.


-- 
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi

^ permalink raw reply

* Re: RFC: btusb firmware load help
From: Luis R. Rodriguez @ 2010-10-05 19:28 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Luis Rodriguez, linux-bluetooth, linux-kernel@vger.kernel.org,
	linux-wireless@vger.kernel.org, Deepak Dhamdhere, Sree Durbha
In-Reply-To: <1286266981.17473.33.camel@aeonflux>

On Tue, Oct 05, 2010 at 01:23:01AM -0700, Marcel Holtmann wrote:
> Hi Luis,
> 
> > Marcel, I was just poked about this thread:
> > 
> > http://www.spinics.net/lists/linux-bluetooth/msg06087.html
> > 
> > The hack is required because our BT hardware does not accept HCI commands
> > when the device is plugged in. If I understood your position you did not
> > want to accept the patch because our BT USB devices are violating the
> > specification by not acceping HCI commands and yet claiming to be BT
> > devices, is that right?
> 
> you don't have to accept HCI commands when your device has no firmware
> loaded. That is just fine. However at that point you should not claim to
> be a Bluetooth H:2 device with USB Bluetooth descriptors.
> 
> Just having different USB PIDs for without firmware and with firmware
> stages would have been fine. The ancient Broadcom 203x devices even got
> that part right.

Ah I see.

> So what about sticking with the current VID:PID for the device without
> firmware and we blacklist it in btusb driver. And then the firmware
> loading ensures that after reset it uses a different PID for the device
> with valid HCI firmware.

How would firmware be uploaded to the device if no module
is claiming it?

  Luis

^ permalink raw reply

* [PATCH] TODO: Automatic server indication/notification owner
From: Claudio Takahasi @ 2010-10-05 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/TODO b/TODO
index 0a82f5c..c5c404c 100644
--- a/TODO
+++ b/TODO
@@ -23,6 +23,7 @@ ATT/GATT
 
   Priority: Medium
   Complexity: C2
+  Owner: Claudio Takahasi <claudio.takahasi@openbossa.org>
 
 - gatttool should wait for req responses before quitting (some servers
   require a small sleep even with cmd's)
-- 
1.7.3.1


^ permalink raw reply related

* [PATCH] Add PSM option for GATT/ATT over BR/EDR on gatttool
From: Claudio Takahasi @ 2010-10-05 17:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO              |    6 ------
 attrib/gatttool.c |    6 ++++--
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/TODO b/TODO
index 41ec7a7..0a82f5c 100644
--- a/TODO
+++ b/TODO
@@ -40,12 +40,6 @@ ATT/GATT
   Priority: Low
   Complexity: C1
 
-- Add command line support for specifying psm with gatttool (e.g. --psm
-  37)
-
-  Priority: Medium
-  Complexity: C1
-
 - Add command line support to use medium instead of (default) low
   security level with gatttool (--sec-level)
 
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 76fe62c..2de3f8b 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -43,7 +43,6 @@
 #include "gattrib.h"
 #include "gatt.h"
 
-#define GATT_PSM 0x1f
 /* Minimum MTU for L2CAP connections over BR/EDR */
 #define ATT_MIN_MTU_L2CAP 48
 #define GATT_CID 4
@@ -55,6 +54,7 @@ static int opt_start = 0x0001;
 static int opt_end = 0xffff;
 static int opt_handle = -1;
 static int opt_mtu = 0;
+static int opt_psm = 0x1f;
 static gboolean opt_primary = FALSE;
 static gboolean opt_characteristics = FALSE;
 static gboolean opt_char_read = FALSE;
@@ -122,7 +122,7 @@ static GIOChannel *do_connect(gboolean le)
 		chan = bt_io_connect(BT_IO_L2CAP, connect_cb, NULL, NULL, &err,
 				BT_IO_OPT_SOURCE_BDADDR, &sba,
 				BT_IO_OPT_DEST_BDADDR, &dba,
-				BT_IO_OPT_PSM, GATT_PSM,
+				BT_IO_OPT_PSM, opt_psm,
 				BT_IO_OPT_OMTU, opt_mtu,
 				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
 				BT_IO_OPT_INVALID);
@@ -518,6 +518,8 @@ static GOptionEntry options[] = {
 		"Specify remote Bluetooth address", "MAC" },
 	{ "mtu", 'm', 0, G_OPTION_ARG_INT, &opt_mtu,
 		"Specify the MTU size", "MTU" },
+	{ "psm", 'p', 0, G_OPTION_ARG_INT, &opt_psm,
+		"Specify the PSM for GATT/ATT over BR/EDR", "PSM" },
 	{ NULL },
 };
 
-- 
1.7.3.1


^ permalink raw reply related

* pull-request: bluetooth-2.6 2010-10-05
From: Gustavo F. Padovan @ 2010-10-05 17:13 UTC (permalink / raw)
  To: David Miller; +Cc: linville, marcel, linux-bluetooth, netdev

Hi Dave,

In this patch set we have two fixes for regressions in L2CAP due to ERTM code
we added in L2CAP for 2.6.36, a bugfix in the L2CAP Streaming Mode that was
making the kernel crash. And a fix for a deadlock issue between the sk_sndbuf
and the backlog queue in ERTM. The rest are also needed bug fixes.

For -next pull request things go back to normal and patches go through John.

Thanks!


The following changes since commit 899611ee7d373e5eeda08e9a8632684e1ebbbf00:

  Linux 2.6.36-rc6 (2010-09-28 18:01:22 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git master

Andrei Emeltchenko (1):
      Bluetooth: fix MTU L2CAP configuration parameter

Gustavo F. Padovan (5):
      Bluetooth: Simplify L2CAP Streaming mode sending
      Bluetooth: Fix inconsistent lock state with RFCOMM
      Revert "Bluetooth: Don't accept ConfigReq if we aren't in the BT_CONFIG state"
      Bluetooth: Fix deadlock in the ERTM logic
      Bluetooth: Disallow to change L2CAP_OPTIONS values when connected

Mat Martineau (1):
      Bluetooth: Only enable L2CAP FCS for ERTM or streaming

 include/net/bluetooth/bluetooth.h |   18 +++++++++++
 net/bluetooth/l2cap.c             |   62 +++++++++++++++++-------------------
 net/bluetooth/rfcomm/sock.c       |    4 ++
 3 files changed, 51 insertions(+), 33 deletions(-)

-- 
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi

^ permalink raw reply

* Re: New Broadcom chip in W510
From: Lu Ran @ 2010-10-05 12:59 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth

[-- Attachment #1: Type: text/plain, Size: 764 bytes --]

Hi,

On Tuesday 05 October 2010 08:13:59 you wrote:
> > I put the output ot "cat /proc/bus/usb/devices" in the attachment, I am
> > pretty sure the setup of my software is OK, because now I can use my
> > bluetooth headset with an dongle, but it does not work for the internal
> > chip.
> 
> maybe that hardware has some limitations that are unclear to me. Can you
> run hcidump -X -V and give us the output when trying to establish a SCO
> connection.

Here is the output of hcidump. This issue might be related to the usb code, 
when I test the dongle, it gives the same error when I connect it through a 
usb3 port, it only works with usb2 port, but for the internal broadcom chip, 
nothing changes even when I remove the xhci_hcd module.

-- 
Best Regards,
LR

[-- Attachment #2: hcidump.log --]
[-- Type: text/x-log, Size: 15373 bytes --]

HCI sniffer - Bluetooth packet analyzer ver 1.42
device: hci0 snap_len: 1028 filter: 0xffffffffffffffff
> HCI Event: Connect Request (0x04) plen 10
    bdaddr 00:19:7F:D8:6A:C3 class 0x200404 type ACL
< HCI Command: Accept Connection Request (0x01|0x0009) plen 7
    bdaddr 00:19:7F:D8:6A:C3 role 0x00
    Role: Master
> HCI Event: Command Status (0x0f) plen 4
    Accept Connection Request (0x01|0x0009) status 0x00 ncmd 1
> HCI Event: Role Change (0x12) plen 8
    status 0x00 bdaddr 00:19:7F:D8:6A:C3 role 0x00
    Role: Master
> HCI Event: Link Key Request (0x17) plen 6
    bdaddr 00:19:7F:D8:6A:C3
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
    bdaddr 00:19:7F:D8:6A:C3 key 9741E3A1976D406A2667C8926C02BDBE
> HCI Event: Command Complete (0x0e) plen 10
    Link Key Request Reply (0x01|0x000b) ncmd 1
    status 0x00 bdaddr 00:19:7F:D8:6A:C3
> HCI Event: Connect Complete (0x03) plen 11
    status 0x00 handle 11 bdaddr 00:19:7F:D8:6A:C3 type ACL encrypt 0x01
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
    handle 11
> HCI Event: Command Status (0x0f) plen 4
    Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1
> HCI Event: Read Remote Supported Features (0x0b) plen 11
    status 0x00 handle 11
    Features: 0xbc 0xe8 0x01 0x00 0x08 0x08 0x00 0x00
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 1 scid 0x0040
< ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 1 status 0
      Connection pending - No futher information available
< ACL data: handle 11 flags 0x02 dlen 10
    L2CAP(s): Info req: type 2
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Info rsp: type 2 result 0
      Extended feature mask 0x0000
< ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0040 scid 0x0040 result 0 status 0
      Connection successful
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
    bdaddr 00:19:7F:D8:6A:C3 mode 2 clkoffset 0x0000
> HCI Event: Command Status (0x0f) plen 4
    Remote Name Request (0x01|0x0019) status 0x00 ncmd 1
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 4
      MTU 48 
< ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 4
      MTU 48 
< ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Config req: dcid 0x0040 flags 0x00 clen 0
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(s): Config rsp: scid 0x0040 flags 0x00 result 0 clen 0
      Success
> HCI Event: Remote Name Req Complete (0x07) plen 255
    status 0x00 bdaddr 00:19:7F:D8:6A:C3 name 'ATT V521'
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0040 len 15 [psm 1]
        SDP SS Req: tid 0x1 len 0xa
          pat uuid-32 0x111f (Handsfree AG)
          max 40
          cont 00
< ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(d): cid 0x0040 len 14 [psm 1]
        SDP SS Rsp: tid 0x1 len 0x9
          count 1
          handle 0x10001
          cont 00
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 21
    L2CAP(d): cid 0x0040 len 17 [psm 1]
        SDP SA Req: tid 0x2 len 0xc
          handle 0x10001
          max 38
          aid(s) 0x0004 (ProtocolDescList)
          cont 00
< ACL data: handle 11 flags 0x02 dlen 31
    L2CAP(d): cid 0x0040 len 27 [psm 1]
        SDP SA Rsp: tid 0x2 len 0x16
          count 19
          aid 0x0004 (ProtocolDescList)
             < < uuid-16 0x0100 (L2CAP) > <
             uuid-16 0x0003 (RFCOMM) uint 0xd > >
          cont 00
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Connect req: psm 3 scid 0x0041
< ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Connect rsp: dcid 0x0041 scid 0x0041 result 0 status 0
      Connection successful
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 132 
< ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
      MTU 132 
< ACL data: handle 11 flags 0x02 dlen 16
    L2CAP(s): Config req: dcid 0x0041 flags 0x00 clen 4
      MTU 1013 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(s): Config rsp: scid 0x0041 flags 0x00 result 0 clen 4
      MTU 1013 
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 0 pf 1 ilen 0 fcs 0x1c 
< ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 0 pf 1 ilen 0 fcs 0xd7 
> ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(s): PN CMD: cr 1 dlci 0 pf 0 ilen 10 fcs 0x70 mcc_len 8
      dlci 26 frame_type 0 credit_flow 15 pri 0 ack_timer 0
      frame_size 126 max_retrans 0 credits 0
< ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(s): PN RSP: cr 0 dlci 0 pf 0 ilen 10 fcs 0xaa mcc_len 8
      dlci 26 frame_type 0 credit_flow 14 pri 0 ack_timer 0
      frame_size 126 max_retrans 0 credits 7
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): SABM: cr 1 dlci 26 pf 1 ilen 0 fcs 0xe7 
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
    handle 11
> HCI Event: Command Status (0x0f) plen 4
    Authentication Requested (0x01|0x0011) status 0x00 ncmd 1
> HCI Event: Link Key Request (0x17) plen 6
    bdaddr 00:19:7F:D8:6A:C3
< HCI Command: Link Key Request Reply (0x01|0x000b) plen 22
    bdaddr 00:19:7F:D8:6A:C3 key 9741E3A1976D406A2667C8926C02BDBE
> HCI Event: Command Complete (0x0e) plen 10
    Link Key Request Reply (0x01|0x000b) ncmd 1
    status 0x00 bdaddr 00:19:7F:D8:6A:C3
> HCI Event: Auth Complete (0x06) plen 3
    status 0x00 handle 11
< HCI Command: Set Connection Encryption (0x01|0x0013) plen 3
    handle 11 encrypt 0x01
> HCI Event: Command Status (0x0f) plen 4
    Set Connection Encryption (0x01|0x0013) status 0x00 ncmd 1
> HCI Event: Encrypt Change (0x08) plen 4
    status 0x00 handle 11 encrypt 0x01
< ACL data: handle 11 flags 0x02 dlen 8
    L2CAP(d): cid 0x0041 len 4 [psm 3]
      RFCOMM(s): UA: cr 1 dlci 26 pf 1 ilen 0 fcs 0x2c 
< ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC CMD: cr 0 dlci 0 pf 0 ilen 4 fcs 0xaa mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 9
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC RSP: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 1 b1 1 b2 0 b3 0 len 9
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC CMD: cr 1 dlci 0 pf 0 ilen 4 fcs 0x70 mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 0 b1 1 b2 0 b3 0 len 9
< ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(d): cid 0x0041 len 8 [psm 3]
      RFCOMM(s): MSC RSP: cr 0 dlci 0 pf 0 ilen 4 fcs 0xaa mcc_len 2
      dlci 26 fc 0 rtc 1 rtr 1 ic 0 dv 0 b1 1 b2 0 b3 0 len 9
< ACL data: handle 11 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 1 ilen 0 fcs 0x22 credits 33
> ACL data: handle 11 flags 0x02 dlen 9
    L2CAP(d): cid 0x0041 len 5 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 0 fcs 0xf8 credits 15
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn req: dcid 0x0040 scid 0x0040
< ACL data: handle 11 flags 0x02 dlen 12
    L2CAP(s): Disconn rsp: dcid 0x0040 scid 0x0040
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0041 len 15 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 0 ilen 11 fcs 0xe4 
      0000: 41 54 2b 42 52 53 46 3d  32 34 0d                 AT+BRSF=24.
< ACL data: handle 11 flags 0x02 dlen 22
    L2CAP(d): cid 0x0041 len 18 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 14 fcs 0x3e 
      0000: 0d 0a 2b 42 52 53 46 3a  20 33 35 32 0d 0a        ..+BRSF: 352..
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0041 len 15 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 10 fcs 0xf8 credits 2
      0000: 41 54 2b 43 49 4e 44 3d  3f 0d                    AT+CIND=?.
< ACL data: handle 11 flags 0x02 dlen 134
    L2CAP(d): cid 0x0041 len 130 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 126 fcs 0x3e 
      0000: 0d 0a 2b 43 49 4e 44 3a  20 28 22 62 61 74 74 63  ..+CIND: ("battc
      0010: 68 67 22 2c 28 30 2d 35  29 29 2c 28 22 73 69 67  hg",(0-5)),("sig
      0020: 6e 61 6c 22 2c 28 30 2d  35 29 29 2c 28 22 73 65  nal",(0-5)),("se
      0030: 72 76 69 63 65 22 2c 28  30 2c 31 29 29 2c 28 22  rvice",(0,1)),("
      0040: 63 61 6c 6c 22 2c 28 30  2c 31 29 29 2c 28 22 63  call",(0,1)),("c
      0050: 61 6c 6c 73 65 74 75 70  22 2c 28 30 2d 33 29 29  allsetup",(0-3))
      0060: 2c 28 22 63 61 6c 6c 68  65 6c 64 22 2c 28 30 2d  ,("callheld",(0-
      0070: 32 29 29 2c 28 22 72 6f  61 6d 22 2c 28 30        2)),("roam",(0
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 2c 31 29 29 0d 0a                                 ,1))..
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 9 fcs 0xf8 credits 2
      0000: 41 54 2b 43 49 4e 44 3f  0d                       AT+CIND?.
< ACL data: handle 11 flags 0x02 dlen 32
    L2CAP(d): cid 0x0041 len 28 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 24 fcs 0x3e 
      0000: 0d 0a 2b 43 49 4e 44 3a  20 35 2c 35 2c 31 2c 30  ..+CIND: 5,5,1,0
      0010: 2c 30 2c 30 2c 30 0d 0a                           ,0,0,0..
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 2
> ACL data: handle 11 flags 0x02 dlen 27
> ACL data: handle 11 flags 0x01 dlen 1
    L2CAP(d): cid 0x0041 len 24 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 19 fcs 0xf8 credits 2
      0000: 41 54 2b 43 4d 45 52 3d  33 2c 20 30 2c 20 30 2c  AT+CMER=3, 0, 0,
      0010: 20 31 0d                                           1.
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0041 len 15 [psm 3]
      RFCOMM(d): UIH: cr 1 dlci 26 pf 1 ilen 10 fcs 0xf8 credits 2
      0000: 41 54 2b 56 47 53 3d 31  35 0d                    AT+VGS=15.
< ACL data: handle 11 flags 0x02 dlen 14
    L2CAP(d): cid 0x0041 len 10 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 6 fcs 0x3e 
      0000: 0d 0a 4f 4b 0d 0a                                 ..OK..
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 11 packets 1
> HCI Event: Encrypt Change (0x08) plen 4
    status 0x00 handle 11 encrypt 0x00
> HCI Event: Role Change (0x12) plen 8
    status 0x00 bdaddr 00:19:7F:D8:6A:C3 role 0x01
    Role: Slave
> HCI Event: Encrypt Change (0x08) plen 4
    status 0x00 handle 11 encrypt 0x01
< HCI Command: Setup Synchronous Connection (0x01|0x0028) plen 17
    handle 11 voice setting 0x0060
> HCI Event: Command Status (0x0f) plen 4
    Setup Synchronous Connection (0x01|0x0028) status 0x00 ncmd 1
> HCI Event: Synchronous Connect Complete (0x2c) plen 17
    status 0x00 handle 1 bdaddr 00:19:7F:D8:6A:C3 type SCO
    Air mode: CVSD
< ACL data: handle 11 flags 0x02 dlen 19
    L2CAP(d): cid 0x0041 len 15 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 11 fcs 0x3e 
      0000: 0d 0a 2b 56 47 53 3d 31  35 0d 0a                 ..+VGS=15..
< ACL data: handle 11 flags 0x02 dlen 18
    L2CAP(d): cid 0x0041 len 14 [psm 3]
      RFCOMM(d): UIH: cr 0 dlci 26 pf 0 ilen 10 fcs 0x3e 
      0000: 0d 0a 2b 56 47 4d 3d 30  0d 0a                    ..+VGM=0..
< SCO data: handle 1 flags 0x00 dlen 48
    0000: 07 00 fb ff 04 00 fa ff  01 00 fb ff 04 00 fb ff  ................
    0010: 02 00 fb ff 05 00 fa ff  03 00 fd ff 02 00 fc ff  ................
    0020: 03 00 fb ff 05 00 fa ff  05 00 fa ff 06 00 fa ff  ................
< SCO data: handle 1 flags 0x00 dlen 48
    0000: 04 00 fc ff 05 00 f9 ff  07 00 fb ff 05 00 fc ff  ................
    0010: 05 00 fc ff 07 00 f7 ff  08 00 fd ff 06 00 fb ff  ................
    0020: 07 00 f8 ff 07 00 f9 ff  09 00 f8 ff 07 00 fa ff  ................
< SCO data: handle 1 flags 0x00 dlen 48
    0000: 09 00 f9 ff 06 00 f6 ff  0b 00 fa ff 07 00 f6 ff  ................
    0010: 09 00 f4 ff 07 00 f7 ff  0b 00 f4 ff 0b 00 f5 ff  ................
    0020: 0a 00 f1 ff 0e 00 f4 ff  0f 00 f6 ff 11 00 f2 ff  ................
< SCO data: handle 1 flags 0x00 dlen 48
    0000: 13 00 f1 ff 17 00 eb ff  1e 00 eb ff 25 00 d9 ff  ............%...
    0010: 52 00 b4 00 1e 01 43 00  a8 ff 1d fe 53 01 76 ff  R.....C.....S.v.
    0020: 37 fe e4 00 a7 fd bb 00  4e ff 4a 01 8b ff 93 01  7.......N.J.....
< SCO data: handle 1 flags 0x00 dlen 48
    0000: fa fc 73 ff 04 05 cd 00  27 fc 25 ff 03 01 d9 00  ..s.....'.%.....
    0010: cb 03 c0 00 1b fe 83 ff  5b ff d4 fc 12 03 53 fe  ........[.....S.
    0020: 30 fd c9 fd 40 04 d0 01  95 02 e0 fa 53 00 63 04  0...@.......S.c.
< SCO data: handle 1 flags 0x00 dlen 48
    0000: 81 d5 87 d9 a4 de 31 e5  5a eb 2e f2 2d fa b5 01  ......1.Z...-...
    0010: 68 08 b4 0f ae 16 01 1c  c0 20 f3 24 16 27 a9 27  h........ .$.'.'
    0020: 25 28 0f 27 0e 23 98 1e  c1 19 14 13 83 0b 05 04  %(.'.#..........
< HCI Command: Disconnect (0x01|0x0006) plen 3
    handle 1 reason 0x13
    Reason: Remote User Terminated Connection
> HCI Event: Command Status (0x0f) plen 4
    Disconnect (0x01|0x0006) status 0x00 ncmd 1
> HCI Event: Disconn Complete (0x05) plen 4
    status 0x00 handle 1 reason 0x16
    Reason: Connection Terminated by Local Host

^ permalink raw reply

* Re: Sim Access profile server implementation
From: Suraj Sumangala @ 2010-10-05 12:46 UTC (permalink / raw)
  To: Marcel Holtmann
  Cc: Waldemar.Rymarkiewicz@tieto.com, Suraj Sumangala,
	linux-bluetooth@vger.kernel.org, Jothikumar Mothilal,
	joakim.xj.ceder@stericsson.com
In-Reply-To: <1286280767.17473.89.camel@aeonflux>

Hi Waldemar,

On 10/5/2010 5:42 PM, Marcel Holtmann wrote:
> Hi Waldemar,
>
> please no top posting on this mailing list.
>
>> I understand you concerns about dbus reliability and I agree with you , but I guess we should find a compromise solution as ofono is not used widely in Linux mobile platforms nowadays.
>>
>> I my view, combination of a bluez plugin for sap and a platform dependend sim driver is a reliable and most available solution so far. The SAP plugin implements BT SAP spec and require simple API (connect, disconnect, apdu, atr, status) which is implemented in SIM driver for a certain platform. This way it's relatively easy to support SAP in different platforms. Ofono can have its own driver as well.
>>
>> What's you view on such design?
>> Can we also have a double solution one in ofono for ofono aware platforms and the second as a plugin for others?
>
> I am fine with starting this in BlueZ and see how far we get. And yes,
> plugin based is a must from my point of view. It is most likely similar
> to our different telephony drivers for Handsfree support.
>
> We will move strongly in the direction of oFono being the main telephony
> stack. So I do care mostly that this work in conjunction with oFono.
> Everything else is just a nice benefit if it doesn't clutter the
> overhaul implementation and requires pointless abstraction everywhere.
>
>> BTW, I already have this implemented and tested with real hardware (STEricsson). Bluez SAP works fine with Nokia 616 carkit :)
>
> Can you share that code with us. And also hardware if you. We are still
> having hard time to find proper hardware to test this on.
>
> Regards
>
> Marcel
>
>

Do let me know if you had to make some changes in the SAP implementation 
for it to work.

It will be great if you can share the code in that case. I can update my 
implementation accordingly.

Regards
Suraj

^ permalink raw reply

* Re: New Broadcom chip in W510
From: Marcel Holtmann @ 2010-10-05 12:13 UTC (permalink / raw)
  To: Lu Ran; +Cc: linux-bluetooth
In-Reply-To: <201010050754.18704.hephooey@gmail.com>

Hi Lu,

> > can you show me the content of /proc/bus/usb/devices (or usbdevices.sh)
> > for that device.
> 
> I put the output ot "cat /proc/bus/usb/devices" in the attachment, I am pretty 
> sure the setup of my software is OK, because now I can use my bluetooth 
> headset with an dongle, but it does not work for the internal chip.

maybe that hardware has some limitations that are unclear to me. Can you
run hcidump -X -V and give us the output when trying to establish a SCO
connection.

Regards

Marcel



^ permalink raw reply

* RE: Sim Access profile server implementation
From: Marcel Holtmann @ 2010-10-05 12:12 UTC (permalink / raw)
  To: Waldemar.Rymarkiewicz
  Cc: suraj, linux-bluetooth, Jothikumar.Mothilal, joakim.xj.ceder
In-Reply-To: <99B09243E1A5DA4898CDD8B700111448097D01B371@EXMB04.eu.tieto.com>

Hi Waldemar,

please no top posting on this mailing list.

> I understand you concerns about dbus reliability and I agree with you , but I guess we should find a compromise solution as ofono is not used widely in Linux mobile platforms nowadays.
> 
> I my view, combination of a bluez plugin for sap and a platform dependend sim driver is a reliable and most available solution so far. The SAP plugin implements BT SAP spec and require simple API (connect, disconnect, apdu, atr, status) which is implemented in SIM driver for a certain platform. This way it's relatively easy to support SAP in different platforms. Ofono can have its own driver as well.
> 
> What's you view on such design?
> Can we also have a double solution one in ofono for ofono aware platforms and the second as a plugin for others? 

I am fine with starting this in BlueZ and see how far we get. And yes,
plugin based is a must from my point of view. It is most likely similar
to our different telephony drivers for Handsfree support.

We will move strongly in the direction of oFono being the main telephony
stack. So I do care mostly that this work in conjunction with oFono.
Everything else is just a nice benefit if it doesn't clutter the
overhaul implementation and requires pointless abstraction everywhere.

> BTW, I already have this implemented and tested with real hardware (STEricsson). Bluez SAP works fine with Nokia 616 carkit :)

Can you share that code with us. And also hardware if you. We are still
having hard time to find proper hardware to test this on.

Regards

Marcel



^ permalink raw reply

* Re: New Broadcom chip in W510
From: Lu Ran @ 2010-10-05 11:54 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1286271048.17473.66.camel@aeonflux>

[-- Attachment #1: Type: Text/Plain, Size: 407 bytes --]

Hi Marcel,

On Tuesday 05 October 2010 05:30:48 Marcel Holtmann wrote:
> can you show me the content of /proc/bus/usb/devices (or usbdevices.sh)
> for that device.

I put the output ot "cat /proc/bus/usb/devices" in the attachment, I am pretty 
sure the setup of my software is OK, because now I can use my bluetooth 
headset with an dongle, but it does not work for the internal chip.

--
Best Regards,
LR

[-- Attachment #2: devices.log --]
[-- Type: text/x-log, Size: 5754 bytes --]


T:  Bus=03 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=??  MxCh= 4
B:  Alloc=  0/900 us ( 0%), #Int=  0, #Iso=  0
D:  Ver= 3.00 Cls=09(hub  ) Sub=00 Prot=03 MxPS= 9 #Cfgs=  1
P:  Vendor=1d6b ProdID=0003 Rev= 2.06
S:  Manufacturer=Linux 2.6.35.6 xhci_hcd
S:  Product=xHCI Host Controller
S:  SerialNumber=0000:0f:00.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=12ms

T:  Bus=02 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480 MxCh= 3
B:  Alloc=  0/800 us ( 0%), #Int=  1, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 2.06
S:  Manufacturer=Linux 2.6.35.6 ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=0000:00:1d.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=02 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480 MxCh= 8
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=8087 ProdID=0020 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   2 Ivl=256ms

T:  Bus=01 Lev=00 Prnt=00 Port=00 Cnt=00 Dev#=  1 Spd=480 MxCh= 3
B:  Alloc=  4/800 us ( 1%), #Int=  4, #Iso=  0
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=1d6b ProdID=0002 Rev= 2.06
S:  Manufacturer=Linux 2.6.35.6 ehci_hcd
S:  Product=EHCI Host Controller
S:  SerialNumber=0000:00:1a.0
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   4 Ivl=256ms

T:  Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#=  2 Spd=480 MxCh= 6
D:  Ver= 2.00 Cls=09(hub  ) Sub=00 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=8087 ProdID=0020 Rev= 0.00
C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=09(hub  ) Sub=00 Prot=00 Driver=hub
E:  Ad=81(I) Atr=03(Int.) MxPS=   1 Ivl=256ms

T:  Bus=01 Lev=02 Prnt=02 Port=01 Cnt=01 Dev#=  3 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=046d ProdID=c52b Rev=12.01
S:  Manufacturer=Logitech
S:  Product=USB Receiver
C:* #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr= 98mA
I:* If#= 0 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=01 Driver=usbhid
E:  Ad=81(I) Atr=03(Int.) MxPS=   8 Ivl=8ms
I:* If#= 1 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=01 Prot=02 Driver=usbhid
E:  Ad=82(I) Atr=03(Int.) MxPS=   8 Ivl=2ms
I:* If#= 2 Alt= 0 #EPs= 1 Cls=03(HID  ) Sub=00 Prot=00 Driver=usbhid
E:  Ad=83(I) Atr=03(Int.) MxPS=  32 Ivl=2ms

T:  Bus=01 Lev=02 Prnt=02 Port=02 Cnt=02 Dev#=  4 Spd=12  MxCh= 0
D:  Ver= 1.01 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs=  1
P:  Vendor=147e ProdID=2016 Rev= 0.02
S:  Manufacturer=UPEK
S:  Product=Biometric Coprocessor
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr=100mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
E:  Ad=81(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=83(I) Atr=03(Int.) MxPS=   4 Ivl=20ms

T:  Bus=01 Lev=02 Prnt=02 Port=03 Cnt=03 Dev#= 17 Spd=12  MxCh= 0
D:  Ver= 2.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=0a5c ProdID=217f Rev= 3.60
S:  Manufacturer=Broadcom Corp
S:  Product=Broadcom Bluetooth Device
S:  SerialNumber=70F395342F29
C:* #Ifs= 4 Cfg#= 1 Atr=e0 MxPwr=  0mA
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=82(I) Atr=02(Bulk) MxPS=  64 Ivl=0ms
E:  Ad=02(O) Atr=02(Bulk) MxPS=  64 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  32 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  32 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  64 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  64 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=83(I) Atr=01(Isoc) MxPS=  64 Ivl=1ms
E:  Ad=03(O) Atr=01(Isoc) MxPS=  64 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none)
E:  Ad=84(I) Atr=02(Bulk) MxPS=  32 Ivl=0ms
E:  Ad=04(O) Atr=02(Bulk) MxPS=  32 Ivl=0ms
I:* If#= 3 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)

T:  Bus=01 Lev=02 Prnt=02 Port=05 Cnt=04 Dev#=  6 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=17ef ProdID=480f Rev=23.45
S:  Manufacturer=Chicony Electronics Co., Ltd.
S:  Product=Integrated Camera
C:* #Ifs= 2 Cfg#= 1 Atr=80 MxPwr=200mA
A:  FirstIf#= 0 IfCount= 2 Cls=0e(video) Sub=03 Prot=00
I:* If#= 0 Alt= 0 #EPs= 1 Cls=0e(video) Sub=01 Prot=00 Driver=uvcvideo
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=16ms
I:* If#= 1 Alt= 0 #EPs= 0 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
I:  If#= 1 Alt= 1 #EPs= 1 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
E:  Ad=82(I) Atr=05(Isoc) MxPS=1936 Ivl=125us
I:  If#= 1 Alt= 2 #EPs= 1 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
E:  Ad=82(I) Atr=05(Isoc) MxPS=3012 Ivl=125us
I:  If#= 1 Alt= 3 #EPs= 1 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
E:  Ad=82(I) Atr=05(Isoc) MxPS=3060 Ivl=125us
I:  If#= 1 Alt= 4 #EPs= 1 Cls=0e(video) Sub=02 Prot=00 Driver=uvcvideo
E:  Ad=82(I) Atr=05(Isoc) MxPS=3072 Ivl=125us

^ permalink raw reply

* RE: Sim Access profile server implementation
From: Waldemar.Rymarkiewicz @ 2010-10-05 10:45 UTC (permalink / raw)
  To: marcel, suraj; +Cc: linux-bluetooth, Jothikumar.Mothilal, joakim.xj.ceder
In-Reply-To: <1286265730.17473.29.camel@aeonflux>

Hi Marcel, 

I understand you concerns about dbus reliability and I agree with you , but I guess we should find a compromise solution as ofono is not used widely in Linux mobile platforms nowadays.

I my view, combination of a bluez plugin for sap and a platform dependend sim driver is a reliable and most available solution so far. The SAP plugin implements BT SAP spec and require simple API (connect, disconnect, apdu, atr, status) which is implemented in SIM driver for a certain platform. This way it's relatively easy to support SAP in different platforms. Ofono can have its own driver as well.

What's you view on such design?
Can we also have a double solution one in ofono for ofono aware platforms and the second as a plugin for others? 

BTW, I already have this implemented and tested with real hardware (STEricsson). Bluez SAP works fine with Nokia 616 carkit :)

Regards,
/Waldek

>-----Original Message-----
>From: linux-bluetooth-owner@vger.kernel.org 
>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of 
>Marcel Holtmann
>Sent: Tuesday, October 05, 2010 10:02 AM
>To: suraj
>Cc: linux-bluetooth@vger.kernel.org; Jothikumar Mothilal
>Subject: Re: Sim Access profile server implementation
>
>Hi Suraj,
>
>> Please find the Git tree for the Sim access profile server role 
>> implementation I have been working on at
>> 
>> git://gitorious.org/sap-server/sap-server.git
>> 
>> Not sure it could be directly used with Bluez. Nevertheless, it has 
>> the parser implementation of Bluetooth SAP packet. Someone could 
>> possibly reuse it in their implementation.
>
>have you actually tested this with real SAP server capable 
>hardware? I am still not convinced at all to push APDU over 
>D-Bus. First, there is potential security issue here and 
>second the latency that D-Bus introduces seems not be 
>acceptable. So what I am getting it, can this be actually used 
>in a product that seriously wants to support SAP server?
>
>Regards
>
>Marcel
>
>
>--
>To unsubscribe from this list: send the line "unsubscribe 
>linux-bluetooth" in the body of a message to 
>majordomo@vger.kernel.org More majordomo info at  
>http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* Re: New Broadcom chip in W510
From: Marcel Holtmann @ 2010-10-05  9:30 UTC (permalink / raw)
  To: Lu Ran; +Cc: linux-bluetooth
In-Reply-To: <201009190926.51131.hephooey@gmail.com>

Hi Lu,

> I am having trouble to make my headset work in my new W510, it works fine in an 
> T61, with has almost identical software and setup with the new W510. The only 
> difference is I am now using a pure 64 bit system, while the old T61 is a 32 
> bit one, and the bluetooth chip is different. the id of the chip in T61 is 
> 0A5C:2110, while W510 has a chip from Broadcom with id 0A5C:217F. I noticed 
> there is a SCO fix for 0A5C:2110 in btusb.c. I tried to copy the line and 
> change the id to 0A5C:217F, but nothing changes. The headset can pair with the 
> laptop with no problem, but there seems to be no data transmition. And I get a 
> lot error messages in dmesg output like this:
> 
> btusb_submit_isoc_urb: hci0 urb ffff880060136e00 submission failed (28)
> 
> and
> 
> btusb_send_frame: hci0 urb ffff8801320e1a00 submission failed
> 
> the output of "hciconfig hci0 version" is
> 
> hci0:   Type: BR/EDR  Bus: USB
>         BD Address: 70:F3:95:34:2F:29  ACL MTU: 1021:8  SCO MTU: 64:8
>         HCI Version: 2.1 (0x4)  Revision: 0x168
>         LMP Version: 2.1 (0x4)  Subversion: 0x4203
>         Manufacturer: Broadcom Corporation (15)
> 
> And the output of "lsusb -v" is in the attachment. I will try to provide any 
> other information you need to analyse the problem.

can you show me the content of /proc/bus/usb/devices (or usbdevices.sh)
for that device.

Regards

Marcel



^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox