示例#1
0
文件: conn.c 项目: sunkaizhu/zephyr
void on_nble_gap_connect_evt(const struct nble_gap_connect_evt *ev)
{
	struct bt_conn *conn;

	BT_DBG("handle %u role %u", ev->conn_handle, ev->role_slave);

	conn = conn_get(&ev->peer_bda);
	if (!conn) {
		BT_ERR("Unable to get bt_conn object");
		return;
	}

	conn->handle = ev->conn_handle;
	conn->role = ev->role_slave ? BT_CONN_ROLE_SLAVE : BT_CONN_ROLE_MASTER;
	conn->interval = ev->conn_values.interval;
	conn->latency = ev->conn_values.latency;
	conn->timeout = ev->conn_values.supervision_to;
	bt_addr_le_copy(&conn->dst, &ev->peer_bda);
	k_delayed_work_init(&conn->update_work, le_conn_update);

	conn->state = BT_CONN_CONNECTED;

	notify_connected(conn);

	/*
	 * Core 4.2 Vol 3, Part C, 9.3.12.2
	 * The Peripheral device should not perform a Connection Parameter
	 * Update procedure within 5 s after establishing a connection.
	 */
	k_delayed_work_submit(&conn->update_work,
			      conn->role == BT_HCI_ROLE_MASTER ? K_NO_WAIT :
			      CONN_UPDATE_TIMEOUT);
}
示例#2
0
文件: keys.c 项目: wosayttn/aos
struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr)
{
	struct bt_keys *keys;
	int i;

	BT_DBG("%s", bt_addr_le_str(addr));

	for (i = 0; i < ARRAY_SIZE(key_pool); i++) {
		keys = &key_pool[i];

		if (!bt_addr_le_cmp(&keys->addr, addr)) {
			return keys;
		}

		if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) {
			bt_addr_le_copy(&keys->addr, addr);
			BT_DBG("created %p for %s", keys, bt_addr_le_str(addr));
			return keys;
		}
	}

	BT_DBG("unable to create keys for %s", bt_addr_le_str(addr));

	return NULL;
}
示例#3
0
文件: gap.c 项目: 32bitmicro/zephyr
static void clear_bonds(const bt_addr_le_t *addr)
{
	struct nble_sm_clear_bonds_req params = { { 0 }, };

	bt_addr_le_copy(&params.addr, addr);

	nble_sm_clear_bonds_req(&params);
}
示例#4
0
文件: conn.c 项目: 32bitmicro/zephyr
struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer,
				  const struct bt_le_conn_param *param)
{
	struct nble_gap_connect_req req;
	struct bt_conn *conn;

	BT_DBG("");

	if (!bt_le_conn_params_valid(param->interval_min, param->interval_max,
				     param->latency, param->timeout)) {
		return NULL;
	}

	conn = bt_conn_lookup_addr_le(peer);
	if (conn) {
		return conn;
	}

	conn = conn_new();
	if (!conn) {
		BT_ERR("Unable to create new bt_conn object");
		return NULL;
	}

	/* Update connection parameters */
	bt_addr_le_copy(&conn->dst, peer);
	conn->latency = param->latency;
	conn->timeout = param->timeout;

	/* Construct parameters to NBLE */
	bt_addr_le_copy(&req.bda, peer);

	req.conn_params.interval_min = param->interval_min;
	req.conn_params.interval_max = param->interval_max;
	req.conn_params.slave_latency = param->latency;
	req.conn_params.link_sup_to = param->timeout;

	req.scan_params.interval = BT_GAP_SCAN_FAST_INTERVAL;
	req.scan_params.window = BT_GAP_SCAN_FAST_WINDOW;

	conn->state = BT_CONN_CONNECT;

	nble_gap_connect_req(&req, conn);

	return conn;
}
示例#5
0
文件: gap.c 项目: 32bitmicro/zephyr
void on_nble_get_bda_rsp(const struct nble_get_bda_rsp *rsp)
{
	bt_addr_le_copy(&nble.addr, &rsp->bda);

	BT_DBG("Local bdaddr: %s", bt_addr_le_str(&nble.addr));

	nble_get_version_req(NULL);
}
示例#6
0
文件: gatt.c 项目: PchZhang/testgit
int bt_gatt_attr_write_ccc(struct bt_conn *conn,
			   const struct bt_gatt_attr *attr, const void *buf,
			   uint16_t len, uint16_t offset)
{
	struct _bt_gatt_ccc *ccc = attr->user_data;
	const uint16_t *data = buf;
	bool bonded;
	size_t i;

	if (offset > sizeof(*data)) {
		return -EINVAL;
	}

	if (offset + len > sizeof(*data)) {
		return -EFBIG;
	}

	if (bt_keys_find_addr(&conn->le.dst))
		bonded = true;
	else
		bonded = false;

	for (i = 0; i < ccc->cfg_len; i++) {
		/* Check for existing configuration */
		if (!bt_addr_le_cmp(&ccc->cfg[i].peer, &conn->le.dst)) {
			break;
		}
	}

	if (i == ccc->cfg_len) {
		for (i = 0; i < ccc->cfg_len; i++) {
			/* Check for unused configuration */
			if (!ccc->cfg[i].valid) {
				bt_addr_le_copy(&ccc->cfg[i].peer, &conn->le.dst);
				/* Only set valid if bonded */
				ccc->cfg[i].valid = bonded;
				break;
			}
		}

		if (i == ccc->cfg_len) {
			BT_WARN("No space to store CCC cfg");
			return -ENOMEM;
		}
	}

	ccc->cfg[i].value = sys_le16_to_cpu(*data);

	BT_DBG("handle 0x%04x value %u", attr->handle, ccc->cfg[i].value);

	/* Update cfg if don't match */
	if (ccc->cfg[i].value != ccc->value) {
		gatt_ccc_changed(ccc);
	}

	return len;
}
示例#7
0
文件: gatt.c 项目: PchZhang/testgit
static void gatt_subscription_add(struct bt_conn *conn,
				  struct bt_gatt_subscribe_params *params)
{
	bt_addr_le_copy(&params->_peer, &conn->le.dst);

	/* Prepend subscription */
	params->_next = subscriptions;
	subscriptions = params;
}
示例#8
0
文件: main.c 项目: lwehmeier/zephyr
static ssize_t storage_write(const bt_addr_le_t *addr, uint16_t key,
			     const void *data, size_t length)
{
	if (addr) {
		return -ENOENT;
	}

	if (key == BT_STORAGE_ID_ADDR && length == sizeof(id_addr)) {
		bt_addr_le_copy(&id_addr, data);
		return sizeof(id_addr);
	}

	return -EIO;
}
示例#9
0
文件: main.c 项目: lwehmeier/zephyr
static ssize_t storage_read(const bt_addr_le_t *addr, uint16_t key, void *data,
			    size_t length)
{
	if (addr) {
		return -ENOENT;
	}

	if (key == BT_STORAGE_ID_ADDR && length == sizeof(id_addr) &&
	    bt_addr_le_cmp(&id_addr, BT_ADDR_LE_ANY)) {
		bt_addr_le_copy(data, &id_addr);
		return sizeof(id_addr);
	}

	return -EIO;
}
bool BLECharacteristicImp::subscribe(void)
{
    int retval = 0;
    bt_conn_t* conn = NULL;
    
    if (true == BLEUtils::isLocalBLE(_ble_device))
    {
        // GATT server can't subscribe
        return false;
    }
    
    if (_gatt_chrc.properties & BT_GATT_CHRC_NOTIFY)
    {
        _sub_params.value |= BT_GATT_CCC_NOTIFY;
    }
    
    if (_gatt_chrc.properties & BT_GATT_CHRC_INDICATE)
    {
        _sub_params.value |= BT_GATT_CCC_INDICATE;
    }
    
    if (_sub_params.value == 0)
    {
        return false;
    }
    
    conn = bt_conn_lookup_addr_le(_ble_device.bt_le_address());
    if (NULL == conn)
    {
        return false;
    }
    
    bt_addr_le_copy(&_sub_params._peer, bt_conn_get_dst(conn));
    _sub_params.ccc_handle = _cccd_handle;
    _sub_params.value_handle = _value_handle;
    
    // Enable CCCD to allow peripheral send Notification/Indication
    retval = bt_gatt_subscribe(conn, &_sub_params);
    bt_conn_unref(conn);
    if (0 == retval)
    {
        _subscribed = true;
    }
    return _subscribed;
}
示例#11
0
文件: conn.c 项目: 32bitmicro/zephyr
struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer)
{
	struct bt_conn *conn = conn_new();

	if (!conn) {
		return NULL;
	}

	bt_addr_le_copy(&conn->le.dst, peer);
#if defined(CONFIG_BLUETOOTH_SMP)
	conn->sec_level = BT_SECURITY_LOW;
	conn->required_sec_level = BT_SECURITY_LOW;
#endif /* CONFIG_BLUETOOTH_SMP */
	conn->type = BT_CONN_TYPE_LE;
	conn->le.interval_min = BT_GAP_INIT_CONN_INT_MIN;
	conn->le.interval_max = BT_GAP_INIT_CONN_INT_MAX;

	return conn;
}
示例#12
0
文件: conn.c 项目: 32bitmicro/zephyr
void on_nble_gap_connect_evt(const struct nble_gap_connect_evt *ev)
{
	struct bt_conn *conn;

	BT_DBG("handle %u role %u", ev->conn_handle, ev->role_slave);

	conn = conn_new();
	if (!conn) {
		BT_ERR("Unable to create new bt_conn object");
		return;
	}

	conn->handle = ev->conn_handle;
	conn->role = ev->role_slave;
	conn->interval = ev->conn_values.interval;
	conn->latency = ev->conn_values.latency;
	conn->timeout = ev->conn_values.supervision_to;
	bt_addr_le_copy(&conn->dst, &ev->peer_bda);

	conn->state = BT_CONN_CONNECTED;

	notify_connected(conn);
}
示例#13
0
void on_nble_gap_connect_evt(const struct nble_gap_connect_evt *evt)
{
	struct bt_conn *conn;

	/* Make lookup to check if there's a connection object in CONNECT state
	 * associated with passed peer LE address.
	 */
	conn = bt_conn_lookup_state_le(&evt->peer_bda, BT_CONN_CONNECT);

#if 0
	/* Nordic has no connection error */
	if (evt->status) {
		if (!conn) {
			return;
		}

		conn->err = BT_HCI_ERR_UNACCEPT_CONN_PARAMS;
		bt_conn_set_state(conn, BT_CONN_DISCONNECTED);

		/* Drop the reference got by lookup call in CONNECT state.
		 * We are now in DISCONNECTED state since no successful LE
		 * link been made.
		 */
		bt_conn_unref(conn);

		return;
	}
#endif
	/*
	 * clear advertising even if we are not able to add connection object
	 * to keep host in sync with controller state
	 */
	if (evt->role_slave == BT_CONN_ROLE_SLAVE) {
		atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING);
	}

	if (!conn) {
		conn = bt_conn_add_le(&evt->peer_bda);
	}

	if (!conn) {
		BT_DBG("Unable to add new conn for handle %u",
		       evt->conn_handle);
		return;
	}

	conn->handle = evt->conn_handle;
	bt_addr_le_copy(&conn->le.dst, &evt->peer_bda);
	conn->le.interval = evt->conn_values.interval;
	conn->le.latency = evt->conn_values.latency;
	conn->le.timeout = evt->conn_values.supervision_to;
	conn->role = evt->role_slave;

#if 0
	src.type = BT_ADDR_LE_PUBLIC;
	memcpy(src.val, bt_dev.bdaddr.val, sizeof(bt_dev.bdaddr.val));

	/* use connection address (instead of identity address) as initiator
	 * or responder address
	 */
	if (conn->role == BT_HCI_ROLE_MASTER) {
		bt_addr_le_copy(&conn->le.init_addr, &src);
		bt_addr_le_copy(&conn->le.resp_addr, &evt->peer_addr);
	} else {
		bt_addr_le_copy(&conn->le.init_addr, &evt->peer_addr);
		bt_addr_le_copy(&conn->le.resp_addr, &src);
	}
#endif
	bt_conn_set_state(conn, BT_CONN_CONNECTED);

	/* Note: Connection update removed because Windows interop and BT spec recommendations */

	bt_conn_unref(conn);
#if 0
	bt_le_scan_update(false);
#endif

}