From bdc10744fb338ae197692713a0b48a7ccc36f566 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 26 Apr 2020 10:25:59 +0200 Subject: Add Nimble in libs directory --- .../gap/include/services/gap/ble_svc_gap.h | 54 ++++ .../mynewt-nimble/nimble/host/services/gap/pkg.yml | 34 +++ .../nimble/host/services/gap/src/ble_svc_gap.c | 298 +++++++++++++++++++++ .../nimble/host/services/gap/syscfg.yml | 83 ++++++ 4 files changed, 469 insertions(+) create mode 100644 src/libs/mynewt-nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h create mode 100644 src/libs/mynewt-nimble/nimble/host/services/gap/pkg.yml create mode 100644 src/libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c create mode 100644 src/libs/mynewt-nimble/nimble/host/services/gap/syscfg.yml (limited to 'src/libs/mynewt-nimble/nimble/host/services/gap') diff --git a/src/libs/mynewt-nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h b/src/libs/mynewt-nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h new file mode 100644 index 00000000..d7b60df4 --- /dev/null +++ b/src/libs/mynewt-nimble/nimble/host/services/gap/include/services/gap/ble_svc_gap.h @@ -0,0 +1,54 @@ +/* + * 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_GAP_ +#define H_BLE_SVC_GAP_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define BLE_SVC_GAP_UUID16 0x1800 +#define BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME 0x2a00 +#define BLE_SVC_GAP_CHR_UUID16_APPEARANCE 0x2a01 +#define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS 0x2a04 +#define BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION 0x2aa6 + +#define BLE_SVC_GAP_APPEARANCE_GEN_UNKNOWN 0 +#define BLE_SVC_GAP_APPEARANCE_GEN_COMPUTER 128 +#define BLE_SVC_GAP_APPEARANCE_CYC_SPEED_AND_CADENCE_SENSOR 1157 + +typedef void (ble_svc_gap_chr_changed_fn) (uint16_t uuid); + +void ble_svc_gap_set_chr_changed_cb(ble_svc_gap_chr_changed_fn *cb); + +const char *ble_svc_gap_device_name(void); +int ble_svc_gap_device_name_set(const char *name); +uint16_t ble_svc_gap_device_appearance(void); +int ble_svc_gap_device_appearance_set(uint16_t appearance); + +void ble_svc_gap_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libs/mynewt-nimble/nimble/host/services/gap/pkg.yml b/src/libs/mynewt-nimble/nimble/host/services/gap/pkg.yml new file mode 100644 index 00000000..a2ef756e --- /dev/null +++ b/src/libs/mynewt-nimble/nimble/host/services/gap/pkg.yml @@ -0,0 +1,34 @@ +# +# 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: nimble/host/services/gap +pkg.description: Implements the GAP Service. +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - ble + - bluetooth + - nimble + - gap + +pkg.deps: + - nimble/host + +pkg.init: + ble_svc_gap_init: 'MYNEWT_VAL(BLE_SVC_GAP_SYSINIT_STAGE)' diff --git a/src/libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c b/src/libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c new file mode 100644 index 00000000..e79b2b87 --- /dev/null +++ b/src/libs/mynewt-nimble/nimble/host/services/gap/src/ble_svc_gap.c @@ -0,0 +1,298 @@ +/* + * 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 +#include + +#include "sysinit/sysinit.h" +#include "host/ble_hs.h" +#include "services/gap/ble_svc_gap.h" +#include "os/endian.h" + +#define PPCP_ENABLED \ + MYNEWT_VAL(BLE_ROLE_PERIPHERAL) && \ + (MYNEWT_VAL(BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL) || \ + MYNEWT_VAL(BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL) || \ + MYNEWT_VAL(BLE_SVC_GAP_PPCP_SLAVE_LATENCY) || \ + MYNEWT_VAL(BLE_SVC_GAP_PPCP_SUPERVISION_TMO)) + +#define BLE_SVC_GAP_NAME_MAX_LEN \ + MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH) + +static ble_svc_gap_chr_changed_fn *ble_svc_gap_chr_changed_cb_fn; + +static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] = + MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME); +static uint16_t ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE); + +static int +ble_svc_gap_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_gap_defs[] = { + { + /*** Service: GAP. */ + .type = BLE_GATT_SVC_TYPE_PRIMARY, + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_UUID16), + .characteristics = (struct ble_gatt_chr_def[]) { { + /*** Characteristic: Device Name. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME), + .access_cb = ble_svc_gap_access, + .flags = BLE_GATT_CHR_F_READ | +#if MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM) >= 0 + BLE_GATT_CHR_F_WRITE | + MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM) | +#endif + 0, + }, { + /*** Characteristic: Appearance. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_APPEARANCE), + .access_cb = ble_svc_gap_access, + .flags = BLE_GATT_CHR_F_READ | +#if MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) >= 0 + BLE_GATT_CHR_F_WRITE | + MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) | +#endif + 0, + }, { +#if PPCP_ENABLED + /*** Characteristic: Peripheral Preferred Connection Parameters. */ + .uuid = + BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS), + .access_cb = ble_svc_gap_access, + .flags = BLE_GATT_CHR_F_READ, + }, { +#endif +#if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0 + /*** Characteristic: Central Address Resolution. */ + .uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION), + .access_cb = ble_svc_gap_access, + .flags = BLE_GATT_CHR_F_READ, + }, { +#endif + 0, /* No more characteristics in this service. */ + } }, + }, + + { + 0, /* No more services. */ + }, +}; + +static int +ble_svc_gap_device_name_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + int rc; + + rc = os_mbuf_append(ctxt->om, ble_svc_gap_name, strlen(ble_svc_gap_name)); + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_gap_device_name_write_access(struct ble_gatt_access_ctxt *ctxt) +{ +#if MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM) < 0 + assert(0); + return 0; +#else + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(ctxt->om); + if (om_len > BLE_SVC_GAP_NAME_MAX_LEN) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(ctxt->om, ble_svc_gap_name, om_len, NULL); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + ble_svc_gap_name[om_len] = '\0'; + + if (ble_svc_gap_chr_changed_cb_fn) { + ble_svc_gap_chr_changed_cb_fn(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME); + } + + return rc; +#endif +} + +static int +ble_svc_gap_appearance_read_access(struct ble_gatt_access_ctxt *ctxt) +{ + uint16_t appearance = htole16(ble_svc_gap_appearance); + int rc; + + rc = os_mbuf_append(ctxt->om, &appearance, sizeof(appearance)); + + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +} + +static int +ble_svc_gap_appearance_write_access(struct ble_gatt_access_ctxt *ctxt) +{ +#if MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) < 0 + assert(0); + return 0; +#else + uint16_t om_len; + int rc; + + om_len = OS_MBUF_PKTLEN(ctxt->om); + if (om_len != sizeof(ble_svc_gap_appearance)) { + return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN; + } + + rc = ble_hs_mbuf_to_flat(ctxt->om, &ble_svc_gap_appearance, om_len, NULL); + if (rc != 0) { + return BLE_ATT_ERR_UNLIKELY; + } + + ble_svc_gap_appearance = le16toh(ble_svc_gap_appearance); + + if (ble_svc_gap_chr_changed_cb_fn) { + ble_svc_gap_chr_changed_cb_fn(BLE_SVC_GAP_CHR_UUID16_APPEARANCE); + } + + return rc; +#endif +} + +static int +ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle, + struct ble_gatt_access_ctxt *ctxt, void *arg) +{ + uint16_t uuid16; +#if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0 + uint8_t central_ar = MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION); +#endif +#if PPCP_ENABLED + uint16_t ppcp[4] = { + htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL)), + htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL)), + htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SLAVE_LATENCY)), + htole16(MYNEWT_VAL(BLE_SVC_GAP_PPCP_SUPERVISION_TMO)) + }; +#endif + int rc; + + uuid16 = ble_uuid_u16(ctxt->chr->uuid); + assert(uuid16 != 0); + + switch (uuid16) { + case BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_gap_device_name_read_access(ctxt); + } else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = ble_svc_gap_device_name_write_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + + case BLE_SVC_GAP_CHR_UUID16_APPEARANCE: + if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { + rc = ble_svc_gap_appearance_read_access(ctxt); + } else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + rc = ble_svc_gap_appearance_write_access(ctxt); + } else { + assert(0); + rc = BLE_ATT_ERR_UNLIKELY; + } + return rc; + +#if PPCP_ENABLED + case BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, &ppcp, sizeof(ppcp)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +#endif + +#if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0 + case BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION: + assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR); + rc = os_mbuf_append(ctxt->om, ¢ral_ar, sizeof(central_ar)); + return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; +#endif + + default: + assert(0); + return BLE_ATT_ERR_UNLIKELY; + } +} + +const char * +ble_svc_gap_device_name(void) +{ + return ble_svc_gap_name; +} + +int +ble_svc_gap_device_name_set(const char *name) +{ + int len; + + len = strlen(name); + if (len > BLE_SVC_GAP_NAME_MAX_LEN) { + return BLE_HS_EINVAL; + } + + memcpy(ble_svc_gap_name, name, len); + ble_svc_gap_name[len] = '\0'; + + return 0; +} + +uint16_t +ble_svc_gap_device_appearance(void) +{ + return ble_svc_gap_appearance; +} + +int +ble_svc_gap_device_appearance_set(uint16_t appearance) +{ + ble_svc_gap_appearance = appearance; + + return 0; +} + +void +ble_svc_gap_set_chr_changed_cb(ble_svc_gap_chr_changed_fn *cb) +{ + ble_svc_gap_chr_changed_cb_fn = cb; +} + +void +ble_svc_gap_init(void) +{ + int rc; + + /* Ensure this function only gets called by sysinit. */ + SYSINIT_ASSERT_ACTIVE(); + + rc = ble_gatts_count_cfg(ble_svc_gap_defs); + SYSINIT_PANIC_ASSERT(rc == 0); + + rc = ble_gatts_add_svcs(ble_svc_gap_defs); + SYSINIT_PANIC_ASSERT(rc == 0); +} diff --git a/src/libs/mynewt-nimble/nimble/host/services/gap/syscfg.yml b/src/libs/mynewt-nimble/nimble/host/services/gap/syscfg.yml new file mode 100644 index 00000000..ad6aa7ef --- /dev/null +++ b/src/libs/mynewt-nimble/nimble/host/services/gap/syscfg.yml @@ -0,0 +1,83 @@ +# 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. +# + +syscfg.defs: + BLE_SVC_GAP_DEVICE_NAME: + description: > + Default value for "Device Name" characteristics, unless overwritten + by application. + value: '"nimble"' + BLE_SVC_GAP_DEVICE_NAME_WRITE_PERM: + description: > + Defines permissions for writing "Device Name" characteristics. Can + be zero to allow write without extra permissions or combination of: + BLE_GATT_CHR_F_WRITE_ENC + BLE_GATT_CHR_F_WRITE_AUTHEN + BLE_GATT_CHR_F_WRITE_AUTHOR + Set to '-1' to make characteristic read only. + value: -1 + BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH: + description: Maximum length for "Device Name" characteristics + value: 31 + BLE_SVC_GAP_APPEARANCE: + description: 'Device appearance' + value: 0 + BLE_SVC_GAP_APPEARANCE_WRITE_PERM: + description: > + Defines permissions for writing "Appearance" characteristics. Can + be zero to allow write without extra permissions or combination of: + BLE_GATT_CHR_F_WRITE_ENC + BLE_GATT_CHR_F_WRITE_AUTHEN + BLE_GATT_CHR_F_WRITE_AUTHOR + Set to '-1' to make characteristic read only. + value: -1 + + # Setting all values for PPCP to '0' will disable characteristic! + BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: + description: > + Value of "minimum connection interval" of PPCP characteristic as + defined by Core specification 5.0, Vol 3, Part C, section 12.3. + value: 0 + BLE_SVC_GAP_PPCP_MAX_CONN_INTERVAL: + description: > + Value of "maximum connection interval" of PPCP characteristic as + defined by Core specification 5.0, Vol 3, Part C, section 12.3. + value: 0 + BLE_SVC_GAP_PPCP_SLAVE_LATENCY: + description: > + Value of "slave latency" of PPCP characteristic as defined by Core + specification 5.0, Vol 3, Part C, section 12.3. + value: 0 + BLE_SVC_GAP_PPCP_SUPERVISION_TMO: + description: > + Value of "connection supervision timeout multiplier" of PPCP + characteristic as defined by Core specification 5.0, Vol 3, Part C, + section 12.3. + value: 0 + + BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION: + description: > + Value of "Central Address Resolution" characteristics, as defined + by Core specification 5.0, Vol 3, Part C, section 12. + Set to '-1' to disable. + value: -1 + + BLE_SVC_GAP_SYSINIT_STAGE: + description: > + Sysinit stage for the GAP BLE service. + value: 301 -- cgit v1.2.3