Merge branch 'master' into bluetooth5_master

Conflicts:
	hw/bsp/bbc_microbit/syscfg.yml
	net/nimble/transport/socket/syscfg.yml

X-Original-Commit: 5a4fa1202415c3705f477a80114ae1217e94c120
This commit is contained in:
Szymon Janc
2017-07-10 11:55:58 +02:00
11 changed files with 178 additions and 301 deletions
+2
View File
@@ -283,6 +283,8 @@ int ble_store_iterate(int obj_type,
ble_store_iterator_fn *callback,
void *cookie);
int ble_store_clear(void);
/*** Utility functions. */
int ble_store_util_bonded_peers(ble_addr_t *out_peer_id_addrs,
@@ -1,52 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#ifndef H_BLE_SVC_LLS_
#define H_BLE_SVC_LLS_
#ifdef __cplusplus
extern "C" {
#endif
struct ble_hs_cfg;
#define BLE_SVC_LLS_UUID16 0x1803
#define BLE_SVC_LLS_CHR_UUID16_ALERT_LEVEL 0x2a06
/* Alert level definitions */
#define BLE_SVC_LLS_ALERT_LEVEL_NO_ALERT 0
#define BLE_SVC_LLS_ALERT_LEVEL_MILD_ALERT 1
#define BLE_SVC_LLS_ALERT_LEVEL_HIGH_ALERT 2
typedef int ble_svc_lls_event_fn(uint8_t alert_level);
uint8_t ble_svc_lls_alert_level_get(void);
int ble_svc_lls_alert_level_set(uint8_t alert_level);
void ble_svc_lls_on_gap_disconnect(int reason);
int ble_svc_lls_init(struct ble_hs_cfg *cfg,
uint8_t initial_alert_level,
ble_svc_lls_event_fn *cb);
#ifdef __cplusplus
}
#endif
#endif
-31
View File
@@ -1,31 +0,0 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
pkg.name: net/nimble/host/profiles/lls
pkg.description: Link Loss Service adopted specification.
pkg.author: "Apache Mynewt <[email protected]>"
pkg.homepage: "http://mynewt.apache.org/"
pkg.keywords:
- ble
- bluetooth
- lls
- nimble
pkg.deps:
- net/nimble/host
-201
View File
@@ -1,201 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include <assert.h>
#include <string.h>
#include "host/ble_hs.h"
#include "profiles/lls/ble_svc_lls.h"
/* Callback function */
static ble_svc_lls_event_fn *cb_fn;
/* Alert level */
static uint8_t ble_svc_lls_alert_level;
/* Write characteristic function */
static int
ble_svc_lls_chr_write(struct os_mbuf *om, uint16_t min_len,
uint16_t max_len, void *dst,
uint16_t *len);
/* Access function */
static int
ble_svc_lls_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
static const struct ble_gatt_svc_def ble_svc_lls_defs[] = {
{
/*** Service: Link Loss Service (LLS). */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = BLE_UUID16(BLE_SVC_LLS_UUID16),
.characteristics = (struct ble_gatt_chr_def[]) { {
/*** Characteristic: Alert Level. */
.uuid = BLE_UUID16(BLE_SVC_LLS_CHR_UUID16_ALERT_LEVEL),
.access_cb = ble_svc_lls_access,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
}, {
0, /* No more characteristics in this service. */
} },
},
{
0, /* No more services. */
},
};
/**
* Writes the received value from a characteristic write to
* the given destination.
*/
static int
ble_svc_lls_chr_write(struct os_mbuf *om, uint16_t min_len,
uint16_t max_len, void *dst,
uint16_t *len)
{
uint16_t om_len;
int rc;
om_len = OS_MBUF_PKTLEN(om);
if (om_len < min_len || om_len > max_len) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
if (rc != 0) {
return BLE_ATT_ERR_UNLIKELY;
}
return 0;
}
/**
* Simple read/write access callback for the alert level
* characteristic.
*/
static int
ble_svc_lls_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
assert(ctxt->chr == &ble_svc_lls_defs[0].characteristics[0]);
int rc;
switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_READ_CHR:
rc = os_mbuf_append(ctxt->om, &ble_svc_lls_alert_level,
sizeof ble_svc_lls_alert_level);
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
case BLE_GATT_ACCESS_OP_WRITE_CHR:
rc = ble_svc_lls_chr_write(ctxt->om,
sizeof ble_svc_lls_alert_level,
sizeof ble_svc_lls_alert_level,
&ble_svc_lls_alert_level, NULL);
return rc;
default:
assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
return 0;
}
/**
* This function is the crux of the link loss service. The application
* developer must call this function inside the gap event callback
* function when a BLE_GAP_EVENT_DISCONNECT event is received and
* pass the disconnect reason into this function.
*
* Here, we then check if the disconnect reason is due to a timout, and if
* so, we call the ble_svc_lls_event_fn callback with the current
* alert level. The actual alert implementation is left up to the
* developer.
*
* @param reason The reason attatched to the GAP disconnect
* event.
*/
void
ble_svc_lls_on_gap_disconnect(int reason)
{
if (reason == BLE_HS_HCI_ERR(BLE_ERR_CONN_SPVN_TMO)) {
cb_fn(ble_svc_lls_alert_level);
}
}
/**
* Gets the current alert level.
*
* @return The current alert level
*/
uint8_t
ble_svc_lls_alert_level_get(void)
{
return ble_svc_lls_alert_level;
}
/**
* Sets the current alert level.
*
* @return 0 on success, BLE_HS_EINVAL if the given alert level is not valid.
*/
int
ble_svc_lls_alert_level_set(uint8_t alert_level)
{
if (alert_level > BLE_SVC_LLS_ALERT_LEVEL_HIGH_ALERT) {
return BLE_HS_EINVAL;
}
memcpy(&ble_svc_lls_alert_level, &alert_level,
sizeof alert_level);
return 0;
}
/**
* Initialize the LLS. The developer must specify the event function
* callback for the LLS to function properly.
*
* @param initial_alert_level The initial alert value to set
* @param cb The callback function to call when
* connection has been lost due to
* link loss
*/
int
ble_svc_lls_init(struct ble_hs_cfg *cfg, uint8_t initial_alert_level,
ble_svc_lls_event_fn *cb)
{
int rc;
if (!cb) {
return BLE_HS_EINVAL;
}
ble_svc_lls_alert_level = initial_alert_level;
cb_fn = cb;
rc = ble_gatts_count_cfg(ble_svc_lls_defs, cfg);
if (rc != 0) {
return rc;
}
rc = ble_gatts_add_svcs(ble_svc_lls_defs);
if (rc != 0) {
return rc;
}
return 0;
}
+14 -5
View File
@@ -1573,17 +1573,26 @@ ble_sm_pair_cfg(struct ble_sm_proc *proc)
proc->flags |= BLE_SM_PROC_F_SC;
}
ble_sm_key_dist(proc, &init_key_dist, &resp_key_dist);
if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
rx_key_dist = resp_key_dist;
} else {
rx_key_dist = init_key_dist;
}
if (pair_req->authreq & BLE_SM_PAIR_AUTHREQ_BOND &&
pair_rsp->authreq & BLE_SM_PAIR_AUTHREQ_BOND) {
proc->flags |= BLE_SM_PROC_F_BONDING;
}
ble_sm_key_dist(proc, &init_key_dist, &resp_key_dist);
if (proc->flags & BLE_SM_PROC_F_INITIATOR) {
rx_key_dist = resp_key_dist;
} else {
rx_key_dist = init_key_dist;
/* In legacy mode, bonding requires the exchange of keys. If no key
* exchange was specified, pretend bonding is not enabled.
*/
if (!(proc->flags & BLE_SM_PROC_F_SC) &&
(init_key_dist == 0 || resp_key_dist == 0)) {
proc->flags &= ~BLE_SM_PROC_F_BONDING;
}
proc->rx_key_flags = 0;
+37
View File
@@ -381,3 +381,40 @@ ble_store_iterate(int obj_type,
idx++;
}
}
/**
* Deletes all objects from the BLE host store.
*
* @return 0 on success; nonzero on failure.
*/
int
ble_store_clear(void)
{
const uint8_t obj_types[] = {
BLE_STORE_OBJ_TYPE_OUR_SEC,
BLE_STORE_OBJ_TYPE_PEER_SEC,
BLE_STORE_OBJ_TYPE_CCCD,
};
union ble_store_key key;
int obj_type;
int rc;
int i;
/* A zeroed key will always retrieve the first value. */
memset(&key, 0, sizeof key);
for (i = 0; i < sizeof obj_types / sizeof obj_types[0]; i++) {
obj_type = obj_types[i];
do {
rc = ble_store_delete(obj_type, &key);
} while (rc == 0);
/* BLE_HS_ENOENT means we deleted everything. */
if (rc != BLE_HS_ENOENT) {
return rc;
}
}
return 0;
}
+2 -4
View File
@@ -17,6 +17,7 @@
* under the License.
*/
#include "sysinit/sysinit.h"
#include "syscfg/syscfg.h"
#include "os/os.h"
#include "nimble/hci_common.h"
@@ -29,10 +30,7 @@
int
main(int argc, char **argv)
{
ts_config.ts_print_results = 1;
tu_parse_args(argc, argv);
tu_init();
sysinit();
ble_att_clt_test_all();
ble_att_svr_test_all();
+2 -1
View File
@@ -19,6 +19,7 @@
#include <string.h>
#include <errno.h>
#include "sysinit/sysinit.h"
#include "stats/stats.h"
#include "testutil/testutil.h"
#include "nimble/ble.h"
@@ -2394,7 +2395,7 @@ ble_hs_test_util_store_delete(int obj_type, const union ble_store_key *key)
void
ble_hs_test_util_init_no_start(void)
{
tu_init();
sysinit();
os_eventq_init(&ble_hs_test_util_evq);
STAILQ_INIT(&ble_hs_test_util_prev_tx_queue);
+83
View File
@@ -113,6 +113,18 @@ ble_store_test_util_overflow_sec(int is_our_sec)
}
}
static int
ble_store_test_util_count(int obj_type)
{
int count;
int rc;
rc = ble_store_util_count(obj_type, &count);
TEST_ASSERT_FATAL(rc == 0);
return count;
}
TEST_CASE(ble_store_test_peers)
{
struct ble_store_value_sec secs[3] = {
@@ -333,6 +345,76 @@ TEST_CASE(ble_store_test_overflow)
ble_store_test_util_overflow_sec(1);
}
TEST_CASE(ble_store_test_clear)
{
const struct ble_store_value_sec secs[2] = {
{
.peer_addr = { BLE_ADDR_PUBLIC, { 1, 2, 3, 4, 5, 6 } },
.ltk_present = 1,
},
{
/* Address value is a duplicate of above, but type differs. */
.peer_addr = { BLE_ADDR_RANDOM, { 1, 2, 3, 4, 5, 6 } },
.ltk_present = 1,
},
};
const struct ble_store_value_cccd cccds[3] = {
/* First two belong to first peer. */
{
.peer_addr = secs[0].peer_addr,
.chr_val_handle = 5,
},
{
.peer_addr = secs[0].peer_addr,
.chr_val_handle = 8,
},
/* Last belongs to second peer. */
{
.peer_addr = secs[1].peer_addr,
.chr_val_handle = 5,
},
};
int rc;
int i;
ble_hs_test_util_init();
for (i = 0; i < sizeof secs / sizeof secs[0]; i++) {
rc = ble_store_write_our_sec(secs + i);
TEST_ASSERT_FATAL(rc == 0);
rc = ble_store_write_peer_sec(secs + i);
TEST_ASSERT_FATAL(rc == 0);
}
for (i = 0; i < sizeof cccds / sizeof cccds[0]; i++) {
rc = ble_store_write_cccd(cccds + i);
TEST_ASSERT_FATAL(rc == 0);
}
/* Sanity check. */
TEST_ASSERT_FATAL(
ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 2);
TEST_ASSERT_FATAL(
ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 2);
TEST_ASSERT_FATAL(
ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 3);
/* Ensure store is empty after clear gets called. */
rc = ble_store_clear();
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);
/* Ensure second clear succeeds with no effect. */
rc = ble_store_clear();
TEST_ASSERT_FATAL(rc == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_OUR_SEC) == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_PEER_SEC) == 0);
TEST_ASSERT(ble_store_test_util_count(BLE_STORE_OBJ_TYPE_CCCD) == 0);
}
TEST_SUITE(ble_store_suite)
{
tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
@@ -341,6 +423,7 @@ TEST_SUITE(ble_store_suite)
ble_store_test_delete_peer();
ble_store_test_count();
ble_store_test_overflow();
ble_store_test_clear();
}
int
+30 -7
View File
@@ -43,6 +43,7 @@
#include <sys/uio.h>
#include <unistd.h>
#include <sys/socket.h>
#include "os/os.h"
#if MYNEWT_VAL(BLE_SOCK_USE_TCP)
#include <sys/errno.h>
@@ -139,6 +140,11 @@ STATS_NAME_END(hci_sock_stats)
#define BLE_HCI_UART_H4_SKIP_CMD 0x81
#define BLE_HCI_UART_H4_SKIP_ACL 0x82
#define BLE_SOCK_STACK_SIZE \
OS_STACK_ALIGN(MYNEWT_VAL(BLE_SOCK_STACK_SIZE))
struct os_task ble_sock_task;
static struct os_mempool ble_hci_sock_evt_hi_pool;
static void *ble_hci_sock_evt_hi_buf;
static struct os_mempool ble_hci_sock_evt_lo_pool;
@@ -158,7 +164,7 @@ static void *ble_hci_sock_rx_acl_arg;
static struct ble_hci_sock_state {
int sock;
struct os_eventq *evq;
struct os_eventq evq;
struct os_event ev;
struct os_callout timer;
@@ -399,7 +405,7 @@ ble_hci_sock_rx_ev(struct os_event *ev)
rc = ble_hci_sock_rx_msg();
if (rc == 0) {
os_eventq_put(ble_hci_sock_state.evq, &ble_hci_sock_state.ev);
os_eventq_put(&ble_hci_sock_state.evq, &ble_hci_sock_state.ev);
} else {
os_callout_reset(&ble_hci_sock_state.timer, OS_TICKS_PER_SEC / 100);
}
@@ -712,12 +718,29 @@ ble_hci_trans_reset(void)
return 0;
}
void
ble_hci_sock_set_evq(struct os_eventq *evq)
static void
ble_hci_sock_ack_handler(void *arg)
{
ble_hci_sock_state.evq = evq;
while (1) {
os_eventq_run(&ble_hci_sock_state.evq);
}
}
static void
ble_hci_sock_init_task(void)
{
os_stack_t *pstack;
pstack = malloc(sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE);
assert(pstack);
os_task_init(&ble_sock_task, "sock", ble_hci_sock_ack_handler, NULL,
MYNEWT_VAL(BLE_SOCK_TASK_PRIO), OS_WAIT_FOREVER, pstack,
BLE_SOCK_STACK_SIZE);
os_eventq_init(&ble_hci_sock_state.evq);
os_callout_stop(&ble_hci_sock_state.timer);
os_callout_init(&ble_hci_sock_state.timer, ble_hci_sock_state.evq,
os_callout_init(&ble_hci_sock_state.timer, &ble_hci_sock_state.evq,
ble_hci_sock_rx_ev, NULL);
}
@@ -740,7 +763,7 @@ ble_hci_sock_init(void)
memset(&ble_hci_sock_state, 0, sizeof(ble_hci_sock_state));
ble_hci_sock_state.sock = -1;
ble_hci_sock_set_evq(os_eventq_dflt_get());
ble_hci_sock_init_task();
ble_hci_sock_state.ev.ev_cb = ble_hci_sock_rx_ev;
/*
+8
View File
@@ -64,5 +64,13 @@ syscfg.defs:
description: 'linux kernel device'
value: 0
BLE_SOCK_TASK_PRIO:
description: 'Priority of the HCI socket task.'
value: 9
BLE_SOCK_STACK_SIZE:
description: 'Size of the HCI socket stack (units=words).'
value: 80
syscfg.vals.BLE_EXT_ADV:
BLE_HCI_EVT_BUF_SIZE: 274