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