* Re: [PATCH BlueZ] android/avrcp-lib: Use cpu_to_* and *_to_cpu
From: Luiz Augusto von Dentz @ 2014-10-20 12:05 UTC (permalink / raw)
To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1413536909-13049-1-git-send-email-luiz.dentz@gmail.com>
Hi,
On Fri, Oct 17, 2014 at 12:08 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> For PDU which have packed struct it is not necessary to use put_*
> and get_* since it should be already aligned.
> ---
> android/avrcp-lib.c | 136 ++++++++++++++++++++++++++--------------------------
> 1 file changed, 68 insertions(+), 68 deletions(-)
>
> diff --git a/android/avrcp-lib.c b/android/avrcp-lib.c
> index 2c3d2e9..cff37a8 100644
> --- a/android/avrcp-lib.c
> +++ b/android/avrcp-lib.c
> @@ -929,7 +929,7 @@ static bool parse_attributes(uint32_t *params, uint16_t params_len,
>
> for (i = 0; i < number && params_len >= sizeof(*attrs); i++,
> params_len -= sizeof(*attrs)) {
> - attrs[i] = get_be32(¶ms[i]);
> + attrs[i] = be32_to_cpu(params[i]);
>
> if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
> attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
> @@ -988,7 +988,7 @@ static ssize_t register_notification(struct avrcp *session, uint8_t transaction,
>
> req = (void *) params;
>
> - interval = get_be32(&req->interval);
> + interval = be32_to_cpu(req->interval);
>
> return player->ind->register_notification(session, transaction,
> req->event, interval,
> @@ -1037,7 +1037,7 @@ static ssize_t set_addressed(struct avrcp *session, uint8_t transaction,
>
> req = (void *) params;
>
> - id = get_be16(&req->id);
> + id = be16_to_cpu(req->id);
>
> return player->ind->set_addressed(session, transaction, id,
> player->user_data);
> @@ -1271,7 +1271,7 @@ static ssize_t set_browsed(struct avrcp *session, uint8_t transaction,
>
> req = (void *) params;
>
> - id = get_be16(&req->id);
> + id = be16_to_cpu(req->id);
>
> return player->ind->set_browsed(session, transaction, id,
> player->user_data);
> @@ -1301,16 +1301,16 @@ static ssize_t get_folder_items(struct avrcp *session, uint8_t transaction,
> if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
> return -EBADRQC;
>
> - start = get_be32(&req->start);
> - end = get_be32(&req->end);
> + start = be32_to_cpu(req->start);
> + end = be32_to_cpu(req->end);
>
> if (start > end)
> return -ERANGE;
>
> - number = get_be16(&req->number);
> + number = be16_to_cpu(req->number);
>
> for (i = 0; i < number; i++) {
> - attrs[i] = get_be32(&req->attrs[i]);
> + attrs[i] = be32_to_cpu(req->attrs[i]);
>
> if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
> attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
> @@ -1341,8 +1341,8 @@ static ssize_t change_path(struct avrcp *session, uint8_t transaction,
>
> req = (void *) params;
>
> - counter = get_be16(&req->counter);
> - uid = get_be64(&req->uid);
> + counter = be16_to_cpu(req->counter);
> + uid = be64_to_cpu(req->uid);
>
> return player->ind->change_path(session, transaction, counter,
> req->direction, uid, player->user_data);
> @@ -1372,11 +1372,11 @@ static ssize_t get_item_attributes(struct avrcp *session, uint8_t transaction,
> if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
> return -EBADRQC;
>
> - uid = get_be64(&req->uid);
> - counter = get_be16(&req->counter);
> + uid = be64_to_cpu(req->uid);
> + counter = be16_to_cpu(req->counter);
>
> for (i = 0; i < req->number; i++) {
> - attrs[i] = get_be32(&req->attrs[i]);
> + attrs[i] = be32_to_cpu(req->attrs[i]);
>
> if (attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
> attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST)
> @@ -1411,8 +1411,8 @@ static ssize_t play_item(struct avrcp *session, uint8_t transaction,
> if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
> return -EBADRQC;
>
> - uid = get_be64(¶ms[1]);
> - counter = get_be16(¶ms[9]);
> + uid = be64_to_cpu(req->uid);
> + counter = be16_to_cpu(req->counter);
>
> return player->ind->play_item(session, transaction, req->scope, uid,
> counter, player->user_data);
> @@ -1438,7 +1438,7 @@ static ssize_t search(struct avrcp *session, uint8_t transaction,
>
> req = (void *) params;
>
> - len = get_be16(&req->len);
> + len = be16_to_cpu(req->len);
> if (!len)
> return -EINVAL;
>
> @@ -1474,8 +1474,8 @@ static ssize_t add_to_now_playing(struct avrcp *session, uint8_t transaction,
> if (req->scope > AVRCP_MEDIA_NOW_PLAYING)
> return -EBADRQC;
>
> - uid = get_be64(&req->uid);
> - counter = get_be16(&req->counter);
> + uid = be64_to_cpu(req->uid);
> + counter = be16_to_cpu(req->counter);
>
> return player->ind->add_to_now_playing(session, transaction, req->scope,
> uid, counter,
> @@ -1859,7 +1859,7 @@ int avrcp_register_notification(struct avrcp *session, uint8_t event,
> return -EINVAL;
>
> req.event = event;
> - put_be32(interval, &req.interval);
> + req.interval = cpu_to_be32(interval);
>
> iov.iov_base = &req;
> iov.iov_len = sizeof(req);
> @@ -2345,8 +2345,8 @@ static gboolean get_play_status_rsp(struct avctp *conn,
>
> rsp = (void *) pdu->params;
>
> - duration = get_be32(&rsp->duration);
> - position = get_be32(&rsp->position);
> + duration = be32_to_cpu(rsp->duration);
> + position = be32_to_cpu(rsp->position);
> status = rsp->status;
> err = 0;
>
> @@ -2432,9 +2432,9 @@ static int parse_attribute_list(uint8_t *params, uint16_t params_len,
> for (i = 0; i < number && params_len >= sizeof(*item); i++) {
> item = (void *) params;
>
> - item->attr = get_be32(&item->attr);
> - item->charset = get_be16(&item->charset);
> - item->len = get_be16(&item->len);
> + item->attr = be32_to_cpu(item->attr);
> + item->charset = be16_to_cpu(item->charset);
> + item->len = be16_to_cpu(item->len);
>
> params_len -= sizeof(*item);
> params += sizeof(*item);
> @@ -2584,7 +2584,7 @@ int avrcp_set_addressed_player(struct avrcp *session, uint16_t player_id)
> struct iovec iov;
> struct set_addressed_req req;
>
> - put_be16(player_id, &req.id);
> + req.id = cpu_to_be16(player_id);
>
> iov.iov_base = &req;
> iov.iov_len = sizeof(req);
> @@ -2658,8 +2658,8 @@ static gboolean set_browsed_rsp(struct avctp *conn, uint8_t *operands,
>
> rsp = (void *) pdu->params;
>
> - counter = get_be16(&rsp->counter);
> - items = get_be32(&rsp->items);
> + counter = be16_to_cpu(rsp->counter);
> + items = be32_to_cpu(rsp->items);
>
> path = parse_folder_list(rsp->data, pdu->params_len - sizeof(*rsp),
> rsp->depth);
> @@ -2676,12 +2676,12 @@ done:
> int avrcp_set_browsed_player(struct avrcp *session, uint16_t player_id)
> {
> struct iovec iov;
> - uint8_t pdu[2];
> + struct set_browsed_req req;
>
> - put_be16(player_id, pdu);
> + req.id = cpu_to_be16(player_id);
>
> - iov.iov_base = pdu;
> - iov.iov_len = sizeof(pdu);
> + iov.iov_base = &req;
> + iov.iov_len = sizeof(req);
>
> return avrcp_send_browsing_req(session, AVRCP_SET_BROWSED_PLAYER,
> &iov, 1, set_browsed_rsp, session);
> @@ -2721,8 +2721,8 @@ static gboolean get_folder_items_rsp(struct avctp *conn,
>
> rsp = (void *) pdu->params;
>
> - counter = get_be16(&rsp->counter);
> - number = get_be16(&rsp->number);
> + counter = be16_to_cpu(rsp->counter);
> + number = be16_to_cpu(rsp->number);
> params = rsp->data;
>
> /* FIXME: Add proper parsing for each item type */
> @@ -2744,8 +2744,8 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
> int i;
>
> req.scope = scope;
> - put_be32(start, &req.start);
> - put_be32(end, &req.end);
> + req.start = cpu_to_be32(start);
> + req.end = cpu_to_be32(end);
> req.number = number;
>
> iov[0].iov_base = &req;
> @@ -2757,7 +2757,7 @@ int avrcp_get_folder_items(struct avrcp *session, uint8_t scope,
> session);
>
> for (i = 0; i < number; i++)
> - put_be32(attrs[i], &attrs[i]);
> + attrs[i] = cpu_to_be32(attrs[i]);
>
> iov[1].iov_base = attrs;
> iov[1].iov_len = number * sizeof(*attrs);
> @@ -2798,7 +2798,7 @@ static gboolean change_path_rsp(struct avctp *conn, uint8_t *operands,
>
> rsp = (void *) pdu->params;
>
> - items = get_be32(&rsp->items);
> + items = be32_to_cpu(rsp->items);
>
> done:
> player->cfm->change_path(session, err, items, player->user_data);
> @@ -2812,9 +2812,9 @@ int avrcp_change_path(struct avrcp *session, uint8_t direction, uint64_t uid,
> struct iovec iov;
> struct change_path_req req;
>
> - put_be16(counter, &req.counter);
> + req.counter = cpu_to_be16(counter);
> req.direction = direction;
> - put_be64(uid, &req.uid);
> + req.uid = cpu_to_be64(uid);
>
> iov.iov_base = &req;
> iov.iov_len = sizeof(req);
> @@ -2867,8 +2867,8 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
> int i;
>
> req.scope = scope;
> - put_be64(uid, &req.uid);
> - put_be16(counter, &req.counter);
> + req.uid = cpu_to_be64(uid);
> + req.counter = cpu_to_be16(counter);
> req.number = number;
>
> iov[0].iov_base = &req;
> @@ -2887,7 +2887,7 @@ int avrcp_get_item_attributes(struct avrcp *session, uint8_t scope,
> if (attrs[i] > AVRCP_MEDIA_ATTRIBUTE_LAST ||
> attrs[i] == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL)
> return -EINVAL;
> - put_be32(attrs[i], &attrs[i]);
> + attrs[i] = cpu_to_be32(attrs[i]);
> }
>
> iov[1].iov_base = attrs;
> @@ -2935,8 +2935,8 @@ int avrcp_play_item(struct avrcp *session, uint8_t scope, uint64_t uid,
> return -EINVAL;
>
> req.scope = scope;
> - put_be64(uid, &req.uid);
> - put_be16(counter, &req.counter);
> + req.uid = cpu_to_be64(uid);
> + req.counter = cpu_to_be16(counter);
>
> iov.iov_base = &req;
> iov.iov_len = sizeof(req);
> @@ -2978,8 +2978,8 @@ static gboolean search_rsp(struct avctp *conn, uint8_t *operands,
>
> rsp = (void *) pdu->params;
>
> - counter = get_be16(&rsp->counter);
> - items = get_be32(&rsp->items);
> + counter = be16_to_cpu(rsp->counter);
> + items = be32_to_cpu(rsp->items);
>
> err = 0;
>
> @@ -3000,8 +3000,8 @@ int avrcp_search(struct avrcp *session, const char *string)
>
> len = strnlen(string, UINT8_MAX);
>
> - put_be16(AVRCP_CHARSET_UTF8, &req.charset);
> - put_be16(len, &req.len);
> + req.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
> + req.len = cpu_to_be16(len);
>
> iov[0].iov_base = &req;
> iov[0].iov_len = sizeof(req);
> @@ -3050,8 +3050,8 @@ int avrcp_add_to_now_playing(struct avrcp *session, uint8_t scope, uint64_t uid,
> return -EINVAL;
>
> req.scope = scope;
> - put_be64(uid, &req.uid);
> - put_be16(counter, &req.counter);
> + req.uid = cpu_to_be64(uid);
> + req.counter = cpu_to_be16(counter);
>
> iov.iov_base = &req;
> iov.iov_len = sizeof(req);
> @@ -3136,7 +3136,7 @@ int avrcp_get_player_attribute_text_rsp(struct avrcp *session,
> len = strlen(text[i]);
>
> val[i].attr = attrs[i];
> - put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
> + val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
> val[i].len = len;
>
> iov[i + 1].iov_base = &val[i];
> @@ -3177,8 +3177,8 @@ int avrcp_get_play_status_rsp(struct avrcp *session, uint8_t transaction,
> struct iovec iov;
> struct get_play_status_rsp rsp;
>
> - put_be32(duration, &rsp.duration);
> - put_be32(position, &rsp.position);
> + rsp.duration = cpu_to_be32(duration);
> + rsp.position = cpu_to_be32(position);
> rsp.status = status;
>
> iov.iov_base = &rsp;
> @@ -3210,7 +3210,7 @@ int avrcp_get_player_values_text_rsp(struct avrcp *session,
> len = strlen(text[i]);
>
> val[i].attr = values[i];
> - put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
> + val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
> val[i].len = len;
>
> iov[i + 1].iov_base = &val[i];
> @@ -3314,8 +3314,8 @@ int avrcp_register_notification_rsp(struct avrcp *session, uint8_t transaction,
> return -EINVAL;
>
> player = data;
> - put_be16(player[0], &player[0]);
> - put_be16(player[1], &player[1]);
> + player[0] = cpu_to_be16(player[0]);
> + player[1] = cpu_to_be16(player[1]);
>
> break;
> case AVRCP_EVENT_SETTINGS_CHANGED:
> @@ -3398,9 +3398,9 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
> AVRCP_SET_BROWSED_PLAYER, status);
>
> rsp.status = status;
> - put_be16(counter, &rsp.counter);
> - put_be32(items, &rsp.items);
> - put_be16(AVRCP_CHARSET_UTF8, &rsp.charset);
> + rsp.counter = cpu_to_be16(counter);
> + rsp.items = cpu_to_be32(items);
> + rsp.charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
> rsp.depth = depth;
>
> iov[0].iov_base = &rsp;
> @@ -3420,7 +3420,7 @@ int avrcp_set_browsed_player_rsp(struct avrcp *session, uint8_t transaction,
> iov[i * 2 + 2].iov_base = (void *) folders[i];
> iov[i * 2 + 2].iov_len = len[i];
>
> - put_be16(len[i], &len[i]);
> + len[i] = cpu_to_be16(len[i]);
>
> iov[i * 2 + 1].iov_base = &len[i];
> iov[i * 2 + 1].iov_len = sizeof(len[i]);
> @@ -3446,8 +3446,8 @@ int avrcp_get_folder_items_rsp(struct avrcp *session, uint8_t transaction,
> AVRCP_GET_FOLDER_ITEMS, status);
>
> rsp.status = status;
> - put_be16(counter, &rsp.counter);
> - put_be16(number, &rsp.number);
> + rsp.counter = cpu_to_be16(counter);
> + rsp.number = cpu_to_be16(number);
>
> iov[0].iov_base = &rsp;
> iov[0].iov_len = sizeof(rsp);
> @@ -3478,7 +3478,7 @@ int avrcp_change_path_rsp(struct avrcp *session, uint8_t transaction,
> status);
>
> rsp.status = status;
> - put_be32(items, &rsp.items);
> + rsp.items = cpu_to_be32(items);
>
> iov.iov_base = &rsp;
> iov.iov_len = sizeof(rsp);
> @@ -3503,9 +3503,9 @@ static bool pack_attribute_list(struct iovec *iov, uint8_t number,
> if (text[i])
> len = strlen(text[i]);
>
> - put_be32(attrs[i], &val[i].attr);
> - put_be16(AVRCP_CHARSET_UTF8, &val[i].charset);
> - put_be16(len, &val[i].len);
> + val[i].attr = cpu_to_be32(attrs[i]);
> + val[i].charset = cpu_to_be16(AVRCP_CHARSET_UTF8);
> + val[i].len = cpu_to_be16(len);
>
> iov[i].iov_base = &val[i];
> iov[i].iov_len = sizeof(val[i]);
> @@ -3563,8 +3563,8 @@ int avrcp_search_rsp(struct avrcp *session, uint8_t transaction, uint8_t status,
> status);
>
> rsp.status = status;
> - put_be16(counter, &rsp.counter);
> - put_be32(items, &rsp.items);
> + rsp.counter = cpu_to_be16(counter);
> + rsp.items = cpu_to_be32(items);
>
> iov.iov_base = &rsp;
> iov.iov_len = sizeof(rsp);
> --
> 1.9.3
Pushed.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH v2 0/5] Introduce shared/gatt-server.
From: Luiz Augusto von Dentz @ 2014-10-20 12:09 UTC (permalink / raw)
To: Arman Uguray; +Cc: BlueZ development
In-Reply-To: <CAHrH25SLjFr4iaKy8WJAfrz0oZpqENpkBJesNd4_xa_br+E6cA@mail.gmail.com>
Hi Arman,
On Thu, Oct 16, 2014 at 9:49 PM, Arman Uguray <armansito@chromium.org> wrote:
> On Mon, Oct 13, 2014 at 2:09 PM, Arman Uguray <armansito@chromium.org> wrote:
>> *v2:
>> - Split read_by_grp_type_cb into two functions by moving the response PDU
>> encoding loop into a helper function.
>>
>> *v1:
>> - Make gatt-db external to gatt-server, as initially discussed.
>> - Also implement Read By Group Type request.
>>
>> Arman Uguray (5):
>> shared/att: Drop the connection if a request is received while one is
>> pending.
>> shared/att: Respond with ERROR_REQUEST_NOT_SUPPORTED for unhandled
>> requests.
>> shared/gatt-server: Introduce shared/gatt-server.
>> shared/gatt-server: Support Exchange MTU request.
>> shared/gatt-server: Support Read By Group Type request.
>>
>> Makefile.am | 1 +
>> src/shared/att.c | 124 +++++++++++------
>> src/shared/gatt-server.c | 356 +++++++++++++++++++++++++++++++++++++++++++++++
>> src/shared/gatt-server.h | 40 ++++++
>> 4 files changed, 481 insertions(+), 40 deletions(-)
>> create mode 100644 src/shared/gatt-server.c
>> create mode 100644 src/shared/gatt-server.h
>>
>> --
>> 2.1.0.rc2.206.gedb03e5
>>
>
> ping. Luiz made comments on one of the patches but I believe they've
> been addressed.
> --
This is now pushed, note that Ive made a couple changes both in the
code and the commit message, please next time follow 50/72 format for
the commit message (check HACKING if you don't know what Im talking
about).
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH 1/6] bnep: Avoid double error print for bnep_connadd()
From: Luiz Augusto von Dentz @ 2014-10-20 12:37 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1413550450-16577-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Fri, Oct 17, 2014 at 3:54 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> This avoids double printing the same error with bnep connection add
> ioctl.
> ---
> profiles/network/bnep.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
> index 136709d..035beb1 100644
> --- a/profiles/network/bnep.c
> +++ b/profiles/network/bnep.c
> @@ -316,10 +316,8 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
> setsockopt(sk, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
>
> sk = g_io_channel_unix_get_fd(session->io);
> - if (bnep_connadd(sk, session->src, session->iface)) {
> - error("bnep conn could not be added");
> + if (bnep_connadd(sk, session->src, session->iface) < 0)
> goto failed;
> - }
>
> if (bnep_if_up(session->iface)) {
> error("could not up %s", session->iface);
> @@ -556,14 +554,14 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
> int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
> const bdaddr_t *addr)
> {
> + int err;
> +
> if (!bridge || !iface || !addr)
> return -EINVAL;
>
> - if (bnep_connadd(sk, dst, iface) < 0) {
> - error("Can't add connection to the bridge %s: %s(%d)",
> - bridge, strerror(errno), errno);
> - return -errno;
> - }
> + err = bnep_connadd(sk, dst, iface);
> + if (err < 0)
> + return err;
>
> if (bnep_add_to_bridge(iface, bridge) < 0) {
> error("Can't add %s to the bridge %s: %s(%d)",
> --
> 1.9.1
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH] hciattach: Add sleep|nosleep keyword
From: Luiz Augusto von Dentz @ 2014-10-20 12:38 UTC (permalink / raw)
To: Andrei Emeltchenko; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1413550093-16448-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>
Hi Andrei,
On Fri, Oct 17, 2014 at 3:48 PM, Andrei Emeltchenko
<Andrei.Emeltchenko.news@gmail.com> wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
>
> ---
> tools/hciattach.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/tools/hciattach.c b/tools/hciattach.c
> index d8ef7e7..808bbac 100644
> --- a/tools/hciattach.c
> +++ b/tools/hciattach.c
> @@ -1276,7 +1276,9 @@ static void usage(void)
> {
> printf("hciattach - HCI UART driver initialization utility\n");
> printf("Usage:\n");
> - printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed] <tty> <type | id> [speed] [flow|noflow] [bdaddr]\n");
> + printf("\thciattach [-n] [-p] [-b] [-r] [-t timeout] [-s initial_speed]"
> + " <tty> <type | id> [speed] [flow|noflow]"
> + " [sleep|nosleep] [bdaddr]\n");
> printf("\thciattach -l\n");
> }
>
> --
> 1.9.1
Applied, thanks.
--
Luiz Augusto von Dentz
^ permalink raw reply
* how to set PSCAN mode in .conf?
From: Jeff Chua @ 2014-10-20 12:56 UTC (permalink / raw)
To: linux-bluetooth
latest bluez doesn't read hcid.conf, so how can I enable "pscan" in
the conf file?
I know "hciconfig hci0 pscan" works, but I would still like to set
that via the .conf file.
Thanks,
Jeff
^ permalink raw reply
* RE: Query regarding creation of multiple MAS Instance ID:
From: Gowtham Anandha Babu @ 2014-10-20 12:59 UTC (permalink / raw)
To: 'Luiz Augusto von Dentz'
Cc: linux-bluetooth, 'Bharat Panda',
'Dmitry Kasatkin', cpgs
In-Reply-To: <CABBYNZKPex1xe0yJQkfOopBWj3QRiwF4cQd=1Jxj=xOLV69QJw@mail.gmail.com>
Hi Luiz,
> -----Original Message-----
> From: Luiz Augusto von Dentz [mailto:luiz.dentz@gmail.com]
> Sent: Friday, October 17, 2014 5:11 PM
> To: Gowtham Anandha Babu
> Cc: linux-bluetooth@vger.kernel.org; Bharat Panda; Dmitry Kasatkin;
> cpgs@samsung.com
> Subject: Re: Query regarding creation of multiple MAS Instance ID:
>
> Hi,
>
> On Thu, Oct 16, 2014 at 4:18 PM, Gowtham Anandha Babu
> <gowtham.ab@samsung.com> wrote:
> > Hi All,
> >
> > I am working on obexd MAP profile. Is it possible to create multiple
> > MAS Instance in bluez?
> > Because right now bluez has only one MAS Instance support (only one
> > MAS_UUID), which is advertised to MCE based on the XML format
> followed
> > in src/profile.c.
> > When I add one more record to MAS_RECORD XML format by changing the
> > value as 0x01, I am not able see two instances getting loaded.
> > <attribute id=\"0x0315\"> \
> > <uint8 value=\"0x01\"/> \
> > </attribute> \
>
> How you are doing that? You should be able to call
> ProfileManager1.RegisterProfile if that is what you doing and it is not working
> perhaps we have a bug somewhere. Two very important things you need to
> check:
>
> 1. It cannot use the same path for both instances 2. Each instance needs a
> different channel
>
> So if you are register via XML you need to take care of those details, but
> perhaps you are using the default record by just providing the UUID, that
> probably will not work because apparently we have hardcoded the channel,
> if that is the case we should probably add a check if there is another instance
> already register and use a different channel/psm.
>
> > Do we need to create one more UUID like OBEX_MAS1_UUID and
> > OBEX_MAS2_UUID to support multiple mas instances?
> > Or what could be the possible solutions?
>
> Each instance has to have the service class set to MAS UUID, otherwise no
> one will be able to discover it.
>
> >
> > Regards.
> > Gowtham Anandha Babu
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe
> > linux-bluetooth" in the body of a message to majordomo@vger.kernel.org
> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
>
> --
> Luiz Augusto von Dentz
Here is what I did exactly after your comments,
1) Based on the flag, I managed the two MAS Instances in bluetooth.c
diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c
index cf326cc..3a0c022 100644
--- a/obexd/plugins/bluetooth.c
+++ b/obexd/plugins/bluetooth.c
@@ -50,6 +50,8 @@
#define BT_RX_MTU 32767
#define BT_TX_MTU 32767
+gboolean MAS = FALSE;
+
struct bluetooth_profile {
struct obex_server *server;
struct obex_service_driver *driver;
@@ -269,7 +271,20 @@ static int register_profile(struct bluetooth_profile *profile)
char *xml;
int ret = 0;
- profile->path = g_strconcat("/org/bluez/obex/", profile->uuid, NULL);
+
+ if(!g_ascii_strcasecmp(profile->uuid, OBEX_MAS_UUID))
+ if(!MAS) {
+ profile->path = g_strconcat("/org/bluez/obex/MAS1/",
+ profile->uuid, NULL);
+ MAS = TRUE;
+ }
+ else
+ profile->path = g_strconcat("/org/bluez/obex/MAS2/",
+ profile->uuid, NULL);
+ else
+ profile->path = g_strconcat("/org/bluez/obex/", profile->uuid, NULL);
+
g_strdelimit(profile->path, "-", '_');
if (!g_dbus_register_interface(connection, profile->path,
@@ -290,6 +305,10 @@ static int register_profile(struct bluetooth_profile *profile)
dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
&profile->path);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
&profile->uuid);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -346,7 +365,9 @@ static const char *service2uuid(uint16_t service)
return "00005005-0000-1000-8000-0002ee000001";
case OBEX_SYNCEVOLUTION:
return "00000002-0000-1000-8000-0002ee000002";
- case OBEX_MAS:
+ case OBEX_MAS1:
+ return OBEX_MAS_UUID;
+ case OBEX_MAS2:
return OBEX_MAS_UUID;
case OBEX_MNS:
return OBEX_MNS_UUID;
2) Created one more MAS Instance in mas.c
diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
index fb97fe3..fb482e2 100644
--- a/obexd/plugins/mas.c
+++ b/obexd/plugins/mas.c
@@ -728,9 +728,9 @@ static int any_close(void *obj)
return 0;
}
-static struct obex_service_driver mas = {
- .name = "Message Access server",
- .service = OBEX_MAS,
+static struct obex_service_driver mas1 = {
+ .name = "Message Access server 1",
+ .service = OBEX_MAS1,
.target = MAS_TARGET,
.target_size = TARGET_SIZE,
.connect = mas_connect,
@@ -740,6 +740,18 @@ static struct obex_service_driver mas = {
.disconnect = mas_disconnect,
};
+static struct obex_service_driver mas2 = {
+ .name = "Message Access server 2",
+ .service = OBEX_MAS2,
+ .target = MAS_TARGET,
+ .target_size = TARGET_SIZE,
+ .connect = mas_connect,
+ .get = mas_get,
+ .put = mas_put,
+ .setpath = mas_setpath,
+ .disconnect = mas_disconnect,
+};
+
static struct obex_mime_type_driver mime_map = {
.target = MAS_TARGET,
.target_size = TARGET_SIZE,
@@ -838,10 +850,14 @@ static int mas_init(void)
goto failed;
}
- err = obex_service_driver_register(&mas);
+ err = obex_service_driver_register(&mas1);
if (err < 0)
goto failed;
+ err = obex_service_driver_register(&mas2);
+ if(err < 0)
+ goto failed;
+
return 0;
failed:
@@ -857,7 +873,8 @@ static void mas_exit(void)
{
int i;
- obex_service_driver_unregister(&mas);
+ obex_service_driver_unregister(&mas1);
+ obex_service_driver_unregister(&mas2);
for (i = 0; map_drivers[i] != NULL; ++i)
obex_mime_type_driver_unregister(map_drivers[i]);
@@ -865,4 +882,5 @@ static void mas_exit(void)
messages_exit();
}
-OBEX_PLUGIN_DEFINE(mas, mas_init, mas_exit)
+OBEX_PLUGIN_DEFINE(mas1, mas_init, mas_exit)
+OBEX_PLUGIN_DEFINE(mas2, mas_init, mas_exit)
diff --git a/obexd/src/obexd.h b/obexd/src/obexd.h
index 42c3c4d..59de70e 100644
--- a/obexd/src/obexd.h
+++ b/obexd/src/obexd.h
@@ -28,7 +28,8 @@
#define OBEX_IRMC (1 << 5)
#define OBEX_PCSUITE (1 << 6)
#define OBEX_SYNCEVOLUTION (1 << 7)
-#define OBEX_MAS (1 << 8)
+#define OBEX_MAS1 (1 << 8)
+#define OBEX_MAS2 (1 << 10)
#define OBEX_MNS (1 << 9)
gboolean plugin_init(const char *pattern, const char *exclude);
3) Assigned different channel and path for both instances
4)Added one more SDP record (XML) in profile.c
diff --git a/src/profile.c b/src/profile.c
index 7aca3be..ab5b5c2 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -62,7 +62,8 @@
#define HFP_AG_DEFAULT_CHANNEL 13
#define SYNC_DEFAULT_CHANNEL 14
#define PBAP_DEFAULT_CHANNEL 15
-#define MAS_DEFAULT_CHANNEL 16
+#define MAS1_DEFAULT_CHANNEL 16
+#define MAS2_DEFAULT_CHANNEL 18
#define MNS_DEFAULT_CHANNEL 17
#define BTD_PROFILE_PSM_AUTO -1
@@ -395,7 +396,7 @@
</attribute> \
</record>"
-#define MAS_RECORD \
+#define MAS_RECORD1 \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
<record> \
<attribute id=\"0x0001\"> \
@@ -441,6 +442,52 @@
</attribute> \
</record>"
+#define MAS_RECORD2 \
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
+ <record> \
+ <attribute id=\"0x0001\"> \
+ <sequence> \
+ <uuid value=\"0x1132\"/> \
+ </sequence> \
+ </attribute> \
+ <attribute id=\"0x0004\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x0100\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0003\"/> \
+ <uint8 value=\"0x%02x\"/> \
+ </sequence> \
+ <sequence> \
+ <uuid value=\"0x0008\"/> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ <attribute id=\"0x0005\"> \
+ <sequence> \
+ <uuid value=\"0x1002\" /> \
+ </sequence> \
+ </attribute> \
+ <attribute id=\"0x0009\"> \
+ <sequence> \
+ <sequence> \
+ <uuid value=\"0x1134\"/> \
+ <uint16 value=\"0x%04x\" /> \
+ </sequence> \
+ </sequence> \
+ </attribute> \
+ <attribute id=\"0x0100\"> \
+ <text value=\"%s\"/> \
+ </attribute> \
+ <attribute id=\"0x0315\"> \
+ <uint8 value=\"0x01\"/> \
+ </attribute> \
+ <attribute id=\"0x0316\"> \
+ <uint8 value=\"0x0F\"/> \
+ </attribute> \
+ </record>"
+
#define MNS_RECORD \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
<record> \
@@ -562,6 +609,8 @@
struct ext_io;
+gboolean MAS = FALSE;
+
struct ext_profile {
struct btd_profile p;
@@ -1734,10 +1787,17 @@ static char *get_pse_record(struct ext_profile *ext, struct ext_io *l2cap,
ext->name);
}
-static char *get_mas_record(struct ext_profile *ext, struct ext_io *l2cap,
+static char *get_mas_record1(struct ext_profile *ext, struct ext_io *l2cap,
+ struct ext_io *rfcomm)
+{
+ return g_strdup_printf(MAS_RECORD1, rfcomm->chan, ext->version,
+ ext->name);
+}
+
+static char *get_mas_record2(struct ext_profile *ext, struct ext_io *l2cap,
struct ext_io *rfcomm)
{
- return g_strdup_printf(MAS_RECORD, rfcomm->chan, ext->version,
+ return g_strdup_printf(MAS_RECORD2, rfcomm->chan, ext->version,
ext->name);
}
@@ -1949,10 +2009,17 @@ static struct default_settings {
.version = 0x0101,
}, {
.uuid = OBEX_MAS_UUID,
- .name = "Message Access",
- .channel = MAS_DEFAULT_CHANNEL,
+ .name = "Message Access 1",
+ .channel = MAS1_DEFAULT_CHANNEL,
+ .authorize = true,
+ .get_record = get_mas_record1,
+ .version = 0x0100
+ }, {
+ .uuid = OBEX_MAS_UUID,
+ .name = "Message Access 2",
+ .channel = MAS2_DEFAULT_CHANNEL,
.authorize = true,
- .get_record = get_mas_record,
+ .get_record = get_mas_record2,
.version = 0x0100
}, {
.uuid = OBEX_MNS_UUID,
@@ -1981,8 +2048,21 @@ static void ext_set_defaults(struct ext_profile *ext)
struct default_settings *settings = &defaults[i];
const char *remote_uuid;
+ DBG("%s == %s",ext->uuid, settings->uuid);
+
if (strcasecmp(ext->uuid, settings->uuid) != 0)
continue;
+
+ if(!strcasecmp(ext->uuid, OBEX_MAS_UUID))
+ if(MAS) {
+ MAS = 0;
+ continue;
+ }
+
+ if(!strcasecmp(ext->uuid, OBEX_MAS_UUID))
+ MAS = TRUE;
+
+ DBG("MATCHED %s == %s MAS = %d",ext->uuid, settings->uuid, MAS);
if (settings->remote_uuid)
remote_uuid = settings->remote_uuid;
@@ -2022,6 +2102,8 @@ static void ext_set_defaults(struct ext_profile *ext)
if (settings->name)
ext->name = g_strdup(settings->name);
+
+ return;
}
}
After this changes I am able to load the two MAS Instances successfully. Is it fine? What do you think?
Regards,
Gowtham Anandha Babu
^ permalink raw reply related
* RE: [PATCH ] audio/avrcp: Add Support for PLAYBACK_POS_CHANGED_EVENT
From: Bharat Bhusan Panda @ 2014-10-20 13:11 UTC (permalink / raw)
To: 'Luiz Augusto von Dentz'; +Cc: linux-bluetooth, cpgs
In-Reply-To: <CABBYNZLTMaJQ2hO_LoCgZQz-EwCQ9LuD9mDgK-w54XDc3wNCvw@mail.gmail.com>
Hi Luiz,
> > As per AVRCP 1.5 spec, 6.7.2, page 57.
> >
> > EVENT_PLAYBACK_POS_CHANGED shall be notified in the following
> conditions:
> >
> > 1. TG has reached the registered playback Interval time.
> > 2. Changed PLAY STATUS.
> > 3. Changed Current Track.
> > 4. Reached end or beginning of track.
> > ---
> > profiles/audio/avrcp.c | 49
> > +++++++++++++++++++++++++++++++++++++++++++++++++
> > profiles/audio/avrcp.h | 1 +
> > profiles/audio/media.c | 23 ++++++++++++++---------
> > 3 files changed, 64 insertions(+), 9 deletions(-)
> >
> > diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index
> > 5c3c4f9..77f1dcb 100644
> > --- a/profiles/audio/avrcp.c
> > +++ b/profiles/audio/avrcp.c
> > @@ -198,6 +198,7 @@ struct pending_list_items { struct avrcp_player {
> > struct avrcp_server *server;
> > GSList *sessions;
> > + uint16_t pos_timer;
> > uint16_t id;
> > uint8_t scope;
> > uint64_t uid;
> > @@ -627,6 +628,7 @@ void avrcp_player_event(struct avrcp_player
> *player, uint8_t id,
> > uint8_t buf[AVRCP_HEADER_LENGTH + 9];
> > struct avrcp_header *pdu = (void *) buf;
> > uint16_t size;
> > + uint32_t *pos = NULL;
> > GSList *l;
> > int attr;
> > int val;
> > @@ -673,6 +675,18 @@ void avrcp_player_event(struct avrcp_player
> *player, uint8_t id,
> > pdu->params[size++] = attr;
> > pdu->params[size++] = val;
> > break;
> > + case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
> > + size = 5;
> > + pos = (uint32_t *) data;
> > +
> > + be32toh(*pos);
> > + memcpy(&pdu->params[1], pos, sizeof(uint32_t));
> > +
> > + if (player->pos_timer > 0) {
> > + g_source_remove(player->pos_timer);
> > + player->pos_timer = 0;
> > + }
> > + break;
>
> Note that it is meant to be playback interval, so if it is not playing we should
> not send anything.
Yes, will change it accordingly.
>
> > default:
> > error("Unknown event %u", id);
> > return;
> > @@ -1429,6 +1443,19 @@ static bool handle_passthrough(struct avctp
> *conn, uint8_t op, bool pressed,
> > return handler->func(session); }
> >
> > +static gboolean interval_timeout(gpointer user_data) {
> > + uint32_t pos;
> > + struct avrcp_player *mp = user_data;
> > +
> > + pos = player_get_position(mp);
> > + mp->pos_timer = 0;
> > + avrcp_player_event(mp, AVRCP_EVENT_PLAYBACK_POS_CHANGED,
> > + &pos);
> > +
> > + return FALSE;
> > +}
> > +
> > static uint8_t avrcp_handle_register_notification(struct avrcp *session,
> > struct avrcp_header *pdu,
> > uint8_t transaction)
> > @@ -1436,6 +1463,8 @@ static uint8_t
> avrcp_handle_register_notification(struct avrcp *session,
> > struct avrcp_player *player = target_get_player(session);
> > struct btd_device *dev = session->dev;
> > uint16_t len = ntohs(pdu->params_len);
> > + uint32_t interval;
> > + uint32_t pos;
> > uint64_t uid;
> > GList *settings;
> >
> > @@ -1467,6 +1496,20 @@ static uint8_t
> avrcp_handle_register_notification(struct avrcp *session,
> > case AVRCP_EVENT_TRACK_REACHED_START:
> > len = 1;
> > break;
> > + case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
> > + len = 5;
> > +
> > + interval = htole32(pdu->params[1]);
> > + player->pos_timer = g_timeout_add_seconds(interval,
> > +
> > + interval_timeout, player);
> > +
> > + pos = player_get_position(player);
> > + be32toh(pos);
> > + /* Fill the value for sending INTERIM response */
> > + memcpy(&pdu->params[1], &pos, sizeof(uint32_t));
> > +
> > + break;
> > +
> > case AVRCP_EVENT_SETTINGS_CHANGED:
> > len = 1;
> > settings = player_list_settings(player); @@ -2949,6
> > +2992,11 @@ static void player_destroy(gpointer data)
> > if (player->destroy)
> > player->destroy(player->user_data);
> >
> > + if (player->pos_timer != 0) {
> > + g_source_remove(player->pos_timer);
> > + player->pos_timer = 0;
> > + }
> > +
> > g_slist_free(player->sessions);
> > g_free(player->path);
> > g_free(player->change_path);
> > @@ -3407,6 +3455,7 @@ static void target_init(struct avrcp *session)
> > (1 << AVRCP_EVENT_TRACK_CHANGED) |
> > (1 << AVRCP_EVENT_TRACK_REACHED_START) |
> > (1 << AVRCP_EVENT_TRACK_REACHED_END) |
> > + (1 <<
> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED) |
> > (1 << AVRCP_EVENT_SETTINGS_CHANGED);
> >
> > if (target->version < 0x0104)
> > diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h index
> > 6ac5294..4816e4b 100644
> > --- a/profiles/audio/avrcp.h
> > +++ b/profiles/audio/avrcp.h
> > @@ -74,6 +74,7 @@
> > #define AVRCP_EVENT_TRACK_CHANGED 0x02
> > #define AVRCP_EVENT_TRACK_REACHED_END 0x03
> > #define AVRCP_EVENT_TRACK_REACHED_START 0x04
> > +#define AVRCP_EVENT_PLAYBACK_POS_CHANGED 0x05
> > #define AVRCP_EVENT_SETTINGS_CHANGED 0x08
> > #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a
> > #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b
> > diff --git a/profiles/audio/media.c b/profiles/audio/media.c index
> > ef7b910..cc19c61 100644
> > --- a/profiles/audio/media.c
> > +++ b/profiles/audio/media.c
> > @@ -1305,6 +1305,9 @@ static gboolean set_status(struct media_player
> *mp, DBusMessageIter *iter)
> > mp->status = g_strdup(value);
> >
> > avrcp_player_event(mp->player, AVRCP_EVENT_STATUS_CHANGED,
> > mp->status);
> > + avrcp_player_event(mp->player,
> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
> > + &mp->position);
> >
> > return TRUE;
> > }
> > @@ -1312,7 +1315,6 @@ static gboolean set_status(struct media_player
> > *mp, DBusMessageIter *iter) static gboolean set_position(struct
> > media_player *mp, DBusMessageIter *iter) {
> > uint64_t value;
> > - const char *status;
> >
> > if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT64)
> > return FALSE;
> > @@ -1321,11 +1323,6 @@ static gboolean set_position(struct
> > media_player *mp, DBusMessageIter *iter)
> >
> > value /= 1000;
> >
> > - if (value > get_position(mp))
> > - status = "forward-seek";
> > - else
> > - status = "reverse-seek";
> > -
>
> Not sure what is reasoning of removing these, the remote side may not
> register for position change and in that case it would not get any seek event
> to synchronize the position.
Yes, PLAYBACK_STATUS_CHANGED and POSITION_CHANGED both should be sent in this case.
If only PLAYBACK_STATUS_CHANGED is sent, the CT will query for position if it didn’t receive " POSITION_CHANGED " event after PLAYBACK_STATUS_CHANGED.
>
> > mp->position = value;
> > g_timer_start(mp->timer);
> >
> > @@ -1334,6 +1331,9 @@ static gboolean set_position(struct media_player
> *mp, DBusMessageIter *iter)
> > if (!mp->position) {
> > avrcp_player_event(mp->player,
> >
> > AVRCP_EVENT_TRACK_REACHED_START, NULL);
> > + avrcp_player_event(mp->player,
> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
> > + &mp->position);
> > return TRUE;
> > }
> >
> > @@ -1344,11 +1344,13 @@ static gboolean set_position(struct
> media_player *mp, DBusMessageIter *iter)
> > if (mp->position == UINT32_MAX || mp->position >= mp->duration) {
> > avrcp_player_event(mp->player,
> AVRCP_EVENT_TRACK_REACHED_END,
> >
> > NULL);
> > + avrcp_player_event(mp->player,
> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
> > + &mp->position);
> > return TRUE;
> > }
> > -
> > - /* Send a status change to force resync the position */
> > - avrcp_player_event(mp->player, AVRCP_EVENT_STATUS_CHANGED,
> status);
> > + avrcp_player_event(mp->player,
> AVRCP_EVENT_PLAYBACK_POS_CHANGED,
> > +
> > + &mp->position);
> >
> > return TRUE;
> > }
> > @@ -1456,6 +1458,7 @@ static gboolean parse_player_metadata(struct
> media_player *mp,
> > int ctype;
> > gboolean title = FALSE;
> > uint64_t uid;
> > + uint32_t pos;
> >
> > ctype = dbus_message_iter_get_arg_type(iter);
> > if (ctype != DBUS_TYPE_ARRAY)
> > @@ -1521,9 +1524,11 @@ static gboolean parse_player_metadata(struct
> media_player *mp,
> > mp->position = 0;
> > g_timer_start(mp->timer);
> > uid = get_uid(mp);
> > + pos = get_position(mp);
> >
> > avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_CHANGED,
> &uid);
> > avrcp_player_event(mp->player,
> > AVRCP_EVENT_TRACK_REACHED_START, NULL);
> > + avrcp_player_event(mp->player,
> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED, &pos);
> >
> > return TRUE;
> > }
> > --
> > 1.9.1
>
> Overall EVENT_PLAYBACK_POS_CHANGED cause more problems than it
> solves, because position is already part of the play status and that normally
> has to be queried anyway, also self synchronizing is way more efficient since
> we can't estimate the speed when the playback is fast-foward or rewind, and
> even if we could that would generate a lot of traffic depending on what
> interval the remote side wants to be updated.
Playback position was not a part of play status though, it was trying resync the position by sending forward-seek or reverse seek as status changed event.
In some control devices, it expects a playback_pos_changed event followed by TRACK_REACHED_START, TRACK_REACHED_END, PLAYBACK_STATUS_CHANGED and also when interval of registered for getting the playback position.
Your input on the same will be highly valuable.
Best Regards,
Bharat
^ permalink raw reply
* Re: how to set PSCAN mode in .conf?
From: Marcel Holtmann @ 2014-10-20 13:27 UTC (permalink / raw)
To: Jeff Chua; +Cc: linux-bluetooth
In-Reply-To: <CAAJw_ZuK6SUy22R133CezsqoU4+dTzxmsipBAp7rCvYBo+zrxw@mail.gmail.com>
Hi Jeff,
> latest bluez doesn't read hcid.conf, so how can I enable "pscan" in
> the conf file?
>
> I know "hciconfig hci0 pscan" works, but I would still like to set
> that via the .conf file.
the mgmt interface has a connectable option and with BlueZ 5 that will be enabled by default for < 3.17 kernel. With >= 3.17 kernels the kernel automatically enables it based on our BR/EDR device list.
Regards
Marcel
^ permalink raw reply
* [PATCH 1/2] android/bluetooth: Fix Supported feature bitmask for MPMD scenarios
From: Marcin Kraglak @ 2014-10-20 13:33 UTC (permalink / raw)
To: linux-bluetooth
Set A2DP-SRC_AVRCP-TG instead of A2DP-SNK_AVRCP-CT_DUN-DT bit.
It was affecting TC_SDP_CTH_SD_BV_01_I PTS test case.
---
android/bluetooth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 827e205..03eb1a1 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -70,7 +70,7 @@
*/
#define MPS_DEFAULT_MPMD ((1ULL << 1) | (1ULL << 3) | (1ULL << 5) | \
(1ULL << 6) | (1ULL << 8) | (1ULL << 10) | \
- (1ULL << 12) | (1ULL << 15) | (1ULL << 18))
+ (1ULL << 12) | (1ULL << 15) | (1ULL << 17))
/*
* bits in bitmask as defined in table 6.5 of Multi Profile Specification
--
1.9.3
^ permalink raw reply related
* [PATCH 2/2] android/pts: Update PICS, PIXIT and test results for MPS
From: Marcin Kraglak @ 2014-10-20 13:33 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1413812032-26631-1-git-send-email-marcin.kraglak@tieto.com>
---
android/pics-mps.txt | 2 +-
android/pixit-mps.txt | 2 +-
android/pts-mps.txt | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/android/pics-mps.txt b/android/pics-mps.txt
index 6fa9858..ab937a6 100644
--- a/android/pics-mps.txt
+++ b/android/pics-mps.txt
@@ -1,6 +1,6 @@
MPS PICS for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
# - not yet implemented/supported
diff --git a/android/pixit-mps.txt b/android/pixit-mps.txt
index 088efe9..56f5122 100644
--- a/android/pixit-mps.txt
+++ b/android/pixit-mps.txt
@@ -1,6 +1,6 @@
MPS PIXIT for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pts-mps.txt b/android/pts-mps.txt
index 2f661bb..46d2510 100644
--- a/android/pts-mps.txt
+++ b/android/pts-mps.txt
@@ -1,7 +1,7 @@
PTS test results for MPS
-PTS version: 5.2
-Tested: 31.07.2014
+PTS version: 5.3
+Tested: 20.10.2014
Android version: 4.4.4
Results:
@@ -50,5 +50,5 @@ TC_SRC_TG_HFAV_CLH_MD_BV_04_I PASS Do not use AOSP Music player.
Use e.g. MortPlayer or Poweramp
TC_SRC_TG_HFAV_CLH_MD_BV_05_I PASS
TC_SRC_TG_HFAV_CLH_MD_BV_06_I PASS
-TC_PAIRING_HF_SNK_CT PASS
+TC_PAIRING_HF_SNK_CT N/A Pairing helper for MD tests
-------------------------------------------------------------------------------
--
1.9.3
^ permalink raw reply related
* Re: [PATCH v4 1/2] core: Add Manufacturer Specific Data EIR field
From: Johan Hedberg @ 2014-10-20 13:41 UTC (permalink / raw)
To: Alfonso Acosta; +Cc: linux-bluetooth
In-Reply-To: <1413290765-20398-2-git-send-email-fons@spotify.com>
Hi Alfonso,
On Tue, Oct 14, 2014, Alfonso Acosta wrote:
> Add data structure and parsing support.
> ---
> src/eir.c | 22 ++++++++++++++++++++++
> src/eir.h | 8 ++++++++
> 2 files changed, 30 insertions(+)
This patch doesn't compile:
In file included from android/bluetooth.c:45:0:
./src/eir.h:53:15: error: ‘HCI_MAX_EIR_LENGTH’ undeclared here (not in a function)
uint8_t data[HCI_MAX_EIR_LENGTH];
^
make[1]: *** [android/bluetooth.o] Error 1
Johan
^ permalink raw reply
* Re: [PATCH v4 2/2] core: Add subscription API for Manufacturer Specific Data
From: Johan Hedberg @ 2014-10-20 13:42 UTC (permalink / raw)
To: Alfonso Acosta; +Cc: linux-bluetooth
In-Reply-To: <1413290765-20398-3-git-send-email-fons@spotify.com>
Hi Alfonso,
On Tue, Oct 14, 2014, Alfonso Acosta wrote:
> This patch allows plugins to be notified whenever an adapter receives
> Manufacturer Specific Data in the advertising reports from a device.
>
> This can happen when new device is discovered or when we autoconnect
> to it.
> ---
> src/adapter.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> src/adapter.h | 10 ++++++++++
> 2 files changed, 54 insertions(+)
This patch also doesn't compile (the error from the first patch might
have gone away, but then there's this new one):
src/adapter.c:4654:6: error: no previous declaration for ‘adapter_msd_notify’ [-Werror=missing-declarations]
void adapter_msd_notify(struct btd_adapter *adapter, struct btd_device *dev,
^
cc1: all warnings being treated as errors
make[1]: *** [src/bluetoothd-adapter.o] Error 1
Johan
^ permalink raw reply
* Re: [PATCH ] audio/avrcp: Add Support for PLAYBACK_POS_CHANGED_EVENT
From: Luiz Augusto von Dentz @ 2014-10-20 13:46 UTC (permalink / raw)
To: Bharat Bhusan Panda; +Cc: linux-bluetooth@vger.kernel.org, cpgs
In-Reply-To: <018701cfec67$7ad7bfa0$70873ee0$@samsung.com>
Hi,
On Mon, Oct 20, 2014 at 4:11 PM, Bharat Bhusan Panda
<bharat.panda@samsung.com> wrote:
> Hi Luiz,
>
>> > As per AVRCP 1.5 spec, 6.7.2, page 57.
>> >
>> > EVENT_PLAYBACK_POS_CHANGED shall be notified in the following
>> conditions:
>> >
>> > 1. TG has reached the registered playback Interval time.
>> > 2. Changed PLAY STATUS.
>> > 3. Changed Current Track.
>> > 4. Reached end or beginning of track.
>> > ---
>> > profiles/audio/avrcp.c | 49
>> > +++++++++++++++++++++++++++++++++++++++++++++++++
>> > profiles/audio/avrcp.h | 1 +
>> > profiles/audio/media.c | 23 ++++++++++++++---------
>> > 3 files changed, 64 insertions(+), 9 deletions(-)
>> >
>> > diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c index
>> > 5c3c4f9..77f1dcb 100644
>> > --- a/profiles/audio/avrcp.c
>> > +++ b/profiles/audio/avrcp.c
>> > @@ -198,6 +198,7 @@ struct pending_list_items { struct avrcp_player {
>> > struct avrcp_server *server;
>> > GSList *sessions;
>> > + uint16_t pos_timer;
>> > uint16_t id;
>> > uint8_t scope;
>> > uint64_t uid;
>> > @@ -627,6 +628,7 @@ void avrcp_player_event(struct avrcp_player
>> *player, uint8_t id,
>> > uint8_t buf[AVRCP_HEADER_LENGTH + 9];
>> > struct avrcp_header *pdu = (void *) buf;
>> > uint16_t size;
>> > + uint32_t *pos = NULL;
>> > GSList *l;
>> > int attr;
>> > int val;
>> > @@ -673,6 +675,18 @@ void avrcp_player_event(struct avrcp_player
>> *player, uint8_t id,
>> > pdu->params[size++] = attr;
>> > pdu->params[size++] = val;
>> > break;
>> > + case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
>> > + size = 5;
>> > + pos = (uint32_t *) data;
>> > +
>> > + be32toh(*pos);
>> > + memcpy(&pdu->params[1], pos, sizeof(uint32_t));
>> > +
>> > + if (player->pos_timer > 0) {
>> > + g_source_remove(player->pos_timer);
>> > + player->pos_timer = 0;
>> > + }
>> > + break;
>>
>> Note that it is meant to be playback interval, so if it is not playing we should
>> not send anything.
> Yes, will change it accordingly.
>>
>> > default:
>> > error("Unknown event %u", id);
>> > return;
>> > @@ -1429,6 +1443,19 @@ static bool handle_passthrough(struct avctp
>> *conn, uint8_t op, bool pressed,
>> > return handler->func(session); }
>> >
>> > +static gboolean interval_timeout(gpointer user_data) {
>> > + uint32_t pos;
>> > + struct avrcp_player *mp = user_data;
>> > +
>> > + pos = player_get_position(mp);
>> > + mp->pos_timer = 0;
>> > + avrcp_player_event(mp, AVRCP_EVENT_PLAYBACK_POS_CHANGED,
>> > + &pos);
>> > +
>> > + return FALSE;
>> > +}
>> > +
>> > static uint8_t avrcp_handle_register_notification(struct avrcp *session,
>> > struct avrcp_header *pdu,
>> > uint8_t transaction)
>> > @@ -1436,6 +1463,8 @@ static uint8_t
>> avrcp_handle_register_notification(struct avrcp *session,
>> > struct avrcp_player *player = target_get_player(session);
>> > struct btd_device *dev = session->dev;
>> > uint16_t len = ntohs(pdu->params_len);
>> > + uint32_t interval;
>> > + uint32_t pos;
>> > uint64_t uid;
>> > GList *settings;
>> >
>> > @@ -1467,6 +1496,20 @@ static uint8_t
>> avrcp_handle_register_notification(struct avrcp *session,
>> > case AVRCP_EVENT_TRACK_REACHED_START:
>> > len = 1;
>> > break;
>> > + case AVRCP_EVENT_PLAYBACK_POS_CHANGED:
>> > + len = 5;
>> > +
>> > + interval = htole32(pdu->params[1]);
>> > + player->pos_timer = g_timeout_add_seconds(interval,
>> > +
>> > + interval_timeout, player);
>> > +
>> > + pos = player_get_position(player);
>> > + be32toh(pos);
>> > + /* Fill the value for sending INTERIM response */
>> > + memcpy(&pdu->params[1], &pos, sizeof(uint32_t));
>> > +
>> > + break;
>> > +
>> > case AVRCP_EVENT_SETTINGS_CHANGED:
>> > len = 1;
>> > settings = player_list_settings(player); @@ -2949,6
>> > +2992,11 @@ static void player_destroy(gpointer data)
>> > if (player->destroy)
>> > player->destroy(player->user_data);
>> >
>> > + if (player->pos_timer != 0) {
>> > + g_source_remove(player->pos_timer);
>> > + player->pos_timer = 0;
>> > + }
>> > +
>> > g_slist_free(player->sessions);
>> > g_free(player->path);
>> > g_free(player->change_path);
>> > @@ -3407,6 +3455,7 @@ static void target_init(struct avrcp *session)
>> > (1 << AVRCP_EVENT_TRACK_CHANGED) |
>> > (1 << AVRCP_EVENT_TRACK_REACHED_START) |
>> > (1 << AVRCP_EVENT_TRACK_REACHED_END) |
>> > + (1 <<
>> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED) |
>> > (1 << AVRCP_EVENT_SETTINGS_CHANGED);
>> >
>> > if (target->version < 0x0104)
>> > diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h index
>> > 6ac5294..4816e4b 100644
>> > --- a/profiles/audio/avrcp.h
>> > +++ b/profiles/audio/avrcp.h
>> > @@ -74,6 +74,7 @@
>> > #define AVRCP_EVENT_TRACK_CHANGED 0x02
>> > #define AVRCP_EVENT_TRACK_REACHED_END 0x03
>> > #define AVRCP_EVENT_TRACK_REACHED_START 0x04
>> > +#define AVRCP_EVENT_PLAYBACK_POS_CHANGED 0x05
>> > #define AVRCP_EVENT_SETTINGS_CHANGED 0x08
>> > #define AVRCP_EVENT_AVAILABLE_PLAYERS_CHANGED 0x0a
>> > #define AVRCP_EVENT_ADDRESSED_PLAYER_CHANGED 0x0b
>> > diff --git a/profiles/audio/media.c b/profiles/audio/media.c index
>> > ef7b910..cc19c61 100644
>> > --- a/profiles/audio/media.c
>> > +++ b/profiles/audio/media.c
>> > @@ -1305,6 +1305,9 @@ static gboolean set_status(struct media_player
>> *mp, DBusMessageIter *iter)
>> > mp->status = g_strdup(value);
>> >
>> > avrcp_player_event(mp->player, AVRCP_EVENT_STATUS_CHANGED,
>> > mp->status);
>> > + avrcp_player_event(mp->player,
>> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
>> > + &mp->position);
>> >
>> > return TRUE;
>> > }
>> > @@ -1312,7 +1315,6 @@ static gboolean set_status(struct media_player
>> > *mp, DBusMessageIter *iter) static gboolean set_position(struct
>> > media_player *mp, DBusMessageIter *iter) {
>> > uint64_t value;
>> > - const char *status;
>> >
>> > if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_INT64)
>> > return FALSE;
>> > @@ -1321,11 +1323,6 @@ static gboolean set_position(struct
>> > media_player *mp, DBusMessageIter *iter)
>> >
>> > value /= 1000;
>> >
>> > - if (value > get_position(mp))
>> > - status = "forward-seek";
>> > - else
>> > - status = "reverse-seek";
>> > -
>>
>> Not sure what is reasoning of removing these, the remote side may not
>> register for position change and in that case it would not get any seek event
>> to synchronize the position.
>
> Yes, PLAYBACK_STATUS_CHANGED and POSITION_CHANGED both should be sent in this case.
> If only PLAYBACK_STATUS_CHANGED is sent, the CT will query for position if it didn’t receive " POSITION_CHANGED " event after PLAYBACK_STATUS_CHANGED.
Exactly, and that means with POSITION_CHANGED you have more traffic
because it first send a changed which is normally followed by register
notification and interim response versus only get play status and
response.
>>
>> > mp->position = value;
>> > g_timer_start(mp->timer);
>> >
>> > @@ -1334,6 +1331,9 @@ static gboolean set_position(struct media_player
>> *mp, DBusMessageIter *iter)
>> > if (!mp->position) {
>> > avrcp_player_event(mp->player,
>> >
>> > AVRCP_EVENT_TRACK_REACHED_START, NULL);
>> > + avrcp_player_event(mp->player,
>> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
>> > + &mp->position);
>> > return TRUE;
>> > }
>> >
>> > @@ -1344,11 +1344,13 @@ static gboolean set_position(struct
>> media_player *mp, DBusMessageIter *iter)
>> > if (mp->position == UINT32_MAX || mp->position >= mp->duration) {
>> > avrcp_player_event(mp->player,
>> AVRCP_EVENT_TRACK_REACHED_END,
>> >
>> > NULL);
>> > + avrcp_player_event(mp->player,
>> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED,
>> > + &mp->position);
>> > return TRUE;
>> > }
>> > -
>> > - /* Send a status change to force resync the position */
>> > - avrcp_player_event(mp->player, AVRCP_EVENT_STATUS_CHANGED,
>> status);
>> > + avrcp_player_event(mp->player,
>> AVRCP_EVENT_PLAYBACK_POS_CHANGED,
>> > +
>> > + &mp->position);
>> >
>> > return TRUE;
>> > }
>> > @@ -1456,6 +1458,7 @@ static gboolean parse_player_metadata(struct
>> media_player *mp,
>> > int ctype;
>> > gboolean title = FALSE;
>> > uint64_t uid;
>> > + uint32_t pos;
>> >
>> > ctype = dbus_message_iter_get_arg_type(iter);
>> > if (ctype != DBUS_TYPE_ARRAY)
>> > @@ -1521,9 +1524,11 @@ static gboolean parse_player_metadata(struct
>> media_player *mp,
>> > mp->position = 0;
>> > g_timer_start(mp->timer);
>> > uid = get_uid(mp);
>> > + pos = get_position(mp);
>> >
>> > avrcp_player_event(mp->player, AVRCP_EVENT_TRACK_CHANGED,
>> &uid);
>> > avrcp_player_event(mp->player,
>> > AVRCP_EVENT_TRACK_REACHED_START, NULL);
>> > + avrcp_player_event(mp->player,
>> > + AVRCP_EVENT_PLAYBACK_POS_CHANGED, &pos);
>> >
>> > return TRUE;
>> > }
>> > --
>> > 1.9.1
>>
>> Overall EVENT_PLAYBACK_POS_CHANGED cause more problems than it
>> solves, because position is already part of the play status and that normally
>> has to be queried anyway, also self synchronizing is way more efficient since
>> we can't estimate the speed when the playback is fast-foward or rewind, and
>> even if we could that would generate a lot of traffic depending on what
>> interval the remote side wants to be updated.
>
> Playback position was not a part of play status though, it was trying resync the position by sending forward-seek or reverse seek as status changed event.
> In some control devices, it expects a playback_pos_changed event followed by TRACK_REACHED_START, TRACK_REACHED_END, PLAYBACK_STATUS_CHANGED and also when interval of registered for getting the playback position.
> Your input on the same will be highly valuable.
It is part of GetPlayStatus which also contains the duration, anyway
afaik position changed event is not mandatory, so the remote control
has to deal with stacks that do not have it which in the end leads to
synchronize via state changes by querying play status, if it cannot do
it you might have IOP problems with a lot stacks including iOS and
Android which does not support position changed.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] android/pts: Update PTS files for HOGP
From: Sebastian Chlad @ 2014-10-20 13:52 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sebastian Chlad
PICS and PIXITs updated to PTS 5.3. Regression done for Android
4.4.4.
---
android/pics-hogp.txt | 2 +-
android/pixit-hogp.txt | 2 +-
android/pts-hogp.txt | 14 ++++++++------
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/android/pics-hogp.txt b/android/pics-hogp.txt
index d7192bf..61cf56a 100644
--- a/android/pics-hogp.txt
+++ b/android/pics-hogp.txt
@@ -1,6 +1,6 @@
HOGP PICS for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
# - not yet implemented/supported
diff --git a/android/pixit-hogp.txt b/android/pixit-hogp.txt
index 067c280..d32fe69 100644
--- a/android/pixit-hogp.txt
+++ b/android/pixit-hogp.txt
@@ -1,6 +1,6 @@
HOGP PIXIT for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pts-hogp.txt b/android/pts-hogp.txt
index 19292d1..d874c9c 100644
--- a/android/pts-hogp.txt
+++ b/android/pts-hogp.txt
@@ -1,7 +1,7 @@
PTS test results for HoG
-PTS version: 5.2
-Tested: 22-July-2014
+PTS version: 5.3
+Tested: 20-October-2014
Android version: 4.4.4
Results:
@@ -54,19 +54,21 @@ TC_HGRF_BH_BV_15_I N/A
TC_HGRF_BH_BV_16_I N/A
TC_HGRF_BH_BV_17_I N/A
TC_HGRF_HH_BV_18_I N/A
-TC_HGWF_RH_BV_01_I PASS haltest: hidhost connect <addr>
+ Note: JIRA bug #BA-175 affecting TC_HGWF_RH
+ section
+TC_HGWF_RH_BV_01_I INC haltest: hidhost connect <addr>
hidhost set_report <addr> BTHH_INPUT_REPORT
AAB3F8A6CD
hidhost disconnect <addr>
-TC_HGWF_RH_BV_02_I PASS haltest: hidhost connect <addr>
+TC_HGWF_RH_BV_02_I INC haltest: hidhost connect <addr>
hidhost set_report <addr> BTHH_OUTPUT_REPORT
EF907856341200
hidhost disconnect <addr>
-TC_HGWF_RH_BV_03_I PASS haltest: hidhost connect <addr>
+TC_HGWF_RH_BV_03_I INC haltest: hidhost connect <addr>
hidhost set_report <addr> BTHH_OUTPUT_REPORT
EF907856341200
hidhost disconnect <addr>
-TC_HGWF_RH_BV_04_I PASS haltest: hidhost connect <addr>
+TC_HGWF_RH_BV_04_I INC haltest: hidhost connect <addr>
hidhost set_report <addr> BTHH_FEATURE_REPORT
EA453F2D87
hidhost disconnect <addr>
--
1.8.5.3
^ permalink raw reply related
* Re: Query regarding creation of multiple MAS Instance ID:
From: Luiz Augusto von Dentz @ 2014-10-20 13:53 UTC (permalink / raw)
To: Gowtham Anandha Babu
Cc: linux-bluetooth@vger.kernel.org, Bharat Panda, Dmitry Kasatkin,
cpgs
In-Reply-To: <000301cfec65$bdb08cf0$3911a6d0$@samsung.com>
Hi,
On Mon, Oct 20, 2014 at 3:59 PM, Gowtham Anandha Babu
<gowtham.ab@samsung.com> wrote:
> Hi Luiz,
>
>> -----Original Message-----
>> From: Luiz Augusto von Dentz [mailto:luiz.dentz@gmail.com]
>> Sent: Friday, October 17, 2014 5:11 PM
>> To: Gowtham Anandha Babu
>> Cc: linux-bluetooth@vger.kernel.org; Bharat Panda; Dmitry Kasatkin;
>> cpgs@samsung.com
>> Subject: Re: Query regarding creation of multiple MAS Instance ID:
>>
>> Hi,
>>
>> On Thu, Oct 16, 2014 at 4:18 PM, Gowtham Anandha Babu
>> <gowtham.ab@samsung.com> wrote:
>> > Hi All,
>> >
>> > I am working on obexd MAP profile. Is it possible to create multiple
>> > MAS Instance in bluez?
>> > Because right now bluez has only one MAS Instance support (only one
>> > MAS_UUID), which is advertised to MCE based on the XML format
>> followed
>> > in src/profile.c.
>> > When I add one more record to MAS_RECORD XML format by changing the
>> > value as 0x01, I am not able see two instances getting loaded.
>> > <attribute id=\"0x0315\"> \
>> > <uint8 value=\"0x01\"/> \
>> > </attribute> \
>>
>> How you are doing that? You should be able to call
>> ProfileManager1.RegisterProfile if that is what you doing and it is not working
>> perhaps we have a bug somewhere. Two very important things you need to
>> check:
>>
>> 1. It cannot use the same path for both instances 2. Each instance needs a
>> different channel
>>
>> So if you are register via XML you need to take care of those details, but
>> perhaps you are using the default record by just providing the UUID, that
>> probably will not work because apparently we have hardcoded the channel,
>> if that is the case we should probably add a check if there is another instance
>> already register and use a different channel/psm.
>>
>> > Do we need to create one more UUID like OBEX_MAS1_UUID and
>> > OBEX_MAS2_UUID to support multiple mas instances?
>> > Or what could be the possible solutions?
>>
>> Each instance has to have the service class set to MAS UUID, otherwise no
>> one will be able to discover it.
>>
>> >
>> > Regards.
>> > Gowtham Anandha Babu
>> >
>> > --
>> > To unsubscribe from this list: send the line "unsubscribe
>> > linux-bluetooth" in the body of a message to majordomo@vger.kernel.org
>> > More majordomo info at http://vger.kernel.org/majordomo-info.html
>>
>>
>>
>> --
>> Luiz Augusto von Dentz
>
> Here is what I did exactly after your comments,
>
> 1) Based on the flag, I managed the two MAS Instances in bluetooth.c
>
> diff --git a/obexd/plugins/bluetooth.c b/obexd/plugins/bluetooth.c
> index cf326cc..3a0c022 100644
> --- a/obexd/plugins/bluetooth.c
> +++ b/obexd/plugins/bluetooth.c
> @@ -50,6 +50,8 @@
> #define BT_RX_MTU 32767
> #define BT_TX_MTU 32767
>
> +gboolean MAS = FALSE;
> +
> struct bluetooth_profile {
> struct obex_server *server;
> struct obex_service_driver *driver;
> @@ -269,7 +271,20 @@ static int register_profile(struct bluetooth_profile *profile)
> char *xml;
> int ret = 0;
>
> - profile->path = g_strconcat("/org/bluez/obex/", profile->uuid, NULL);
> +
> + if(!g_ascii_strcasecmp(profile->uuid, OBEX_MAS_UUID))
> + if(!MAS) {
> + profile->path = g_strconcat("/org/bluez/obex/MAS1/",
> + profile->uuid, NULL);
> + MAS = TRUE;
> + }
> + else
> + profile->path = g_strconcat("/org/bluez/obex/MAS2/",
> + profile->uuid, NULL);
> + else
> + profile->path = g_strconcat("/org/bluez/obex/", profile->uuid, NULL);
> +
> g_strdelimit(profile->path, "-", '_');
>
> if (!g_dbus_register_interface(connection, profile->path,
> @@ -290,6 +305,10 @@ static int register_profile(struct bluetooth_profile *profile)
>
> dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
> &profile->path);
> dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING,
> &profile->uuid);
> dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
> @@ -346,7 +365,9 @@ static const char *service2uuid(uint16_t service)
> return "00005005-0000-1000-8000-0002ee000001";
> case OBEX_SYNCEVOLUTION:
> return "00000002-0000-1000-8000-0002ee000002";
> - case OBEX_MAS:
> + case OBEX_MAS1:
> + return OBEX_MAS_UUID;
> + case OBEX_MAS2:
> return OBEX_MAS_UUID;
> case OBEX_MNS:
> return OBEX_MNS_UUID;
>
> 2) Created one more MAS Instance in mas.c
>
> diff --git a/obexd/plugins/mas.c b/obexd/plugins/mas.c
> index fb97fe3..fb482e2 100644
> --- a/obexd/plugins/mas.c
> +++ b/obexd/plugins/mas.c
> @@ -728,9 +728,9 @@ static int any_close(void *obj)
> return 0;
> }
>
> -static struct obex_service_driver mas = {
> - .name = "Message Access server",
> - .service = OBEX_MAS,
> +static struct obex_service_driver mas1 = {
> + .name = "Message Access server 1",
> + .service = OBEX_MAS1,
> .target = MAS_TARGET,
> .target_size = TARGET_SIZE,
> .connect = mas_connect,
> @@ -740,6 +740,18 @@ static struct obex_service_driver mas = {
> .disconnect = mas_disconnect,
> };
>
> +static struct obex_service_driver mas2 = {
> + .name = "Message Access server 2",
> + .service = OBEX_MAS2,
> + .target = MAS_TARGET,
> + .target_size = TARGET_SIZE,
> + .connect = mas_connect,
> + .get = mas_get,
> + .put = mas_put,
> + .setpath = mas_setpath,
> + .disconnect = mas_disconnect,
> +};
> +
> static struct obex_mime_type_driver mime_map = {
> .target = MAS_TARGET,
> .target_size = TARGET_SIZE,
> @@ -838,10 +850,14 @@ static int mas_init(void)
> goto failed;
> }
>
> - err = obex_service_driver_register(&mas);
> + err = obex_service_driver_register(&mas1);
> if (err < 0)
> goto failed;
>
> + err = obex_service_driver_register(&mas2);
> + if(err < 0)
> + goto failed;
> +
> return 0;
>
> failed:
> @@ -857,7 +873,8 @@ static void mas_exit(void)
> {
> int i;
>
> - obex_service_driver_unregister(&mas);
> + obex_service_driver_unregister(&mas1);
> + obex_service_driver_unregister(&mas2);
>
> for (i = 0; map_drivers[i] != NULL; ++i)
> obex_mime_type_driver_unregister(map_drivers[i]);
> @@ -865,4 +882,5 @@ static void mas_exit(void)
> messages_exit();
> }
>
> -OBEX_PLUGIN_DEFINE(mas, mas_init, mas_exit)
> +OBEX_PLUGIN_DEFINE(mas1, mas_init, mas_exit)
> +OBEX_PLUGIN_DEFINE(mas2, mas_init, mas_exit)
> diff --git a/obexd/src/obexd.h b/obexd/src/obexd.h
> index 42c3c4d..59de70e 100644
> --- a/obexd/src/obexd.h
> +++ b/obexd/src/obexd.h
> @@ -28,7 +28,8 @@
> #define OBEX_IRMC (1 << 5)
> #define OBEX_PCSUITE (1 << 6)
> #define OBEX_SYNCEVOLUTION (1 << 7)
> -#define OBEX_MAS (1 << 8)
> +#define OBEX_MAS1 (1 << 8)
> +#define OBEX_MAS2 (1 << 10)
> #define OBEX_MNS (1 << 9)
>
> gboolean plugin_init(const char *pattern, const char *exclude);
>
> 3) Assigned different channel and path for both instances
> 4)Added one more SDP record (XML) in profile.c
>
> diff --git a/src/profile.c b/src/profile.c
> index 7aca3be..ab5b5c2 100644
> --- a/src/profile.c
> +++ b/src/profile.c
> @@ -62,7 +62,8 @@
> #define HFP_AG_DEFAULT_CHANNEL 13
> #define SYNC_DEFAULT_CHANNEL 14
> #define PBAP_DEFAULT_CHANNEL 15
> -#define MAS_DEFAULT_CHANNEL 16
> +#define MAS1_DEFAULT_CHANNEL 16
> +#define MAS2_DEFAULT_CHANNEL 18
> #define MNS_DEFAULT_CHANNEL 17
>
> #define BTD_PROFILE_PSM_AUTO -1
> @@ -395,7 +396,7 @@
> </attribute> \
> </record>"
>
> -#define MAS_RECORD \
> +#define MAS_RECORD1 \
> "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
> <record> \
> <attribute id=\"0x0001\"> \
> @@ -441,6 +442,52 @@
> </attribute> \
> </record>"
>
> +#define MAS_RECORD2 \
> + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
> + <record> \
> + <attribute id=\"0x0001\"> \
> + <sequence> \
> + <uuid value=\"0x1132\"/> \
> + </sequence> \
> + </attribute> \
> + <attribute id=\"0x0004\"> \
> + <sequence> \
> + <sequence> \
> + <uuid value=\"0x0100\"/> \
> + </sequence> \
> + <sequence> \
> + <uuid value=\"0x0003\"/> \
> + <uint8 value=\"0x%02x\"/> \
> + </sequence> \
> + <sequence> \
> + <uuid value=\"0x0008\"/> \
> + </sequence> \
> + </sequence> \
> + </attribute> \
> + <attribute id=\"0x0005\"> \
> + <sequence> \
> + <uuid value=\"0x1002\" /> \
> + </sequence> \
> + </attribute> \
> + <attribute id=\"0x0009\"> \
> + <sequence> \
> + <sequence> \
> + <uuid value=\"0x1134\"/> \
> + <uint16 value=\"0x%04x\" /> \
> + </sequence> \
> + </sequence> \
> + </attribute> \
> + <attribute id=\"0x0100\"> \
> + <text value=\"%s\"/> \
> + </attribute> \
> + <attribute id=\"0x0315\"> \
> + <uint8 value=\"0x01\"/> \
> + </attribute> \
> + <attribute id=\"0x0316\"> \
> + <uint8 value=\"0x0F\"/> \
> + </attribute> \
> + </record>"
> +
> #define MNS_RECORD \
> "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
> <record> \
> @@ -562,6 +609,8 @@
>
> struct ext_io;
>
> +gboolean MAS = FALSE;
> +
> struct ext_profile {
> struct btd_profile p;
>
> @@ -1734,10 +1787,17 @@ static char *get_pse_record(struct ext_profile *ext, struct ext_io *l2cap,
> ext->name);
> }
>
> -static char *get_mas_record(struct ext_profile *ext, struct ext_io *l2cap,
> +static char *get_mas_record1(struct ext_profile *ext, struct ext_io *l2cap,
> + struct ext_io *rfcomm)
> +{
> + return g_strdup_printf(MAS_RECORD1, rfcomm->chan, ext->version,
> + ext->name);
> +}
> +
> +static char *get_mas_record2(struct ext_profile *ext, struct ext_io *l2cap,
> struct ext_io *rfcomm)
> {
> - return g_strdup_printf(MAS_RECORD, rfcomm->chan, ext->version,
> + return g_strdup_printf(MAS_RECORD2, rfcomm->chan, ext->version,
> ext->name);
> }
>
> @@ -1949,10 +2009,17 @@ static struct default_settings {
> .version = 0x0101,
> }, {
> .uuid = OBEX_MAS_UUID,
> - .name = "Message Access",
> - .channel = MAS_DEFAULT_CHANNEL,
> + .name = "Message Access 1",
> + .channel = MAS1_DEFAULT_CHANNEL,
> + .authorize = true,
> + .get_record = get_mas_record1,
> + .version = 0x0100
> + }, {
> + .uuid = OBEX_MAS_UUID,
> + .name = "Message Access 2",
> + .channel = MAS2_DEFAULT_CHANNEL,
> .authorize = true,
> - .get_record = get_mas_record,
> + .get_record = get_mas_record2,
> .version = 0x0100
> }, {
> .uuid = OBEX_MNS_UUID,
> @@ -1981,8 +2048,21 @@ static void ext_set_defaults(struct ext_profile *ext)
> struct default_settings *settings = &defaults[i];
> const char *remote_uuid;
>
> + DBG("%s == %s",ext->uuid, settings->uuid);
> +
> if (strcasecmp(ext->uuid, settings->uuid) != 0)
> continue;
> +
> + if(!strcasecmp(ext->uuid, OBEX_MAS_UUID))
> + if(MAS) {
> + MAS = 0;
> + continue;
> + }
> +
> + if(!strcasecmp(ext->uuid, OBEX_MAS_UUID))
> + MAS = TRUE;
> +
> + DBG("MATCHED %s == %s MAS = %d",ext->uuid, settings->uuid, MAS);
>
> if (settings->remote_uuid)
> remote_uuid = settings->remote_uuid;
> @@ -2022,6 +2102,8 @@ static void ext_set_defaults(struct ext_profile *ext)
>
> if (settings->name)
> ext->name = g_strdup(settings->name);
> +
> + return;
> }
> }
>
>
> After this changes I am able to load the two MAS Instances successfully. Is it fine? What do you think?
Well the main problem then becomes how to decide how many instance it
should register and what each instance should be, in the past I
comment that I would like to see the backends evolving into D-Bus
agent/entities that register at runtime perhaps we should looking into
that direction so we don't have to hardcode the records.
--
Luiz Augusto von Dentz
^ permalink raw reply
* [PATCH] android/pts: Updated SM PICS and PIXITs for PTS 5.3
From: Ruslan Mstoi @ 2014-10-20 14:21 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Ruslan Mstoi
---
android/pics-sm.txt | 6 +++---
android/pixit-sm.txt | 2 +-
android/pts-sm.txt | 12 +++++-------
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/android/pics-sm.txt b/android/pics-sm.txt
index dcdfff8..c1bfe0e 100644
--- a/android/pics-sm.txt
+++ b/android/pics-sm.txt
@@ -1,6 +1,6 @@
SM PICS for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
@@ -25,7 +25,7 @@ Parameter Name Selected Description
TSPC_SM_2_1 True Authenticated MITM protection (O)
TSPC_SM_2_2 True Unauthenticated no MITM protection (C.1)
TSPC_SM_2_3 True No security requirements (M)
-TSPC_SM_2_4 False OOB supported (O)
+TSPC_SM_2_4 False (*) OOB supported (O)
-------------------------------------------------------------------------------
C.1: If TSPC_SM_2_1 is supported then Mandatory, else Optional
-------------------------------------------------------------------------------
@@ -45,7 +45,7 @@ Parameter Name Selected Description
-------------------------------------------------------------------------------
TSPC_SM_4_1 True Just Works (O)
TSPC_SM_4_2 True Passkey Entry (C.1)
-TSPC_SM_4_3 False Out of Band (C.1)
+TSPC_SM_4_3 False (*) Out of Band (C.1)
-------------------------------------------------------------------------------
C.1: If TSPC_SM_2_1 is supported, at least one of these features shall be
supported.
diff --git a/android/pixit-sm.txt b/android/pixit-sm.txt
index 2526e29..2d1442b 100644
--- a/android/pixit-sm.txt
+++ b/android/pixit-sm.txt
@@ -1,6 +1,6 @@
SM PIXIT for the PTS tool.
-PTS version: 5.2
+PTS version: 5.3
* - different than PTS defaults
& - should be set to IUT Bluetooth address
diff --git a/android/pts-sm.txt b/android/pts-sm.txt
index a5c0aba..8a38d32 100644
--- a/android/pts-sm.txt
+++ b/android/pts-sm.txt
@@ -1,7 +1,7 @@
PTS test results for SM
-PTS version: 5.2
-Tested: 25-July-2014
+PTS version: 5.3
+Tested: 20-October-2014
Android version: 4.4.4
kernel version: 3.17
@@ -66,8 +66,7 @@ TC_OOB_BI_01_C N/A
TC_OOB_BI_02_C N/A
TC_EKS_BV_01_C PASS
TC_EKS_BV_02_C PASS
-TC_EKS_BI_01_C INC PTS issue #12449
- btmgmt io-cap 0x03
+TC_EKS_BI_01_C PASS btmgmt io-cap 0x03
TC_EKS_BI_02_C PASS
TC_SIGN_BV_01_C INC PTS issue #12305
TC_SIGN_BV_03_C PASS haltest
@@ -79,7 +78,7 @@ TC_KDU_BV_01_C PASS btmgmt pairable on
TC_KDU_BV_02_C PASS PTS issue #12302
Note: Can pass it with following instructions:
btmgmt privacy on
- btmgmt advetising on
+ btmgmt advertising on
Check our random address (valid for 15 min)
Set PIXIT TSPX_bd_addr_iut to random address
Set PIXIT TSPX_peer_type to 01
@@ -95,7 +94,6 @@ TC_KDU_BV_05_C PASS PTS issue #12302
TC_KDU_BV_06_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
TC_KDU_BV_07_C PASS btmgmt pairable on
TC_SIP_BV_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
-TC_SIP_BV_02_C INC PTS issue #12460
- l2test -n -J4 -V le_public <addr>
+TC_SIP_BV_02_C PASS l2test -n -J4 -V le_public <addr>
TC_SIE_BV_01_C PASS btmgmt pair -c 0x03 -t 0x01 <addr>
-------------------------------------------------------------------------------
--
1.9.1
^ permalink raw reply related
* [PATCH v2 bluetooth-next 0/4] 6lowpan: Move skb delivery out of IPHC
From: Martin Townsend @ 2014-10-20 14:39 UTC (permalink / raw)
To: linux-bluetooth, linux-wpan
Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend
This series moves skb delivery out of IPHC and into the receive routines of
both bluetooth and 802.15.4. The reason is that we need to support more
(de)compression schemes in the future. It also means that calling
lowpan_process_data now only returns error codes or 0 for success so
this has been cleaned up. The final patch then renames occurences of
lowpan_process_data and process_data to something more meaningful.
v1 -> v2
* Handle freeing of skb in lowpan_give_skb_to_devices for 802.15.14
* Added another skb_consume in bluetooth code for uncompressed IPv6 headers
* Added missing skb_consume for local_skb for bluetooth in compreesed IPv6 header
path
* Combine patch 4 into 1.
Martin Townsend (4):
6lowpan: remove skb_deliver from IPHC
6lowpan: fix process_data return values
bluetooth:6lowpan: use consume_skb when packet processed successfully
ieee802154: 6lowpan: rename process_data and lowpan_process_data
include/net/6lowpan.h | 12 ++++++------
net/6lowpan/iphc.c | 42 ++++++++++++----------------------------
net/bluetooth/6lowpan.c | 34 +++++++++++++++++++++-----------
net/ieee802154/6lowpan_rtnl.c | 45 +++++++++++++++++++++++--------------------
4 files changed, 65 insertions(+), 68 deletions(-)
--
1.9.1
^ permalink raw reply
* [PATCH v2 bluetooth-next 1/4] 6lowpan: remove skb_deliver from IPHC
From: Martin Townsend @ 2014-10-20 14:39 UTC (permalink / raw)
To: linux-bluetooth, linux-wpan
Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
Martin Townsend
In-Reply-To: <1413815991-5078-1-git-send-email-martin.townsend@xsilon.com>
Separating skb delivery from decompression ensures that we can support further
decompression schemes and removes the mixed return value of error codes with
NET_RX_FOO.
Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
---
include/net/6lowpan.h | 4 +---
net/6lowpan/iphc.c | 32 ++++++--------------------------
net/bluetooth/6lowpan.c | 12 +++++++++++-
net/ieee802154/6lowpan_rtnl.c | 26 ++++++++++++++------------
4 files changed, 32 insertions(+), 42 deletions(-)
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index d184df1..abfa359 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -372,12 +372,10 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
return skb->len + uncomp_header - ret;
}
-typedef int (*skb_delivery_cb)(struct sk_buff *skb, struct net_device *dev);
-
int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
- u8 iphc0, u8 iphc1, skb_delivery_cb skb_deliver);
+ u8 iphc0, u8 iphc1);
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len);
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 747b3cc..45714fe 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -171,29 +171,6 @@ static int uncompress_context_based_src_addr(struct sk_buff *skb,
return 0;
}
-static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
- struct net_device *dev, skb_delivery_cb deliver_skb)
-{
- int stat;
-
- skb_push(skb, sizeof(struct ipv6hdr));
- skb_reset_network_header(skb);
- skb_copy_to_linear_data(skb, hdr, sizeof(struct ipv6hdr));
-
- skb->protocol = htons(ETH_P_IPV6);
- skb->pkt_type = PACKET_HOST;
- skb->dev = dev;
-
- raw_dump_table(__func__, "raw skb data dump before receiving",
- skb->data, skb->len);
-
- stat = deliver_skb(skb, dev);
-
- consume_skb(skb);
-
- return stat;
-}
-
/* Uncompress function for multicast destination address,
* when M bit is set.
*/
@@ -327,7 +304,7 @@ static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
- u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb)
+ u8 iphc0, u8 iphc1)
{
struct ipv6hdr hdr = {};
u8 tmp, num_context = 0;
@@ -492,10 +469,13 @@ int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
hdr.hop_limit, &hdr.daddr);
- raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
+ skb_push(skb, sizeof(hdr));
+ skb_reset_network_header(skb);
+ skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));
- return skb_deliver(skb, &hdr, dev, deliver_skb);
+ raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
+ return 0;
drop:
kfree_skb(skb);
return -EINVAL;
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 6c5c2ef..03787e0 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -290,7 +290,7 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
return lowpan_process_data(skb, netdev,
saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
- iphc0, iphc1, give_skb_to_upper);
+ iphc0, iphc1);
drop:
kfree_skb(skb);
@@ -350,6 +350,16 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
if (ret != NET_RX_SUCCESS)
goto drop;
+ local_skb->protocol = htons(ETH_P_IPV6);
+ local_skb->pkt_type = PACKET_HOST;
+ local_skb->dev = dev;
+
+ if (give_skb_to_upper(local_skb, dev)
+ != NET_RX_SUCCESS) {
+ kfree_skb(local_skb);
+ goto drop;
+ }
+
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 0c1a49b..898d317 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -146,8 +146,9 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
if (lowpan_dev_info(entry->ldev)->real_dev == skb->dev) {
skb_cp = skb_copy(skb, GFP_ATOMIC);
if (!skb_cp) {
- stat = -ENOMEM;
- break;
+ kfree_skb(skb);
+ rcu_read_unlock();
+ return NET_RX_DROP;
}
skb_cp->dev = entry->ldev;
@@ -155,6 +156,11 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
}
rcu_read_unlock();
+ if (stat == NET_RX_SUCCESS)
+ consume_skb(skb);
+ else
+ kfree_skb(skb);
+
return stat;
}
@@ -190,8 +196,7 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
IEEE802154_ADDR_LEN, dap, da.addr_type,
- IEEE802154_ADDR_LEN, iphc0, iphc1,
- lowpan_give_skb_to_devices);
+ IEEE802154_ADDR_LEN, iphc0, iphc1);
drop:
kfree_skb(skb);
@@ -528,15 +533,8 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
/* check that it's our buffer */
if (skb->data[0] == LOWPAN_DISPATCH_IPV6) {
- skb->protocol = htons(ETH_P_IPV6);
- skb->pkt_type = PACKET_HOST;
-
/* Pull off the 1-byte of 6lowpan header. */
skb_pull(skb, 1);
-
- ret = lowpan_give_skb_to_devices(skb, NULL);
- if (ret == NET_RX_DROP)
- goto drop;
} else {
switch (skb->data[0] & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
@@ -565,7 +563,11 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
}
}
- return NET_RX_SUCCESS;
+ /* Pass IPv6 packet up to the next layer */
+ skb->protocol = htons(ETH_P_IPV6);
+ skb->pkt_type = PACKET_HOST;
+ return lowpan_give_skb_to_devices(skb, NULL);
+
drop_skb:
kfree_skb(skb);
drop:
--
1.9.1
^ permalink raw reply related
* [PATCH v2 bluetooth-next 2/4] 6lowpan: fix process_data return values
From: Martin Townsend @ 2014-10-20 14:39 UTC (permalink / raw)
To: linux-bluetooth, linux-wpan
Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
Martin Townsend
In-Reply-To: <1413815991-5078-1-git-send-email-martin.townsend@xsilon.com>
As process_data now returns just error codes fix up the calls to this
function to only drop the skb if an error code is returned.
Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
---
net/bluetooth/6lowpan.c | 2 +-
net/ieee802154/6lowpan_rtnl.c | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 03787e0..702bf3c 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -347,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
goto drop;
ret = process_data(local_skb, dev, chan);
- if (ret != NET_RX_SUCCESS)
+ if (ret < 0)
goto drop;
local_skb->protocol = htons(ETH_P_IPV6);
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index 898d317..a160d0b 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -539,14 +539,14 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
switch (skb->data[0] & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
ret = process_data(skb, &hdr);
- if (ret == NET_RX_DROP)
+ if (ret < 0)
goto drop;
break;
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
if (ret == 1) {
ret = process_data(skb, &hdr);
- if (ret == NET_RX_DROP)
+ if (ret < 0)
goto drop;
}
break;
@@ -554,7 +554,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
if (ret == 1) {
ret = process_data(skb, &hdr);
- if (ret == NET_RX_DROP)
+ if (ret < 0)
goto drop;
}
break;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 bluetooth-next 3/4] bluetooth:6lowpan: use consume_skb when packet processed successfully
From: Martin Townsend @ 2014-10-20 14:39 UTC (permalink / raw)
To: linux-bluetooth, linux-wpan
Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
Martin Townsend
In-Reply-To: <1413815991-5078-1-git-send-email-martin.townsend@xsilon.com>
From: Martin Townsend <mtownsend1973@gmail.com>
Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
---
net/bluetooth/6lowpan.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 702bf3c..6c3182f 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -337,8 +337,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
- kfree_skb(local_skb);
- kfree_skb(skb);
+ consume_skb(local_skb);
+ consume_skb(skb);
} else {
switch (skb->data[0] & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
@@ -363,7 +363,8 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
dev->stats.rx_bytes += skb->len;
dev->stats.rx_packets++;
- kfree_skb(skb);
+ consume_skb(local_skb);
+ consume_skb(skb);
break;
default:
break;
--
1.9.1
^ permalink raw reply related
* [PATCH v2 bluetooth-next 4/4] ieee802154: 6lowpan: rename process_data and lowpan_process_data
From: Martin Townsend @ 2014-10-20 14:39 UTC (permalink / raw)
To: linux-bluetooth, linux-wpan
Cc: marcel, alex.aring, jukka.rissanen, Martin Townsend,
Martin Townsend
In-Reply-To: <1413815991-5078-1-git-send-email-martin.townsend@xsilon.com>
From: Martin Townsend <mtownsend1973@gmail.com>
As we have decouple decompression from data delivery we can now rename all
occurences of process_data in receive path.
Signed-off-by: Martin Townsend <mtownsend1973@gmail.com>
Signed-off-by: Martin Townsend <martin.townsend@xsilon.com>
---
include/net/6lowpan.h | 10 ++++++----
net/6lowpan/iphc.c | 12 +++++++-----
net/bluetooth/6lowpan.c | 15 ++++++++-------
net/ieee802154/6lowpan_rtnl.c | 15 ++++++++-------
4 files changed, 29 insertions(+), 23 deletions(-)
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index abfa359..dc03d77 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -372,10 +372,12 @@ lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset)
return skb->len + uncomp_header - ret;
}
-int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
- const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
- const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
- u8 iphc0, u8 iphc1);
+int
+lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
+ const u8 *saddr, const u8 saddr_type,
+ const u8 saddr_len, const u8 *daddr,
+ const u8 daddr_type, const u8 daddr_len,
+ u8 iphc0, u8 iphc1);
int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len);
diff --git a/net/6lowpan/iphc.c b/net/6lowpan/iphc.c
index 45714fe..73a7065 100644
--- a/net/6lowpan/iphc.c
+++ b/net/6lowpan/iphc.c
@@ -301,10 +301,12 @@ err:
/* TTL uncompression values */
static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
-int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
- const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
- const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
- u8 iphc0, u8 iphc1)
+int
+lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev,
+ const u8 *saddr, const u8 saddr_type,
+ const u8 saddr_len, const u8 *daddr,
+ const u8 daddr_type, const u8 daddr_len,
+ u8 iphc0, u8 iphc1)
{
struct ipv6hdr hdr = {};
u8 tmp, num_context = 0;
@@ -480,7 +482,7 @@ drop:
kfree_skb(skb);
return -EINVAL;
}
-EXPORT_SYMBOL_GPL(lowpan_process_data);
+EXPORT_SYMBOL_GPL(lowpan_header_decompress);
static u8 lowpan_compress_addr_64(u8 **hc_ptr, u8 shift,
const struct in6_addr *ipaddr,
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 6c3182f..13b326d 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -257,8 +257,8 @@ static int give_skb_to_upper(struct sk_buff *skb, struct net_device *dev)
return netif_rx(skb_cp);
}
-static int process_data(struct sk_buff *skb, struct net_device *netdev,
- struct l2cap_chan *chan)
+static int iphc_decompress(struct sk_buff *skb, struct net_device *netdev,
+ struct l2cap_chan *chan)
{
const u8 *saddr, *daddr;
u8 iphc0, iphc1;
@@ -287,10 +287,11 @@ static int process_data(struct sk_buff *skb, struct net_device *netdev,
if (lowpan_fetch_skb_u8(skb, &iphc1))
goto drop;
- return lowpan_process_data(skb, netdev,
- saddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
- daddr, IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
- iphc0, iphc1);
+ return lowpan_header_decompress(skb, netdev,
+ saddr, IEEE802154_ADDR_LONG,
+ EUI64_ADDR_LEN, daddr,
+ IEEE802154_ADDR_LONG, EUI64_ADDR_LEN,
+ iphc0, iphc1);
drop:
kfree_skb(skb);
@@ -346,7 +347,7 @@ static int recv_pkt(struct sk_buff *skb, struct net_device *dev,
if (!local_skb)
goto drop;
- ret = process_data(local_skb, dev, chan);
+ ret = iphc_decompress(local_skb, dev, chan);
if (ret < 0)
goto drop;
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index a160d0b..b98eede 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -164,7 +164,8 @@ static int lowpan_give_skb_to_devices(struct sk_buff *skb,
return stat;
}
-static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
+static int
+iphc_decompress(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
{
u8 iphc0, iphc1;
struct ieee802154_addr_sa sa, da;
@@ -194,9 +195,9 @@ static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr)
else
dap = &da.hwaddr;
- return lowpan_process_data(skb, skb->dev, sap, sa.addr_type,
- IEEE802154_ADDR_LEN, dap, da.addr_type,
- IEEE802154_ADDR_LEN, iphc0, iphc1);
+ return lowpan_header_decompress(skb, skb->dev, sap, sa.addr_type,
+ IEEE802154_ADDR_LEN, dap, da.addr_type,
+ IEEE802154_ADDR_LEN, iphc0, iphc1);
drop:
kfree_skb(skb);
@@ -538,14 +539,14 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
} else {
switch (skb->data[0] & 0xe0) {
case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */
- ret = process_data(skb, &hdr);
+ ret = iphc_decompress(skb, &hdr);
if (ret < 0)
goto drop;
break;
case LOWPAN_DISPATCH_FRAG1: /* first fragment header */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAG1);
if (ret == 1) {
- ret = process_data(skb, &hdr);
+ ret = iphc_decompress(skb, &hdr);
if (ret < 0)
goto drop;
}
@@ -553,7 +554,7 @@ static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */
ret = lowpan_frag_rcv(skb, LOWPAN_DISPATCH_FRAGN);
if (ret == 1) {
- ret = process_data(skb, &hdr);
+ ret = iphc_decompress(skb, &hdr);
if (ret < 0)
goto drop;
}
--
1.9.1
^ permalink raw reply related
* [PATCH v5 0/2] core: Add plugin-support for Manufacturer Specific Data EIR
From: Alfonso Acosta @ 2014-10-20 14:50 UTC (permalink / raw)
To: linux-bluetooth
v5:
* rebased
* fixed warning
* fixed android compilation error
v4:
* Support for multiple MSD fields in the same EIR data block.
* Moved parsing to a separate function: eir_parse_msd()
v3:
* Corrections suggested by Johan on the handling of eir.h
* Parser sanity check on the size of the MSD payload.
* Minor typo correction on commit message.
Alfonso Acosta (2):
core: Add Manufacturer Specific Data EIR field
core: Add subscription API for Manufacturer Specific Data
src/adapter.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/adapter.h | 10 ++++++++++
src/eir.c | 22 ++++++++++++++++++++++
src/eir.h | 10 ++++++++++
4 files changed, 87 insertions(+)
--
1.9.1
^ permalink raw reply
* [PATCH v5 1/2] core: Add Manufacturer Specific Data EIR field
From: Alfonso Acosta @ 2014-10-20 14:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1413816661-19290-1-git-send-email-fons@spotify.com>
Add data structure and parsing support.
---
src/eir.c | 22 ++++++++++++++++++++++
src/eir.h | 10 ++++++++++
2 files changed, 32 insertions(+)
diff --git a/src/eir.c b/src/eir.c
index d22ad91..2ea8731 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -53,6 +53,8 @@ void eir_data_free(struct eir_data *eir)
eir->hash = NULL;
g_free(eir->randomizer);
eir->randomizer = NULL;
+ g_slist_free_full(eir->msd_list, g_free);
+ eir->msd_list = NULL;
}
static void eir_parse_uuid16(struct eir_data *eir, const void *data,
@@ -137,6 +139,22 @@ static char *name2utf8(const uint8_t *name, uint8_t len)
return g_strdup(utf8_name);
}
+static void eir_parse_msd(struct eir_data *eir, const uint8_t *data,
+ uint8_t len)
+{
+ struct eir_msd *msd;
+
+ if (len < 2 || len > 2 + sizeof(msd->data))
+ return;
+
+ msd = g_malloc(sizeof(*msd));
+ msd->company = get_le16(data);
+ msd->data_len = len - 2;
+ memcpy(&msd->data, data + 2, msd->data_len);
+
+ eir->msd_list = g_slist_append(eir->msd_list, msd);
+}
+
void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len)
{
uint16_t len = 0;
@@ -240,6 +258,10 @@ void eir_parse(struct eir_data *eir, const uint8_t *eir_data, uint8_t eir_len)
eir->did_product = data[4] | (data[5] << 8);
eir->did_version = data[6] | (data[7] << 8);
break;
+
+ case EIR_MANUFACTURER_DATA:
+ eir_parse_msd(eir, data, data_len);
+ break;
}
eir_data += field_len + 1;
diff --git a/src/eir.h b/src/eir.h
index e486fa2..86a9527 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -22,6 +22,8 @@
*
*/
+#include <hci.h>
+
#define EIR_FLAGS 0x01 /* flags */
#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
@@ -37,6 +39,7 @@
#define EIR_SSP_RANDOMIZER 0x0F /* SSP Randomizer */
#define EIR_DEVICE_ID 0x10 /* device ID */
#define EIR_GAP_APPEARANCE 0x19 /* GAP appearance */
+#define EIR_MANUFACTURER_DATA 0xFF /* Manufacturer Specific Data */
/* Flags Descriptions */
#define EIR_LIM_DISC 0x01 /* LE Limited Discoverable Mode */
@@ -47,6 +50,12 @@
#define EIR_SIM_HOST 0x10 /* Simultaneous LE and BR/EDR to Same
Device Capable (Host) */
+struct eir_msd {
+ uint16_t company;
+ uint8_t data[HCI_MAX_EIR_LENGTH];
+ uint8_t data_len;
+};
+
struct eir_data {
GSList *services;
unsigned int flags;
@@ -62,6 +71,7 @@ struct eir_data {
uint16_t did_product;
uint16_t did_version;
uint16_t did_source;
+ GSList *msd_list;
};
void eir_data_free(struct eir_data *eir);
--
1.9.1
^ permalink raw reply related
* [PATCH v5 2/2] core: Add subscription API for Manufacturer Specific Data
From: Alfonso Acosta @ 2014-10-20 14:51 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1413816661-19290-1-git-send-email-fons@spotify.com>
This patch allows plugins to be notified whenever an adapter receives
Manufacturer Specific Data in the advertising reports from a device.
This can happen when new device is discovered or when we autoconnect
to it.
---
src/adapter.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/adapter.h | 10 ++++++++++
2 files changed, 55 insertions(+)
diff --git a/src/adapter.c b/src/adapter.c
index 1a7d4eb..54e7496 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -206,6 +206,7 @@ struct btd_adapter {
gboolean initialized;
GSList *pin_callbacks;
+ GSList *msd_callbacks;
GSList *drivers;
GSList *profiles;
@@ -4549,6 +4550,9 @@ static void adapter_remove(struct btd_adapter *adapter)
g_slist_free(adapter->pin_callbacks);
adapter->pin_callbacks = NULL;
+
+ g_slist_free(adapter->msd_callbacks);
+ adapter->msd_callbacks = NULL;
}
const char *adapter_get_path(struct btd_adapter *adapter)
@@ -4647,6 +4651,29 @@ static void confirm_name(struct btd_adapter *adapter, const bdaddr_t *bdaddr,
confirm_name_timeout, adapter);
}
+static void adapter_msd_notify(struct btd_adapter *adapter,
+ struct btd_device *dev,
+ GSList *msd_list)
+{
+ GSList *cb_l, *cb_next;
+ GSList *msd_l, *msd_next;
+
+ for (cb_l = adapter->msd_callbacks; cb_l != NULL; cb_l = cb_next) {
+ btd_msd_cb_t cb = cb_l->data;
+
+ cb_next = g_slist_next(cb_l);
+
+ for (msd_l = msd_list; msd_l != NULL; msd_l = msd_next) {
+ const struct eir_msd *msd = msd_l->data;
+
+ msd_next = g_slist_next(msd_l);
+
+ cb(adapter, dev, msd->company, msd->data,
+ msd->data_len);
+ }
+ }
+}
+
static void update_found_devices(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type, int8_t rssi,
@@ -4738,6 +4765,9 @@ static void update_found_devices(struct btd_adapter *adapter,
device_add_eir_uuids(dev, eir_data.services);
+ if (eir_data.msd_list)
+ adapter_msd_notify(adapter, dev, eir_data.msd_list);
+
eir_data_free(&eir_data);
/*
@@ -5173,6 +5203,18 @@ void btd_adapter_unregister_pin_cb(struct btd_adapter *adapter,
adapter->pin_callbacks = g_slist_remove(adapter->pin_callbacks, cb);
}
+void btd_adapter_unregister_msd_cb(struct btd_adapter *adapter,
+ btd_msd_cb_t cb)
+{
+ adapter->msd_callbacks = g_slist_remove(adapter->msd_callbacks, cb);
+}
+
+void btd_adapter_register_msd_cb(struct btd_adapter *adapter,
+ btd_msd_cb_t cb)
+{
+ adapter->msd_callbacks = g_slist_prepend(adapter->msd_callbacks, cb);
+}
+
int btd_adapter_set_fast_connectable(struct btd_adapter *adapter,
gboolean enable)
{
@@ -6663,6 +6705,9 @@ static void connected_callback(uint16_t index, uint16_t length,
btd_device_device_set_name(device, eir_data.name);
}
+ if (eir_data.msd_list)
+ adapter_msd_notify(adapter, device, eir_data.msd_list);
+
eir_data_free(&eir_data);
}
diff --git a/src/adapter.h b/src/adapter.h
index 6801fee..8f4098a 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -138,6 +138,16 @@ struct btd_adapter_pin_cb_iter *btd_adapter_pin_cb_iter_new(
void btd_adapter_pin_cb_iter_free(struct btd_adapter_pin_cb_iter *iter);
bool btd_adapter_pin_cb_iter_end(struct btd_adapter_pin_cb_iter *iter);
+typedef void (*btd_msd_cb_t) (struct btd_adapter *adapter,
+ struct btd_device *dev,
+ uint16_t company,
+ const uint8_t *data,
+ uint8_t data_len);
+void btd_adapter_register_msd_cb(struct btd_adapter *adapter,
+ btd_msd_cb_t cb);
+void btd_adapter_unregister_msd_cb(struct btd_adapter *adapter,
+ btd_msd_cb_t cb);
+
/* If TRUE, enables fast connectabe, i.e. reduces page scan interval and changes
* type. If FALSE, disables fast connectable, i.e. sets page scan interval and
* type to default values. Valid for both connectable and discoverable modes. */
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v4 2/2] core: Add subscription API for Manufacturer Specific Data
From: Alfonso Acosta @ 2014-10-20 14:53 UTC (permalink / raw)
To: Alfonso Acosta, BlueZ development
In-Reply-To: <CAHF=Y4q0ZRbGAUMtMi5vA13hQFn8JCmu+7B1rLdRxDSO6jxiCg@mail.gmail.com>
Hi Johan,
>
> This patch also doesn't compile (the error from the first patch might
> have gone away, but then there's this new one):
>
> src/adapter.c:4654:6: error: no previous declaration for ‘adapter_msd_notify’ [-Werror=missing-declarations]
> void adapter_msd_notify(struct btd_adapter *adapter, struct btd_device *dev,
> ^
> cc1: all warnings being treated as errors
> make[1]: *** [src/bluetoothd-adapter.o] Error 1
v5 corrects this problem.
I didn't know that -Wall is only enabled when passing
--enable-maintainer-mode to configure (which I wasn't doing).
--
Alfonso Acosta
Embedded Systems Engineer at Spotify
Birger Jarlsgatan 61, Stockholm, Sweden
http://www.spotify.com
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox