Linux bluetooth development
 help / color / mirror / Atom feed
* [RFC v2] Convert storage to use per-remote device directories
From: Frederic Danis @ 2012-10-02 12:08 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hi everyone,

Here is my proposal for new storage directory structure using ini-file 
format.

Each adapter directory (/var/lib/bluetooth/<adapter address>/) will contain:
  - an adapter.conf file for the local adapter
  - an attribute_db.conf file containing attributes of supported LE services
  - one directory per remote device, named by remote device address. A 
directory will contain:
     - a device.conf file
     - a key file accessible only by root
     - an attribute_db.conf file containing attributes of remote LE services

So the directory structure should be:
     /var/lib/bluetooth/<adapter address>/
         ./adapter.conf
         ./attribute_db.conf
         ./<remote device address>/
             ./device.conf
             ./keys.conf
             ./attribute_db.conf
         ./<remote device address>/
             ./device.conf
             ./keys.conf
             ./attribute_db.conf
         ...


The adapter config file just need to be converted to ini-file format 
with only 1 group called [adapter], for example:
   [Adapter]
   Name=desktop-0
   Class=0x780011
   Pairable=true
   OnMode=discoverable
   Mode=discoverable

The attribute_db.conf file should be a list of handles (group name) with 
UUID and Value as keys, for example:
   [0x0001]
   UUID=00002800-0000-1000-8000-00805f9b34fb
   Value=0018

   [0x0004]
   UUID=00002803-0000-1000-8000-00805f9b34fb
   Value=020600002A

   [0x0006]
   UUID=00002a00-0000-1000-8000-00805f9b34fb
   Value=4578616D706C6520446576696365


Remote device config file will include a [device] group with general 
device infos (name, alias, profiles or primary services list, ...), for 
example:
   [Device]
   Name=MyPhone
   Alias=Fred's phone
   Class=0x180204
   DeviceId=FFFF 0000 0000 0000
   EIR=040D040218
   Manufacturer=15
   LmpVersion=2
   LmpSubversion=777
   Features=FFFE0D0008080000
   LastSeen=2012-09-26 11:19:40 GMT
   LastUsed=2012-09-26 11:43:42 GMT
   Trusted=true
 
Profiles=00001101-0000-1000-8000-00805f9b34fb;00001103-0000-1000-8000-00805f9b34fb

For LE devices, LEAddressType entry should exist to distinguish 
LE-Public from LE-Random address.

Keys file will include informations related to link key or long term 
link key, for example:
   [LinkKey]
   Key=9EF4BDFA68C5438A176DF42ACD59816C
   Type=0
   Length=4

   [LongTermKey]
   Key=
   Authenticated=
   EncSize=
   EDiv=
   Rand=

-- 
Frederic Danis                            Open Source Technology Center
frederic.danis@intel.com                              Intel Corporation




^ permalink raw reply

* Re: [PATCH] device: Remove not used variables from search_cb
From: Johan Hedberg @ 2012-10-02 12:07 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1349177995-29253-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Tue, Oct 02, 2012, Szymon Janc wrote:
> sda and dba are not used in function code.
> 
> ---
>  src/device.c |    8 +-------
>  1 file changed, 1 insertion(+), 7 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] device: Remove not used variables from search_cb
From: Szymon Janc @ 2012-10-02 11:39 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1349176333-26638-1-git-send-email-szymon.janc@tieto.com>

sda and dba are not used in function code.

---
 src/device.c |    8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/device.c b/src/device.c
index c41b0c8..fb7c4f8 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1818,14 +1818,8 @@ send_reply:
 	}
 
 cleanup:
-	if (!device->temporary) {
-		bdaddr_t sba, dba;
-
-		adapter_get_address(device->adapter, &sba);
-		device_get_address(device, &dba, NULL);
-
+	if (!device->temporary)
 		store_profiles(device);
-	}
 
 	device->browse = NULL;
 	browse_request_free(req);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH] device: Remove not used variable from search_cb
From: Szymon Janc @ 2012-10-02 11:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

dba is not used in function code.

---
 src/device.c |    7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/device.c b/src/device.c
index ab9e897..cb6812a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1802,13 +1802,8 @@ send_reply:
 	}
 
 cleanup:
-	if (!device->temporary) {
-		bdaddr_t dba;
-
-		device_get_address(device, &dba, NULL);
-
+	if (!device->temporary)
 		store_profiles(device);
-	}
 
 	device->browse = NULL;
 	browse_request_free(req);
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH BlueZ 02/10] gdbus: Remove connection from g_dbus_remove_watch
From: Lucas De Marchi @ 2012-10-02 10:49 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZ+f+idjJw1_i4uqoTJTdXMfr1xHAvdpGj4-59vchV+ouA@mail.gmail.com>

On Tue, Oct 2, 2012 at 5:05 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Lucas,
>
> On Tue, Oct 2, 2012 at 7:23 AM, Lucas De Marchi
> <lucas.demarchi@profusion.mobi> wrote:
>> On Mon, Oct 1, 2012 at 2:53 PM, Luiz Augusto von Dentz
>> <luiz.dentz@gmail.com> wrote:
>>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>>
>>> The connection is not really needed since the list of listeners is
>>> global not per connection, besides it is more convenient this way as
>>> only the id is needed.
>>> ---
>>>  gdbus/gdbus.h | 2 +-
>>>  gdbus/watch.c | 4 ++--
>>>  2 files changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>>> index 0a8a27c..3bd8986 100644
>>> --- a/gdbus/gdbus.h
>>> +++ b/gdbus/gdbus.h
>>> @@ -217,7 +217,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>>                                 const char *interface, const char *member,
>>>                                 GDBusSignalFunction function, void *user_data,
>>>                                 GDBusDestroyFunction destroy);
>>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
>>> +gboolean g_dbus_remove_watch(guint id);
>>>  void g_dbus_remove_all_watches(DBusConnection *connection);
>>>
>>>  #ifdef __cplusplus
>>> diff --git a/gdbus/watch.c b/gdbus/watch.c
>>> index 07feb61..00cedae 100644
>>> --- a/gdbus/watch.c
>>> +++ b/gdbus/watch.c
>>> @@ -285,7 +285,7 @@ static void filter_data_free(struct filter_data *data)
>>>                 g_free(l->data);
>>>
>>>         g_slist_free(data->callbacks);
>>> -       g_dbus_remove_watch(data->connection, data->name_watch);
>>> +       g_dbus_remove_watch(data->name_watch);
>>>         g_free(data->name);
>>>         g_free(data->owner);
>>>         g_free(data->path);
>>> @@ -752,7 +752,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>>         return cb->id;
>>>  }
>>>
>>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
>>> +gboolean g_dbus_remove_watch(guint id)
>>>  {
>>>         struct filter_data *data;
>>>         struct filter_callback *cb;
>>> --
>>
>> This will lead to a broken build which is not nice to bisect. Any
>> other option besides adding with another name, converting everybody
>> and then renaming?
>>
>> The only other option I can think of is adding an ifdef and an option
>> to build-sys... this would avoid the final renaming.
>
> I guess this time it worth having the break of bisect in favor of a
> more convenient API, if you look at what the code is doing the
> connection is useless and normally we end up having to call the core
> to figure out a connection that is not used for anything.

Ahn? did you read what I proposed as an option? I proposed splitting
the patch in 4 as opposed to 2 as you did.

0001) WARNING, whitespace error below

diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
index 0a8a27c..d254562 100644
--- a/gdbus/gdbus.h
+++ b/gdbus/gdbus.h
@@ -217,7 +217,12 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
 				const char *interface, const char *member,
 				GDBusSignalFunction function, void *user_data,
 				GDBusDestroyFunction destroy);
-gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
+#ifdef _GDBUS_WITH_NEW_REMOVE_WATCH
+gboolean g_dbus_remove_watch(guint tag);
+#else
+gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
+#endif
+
 void g_dbus_remove_all_watches(DBusConnection *connection);

 #ifdef __cplusplus


0002) Convert everybody adding the definition on Makefile.am

0003) Remove the define from Makefile.am

0004) Remove the old code from gdbus/


Lucas De Marchi

^ permalink raw reply related

* Re: [PATCH 1/2] service: Remove extra memory copying from cancel_authorization
From: Johan Hedberg @ 2012-10-02  9:50 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1349170392-16498-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

On Tue, Oct 02, 2012, Szymon Janc wrote:
> src is never read before being overwritten few lines below.
> 
> ---
>  plugins/service.c |    5 -----
>  1 file changed, 5 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] agent: Remote not used variables from pincode_reply
From: Szymon Janc @ 2012-10-02  9:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1349170392-16498-1-git-send-email-szymon.janc@tieto.com>

adapter and sba are not used later in function code.

---
 src/agent.c |    4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/agent.c b/src/agent.c
index 8cf37b1..e206c56 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -355,16 +355,12 @@ static void pincode_reply(DBusPendingCall *call, void *user_data)
 {
 	struct agent_request *req = user_data;
 	struct agent *agent = req->agent;
-	struct btd_adapter *adapter = agent->adapter;
 	agent_pincode_cb cb = req->cb;
 	DBusMessage *message;
 	DBusError err;
-	bdaddr_t sba;
 	size_t len;
 	char *pin;
 
-	adapter_get_address(adapter, &sba);
-
 	/* steal_reply will always return non-NULL since the callback
 	 * is only called after a reply has been received */
 	message = dbus_pending_call_steal_reply(call);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/2] service: Remove extra memory copying from cancel_authorization
From: Szymon Janc @ 2012-10-02  9:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

src is never read before being overwritten few lines below.

---
 plugins/service.c |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/plugins/service.c b/plugins/service.c
index 45886ac..d586d79 100644
--- a/plugins/service.c
+++ b/plugins/service.c
@@ -662,11 +662,6 @@ static DBusMessage *cancel_authorization(DBusConnection *conn,
 	if (auth == NULL)
 		return btd_error_does_not_exist(msg);
 
-	if (serv_adapter->adapter)
-		adapter_get_address(serv_adapter->adapter, &src);
-	else
-		bacpy(&src, BDADDR_ANY);
-
 	btd_cancel_authorization(auth->id);
 
 	reply = btd_error_not_authorized(auth->msg);
-- 
1.7.9.5


^ permalink raw reply related

* Re: [PATCH v2 07/15] thermometer: Reformat MeasurementReceived description
From: Andrzej Kaczmarek @ 2012-10-02  8:52 UTC (permalink / raw)
  To: Santiago Carot; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <CACLukz+Ducgd2LmFCrqyb6TnSz_BSEVm1x=rKXrOzSzKNg6ung@mail.gmail.com>

Hi Santiago,

On 10/01/2012 02:08 PM, Santiago Carot wrote:
>>> Mantissa values must not always be 2^23-1 on special cases.
>>> Information provided here is required for upper profiles which are
>>> implementing an 11073-20601 protocol layer because they have to
>>> differentiate among these values. In my opinion, documentation about
>>> passible values for the mantissa should remain as they are.
>>
>>
>> HTS specification states (see quote below) that measurement value field may
>> be NaN in case sensor is not able to provide valid measurement. So I assume
>> here that either it has valid data or NaN otherwise and thus there's no need
>> to specify other special values as they should not be received here.
>>
>> <quote>
>> The Temperature Measurement Value field may contain special float value NaN
>> (0x007FFFFF) defined in IEEE 11073-20601 [4] to report an invalid result
>> from a computation step or missing data due to the hardware’s inability to
>> provide a valid measurement.
>> </quote>
>>
>
> IMHO that doesn't justify you to force all mantisse values to be
> 2^23-1, first of all because the value type for this characteristic is
> a FLOAT type, so any value that a thermometer could send, it does it
> using the format defined for FLOAT types which is explained in
> IEEE-11073-20601,
> [http://developer.bluetooth.org/gatt/Pages/FormatTypes.aspx]
>
> On the other hand, I understand from this quote that thermometers MAY
> set NaN in case sensor is not able to provide valid measuremen due to
> an invalid result or missing data, but it doesn't say anything about
> other values that a FLOAT types can take, so you are forcing to be NaN
> other special cases that are defined for this kind of type.
>
> If you had a look to that spec you could see wich other special values
> a FLOAT type could take, if not, you could at least have a look to one
> of the whitepapers defined in bluetooth sig for transcoders.

Just to be clear here: I do not force mantissa values to any particular 
value. Whatever is received from remote device is still dispatched to 
application as-is. I just modified description so it mentions what HTS 
specification says about this value and that's all and since it was just 
done "by the way" when reformatting description I won't push for it.

But perhaps it's worth just adding note that exponent and mantissa are 
as in IEEE-11073-20601. This clearly states that apps working in 
IEEE-11073-20601 ecosystem can pack both values directly into float and 
there's no need to specify all special values.

BR,
Andrzej

^ permalink raw reply

* Re: [PATCH BlueZ v8 1/8] core: Mutually exclude concurrent connections
From: Johan Hedberg @ 2012-10-02  8:30 UTC (permalink / raw)
  To: João Paulo Rechi Vita; +Cc: linux-bluetooth
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

Hi,

On Mon, Oct 01, 2012, João Paulo Rechi Vita wrote:
>  static gboolean connect_pending_cb(gpointer user_data)
>  {
>  	struct btd_device *device = user_data;
>  	struct btd_adapter *adapter = device_get_adapter(device);
> +	GIOChannel *io;
>  
>  	/* in the future we may want to check here if the controller supports
>  	 * scanning and connecting at the same time */
>  	if (adapter->discovering)
>  		return TRUE;
>  
> -	device_att_connect(device);
> +	if (adapter->connecting)
> +		return TRUE;
> +
> +	adapter->connecting = TRUE;
> +	adapter->waiting_to_connect--;
> +
> +	io = device_att_connect(device);
> +	g_io_add_watch(io, G_IO_OUT | G_IO_ERR, clean_connecting_state,
> +						btd_device_ref(device));

Looks like there is some error handling missing here since
device_att_connect could return NULL;

> +		g_idle_add(connect_pending_cb,  btd_device_ref(device));

Two spaces after the comma here. What's a bit worrying also is that you
don't store the idle id, but I suppose that's safe since you ensure that
this asynchronous operation has it's own reference to the device.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ 02/10] gdbus: Remove connection from g_dbus_remove_watch
From: Luiz Augusto von Dentz @ 2012-10-02  8:05 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth
In-Reply-To: <CAMOw1v503Fxkx6tD-cN1s_buev89ytSG1P-ngSxUCLk4eMVa6Q@mail.gmail.com>

Hi Lucas,

On Tue, Oct 2, 2012 at 7:23 AM, Lucas De Marchi
<lucas.demarchi@profusion.mobi> wrote:
> On Mon, Oct 1, 2012 at 2:53 PM, Luiz Augusto von Dentz
> <luiz.dentz@gmail.com> wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> The connection is not really needed since the list of listeners is
>> global not per connection, besides it is more convenient this way as
>> only the id is needed.
>> ---
>>  gdbus/gdbus.h | 2 +-
>>  gdbus/watch.c | 4 ++--
>>  2 files changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
>> index 0a8a27c..3bd8986 100644
>> --- a/gdbus/gdbus.h
>> +++ b/gdbus/gdbus.h
>> @@ -217,7 +217,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>                                 const char *interface, const char *member,
>>                                 GDBusSignalFunction function, void *user_data,
>>                                 GDBusDestroyFunction destroy);
>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
>> +gboolean g_dbus_remove_watch(guint id);
>>  void g_dbus_remove_all_watches(DBusConnection *connection);
>>
>>  #ifdef __cplusplus
>> diff --git a/gdbus/watch.c b/gdbus/watch.c
>> index 07feb61..00cedae 100644
>> --- a/gdbus/watch.c
>> +++ b/gdbus/watch.c
>> @@ -285,7 +285,7 @@ static void filter_data_free(struct filter_data *data)
>>                 g_free(l->data);
>>
>>         g_slist_free(data->callbacks);
>> -       g_dbus_remove_watch(data->connection, data->name_watch);
>> +       g_dbus_remove_watch(data->name_watch);
>>         g_free(data->name);
>>         g_free(data->owner);
>>         g_free(data->path);
>> @@ -752,7 +752,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>>         return cb->id;
>>  }
>>
>> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
>> +gboolean g_dbus_remove_watch(guint id)
>>  {
>>         struct filter_data *data;
>>         struct filter_callback *cb;
>> --
>
> This will lead to a broken build which is not nice to bisect. Any
> other option besides adding with another name, converting everybody
> and then renaming?
>
> The only other option I can think of is adding an ifdef and an option
> to build-sys... this would avoid the final renaming.

I guess this time it worth having the break of bisect in favor of a
more convenient API, if you look at what the code is doing the
connection is useless and normally we end up having to call the core
to figure out a connection that is not used for anything.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v1 0/2] audio: Fixes in HFP gateway
From: Johan Hedberg @ 2012-10-02  7:45 UTC (permalink / raw)
  To: Mikel Astiz; +Cc: linux-bluetooth, Mikel Astiz
In-Reply-To: <1349105046-20035-1-git-send-email-mikel.astiz.oss@gmail.com>

Hi Mikel,

On Mon, Oct 01, 2012, Mikel Astiz wrote:
> I'm grouping these two patches -originally sent separately- into a
> single patchset, after changing the approach as suggested by Luiz.
> 
> Mikel Astiz (2):
>   audio: Fix crash if gateway closed before reply
>   audio: Fix crash on gateway close while connected
> 
>  audio/gateway.c | 68 +++++++++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 54 insertions(+), 14 deletions(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] client-doc: Add documentation for Message.SetProperty and Message.GetProperties
From: Srinivasa Ragavan @ 2012-10-02  6:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan

---
 doc/client-api.txt |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 25fd3e4..6487146 100644
--- a/doc/client-api.txt
+++ b/doc/client-api.txt
@@ -534,6 +534,85 @@ Methods		object, dict Get(string targetfile, boolean attachment)
 			The properties of this transfer are also returned along
 			with the object path, to avoid a call to GetProperties.
 
+		dict GetProperties()
+
+			Returns all properties for the message. See the
+			properties section for available properties.
+
+		void SetProperty (string name, variant value)
+			
+			Sets value to the mentioned property. 
+
+			Possible properties: Read and Deleted.
+			
+			
+Properties	string Subject [readonly]
+
+			Message subject
+
+		string Timestamp [readonly]
+
+			Message timestamp
+
+		string Sender [readonly]
+
+			Message sender name
+
+		string SenderAddress [readonly]
+
+			Message sender address
+
+		string ReplyTo [readonly]
+
+			Message Reply-To address
+
+		string Recipient [readonly]
+
+			Message recipient name
+
+		string RecipientAddress [readonly]
+
+			Message recipient address
+
+		string Type [readonly]
+
+			Message type
+
+			Possible values: "EMAIL", "SMS_GSM",
+			"SMS_CDMA" and "MMS"
+
+		uint64 Size [readonly]
+
+			Message size in bytes
+
+		string Status [readonly]
+
+			Message reception status
+
+			Possible values: "complete",
+			"fractioned" and "notification"
+
+		boolean Priority [readonly]
+
+			Message priority flag
+
+		boolean Read [read/write]
+
+			Message read flag
+
+		boolean Deleted [writeonly]
+
+			Message read flag
+
+		boolean Sent [readonly]
+
+			Message sent flag
+
+		boolean Protected [readonly]
+
+			Message protected flag
+
+
 Transfer hierarchy
 ==================
 
-- 
1.7.10.4


^ permalink raw reply related

* [PATCH 1/2] client: Add Message.SetProperty and Message.GetProperties implementation.
From: Srinivasa Ragavan @ 2012-10-02  6:43 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan

---
 client/map.c |  170 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 170 insertions(+)

diff --git a/client/map.c b/client/map.c
index e78cd68..8d6f930 100644
--- a/client/map.c
+++ b/client/map.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <glib.h>
+#include <glib/gstdio.h>
 #include <gdbus.h>
 
 #include <gobex-apparam.h>
@@ -78,6 +79,10 @@ static const char * const filter_list[] = {
 #define FILTER_BIT_MAX	15
 #define FILTER_ALL	0xFF
 
+#define STATUS_READ 0
+#define STATUS_DELETE 1
+#define FILLER_BYTE 0x30
+
 struct map_data {
 	struct obc_session *session;
 	DBusMessage *msg;
@@ -104,6 +109,7 @@ struct map_msg {
 	uint64_t size;
 	char *status;
 	uint8_t flags;
+	DBusMessage *msg;	
 };
 
 struct map_parser {
@@ -412,6 +418,163 @@ fail:
 	return reply;
 }
 
+static void set_message_status_cb(struct obc_session *session,
+						struct obc_transfer *transfer,
+						GError *err, void *user_data)
+{
+	struct map_msg *msg = user_data;
+	DBusMessage *reply;
+
+	if (err != NULL) {
+		reply = g_dbus_create_error(msg->msg,
+						ERROR_INTERFACE ".Failed",
+						"%s", err->message);
+		goto done;
+	}
+
+	reply = dbus_message_new_method_return(msg->msg);
+	if (reply == NULL) {
+		reply = g_dbus_create_error(msg->msg,
+						ERROR_INTERFACE ".Failed",
+						"%s", err->message);
+	}
+
+done:
+	g_dbus_send_message(conn, reply);
+	dbus_message_unref(msg->msg);
+	msg->msg = NULL;
+}
+
+static DBusMessage *map_msg_set_property (DBusConnection *connection,
+						DBusMessage *message, void *user_data)
+{
+	struct map_msg *msg = user_data;
+	struct obc_transfer *transfer;
+	char *property;
+	gboolean status;
+	GError *err = NULL;
+	DBusMessage *reply;
+	GObexApparam *apparam;
+	char contents[2];
+	int op;
+	DBusMessageIter args, variant;
+
+	dbus_message_iter_init(message, &args);
+	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) 
+		return g_dbus_create_error(message,
+				ERROR_INTERFACE ".InvalidArguments", NULL);
+
+	dbus_message_iter_get_basic(&args, &property);
+	dbus_message_iter_next (&args);
+	if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) 
+		return g_dbus_create_error(message,
+				ERROR_INTERFACE ".InvalidArguments", NULL);
+	
+	dbus_message_iter_recurse(&args, &variant);
+	if (dbus_message_iter_get_arg_type(&variant) != DBUS_TYPE_BOOLEAN) 
+		return g_dbus_create_error(message,
+				ERROR_INTERFACE ".InvalidArguments", NULL);
+	
+	dbus_message_iter_get_basic(&variant, &status);
+
+	/* MAP supports modifying only these two properties. */
+	if (property && strcasecmp (property, "Read") == 0) {
+		op = STATUS_READ;
+		if (status)
+			msg->flags |= MAP_MSG_FLAG_READ;
+		else
+			msg->flags &= ~MAP_MSG_FLAG_READ;
+	} else if (property && strcasecmp (property, "Deleted") == 0)
+		op = STATUS_DELETE;
+	else {
+		return g_dbus_create_error(message,
+				ERROR_INTERFACE ".InvalidArguments", NULL);
+	}
+
+	contents[0] = FILLER_BYTE;
+	contents[1] = '\0';
+	
+	transfer = obc_transfer_put("x-bt/messageStatus", msg->handle, NULL,
+							contents, sizeof(contents), &err);
+	if (transfer == NULL)
+		goto fail;
+
+	apparam = g_obex_apparam_set_uint8(NULL, MAP_AP_STATUSINDICATOR,
+								op);
+	apparam = g_obex_apparam_set_uint8(apparam, MAP_AP_STATUSVALUE,
+								status);
+	obc_transfer_set_apparam(transfer, apparam);
+
+	if (!obc_session_queue(msg->data->session, transfer, set_message_status_cb, msg, &err))
+		goto fail;
+
+	msg->msg = dbus_message_ref (message);
+	return NULL;
+
+fail:
+	reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
+								err->message);
+	g_error_free(err);
+	return reply;
+}
+
+static DBusMessage *map_msg_get_properties (DBusConnection *connection,
+						DBusMessage *message, void *user_data)
+{
+	struct map_msg *msg = user_data;
+	GError *err = NULL;
+	DBusMessage *reply;
+	DBusMessageIter iter, data_array;
+	gboolean flag;
+	
+	reply = dbus_message_new_method_return(message);
+	if (reply == NULL) {
+		reply = g_dbus_create_error(message,
+						ERROR_INTERFACE ".Failed",
+						NULL);
+		goto done;
+	}
+
+	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,
+					&data_array);
+
+
+	obex_dbus_dict_append(&data_array, "Subject", DBUS_TYPE_STRING, &msg->subject);
+	obex_dbus_dict_append(&data_array, "Timestamp", DBUS_TYPE_STRING, &msg->timestamp);
+	obex_dbus_dict_append(&data_array, "Sender", DBUS_TYPE_STRING, &msg->sender);
+	obex_dbus_dict_append(&data_array, "SenderAddress", DBUS_TYPE_STRING,
+						&msg->sender_address);
+	obex_dbus_dict_append(&data_array, "ReplyTo", DBUS_TYPE_STRING, &msg->replyto);
+	obex_dbus_dict_append(&data_array, "Recipient", DBUS_TYPE_STRING, &msg->recipient);
+	obex_dbus_dict_append(&data_array, "RecipientAddress", DBUS_TYPE_STRING,
+								&msg->recipient_address);
+	obex_dbus_dict_append(&data_array, "Type", DBUS_TYPE_STRING, &msg->type);
+	obex_dbus_dict_append(&data_array, "Status", DBUS_TYPE_STRING, &msg->status);
+	obex_dbus_dict_append(&data_array, "Size", DBUS_TYPE_UINT64, &msg->size);
+	flag = (msg->flags & MAP_MSG_FLAG_PRIORITY) != 0;
+	obex_dbus_dict_append(&data_array, "Priority", DBUS_TYPE_BOOLEAN, &flag);
+	flag = (msg->flags & MAP_MSG_FLAG_READ) != 0;
+	obex_dbus_dict_append(&data_array, "Read", DBUS_TYPE_BOOLEAN, &flag);
+	flag = (msg->flags & MAP_MSG_FLAG_SENT) != 0;
+	obex_dbus_dict_append(&data_array, "Sent", DBUS_TYPE_BOOLEAN, &flag);
+	flag = (msg->flags & MAP_MSG_FLAG_PROTECTED) != 0;
+	obex_dbus_dict_append(&data_array, "Protected", DBUS_TYPE_BOOLEAN, &flag);
+
+	dbus_message_iter_close_container(&iter, &data_array);
+
+
+done:
+	if (err)
+		g_error_free(err);
+
+	return reply;	
+}
+
 static const GDBusMethodTable map_msg_methods[] = {
 	{ GDBUS_METHOD("Get",
 			GDBUS_ARGS({ "targetfile", "s" },
@@ -419,6 +582,13 @@ static const GDBusMethodTable map_msg_methods[] = {
 			GDBUS_ARGS({ "transfer", "o" },
 						{ "properties", "a{sv}" }),
 			map_msg_get) },
+	{ GDBUS_METHOD("GetProperties",
+			NULL,
+			GDBUS_ARGS({ "properties", "a{sv}" }),
+			map_msg_get_properties) },
+	{ GDBUS_ASYNC_METHOD("SetProperty",
+			GDBUS_ARGS({ "property", "sv" }), NULL,
+			map_msg_set_property) },
 	{ }
 };
 
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH BlueZ 02/10] gdbus: Remove connection from g_dbus_remove_watch
From: Lucas De Marchi @ 2012-10-02  4:23 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1349114021-19067-2-git-send-email-luiz.dentz@gmail.com>

On Mon, Oct 1, 2012 at 2:53 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> The connection is not really needed since the list of listeners is
> global not per connection, besides it is more convenient this way as
> only the id is needed.
> ---
>  gdbus/gdbus.h | 2 +-
>  gdbus/watch.c | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/gdbus/gdbus.h b/gdbus/gdbus.h
> index 0a8a27c..3bd8986 100644
> --- a/gdbus/gdbus.h
> +++ b/gdbus/gdbus.h
> @@ -217,7 +217,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>                                 const char *interface, const char *member,
>                                 GDBusSignalFunction function, void *user_data,
>                                 GDBusDestroyFunction destroy);
> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint tag);
> +gboolean g_dbus_remove_watch(guint id);
>  void g_dbus_remove_all_watches(DBusConnection *connection);
>
>  #ifdef __cplusplus
> diff --git a/gdbus/watch.c b/gdbus/watch.c
> index 07feb61..00cedae 100644
> --- a/gdbus/watch.c
> +++ b/gdbus/watch.c
> @@ -285,7 +285,7 @@ static void filter_data_free(struct filter_data *data)
>                 g_free(l->data);
>
>         g_slist_free(data->callbacks);
> -       g_dbus_remove_watch(data->connection, data->name_watch);
> +       g_dbus_remove_watch(data->name_watch);
>         g_free(data->name);
>         g_free(data->owner);
>         g_free(data->path);
> @@ -752,7 +752,7 @@ guint g_dbus_add_signal_watch(DBusConnection *connection,
>         return cb->id;
>  }
>
> -gboolean g_dbus_remove_watch(DBusConnection *connection, guint id)
> +gboolean g_dbus_remove_watch(guint id)
>  {
>         struct filter_data *data;
>         struct filter_callback *cb;
> --

This will lead to a broken build which is not nice to bisect. Any
other option besides adding with another name, converting everybody
and then renaming?

The only other option I can think of is adding an ifdef and an option
to build-sys... this would avoid the final renaming.


Lucas De Marchi

^ permalink raw reply

* Re: [PATCH BlueZ 01/10] gdbus: Fix not freeing list node by using g_slist_delete_link
From: Lucas De Marchi @ 2012-10-02  4:10 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1349114021-19067-1-git-send-email-luiz.dentz@gmail.com>

On Mon, Oct 1, 2012 at 2:53 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> g_slist_remove_link does not free the node which can cause leaks so
> replace that with g_slist_delete_link which does free memory properly.
> ---
>  gdbus/watch.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/gdbus/watch.c b/gdbus/watch.c
> index a402ca9..07feb61 100644
> --- a/gdbus/watch.c
> +++ b/gdbus/watch.c
> @@ -574,7 +574,7 @@ static DBusHandlerResult message_filter(DBusConnection *connection,
>                         continue;
>
>                 remove_match(data);
> -               listeners = g_slist_remove_link(listeners, l);
> +               listeners = g_slist_delete_link(listeners, l);
>
>                 filter_data_free(data);
>         }
> --

Ack,

Lucas De Marchi

^ permalink raw reply

* [PATCH BlueZ v8 8/8] core: Suspend scanning before connect on pairing
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

If there is a disconnected bonded device there will be a scanning
procedure active due to the General Connection Establishment Procedure.
This scan have to be suspended before trying to connect to the remote
device for pairing.
---
 src/device.c | 137 +++++++++++++++++++++++++++++++----------------------------
 1 file changed, 72 insertions(+), 65 deletions(-)

diff --git a/src/device.c b/src/device.c
index dccec4f..cf8ade1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2020,6 +2020,36 @@ done:
 	browse_request_free(req);
 }
 
+static void bonding_request_free(struct bonding_req *bonding)
+{
+	struct btd_device *device;
+
+	if (!bonding)
+		return;
+
+	if (bonding->listener_id)
+		g_dbus_remove_watch(btd_get_dbus_connection(),
+							bonding->listener_id);
+
+	if (bonding->msg)
+		dbus_message_unref(bonding->msg);
+
+	device = bonding->device;
+	g_free(bonding);
+
+	if (!device)
+		return;
+
+	device->bonding = NULL;
+
+	if (!device->agent)
+		return;
+
+	agent_cancel(device->agent);
+	agent_free(device->agent);
+	device->agent = NULL;
+}
+
 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
 	struct att_callbacks *attcb = user_data;
@@ -2049,6 +2079,21 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 
 	if (attcb->success)
 		attcb->success(user_data);
+
+	if (device->bonding) {
+		/* this is a LE device during pairing */
+		int err = adapter_create_bonding(device->adapter,
+				&device->bdaddr, device->bdaddr_type,
+				agent_get_io_capability(device->agent));
+		if (err < 0) {
+			DBusMessage *reply = btd_error_failed(
+					device->bonding->msg, strerror(-err));
+			g_dbus_send_message(btd_get_dbus_connection(), reply);
+			bonding_request_cancel(device->bonding);
+			bonding_request_free(device->bonding);
+		}
+	}
+
 done:
 	g_free(attcb);
 }
@@ -2107,6 +2152,23 @@ GIOChannel *device_att_connect(gpointer user_data)
 					BT_IO_OPT_PSM, ATT_PSM,
 					BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
 					BT_IO_OPT_INVALID);
+	} else if (device->bonding) {
+		/* this is a LE device during pairing, using low sec level */
+		io = bt_io_connect(att_connect_cb,
+				attcb, NULL, &gerr,
+				BT_IO_OPT_SOURCE_BDADDR, &sba,
+				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
+				BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
+				BT_IO_OPT_CID, ATT_CID,
+				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+				BT_IO_OPT_INVALID);
+		if (io == NULL) {
+			DBusMessage *reply = btd_error_failed(
+					device->bonding->msg, gerr->message);
+			g_dbus_send_message(btd_get_dbus_connection(), reply);
+			bonding_request_cancel(device->bonding);
+			bonding_request_free(device->bonding);
+		}
 	} else {
 		io = bt_io_connect(att_connect_cb,
 				attcb, NULL, &gerr,
@@ -2429,36 +2491,6 @@ static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
 	}
 }
 
-static void bonding_request_free(struct bonding_req *bonding)
-{
-	struct btd_device *device;
-
-	if (!bonding)
-		return;
-
-	if (bonding->listener_id)
-		g_dbus_remove_watch(btd_get_dbus_connection(),
-							bonding->listener_id);
-
-	if (bonding->msg)
-		dbus_message_unref(bonding->msg);
-
-	device = bonding->device;
-	g_free(bonding);
-
-	if (!device)
-		return;
-
-	device->bonding = NULL;
-
-	if (!device->agent)
-		return;
-
-	agent_cancel(device->agent);
-	agent_free(device->agent);
-	device->agent = NULL;
-}
-
 void device_set_paired(struct btd_device *device, gboolean value)
 {
 	if (device->paired == value)
@@ -2548,41 +2580,6 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 	if (device_is_bonded(device))
 		return btd_error_already_exists(msg);
 
-	if (device_is_le(device)) {
-		struct att_callbacks *attcb;
-		GError *gerr = NULL;
-		bdaddr_t sba;
-
-		adapter_get_address(adapter, &sba);
-
-		attcb = g_new0(struct att_callbacks, 1);
-		attcb->user_data = device;
-
-		device->att_io = bt_io_connect(att_connect_cb,
-				attcb, NULL, &gerr,
-				BT_IO_OPT_SOURCE_BDADDR, &sba,
-				BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
-				BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
-				BT_IO_OPT_CID, ATT_CID,
-				BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
-				BT_IO_OPT_INVALID);
-
-		if (device->att_io == NULL) {
-			DBusMessage *reply = btd_error_failed(msg,
-								gerr->message);
-
-			error("Bonding bt_io_connect(): %s", gerr->message);
-			g_error_free(gerr);
-			g_free(attcb);
-			return reply;
-		}
-	}
-
-	err = adapter_create_bonding(adapter, &device->bdaddr,
-					device->bdaddr_type, capability);
-	if (err < 0)
-		return btd_error_failed(msg, strerror(-err));
-
 	bonding = bonding_request_new(msg, device, agent_path,
 					capability);
 
@@ -2595,6 +2592,16 @@ DBusMessage *device_create_bonding(struct btd_device *device,
 	device->bonding = bonding;
 	bonding->device = device;
 
+	if (device_is_le(device)) {
+		adapter_connect_list_add(adapter, device);
+		return NULL;
+	}
+
+	err = adapter_create_bonding(adapter, &device->bdaddr,
+					device->bdaddr_type, capability);
+	if (err < 0)
+		return btd_error_failed(msg, strerror(-err));
+
 	return NULL;
 }
 
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 7/8] mgmt: Add address type to bonding debug message
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

---
 src/mgmt.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/mgmt.c b/src/mgmt.c
index fc0e5e4..4354dc4 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -2383,7 +2383,8 @@ int mgmt_create_bonding(int index, bdaddr_t *bdaddr, uint8_t addr_type, uint8_t
 	char addr[18];
 
 	ba2str(bdaddr, addr);
-	DBG("hci%d bdaddr %s io_cap 0x%02x", index, addr, io_cap);
+	DBG("hci%d bdaddr %s type %d io_cap 0x%02x",
+					index, addr, addr_type, io_cap);
 
 	memset(buf, 0, sizeof(buf));
 	hdr->opcode = htobs(MGMT_OP_PAIR_DEVICE);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 6/8] core: Re-connect for ECONNRESET or ECONNABORTED
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch keeps scanning and re-connections active if the disconnection
reason is ECONNRESET(Remote Initiated Disconnection).

Re-connection is a behaviour determined by Profiles or by the upper
layer(user actions). For instance, HoG requires re-connection always
active, no matter if the previous disconnection reason was page timeout
or remote initiated disconnection (ECONNRESET). Some devices disconnects
after some idle time, connectable advertises are sent by the peripheral
when commanded by the user(eg: key pressed). Disconnection can be also
triggered by the local host (ECONNABORTED) using command line tools or
Disconnect method in the Device interface.

The peripheral dictates the re-connection controlling the connectable
advertises, BlueZ(central) needs to keep the scanning always active to
able to detect the advertises and trigger the connection.
---
 src/device.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/device.c b/src/device.c
index 558ec5e..dccec4f 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1950,10 +1950,18 @@ static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
 
 	g_slist_foreach(device->attios, attio_disconnected, NULL);
 
-	if (device->auto_connect == FALSE || err != ETIMEDOUT)
+	if (device->auto_connect == FALSE) {
+		DBG("Automatic connection disabled");
 		goto done;
+	}
 
-	adapter_connect_list_add(device_get_adapter(device), device);
+	/*
+	 * Keep scanning/re-connection active if disconnection reason
+	 * is connection timeout, remote user terminated connection or local
+	 * initiated disconnection.
+	 */
+	if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
+		adapter_connect_list_add(device_get_adapter(device), device);
 
 done:
 	attio_cleanup(device);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 5/8] core: Disable unnecessary auto connections
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Alcantara
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

From: Paulo Alcantara <paulo.alcantara@openbossa.org>

BlueZ host disconnects the link when encryption fails. ECONNABORTED
error is returned by the kernel when the connection is terminated by the
local host. This scenario commonly happens when authentication fails due
PIN or Key Missing.
---
 src/device.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/device.c b/src/device.c
index 40d48fe..558ec5e 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2050,6 +2050,9 @@ static void att_error_cb(const GError *gerr, gpointer user_data)
 	struct att_callbacks *attcb = user_data;
 	struct btd_device *device = attcb->user_data;
 
+	if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
+		return;
+
 	if (device->auto_connect == FALSE)
 		return;
 
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 4/8] core: Start LE scanning when a device requests
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch enables the LE scanning when a device requires connection and
there isn't discovery sessions, triggering the General Connection
Establishment Procedure.
---
 src/adapter.c | 70 ++++++++++++++++++++++++++++++++++++++++++++---------------
 1 file changed, 53 insertions(+), 17 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 05bcb79..00f0891 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -133,6 +133,7 @@ struct btd_adapter {
 	GSList *devices;		/* Devices structure pointers */
 	GSList *mode_sessions;		/* Request Mode sessions */
 	GSList *disc_sessions;		/* Discovery sessions */
+	struct session_req *scanning_session;
 	GSList *connect_list;		/* Devices to connect when found */
 	guint discov_id;		/* Discovery timer */
 	gboolean discovering;		/* Discovery active */
@@ -224,17 +225,22 @@ static struct session_req *create_session(struct btd_adapter *adapter,
 					DBusMessage *msg, uint8_t mode,
 					GDBusWatchFunction cb)
 {
-	const char *sender = dbus_message_get_sender(msg);
+	const char *sender;
 	struct session_req *req;
 
 	req = g_new0(struct session_req, 1);
 	req->adapter = adapter;
-	req->msg = dbus_message_ref(msg);
 	req->mode = mode;
 
-	if (cb == NULL)
+	if (msg == NULL)
+		return session_ref(req);
+
+	req->msg = dbus_message_ref(msg);
+
+	if(cb == NULL)
 		return session_ref(req);
 
+	sender = dbus_message_get_sender(msg);
 	req->owner = g_strdup(sender);
 	req->id = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
 							sender, cb, req, NULL);
@@ -445,7 +451,9 @@ static struct session_req *find_session(GSList *list, const char *sender)
 	for (; list; list = list->next) {
 		struct session_req *req = list->data;
 
-		if (g_str_equal(req->owner, sender))
+		/* req->owner may be NULL if the session has been added by the
+		 * daemon itself, so we use g_strcmp0 instead of g_str_equal */
+		if (g_strcmp0(req->owner, sender) == 0)
 			return req;
 	}
 
@@ -520,7 +528,7 @@ static void session_remove(struct session_req *req)
 	struct btd_adapter *adapter = req->adapter;
 
 	/* Ignore set_mode session */
-	if (req->owner == NULL)
+	if (req->owner == NULL && adapter->pending_mode)
 		return;
 
 	DBG("%s session %p with %s deactivated",
@@ -1028,7 +1036,12 @@ static gboolean discovery_cb(gpointer user_data)
 	struct btd_adapter *adapter = user_data;
 
 	adapter->discov_id = 0;
-	mgmt_start_discovery(adapter->dev_id);
+
+	if (adapter->scanning_session &&
+			(g_slist_length(adapter->disc_sessions) == 1))
+		mgmt_start_le_scanning(adapter->dev_id);
+	else
+		mgmt_start_discovery(adapter->dev_id);
 
 	return FALSE;
 }
@@ -2249,6 +2262,8 @@ const char *btd_adapter_get_name(struct btd_adapter *adapter)
 void adapter_connect_list_add(struct btd_adapter *adapter,
 					struct btd_device *device)
 {
+	struct session_req *req;
+
 	if (g_slist_find(adapter->connect_list, device)) {
 		DBG("ignoring already added device %s",
 						device_get_path(device));
@@ -2259,6 +2274,22 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
 						btd_device_ref(device));
 	DBG("%s added to %s's connect_list", device_get_path(device),
 								adapter->name);
+
+	if (!adapter->up)
+		return;
+
+	if (adapter->off_requested)
+		return;
+
+	if (adapter->scanning_session)
+		return;
+
+	if (adapter->disc_sessions == NULL)
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+	req = create_session(adapter, NULL, 0, NULL);
+	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+	adapter->scanning_session = req;
 }
 
 void adapter_connect_list_remove(struct btd_adapter *adapter,
@@ -2278,6 +2309,7 @@ void adapter_connect_list_remove(struct btd_adapter *adapter,
 
 void btd_adapter_start(struct btd_adapter *adapter)
 {
+	struct session_req *req;
 	char address[18];
 	gboolean powered;
 
@@ -2304,8 +2336,15 @@ void btd_adapter_start(struct btd_adapter *adapter)
 
 	info("Adapter %s has been enabled", adapter->path);
 
-	if (g_slist_length(adapter->connect_list) > 0)
-		mgmt_start_le_scanning(adapter->dev_id);
+	if (g_slist_length(adapter->connect_list) == 0 ||
+					adapter->disc_sessions != NULL)
+		return;
+
+	req = create_session(adapter, NULL, 0, NULL);
+	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+	adapter->scanning_session = req;
+
+	adapter->discov_id = g_idle_add(discovery_cb, adapter);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2652,6 +2691,11 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 
 	connect_list_len = g_slist_length(adapter->connect_list);
 
+	if (connect_list_len == 0 && adapter->scanning_session) {
+		session_unref(adapter->scanning_session);
+		adapter->scanning_session = NULL;
+	}
+
 	if (adapter_has_discov_sessions(adapter)) {
 		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
@@ -2660,14 +2704,6 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 				g_slist_length(adapter->disc_sessions));
 		return;
 	}
-
-	if (connect_list_len > 0) {
-		mgmt_start_le_scanning(adapter->dev_id);
-
-		DBG("hci%u restarting scanning connect_list_len %u",
-				adapter->dev_id, connect_list_len);
-		return;
-	}
 }
 
 static void suspend_discovery(struct btd_adapter *adapter)
@@ -2982,7 +3018,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
 
 	if (adapter->waiting_to_connect == 0 &&
 				g_slist_length(adapter->connect_list) > 0)
-		mgmt_start_le_scanning(adapter->dev_id);
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
 	btd_device_unref(device);
 
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 3/8] core: Replace interleaved by LE scanning
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patches replaces the interleaved discovery by LE scanning when LE
re-connection is required.
---
 src/adapter.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 40d0b07..05bcb79 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2305,7 +2305,7 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	info("Adapter %s has been enabled", adapter->path);
 
 	if (g_slist_length(adapter->connect_list) > 0)
-		mgmt_start_discovery(adapter->dev_id);
+		mgmt_start_le_scanning(adapter->dev_id);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2652,14 +2652,22 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 
 	connect_list_len = g_slist_length(adapter->connect_list);
 
-	if (!adapter_has_discov_sessions(adapter) && connect_list_len == 0)
+	if (adapter_has_discov_sessions(adapter)) {
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+		DBG("hci%u restarting discovery: disc_sessions %u",
+				adapter->dev_id,
+				g_slist_length(adapter->disc_sessions));
 		return;
+	}
 
-	DBG("hci%u restarting discovery: disc_sessions %u connect_list_len %u",
-		adapter->dev_id, g_slist_length(adapter->disc_sessions),
-							connect_list_len);
+	if (connect_list_len > 0) {
+		mgmt_start_le_scanning(adapter->dev_id);
 
-	adapter->discov_id = g_idle_add(discovery_cb, adapter);
+		DBG("hci%u restarting scanning connect_list_len %u",
+				adapter->dev_id, connect_list_len);
+		return;
+	}
 }
 
 static void suspend_discovery(struct btd_adapter *adapter)
@@ -2974,7 +2982,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
 
 	if (adapter->waiting_to_connect == 0 &&
 				g_slist_length(adapter->connect_list) > 0)
-		mgmt_start_discovery(adapter->dev_id);
+		mgmt_start_le_scanning(adapter->dev_id);
 
 	btd_device_unref(device);
 
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 2/8] mgmt: Add LE scanning callback
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1349126651-749-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch adds a new callback to allow the adapter to control LE
scanning. The current approach uses the active scanning with default
windows and intervals defined by the core spec without any filtering.
---
 src/mgmt.c | 34 ++++++++++++++++++++++++++++++++++
 src/mgmt.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/src/mgmt.c b/src/mgmt.c
index e368b8a..fc0e5e4 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -2055,6 +2055,40 @@ int mgmt_start_discovery(int index)
 	return 0;
 }
 
+int mgmt_start_le_scanning(int index)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
+	struct controller_info *info = &controllers[index];
+
+	DBG("index %d", index);
+
+	if (!mgmt_low_energy(info->current_settings)) {
+		error("scanning failed: Low Energy not enabled/supported");
+		return -ENOTSUP;
+	}
+
+	info->discov_type = 0;
+	hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
+	hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
+	hdr->len = htobs(sizeof(*cp));
+	hdr->index = htobs(index);
+
+	cp->type = info->discov_type;
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+		int err = -errno;
+		error("failed to write to MGMT socket: %s", strerror(-err));
+		return err;
+	}
+
+	return 0;
+}
+
 int mgmt_stop_discovery(int index)
 {
 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
diff --git a/src/mgmt.h b/src/mgmt.h
index 95245d2..1d25cb0 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -33,6 +33,7 @@ int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor);
 int mgmt_set_fast_connectable(int index, gboolean enable);
 
 int mgmt_start_discovery(int index);
+int mgmt_start_le_scanning(int index);
 int mgmt_stop_discovery(int index);
 
 int mgmt_read_clock(int index, bdaddr_t *bdaddr, int which, int timeout,
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v8 1/8] core: Mutually exclude concurrent connections
From: João Paulo Rechi Vita @ 2012-10-01 21:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita

Since controllers don't support more than one ongoing connection
procedure at the same time, new connection attempts needs to yield if
there is an ongoing connection procedure already.
---
 src/adapter.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 src/device.c  |  6 +++---
 src/device.h  |  2 +-
 3 files changed, 60 insertions(+), 12 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index f11be70..40d0b07 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -136,6 +136,8 @@ struct btd_adapter {
 	GSList *connect_list;		/* Devices to connect when found */
 	guint discov_id;		/* Discovery timer */
 	gboolean discovering;		/* Discovery active */
+	gboolean connecting;		/* Connect active */
+	guint waiting_to_connect;	/* # of devices waiting to connect */
 	gboolean discov_suspended;	/* Discovery suspended */
 	guint auto_timeout_id;		/* Automatic connections timeout */
 	sdp_list_t *services;		/* Services associated to adapter */
@@ -2301,6 +2303,9 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	call_adapter_powered_callbacks(adapter, TRUE);
 
 	info("Adapter %s has been enabled", adapter->path);
+
+	if (g_slist_length(adapter->connect_list) > 0)
+		mgmt_start_discovery(adapter->dev_id);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2627,6 +2632,7 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 						gboolean discovering)
 {
 	const char *path = adapter->path;
+	guint connect_list_len;
 
 	adapter->discovering = discovering;
 
@@ -2641,11 +2647,17 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 	g_slist_free_full(adapter->oor_devices, dev_info_free);
 	adapter->oor_devices = g_slist_copy(adapter->found_devices);
 
-	if (!adapter_has_discov_sessions(adapter) || adapter->discov_suspended)
+	if (adapter->discov_suspended)
+		return;
+
+	connect_list_len = g_slist_length(adapter->connect_list);
+
+	if (!adapter_has_discov_sessions(adapter) && connect_list_len == 0)
 		return;
 
-	DBG("hci%u restarting discovery, disc_sessions %u", adapter->dev_id,
-					g_slist_length(adapter->disc_sessions));
+	DBG("hci%u restarting discovery: disc_sessions %u connect_list_len %u",
+		adapter->dev_id, g_slist_length(adapter->disc_sessions),
+							connect_list_len);
 
 	adapter->discov_id = g_idle_add(discovery_cb, adapter);
 }
@@ -2952,17 +2964,46 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer,
 	return textfile_get(filename, key);
 }
 
+static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+
+	adapter->connecting = FALSE;
+
+	if (adapter->waiting_to_connect == 0 &&
+				g_slist_length(adapter->connect_list) > 0)
+		mgmt_start_discovery(adapter->dev_id);
+
+	btd_device_unref(device);
+
+	return FALSE;
+}
+
 static gboolean connect_pending_cb(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device_get_adapter(device);
+	GIOChannel *io;
 
 	/* in the future we may want to check here if the controller supports
 	 * scanning and connecting at the same time */
 	if (adapter->discovering)
 		return TRUE;
 
-	device_att_connect(device);
+	if (adapter->connecting)
+		return TRUE;
+
+	adapter->connecting = TRUE;
+	adapter->waiting_to_connect--;
+
+	io = device_att_connect(device);
+	g_io_add_watch(io, G_IO_OUT | G_IO_ERR, clean_connecting_state,
+						btd_device_ref(device));
+	g_io_channel_unref(io);
+
+	btd_device_unref(device);
 
 	return FALSE;
 }
@@ -3055,12 +3096,19 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 
 	if (bdaddr_type == BDADDR_LE_PUBLIC ||
 					bdaddr_type == BDADDR_LE_RANDOM) {
+		struct btd_device *device;
+
 		l = g_slist_find_custom(adapter->connect_list, bdaddr,
 					(GCompareFunc) device_bdaddr_cmp);
-		if (l) {
-			g_idle_add(connect_pending_cb, l->data);
-			stop_discovery(adapter);
-		}
+		if (!l)
+			goto done;
+
+		device = l->data;
+		adapter_connect_list_remove(adapter, device);
+
+		g_idle_add(connect_pending_cb,  btd_device_ref(device));
+		stop_discovery(adapter);
+		adapter->waiting_to_connect++;
 	}
 
 done:
diff --git a/src/device.c b/src/device.c
index c41b0c8..40d48fe 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2068,7 +2068,7 @@ static void att_success_cb(gpointer user_data)
 	g_slist_foreach(device->attios, attio_connected, device->attrib);
 }
 
-gboolean device_att_connect(gpointer user_data)
+GIOChannel *device_att_connect(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device->adapter;
@@ -2111,12 +2111,12 @@ gboolean device_att_connect(gpointer user_data)
 		error("ATT bt_io_connect(%s): %s", addr, gerr->message);
 		g_error_free(gerr);
 		g_free(attcb);
-		return FALSE;
+		return NULL;
 	}
 
 	device->att_io = io;
 
-	return FALSE;
+	return g_io_channel_ref(io);
 }
 
 static void att_browse_error_cb(const GError *gerr, gpointer user_data)
diff --git a/src/device.h b/src/device.h
index e82fd0e..462b9a1 100644
--- a/src/device.h
+++ b/src/device.h
@@ -124,4 +124,4 @@ int device_unblock(struct btd_device *device, gboolean silent,
 void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 			uint16_t vendor_id, uint16_t product_id,
 			uint16_t product_ver);
-gboolean device_att_connect(gpointer user_data);
+GIOChannel *device_att_connect(gpointer user_data);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH] client: Update the file offset to the beginning after writing to the file
From: Srinivasa Ragavan @ 2012-10-01 20:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan

When the transfer file is opened in O_RDWR mode, just after the contents are
written to the file, the file offset has to be set to the beginning of the
file. If not subsequent read fails. This patch fixes this.
---
 client/transfer.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/client/transfer.c b/client/transfer.c
index bd5277b..fe9d248 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -425,6 +425,7 @@ struct obc_transfer *obc_transfer_put(const char *type, const char *name,
 					"Writing all contents to file failed");
 			goto fail;
 		}
+		lseek(transfer->fd, 0, SEEK_SET);
 	} else {
 		if (!transfer_open(transfer, O_RDONLY, 0, err))
 			goto fail;
-- 
1.7.10.4


^ permalink raw reply related


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