mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-08-11 04:27:58 +00:00
nimble/host: Initial EATT support
The idea for EATT in Mynewt is as follow. EATT is not exposed to the user i.e. GATT API stays the same. User can define number of EATT channels supported by the host and it is host managing those channels. EATT will be fist choice channel for every ATT operation. In the future we can make it smarted and make a choice based on the ATT data in the packet TODO: * handle reading and setting client/server Supported features in the stack instead of eatt code * add test API to choose channel to use (needed by PTS)
This commit is contained in:
committed by
Krzysztof Kopyściński
parent
86c77a41df
commit
133cafdac2
@@ -41,6 +41,9 @@ pkg.deps.BLE_SM_SC:
|
||||
pkg.deps.BLE_MESH:
|
||||
- nimble/host/mesh
|
||||
|
||||
pkg.deps.BLE_EATT_CHAN_NUM:
|
||||
- nimble/host/services/gatt
|
||||
|
||||
pkg.req_apis:
|
||||
- ble_transport
|
||||
- console
|
||||
|
||||
@@ -28,8 +28,11 @@ extern "C" {
|
||||
|
||||
struct ble_hs_cfg;
|
||||
|
||||
#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05
|
||||
#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05
|
||||
#define BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16 0x2b3a
|
||||
#define BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16 0x2b29
|
||||
|
||||
uint8_t ble_svc_gatt_get_local_cl_supported_feat(void);
|
||||
void ble_svc_gatt_changed(uint16_t start_handle, uint16_t end_handle);
|
||||
void ble_svc_gatt_init(void);
|
||||
|
||||
|
||||
@@ -27,23 +27,55 @@ static uint16_t ble_svc_gatt_changed_val_handle;
|
||||
static uint16_t ble_svc_gatt_start_handle;
|
||||
static uint16_t ble_svc_gatt_end_handle;
|
||||
|
||||
/* Server supported features */
|
||||
#define BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT (0x00)
|
||||
|
||||
/* Client supported features */
|
||||
#define BLE_SVC_GATT_CLI_SUP_FEAT_ROBUST_CATCHING_BIT (0x00)
|
||||
#define BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT (0x01)
|
||||
#define BLE_SVC_GATT_CLI_SUP_FEAT_MULT_NTF_BIT (0x02)
|
||||
|
||||
static uint8_t ble_svc_gatt_srv_sup_feat = 0;
|
||||
static uint8_t ble_svc_gatt_cl_sup_feat = 0;
|
||||
|
||||
static int
|
||||
ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
static int
|
||||
ble_svc_gatt_srv_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg);
|
||||
|
||||
static int
|
||||
ble_svc_gatt_cl_sup_feat_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_gatt_defs[] = {
|
||||
{
|
||||
/*** Service: GATT */
|
||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_GATT_SVC_UUID16),
|
||||
.characteristics = (struct ble_gatt_chr_def[]) { {
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16),
|
||||
.access_cb = ble_svc_gatt_access,
|
||||
.val_handle = &ble_svc_gatt_changed_val_handle,
|
||||
.flags = BLE_GATT_CHR_F_INDICATE,
|
||||
}, {
|
||||
0, /* No more characteristics in this service. */
|
||||
} },
|
||||
.characteristics = (struct ble_gatt_chr_def[]) {
|
||||
{
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16),
|
||||
.access_cb = ble_svc_gatt_access,
|
||||
.val_handle = &ble_svc_gatt_changed_val_handle,
|
||||
.flags = BLE_GATT_CHR_F_INDICATE,
|
||||
},
|
||||
{
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16),
|
||||
.access_cb = ble_svc_gatt_srv_sup_feat_access,
|
||||
.flags = BLE_GATT_CHR_F_READ,
|
||||
},
|
||||
{
|
||||
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16),
|
||||
.access_cb = ble_svc_gatt_cl_sup_feat_access,
|
||||
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
|
||||
},
|
||||
{
|
||||
0, /* No more characteristics in this service. */
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
@@ -51,6 +83,34 @@ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static int
|
||||
ble_svc_gatt_srv_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
if (ctxt->op != BLE_GATT_ACCESS_OP_READ_CHR) {
|
||||
return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
|
||||
}
|
||||
|
||||
os_mbuf_append(ctxt->om, &ble_svc_gatt_srv_sup_feat, sizeof(ble_svc_gatt_srv_sup_feat));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
{
|
||||
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
|
||||
/* TODO For now just send 1*/
|
||||
uint8_t eatt_supported = 2;
|
||||
os_mbuf_append(ctxt->om, &eatt_supported, sizeof(eatt_supported));
|
||||
return 0;
|
||||
}
|
||||
/* TODO For write just return OK */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
struct ble_gatt_access_ctxt *ctxt, void *arg)
|
||||
@@ -77,6 +137,12 @@ ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
ble_svc_gatt_get_local_cl_supported_feat(void)
|
||||
{
|
||||
return ble_svc_gatt_cl_sup_feat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates a change in attribute assignment to all subscribed peers.
|
||||
* Unconnected bonded peers receive an indication when they next connect.
|
||||
@@ -105,4 +171,12 @@ ble_svc_gatt_init(void)
|
||||
|
||||
rc = ble_gatts_add_svcs(ble_svc_gatt_defs);
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) {
|
||||
ble_svc_gatt_srv_sup_feat |= (1 << BLE_SVC_GATT_SRV_SUP_FEAT_EATT_BIT);
|
||||
}
|
||||
|
||||
if (MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0) {
|
||||
ble_svc_gatt_cl_sup_feat |= (1 << BLE_SVC_GATT_CLI_SUP_FEAT_EATT_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
+40
-12
@@ -498,22 +498,31 @@ ble_att_rx_handle_unknown_request(uint8_t op, uint16_t conn_handle,
|
||||
*om = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_att_send_outstanding_after_response(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_hs_conn *conn;
|
||||
struct ble_l2cap_chan *chan;
|
||||
int rc;
|
||||
|
||||
ble_hs_lock();
|
||||
rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn,
|
||||
&chan);
|
||||
if (rc) {
|
||||
return;
|
||||
}
|
||||
conn->client_att_busy = false;
|
||||
ble_att_tx_with_conn(conn, chan, NULL);
|
||||
ble_hs_unlock();
|
||||
}
|
||||
|
||||
static int
|
||||
ble_att_rx(struct ble_l2cap_chan *chan)
|
||||
ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om)
|
||||
{
|
||||
const struct ble_att_rx_dispatch_entry *entry;
|
||||
uint8_t op;
|
||||
uint16_t conn_handle;
|
||||
struct os_mbuf **om;
|
||||
int rc;
|
||||
|
||||
conn_handle = ble_l2cap_get_conn_handle(chan);
|
||||
if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
|
||||
return BLE_HS_ENOTCONN;
|
||||
}
|
||||
|
||||
om = &chan->rx_buf;
|
||||
BLE_HS_DBG_ASSERT(*om != NULL);
|
||||
|
||||
rc = os_mbuf_copydata(*om, 0, 1, &op);
|
||||
@@ -521,9 +530,13 @@ ble_att_rx(struct ble_l2cap_chan *chan)
|
||||
return BLE_HS_EMSGSIZE;
|
||||
}
|
||||
|
||||
if (cid == BLE_L2CAP_CID_ATT && ble_att_is_response_op(op)) {
|
||||
ble_att_send_outstanding_after_response(conn_handle);
|
||||
}
|
||||
|
||||
entry = ble_att_rx_dispatch_entry_find(op);
|
||||
if (entry == NULL) {
|
||||
ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om);
|
||||
ble_att_rx_handle_unknown_request(op, conn_handle, cid, om);
|
||||
return BLE_HS_ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -532,10 +545,10 @@ ble_att_rx(struct ble_l2cap_chan *chan)
|
||||
/* Strip L2CAP ATT header from the front of the mbuf. */
|
||||
os_mbuf_adj(*om, 1);
|
||||
|
||||
rc = entry->bde_fn(conn_handle, chan->scid, om);
|
||||
rc = entry->bde_fn(conn_handle, cid, om);
|
||||
if (rc != 0) {
|
||||
if (rc == BLE_HS_ENOTSUP) {
|
||||
ble_att_rx_handle_unknown_request(op, conn_handle, chan->scid, om);
|
||||
ble_att_rx_handle_unknown_request(op, conn_handle, cid, om);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@@ -543,6 +556,19 @@ ble_att_rx(struct ble_l2cap_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_att_rx(struct ble_l2cap_chan *chan)
|
||||
{
|
||||
uint16_t conn_handle;
|
||||
|
||||
conn_handle = ble_l2cap_get_conn_handle(chan);
|
||||
if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
|
||||
return BLE_HS_ENOTCONN;
|
||||
}
|
||||
|
||||
return ble_att_rx_extended(conn_handle, chan->scid, &chan->rx_buf);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ble_att_preferred_mtu(void)
|
||||
{
|
||||
@@ -661,6 +687,8 @@ ble_att_init(void)
|
||||
return BLE_HS_EOS;
|
||||
}
|
||||
|
||||
ble_eatt_init(ble_att_rx_extended);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -911,8 +911,9 @@ ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
|
||||
req->banq_handle = htole16(handle);
|
||||
os_mbuf_concat(txom2, txom);
|
||||
|
||||
cid = BLE_L2CAP_CID_ATT;
|
||||
cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY);
|
||||
return ble_att_tx(conn_handle, cid, txom2);
|
||||
ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY);
|
||||
|
||||
err:
|
||||
os_mbuf_free_chain(txom);
|
||||
|
||||
@@ -66,16 +66,19 @@ ble_att_tx_with_conn(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, stru
|
||||
}
|
||||
omp = STAILQ_FIRST(&conn->att_tx_q);
|
||||
if (omp == NULL) {
|
||||
BLE_EATT_LOG_ERROR("%s: wakeup but nothing in the queue\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&conn->att_tx_q, omp_next);
|
||||
txom = OS_MBUF_PKTHDR_TO_MBUF(omp);
|
||||
BLE_EATT_LOG_DEBUG("%s: wakeup will send %p\n", __func__, txom);
|
||||
}
|
||||
|
||||
BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1);
|
||||
|
||||
if (ble_att_is_request_op(txom->om_data[0])) {
|
||||
if (conn->client_att_busy) {
|
||||
BLE_EATT_LOG_DEBUG("ATT Queue %p, client busy %d\n", txom, conn->client_att_busy);
|
||||
STAILQ_INSERT_TAIL(&conn->att_tx_q, OS_MBUF_PKTHDR(txom), omp_next);
|
||||
return 0;
|
||||
}
|
||||
@@ -97,6 +100,12 @@ ble_att_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom)
|
||||
struct ble_hs_conn *conn;
|
||||
int rc;
|
||||
|
||||
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
|
||||
if (cid != BLE_L2CAP_CID_ATT) {
|
||||
return ble_eatt_tx(conn_handle, cid, txom);
|
||||
}
|
||||
#endif
|
||||
|
||||
ble_hs_lock();
|
||||
rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_ATT, &conn,
|
||||
&chan);
|
||||
|
||||
@@ -625,10 +625,7 @@ static int
|
||||
ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_mbuf *om,
|
||||
uint8_t att_op, uint8_t err_status, uint16_t err_handle)
|
||||
{
|
||||
struct ble_l2cap_chan *chan;
|
||||
struct ble_hs_conn *conn;
|
||||
int do_tx;
|
||||
int rc;
|
||||
|
||||
if (hs_status != 0 && err_status == 0) {
|
||||
/* Processing failed, but err_status of 0 means don't send error. */
|
||||
@@ -638,28 +635,14 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, uint16_t cid, int hs_status, struct os_
|
||||
}
|
||||
|
||||
if (do_tx) {
|
||||
ble_hs_lock();
|
||||
|
||||
rc = ble_att_conn_chan_find(conn_handle, cid, &conn, &chan);
|
||||
if (rc != 0) {
|
||||
/* No longer connected. */
|
||||
hs_status = rc;
|
||||
} else {
|
||||
if (hs_status == 0) {
|
||||
BLE_HS_DBG_ASSERT(om != NULL);
|
||||
|
||||
ble_att_inc_tx_stat(om->om_data[0]);
|
||||
ble_att_truncate_to_mtu(chan, om);
|
||||
hs_status = ble_l2cap_tx(conn, chan, om);
|
||||
om = NULL;
|
||||
if (hs_status != 0) {
|
||||
err_status = BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
}
|
||||
if (hs_status == 0) {
|
||||
hs_status = ble_att_tx(conn_handle, cid, om);
|
||||
om = NULL;
|
||||
if (hs_status) {
|
||||
err_status = BLE_ATT_ERR_UNLIKELY;
|
||||
}
|
||||
}
|
||||
|
||||
ble_hs_unlock();
|
||||
|
||||
if (hs_status != 0) {
|
||||
STATS_INC(ble_att_stats, error_rsp_tx);
|
||||
|
||||
|
||||
@@ -0,0 +1,552 @@
|
||||
/*
|
||||
* 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 "syscfg/syscfg.h"
|
||||
|
||||
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
|
||||
|
||||
#include "os/mynewt.h"
|
||||
#include "mem/mem.h"
|
||||
#include "host/ble_hs_log.h"
|
||||
#include "ble_att_cmd_priv.h"
|
||||
#include "ble_hs_priv.h"
|
||||
#include "ble_l2cap_priv.h"
|
||||
#include "ble_eatt_priv.h"
|
||||
#include "services/gatt/ble_svc_gatt.h"
|
||||
|
||||
struct ble_eatt {
|
||||
SLIST_ENTRY(ble_eatt) next;
|
||||
uint16_t conn_handle;
|
||||
struct ble_l2cap_chan *chan;
|
||||
uint8_t client_op;
|
||||
bool client_proceed;
|
||||
|
||||
bool server_proceed;
|
||||
/* Packet transmit queue */
|
||||
STAILQ_HEAD(, os_mbuf_pkthdr) eatt_tx_q;
|
||||
|
||||
struct ble_npl_event setup_ev;
|
||||
struct ble_npl_event wakeup_ev;
|
||||
};
|
||||
|
||||
SLIST_HEAD(ble_eatt_list, ble_eatt);
|
||||
|
||||
static struct ble_eatt_list g_ble_eatt_list;
|
||||
static ble_eatt_att_rx_fn ble_eatt_att_rx_cb;
|
||||
|
||||
#define BLE_EATT_DATABUF_SIZE ( \
|
||||
MYNEWT_VAL(BLE_EATT_MTU) + \
|
||||
2 + \
|
||||
sizeof (struct os_mbuf_pkthdr) + \
|
||||
sizeof (struct os_mbuf))
|
||||
|
||||
#define BLE_EATT_MEMBLOCK_SIZE \
|
||||
(OS_ALIGN(BLE_EATT_DATABUF_SIZE, 4))
|
||||
|
||||
#define BLE_EATT_MEMPOOL_SIZE \
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1, BLE_EATT_MEMBLOCK_SIZE)
|
||||
static os_membuf_t ble_eatt_conn_mem[
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(BLE_EATT_CHAN_NUM),
|
||||
sizeof(struct ble_eatt))
|
||||
];
|
||||
static struct os_mempool ble_eatt_conn_pool;
|
||||
static os_membuf_t ble_eatt_sdu_coc_mem[BLE_EATT_MEMPOOL_SIZE];
|
||||
struct os_mbuf_pool ble_eatt_sdu_os_mbuf_pool;
|
||||
static struct os_mempool ble_eatt_sdu_mbuf_mempool;
|
||||
|
||||
static struct ble_gap_event_listener ble_eatt_listener;
|
||||
|
||||
static struct ble_npl_event g_read_sup_cl_feat_ev;
|
||||
static struct ble_npl_event g_read_sup_srv_feat_ev;
|
||||
|
||||
static void ble_eatt_setup_cb(struct ble_npl_event *ev);
|
||||
|
||||
static struct ble_eatt *
|
||||
ble_eatt_find_not_busy(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
SLIST_FOREACH(eatt, &g_ble_eatt_list, next) {
|
||||
if ((eatt->conn_handle == conn_handle) && !eatt->client_op) {
|
||||
return eatt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ble_eatt *
|
||||
ble_eatt_find_by_conn_handle(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
SLIST_FOREACH(eatt, &g_ble_eatt_list, next) {
|
||||
if (eatt->conn_handle == conn_handle) {
|
||||
return eatt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static struct ble_eatt *
|
||||
ble_eatt_find_by_conn_handle_and_busy_op(uint16_t conn_handle, uint8_t op)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
SLIST_FOREACH(eatt, &g_ble_eatt_list, next) {
|
||||
if (eatt->conn_handle == conn_handle && eatt->client_op == op) {
|
||||
return eatt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static struct ble_eatt *
|
||||
ble_eatt_find(uint16_t conn_handle, uint16_t cid)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
SLIST_FOREACH(eatt, &g_ble_eatt_list, next) {
|
||||
if ((eatt->conn_handle == conn_handle) &&
|
||||
(eatt->chan) &&
|
||||
(eatt->chan->scid == cid)) {
|
||||
return eatt;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
ble_eatt_prepare_rx_sdu(struct ble_l2cap_chan *chan)
|
||||
{
|
||||
int rc;
|
||||
struct os_mbuf *om;
|
||||
|
||||
om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0);
|
||||
if (!om) {
|
||||
BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n");
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
|
||||
rc = ble_l2cap_recv_ready(chan, om);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_eatt_wakeup_cb(struct ble_npl_event *ev)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
struct os_mbuf *txom;
|
||||
struct os_mbuf_pkthdr *omp;
|
||||
struct ble_l2cap_chan_info info;
|
||||
|
||||
eatt = ble_npl_event_get_arg(ev);
|
||||
assert(eatt);
|
||||
|
||||
omp = STAILQ_FIRST(&eatt->eatt_tx_q);
|
||||
if (omp != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next);
|
||||
|
||||
txom = OS_MBUF_PKTHDR_TO_MBUF(omp);
|
||||
ble_l2cap_get_chan_info(eatt->chan, &info);
|
||||
ble_eatt_tx(eatt->conn_handle, info.dcid, txom);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ble_eatt *
|
||||
ble_eatt_alloc(void)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
eatt = os_memblock_get(&ble_eatt_conn_pool);
|
||||
if (eatt) {
|
||||
SLIST_INSERT_HEAD(&g_ble_eatt_list, eatt, next);
|
||||
}
|
||||
|
||||
eatt->conn_handle = BLE_HS_CONN_HANDLE_NONE;
|
||||
eatt->chan = NULL;
|
||||
eatt->client_op = 0;
|
||||
|
||||
STAILQ_INIT(&eatt->eatt_tx_q);
|
||||
ble_npl_event_init(&eatt->setup_ev, ble_eatt_setup_cb, eatt);
|
||||
ble_npl_event_init(&eatt->wakeup_ev, ble_eatt_wakeup_cb, eatt);
|
||||
return eatt;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_eatt_free(struct ble_eatt *eatt)
|
||||
{
|
||||
struct os_mbuf_pkthdr *omp;
|
||||
|
||||
while ((omp = STAILQ_FIRST(&eatt->eatt_tx_q)) != NULL) {
|
||||
STAILQ_REMOVE_HEAD(&eatt->eatt_tx_q, omp_next);
|
||||
os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(omp));
|
||||
}
|
||||
|
||||
SLIST_REMOVE(&g_ble_eatt_list, eatt, ble_eatt, next);
|
||||
os_memblock_put(&ble_eatt_conn_pool, eatt);
|
||||
}
|
||||
|
||||
static int
|
||||
ble_eatt_l2cap_event_fn(struct ble_l2cap_event *event, void *arg)
|
||||
{
|
||||
struct ble_eatt *eatt = arg;
|
||||
uint8_t opcode;
|
||||
int rc;
|
||||
|
||||
switch (event->type) {
|
||||
case BLE_L2CAP_EVENT_COC_CONNECTED:
|
||||
BLE_EATT_LOG_DEBUG("eatt: Connected \n");
|
||||
if (event->connect.status) {
|
||||
ble_eatt_free(eatt);
|
||||
return 0;
|
||||
}
|
||||
eatt->chan = event->connect.chan;
|
||||
break;
|
||||
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
|
||||
BLE_EATT_LOG_DEBUG("eatt: Disconnected \n");
|
||||
ble_eatt_free(eatt);
|
||||
break;
|
||||
case BLE_L2CAP_EVENT_COC_ACCEPT:
|
||||
BLE_EATT_LOG_DEBUG("eatt: Accept request\n");
|
||||
eatt = ble_eatt_find_by_conn_handle(event->accept.conn_handle);
|
||||
if (eatt) {
|
||||
/* For now we accept only one additional coc channel per ACL
|
||||
* TODO: improve it
|
||||
*/
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
|
||||
eatt = ble_eatt_alloc();
|
||||
if (!eatt) {
|
||||
return BLE_HS_ENOMEM;
|
||||
}
|
||||
eatt->conn_handle = event->accept.conn_handle;
|
||||
event->accept.chan->cb_arg = eatt;
|
||||
|
||||
rc = ble_eatt_prepare_rx_sdu(event->accept.chan);
|
||||
if (rc) {
|
||||
ble_eatt_free(eatt);
|
||||
}
|
||||
assert(rc == 0);
|
||||
return 0;
|
||||
case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev);
|
||||
break;
|
||||
case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
|
||||
assert(eatt->chan == event->receive.chan);
|
||||
opcode = event->receive.sdu_rx->om_data[0];
|
||||
if (ble_att_is_request_op(opcode)) {
|
||||
eatt->server_proceed = true;
|
||||
} else if (ble_att_is_response_op(opcode)) {
|
||||
eatt->client_proceed = false;
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
ble_eatt_att_rx_cb(event->receive.conn_handle, eatt->chan->scid, &event->receive.sdu_rx);
|
||||
if (event->receive.sdu_rx) {
|
||||
os_mbuf_free_chain(event->receive.sdu_rx);
|
||||
event->receive.sdu_rx = NULL;
|
||||
}
|
||||
rc = ble_eatt_prepare_rx_sdu(event->receive.chan);
|
||||
|
||||
/* FIXME Figure out what to do here, probably disconnect EATT */
|
||||
assert(rc == 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_eatt_setup_cb(struct ble_npl_event *ev)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
struct os_mbuf *om;
|
||||
|
||||
eatt = ble_npl_event_get_arg(ev);
|
||||
assert(eatt);
|
||||
|
||||
om = os_mbuf_get_pkthdr(&ble_eatt_sdu_os_mbuf_pool, 0);
|
||||
if (!om) {
|
||||
ble_eatt_free(eatt);
|
||||
BLE_EATT_LOG_ERROR("eatt: no memory for sdu\n");
|
||||
return;
|
||||
}
|
||||
|
||||
BLE_EATT_LOG_DEBUG("eatt: connecting eatt on conn_handle 0x%04x\n", eatt->conn_handle);
|
||||
ble_l2cap_enhanced_connect(eatt->conn_handle, BLE_EATT_PSM,
|
||||
MYNEWT_VAL(BLE_EATT_MTU), 1, &om, ble_eatt_l2cap_event_fn, eatt);
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gatt_eatt_write_cl_cb(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) {
|
||||
BLE_EATT_LOG_DEBUG("eatt: Cannot write to Client Supported features on peer device\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ble_eatt_start(conn_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gatt_eatt_read_cl_uuid_cb(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
uint8_t client_supported_feat;
|
||||
int rc;
|
||||
|
||||
if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) {
|
||||
BLE_EATT_LOG_DEBUG("eatt: Cannot find Client Supported features on peer device\n");
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
if (attr == NULL) {
|
||||
BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n");
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
if (error->status == 0) {
|
||||
client_supported_feat = ble_svc_gatt_get_local_cl_supported_feat();
|
||||
rc = ble_gattc_write_flat(conn_handle, attr->handle, &client_supported_feat, 1,
|
||||
ble_gatt_eatt_write_cl_cb, NULL);
|
||||
BLE_EATT_LOG_DEBUG("eatt: %s , write rc = %d \n", __func__, rc);
|
||||
assert(rc == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
static int
|
||||
ble_gatt_eatt_read_uuid_cb(uint16_t conn_handle,
|
||||
const struct ble_gatt_error *error,
|
||||
struct ble_gatt_attr *attr, void *arg)
|
||||
{
|
||||
uint8_t supported_features;
|
||||
int rc;
|
||||
|
||||
if (error == NULL || (error->status != 0 && error->status != BLE_HS_EDONE)) {
|
||||
BLE_EATT_LOG_DEBUG("eatt: Cannot find Server Supported features on peer device\n");
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
if (attr == NULL) {
|
||||
BLE_EATT_LOG_ERROR("eatt: Invalid attribute \n");
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
rc = os_mbuf_copydata(attr->om, 0, 1, &supported_features);
|
||||
if (rc) {
|
||||
BLE_EATT_LOG_ERROR("eatt: Cannot read srv supported features \n");
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
if (supported_features & 0x01) {
|
||||
ble_npl_event_set_arg(&g_read_sup_cl_feat_ev, UINT_TO_POINTER(conn_handle));
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_cl_feat_ev);
|
||||
}
|
||||
return BLE_HS_EDONE;
|
||||
}
|
||||
|
||||
static void
|
||||
ble_gatt_eatt_read_svr_uuid(struct ble_npl_event *ev)
|
||||
{
|
||||
uint16_t conn_handle;
|
||||
|
||||
conn_handle = POINTER_TO_UINT(ble_npl_event_get_arg(ev));
|
||||
|
||||
ble_gattc_read_by_uuid(conn_handle, 1, 0xffff,
|
||||
BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16),
|
||||
ble_gatt_eatt_read_uuid_cb, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
ble_gatt_eatt_read_cl_uuid(struct ble_npl_event *ev)
|
||||
{
|
||||
uint16_t conn_handle;
|
||||
|
||||
conn_handle = POINTER_TO_UINT(ble_npl_event_get_arg(ev));
|
||||
|
||||
ble_gattc_read_by_uuid(conn_handle, 1, 0xffff,
|
||||
BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16),
|
||||
ble_gatt_eatt_read_cl_uuid_cb, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
ble_eatt_gap_event(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
BLE_EATT_LOG_DEBUG("eatt: Device connected, waiting to write into "
|
||||
"client supported features\n");
|
||||
|
||||
ble_npl_event_set_arg(&g_read_sup_srv_feat_ev, UINT_TO_POINTER(event->connect.conn_handle));
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &g_read_sup_srv_feat_ev);
|
||||
|
||||
break;
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
eatt = ble_eatt_find_by_conn_handle(event->disconnect.conn.conn_handle);
|
||||
assert(eatt == NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op)
|
||||
{
|
||||
struct ble_eatt * eatt;
|
||||
|
||||
eatt = ble_eatt_find_not_busy(conn_handle);
|
||||
if (!eatt) {
|
||||
return BLE_L2CAP_CID_ATT;
|
||||
}
|
||||
|
||||
eatt->client_op = op;
|
||||
return eatt->chan->scid;
|
||||
}
|
||||
|
||||
void
|
||||
ble_eatt_release_chan(uint16_t conn_handle, uint8_t op)
|
||||
{
|
||||
struct ble_eatt * eatt;
|
||||
|
||||
eatt = ble_eatt_find_by_conn_handle_and_busy_op(conn_handle, op);
|
||||
if (!eatt) {
|
||||
BLE_EATT_LOG_WARN("ble_eatt_release_chan:"
|
||||
"EATT not found for conn_handle 0x%04x, operation 0x%02\n", conn_handle, op);
|
||||
return;
|
||||
}
|
||||
|
||||
eatt->client_op = 0;
|
||||
}
|
||||
|
||||
int
|
||||
ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom)
|
||||
{
|
||||
struct ble_eatt *eatt;
|
||||
int rc;
|
||||
|
||||
BLE_EATT_LOG_DEBUG("eatt: %s, size %d ", __func__, OS_MBUF_PKTLEN(txom));
|
||||
eatt = ble_eatt_find(conn_handle, cid);
|
||||
if (!eatt || !eatt->chan) {
|
||||
BLE_EATT_LOG_ERROR("Eatt not available");
|
||||
rc = BLE_HS_ENOENT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
rc = ble_l2cap_send(eatt->chan, txom);
|
||||
if (rc == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (rc == BLE_HS_ESTALLED) {
|
||||
BLE_EATT_LOG_DEBUG("ble_eatt_tx: Eatt stalled");
|
||||
} else if (rc == BLE_HS_EBUSY) {
|
||||
BLE_EATT_LOG_DEBUG("ble_eatt_tx: Message queued");
|
||||
STAILQ_INSERT_HEAD(&eatt->eatt_tx_q, OS_MBUF_PKTHDR(txom), omp_next);
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->wakeup_ev);
|
||||
} else {
|
||||
BLE_EATT_LOG_ERROR("eatt: %s, ERROR %d ", __func__, rc);
|
||||
assert(0);
|
||||
}
|
||||
done:
|
||||
return 0;
|
||||
|
||||
error:
|
||||
os_mbuf_free_chain(txom);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
ble_eatt_start(uint16_t conn_handle)
|
||||
{
|
||||
struct ble_gap_conn_desc desc;
|
||||
struct ble_eatt *eatt;
|
||||
int rc;
|
||||
|
||||
rc = ble_gap_conn_find(conn_handle, &desc);
|
||||
assert(rc == 0);
|
||||
if (desc.role != BLE_GAP_ROLE_MASTER) {
|
||||
/* Let master to create ecoc.
|
||||
* TODO: Slave could setup after some timeout
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
eatt = ble_eatt_alloc();
|
||||
if (!eatt) {
|
||||
BLE_EATT_LOG_ERROR("eatt: no available eatt resources\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
eatt->conn_handle = conn_handle;
|
||||
|
||||
/* Setup EATT */
|
||||
ble_npl_eventq_put(ble_hs_evq_get(), &eatt->setup_ev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ble_eatt_init(ble_eatt_att_rx_fn att_rx_cb)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = mem_init_mbuf_pool(ble_eatt_sdu_coc_mem,
|
||||
&ble_eatt_sdu_mbuf_mempool,
|
||||
&ble_eatt_sdu_os_mbuf_pool,
|
||||
MYNEWT_VAL(BLE_EATT_CHAN_NUM) + 1,
|
||||
BLE_EATT_MEMBLOCK_SIZE,
|
||||
"ble_eatt_sdu");
|
||||
BLE_HS_DBG_ASSERT_EVAL(rc == 0);
|
||||
|
||||
rc = os_mempool_init(&ble_eatt_conn_pool, MYNEWT_VAL(BLE_EATT_CHAN_NUM),
|
||||
sizeof (struct ble_eatt),
|
||||
ble_eatt_conn_mem, "ble_eatt_conn_pool");
|
||||
BLE_HS_DBG_ASSERT_EVAL(rc == 0);
|
||||
|
||||
ble_gap_event_listener_register(&ble_eatt_listener, ble_eatt_gap_event, NULL);
|
||||
ble_l2cap_create_server(BLE_EATT_PSM, MYNEWT_VAL(BLE_EATT_MTU), ble_eatt_l2cap_event_fn, NULL);
|
||||
|
||||
ble_npl_event_init(&g_read_sup_srv_feat_ev, ble_gatt_eatt_read_svr_uuid, NULL);
|
||||
ble_npl_event_init(&g_read_sup_cl_feat_ev, ble_gatt_eatt_read_cl_uuid, NULL);
|
||||
|
||||
ble_eatt_att_rx_cb = att_rx_cb;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 "syscfg/syscfg.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "host/ble_l2cap.h"
|
||||
|
||||
#ifndef BLE_EATT_H_
|
||||
#define BLE_EATT_H_
|
||||
|
||||
typedef int (* ble_eatt_att_rx_fn)(uint16_t conn_handle, uint16_t cid, struct os_mbuf **rx_buf);
|
||||
|
||||
#define BLE_EATT_PSM (0x0027)
|
||||
|
||||
#define BLE_GATT_OP_SERVER 0xF1
|
||||
#define BLE_GATT_OP_DUMMY 0xF2
|
||||
|
||||
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
|
||||
void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn);
|
||||
uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op);
|
||||
void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op);
|
||||
int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom);
|
||||
int ble_eatt_start(uint16_t conn_handle);
|
||||
#else
|
||||
static inline void
|
||||
ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
ble_eatt_release_chan(uint16_t conn_handle, uint8_t op)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op)
|
||||
{
|
||||
return BLE_L2CAP_CID_ATT;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ble_eatt_start(uint16_t conn_handle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -700,7 +700,7 @@ ble_gattc_proc_prepare(struct ble_gattc_proc *proc, uint16_t conn_handle, uint8_
|
||||
{
|
||||
proc->conn_handle = conn_handle;
|
||||
proc->op = op;
|
||||
proc->cid = BLE_L2CAP_CID_ATT;
|
||||
proc->cid = ble_eatt_get_available_chan_cid(conn_handle, op);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -734,6 +734,12 @@ ble_gattc_proc_free(struct ble_gattc_proc *proc)
|
||||
break;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(BLE_EATT_CHAN_NUM) > 0
|
||||
if (proc->cid != BLE_L2CAP_CID_ATT) {
|
||||
ble_eatt_release_chan(proc->conn_handle, proc->op);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(BLE_HS_DEBUG)
|
||||
memset(proc, 0xff, sizeof *proc);
|
||||
#endif
|
||||
@@ -3465,15 +3471,18 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
|
||||
#endif
|
||||
|
||||
int rc;
|
||||
uint16_t cid;
|
||||
|
||||
STATS_INC(ble_gattc_stats, write_no_rsp);
|
||||
|
||||
ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 0);
|
||||
|
||||
rc = ble_att_clt_tx_write_cmd(conn_handle, BLE_L2CAP_CID_ATT, attr_handle, txom);
|
||||
cid = ble_eatt_get_available_chan_cid(conn_handle, BLE_GATT_OP_DUMMY);
|
||||
rc = ble_att_clt_tx_write_cmd(conn_handle, cid, attr_handle, txom);
|
||||
if (rc != 0) {
|
||||
STATS_INC(ble_gattc_stats, write);
|
||||
}
|
||||
ble_eatt_release_chan(conn_handle, BLE_GATT_OP_DUMMY);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <inttypes.h>
|
||||
#include "ble_att_cmd_priv.h"
|
||||
#include "ble_att_priv.h"
|
||||
#include "ble_eatt_priv.h"
|
||||
#include "ble_gap_priv.h"
|
||||
#include "ble_gatt_priv.h"
|
||||
#include "ble_hs_hci_priv.h"
|
||||
|
||||
@@ -295,6 +295,16 @@ syscfg.defs:
|
||||
value: 1000
|
||||
|
||||
# Supported server ATT commands. (0/1)
|
||||
BLE_EATT_CHAN_NUM:
|
||||
description: >
|
||||
Number of CoC channels allocated to EATT
|
||||
value: 0
|
||||
|
||||
BLE_EATT_MTU:
|
||||
description: >
|
||||
MTU used for EATT channels.
|
||||
value: 128
|
||||
|
||||
BLE_ATT_SVR_FIND_INFO:
|
||||
description: >
|
||||
Enables processing of incoming Find Information Request ATT
|
||||
@@ -462,11 +472,22 @@ syscfg.defs:
|
||||
description: 'Minimum level for the BLE host log.'
|
||||
value: 1
|
||||
|
||||
BLE_EATT_LOG_MOD:
|
||||
description: 'Numeric module ID to use for BLE EATT log messages.'
|
||||
value: 27
|
||||
BLE_EATT_LOG_LVL:
|
||||
description: 'Minimum level for the BLE EATT log.'
|
||||
value: 1
|
||||
|
||||
syscfg.logs:
|
||||
BLE_HS_LOG:
|
||||
module: MYNEWT_VAL(BLE_HS_LOG_MOD)
|
||||
level: MYNEWT_VAL(BLE_HS_LOG_LVL)
|
||||
|
||||
BLE_EATT_LOG:
|
||||
module: MYNEWT_VAL(BLE_EATT_LOG_MOD)
|
||||
level: MYNEWT_VAL(BLE_EATT_LOG_LVL)
|
||||
|
||||
syscfg.vals.BLE_MESH:
|
||||
BLE_SM_SC: 1
|
||||
|
||||
|
||||
@@ -30,3 +30,4 @@ syscfg.vals:
|
||||
BLE_VERSION: 52
|
||||
BLE_L2CAP_ENHANCED_COC: 1
|
||||
BLE_TRANSPORT_LL: custom
|
||||
BLE_EATT_CHAN_NUM: 0
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#include "modlog/modlog.h"
|
||||
#include "log_common/log_common.h"
|
||||
|
||||
#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__)
|
||||
|
||||
#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__)
|
||||
#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__)
|
||||
|
||||
@@ -571,6 +571,22 @@
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
|
||||
#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_MTU
|
||||
#define MYNEWT_VAL_BLE_EATT_MTU (128)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
|
||||
#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#include "modlog/modlog.h"
|
||||
#include "log_common/log_common.h"
|
||||
|
||||
#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__)
|
||||
|
||||
#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__)
|
||||
#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__)
|
||||
|
||||
@@ -572,6 +572,22 @@
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
|
||||
#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_MTU
|
||||
#define MYNEWT_VAL_BLE_EATT_MTU (128)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
|
||||
#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#include "modlog/modlog.h"
|
||||
#include "log_common/log_common.h"
|
||||
|
||||
#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__)
|
||||
|
||||
#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__)
|
||||
#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__)
|
||||
|
||||
@@ -570,6 +570,22 @@
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
|
||||
#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_MTU
|
||||
#define MYNEWT_VAL_BLE_EATT_MTU (128)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
|
||||
#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
|
||||
#endif
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
#include "modlog/modlog.h"
|
||||
#include "log_common/log_common.h"
|
||||
|
||||
#define BLE_EATT_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_EATT_LOG_INFO(...) MODLOG_INFO(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_WARN(...) MODLOG_WARN(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_ERROR(...) MODLOG_ERROR(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_CRITICAL(...) MODLOG_CRITICAL(22, __VA_ARGS__)
|
||||
#define BLE_EATT_LOG_DISABLED(...) MODLOG_DISABLED(22, __VA_ARGS__)
|
||||
|
||||
#define BLE_HS_LOG_DEBUG(...) IGNORE(__VA_ARGS__)
|
||||
#define BLE_HS_LOG_INFO(...) MODLOG_INFO(4, __VA_ARGS__)
|
||||
#define BLE_HS_LOG_WARN(...) MODLOG_WARN(4, __VA_ARGS__)
|
||||
|
||||
@@ -1434,6 +1434,22 @@
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_CHAN_NUM
|
||||
#define MYNEWT_VAL_BLE_EATT_CHAN_NUM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_LVL
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_LVL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_LOG_MOD
|
||||
#define MYNEWT_VAL_BLE_EATT_LOG_MOD (27)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EATT_MTU
|
||||
#define MYNEWT_VAL_BLE_EATT_MTU (128)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE
|
||||
#define MYNEWT_VAL_BLE_GAP_MAX_PENDING_CONN_PARAM_UPDATE (1)
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user