/*
|
* 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_ATT_PRIV_
|
#define H_BLE_ATT_PRIV_
|
|
#include <inttypes.h>
|
#include "stats/stats.h"
|
#include "host/ble_att.h"
|
#include "host/ble_uuid.h"
|
#include "nimble/nimble_npl.h"
|
|
#ifdef __cplusplus
|
extern "C" {
|
#endif
|
|
struct os_mbuf;
|
struct ble_hs_conn;
|
struct ble_l2cap_chan;
|
struct ble_att_find_info_req;
|
struct ble_att_error_rsp;
|
struct ble_att_mtu_cmd;
|
struct ble_att_read_req;
|
struct ble_att_read_blob_req;
|
struct ble_att_read_type_req;
|
struct ble_att_read_group_type_req;
|
struct ble_att_read_group_type_rsp;
|
struct ble_att_find_type_value_req;
|
struct ble_att_write_req;
|
struct ble_att_prep_write_cmd;
|
struct ble_att_exec_write_req;
|
struct ble_att_notify_req;
|
struct ble_att_indicate_req;
|
|
STATS_SECT_START(ble_att_stats)
|
STATS_SECT_ENTRY(error_rsp_rx)
|
STATS_SECT_ENTRY(error_rsp_tx)
|
STATS_SECT_ENTRY(mtu_req_rx)
|
STATS_SECT_ENTRY(mtu_req_tx)
|
STATS_SECT_ENTRY(mtu_rsp_rx)
|
STATS_SECT_ENTRY(mtu_rsp_tx)
|
STATS_SECT_ENTRY(find_info_req_rx)
|
STATS_SECT_ENTRY(find_info_req_tx)
|
STATS_SECT_ENTRY(find_info_rsp_rx)
|
STATS_SECT_ENTRY(find_info_rsp_tx)
|
STATS_SECT_ENTRY(find_type_value_req_rx)
|
STATS_SECT_ENTRY(find_type_value_req_tx)
|
STATS_SECT_ENTRY(find_type_value_rsp_rx)
|
STATS_SECT_ENTRY(find_type_value_rsp_tx)
|
STATS_SECT_ENTRY(read_type_req_rx)
|
STATS_SECT_ENTRY(read_type_req_tx)
|
STATS_SECT_ENTRY(read_type_rsp_rx)
|
STATS_SECT_ENTRY(read_type_rsp_tx)
|
STATS_SECT_ENTRY(read_req_rx)
|
STATS_SECT_ENTRY(read_req_tx)
|
STATS_SECT_ENTRY(read_rsp_rx)
|
STATS_SECT_ENTRY(read_rsp_tx)
|
STATS_SECT_ENTRY(read_blob_req_rx)
|
STATS_SECT_ENTRY(read_blob_req_tx)
|
STATS_SECT_ENTRY(read_blob_rsp_rx)
|
STATS_SECT_ENTRY(read_blob_rsp_tx)
|
STATS_SECT_ENTRY(read_mult_req_rx)
|
STATS_SECT_ENTRY(read_mult_req_tx)
|
STATS_SECT_ENTRY(read_mult_rsp_rx)
|
STATS_SECT_ENTRY(read_mult_rsp_tx)
|
STATS_SECT_ENTRY(read_group_type_req_rx)
|
STATS_SECT_ENTRY(read_group_type_req_tx)
|
STATS_SECT_ENTRY(read_group_type_rsp_rx)
|
STATS_SECT_ENTRY(read_group_type_rsp_tx)
|
STATS_SECT_ENTRY(write_req_rx)
|
STATS_SECT_ENTRY(write_req_tx)
|
STATS_SECT_ENTRY(write_rsp_rx)
|
STATS_SECT_ENTRY(write_rsp_tx)
|
STATS_SECT_ENTRY(prep_write_req_rx)
|
STATS_SECT_ENTRY(prep_write_req_tx)
|
STATS_SECT_ENTRY(prep_write_rsp_rx)
|
STATS_SECT_ENTRY(prep_write_rsp_tx)
|
STATS_SECT_ENTRY(exec_write_req_rx)
|
STATS_SECT_ENTRY(exec_write_req_tx)
|
STATS_SECT_ENTRY(exec_write_rsp_rx)
|
STATS_SECT_ENTRY(exec_write_rsp_tx)
|
STATS_SECT_ENTRY(notify_req_rx)
|
STATS_SECT_ENTRY(notify_req_tx)
|
STATS_SECT_ENTRY(indicate_req_rx)
|
STATS_SECT_ENTRY(indicate_req_tx)
|
STATS_SECT_ENTRY(indicate_rsp_rx)
|
STATS_SECT_ENTRY(indicate_rsp_tx)
|
STATS_SECT_ENTRY(write_cmd_rx)
|
STATS_SECT_ENTRY(write_cmd_tx)
|
STATS_SECT_END
|
extern STATS_SECT_DECL(ble_att_stats) ble_att_stats;
|
|
struct ble_att_prep_entry {
|
SLIST_ENTRY(ble_att_prep_entry) bape_next;
|
uint16_t bape_handle;
|
uint16_t bape_offset;
|
|
/* XXX: This is wasteful; we should use one mbuf chain for the entire
|
* prepared write, and compress the data into as few mbufs as possible.
|
*/
|
struct os_mbuf *bape_value;
|
};
|
|
SLIST_HEAD(ble_att_prep_entry_list, ble_att_prep_entry);
|
|
struct ble_att_svr_conn {
|
/** This list is sorted by attribute handle ID. */
|
struct ble_att_prep_entry_list basc_prep_list;
|
ble_npl_time_t basc_prep_timeout_at;
|
};
|
|
/**
|
* Handles a host attribute request.
|
*
|
* @param entry The host attribute being requested.
|
* @param op The operation being performed on the attribute.
|
* @param arg The request data associated with that host
|
* attribute.
|
*
|
* @return 0 on success;
|
* One of the BLE_ATT_ERR_[...] codes on
|
* failure.
|
*/
|
typedef int ble_att_svr_access_fn(uint16_t conn_handle, uint16_t attr_handle,
|
uint8_t op, uint16_t offset,
|
struct os_mbuf **om, void *arg);
|
|
int ble_att_svr_register(const ble_uuid_t *uuid, uint8_t flags,
|
uint8_t min_key_size, uint16_t *handle_id,
|
ble_att_svr_access_fn *cb, void *cb_arg);
|
|
struct ble_att_svr_entry {
|
STAILQ_ENTRY(ble_att_svr_entry) ha_next;
|
|
const ble_uuid_t *ha_uuid;
|
uint8_t ha_flags;
|
uint8_t ha_min_key_size;
|
uint16_t ha_handle_id;
|
ble_att_svr_access_fn *ha_cb;
|
void *ha_cb_arg;
|
};
|
|
SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry);
|
|
/*** @gen */
|
|
struct ble_l2cap_chan *ble_att_create_chan(uint16_t conn_handle);
|
int ble_att_conn_chan_find(uint16_t conn_handle, struct ble_hs_conn **out_conn,
|
struct ble_l2cap_chan **out_chan);
|
void ble_att_inc_tx_stat(uint8_t att_op);
|
void ble_att_truncate_to_mtu(const struct ble_l2cap_chan *att_chan,
|
struct os_mbuf *txom);
|
void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu);
|
uint16_t ble_att_chan_mtu(const struct ble_l2cap_chan *chan);
|
int ble_att_init(void);
|
|
/*** @svr */
|
|
int ble_att_svr_start(void);
|
|
struct ble_att_svr_entry *
|
ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at,
|
const ble_uuid_t *uuid,
|
uint16_t end_handle);
|
uint16_t ble_att_svr_prev_handle(void);
|
int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
|
struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id);
|
int32_t ble_att_svr_ticks_until_tmo(const struct ble_att_svr_conn *svr,
|
ble_npl_time_t now);
|
int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_svr_rx_find_type_value(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_read_type(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_read_group_type(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_read(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_read_blob(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_read_mult(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_write(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_svr_rx_prep_write(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_exec_write(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_notify(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_svr_rx_indicate(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
void ble_att_svr_prep_clear(struct ble_att_prep_entry_list *prep_list);
|
int ble_att_svr_read_handle(uint16_t conn_handle, uint16_t attr_handle,
|
uint16_t offset, struct os_mbuf *om,
|
uint8_t *out_att_err);
|
void ble_att_svr_reset(void);
|
int ble_att_svr_init(void);
|
|
void ble_att_svr_hide_range(uint16_t start_handle, uint16_t end_handle);
|
void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
|
|
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, struct os_mbuf *txom,
|
uint8_t req_op, uint16_t handle,
|
uint8_t error_code);
|
/*** $clt */
|
|
/** An information-data entry in a find information response. */
|
struct ble_att_find_info_idata {
|
uint16_t attr_handle;
|
ble_uuid_any_t uuid;
|
};
|
|
/** A handles-information entry in a find by type value response. */
|
struct ble_att_find_type_value_hinfo {
|
uint16_t attr_handle;
|
uint16_t group_end_handle;
|
};
|
|
/** An attribute-data entry in a read by type response. */
|
struct ble_att_read_type_adata {
|
uint16_t att_handle;
|
int value_len;
|
uint8_t *value;
|
|
};
|
|
/** An attribute-data entry in a read by group type response. */
|
struct ble_att_read_group_type_adata {
|
uint16_t att_handle;
|
uint16_t end_group_handle;
|
int value_len;
|
uint8_t *value;
|
};
|
|
int ble_att_clt_rx_error(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_mtu(uint16_t conn_handle, uint16_t mtu);
|
int ble_att_clt_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_read(uint16_t conn_handle, uint16_t handle);
|
int ble_att_clt_rx_read(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_read_blob(uint16_t conn_handle, uint16_t handle,
|
uint16_t offset);
|
int ble_att_clt_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_read_mult(uint16_t conn_handle,
|
const uint16_t *handles, int num_handles);
|
int ble_att_clt_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_read_type(uint16_t conn_handle, uint16_t start_handle,
|
uint16_t end_handle, const ble_uuid_t *uuid);
|
int ble_att_clt_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_read_group_type(uint16_t conn_handle,
|
uint16_t start_handle, uint16_t end_handle,
|
const ble_uuid_t *uuid128);
|
int ble_att_clt_rx_read_group_type(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_clt_tx_find_info(uint16_t conn_handle, uint16_t start_handle,
|
uint16_t end_handle);
|
int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_find_type_value(uint16_t conn_handle, uint16_t start_handle,
|
uint16_t end_handle, uint16_t attribute_type,
|
const void *attribute_value, int value_len);
|
int ble_att_clt_rx_find_type_value(uint16_t conn_handle,
|
struct os_mbuf **rxom);
|
int ble_att_clt_tx_write_req(uint16_t conn_handle, uint16_t handle,
|
struct os_mbuf *txom);
|
int ble_att_clt_tx_write_cmd(uint16_t conn_handle, uint16_t handle,
|
struct os_mbuf *txom);
|
int ble_att_clt_tx_prep_write(uint16_t conn_handle, uint16_t handle,
|
uint16_t offset, struct os_mbuf *txom);
|
int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_exec_write(uint16_t conn_handle, uint8_t flags);
|
int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
|
int ble_att_clt_tx_notify(uint16_t conn_handle, uint16_t handle,
|
struct os_mbuf *txom);
|
int ble_att_clt_tx_indicate(uint16_t conn_handle, uint16_t handle,
|
struct os_mbuf *txom);
|
int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom);
|
|
#ifdef __cplusplus
|
}
|
#endif
|
|
#endif
|