You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2020/05/04 12:56:05 UTC
[GitHub] [mynewt-nimble] michal-narajowski opened a new pull request #811: apps/bttester: Add support for Enhanced L2CAP COC
michal-narajowski opened a new pull request #811:
URL: https://github.com/apache/mynewt-nimble/pull/811
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
[GitHub] [mynewt-nimble] apache-mynewt-bot commented on pull request #811: apps/bttester: Add support for Enhanced L2CAP COC
Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on pull request #811:
URL: https://github.com/apache/mynewt-nimble/pull/811#issuecomment-623447568
<!-- style-bot -->
## Style check summary
### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
#### apps/bttester/src/bttester.h
<details>
```diff
@@ -704,88 +704,90 @@
} __packed;
/* GATT events */
-#define GATT_EV_NOTIFICATION 0x80
+#define GATT_EV_NOTIFICATION 0x80
struct gatt_notification_ev {
- u8_t address_type;
- u8_t address[6];
- u8_t type;
- u16_t handle;
- u16_t data_length;
- u8_t data[0];
-} __packed;
-
-#define GATT_EV_ATTR_VALUE_CHANGED 0x81
+ u8_t address_type;
+ u8_t address[6];
+ u8_t type;
+ u16_t handle;
+ u16_t data_length;
+ u8_t data[0];
+} __packed;
+
+#define GATT_EV_ATTR_VALUE_CHANGED 0x81
struct gatt_attr_value_changed_ev {
- u16_t handle;
- u16_t data_length;
- u8_t data[0];
-} __packed;
-
-static inline void tester_set_bit(u8_t *addr, unsigned int bit)
+ u16_t handle;
+ u16_t data_length;
+ u8_t data[0];
+} __packed;
+
+static inline void
+tester_set_bit(u8_t *addr, unsigned int bit)
{
- u8_t *p = addr + (bit / 8);
-
- *p |= BIT(bit % 8);
+ u8_t *p = addr + (bit / 8);
+
+ *p |= BIT(bit % 8);
}
-static inline u8_t tester_test_bit(const u8_t *addr, unsigned int bit)
+static inline u8_t
+tester_test_bit(const u8_t *addr, unsigned int bit)
{
- const u8_t *p = addr + (bit / 8);
-
- return *p & BIT(bit % 8);
+ const u8_t *p = addr + (bit / 8);
+
+ return *p & BIT(bit % 8);
}
/* L2CAP Service */
/* commands */
-#define L2CAP_READ_SUPPORTED_COMMANDS 0x01
+#define L2CAP_READ_SUPPORTED_COMMANDS 0x01
struct l2cap_read_supported_commands_rp {
- u8_t data[0];
-} __packed;
-
-#define L2CAP_CONNECT 0x02
+ u8_t data[0];
+} __packed;
+
+#define L2CAP_CONNECT 0x02
struct l2cap_connect_cmd {
- u8_t address_type;
- u8_t address[6];
- u16_t psm;
- u16_t mtu;
- u8_t num;
+ u8_t address_type;
+ u8_t address[6];
+ u16_t psm;
+ u16_t mtu;
+ u8_t num;
} __packed;
struct l2cap_connect_rp {
- u8_t num;
- u8_t chan_ids[0];
-} __packed;
-
-#define L2CAP_DISCONNECT 0x03
+ u8_t num;
+ u8_t chan_ids[0];
+} __packed;
+
+#define L2CAP_DISCONNECT 0x03
struct l2cap_disconnect_cmd {
- u8_t chan_id;
-} __packed;
-
-#define L2CAP_SEND_DATA 0x04
+ u8_t chan_id;
+} __packed;
+
+#define L2CAP_SEND_DATA 0x04
struct l2cap_send_data_cmd {
- u8_t chan_id;
- u16_t data_len;
- u8_t data[];
-} __packed;
-
-#define L2CAP_TRANSPORT_BREDR 0x00
-#define L2CAP_TRANSPORT_LE 0x01
-
-#define L2CAP_LISTEN 0x05
+ u8_t chan_id;
+ u16_t data_len;
+ u8_t data[];
+} __packed;
+
+#define L2CAP_TRANSPORT_BREDR 0x00
+#define L2CAP_TRANSPORT_LE 0x01
+
+#define L2CAP_LISTEN 0x05
struct l2cap_listen_cmd {
- u16_t psm;
- u8_t transport;
- u16_t mtu;
- u16_t response;
-} __packed;
-
-#define L2CAP_ACCEPT_CONNECTION 0x06
+ u16_t psm;
+ u8_t transport;
+ u16_t mtu;
+ u16_t response;
+} __packed;
+
+#define L2CAP_ACCEPT_CONNECTION 0x06
struct l2cap_accept_connection_cmd {
- u8_t chan_id;
- u16_t result;
-} __packed;
-
-#define L2CAP_RECONFIGURE 0x07
+ u8_t chan_id;
+ u16_t result;
+} __packed;
+
+#define L2CAP_RECONFIGURE 0x07
struct l2cap_reconfigure_cmd {
u8_t address_type;
u8_t address[6];
@@ -795,234 +797,234 @@
} __packed;
/* events */
-#define L2CAP_EV_CONNECTION_REQ 0x80
+#define L2CAP_EV_CONNECTION_REQ 0x80
struct l2cap_connection_req_ev {
- u8_t chan_id;
- u16_t psm;
- u8_t address_type;
- u8_t address[6];
-} __packed;
-
-#define L2CAP_EV_CONNECTED 0x81
+ u8_t chan_id;
+ u16_t psm;
+ u8_t address_type;
+ u8_t address[6];
+} __packed;
+
+#define L2CAP_EV_CONNECTED 0x81
struct l2cap_connected_ev {
- u8_t chan_id;
- u16_t psm;
- u16_t peer_mtu;
- u16_t peer_mps;
- u16_t our_mtu;
- u16_t our_mps;
- u8_t address_type;
- u8_t address[6];
-} __packed;
-
-#define L2CAP_EV_DISCONNECTED 0x82
+ u8_t chan_id;
+ u16_t psm;
+ u16_t peer_mtu;
+ u16_t peer_mps;
+ u16_t our_mtu;
+ u16_t our_mps;
+ u8_t address_type;
+ u8_t address[6];
+} __packed;
+
+#define L2CAP_EV_DISCONNECTED 0x82
struct l2cap_disconnected_ev {
- u16_t result;
- u8_t chan_id;
- u16_t psm;
- u8_t address_type;
- u8_t address[6];
-} __packed;
-
-#define L2CAP_EV_DATA_RECEIVED 0x83
+ u16_t result;
+ u8_t chan_id;
+ u16_t psm;
+ u8_t address_type;
+ u8_t address[6];
+} __packed;
+
+#define L2CAP_EV_DATA_RECEIVED 0x83
struct l2cap_data_received_ev {
- u8_t chan_id;
- u16_t data_length;
- u8_t data[0];
-} __packed;
-
-#define L2CAP_EV_RECONFIGURED 0x84
+ u8_t chan_id;
+ u16_t data_length;
+ u8_t data[0];
+} __packed;
+
+#define L2CAP_EV_RECONFIGURED 0x84
struct l2cap_reconfigured_ev {
- u8_t chan_id;
- u16_t peer_mtu;
- u16_t peer_mps;
- u16_t our_mtu;
- u16_t our_mps;
+ u8_t chan_id;
+ u16_t peer_mtu;
+ u16_t peer_mps;
+ u16_t our_mtu;
+ u16_t our_mps;
} __packed;
/* MESH Service */
/* commands */
-#define MESH_READ_SUPPORTED_COMMANDS 0x01
+#define MESH_READ_SUPPORTED_COMMANDS 0x01
struct mesh_read_supported_commands_rp {
- u8_t data[0];
-} __packed;
-
-#define MESH_OUT_BLINK BIT(0)
-#define MESH_OUT_BEEP BIT(1)
-#define MESH_OUT_VIBRATE BIT(2)
-#define MESH_OUT_DISPLAY_NUMBER BIT(3)
-#define MESH_OUT_DISPLAY_STRING BIT(4)
-
-#define MESH_IN_PUSH BIT(0)
-#define MESH_IN_TWIST BIT(1)
-#define MESH_IN_ENTER_NUMBER BIT(2)
-#define MESH_IN_ENTER_STRING BIT(3)
-
-#define MESH_CONFIG_PROVISIONING 0x02
+ u8_t data[0];
+} __packed;
+
+#define MESH_OUT_BLINK BIT(0)
+#define MESH_OUT_BEEP BIT(1)
+#define MESH_OUT_VIBRATE BIT(2)
+#define MESH_OUT_DISPLAY_NUMBER BIT(3)
+#define MESH_OUT_DISPLAY_STRING BIT(4)
+
+#define MESH_IN_PUSH BIT(0)
+#define MESH_IN_TWIST BIT(1)
+#define MESH_IN_ENTER_NUMBER BIT(2)
+#define MESH_IN_ENTER_STRING BIT(3)
+
+#define MESH_CONFIG_PROVISIONING 0x02
struct mesh_config_provisioning_cmd {
- u8_t uuid[16];
- u8_t static_auth[16];
- u8_t out_size;
- u16_t out_actions;
- u8_t in_size;
- u16_t in_actions;
-} __packed;
-
-#define MESH_PROVISION_NODE 0x03
+ u8_t uuid[16];
+ u8_t static_auth[16];
+ u8_t out_size;
+ u16_t out_actions;
+ u8_t in_size;
+ u16_t in_actions;
+} __packed;
+
+#define MESH_PROVISION_NODE 0x03
struct mesh_provision_node_cmd {
- u8_t net_key[16];
- u16_t net_key_idx;
- u8_t flags;
- u32_t iv_index;
- u32_t seq_num;
- u16_t addr;
- u8_t dev_key[16];
-} __packed;
-
-#define MESH_INIT 0x04
-#define MESH_RESET 0x05
-#define MESH_INPUT_NUMBER 0x06
+ u8_t net_key[16];
+ u16_t net_key_idx;
+ u8_t flags;
+ u32_t iv_index;
+ u32_t seq_num;
+ u16_t addr;
+ u8_t dev_key[16];
+} __packed;
+
+#define MESH_INIT 0x04
+#define MESH_RESET 0x05
+#define MESH_INPUT_NUMBER 0x06
struct mesh_input_number_cmd {
- u32_t number;
-} __packed;
-
-#define MESH_INPUT_STRING 0x07
+ u32_t number;
+} __packed;
+
+#define MESH_INPUT_STRING 0x07
struct mesh_input_string_cmd {
- u8_t string_len;
- u8_t string[0];
-} __packed;
-
-#define MESH_IVU_TEST_MODE 0x08
+ u8_t string_len;
+ u8_t string[0];
+} __packed;
+
+#define MESH_IVU_TEST_MODE 0x08
struct mesh_ivu_test_mode_cmd {
- u8_t enable;
-} __packed;
-
-#define MESH_IVU_TOGGLE_STATE 0x09
-
-#define MESH_NET_SEND 0x0a
+ u8_t enable;
+} __packed;
+
+#define MESH_IVU_TOGGLE_STATE 0x09
+
+#define MESH_NET_SEND 0x0a
struct mesh_net_send_cmd {
- u8_t ttl;
- u16_t src;
- u16_t dst;
- u8_t payload_len;
- u8_t payload[0];
-} __packed;
-
-#define MESH_HEALTH_GENERATE_FAULTS 0x0b
+ u8_t ttl;
+ u16_t src;
+ u16_t dst;
+ u8_t payload_len;
+ u8_t payload[0];
+} __packed;
+
+#define MESH_HEALTH_GENERATE_FAULTS 0x0b
struct mesh_health_generate_faults_rp {
- u8_t test_id;
- u8_t cur_faults_count;
- u8_t reg_faults_count;
- u8_t current_faults[0];
- u8_t registered_faults[0];
-} __packed;
-
-#define MESH_HEALTH_CLEAR_FAULTS 0x0c
-
-#define MESH_LPN 0x0d
+ u8_t test_id;
+ u8_t cur_faults_count;
+ u8_t reg_faults_count;
+ u8_t current_faults[0];
+ u8_t registered_faults[0];
+} __packed;
+
+#define MESH_HEALTH_CLEAR_FAULTS 0x0c
+
+#define MESH_LPN 0x0d
struct mesh_lpn_set_cmd {
- u8_t enable;
-} __packed;
-
-#define MESH_LPN_POLL 0x0e
-
-#define MESH_MODEL_SEND 0x0f
+ u8_t enable;
+} __packed;
+
+#define MESH_LPN_POLL 0x0e
+
+#define MESH_MODEL_SEND 0x0f
struct mesh_model_send_cmd {
- u16_t src;
- u16_t dst;
- u8_t payload_len;
- u8_t payload[0];
-} __packed;
-
-#define MESH_LPN_SUBSCRIBE 0x10
+ u16_t src;
+ u16_t dst;
+ u8_t payload_len;
+ u8_t payload[0];
+} __packed;
+
+#define MESH_LPN_SUBSCRIBE 0x10
struct mesh_lpn_subscribe_cmd {
- u16_t address;
-} __packed;
-
-#define MESH_LPN_UNSUBSCRIBE 0x11
+ u16_t address;
+} __packed;
+
+#define MESH_LPN_UNSUBSCRIBE 0x11
struct mesh_lpn_unsubscribe_cmd {
- u16_t address;
-} __packed;
-
-#define MESH_RPL_CLEAR 0x12
-#define MESH_PROXY_IDENTITY 0x13
+ u16_t address;
+} __packed;
+
+#define MESH_RPL_CLEAR 0x12
+#define MESH_PROXY_IDENTITY 0x13
/* events */
-#define MESH_EV_OUT_NUMBER_ACTION 0x80
+#define MESH_EV_OUT_NUMBER_ACTION 0x80
struct mesh_out_number_action_ev {
- u16_t action;
- u32_t number;
-} __packed;
-
-#define MESH_EV_OUT_STRING_ACTION 0x81
+ u16_t action;
+ u32_t number;
+} __packed;
+
+#define MESH_EV_OUT_STRING_ACTION 0x81
struct mesh_out_string_action_ev {
- u8_t string_len;
- u8_t string[0];
-} __packed;
-
-#define MESH_EV_IN_ACTION 0x82
+ u8_t string_len;
+ u8_t string[0];
+} __packed;
+
+#define MESH_EV_IN_ACTION 0x82
struct mesh_in_action_ev {
- u16_t action;
- u8_t size;
-} __packed;
-
-#define MESH_EV_PROVISIONED 0x83
-
-#define MESH_PROV_BEARER_PB_ADV 0x00
-#define MESH_PROV_BEARER_PB_GATT 0x01
-#define MESH_EV_PROV_LINK_OPEN 0x84
+ u16_t action;
+ u8_t size;
+} __packed;
+
+#define MESH_EV_PROVISIONED 0x83
+
+#define MESH_PROV_BEARER_PB_ADV 0x00
+#define MESH_PROV_BEARER_PB_GATT 0x01
+#define MESH_EV_PROV_LINK_OPEN 0x84
struct mesh_prov_link_open_ev {
- u8_t bearer;
-} __packed;
-
-#define MESH_EV_PROV_LINK_CLOSED 0x85
+ u8_t bearer;
+} __packed;
+
+#define MESH_EV_PROV_LINK_CLOSED 0x85
struct mesh_prov_link_closed_ev {
- u8_t bearer;
-} __packed;
-
-#define MESH_EV_NET_RECV 0x86
+ u8_t bearer;
+} __packed;
+
+#define MESH_EV_NET_RECV 0x86
struct mesh_net_recv_ev {
- u8_t ttl;
- u8_t ctl;
- u16_t src;
- u16_t dst;
- u8_t payload_len;
- u8_t payload[0];
-} __packed;
-
-#define MESH_EV_INVALID_BEARER 0x87
+ u8_t ttl;
+ u8_t ctl;
+ u16_t src;
+ u16_t dst;
+ u8_t payload_len;
+ u8_t payload[0];
+} __packed;
+
+#define MESH_EV_INVALID_BEARER 0x87
struct mesh_invalid_bearer_ev {
- u8_t opcode;
-} __packed;
-
-#define MESH_EV_INCOMP_TIMER_EXP 0x88
+ u8_t opcode;
+} __packed;
+
+#define MESH_EV_INCOMP_TIMER_EXP 0x88
void tester_init(void);
void tester_rsp(u8_t service, u8_t opcode, u8_t index, u8_t status);
void tester_send(u8_t service, u8_t opcode, u8_t index, u8_t *data,
- size_t len);
+ size_t len);
void tester_send_buf(u8_t service, u8_t opcode, u8_t index,
- struct os_mbuf *buf);
+ struct os_mbuf *buf);
u8_t tester_init_gap(void);
u8_t tester_unregister_gap(void);
void tester_handle_gap(u8_t opcode, u8_t index, u8_t *data,
- u16_t len);
+ u16_t len);
u8_t tester_init_gatt(void);
u8_t tester_unregister_gatt(void);
void tester_handle_gatt(u8_t opcode, u8_t index, u8_t *data,
- u16_t len);
+ u16_t len);
int tester_gatt_notify_rx_ev(u16_t conn_handle, u16_t attr_handle,
- u8_t indication, struct os_mbuf *om);
+ u8_t indication, struct os_mbuf *om);
int tester_gatt_subscribe_ev(u16_t conn_handle, u16_t attr_handle, u8_t reason,
- u8_t prev_notify, u8_t cur_notify,
- u8_t prev_indicate, u8_t cur_indicate);
+ u8_t prev_notify, u8_t cur_notify,
+ u8_t prev_indicate, u8_t cur_indicate);
#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
u8_t tester_init_l2cap(void);
u8_t tester_unregister_l2cap(void);
void tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
- u16_t len);
+ u16_t len);
#endif
#if MYNEWT_VAL(BLE_MESH)
```
</details>
#### apps/bttester/src/l2cap.c
<details>
```diff
@@ -43,636 +43,654 @@
#define TESTER_COC_BUF_COUNT (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
static os_membuf_t tester_sdu_coc_mem[
- OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU)
+ OS_MEMPOOL_SIZE(TESTER_COC_BUF_COUNT, TESTER_COC_MTU)
];
struct os_mbuf_pool sdu_os_mbuf_pool;
static struct os_mempool sdu_coc_mbuf_mempool;
static struct channel {
- u8_t chan_id; /* Internal number that identifies L2CAP channel. */
- u8_t state;
- struct ble_l2cap_chan *chan;
+ u8_t chan_id; /* Internal number that identifies L2CAP channel. */
+ u8_t state;
+ struct ble_l2cap_chan *chan;
} channels[CHANNELS];
static u8_t recv_cb_buf[TESTER_COC_MTU + sizeof(struct l2cap_data_received_ev)];
-static struct channel *get_free_channel(void)
-{
- u8_t i;
- struct channel *chan;
-
- for (i = 0; i < CHANNELS; i++) {
- if (channels[i].state) {
- continue;
- }
-
- chan = &channels[i];
- chan->chan_id = i;
-
- return chan;
- }
-
- return NULL;
-}
-
-struct channel *find_channel(struct ble_l2cap_chan *chan)
-{
- int i;
-
- for (i = 0; i < CHANNELS; ++i) {
- if (channels[i].chan == chan) {
- return &channels[i];
- }
- }
-
- return NULL;
-}
-
-struct channel *get_channel(uint8_t chan_id)
-{
- if (chan_id >= CHANNELS) {
- return NULL;
- }
-
- return &channels[chan_id];
+static struct channel *
+get_free_channel(void)
+{
+ u8_t i;
+ struct channel *chan;
+
+ for (i = 0; i < CHANNELS; i++) {
+ if (channels[i].state) {
+ continue;
+ }
+
+ chan = &channels[i];
+ chan->chan_id = i;
+
+ return chan;
+ }
+
+ return NULL;
+}
+
+struct channel *
+find_channel(struct ble_l2cap_chan *chan)
+{
+ int i;
+
+ for (i = 0; i < CHANNELS; ++i) {
+ if (channels[i].chan == chan) {
+ return &channels[i];
+ }
+ }
+
+ return NULL;
+}
+
+struct channel *
+get_channel(uint8_t chan_id)
+{
+ if (chan_id >= CHANNELS) {
+ return NULL;
+ }
+
+ return &channels[chan_id];
}
static void
tester_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
{
- SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d",
- (uint32_t) chan, OS_MBUF_PKTLEN(sdu));
-
- os_mbuf_free_chain(sdu);
- sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
- assert(sdu != NULL);
-
- ble_l2cap_recv_ready(chan, sdu);
-}
-
-static void recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
- struct os_mbuf *buf, void *arg)
-{
- struct l2cap_data_received_ev *ev = (void *) recv_cb_buf;
- struct channel *channel = find_channel(chan);
- assert(channel != NULL);
-
- ev->chan_id = channel->chan_id;
- ev->data_length = OS_MBUF_PKTLEN(buf);
-
- if (ev->data_length > TESTER_COC_MTU) {
- SYS_LOG_ERR("Too large sdu received, truncating data");
- ev->data_length = TESTER_COC_MTU;
- }
- os_mbuf_copydata(buf, 0, ev->data_length, ev->data);
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED,
- CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length);
-
- tester_l2cap_coc_recv(chan, buf);
-}
-
-static void unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
- int status, void *arg)
-{
- if (status) {
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA,
- CONTROLLER_INDEX, BTP_STATUS_FAILED);
- } else {
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA,
- CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
- }
-}
-
-static void reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan,
- struct ble_l2cap_chan_info *chan_info,
- int status)
-{
- struct l2cap_reconfigured_ev ev;
- struct channel *channel;
-
- if (status != 0) {
- return;
- }
-
- channel = find_channel(chan);
- assert(channel != NULL);
-
- ev.chan_id = channel->chan_id;
- ev.peer_mtu = chan_info->peer_coc_mtu;
- ev.peer_mps = chan_info->peer_l2cap_mtu;
- ev.our_mtu = chan_info->our_coc_mtu;
- ev.our_mps = chan_info->our_l2cap_mtu;
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED,
- CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
-}
-
-static void connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
- struct ble_l2cap_chan_info *chan_info, void *arg)
-{
- struct l2cap_connected_ev ev;
- struct ble_gap_conn_desc desc;
- struct channel *channel = find_channel(chan);
-
- if (channel == NULL) {
- channel = get_free_channel();
- }
-
- ev.chan_id = channel->chan_id;
- ev.psm = chan_info->psm;
- ev.peer_mtu = chan_info->peer_coc_mtu;
- ev.peer_mps = chan_info->peer_l2cap_mtu;
- ev.our_mtu = chan_info->our_coc_mtu;
- ev.our_mps = chan_info->our_l2cap_mtu;
- channel->state = 1;
- channel->chan = chan;
-
- if (!ble_gap_conn_find(conn_handle, &desc)) {
- ev.address_type = desc.peer_ota_addr.type;
- memcpy(ev.address, desc.peer_ota_addr.val,
- sizeof(ev.address));
- }
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX,
- (u8_t *) &ev, sizeof(ev));
-}
-
-static void disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
- struct ble_l2cap_chan_info *chan_info, void *arg)
-{
- struct l2cap_disconnected_ev ev;
- struct ble_gap_conn_desc desc;
- struct channel *channel;
-
- memset(&ev, 0, sizeof(struct l2cap_disconnected_ev));
-
- channel = find_channel(chan);
- assert(channel != NULL);
-
- channel->state = 0;
- channel->chan = chan;
- ev.chan_id = channel->chan_id;
- ev.psm = chan_info->psm;
-
- if (!ble_gap_conn_find(conn_handle, &desc)) {
- ev.address_type = desc.peer_ota_addr.type;
- memcpy(ev.address, desc.peer_ota_addr.val,
- sizeof(ev.address));
- }
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED,
- CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
-}
-
-static int accept_cb(uint16_t conn_handle, uint16_t peer_mtu,
- struct ble_l2cap_chan *chan)
-{
- struct os_mbuf *sdu_rx;
-
- SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d",
- (uint32_t) chan, peer_mtu);
-
- sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
- if (!sdu_rx) {
- return BLE_HS_ENOMEM;
- }
-
- ble_l2cap_recv_ready(chan, sdu_rx);
-
- return 0;
+ SYS_LOG_DBG("LE CoC SDU received, chan: 0x%08lx, data len %d",
+ (uint32_t) chan, OS_MBUF_PKTLEN(sdu));
+
+ os_mbuf_free_chain(sdu);
+ sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
+ assert(sdu != NULL);
+
+ ble_l2cap_recv_ready(chan, sdu);
+}
+
+static void
+recv_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
+ struct os_mbuf *buf, void *arg)
+{
+ struct l2cap_data_received_ev *ev = (void *) recv_cb_buf;
+ struct channel *channel = find_channel(chan);
+ assert(channel != NULL);
+
+ ev->chan_id = channel->chan_id;
+ ev->data_length = OS_MBUF_PKTLEN(buf);
+
+ if (ev->data_length > TESTER_COC_MTU) {
+ SYS_LOG_ERR("Too large sdu received, truncating data");
+ ev->data_length = TESTER_COC_MTU;
+ }
+ os_mbuf_copydata(buf, 0, ev->data_length, ev->data);
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DATA_RECEIVED,
+ CONTROLLER_INDEX, recv_cb_buf, sizeof(*ev) + ev->data_length);
+
+ tester_l2cap_coc_recv(chan, buf);
+}
+
+static void
+unstalled_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
+ int status, void *arg)
+{
+ if (status) {
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA,
+ CONTROLLER_INDEX, BTP_STATUS_FAILED);
+ } else {
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA,
+ CONTROLLER_INDEX, BTP_STATUS_SUCCESS);
+ }
+}
+
+static void
+reconfigured_ev(uint16_t conn_handle, struct ble_l2cap_chan *chan,
+ struct ble_l2cap_chan_info *chan_info,
+ int status)
+{
+ struct l2cap_reconfigured_ev ev;
+ struct channel *channel;
+
+ if (status != 0) {
+ return;
+ }
+
+ channel = find_channel(chan);
+ assert(channel != NULL);
+
+ ev.chan_id = channel->chan_id;
+ ev.peer_mtu = chan_info->peer_coc_mtu;
+ ev.peer_mps = chan_info->peer_l2cap_mtu;
+ ev.our_mtu = chan_info->our_coc_mtu;
+ ev.our_mps = chan_info->our_l2cap_mtu;
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_RECONFIGURED,
+ CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
+}
+
+static void
+connected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
+ struct ble_l2cap_chan_info *chan_info, void *arg)
+{
+ struct l2cap_connected_ev ev;
+ struct ble_gap_conn_desc desc;
+ struct channel *channel = find_channel(chan);
+
+ if (channel == NULL) {
+ channel = get_free_channel();
+ }
+
+ ev.chan_id = channel->chan_id;
+ ev.psm = chan_info->psm;
+ ev.peer_mtu = chan_info->peer_coc_mtu;
+ ev.peer_mps = chan_info->peer_l2cap_mtu;
+ ev.our_mtu = chan_info->our_coc_mtu;
+ ev.our_mps = chan_info->our_l2cap_mtu;
+ channel->state = 1;
+ channel->chan = chan;
+
+ if (!ble_gap_conn_find(conn_handle, &desc)) {
+ ev.address_type = desc.peer_ota_addr.type;
+ memcpy(ev.address, desc.peer_ota_addr.val,
+ sizeof(ev.address));
+ }
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_CONNECTED, CONTROLLER_INDEX,
+ (u8_t *) &ev, sizeof(ev));
+}
+
+static void
+disconnected_cb(uint16_t conn_handle, struct ble_l2cap_chan *chan,
+ struct ble_l2cap_chan_info *chan_info, void *arg)
+{
+ struct l2cap_disconnected_ev ev;
+ struct ble_gap_conn_desc desc;
+ struct channel *channel;
+
+ memset(&ev, 0, sizeof(struct l2cap_disconnected_ev));
+
+ channel = find_channel(chan);
+ assert(channel != NULL);
+
+ channel->state = 0;
+ channel->chan = chan;
+ ev.chan_id = channel->chan_id;
+ ev.psm = chan_info->psm;
+
+ if (!ble_gap_conn_find(conn_handle, &desc)) {
+ ev.address_type = desc.peer_ota_addr.type;
+ memcpy(ev.address, desc.peer_ota_addr.val,
+ sizeof(ev.address));
+ }
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_EV_DISCONNECTED,
+ CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
+}
+
+static int
+accept_cb(uint16_t conn_handle, uint16_t peer_mtu,
+ struct ble_l2cap_chan *chan)
+{
+ struct os_mbuf *sdu_rx;
+
+ SYS_LOG_DBG("LE CoC accepting, chan: 0x%08lx, peer_mtu %d",
+ (uint32_t) chan, peer_mtu);
+
+ sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
+ if (!sdu_rx) {
+ return BLE_HS_ENOMEM;
+ }
+
+ ble_l2cap_recv_ready(chan, sdu_rx);
+
+ return 0;
}
static int
tester_l2cap_event(struct ble_l2cap_event *event, void *arg)
{
- struct ble_l2cap_chan_info chan_info;
- int accept_response;
-
- switch (event->type) {
- case BLE_L2CAP_EVENT_COC_CONNECTED:
- if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) {
- assert(0);
- }
-
- if (event->connect.status) {
- console_printf("LE COC error: %d\n", event->connect.status);
- disconnected_cb(event->connect.conn_handle,
- event->connect.chan, &chan_info, arg);
- return 0;
- }
-
- console_printf("LE COC connected, conn: %d, chan: 0x%08lx, "
- "psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, "
- "our_mps: %d, our_mtu: %d, peer_mps: %d, "
- "peer_mtu: %d\n", event->connect.conn_handle,
- (uint32_t) event->connect.chan, chan_info.psm,
- chan_info.scid, chan_info.dcid,
- chan_info.our_l2cap_mtu, chan_info.our_coc_mtu,
- chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
-
- connected_cb(event->connect.conn_handle,
- event->connect.chan, &chan_info, arg);
-
- return 0;
- case BLE_L2CAP_EVENT_COC_DISCONNECTED:
- if (ble_l2cap_get_chan_info(event->disconnect.chan,
- &chan_info)) {
- assert(0);
- }
- console_printf("LE CoC disconnected, chan: 0x%08lx\n",
- (uint32_t) event->disconnect.chan);
-
- disconnected_cb(event->disconnect.conn_handle,
- event->disconnect.chan, &chan_info, arg);
- return 0;
- case BLE_L2CAP_EVENT_COC_ACCEPT:
- accept_response = POINTER_TO_INT(arg);
- if (accept_response) {
- return accept_response;
- }
-
- console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n",
- (uint32_t) event->accept.chan,
- event->accept.conn_handle,
- event->accept.peer_sdu_size);
-
- return accept_cb(event->accept.conn_handle,
- event->accept.peer_sdu_size,
- event->accept.chan);
-
- case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
- console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n",
- (uint32_t) event->receive.chan,
- event->receive.conn_handle,
- OS_MBUF_PKTLEN(event->receive.sdu_rx));
-
- recv_cb(event->receive.conn_handle, event->receive.chan,
- event->receive.sdu_rx, arg);
- return 0;
- case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
- console_printf("LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n",
- (uint32_t) event->tx_unstalled.chan,
- event->tx_unstalled.conn_handle,
- event->tx_unstalled.status);
-
- unstalled_cb(event->tx_unstalled.conn_handle,
- event->tx_unstalled.chan,
- event->tx_unstalled.status, arg);
- return 0;
- case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED:
- if (ble_l2cap_get_chan_info(event->reconfigured.chan,
- &chan_info)) {
- assert(0);
- }
- console_printf("LE CoC reconfigure completed status 0x%02x, "
- "chan: 0x%08lx\n", event->reconfigured.status,
- (uint32_t) event->reconfigured.chan);
-
- if (event->reconfigured.status == 0) {
- console_printf("\t our_mps: %d our_mtu %d\n",
- chan_info.our_l2cap_mtu, chan_info.our_coc_mtu);
- }
-
- reconfigured_ev(event->reconfigured.conn_handle,
- event->reconfigured.chan,
- &chan_info,
- event->reconfigured.status);
- return 0;
- case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED:
- if (ble_l2cap_get_chan_info(event->reconfigured.chan,
- &chan_info)) {
- assert(0);
- }
- console_printf("LE CoC peer reconfigured status 0x%02x, "
- "chan: 0x%08lx\n", event->reconfigured.status,
- (uint32_t) event->reconfigured.chan);
-
- if (event->reconfigured.status == 0) {
- console_printf("\t peer_mps: %d peer_mtu %d\n",
- chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
- }
-
- reconfigured_ev(event->reconfigured.conn_handle,
- event->reconfigured.chan,
- &chan_info,
- event->reconfigured.status);
- return 0;
- default:
- return 0;
- }
-}
-
-static void connect(u8_t *data, u16_t len)
-{
- const struct l2cap_connect_cmd *cmd = (void *) data;
- u8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num];
- struct l2cap_connect_rp *rp = (void *) rp_buf;
- struct ble_gap_conn_desc desc;
- struct channel *chan;
- struct os_mbuf *sdu_rx[cmd->num];
- ble_addr_t *addr = (void *) data;
- uint16_t mtu = htole16(cmd->mtu);
- int rc;
- int i;
-
- SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6));
-
- if (mtu == 0 || mtu > TESTER_COC_MTU) {
- mtu = TESTER_COC_MTU;
- }
-
- rc = ble_gap_conn_find_by_addr(addr, &desc);
- if (rc) {
- SYS_LOG_ERR("GAP conn find failed");
- goto fail;
- }
-
- rp->num = cmd->num;
-
- for (i = 0; i < cmd->num; i++) {
- chan = get_free_channel();
- if (!chan) {
- SYS_LOG_ERR("No free channels");
- goto fail;
- }
-
- rp->chan_ids[i] = chan->chan_id;
-
- sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
- if (sdu_rx[i] == NULL) {
- SYS_LOG_ERR("Failed to alloc buf");
- goto fail;
- }
- }
-
- if (cmd->num == 1) {
- rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm),
- mtu, sdu_rx[0],
- tester_l2cap_event, NULL);
- } else if (cmd->num > 1) {
- rc = ble_l2cap_enhanced_connect(desc.conn_handle,
- htole16(cmd->psm), mtu,
- cmd->num, sdu_rx,
- tester_l2cap_event, NULL);
- } else {
- SYS_LOG_ERR("Invalid 'num' parameter value");
- goto fail;
- }
-
- if (rc) {
- SYS_LOG_ERR("L2CAP connect failed\n");
- goto fail;
- }
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
- (u8_t *) rp, sizeof(rp_buf));
-
- return;
+ struct ble_l2cap_chan_info chan_info;
+ int accept_response;
+
+ switch (event->type) {
+ case BLE_L2CAP_EVENT_COC_CONNECTED:
+ if (ble_l2cap_get_chan_info(event->connect.chan, &chan_info)) {
+ assert(0);
+ }
+
+ if (event->connect.status) {
+ console_printf("LE COC error: %d\n", event->connect.status);
+ disconnected_cb(event->connect.conn_handle,
+ event->connect.chan, &chan_info, arg);
+ return 0;
+ }
+
+ console_printf("LE COC connected, conn: %d, chan: 0x%08lx, "
+ "psm: 0x%02x, scid: 0x%04x, dcid: 0x%04x, "
+ "our_mps: %d, our_mtu: %d, peer_mps: %d, "
+ "peer_mtu: %d\n", event->connect.conn_handle,
+ (uint32_t) event->connect.chan, chan_info.psm,
+ chan_info.scid, chan_info.dcid,
+ chan_info.our_l2cap_mtu, chan_info.our_coc_mtu,
+ chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
+
+ connected_cb(event->connect.conn_handle,
+ event->connect.chan, &chan_info, arg);
+
+ return 0;
+ case BLE_L2CAP_EVENT_COC_DISCONNECTED:
+ if (ble_l2cap_get_chan_info(event->disconnect.chan,
+ &chan_info)) {
+ assert(0);
+ }
+ console_printf("LE CoC disconnected, chan: 0x%08lx\n",
+ (uint32_t) event->disconnect.chan);
+
+ disconnected_cb(event->disconnect.conn_handle,
+ event->disconnect.chan, &chan_info, arg);
+ return 0;
+ case BLE_L2CAP_EVENT_COC_ACCEPT:
+ accept_response = POINTER_TO_INT(arg);
+ if (accept_response) {
+ return accept_response;
+ }
+
+ console_printf("LE CoC accept, chan: 0x%08lx, handle: %u, sdu_size: %u\n",
+ (uint32_t) event->accept.chan,
+ event->accept.conn_handle,
+ event->accept.peer_sdu_size);
+
+ return accept_cb(event->accept.conn_handle,
+ event->accept.peer_sdu_size,
+ event->accept.chan);
+
+ case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
+ console_printf("LE CoC data received, chan: 0x%08lx, handle: %u, sdu_len: %u\n",
+ (uint32_t) event->receive.chan,
+ event->receive.conn_handle,
+ OS_MBUF_PKTLEN(event->receive.sdu_rx));
+
+ recv_cb(event->receive.conn_handle, event->receive.chan,
+ event->receive.sdu_rx, arg);
+ return 0;
+ case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
+ console_printf("LE CoC tx unstalled, chan: 0x%08lx, handle: %u, status: %d\n",
+ (uint32_t) event->tx_unstalled.chan,
+ event->tx_unstalled.conn_handle,
+ event->tx_unstalled.status);
+
+ unstalled_cb(event->tx_unstalled.conn_handle,
+ event->tx_unstalled.chan,
+ event->tx_unstalled.status, arg);
+ return 0;
+ case BLE_L2CAP_EVENT_COC_RECONFIG_COMPLETED:
+ if (ble_l2cap_get_chan_info(event->reconfigured.chan,
+ &chan_info)) {
+ assert(0);
+ }
+ console_printf("LE CoC reconfigure completed status 0x%02x, "
+ "chan: 0x%08lx\n", event->reconfigured.status,
+ (uint32_t) event->reconfigured.chan);
+
+ if (event->reconfigured.status == 0) {
+ console_printf("\t our_mps: %d our_mtu %d\n",
+ chan_info.our_l2cap_mtu, chan_info.our_coc_mtu);
+ }
+
+ reconfigured_ev(event->reconfigured.conn_handle,
+ event->reconfigured.chan,
+ &chan_info,
+ event->reconfigured.status);
+ return 0;
+ case BLE_L2CAP_EVENT_COC_PEER_RECONFIGURED:
+ if (ble_l2cap_get_chan_info(event->reconfigured.chan,
+ &chan_info)) {
+ assert(0);
+ }
+ console_printf("LE CoC peer reconfigured status 0x%02x, "
+ "chan: 0x%08lx\n", event->reconfigured.status,
+ (uint32_t) event->reconfigured.chan);
+
+ if (event->reconfigured.status == 0) {
+ console_printf("\t peer_mps: %d peer_mtu %d\n",
+ chan_info.peer_l2cap_mtu, chan_info.peer_coc_mtu);
+ }
+
+ reconfigured_ev(event->reconfigured.conn_handle,
+ event->reconfigured.chan,
+ &chan_info,
+ event->reconfigured.status);
+ return 0;
+ default:
+ return 0;
+ }
+}
+
+static void
+connect(u8_t *data, u16_t len)
+{
+ const struct l2cap_connect_cmd *cmd = (void *) data;
+ u8_t rp_buf[sizeof(struct l2cap_connect_rp) + cmd->num];
+ struct l2cap_connect_rp *rp = (void *) rp_buf;
+ struct ble_gap_conn_desc desc;
+ struct channel *chan;
+ struct os_mbuf *sdu_rx[cmd->num];
+ ble_addr_t *addr = (void *) data;
+ uint16_t mtu = htole16(cmd->mtu);
+ int rc;
+ int i;
+
+ SYS_LOG_DBG("connect: type: %d addr: %s", addr->type, bt_hex(addr->val, 6));
+
+ if (mtu == 0 || mtu > TESTER_COC_MTU) {
+ mtu = TESTER_COC_MTU;
+ }
+
+ rc = ble_gap_conn_find_by_addr(addr, &desc);
+ if (rc) {
+ SYS_LOG_ERR("GAP conn find failed");
+ goto fail;
+ }
+
+ rp->num = cmd->num;
+
+ for (i = 0; i < cmd->num; i++) {
+ chan = get_free_channel();
+ if (!chan) {
+ SYS_LOG_ERR("No free channels");
+ goto fail;
+ }
+
+ rp->chan_ids[i] = chan->chan_id;
+
+ sdu_rx[i] = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
+ if (sdu_rx[i] == NULL) {
+ SYS_LOG_ERR("Failed to alloc buf");
+ goto fail;
+ }
+ }
+
+ if (cmd->num == 1) {
+ rc = ble_l2cap_connect(desc.conn_handle, htole16(cmd->psm),
+ mtu, sdu_rx[0],
+ tester_l2cap_event, NULL);
+ } else if (cmd->num > 1) {
+ rc = ble_l2cap_enhanced_connect(desc.conn_handle,
+ htole16(cmd->psm), mtu,
+ cmd->num, sdu_rx,
+ tester_l2cap_event, NULL);
+ } else {
+ SYS_LOG_ERR("Invalid 'num' parameter value");
+ goto fail;
+ }
+
+ if (rc) {
+ SYS_LOG_ERR("L2CAP connect failed\n");
+ goto fail;
+ }
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
+ (u8_t *) rp, sizeof(rp_buf));
+
+ return;
fail:
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
-}
-
-static void disconnect(const u8_t *data, u16_t len)
-{
- const struct l2cap_disconnect_cmd *cmd = (void *) data;
- struct channel *chan;
- u8_t status;
- int err;
-
- SYS_LOG_DBG("");
-
- chan = get_channel(cmd->chan_id);
- assert(chan != NULL);
-
- err = ble_l2cap_disconnect(chan->chan);
- if (err) {
- status = BTP_STATUS_FAILED;
- goto rsp;
- }
-
- status = BTP_STATUS_SUCCESS;
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_CONNECT, CONTROLLER_INDEX,
+ BTP_STATUS_FAILED);
+}
+
+static void
+disconnect(const u8_t *data, u16_t len)
+{
+ const struct l2cap_disconnect_cmd *cmd = (void *) data;
+ struct channel *chan;
+ u8_t status;
+ int err;
+
+ SYS_LOG_DBG("");
+
+ chan = get_channel(cmd->chan_id);
+ assert(chan != NULL);
+
+ err = ble_l2cap_disconnect(chan->chan);
+ if (err) {
+ status = BTP_STATUS_FAILED;
+ goto rsp;
+ }
+
+ status = BTP_STATUS_SUCCESS;
rsp:
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX,
- status);
-}
-
-static void send_data(const u8_t *data, u16_t len)
-{
- const struct l2cap_send_data_cmd *cmd = (void *) data;
- struct os_mbuf *sdu_tx = NULL;
- int rc;
- u16_t data_len = sys_le16_to_cpu(cmd->data_len);
- struct channel *chan = get_channel(cmd->chan_id);
-
- SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id);
-
- if (!chan) {
- SYS_LOG_ERR("Invalid channel\n");
- goto fail;
- }
-
- /* FIXME: For now, fail if data length exceeds buffer length */
- if (data_len > TESTER_COC_MTU) {
- SYS_LOG_ERR("Data length exceeds buffer length");
- goto fail;
- }
-
- sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
- if (sdu_tx == NULL) {
- SYS_LOG_ERR("No memory in the test sdu pool\n");
- goto fail;
- }
-
- os_mbuf_append(sdu_tx, cmd->data, data_len);
-
- /* ble_l2cap_send takes ownership of the sdu */
- rc = ble_l2cap_send(chan->chan, sdu_tx);
- if (rc == 0 || rc == BLE_HS_ESTALLED) {
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX,
- BTP_STATUS_SUCCESS);
- return;
- }
-
- SYS_LOG_ERR("Unable to send data: %d", rc);
- os_mbuf_free_chain(sdu_tx);
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT, CONTROLLER_INDEX,
+ status);
+}
+
+static void
+send_data(const u8_t *data, u16_t len)
+{
+ const struct l2cap_send_data_cmd *cmd = (void *) data;
+ struct os_mbuf *sdu_tx = NULL;
+ int rc;
+ u16_t data_len = sys_le16_to_cpu(cmd->data_len);
+ struct channel *chan = get_channel(cmd->chan_id);
+
+ SYS_LOG_DBG("cmd->chan_id=%d", cmd->chan_id);
+
+ if (!chan) {
+ SYS_LOG_ERR("Invalid channel\n");
+ goto fail;
+ }
+
+ /* FIXME: For now, fail if data length exceeds buffer length */
+ if (data_len > TESTER_COC_MTU) {
+ SYS_LOG_ERR("Data length exceeds buffer length");
+ goto fail;
+ }
+
+ sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
+ if (sdu_tx == NULL) {
+ SYS_LOG_ERR("No memory in the test sdu pool\n");
+ goto fail;
+ }
+
+ os_mbuf_append(sdu_tx, cmd->data, data_len);
+
+ /* ble_l2cap_send takes ownership of the sdu */
+ rc = ble_l2cap_send(chan->chan, sdu_tx);
+ if (rc == 0 || rc == BLE_HS_ESTALLED) {
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX,
+ BTP_STATUS_SUCCESS);
+ return;
+ }
+
+ SYS_LOG_ERR("Unable to send data: %d", rc);
+ os_mbuf_free_chain(sdu_tx);
fail:
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_SEND_DATA, CONTROLLER_INDEX,
+ BTP_STATUS_FAILED);
}
static int
l2cap_coc_err2hs_err(uint16_t coc_err)
{
- switch (coc_err) {
- case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM:
- return BLE_HS_ENOTSUP;
- case BLE_L2CAP_COC_ERR_NO_RESOURCES:
- return BLE_HS_ENOMEM;
- case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN:
- return BLE_HS_EAUTHEN;
- case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR:
- return BLE_HS_EAUTHOR;
- case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC:
- return BLE_HS_EENCRYPT;
- case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ:
- return BLE_HS_EENCRYPT_KEY_SZ;
- case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS:
- return BLE_HS_EINVAL;
- default:
- return 0;
- }
-}
-
-
-static void listen(const u8_t *data, u16_t len)
-{
- const struct l2cap_listen_cmd *cmd = (void *) data;
- uint16_t mtu = htole16(cmd->mtu);
- uint16_t rsp = htole16(cmd->response);
- int rc;
-
- SYS_LOG_DBG("");
-
- if (mtu == 0 || mtu > TESTER_COC_MTU) {
- mtu = TESTER_COC_MTU;
- }
-
- rsp = l2cap_coc_err2hs_err(rsp);
-
- /* TODO: Handle cmd->transport flag */
- rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event,
- INT_TO_POINTER(rsp));
- if (rc) {
- goto fail;
- }
-
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX,
- BTP_STATUS_SUCCESS);
- return;
+ switch (coc_err) {
+ case BLE_L2CAP_COC_ERR_UNKNOWN_LE_PSM:
+ return BLE_HS_ENOTSUP;
+ case BLE_L2CAP_COC_ERR_NO_RESOURCES:
+ return BLE_HS_ENOMEM;
+ case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHEN:
+ return BLE_HS_EAUTHEN;
+ case BLE_L2CAP_COC_ERR_INSUFFICIENT_AUTHOR:
+ return BLE_HS_EAUTHOR;
+ case BLE_L2CAP_COC_ERR_INSUFFICIENT_ENC:
+ return BLE_HS_EENCRYPT;
+ case BLE_L2CAP_COC_ERR_INSUFFICIENT_KEY_SZ:
+ return BLE_HS_EENCRYPT_KEY_SZ;
+ case BLE_L2CAP_COC_ERR_UNACCEPTABLE_PARAMETERS:
+ return BLE_HS_EINVAL;
+ default:
+ return 0;
+ }
+}
+
+
+static void
+listen(const u8_t *data, u16_t len)
+{
+ const struct l2cap_listen_cmd *cmd = (void *) data;
+ uint16_t mtu = htole16(cmd->mtu);
+ uint16_t rsp = htole16(cmd->response);
+ int rc;
+
+ SYS_LOG_DBG("");
+
+ if (mtu == 0 || mtu > TESTER_COC_MTU) {
+ mtu = TESTER_COC_MTU;
+ }
+
+ rsp = l2cap_coc_err2hs_err(rsp);
+
+ /* TODO: Handle cmd->transport flag */
+ rc = ble_l2cap_create_server(cmd->psm, mtu, tester_l2cap_event,
+ INT_TO_POINTER(rsp));
+ if (rc) {
+ goto fail;
+ }
+
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX,
+ BTP_STATUS_SUCCESS);
+ return;
fail:
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
-}
-
-static void reconfigure(const u8_t *data, u16_t len)
-{
- const struct l2cap_reconfigure_cmd *cmd = (void *) data;
- uint16_t mtu = htole16(cmd->mtu);
- struct ble_gap_conn_desc desc;
- ble_addr_t *addr = (void *) data;
- struct ble_l2cap_chan *chans[cmd->num];
- struct channel *channel;
- int rc;
- int i;
-
- SYS_LOG_DBG("");
-
- if (mtu == 0 || mtu > TESTER_COC_MTU) {
- mtu = TESTER_COC_MTU;
- }
-
- rc = ble_gap_conn_find_by_addr(addr, &desc);
- if (rc) {
- SYS_LOG_ERR("GAP conn find failed");
- goto fail;
- }
-
- for (i = 0; i < cmd->num; ++i) {
- channel = get_channel(cmd->idxs[i]);
- if (channel == NULL) {
- goto fail;
- }
- chans[i] = channel->chan;
- }
-
- rc = ble_l2cap_reconfig(chans, cmd->num, mtu);
- if (rc) {
- goto fail;
- }
-
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
- BTP_STATUS_SUCCESS);
- return;
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_LISTEN, CONTROLLER_INDEX,
+ BTP_STATUS_FAILED);
+}
+
+static void
+reconfigure(const u8_t *data, u16_t len)
+{
+ const struct l2cap_reconfigure_cmd *cmd = (void *) data;
+ uint16_t mtu = htole16(cmd->mtu);
+ struct ble_gap_conn_desc desc;
+ ble_addr_t *addr = (void *) data;
+ struct ble_l2cap_chan *chans[cmd->num];
+ struct channel *channel;
+ int rc;
+ int i;
+
+ SYS_LOG_DBG("");
+
+ if (mtu == 0 || mtu > TESTER_COC_MTU) {
+ mtu = TESTER_COC_MTU;
+ }
+
+ rc = ble_gap_conn_find_by_addr(addr, &desc);
+ if (rc) {
+ SYS_LOG_ERR("GAP conn find failed");
+ goto fail;
+ }
+
+ for (i = 0; i < cmd->num; ++i) {
+ channel = get_channel(cmd->idxs[i]);
+ if (channel == NULL) {
+ goto fail;
+ }
+ chans[i] = channel->chan;
+ }
+
+ rc = ble_l2cap_reconfig(chans, cmd->num, mtu);
+ if (rc) {
+ goto fail;
+ }
+
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
+ BTP_STATUS_SUCCESS);
+ return;
fail:
- tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
- BTP_STATUS_FAILED);
-}
-
-static void supported_commands(u8_t *data, u16_t len)
-{
- u8_t cmds[1];
- struct l2cap_read_supported_commands_rp *rp = (void *) cmds;
-
- memset(cmds, 0, sizeof(cmds));
-
- tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS);
- tester_set_bit(cmds, L2CAP_CONNECT);
- tester_set_bit(cmds, L2CAP_DISCONNECT);
- tester_set_bit(cmds, L2CAP_LISTEN);
- tester_set_bit(cmds, L2CAP_SEND_DATA);
- tester_set_bit(cmds, L2CAP_RECONFIGURE);
-
- tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS,
- CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
-}
-
-void tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
- u16_t len)
-{
- switch (opcode) {
- case L2CAP_READ_SUPPORTED_COMMANDS:
- supported_commands(data, len);
- return;
- case L2CAP_CONNECT:
- connect(data, len);
- return;
- case L2CAP_DISCONNECT:
- disconnect(data, len);
- return;
- case L2CAP_SEND_DATA:
- send_data(data, len);
- return;
- case L2CAP_LISTEN:
- listen(data, len);
- return;
- case L2CAP_RECONFIGURE:
- reconfigure(data, len);
- return;
- default:
- tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index,
- BTP_STATUS_UNKNOWN_CMD);
- return;
- }
-}
-
-u8_t tester_init_l2cap(void)
-{
- int rc;
-
- /* For testing we want to support all the available channels */
- rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT,
- TESTER_COC_MTU, tester_sdu_coc_mem,
- "tester_coc_sdu_pool");
- assert(rc == 0);
-
- rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool,
- TESTER_COC_MTU, TESTER_COC_BUF_COUNT);
- assert(rc == 0);
-
- return BTP_STATUS_SUCCESS;
-}
-
-u8_t tester_unregister_l2cap(void)
-{
- return BTP_STATUS_SUCCESS;
+ tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_RECONFIGURE, CONTROLLER_INDEX,
+ BTP_STATUS_FAILED);
+}
+
+static void
+supported_commands(u8_t *data, u16_t len)
+{
+ u8_t cmds[1];
+ struct l2cap_read_supported_commands_rp *rp = (void *) cmds;
+
+ memset(cmds, 0, sizeof(cmds));
+
+ tester_set_bit(cmds, L2CAP_READ_SUPPORTED_COMMANDS);
+ tester_set_bit(cmds, L2CAP_CONNECT);
+ tester_set_bit(cmds, L2CAP_DISCONNECT);
+ tester_set_bit(cmds, L2CAP_LISTEN);
+ tester_set_bit(cmds, L2CAP_SEND_DATA);
+ tester_set_bit(cmds, L2CAP_RECONFIGURE);
+
+ tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS,
+ CONTROLLER_INDEX, (u8_t *) rp, sizeof(cmds));
+}
+
+void
+tester_handle_l2cap(u8_t opcode, u8_t index, u8_t *data,
+ u16_t len)
+{
+ switch (opcode) {
+ case L2CAP_READ_SUPPORTED_COMMANDS:
+ supported_commands(data, len);
+ return;
+ case L2CAP_CONNECT:
+ connect(data, len);
+ return;
+ case L2CAP_DISCONNECT:
+ disconnect(data, len);
+ return;
+ case L2CAP_SEND_DATA:
+ send_data(data, len);
+ return;
+ case L2CAP_LISTEN:
+ listen(data, len);
+ return;
+ case L2CAP_RECONFIGURE:
+ reconfigure(data, len);
+ return;
+ default:
+ tester_rsp(BTP_SERVICE_ID_L2CAP, opcode, index,
+ BTP_STATUS_UNKNOWN_CMD);
+ return;
+ }
+}
+
+u8_t
+tester_init_l2cap(void)
+{
+ int rc;
+
+ /* For testing we want to support all the available channels */
+ rc = os_mempool_init(&sdu_coc_mbuf_mempool, TESTER_COC_BUF_COUNT,
+ TESTER_COC_MTU, tester_sdu_coc_mem,
+ "tester_coc_sdu_pool");
+ assert(rc == 0);
+
+ rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool,
+ TESTER_COC_MTU, TESTER_COC_BUF_COUNT);
+ assert(rc == 0);
+
+ return BTP_STATUS_SUCCESS;
+}
+
+u8_t
+tester_unregister_l2cap(void)
+{
+ return BTP_STATUS_SUCCESS;
}
#endif
```
</details>
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org