* Re: [PATCH 1/1] Add Sim Access Plugin
From: Suraj Sumangala @ 2010-10-20 8:37 UTC (permalink / raw)
To: Waldemar Rymarkiewicz
Cc: linux-bluetooth@vger.kernel.org, Marcel Holtmann, Suraj Sumangala,
Johan Hedberg, joakim.xj.ceder@stericsson.com,
arunkr.singh@stericsson.com
In-Reply-To: <1287561308-18611-2-git-send-email-waldemar.rymarkiewicz@tieto.com>
Hi Waldemar,
On 10/20/2010 1:25 PM, Waldemar Rymarkiewicz wrote:
> Sim Access plugin implements Sim Access Profile server role
> according to the Bluetooth Sim Access Profile v1.1 specification.
> ---
> .gitignore | 1 +
> Makefile.am | 25 +-
> acinclude.m4 | 14 +
> doc/sap-api.txt | 57 ++
> sap/main.c | 54 ++
> sap/manager.c | 94 ++++
> sap/manager.h | 21 +
> sap/sap-dummy.c | 306 +++++++++++
> sap/sap-ste.c | 1265 ++++++++++++++++++++++++++++++++++++++++++++++
> sap/sap.h | 187 +++++++
> sap/server.c | 1516 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> sap/server.h | 23 +
> 12 files changed, 3559 insertions(+), 4 deletions(-)
> create mode 100644 doc/sap-api.txt
> 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
I am assuming that this is the ST specific plugin. May be you can just
keep the dummy plugin only so that someone can use that as a reference.
> create mode 100644 sap/sap.h
> create mode 100644 sap/server.c
> create mode 100644 sap/server.h
I guess it would be better if you can split this into multiple patches
so that it would be easier to review.
Regards
Suraj
^ permalink raw reply
* RE: [PATCH 1/1] Add Sim Access Plugin
From: Waldemar.Rymarkiewicz @ 2010-10-20 8:47 UTC (permalink / raw)
To: suraj
Cc: linux-bluetooth, marcel, Suraj.Sumangala, johan.hedberg,
joakim.xj.ceder, arunkr.singh
In-Reply-To: <4CBEAA45.4010702@Atheros.com>
Hi Suraj,
>> create mode 100644 sap/sap-ste.c
>I am assuming that this is the ST specific plugin. May be you=20
>can just keep the dummy plugin only so that someone can use=20
>that as a reference.
In fact, you are right. Will remove this for the time being.=20
>> create mode 100644 sap/sap.h
>> create mode 100644 sap/server.c
>> create mode 100644 sap/server.h
>
>I guess it would be better if you can split this into multiple=20
>patches so that it would be easier to review.
Ok.=20
Regards,
/Waldek
^ permalink raw reply
* [PATCH] audio/device.h: use lower case in profile UUIDs
From: Daniel Örstadius @ 2010-10-20 8:52 UTC (permalink / raw)
To: linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Hi,
Please review.
/Daniel
[-- Attachment #2: 0001-audio-device.h-use-lower-case-in-profile-UUIDs.patch --]
[-- Type: text/x-patch, Size: 2329 bytes --]
From 4b7952b51b6b6663bdacbd0ab0f21f9d1f2b2720 Mon Sep 17 00:00:00 2001
From: Daniel Orstadius <daniel.orstadius@nokia.com>
Date: Tue, 19 Oct 2010 17:41:27 +0300
Subject: [PATCH] audio/device.h: use lower case in profile UUIDs
BlueZ seems to use lower case when emitting signals containing
UUIDs retrived from a remote device.
The definitions affected by this patch look to be used for example
if the remote connects an audio profile which BlueZ has not
discovered (perhaps it had not yet browsed the service records of
the remote).
In that case the format of the stored and emitted UUID should be
consistent with the UUIDs received during service discovery.
---
audio/device.h | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/audio/device.h b/audio/device.h
index 6ec3938..35af788 100644
--- a/audio/device.h
+++ b/audio/device.h
@@ -22,21 +22,21 @@
*
*/
-#define GENERIC_AUDIO_UUID "00001203-0000-1000-8000-00805F9B34FB"
+#define GENERIC_AUDIO_UUID "00001203-0000-1000-8000-00805f9b34fb"
-#define HSP_HS_UUID "00001108-0000-1000-8000-00805F9B34FB"
-#define HSP_AG_UUID "00001112-0000-1000-8000-00805F9B34FB"
+#define HSP_HS_UUID "00001108-0000-1000-8000-00805f9b34fb"
+#define HSP_AG_UUID "00001112-0000-1000-8000-00805f9b34fb"
-#define HFP_HS_UUID "0000111E-0000-1000-8000-00805F9B34FB"
-#define HFP_AG_UUID "0000111F-0000-1000-8000-00805F9B34FB"
+#define HFP_HS_UUID "0000111e-0000-1000-8000-00805f9b34fb"
+#define HFP_AG_UUID "0000111f-0000-1000-8000-00805f9b34fb"
-#define ADVANCED_AUDIO_UUID "0000110D-0000-1000-8000-00805F9B34FB"
+#define ADVANCED_AUDIO_UUID "0000110d-0000-1000-8000-00805f9b34fb"
-#define A2DP_SOURCE_UUID "0000110A-0000-1000-8000-00805F9B34FB"
-#define A2DP_SINK_UUID "0000110B-0000-1000-8000-00805F9B34FB"
+#define A2DP_SOURCE_UUID "0000110a-0000-1000-8000-00805f9b34fb"
+#define A2DP_SINK_UUID "0000110b-0000-1000-8000-00805f9b34fb"
-#define AVRCP_REMOTE_UUID "0000110E-0000-1000-8000-00805F9B34FB"
-#define AVRCP_TARGET_UUID "0000110C-0000-1000-8000-00805F9B34FB"
+#define AVRCP_REMOTE_UUID "0000110e-0000-1000-8000-00805f9b34fb"
+#define AVRCP_TARGET_UUID "0000110c-0000-1000-8000-00805f9b34fb"
/* Move these to respective .h files once they exist */
#define AUDIO_SOURCE_INTERFACE "org.bluez.AudioSource"
--
1.6.0.4
^ permalink raw reply related
* Re: [PATCH 1/3] Make use of transfer->err to store transfer errors
From: Johan Hedberg @ 2010-10-20 8:57 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1287411529-5806-1-git-send-email-luiz.dentz@gmail.com>
Hi Luiz,
On Mon, Oct 18, 2010, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.dentz-von@nokia.com>
>
> ---
> client/transfer.c | 10 +++++-----
> 1 files changed, 5 insertions(+), 5 deletions(-)
This one and the two other patches have been pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] audio/device.h: use lower case in profile UUIDs
From: Johan Hedberg @ 2010-10-20 9:02 UTC (permalink / raw)
To: Daniel Örstadius; +Cc: linux-bluetooth
In-Reply-To: <AANLkTinAybAb8Kyux0keA26_ASVDFZFMu3vAB_5ke2zo@mail.gmail.com>
Hi Daniel,
On Wed, Oct 20, 2010, Daniel Örstadius wrote:
> BlueZ seems to use lower case when emitting signals containing
> UUIDs retrived from a remote device.
>
> The definitions affected by this patch look to be used for example
> if the remote connects an audio profile which BlueZ has not
> discovered (perhaps it had not yet browsed the service records of
> the remote).
>
> In that case the format of the stored and emitted UUID should be
> consistent with the UUIDs received during service discovery.
> ---
> audio/device.h | 20 ++++++++++----------
> 1 files changed, 10 insertions(+), 10 deletions(-)
Looks fine to me. Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH] hidd shows different names for same device when connected from GUI and CLI.
From: Balamurugan Mahalingam @ 2010-10-20 9:12 UTC (permalink / raw)
To: Balamurugan Mahalingam, marcel, linux-bluetooth, charubala
In-Reply-To: <20101019140916.GA14730@jh-x301>
Johan Hedberg wrote:
> Hi,
>
> On Tue, Oct 19, 2010, Balamurugan Mahalingam wrote:
>
>> Blueman and other GUIs use the string from ServiceName attribute as
>> device name in the SDP response, but hidd tool uses strings from
>> Service Description and Provider Name atrribute.
>>
>> SDP response from Microsoft Bluetooth device has extended ASCII
>> character 174(registered symbol) in its ServiceDescription attribute.
>> Android platform expects the device name to have only printable
>> characters and therefore GUI Crashes while connecting Microsoft
>> Bluetooth Mouse using hidd
>>
>> Using the ServiceName attribute from the SDP response
>> instead of ProviderName+ServiceDescription for device name in the
>> hidd tool solves both the issues.
>> ---
>> compat/sdp.c | 33 +++++++++++++++++----------------
>> 1 files changed, 17 insertions(+), 16 deletions(-)
>>
>
> Same issues as with the previous commit message. Lines should be max 74
> characters long and please redo the summary line to be of the format
> "Fix ..." and shorter than it is now.
>
> Btw, why are you using hidd and not the bluetoothd input plugin? hidd is
> legacy stuff which will disappear from BlueZ in the future.
>
> Johan
> .
>
>
Johan,
We use the bluetooth input plugin too.
We use hidd for some scripting works.
Regards
Balamurugan
^ permalink raw reply
* [PATCH] Fix hidd showing different names for same device
From: Balamurugan Mahalingam @ 2010-10-20 9:12 UTC (permalink / raw)
To: marcel; +Cc: johan.hedberg, linux-bluetooth, charubala, Balamurugan Mahalingam
hidd shows different names for a same device when
connected from GUI and CLI
Blueman and other GUIs use the string from ServiceName attribute as
device name in the SDP response, but hidd tool uses strings from
Service Description and Provider Name atrribute.
SDP response from Microsoft Bluetooth device has extended ASCII
character 174(registered symbol) in its ServiceDescription attribute.
Android platform expects the device name to have only printable
characters and therefore GUI Crashes while connecting Microsoft
Bluetooth Mouse using hidd
Using the ServiceName attribute from the SDP response
instead of ProviderName+ServiceDescription for device name in the
hidd tool solves both the issues.
---
compat/sdp.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/compat/sdp.c b/compat/sdp.c
index ff2e39f..f384844 100644
--- a/compat/sdp.c
+++ b/compat/sdp.c
@@ -248,22 +248,23 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co
rec = (sdp_record_t *) hid_rsp->data;
- pdlist = sdp_data_get(rec, 0x0101);
- pdlist2 = sdp_data_get(rec, 0x0102);
- if (pdlist) {
- if (pdlist2) {
- if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
- strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
- strcat(req->name, " ");
- }
- strncat(req->name, pdlist->val.str,
- sizeof(req->name) - strlen(req->name));
- } else
- strncpy(req->name, pdlist->val.str, sizeof(req->name) - 1);
- } else {
- pdlist2 = sdp_data_get(rec, 0x0100);
- if (pdlist2)
- strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ pdlist2 = sdp_data_get(rec, 0x0100);
+ if (pdlist2)
+ strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ else {
+ pdlist = sdp_data_get(rec, 0x0101);
+ pdlist2 = sdp_data_get(rec, 0x0102);
+ if (pdlist) {
+ if (pdlist2) {
+ if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
+ strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ strcat(req->name, " ");
+ }
+ strncat(req->name, pdlist->val.str,
+ sizeof(req->name) - strlen(req->name));
+ } else
+ strncpy(req->name, pdlist->val.str, sizeof(req->name) - 1);
+ }
}
pdlist = sdp_data_get(rec, 0x0201);
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] Fix hidd showing different names for same device
From: Suraj Sumangala @ 2010-10-20 9:45 UTC (permalink / raw)
To: Balamurugan Mahalingam
Cc: marcel@holtmann.org, johan.hedberg@gmail.com,
linux-bluetooth@vger.kernel.org, charubala@charubala.com,
Mahalingam Balamurugan
In-Reply-To: <1287565973-5350-1-git-send-email-mbalamurugan@atheros.com>
Hi Bala,
On 10/20/2010 2:42 PM, Balamurugan Mahalingam wrote:
> hidd shows different names for a same device when
> connected from GUI and CLI
>
> Blueman and other GUIs use the string from ServiceName attribute as
> device name in the SDP response, but hidd tool uses strings from
> Service Description and Provider Name atrribute.
>
> SDP response from Microsoft Bluetooth device has extended ASCII
> character 174(registered symbol) in its ServiceDescription attribute.
> Android platform expects the device name to have only printable
> characters and therefore GUI Crashes while connecting Microsoft
> Bluetooth Mouse using hidd
>
> Using the ServiceName attribute from the SDP response
> instead of ProviderName+ServiceDescription for device name in the
> hidd tool solves both the issues.
> ---
may be you can shorten the commit message. May be have something like this
This patch lets hidd use ServiceName attribute from the SDP response
instead of ProviderName+ServiceDescription for device name.
SDP response from Microsoft Bluetooth device has extended ASCII
character 174(registered symbol) in its ServiceDescription attribute.
This causes some Bluetooth application which expects only printable
characters as device name to crash.
Regards
Suraj
^ permalink raw reply
* Re: [PATCH] Fix hidd showing different names for same device
From: Balamurugan Mahalingam @ 2010-10-20 10:15 UTC (permalink / raw)
To: Suraj Sumangala
Cc: Mahalingam Balamurugan, marcel@holtmann.org,
johan.hedberg@gmail.com, linux-bluetooth@vger.kernel.org,
charubala@charubala.com
In-Reply-To: <4CBEBA32.3040806@Atheros.com>
Suraj Sumangala wrote:
> Hi Bala,
>
> On 10/20/2010 2:42 PM, Balamurugan Mahalingam wrote:
>
>> hidd shows different names for a same device when
>> connected from GUI and CLI
>>
>> Blueman and other GUIs use the string from ServiceName attribute as
>> device name in the SDP response, but hidd tool uses strings from
>> Service Description and Provider Name atrribute.
>>
>> SDP response from Microsoft Bluetooth device has extended ASCII
>> character 174(registered symbol) in its ServiceDescription attribute.
>> Android platform expects the device name to have only printable
>> characters and therefore GUI Crashes while connecting Microsoft
>> Bluetooth Mouse using hidd
>>
>> Using the ServiceName attribute from the SDP response
>> instead of ProviderName+ServiceDescription for device name in the
>> hidd tool solves both the issues.
>> ---
>>
>
> may be you can shorten the commit message. May be have something like this
>
> This patch lets hidd use ServiceName attribute from the SDP response
> instead of ProviderName+ServiceDescription for device name.
> SDP response from Microsoft Bluetooth device has extended ASCII
> character 174(registered symbol) in its ServiceDescription attribute.
> This causes some Bluetooth application which expects only printable
> characters as device name to crash.
>
> Regards
> Suraj
> .
>
>
Ok Suraj. I will send the patch once again
Thanks & Regards
Balamurugan Mahalingam
^ permalink raw reply
* [PATCH] Fix hidd to use ServiceName attribute for device name
From: Balamurugan Mahalingam @ 2010-10-20 10:21 UTC (permalink / raw)
To: marcel; +Cc: johan.hedberg, linux-bluetooth, charubala, Balamurugan Mahalingam
This patch lets hidd use ServiceName attribute from the SDP response
instead of ProviderName+ServiceDescription for device name.
SDP response from Microsoft Bluetooth device has extended ASCII
character 174(registered symbol) in its ServiceDescription attribute.
This causes some Bluetooth application which expects only printable
characters as device name to crash.
---
compat/sdp.c | 33 +++++++++++++++++----------------
1 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/compat/sdp.c b/compat/sdp.c
index ff2e39f..f384844 100644
--- a/compat/sdp.c
+++ b/compat/sdp.c
@@ -248,22 +248,23 @@ int get_sdp_device_info(const bdaddr_t *src, const bdaddr_t *dst, struct hidp_co
rec = (sdp_record_t *) hid_rsp->data;
- pdlist = sdp_data_get(rec, 0x0101);
- pdlist2 = sdp_data_get(rec, 0x0102);
- if (pdlist) {
- if (pdlist2) {
- if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
- strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
- strcat(req->name, " ");
- }
- strncat(req->name, pdlist->val.str,
- sizeof(req->name) - strlen(req->name));
- } else
- strncpy(req->name, pdlist->val.str, sizeof(req->name) - 1);
- } else {
- pdlist2 = sdp_data_get(rec, 0x0100);
- if (pdlist2)
- strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ pdlist2 = sdp_data_get(rec, 0x0100);
+ if (pdlist2)
+ strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ else {
+ pdlist = sdp_data_get(rec, 0x0101);
+ pdlist2 = sdp_data_get(rec, 0x0102);
+ if (pdlist) {
+ if (pdlist2) {
+ if (strncmp(pdlist->val.str, pdlist2->val.str, 5)) {
+ strncpy(req->name, pdlist2->val.str, sizeof(req->name) - 1);
+ strcat(req->name, " ");
+ }
+ strncat(req->name, pdlist->val.str,
+ sizeof(req->name) - strlen(req->name));
+ } else
+ strncpy(req->name, pdlist->val.str, sizeof(req->name) - 1);
+ }
}
pdlist = sdp_data_get(rec, 0x0201);
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] Fix hidd to use ServiceName attribute for device name
From: Johan Hedberg @ 2010-10-20 10:38 UTC (permalink / raw)
To: Balamurugan Mahalingam; +Cc: marcel, linux-bluetooth, charubala
In-Reply-To: <1287570077-5669-1-git-send-email-mbalamurugan@atheros.com>
Hi,
On Wed, Oct 20, 2010, Balamurugan Mahalingam wrote:
> This patch lets hidd use ServiceName attribute from the SDP response
> instead of ProviderName+ServiceDescription for device name.
> SDP response from Microsoft Bluetooth device has extended ASCII
> character 174(registered symbol) in its ServiceDescription attribute.
> This causes some Bluetooth application which expects only printable
> characters as device name to crash.
> ---
> compat/sdp.c | 33 +++++++++++++++++----------------
> 1 files changed, 17 insertions(+), 16 deletions(-)
The patch has been pushed upstream. Thanks.
Johan
^ permalink raw reply
* [PATCH 1/4] Sim Access Profile API
From: Waldemar Rymarkiewicz @ 2010-10-20 12:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, suraj, Waldemar Rymarkiewicz
New API for Sim Access Profile.
---
Makefile.am | 2 +-
doc/sap-api.txt | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 58 insertions(+), 1 deletions(-)
create mode 100644 doc/sap-api.txt
diff --git a/Makefile.am b/Makefile.am
index 6e8fc7d..eeb1780 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -352,7 +352,7 @@ EXTRA_DIST += doc/manager-api.txt \
doc/service-api.txt doc/agent-api.txt doc/attribute-api.txt \
doc/serial-api.txt doc/network-api.txt \
doc/input-api.txt doc/audio-api.txt doc/control-api.txt \
- doc/hfp-api.txt doc/assigned-numbers.txt
+ doc/hfp-api.txt doc/assigned-numbers.txt doc/sap-api.txt
AM_YFLAGS = -d
diff --git a/doc/sap-api.txt b/doc/sap-api.txt
new file mode 100644
index 0000000..7951f56
--- /dev/null
+++ b/doc/sap-api.txt
@@ -0,0 +1,57 @@
+BlueZ D-Bus Sim Access Profile API description
+***********************************
+
+Copyright (C) 2010 ST-Ericsson SA
+
+
+Sim Access Profile hierarchy
+============================
+
+Service org.bluez
+Interface org.bluez.SimAccess
+Object path [variable prefix]/{hci0,hci1,...}
+
+Methods void Enable()
+
+ Start up SAP server and register SDP record for it.
+
+ Possible errors: org.bluez.Error.Failed
+
+ void Disable()
+
+ Shudown SAP server and remove the SDP record.
+
+ Possible errors: org.bluez.Error.Failed
+
+ void Disconnect(boolean type)
+
+ Disconnect SAP client from the server. The 'type'
+ parameter indicates disconnection type.
+
+ True - gracefull disconnection
+ False - immediate disconnection
+
+ Possible errors: org.bluez.Error.Failed
+
+ dict GetProperties()
+
+ Return all properties for the interface. See the
+ properties section for available properties.
+
+ Possible Errors: org.bluez.Error.Failed
+
+Signals PropertyChanged(string name, variant value)
+
+ This signal indicates a changed value of the given
+ property.
+
+
+Properties boolean Enabled [readonly]
+
+ Indicates the state of the server. True if the server
+ is enabled and False otherwise.
+
+ boolean Connected [readonly]
+
+ Indicates if SAP client is connected to the server.
+
--
1.7.0.4
^ permalink raw reply related
* [PATCH 2/4] Sim Access Profile Manager
From: Waldemar Rymarkiewicz @ 2010-10-20 12:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, suraj, Waldemar Rymarkiewicz
In-Reply-To: <1287576681-12669-1-git-send-email-waldemar.rymarkiewicz@tieto.com>
Add a SAP plugin main file and the plugin manager. Also include the SAP
plugin in the Makefile.
---
Makefile.am | 7 ++++
acinclude.m4 | 6 ++++
sap/main.c | 54 ++++++++++++++++++++++++++++++++
sap/manager.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
sap/manager.h | 21 +++++++++++++
sap/server.c | 48 +++++++++++++++++++++++++++++
sap/server.h | 25 +++++++++++++++
7 files changed, 255 insertions(+), 0 deletions(-)
create mode 100644 sap/main.c
create mode 100644 sap/manager.c
create mode 100644 sap/manager.h
create mode 100644 sap/server.c
create mode 100644 sap/server.h
diff --git a/Makefile.am b/Makefile.am
index eeb1780..4c91469 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -142,6 +142,13 @@ audio_libtelephony_a_SOURCES = audio/telephony.h audio/telephony-dummy.c \
audio/telephony-maemo6.c
endif
+if SAPPLUGIN
+builtin_modules += sap
+builtin_sources += sap/main.c \
+ sap/manager.h sap/manager.c \
+ sap/server.h sap/server.c
+endif
+
if INPUTPLUGIN
builtin_modules += input
builtin_sources += input/main.c \
diff --git a/acinclude.m4 b/acinclude.m4
index 287f07d..1f76b4d 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -174,6 +174,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
input_enable=yes
serial_enable=yes
network_enable=yes
+ sap_enable=yes
service_enable=yes
health_enable=no
pnat_enable=no
@@ -210,6 +211,10 @@ AC_DEFUN([AC_ARG_BLUEZ], [
network_enable=${enableval}
])
+ AC_ARG_ENABLE(sap, AC_HELP_STRING([--disable-sap], [disable sap plugin]), [
+ sap_enable=${enableval}
+ ])
+
AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [disable serial plugin]), [
serial_enable=${enableval}
])
@@ -351,6 +356,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(HEALTHPLUGIN, test "${health_enable}" = "yes")
AM_CONDITIONAL(MCAP, test "${health_enable}" = "yes")
diff --git a/sap/main.c b/sap/main.c
new file mode 100644
index 0000000..b3efcf8
--- /dev/null
+++ b/sap/main.c
@@ -0,0 +1,54 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * 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; 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)
+ 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..972a46b
--- /dev/null
+++ b/sap/manager.c
@@ -0,0 +1,94 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * 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; 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 "log.h"
+#include "adapter.h"
+#include "device.h"
+
+#include "manager.h"
+
+#include "server.h"
+
+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..5a779df
--- /dev/null
+++ b/sap/manager.h
@@ -0,0 +1,21 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * 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; 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/server.c b/sap/server.c
new file mode 100644
index 0000000..2728778
--- /dev/null
+++ b/sap/server.c
@@ -0,0 +1,48 @@
+/*
+ * 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; 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
+ */
+
+#include "bluetooth.h"
+#include "log.h"
+
+#include "server.h"
+
+int sap_server_register(const char *path, bdaddr_t *src)
+{
+ DBG("Register SAP server.");
+ return 0;
+}
+
+int sap_server_unregister(const char *path)
+{
+ DBG("Unregister SAP server.");
+ return 0;
+}
+
+int sap_server_init(DBusConnection *conn)
+{
+ DBG("Init SAP server.");
+ return 0;
+}
+
+void sap_server_exit(void)
+{
+ DBG("Exit SAP server.");
+}
diff --git a/sap/server.h b/sap/server.h
new file mode 100644
index 0000000..cb77828
--- /dev/null
+++ b/sap/server.h
@@ -0,0 +1,25 @@
+/*
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * 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; 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
+ */
+
+#include <gdbus.h>
+
+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
* [PATCH 3/4] Sim Access Profile Server
From: Waldemar Rymarkiewicz @ 2010-10-20 12:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, suraj, Waldemar Rymarkiewicz
In-Reply-To: <1287576681-12669-1-git-send-email-waldemar.rymarkiewicz@tieto.com>
Add a Sim Access Server to the SAP plugin and a framework for the dummy
sap driver as well.
---
Makefile.am | 3 +-
sap/sap-dummy.c | 85 ++++
sap/sap.h | 187 +++++++
sap/server.c | 1476 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
4 files changed, 1745 insertions(+), 6 deletions(-)
create mode 100644 sap/sap-dummy.c
create mode 100644 sap/sap.h
diff --git a/Makefile.am b/Makefile.am
index 4c91469..0facbe2 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,7 +146,8 @@ if SAPPLUGIN
builtin_modules += sap
builtin_sources += sap/main.c \
sap/manager.h sap/manager.c \
- sap/server.h sap/server.c
+ sap/server.h sap/server.c \
+ sap/sap.h sap/sap-dummy.c
endif
if INPUTPLUGIN
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c
new file mode 100644
index 0000000..e04660f
--- /dev/null
+++ b/sap/sap-dummy.c
@@ -0,0 +1,85 @@
+/*
+ * 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; 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
+ */
+
+#include "log.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, uint8_t linkloss)
+{
+ sap_disconnect_rsp(sap_device);
+}
+
+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);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+}
+
+void sap_transfer_card_reader_status_req(void * sap_device)
+{
+ sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK,
+ ICC_READER_CARD_POWERED_ON);
+}
+
+void sap_set_transport_protocol_req(void * sap_device,sap_parameter * param)
+{
+ sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
+}
+
+int sap_init(void)
+{
+ DBG("SAP driver init.");
+ return 0;
+}
+
+void sap_exit(void)
+{
+ DBG("SAP driver exit.");
+}
diff --git a/sap/sap.h b/sap/sap.h
new file mode 100644
index 0000000..a9189fc
--- /dev/null
+++ b/sap/sap.h
@@ -0,0 +1,187 @@
+/*
+ * 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.
+ * 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; 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
+ */
+
+#include <stdint.h>
+#include <glib.h>
+
+ #define SAP_VERSION 0x0101
+
+/* Connection Status - SAP v1.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;
+
+/* Disconnection Type - SAP v1.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;
+
+/* Result codes - SAP v1.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;
+
+/* Status Change - SAP v1.1 section 5.2.8 */
+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;
+
+/* Message format - SAP v1.1 section 5.1 */
+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,
+ SAP_CONNECT_RESP = 0x01,
+ SAP_DISCONNECT_REQ = 0x02,
+ SAP_DISCONNECT_RESP = 0x03,
+ SAP_DISCONNECT_IND = 0x04,
+ SAP_TRANSFER_APDU_REQ = 0x05,
+ SAP_TRANSFER_APDU_RESP = 0x06,
+ SAP_TRANSFER_ATR_REQ = 0x07,
+ SAP_TRANSFER_ATR_RESP = 0x08,
+ SAP_POWER_SIM_OFF_REQ = 0x09,
+ SAP_POWER_SIM_OFF_RESP = 0x0A,
+ SAP_POWER_SIM_ON_REQ = 0x0B,
+ SAP_POWER_SIM_ON_RESP = 0x0C,
+ SAP_RESET_SIM_REQ = 0x0D,
+ SAP_RESET_SIM_RESP = 0x0E,
+ SAP_TRANSFER_CARD_READER_STATUS_REQ = 0x0F,
+ SAP_TRANSFER_CARD_READER_STATUS_RESP = 0x10,
+ SAP_STATUS_IND = 0x11,
+ SAP_ERROR_RESP = 0x12,
+ SAP_SET_TRANSPORT_PROTOCOL_REQ = 0x13,
+ SAP_SET_TRANSPORT_PROTOCOL_RESP = 0x14,
+} sap_protocol;
+
+/* Parameters Ids - SAP 1.1 section 5.2 */
+#define SAP_PARAM_ID_MAX_MSG_SIZE 0x00
+#define SAP_PARAM_ID_MAX_MSG_SIZE_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
+
+/* Transport Protocol - SAP v1.1 section 5.2.9 */
+#define SAP_TRANSPORT_PROTOCOL_T0 0x00
+#define SAP_TRANSPORT_PROTOCOL_T1 0x01
+
+/*SAP driver init and exit routines. Implemented by sap-*.c */
+int sap_init(void);
+void sap_exit(void);
+
+/* SAP requests implemented by 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);
+
+/*SAP responses to SAP requests. Implemented by 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_rsp(void *sap_device, sap_result_t result);
+
+/* Event indication. Implemented by 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
index 2728778..5683e66 100644
--- a/sap/server.c
+++ b/sap/server.c
@@ -2,7 +2,9 @@
* 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.
* Author: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> for ST-Ericsson.
*
* This program is free software; you can redistribute it and/or modify
@@ -19,30 +21,1494 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include "bluetooth.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <glib.h>
+#include <netinet/in.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
+
+#include "adapter.h"
+#include "btio.h"
+#include "sdpd.h"
#include "log.h"
+#include "error.h"
+#include "dbus-common.h"
+#include "sap.h"
#include "server.h"
+#define SAP_SERVER_INTERFACE "org.bluez.SimAccess"
+#define SAP_UUID "0000112D-0000-1000-8000-00805F9B34FB"
+#define SAP_SERVER_CHANNEL 8
+#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;
+ uint32_t record_id;
+ GIOChannel *listen_io;
+ GIOChannel *io; /* Connected client channel.*/
+ sap_state_t state;
+ uint8_t processing_req;
+ guint timer_id;
+};
+
+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 *server, guint interval);
+static void stop_guard_timer(struct sap_server *server);
+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)
+{
+ if(!msg)
+ return -EFAULT;
+
+ switch(msg->id) {
+ case SAP_CONNECT_REQ:
+ if (msg->nparam == 0x01 &&
+ msg->param->id == SAP_PARAM_ID_MAX_MSG_SIZE &&
+ ntohs(msg->param->len) == SAP_PARAM_ID_MAX_MSG_SIZE_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 *server, guint interval)
+{
+ if(!server)
+ return;
+
+ if (!server->timer_id)
+ server->timer_id = g_timeout_add_seconds(interval,
+ guard_timeout, server);
+ else
+ error("Timer is already active.");
+}
+
+static void stop_guard_timer(struct sap_server *server)
+{
+ if (server && server->timer_id) {
+ g_source_remove(server->timer_id);
+ server->timer_id = 0;
+ }
+}
+
+static gboolean guard_timeout(gpointer data)
+{
+ struct sap_server *server = data;
+
+ if (!server)
+ return FALSE;
+
+ DBG("guard_timeout: state: %x pr %x", server->state,
+ server->processing_req);
+
+ server->timer_id = 0;
+
+ switch(server->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.*/
+ if (server->io)
+ g_io_channel_shutdown(server->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(server, SAP_DISCONNECTION_TYPE_IMMEDIATE);
+ break;
+ default:
+ error("guard_timeout: Unexpected state.");
+ break;
+ }
+
+ return FALSE;
+}
+
+static sdp_record_t *create_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(>_uuid, GENERIC_TELEPHONY_SVCLASS_ID);
+ svclass_id = sdp_list_append(svclass_id, >_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_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 *server, gchar *buf, gssize size)
+{
+ gsize written = 0;
+ GError *gerr = NULL;
+ GIOStatus gstatus;
+
+ if(!server || !buf)
+ return -1;
+
+ DBG("send_message: size=%x",(unsigned int)size);
+
+ gstatus = g_io_channel_write_chars(server->io, buf, size, &written, &gerr);
+
+ if (gstatus != G_IO_STATUS_NORMAL) {
+ if (gerr)
+ g_error_free(gerr);
+
+ error("send_message:write error (%d)", gstatus);
+ return -1;
+ }
+ if(written != (gsize)size) {
+ error("send_message:write error. written %d size %d", written, size);
+ }
+ DBG("send_message: written=%x",(unsigned int)written);
+ return 0;
+}
+
+static void connect_req(void *data, sap_parameter *param)
+{
+ struct sap_server *server = data;
+ uint16_t maxmsgsize, *val;
+
+ if(!server || !param)
+ goto error_rsp;
+
+ if (server->state != SAP_STATE_DISCONNECTED)
+ goto error_rsp;
+
+ stop_guard_timer(server);
+
+ val = (uint16_t *) ¶m->val;
+ maxmsgsize = ntohs(*val);
+
+ DBG("Connect MaxMsgSize: 0x%04X(%d)", maxmsgsize, maxmsgsize);
+
+ server->state = SAP_STATE_CONNECT_IN_PROGRESS;
+
+ if (maxmsgsize <= SAP_BUF_SIZE){
+ server->processing_req = SAP_CONNECT_REQ;
+ sap_connect_req(server, maxmsgsize);
+ }else{
+ sap_connect_rsp(server, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED,
+ SAP_BUF_SIZE);
+ }
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(data);
+}
+
+static int disconnect_req(void *data, sap_disconnection_type_t disc_type)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("disconnect_req: type 0x%x state %d", disc_type, server->state);
+
+ switch(disc_type) {
+ case SAP_DISCONNECTION_TYPE_GRACEFUL:
+
+ if (server->state == SAP_STATE_DISCONNECTED ||
+ server->state == SAP_STATE_CONNECT_IN_PROGRESS)
+ goto error_req;
+
+ if (server->state == SAP_STATE_CONNECTED) {
+ server->state = SAP_STATE_GRACEFUL_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+ disconnect_ind(server, disc_type);
+
+ /* Start guard timer - timer will disconnect connection
+ * if client doesn't do it. */
+ start_guard_timer(server, SAP_TIMER_GRACEFUL_DISCONNECT);
+
+ return 0;
+ }
+ /* Disconnection is ongoing - do nothing. */
+ return 0;
+
+ case SAP_DISCONNECTION_TYPE_IMMEDIATE:
+
+ if (server->state == SAP_STATE_DISCONNECTED ||
+ server->state == SAP_STATE_CONNECT_IN_PROGRESS)
+ goto error_req;
+
+ if (server->state == SAP_STATE_CONNECTED ||
+ server->state == SAP_STATE_GRACEFUL_DISCONNECT) {
+ server->state = SAP_STATE_IMMEDIATE_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+
+ stop_guard_timer(server);
+
+ disconnect_ind(server, disc_type);
+ sap_disconnect_req(server, 0);
+
+ return 0;
+ }
+ /* Disconnection is ongoing - do nothing. */
+ return 0;
+
+ case SAP_DISCONNECTION_TYPE_CLIENT:
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ goto error_rsp;
+
+ server->state = SAP_STATE_CLIENT_DISCONNECT;
+ server->processing_req = SAP_NO_REQ;
+
+ stop_guard_timer(server);
+
+ sap_disconnect_req(server, 0);
+
+ return 0;
+
+ default:
+ error("Unknown disconnection type (type %x).", disc_type);
+ return -EINVAL;
+ }
+
+error_rsp:
+ sap_error_rsp(server);
+error_req:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ return -EPERM;
+}
+
+static void transfer_apdu_req(void * data, sap_parameter * param)
+{
+ struct sap_server *server = data;
+
+ if(!server || !param)
+ goto error_rsp;
+
+ param->len = ntohs(param->len);
+
+ DBG("transfer_apdu_req: data %p state %d", data, server->state);
+ DBG("transfer_apdu_req: apdu param id %d val %s len %d ",
+ param->id, param->val, param->len);
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_APDU_REQ;
+ sap_transfer_apdu_req(server, param);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+
+static void transfer_atr_req(void * data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("transfer_atr_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_ATR_REQ;
+ sap_transfer_atr_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+
+static void power_sim_off_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("power_sim_off_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (!is_power_sim_off_req_allowed(server->processing_req))
+ goto error_rsp;
+
+ server->processing_req = SAP_POWER_SIM_OFF_REQ;
+ sap_power_sim_off_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void power_sim_on_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("power_sim_on_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_POWER_SIM_ON_REQ;
+ sap_power_sim_on_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void reset_sim_req(void *data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("reset_sim_req: data %p state %d", data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (!is_reset_sim_req_allowed(server->processing_req))
+ goto error_rsp;
+
+ server->processing_req = SAP_RESET_SIM_REQ;
+ sap_reset_sim_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void transfer_card_reader_status_req(void * data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ goto error_rsp;
+
+ DBG("transfer_card_reader_status_req: data %p state %d",
+ data, server->state);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_TRANSFER_CARD_READER_STATUS_REQ;
+ sap_transfer_card_reader_status_req(server);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static void set_transport_protocol_req(void *data, sap_parameter *param)
+{
+ struct sap_server *server = data;
+
+ if(!server || !param)
+ goto error_rsp;
+
+ DBG("set_transport_protocol_req: data %p state %d param %p",
+ data, server->state, param);
+
+ if (server->state != SAP_STATE_CONNECTED)
+ goto error_rsp;
+
+ if (server->processing_req != SAP_NO_REQ)
+ goto error_rsp;
+
+ server->processing_req = SAP_SET_TRANSPORT_PROTOCOL_REQ;
+ sap_set_transport_protocol_req(server, param);
+
+ return;
+
+error_rsp:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ sap_error_rsp(server);
+}
+
+static int disconnect_ind(void *sap_device, sap_disconnection_type_t type)
+{
+ struct sap_server *server = sap_device;
+ gchar buf[SAP_BUF_SIZE];
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("disconnect_ind: data %p state %d disc_type %d",
+ server, server->state, type);
+
+ if (server->state != SAP_STATE_GRACEFUL_DISCONNECT &&
+ server->state != SAP_STATE_IMMEDIATE_DISCONNECT)
+ goto error_ind;
+
+ memset(buf, 0, sizeof(buf));
+ msg->id = SAP_DISCONNECT_IND;
+ msg->nparam = 0x01;
+
+ /* Add 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);
+
+ return send_message(sap_device, buf, size);
+
+error_ind:
+ error("Wrong state (state %x pr %x)", server->state,
+ server->processing_req);
+ return -EPERM;
+}
+
+int sap_connect_rsp(void *sap_device, sap_status_t status, uint16_t maxmsgsize)
+{
+ struct sap_server *server = sap_device;
+ gchar buf[SAP_BUF_SIZE];
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_connect_rsp: state %x pr %x status %x", server->state,
+ server->processing_req, status);
+
+ if (server->state != SAP_STATE_CONNECT_IN_PROGRESS) {
+ return -EPERM;
+ }
+
+ memset(buf, 0, sizeof(buf));
+ msg->id = SAP_CONNECT_RESP;
+ msg->nparam = 0x01;
+
+ /* Add 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);
+
+ /* Add MaxMsgSize */
+ if (maxmsgsize && (status == SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED ||
+ status == SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL)) {
+ uint16_t *len;
+ msg->nparam++;
+ /* Skip the first param */
+ param = (sap_parameter *) &buf[size];
+ param->id = SAP_PARAM_ID_MAX_MSG_SIZE;
+ param->len = htons(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
+ len = (uint16_t *) ¶m->val;
+ *len = htons(maxmsgsize);
+ size += PARAMETER_SIZE(SAP_PARAM_ID_MAX_MSG_SIZE_LEN);
+ }
+
+ if (status == SAP_STATUS_OK) {
+ gboolean connected = TRUE;
+ emit_property_changed(connection, server->path, SAP_SERVER_INTERFACE,
+ "Connected", DBUS_TYPE_BOOLEAN, &connected);
+
+ server->state = SAP_STATE_CONNECTED;
+ } else {
+ server->state = SAP_STATE_DISCONNECTED;
+
+ /* Timer will shutdown channel if client doesn't send
+ * CONNECT_REQ or doesn't shutdown channel itself.*/
+ start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_disconnect_rsp(void *sap_device)
+{
+ struct sap_server *server = sap_device;
+ sap_message msg = {0};
+
+ if(!server)
+ return -1;
+
+ DBG("sap_disconnect_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ switch(server->state) {
+ case SAP_STATE_CLIENT_DISCONNECT:
+ msg.id = SAP_DISCONNECT_RESP;
+
+ server->state = SAP_STATE_DISCONNECTED;
+ server->processing_req = SAP_NO_REQ;
+
+ /* Timer will close channel if client doesn't do it.*/
+ start_guard_timer(server, SAP_TIMER_NO_ACTIVITY);
+
+ return send_message(sap_device, (gchar *) &msg, sizeof(msg));
+
+ case SAP_STATE_IMMEDIATE_DISCONNECT:
+ server->state = SAP_STATE_DISCONNECTED;
+ server->processing_req = SAP_NO_REQ;
+
+ if (server->io)
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ return 0;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+int sap_transfer_apdu_rsp(void *sap_device, sap_result_t result, uint8_t *apdu,
+ uint16_t length)
+{
+ struct sap_server *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_transfer_apdu_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add 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);
+ }
+
+ server->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 *server = sap_device;
+ gchar buf[SAP_BUF_SIZE]= {0};
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_transfer_atr_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add ATR response */
+ if (result == SAP_RESULT_OK) {
+ msg->nparam++;
+ /* Skip 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);
+ }
+
+ server->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 *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_power_sim_off_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code.*/
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->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 *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_power_sim_on_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->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 *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_reset_sim_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->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 *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_transfer_card_reader_status_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->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;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, param);
+
+ /* Add card reader status. */
+ if (result == SAP_RESULT_OK) {
+ msg->nparam++;
+ /* Skipp 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);
+ }
+
+ server->processing_req = SAP_NO_REQ;
+ return send_message(sap_device, buf, size);
+}
+
+int sap_transport_protocol_rsp(void *sap_device, sap_result_t result)
+{
+ struct sap_server *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_transport_protocol_rsp: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->processing_req != SAP_SET_TRANSPORT_PROTOCOL_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_SET_TRANSPORT_PROTOCOL_RESP;
+
+ /* Add result code */
+ msg->nparam = 0x01;
+ size += add_result_parameter(result, msg->param);
+
+ server->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, (gchar *) &msg, sizeof(msg));
+}
+
+int sap_status_ind(void *sap_device, sap_status_change_t status_change)
+{
+ struct sap_server *server = sap_device;
+ gchar buf[SAP_BUF_SIZE] = {0};
+ sap_message *msg = (sap_message *) buf;
+ sap_parameter *param = (sap_parameter *) msg->param;
+ gsize size = sizeof(sap_message);
+
+ if(!server)
+ return -1;
+
+ DBG("sap_status_ind: state %x pr %x", server->state,
+ server->processing_req);
+
+ if (server->state != SAP_STATE_CONNECTED &&
+ server->state != SAP_STATE_GRACEFUL_DISCONNECT)
+ /*Don't propagate status indication if client is not connected */
+ return 0;
+
+ msg->id = SAP_STATUS_IND;
+ msg->nparam = 0x01;
+
+ /* Add 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);
+}
+
+static int handle_cmd(void *data, gchar *buf, gsize size)
+{
+ sap_message *msg = (sap_message *) buf;
+
+ if (size < sizeof(sap_message))
+ goto error_rsp;
+
+ 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:
+ DBG("SAP Connect.");
+ connect_req(data, msg->param);
+ return 0;
+ case SAP_DISCONNECT_REQ:
+ DBG("SAP Disconnect.");
+ disconnect_req(data, SAP_DISCONNECTION_TYPE_CLIENT);
+ return 0;
+ case SAP_TRANSFER_APDU_REQ:
+ DBG("SAP Transfer APDU.");
+ transfer_apdu_req(data, msg->param);
+ return 0;
+ case SAP_TRANSFER_ATR_REQ:
+ DBG("SAP Transfer ATR.");
+ transfer_atr_req(data);
+ return 0;
+ case SAP_POWER_SIM_OFF_REQ:
+ DBG("SAP SIM off.");
+ power_sim_off_req(data);
+ return 0;
+ case SAP_POWER_SIM_ON_REQ:
+ DBG("SAP SIM on.");
+ power_sim_on_req(data);
+ return 0;
+ case SAP_RESET_SIM_REQ:
+ DBG("SAP SIM reset.");
+ reset_sim_req(data);
+ return 0;
+ case SAP_TRANSFER_CARD_READER_STATUS_REQ:
+ DBG("SAP reader status.");
+ transfer_card_reader_status_req(data);
+ return 0;
+ case SAP_SET_TRANSPORT_PROTOCOL_REQ:
+ DBG("SAP set proto request.");
+ set_transport_protocol_req(data, msg->param);
+ return 0;
+ default:
+ DBG("SAP unknown message.");
+ break;
+ }
+
+error_rsp:
+ DBG("SAP ERROR RSP");
+ sap_error_rsp(data);
+ return -EBADMSG;
+}
+
+static gboolean sap_io_cb(GIOChannel *chan, GIOCondition cond, void *data)
+{
+ gchar buf[SAP_BUF_SIZE];
+ gsize bytes_read = 0;
+ GError *gerr = NULL;
+ GIOStatus gstatus;
+
+ if (cond & G_IO_NVAL){
+ DBG("ERR (G_IO_NVAL) on rfcomm socket.");
+ return FALSE;
+ }
+
+ if (cond & G_IO_ERR) {
+ DBG("ERR (G_IO_ERR) on rfcomm socket.");
+ return FALSE;
+ }
+
+ if (cond & G_IO_HUP ) {
+ DBG("HUP on rfcomm socket.");
+ return FALSE;
+ }
+
+ gstatus = g_io_channel_read_chars(chan, buf, sizeof(buf) - 1,
+ &bytes_read, &gerr);
+
+ if (gstatus != G_IO_STATUS_NORMAL) {
+ if(gerr)
+ g_error_free(gerr);
+ return TRUE;
+ }
+
+ if (handle_cmd(data, buf, bytes_read) < 0) {
+ error("Invalid SAP message.");
+ }
+
+ return TRUE;
+}
+
+static void sap_io_destroy(void *data)
+{
+ struct sap_server *server = data;
+
+ if (server && server->io) {
+ gboolean connected = FALSE;
+
+ stop_guard_timer(server);
+
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+
+ server->io = NULL;
+
+ if (server->state != SAP_STATE_CONNECT_IN_PROGRESS)
+ emit_property_changed(connection, server->path,
+ SAP_SERVER_INTERFACE,"Connected",
+ DBUS_TYPE_BOOLEAN, &connected);
+
+ if (server->state == SAP_STATE_CONNECT_IN_PROGRESS ||
+ server->state == SAP_STATE_CONNECTED ||
+ server->state == SAP_STATE_GRACEFUL_DISCONNECT){
+ sap_disconnect_req(NULL, 1);
+ }
+
+ server->state = SAP_STATE_DISCONNECTED;
+ }
+}
+
+static void sap_connect_cb(GIOChannel *chan, GError *gerr, gpointer data)
+{
+ struct sap_server *server = data;
+
+ if(!server)
+ return;
+
+ /* Timer will shutdown the channel in case of lack of client activity */
+ start_guard_timer(server, 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, server, sap_io_destroy);
+}
+
+static void connect_auth_cb(DBusError *derr, void *data)
+{
+ struct sap_server *server = data;
+ GError *gerr = NULL;
+
+ if(!server || !server->io)
+ return;
+
+ if (derr && dbus_error_is_set(derr)) {
+ error("Access denied: %s", derr->message);
+ goto drop;
+ }
+
+ if (!bt_io_accept(server->io, sap_connect_cb, server, NULL, &gerr)) {
+ error("bt_io_accept: %s", gerr->message);
+ g_error_free(gerr);
+ goto drop;
+ }
+ return;
+
+drop:
+ g_io_channel_shutdown(server->io, TRUE, NULL);
+ g_io_channel_unref(server->io);
+ server->io = NULL;
+}
+
+static void connect_confirm_cb(GIOChannel *chan, gpointer data)
+{
+ struct sap_server *server = data;
+ GError *gerr = NULL;
+ bdaddr_t src, dst;
+ int err;
+
+ if(!chan || !server)
+ return;
+
+ if (server->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;
+ }
+
+ server->io = g_io_channel_ref(chan);
+
+ err = btd_request_authorization(&src, &dst, SAP_UUID, connect_auth_cb, server);
+
+ if (err < 0) {
+ DBG("Authorization denied: %s", strerror(err));
+ goto drop;
+ }
+
+ DBG("SAP incoming connection (sock %d) authorization.", g_io_channel_unix_get_fd(chan));
+
+ return;
+
+drop:
+ g_io_channel_shutdown(chan, TRUE, NULL);
+ if (server->io && server->io == chan) {
+ g_io_channel_unref(server->io);
+ server->io = NULL;
+ }
+}
+
+
+
+static inline DBusMessage *message_failed(DBusMessage *msg,
+ const char *description)
+{
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
+ "%s", description);
+}
+
+static DBusMessage *enable(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ sdp_record_t *record = NULL;
+ GIOChannel *io = NULL;
+ GError *gerr = NULL;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (server->enable)
+ return message_failed(msg, "Server already enabled.");
+
+ record = create_sap_record(SAP_SERVER_CHANNEL);
+ if (!record)
+ return message_failed(msg, "Can't create SDP record for SAP.");
+
+ if (add_record_to_server(&server->src, record) < 0) {
+ sdp_record_free(record);
+ return message_failed(msg, "SDP record registration failed.");
+ }
+
+ io = bt_io_listen(BT_IO_RFCOMM, NULL, connect_confirm_cb, server, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &server->src,
+ BT_IO_OPT_CHANNEL, SAP_SERVER_CHANNEL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_HIGH,
+ BT_IO_OPT_MASTER, TRUE,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ g_error_free(gerr);
+ sdp_record_free(record);
+ return message_failed(msg, "Listen rfcomm channel failed.");
+ }
+
+ DBG("Listen socket %x", g_io_channel_unix_get_fd(io));
+
+ server->enable = TRUE;
+ server->record_id = record->handle;
+ server->listen_io = io;
+
+ emit_property_changed(connection, server->path, SAP_SERVER_INTERFACE,
+ "Enabled", DBUS_TYPE_BOOLEAN, &server->enable);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disable(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ DBusMessage *reply = NULL;
+
+ if(!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (!server->enable)
+ return message_failed(msg, "Server already disabled.");
+
+ if (server->state != SAP_STATE_DISCONNECTED)
+ return message_failed(msg, "Ongoing connection exists.");
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ remove_record_from_server(server->record_id);
+
+ if (server->listen_io) {
+ g_io_channel_shutdown(server->listen_io, TRUE, NULL);
+ g_io_channel_unref(server->listen_io);
+ server->listen_io = NULL;
+ }
+
+ server->enable = FALSE;
+
+ emit_property_changed(connection, server->path, SAP_SERVER_INTERFACE,
+ "Enabled", DBUS_TYPE_BOOLEAN, &server->enable);
+
+ return reply;
+}
+
+static DBusMessage *get_properties(DBusConnection *conn,
+ DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter dict;
+ dbus_bool_t connected;
+
+ if(!server)
+ return message_failed(msg, "Server internal error.");
+
+ 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);
+
+ dict_append_entry(&dict, "Enabled", DBUS_TYPE_BOOLEAN, &server->enable);
+
+ connected = (server->state == SAP_STATE_CONNECTED ||
+ server->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 *disconnect(DBusConnection *conn, DBusMessage *msg, void *data)
+{
+ struct sap_server *server = data;
+ dbus_bool_t disc_type;
+ sap_disconnection_type_t sap_disc_type;
+
+ if (!server)
+ return message_failed(msg, "Server internal error.");
+
+ if (!server->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(server, 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[] = {
+ { "Enable","","", enable },
+ { "Disable","","", disable },
+ { "GetProperties","","a{sv}",get_properties },
+ { "Disconnect","b","", disconnect },
+ { }
+};
+
+static GDBusSignalTable server_signals[] = {
+ { "PropertyChanged", "sv"},
+ { }
+};
+
+static void server_free(struct sap_server *server)
+{
+ DBG("[%s::%s]", __FILE__, __FUNCTION__);
+
+ if (!server)
+ return;
+
+ g_free(server->path);
+ g_free(server);
+}
+
+static void destroy_sap_interface(void *data)
+{
+ struct sap_server *server = data;
+
+ DBG("Unregistered interface %s on path %s",
+ SAP_SERVER_INTERFACE, server->path);
+
+ server_free(server);
+}
+
int sap_server_register(const char *path, bdaddr_t *src)
{
- DBG("Register SAP server.");
+ struct sap_server *server;
+
+ if(sap_init() < 0) {
+ error("Sap driver initialization failed.");
+ return -1;
+ }
+
+ server = g_new0(struct sap_server, 1);
+
+ if (!server) {
+ sap_exit();
+ return -ENOMEM;
+ }
+
+ server->enable = FALSE;
+
+ if (!g_dbus_register_interface(connection, path, SAP_SERVER_INTERFACE,
+ server_methods, server_signals, NULL,
+ server, destroy_sap_interface)) {
+ error("D-Bus failed to register %s interface",
+ SAP_SERVER_INTERFACE);
+ server_free(server);
+ sap_exit();
+ return -1;
+ }
+
+ server->path = g_strdup(path);
+ bacpy(&server->src, src);
+
return 0;
}
int sap_server_unregister(const char *path)
{
- DBG("Unregister SAP server.");
+ g_dbus_unregister_interface(connection, path, SAP_SERVER_INTERFACE);
+ sap_exit();
return 0;
}
int sap_server_init(DBusConnection *conn)
{
- DBG("Init SAP server.");
+ connection = dbus_connection_ref(conn);
return 0;
}
void sap_server_exit(void)
{
- DBG("Exit SAP server.");
+ dbus_connection_unref(connection);
+ connection = NULL;
}
--
1.7.0.4
^ permalink raw reply related
* [PATCH 4/4] Sim Access Profile dummy driver
From: Waldemar Rymarkiewicz @ 2010-10-20 12:11 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Marcel Holtmann, suraj, Waldemar Rymarkiewicz
In-Reply-To: <1287576681-12669-1-git-send-email-waldemar.rymarkiewicz@tieto.com>
Add SAP dummy driver implementation and extend configure
with --with-sap=<driver>.
---
.gitignore | 1 +
Makefile.am | 13 +++-
acinclude.m4 | 6 ++
sap/sap-dummy.c | 243 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 249 insertions(+), 14 deletions(-)
diff --git a/.gitignore b/.gitignore
index 07e239f..3e36a59 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,6 +35,7 @@ lib/bluetooth
src/builtin.h
src/bluetoothd
audio/telephony.c
+sap/sap.c
scripts/bluetooth.rules
scripts/97-bluetooth.rules
scripts/97-bluetooth-hid2hci.rules
diff --git a/Makefile.am b/Makefile.am
index 0facbe2..64c60f6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -147,7 +147,13 @@ builtin_modules += sap
builtin_sources += sap/main.c \
sap/manager.h sap/manager.c \
sap/server.h sap/server.c \
- sap/sap.h sap/sap-dummy.c
+ sap/sap.h
+
+builtin_nodist += sap/sap.c
+
+noinst_LIBRARIES = sap/libsap.a
+
+sap_libsap_a_SOURCES = sap/sap.h sap/sap-dummy.c
endif
if INPUTPLUGIN
@@ -271,7 +277,7 @@ EXTRA_DIST += src/genbuiltin src/bluetooth.conf \
input/input.conf serial/serial.conf \
audio/audio.conf audio/telephony-dummy.c \
audio/telephony-maemo5.c audio/telephony-ofono.c \
- audio/telephony-maemo6.c
+ audio/telephony-maemo6.c sap/sap-dummy.c
if ALSA
@@ -395,6 +401,9 @@ src/builtin.h: src/genbuiltin $(builtin_sources)
audio/telephony.c: audio/@TELEPHONY_DRIVER@
$(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+sap/sap.c: sap/@SAP_DRIVER@
+ $(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
+
scripts/%.rules:
$(AM_V_GEN)cp $(subst 97-,,$@) $@
diff --git a/acinclude.m4 b/acinclude.m4
index 1f76b4d..0ebeb11 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -194,6 +194,7 @@ AC_DEFUN([AC_ARG_BLUEZ], [
configfiles_enable=yes
telephony_driver=dummy
maemo6_enable=no
+ sap_driver=dummy
AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable code optimization]), [
optimization_enable=${enableval}
@@ -219,6 +220,11 @@ AC_DEFUN([AC_ARG_BLUEZ], [
serial_enable=${enableval}
])
+ AC_ARG_WITH(sap, AC_HELP_STRING([--with-sap=DRIVER], [select SAP driver]), [
+ sap_driver=${withval}
+ ])
+ AC_SUBST([SAP_DRIVER], [sap-${sap_driver}.c])
+
AC_ARG_ENABLE(input, AC_HELP_STRING([--disable-input], [disable input plugin]), [
input_enable=${enableval}
])
diff --git a/sap/sap-dummy.c b/sap/sap-dummy.c
index e04660f..da72369 100644
--- a/sap/sap-dummy.c
+++ b/sap/sap-dummy.c
@@ -19,23 +19,89 @@
* 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 <glib.h>
+#include <gdbus.h>
+
#include "log.h"
#include "sap.h"
+#define SAP_DUMMY_IFACE "org.bluez.SimAccessTest"
+#define SAP_DUMMY_PATH "/org/bluez/test"
+
+typedef enum {
+ SIM_CONNECTED = 0x00,
+ SIM_DISCONNECTED= 0x01,
+ SIM_POWERED_OFF = 0x02,
+ SIM_MISSING = 0x03
+} sim_connection_status_t;
+
+static DBusConnection *connection = NULL;
+
+static sim_connection_status_t sim_card_connection_status = SIM_DISCONNECTED;
+static void * sap_data = NULL; /* SAP server private data.*/
+static gboolean ongoing_call_status = FALSE;
+static int max_msg_size_supported = 512;
+
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);
+ if (sim_card_connection_status != SIM_CONNECTED) {
+ sap_connect_rsp(sap_device, SAP_STATUS_CONNECTION_FAILED,
+ maxmsgsize);
+ return;
+ } else if(max_msg_size_supported > maxmsgsize) {
+ sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_TOO_SMALL,
+ max_msg_size_supported);
+ return;
+ }else if (max_msg_size_supported < maxmsgsize) {
+ sap_connect_rsp(sap_device, SAP_STATUS_MAX_MSG_SIZE_NOT_SUPPORTED,
+ max_msg_size_supported);
+ return;
+ } else if(ongoing_call_status) {
+ sap_connect_rsp(sap_device, SAP_STATUS_OK_ONGOING_CALL,
+ maxmsgsize);
+ return;
+ } else {
+ sim_card_connection_status = SIM_CONNECTED;
+ sap_data = sap_device;
+
+ 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, uint8_t linkloss)
{
+ sim_card_connection_status = SIM_DISCONNECTED;
+ sap_data = NULL;
+ ongoing_call_status = FALSE;
+
+ if(linkloss)
+ return;
+
sap_disconnect_rsp(sap_device);
}
void sap_transfer_apdu_req(void *sap_device, sap_parameter *param)
{
- sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
+ if (sim_card_connection_status == SIM_MISSING)
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED,
+ NULL, 0);
+ else if (sim_card_connection_status == SIM_POWERED_OFF)
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF,
+ NULL, 0);
+ else if (sim_card_connection_status != SIM_CONNECTED)
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_ERROR_NOT_ACCESSIBLE,
+ NULL, 0);
+ else
+ sap_transfer_apdu_rsp(sap_device, SAP_RESULT_OK, NULL, 0);
}
void sap_transfer_atr_req(void * sap_device)
@@ -43,29 +109,70 @@ 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);
+ if (sim_card_connection_status == SIM_MISSING)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED,
+ NULL, 0);
+ else if (sim_card_connection_status == SIM_POWERED_OFF)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF,
+ NULL, 0);
+ else if (sim_card_connection_status != SIM_CONNECTED)
+ sap_transfer_atr_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON,
+ NULL, 0);
+ else
+ 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);
+ if(sim_card_connection_status == SIM_MISSING)
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED);
+ else if (sim_card_connection_status == SIM_POWERED_OFF)
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF);
+ else if(sim_card_connection_status != SIM_CONNECTED)
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
+ else {
+ sap_power_sim_off_rsp(sap_device, SAP_RESULT_OK);
+ sim_card_connection_status = SIM_POWERED_OFF;
+ }
}
void sap_power_sim_on_req(void *sap_device)
{
- sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+ if (sim_card_connection_status == SIM_MISSING)
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED);
+ else if (sim_card_connection_status == SIM_POWERED_OFF) {
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_OK);
+ sim_card_connection_status = SIM_CONNECTED;
+ return;
+ }else if(sim_card_connection_status != SIM_CONNECTED)
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_ERROR_NOT_ACCESSIBLE);
+ else {
+ sap_power_sim_on_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
+ }
}
void sap_reset_sim_req(void *sap_device)
{
- sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
- sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ if (sim_card_connection_status == SIM_MISSING)
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_CARD_REMOVED);
+ else if (sim_card_connection_status == SIM_POWERED_OFF)
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_POWERED_OFF);
+ else if (sim_card_connection_status != SIM_CONNECTED)
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_ERROR_NO_REASON);
+ else {
+ sap_reset_sim_rsp(sap_device, SAP_RESULT_OK);
+ sap_status_ind(sap_device, SAP_STATUS_CHANGE_CARD_RESET);
+ }
}
void sap_transfer_card_reader_status_req(void * sap_device)
{
- sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK,
- ICC_READER_CARD_POWERED_ON);
+ if (sim_card_connection_status != SIM_CONNECTED) {
+ sap_transfer_card_reader_status_rsp(sap_device,
+ SAP_RESULT_ERROR_NO_REASON, 0xF1);
+ return;
+ }
+ sap_transfer_card_reader_status_rsp(sap_device, SAP_RESULT_OK, 0xF1);
}
void sap_set_transport_protocol_req(void * sap_device,sap_parameter * param)
@@ -73,13 +180,125 @@ void sap_set_transport_protocol_req(void * sap_device,sap_parameter * param)
sap_transport_protocol_rsp(sap_device, SAP_RESULT_NOT_SUPPORTED);
}
+static inline DBusMessage *invalid_args(DBusMessage *msg)
+{
+ return g_dbus_create_error(msg, "org.bluez.Error.InvalidArguments",
+ "Invalid arguments in method call");
+}
+
+static DBusMessage *ongoing_call(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_bool_t ongoing;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &ongoing,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ if (ongoing_call_status && !ongoing) {
+ /* An ongoing call has finished. Continue connection.*/
+ sap_connect_rsp(sap_data, SAP_STATUS_OK, max_msg_size_supported);
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_RESET);
+ ongoing_call_status = ongoing;
+ } else if (!ongoing_call_status && ongoing) {
+ /* An ongoing call has started.*/
+ ongoing_call_status = ongoing;
+ }
+
+ DBG("sap-dummy: OngoingCall status set to %d", ongoing_call_status);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *max_msg_size(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_uint32_t size;
+
+ if (sim_card_connection_status == SIM_CONNECTED)
+ return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ "Can't change msg size when connected.");
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &size,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ max_msg_size_supported = size;
+
+ DBG("sap-dummy: MaxMessageSize set to %d", max_msg_size_supported);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ sim_card_connection_status = SIM_DISCONNECTED;
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_NOT_ACCESSIBLE);
+
+ return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *card_status(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ dbus_uint32_t status;
+
+ if(sim_card_connection_status != SIM_CONNECTED)
+ return g_dbus_create_error(msg, "org.bluez.Error.Failed",
+ "Can't change msg size when connected.");
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &status,
+ DBUS_TYPE_INVALID))
+ return invalid_args(msg);
+
+ if (status) {
+ if (sim_card_connection_status == SIM_MISSING) {
+ sim_card_connection_status = SIM_CONNECTED;
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_INSERTED);
+ }
+ } else {
+ sim_card_connection_status = SIM_MISSING;
+ sap_status_ind(sap_data, SAP_STATUS_CHANGE_CARD_REMOVED);
+ }
+
+ DBG("sap-dummy: Card status changed to %d", status);
+
+ return dbus_message_new_method_return(msg);
+}
+
+
+static GDBusMethodTable dummy_methods[] = {
+ { "OngoingCall", "b", "", ongoing_call},
+ { "MaxMessageSize", "u", "", max_msg_size},
+ { "Disconnect", "", "", disconnect},
+ { "CardStatus", "u", "", card_status},
+ { }
+};
+
+static GDBusSignalTable dummy_signals[] = {
+ { "","" },
+ { }
+};
+
int sap_init(void)
{
- DBG("SAP driver init.");
+ connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
+
+ if (g_dbus_register_interface(connection, SAP_DUMMY_PATH,
+ SAP_DUMMY_IFACE,
+ dummy_methods, dummy_signals,
+ NULL, NULL, NULL) == FALSE) {
+ error("sap-dummy interface %s init failed on path %s",
+ SAP_DUMMY_IFACE, SAP_DUMMY_PATH);
+ return -1;
+ }
+
return 0;
}
void sap_exit(void)
{
- DBG("SAP driver exit.");
+ dbus_connection_unref(connection);
+ connection = NULL;
}
--
1.7.0.4
^ permalink raw reply related
* Activating a serial connection with qdbus
From: Igor pesando @ 2010-10-20 14:21 UTC (permalink / raw)
To: linux-bluetooth
Hi *,
If I try to connect with the spp profile to a device using qdbus o dbus.send as
qdbus --system org.bluez /org/bluez/5989/hci1/dev_00_11_22_33_44
org.bluez.Serial.Connect spp
I get the proper reply /dev/rfcomm0 but the connection is dropped
immediately as rfcomm shows.
On the other side if I use rfcomm or the python script test-serial the
connection is established and kept alive.
So the questions is whether this is the expected behaviour.
Equivalently I ask whether one should interact with the dbus interface
only by programs
and use rfcomm otherwise. If so I do not understand why it is not
possible to set the Powered property
using hciconfig since if the device property Powered is false it is
not possible to initialize HCI device.
Thanks in advance for any answer.
Igor
--
-----------------------------------------------------------
fatti non foste a viver come bruti,
ma per seguire virtute e canoscenza.
Dante, Inf. XXVI 119-120
Ye were not made to live like unto brutes,
But for pursuit of virtue and of knowledge.
(Trans. H.W. Longfellow)
^ permalink raw reply
* Re: Activating a serial connection with qdbus
From: Johan Hedberg @ 2010-10-20 14:40 UTC (permalink / raw)
To: Igor pesando; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikmAHP8JiBw=cYqHCbiLot6rLjjboc7wnySmEmj@mail.gmail.com>
Hi Igor,
On Wed, Oct 20, 2010, Igor pesando wrote:
> If I try to connect with the spp profile to a device using qdbus o dbus.send as
>
> qdbus --system org.bluez /org/bluez/5989/hci1/dev_00_11_22_33_44
> org.bluez.Serial.Connect spp
>
> I get the proper reply /dev/rfcomm0 but the connection is dropped
> immediately as rfcomm shows.
> On the other side if I use rfcomm or the python script test-serial the
> connection is established and kept alive.
>
> So the questions is whether this is the expected behaviour.
> Equivalently I ask whether one should interact with the dbus interface
> only by programs and use rfcomm otherwise.
bluetoothd is "intelligent" and cleans up after the D-Bus client if the
client exists unexpectedly without calling Serial.Disconnect() first
(which is what qdbus does when it receives the reply). So the only way
to keep the connection alive is to also keep the process alive that
requested it. I.e. probably you can't use qdbus for this.
> If so I do not understand why it is not possible to set the Powered
> property using hciconfig since if the device property Powered is false
> it is not possible to initialize HCI device.
I'm not quite following your question. You can use "test-adapter powered
yes/no" and even "hciconfig hci0 up/down" should also work.
Johan
^ permalink raw reply
* [PATCH] Fix Maemo6 MCE: set state variable directly
From: Daniel Örstadius @ 2010-10-20 14:59 UTC (permalink / raw)
To: linux-bluetooth
[-- Attachment #1: Type: text/plain, Size: 29 bytes --]
Hi,
Please review.
/Daniel
[-- Attachment #2: 0001-Fix-Maemo6-MCE-set-state-variable-directly.patch --]
[-- Type: text/x-patch, Size: 1285 bytes --]
From b9adfbe1db7b6f783d3bd6b98962a32161284127 Mon Sep 17 00:00:00 2001
From: Daniel Orstadius <daniel.orstadius@nokia.com>
Date: Wed, 20 Oct 2010 17:13:17 +0300
Subject: [PATCH] Fix Maemo6 MCE: set state variable directly
If the state variable is not updated until mce_signal_callback and
SetProperty(Powered) is called two times quickly, then the second
call will not generate a request to change the radio state of the
MCE if its corresponding call to adapter_powered occurs before the
first triggering of mce_signal_callback.
With this patch two calls to the MCE are executed, although there
might still be an unnecessary power cycle in that
mce_signal_callback is also triggered twice.
---
plugins/maemo6.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/plugins/maemo6.c b/plugins/maemo6.c
index 0a1e551..3c91926 100644
--- a/plugins/maemo6.c
+++ b/plugins/maemo6.c
@@ -166,7 +166,9 @@ static void adapter_powered(struct btd_adapter *adapter, gboolean powered)
DBUS_TYPE_UINT32, &radio_mask,
DBUS_TYPE_INVALID);
- if (!dbus_connection_send(conn, msg, NULL))
+ if (dbus_connection_send(conn, msg, NULL))
+ mce_bt_set = powered;
+ else
error("calling %s failed", MCE_RADIO_STATES_CHANGE_REQ);
dbus_message_unref(msg);
--
1.6.0.4
^ permalink raw reply related
* Re: Activating a serial connection with qdbus
From: Igor pesando @ 2010-10-20 15:17 UTC (permalink / raw)
To: Igor pesando, linux-bluetooth
In-Reply-To: <20101020144004.GA14607@jh-x301>
Hi Johan,
thank for the quick and precise answer for what qdbus concerns.
On Wed, Oct 20, 2010 at 4:40 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
>
>> If so I do not understand why it is not possible to set the Powered
>> property using hciconfig since if the device property Powered is false
>> it is not possible to initialize HCI device.
>
> I'm not quite following your question. You can use "test-adapter powered
> yes/no" and even "hciconfig hci0 up/down" should also work.
>
You are right.
The issue I have is therefore associated with blueman:
when you switch off the adapter with blueman and then kill blueman-applet
hciconfig hci0 up does not work and returns an error (Can't init
device hci1: Unknown error 132 (132) )
and sometimes
dbus-send and test-adapter do the same (
dbus.exceptions.DBusException: org.bluez.Error.Failed: Unknown error
132)
while blueman-applet can solve the problem if restarted.
Igor
--
-----------------------------------------------------------
fatti non foste a viver come bruti,
ma per seguire virtute e canoscenza.
Dante, Inf. XXVI 119-120
Ye were not made to live like unto brutes,
But for pursuit of virtue and of knowledge.
(Trans. H.W. Longfellow)
^ permalink raw reply
* Re: Activating a serial connection with qdbus
From: Anderson Lizardo @ 2010-10-20 16:56 UTC (permalink / raw)
To: Igor pesando; +Cc: linux-bluetooth
In-Reply-To: <AANLkTi=QGnn5bhWSvBvaAE-k0NiRcKoybQM+pjGtn9ua@mail.gmail.com>
On Wed, Oct 20, 2010 at 11:17 AM, Igor pesando <ipesando@gmail.com> wrote:
> The issue I have is therefore associated with blueman:
> when you switch off the adapter with blueman and then kill blueman-applet
> hciconfig hci0 up does not work and returns an error (Can't init
> device hci1: Unknown error 132 (132) )
> and sometimes
> dbus-send and test-adapter do the same (
> dbus.exceptions.DBusException: org.bluez.Error.Failed: Unknown error
> 132)
> while blueman-applet can solve the problem if restarted.
Might not be related but... it could be that RFKILL has disabled the
device. Run "rfkill list" and see if is either hard or soft blocked.
If it is, unblock it with "rfkill unblock <id>".
I've seen many times bluetoothd blocking devices on shutdown, maybe
because it thinks the device is blocked during start.
Regards,
--
Anderson Lizardo
OpenBossa Labs - INdT
Manaus - Brazil
^ permalink raw reply
* Change in Bluetooth Subsystem maintainership
From: Gustavo F. Padovan @ 2010-10-20 22:23 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
Hi everyone,
As some of you have noticed already, I'm on charge of maintain the
Bluetooth subsystem tree since the beginning of the month. Marcel will
be around as before, but now only reviewing, ACKing and NACKing patches.
Pick the patches and put them on the way to mainline is my job now.
The tree for development looking the -next linux release is
http://git.kernel.org/?p=linux/kernel/git/padovan/bluetooth-next-2.6.git
and the tree for fixes in the current release is
http://git.kernel.org/?p=linux/kernel/git/padovan/bluetooth-2.6.git
Regards,
--
Gustavo F. Padovan
ProFUSION embedded systems - http://profusion.mobi
^ permalink raw reply
* Re: AVRCP 1.4 : Future on Target Role
From: David Stockwell @ 2010-10-20 22:24 UTC (permalink / raw)
To: Shivendra Agrawal, linux-bluetooth
In-Reply-To: <AANLkTim9ypGcMEJ4+HqSZT_uxH4x9chHUW3mU0uDbfrR@mail.gmail.com>
Hi Shivendra,
> Hi All,
>
> David,
> If you are going to resume AVRCP 1.3 implementation, can we sync
> together as I have done some study on this part as well.
> So far I don't have any device and guess PTS can be taken as start point.
(PTS??)
Regarding an AVRCP device, I have not found any on the market. I designed
and built a remote control based on a CSR BC4 chip, with LCD display and
keypad controller (and battery charger, USB, etc., etc.). Firmware is
programmed using the CSR BlueCore SDK. The latest version (version 4.1.2)
of the SDK includes functions that provide support for AVRCP 1.3, but
probably not for 1.4 AFAIK.
For my purposes, I am not implementing A2DP and headset capability in this
remote.
David
>
> Regards,
> Shivendra
>
^ permalink raw reply
* keep-alive on mouse and keyboard
From: Scott Serr @ 2010-10-20 23:03 UTC (permalink / raw)
To: linux-bluetooth
I've been searching for a way to keep my MS 6000 keyboard and MS 5000
mouse awake. I'm using Ubuntu 10.10 with bluez 4.69, it works very well
but I'd like to figure out how to keep them from falling asleep. (they
do wake up after a key-press and reconnect, but takes about 5 seconds
each time)
I hoped l2ping might do it, but no luck.
I'll be programming for a bluetooth barcode scanner soon, is there a
general way to keep all these devices awake?
Thank you,
Scott Serr
^ permalink raw reply
* [PATCH 0/1] Bluetooth: fix crash in L2CAP
From: Gustavo F. Padovan @ 2010-10-21 5:19 UTC (permalink / raw)
To: greg, linux-bluetooth; +Cc: stable, linux-kernel
Hi Greg,
The following patch is good for 2.6.36.1. It arrived too late in linux-bluetooth
and we didn't had time to put it into 2.6.36. It fixes a serious crash into
the L2CAP layer. The issue isn't in 2.6.35 and below.
Thanks.
Nathan Holstein (1):
Bluetooth: fix oops in l2cap_connect_req
net/bluetooth/l2cap.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
--
1.7.3.1
^ permalink raw reply
* [PATCH 1/1] Bluetooth: fix oops in l2cap_connect_req
From: Gustavo F. Padovan @ 2010-10-21 5:19 UTC (permalink / raw)
To: greg, linux-bluetooth; +Cc: stable, linux-kernel, Nathan Holstein
In-Reply-To: <1287638393-8573-1-git-send-email-padovan@profusion.mobi>
From: Nathan Holstein <nathan.holstein@gmail.com>
In error cases when the ACL is insecure or we fail to allocate a new
struct sock, we jump to the "response" label. If so, "sk" will be
null and the kernel crashes.
Signed-off-by: Nathan Holstein <nathan.holstein@gmail.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
---
net/bluetooth/l2cap.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 0b54b7d..dc60205 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2891,7 +2891,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
struct l2cap_chan_list *list = &conn->chan_list;
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp;
- struct sock *parent, *uninitialized_var(sk);
+ struct sock *parent, *sk = NULL;
int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3000,7 +3000,7 @@ sendresp:
L2CAP_INFO_REQ, sizeof(info), &info);
}
- if (!(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
+ if (sk && !(l2cap_pi(sk)->conf_state & L2CAP_CONF_REQ_SENT) &&
result == L2CAP_CR_SUCCESS) {
u8 buf[128];
l2cap_pi(sk)->conf_state |= L2CAP_CONF_REQ_SENT;
--
1.7.3.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox