ATT read by group type; fix bugs.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/commit/c1ac77ce Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/tree/c1ac77ce Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/diff/c1ac77ce Branch: refs/heads/master Commit: c1ac77ce1231b259ea0283745fe145f83143d4a5 Parents: 984a4b4 Author: Christopher Collins <ccollins47...@gmail.com> Authored: Tue Dec 8 18:37:57 2015 -0800 Committer: Christopher Collins <ccollins47...@gmail.com> Committed: Tue Dec 8 18:42:06 2015 -0800 ---------------------------------------------------------------------- compiler/arm-none-eabi-m4/compiler.yml | 2 +- net/nimble/host/include/host/ble_att.h | 63 +++-- net/nimble/host/src/ble_att.c | 21 ++ net/nimble/host/src/ble_att_clt.c | 107 ++++---- net/nimble/host/src/ble_att_cmd.h | 2 + net/nimble/host/src/ble_att_priv.h | 4 + net/nimble/host/src/ble_att_svr.c | 301 ++++++++++++++++++++++- net/nimble/host/src/ble_gatt.c | 3 - net/nimble/host/src/ble_hs.c | 2 +- net/nimble/host/src/ble_hs_uuid.c | 2 +- net/nimble/host/src/ble_l2cap.c | 4 +- net/nimble/host/src/host_hci.c | 21 +- net/nimble/host/src/test/ble_hs_test_util.c | 3 +- net/nimble/host/src/test/ble_l2cap_test.c | 2 +- 14 files changed, 446 insertions(+), 91 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/compiler/arm-none-eabi-m4/compiler.yml ---------------------------------------------------------------------- diff --git a/compiler/arm-none-eabi-m4/compiler.yml b/compiler/arm-none-eabi-m4/compiler.yml index 8cde544..29a9bcf 100644 --- a/compiler/arm-none-eabi-m4/compiler.yml +++ b/compiler/arm-none-eabi-m4/compiler.yml @@ -24,7 +24,7 @@ compiler.path.objcopy: arm-none-eabi-objcopy compiler.flags.default: -mcpu=cortex-m4 -mthumb-interwork -mthumb -Wall -Werror -fno-exceptions compiler.flags.optimized: [compiler.flags.default, -Os -ggdb] -compiler.flags.debug: [compiler.flags.default, -O1 -ggdb] +compiler.flags.debug: [compiler.flags.default, -O0 -ggdb] compiler.ld.flags: -static -lgcc compiler.ld.resolve_circular_deps: true http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/include/host/ble_att.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/include/host/ble_att.h b/net/nimble/host/include/host/ble_att.h index 18ee5cd..f8375d5 100644 --- a/net/nimble/host/include/host/ble_att.h +++ b/net/nimble/host/include/host/ble_att.h @@ -1,21 +1,42 @@ +/** + * Copyright (c) 2015 Runtime Inc. + * + * Licensed 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_ #define H_BLE_ATT_ -#define BLE_ATT_OP_ERROR_RSP 0x01 -#define BLE_ATT_OP_MTU_REQ 0x02 -#define BLE_ATT_OP_MTU_RSP 0x03 -#define BLE_ATT_OP_FIND_INFO_REQ 0x04 -#define BLE_ATT_OP_FIND_INFO_RSP 0x05 -#define BLE_ATT_OP_FIND_TYPE_VALUE_REQ 0x06 -#define BLE_ATT_OP_FIND_TYPE_VALUE_RSP 0x07 -#define BLE_ATT_OP_READ_TYPE_REQ 0x08 -#define BLE_ATT_OP_READ_TYPE_RSP 0x09 -#define BLE_ATT_OP_READ_REQ 0x0a -#define BLE_ATT_OP_READ_RSP 0x0b -#define BLE_ATT_OP_READ_GROUP_TYPE_REQ 0x10 -#define BLE_ATT_OP_READ_GROUP_TYPE_RSP 0x11 -#define BLE_ATT_OP_WRITE_REQ 0x12 -#define BLE_ATT_OP_WRITE_RSP 0x13 +#define BLE_ATT_UUID_PRIMARY_SERVICE 0x2800 +#define BLE_ATT_UUID_SECONDARY_SERVICE 0x2801 +#define BLE_ATT_UUID_INCLUDE 0x2802 +#define BLE_ATT_UUID_CHARACTERISTIC 0x2803 + +#define BLE_ATT_OP_ERROR_RSP 0x01 +#define BLE_ATT_OP_MTU_REQ 0x02 +#define BLE_ATT_OP_MTU_RSP 0x03 +#define BLE_ATT_OP_FIND_INFO_REQ 0x04 +#define BLE_ATT_OP_FIND_INFO_RSP 0x05 +#define BLE_ATT_OP_FIND_TYPE_VALUE_REQ 0x06 +#define BLE_ATT_OP_FIND_TYPE_VALUE_RSP 0x07 +#define BLE_ATT_OP_READ_TYPE_REQ 0x08 +#define BLE_ATT_OP_READ_TYPE_RSP 0x09 +#define BLE_ATT_OP_READ_REQ 0x0a +#define BLE_ATT_OP_READ_RSP 0x0b +#define BLE_ATT_OP_READ_GROUP_TYPE_REQ 0x10 +#define BLE_ATT_OP_READ_GROUP_TYPE_RSP 0x11 +#define BLE_ATT_OP_WRITE_REQ 0x12 +#define BLE_ATT_OP_WRITE_RSP 0x13 union ble_att_svr_handle_arg { struct { @@ -29,12 +50,12 @@ union ble_att_svr_handle_arg { } aha_write; }; -#define HA_FLAG_PERM_READ (1 << 0) -#define HA_FLAG_PERM_WRITE (1 << 1) -#define HA_FLAG_PERM_RW (1 << 2) -#define HA_FLAG_ENC_REQ (1 << 3) -#define HA_FLAG_AUTHENTICATION_REQ (1 << 4) -#define HA_FLAG_AUTHORIZATION_REQ (1 << 5) +#define HA_FLAG_PERM_READ (1 << 0) +#define HA_FLAG_PERM_WRITE (1 << 1) +#define HA_FLAG_PERM_RW (1 << 2) +#define HA_FLAG_ENC_REQ (1 << 3) +#define HA_FLAG_AUTHENTICATION_REQ (1 << 4) +#define HA_FLAG_AUTHORIZATION_REQ (1 << 5) struct ble_att_svr_entry; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att.c b/net/nimble/host/src/ble_att.c index 7ef6424..1398d39 100644 --- a/net/nimble/host/src/ble_att.c +++ b/net/nimble/host/src/ble_att.c @@ -16,6 +16,7 @@ #include <stddef.h> #include <errno.h> +#include "host/ble_hs.h" #include "ble_l2cap.h" #include "ble_att_cmd.h" #include "ble_att_priv.h" @@ -41,6 +42,7 @@ static struct ble_att_rx_dispatch_entry ble_att_rx_dispatch[] = { { BLE_ATT_OP_READ_TYPE_RSP, ble_att_clt_rx_read_type }, { BLE_ATT_OP_READ_REQ, ble_att_svr_rx_read }, { BLE_ATT_OP_READ_RSP, ble_att_clt_rx_read }, + { BLE_ATT_OP_READ_GROUP_TYPE_REQ, ble_att_svr_rx_read_group_type }, { BLE_ATT_OP_READ_GROUP_TYPE_RSP, ble_att_clt_rx_read_group_type }, { BLE_ATT_OP_WRITE_REQ, ble_att_svr_rx_write }, }; @@ -121,3 +123,22 @@ ble_att_create_chan(void) return chan; } + +/** + * Allocates an mbuf for use as an ATT request or response. + */ +struct os_mbuf * +ble_att_get_pkthdr(void) +{ + struct os_mbuf *om; + + om = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + if (om == NULL) { + return NULL; + } + + /* Make room in the buffer for various headers. XXX Check this number. */ + om->om_data += 8; + + return om; +} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_clt.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att_clt.c b/net/nimble/host/src/ble_att_clt.c index e78b337..ae90413 100644 --- a/net/nimble/host/src/ble_att_clt.c +++ b/net/nimble/host/src/ble_att_clt.c @@ -37,15 +37,12 @@ ble_att_clt_prep_req(struct ble_hs_conn *conn, struct ble_l2cap_chan **chan, *chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT); assert(*chan != NULL); - *txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + *txom = ble_att_get_pkthdr(); if (*txom == NULL) { rc = ENOMEM; goto err; } - /* Make room in the buffer for various headers. XXX Check this number. */ - (*txom)->om_data += 8; - buf = os_mbuf_extend(*txom, initial_sz); if (buf == NULL) { rc = ENOMEM; @@ -358,54 +355,6 @@ done: } int -ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn, - struct ble_att_read_group_type_req *req, - void *uuid128) -{ - struct ble_l2cap_chan *chan; - struct os_mbuf *txom; - int rc; - - txom = NULL; - - if (req->bagq_start_handle == 0 || - req->bagq_start_handle > req->bagq_end_handle) { - - rc = EINVAL; - goto err; - } - - rc = ble_att_clt_prep_req(conn, &chan, &txom, - BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ); - if (rc != 0) { - goto err; - } - - rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len, - req); - if (rc != 0) { - goto err; - } - - rc = ble_hs_uuid_append(txom, uuid128); - if (rc != 0) { - goto err; - } - - rc = ble_l2cap_tx(conn, chan, txom); - txom = NULL; - if (rc != 0) { - goto err; - } - - return 0; - -err: - os_mbuf_free_chain(txom); - return rc; -} - -int ble_att_clt_tx_read(struct ble_hs_conn *conn, struct ble_att_read_req *req) { struct ble_l2cap_chan *chan; @@ -475,10 +424,62 @@ done: return rc; } +int +ble_att_clt_tx_read_group_type(struct ble_hs_conn *conn, + struct ble_att_read_group_type_req *req, + void *uuid128) +{ + struct ble_l2cap_chan *chan; + struct os_mbuf *txom; + int rc; + + txom = NULL; + + if (req->bagq_start_handle == 0 || + req->bagq_start_handle > req->bagq_end_handle) { + + rc = EINVAL; + goto err; + } + + rc = ble_att_clt_prep_req(conn, &chan, &txom, + BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ); + if (rc != 0) { + goto err; + } + + rc = ble_att_read_group_type_req_write(txom->om_data, txom->om_len, + req); + if (rc != 0) { + goto err; + } + + rc = ble_hs_uuid_append(txom, uuid128); + if (rc != 0) { + goto err; + } + + rc = ble_l2cap_tx(conn, chan, txom); + txom = NULL; + if (rc != 0) { + goto err; + } + + return 0; + +err: + os_mbuf_free_chain(txom); + return rc; +} + static int ble_att_clt_parse_group_attribute_data(struct os_mbuf **om, int data_len, - struct ble_att_clt_adata *adata) + struct ble_att_clt_adata *adata) { + if (data_len < BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 1) { + return EMSGSIZE; + } + *om = os_mbuf_pullup(*om, data_len); if (*om == NULL) { return ENOMEM; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_cmd.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att_cmd.h b/net/nimble/host/src/ble_att_cmd.h index cd757d6..499aebf 100644 --- a/net/nimble/host/src/ble_att_cmd.h +++ b/net/nimble/host/src/ble_att_cmd.h @@ -175,6 +175,8 @@ struct ble_att_read_group_type_rsp { }; #define BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ 4 +#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16 6 +#define BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128 20 /** * | Parameter | Size (octets) | http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_priv.h ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att_priv.h b/net/nimble/host/src/ble_att_priv.h index f8d7539..b8bcec2 100644 --- a/net/nimble/host/src/ble_att_priv.h +++ b/net/nimble/host/src/ble_att_priv.h @@ -72,6 +72,7 @@ SLIST_HEAD(ble_att_clt_entry_list, ble_att_clt_entry); /*** @gen */ struct ble_l2cap_chan *ble_att_create_chan(void); void ble_att_set_peer_mtu(struct ble_l2cap_chan *chan, uint16_t peer_mtu); +struct os_mbuf *ble_att_get_pkthdr(void); /*** @svr */ int ble_att_svr_rx_mtu(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, @@ -85,6 +86,9 @@ int ble_att_svr_rx_find_type_value(struct ble_hs_conn *conn, int ble_att_svr_rx_read_type(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf **rxom); +int ble_att_svr_rx_read_group_type(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan, + struct os_mbuf **rxom); int ble_att_svr_rx_read(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, struct os_mbuf **rxom); int ble_att_svr_rx_write(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_att_svr.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_att_svr.c b/net/nimble/host/src/ble_att_svr.c index 611c0e9..7b688d3 100644 --- a/net/nimble/host/src/ble_att_svr.c +++ b/net/nimble/host/src/ble_att_svr.c @@ -273,7 +273,7 @@ ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, void *dst; int rc; - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -318,7 +318,7 @@ ble_att_svr_tx_mtu_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, assert(op == BLE_ATT_OP_MTU_REQ || op == BLE_ATT_OP_MTU_RSP); assert(mtu >= BLE_ATT_MTU_DFLT); - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -528,7 +528,7 @@ ble_att_svr_rx_find_info(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, goto err; } - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -815,7 +815,7 @@ ble_att_svr_rx_find_type_value(struct ble_hs_conn *conn, goto err; } - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -868,7 +868,7 @@ ble_att_svr_tx_read_type_rsp(struct ble_hs_conn *conn, int attr_len; int rc; - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -1017,7 +1017,7 @@ ble_att_svr_tx_read_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, uint8_t op; int rc; - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; @@ -1109,13 +1109,300 @@ err: } static int +ble_att_svr_is_valid_group_type(uint8_t *uuid128) +{ + uint16_t uuid16; + + uuid16 = ble_hs_uuid_16bit(uuid128); + + return uuid16 == BLE_ATT_UUID_PRIMARY_SERVICE || + uuid16 == BLE_ATT_UUID_SECONDARY_SERVICE; +} + +static int +ble_att_svr_is_valid_group_member(uint8_t *uuid128) +{ + uint16_t uuid16; + + /* Assumes the group type is primary or secondary service. */ + + uuid16 = ble_hs_uuid_16bit(uuid128); + + return uuid16 == BLE_ATT_UUID_INCLUDE || + uuid16 == BLE_ATT_UUID_CHARACTERISTIC; +} + +static int +ble_att_svr_service_uuid(struct ble_att_svr_entry *entry, uint16_t *uuid16, + uint8_t *uuid128) +{ + union ble_att_svr_handle_arg arg; + int rc; + + rc = entry->ha_fn(entry, BLE_ATT_OP_READ_REQ, &arg); + if (rc != 0) { + return rc; + } + + switch (arg.aha_read.attr_len) { + case 16: + *uuid16 = 0; + memcpy(uuid128, arg.aha_read.attr_data, 16); + return 0; + + case 2: + *uuid16 = le16toh(arg.aha_read.attr_data); + if (*uuid16 == 0) { + return EINVAL; + } + return 0; + + default: + return EINVAL; + } +} + +static int +ble_att_svr_read_group_type_entry_write(struct os_mbuf *om, uint16_t mtu, + uint16_t start_group_handle, + uint16_t end_group_handle, + uint16_t service_uuid16, + uint8_t *service_uuid128) +{ + uint8_t *buf; + int len; + + if (service_uuid16 != 0) { + len = BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_16; + } else { + len = BLE_ATT_READ_GROUP_TYPE_ADATA_SZ_128; + } + if (OS_MBUF_PKTLEN(om) + len > mtu) { + return EMSGSIZE; + } + + buf = os_mbuf_extend(om, len); + if (buf == NULL) { + return ENOMEM; + } + + htole16(buf + 0, start_group_handle); + htole16(buf + 2, end_group_handle); + if (service_uuid16 != 0) { + htole16(buf + 4, service_uuid16); + } else { + memcpy(buf + 4, service_uuid128, 16); + } + + return 0; +} + +static int +ble_att_svr_tx_read_group_type(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan, + struct ble_att_read_group_type_req *req, + uint8_t *group_uuid128, uint16_t *err_handle) +{ + struct ble_att_read_group_type_rsp rsp; + struct ble_att_svr_entry *entry; + struct os_mbuf *txom; + uint16_t start_group_handle; + uint16_t end_group_handle; + uint16_t service_uuid16; + uint8_t service_uuid128[16]; + void *rsp_buf; + int rc; + + *err_handle = req->bagq_start_handle; + + txom = ble_att_get_pkthdr(); + if (txom == NULL) { + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; + } + + /* Reserve space for the response base. */ + rsp_buf = os_mbuf_extend(txom, BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ); + if (rsp_buf == NULL) { + rc = BLE_ATT_ERR_INSUFFICIENT_RES; + goto done; + } + + start_group_handle = 0; + rsp.bagp_length = 0; + STAILQ_FOREACH(entry, &ble_att_svr_list, ha_next) { + if (entry->ha_handle_id < req->bagq_start_handle) { + continue; + } + if (entry->ha_handle_id > req->bagq_end_handle) { + /* The full input range has been searched. */ + rc = 0; + goto done; + } + + if (start_group_handle != 0) { + /* We have already found the start of a group. */ + if (ble_att_svr_is_valid_group_member(entry->ha_uuid)) { + /* This attribute is part of the current group. */ + end_group_handle = entry->ha_handle_id; + } else { + /* This attribute marks the end of the group. Write an entry + * representing the group to the response. + */ + rc = ble_att_svr_read_group_type_entry_write( + txom, ble_l2cap_chan_mtu(chan), + start_group_handle, end_group_handle, + service_uuid16, service_uuid128); + start_group_handle = 0; + end_group_handle = 0; + if (rc != 0) { + *err_handle = entry->ha_handle_id; + goto done; + } + } + } + + if (start_group_handle == 0) { + /* We are looking for the start of a group. */ + if (memcmp(entry->ha_uuid, group_uuid128, 16) == 0) { + /* Found a group start. Read the group UUID. */ + rc = ble_att_svr_service_uuid(entry, &service_uuid16, + service_uuid128); + if (rc != 0) { + *err_handle = entry->ha_handle_id; + rc = BLE_ATT_ERR_UNLIKELY; + goto done; + } + + /* Make sure the group UUID lengths are consistent. If this + * group has a different length UUID, then cut the response + * short. + */ + switch (rsp.bagp_length) { + case 0: + if (service_uuid16 != 0) { + rsp.bagp_length = + BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 2; + } else { + rsp.bagp_length = + BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 16; + } + break; + + case BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 2: + if (service_uuid16 == 0) { + rc = 0; + goto done; + } + break; + + case BLE_ATT_READ_GROUP_TYPE_ADATA_BASE_SZ + 16: + if (service_uuid16 != 0) { + rc = 0; + goto done; + } + break; + + default: + assert(0); + goto done; + } + + start_group_handle = entry->ha_handle_id; + end_group_handle = entry->ha_handle_id; + } + } + } + + rc = 0; + +done: + if (rc == 0) { + if (start_group_handle != 0) { + /* A group was being processed. Add its corresponding entry to the + * response. + */ + rc = ble_att_svr_read_group_type_entry_write( + txom, ble_l2cap_chan_mtu(chan), + start_group_handle, end_group_handle, + service_uuid16, service_uuid128); + } else { + rc = BLE_ATT_ERR_ATTR_NOT_FOUND; + } + } + + if (rc == 0 || rc == EMSGSIZE) { + rc = ble_att_read_group_type_rsp_write( + rsp_buf, BLE_ATT_READ_GROUP_TYPE_RSP_BASE_SZ, &rsp); + assert(rc == 0); + + rc = ble_l2cap_tx(conn, chan, txom); + } else { + os_mbuf_free_chain(txom); + } + + return rc; +} + + +int +ble_att_svr_rx_read_group_type(struct ble_hs_conn *conn, + struct ble_l2cap_chan *chan, + struct os_mbuf **rxom) +{ + struct ble_att_read_group_type_req req; + uint16_t err_handle; + uint8_t uuid128[16]; + int rc; + + err_handle = 0; + + *rxom = os_mbuf_pullup(*rxom, OS_MBUF_PKTLEN(*rxom)); + if (*rxom == NULL) { + rc = ENOMEM; + goto err; + } + + rc = ble_att_read_group_type_req_parse((*rxom)->om_data, (*rxom)->om_len, + &req); + if (rc != 0) { + goto err; + } + err_handle = req.bagq_start_handle; + + rc = ble_hs_uuid_extract(*rxom, BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ, + uuid128); + if (rc != 0) { + goto err; + } + + if (!ble_att_svr_is_valid_group_type(uuid128)) { + rc = EINVAL; // XXX + goto err; + } + + rc = ble_att_svr_tx_read_group_type(conn, chan, &req, uuid128, + &err_handle); + if (rc != 0) { + goto err; + } + + return 0; + +err: + ble_att_svr_tx_error_rsp(conn, chan, BLE_ATT_OP_READ_GROUP_TYPE_REQ, + err_handle, rc); + return rc; +} + +static int ble_att_svr_tx_write_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan) { struct os_mbuf *txom; uint8_t *dst; int rc; - txom = os_mbuf_get_pkthdr(&ble_hs_mbuf_pool, 0); + txom = ble_att_get_pkthdr(); if (txom == NULL) { rc = BLE_ATT_ERR_INSUFFICIENT_RES; goto err; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_gatt.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_gatt.c b/net/nimble/host/src/ble_gatt.c index d8575c4..55e4b0b 100644 --- a/net/nimble/host/src/ble_gatt.c +++ b/net/nimble/host/src/ble_gatt.c @@ -28,9 +28,6 @@ #include "ble_att_cmd.h" #include "ble_att_priv.h" -#define BLE_ATT_UUID_PRIMARY_SERVICE 0x2800 -#define BLE_ATT_UUID_CHARACTERISTIC 0x2803 - struct ble_gatt_entry { STAILQ_ENTRY(ble_gatt_entry) next; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_hs.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs.c b/net/nimble/host/src/ble_hs.c index b6800e3..b196f78 100644 --- a/net/nimble/host/src/ble_hs.c +++ b/net/nimble/host/src/ble_hs.c @@ -39,7 +39,7 @@ static struct os_task ble_hs_task; static os_stack_t ble_hs_stack[BLE_HS_STACK_SIZE]; -#define HCI_CMD_BUFS (8) +#define HCI_CMD_BUFS (6) #define HCI_CMD_BUF_SIZE (260) /* XXX: temporary, Fix later */ struct os_mempool g_hci_cmd_pool; static os_membuf_t g_hci_cmd_buf[OS_MEMPOOL_BYTES(HCI_CMD_BUFS, http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_hs_uuid.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_hs_uuid.c b/net/nimble/host/src/ble_hs_uuid.c index fe2dfae..eb3d943 100644 --- a/net/nimble/host/src/ble_hs_uuid.c +++ b/net/nimble/host/src/ble_hs_uuid.c @@ -114,7 +114,7 @@ ble_hs_uuid_extract(struct os_mbuf *om, int off, void *uuid128) int remlen; int rc; - remlen = OS_MBUF_PKTHDR(om)->omp_len; + remlen = OS_MBUF_PKTHDR(om)->omp_len - off; switch (remlen) { case 2: rc = os_mbuf_copydata(om, off, 2, &uuid16); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/ble_l2cap.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/ble_l2cap.c b/net/nimble/host/src/ble_l2cap.c index 2a4e81b..f75e91d 100644 --- a/net/nimble/host/src/ble_l2cap.c +++ b/net/nimble/host/src/ble_l2cap.c @@ -147,7 +147,8 @@ ble_l2cap_rx(struct ble_hs_conn *conn, int rc; /* XXX: HCI-fragmentation unsupported. */ - assert(BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc) == BLE_HCI_PB_FULL); + assert(BLE_HCI_DATA_PB(hci_hdr->hdh_handle_pb_bc) == + BLE_HCI_PB_FIRST_FLUSH); rc = ble_l2cap_parse_hdr(om, 0, &l2cap_hdr); if (rc != 0) { @@ -196,6 +197,7 @@ ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan, } rc = host_hci_data_tx(conn, om); + om = NULL; if (rc != 0) { goto err; } http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/host_hci.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/host_hci.c b/net/nimble/host/src/host_hci.c index 67d3def..7ff42de 100644 --- a/net/nimble/host/src/host_hci.c +++ b/net/nimble/host/src/host_hci.c @@ -413,6 +413,19 @@ host_hci_data_hdr_strip(struct os_mbuf *om, struct hci_data_hdr *hdr) return 0; } +static void +host_hci_log_pkt(struct os_mbuf *om) +{ + uint8_t u8; + int i; + + for (i = 0; i < OS_MBUF_PKTLEN(om); i++) { + os_mbuf_copydata(om, i, 1, &u8); + console_printf("0x%02x ", u8); + } + console_printf("\n"); +} + /** * Called when a data packet is received from the controller. This function * consumes the supplied mbuf, regardless of the outcome. @@ -430,6 +443,9 @@ host_hci_data_rx(struct os_mbuf *om) uint16_t handle; int rc; + console_printf("host_hci_data_rx(): "); + host_hci_log_pkt(om); + rc = host_hci_data_hdr_strip(om, &hci_hdr); if (rc != 0) { goto done; @@ -501,11 +517,14 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *om) * requirements. For now, never fragment. */ om = host_hci_data_hdr_prepend(om, connection->bhc_handle, - BLE_HCI_PB_FULL); + BLE_HCI_PB_FIRST_NON_FLUSH); if (om == NULL) { return ENOMEM; } + console_printf("host_hci_data_tx(): "); + host_hci_log_pkt(om); + rc = ble_hs_tx_data(om); if (rc != 0) { return rc; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/test/ble_hs_test_util.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_hs_test_util.c b/net/nimble/host/src/test/ble_hs_test_util.c index 488e0d4..d7b6d3c 100644 --- a/net/nimble/host/src/test/ble_hs_test_util.c +++ b/net/nimble/host/src/test/ble_hs_test_util.c @@ -142,7 +142,8 @@ ble_hs_test_util_l2cap_rx_payload_flat(struct ble_hs_conn *conn, TEST_ASSERT_FATAL(om != NULL); hci_hdr.hdh_handle_pb_bc = - host_hci_handle_pb_bc_join(conn->bhc_handle, BLE_HCI_PB_FULL, 0); + host_hci_handle_pb_bc_join(conn->bhc_handle, + BLE_HCI_PB_FIRST_FLUSH, 0); hci_hdr.hdh_len = OS_MBUF_PKTHDR(om)->omp_len; rc = ble_l2cap_rx(conn, &hci_hdr, om); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/c1ac77ce/net/nimble/host/src/test/ble_l2cap_test.c ---------------------------------------------------------------------- diff --git a/net/nimble/host/src/test/ble_l2cap_test.c b/net/nimble/host/src/test/ble_l2cap_test.c index 48fb259..a1fe064 100644 --- a/net/nimble/host/src/test/ble_l2cap_test.c +++ b/net/nimble/host/src/test/ble_l2cap_test.c @@ -39,7 +39,7 @@ TEST_CASE(l2cap_test_bad_header) TEST_ASSERT_FATAL(conn != NULL); hci_hdr.hdh_handle_pb_bc = - host_hci_handle_pb_bc_join(0, BLE_HCI_PB_FULL, 0); + host_hci_handle_pb_bc_join(0, BLE_HCI_PB_FIRST_FLUSH, 0); hci_hdr.hdh_len = 10; /*** HCI header indicates a length of 10, but L2CAP header has a length