* [PATCH] android/pixit: correct PIXIT value
From: Sebastian Chlad @ 2014-02-19 14:04 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sebastian Chlad
It is important for NAP role to set proper PTS btaddr in PIXIT
---
android/pixit-pan.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/android/pixit-pan.txt b/android/pixit-pan.txt
index 6544a9c..21434fb 100644
--- a/android/pixit-pan.txt
+++ b/android/pixit-pan.txt
@@ -3,7 +3,7 @@ PAN PIXIT for the PTS tool.
PTS version: 5.0
* - different than PTS defaults
-& - should be set to IUT Bluetooth address
+& - should be set to IUT or PTS Bluetooth address respectively
Required PIXIT settings
-------------------------------------------------------------------------------
@@ -22,7 +22,7 @@ TSPX_iut_ip_address 192.168.167.152
TSPX_iut_port_number 4242
TSPX_PTS_ip_address 192.168.168.100
TSPX_PTS_port_number 4242
-TSPX_bd_addr_PTS 000000000000
+TSPX_bd_addr_PTS 112233445566 (*&)
TSPX_checksum E851
TSPX_secure_simple_pairing_pass_key_confirmation False
TSPX_iut_friendly_bt_name gprs-pc
--
1.8.5.3
^ permalink raw reply related
* [PATCH] android/pts: PTS test results for PAN
From: Sebastian Chlad @ 2014-02-19 14:10 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Sebastian Chlad
This adds initial PTS test results for PAN profile.
---
android/pts-pan.txt | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 android/pts-pan.txt
diff --git a/android/pts-pan.txt b/android/pts-pan.txt
new file mode 100644
index 0000000..8e8ae41
--- /dev/null
+++ b/android/pts-pan.txt
@@ -0,0 +1,70 @@
+PTS test results for PAN
+
+PTS version: 5.0
+Tested: 19.02.2014
+Android version: 4.4.2
+
+Results:
+PASS test passed
+FAIL test failed
+INC test is inconclusive
+N/A test is disabled due to PICS setup
+
+-------------------------------------------------------------------------------
+Test Name Result Notes
+-------------------------------------------------------------------------------
+TC_BNEP_GN_BROADCAST_0_BV_03_C N/A
+TC_GN_Ipv4_Autonet_BV_01_I N/A
+TC_GN_Ipv6_Autonet_BV_02_I N/A
+TC_GN_IP_DHCP_BV_03_I N/A
+TC_GN_IP_LLMNR_BV_01_I N/A
+TC_GN_IP_LLMNR_BV_02_I N/A
+TC_GN_IP_DNS_BV_01_I N/A
+TC_GN_IP_APP_BV_01_I N/A
+TC_GN_IP_APP_BV_02_I N/A
+TC_GN_IP_APP_BV_03_I N/A
+TC_GN_IP_APP_BV_04_I N/A
+TC_GN_IP_APP_BV_05_I N/A
+TC_SDP_GN_BV_02_C N/A
+TC_MISC_GN_UUID_BV_01_C N/A
+TC_MISC_GN_UUID_BV_02_C N/A
+TC_BNEP_NAP_BROADCAST_0_BV_01_C N/A
+TC_BNEP_NAP_BROADCAST_0_BV_02_C N/A
+TC_BNEP_NAP_FORWARD_UNICAST_BV_05_C N/A
+TC_BNEP_NAP_FORWARD_UNICAST_BV_06_C N/A
+TC_BNEP_NAP_MULTICAST_0_BV_03_C N/A
+TC_BNEP_NAP_MULTICAST_0_BV_04_C N/A
+TC_BNEP_BRIDGE_RX_BV_02_I INC
+TC_BNEP_BRIDGE_TX_BV_01_I PASS
+TC_NAP_Ipv4_Autonet_BV_01_I N/A
+TC_NAP_Ipv6_Autonet_BV_02_I N/A
+TC_NAP_IP_DHCP_BV_03_I N/A
+TC_NAP_IP_LLMNR_BV_01_I INC
+TC_NAP_IP_LLMNR_BV_02_I N/A
+TC_NAP_IP_DNS_BV_01_I N/A
+TC_NAP_IP_APP_BV_01_I N/A
+TC_NAP_IP_APP_BV_02_I N/A
+TC_NAP_IP_APP_BV_03_I N/A
+TC_NAP_IP_APP_BV_04_I N/A
+TC_NAP_IP_APP_BV_05_I PASS
+TC_SDP_NAP_BV_01_C PASS
+TC_MISC_NAP_UUID_BV_01_C PASS
+TC_MISC_NAP_UUID_BV_02_C PASS
+TC_BNEP_PANU_BROADCAST_0_BV_04_C N/A
+TC_PANU_Ipv4_Autonet_BV_01_I INC
+TC_PANU_Ipv6_Autonet_BV_02_I N/A
+TC_PANU_IP_LLMNR_BV_01_I INC
+TC_PANU_IP_LLMNR_BV_02_I N/A
+TC_PANU_IP_DHCP_BV_03_I PASS
+TC_PANU_IP_DNS_BV_01_I N/A
+TC_PANU_IP_APP_BV_01_I N/A
+TC_PANU_IP_APP_BV_02_I N/A
+TC_PANU_IP_APP_BV_03_I INC
+TC_PANU_IP_APP_BV_04_I INC
+TC_PANU_IP_APP_BV_05_I PASS
+TC_SDP_PANU_BV_01_C N/A
+TC_MISC_PANU_UUID_BV_01_C N/A
+TC_MISC_PANU_UUID_BV_02_C N/A
+TC_MISC_ROLE_BV_01_C N/A
+TC_MISC_ROLE_BV_BV_02_C N/A
+-------------------------------------------------------------------------------
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCHv2] emulator/bthost: Fix command queue
From: Johan Hedberg @ 2014-02-19 15:23 UTC (permalink / raw)
To: Marcin Kraglak; +Cc: linux-bluetooth
In-Reply-To: <1392817178-15022-1-git-send-email-marcin.kraglak@tieto.com>
Hi Marcin,
On Wed, Feb 19, 2014, Marcin Kraglak wrote:
> Now new commands will be pushed to tail. Queue will be consumed
> from head, firstly added commands will be sent. It repairs this
> warning from android-tester:
> ==20561== 1,904 bytes in 7 blocks are definitely
> lost in loss record 30 of 31
> ==20561== at 0x4006AB1: malloc (in /usr/lib/valgrind/
> vgpreload_memcheck-x86-linux.so)
> ==20561== by 0x8050293: send_command (bthost.c:389)
> ==20561== by 0x80543E1: start_stack (hciemu.c:299)
> ==20561== by 0x41043D00: ??? (in /usr/lib/libglib-2.0.so.0.3600.4)
> ==20561== by 0x410470E5: g_main_context_dispatch (in
> /usr/lib/libglib-2.0.so.0.3600.4)
> ==20561== by 0x41047497: ??? (in
> /usr/lib/libglib-2.0.so.0.3600.4)
> ==20561== by 0x41047912: g_main_loop_run (in
> /usr/lib/libglib-2.0.so.0.3600.4)
> ==20561== by 0x8055870: tester_run (tester.c:798)
> ==20561== by 0x804B980: main (android-tester.c:3984)
> ---
> emulator/bthost.c | 10 +++++++---
> 1 file changed, 7 insertions(+), 3 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Marvell 88W8787 Bluetooth highh speed
From: Viswanatham, RaviTeja @ 2014-02-19 15:24 UTC (permalink / raw)
To: bluez mailin list (linux-bluetooth@vger.kernel.org)
Hello ,
First of all, I thank you for your guidance on regarding Bluetooth high speed. I found the Marvell 88W8787 device which can support Bluetooth high speed with your suggested help.
The Marvell 88W8787 supports host interfaces like SDIO, I²C, SPI, and UART. I would like to know on which interface did you worked to get an Bluetooth high Speed ?
I am presently working on Altera SoCfpga Cyclone V evaluation board, where it can support all the available host interfaces from Marvell 88w8787. Please could you suggest me to get some idea to work on Bluetooth high speed.
I am expecting that SDIO would work this is just a guess.
Thanks in advance,
Best Regards
Raviteja
^ permalink raw reply
* Re: [PATCHv5] hog: Use HoG device name as uHID input device name
From: Johan Hedberg @ 2014-02-19 15:25 UTC (permalink / raw)
To: Petri Gynther; +Cc: linux-bluetooth
In-Reply-To: <20140219074018.B736F1005F0@puck.mtv.corp.google.com>
Hi Petri,
On Tue, Feb 18, 2014, Petri Gynther wrote:
> ---
> profiles/input/hog.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: Marvell 88W8787 Bluetooth highh speed
From: Andrei Emeltchenko @ 2014-02-19 15:44 UTC (permalink / raw)
To: Viswanatham, RaviTeja; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <9BC883E0D59F6B4DBD525D460025714B08AE47D6@deessmx03.dees.eberspaecher.com>
Hi Raviteja,
On Wed, Feb 19, 2014 at 03:24:48PM +0000, Viswanatham, RaviTeja wrote:
> Hello ,
>
> First of all, I thank you for your guidance on regarding Bluetooth high
> speed. I found the Marvell 88W8787 device which can support Bluetooth
> high speed with your suggested help.
>
> The Marvell 88W8787 supports host interfaces like SDIO, I²C, SPI, and
> UART. I would like to know on which interface did you worked to get an
> Bluetooth high Speed ?
SDIO was working, some newer boards have USB interface which is better.
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH 0/6] Bluetooth: Add support for New IRK mgmt event
From: Marcel Holtmann @ 2014-02-19 16:03 UTC (permalink / raw)
To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392814668-4830-1-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
> This patch set adds support for the New IRK mgmt event and moves the
> sending of New LTK events after that event (ensuring they all contain
> the Identity Address insted of the RPA).
>
> Johan
>
> ----------------------------------------------------------------
> Johan Hedberg (6):
> Bluetooth: Avoid using GFP_ATOMIC where not necessary
> Bluetooth: Return added key when adding LTKs and IRKs
> Bluetooth: Move New LTK store hint evaluation into mgmt_new_ltk
> Bluetooth: Track SMP keys in the SMP context
> Bluetooth: Move SMP LTK notification after key distribution
> Bluetooth: Add support for sending New IRK event
>
> include/net/bluetooth/hci_core.h | 13 ++++++-----
> include/net/bluetooth/mgmt.h | 7 ++++++
> net/bluetooth/hci_core.c | 38 +++++++++++--------------------
> net/bluetooth/mgmt.c | 30 ++++++++++++++++++++-----
> net/bluetooth/smp.c | 45 +++++++++++++++++++++++++++++--------
> net/bluetooth/smp.h | 3 +++
> 6 files changed, 91 insertions(+), 45 deletions(-)
all 6 patches have been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply
* Re: [RFC v10 06/10] Bluetooth: Introduce LE auto connection infrastructure
From: Andre Guedes @ 2014-02-19 16:37 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <9E70336A-B971-4FBB-A185-0F28BE27A5F5@holtmann.org>
Hi Marcel,
On Tue, Feb 18, 2014 at 5:52 PM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Andre,
>
>> This patch introduces the LE auto connection infrastructure which
>> will be used to implement the LE auto connection options.
>>
>> In summary, the auto connection mechanism works as follows: Once the
>> first pending LE connection is created, the background scanning is
>> started. When the target device is found in range, the kernel
>> autonomously starts the connection attempt. If connection is
>> established successfully, that pending LE connection is deleted and
>> the background is stopped.
>>
>> To achieve that, this patch introduces the hci_update_background_scan()
>> which controls the background scanning state. This function starts or
>> stops the background scanning based on the hdev->pend_le_conns list. If
>> there is no pending LE connection, the background scanning is stopped.
>> Otherwise, we start the background scanning.
>>
>> Then, every time a pending LE connection is added we call hci_update_
>> background_scan() so the background scanning is started (in case it is
>> not already running). Likewise, every time a pending LE connection is
>> deleted we call hci_update_background_scan() so the background scanning
>> is stopped (in case this was the last pending LE connection) or it is
>> started again (in case we have more pending LE connections). Finally,
>> we also call hci_update_background_scan() in hci_le_conn_failed() so
>> the background scan is restarted in case the connection establishment
>> fails. This way the background scanning keeps running until all pending
>> LE connection are established.
>>
>> Signed-off-by: Andre Guedes <andre.guedes@openbossa.org>
>> ---
>> include/net/bluetooth/hci_core.h | 2 +
>> net/bluetooth/hci_conn.c | 5 +++
>> net/bluetooth/hci_core.c | 83 ++++++++++++++++++++++++++++++++++=
+++++-
>> net/bluetooth/hci_event.c | 44 +++++++++++++++++++++
>> 4 files changed, 132 insertions(+), 2 deletions(-)
>>
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hc=
i_core.h
>> index f0617ab..297b954 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -788,6 +788,8 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdad=
dr_t *addr, u8 addr_type);
>> void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_=
type);
>> void hci_pend_le_conns_clear(struct hci_dev *hdev);
>>
>> +void hci_update_background_scan(struct hci_dev *hdev);
>> +
>> void hci_uuids_clear(struct hci_dev *hdev);
>>
>> void hci_link_keys_clear(struct hci_dev *hdev);
>> diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
>> index 0ae7692..e291d68 100644
>> --- a/net/bluetooth/hci_conn.c
>> +++ b/net/bluetooth/hci_conn.c
>> @@ -527,6 +527,11 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 s=
tatus)
>> hci_proto_connect_cfm(conn, status);
>>
>> hci_conn_del(conn);
>> +
>> + /* Since we may have temporarily stopped the background scanning i=
n
>> + * favor of connection establishment, we should restart it.
>> + */
>> + hci_update_background_scan(hdev);
>> }
>>
>> static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
>> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
>> index 992f9ea..18ef960 100644
>> --- a/net/bluetooth/hci_core.c
>> +++ b/net/bluetooth/hci_core.c
>> @@ -3114,7 +3114,7 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bd=
addr_t *addr, u8 addr_type)
>>
>> entry =3D hci_pend_le_conn_lookup(hdev, addr, addr_type);
>> if (entry)
>> - return;
>> + goto done;
>>
>> entry =3D kzalloc(sizeof(*entry), GFP_KERNEL);
>> if (!entry) {
>> @@ -3128,6 +3128,9 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bd=
addr_t *addr, u8 addr_type)
>> list_add(&entry->list, &hdev->pend_le_conns);
>>
>> BT_DBG("addr %pMR (type %u)", addr, addr_type);
>> +
>> +done:
>> + hci_update_background_scan(hdev);
>> }
>>
>> /* This function requires the caller holds hdev->lock */
>> @@ -3137,12 +3140,15 @@ void hci_pend_le_conn_del(struct hci_dev *hdev, =
bdaddr_t *addr, u8 addr_type)
>>
>> entry =3D hci_pend_le_conn_lookup(hdev, addr, addr_type);
>> if (!entry)
>> - return;
>> + goto done;
>>
>> list_del(&entry->list);
>> kfree(entry);
>>
>> BT_DBG("addr %pMR (type %u)", addr, addr_type);
>> +
>> +done:
>> + hci_update_background_scan(hdev);
>> }
>>
>> /* This function requires the caller holds hdev->lock */
>> @@ -4706,3 +4712,76 @@ void hci_req_add_le_scan_disable(struct hci_reque=
st *req)
>> cp.enable =3D LE_SCAN_DISABLE;
>> hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
>> }
>> +
>> +static void update_background_scan_complete(struct hci_dev *hdev, u8 st=
atus)
>> +{
>> + if (status)
>> + BT_DBG("HCI request failed to update background scanning: =
"
>> + "status 0x%2.2x", status);
>> +}
>> +
>> +/* This function controls the background scanning based on hdev->pend_l=
e_conns
>> + * list. If there are pending LE connection we start the background sca=
nning,
>> + * otherwise we stop it.
>> + *
>> + * This function requires the caller holds hdev->lock.
>> + */
>> +void hci_update_background_scan(struct hci_dev *hdev)
>> +{
>> + struct hci_cp_le_set_scan_param param_cp;
>> + struct hci_cp_le_set_scan_enable enable_cp;
>> + struct hci_request req;
>> + struct hci_conn *conn;
>> + int err;
>> +
>> + hci_req_init(&req, hdev);
>> +
>> + if (list_empty(&hdev->pend_le_conns)) {
>> + /* If there is no pending LE connections, we should stop
>> + * the background scanning.
>> + */
>> +
>> + /* If controller is not scanning we are done. */
>> + if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
>> + return;
>> +
>> + hci_req_add_le_scan_disable(&req);
>> +
>> + BT_DBG("%s stopping background scanning", hdev->name);
>> + } else {
>> + /* If there is at least one pending LE connection, we shou=
ld
>> + * keep the background scan running.
>> + */
>> +
>> + /* If controller is already scanning we are done. */
>> + if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
>> + return;
>> +
>> + /* If controller is connecting, we should not start scanni=
ng
>> + * since some controllers are not able to scan and connect=
at
>> + * the same time.
>> + */
>> + conn =3D hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONN=
ECT);
>> + if (conn)
>> + return;
>> +
>> + memset(¶m_cp, 0, sizeof(param_cp));
>> + param_cp.type =3D LE_SCAN_PASSIVE;
>> + param_cp.interval =3D cpu_to_le16(hdev->le_scan_interval);
>> + param_cp.window =3D cpu_to_le16(hdev->le_scan_window);
>> + hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_c=
p),
>> + ¶m_cp);
>> +
>> + memset(&enable_cp, 0, sizeof(enable_cp));
>> + enable_cp.enable =3D LE_SCAN_ENABLE;
>> + enable_cp.filter_dup =3D LE_SCAN_FILTER_DUP_DISABLE;
>> + hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable=
_cp),
>> + &enable_cp);
>> +
>> + BT_DBG("%s starting background scanning", hdev->name);
>> + }
>
> so I was inclined to take the whole patch set as it is, but this code is =
not useful at all at the moment.
>
> Disabling the duplicate filter is a horrible idea. I just have my control=
ler going crazy. I rather background scan with the filter enabled and then =
from time to time disable scanning and start it again to make sure that new=
devices are captured. This idea of reporting everything up to the host eve=
ry single time is insane.
How many time should we wait to re-enable scan?
> Also we need to fine tune the scan_interval and scan_window we use for co=
nnection attempts for background scanning. This is just crazy. We have a mg=
mt command that lets us configure these values. So please make sure that it=
integrates with the background scanning and allows us to change these para=
meters on the fly. I want to see what kind of difference different values m=
ake.
The "Set Scan Parameters" command and the background scan are already
integrated. I'll just add an extra patch to restart background scan if
scan parameters are changed.
> There is a difference between we lost our link and want to reconnect as q=
uickly as possible. And hey, we have some devices that we might want to con=
nect to. When you find it, go ahead and connect, but no hurry type of conne=
ction establishment.
>
> And most importantly. Make sure this works with the RPA resolving work th=
at we just merged. I am testing this against my iPhone and auto-connect is =
not picking up my public identity address.
Ok.
Regards,
Andre
^ permalink raw reply
* Re: [RFC v10 09/10] Bluetooth: Auto connection and power on
From: Andre Guedes @ 2014-02-19 16:37 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <66746AF2-08CF-4E22-95D0-1ADB649BBED8@holtmann.org>
Hi Marcel,
On Tue, Feb 18, 2014 at 5:55 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Andre,
>
>> When hdev is closed (e.g. Mgmt power off command, RFKILL or controller
>> is reset), the ongoing active connections are silently dropped by the
>> controller (no Disconnection Complete Event is sent to host). For that
>> reason, the devices that require HCI_AUTO_CONN_ALWAYS are not added to
>> hdev->pend_le_conns list and they won't auto connect.
>>
>> So to fix this issue, during hdev closing, we remove all pending LE
>> connections. After adapter is powered on, we add a pending LE connection
>> for each HCI_AUTO_CONN_ALWAYS address.
>>
>> This way, the auto connection mechanism works propely after a power
>> off and power on sequence as well as RFKILL block/unblock.
>
> and when background scan is running, you might want to make sure to disable LE scan first before doing the actual power down. I just crashed my controller.
Hum, I didn't get any crash with my controllers. Could you send your kernel log?
BR,
Andre
^ permalink raw reply
* Re: [RFC v10 10/10] Bluetooth: Add le_auto_conn file on debugfs
From: Andre Guedes @ 2014-02-19 16:37 UTC (permalink / raw)
To: Marcel Holtmann; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <724E8886-CDAC-4EE8-AA00-184A247E89AA@holtmann.org>
Hi Marcel,
On Tue, Feb 18, 2014 at 5:53 PM, Marcel Holtmann <marcel@holtmann.org> wrote:
> Hi Andre,
>
>> This patch adds to debugfs the le_auto_conn file. This file will be
>> used to test LE auto connection infrastructure.
>>
>> To add a new auto connection address we write on le_auto_conn file
>> following the format <address> <address type> <auto_connect>.
>>
>> The <address type> values are:
>> * 0 for public address
>> * 1 for random address
>>
>> The <auto_connect> values are (for more details see struct hci_
>> conn_params):
>> * 0 for disabled
>> * 1 for always
>> * 2 for link loss
>>
>> So for instance, if you want the kernel autonomously establishes
>> connections with device AA:BB:CC:DD:EE:FF (public address) every
>> time the device enters in connectable mode (starts advertising),
>> you should run the command:
>> $ echo "AA:BB:CC:DD:EE:FF 0 1" > /sys/kernel/debug/bluetooth/hci0/le_auto_conn
>>
>> To get the list of connection parameters configured in kernel, read
>> the le_auto_conn file:
>> $ cat /sys/kernel/debug/bluetooth/hci0/le_auto_conn
>>
>> Finally, to clear the connection parameters list, write an empty
>> string:
>> $ echo "" > /sys/kernel/debug/bluetooth/hci0/le_auto_conn
>
> adding the first entry to this list should start scanning and deleting the last entry should stop scanning.
Ok, I'll do it.
BR,
Andre
^ permalink raw reply
* [PATCH BlueZ v2 01/14] android/hal-ipc-api: Add Set Volume command
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
v2: Use fixed buffers instead of allocating memory for ipc commands, also
change to use variable length for text attributes to avoid having to define a
huge MTU which in most cases would be filled with 0.
android/hal-ipc-api.txt | 6 ++++++
android/hal-msg.h | 5 +++++
2 files changed, 11 insertions(+)
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index ee3bd76..ea26d0d 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -1300,6 +1300,12 @@ Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID)
Valid type values : 0x00 = Interim
0x01 = Changed
+ Opcode 0x0a - Set Volume command/response
+
+ Command parameters: Value (1 octet)
+
+ In case of an error, the error response will be returned.
+
Opcode 0x81 - Remote Features notification
Notification parameters: Remote address (6 octets)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6504408..9d396a1 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -882,6 +882,11 @@ struct hal_cmd_avrcp_register_notification {
uint8_t data[0];
} __attribute__((packed));
+#define HAL_OP_AVRCP_SET_VOLUME 0x0a
+struct hal_cmd_avrcp_set_volume {
+ uint8_t value;
+};
+
#define HAL_EV_AVRCP_REMOTE_FEATURES 0x81
struct hal_ev_avrcp_remote_features {
uint8_t bdaddr[6];
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 02/14] android/hal-ipc-api: Use variable length for text attributes
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This prevent having to increase the MTU size just to fit all attributes
when in fact some attributes are numbers (3 out of 8) in text format
which should not get even close to use 256 bytes defined by bt_rc.h.
---
android/hal-ipc-api.txt | 6 ++++--
android/hal-msg.h | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index ea26d0d..02355dc 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -1251,7 +1251,8 @@ Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID)
Command parameters: Number of values (1 octet)
Value # (1 octet)
- Value # text (255 octets)
+ Value # text length (1 octet)
+ Value # text (variable)
...
In case of an error, the error response will be returned.
@@ -1260,7 +1261,8 @@ Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID)
Command parameters: Number of elements (1 octet)
Element # (1 octet)
- Element # text (255 octets)
+ Element # text length (1 octet)
+ Element # text (variable)
...
In case of an error, the error response will be returned.
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 9d396a1..55ffd08 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -830,7 +830,8 @@ struct hal_cmd_avrcp_get_player_attrs {
struct hal_avrcp_player_setting_text {
uint8_t id;
- uint8_t text[255];
+ uint8_t len;
+ uint8_t text[0];
} __attribute__((packed));
#define HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT 0x05
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 03/14] android/avrcp: Add command handlers stubs
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/avrcp.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/android/avrcp.c b/android/avrcp.c
index 65b3417..b1b6dbe 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -57,7 +57,116 @@ struct avrcp_device {
GIOChannel *io;
};
+static void handle_get_play_status(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_attrs(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_values(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs_text(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_values_text(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_get_element_attrs_text(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_set_player_attrs_value(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_register_notification(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ HAL_STATUS_FAILED);
+}
+
+static void handle_set_volume(const void *buf, uint16_t len)
+{
+ DBG("");
+
+ ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
+ HAL_STATUS_FAILED);
+}
+
static const struct ipc_handler cmd_handlers[] = {
+ /* HAL_OP_AVRCP_GET_PLAY_STATUS */
+ { handle_get_play_status, false,
+ sizeof(struct hal_cmd_avrcp_get_play_status) },
+ /* HAL_OP_AVRCP_LIST_PLAYER_ATTRS */
+ { handle_list_player_attrs, true,
+ sizeof(struct hal_cmd_avrcp_list_player_attrs) },
+ /* HAL_OP_AVRCP_LIST_PLAYER_VALUES */
+ { handle_list_player_values, true,
+ sizeof(struct hal_cmd_avrcp_list_player_values) },
+ /* HAL_OP_AVRCP_GET_PLAYER_ATTRS */
+ { handle_get_player_attrs, true,
+ sizeof(struct hal_cmd_avrcp_get_player_attrs) },
+ /* HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT */
+ { handle_get_player_attrs_text, true,
+ sizeof(struct hal_cmd_avrcp_get_player_attrs_text) },
+ /* HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT */
+ { handle_get_player_values_text, true,
+ sizeof(struct hal_cmd_avrcp_get_player_values_text) },
+ /* HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT */
+ { handle_get_element_attrs_text, true,
+ sizeof(struct hal_cmd_avrcp_get_element_attrs_text) },
+ /* HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE */
+ { handle_set_player_attrs_value, true,
+ sizeof(struct hal_cmd_avrcp_set_player_attrs_value) },
+ /* HAL_OP_AVRCP_REGISTER_NOTIFICATION */
+ { handle_register_notification, true,
+ sizeof(struct hal_cmd_avrcp_register_notification) },
+ /* HAL_OP_AVRCP_SET_VOLUME */
+ { handle_set_volume, false, sizeof(struct hal_cmd_avrcp_set_volume) },
};
static sdp_record_t *avrcp_record(void)
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 04/14] android/hal-avrcp: Add .get_play_status implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 01d233b..9937a11 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -56,6 +56,24 @@ static bt_status_t init(btrc_callbacks_t *callbacks)
return ret;
}
+static bt_status_t get_play_status_rsp(btrc_play_status_t status,
+ uint32_t song_len, uint32_t song_pos)
+{
+ struct hal_cmd_avrcp_get_play_status cmd;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ cmd.status = status;
+ cmd.duration = song_len;
+ cmd.position = song_pos;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -78,6 +96,7 @@ static void cleanup()
static btrc_interface_t iface = {
.size = sizeof(iface),
.init = init,
+ .get_play_status_rsp = get_play_status_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 05/14] android/hal-avrcp: Add .list_player_app_attr_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 9937a11..9735c22 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -18,6 +18,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
+#include <stdlib.h>
#include "hal-log.h"
#include "hal.h"
@@ -74,6 +75,33 @@ static bt_status_t get_play_status_rsp(btrc_play_status_t status,
sizeof(cmd), &cmd, 0, NULL, NULL);
}
+static bt_status_t list_player_app_attr_rsp(int num_attr,
+ btrc_player_attr_t *p_attrs)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_list_player_attrs *cmd = (void *) buf;
+ size_t len;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (num_attr < 0)
+ return BT_STATUS_PARM_INVALID;
+
+ len = sizeof(*cmd) + num_attr;
+ if (len > BLUEZ_HAL_MTU)
+ return BT_STATUS_PARM_INVALID;
+
+ cmd->number = num_attr;
+ memcpy(cmd->attrs, p_attrs, num_attr);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -97,6 +125,7 @@ static btrc_interface_t iface = {
.size = sizeof(iface),
.init = init,
.get_play_status_rsp = get_play_status_rsp,
+ .list_player_app_attr_rsp = list_player_app_attr_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 06/14] android/hal-avrcp: Add .list_player_app_value_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 9735c22..42b1dad 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -102,6 +102,33 @@ static bt_status_t list_player_app_attr_rsp(int num_attr,
len, cmd, 0, NULL, NULL);
}
+static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_list_player_values *cmd = (void *) buf;
+ size_t len;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (num_val < 0)
+ return BT_STATUS_PARM_INVALID;
+
+ len = sizeof(*cmd) + num_val;
+
+ if (len > BLUEZ_HAL_MTU)
+ return BT_STATUS_PARM_INVALID;
+
+ cmd->number = num_val;
+ memcpy(cmd->values, p_vals, num_val);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_LIST_PLAYER_VALUES,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -126,6 +153,7 @@ static btrc_interface_t iface = {
.init = init,
.get_play_status_rsp = get_play_status_rsp,
.list_player_app_attr_rsp = list_player_app_attr_rsp,
+ .list_player_app_value_rsp = list_player_app_value_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 07/14] android/hal-avrcp: Add .get_player_app_value_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 42b1dad..c9e1be2 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -129,6 +129,40 @@ static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
len, cmd, 0, NULL, NULL);
}
+static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_get_player_attrs *cmd = (void *) buf;
+ size_t len, attrs_len;
+ int i;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (!p_vals)
+ return BT_STATUS_PARM_INVALID;
+
+ attrs_len = p_vals->num_attr *
+ sizeof(struct hal_avrcp_player_attr_value);
+ len = sizeof(*cmd) + attrs_len;
+
+ if (len > BLUEZ_HAL_MTU)
+ return BT_STATUS_PARM_INVALID;
+
+ cmd->number = p_vals->num_attr;
+
+ for (i = 0; i < p_vals->num_attr; i++) {
+ cmd->attrs[i].attr = p_vals->attr_ids[i];
+ cmd->attrs[i].value = p_vals->attr_values[i];
+ }
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_GET_PLAYER_ATTRS,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -154,6 +188,7 @@ static btrc_interface_t iface = {
.get_play_status_rsp = get_play_status_rsp,
.list_player_app_attr_rsp = list_player_app_attr_rsp,
.list_player_app_value_rsp = list_player_app_value_rsp,
+ .get_player_app_value_rsp = get_player_app_value_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 08/14] android/hal-avrcp: Add .get_player_app_attr_text_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index c9e1be2..5d1bb94 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -163,6 +163,74 @@ static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
len, cmd, 0, NULL, NULL);
}
+static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len)
+{
+ struct hal_avrcp_player_setting_text *value = (void *) ptr;
+ size_t attr_len = sizeof(*value);
+
+ if (attr_len + *len > BLUEZ_HAL_MTU)
+ return 0;
+
+ value->id = id;
+ value->len = strnlen((const char *) text, BTRC_MAX_ATTR_STR_LEN);
+
+ *len += attr_len;
+ ptr += attr_len;
+
+ if (value->len + *len > BLUEZ_HAL_MTU)
+ value->len = BLUEZ_HAL_MTU - *len;
+
+ memcpy(value->text, text, value->len);
+
+ *len += value->len;
+
+ return attr_len + value->len;
+}
+
+static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr,
+ btrc_player_setting_text_t *p_attrs,
+ size_t *len)
+{
+ int i;
+
+ for (i = 0; i < num_attr && *len < BLUEZ_HAL_MTU; i++) {
+ int ret;
+
+ ret = write_text(ptr, p_attrs[i].id, p_attrs[i].text, len);
+ if (ret == 0)
+ break;
+
+ ptr += ret;
+ }
+
+ return i;
+}
+
+static bt_status_t get_player_app_attr_text_rsp(int num_attr,
+ btrc_player_setting_text_t *p_attrs)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_get_player_attrs_text *cmd = (void *) buf;
+ uint8_t *ptr;
+ size_t len;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (num_attr < 0 || num_attr > BTRC_MAX_APP_SETTINGS)
+ return BT_STATUS_PARM_INVALID;
+
+ len = sizeof(*cmd);
+ ptr = (uint8_t *) &cmd->attrs[0];
+ cmd->number = write_player_setting_text(ptr, num_attr, p_attrs, &len);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -189,6 +257,7 @@ static btrc_interface_t iface = {
.list_player_app_attr_rsp = list_player_app_attr_rsp,
.list_player_app_value_rsp = list_player_app_value_rsp,
.get_player_app_value_rsp = get_player_app_value_rsp,
+ .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 09/14] android/hal-avrcp: Add .get_player_app_value_text_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 5d1bb94..df32e2f 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -231,6 +231,31 @@ static bt_status_t get_player_app_attr_text_rsp(int num_attr,
len, cmd, 0, NULL, NULL);
}
+static bt_status_t get_player_app_value_text_rsp(int num_val,
+ btrc_player_setting_text_t *p_vals)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_get_player_values_text *cmd = (void *) buf;
+ uint8_t *ptr;
+ size_t len;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ if (num_val < 0)
+ return BT_STATUS_PARM_INVALID;
+
+ len = sizeof(*cmd);
+ ptr = (uint8_t *) &cmd->values[0];
+ cmd->number = write_player_setting_text(ptr, num_val, p_vals, &len);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -258,6 +283,7 @@ static btrc_interface_t iface = {
.list_player_app_value_rsp = list_player_app_value_rsp,
.get_player_app_value_rsp = get_player_app_value_rsp,
.get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
+ .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 10/14] android/hal-avrcp: Add .get_element_attr_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index df32e2f..3a39918 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -256,6 +256,47 @@ static bt_status_t get_player_app_value_text_rsp(int num_val,
len, cmd, 0, NULL, NULL);
}
+static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr,
+ btrc_element_attr_val_t *p_attrs,
+ size_t *len)
+{
+ int i;
+
+ for (i = 0; i < num_attr && *len < BLUEZ_HAL_MTU; i++) {
+ int ret;
+
+ ret = write_text(ptr, p_attrs[i].attr_id, p_attrs[i].text, len);
+ if (ret == 0)
+ break;
+
+ ptr += ret;
+ }
+
+ return i;
+}
+
+static bt_status_t get_element_attr_rsp(uint8_t num_attr,
+ btrc_element_attr_val_t *p_attrs)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf;
+ size_t len;
+ uint8_t *ptr;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ len = sizeof(*cmd);
+ ptr = (uint8_t *) &cmd->values[0];
+ cmd->number = write_element_attr_text(ptr, num_attr, p_attrs, &len);
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
+ len, cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -284,6 +325,7 @@ static btrc_interface_t iface = {
.get_player_app_value_rsp = get_player_app_value_rsp,
.get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
.get_player_app_value_text_rsp = get_player_app_value_text_rsp,
+ .get_element_attr_rsp = get_element_attr_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 11/14] android/hal-avrcp: Add .set_player_app_value_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 3a39918..d9069c0 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -297,6 +297,22 @@ static bt_status_t get_element_attr_rsp(uint8_t num_attr,
len, cmd, 0, NULL, NULL);
}
+static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status)
+{
+ struct hal_cmd_avrcp_set_player_attrs_value cmd;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ cmd.status = rsp_status;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -326,6 +342,7 @@ static btrc_interface_t iface = {
.get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
.get_player_app_value_text_rsp = get_player_app_value_text_rsp,
.get_element_attr_rsp = get_element_attr_rsp,
+ .set_player_app_value_rsp = set_player_app_value_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 12/14] android/hal-avrcp: Add .register_notification_rsp implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index d9069c0..bf3e3dc 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -313,6 +313,146 @@ static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status)
sizeof(cmd), &cmd, 0, NULL, NULL);
}
+static bt_status_t play_status_changed_rsp(btrc_notification_type_t type,
+ btrc_play_status_t *play_status)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
+ size_t len;
+
+ cmd->event = BTRC_EVT_PLAY_STATUS_CHANGED;
+ cmd->type = type;
+ cmd->len = 1;
+ memcpy(cmd->data, play_status, cmd->len);
+
+ len = sizeof(*cmd) + cmd->len;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ len, cmd, 0, NULL, NULL);
+}
+
+static bt_status_t track_change_rsp(btrc_notification_type_t type,
+ btrc_uid_t *track)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
+ size_t len;
+
+ cmd->event = BTRC_EVT_TRACK_CHANGE;
+ cmd->type = type;
+ cmd->len = sizeof(*track);
+ memcpy(cmd->data, track, cmd->len);
+
+ len = sizeof(*cmd) + cmd->len;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ len, cmd, 0, NULL, NULL);
+}
+
+static bt_status_t track_reached_end_rsp(btrc_notification_type_t type)
+{
+ struct hal_cmd_avrcp_register_notification cmd;
+
+ cmd.event = BTRC_EVT_TRACK_REACHED_END;
+ cmd.type = type;
+ cmd.len = 0;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
+static bt_status_t track_reached_start_rsp(btrc_notification_type_t type)
+{
+ struct hal_cmd_avrcp_register_notification cmd;
+
+ cmd.event = BTRC_EVT_TRACK_REACHED_START;
+ cmd.type = type;
+ cmd.len = 0;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
+static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type,
+ uint32_t *song_pos)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
+ size_t len;
+
+ cmd->event = BTRC_EVT_PLAY_POS_CHANGED;
+ cmd->type = type;
+ cmd->len = sizeof(*song_pos);
+ memcpy(cmd->data, song_pos, cmd->len);
+
+ len = sizeof(*cmd) + cmd->len;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ len, cmd, 0, NULL, NULL);
+}
+
+static bt_status_t settings_changed_rsp(btrc_notification_type_t type,
+ btrc_player_settings_t *player_setting)
+{
+ char buf[BLUEZ_HAL_MTU];
+ struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
+ struct hal_avrcp_player_attr_value *attrs;
+ size_t len, param_len;
+ int i;
+
+ param_len = player_setting->num_attr * sizeof(*attrs);
+ len = sizeof(*cmd) + param_len;
+
+ if (len > BLUEZ_HAL_MTU)
+ return BT_STATUS_PARM_INVALID;
+
+ cmd->event = BTRC_EVT_APP_SETTINGS_CHANGED;
+ cmd->type = type;
+ cmd->len = param_len;
+
+ attrs = (struct hal_avrcp_player_attr_value *) &cmd->data[0];
+ for (i = 0; i < player_setting->num_attr; i++) {
+ attrs[i].attr = player_setting->attr_ids[i];
+ attrs[i].value = player_setting->attr_values[i];
+ }
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
+ HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+ len, cmd, 0, NULL, NULL);
+}
+
+static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
+ btrc_notification_type_t type,
+ btrc_register_notification_t *p_param)
+{
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ switch (event_id) {
+ case BTRC_EVT_PLAY_STATUS_CHANGED:
+ return play_status_changed_rsp(type, &p_param->play_status);
+ case BTRC_EVT_TRACK_CHANGE:
+ return track_change_rsp(type, &p_param->track);
+ case BTRC_EVT_TRACK_REACHED_END:
+ return track_reached_end_rsp(type);
+ case BTRC_EVT_TRACK_REACHED_START:
+ return track_reached_start_rsp(type);
+ case BTRC_EVT_PLAY_POS_CHANGED:
+ return play_pos_changed_rsp(type, &p_param->song_pos);
+ case BTRC_EVT_APP_SETTINGS_CHANGED:
+ return settings_changed_rsp(type, &p_param->player_setting);
+ default:
+ return BT_STATUS_PARM_INVALID;
+ }
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -343,6 +483,7 @@ static btrc_interface_t iface = {
.get_player_app_value_text_rsp = get_player_app_value_text_rsp,
.get_element_attr_rsp = get_element_attr_rsp,
.set_player_app_value_rsp = set_player_app_value_rsp,
+ .register_notification_rsp = register_notification_rsp,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 13/14] android/hal-avrcp: Add .set_volume implementation
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index bf3e3dc..f982f48 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -453,6 +453,21 @@ static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
}
}
+static bt_status_t set_volume(uint8_t volume)
+{
+ struct hal_cmd_avrcp_set_volume cmd;
+
+ DBG("");
+
+ if (!interface_ready())
+ return BT_STATUS_NOT_READY;
+
+ cmd.value = volume;
+
+ return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
+ sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
static void cleanup()
{
struct hal_cmd_unregister_module cmd;
@@ -484,6 +499,7 @@ static btrc_interface_t iface = {
.get_element_attr_rsp = get_element_attr_rsp,
.set_player_app_value_rsp = set_player_app_value_rsp,
.register_notification_rsp = register_notification_rsp,
+ .set_volume = set_volume,
.cleanup = cleanup
};
--
1.8.5.3
^ permalink raw reply related
* [PATCH BlueZ v2 14/14] android/hal-avrcp: Add notification handlers
From: Luiz Augusto von Dentz @ 2014-02-19 16:58 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1392829138-10346-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
---
android/hal-avrcp.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 174 insertions(+)
diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index f982f48..a11aaa3 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -32,6 +32,177 @@ static bool interface_ready(void)
return cbs != NULL;
}
+static void handle_remote_features(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_remote_features *ev = buf;
+
+ if (cbs->remote_features_cb)
+ cbs->remote_features_cb((bt_bdaddr_t *) (ev->bdaddr),
+ ev->features);
+}
+
+static void handle_get_play_status(void *buf, uint16_t len)
+{
+ if (cbs->get_play_status_cb)
+ cbs->get_play_status_cb();
+}
+
+static void handle_list_player_attrs(void *buf, uint16_t len)
+{
+ if (cbs->list_player_app_attr_cb)
+ cbs->list_player_app_attr_cb();
+}
+
+static void handle_list_player_values(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_list_player_values *ev = buf;
+
+ if (cbs->list_player_app_values_cb)
+ cbs->list_player_app_values_cb(ev->attr);
+}
+
+static void handle_get_player_values(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_get_player_values *ev = buf;
+ btrc_player_attr_t attrs[4];
+ int i;
+
+ if (!cbs->get_player_app_value_cb)
+ return;
+
+ /* Convert uint8_t array to btrc_player_attr_t array */
+ for (i = 0; i < ev->number; i++)
+ attrs[i] = ev->attrs[i];
+
+ cbs->get_player_app_value_cb(ev->number, attrs);
+}
+
+static void handle_get_player_attrs_text(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_get_player_attrs_text *ev = buf;
+ btrc_player_attr_t attrs[4];
+ int i;
+
+ if (!cbs->get_player_app_attrs_text_cb)
+ return;
+
+ /* Convert uint8_t array to btrc_player_attr_t array */
+ for (i = 0; i < ev->number; i++)
+ attrs[i] = ev->attrs[i];
+
+ cbs->get_player_app_attrs_text_cb(ev->number, attrs);
+}
+
+static void handle_get_player_values_text(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_get_player_values_text *ev = buf;
+
+ if (cbs->get_player_app_values_text_cb)
+ cbs->get_player_app_values_text_cb(ev->attr, ev->number,
+ ev->values);
+}
+
+static void handle_set_player_value(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_set_player_values *ev = buf;
+ struct hal_avrcp_player_attr_value *attrs;
+ btrc_player_settings_t values;
+ int i;
+
+ if (!cbs->set_player_app_value_cb)
+ return;
+
+ attrs = (struct hal_avrcp_player_attr_value *) ev->attrs;
+
+ /* Convert to btrc_player_settings_t */
+ values.num_attr = ev->number;
+ for (i = 0; i < ev->number; i++) {
+ values.attr_ids[i] = attrs[i].attr;
+ values.attr_values[i] = attrs[i].value;
+ }
+
+ cbs->set_player_app_value_cb(&values);
+}
+
+static void handle_get_element_attrs(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_get_element_attrs *ev = buf;
+ btrc_media_attr_t attrs[BTRC_MAX_APP_SETTINGS];
+ int i;
+
+ if (!cbs->get_element_attr_cb)
+ return;
+
+ /* Convert uint8_t array to btrc_media_attr_t array */
+ for (i = 0; i < ev->number; i++)
+ attrs[i] = ev->attrs[i];
+
+ cbs->get_element_attr_cb(ev->number, attrs);
+}
+
+static void handle_register_notification(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_register_notification *ev = buf;
+
+ if (cbs->register_notification_cb)
+ cbs->register_notification_cb(ev->event, ev->param);
+}
+
+static void handle_volume_changed(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_volume_changed *ev = buf;
+
+ if (cbs->volume_change_cb)
+ cbs->volume_change_cb(ev->volume, ev->type);
+}
+
+static void handle_passthrough_cmd(void *buf, uint16_t len)
+{
+ struct hal_ev_avrcp_passthrough_cmd *ev = buf;
+
+ if (cbs->passthrough_cmd_cb)
+ cbs->passthrough_cmd_cb(ev->id, ev->state);
+}
+
+/* handlers will be called from notification thread context,
+ * index in table equals to 'opcode - HAL_MINIMUM_EVENT' */
+static const struct hal_ipc_handler ev_handlers[] = {
+ /* HAL_EV_AVRCP_REMOTE_FEATURES */
+ { handle_remote_features, false,
+ sizeof(struct hal_ev_avrcp_remote_features) },
+ /* HAL_EV_AVRCP_GET_PLAY_STATUS */
+ { handle_get_play_status, false, 0 },
+ /* HAL_EV_AVRCP_LIST_PLAYER_ATTRS */
+ { handle_list_player_attrs, false, 0 },
+ /* HAL_EV_AVRCP_LIST_PLAYER_VALUES */
+ { handle_list_player_values, false,
+ sizeof(struct hal_ev_avrcp_list_player_values) },
+ /* HAL_EV_AVRCP_GET_PLAYER_VALUES */
+ { handle_get_player_values, true,
+ sizeof(struct hal_ev_avrcp_get_player_values) },
+ /* HAL_EV_AVRCP_GET_PLAYER_ATTRS_TEXT */
+ { handle_get_player_attrs_text, true,
+ sizeof(struct hal_ev_avrcp_get_player_attrs_text) },
+ /* HAL_EV_AVRCP_GET_PLAYER_VALUES_TEXT */
+ { handle_get_player_values_text, true,
+ sizeof(struct hal_ev_avrcp_get_player_values_text) },
+ /* HAL_EV_AVRCP_SET_PLAYER_VALUES */
+ { handle_set_player_value, true,
+ sizeof(struct hal_ev_avrcp_set_player_values) },
+ /* HAL_EV_AVRCP_GET_ELEMENT_ATTRS */
+ { handle_get_element_attrs, true,
+ sizeof(struct hal_ev_avrcp_get_element_attrs) },
+ /* HAL_EV_AVRCP_REGISTER_NOTIFICATION */
+ { handle_register_notification, false,
+ sizeof(struct hal_ev_avrcp_register_notification) },
+ /* HAL_EV_AVRCP_VOLUME_CHANGED */
+ { handle_volume_changed, false,
+ sizeof(struct hal_ev_avrcp_volume_changed) },
+ /* HAL_EV_AVRCP_PASSTHROUGH_CMD */
+ { handle_passthrough_cmd, false,
+ sizeof(struct hal_ev_avrcp_passthrough_cmd) },
+};
+
static bt_status_t init(btrc_callbacks_t *callbacks)
{
struct hal_cmd_register_module cmd;
@@ -44,6 +215,9 @@ static bt_status_t init(btrc_callbacks_t *callbacks)
cbs = callbacks;
+ hal_ipc_register(HAL_SERVICE_ID_AVRCP, ev_handlers,
+ sizeof(ev_handlers) / sizeof(ev_handlers[0]));
+
cmd.service_id = HAL_SERVICE_ID_AVRCP;
ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
--
1.8.5.3
^ permalink raw reply related
* Re: [PATCH BlueZ 8/8] doc/obex-api: Update documentation
From: Luiz Augusto von Dentz @ 2014-02-19 17:11 UTC (permalink / raw)
To: Patrick Ohly; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1392742461.6118.25.camel@pohly-mobl1.fritz.box>
Hi Patrick,
On Tue, Feb 18, 2014 at 6:54 PM, Patrick Ohly <patrick.ohly@intel.com> wrote:
> On Tue, 2014-02-18 at 11:30 +0200, Luiz Augusto von Dentz wrote:
>> Hi Patrick,
>>
>> On Tue, Feb 18, 2014 at 11:09 AM, Patrick Ohly <patrick.ohly@intel.com> wrote:
>> > On Fri, 2014-02-14 at 17:53 +0200, Luiz Augusto von Dentz wrote:
>> >> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>> >>
>> >> This adds Suspend and Resume methods and 'suspended' value as status in
>> >> the Transfer interface documentation.
>> >> ---
>> >> doc/obex-api.txt | 18 ++++++++++++++++--
>> >> 1 file changed, 16 insertions(+), 2 deletions(-)
>> >>
>> >> diff --git a/doc/obex-api.txt b/doc/obex-api.txt
>> >> index 1f22fea..0f57ce1 100644
>> >> --- a/doc/obex-api.txt
>> >> +++ b/doc/obex-api.txt
>> >> @@ -90,12 +90,26 @@ Methods void Cancel()
>> >> org.bluez.obex.Error.InProgress
>> >> org.bluez.obex.Error.Failed
>> >>
>> >> + void Suspend()
>> >> +
>> >> + Suspend transference.
>> >> +
>> >> + Possible errors: org.bluez.obex.Error.NotAuthorized
>> >> + org.bluez.obex.Error.NotInProgress
>> >> +
>> >> + void Resume()
>> >> +
>> >> + Resume transference.
>> >> +
>> >> + Possible errors: org.bluez.obex.Error.NotAuthorized
>> >> + org.bluez.obex.Error.NotInProgress
>> > ^^^^^^^^^^^^^
>> >
>> > Should this be a NotSuspended error? Or is it not an error to resume a
>> > transfer which is currently not suspended?
>>
>> Hmm, I would go for InProgress like in Cancel although now that you
>> mentioned we could perhaps ignore such errors if you don't see any
>> value on those.
>
> I think I would prefer to *not* get errors when Suspend() is called on
> an already suspended transfer or when Resume() is called on a running
> transfer. The rationale is that the caller will typically only care
> about the end result and not so much whether it was the one who
> triggered the change. If we remove NotInProgress resp. InProgress errors
> from the API, then such a caller can treat all errors as fatal problem,
> without having to check the exact error.
Actually the NotInProgress error is for transfer queued, I guess for
this case it makes sense to return an error since otherwise we would
have to queue commands to be send when the transfer becomes active I
believe this should probably be considered an error.
--
Luiz Augusto von Dentz
^ 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