* RE: L2cap Security And Role Switch
From: Waldemar.Rymarkiewicz @ 2010-08-05 12:54 UTC (permalink / raw)
To: mcprabhakaran; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikQMqvPQ8-Gv6CqSGgL0fv7ZV3ji4TQUvgkQFGe@mail.gmail.com>
Hi
>-----Original Message-----
>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>Sent: Thursday, August 05, 2010 2:44 PM
>To: Rymarkiewicz Waldemar
>Cc: linux-bluetooth@vger.kernel.org
>Subject: Re: L2cap Security And Role Switch
>
>Hi ,
>
>2010/8/5 <Waldemar.Rymarkiewicz@tieto.com>:
>> Hi,
>>
>>>-----Original Message-----
>>>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>>>Sent: Thursday, August 05, 2010 12:38 PM
>>>To: Rymarkiewicz Waldemar
>>>Cc: linux-bluetooth@vger.kernel.org
>>>Subject: Re: L2cap Security And Role Switch
>>>
>>>Hi Waldek,
>>>
>>>On Thu, Aug 5, 2010 at 3:37 PM,
>>><Waldemar.Rymarkiewicz@tieto.com> wrote:
>>>> Hi,
>>>>
>>>>>-----Original Message-----
>>>>>From: linux-bluetooth-owner@vger.kernel.org
>>>>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>>>>>Prabhakaran M.C
>>>>>Sent: Wednesday, August 04, 2010 4:09 PM
>>>>>To: linux-bluetooth@vger.kernel.org
>>>>>Subject: Reg: L2cap Security And Role Switch
>>>>>
>>>>>Hello All,
>>>>>
>>>>> Whenever L2cap security is HIGH and remote device does
>role switch,
>>>>>Bluez accepts the Role switch and L2cap disconnects the channel
>>>>>because of HIGH security.
>>>>>
>>>>> For PAN profile, I would like to keep the L2cap security to HIGH
>>>>>since it involves internet browsing but the Widcomm stack
>>>always does
>>>>>a role switch in PAN connection and Bluez disconnects
>l2cap channel.
>>>>>
>>>>> Can someone please point in specification about the l2cap
>security
>>>>>level and Role switch relation. I tried to find out this
>but I could
>>>>>not get this behavior described in specification. Please
>>>provide your
>>>>>comments and inputs. Thanks in Advance.
>>>>>
>>>>>Thanks,
>>>>>Prabhakaran.
>>>>>--
>>>>
>>>> Note that HIGH sec level requires encription on the link.
>>>Role switch procedure turn off the encription before it starts
>>>switching roles and turn on it again after all. In 2.1 spec the
>>>controller handles switching off/on encription (pause/resume).
>>>>
>>>> Thanks,
>>>> /Waldek
>>>
>>> From the logs, the link was authenticated and encrypted.
>>>Then Widcomm stack disables the encryption, does a role switch,
>>>enables the encryption.
>>>After role switch bluez kernel disconnects l2cap channel due to HIGH
>>>security. I just want to know where this disconnection part
>is defined
>>>in spec. Or Bluez has to just reject the role switch
>operation instead
>>>of disconnection?
>>>
>>>--
>>>Thanks,
>>>Prabhakaran.
>>
>> As far as I know it's not defined in the spec. It's simply
>Bluez design. What I would like to see, the bluez should block
>outgoing data flow in l2cap for the period of role switch.
>> It's done in rfcomm this way, I guess (?).
>>
>> I agree, in my view the current desing in this use case is
>not perfect.
>>
>> Thanks,
>> /Waldek
>>
>>
>>
>>
>>
>>
>>
>
>Thanks for your response.
>One small correction here (My Bad). The l2cap channel is
>getting closed because encryption of the link goes down during
>role switch.
>"l2cap_check_encryption" function validates the encryption, if
>it is disabled and security is high then channel is getting
>closed by this function. Please let me know your comments about this.
>
>--
>Thanks,
>Prabhakaran.
As I said, if the encryption is disabled due to role switch, l2cap should block data flow and wait some time when the encription is switched on again. If this will not occur l2cap shoudl close the channel otherwise should continue as before the role switch.
Thanks,
/Waldek
^ permalink raw reply
* Re: L2cap Security And Role Switch
From: Prabhakaran M.C @ 2010-08-05 12:43 UTC (permalink / raw)
To: Waldemar.Rymarkiewicz; +Cc: linux-bluetooth
In-Reply-To: <99B09243E1A5DA4898CDD8B700111448096BA3C277@EXMB04.eu.tieto.com>
Hi ,
2010/8/5 <Waldemar.Rymarkiewicz@tieto.com>:
> Hi,
>
>>-----Original Message-----
>>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>>Sent: Thursday, August 05, 2010 12:38 PM
>>To: Rymarkiewicz Waldemar
>>Cc: linux-bluetooth@vger.kernel.org
>>Subject: Re: L2cap Security And Role Switch
>>
>>Hi Waldek,
>>
>>On Thu, Aug 5, 2010 at 3:37 PM,
>><Waldemar.Rymarkiewicz@tieto.com> wrote:
>>> Hi,
>>>
>>>>-----Original Message-----
>>>>From: linux-bluetooth-owner@vger.kernel.org
>>>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>>>>Prabhakaran M.C
>>>>Sent: Wednesday, August 04, 2010 4:09 PM
>>>>To: linux-bluetooth@vger.kernel.org
>>>>Subject: Reg: L2cap Security And Role Switch
>>>>
>>>>Hello All,
>>>>
>>>> Whenever L2cap security is HIGH and remote device does role switch,
>>>>Bluez accepts the Role switch and L2cap disconnects the channel
>>>>because of HIGH security.
>>>>
>>>> For PAN profile, I would like to keep the L2cap security to HIGH
>>>>since it involves internet browsing but the Widcomm stack
>>always does
>>>>a role switch in PAN connection and Bluez disconnects l2cap channel.
>>>>
>>>> Can someone please point in specification about the l2cap security
>>>>level and Role switch relation. I tried to find out this but I could
>>>>not get this behavior described in specification. Please
>>provide your
>>>>comments and inputs. Thanks in Advance.
>>>>
>>>>Thanks,
>>>>Prabhakaran.
>>>>--
>>>
>>> Note that HIGH sec level requires encription on the link.
>>Role switch procedure turn off the encription before it
>>starts switching roles and turn on it again after all. In 2.1
>>spec the controller handles switching off/on encription (pause/resume).
>>>
>>> Thanks,
>>> /Waldek
>>
>> From the logs, the link was authenticated and encrypted.
>>Then Widcomm stack disables the encryption, does a role
>>switch, enables the encryption.
>>After role switch bluez kernel disconnects l2cap channel due
>>to HIGH security. I just want to know where this disconnection
>>part is defined in spec. Or Bluez has to just reject the role
>>switch operation instead of disconnection?
>>
>>--
>>Thanks,
>>Prabhakaran.
>
> As far as I know it's not defined in the spec. It's simply Bluez design. What I would like to see, the bluez should block outgoing data flow in l2cap for the period of role switch.
> It's done in rfcomm this way, I guess (?).
>
> I agree, in my view the current desing in this use case is not perfect.
>
> Thanks,
> /Waldek
>
>
>
>
>
>
>
Thanks for your response.
One small correction here (My Bad). The l2cap channel is getting
closed because encryption of the link goes down during role switch.
"l2cap_check_encryption" function validates the encryption, if it is
disabled and security is high then channel is getting closed by this
function. Please let me know your comments about this.
--
Thanks,
Prabhakaran.
^ permalink raw reply
* RE: L2cap Security And Role Switch
From: Waldemar.Rymarkiewicz @ 2010-08-05 10:53 UTC (permalink / raw)
To: mcprabhakaran; +Cc: linux-bluetooth
In-Reply-To: <AANLkTikLE+ybEx=9SOQNEhc5hptMXmcuHwyX3EY69XYD@mail.gmail.com>
Hi,
>-----Original Message-----
>From: Prabhakaran M.C [mailto:mcprabhakaran@gmail.com]
>Sent: Thursday, August 05, 2010 12:38 PM
>To: Rymarkiewicz Waldemar
>Cc: linux-bluetooth@vger.kernel.org
>Subject: Re: L2cap Security And Role Switch
>
>Hi Waldek,
>
>On Thu, Aug 5, 2010 at 3:37 PM,
><Waldemar.Rymarkiewicz@tieto.com> wrote:
>> Hi,
>>
>>>-----Original Message-----
>>>From: linux-bluetooth-owner@vger.kernel.org
>>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>>>Prabhakaran M.C
>>>Sent: Wednesday, August 04, 2010 4:09 PM
>>>To: linux-bluetooth@vger.kernel.org
>>>Subject: Reg: L2cap Security And Role Switch
>>>
>>>Hello All,
>>>
>>> Whenever L2cap security is HIGH and remote device does role switch,
>>>Bluez accepts the Role switch and L2cap disconnects the channel
>>>because of HIGH security.
>>>
>>> For PAN profile, I would like to keep the L2cap security to HIGH
>>>since it involves internet browsing but the Widcomm stack
>always does
>>>a role switch in PAN connection and Bluez disconnects l2cap channel.
>>>
>>> Can someone please point in specification about the l2cap security
>>>level and Role switch relation. I tried to find out this but I could
>>>not get this behavior described in specification. Please
>provide your
>>>comments and inputs. Thanks in Advance.
>>>
>>>Thanks,
>>>Prabhakaran.
>>>--
>>
>> Note that HIGH sec level requires encription on the link.
>Role switch procedure turn off the encription before it
>starts switching roles and turn on it again after all. In 2.1
>spec the controller handles switching off/on encription (pause/resume).
>>
>> Thanks,
>> /Waldek
>
> From the logs, the link was authenticated and encrypted.
>Then Widcomm stack disables the encryption, does a role
>switch, enables the encryption.
>After role switch bluez kernel disconnects l2cap channel due
>to HIGH security. I just want to know where this disconnection
>part is defined in spec. Or Bluez has to just reject the role
>switch operation instead of disconnection?
>
>--
>Thanks,
>Prabhakaran.
As far as I know it's not defined in the spec. It's simply Bluez design. What I would like to see, the bluez should block outgoing data flow in l2cap for the period of role switch.
It's done in rfcomm this way, I guess (?).
I agree, in my view the current desing in this use case is not perfect.
Thanks,
/Waldek
^ permalink raw reply
* Re: L2cap Security And Role Switch
From: Prabhakaran M.C @ 2010-08-05 10:38 UTC (permalink / raw)
To: Waldemar.Rymarkiewicz; +Cc: linux-bluetooth
In-Reply-To: <99B09243E1A5DA4898CDD8B700111448096BA3C23C@EXMB04.eu.tieto.com>
Hi Waldek,
On Thu, Aug 5, 2010 at 3:37 PM, <Waldemar.Rymarkiewicz@tieto.com> wrote:
> Hi,
>
>>-----Original Message-----
>>From: linux-bluetooth-owner@vger.kernel.org
>>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>>Prabhakaran M.C
>>Sent: Wednesday, August 04, 2010 4:09 PM
>>To: linux-bluetooth@vger.kernel.org
>>Subject: Reg: L2cap Security And Role Switch
>>
>>Hello All,
>>
>> Whenever L2cap security is HIGH and remote device does role
>>switch, Bluez accepts the Role switch and L2cap disconnects
>>the channel because of HIGH security.
>>
>> For PAN profile, I would like to keep the L2cap security to
>>HIGH since it involves internet browsing but the Widcomm stack
>>always does a role switch in PAN connection and Bluez
>>disconnects l2cap channel.
>>
>> Can someone please point in specification about the l2cap
>>security level and Role switch relation. I tried to find out
>>this but I could not get this behavior described in
>>specification. Please provide your comments and inputs. Thanks
>>in Advance.
>>
>>Thanks,
>>Prabhakaran.
>>--
>
> Note that HIGH sec level requires encription on the link. Role switch procedure turn off the encription before it starts switching roles and turn on it again after all. In 2.1 spec the controller handles switching off/on encription (pause/resume).
>
> Thanks,
> /Waldek
From the logs, the link was authenticated and encrypted.
Then Widcomm stack disables the encryption, does a role switch,
enables the encryption.
After role switch bluez kernel disconnects l2cap channel due to HIGH
security. I just want to know where this disconnection part is defined
in spec. Or Bluez has to just reject the role switch operation instead
of disconnection?
--
Thanks,
Prabhakaran.
^ permalink raw reply
* Re: [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Johan Hedberg @ 2010-08-05 10:25 UTC (permalink / raw)
To: Inga Stotland; +Cc: linux-bluetooth, rshaffer, marcel
In-Reply-To: <1280962831-18147-8-git-send-email-ingas@codeaurora.org>
Hi Inga,
On Wed, Aug 04, 2010, Inga Stotland wrote:
> ---
> src/adapter.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
> src/adapter.h | 4 +-
> src/dbus-hci.c | 6 ++--
> 3 files changed, 102 insertions(+), 8 deletions(-)
I've pushed the six other patches upstream, but I'm still a bit
concerned with this one. First there's a minor coding style issue:
> +static char **get_eir_uuids(uint8_t *eir_data, size_t *uuid_count)
> +{
> + uint8_t len = 0;
> + char **uuids = NULL;
> + size_t total = 0;
Neither the uuids nor the total variable need to be initialized upon
declaration if you look at the function's code flow. In general
initialization upon declaration of variables is something that should be
avoided whenever not strictly needed since it can hide real issues that
the compiler would otherwise be able to catch.
Then, a more general concern about this function. It will receive data
as input that any nearby device that's discoverable has declared in
their EIR data. I.e. we need to be super strict about checking the
validity of the data and not make any assumptions about the correctness
of encoded field lengths etc. in order not to do buffer overflows. Have
you taken this into account when designing the function? Looking at it
it seems it might be possible to give it data that will cause some
buffer overflows (by e.g. placing a uuid list at the very end of the EIR
data with an invalid field length value).
Johan
^ permalink raw reply
* RE: L2cap Security And Role Switch
From: Waldemar.Rymarkiewicz @ 2010-08-05 10:07 UTC (permalink / raw)
To: mcprabhakaran, linux-bluetooth
In-Reply-To: <AANLkTimAktDFG+abbsMpgKfkNtmX3tqqhwXd-OZwgRWj@mail.gmail.com>
Hi,
>-----Original Message-----
>From: linux-bluetooth-owner@vger.kernel.org
>[mailto:linux-bluetooth-owner@vger.kernel.org] On Behalf Of
>Prabhakaran M.C
>Sent: Wednesday, August 04, 2010 4:09 PM
>To: linux-bluetooth@vger.kernel.org
>Subject: Reg: L2cap Security And Role Switch
>
>Hello All,
>
> Whenever L2cap security is HIGH and remote device does role
>switch, Bluez accepts the Role switch and L2cap disconnects
>the channel because of HIGH security.
>
> For PAN profile, I would like to keep the L2cap security to
>HIGH since it involves internet browsing but the Widcomm stack
>always does a role switch in PAN connection and Bluez
>disconnects l2cap channel.
>
> Can someone please point in specification about the l2cap
>security level and Role switch relation. I tried to find out
>this but I could not get this behavior described in
>specification. Please provide your comments and inputs. Thanks
>in Advance.
>
>Thanks,
>Prabhakaran.
>--
Note that HIGH sec level requires encription on the link. Role switch procedure turn off the encription before it starts switching roles and turn on it again after all. In 2.1 spec the controller handles switching off/on encription (pause/resume).
Thanks,
/Waldek
^ permalink raw reply
* Re: Changes in HDP API
From: José Antonio Santos Cadenas @ 2010-08-05 9:29 UTC (permalink / raw)
To: Elvis Pfützenreuter; +Cc: linux-bluetooth
In-Reply-To: <0AEF6BD1-2A78-47E2-9445-87D78E4C85F8@signove.com>
El Wednesday 04 August 2010 20:22:29 Elvis Pfützenreuter escribió:
> On 04/08/2010, at 04:49, Jose Antonio Santos Cadenas wrote:
> > This patch makes some changes in the HDP API based in the conversation
> > that I had yesterday with Luiz and Elvis.
> >
> > I still have a doubt about the notification of devices in the agent. Luiz
> > commented that with this API the Agent and the Application could not be
> > in different processes, is this a problem?
>
> Is not a problem and IMHO it does not make sense at all. The Agent in HDP
> API context is as a mere vehicle for callbacks, because signals are seen
> by every process while the nature of health devices demands some
> privacy/secrecy (I have a faint memory about privacy being a general
> requirement for IEEE protocol as well as Continua certification.)
I've been thinking about this issue and I'm changing my opinion about this a
little bit. I will expose my "new" view and later today I will send a new API
proposal if you think this approach is OK.
In fact the privacy issue should concern to the data that is being transmitted
over the data channel, not the creation and destruction of the data channel.
If we start from that point. Sending new channel events as signals will not be
a privacy problem if we protect the data channel itself.
The DataChannel object (as is defined in the current API) could be protected
and only reply to method calls from the process owner of the application that
waited for this data channel (if it was opened by the remote side) or from the
creator of the data channel (if it was opened by the local side). This way
only this process will be able to get the file descriptor (what means get
access to the data) and to manage the connection closing, reconnecting or
deleting the data channel. So in this way the privacy of the data is
guaranteed.
An other thing to take into account is that all the application will be
bothered with signals of data channel creation an deletion even when they
could not use them. But I thing that this is not too much extra load because
in a typical scenario only one or two application will be interested in health
data channels.
>
> The agent is always coupled with an application. The most typical usage of
> BlueZ HDP is as sink role, which means the application creates the
> application, which publishes the role via SDP, and sits idle until some
> source connects, which is notified via the agent.
Regards.
^ permalink raw reply
* Re: [PATCH 5/9] Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM.
From: Gustavo F. Padovan @ 2010-08-05 4:20 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <1280962146-22604-6-git-send-email-mathewm@codeaurora.org>
Hi Mat,
* Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:49:02 -0700]:
> remote_tx_win is intended to be set on receipt of an L2CAP
> configuration request. The value is used to determine the size of the
> transmit window on the remote side of an ERTM connection, so L2CAP
> can stop sending frames when that remote window is full.
>
> An incorrect remote_tx_win value will cause the stack to not fully
> utilize the tx window (performance impact), or to overfill the remote
> tx window (causing dropped frames or a disconnect).
>
> This patch removes an extra setting of remote_tx_win when a
> configuration response is received. The transmit window has a
> different meaning in a response - it is an informational value
> less than or equal to the local tx_win.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 1 -
> 1 files changed, 0 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 8cf9569..f0f3c7c 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -2808,7 +2808,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
> if (*result == L2CAP_CONF_SUCCESS) {
> switch (rfc.mode) {
> case L2CAP_MODE_ERTM:
> - pi->remote_tx_win = rfc.txwin_size;
> pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
> pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
> pi->mps = le16_to_cpu(rfc.max_pdu_size);
I agree. But you may also want to remove the same check inside
l2cap_conf_rfc_get()
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: [PATCH 4/9] Bluetooth: Fix endianness issue with L2CAP MPS configuration.
From: Gustavo F. Padovan @ 2010-08-05 4:00 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <1280962146-22604-5-git-send-email-mathewm@codeaurora.org>
Hi Mat,
* Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:49:01 -0700]:
> Incoming configuration values must be converted to native CPU order
> before use. This fixes a bug where a little-endian MPS value is
> compared to a native CPU value. On big-endian processors, this
> can cause ERTM and streaming mode segmentation to produce PDUs
> that are larger than the remote stack is expecting, or that would
> produce fragmented skbs that the current FCS code cannot handle.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 9 ++++-----
> 1 files changed, 4 insertions(+), 5 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 920a53f..8cf9569 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -2708,10 +2708,10 @@ done:
> case L2CAP_MODE_ERTM:
> pi->remote_tx_win = rfc.txwin_size;
> pi->remote_max_tx = rfc.max_transmit;
> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
> - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
>
> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
> + if (pi->remote_mps > pi->conn->mtu - 10)
> + pi->remote_mps = pi->conn->mtu - 10;
What happened with thte "rfc.max_pdu_size =" attribution. We have the
send the value to through the RFC option. So what I do propose here is:
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 0f34e12..11d4405 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2705,7 +2705,7 @@ done:
case L2CAP_MODE_ERTM:
pi->remote_tx_win = rfc.txwin_size;
pi->remote_max_tx = rfc.max_transmit;
- if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
@@ -2723,7 +2723,7 @@ done:
break;
case L2CAP_MODE_STREAMING:
- if (rfc.max_pdu_size > pi->conn->mtu - 10)
+ if (le16_to_cpu(rfc.max_pdu_size) > pi->conn->mtu - 10)
rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
>
> rfc.retrans_timeout =
> le16_to_cpu(L2CAP_DEFAULT_RETRANS_TO);
> @@ -2726,10 +2726,9 @@ done:
> break;
>
> case L2CAP_MODE_STREAMING:
> - if (rfc.max_pdu_size > pi->conn->mtu - 10)
> - rfc.max_pdu_size = le16_to_cpu(pi->conn->mtu - 10);
> -
> pi->remote_mps = le16_to_cpu(rfc.max_pdu_size);
> + if (pi->remote_mps > pi->conn->mtu - 10)
> + pi->remote_mps = pi->conn->mtu - 10;
>
> pi->conf_state |= L2CAP_CONF_MODE_DONE;
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply related
* Re: [PATCH 1/9] Bluetooth: Only enable for L2CAP FCS for ERTM or streaming.
From: Gustavo F. Padovan @ 2010-08-05 3:38 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <1280962146-22604-2-git-send-email-mathewm@codeaurora.org>
HI Mat,
You are adding to spaces after "Bluetooth:" and the commit message, one is
fine. All the patches have this issue.
* Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:48:58 -0700]:
> This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16
> with L2CAP modes other than ERTM or streaming. At present, this only
> affects the FCS value shown with getsockopt() for basic mode.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 17 +++++++++++++----
> 1 files changed, 13 insertions(+), 4 deletions(-)
>
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: [PATCH 1/9] Bluetooth: Only enable for L2CAP FCS for ERTM or streaming.
From: Gustavo F. Padovan @ 2010-08-05 3:32 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <1280962146-22604-2-git-send-email-mathewm@codeaurora.org>
Hi Mat,
* Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:48:58 -0700]:
> This fixes a bug which caused the FCS setting to show L2CAP_FCS_CRC16
> with L2CAP modes other than ERTM or streaming. At present, this only
> affects the FCS value shown with getsockopt() for basic mode.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> net/bluetooth/l2cap.c | 17 +++++++++++++----
> 1 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index 9ba1e8e..a2706d9 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -3063,6 +3063,17 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
> return 0;
> }
>
> +static inline int l2cap_fcs_needed(struct l2cap_pinfo *pi)
> +{
> + if (pi->mode != L2CAP_MODE_ERTM && pi->mode != L2CAP_MODE_STREAMING)
> + return 0;
> + else {
> + /* FCS is enabled if one or both sides request it. */
> + return !(pi->conf_state & L2CAP_CONF_NO_FCS_RECV) ||
> + pi->fcs == L2CAP_FCS_CRC16;
> + }
Get ride of the else, just put the return !(pi->....
Also I would like to see the use case for the check for the ERTM and
Streaming before merge this patch. ;)
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* Re: [PATCH 2/9] Bluetooth: Change default ERTM retransmit timeout.
From: Gustavo F. Padovan @ 2010-08-05 3:29 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, marcel, rshaffer, linux-arm-msm
In-Reply-To: <1280962146-22604-3-git-send-email-mathewm@codeaurora.org>
Hi Mat,
* Mat Martineau <mathewm@codeaurora.org> [2010-08-04 15:48:59 -0700]:
> The L2CAP spec requires that the ERTM retransmit timeout be at least 2
> seconds for BR/EDR connections.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
> ---
> include/net/bluetooth/l2cap.h | 2 +-
> 1 files changed, 1 insertions(+), 1 deletions(-)
>
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 636724b..16e412f 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -33,7 +33,7 @@
> #define L2CAP_DEFAULT_FLUSH_TO 0xffff
> #define L2CAP_DEFAULT_TX_WINDOW 63
> #define L2CAP_DEFAULT_MAX_TX 3
> -#define L2CAP_DEFAULT_RETRANS_TO 1000 /* 1 second */
> +#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
> #define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
> #define L2CAP_DEFAULT_MAX_PDU_SIZE 672
> #define L2CAP_DEFAULT_ACK_TO 200
The spec says that a 2 seconds retransmission timeout shall be used
after a move channel operation in a BR/EDR radio. (section 8.6.2.3)
For a normal ACL connection the default value is 1 second(section
8.6.2.1), so I prefer to keep L2CAP_DEFAULT_RETRANS_TO set to 1000.
--
Gustavo F. Padovan
http://padovan.org
^ permalink raw reply
* [PATCH 7/7] Add service UUIDs from EIR to device properties in "Device Found" signal.
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/adapter.c | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/adapter.h | 4 +-
src/dbus-hci.c | 6 ++--
3 files changed, 102 insertions(+), 8 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index c142a4a..d191014 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2749,8 +2749,94 @@ static void emit_device_found(const char *path, const char *address,
g_dbus_send_message(connection, signal);
}
+static char **get_eir_uuids(uint8_t *eir_data, size_t *uuid_count)
+{
+ uint8_t len = 0;
+ char **uuids = NULL;
+ size_t total = 0;
+ size_t uuid16_count = 0;
+ size_t uuid32_count = 0;
+ size_t uuid128_count = 0;
+ uint8_t *uuid16;
+ uint8_t *uuid32;
+ uint8_t *uuid128;
+ uuid_t service;
+ int i;
+
+ while (len < EIR_DATA_LENGTH) {
+ uint8_t type = eir_data[1];
+ uint8_t field_len = eir_data[0];
+
+ switch (type) {
+ case EIR_UUID16_SOME:
+ case EIR_UUID16_ALL:
+ uuid16_count = field_len / 2;
+ uuid16 = &eir_data[2];
+ break;
+ case EIR_UUID32_SOME:
+ case EIR_UUID32_ALL:
+ uuid32_count = field_len / 4;
+ uuid32 = &eir_data[2];
+ break;
+ case EIR_UUID128_SOME:
+ case EIR_UUID128_ALL:
+ uuid128_count = field_len / 16;
+ uuid128 = &eir_data[2];
+ break;
+ }
+
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+
+ total = uuid16_count + uuid32_count + uuid128_count;
+ *uuid_count = total;
+
+ if (!total)
+ return NULL;
+
+ uuids = g_new0(char *, total + 1);
+
+ /* Generate uuids in SDP format (EIR data is Little Endian) */
+ service.type = SDP_UUID16;
+ for (i = 0; i < uuid16_count; i++) {
+ uint16_t val16 = uuid16[1];
+
+ val16 = (val16 << 8) + uuid16[0];
+ service.value.uuid16 = val16;
+ uuids[i] = bt_uuid2string(&service);
+ uuid16 += 2;
+ }
+
+ service.type = SDP_UUID32;
+ for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+ uint32_t val32 = uuid32[3];
+ int k;
+
+ for (k = 2; k >= 0; k--)
+ val32 = (val32 << 8) + uuid32[k];
+
+ service.value.uuid32 = val32;
+ uuids[i] = bt_uuid2string(&service);
+ uuid32 += 4;
+ }
+
+ service.type = SDP_UUID128;
+ for (i = uuid32_count + uuid16_count; i < total; i++) {
+ int k;
+
+ for (k = 0; k < 16; k++)
+ service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+ uuids[i] = bt_uuid2string(&service);
+ uuid128 += 16;
+ }
+
+ return uuids;
+}
+
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev)
+ struct remote_dev_info *dev, uint8_t *eir_data)
{
struct btd_device *device;
char peer_addr[18], local_addr[18];
@@ -2758,6 +2844,8 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
dbus_bool_t paired = FALSE;
dbus_int16_t rssi = dev->rssi;
char *alias;
+ char **uuids = NULL;
+ size_t uuid_count = 0;
ba2str(&dev->bdaddr, peer_addr);
ba2str(&adapter->bdaddr, local_addr);
@@ -2777,6 +2865,10 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
} else
alias = g_strdup(dev->alias);
+ /* Extract UUIDs from extended inquiry response if any*/
+ if (eir_data != NULL)
+ uuids = get_eir_uuids(eir_data, &uuid_count);
+
emit_device_found(adapter->path, paddr,
"Address", DBUS_TYPE_STRING, &paddr,
"Class", DBUS_TYPE_UINT32, &dev->class,
@@ -2786,15 +2878,17 @@ void adapter_emit_device_found(struct btd_adapter *adapter,
"Alias", DBUS_TYPE_STRING, &alias,
"LegacyPairing", DBUS_TYPE_BOOLEAN, &dev->legacy,
"Paired", DBUS_TYPE_BOOLEAN, &paired,
+ "UUIDs", DBUS_TYPE_ARRAY, &uuids, uuid_count,
NULL);
g_free(alias);
+ g_strfreev(uuids);
}
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status)
+ name_status_t name_status, uint8_t *eir_data)
{
struct remote_dev_info *dev, match;
@@ -2833,7 +2927,7 @@ done:
adapter->found_devices = g_slist_sort(adapter->found_devices,
(GCompareFunc) dev_rssi_cmp);
- adapter_emit_device_found(adapter, dev);
+ adapter_emit_device_found(adapter, dev, eir_data);
}
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr)
diff --git a/src/adapter.h b/src/adapter.h
index 8226514..a7eca0e 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -113,10 +113,10 @@ struct remote_dev_info *adapter_search_found_devices(struct btd_adapter *adapter
void adapter_update_found_devices(struct btd_adapter *adapter, bdaddr_t *bdaddr,
int8_t rssi, uint32_t class, const char *name,
const char *alias, gboolean legacy,
- name_status_t name_status);
+ name_status_t name_status, uint8_t *eir_data);
int adapter_remove_found_device(struct btd_adapter *adapter, bdaddr_t *bdaddr);
void adapter_emit_device_found(struct btd_adapter *adapter,
- struct remote_dev_info *dev);
+ struct remote_dev_info *dev, uint8_t *eir_data);
void adapter_update_oor_devices(struct btd_adapter *adapter);
void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode);
void adapter_setname_complete(bdaddr_t *local, uint8_t status);
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index b83506f..6d27caa 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -515,7 +515,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
if (dev) {
adapter_update_found_devices(adapter, peer, rssi, class,
NULL, NULL, dev->legacy,
- NAME_NOT_REQUIRED);
+ NAME_NOT_REQUIRED, data);
return;
}
@@ -566,7 +566,7 @@ void hcid_dbus_inquiry_result(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
/* add in the list to track name sent/pending */
adapter_update_found_devices(adapter, peer, rssi, class, name, alias,
- legacy, name_status);
+ legacy, name_status, data);
g_free(name);
g_free(alias);
@@ -642,7 +642,7 @@ void hcid_dbus_remote_name(bdaddr_t *local, bdaddr_t *peer, uint8_t status,
if (dev_info) {
g_free(dev_info->name);
dev_info->name = g_strdup(name);
- adapter_emit_device_found(adapter, dev_info);
+ adapter_emit_device_found(adapter, dev_info, NULL);
}
if (device)
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 6/7] Handle arrays in device properties dictionary.
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/adapter.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index b735bdd..c142a4a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2700,6 +2700,7 @@ static void append_dict_valist(DBusMessageIter *iter,
DBusMessageIter dict;
const char *key;
int type;
+ int n_elements;
void *val;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
@@ -2711,7 +2712,13 @@ static void append_dict_valist(DBusMessageIter *iter,
while (key) {
type = va_arg(var_args, int);
val = va_arg(var_args, void *);
- dict_append_entry(&dict, key, type, val);
+ if (type == DBUS_TYPE_ARRAY) {
+ n_elements = va_arg(var_args, int);
+ if (n_elements > 0)
+ dict_append_array(&dict, key, DBUS_TYPE_STRING,
+ val, n_elements);
+ } else
+ dict_append_entry(&dict, key, type, val);
key = va_arg(var_args, char *);
}
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 5/7] Fix in logic to write EIR when SDP records are changed.
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
Whenever SDP service record is added/deleted/modified check for whether
class of device needs to be updated as well. If the update is
needed, proceed as before: new EIR will be written subsequently.
If the class of device is already present, just update EIR and return.
---
src/adapter.c | 69 ++++++++++++++++++++++++++++++--------------------------
1 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 4615326..b735bdd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -206,6 +206,34 @@ void clear_found_devices_list(struct btd_adapter *adapter)
adapter->found_devices = NULL;
}
+static void update_ext_inquiry_response(struct btd_adapter *adapter)
+{
+ uint8_t fec = 0, data[240];
+ struct hci_dev *dev = &adapter->dev;
+ int dd;
+
+ if (!(dev->features[6] & LMP_EXT_INQ))
+ return;
+
+ memset(data, 0, sizeof(data));
+
+ dd = hci_open_dev(adapter->dev_id);
+ if (dd < 0)
+ return;
+
+ if (dev->ssp_mode > 0)
+ create_ext_inquiry_response((char *) dev->name,
+ adapter->tx_power,
+ adapter->services, data);
+
+ if (hci_write_ext_inquiry_response(dd, fec, data,
+ HCI_REQ_TIMEOUT) < 0)
+ error("Can't write extended inquiry response: %s (%d)",
+ strerror(errno), errno);
+
+ hci_close_dev(dd);
+}
+
static int adapter_set_service_classes(struct btd_adapter *adapter,
uint8_t value)
{
@@ -216,11 +244,16 @@ static int adapter_set_service_classes(struct btd_adapter *adapter,
adapter->wanted_cod &= 0x00ffff;
adapter->wanted_cod |= (value << 16);
- /* If we already have the CoD we want or the cache is enabled or an
- * existing CoD write is in progress just bail out */
- if (adapter->current_cod == adapter->wanted_cod ||
- adapter->cache_enable || adapter->pending_cod)
+ /* If the cache is enabled or an existing CoD write is in progress
+ * just bail out */
+ if (adapter->cache_enable || adapter->pending_cod)
+ return 0;
+
+ /* If we already have the CoD we want, update EIR and return */
+ if (adapter->current_cod == adapter->wanted_cod) {
+ update_ext_inquiry_response(adapter);
return 0;
+ }
DBG("Changing service classes to 0x%06x", adapter->wanted_cod);
@@ -818,34 +851,6 @@ static DBusMessage *set_pairable_timeout(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
-static void update_ext_inquiry_response(struct btd_adapter *adapter)
-{
- uint8_t fec = 0, data[240];
- struct hci_dev *dev = &adapter->dev;
- int dd;
-
- if (!(dev->features[6] & LMP_EXT_INQ))
- return;
-
- memset(data, 0, sizeof(data));
-
- dd = hci_open_dev(adapter->dev_id);
- if (dd < 0)
- return;
-
- if (dev->ssp_mode > 0)
- create_ext_inquiry_response((char *) dev->name,
- adapter->tx_power,
- adapter->services, data);
-
- if (hci_write_ext_inquiry_response(dd, fec, data,
- HCI_REQ_TIMEOUT) < 0)
- error("Can't write extended inquiry response: %s (%d)",
- strerror(errno), errno);
-
- hci_close_dev(dd);
-}
-
void adapter_set_class_complete(bdaddr_t *bdaddr, uint8_t status)
{
uint8_t class[3];
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 4/7] Support for adding UUID128 to extended inquiry response
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd-service.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index 5c56e2d..26ab9a5 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -49,6 +49,8 @@
#include "manager.h"
#include "adapter.h"
+#define SIZEOF_UUID128 16
+
static sdp_record_t *server = NULL;
static uint16_t did_vendor = 0x0000;
@@ -174,6 +176,63 @@ static void update_svclass_list(const bdaddr_t *src)
}
+static void eir_generate_uuid128(sdp_list_t *list,
+ uint8_t *ptr, uint16_t *eir_len)
+{
+ int i, k, index = 0;
+ uint16_t len = *eir_len;
+ uint8_t *uuid128;
+ gboolean truncated = FALSE;
+
+ /* Store UUIDs in place, skip 2 bytes to write type and length later */
+ uuid128 = ptr + 2;
+
+ for (; list; list = list->next) {
+ sdp_record_t *rec = (sdp_record_t *) list->data;
+ uint8_t *uuid128_data = rec->svclass.value.uuid128.data;
+
+ if (rec->svclass.type != SDP_UUID128)
+ continue;
+
+ /* Stop if not enough space to put next UUID128 */
+ if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
+ break;
+ }
+
+ /* Check for duplicates, EIR data is Little Endian */
+ for (i = 0; i < index; i++) {
+ for (k = 0; k < SIZEOF_UUID128; k++) {
+ if (uuid128[i * SIZEOF_UUID128 + k] !=
+ uuid128_data[SIZEOF_UUID128 - k])
+ break;
+ }
+ if (k == SIZEOF_UUID128)
+ break;
+ }
+
+ if (i < index)
+ continue;
+
+ /* EIR data is Little Endian */
+ for (k = 0; k < SIZEOF_UUID128; k++)
+ uuid128[index * SIZEOF_UUID128 + k] =
+ uuid128_data[SIZEOF_UUID128 - 1 - k];
+
+ len += SIZEOF_UUID128;
+ index++;
+ }
+
+ if (index > 0 || truncated) {
+ /* EIR Data length */
+ ptr[0] = (index * SIZEOF_UUID128) + 1;
+ /* EIR Data type */
+ ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
+ len += 2;
+ *eir_len = len;
+ }
+}
+
void create_ext_inquiry_response(const char *name,
int8_t tx_power, sdp_list_t *services,
uint8_t *data)
@@ -271,6 +330,10 @@ void create_ext_inquiry_response(const char *name,
*ptr++ = (uuid16[i] & 0xff00) >> 8;
}
}
+
+ /* Group all UUID128 types */
+ if (eir_len <= EIR_DATA_LENGTH - 2)
+ eir_generate_uuid128(services, ptr, &eir_len);
}
void register_public_browse_group(void)
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 3/7] Clean up code that generates extended inquiry response.
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd-service.c | 44 +++++++++++++++++++++++++++++---------------
1 files changed, 29 insertions(+), 15 deletions(-)
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index 35e333d..5c56e2d 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -180,35 +180,41 @@ void create_ext_inquiry_response(const char *name,
{
sdp_list_t *list = services;
uint8_t *ptr = data;
- uint16_t uuid[24];
+ uint16_t eir_len = 0;
+ uint16_t uuid16[EIR_DATA_LENGTH / 2];
int i, index = 0;
+ gboolean truncated = FALSE;
if (name) {
int len = strlen(name);
+ /* EIR Data type */
if (len > 48) {
len = 48;
- ptr[1] = 0x08;
+ ptr[1] = EIR_NAME_SHORT;
} else
- ptr[1] = 0x09;
+ ptr[1] = EIR_NAME_COMPLETE;
+ /* EIR Data length */
ptr[0] = len + 1;
memcpy(ptr + 2, name, len);
- ptr += len + 2;
+ eir_len += (len + 2);
+ ptr += (len + 2);
}
if (tx_power != 0) {
*ptr++ = 2;
- *ptr++ = 0x0a;
+ *ptr++ = EIR_TX_POWER;
*ptr++ = (uint8_t) tx_power;
+ eir_len += 3;
}
if (did_vendor != 0x0000) {
uint16_t source = 0x0002;
*ptr++ = 9;
- *ptr++ = 0x10;
+ *ptr++ = EIR_DEVICE_ID;
*ptr++ = (source & 0x00ff);
*ptr++ = (source & 0xff00) >> 8;
*ptr++ = (did_vendor & 0x00ff);
@@ -217,10 +223,10 @@ void create_ext_inquiry_response(const char *name,
*ptr++ = (did_product & 0xff00) >> 8;
*ptr++ = (did_version & 0x00ff);
*ptr++ = (did_version & 0xff00) >> 8;
+ eir_len += 10;
}
- ptr[1] = 0x03;
-
+ /* Group all UUID16 types */
for (; list; list = list->next) {
sdp_record_t *rec = (sdp_record_t *) list->data;
@@ -233,28 +239,36 @@ void create_ext_inquiry_response(const char *name,
if (rec->svclass.value.uuid16 == PNP_INFO_SVCLASS_ID)
continue;
- if (index > 23) {
- ptr[1] = 0x02;
+ /* Stop if not enough space to put next UUID16 */
+ if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
break;
}
+ /* Check for duplicates */
for (i = 0; i < index; i++)
- if (uuid[i] == rec->svclass.value.uuid16)
+ if (uuid16[i] == rec->svclass.value.uuid16)
break;
if (i < index)
continue;
- uuid[index++] = rec->svclass.value.uuid16;
+ uuid16[index++] = rec->svclass.value.uuid16;
+ eir_len += sizeof(uint16_t);
}
if (index > 0) {
- ptr[0] = (index * 2) + 1;
+ /* EIR Data length */
+ ptr[0] = (index * sizeof(uint16_t)) + 1;
+ /* EIR Data type */
+ ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
ptr += 2;
+ eir_len += 2;
for (i = 0; i < index; i++) {
- *ptr++ = (uuid[i] & 0x00ff);
- *ptr++ = (uuid[i] & 0xff00) >> 8;
+ *ptr++ = (uuid16[i] & 0x00ff);
+ *ptr++ = (uuid16[i] & 0xff00) >> 8;
}
}
}
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 2/7] Minor fix when skipping duplicate UUID16 from EIR.
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd-service.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index cdbb4f4..35e333d 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -242,7 +242,7 @@ void create_ext_inquiry_response(const char *name,
if (uuid[i] == rec->svclass.value.uuid16)
break;
- if (i == index - 1)
+ if (i < index)
continue;
uuid[index++] = rec->svclass.value.uuid16;
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH 1/7] Spec constants for Extended Inquiry Response field types
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel, Inga Stotland
In-Reply-To: <1280962831-18147-1-git-send-email-ingas@codeaurora.org>
---
src/sdpd.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/sdpd.h b/src/sdpd.h
index e93b0b6..5bab869 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -34,6 +34,19 @@
#define SDPDBG(fmt...)
#endif
+#define EIR_DATA_LENGTH 240
+
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_TX_POWER 0x0A /* transmit power level */
+#define EIR_DEVICE_ID 0x10 /* device ID */
+
typedef struct request {
bdaddr_t device;
bdaddr_t bdaddr;
--
1.7.2
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply related
* [PATCH v8 0/7] Enhanced support for extended inquiry response
From: Inga Stotland @ 2010-08-04 23:00 UTC (permalink / raw)
To: linux-bluetooth; +Cc: rshaffer, johan.hedberg, marcel
EIR needs to be updated whenever local SDP record database changes.
Previously, when an SDP record was added/removed/updated, EIR would
be written in callback fired off HCI "Command Complete" event set off by
"Write Class Of Device" command. However, if the class of device did not
need to be updated, the EIR write was not happening either. This
implementation has been augmented to write new EIR when modification
in SDP database does not lead to updating of class of device.
Added support for UUID128 service descriptors in local EIR.
Service UUIDs are written to "device properties" dictionary when emitting
"Device Found" signal. This allows peek at available services offered by
a remote device without establishing SDP connection.
--
Inga Stotland
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply
* [PATCH 9/9] Bluetooth: Use 3-DH5 payload size for default ERTM max PDU size.
From: Mat Martineau @ 2010-08-04 22:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1280962146-22604-1-git-send-email-mathewm@codeaurora.org>
The previous value of 672 for L2CAP_DEFAULT_MAX_PDU_SIZE is based on
the default L2CAP MTU. That default MTU is calculated from the size
of two DH5 packets, minus ACL and L2CAP b-frame header overhead.
ERTM is used with newer basebands that typically support larger 3-DH5
packets, and i-frames and s-frames have more header overhead. With
clean RF conditions, basebands will typically attempt to use 1021-byte
3-DH5 packets for maximum throughput. Adjusting for 2 bytes of ACL
headers plus 10 bytes of worst-case L2CAP headers yields 1009 bytes
of payload.
This PDU size imposes less overhead for header bytes and gives the
baseband the option to choose 3-DH5 packets, but is small enough for
ERTM traffic to interleave well with other L2CAP or SCO data.
672-byte payloads do not allow the most efficient over-the-air
packet choice, and cannot achieve maximum throughput over BR/EDR.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/l2cap.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 16e412f..6c24144 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -35,7 +35,7 @@
#define L2CAP_DEFAULT_MAX_TX 3
#define L2CAP_DEFAULT_RETRANS_TO 2000 /* 2 seconds */
#define L2CAP_DEFAULT_MONITOR_TO 12000 /* 12 seconds */
-#define L2CAP_DEFAULT_MAX_PDU_SIZE 672
+#define L2CAP_DEFAULT_MAX_PDU_SIZE 1009 /* Sized for 3-DH5 packet */
#define L2CAP_DEFAULT_ACK_TO 200
#define L2CAP_LOCAL_BUSY_TRIES 12
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 8/9] Bluetooth: Use a stream-oriented recvmsg with SOCK_STREAM L2CAP sockets.
From: Mat Martineau @ 2010-08-04 22:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1280962146-22604-1-git-send-email-mathewm@codeaurora.org>
L2CAP ERTM sockets can be opened with the SOCK_STREAM socket type,
which is a mandatory request for ERTM mode.
However, these sockets still have SOCK_SEQPACKET read semantics when
bt_sock_recvmsg() is used to pull data from the receive queue. If the
application is only reading part of a frame, then the unread portion
of the frame is discarded. If the application requests more bytes
than are in the current frame, only the current frame's data is
returned.
This patch utilizes common code derived from RFCOMM's recvmsg()
function to make L2CAP SOCK_STREAM reads behave like RFCOMM reads (and
other SOCK_STREAM sockets in general). The application may read one
byte at a time from the input stream and not lose any data, and may
also read across L2CAP frame boundaries.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index f0f3c7c..b9de88d 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1956,7 +1956,10 @@ static int l2cap_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct ms
release_sock(sk);
- return bt_sock_recvmsg(iocb, sock, msg, len, flags);
+ if (sock->type == SOCK_STREAM)
+ return bt_sock_stream_recvmsg(iocb, sock, msg, len, flags);
+ else
+ return bt_sock_recvmsg(iocb, sock, msg, len, flags);
}
static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 7/9] Bluetooth: Use common SOCK_STREAM receive code in RFCOMM.
From: Mat Martineau @ 2010-08-04 22:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1280962146-22604-1-git-send-email-mathewm@codeaurora.org>
To reduce code duplication, have rfcomm_sock_recvmsg() call
bt_sock_stream_recvmsg(). The common bt_sock_stream_recvmsg()
code is nearly identical, with the RFCOMM-specific functionality
for deferred setup and connection unthrottling left in
rfcomm_sock_recvmsg().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/rfcomm/sock.c | 104 +++----------------------------------------
1 files changed, 6 insertions(+), 98 deletions(-)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 44a6232..4396f47 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -617,121 +617,29 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
return sent;
}
-static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
-{
- DECLARE_WAITQUEUE(wait, current);
-
- add_wait_queue(sk_sleep(sk), &wait);
- for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
-
- if (!skb_queue_empty(&sk->sk_receive_queue) ||
- sk->sk_err ||
- (sk->sk_shutdown & RCV_SHUTDOWN) ||
- signal_pending(current) ||
- !timeo)
- break;
-
- set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- release_sock(sk);
- timeo = schedule_timeout(timeo);
- lock_sock(sk);
- clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
- }
-
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(sk_sleep(sk), &wait);
- return timeo;
-}
-
static int rfcomm_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *msg, size_t size, int flags)
{
struct sock *sk = sock->sk;
struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
- int err = 0;
- size_t target, copied = 0;
- long timeo;
+ int len;
if (test_and_clear_bit(RFCOMM_DEFER_SETUP, &d->flags)) {
rfcomm_dlc_accept(d);
return 0;
}
- if (flags & MSG_OOB)
- return -EOPNOTSUPP;
-
- msg->msg_namelen = 0;
-
- BT_DBG("sk %p size %zu", sk, size);
+ len = bt_sock_stream_recvmsg(iocb, sock, msg, size, flags);
lock_sock(sk);
+ if (!(flags & MSG_PEEK) && len > 0)
+ atomic_sub(len, &sk->sk_rmem_alloc);
- target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
- timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
-
- do {
- struct sk_buff *skb;
- int chunk;
-
- skb = skb_dequeue(&sk->sk_receive_queue);
- if (!skb) {
- if (copied >= target)
- break;
-
- if ((err = sock_error(sk)) != 0)
- break;
- if (sk->sk_shutdown & RCV_SHUTDOWN)
- break;
-
- err = -EAGAIN;
- if (!timeo)
- break;
-
- timeo = rfcomm_sock_data_wait(sk, timeo);
-
- if (signal_pending(current)) {
- err = sock_intr_errno(timeo);
- goto out;
- }
- continue;
- }
-
- chunk = min_t(unsigned int, skb->len, size);
- if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- if (!copied)
- copied = -EFAULT;
- break;
- }
- copied += chunk;
- size -= chunk;
-
- sock_recv_ts_and_drops(msg, sk, skb);
-
- if (!(flags & MSG_PEEK)) {
- atomic_sub(chunk, &sk->sk_rmem_alloc);
-
- skb_pull(skb, chunk);
- if (skb->len) {
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- kfree_skb(skb);
-
- } else {
- /* put message back and return */
- skb_queue_head(&sk->sk_receive_queue, skb);
- break;
- }
- } while (size);
-
-out:
if (atomic_read(&sk->sk_rmem_alloc) <= (sk->sk_rcvbuf >> 2))
rfcomm_dlc_unthrottle(rfcomm_pi(sk)->dlc);
-
release_sock(sk);
- return copied ? : err;
+
+ return len;
}
static int rfcomm_sock_setsockopt_old(struct socket *sock, int optname, char __user *optval, unsigned int optlen)
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 6/9] Bluetooth: Add common code for stream-oriented recvmsg()
From: Mat Martineau @ 2010-08-04 22:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1280962146-22604-1-git-send-email-mathewm@codeaurora.org>
This commit adds a bt_sock_stream_recvmsg() function for use by any
Bluetooth code that uses SOCK_STREAM sockets. This code is copied
from rfcomm_sock_recvmsg() with minimal modifications to remove
RFCOMM-specific functionality and improve readability.
L2CAP (with the SOCK_STREAM socket type) and RFCOMM have common needs
when it comes to reading data. Proper stream read semantics require
that applications can read from a stream one byte at a time and not
lose any data. The RFCOMM code already operated on and pulled data
from the underlying L2CAP socket, so very few changes were required to
make the code more generic for use with non-RFCOMM data over L2CAP.
Applications that need more awareness of L2CAP frame boundaries are
still free to use SOCK_SEQPACKET sockets, and may verify that they
connection did not fall back to basic mode by calling getsockopt().
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
include/net/bluetooth/bluetooth.h | 2 +
net/bluetooth/af_bluetooth.c | 109 +++++++++++++++++++++++++++++++++++++
2 files changed, 111 insertions(+), 0 deletions(-)
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 27a902d..08b6c2a 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -126,6 +126,8 @@ int bt_sock_unregister(int proto);
void bt_sock_link(struct bt_sock_list *l, struct sock *s);
void bt_sock_unlink(struct bt_sock_list *l, struct sock *s);
int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags);
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t len, int flags);
uint bt_sock_poll(struct file * file, struct socket *sock, poll_table *wait);
int bt_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
int bt_sock_wait_state(struct sock *sk, int state, unsigned long timeo);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 421c45b..77a26fe 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -265,6 +265,115 @@ int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
}
EXPORT_SYMBOL(bt_sock_recvmsg);
+static long bt_sock_data_wait(struct sock *sk, long timeo)
+{
+ DECLARE_WAITQUEUE(wait, current);
+
+ add_wait_queue(sk_sleep(sk), &wait);
+ for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
+
+ if (!skb_queue_empty(&sk->sk_receive_queue))
+ break;
+
+ if (sk->sk_err || (sk->sk_shutdown & RCV_SHUTDOWN))
+ break;
+
+ if (signal_pending(current) || !timeo)
+ break;
+
+ set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ release_sock(sk);
+ timeo = schedule_timeout(timeo);
+ lock_sock(sk);
+ clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags);
+ }
+
+ __set_current_state(TASK_RUNNING);
+ remove_wait_queue(sk_sleep(sk), &wait);
+ return timeo;
+}
+
+int bt_sock_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size, int flags)
+{
+ struct sock *sk = sock->sk;
+ int err = 0;
+ size_t target, copied = 0;
+ long timeo;
+
+ if (flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ msg->msg_namelen = 0;
+
+ BT_DBG("sk %p size %zu", sk, size);
+
+ lock_sock(sk);
+
+ target = sock_rcvlowat(sk, flags & MSG_WAITALL, size);
+ timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
+
+ do {
+ struct sk_buff *skb;
+ int chunk;
+
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ if (!skb) {
+ if (copied >= target)
+ break;
+
+ if ((err = sock_error(sk)) != 0)
+ break;
+ if (sk->sk_shutdown & RCV_SHUTDOWN)
+ break;
+
+ err = -EAGAIN;
+ if (!timeo)
+ break;
+
+ timeo = bt_sock_data_wait(sk, timeo);
+
+ if (signal_pending(current)) {
+ err = sock_intr_errno(timeo);
+ goto out;
+ }
+ continue;
+ }
+
+ chunk = min_t(unsigned int, skb->len, size);
+ if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ if (!copied)
+ copied = -EFAULT;
+ break;
+ }
+ copied += chunk;
+ size -= chunk;
+
+ sock_recv_ts_and_drops(msg, sk, skb);
+
+ if (!(flags & MSG_PEEK)) {
+ skb_pull(skb, chunk);
+ if (skb->len) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ kfree_skb(skb);
+
+ } else {
+ /* put message back and return */
+ skb_queue_head(&sk->sk_receive_queue, skb);
+ break;
+ }
+ } while (size);
+
+out:
+ release_sock(sk);
+ return copied ? : err;
+}
+EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+
static inline unsigned int bt_accept_poll(struct sock *parent)
{
struct list_head *p, *n;
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
* [PATCH 5/9] Bluetooth: Fix incorrect setting of remote_tx_win for L2CAP ERTM.
From: Mat Martineau @ 2010-08-04 22:49 UTC (permalink / raw)
To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm, Mat Martineau
In-Reply-To: <1280962146-22604-1-git-send-email-mathewm@codeaurora.org>
remote_tx_win is intended to be set on receipt of an L2CAP
configuration request. The value is used to determine the size of the
transmit window on the remote side of an ERTM connection, so L2CAP
can stop sending frames when that remote window is full.
An incorrect remote_tx_win value will cause the stack to not fully
utilize the tx window (performance impact), or to overfill the remote
tx window (causing dropped frames or a disconnect).
This patch removes an extra setting of remote_tx_win when a
configuration response is received. The transmit window has a
different meaning in a response - it is an informational value
less than or equal to the local tx_win.
Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
---
net/bluetooth/l2cap.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 8cf9569..f0f3c7c 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -2808,7 +2808,6 @@ static int l2cap_parse_conf_rsp(struct sock *sk, void *rsp, int len, void *data,
if (*result == L2CAP_CONF_SUCCESS) {
switch (rfc.mode) {
case L2CAP_MODE_ERTM:
- pi->remote_tx_win = rfc.txwin_size;
pi->retrans_timeout = le16_to_cpu(rfc.retrans_timeout);
pi->monitor_timeout = le16_to_cpu(rfc.monitor_timeout);
pi->mps = le16_to_cpu(rfc.max_pdu_size);
--
1.7.1
--
Mat Martineau
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox