diff --git a/nimble/host/include/host/ble_hs.h b/nimble/host/include/host/ble_hs.h index ba874b1c9..6719a6f05 100644 --- a/nimble/host/include/host/ble_hs.h +++ b/nimble/host/include/host/ble_hs.h @@ -364,6 +364,17 @@ void ble_hs_evq_set(struct ble_npl_eventq *evq); */ void ble_hs_init(void); +/** + * @brief Called when the system is shutting down. Stops the BLE host. + * + * @param reason The reason for the shutdown. One of the + * HAL_RESET_[...] codes or an + * implementation-defined value. + * + * @return SYSDOWN_IN_PROGRESS. + */ +int ble_hs_shutdown(int reason); + #ifdef __cplusplus } #endif diff --git a/nimble/host/pkg.yml b/nimble/host/pkg.yml index d91454ed8..7c8c021b1 100644 --- a/nimble/host/pkg.yml +++ b/nimble/host/pkg.yml @@ -50,3 +50,6 @@ pkg.req_apis: pkg.init: ble_hs_init: 200 + +pkg.down.BLE_HS_STOP_ON_SHUTDOWN: + ble_hs_shutdown: 200 diff --git a/nimble/host/src/ble_hs_shutdown.c b/nimble/host/src/ble_hs_shutdown.c new file mode 100644 index 000000000..f29d4a669 --- /dev/null +++ b/nimble/host/src/ble_hs_shutdown.c @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#if MYNEWT + +#include "os/mynewt.h" +#include "ble_hs_priv.h" + +static struct ble_hs_stop_listener ble_hs_shutdown_stop_listener; + +/** + * Called when the host stop procedure has completed. + */ +static void +ble_hs_shutdown_stop_cb(int status, void *arg) +{ + SYSDOWN_ASSERT_ACTIVE(); + + /* Indicate to sysdown that the host is fully shut down. */ + sysdown_release(); +} + +int +ble_hs_shutdown(int reason) +{ + int rc; + + /* Ensure this function only gets called by sysdown. */ + SYSDOWN_ASSERT_ACTIVE(); + + /* Initiate a host stop procedure. */ + rc = ble_hs_stop(&ble_hs_shutdown_stop_listener, ble_hs_shutdown_stop_cb, + NULL); + switch (rc) { + case 0: + /* Stop initiated. Wait for result to be reported asynchronously. */ + return SYSDOWN_IN_PROGRESS; + + case BLE_HS_EBUSY: + /* Already stopping. Wait for result to be reported asynchronously. */ + return SYSDOWN_IN_PROGRESS; + + case BLE_HS_EALREADY: + /* Already stopped. Shutdown complete. */ + return SYSDOWN_COMPLETE; + + default: + BLE_HS_LOG(ERROR, "ble_hs_shutdown: failed to stop host; rc=%d\n", rc); + return SYSDOWN_COMPLETE; + } +} + +#endif diff --git a/nimble/host/syscfg.yml b/nimble/host/syscfg.yml index 90a61c190..d16d93fb0 100644 --- a/nimble/host/syscfg.yml +++ b/nimble/host/syscfg.yml @@ -422,5 +422,12 @@ syscfg.defs: a necessary workaround when interfacing with some controllers. value: 0 + BLE_HS_STOP_ON_SHUTDOWN: + description: > + Stops the Bluetooth host when the system shuts down. Stopping + entails aborting all GAP procedures and terminating open + connections. + value: 1 + syscfg.vals.BLE_MESH: BLE_SM_SC: 1