You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by na...@apache.org on 2019/09/13 13:32:44 UTC

[mynewt-nimble] 14/32: apps/bttester: Add Connection Parameter Update implementation

This is an automated email from the ASF dual-hosted git repository.

naraj pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git

commit 409c5a30b3209eb9bf2bd84d3e712961c33d66cc
Author: MichaƂ Narajowski <mi...@codecoup.pl>
AuthorDate: Tue Jul 9 16:26:31 2019 +0200

    apps/bttester: Add Connection Parameter Update implementation
---
 apps/bttester/src/bttester.h |  22 +++++++
 apps/bttester/src/gap.c      | 140 ++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 161 insertions(+), 1 deletion(-)

diff --git a/apps/bttester/src/bttester.h b/apps/bttester/src/bttester.h
index 9e88842..9e41f57 100644
--- a/apps/bttester/src/bttester.h
+++ b/apps/bttester/src/bttester.h
@@ -274,6 +274,16 @@ struct gap_passkey_confirm_cmd {
 	u8_t match;
 } __packed;
 
+#define GAP_CONN_PARAM_UPDATE		0x16
+struct gap_conn_param_update_cmd {
+    u8_t address_type;
+    u8_t address[6];
+    u16_t conn_itvl_min;
+    u16_t conn_itvl_max;
+    u16_t conn_latency;
+    u16_t supervision_timeout;
+} __packed;
+
 /* events */
 #define GAP_EV_NEW_SETTINGS		0x80
 struct gap_new_settings_ev {
@@ -298,6 +308,9 @@ struct gap_device_found_ev {
 struct gap_device_connected_ev {
 	u8_t address_type;
 	u8_t address[6];
+	u16_t conn_itvl;
+	u16_t conn_latency;
+	u16_t supervision_timeout;
 } __packed;
 
 #define GAP_EV_DEVICE_DISCONNECTED	0x83
@@ -334,6 +347,15 @@ struct gap_identity_resolved_ev {
 	u8_t identity_address[6];
 } __packed;
 
+#define GAP_EV_CONN_PARAM_UPDATE	0x88
+struct gap_conn_param_update_ev {
+    u8_t address_type;
+    u8_t address[6];
+    u16_t conn_itvl;
+    u16_t conn_latency;
+    u16_t supervision_timeout;
+} __packed;
+
 /* GATT Service */
 /* commands */
 #define GATT_READ_SUPPORTED_COMMANDS	0x01
diff --git a/apps/bttester/src/gap.c b/apps/bttester/src/gap.c
index 719971d..19bd72d 100644
--- a/apps/bttester/src/gap.c
+++ b/apps/bttester/src/gap.c
@@ -25,6 +25,7 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 
+#include <host/ble_gap.h>
 #include "host/ble_gap.h"
 #include "console/console.h"
 
@@ -665,7 +666,9 @@ static void le_connected(u16_t conn_handle, int status)
 
 	memcpy(ev.address, addr->val, sizeof(ev.address));
 	ev.address_type = addr->type;
-
+	ev.conn_itvl = desc.conn_itvl;
+	ev.conn_latency = desc.conn_latency;
+	ev.supervision_timeout = desc.supervision_timeout;
 
 #if MYNEWT_VAL(BTTESTER_CONN_PARAM_UPDATE)
 	if (desc.role == BLE_GAP_ROLE_MASTER) {
@@ -828,6 +831,23 @@ static void le_encryption_changed(struct ble_gap_conn_desc *desc)
 	encrypted = (bool) desc->sec_state.encrypted;
 }
 
+static void le_conn_param_update(struct ble_gap_conn_desc *desc)
+{
+	struct gap_conn_param_update_ev ev;
+
+	SYS_LOG_DBG("");
+
+	ev.address_type = desc->peer_ota_addr.type;
+	memcpy(ev.address, desc->peer_ota_addr.val, sizeof(ev.address));
+
+	ev.conn_itvl = desc->conn_itvl;
+	ev.conn_latency = desc->conn_latency;
+	ev.supervision_timeout = desc->supervision_timeout;
+
+	tester_send(BTP_SERVICE_ID_GAP, GAP_EV_CONN_PARAM_UPDATE,
+		    CONTROLLER_INDEX, (u8_t *) &ev, sizeof(ev));
+}
+
 static void print_bytes(const uint8_t *bytes, int len)
 {
 	int i;
@@ -1004,6 +1024,30 @@ static int gap_event_cb(struct ble_gap_event *event, void *arg)
 		rc = ble_store_util_delete_peer(&desc.peer_id_addr);
 		assert(rc == 0);
 		return BLE_GAP_REPEAT_PAIRING_RETRY;
+	case BLE_GAP_EVENT_CONN_UPDATE:
+		console_printf("connection update event; status=%d ",
+			       event->conn_update.status);
+			rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
+			assert(rc == 0);
+			print_conn_desc(&desc);
+			le_conn_param_update(&desc);
+		break;
+	case BLE_GAP_EVENT_CONN_UPDATE_REQ:
+		console_printf("connection update request event; "
+			       "conn_handle=%d itvl_min=%d itvl_max=%d "
+			       "latency=%d supervision_timoeut=%d "
+			       "min_ce_len=%d max_ce_len=%d\n",
+			       event->conn_update_req.conn_handle,
+			       event->conn_update_req.peer_params->itvl_min,
+			       event->conn_update_req.peer_params->itvl_max,
+			       event->conn_update_req.peer_params->latency,
+			       event->conn_update_req.peer_params->supervision_timeout,
+			       event->conn_update_req.peer_params->min_ce_len,
+			       event->conn_update_req.peer_params->max_ce_len);
+
+		*event->conn_update_req.self_params =
+			*event->conn_update_req.peer_params;
+		break;
 	default:
 		break;
 	}
@@ -1210,6 +1254,97 @@ rsp:
 		   status);
 }
 
+static void conn_param_update_cb(uint16_t conn_handle, int status, void *arg)
+{
+	u8_t btp_status;
+
+	console_printf("conn param update complete; conn_handle=%d status=%d\n",
+		       conn_handle, status);
+
+	btp_status = status ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
+
+	tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE,
+		   CONTROLLER_INDEX, btp_status);
+}
+
+static int conn_param_update_slave(u16_t conn_handle,
+				   const struct gap_conn_param_update_cmd *cmd)
+{
+	int rc;
+	struct ble_l2cap_sig_update_params params;
+
+	params.itvl_min = cmd->conn_itvl_min;
+	params.itvl_max = cmd->conn_itvl_max;
+	params.slave_latency = cmd->conn_latency;
+	params.timeout_multiplier = cmd->supervision_timeout;
+
+	rc = ble_l2cap_sig_update(conn_handle, &params,
+				  conn_param_update_cb, NULL);
+	if (rc) {
+		tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE,
+			   CONTROLLER_INDEX, BTP_STATUS_FAILED);
+	}
+
+	return 0;
+}
+
+static int conn_param_update_master(u16_t conn_handle,
+				    const struct gap_conn_param_update_cmd *cmd)
+{
+	int rc;
+	struct ble_gap_upd_params params;
+
+	params.itvl_min = cmd->conn_itvl_min;
+	params.itvl_max = cmd->conn_itvl_max;
+	params.latency = cmd->conn_latency;
+	params.supervision_timeout = cmd->supervision_timeout;
+	rc = ble_gap_update_params(conn_handle, &params);
+	if (rc) {
+		SYS_LOG_ERR("Failed to send update params: rc=%d", rc);
+	}
+
+	return rc;
+}
+
+static void conn_param_update(const u8_t *data, u16_t len)
+{
+	const struct gap_conn_param_update_cmd *cmd = (void *) data;
+	struct ble_gap_conn_desc desc;
+	u8_t status = BTP_STATUS_SUCCESS;
+	int rc;
+
+	SYS_LOG_DBG("");
+
+	rc = gap_conn_find_by_addr((ble_addr_t *)data, &desc);
+	if (rc) {
+		status = BTP_STATUS_FAILED;
+		goto rsp;
+	}
+
+	if ((desc.conn_itvl >= cmd->conn_itvl_min) &&
+	    (desc.conn_itvl <= cmd->conn_itvl_max) &&
+	    (desc.conn_latency == cmd->conn_latency) &&
+	    (desc.supervision_timeout == cmd->supervision_timeout)) {
+		goto rsp;
+	}
+
+	if (desc.role == BLE_GAP_ROLE_MASTER) {
+		rc = conn_param_update_master(desc.conn_handle, cmd);
+	} else {
+		rc = conn_param_update_slave(desc.conn_handle, cmd);
+		if (!rc) {
+			/* Response will be sent from callback */
+			return;
+		}
+	}
+
+	status = rc ? BTP_STATUS_FAILED : BTP_STATUS_SUCCESS;
+
+rsp:
+	tester_rsp(BTP_SERVICE_ID_GAP, GAP_CONN_PARAM_UPDATE, CONTROLLER_INDEX,
+		   status);
+}
+
 void tester_handle_gap(u8_t opcode, u8_t index, u8_t *data,
 		       u16_t len)
 {
@@ -1280,6 +1415,9 @@ void tester_handle_gap(u8_t opcode, u8_t index, u8_t *data,
 	case GAP_PASSKEY_CONFIRM:
 		passkey_confirm(data, len);
 		return;
+	case GAP_CONN_PARAM_UPDATE:
+		conn_param_update(data, len);
+		return;
 	default:
 		tester_rsp(BTP_SERVICE_ID_GAP, opcode, index,
 			   BTP_STATUS_UNKNOWN_CMD);