Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH v2 resend 1/2] Introduced a load_firmware callback to struct hci_dev
From: Marcel Holtmann @ 2012-10-04 13:06 UTC (permalink / raw)
  To: Jesse Sung; +Cc: Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <CAH10aOiwWGseiYEiqk_h=WhNyGGGhpWPhU1TO8E948Ka+xHu9w@mail.gmail.com>

Hi Jesse,

> >> load_firmware will be called at the end of hci_dev_open() if it
> >> is defined.
> >>
> >> Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
> >> ---
> >>  include/net/bluetooth/hci_core.h |    1 +
> >>  net/bluetooth/hci_core.c         |    2 ++
> >>  2 files changed, 3 insertions(+)
> >>
> >> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> >> index 593cd1d..40972a3 100644
> >> --- a/include/net/bluetooth/hci_core.h
> >> +++ b/include/net/bluetooth/hci_core.h
> >> @@ -281,6 +281,7 @@ struct hci_dev {
> >>       int (*send)(struct sk_buff *skb);
> >>       void (*notify)(struct hci_dev *hdev, unsigned int evt);
> >>       int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
> >> +     void (*load_firmware)(struct hci_dev *hdev);
> >>  };
> >>
> >>  struct hci_conn {
> >> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> >> index d4de5db..49be87a 100644
> >> --- a/net/bluetooth/hci_core.c
> >> +++ b/net/bluetooth/hci_core.c
> >> @@ -725,6 +725,8 @@ int hci_dev_open(__u16 dev)
> >>  done:
> >>       hci_req_unlock(hdev);
> >>       hci_dev_put(hdev);
> >> +     if (!ret && hdev->load_firmware)
> >> +             hdev->load_firmware(hdev);
> >>       return ret;
> >>  }
> >>
> >
> > has anybody thought this through actually? Do we need to reload the
> > firmware after every HCI_Reset? Since hci_dev_open() is used at least
> > twice during normal operation. And for every RFKILL or power down/up
> > cycle of the chip.
> >
> > And there is an internal process of hci_dev_open() trigger on
> > registration and others triggered by hciconfig hci0 up. I am pretty much
> > against having to wait for all this firmware loading crap during every
> > bring up of the device. Especially since it always does a trip via
> > request_firmware().
> 
> In the second patch, firmware loading would be done only once per
> power cycle of the chip. Since I think it should be the device driver, not hci,
> who knows when and how to load firmware, the lock is placed in btusb.c.

and how does the driver knows these details? That makes no sense. How
does the driver know it got rebooted?

The hci_dev_open() will start the transport. And as I explained before,
that can happen twice during boot time.

Regards

Marcel



^ permalink raw reply

* [PATCH 4/4] audio: Add check for non-a2dp codec
From: chanyeol.park @ 2012-10-04 13:14 UTC (permalink / raw)
  To: linux-bluetooth

From: Chan-yeol Park <chanyeol.park@samsung.com>

This patch adds checks(vendor ID, vendor specific codec ID) to make sure of
non-a2dp codec selection.
---
 audio/a2dp-codecs.h |    6 +++++
 audio/a2dp.c        |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/audio/a2dp-codecs.h b/audio/a2dp-codecs.h
index 51c796a..e3d2cba 100644
--- a/audio/a2dp-codecs.h
+++ b/audio/a2dp-codecs.h
@@ -26,6 +26,7 @@
 #define A2DP_CODEC_MPEG12		0x01
 #define A2DP_CODEC_MPEG24		0x02
 #define A2DP_CODEC_ATRAC		0x03
+#define A2DP_CODEC_NON_A2DP		0xFF
 
 #define SBC_SAMPLING_FREQ_16000		(1 << 3)
 #define SBC_SAMPLING_FREQ_32000		(1 << 2)
@@ -114,3 +115,8 @@ typedef struct {
 #else
 #error "Unknown byte order"
 #endif
+
+typedef struct {
+	uint8_t vendor_id[4];
+	uint8_t codec_id[2];
+} __attribute__ ((packed)) non_a2dp_vendor_codec_t;
diff --git a/audio/a2dp.c b/audio/a2dp.c
index fd1c494..9b4adb1 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -44,6 +44,7 @@
 #include "sink.h"
 #include "source.h"
 #include "a2dp.h"
+#include "a2dp-codecs.h"
 #include "sdpd.h"
 
 /* The duration that streams without users are allowed to stay in
@@ -1427,11 +1428,66 @@ done:
 	finalize_select(setup);
 }
 
+static gboolean non_a2dp_codec_is_supported(uint8_t *remote_cap,
+				size_t remote_cap_len, struct a2dp_sep *sep)
+{
+	uint8_t *capabilities;
+	size_t	length;
+
+	non_a2dp_vendor_codec_t *local_codec;
+	non_a2dp_vendor_codec_t *remote_codec;
+
+	if (remote_cap_len < sizeof(non_a2dp_vendor_codec_t))
+		return FALSE;
+
+	remote_codec = (non_a2dp_vendor_codec_t *) remote_cap;
+
+	DBG("Remote vendor id %x %x %x %x", remote_codec->vendor_id[0],
+			remote_codec->vendor_id[1], remote_codec->vendor_id[2],
+						remote_codec->vendor_id[3]);
+
+	DBG("Remote vendor codec id %x %x", remote_codec->codec_id[0],
+						remote_codec->codec_id[1]);
+
+	if (sep->endpoint == NULL)
+		return FALSE;
+
+	length = sep->endpoint->get_capabilities(sep,
+				&capabilities, sep->user_data);
+
+	if (length < sizeof(non_a2dp_vendor_codec_t))
+		return FALSE;
+
+	local_codec = (non_a2dp_vendor_codec_t *) capabilities;
+
+	DBG("Registered vendor id %x %x %x %x", local_codec->vendor_id[0],
+			local_codec->vendor_id[1], local_codec->vendor_id[2],
+						local_codec->vendor_id[3]);
+
+	DBG("Registered vendor codec id %x %x", local_codec->codec_id[0],
+						local_codec->codec_id[1]);
+
+	if (memcmp(remote_codec->vendor_id, local_codec->vendor_id,
+					sizeof(local_codec->vendor_id)))
+		return FALSE;
+
+	if (memcmp(remote_codec->codec_id, local_codec->codec_id,
+					sizeof(local_codec->codec_id)))
+		return FALSE;
+
+	DBG("Remote non a2dp codec is supported");
+
+	return TRUE;
+}
+
 static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
 					const char *sender)
 {
 	for (; list; list = list->next) {
 		struct a2dp_sep *sep = list->data;
+		struct avdtp_remote_sep *rsep;
+		struct avdtp_media_codec_capability *rsep_codec;
+		struct avdtp_service_capability *service;
 
 		/* Use sender's endpoint if available */
 		if (sender) {
@@ -1445,7 +1501,17 @@ static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
 				continue;
 		}
 
-		if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
+		rsep = avdtp_find_remote_sep(session, sep->lsep);
+		if (rsep == NULL)
+			continue;
+
+		service = avdtp_get_codec(rsep);
+		rsep_codec = (struct avdtp_media_codec_capability *)
+								service->data;
+
+		if (rsep_codec->media_codec_type == A2DP_CODEC_NON_A2DP &&
+			!non_a2dp_codec_is_supported(rsep_codec->data,
+				service->length - sizeof(*rsep_codec), sep))
 			continue;
 
 		return sep;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 3/4] audio: Remove redundant procedure when a2dp connect
From: chanyeol.park @ 2012-10-04 13:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1349356447-8369-1-git-send-email-chanyeol.park@samsung.com>

From: Chan-yeol Park <chanyeol.park@samsung.com>

This patch fixes the bug that a2dp connection failure is handled like XCASE
when remote host is down.
---
 audio/avdtp.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index 54b3d08..e450ec7 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -2481,7 +2481,8 @@ failed:
 			avdtp_sep_set_state(session, stream->lsep,
 						AVDTP_STATE_IDLE);
 	} else
-		connection_lost(session, EIO);
+		connection_lost(session, err->code == EHOSTDOWN ?
+						EHOSTDOWN : EIO);
 }
 
 static void auth_cb(DBusError *derr, void *user_data)
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 2/4] audio: Remove unused function
From: chanyeol.park @ 2012-10-04 13:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1349356447-8369-1-git-send-email-chanyeol.park@samsung.com>

From: Chan-yeol Park <chanyeol.park@samsung.com>

---
 audio/avdtp.c |   39 ---------------------------------------
 audio/avdtp.h |    2 --
 2 files changed, 41 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index 7db3c02..54b3d08 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -3581,45 +3581,6 @@ int avdtp_set_configuration(struct avdtp *session,
 	return err;
 }
 
-int avdtp_reconfigure(struct avdtp *session, GSList *caps,
-			struct avdtp_stream *stream)
-{
-	struct reconf_req *req;
-	unsigned char *ptr;
-	int caps_len, err;
-	GSList *l;
-	struct avdtp_service_capability *cap;
-
-	if (!g_slist_find(session->streams, stream))
-		return -EINVAL;
-
-	if (stream->lsep->state != AVDTP_STATE_OPEN)
-		return -EINVAL;
-
-	/* Calculate total size of request */
-	for (l = caps, caps_len = 0; l != NULL; l = g_slist_next(l)) {
-		cap = l->data;
-		caps_len += cap->length + 2;
-	}
-
-	req = g_malloc0(sizeof(struct reconf_req) + caps_len);
-
-	req->acp_seid = stream->rseid;
-
-	/* Copy the capabilities into the request */
-	for (l = caps, ptr = req->caps; l != NULL; l = g_slist_next(l)) {
-		cap = l->data;
-		memcpy(ptr, cap, cap->length + 2);
-		ptr += cap->length + 2;
-	}
-
-	err = send_request(session, FALSE, stream, AVDTP_RECONFIGURE, req,
-						sizeof(*req) + caps_len);
-	g_free(req);
-
-	return err;
-}
-
 int avdtp_open(struct avdtp *session, struct avdtp_stream *stream)
 {
 	struct seid_req req;
diff --git a/audio/avdtp.h b/audio/avdtp.h
index e294ded..7b330b9 100644
--- a/audio/avdtp.h
+++ b/audio/avdtp.h
@@ -274,8 +274,6 @@ int avdtp_get_configuration(struct avdtp *session,
 				struct avdtp_stream *stream);
 
 int avdtp_open(struct avdtp *session, struct avdtp_stream *stream);
-int avdtp_reconfigure(struct avdtp *session, GSList *caps,
-			struct avdtp_stream *stream);
 int avdtp_start(struct avdtp *session, struct avdtp_stream *stream);
 int avdtp_suspend(struct avdtp *session, struct avdtp_stream *stream);
 int avdtp_close(struct avdtp *session, struct avdtp_stream *stream,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH 1/4] mgmt: Add string for Passkey Notify Event
From: chanyeol.park @ 2012-10-04 13:14 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1349356447-8369-1-git-send-email-chanyeol.park@samsung.com>

From: Chan-yeol Park <chanyeol.park@samsung.com>

---
 lib/mgmt.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/mgmt.h b/lib/mgmt.h
index 3432f94..6c7e44a 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -522,6 +522,7 @@ static const char *mgmt_ev[] = {
 	"Device Blocked",
 	"Device Unblocked",
 	"Device Unpaired",
+	"Passkey Notify",
 };
 
 static const char *mgmt_status[] = {
-- 
1.7.9.5


^ permalink raw reply related

* Using multiple adapters do not work
From: Sietse Achterop @ 2012-10-04 13:23 UTC (permalink / raw)
  To: linux-bluetooth

  Dear list,

I want to use a number, say 2, of local bluetooth adapters that each communicate with a single
different bluetooth device. The	devices	appear as rfcomm devices.
We can communicate with the devices using minicom.

Binding of the 2 adapters in linux:
   rfcomm -i hci0 bind /dev/rfcomm1 10:00:E8:6C:D8:14 1
   rfcomm -i hci1 bind /dev/rfcomm7 10:00:E8:6C:EC:9E 1
I test with starting minicom for each rfcomm device.
The first minicom invocation works perfectly, but the second (and third ...) gets an error:
  minicom: cannot open /dev/rfcomm7: No such file or directory
or sometimes: Permission denied.
  (the device exists and is said to be readable by ls -l)
This on 2 machines with up to date kernels  2.6.32-43-generic and  3.2.0-31-generic (ubuntu)

Using only a single adapter in the usual way, using rfcomm.conf, it works perfectly.
That is the way in which the pairing has been done before doing the above tests.

I assumed that the above would work.
What am I doing wrong?


Again, if this is the wrong list, please tell me.

  Regards,
    Sietse


PS I am using this approach because of problems as described on this list on
   October 2-nd in:
    Unreliable communication with multiple bluetooth devices and some delay.


^ permalink raw reply

* [PATCH 1/4] client: Update the file offset to the beginning after writing to the file
From: Srinivasa Ragavan @ 2012-10-04 13:30 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 fbcafc8..cac3884 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -426,6 +426,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

* [PATCH 2/4] client: Add Message.SetProperty and Message.GetProperties implementation.
From: Srinivasa Ragavan @ 2012-10-04 13:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349357403-16354-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

---
 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

* [PATCH 3/4] client-doc: Add documentation for Message.SetProperty and Message.GetProperties
From: Srinivasa Ragavan @ 2012-10-04 13:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349357403-16354-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

---
 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 4/4] test: Update map-client to include Message.SetProperty and Message.GetProperties
From: Srinivasa Ragavan @ 2012-10-04 13:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349357403-16354-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

---
 test/map-client |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/test/map-client b/test/map-client
index 2075844..54e3900 100755
--- a/test/map-client
+++ b/test/map-client
@@ -41,6 +41,16 @@ def parse_options():
 			help="List messages in supplied CWD subdir")
 	parser.add_option("-g", "--get", action="store", dest="get_msg",
 			help="Get message contents")
+	parser.add_option("--get-properties", action="store", dest="get_msg_properties",
+			help="Get message properties")
+	parser.add_option("--mark-read", action="store", dest="mark_msg_read",
+			help="Marks the messages as read")
+	parser.add_option("--mark-unread", action="store", dest="mark_msg_unread",
+			help="Marks the messages as unread")
+	parser.add_option("--mark-deleted", action="store", dest="mark_msg_deleted",
+			help="Deletes the message from the folder")
+	parser.add_option("--mark-undeleted", action="store", dest="mark_msg_undeleted",
+			help="Undeletes the message")
 
 	return parser.parse_args()
 
@@ -120,6 +130,22 @@ class MapClient:
 		msg.Get("", True, reply_handler=self.create_transfer_reply,
 						error_handler=self.error)
 
+	def get_message_properties(self, handle):
+		self.map.ListMessages("", dict())
+		path = self.path + "/message" + handle
+		obj = bus.get_object("org.bluez.obex.client", path)
+		msg = dbus.Interface(obj, "org.bluez.obex.Message")
+		ret = msg.GetProperties()
+		print pformat(unwrap(ret))
+
+	def set_message_property(self, handle, prop, flag):
+		self.map.ListMessages("", dict())
+		path = self.path + "/message" + handle
+		obj = bus.get_object("org.bluez.obex.client", path)
+		msg = dbus.Interface(obj, "org.bluez.obex.Message")
+		msg.SetProperty (prop, flag);
+
+
 if  __name__ == '__main__':
 
 	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
@@ -155,4 +181,20 @@ if  __name__ == '__main__':
 	if options.get_msg is not None:
 		map_client.get_message(options.get_msg)
 
+	if options.get_msg_properties is not None:
+		map_client.get_message_properties(options.get_msg_properties)
+
+	if options.mark_msg_read is not None:
+		map_client.set_message_property(options.mark_msg_read, "Read", True)
+
+	if options.mark_msg_unread is not None:
+		map_client.set_message_property(options.mark_msg_unread, "Read", False)
+
+	if options.mark_msg_deleted is not None:
+		map_client.set_message_property(options.mark_msg_deleted, "Deleted", True)
+
+	if options.mark_msg_undeleted is not None:
+		map_client.set_message_property(options.mark_msg_undeleted, "Deleted", False)
+
+
 	mainloop.run()
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH v2 resend 1/2] Introduced a load_firmware callback to struct hci_dev
From: Jesse Sung @ 2012-10-04 13:39 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Gustavo Padovan, Johan Hedberg, linux-bluetooth
In-Reply-To: <1349355967.27233.35.camel@aeonflux>

Hi Marcel,

>> >> load_firmware will be called at the end of hci_dev_open() if it
>> >> is defined.
>> >>
>> >> Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com>
>> >> ---
>> >>  include/net/bluetooth/hci_core.h |    1 +
>> >>  net/bluetooth/hci_core.c         |    2 ++
>> >>  2 files changed, 3 insertions(+)
>> >>
>> >> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> >> index 593cd1d..40972a3 100644
>> >> --- a/include/net/bluetooth/hci_core.h
>> >> +++ b/include/net/bluetooth/hci_core.h
>> >> @@ -281,6 +281,7 @@ struct hci_dev {
>> >>       int (*send)(struct sk_buff *skb);
>> >>       void (*notify)(struct hci_dev *hdev, unsigned int evt);
>> >>       int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg);
>> >> +     void (*load_firmware)(struct hci_dev *hdev);
>> >>  };
>> >>
>> >>  struct hci_conn {
>> >> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> >> index d4de5db..49be87a 100644
>> >> --- a/net/bluetooth/hci_core.c
>> >> +++ b/net/bluetooth/hci_core.c
>> >> @@ -725,6 +725,8 @@ int hci_dev_open(__u16 dev)
>> >>  done:
>> >>       hci_req_unlock(hdev);
>> >>       hci_dev_put(hdev);
>> >> +     if (!ret && hdev->load_firmware)
>> >> +             hdev->load_firmware(hdev);
>> >>       return ret;
>> >>  }
>> >>
>> >
>> > has anybody thought this through actually? Do we need to reload the
>> > firmware after every HCI_Reset? Since hci_dev_open() is used at least
>> > twice during normal operation. And for every RFKILL or power down/up
>> > cycle of the chip.
>> >
>> > And there is an internal process of hci_dev_open() trigger on
>> > registration and others triggered by hciconfig hci0 up. I am pretty much
>> > against having to wait for all this firmware loading crap during every
>> > bring up of the device. Especially since it always does a trip via
>> > request_firmware().
>>
>> In the second patch, firmware loading would be done only once per
>> power cycle of the chip. Since I think it should be the device driver, not hci,
>> who knows when and how to load firmware, the lock is placed in btusb.c.
>
> and how does the driver knows these details? That makes no sense. How
> does the driver know it got rebooted?
>
> The hci_dev_open() will start the transport. And as I explained before,
> that can happen twice during boot time.

Please take a look at the second part of this patchset, which is in patch 2/2.
Loading firmware is needed when the chip is rebooted, and a reboot would trigger
a probe in btusb. So btusb can know a firmware loading is needed whenever
a new patchram device is probed. And the load_firmware callback in
btusb would do
test_and_set_bit to ensure that the loading process would only be done once.

Thanks,
Jesse

^ permalink raw reply

* Re: [PATCH 4/4] audio: Add check for non-a2dp codec
From: Luiz Augusto von Dentz @ 2012-10-04 14:02 UTC (permalink / raw)
  To: chanyeol.park; +Cc: linux-bluetooth
In-Reply-To: <1349356447-8369-1-git-send-email-chanyeol.park@samsung.com>

Hi Chanyel,

On Thu, Oct 4, 2012 at 4:14 PM,  <chanyeol.park@samsung.com> wrote:
> From: Chan-yeol Park <chanyeol.park@samsung.com>
>
> This patch adds checks(vendor ID, vendor specific codec ID) to make sure of
> non-a2dp codec selection.
> ---
>  audio/a2dp-codecs.h |    6 +++++
>  audio/a2dp.c        |   68 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  2 files changed, 73 insertions(+), 1 deletion(-)
>
> diff --git a/audio/a2dp-codecs.h b/audio/a2dp-codecs.h
> index 51c796a..e3d2cba 100644
> --- a/audio/a2dp-codecs.h
> +++ b/audio/a2dp-codecs.h
> @@ -26,6 +26,7 @@
>  #define A2DP_CODEC_MPEG12              0x01
>  #define A2DP_CODEC_MPEG24              0x02
>  #define A2DP_CODEC_ATRAC               0x03
> +#define A2DP_CODEC_NON_A2DP            0xFF

I prefer A2DP_CODEC_VENDOR

>  #define SBC_SAMPLING_FREQ_16000                (1 << 3)
>  #define SBC_SAMPLING_FREQ_32000                (1 << 2)
> @@ -114,3 +115,8 @@ typedef struct {
>  #else
>  #error "Unknown byte order"
>  #endif
> +
> +typedef struct {
> +       uint8_t vendor_id[4];
> +       uint8_t codec_id[2];
> +} __attribute__ ((packed)) non_a2dp_vendor_codec_t;

We normally don't typedef this type of structs, besides
a2dp_vendor_codec should be enough so this should be named struct
a2dp_vendor_codec.

> diff --git a/audio/a2dp.c b/audio/a2dp.c
> index fd1c494..9b4adb1 100644
> --- a/audio/a2dp.c
> +++ b/audio/a2dp.c
> @@ -44,6 +44,7 @@
>  #include "sink.h"
>  #include "source.h"
>  #include "a2dp.h"
> +#include "a2dp-codecs.h"
>  #include "sdpd.h"
>
>  /* The duration that streams without users are allowed to stay in
> @@ -1427,11 +1428,66 @@ done:
>         finalize_select(setup);
>  }
>
> +static gboolean non_a2dp_codec_is_supported(uint8_t *remote_cap,
> +                               size_t remote_cap_len, struct a2dp_sep *sep)

Use vendor_codec_is_supported as function name.

> +{
> +       uint8_t *capabilities;
> +       size_t  length;
> +
> +       non_a2dp_vendor_codec_t *local_codec;
> +       non_a2dp_vendor_codec_t *remote_codec;
> +
> +       if (remote_cap_len < sizeof(non_a2dp_vendor_codec_t))
> +               return FALSE;
> +
> +       remote_codec = (non_a2dp_vendor_codec_t *) remote_cap;
> +
> +       DBG("Remote vendor id %x %x %x %x", remote_codec->vendor_id[0],
> +                       remote_codec->vendor_id[1], remote_codec->vendor_id[2],
> +                                               remote_codec->vendor_id[3]);
> +
> +       DBG("Remote vendor codec id %x %x", remote_codec->codec_id[0],
> +                                               remote_codec->codec_id[1]);

You can probably join this 2 DBGs in one, also fix the printing format
for uint8_t it should be %02x and if is hex add 0x e.g. Remote vendor
0x%02x%02x%02x%02x codec 0x%02x%02x

> +       if (sep->endpoint == NULL)
> +               return FALSE;
> +
> +       length = sep->endpoint->get_capabilities(sep,
> +                               &capabilities, sep->user_data);
> +
> +       if (length < sizeof(non_a2dp_vendor_codec_t))
> +               return FALSE;
> +
> +       local_codec = (non_a2dp_vendor_codec_t *) capabilities;
> +
> +       DBG("Registered vendor id %x %x %x %x", local_codec->vendor_id[0],
> +                       local_codec->vendor_id[1], local_codec->vendor_id[2],
> +                                               local_codec->vendor_id[3]);
> +
> +       DBG("Registered vendor codec id %x %x", local_codec->codec_id[0],
> +                                               local_codec->codec_id[1]);

Same as above.

> +       if (memcmp(remote_codec->vendor_id, local_codec->vendor_id,
> +                                       sizeof(local_codec->vendor_id)))
> +               return FALSE;
> +
> +       if (memcmp(remote_codec->codec_id, local_codec->codec_id,
> +                                       sizeof(local_codec->codec_id)))
> +               return FALSE;
> +
> +       DBG("Remote non a2dp codec is supported");

Not sure if this DBG would be of much use since latter you select it,
so it is implicit whether it is supported or not.

> +       return TRUE;
> +}
> +
>  static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
>                                         const char *sender)
>  {
>         for (; list; list = list->next) {
>                 struct a2dp_sep *sep = list->data;
> +               struct avdtp_remote_sep *rsep;
> +               struct avdtp_media_codec_capability *rsep_codec;
> +               struct avdtp_service_capability *service;
>
>                 /* Use sender's endpoint if available */
>                 if (sender) {
> @@ -1445,7 +1501,17 @@ static struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
>                                 continue;
>                 }
>
> -               if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
> +               rsep = avdtp_find_remote_sep(session, sep->lsep);
> +               if (rsep == NULL)
> +                       continue;
> +
> +               service = avdtp_get_codec(rsep);
> +               rsep_codec = (struct avdtp_media_codec_capability *)
> +                                                               service->data;
> +
> +               if (rsep_codec->media_codec_type == A2DP_CODEC_NON_A2DP &&
> +                       !non_a2dp_codec_is_supported(rsep_codec->data,
> +                               service->length - sizeof(*rsep_codec), sep))
>                         continue;
>
>                 return sep;
> --
> 1.7.9.5

The rest looks okay.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH 3/4] audio: Remove redundant procedure when a2dp connect
From: Luiz Augusto von Dentz @ 2012-10-04 14:11 UTC (permalink / raw)
  To: chanyeol.park; +Cc: linux-bluetooth
In-Reply-To: <1349356447-8369-2-git-send-email-chanyeol.park@samsung.com>

Hi Chanyeol,

On Thu, Oct 4, 2012 at 4:14 PM,  <chanyeol.park@samsung.com> wrote:
> From: Chan-yeol Park <chanyeol.park@samsung.com>
>
> This patch fixes the bug that a2dp connection failure is handled like XCASE
> when remote host is down.
> ---
>  audio/avdtp.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/audio/avdtp.c b/audio/avdtp.c
> index 54b3d08..e450ec7 100644
> --- a/audio/avdtp.c
> +++ b/audio/avdtp.c
> @@ -2481,7 +2481,8 @@ failed:
>                         avdtp_sep_set_state(session, stream->lsep,
>                                                 AVDTP_STATE_IDLE);
>         } else
> -               connection_lost(session, EIO);
> +               connection_lost(session, err->code == EHOSTDOWN ?
> +                                               EHOSTDOWN : EIO);
>  }

This rely on err being set which may not always be the case since
there are other places calling goto failed.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ v4 00/15] Properties + ObjectManager
From: Johan Hedberg @ 2012-10-04 14:17 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349335599-12443-1-git-send-email-lucas.de.marchi@gmail.com>

Hi Lucas,

On Thu, Oct 04, 2012, Lucas De Marchi wrote:
> Here is a rebased version of the patches. Most notable change is on patch
> implementing the Set() method after feedback from Marcel. It doesn't cover the
> concerns from Luiz about checking privileges per-property since I think this
> could be added in a separate patch. As far as I could see the only user is
> MediaTransport interface. The most obvious way would be to add another hook in
> GDBusPropertyTable in order to check the privileges. Suggestions?
> 
> First 2 patches could be applied nonetheles. Get and GetAll are well tested,
> both now and in the previous version of this patch set. Set() is still a
> bit raw - the users implementing it are very big (adapter, device) so
> they are not converted yet (previous patch doesn't apply anymore and there's a
> change in the API that requires them to be rewritten).
> 
> 
> Lucas De Marchi (10):
>   gdbus: Move typedefs up
>   gdbus: Use macros to add annotations
>   gdbus: Add skeleton of DBus.Properties interface
>   gdbus: Implement DBus.Properties.Get method
>   gdbus: Implement DBus.Properties.GetAll method
>   gdbus: Implement DBus.Properties.Set method
>   gdbus: Add properties into Introspectable interface
>   gdbus: Implement PropertiesChanged signal
>   Use DBus.Properties on Control interface
>   Use DBus.Properties on Manager interface
> 
> Luiz Augusto von Dentz (5):
>   gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
>   gdbus: Group interface changes to reduce the amount of signals
>     emitted
>   gdbus: Only export ObjectManager interface on root path
>   gdbus: Integrates ObjectManager with Properties interface
>   gdbus: Simplify code for appending properties
> 
>  audio/control.c |  57 ++--
>  gdbus/gdbus.h   |  74 +++--
>  gdbus/object.c  | 867 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  src/manager.c   |  81 ++----
>  4 files changed, 897 insertions(+), 182 deletions(-)

This initial set has been applied. Now let's get testing it and fix any
pending issues that are found. Also please remember send the adapter and
device conversions when you've got them ready so that we get them stress
tested at the UPF next week.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ v4 14/15] Use DBus.Properties on Control interface
From: Johan Hedberg @ 2012-10-04 14:22 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Lucas De Marchi, linux-bluetooth, Lucas De Marchi
In-Reply-To: <CAJdJm_PZbDinMxO4En=3XMzjnNVTWpGQ9-pOV7VyfLJOJjY9Qg@mail.gmail.com>

Hi Lizardo,

On Thu, Oct 04, 2012, Anderson Lizardo wrote:
> On Thu, Oct 4, 2012 at 3:26 AM, Lucas De Marchi
> <lucas.demarchi@profusion.mobi> wrote:
> > @@ -77,13 +76,11 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
> >                 if (old_state != AVCTP_STATE_CONNECTED)
> >                         break;
> >
> > -               value = FALSE;
> >                 g_dbus_emit_signal(conn, dev->path,
> >                                         AUDIO_CONTROL_INTERFACE,
> >                                         "Disconnected", DBUS_TYPE_INVALID);
> > -               emit_property_changed(dev->path,
> > -                                       AUDIO_CONTROL_INTERFACE, "Connected",
> > -                                       DBUS_TYPE_BOOLEAN, &value);
> > +               g_dbus_emit_property_changed(conn, dev->path,
> > +                                       AUDIO_CONTROL_INTERFACE, "Connected");
> 
> Out of curiosity, do you know why this API has Connected/Disconnected
> signals besides the PropertyChanged("Connected", ...) ?

I think those should have been marked as deprecated in 4.x and removed
for BlueZ 5.

Johan

^ permalink raw reply

* [PATCH 1/4] client: Update the file offset to the beginning after writing to the file
From: Srinivasa Ragavan @ 2012-10-04 14:22 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 fbcafc8..cac3884 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -426,6 +426,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

* [PATCH 2/4] client: Add Message.SetProperty and Message.GetProperties implementation.
From: Srinivasa Ragavan @ 2012-10-04 14:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349360560-21631-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

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

diff --git a/client/map.c b/client/map.c
index e78cd68..fc2d874 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,183 @@ 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 +602,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

* [PATCH 3/4] client-doc: Add documentation for Message.SetProperty and Message.GetProperties
From: Srinivasa Ragavan @ 2012-10-04 14:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349360560-21631-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

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

diff --git a/doc/client-api.txt b/doc/client-api.txt
index 25fd3e4..e680427 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 4/4] test: Update map-client to include Message.SetProperty and Message.GetProperties
From: Srinivasa Ragavan @ 2012-10-04 14:22 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Srinivasa Ragavan
In-Reply-To: <1349360560-21631-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

---
 test/map-client |   42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/test/map-client b/test/map-client
index 2075844..e8c42e3 100755
--- a/test/map-client
+++ b/test/map-client
@@ -41,6 +41,16 @@ def parse_options():
 			help="List messages in supplied CWD subdir")
 	parser.add_option("-g", "--get", action="store", dest="get_msg",
 			help="Get message contents")
+	parser.add_option("--get-properties", action="store", dest="get_msg_properties",
+			help="Get message properties")
+	parser.add_option("--mark-read", action="store", dest="mark_msg_read",
+			help="Marks the messages as read")
+	parser.add_option("--mark-unread", action="store", dest="mark_msg_unread",
+			help="Marks the messages as unread")
+	parser.add_option("--mark-deleted", action="store", dest="mark_msg_deleted",
+			help="Deletes the message from the folder")
+	parser.add_option("--mark-undeleted", action="store", dest="mark_msg_undeleted",
+			help="Undeletes the message")
 
 	return parser.parse_args()
 
@@ -120,6 +130,22 @@ class MapClient:
 		msg.Get("", True, reply_handler=self.create_transfer_reply,
 						error_handler=self.error)
 
+	def get_message_properties(self, handle):
+		self.map.ListMessages("", dict())
+		path = self.path + "/message" + handle
+		obj = bus.get_object("org.bluez.obex.client", path)
+		msg = dbus.Interface(obj, "org.bluez.obex.Message")
+		ret = msg.GetProperties()
+		print pformat(unwrap(ret))
+
+	def set_message_property(self, handle, prop, flag):
+		self.map.ListMessages("", dict())
+		path = self.path + "/message" + handle
+		obj = bus.get_object("org.bluez.obex.client", path)
+		msg = dbus.Interface(obj, "org.bluez.obex.Message")
+		msg.SetProperty (prop, flag);
+
+
 if  __name__ == '__main__':
 
 	dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
@@ -155,4 +181,20 @@ if  __name__ == '__main__':
 	if options.get_msg is not None:
 		map_client.get_message(options.get_msg)
 
+	if options.get_msg_properties is not None:
+		map_client.get_message_properties(options.get_msg_properties)
+
+	if options.mark_msg_read is not None:
+		map_client.set_message_property(options.mark_msg_read, "Read", True)
+
+	if options.mark_msg_unread is not None:
+		map_client.set_message_property(options.mark_msg_unread, "Read", False)
+
+	if options.mark_msg_deleted is not None:
+		map_client.set_message_property(options.mark_msg_deleted, "Deleted", True)
+
+	if options.mark_msg_undeleted is not None:
+		map_client.set_message_property(options.mark_msg_undeleted, "Deleted", False)
+
+
 	mainloop.run()
-- 
1.7.10.4


^ permalink raw reply related

* Re: [PATCH BlueZ v4 00/15] Properties + ObjectManager
From: Lucas De Marchi @ 2012-10-04 14:29 UTC (permalink / raw)
  To: Lucas De Marchi, linux-bluetooth, Lucas De Marchi
In-Reply-To: <20121004141722.GA4173@x220>

On Thu, Oct 4, 2012 at 11:17 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Lucas,
>
> On Thu, Oct 04, 2012, Lucas De Marchi wrote:
>> Here is a rebased version of the patches. Most notable change is on patch
>> implementing the Set() method after feedback from Marcel. It doesn't cover the
>> concerns from Luiz about checking privileges per-property since I think this
>> could be added in a separate patch. As far as I could see the only user is
>> MediaTransport interface. The most obvious way would be to add another hook in
>> GDBusPropertyTable in order to check the privileges. Suggestions?
>>
>> First 2 patches could be applied nonetheles. Get and GetAll are well tested,
>> both now and in the previous version of this patch set. Set() is still a
>> bit raw - the users implementing it are very big (adapter, device) so
>> they are not converted yet (previous patch doesn't apply anymore and there's a
>> change in the API that requires them to be rewritten).
>>
>>
>> Lucas De Marchi (10):
>>   gdbus: Move typedefs up
>>   gdbus: Use macros to add annotations
>>   gdbus: Add skeleton of DBus.Properties interface
>>   gdbus: Implement DBus.Properties.Get method
>>   gdbus: Implement DBus.Properties.GetAll method
>>   gdbus: Implement DBus.Properties.Set method
>>   gdbus: Add properties into Introspectable interface
>>   gdbus: Implement PropertiesChanged signal
>>   Use DBus.Properties on Control interface
>>   Use DBus.Properties on Manager interface
>>
>> Luiz Augusto von Dentz (5):
>>   gdbus: Add support for org.freedesktop.DBus.ObjectManager interface
>>   gdbus: Group interface changes to reduce the amount of signals
>>     emitted
>>   gdbus: Only export ObjectManager interface on root path
>>   gdbus: Integrates ObjectManager with Properties interface
>>   gdbus: Simplify code for appending properties
>>
>>  audio/control.c |  57 ++--
>>  gdbus/gdbus.h   |  74 +++--
>>  gdbus/object.c  | 867 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
>>  src/manager.c   |  81 ++----
>>  4 files changed, 897 insertions(+), 182 deletions(-)
>
> This initial set has been applied. Now let's get testing it and fix any
> pending issues that are found. Also please remember send the adapter and
> device conversions when you've got them ready so that we get them stress
> tested at the UPF next week.

Thanks... I'll submit them soonish.

Should we change the interface names to include a version, too? Or
change the bus name to something like bluez5?

"It is also a good idea to include the major version of the interface
in the name, and increment it if incompatible changes are made; this
way, a single object can implement several versions of an interface in
parallel, if necessary." from
http://dbus.freedesktop.org/doc/dbus-specification.html


Lucas De Marchi

^ permalink raw reply

* Re: [PATCH 1/4] mgmt: Add string for Passkey Notify Event
From: Johan Hedberg @ 2012-10-04 15:05 UTC (permalink / raw)
  To: chanyeol.park; +Cc: linux-bluetooth
In-Reply-To: <1349356447-8369-4-git-send-email-chanyeol.park@samsung.com>

Hi Chan-yeol,

On Thu, Oct 04, 2012, chanyeol.park@samsung.com wrote:
> From: Chan-yeol Park <chanyeol.park@samsung.com>
> 
> ---
>  lib/mgmt.h |    1 +
>  1 file changed, 1 insertion(+)

Patches 1/4 and 2/4 have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ] core: Fix walking the list while removing elements
From: Lucas De Marchi @ 2012-10-04 17:07 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

If we are walking a GSList and remove the element we are pointing to,
the next iteration g_slist_next() will access previously freed
memory.
---
 src/device.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/device.c b/src/device.c
index c659164..0339bcf 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1469,7 +1469,7 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)
 	char srcaddr[18], dstaddr[18];
 	bdaddr_t src;
 	sdp_list_t *records;
-	GSList *l;
+	GSList *l, *next;
 
 	adapter_get_address(adapter, &src);
 	ba2str(&src, srcaddr);
@@ -1498,10 +1498,11 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)
 	if (records)
 		sdp_list_free(records, (sdp_free_func_t) sdp_record_free);
 
-	for (l = device->profiles; l != NULL; l = g_slist_next(l)) {
+	for (l = device->profiles; l != NULL; l = next) {
 		struct btd_profile *profile = l->data;
 		GSList *probe_uuids;
 
+		next = l->next;
 		probe_uuids = device_match_profile(device, profile,
 								device->uuids);
 		if (probe_uuids != NULL) {
-- 
1.7.12.2


^ permalink raw reply related

* Re: [PATCH BlueZ] core: Fix walking the list while removing elements
From: Bastien Nocera @ 2012-10-04 17:16 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349370439-6345-1-git-send-email-lucas.demarchi@profusion.mobi>

On Thu, 2012-10-04 at 14:07 -0300, Lucas De Marchi wrote:
> -       for (l = device->profiles; l != NULL; l = g_slist_next(l)) {
> +       for (l = device->profiles; l != NULL; l = next) {

+       for (l = device->profiles; l != NULL; l = l->next) {

>                 struct btd_profile *profile = l->data;
>                 GSList *probe_uuids;
>  
> +               next = l->next; 

Remove.


^ permalink raw reply

* Re: [PATCH BlueZ] core: Fix walking the list while removing elements
From: Lucas De Marchi @ 2012-10-04 17:21 UTC (permalink / raw)
  To: Bastien Nocera; +Cc: Lucas De Marchi, linux-bluetooth
In-Reply-To: <1349370976.8332.21.camel@novo.hadess.net>

On Thu, Oct 4, 2012 at 2:16 PM, Bastien Nocera <hadess@hadess.net> wrote:
> On Thu, 2012-10-04 at 14:07 -0300, Lucas De Marchi wrote:
>> -       for (l = device->profiles; l != NULL; l = g_slist_next(l)) {
>> +       for (l = device->profiles; l != NULL; l = next) {
>
> +       for (l = device->profiles; l != NULL; l = l->next) {

nops. you can't access "l" if it was deleted from the list

>
>>                 struct btd_profile *profile = l->data;
>>                 GSList *probe_uuids;
>>
>> +               next = l->next;
>
> Remove.

nops.


See previous patch.



Lucas De Marchi

^ permalink raw reply

* Re: [PATCH BlueZ] core: Fix walking the list while removing elements
From: Bastien Nocera @ 2012-10-04 17:30 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: Lucas De Marchi, linux-bluetooth
In-Reply-To: <CAKi4VALw4TTh0z3Yppov71Anf4g1sNPnRYaQPouaaiYcEb79_g@mail.gmail.com>

On Thu, 2012-10-04 at 14:21 -0300, Lucas De Marchi wrote:
> On Thu, Oct 4, 2012 at 2:16 PM, Bastien Nocera <hadess@hadess.net> wrote:
> > On Thu, 2012-10-04 at 14:07 -0300, Lucas De Marchi wrote:
> >> -       for (l = device->profiles; l != NULL; l = g_slist_next(l)) {
> >> +       for (l = device->profiles; l != NULL; l = next) {
> >
> > +       for (l = device->profiles; l != NULL; l = l->next) {
> 
> nops. you can't access "l" if it was deleted from the list

Right.


^ permalink raw reply


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