2015-03-09 16:24:46

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 01/10] profiles/network: Move bnep connection setup logic to bnep

BNEP connection set up logic which was added before bnep_server_add,
can be private method of bnep. Moved logic was almost doubled in two
cases: NAP role in PAN, server listening. Now set up and connect
scenario check of bnep connection is only handled in bnep part for
listen connections.
---
android/pan.c | 27 ++--------
profiles/network/bnep.c | 128 ++++++++++++++++++++++++++++------------------
profiles/network/bnep.h | 6 +--
profiles/network/server.c | 53 +++++++++++--------
4 files changed, 118 insertions(+), 96 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index 2afc92a..a1356eb 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -463,8 +463,7 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
{
struct pan_device *dev = user_data;
uint8_t packet[BNEP_MTU];
- struct bnep_setup_conn_req *req = (void *) packet;
- uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+ uint16_t rsp = BNEP_CONN_NOT_ALLOWED;
int sk, n, err;

if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
@@ -481,24 +480,8 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
goto failed;
}

- /* Highest known control command id BNEP_FILTER_MULT_ADDR_RSP 0x06 */
- if (req->type == BNEP_CONTROL &&
- req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
- error("cmd not understood");
- bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_CMD_NOT_UNDERSTOOD,
- req->ctrl);
- goto failed;
- }
-
- if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) {
- error("cmd is not BNEP_SETUP_CONN_REQ %02X %02X", req->type,
- req->ctrl);
- goto failed;
- }
-
- rsp = bnep_setup_decode(req, &dst_role, &src_role);
- if (rsp != BNEP_SUCCESS) {
- error("bnep_setup_decode failed");
+ if (n < 3) {
+ error("pan: to few setup connection request data received");
goto failed;
}

@@ -509,8 +492,8 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
goto failed;
}

- if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
- &dev->dst) < 0) {
+ if (bnep_server_add(sk, BNEP_BRIDGE, dev->iface, &dev->dst, packet, n)
+ < 0) {
error("pan: server_connadd failed");
rsp = BNEP_CONN_NOT_ALLOWED;
goto failed;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 0493260..0a41d73 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -524,63 +524,25 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
return err;
}

-int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
- const bdaddr_t *addr)
-{
- int err;
-
- if (!bridge || !iface || !addr)
- return -EINVAL;
-
- err = bnep_connadd(sk, dst, iface);
- if (err < 0)
- return err;
-
- err = bnep_add_to_bridge(iface, bridge);
- if (err < 0) {
- bnep_conndel(addr);
- return err;
- }
-
- return bnep_if_up(iface);
-}
-
-void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
-{
- if (!bridge || !iface || !addr)
- return;
-
- bnep_del_from_bridge(iface, bridge);
- bnep_if_down(iface);
- bnep_conndel(addr);
-}
-
-ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
-{
- struct bnep_control_rsp rsp;
-
- rsp.type = type;
- rsp.ctrl = ctrl;
- rsp.resp = htons(resp);
-
- return send(sk, &rsp, sizeof(rsp), 0);
-}
-
-uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
- uint16_t *src)
+static uint16_t bnep_setup_decode(int sk, struct bnep_setup_conn_req *req,
+ uint16_t *dst)
{
const uint8_t bt_base[] = { 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
+ uint16_t src;
uint8_t *dest, *source;
uint32_t val;

+ if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ)
+ return BNEP_CONN_NOT_ALLOWED;
+
dest = req->service;
source = req->service + req->uuid_size;

switch (req->uuid_size) {
case 2: /* UUID16 */
*dst = get_be16(dest);
- *src = get_be16(source);
+ src = get_be16(source);
break;
case 16: /* UUID128 */
/* Check that the bytes in the UUID, except the service ID
@@ -604,7 +566,7 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
if (val > 0xffff)
return BNEP_CONN_INVALID_SRC;

- *src = val;
+ src = val;
break;
default:
return BNEP_CONN_INVALID_SVC;
@@ -614,12 +576,13 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
switch (*dst) {
case BNEP_SVC_NAP:
case BNEP_SVC_GN:
- if (*src == BNEP_SVC_PANU)
+ if (src == BNEP_SVC_PANU)
return BNEP_SUCCESS;
+
return BNEP_CONN_INVALID_SRC;
case BNEP_SVC_PANU:
- if (*src == BNEP_SVC_PANU || *src == BNEP_SVC_GN ||
- *src == BNEP_SVC_NAP)
+ if (src == BNEP_SVC_PANU || src == BNEP_SVC_GN ||
+ src == BNEP_SVC_NAP)
return BNEP_SUCCESS;

return BNEP_CONN_INVALID_SRC;
@@ -627,3 +590,70 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,

return BNEP_CONN_INVALID_DST;
}
+
+int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
+ uint8_t *setup_data, int len)
+{
+ int err;
+ uint16_t dst = NULL;
+ struct bnep_setup_conn_req *req = (void *) setup_data;
+
+ /* Highest known Control command ID
+ * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
+ if (req->type == BNEP_CONTROL &&
+ req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
+ uint8_t pkt[3];
+
+ pkt[0] = BNEP_CONTROL;
+ pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
+ pkt[2] = req->ctrl;
+
+ send(sk, pkt, sizeof(pkt), 0);
+
+ return -EINVAL;
+ }
+
+ /* Processing BNEP_SETUP_CONNECTION_REQUEST_MSG */
+ err = bnep_setup_decode(sk, req, &dst);
+ if (err < 0) {
+ error("bnep: error while decoding setup connection request: %d",
+ err);
+ return -EINVAL;
+ }
+
+ if (!bridge || !iface || !addr || !dst)
+ return -EINVAL;
+
+ err = bnep_connadd(sk, dst, iface);
+ if (err < 0)
+ return err;
+
+ err = bnep_add_to_bridge(iface, bridge);
+ if (err < 0) {
+ bnep_conndel(addr);
+ return err;
+ }
+
+ return bnep_if_up(iface);
+}
+
+void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
+{
+ if (!bridge || !iface || !addr)
+ return;
+
+ bnep_del_from_bridge(iface, bridge);
+ bnep_if_down(iface);
+ bnep_conndel(addr);
+}
+
+ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
+{
+ struct bnep_control_rsp rsp;
+
+ rsp.type = type;
+ rsp.ctrl = ctrl;
+ rsp.resp = htons(resp);
+
+ return send(sk, &rsp, sizeof(rsp), 0);
+}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index b0a91e5..2686ea8 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -40,10 +40,8 @@ void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
void *data);
void bnep_disconnect(struct bnep *session);

-int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
- const bdaddr_t *addr);
+int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
+ uint8_t *setup_data, int len);
void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);

ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
-uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
- uint16_t *src);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 04f188a..4644133 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -47,6 +47,7 @@
#include "src/log.h"
#include "src/error.h"
#include "src/sdpd.h"
+#include "src/shared/util.h"

#include "bnep.h"
#include "server.h"
@@ -281,11 +282,14 @@ static void setup_destroy(void *user_data)
static gboolean bnep_setup(GIOChannel *chan,
GIOCondition cond, gpointer user_data)
{
+ const uint8_t bt_base[] = { 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
+ 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
struct network_adapter *na = user_data;
struct network_server *ns;
uint8_t packet[BNEP_MTU];
struct bnep_setup_conn_req *req = (void *) packet;
- uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+ uint16_t dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+ uint32_t val;
int n, sk;

if (cond & G_IO_NVAL)
@@ -305,29 +309,36 @@ static gboolean bnep_setup(GIOChannel *chan,
return FALSE;
}

- /* Highest known Control command ID
- * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
- if (req->type == BNEP_CONTROL &&
- req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
- uint8_t pkt[3];
-
- pkt[0] = BNEP_CONTROL;
- pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
- pkt[2] = req->ctrl;
-
- send(sk, pkt, sizeof(pkt), 0);
-
+ /*
+ * Initial received data packet is BNEP_SETUP_CONNECTION_REQUEST_MSG
+ * minimal size of this frame is 3 octets: 1 byte of BNEP Type +
+ * 1 byte of BNEP Control Type + 1 byte of BNEP services UUID size.
+ */
+ if (n < 3) {
+ error("To few setup connection request data received");
return FALSE;
}

- if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ)
- return FALSE;
+ switch (req->uuid_size) {
+ case 2:
+ dst_role = get_be16(req->service);
+ break;
+ case 16:
+ if (memcmp(&req->service[4], bt_base, sizeof(bt_base)) != 0)
+ return FALSE;

- rsp = bnep_setup_decode(req, &dst_role, &src_role);
- if (rsp != BNEP_SUCCESS)
- goto reply;
+ /* Intentional no-brake */

- rsp = BNEP_CONN_NOT_ALLOWED;
+ case 4:
+ val = get_be32(req->service);
+ if (val > 0xffff)
+ return FALSE;
+
+ dst_role = val;
+ break;
+ default:
+ return FALSE;
+ }

ns = find_server(na->servers, dst_role);
if (!ns) {
@@ -348,8 +359,8 @@ static gboolean bnep_setup(GIOChannel *chan,
strncpy(na->setup->dev, BNEP_INTERFACE, 16);
na->setup->dev[15] = '\0';

- if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
- &na->setup->dst) < 0)
+ if (bnep_server_add(sk, ns->bridge, na->setup->dev,
+ &na->setup->dst, packet, n) < 0)
goto reply;

na->setup = NULL;
--
2.1.0



2015-03-12 10:32:48

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] android/pts: Add BNEP PTS 6.0 results for android 5.0

Hi Szymon,


On 12 March 2015 at 11:07, Szymon Janc <[email protected]> wrote:
> Hi Grzegorz,
>
> On Monday 09 of March 2015 17:24:55 Grzegorz Kolodziejczyk wrote:
>> This patch adds test case list and results for BNEP profile against
>> android 5.0
>> ---
>> android/pics-bnep.txt | 26 ++++++++++++++
>> android/pixit-bnep.txt | 30 ++++++++++++++++
>> android/pts-bnep.txt | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 148 insertions(+)
>> create mode 100644 android/pics-bnep.txt
>> create mode 100644 android/pixit-bnep.txt
>> create mode 100644 android/pts-bnep.txt
>
> One more thing: new txt files need to be added to EXTRA_DIST in android/Makefile.am
>
Yes, I've missed it.
>>
>> diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt
>> new file mode 100644
>> index 0000000..2279c9a
>> --- /dev/null
>> +++ b/android/pics-bnep.txt
>> @@ -0,0 +1,26 @@
>> +BNEP PICS for the PTS tool.
>> +
>> +PTS version: 6.0
>> +
>> +* - different than PTS defaults
>> +# - not yet implemented/supported
>> +
>> +M - mandatory if such role selected
>> +O - optional
>> +
>> + Profile Version
>> +-------------------------------------------------------------------------------
>> +Parameter Name Selected Description
>> +-------------------------------------------------------------------------------
>> +TSPC_BNEP_1_1 True BNEP Connection Setup (M)
>> +TSPC_BNEP_1_2 False BNEP Data Packet Reception (M)
>> +TSPC_BNEP_1_3 False BNEP Data Packet Transmission (M)
>> +TSPC_BNEP_1_3a False BNEP Compressed Packet Transmission (O)
>> +TSPC_BNEP_1_3b False BNEP Compressed Packet Transmission Source Only
>> + (O)
>> +TSPC_BNEP_1_4 True BNEP Control Message Processing (M)
>> +TSPC_BNEP_1_5 True BNEP Extension Header Processing (M)
>> +TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O)
>> +TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission
>> + (O)
>> +-------------------------------------------------------------------------------
>> diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt
>> new file mode 100644
>> index 0000000..9a26cd2
>> --- /dev/null
>> +++ b/android/pixit-bnep.txt
>> @@ -0,0 +1,30 @@
>> +BNEP PIXIT for the PTS tool.
>> +
>> +PTS version: 6.0
>> +
>> +* - different than PTS defaults
>> +& - should be set to IUT Bluetooth address
>> +# - should be set to PTS's bin/audio folder
>> +
>> +Required PIXIT settings
>> +-------------------------------------------------------------------------------
>> +Parameter Name Value
>> +-------------------------------------------------------------------------------
>> +TSPX_class_of_device 04041C
>> +TSPX_security_control_data
>> +TSPX_content_protection_data
>> +TSPX_bd_addr_iut 112233445566 (*&)
>> +TSPX_delete_link_key FALSE
>> +TSPX_pin_code 1234
>> +TSPX_security_enabled FALSE
>> +TSPX_time_guard 300000
>> +TSPX_use_implicit_send TRUE
>> +TSPX_auth_password 0000
>> +TSPX_auth_user_id PTS
>> +TSPX_l2cap_psm 000F
>> +TSPX_rfcomm_channel 8
>> +TSPX_no_confirmations FALSE
>> +TSPX_UUID_dest_address 1116
>> +TSPX_UUID_source_address 1115
>> +TSPX_MAC_dest_address 000000000000 (*&)
>> +TSPX_MAC_source_address 000000000000 (*&)
>> diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt
>> new file mode 100644
>> index 0000000..7945385
>> --- /dev/null
>> +++ b/android/pts-bnep.txt
>> @@ -0,0 +1,92 @@
>> +PTS test results for BNEP
>> +
>> +PTS version: 6.0
>> +Tested: 03-March-2015
>> +Android version: 5.0
>> +Kernel version: 3.20
>> +
>> +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_CTRL_BV_01_C PASS bneptest -s
>> +TC_CTRL_BV_02_C PASS bneptest -c <PTS addr>
>> +TC_CTRL_BV_03_C PASS bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_04_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_05_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_06_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_07_C INC PTS issue #13170
>> + bneptest -c <PTS addr> -t 3 -d 0 -e 1500
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_08_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_09_C INC PTS issue #13170
>> + bneptest -c 00:1b:dc:06:06:ca -n enp0s29u1u7
>> + -t 5 -g 00:00:00:00:00:00
>> + -j ff:ff:ff:ff:ff:ff
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_10_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_19_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_11_C N/A
>> +TC_RX_C_BV_12_C N/A
>> +TC_RX_C_S_BV_13_C N/A
>> +TC_RX_C_S_BV_14_C N/A
>> +TC_RX_TYPE_0_BV_15_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_16_C INC PTS issue #13171
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_17_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_18_C INC PTS issue #13171
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_TX_TYPE_0_BV_20_C N/A
>> +TC_TX_C_BV_21_C N/A
>> +TC_TX_C_S_BV_22_C N/A
>> +TC_TX_C_D_BV_23_C N/A
>>
>
> --
> Best regards,
> Szymon Janc
BR,
Grzegorz Kolodziejczyk

2015-03-12 10:12:15

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v3 01/10] profiles/network: Move bnep connection setup logic to bnep

Hi Grzegorz,

On Monday 09 of March 2015 17:24:46 Grzegorz Kolodziejczyk wrote:
> BNEP connection set up logic which was added before bnep_server_add,
> can be private method of bnep. Moved logic was almost doubled in two
> cases: NAP role in PAN, server listening. Now set up and connect
> scenario check of bnep connection is only handled in bnep part for
> listen connections.
> ---
> android/pan.c | 27 ++--------
> profiles/network/bnep.c | 128 ++++++++++++++++++++++++++++------------------
> profiles/network/bnep.h | 6 +--
> profiles/network/server.c | 53 +++++++++++--------
> 4 files changed, 118 insertions(+), 96 deletions(-)
>
> diff --git a/android/pan.c b/android/pan.c
> index 2afc92a..a1356eb 100644
> --- a/android/pan.c
> +++ b/android/pan.c
> @@ -463,8 +463,7 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
> {
> struct pan_device *dev = user_data;
> uint8_t packet[BNEP_MTU];
> - struct bnep_setup_conn_req *req = (void *) packet;
> - uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
> + uint16_t rsp = BNEP_CONN_NOT_ALLOWED;
> int sk, n, err;
>
> if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
> @@ -481,24 +480,8 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
> goto failed;
> }
>
> - /* Highest known control command id BNEP_FILTER_MULT_ADDR_RSP 0x06 */
> - if (req->type == BNEP_CONTROL &&
> - req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
> - error("cmd not understood");
> - bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_CMD_NOT_UNDERSTOOD,
> - req->ctrl);
> - goto failed;
> - }
> -
> - if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) {
> - error("cmd is not BNEP_SETUP_CONN_REQ %02X %02X", req->type,
> - req->ctrl);
> - goto failed;
> - }
> -
> - rsp = bnep_setup_decode(req, &dst_role, &src_role);
> - if (rsp != BNEP_SUCCESS) {
> - error("bnep_setup_decode failed");
> + if (n < 3) {
> + error("pan: to few setup connection request data received");
> goto failed;
> }
>
> @@ -509,8 +492,8 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
> goto failed;
> }
>
> - if (bnep_server_add(sk, dst_role, BNEP_BRIDGE, dev->iface,
> - &dev->dst) < 0) {
> + if (bnep_server_add(sk, BNEP_BRIDGE, dev->iface, &dev->dst, packet, n)
> + < 0) {
> error("pan: server_connadd failed");
> rsp = BNEP_CONN_NOT_ALLOWED;
> goto failed;
> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
> index 0493260..0a41d73 100644
> --- a/profiles/network/bnep.c
> +++ b/profiles/network/bnep.c
> @@ -524,63 +524,25 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
> return err;
> }
>
> -int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
> - const bdaddr_t *addr)
> -{
> - int err;
> -
> - if (!bridge || !iface || !addr)
> - return -EINVAL;
> -
> - err = bnep_connadd(sk, dst, iface);
> - if (err < 0)
> - return err;
> -
> - err = bnep_add_to_bridge(iface, bridge);
> - if (err < 0) {
> - bnep_conndel(addr);
> - return err;
> - }
> -
> - return bnep_if_up(iface);
> -}
> -
> -void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
> -{
> - if (!bridge || !iface || !addr)
> - return;
> -
> - bnep_del_from_bridge(iface, bridge);
> - bnep_if_down(iface);
> - bnep_conndel(addr);
> -}
> -
> -ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
> -{
> - struct bnep_control_rsp rsp;
> -
> - rsp.type = type;
> - rsp.ctrl = ctrl;
> - rsp.resp = htons(resp);
> -
> - return send(sk, &rsp, sizeof(rsp), 0);
> -}
> -
> -uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
> - uint16_t *src)
> +static uint16_t bnep_setup_decode(int sk, struct bnep_setup_conn_req *req,
> + uint16_t *dst)
> {
> const uint8_t bt_base[] = { 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
> 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
> + uint16_t src;
> uint8_t *dest, *source;
> uint32_t val;
>
> + if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ)
> + return BNEP_CONN_NOT_ALLOWED;
> +
> dest = req->service;
> source = req->service + req->uuid_size;
>
> switch (req->uuid_size) {
> case 2: /* UUID16 */
> *dst = get_be16(dest);
> - *src = get_be16(source);
> + src = get_be16(source);
> break;
> case 16: /* UUID128 */
> /* Check that the bytes in the UUID, except the service ID
> @@ -604,7 +566,7 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
> if (val > 0xffff)
> return BNEP_CONN_INVALID_SRC;
>
> - *src = val;
> + src = val;
> break;
> default:
> return BNEP_CONN_INVALID_SVC;
> @@ -614,12 +576,13 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
> switch (*dst) {
> case BNEP_SVC_NAP:
> case BNEP_SVC_GN:
> - if (*src == BNEP_SVC_PANU)
> + if (src == BNEP_SVC_PANU)
> return BNEP_SUCCESS;
> +
> return BNEP_CONN_INVALID_SRC;
> case BNEP_SVC_PANU:
> - if (*src == BNEP_SVC_PANU || *src == BNEP_SVC_GN ||
> - *src == BNEP_SVC_NAP)
> + if (src == BNEP_SVC_PANU || src == BNEP_SVC_GN ||
> + src == BNEP_SVC_NAP)
> return BNEP_SUCCESS;
>
> return BNEP_CONN_INVALID_SRC;
> @@ -627,3 +590,70 @@ uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
>
> return BNEP_CONN_INVALID_DST;
> }
> +
> +int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
> + uint8_t *setup_data, int len)
> +{
> + int err;
> + uint16_t dst = NULL;
> + struct bnep_setup_conn_req *req = (void *) setup_data;
> +
> + /* Highest known Control command ID
> + * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
> + if (req->type == BNEP_CONTROL &&
> + req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
> + uint8_t pkt[3];
> +
> + pkt[0] = BNEP_CONTROL;
> + pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
> + pkt[2] = req->ctrl;
> +
> + send(sk, pkt, sizeof(pkt), 0);
> +
> + return -EINVAL;
> + }
> +
> + /* Processing BNEP_SETUP_CONNECTION_REQUEST_MSG */
> + err = bnep_setup_decode(sk, req, &dst);
> + if (err < 0) {
> + error("bnep: error while decoding setup connection request: %d",
> + err);
> + return -EINVAL;
> + }
> +
> + if (!bridge || !iface || !addr || !dst)
> + return -EINVAL;
> +
> + err = bnep_connadd(sk, dst, iface);
> + if (err < 0)
> + return err;
> +
> + err = bnep_add_to_bridge(iface, bridge);
> + if (err < 0) {
> + bnep_conndel(addr);
> + return err;
> + }
> +
> + return bnep_if_up(iface);
> +}
> +
> +void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
> +{
> + if (!bridge || !iface || !addr)
> + return;
> +
> + bnep_del_from_bridge(iface, bridge);
> + bnep_if_down(iface);
> + bnep_conndel(addr);
> +}
> +
> +ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
> +{
> + struct bnep_control_rsp rsp;
> +
> + rsp.type = type;
> + rsp.ctrl = ctrl;
> + rsp.resp = htons(resp);
> +
> + return send(sk, &rsp, sizeof(rsp), 0);
> +}
> diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
> index b0a91e5..2686ea8 100644
> --- a/profiles/network/bnep.h
> +++ b/profiles/network/bnep.h
> @@ -40,10 +40,8 @@ void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
> void *data);
> void bnep_disconnect(struct bnep *session);
>
> -int bnep_server_add(int sk, uint16_t dst, char *bridge, char *iface,
> - const bdaddr_t *addr);
> +int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
> + uint8_t *setup_data, int len);
> void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
>
> ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
> -uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, uint16_t *dst,
> - uint16_t *src);
> diff --git a/profiles/network/server.c b/profiles/network/server.c
> index 04f188a..4644133 100644
> --- a/profiles/network/server.c
> +++ b/profiles/network/server.c
> @@ -47,6 +47,7 @@
> #include "src/log.h"
> #include "src/error.h"
> #include "src/sdpd.h"
> +#include "src/shared/util.h"
>
> #include "bnep.h"
> #include "server.h"
> @@ -281,11 +282,14 @@ static void setup_destroy(void *user_data)
> static gboolean bnep_setup(GIOChannel *chan,
> GIOCondition cond, gpointer user_data)
> {
> + const uint8_t bt_base[] = { 0x00, 0x00, 0x10, 0x00, 0x80, 0x00,
> + 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB };
> struct network_adapter *na = user_data;
> struct network_server *ns;
> uint8_t packet[BNEP_MTU];
> struct bnep_setup_conn_req *req = (void *) packet;
> - uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
> + uint16_t dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
> + uint32_t val;
> int n, sk;
>
> if (cond & G_IO_NVAL)
> @@ -305,29 +309,36 @@ static gboolean bnep_setup(GIOChannel *chan,
> return FALSE;
> }
>
> - /* Highest known Control command ID
> - * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
> - if (req->type == BNEP_CONTROL &&
> - req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
> - uint8_t pkt[3];
> -
> - pkt[0] = BNEP_CONTROL;
> - pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
> - pkt[2] = req->ctrl;
> -
> - send(sk, pkt, sizeof(pkt), 0);
> -
> + /*
> + * Initial received data packet is BNEP_SETUP_CONNECTION_REQUEST_MSG
> + * minimal size of this frame is 3 octets: 1 byte of BNEP Type +
> + * 1 byte of BNEP Control Type + 1 byte of BNEP services UUID size.
> + */
> + if (n < 3) {
> + error("To few setup connection request data received");
> return FALSE;
> }
>
> - if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ)
> - return FALSE;
> + switch (req->uuid_size) {
> + case 2:
> + dst_role = get_be16(req->service);
> + break;
> + case 16:
> + if (memcmp(&req->service[4], bt_base, sizeof(bt_base)) != 0)
> + return FALSE;
>
> - rsp = bnep_setup_decode(req, &dst_role, &src_role);
> - if (rsp != BNEP_SUCCESS)
> - goto reply;
> + /* Intentional no-brake */
>
> - rsp = BNEP_CONN_NOT_ALLOWED;
> + case 4:
> + val = get_be32(req->service);
> + if (val > 0xffff)
> + return FALSE;
> +
> + dst_role = val;
> + break;
> + default:
> + return FALSE;
> + }
>
> ns = find_server(na->servers, dst_role);
> if (!ns) {
> @@ -348,8 +359,8 @@ static gboolean bnep_setup(GIOChannel *chan,
> strncpy(na->setup->dev, BNEP_INTERFACE, 16);
> na->setup->dev[15] = '\0';
>
> - if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
> - &na->setup->dst) < 0)
> + if (bnep_server_add(sk, ns->bridge, na->setup->dev,
> + &na->setup->dst, packet, n) < 0)
> goto reply;
>
> na->setup = NULL;

Patches 1-4 are now applied, thanks.



--
Best regards,
Szymon Janc

2015-03-12 10:09:49

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v3 09/10] tools/bneptest: Add generic connect/listen funcionality

Hi Grzegorz,

On Monday 09 of March 2015 17:24:54 Grzegorz Kolodziejczyk wrote:

There is typo in commit message: funcionality -> functionality

> This patch adds general funcionality of bnep connect and listen.
> ---
> tools/bneptest.c | 553 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 548 insertions(+), 5 deletions(-)
>
> diff --git a/tools/bneptest.c b/tools/bneptest.c
> index cafeba9..251b71d 100644
> --- a/tools/bneptest.c
> +++ b/tools/bneptest.c
> @@ -26,43 +26,549 @@
> #endif
>
> #include <stdio.h>
> +#include <signal.h>
> #include <stdlib.h>
> #include <getopt.h>
> +#include <stdbool.h>
> +#include <errno.h>
> +#include <unistd.h>
> +#include <sys/ioctl.h>
> +#include <net/if.h>
> +#include <linux/sockios.h>
> +#include <netinet/in.h>
> +#include <linux/if_bridge.h>
> +
> +#include <bluetooth/bluetooth.h>
> +#include <bluetooth/hci.h>
> +#include <bluetooth/hci_lib.h>
>
> #include <glib.h>
>
> #include "src/log.h"
> +#include "btio/btio.h"
> +#include "lib/bnep.h"
> +#include "profiles/network/bnep.h"
> +
> +enum {
> + MODE_NONE,
> + MODE_CONNECT,
> + MODE_LISTEN,
> +};
>
> static GMainLoop *mloop;
> +static GIOChannel *bnep_io;
> +
> +static int mode;
> +static bool no_close_after_disconn;
> +static int send_ctrl_frame_timeout;
> +
> +static bdaddr_t src_addr, dst_addr;
> +static char iface[16] = "nap_iface%d";
> +static char bridge[16] = "bnep_bridge";
> +static uint8_t send_msg_type = 0x00;
> +static uint16_t local_role = BNEP_SVC_PANU;
> +static uint16_t remote_role = BNEP_SVC_NAP;
> +static uint16_t ntw_proto_down_range = 0x0000;
> +static uint16_t ntw_proto_up_range = 0xdc05;
> +static uint8_t mcast_addr_down_range[6] = { 0x00, 0x00, 0x00, 0x00, 0x00,
> + 0x00 };
> +static uint8_t mcast_addr_up_range[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
> +static struct bnep *session;
> +
> +
> +static int set_forward_delay(int sk)
> +{
> + unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0, 0, 0 };
> + struct ifreq ifr;
> +
> + memset(&ifr, 0, sizeof(ifr));
> + strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
> + ifr.ifr_data = (char *) args;
> +
> + if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) {
> + error("setting forward delay failed: %d (%s)",
> + errno, strerror(errno));
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int nap_create_bridge(void)
> +{
> + int sk, err;
> +
> + sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
> + if (sk < 0)
> + return -EOPNOTSUPP;
> +
> + if (ioctl(sk, SIOCBRADDBR, bridge) < 0) {
> + err = -errno;
> + if (err != -EEXIST) {
> + close(sk);
> + return -EOPNOTSUPP;
> + }
> + }
> +
> + err = set_forward_delay(sk);
> + if (err < 0) {
> + printf("failed to set forward delay\n");
> + ioctl(sk, SIOCBRDELBR, bridge);
> + }
> +
> + close(sk);
> +
> + return err;
> +}
> +
> +static int cleanup(void)
> +{
> + bnep_cleanup();
> +
> + if (mode == MODE_LISTEN)
> + bnep_server_delete(bridge, iface, &dst_addr);
> +
> + if (bnep_io) {
> + g_io_channel_shutdown(bnep_io, TRUE, NULL);
> + g_io_channel_unref(bnep_io);
> + }
> +
> + return 0;
> +}
> +
> +static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
> + gpointer user_data)
> +{
> + printf("%s\n", __func__);
> +
> + if (no_close_after_disconn)
> + return FALSE;
> +
> + /* Cleanup since it's called when disconnected l2cap */
> + if (cleanup() < 0) {
> + printf("cleanup went wrong...\n");
> + return FALSE;
> + }
> +
> + g_main_loop_quit(mloop);
> + return FALSE;
> +}
> +
> +static ssize_t send_ctrl_frame(int sk)
> +{
> + /* Max buff size = type(1byte) + ctrl(1byte) + len(2byte) +
> + * mcast_addr_down(6byte) + mcast_addr_up(6byte) */
> + uint8_t buff[16];
> + int err;
> +
> + printf("%s\n", __func__);
> +
> + if (send_ctrl_frame_timeout > 0) {
> + printf("waiting %d seconds before sending msg\n",
> + send_ctrl_frame_timeout);
> + sleep(send_ctrl_frame_timeout);
> + }
> +
> + switch (send_msg_type) {
> + case BNEP_FILTER_NET_TYPE_SET: {
> + struct bnep_set_filter_req *frame = (void *)buff;
> +
> + frame->type = BNEP_CONTROL;
> + frame->ctrl = send_msg_type;
> + frame->len = htons(sizeof(ntw_proto_down_range) +
> + sizeof(ntw_proto_up_range));
> + memcpy(frame->list, &ntw_proto_down_range,
> + sizeof(ntw_proto_down_range));
> + memcpy(frame->list + sizeof(ntw_proto_down_range),
> + &ntw_proto_up_range, sizeof(ntw_proto_up_range));
> +
> + err = send(sk, frame, sizeof(*frame) +
> + sizeof(ntw_proto_down_range) +
> + sizeof(ntw_proto_up_range), 0);
> +
> + break;
> +
> + }
> + case BNEP_FILTER_MULT_ADDR_SET: {
> + struct bnep_set_filter_req *frame = (void *)buff;
> +
> + frame->type = BNEP_CONTROL;
> + frame->ctrl = send_msg_type;
> + frame->len = htons(sizeof(mcast_addr_down_range) +
> + sizeof(mcast_addr_up_range));
> + memcpy(frame->list, mcast_addr_down_range,
> + sizeof(mcast_addr_down_range));
> + memcpy(frame->list + sizeof(mcast_addr_down_range),
> + mcast_addr_up_range, sizeof(mcast_addr_up_range));
> +
> + err = send(sk, frame, sizeof(*frame) +
> + sizeof(mcast_addr_down_range) +
> + sizeof(mcast_addr_up_range), 0);
> +
> + break;
> +
> + }
> + default:
> + err = -1;
> + }
> +
> + return err;
> +}
> +
> +static gboolean setup_bnep_cb(GIOChannel *chan, GIOCondition cond,
> + gpointer user_data)
> +{
> + uint8_t packet[BNEP_MTU];
> + int sk, n, err;
> +
> + printf("%s\n", __func__);
> +
> + if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
> + error("hangup or error or inval on BNEP socket");
> + return FALSE;
> + }
> +
> + sk = g_io_channel_unix_get_fd(chan);
> +
> + /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
> + n = read(sk, packet, sizeof(packet));
> + if (n < 0) {
> + error("read(): %s(%d)", strerror(errno), errno);
> + return FALSE;
> + }
> +
> + err = nap_create_bridge();
> + if (err < 0) {
> + error("failed to create bridge: %s (%d)", strerror(-err), err);
> + return FALSE;
> + }
> +
> + if (bnep_server_add(sk, (err < 0) ? NULL : bridge, iface, &dst_addr,
> + packet, n) < 0) {
> + printf("server_connadd failed\n");
> + cleanup();
> + return FALSE;
> + }
> +
> + g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL, bnep_watchdog_cb,
> + NULL);
> +
> + if (send_msg_type) {
> + if (send_ctrl_frame(sk) < 0)
> + printf("error while sending ctrl frame : %s (%d)\n",
> + strerror(errno), errno);
> + }
> +
> + g_io_channel_unref(bnep_io);
> + bnep_io = NULL;
> +
> + return FALSE;
> +}
> +
> +static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
> +{
> + printf("%s\n", __func__);
> +
> + if (err) {
> + error("%s", err->message);
> + return;
> + }
> +
> + g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
> + setup_bnep_cb, NULL);
> +}
> +
> +static void connected_client_cb(char *iface, int err, void *data)
> +{
> + int sk = *((int *)data);
> +
> + printf("%s\n", __func__);
> +
> + free(data);
> +
> + if (send_msg_type) {
> + if (send_ctrl_frame(sk) < 0)
> + printf("error while sendind ctrl frame : %s (%d)\n",
> + strerror(errno), errno);
> + }
> +}
> +
> +static void disconnected_client_cb(void *data)
> +{
> + printf("%s\n", __func__);
> +
> + if (no_close_after_disconn)
> + return;
> +
> + /* Cleanup since it's called when disconnected l2cap */
> + if (cleanup() < 0) {
> + printf("cleanup went wrong...\n");
> + return;
> + }
> +
> + g_main_loop_quit(mloop);
> +}
> +
> +static void connect_client_cb(GIOChannel *chan, GError *err, gpointer user_data)
> +{
> + int perr;
> + int *sk;
> +
> + sk = malloc(sizeof(*sk));
> +
> + *sk = g_io_channel_unix_get_fd(bnep_io);
> +
> + session = bnep_new(*sk, local_role, remote_role, bridge);
> + if (!session) {
> + printf("cannot create bnep session\n");
> + free(sk);
> + return;
> + }
> +
> + perr = bnep_connect(session, connected_client_cb,
> + disconnected_client_cb, sk, NULL);
> + if (perr < 0)
> + printf("cannot initiate bnep connection\n");
> +}
> +
> +static void confirm_cb(GIOChannel *chan, gpointer data)
> +{
> + GError *err = NULL;
> + char address[18];
> +
> + printf("%s\n", __func__);
> +
> + bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst_addr, BT_IO_OPT_DEST,
> + address, BT_IO_OPT_INVALID);
> + if (err) {
> + error("%s", err->message);
> + g_error_free(err);
> + return;
> + }
> +
> + printf("incoming connection from: %s\n", address);
> +
> + bnep_io = g_io_channel_ref(chan);
> + g_io_channel_set_close_on_unref(bnep_io, TRUE);
> +
> + if (!bt_io_accept(bnep_io, connect_cb, NULL, NULL, &err)) {
> + error("bt_io_accept: %s", err->message);
> + g_error_free(err);
> + }
> +}
> +
> +static int bnep_server_listen(void)
> +{
> + GError *gerr = NULL;
> +
> + printf("%s\n", __func__);
> +
> + bnep_io = bt_io_listen(NULL, confirm_cb, NULL, NULL, &gerr,
> + BT_IO_OPT_SOURCE_BDADDR, &src_addr,
> + BT_IO_OPT_PSM, BNEP_PSM,
> + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
> + BT_IO_OPT_OMTU, BNEP_MTU,
> + BT_IO_OPT_IMTU, BNEP_MTU,
> + BT_IO_OPT_INVALID);
> +
> + if (!bnep_io) {
> + printf("can't start server listening: err %s\n", gerr->message);
> + g_error_free(gerr);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static int bnep_client_connect(void)
> +{
> + GError *gerr = NULL;
> + char *dst_addr_str = batostr(&dst_addr);
> +
> + printf("%s\n", __func__);
> +
> + printf("connecting %s\n", dst_addr_str);
> + free(dst_addr_str);
> +
> + bnep_io = bt_io_connect(connect_client_cb, NULL, NULL, &gerr,
> + BT_IO_OPT_SOURCE_BDADDR, &src_addr,
> + BT_IO_OPT_DEST_BDADDR, &dst_addr,
> + BT_IO_OPT_PSM, BNEP_PSM,
> + BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
> + BT_IO_OPT_OMTU, BNEP_MTU,
> + BT_IO_OPT_IMTU, BNEP_MTU,
> + BT_IO_OPT_INVALID);
> +
> + if (!bnep_io) {
> + printf("cannot connect: err %s\n", gerr->message);
> + g_error_free(gerr);
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +static void exit_handler(int sig)
> +{
> + printf("got sig = %d, cleaning up...\n", sig);
> +
> + if (cleanup() < 0)
> + printf("cleanup failure...\n");
> + else
> + printf("cleanup successful - exit\n");
> +
> + exit(0);
> +}
>
> static void usage(void)
> {
> printf("bneptest - BNEP testing ver %s\n", VERSION);
> printf("Usage:\n"
> - "\tbneptest [options]\n");
> + "\tbneptest <connection mode> [send_ctrl_cmd] [options]\n");
> + printf("Connect Mode:\n"
> + "\t-c connect <dst_addr>\n"
> + "\t-r remote role <16 bit svc value>\n"
> + "\t-l local role <16 bit svc valu>\n");
> + printf("Listen Mode:\n"
> + "\t-s start server listening\n");
> + printf("Send control command:\n"
> + "\t-t send message type <control msg type>\n"
> + "\t-T send message timeout after setup <seconds>\n"
> + "\t-e starting network protocol type range <16 bit value>\n"
> + "\t-d ending network protocol type range <16 bit value>\n"
> + "\t-g starting multicast addr range <xx:xx:xx:xx:xx:xx>\n"
> + "\t-j ending multicast addr range <xx:xx:xx:xx:xx:xx>\n");
> + printf("Options:\n"
> + "\t-b bridge name <string>\n"
> + "\t-n interface name <string>\n");
> }
>
> static struct option main_options[] = {
> - { "help", 0, 0, 'h' },
> + { "device", 1, 0, 'i' },
> + { "listen", 0, 0, 's' },
> + { "connect", 1, 0, 'c' },
> + { "snd_msg_type", 1, 0, 't' },
> + { "send_timeout", 1, 0, 'T' },
> + { "ntw_proto_down_range", 1, 0, 'd' },
> + { "ntw_proto_up_range", 1, 0, 'e' },
> + { "mcast_addr_down_range", 1, 0, 'g' },
> + { "mcast_addr_up_range", 1, 0, 'j' },
> + { "local_role", 1, 0, 'l' },
> + { "remote_role", 1, 0, 'r' },
> + { "bridge name", 1, 0, 'b' },
> + { "iface name", 1, 0, 'n' },
> + { "no_close", 0, 0, 'N' },
> + { "help", 0, 0, 'h' },
> { 0, 0, 0, 0 }
> };
>
> int main(int argc, char *argv[])
> {
> int opt;
> + int err;
>
> DBG("");
>
> + signal(SIGINT, exit_handler);
> +
> + hci_devba(0, &src_addr);
> + bacpy(&src_addr, BDADDR_ANY);
> +
> mloop = g_main_loop_new(NULL, FALSE);
> if (!mloop) {
> - printf("Cannot create main loop\n");
> + printf("cannot create main loop\n");
>
> exit(1);
> }
>
> - while ((opt = getopt_long(argc, argv, "h", main_options, NULL))
> - != EOF) {
> + while ((opt = getopt_long(argc, argv, "+i:b:n:c:t:T:d:e:g:j:Nsh",
> + main_options, NULL)) != EOF) {
> switch (opt) {
> + case 'i':
> + if (!strncmp(optarg, "hci", 3))
> + hci_devba(atoi(optarg + 3), &src_addr);
> + else
> + str2ba(optarg, &src_addr);
> +
> + break;
> +
> + case 's':
> + mode = MODE_LISTEN;
> + break;
> +
> + case 'c':
> + str2ba(optarg, &dst_addr);
> + mode = MODE_CONNECT;
> +
> + break;
> +
> + case 't':
> + send_msg_type = atoi(optarg);
> +
> + break;
> +
> + case 'T':
> + send_ctrl_frame_timeout = atoi(optarg);
> +
> + break;
> +
> + case 'd':
> + ntw_proto_down_range = htons(atoi(optarg));
> +
> + break;
> +
> + case 'e':
> + ntw_proto_up_range = htons(atoi(optarg));
> +
> + break;
> +
> + case 'g': {
> + int i = 0;
> +
> + for (i = 5; i >= 0; i--, optarg += 3)
> + mcast_addr_down_range[i] =
> + strtol(optarg, NULL, 16);
> +
> + break;
> + }
> +
> + case 'j': {
> + int i = 0;
> +
> + for (i = 5; i >= 0; i--, optarg += 3)
> + mcast_addr_up_range[i] =
> + strtol(optarg, NULL, 16);
> +
> + break;
> + }
> +
> + case 'l':
> + local_role = atoi(optarg);
> +
> + break;
> +
> + case 'r':
> + remote_role = atoi(optarg);
> +
> + break;
> +
> + case 'b':
> + strncpy(bridge, optarg, 16);
> + bridge[15] = '\0';
> +
> + break;
> +
> + case 'n':
> + strncpy(iface, optarg, 16);
> + iface[15] = '\0';
> +
> + break;
> +
> + case 'N':
> + no_close_after_disconn = true;
> +
> + break;
> +
> case 'h':
> default:
> usage();
> @@ -70,5 +576,42 @@ int main(int argc, char *argv[])
> }
> }
>
> + switch (mode) {
> + case MODE_CONNECT:
> + err = bnep_init();
> + if (err < 0) {
> + printf("cannot initialize bnep\n");
> + exit(1);
> + }
> + err = bnep_client_connect();
> + if (err < 0)
> + exit(1);
> +
> + break;
> +
> + case MODE_LISTEN:
> + err = bnep_init();
> + if (err < 0) {
> + printf("cannot initialize bnep\n");
> + exit(1);
> + }
> + err = bnep_server_listen();
> + if (err < 0)
> + exit(1);
> +
> + break;
> +
> + case MODE_NONE:
> + default:
> + printf("connect/listen mode not set, exit...\n");
> + exit(1);
> + }
> +
> + g_main_loop_run(mloop);
> +
> + printf("Done\n");
> +
> + g_main_loop_unref(mloop);
> +
> return 0;
> }
>

--
Best regards,
Szymon Janc

2015-03-12 10:07:37

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] android/pts: Add BNEP PTS 6.0 results for android 5.0

Hi Grzegorz,

On Monday 09 of March 2015 17:24:55 Grzegorz Kolodziejczyk wrote:
> This patch adds test case list and results for BNEP profile against
> android 5.0
> ---
> android/pics-bnep.txt | 26 ++++++++++++++
> android/pixit-bnep.txt | 30 ++++++++++++++++
> android/pts-bnep.txt | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 148 insertions(+)
> create mode 100644 android/pics-bnep.txt
> create mode 100644 android/pixit-bnep.txt
> create mode 100644 android/pts-bnep.txt

One more thing: new txt files need to be added to EXTRA_DIST in android/Makefile.am

>
> diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt
> new file mode 100644
> index 0000000..2279c9a
> --- /dev/null
> +++ b/android/pics-bnep.txt
> @@ -0,0 +1,26 @@
> +BNEP PICS for the PTS tool.
> +
> +PTS version: 6.0
> +
> +* - different than PTS defaults
> +# - not yet implemented/supported
> +
> +M - mandatory if such role selected
> +O - optional
> +
> + Profile Version
> +-------------------------------------------------------------------------------
> +Parameter Name Selected Description
> +-------------------------------------------------------------------------------
> +TSPC_BNEP_1_1 True BNEP Connection Setup (M)
> +TSPC_BNEP_1_2 False BNEP Data Packet Reception (M)
> +TSPC_BNEP_1_3 False BNEP Data Packet Transmission (M)
> +TSPC_BNEP_1_3a False BNEP Compressed Packet Transmission (O)
> +TSPC_BNEP_1_3b False BNEP Compressed Packet Transmission Source Only
> + (O)
> +TSPC_BNEP_1_4 True BNEP Control Message Processing (M)
> +TSPC_BNEP_1_5 True BNEP Extension Header Processing (M)
> +TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O)
> +TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission
> + (O)
> +-------------------------------------------------------------------------------
> diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt
> new file mode 100644
> index 0000000..9a26cd2
> --- /dev/null
> +++ b/android/pixit-bnep.txt
> @@ -0,0 +1,30 @@
> +BNEP PIXIT for the PTS tool.
> +
> +PTS version: 6.0
> +
> +* - different than PTS defaults
> +& - should be set to IUT Bluetooth address
> +# - should be set to PTS's bin/audio folder
> +
> +Required PIXIT settings
> +-------------------------------------------------------------------------------
> +Parameter Name Value
> +-------------------------------------------------------------------------------
> +TSPX_class_of_device 04041C
> +TSPX_security_control_data
> +TSPX_content_protection_data
> +TSPX_bd_addr_iut 112233445566 (*&)
> +TSPX_delete_link_key FALSE
> +TSPX_pin_code 1234
> +TSPX_security_enabled FALSE
> +TSPX_time_guard 300000
> +TSPX_use_implicit_send TRUE
> +TSPX_auth_password 0000
> +TSPX_auth_user_id PTS
> +TSPX_l2cap_psm 000F
> +TSPX_rfcomm_channel 8
> +TSPX_no_confirmations FALSE
> +TSPX_UUID_dest_address 1116
> +TSPX_UUID_source_address 1115
> +TSPX_MAC_dest_address 000000000000 (*&)
> +TSPX_MAC_source_address 000000000000 (*&)
> diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt
> new file mode 100644
> index 0000000..7945385
> --- /dev/null
> +++ b/android/pts-bnep.txt
> @@ -0,0 +1,92 @@
> +PTS test results for BNEP
> +
> +PTS version: 6.0
> +Tested: 03-March-2015
> +Android version: 5.0
> +Kernel version: 3.20
> +
> +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_CTRL_BV_01_C PASS bneptest -s
> +TC_CTRL_BV_02_C PASS bneptest -c <PTS addr>
> +TC_CTRL_BV_03_C PASS bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_04_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_05_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_06_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_07_C INC PTS issue #13170
> + bneptest -c <PTS addr> -t 3 -d 0 -e 1500
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_08_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_09_C INC PTS issue #13170
> + bneptest -c 00:1b:dc:06:06:ca -n enp0s29u1u7
> + -t 5 -g 00:00:00:00:00:00
> + -j ff:ff:ff:ff:ff:ff
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_10_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_19_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_11_C N/A
> +TC_RX_C_BV_12_C N/A
> +TC_RX_C_S_BV_13_C N/A
> +TC_RX_C_S_BV_14_C N/A
> +TC_RX_TYPE_0_BV_15_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_16_C INC PTS issue #13171
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_17_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_18_C INC PTS issue #13171
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_TX_TYPE_0_BV_20_C N/A
> +TC_TX_C_BV_21_C N/A
> +TC_TX_C_S_BV_22_C N/A
> +TC_TX_C_D_BV_23_C N/A
>

--
Best regards,
Szymon Janc

2015-03-12 10:07:04

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] android/pts: Add BNEP PTS 6.0 results for android 5.0

Hi Grzegorz,


On 12 March 2015 at 11:04, Szymon Janc <[email protected]> wrote:
> Hi Grzegorz,
>
> On Monday 09 of March 2015 17:24:55 Grzegorz Kolodziejczyk wrote:
>> This patch adds test case list and results for BNEP profile against
>> android 5.0
>> ---
>> android/pics-bnep.txt | 26 ++++++++++++++
>> android/pixit-bnep.txt | 30 ++++++++++++++++
>> android/pts-bnep.txt | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
>> 3 files changed, 148 insertions(+)
>> create mode 100644 android/pics-bnep.txt
>> create mode 100644 android/pixit-bnep.txt
>> create mode 100644 android/pts-bnep.txt
>>
>> diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt
>> new file mode 100644
>> index 0000000..2279c9a
>> --- /dev/null
>> +++ b/android/pics-bnep.txt
>> @@ -0,0 +1,26 @@
>> +BNEP PICS for the PTS tool.
>> +
>> +PTS version: 6.0
>> +
>> +* - different than PTS defaults
>> +# - not yet implemented/supported
>> +
>> +M - mandatory if such role selected
>> +O - optional
>> +
>> + Profile Version
>> +-------------------------------------------------------------------------------
>> +Parameter Name Selected Description
>> +-------------------------------------------------------------------------------
>> +TSPC_BNEP_1_1 True BNEP Connection Setup (M)
>> +TSPC_BNEP_1_2 False BNEP Data Packet Reception (M)
>> +TSPC_BNEP_1_3 False BNEP Data Packet Transmission (M)
>> +TSPC_BNEP_1_3a False BNEP Compressed Packet Transmission (O)
>
> 1_2 1_3 and 1_3a should be True.
>
So, I'll set it to True and update results.
>> +TSPC_BNEP_1_3b False BNEP Compressed Packet Transmission Source Only
>> + (O)
>> +TSPC_BNEP_1_4 True BNEP Control Message Processing (M)
>> +TSPC_BNEP_1_5 True BNEP Extension Header Processing (M)
>> +TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O)
>> +TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission
>> + (O)
>> +-------------------------------------------------------------------------------
>> diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt
>> new file mode 100644
>> index 0000000..9a26cd2
>> --- /dev/null
>> +++ b/android/pixit-bnep.txt
>> @@ -0,0 +1,30 @@
>> +BNEP PIXIT for the PTS tool.
>> +
>> +PTS version: 6.0
>> +
>> +* - different than PTS defaults
>> +& - should be set to IUT Bluetooth address
>> +# - should be set to PTS's bin/audio folder
>> +
>> +Required PIXIT settings
>> +-------------------------------------------------------------------------------
>> +Parameter Name Value
>> +-------------------------------------------------------------------------------
>> +TSPX_class_of_device 04041C
>> +TSPX_security_control_data
>> +TSPX_content_protection_data
>> +TSPX_bd_addr_iut 112233445566 (*&)
>> +TSPX_delete_link_key FALSE
>> +TSPX_pin_code 1234
>> +TSPX_security_enabled FALSE
>> +TSPX_time_guard 300000
>> +TSPX_use_implicit_send TRUE
>> +TSPX_auth_password 0000
>> +TSPX_auth_user_id PTS
>> +TSPX_l2cap_psm 000F
>> +TSPX_rfcomm_channel 8
>> +TSPX_no_confirmations FALSE
>> +TSPX_UUID_dest_address 1116
>> +TSPX_UUID_source_address 1115
>> +TSPX_MAC_dest_address 000000000000 (*&)
>> +TSPX_MAC_source_address 000000000000 (*&)
>> diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt
>> new file mode 100644
>> index 0000000..7945385
>> --- /dev/null
>> +++ b/android/pts-bnep.txt
>> @@ -0,0 +1,92 @@
>> +PTS test results for BNEP
>> +
>> +PTS version: 6.0
>> +Tested: 03-March-2015
>> +Android version: 5.0
>> +Kernel version: 3.20
>> +
>> +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_CTRL_BV_01_C PASS bneptest -s
>> +TC_CTRL_BV_02_C PASS bneptest -c <PTS addr>
>> +TC_CTRL_BV_03_C PASS bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_04_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_05_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_06_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_07_C INC PTS issue #13170
>> + bneptest -c <PTS addr> -t 3 -d 0 -e 1500
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_08_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_09_C INC PTS issue #13170
>> + bneptest -c 00:1b:dc:06:06:ca -n enp0s29u1u7
>> + -t 5 -g 00:00:00:00:00:00
>> + -j ff:ff:ff:ff:ff:ff
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_10_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_CTRL_BV_19_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_11_C N/A
>> +TC_RX_C_BV_12_C N/A
>> +TC_RX_C_S_BV_13_C N/A
>> +TC_RX_C_S_BV_14_C N/A
>> +TC_RX_TYPE_0_BV_15_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_16_C INC PTS issue #13171
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_17_C INC PTS issue #13169
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_RX_TYPE_0_BV_18_C INC PTS issue #13171
>> + bneptest -s
>> + Note: could be necessary setting approperiate
>> + naming of interface using option
>> + -n <iface name>, eg. -n enp0s29u1u7
>> +TC_TX_TYPE_0_BV_20_C N/A
>> +TC_TX_C_BV_21_C N/A
>> +TC_TX_C_S_BV_22_C N/A
>> +TC_TX_C_D_BV_23_C N/A
>>
>
> --
> Best regards,
> Szymon Janc

Best regards,
Grzegorz Kolodziejczyk

2015-03-12 10:05:16

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: Re: [PATCH v3 05/10] profiles/network: Remove unneded bnep_uuid function from bnep code

Hi Szymon,

On 12 March 2015 at 11:02, Szymon Janc <[email protected]> wrote:
> Hi Grzegorz,
>
> On Monday 09 of March 2015 17:24:50 Grzegorz Kolodziejczyk wrote:
>> This function is no longer needed since connection and server can handle
>> this funcionality by itself.
>> ---
>> profiles/network/bnep.c | 10 ----------
>> profiles/network/bnep.h | 1 -
>> profiles/network/connection.c | 19 ++++++++++++-------
>> profiles/network/server.c | 24 +++++++++++++++++++++---
>> 4 files changed, 33 insertions(+), 21 deletions(-)
>>
>> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
>> index 3fe63f0..a81a260 100644
>> --- a/profiles/network/bnep.c
>> +++ b/profiles/network/bnep.c
>> @@ -85,16 +85,6 @@ struct bnep {
>> void *disconn_data;
>> };
>>
>> -const char *bnep_uuid(uint16_t id)
>> -{
>> - int i;
>> -
>> - for (i = 0; __svc[i].uuid128; i++)
>> - if (__svc[i].id == id)
>> - return __svc[i].uuid128;
>> - return NULL;
>> -}
>> -
>> const char *bnep_name(uint16_t id)
>> {
>> int i;
>> diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
>> index 31579f9..811ea14 100644
>> --- a/profiles/network/bnep.h
>> +++ b/profiles/network/bnep.h
>> @@ -26,7 +26,6 @@ struct bnep;
>> int bnep_init(void);
>> int bnep_cleanup(void);
>>
>> -const char *bnep_uuid(uint16_t id);
>> const char *bnep_name(uint16_t id);
>>
>> struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
>> diff --git a/profiles/network/connection.c b/profiles/network/connection.c
>> index 4311cc9..da8b86e 100644
>> --- a/profiles/network/connection.c
>> +++ b/profiles/network/connection.c
>> @@ -284,21 +284,23 @@ static DBusMessage *local_connect(DBusConnection *conn,
>> struct btd_service *service;
>> struct network_conn *nc;
>> const char *svc;
>> - const char *uuid;
>> uint16_t id;
>> int err;
>> + char uuid_str[MAX_LEN_UUID_STR];
>> + bt_uuid_t uuid;
>>
>> if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
>> DBUS_TYPE_INVALID) == FALSE)
>> return btd_error_invalid_args(msg);
>>
>> id = get_pan_srv_id(svc);
>> - uuid = bnep_uuid(id);
>> + bt_uuid16_create(&uuid, id);
>> + bt_uuid_to_uuid128(&uuid, &uuid);
>>
>> - if (uuid == NULL)
>> + if (bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR) < 0)
>> return btd_error_invalid_args(msg);
>>
>> - service = btd_device_get_service(peer->device, uuid);
>> + service = btd_device_get_service(peer->device, uuid_str);
>> if (service == NULL)
>> return btd_error_not_supported(msg);
>>
>> @@ -439,15 +441,18 @@ static gboolean network_property_get_uuid(const GDBusPropertyTable *property,
>> {
>> struct network_peer *peer = data;
>> struct network_conn *nc;
>> - const char *uuid;
>> + char uuid_str[MAX_LEN_UUID_STR];
>> + bt_uuid_t uuid;
>>
>> nc = find_connection_by_state(peer->connections, CONNECTED);
>> if (nc == NULL)
>> return FALSE;
>>
>> - uuid = bnep_uuid(nc->id);
>> + bt_uuid16_create(&uuid, nc->id);
>> + bt_uuid_to_uuid128(&uuid, &uuid);
>> + bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR);
>>
>> - dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
>> + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid_str);
>>
>> return TRUE;
>> }
>> diff --git a/profiles/network/server.c b/profiles/network/server.c
>> index 9caabb0..e05bc1a 100644
>> --- a/profiles/network/server.c
>> +++ b/profiles/network/server.c
>> @@ -114,14 +114,32 @@ static struct network_server *find_server(GSList *list, uint16_t id)
>> static struct network_server *find_server_by_uuid(GSList *list,
>> const char *uuid)
>> {
>> + bt_uuid_t srv_uuid, bnep_uuid;
>> +
>> for (; list; list = list->next) {
>> struct network_server *ns = list->data;
>> + bt_uuid16_create(&bnep_uuid, ns->id);
>>
>> - if (strcasecmp(uuid, bnep_uuid(ns->id)) == 0)
>> + /* UUID value compare */
>> + if (!bt_string_to_uuid(&srv_uuid, uuid) &&
>> + !bt_uuid_cmp(&srv_uuid, &bnep_uuid))
>> return ns;
>
> Please call bt_string_to_uuid() before loop and based on its result
> check if uuid or name compare is needed.
>
> This should make code a bit faster and easier to read.
>
Ok, I agree. I'll reorganize this.
>>
>> - if (strcasecmp(uuid, bnep_name(ns->id)) == 0)
>> - return ns;
>> + /* String value compare */
>> + switch (ns->id) {
>> + case BNEP_SVC_PANU:
>> + if (!strcasecmp(uuid, "panu"))
>> + return ns;
>> + break;
>> + case BNEP_SVC_NAP:
>> + if (!strcasecmp(uuid, "nap"))
>> + return ns;
>> + break;
>> + case BNEP_SVC_GN:
>> + if (!strcasecmp(uuid, "gn"))
>> + return ns;
>> + break;
>> + }
>> }
>>
>> return NULL;
>>
>
> --
> Best regards,
> Szymon Janc
Best regards,
Grzegorz Kolodziejczyk

2015-03-12 10:04:36

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v3 10/10] android/pts: Add BNEP PTS 6.0 results for android 5.0

Hi Grzegorz,

On Monday 09 of March 2015 17:24:55 Grzegorz Kolodziejczyk wrote:
> This patch adds test case list and results for BNEP profile against
> android 5.0
> ---
> android/pics-bnep.txt | 26 ++++++++++++++
> android/pixit-bnep.txt | 30 ++++++++++++++++
> android/pts-bnep.txt | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 148 insertions(+)
> create mode 100644 android/pics-bnep.txt
> create mode 100644 android/pixit-bnep.txt
> create mode 100644 android/pts-bnep.txt
>
> diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt
> new file mode 100644
> index 0000000..2279c9a
> --- /dev/null
> +++ b/android/pics-bnep.txt
> @@ -0,0 +1,26 @@
> +BNEP PICS for the PTS tool.
> +
> +PTS version: 6.0
> +
> +* - different than PTS defaults
> +# - not yet implemented/supported
> +
> +M - mandatory if such role selected
> +O - optional
> +
> + Profile Version
> +-------------------------------------------------------------------------------
> +Parameter Name Selected Description
> +-------------------------------------------------------------------------------
> +TSPC_BNEP_1_1 True BNEP Connection Setup (M)
> +TSPC_BNEP_1_2 False BNEP Data Packet Reception (M)
> +TSPC_BNEP_1_3 False BNEP Data Packet Transmission (M)
> +TSPC_BNEP_1_3a False BNEP Compressed Packet Transmission (O)

1_2 1_3 and 1_3a should be True.

> +TSPC_BNEP_1_3b False BNEP Compressed Packet Transmission Source Only
> + (O)
> +TSPC_BNEP_1_4 True BNEP Control Message Processing (M)
> +TSPC_BNEP_1_5 True BNEP Extension Header Processing (M)
> +TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O)
> +TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission
> + (O)
> +-------------------------------------------------------------------------------
> diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt
> new file mode 100644
> index 0000000..9a26cd2
> --- /dev/null
> +++ b/android/pixit-bnep.txt
> @@ -0,0 +1,30 @@
> +BNEP PIXIT for the PTS tool.
> +
> +PTS version: 6.0
> +
> +* - different than PTS defaults
> +& - should be set to IUT Bluetooth address
> +# - should be set to PTS's bin/audio folder
> +
> +Required PIXIT settings
> +-------------------------------------------------------------------------------
> +Parameter Name Value
> +-------------------------------------------------------------------------------
> +TSPX_class_of_device 04041C
> +TSPX_security_control_data
> +TSPX_content_protection_data
> +TSPX_bd_addr_iut 112233445566 (*&)
> +TSPX_delete_link_key FALSE
> +TSPX_pin_code 1234
> +TSPX_security_enabled FALSE
> +TSPX_time_guard 300000
> +TSPX_use_implicit_send TRUE
> +TSPX_auth_password 0000
> +TSPX_auth_user_id PTS
> +TSPX_l2cap_psm 000F
> +TSPX_rfcomm_channel 8
> +TSPX_no_confirmations FALSE
> +TSPX_UUID_dest_address 1116
> +TSPX_UUID_source_address 1115
> +TSPX_MAC_dest_address 000000000000 (*&)
> +TSPX_MAC_source_address 000000000000 (*&)
> diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt
> new file mode 100644
> index 0000000..7945385
> --- /dev/null
> +++ b/android/pts-bnep.txt
> @@ -0,0 +1,92 @@
> +PTS test results for BNEP
> +
> +PTS version: 6.0
> +Tested: 03-March-2015
> +Android version: 5.0
> +Kernel version: 3.20
> +
> +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_CTRL_BV_01_C PASS bneptest -s
> +TC_CTRL_BV_02_C PASS bneptest -c <PTS addr>
> +TC_CTRL_BV_03_C PASS bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_04_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_05_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_06_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_07_C INC PTS issue #13170
> + bneptest -c <PTS addr> -t 3 -d 0 -e 1500
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_08_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_09_C INC PTS issue #13170
> + bneptest -c 00:1b:dc:06:06:ca -n enp0s29u1u7
> + -t 5 -g 00:00:00:00:00:00
> + -j ff:ff:ff:ff:ff:ff
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_10_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_CTRL_BV_19_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_11_C N/A
> +TC_RX_C_BV_12_C N/A
> +TC_RX_C_S_BV_13_C N/A
> +TC_RX_C_S_BV_14_C N/A
> +TC_RX_TYPE_0_BV_15_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_16_C INC PTS issue #13171
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_17_C INC PTS issue #13169
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_RX_TYPE_0_BV_18_C INC PTS issue #13171
> + bneptest -s
> + Note: could be necessary setting approperiate
> + naming of interface using option
> + -n <iface name>, eg. -n enp0s29u1u7
> +TC_TX_TYPE_0_BV_20_C N/A
> +TC_TX_C_BV_21_C N/A
> +TC_TX_C_S_BV_22_C N/A
> +TC_TX_C_D_BV_23_C N/A
>

--
Best regards,
Szymon Janc

2015-03-12 10:02:18

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v3 05/10] profiles/network: Remove unneded bnep_uuid function from bnep code

Hi Grzegorz,

On Monday 09 of March 2015 17:24:50 Grzegorz Kolodziejczyk wrote:
> This function is no longer needed since connection and server can handle
> this funcionality by itself.
> ---
> profiles/network/bnep.c | 10 ----------
> profiles/network/bnep.h | 1 -
> profiles/network/connection.c | 19 ++++++++++++-------
> profiles/network/server.c | 24 +++++++++++++++++++++---
> 4 files changed, 33 insertions(+), 21 deletions(-)
>
> diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
> index 3fe63f0..a81a260 100644
> --- a/profiles/network/bnep.c
> +++ b/profiles/network/bnep.c
> @@ -85,16 +85,6 @@ struct bnep {
> void *disconn_data;
> };
>
> -const char *bnep_uuid(uint16_t id)
> -{
> - int i;
> -
> - for (i = 0; __svc[i].uuid128; i++)
> - if (__svc[i].id == id)
> - return __svc[i].uuid128;
> - return NULL;
> -}
> -
> const char *bnep_name(uint16_t id)
> {
> int i;
> diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
> index 31579f9..811ea14 100644
> --- a/profiles/network/bnep.h
> +++ b/profiles/network/bnep.h
> @@ -26,7 +26,6 @@ struct bnep;
> int bnep_init(void);
> int bnep_cleanup(void);
>
> -const char *bnep_uuid(uint16_t id);
> const char *bnep_name(uint16_t id);
>
> struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
> diff --git a/profiles/network/connection.c b/profiles/network/connection.c
> index 4311cc9..da8b86e 100644
> --- a/profiles/network/connection.c
> +++ b/profiles/network/connection.c
> @@ -284,21 +284,23 @@ static DBusMessage *local_connect(DBusConnection *conn,
> struct btd_service *service;
> struct network_conn *nc;
> const char *svc;
> - const char *uuid;
> uint16_t id;
> int err;
> + char uuid_str[MAX_LEN_UUID_STR];
> + bt_uuid_t uuid;
>
> if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
> DBUS_TYPE_INVALID) == FALSE)
> return btd_error_invalid_args(msg);
>
> id = get_pan_srv_id(svc);
> - uuid = bnep_uuid(id);
> + bt_uuid16_create(&uuid, id);
> + bt_uuid_to_uuid128(&uuid, &uuid);
>
> - if (uuid == NULL)
> + if (bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR) < 0)
> return btd_error_invalid_args(msg);
>
> - service = btd_device_get_service(peer->device, uuid);
> + service = btd_device_get_service(peer->device, uuid_str);
> if (service == NULL)
> return btd_error_not_supported(msg);
>
> @@ -439,15 +441,18 @@ static gboolean network_property_get_uuid(const GDBusPropertyTable *property,
> {
> struct network_peer *peer = data;
> struct network_conn *nc;
> - const char *uuid;
> + char uuid_str[MAX_LEN_UUID_STR];
> + bt_uuid_t uuid;
>
> nc = find_connection_by_state(peer->connections, CONNECTED);
> if (nc == NULL)
> return FALSE;
>
> - uuid = bnep_uuid(nc->id);
> + bt_uuid16_create(&uuid, nc->id);
> + bt_uuid_to_uuid128(&uuid, &uuid);
> + bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR);
>
> - dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
> + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid_str);
>
> return TRUE;
> }
> diff --git a/profiles/network/server.c b/profiles/network/server.c
> index 9caabb0..e05bc1a 100644
> --- a/profiles/network/server.c
> +++ b/profiles/network/server.c
> @@ -114,14 +114,32 @@ static struct network_server *find_server(GSList *list, uint16_t id)
> static struct network_server *find_server_by_uuid(GSList *list,
> const char *uuid)
> {
> + bt_uuid_t srv_uuid, bnep_uuid;
> +
> for (; list; list = list->next) {
> struct network_server *ns = list->data;
> + bt_uuid16_create(&bnep_uuid, ns->id);
>
> - if (strcasecmp(uuid, bnep_uuid(ns->id)) == 0)
> + /* UUID value compare */
> + if (!bt_string_to_uuid(&srv_uuid, uuid) &&
> + !bt_uuid_cmp(&srv_uuid, &bnep_uuid))
> return ns;

Please call bt_string_to_uuid() before loop and based on its result
check if uuid or name compare is needed.

This should make code a bit faster and easier to read.

>
> - if (strcasecmp(uuid, bnep_name(ns->id)) == 0)
> - return ns;
> + /* String value compare */
> + switch (ns->id) {
> + case BNEP_SVC_PANU:
> + if (!strcasecmp(uuid, "panu"))
> + return ns;
> + break;
> + case BNEP_SVC_NAP:
> + if (!strcasecmp(uuid, "nap"))
> + return ns;
> + break;
> + case BNEP_SVC_GN:
> + if (!strcasecmp(uuid, "gn"))
> + return ns;
> + break;
> + }
> }
>
> return NULL;
>

--
Best regards,
Szymon Janc

2015-03-09 16:24:54

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 09/10] tools/bneptest: Add generic connect/listen funcionality

This patch adds general funcionality of bnep connect and listen.
---
tools/bneptest.c | 553 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 548 insertions(+), 5 deletions(-)

diff --git a/tools/bneptest.c b/tools/bneptest.c
index cafeba9..251b71d 100644
--- a/tools/bneptest.c
+++ b/tools/bneptest.c
@@ -26,43 +26,549 @@
#endif

#include <stdio.h>
+#include <signal.h>
#include <stdlib.h>
#include <getopt.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include <netinet/in.h>
+#include <linux/if_bridge.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>

#include <glib.h>

#include "src/log.h"
+#include "btio/btio.h"
+#include "lib/bnep.h"
+#include "profiles/network/bnep.h"
+
+enum {
+ MODE_NONE,
+ MODE_CONNECT,
+ MODE_LISTEN,
+};

static GMainLoop *mloop;
+static GIOChannel *bnep_io;
+
+static int mode;
+static bool no_close_after_disconn;
+static int send_ctrl_frame_timeout;
+
+static bdaddr_t src_addr, dst_addr;
+static char iface[16] = "nap_iface%d";
+static char bridge[16] = "bnep_bridge";
+static uint8_t send_msg_type = 0x00;
+static uint16_t local_role = BNEP_SVC_PANU;
+static uint16_t remote_role = BNEP_SVC_NAP;
+static uint16_t ntw_proto_down_range = 0x0000;
+static uint16_t ntw_proto_up_range = 0xdc05;
+static uint8_t mcast_addr_down_range[6] = { 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00 };
+static uint8_t mcast_addr_up_range[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+static struct bnep *session;
+
+
+static int set_forward_delay(int sk)
+{
+ unsigned long args[4] = { BRCTL_SET_BRIDGE_FORWARD_DELAY, 0, 0, 0 };
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, bridge, IFNAMSIZ);
+ ifr.ifr_data = (char *) args;
+
+ if (ioctl(sk, SIOCDEVPRIVATE, &ifr) < 0) {
+ error("setting forward delay failed: %d (%s)",
+ errno, strerror(errno));
+ return -1;
+ }
+
+ return 0;
+}
+
+static int nap_create_bridge(void)
+{
+ int sk, err;
+
+ sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
+ if (sk < 0)
+ return -EOPNOTSUPP;
+
+ if (ioctl(sk, SIOCBRADDBR, bridge) < 0) {
+ err = -errno;
+ if (err != -EEXIST) {
+ close(sk);
+ return -EOPNOTSUPP;
+ }
+ }
+
+ err = set_forward_delay(sk);
+ if (err < 0) {
+ printf("failed to set forward delay\n");
+ ioctl(sk, SIOCBRDELBR, bridge);
+ }
+
+ close(sk);
+
+ return err;
+}
+
+static int cleanup(void)
+{
+ bnep_cleanup();
+
+ if (mode == MODE_LISTEN)
+ bnep_server_delete(bridge, iface, &dst_addr);
+
+ if (bnep_io) {
+ g_io_channel_shutdown(bnep_io, TRUE, NULL);
+ g_io_channel_unref(bnep_io);
+ }
+
+ return 0;
+}
+
+static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer user_data)
+{
+ printf("%s\n", __func__);
+
+ if (no_close_after_disconn)
+ return FALSE;
+
+ /* Cleanup since it's called when disconnected l2cap */
+ if (cleanup() < 0) {
+ printf("cleanup went wrong...\n");
+ return FALSE;
+ }
+
+ g_main_loop_quit(mloop);
+ return FALSE;
+}
+
+static ssize_t send_ctrl_frame(int sk)
+{
+ /* Max buff size = type(1byte) + ctrl(1byte) + len(2byte) +
+ * mcast_addr_down(6byte) + mcast_addr_up(6byte) */
+ uint8_t buff[16];
+ int err;
+
+ printf("%s\n", __func__);
+
+ if (send_ctrl_frame_timeout > 0) {
+ printf("waiting %d seconds before sending msg\n",
+ send_ctrl_frame_timeout);
+ sleep(send_ctrl_frame_timeout);
+ }
+
+ switch (send_msg_type) {
+ case BNEP_FILTER_NET_TYPE_SET: {
+ struct bnep_set_filter_req *frame = (void *)buff;
+
+ frame->type = BNEP_CONTROL;
+ frame->ctrl = send_msg_type;
+ frame->len = htons(sizeof(ntw_proto_down_range) +
+ sizeof(ntw_proto_up_range));
+ memcpy(frame->list, &ntw_proto_down_range,
+ sizeof(ntw_proto_down_range));
+ memcpy(frame->list + sizeof(ntw_proto_down_range),
+ &ntw_proto_up_range, sizeof(ntw_proto_up_range));
+
+ err = send(sk, frame, sizeof(*frame) +
+ sizeof(ntw_proto_down_range) +
+ sizeof(ntw_proto_up_range), 0);
+
+ break;
+
+ }
+ case BNEP_FILTER_MULT_ADDR_SET: {
+ struct bnep_set_filter_req *frame = (void *)buff;
+
+ frame->type = BNEP_CONTROL;
+ frame->ctrl = send_msg_type;
+ frame->len = htons(sizeof(mcast_addr_down_range) +
+ sizeof(mcast_addr_up_range));
+ memcpy(frame->list, mcast_addr_down_range,
+ sizeof(mcast_addr_down_range));
+ memcpy(frame->list + sizeof(mcast_addr_down_range),
+ mcast_addr_up_range, sizeof(mcast_addr_up_range));
+
+ err = send(sk, frame, sizeof(*frame) +
+ sizeof(mcast_addr_down_range) +
+ sizeof(mcast_addr_up_range), 0);
+
+ break;
+
+ }
+ default:
+ err = -1;
+ }
+
+ return err;
+}
+
+static gboolean setup_bnep_cb(GIOChannel *chan, GIOCondition cond,
+ gpointer user_data)
+{
+ uint8_t packet[BNEP_MTU];
+ int sk, n, err;
+
+ printf("%s\n", __func__);
+
+ if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
+ error("hangup or error or inval on BNEP socket");
+ return FALSE;
+ }
+
+ sk = g_io_channel_unix_get_fd(chan);
+
+ /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
+ n = read(sk, packet, sizeof(packet));
+ if (n < 0) {
+ error("read(): %s(%d)", strerror(errno), errno);
+ return FALSE;
+ }
+
+ err = nap_create_bridge();
+ if (err < 0) {
+ error("failed to create bridge: %s (%d)", strerror(-err), err);
+ return FALSE;
+ }
+
+ if (bnep_server_add(sk, (err < 0) ? NULL : bridge, iface, &dst_addr,
+ packet, n) < 0) {
+ printf("server_connadd failed\n");
+ cleanup();
+ return FALSE;
+ }
+
+ g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL, bnep_watchdog_cb,
+ NULL);
+
+ if (send_msg_type) {
+ if (send_ctrl_frame(sk) < 0)
+ printf("error while sending ctrl frame : %s (%d)\n",
+ strerror(errno), errno);
+ }
+
+ g_io_channel_unref(bnep_io);
+ bnep_io = NULL;
+
+ return FALSE;
+}
+
+static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+ printf("%s\n", __func__);
+
+ if (err) {
+ error("%s", err->message);
+ return;
+ }
+
+ g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+ setup_bnep_cb, NULL);
+}
+
+static void connected_client_cb(char *iface, int err, void *data)
+{
+ int sk = *((int *)data);
+
+ printf("%s\n", __func__);
+
+ free(data);
+
+ if (send_msg_type) {
+ if (send_ctrl_frame(sk) < 0)
+ printf("error while sendind ctrl frame : %s (%d)\n",
+ strerror(errno), errno);
+ }
+}
+
+static void disconnected_client_cb(void *data)
+{
+ printf("%s\n", __func__);
+
+ if (no_close_after_disconn)
+ return;
+
+ /* Cleanup since it's called when disconnected l2cap */
+ if (cleanup() < 0) {
+ printf("cleanup went wrong...\n");
+ return;
+ }
+
+ g_main_loop_quit(mloop);
+}
+
+static void connect_client_cb(GIOChannel *chan, GError *err, gpointer user_data)
+{
+ int perr;
+ int *sk;
+
+ sk = malloc(sizeof(*sk));
+
+ *sk = g_io_channel_unix_get_fd(bnep_io);
+
+ session = bnep_new(*sk, local_role, remote_role, bridge);
+ if (!session) {
+ printf("cannot create bnep session\n");
+ free(sk);
+ return;
+ }
+
+ perr = bnep_connect(session, connected_client_cb,
+ disconnected_client_cb, sk, NULL);
+ if (perr < 0)
+ printf("cannot initiate bnep connection\n");
+}
+
+static void confirm_cb(GIOChannel *chan, gpointer data)
+{
+ GError *err = NULL;
+ char address[18];
+
+ printf("%s\n", __func__);
+
+ bt_io_get(chan, &err, BT_IO_OPT_DEST_BDADDR, &dst_addr, BT_IO_OPT_DEST,
+ address, BT_IO_OPT_INVALID);
+ if (err) {
+ error("%s", err->message);
+ g_error_free(err);
+ return;
+ }
+
+ printf("incoming connection from: %s\n", address);
+
+ bnep_io = g_io_channel_ref(chan);
+ g_io_channel_set_close_on_unref(bnep_io, TRUE);
+
+ if (!bt_io_accept(bnep_io, connect_cb, NULL, NULL, &err)) {
+ error("bt_io_accept: %s", err->message);
+ g_error_free(err);
+ }
+}
+
+static int bnep_server_listen(void)
+{
+ GError *gerr = NULL;
+
+ printf("%s\n", __func__);
+
+ bnep_io = bt_io_listen(NULL, confirm_cb, NULL, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src_addr,
+ BT_IO_OPT_PSM, BNEP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_OMTU, BNEP_MTU,
+ BT_IO_OPT_IMTU, BNEP_MTU,
+ BT_IO_OPT_INVALID);
+
+ if (!bnep_io) {
+ printf("can't start server listening: err %s\n", gerr->message);
+ g_error_free(gerr);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int bnep_client_connect(void)
+{
+ GError *gerr = NULL;
+ char *dst_addr_str = batostr(&dst_addr);
+
+ printf("%s\n", __func__);
+
+ printf("connecting %s\n", dst_addr_str);
+ free(dst_addr_str);
+
+ bnep_io = bt_io_connect(connect_client_cb, NULL, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR, &src_addr,
+ BT_IO_OPT_DEST_BDADDR, &dst_addr,
+ BT_IO_OPT_PSM, BNEP_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+ BT_IO_OPT_OMTU, BNEP_MTU,
+ BT_IO_OPT_IMTU, BNEP_MTU,
+ BT_IO_OPT_INVALID);
+
+ if (!bnep_io) {
+ printf("cannot connect: err %s\n", gerr->message);
+ g_error_free(gerr);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void exit_handler(int sig)
+{
+ printf("got sig = %d, cleaning up...\n", sig);
+
+ if (cleanup() < 0)
+ printf("cleanup failure...\n");
+ else
+ printf("cleanup successful - exit\n");
+
+ exit(0);
+}

static void usage(void)
{
printf("bneptest - BNEP testing ver %s\n", VERSION);
printf("Usage:\n"
- "\tbneptest [options]\n");
+ "\tbneptest <connection mode> [send_ctrl_cmd] [options]\n");
+ printf("Connect Mode:\n"
+ "\t-c connect <dst_addr>\n"
+ "\t-r remote role <16 bit svc value>\n"
+ "\t-l local role <16 bit svc valu>\n");
+ printf("Listen Mode:\n"
+ "\t-s start server listening\n");
+ printf("Send control command:\n"
+ "\t-t send message type <control msg type>\n"
+ "\t-T send message timeout after setup <seconds>\n"
+ "\t-e starting network protocol type range <16 bit value>\n"
+ "\t-d ending network protocol type range <16 bit value>\n"
+ "\t-g starting multicast addr range <xx:xx:xx:xx:xx:xx>\n"
+ "\t-j ending multicast addr range <xx:xx:xx:xx:xx:xx>\n");
+ printf("Options:\n"
+ "\t-b bridge name <string>\n"
+ "\t-n interface name <string>\n");
}

static struct option main_options[] = {
- { "help", 0, 0, 'h' },
+ { "device", 1, 0, 'i' },
+ { "listen", 0, 0, 's' },
+ { "connect", 1, 0, 'c' },
+ { "snd_msg_type", 1, 0, 't' },
+ { "send_timeout", 1, 0, 'T' },
+ { "ntw_proto_down_range", 1, 0, 'd' },
+ { "ntw_proto_up_range", 1, 0, 'e' },
+ { "mcast_addr_down_range", 1, 0, 'g' },
+ { "mcast_addr_up_range", 1, 0, 'j' },
+ { "local_role", 1, 0, 'l' },
+ { "remote_role", 1, 0, 'r' },
+ { "bridge name", 1, 0, 'b' },
+ { "iface name", 1, 0, 'n' },
+ { "no_close", 0, 0, 'N' },
+ { "help", 0, 0, 'h' },
{ 0, 0, 0, 0 }
};

int main(int argc, char *argv[])
{
int opt;
+ int err;

DBG("");

+ signal(SIGINT, exit_handler);
+
+ hci_devba(0, &src_addr);
+ bacpy(&src_addr, BDADDR_ANY);
+
mloop = g_main_loop_new(NULL, FALSE);
if (!mloop) {
- printf("Cannot create main loop\n");
+ printf("cannot create main loop\n");

exit(1);
}

- while ((opt = getopt_long(argc, argv, "h", main_options, NULL))
- != EOF) {
+ while ((opt = getopt_long(argc, argv, "+i:b:n:c:t:T:d:e:g:j:Nsh",
+ main_options, NULL)) != EOF) {
switch (opt) {
+ case 'i':
+ if (!strncmp(optarg, "hci", 3))
+ hci_devba(atoi(optarg + 3), &src_addr);
+ else
+ str2ba(optarg, &src_addr);
+
+ break;
+
+ case 's':
+ mode = MODE_LISTEN;
+ break;
+
+ case 'c':
+ str2ba(optarg, &dst_addr);
+ mode = MODE_CONNECT;
+
+ break;
+
+ case 't':
+ send_msg_type = atoi(optarg);
+
+ break;
+
+ case 'T':
+ send_ctrl_frame_timeout = atoi(optarg);
+
+ break;
+
+ case 'd':
+ ntw_proto_down_range = htons(atoi(optarg));
+
+ break;
+
+ case 'e':
+ ntw_proto_up_range = htons(atoi(optarg));
+
+ break;
+
+ case 'g': {
+ int i = 0;
+
+ for (i = 5; i >= 0; i--, optarg += 3)
+ mcast_addr_down_range[i] =
+ strtol(optarg, NULL, 16);
+
+ break;
+ }
+
+ case 'j': {
+ int i = 0;
+
+ for (i = 5; i >= 0; i--, optarg += 3)
+ mcast_addr_up_range[i] =
+ strtol(optarg, NULL, 16);
+
+ break;
+ }
+
+ case 'l':
+ local_role = atoi(optarg);
+
+ break;
+
+ case 'r':
+ remote_role = atoi(optarg);
+
+ break;
+
+ case 'b':
+ strncpy(bridge, optarg, 16);
+ bridge[15] = '\0';
+
+ break;
+
+ case 'n':
+ strncpy(iface, optarg, 16);
+ iface[15] = '\0';
+
+ break;
+
+ case 'N':
+ no_close_after_disconn = true;
+
+ break;
+
case 'h':
default:
usage();
@@ -70,5 +576,42 @@ int main(int argc, char *argv[])
}
}

+ switch (mode) {
+ case MODE_CONNECT:
+ err = bnep_init();
+ if (err < 0) {
+ printf("cannot initialize bnep\n");
+ exit(1);
+ }
+ err = bnep_client_connect();
+ if (err < 0)
+ exit(1);
+
+ break;
+
+ case MODE_LISTEN:
+ err = bnep_init();
+ if (err < 0) {
+ printf("cannot initialize bnep\n");
+ exit(1);
+ }
+ err = bnep_server_listen();
+ if (err < 0)
+ exit(1);
+
+ break;
+
+ case MODE_NONE:
+ default:
+ printf("connect/listen mode not set, exit...\n");
+ exit(1);
+ }
+
+ g_main_loop_run(mloop);
+
+ printf("Done\n");
+
+ g_main_loop_unref(mloop);
+
return 0;
}
--
2.1.0


2015-03-09 16:24:55

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 10/10] android/pts: Add BNEP PTS 6.0 results for android 5.0

This patch adds test case list and results for BNEP profile against
android 5.0
---
android/pics-bnep.txt | 26 ++++++++++++++
android/pixit-bnep.txt | 30 ++++++++++++++++
android/pts-bnep.txt | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+)
create mode 100644 android/pics-bnep.txt
create mode 100644 android/pixit-bnep.txt
create mode 100644 android/pts-bnep.txt

diff --git a/android/pics-bnep.txt b/android/pics-bnep.txt
new file mode 100644
index 0000000..2279c9a
--- /dev/null
+++ b/android/pics-bnep.txt
@@ -0,0 +1,26 @@
+BNEP PICS for the PTS tool.
+
+PTS version: 6.0
+
+* - different than PTS defaults
+# - not yet implemented/supported
+
+M - mandatory if such role selected
+O - optional
+
+ Profile Version
+-------------------------------------------------------------------------------
+Parameter Name Selected Description
+-------------------------------------------------------------------------------
+TSPC_BNEP_1_1 True BNEP Connection Setup (M)
+TSPC_BNEP_1_2 False BNEP Data Packet Reception (M)
+TSPC_BNEP_1_3 False BNEP Data Packet Transmission (M)
+TSPC_BNEP_1_3a False BNEP Compressed Packet Transmission (O)
+TSPC_BNEP_1_3b False BNEP Compressed Packet Transmission Source Only
+ (O)
+TSPC_BNEP_1_4 True BNEP Control Message Processing (M)
+TSPC_BNEP_1_5 True BNEP Extension Header Processing (M)
+TSPC_BNEP_1_6 True Network Protocol Filter Message Transmission (O)
+TSPC_BNEP_1_7 True Multicast Address Filter Message Transmission
+ (O)
+-------------------------------------------------------------------------------
diff --git a/android/pixit-bnep.txt b/android/pixit-bnep.txt
new file mode 100644
index 0000000..9a26cd2
--- /dev/null
+++ b/android/pixit-bnep.txt
@@ -0,0 +1,30 @@
+BNEP PIXIT for the PTS tool.
+
+PTS version: 6.0
+
+* - different than PTS defaults
+& - should be set to IUT Bluetooth address
+# - should be set to PTS's bin/audio folder
+
+Required PIXIT settings
+-------------------------------------------------------------------------------
+Parameter Name Value
+-------------------------------------------------------------------------------
+TSPX_class_of_device 04041C
+TSPX_security_control_data
+TSPX_content_protection_data
+TSPX_bd_addr_iut 112233445566 (*&)
+TSPX_delete_link_key FALSE
+TSPX_pin_code 1234
+TSPX_security_enabled FALSE
+TSPX_time_guard 300000
+TSPX_use_implicit_send TRUE
+TSPX_auth_password 0000
+TSPX_auth_user_id PTS
+TSPX_l2cap_psm 000F
+TSPX_rfcomm_channel 8
+TSPX_no_confirmations FALSE
+TSPX_UUID_dest_address 1116
+TSPX_UUID_source_address 1115
+TSPX_MAC_dest_address 000000000000 (*&)
+TSPX_MAC_source_address 000000000000 (*&)
diff --git a/android/pts-bnep.txt b/android/pts-bnep.txt
new file mode 100644
index 0000000..7945385
--- /dev/null
+++ b/android/pts-bnep.txt
@@ -0,0 +1,92 @@
+PTS test results for BNEP
+
+PTS version: 6.0
+Tested: 03-March-2015
+Android version: 5.0
+Kernel version: 3.20
+
+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_CTRL_BV_01_C PASS bneptest -s
+TC_CTRL_BV_02_C PASS bneptest -c <PTS addr>
+TC_CTRL_BV_03_C PASS bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_04_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_05_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_06_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_07_C INC PTS issue #13170
+ bneptest -c <PTS addr> -t 3 -d 0 -e 1500
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_08_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_09_C INC PTS issue #13170
+ bneptest -c 00:1b:dc:06:06:ca -n enp0s29u1u7
+ -t 5 -g 00:00:00:00:00:00
+ -j ff:ff:ff:ff:ff:ff
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_10_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_CTRL_BV_19_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_RX_TYPE_0_BV_11_C N/A
+TC_RX_C_BV_12_C N/A
+TC_RX_C_S_BV_13_C N/A
+TC_RX_C_S_BV_14_C N/A
+TC_RX_TYPE_0_BV_15_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_RX_TYPE_0_BV_16_C INC PTS issue #13171
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_RX_TYPE_0_BV_17_C INC PTS issue #13169
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_RX_TYPE_0_BV_18_C INC PTS issue #13171
+ bneptest -s
+ Note: could be necessary setting approperiate
+ naming of interface using option
+ -n <iface name>, eg. -n enp0s29u1u7
+TC_TX_TYPE_0_BV_20_C N/A
+TC_TX_C_BV_21_C N/A
+TC_TX_C_S_BV_22_C N/A
+TC_TX_C_D_BV_23_C N/A
--
2.1.0


2015-03-09 16:24:50

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 05/10] profiles/network: Remove unneded bnep_uuid function from bnep code

This function is no longer needed since connection and server can handle
this funcionality by itself.
---
profiles/network/bnep.c | 10 ----------
profiles/network/bnep.h | 1 -
profiles/network/connection.c | 19 ++++++++++++-------
profiles/network/server.c | 24 +++++++++++++++++++++---
4 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 3fe63f0..a81a260 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -85,16 +85,6 @@ struct bnep {
void *disconn_data;
};

-const char *bnep_uuid(uint16_t id)
-{
- int i;
-
- for (i = 0; __svc[i].uuid128; i++)
- if (__svc[i].id == id)
- return __svc[i].uuid128;
- return NULL;
-}
-
const char *bnep_name(uint16_t id)
{
int i;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 31579f9..811ea14 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -26,7 +26,6 @@ struct bnep;
int bnep_init(void);
int bnep_cleanup(void);

-const char *bnep_uuid(uint16_t id);
const char *bnep_name(uint16_t id);

struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 4311cc9..da8b86e 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -284,21 +284,23 @@ static DBusMessage *local_connect(DBusConnection *conn,
struct btd_service *service;
struct network_conn *nc;
const char *svc;
- const char *uuid;
uint16_t id;
int err;
+ char uuid_str[MAX_LEN_UUID_STR];
+ bt_uuid_t uuid;

if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &svc,
DBUS_TYPE_INVALID) == FALSE)
return btd_error_invalid_args(msg);

id = get_pan_srv_id(svc);
- uuid = bnep_uuid(id);
+ bt_uuid16_create(&uuid, id);
+ bt_uuid_to_uuid128(&uuid, &uuid);

- if (uuid == NULL)
+ if (bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR) < 0)
return btd_error_invalid_args(msg);

- service = btd_device_get_service(peer->device, uuid);
+ service = btd_device_get_service(peer->device, uuid_str);
if (service == NULL)
return btd_error_not_supported(msg);

@@ -439,15 +441,18 @@ static gboolean network_property_get_uuid(const GDBusPropertyTable *property,
{
struct network_peer *peer = data;
struct network_conn *nc;
- const char *uuid;
+ char uuid_str[MAX_LEN_UUID_STR];
+ bt_uuid_t uuid;

nc = find_connection_by_state(peer->connections, CONNECTED);
if (nc == NULL)
return FALSE;

- uuid = bnep_uuid(nc->id);
+ bt_uuid16_create(&uuid, nc->id);
+ bt_uuid_to_uuid128(&uuid, &uuid);
+ bt_uuid_to_string(&uuid, uuid_str, MAX_LEN_UUID_STR);

- dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &uuid_str);

return TRUE;
}
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 9caabb0..e05bc1a 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -114,14 +114,32 @@ static struct network_server *find_server(GSList *list, uint16_t id)
static struct network_server *find_server_by_uuid(GSList *list,
const char *uuid)
{
+ bt_uuid_t srv_uuid, bnep_uuid;
+
for (; list; list = list->next) {
struct network_server *ns = list->data;
+ bt_uuid16_create(&bnep_uuid, ns->id);

- if (strcasecmp(uuid, bnep_uuid(ns->id)) == 0)
+ /* UUID value compare */
+ if (!bt_string_to_uuid(&srv_uuid, uuid) &&
+ !bt_uuid_cmp(&srv_uuid, &bnep_uuid))
return ns;

- if (strcasecmp(uuid, bnep_name(ns->id)) == 0)
- return ns;
+ /* String value compare */
+ switch (ns->id) {
+ case BNEP_SVC_PANU:
+ if (!strcasecmp(uuid, "panu"))
+ return ns;
+ break;
+ case BNEP_SVC_NAP:
+ if (!strcasecmp(uuid, "nap"))
+ return ns;
+ break;
+ case BNEP_SVC_GN:
+ if (!strcasecmp(uuid, "gn"))
+ return ns;
+ break;
+ }
}

return NULL;
--
2.1.0


2015-03-09 16:24:53

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 08/10] tools/bneptest: Add initial support for bneptest tool

This tool should be designed to help testing bnep on Bluez.
---
.gitignore | 1 +
Makefile.tools | 12 ++++++---
android/Android.mk | 35 ++++++++++++++++++++++++++
tools/bneptest.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+), 3 deletions(-)
create mode 100644 tools/bneptest.c

diff --git a/.gitignore b/.gitignore
index a207a0f..a4f06dc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,6 +82,7 @@ tools/gatt-service
tools/btgatt-client
tools/btgatt-server
tools/mcaptest
+tools/bneptest
test/sap_client.pyc
test/bluezutils.pyc
unit/test-ringbuf
diff --git a/Makefile.tools b/Makefile.tools
index e28f3cb..1aafb28 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -223,9 +223,9 @@ noinst_PROGRAMS += tools/bdaddr tools/avinfo tools/avtest \
tools/hcieventmask tools/hcisecfilter \
tools/btmgmt tools/btinfo tools/btattach \
tools/btsnoop tools/btproxy \
- tools/btiotest tools/mcaptest tools/cltest \
- tools/oobtest tools/seq2bseq tools/ibeacon \
- tools/btgatt-client tools/btgatt-server
+ tools/btiotest tools/bneptest tools/mcaptest \
+ tools/cltest tools/oobtest tools/seq2bseq \
+ tools/ibeacon tools/btgatt-client tools/btgatt-server

tools_bdaddr_SOURCES = tools/bdaddr.c src/oui.h src/oui.c
tools_bdaddr_LDADD = lib/libbluetooth-internal.la @UDEV_LIBS@
@@ -267,6 +267,12 @@ tools_mcaptest_SOURCES = tools/mcaptest.c \
profiles/health/mcap.h profiles/health/mcap.c
tools_mcaptest_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@

+tools_bneptest_SOURCES = tools/bneptest.c \
+ btio/btio.h btio/btio.c \
+ src/log.c src/log.h \
+ profiles/network/bnep.h profiles/network/bnep.c
+tools_bneptest_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
+
tools_cltest_SOURCES = tools/cltest.c
tools_cltest_LDADD = lib/libbluetooth-internal.la src/libshared-mainloop.la

diff --git a/android/Android.mk b/android/Android.mk
index 6c0eda8..f218805 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -256,6 +256,41 @@ LOCAL_MODULE := mcaptest
include $(BUILD_EXECUTABLE)

#
+# bneptest
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ bluez/src/log.c \
+ bluez/btio/btio.c \
+ bluez/lib/bluetooth.c \
+ bluez/lib/hci.c \
+ bluez/profiles/network/bnep.c \
+ bluez/tools/bneptest.c \
+
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, glib) \
+ $(call include-path-for, glib)/glib \
+
+LOCAL_C_INCLUDES += \
+ $(LOCAL_PATH)/bluez \
+
+LOCAL_CFLAGS := $(BLUEZ_COMMON_CFLAGS)
+
+LOCAL_SHARED_LIBRARIES := \
+ libglib \
+
+LOCAL_STATIC_LIBRARIES := \
+ bluetooth-headers \
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := bneptest
+
+include $(BUILD_EXECUTABLE)
+
+#
# avdtptest
#

diff --git a/tools/bneptest.c b/tools/bneptest.c
new file mode 100644
index 0000000..cafeba9
--- /dev/null
+++ b/tools/bneptest.c
@@ -0,0 +1,74 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2015 Intel Corporation
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+
+#include <glib.h>
+
+#include "src/log.h"
+
+static GMainLoop *mloop;
+
+static void usage(void)
+{
+ printf("bneptest - BNEP testing ver %s\n", VERSION);
+ printf("Usage:\n"
+ "\tbneptest [options]\n");
+}
+
+static struct option main_options[] = {
+ { "help", 0, 0, 'h' },
+ { 0, 0, 0, 0 }
+};
+
+int main(int argc, char *argv[])
+{
+ int opt;
+
+ DBG("");
+
+ mloop = g_main_loop_new(NULL, FALSE);
+ if (!mloop) {
+ printf("Cannot create main loop\n");
+
+ exit(1);
+ }
+
+ while ((opt = getopt_long(argc, argv, "h", main_options, NULL))
+ != EOF) {
+ switch (opt) {
+ case 'h':
+ default:
+ usage();
+ exit(0);
+ }
+ }
+
+ return 0;
+}
--
2.1.0


2015-03-09 16:24:52

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 07/10] profiles/network: Move disconn cb setting to bnep connect method

Disconnect callback can be set while connececting bnep. In previous
implementation there was separated method to setting up the disconnect
callback and it was always called immediately after calling connect -
this method was redundand.
---
android/pan.c | 5 ++---
profiles/network/bnep.c | 22 +++++++---------------
profiles/network/bnep.h | 6 +++---
profiles/network/connection.c | 4 +---
4 files changed, 13 insertions(+), 24 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index a14ed84..6c9815b 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -324,14 +324,13 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
if (!dev->session)
goto fail;

- perr = bnep_connect(dev->session, bnep_conn_cb, dev);
+ perr = bnep_connect(dev->session, bnep_conn_cb, bnep_disconn_cb, dev,
+ dev);
if (perr < 0) {
error("bnep connect req failed: %s", strerror(-perr));
goto fail;
}

- bnep_set_disconnect(dev->session, bnep_disconn_cb, dev);
-
if (dev->io) {
g_io_channel_unref(dev->io);
dev->io = NULL;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index e133dd9..87f50fd 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -369,17 +369,21 @@ void bnep_free(struct bnep *session)
g_free(session);
}

-int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data)
+int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb,
+ bnep_disconnect_cb disconn_cb,
+ void *conn_data, void *disconn_data)
{
GError *gerr = NULL;
int err;

- if (!session || !conn_cb)
+ if (!session || !conn_cb || !disconn_cb)
return -EINVAL;

session->attempts = 0;
session->conn_cb = conn_cb;
- session->conn_data = data;
+ session->disconn_cb = disconn_cb;
+ session->conn_data = conn_data;
+ session->disconn_data = disconn_data;

bt_io_get(session->io, &gerr, BT_IO_OPT_DEST_BDADDR, &session->dst_addr,
BT_IO_OPT_INVALID);
@@ -417,18 +421,6 @@ void bnep_disconnect(struct bnep *session)
bnep_conndel(&session->dst_addr);
}

-void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
- void *data)
-{
- if (!session || !disconn_cb)
- return;
-
- if (!session->disconn_cb && !session->disconn_data) {
- session->disconn_cb = disconn_cb;
- session->disconn_data = data;
- }
-}
-
static int bnep_add_to_bridge(const char *devname, const char *bridge)
{
int ifindex;
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index da706ac..e9f4c1c 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -31,10 +31,10 @@ struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
void bnep_free(struct bnep *session);

typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
-int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data);
typedef void (*bnep_disconnect_cb) (void *data);
-void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
- void *data);
+int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb,
+ bnep_disconnect_cb disconn_cb,
+ void *conn_data, void *disconn_data);
void bnep_disconnect(struct bnep *session);

int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index da8b86e..ff4ebc9 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -258,14 +258,12 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer data)
if (!nc->session)
goto failed;

- perr = bnep_connect(nc->session, bnep_conn_cb, nc);
+ perr = bnep_connect(nc->session, bnep_conn_cb, bnep_disconn_cb, nc, nc);
if (perr < 0) {
error("bnep connect(): %s (%d)", strerror(-perr), -perr);
goto failed;
}

- bnep_set_disconnect(nc->session, bnep_disconn_cb, nc);
-
if (nc->io) {
g_io_channel_unref(nc->io);
nc->io = NULL;
--
2.1.0


2015-03-09 16:24:51

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 06/10] profiles/network: Remove not needed get name by bnep id function

This function and service structure declaration is no longer needed
since related code was distracted.
---
profiles/network/bnep.c | 21 ---------------------
profiles/network/bnep.h | 2 --
2 files changed, 23 deletions(-)

diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index a81a260..e133dd9 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -54,17 +54,6 @@

static int ctl;

-static struct {
- const char *name; /* Friendly name */
- const char *uuid128; /* UUID 128 */
- uint16_t id; /* Service class identifier */
-} __svc[] = {
- { "panu", PANU_UUID, BNEP_SVC_PANU },
- { "gn", GN_UUID, BNEP_SVC_GN },
- { "nap", NAP_UUID, BNEP_SVC_NAP },
- { NULL }
-};
-
struct __service_16 {
uint16_t dst;
uint16_t src;
@@ -85,16 +74,6 @@ struct bnep {
void *disconn_data;
};

-const char *bnep_name(uint16_t id)
-{
- int i;
-
- for (i = 0; __svc[i].name; i++)
- if (__svc[i].id == id)
- return __svc[i].name;
- return NULL;
-}
-
int bnep_init(void)
{
ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP);
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 811ea14..da706ac 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -26,8 +26,6 @@ struct bnep;
int bnep_init(void);
int bnep_cleanup(void);

-const char *bnep_name(uint16_t id);
-
struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
char *iface);
void bnep_free(struct bnep *session);
--
2.1.0


2015-03-09 16:24:48

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 03/10] profiles/network: Fix sending command responses

Command response can be three bytes long (in case if command is not
understood) 1 byte(packet type) + 1 byte(control type) + 1 byte(unknown
control type). Command response can be also four bytes long if it's
response for setup connection, filter net type and filter multi addr,
1 byte(packet type) + 1 byte(control type) + 2 byte(response message).
---
lib/bnep.h | 6 +++++
profiles/network/bnep.c | 60 +++++++++++++++++++++++++++++++++++--------------
2 files changed, 49 insertions(+), 17 deletions(-)

diff --git a/lib/bnep.h b/lib/bnep.h
index 2bbfb17..aa46852 100644
--- a/lib/bnep.h
+++ b/lib/bnep.h
@@ -103,6 +103,12 @@ struct bnep_set_filter_req {
uint8_t list[0];
} __attribute__((packed));

+struct bnep_ctrl_cmd_not_understood_cmd {
+ uint8_t type;
+ uint8_t ctrl;
+ uint8_t unkn_ctrl;
+} __attribute__((packed));
+
struct bnep_control_rsp {
uint8_t type;
uint8_t ctrl;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index afd94c5..3fe63f0 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -524,16 +524,40 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
return err;
}

-static ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl,
- uint16_t resp)
+static ssize_t bnep_send_ctrl_rsp(int sk, uint8_t ctrl, uint16_t resp)
{
- struct bnep_control_rsp rsp;
+ ssize_t sent;

- rsp.type = type;
- rsp.ctrl = ctrl;
- rsp.resp = htons(resp);
+ switch (ctrl) {
+ case BNEP_CMD_NOT_UNDERSTOOD: {
+ struct bnep_ctrl_cmd_not_understood_cmd rsp;

- return send(sk, &rsp, sizeof(rsp), 0);
+ rsp.type = BNEP_CONTROL;
+ rsp.ctrl = ctrl;
+ rsp.unkn_ctrl = (uint8_t) resp;
+
+ sent = send(sk, &rsp, sizeof(rsp), 0);
+ break;
+ }
+ case BNEP_FILTER_MULT_ADDR_RSP:
+ case BNEP_FILTER_NET_TYPE_RSP:
+ case BNEP_SETUP_CONN_RSP: {
+ struct bnep_control_rsp rsp;
+
+ rsp.type = BNEP_CONTROL;
+ rsp.ctrl = ctrl;
+ rsp.resp = htons(resp);
+
+ sent = send(sk, &rsp, sizeof(rsp), 0);
+ break;
+ }
+ default:
+ error("bnep: wrong response type");
+ sent = -1;
+ break;
+ }
+
+ return sent;
}

static uint16_t bnep_setup_decode(int sk, struct bnep_setup_conn_req *req,
@@ -612,16 +636,15 @@ int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
/* Highest known Control command ID
* is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
if (req->type == BNEP_CONTROL &&
- req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
- uint8_t pkt[3];
-
- pkt[0] = BNEP_CONTROL;
- pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
- pkt[2] = req->ctrl;
+ req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
+ error("bnep: cmd not understood");
+ err = bnep_send_ctrl_rsp(sk, BNEP_CMD_NOT_UNDERSTOOD,
+ req->ctrl);
+ if (err < 0)
+ error("send not understood ctrl rsp error: %s (%d)",
+ strerror(errno), errno);

- send(sk, pkt, sizeof(pkt), 0);
-
- return -EINVAL;
+ return err;
}

/* Processing BNEP_SETUP_CONNECTION_REQUEST_MSG */
@@ -657,7 +680,10 @@ int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
rsp = BNEP_CONN_NOT_ALLOWED;

reply:
- bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+ err = bnep_send_ctrl_rsp(sk, BNEP_SETUP_CONN_RSP, rsp);
+ if (err < 0)
+ error("bnep: send ctrl rsp error: %s (%d)", strerror(errno),
+ errno);

return err;
}
--
2.1.0


2015-03-09 16:24:49

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 04/10] profiles/network: Keep interface arguments naming consistent

Arguments shall keep consistent naming.
---
profiles/network/bnep.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 633baeb..31579f9 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -34,7 +34,7 @@ struct bnep *bnep_new(int sk, uint16_t local_role, uint16_t remote_role,
void bnep_free(struct bnep *session);

typedef void (*bnep_connect_cb) (char *iface, int err, void *data);
-int bnep_connect(struct bnep *b, bnep_connect_cb conn_cb, void *data);
+int bnep_connect(struct bnep *session, bnep_connect_cb conn_cb, void *data);
typedef void (*bnep_disconnect_cb) (void *data);
void bnep_set_disconnect(struct bnep *session, bnep_disconnect_cb disconn_cb,
void *data);
--
2.1.0


2015-03-09 16:24:47

by Grzegorz Kolodziejczyk

[permalink] [raw]
Subject: [PATCH v3 02/10] profiles/network: Handle ctrl rsp after conn setup by bnep

This patch moves setup control response to bnep and makes it private.
---
android/pan.c | 14 +++--------
profiles/network/bnep.c | 60 +++++++++++++++++++++++++++++------------------
profiles/network/bnep.h | 2 --
profiles/network/server.c | 38 ++++++++++--------------------
4 files changed, 52 insertions(+), 62 deletions(-)

diff --git a/android/pan.c b/android/pan.c
index a1356eb..a14ed84 100644
--- a/android/pan.c
+++ b/android/pan.c
@@ -463,7 +463,6 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
{
struct pan_device *dev = user_data;
uint8_t packet[BNEP_MTU];
- uint16_t rsp = BNEP_CONN_NOT_ALLOWED;
int sk, n, err;

if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
@@ -486,22 +485,16 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
}

err = nap_create_bridge();
- if (err < 0) {
+ if (err < 0)
error("pan: Failed to create bridge: %s (%d)", strerror(-err),
-err);
- goto failed;
- }

- if (bnep_server_add(sk, BNEP_BRIDGE, dev->iface, &dev->dst, packet, n)
- < 0) {
+ if (bnep_server_add(sk, (err < 0) ? NULL : BNEP_BRIDGE, dev->iface,
+ &dev->dst, packet, n) < 0) {
error("pan: server_connadd failed");
- rsp = BNEP_CONN_NOT_ALLOWED;
goto failed;
}

- rsp = BNEP_SUCCESS;
- bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
-
dev->watch = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
nap_watchdog_cb, dev);
g_io_channel_unref(dev->io);
@@ -513,7 +506,6 @@ static gboolean nap_setup_cb(GIOChannel *chan, GIOCondition cond,
return FALSE;

failed:
- bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
pan_device_remove(dev);

return FALSE;
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 0a41d73..afd94c5 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -524,6 +524,18 @@ static int bnep_del_from_bridge(const char *devname, const char *bridge)
return err;
}

+static ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl,
+ uint16_t resp)
+{
+ struct bnep_control_rsp rsp;
+
+ rsp.type = type;
+ rsp.ctrl = ctrl;
+ rsp.resp = htons(resp);
+
+ return send(sk, &rsp, sizeof(rsp), 0);
+}
+
static uint16_t bnep_setup_decode(int sk, struct bnep_setup_conn_req *req,
uint16_t *dst)
{
@@ -578,7 +590,6 @@ static uint16_t bnep_setup_decode(int sk, struct bnep_setup_conn_req *req,
case BNEP_SVC_GN:
if (src == BNEP_SVC_PANU)
return BNEP_SUCCESS;
-
return BNEP_CONN_INVALID_SRC;
case BNEP_SVC_PANU:
if (src == BNEP_SVC_PANU || src == BNEP_SVC_GN ||
@@ -595,7 +606,7 @@ int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
uint8_t *setup_data, int len)
{
int err;
- uint16_t dst = NULL;
+ uint16_t rsp, dst = NULL;
struct bnep_setup_conn_req *req = (void *) setup_data;

/* Highest known Control command ID
@@ -614,27 +625,41 @@ int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
}

/* Processing BNEP_SETUP_CONNECTION_REQUEST_MSG */
- err = bnep_setup_decode(sk, req, &dst);
- if (err < 0) {
+ rsp = bnep_setup_decode(sk, req, &dst);
+ if (rsp != BNEP_SUCCESS || !dst) {
+ err = -rsp;
error("bnep: error while decoding setup connection request: %d",
- err);
- return -EINVAL;
+ rsp);
+ goto reply;
}

- if (!bridge || !iface || !addr || !dst)
- return -EINVAL;
+ if (!dst) {
+ error("bnep: cannot decode proper destination service UUID");
+ rsp = BNEP_CONN_INVALID_DST;
+ goto reply;
+ }

err = bnep_connadd(sk, dst, iface);
- if (err < 0)
- return err;
+ if (err < 0) {
+ rsp = BNEP_CONN_NOT_ALLOWED;
+ goto reply;
+ }

err = bnep_add_to_bridge(iface, bridge);
if (err < 0) {
bnep_conndel(addr);
- return err;
+ rsp = BNEP_CONN_NOT_ALLOWED;
+ goto reply;
}

- return bnep_if_up(iface);
+ err = bnep_if_up(iface);
+ if (err < 0)
+ rsp = BNEP_CONN_NOT_ALLOWED;
+
+reply:
+ bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
+
+ return err;
}

void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
@@ -646,14 +671,3 @@ void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr)
bnep_if_down(iface);
bnep_conndel(addr);
}
-
-ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp)
-{
- struct bnep_control_rsp rsp;
-
- rsp.type = type;
- rsp.ctrl = ctrl;
- rsp.resp = htons(resp);
-
- return send(sk, &rsp, sizeof(rsp), 0);
-}
diff --git a/profiles/network/bnep.h b/profiles/network/bnep.h
index 2686ea8..633baeb 100644
--- a/profiles/network/bnep.h
+++ b/profiles/network/bnep.h
@@ -43,5 +43,3 @@ void bnep_disconnect(struct bnep *session);
int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
uint8_t *setup_data, int len);
void bnep_server_delete(char *bridge, char *iface, const bdaddr_t *addr);
-
-ssize_t bnep_send_ctrl_rsp(int sk, uint8_t type, uint8_t ctrl, uint16_t resp);
diff --git a/profiles/network/server.c b/profiles/network/server.c
index 4644133..9caabb0 100644
--- a/profiles/network/server.c
+++ b/profiles/network/server.c
@@ -288,9 +288,10 @@ static gboolean bnep_setup(GIOChannel *chan,
struct network_server *ns;
uint8_t packet[BNEP_MTU];
struct bnep_setup_conn_req *req = (void *) packet;
- uint16_t dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
+ uint16_t dst_role = 0;
uint32_t val;
int n, sk;
+ char *bridge = NULL;

if (cond & G_IO_NVAL)
return FALSE;
@@ -325,51 +326,36 @@ static gboolean bnep_setup(GIOChannel *chan,
break;
case 16:
if (memcmp(&req->service[4], bt_base, sizeof(bt_base)) != 0)
- return FALSE;
+ break;

/* Intentional no-brake */

case 4:
val = get_be32(req->service);
if (val > 0xffff)
- return FALSE;
+ break;

dst_role = val;
break;
default:
- return FALSE;
+ break;
}

ns = find_server(na->servers, dst_role);
- if (!ns) {
- error("Server unavailable: (0x%x)", dst_role);
- goto reply;
- }
-
- if (!ns->record_id) {
- error("Service record not available");
- goto reply;
- }
-
- if (!ns->bridge) {
- error("Bridge interface not configured");
- goto reply;
- }
+ if (!ns || !ns->record_id || !ns->bridge)
+ error("Server error, bridge not initialized: (0x%x)", dst_role);
+ else
+ bridge = ns->bridge;

strncpy(na->setup->dev, BNEP_INTERFACE, 16);
na->setup->dev[15] = '\0';

- if (bnep_server_add(sk, ns->bridge, na->setup->dev,
- &na->setup->dst, packet, n) < 0)
- goto reply;
+ if (bnep_server_add(sk, bridge, na->setup->dev, &na->setup->dst,
+ packet, n) < 0)
+ error("BNEP server cannot be added");

na->setup = NULL;

- rsp = BNEP_SUCCESS;
-
-reply:
- bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
-
return FALSE;
}

--
2.1.0