You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/04/20 03:17:45 UTC
[3/7] incubator-mynewt-core git commit: ble host - major changes.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatts.c b/net/nimble/host/src/ble_gatts.c
index 007958b..73bee78 100644
--- a/net/nimble/host/src/ble_gatts.c
+++ b/net/nimble/host/src/ble_gatts.c
@@ -639,7 +639,7 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_hs_conn *conn;
int rc;
- ble_hs_conn_lock();
+ ble_hs_lock();
conn = ble_hs_conn_find(conn_handle);
if (conn == NULL) {
@@ -649,7 +649,7 @@ ble_gatts_clt_cfg_access(uint16_t conn_handle, uint16_t attr_handle,
ctxt, arg);
}
- ble_hs_conn_unlock();
+ ble_hs_unlock();
return rc;
}
@@ -1129,7 +1129,7 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
return;
}
- ble_hs_conn_lock();
+ ble_hs_lock();
for (conn = ble_hs_conn_first();
conn != NULL;
@@ -1148,7 +1148,7 @@ ble_gatts_chr_updated(uint16_t chr_def_handle)
}
}
- ble_hs_conn_unlock();
+ ble_hs_unlock();
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_block.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_block.c b/net/nimble/host/src/ble_hci_block.c
deleted file mode 100644
index e8112c1..0000000
--- a/net/nimble/host/src/ble_hci_block.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/**
- * 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.
- */
-
-/**
- * Provides a blocking HCI send interface. These functions must not be called
- * from the ble_hs task.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "os/os.h"
-#include "ble_hs_priv.h"
-
-#define BLE_HCI_BLOCK_TIMEOUT (OS_TICKS_PER_SEC)
-
-/** Protects resources from 2+ application tasks. */
-static struct os_mutex ble_hci_block_mutex;
-
-/** Used to block on expected HCI acknowledgements. */
-static struct os_sem ble_hci_block_sem;
-
-/** Global state corresponding to the current blocking operation. */
-static void *ble_hci_block_cmd;
-static void *ble_hci_block_evt_buf;
-static uint8_t ble_hci_block_evt_buf_len;
-static struct ble_hci_block_result *ble_hci_block_result;
-static uint8_t ble_hci_block_handle;
-static int ble_hci_block_status;
-
-/**
- * Used when the client passes a null result pointer (doesn't care about the
- * event data).
- */
-static struct ble_hci_block_result ble_hci_block_result_anon;
-
-#if PHONY_HCI_ACKS
-static uint8_t ble_hci_block_phony_ack_buf[256];
-static ble_hci_block_phony_ack_fn *ble_hci_block_phony_ack_cb;
-#endif
-
-/**
- * Copies the parameters from an acknowledgement into the application event
- * buffer.
- */
-static void
-ble_hci_block_copy_evt_data(void *src_data, uint8_t src_data_len)
-{
- if (ble_hci_block_evt_buf_len > src_data_len) {
- ble_hci_block_result->evt_buf_len = ble_hci_block_evt_buf_len;
- } else {
- ble_hci_block_result->evt_buf_len = src_data_len;
- }
- ble_hci_block_result->evt_total_len = src_data_len;
-
- if (ble_hci_block_result->evt_buf_len > 0) {
- memcpy(ble_hci_block_evt_buf, src_data,
- ble_hci_block_result->evt_buf_len);
- }
-}
-
-/**
- * Callback that gets executed upon receiving an HCI acknowledgement.
- */
-static void
-ble_hci_block_ack_cb(struct ble_hci_ack *ack, void *arg)
-{
- uint8_t *ack_params;
- uint8_t ack_params_len;
-
- BLE_HS_DBG_ASSERT(ack->bha_hci_handle == ble_hci_block_handle);
-
- ack_params = ack->bha_params;
- ack_params_len = ack->bha_params_len;
- if (ack->bha_params_len > 0) {
- /* +1/-1 to ignore the status byte. */
- ack_params++;
- ack_params_len--;
- }
- ble_hci_block_copy_evt_data(ack_params, ack_params_len);
- ble_hci_block_status = ack->bha_status;
-
- /* Wake the application task up now that the acknowledgement has been
- * received.
- */
- os_sem_release(&ble_hci_block_sem);
-}
-
-/**
- * Callback that gets executed when an HCI tx reservation is services.
- * Transmits the HCI command specifed by the client task.
- */
-static int
-ble_hci_block_tx_cb(void *arg)
-{
- int rc;
-
- ble_hci_sched_set_ack_cb(ble_hci_block_ack_cb, NULL);
-
- rc = host_hci_cmd_send_buf(ble_hci_block_cmd);
- if (rc != 0) {
- os_sem_release(&ble_hci_block_sem);
- return rc;
- }
-
- return 0;
-}
-
-#if PHONY_HCI_ACKS
-void
-ble_hci_block_set_phony_ack_cb(ble_hci_block_phony_ack_fn *cb)
-{
- ble_hci_block_phony_ack_cb = cb;
-}
-#endif
-
-
-static int
-ble_hci_block_wait_for_ack(void)
-{
-#if PHONY_HCI_ACKS
- int rc;
-
- if (!os_started()) {
- /* Force the pending HCI command to transmit. */
- ble_hci_sched_wakeup();
- }
- if (ble_hci_block_phony_ack_cb == NULL) {
- return BLE_HS_ETIMEOUT;
- } else {
- rc = ble_hci_block_phony_ack_cb(ble_hci_block_cmd,
- ble_hci_block_phony_ack_buf,
- sizeof ble_hci_block_phony_ack_buf);
- if (rc == 0) {
- rc = host_hci_event_rx(ble_hci_block_phony_ack_buf);
- if (rc == 0) {
- rc = ble_hci_block_status;
- }
- }
-
- return rc;
- }
-#else
- int rc;
-
- rc = os_sem_pend(&ble_hci_block_sem, BLE_HCI_BLOCK_TIMEOUT);
- switch (rc) {
- case 0:
- rc = ble_hci_block_status;
- break;
-
- case OS_NOT_STARTED:
- rc = BLE_HS_EOS;
- break;
-
- case OS_TIMEOUT:
- rc = BLE_HS_ETIMEOUT;
- break;
-
- default:
- BLE_HS_DBG_ASSERT(0);
- rc = BLE_HS_EOS;
- break;
- }
-
- return rc;
-#endif
-}
-
-/**
- * Performs a blocking HCI send. Must not be called from the ble_hs task.
- */
-int
-ble_hci_block_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
- struct ble_hci_block_result *result)
-{
- int rc;
-
- BLE_HS_DBG_ASSERT(os_sched_get_current_task() != &ble_hs_task);
-
- os_mutex_pend(&ble_hci_block_mutex, OS_WAIT_FOREVER);
-
- ble_hci_block_cmd = cmd;
- ble_hci_block_evt_buf = evt_buf;
- ble_hci_block_evt_buf_len = evt_buf_len;
-
- if (result != NULL) {
- ble_hci_block_result = result;
- } else {
- ble_hci_block_result = &ble_hci_block_result_anon;
- }
- memset(ble_hci_block_result, 0, sizeof *ble_hci_block_result);
-
- rc = ble_hci_sched_enqueue(ble_hci_block_tx_cb, NULL,
- &ble_hci_block_handle);
- if (rc == 0) {
- rc = ble_hci_block_wait_for_ack();
- }
-
- os_mutex_release(&ble_hci_block_mutex);
- return rc;
-}
-
-void
-ble_hci_block_init(void)
-{
- int rc;
-
- rc = os_mutex_init(&ble_hci_block_mutex);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-
- rc = os_sem_init(&ble_hci_block_sem, 0);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_sched.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_sched.c b/net/nimble/host/src/ble_hci_sched.c
deleted file mode 100644
index 068e986..0000000
--- a/net/nimble/host/src/ble_hci_sched.c
+++ /dev/null
@@ -1,474 +0,0 @@
-/**
- * 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 <stdlib.h>
-#include <string.h>
-#include "os/queue.h"
-#include "os/os_mempool.h"
-#include "ble_hs_priv.h"
-
-struct ble_hci_sched_entry {
- STAILQ_ENTRY(ble_hci_sched_entry) next;
-
- ble_hci_sched_tx_fn *tx_cb;
- void *tx_cb_arg;
-
- uint8_t handle;
-};
-
-static STAILQ_HEAD(, ble_hci_sched_entry) ble_hci_sched_list;
-
-static void *ble_hci_sched_entry_mem;
-static struct os_mempool ble_hci_sched_entry_pool;
-static struct ble_hci_sched_entry *ble_hci_sched_cur_entry;
-static uint8_t ble_hci_sched_prev_handle;
-
-static ble_hci_sched_ack_fn *ble_hci_sched_ack_cb;
-static void *ble_hci_sched_ack_arg;
-
-static struct os_mutex ble_hci_sched_mutex;
-
-static void
-ble_hci_sched_lock(void)
-{
- struct os_task *owner;
- int rc;
-
- owner = ble_hci_sched_mutex.mu_owner;
- BLE_HS_DBG_ASSERT_EVAL(owner == NULL ||
- owner != os_sched_get_current_task());
-
- rc = os_mutex_pend(&ble_hci_sched_mutex, 0xffffffff);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-static void
-ble_hci_sched_unlock(void)
-{
- int rc;
-
- rc = os_mutex_release(&ble_hci_sched_mutex);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_hci_sched_locked_by_cur_task(void)
-{
- struct os_task *owner;
-
- owner = ble_hci_sched_mutex.mu_owner;
- return owner != NULL && owner == os_sched_get_current_task();
-}
-
-/**
- * Lock restrictions: none.
- */
-static struct ble_hci_sched_entry *
-ble_hci_sched_entry_alloc(void)
-{
- struct ble_hci_sched_entry *entry;
-
- entry = os_memblock_get(&ble_hci_sched_entry_pool);
- if (entry != NULL) {
- memset(entry, 0, sizeof *entry);
- }
-
- return entry;
-}
-
-/**
- * Lock restrictions: none.
- */
-static void
-ble_hci_sched_entry_free(struct ble_hci_sched_entry *entry)
-{
- int rc;
-
- rc = os_memblock_put(&ble_hci_sched_entry_pool, entry);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0);
-}
-
-/**
- * Removes the specified entry from the HCI reservation list.
- *
- * Lock restrictions:
- * o Caller locks hci_sched.
- */
-static void
-ble_hci_sched_entry_remove(struct ble_hci_sched_entry *entry,
- struct ble_hci_sched_entry *prev)
-{
- if (os_started()) {
- BLE_HS_DBG_ASSERT(ble_hci_sched_locked_by_cur_task());
- }
-
- if (prev == NULL) {
- BLE_HS_DBG_ASSERT(STAILQ_FIRST(&ble_hci_sched_list) == entry);
- STAILQ_REMOVE_HEAD(&ble_hci_sched_list, next);
- } else {
- BLE_HS_DBG_ASSERT(STAILQ_NEXT(prev, next) == prev);
- STAILQ_NEXT(prev, next) = STAILQ_NEXT(prev, next);
- }
-}
-
-/**
- * Generates an HCI handle for a newly-allocated entry.
- *
- * Lock restrictions:
- * o Caller unlocks hci_sched.
- *
- * @return A new HCI handle.
- */
-static uint8_t
-ble_hci_sched_new_handle(void)
-{
- uint8_t handle;
-
- ble_hci_sched_lock();
-
- ble_hci_sched_prev_handle++;
- if (ble_hci_sched_prev_handle == BLE_HCI_SCHED_HANDLE_NONE) {
- ble_hci_sched_prev_handle++;
- }
-
- handle = ble_hci_sched_prev_handle;
-
- ble_hci_sched_unlock();
-
- return handle;
-}
-
-/**
- * Schedules an HCI transmit slot. When it is the slot's turn to transmit,
- * the specified callback is executed. The expectation is for the callback to
- * transmit an HCI command via the functions in host_hci_cmd.c.
- *
- * Lock restrictions:
- * o Caller unlocks hci_sched.
- *
- * @param tx_cb Callback that gets executed when a transmit
- * slot is available; should send a single
- * HCI command.
- * @param tx_cb_arg Argument that gets passed to the tx callback.
- * @param out_hci_handle On success, the HCI slot handle gets written
- * here. This handle can be used to cancel
- * the HCI slot reservation. You can pass
- * null here if you won't need to cancel.
- *
- * @return 0 on success; BLE_HS_E[...] on failure.
- */
-int
-ble_hci_sched_enqueue(ble_hci_sched_tx_fn *tx_cb, void *tx_cb_arg,
- uint8_t *out_hci_handle)
-{
- struct ble_hci_sched_entry *entry;
-
- entry = ble_hci_sched_entry_alloc();
- if (entry == NULL) {
- return BLE_HS_ENOMEM;
- }
-
- entry->handle = ble_hci_sched_new_handle();
- entry->tx_cb = tx_cb;
- entry->tx_cb_arg = tx_cb_arg;
-
- if (out_hci_handle != NULL) {
- *out_hci_handle = entry->handle;
- }
-
- ble_hci_sched_lock();
- STAILQ_INSERT_TAIL(&ble_hci_sched_list, entry, next);
- ble_hci_sched_unlock();
-
- if (ble_hci_sched_cur_entry == NULL) {
- ble_hs_kick_hci();
- }
-
- return 0;
-}
-
-/**
- * Cancels the HCI slot reservation with the specified handle. If the slot
- * being cancelled is already in progress, the HCI ack callback is reset, and
- * the next HCI slot is initiated (if there is one).
- *
- * Lock restrictions:
- * o Caller unlocks hci_sched.
- *
- * @param handle The handle of the slot to cancel.
- *
- * @return 0 on success; BLE_HS_E[...] on failure.
- */
-int
-ble_hci_sched_cancel(uint8_t handle)
-{
- struct ble_hci_sched_entry *entry;
- struct ble_hci_sched_entry *prev;
- int do_kick;
- int rc;
-
- ble_hci_sched_lock();
-
- if (ble_hci_sched_cur_entry != NULL &&
- ble_hci_sched_cur_entry->handle == handle) {
-
- /* User is cancelling an in-progress operation. */
- entry = ble_hci_sched_cur_entry;
- ble_hci_sched_cur_entry = NULL;
- ble_hci_sched_set_ack_cb(NULL, NULL);
- do_kick = !STAILQ_EMPTY(&ble_hci_sched_list);
- } else {
- do_kick = 0;
-
- prev = NULL;
- STAILQ_FOREACH(entry, &ble_hci_sched_list, next) {
- if (entry->handle == handle) {
- ble_hci_sched_entry_remove(entry, prev);
- break;
- }
-
- prev = entry;
- }
- }
-
- ble_hci_sched_unlock();
-
- if (entry == NULL) {
- rc = BLE_HS_ENOENT;
- } else {
- ble_hci_sched_entry_free(entry);
- rc = 0;
- }
-
- if (do_kick) {
- ble_hs_kick_hci();
- }
-
- return rc;
-}
-
-/**
- * Executes the specified scheduled HCI transmit slot.
- *
- * Lock restrictions:
- * o Caller unlocks all ble_hs mutexes.
- *
- * @return 0 on success; nonzero on failure.
- */
-static int
-ble_hci_sched_tx(struct ble_hci_sched_entry *entry)
-{
- int rc;
-
- ble_hs_misc_assert_no_locks();
-
- rc = entry->tx_cb(entry->tx_cb_arg);
- if (rc == 0) {
- ble_hci_sched_cur_entry = entry;
- }
-
- return rc;
-}
-
-/**
- * Executes the next scheduled HCI transmit slot if there is one.
- *
- * Lock restrictions:
- * o Caller unlocks all ble_hs mutexes.
- *
- * @return 0 if no more slots should be executed (either a
- * transmit succeeded or there are no more
- * reserved slots);
- * BLE_HS_EAGAIN if the next slot should be
- * executed.
- */
-static int
-ble_hci_sched_process_next(void)
-{
- struct ble_hci_sched_entry *entry;
- int rc;
-
- BLE_HS_DBG_ASSERT(ble_hci_sched_cur_entry == NULL);
-
- ble_hci_sched_lock();
-
- entry = STAILQ_FIRST(&ble_hci_sched_list);
- if (entry != NULL) {
- STAILQ_REMOVE_HEAD(&ble_hci_sched_list, next);
- }
-
- ble_hci_sched_unlock();
-
- if (entry == NULL) {
- rc = 0;
- } else {
- rc = ble_hci_sched_tx(entry);
- if (rc != 0) {
- ble_hci_sched_entry_free(entry);
- rc = BLE_HS_EAGAIN;
- }
- }
-
- return rc;
-}
-
-/**
- * Executes the next scheduled HCI transmit slot if there is one. If a
- * transmit fails (i.e., the user callback returns nonzero), the corresponding
- * slot is freed and the next slot is executed. This process repeats until
- * either:
- * o A transmit succeeds, or
- * o There are no more scheduled transmit slots.
- *
- * Lock restrictions:
- * o Caller unlocks all ble_hs mutexes.
- */
-void
-ble_hci_sched_wakeup(void)
-{
- int rc;
-
- do {
- rc = ble_hci_sched_process_next();
- } while (rc == BLE_HS_EAGAIN);
-}
-
-/**
- * Called when the controller has acknowledged the current HCI command.
- * Acknowledgment occurs via either a command-complete or command-status HCI
- * event.
- *
- * Lock restrictions:
- * o Caller unlocks hci_sched.
- */
-static void
-ble_hci_sched_transaction_complete(void)
-{
- struct ble_hci_sched_entry *entry;
-
- ble_hci_sched_lock();
-
- entry = ble_hci_sched_cur_entry;
- ble_hci_sched_cur_entry = NULL;
-
- ble_hci_sched_unlock();
-
- if (entry != NULL) {
- ble_hci_sched_entry_free(entry);
- }
-
- if (!STAILQ_EMPTY(&ble_hci_sched_list)) {
- ble_hs_kick_hci();
- }
-}
-
-void
-ble_hci_sched_rx_ack(struct ble_hci_ack *ack)
-{
- ble_hci_sched_ack_fn *cb;
-
- if (ble_hci_sched_ack_cb != NULL) {
- cb = ble_hci_sched_ack_cb;
- ble_hci_sched_ack_cb = NULL;
-
- ack->bha_hci_handle = ble_hci_sched_prev_handle;
- cb(ack, ble_hci_sched_ack_arg);
- }
-
- ble_hci_sched_transaction_complete();
-}
-
-void
-ble_hci_sched_set_ack_cb(ble_hci_sched_ack_fn *cb, void *arg)
-{
- /* Don't allow the current callback to be replaced with another. */
- BLE_HS_DBG_ASSERT(ble_hci_sched_ack_cb == NULL || cb == NULL);
-
- ble_hci_sched_ack_cb = cb;
- ble_hci_sched_ack_arg = arg;
-}
-
-/**
- * This is really only useful for unit testing.
- *
- * Lock restrictions: none.
- */
-ble_hci_sched_ack_fn *
-ble_hci_sched_get_ack_cb(void)
-{
- return ble_hci_sched_ack_cb;
-}
-
-/**
- * Lock restrictions: none.
- */
-static void
-ble_hci_sched_free_mem(void)
-{
- free(ble_hci_sched_entry_mem);
- ble_hci_sched_entry_mem = NULL;
-}
-
-/**
- * Lock restrictions: none.
- */
-int
-ble_hci_sched_init(void)
-{
- int rc;
-
- ble_hci_sched_free_mem();
-
- rc = os_mutex_init(&ble_hci_sched_mutex);
- if (rc != 0) {
- rc = BLE_HS_EOS;
- goto err;
- }
-
- if (ble_hs_cfg.max_hci_tx_slots > 0) {
- ble_hci_sched_entry_mem = malloc(
- OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_tx_slots,
- sizeof (struct ble_hci_sched_entry)));
- if (ble_hci_sched_entry_mem == NULL) {
- rc = BLE_HS_ENOMEM;
- goto err;
- }
-
- rc = os_mempool_init(&ble_hci_sched_entry_pool,
- ble_hs_cfg.max_hci_tx_slots,
- sizeof (struct ble_hci_sched_entry),
- ble_hci_sched_entry_mem,
- "ble_hci_sched_entry_pool");
- if (rc != 0) {
- rc = BLE_HS_EOS;
- goto err;
- }
- }
-
- STAILQ_INIT(&ble_hci_sched_list);
-
- ble_hci_sched_cur_entry = NULL;
- ble_hci_sched_set_ack_cb(NULL, NULL);
-
- return 0;
-
-err:
- ble_hci_sched_free_mem();
- return rc;
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_sched.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_sched.h b/net/nimble/host/src/ble_hci_sched.h
deleted file mode 100644
index a53f06e..0000000
--- a/net/nimble/host/src/ble_hci_sched.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/**
- * 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_HCI_SCHED_
-#define H_BLE_HCI_SCHED_
-
-#define BLE_HCI_SCHED_HANDLE_NONE 0
-
-struct ble_hci_ack {
- int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */
- uint8_t *bha_params;
- int bha_params_len;
- uint16_t bha_opcode;
- uint8_t bha_hci_handle;
-};
-
-typedef int ble_hci_sched_tx_fn(void *arg);
-typedef void ble_hci_sched_ack_fn(struct ble_hci_ack *ack, void *arg);
-
-int ble_hci_sched_locked_by_cur_task(void);
-
-int ble_hci_sched_enqueue(ble_hci_sched_tx_fn *tx_cb, void *tx_cb_arg,
- uint8_t *out_hci_handle);
-int ble_hci_sched_cancel(uint8_t handle);
-void ble_hci_sched_wakeup(void);
-void ble_hci_sched_rx_ack(struct ble_hci_ack *ack);
-void ble_hci_sched_set_ack_cb(ble_hci_sched_ack_fn *cb, void *arg);
-ble_hci_sched_ack_fn *ble_hci_sched_get_ack_cb(void);
-int ble_hci_sched_init(void);
-
-#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_util.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.c b/net/nimble/host/src/ble_hci_util.c
new file mode 100644
index 0000000..2ff159d
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_util.c
@@ -0,0 +1,78 @@
+/**
+ * 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 <string.h>
+#include "nimble/hci_common.h"
+#include "host/host_hci.h"
+#include "ble_hs_priv.h"
+
+int
+ble_hci_util_read_adv_tx_pwr(int8_t *out_tx_pwr)
+{
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+ uint8_t params_len;
+ int rc;
+
+ host_hci_cmd_build_read_adv_pwr(buf, sizeof buf);
+ rc = ble_hci_tx_cmd(buf, out_tx_pwr, 1, ¶ms_len);
+ if (rc != 0) {
+ return rc;
+ }
+
+ if (params_len != 1 ||
+ *out_tx_pwr < BLE_HCI_ADV_CHAN_TXPWR_MIN ||
+ *out_tx_pwr > BLE_HCI_ADV_CHAN_TXPWR_MAX) {
+
+ return BLE_HS_ECONTROLLER;
+ }
+
+ return 0;
+}
+
+int
+ble_hci_util_rand(void *dst, int len)
+{
+ uint8_t rsp_buf[BLE_HCI_LE_RAND_LEN];
+ uint8_t req_buf[BLE_HCI_CMD_HDR_LEN];
+ uint8_t params_len;
+ uint8_t *u8ptr;
+ int chunk_sz;
+ int rc;
+
+ host_hci_cmd_build_le_rand(req_buf, sizeof req_buf);
+
+ u8ptr = dst;
+ while (len > 0) {
+ rc = ble_hci_tx_cmd(req_buf, rsp_buf, sizeof rsp_buf, ¶ms_len);
+ if (rc != 0) {
+ return rc;
+ }
+ if (params_len != sizeof rsp_buf) {
+ return BLE_HS_ECONTROLLER;
+ }
+
+ chunk_sz = min(len, sizeof rsp_buf);
+ memcpy(u8ptr, rsp_buf, chunk_sz);
+
+ len -= chunk_sz;
+ u8ptr += chunk_sz;
+ }
+
+ return 0;
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hci_util.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hci_util.h b/net/nimble/host/src/ble_hci_util.h
new file mode 100644
index 0000000..c259d6d
--- /dev/null
+++ b/net/nimble/host/src/ble_hci_util.h
@@ -0,0 +1,26 @@
+/**
+ * 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_HCI_UTIL_
+#define H_BLE_HCI_UTIL_
+
+int ble_hci_util_read_adv_tx_pwr(int8_t *out_pwr);
+int ble_hci_util_rand(void *dst, int len);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/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 0a518d1..2de2bf9 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -40,9 +40,6 @@ static struct log_handler ble_hs_log_console_handler;
struct ble_hs_dev ble_hs_our_dev;
struct log ble_hs_log;
-struct os_task ble_hs_task;
-static os_stack_t ble_hs_stack[BLE_HS_STACK_SIZE] bssnz_t;
-
#define HCI_CMD_BUF_SIZE (260) /* XXX: temporary, Fix later */
struct os_mempool g_hci_cmd_pool;
static void *ble_hs_hci_cmd_buf;
@@ -65,17 +62,17 @@ static void *ble_hs_hci_os_event_buf;
* shortage.
*/
static struct os_callout_func ble_hs_heartbeat_timer;
+static struct os_callout_func ble_hs_event_co;
/* Host HCI Task Events */
-struct os_eventq ble_hs_evq;
-static struct os_event ble_hs_kick_hci_ev;
-static struct os_event ble_hs_kick_gatt_ev;
-static struct os_event ble_hs_kick_l2cap_sig_ev;
-static struct os_event ble_hs_kick_l2cap_sm_ev;
+static struct os_eventq ble_hs_evq;
+static struct os_eventq *ble_hs_app_evq;
static struct os_mqueue ble_hs_rx_q;
static struct os_mqueue ble_hs_tx_q;
+static struct os_mutex ble_hs_mutex;
+
STATS_SECT_DECL(ble_hs_stats) ble_hs_stats;
STATS_NAME_START(ble_hs_stats)
STATS_NAME(ble_hs_stats, conn_create)
@@ -87,6 +84,36 @@ STATS_NAME_START(ble_hs_stats)
STATS_NAME_END(ble_hs_stats)
void
+ble_hs_lock(void)
+{
+ struct os_task *owner;
+ int rc;
+
+ owner = ble_hs_mutex.mu_owner;
+ if (owner != NULL) {
+ BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
+ }
+
+ rc = os_mutex_pend(&ble_hs_mutex, 0xffffffff);
+ BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+void
+ble_hs_unlock(void)
+{
+ int rc;
+
+ rc = os_mutex_release(&ble_hs_mutex);
+ BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
+}
+
+int
+ble_hs_locked(void)
+{
+ return ble_hs_mutex.mu_level > 0;
+}
+
+void
ble_hs_process_tx_data_queue(void)
{
struct os_mbuf *om;
@@ -130,28 +157,32 @@ ble_hs_heartbeat_timer_reset(void)
static void
ble_hs_heartbeat(void *unused)
{
- ble_hs_misc_assert_no_locks();
+ ble_hs_misc_assert_not_locked();
ble_gattc_heartbeat();
ble_gap_heartbeat();
+ ble_l2cap_sig_heartbeat();
ble_l2cap_sm_heartbeat();
ble_hs_heartbeat_timer_reset();
}
static void
-ble_hs_task_handler(void *arg)
+ble_hs_event_handle(void *unused)
{
- struct os_event *ev;
struct os_callout_func *cf;
- int rc;
+ struct os_event *ev;
+ os_sr_t sr;
- ble_hs_heartbeat_timer_reset();
+ while (1) {
+ OS_ENTER_CRITICAL(sr);
+ ev = STAILQ_FIRST(&ble_hs_evq.evq_list);
+ OS_EXIT_CRITICAL(sr);
- rc = ble_hs_startup_go();
- assert(rc == 0);
+ if (ev == NULL) {
+ break;
+ }
- while (1) {
ev = os_eventq_get(&ble_hs_evq);
switch (ev->ev_type) {
case OS_EVENT_T_TIMER:
@@ -170,22 +201,6 @@ ble_hs_task_handler(void *arg)
ble_hs_process_rx_data_queue();
break;
- case BLE_HS_KICK_HCI_EVENT:
- ble_hci_sched_wakeup();
- break;
-
- case BLE_HS_KICK_GATT_EVENT:
- ble_gattc_wakeup();
- break;
-
- case BLE_HS_KICK_L2CAP_SIG_EVENT:
- ble_l2cap_sig_wakeup();
- break;
-
- case BLE_HS_KICK_L2CAP_SM_EVENT:
- ble_l2cap_sm_wakeup();
- break;
-
default:
BLE_HS_DBG_ASSERT(0);
break;
@@ -193,6 +208,24 @@ ble_hs_task_handler(void *arg)
}
}
+void
+ble_hs_event_enqueue(struct os_event *ev)
+{
+ os_eventq_put(&ble_hs_evq, ev);
+ os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
+}
+
+int
+ble_hs_start(void)
+{
+ int rc;
+
+ ble_hs_heartbeat_timer_reset();
+
+ rc = ble_hs_startup_go();
+ return rc;
+}
+
/**
* Called when a data packet is received from the controller. This function
* consumes the supplied mbuf, regardless of the outcome.
@@ -211,6 +244,7 @@ ble_hs_rx_data(struct os_mbuf *om)
if (rc != 0) {
return BLE_HS_EOS;
}
+ os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
return 0;
}
@@ -224,46 +258,11 @@ ble_hs_tx_data(struct os_mbuf *om)
if (rc != 0) {
return BLE_HS_EOS;
}
+ os_eventq_put(ble_hs_app_evq, &ble_hs_event_co.cf_c.c_ev);
return 0;
}
-/**
- * Wakes the BLE host task so that it can process hci events.
- */
-void
-ble_hs_kick_hci(void)
-{
- os_eventq_put(&ble_hs_evq, &ble_hs_kick_hci_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process GATT events.
- */
-void
-ble_hs_kick_gatt(void)
-{
- os_eventq_put(&ble_hs_evq, &ble_hs_kick_gatt_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process L2CAP sig events.
- */
-void
-ble_hs_kick_l2cap_sig(void)
-{
- os_eventq_put(&ble_hs_evq, &ble_hs_kick_l2cap_sig_ev);
-}
-
-/**
- * Wakes the BLE host task so that it can process L2CAP security events.
- */
-void
-ble_hs_kick_l2cap_sm(void)
-{
- os_eventq_put(&ble_hs_evq, &ble_hs_kick_l2cap_sm_ev);
-}
-
static void
ble_hs_free_mem(void)
{
@@ -278,21 +277,24 @@ ble_hs_free_mem(void)
* Initializes the host portion of the BLE stack.
*/
int
-ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
+ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg)
{
int rc;
ble_hs_free_mem();
+ if (app_evq == NULL) {
+ rc = BLE_HS_EINVAL;
+ goto err;
+ }
+ ble_hs_app_evq = app_evq;
+
ble_hs_cfg_init(cfg);
log_init();
log_console_handler_init(&ble_hs_log_console_handler);
log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler);
- os_task_init(&ble_hs_task, "ble_hs", ble_hs_task_handler, NULL, prio,
- OS_WAIT_FOREVER, ble_hs_stack, BLE_HS_STACK_SIZE);
-
ble_hs_hci_cmd_buf = malloc(OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs,
HCI_CMD_BUF_SIZE));
if (ble_hs_hci_cmd_buf == NULL) {
@@ -356,11 +358,6 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
goto err;
}
- rc = ble_hci_sched_init();
- if (rc != 0) {
- goto err;
- }
-
rc = ble_gattc_init();
if (rc != 0) {
goto err;
@@ -371,24 +368,6 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
goto err;
}
- ble_hci_block_init();
-
- ble_hs_kick_hci_ev.ev_queued = 0;
- ble_hs_kick_hci_ev.ev_type = BLE_HS_KICK_HCI_EVENT;
- ble_hs_kick_hci_ev.ev_arg = NULL;
-
- ble_hs_kick_gatt_ev.ev_queued = 0;
- ble_hs_kick_gatt_ev.ev_type = BLE_HS_KICK_GATT_EVENT;
- ble_hs_kick_gatt_ev.ev_arg = NULL;
-
- ble_hs_kick_l2cap_sig_ev.ev_queued = 0;
- ble_hs_kick_l2cap_sig_ev.ev_type = BLE_HS_KICK_L2CAP_SIG_EVENT;
- ble_hs_kick_l2cap_sig_ev.ev_arg = NULL;
-
- ble_hs_kick_l2cap_sm_ev.ev_queued = 0;
- ble_hs_kick_l2cap_sm_ev.ev_type = BLE_HS_KICK_L2CAP_SM_EVENT;
- ble_hs_kick_l2cap_sm_ev.ev_arg = NULL;
-
os_mqueue_init(&ble_hs_rx_q, NULL);
os_mqueue_init(&ble_hs_tx_q, NULL);
@@ -400,8 +379,16 @@ ble_hs_init(uint8_t prio, struct ble_hs_cfg *cfg)
goto err;
}
- os_callout_func_init(&ble_hs_heartbeat_timer, &ble_hs_evq,
+ os_callout_func_init(&ble_hs_heartbeat_timer, ble_hs_app_evq,
ble_hs_heartbeat, NULL);
+ os_callout_func_init(&ble_hs_event_co, &ble_hs_evq,
+ ble_hs_event_handle, NULL);
+
+ rc = os_mutex_init(&ble_hs_mutex);
+ if (rc != 0) {
+ rc = BLE_HS_EOS;
+ goto err;
+ }
return 0;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_atomic.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.c b/net/nimble/host/src/ble_hs_atomic.c
new file mode 100644
index 0000000..4aeabe6
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_atomic.c
@@ -0,0 +1,45 @@
+/**
+ * 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 "ble_hs_priv.h"
+
+int
+ble_hs_atomic_conn_delete(uint16_t conn_handle)
+{
+ struct ble_hs_conn *conn;
+
+ ble_hs_lock();
+ conn = ble_hs_conn_find(conn_handle);
+ if (conn != NULL) {
+ ble_hs_conn_remove(conn);
+ ble_hs_conn_free(conn);
+
+ }
+ ble_hs_unlock();
+
+ return conn != NULL ? 0 : BLE_HS_ENOTCONN;
+}
+
+void
+ble_hs_atomic_conn_insert(struct ble_hs_conn *conn)
+{
+ ble_hs_lock();
+ ble_hs_conn_insert(conn);
+ ble_hs_unlock();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_atomic.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_atomic.h b/net/nimble/host/src/ble_hs_atomic.h
new file mode 100644
index 0000000..5bb3665
--- /dev/null
+++ b/net/nimble/host/src/ble_hs_atomic.h
@@ -0,0 +1,25 @@
+/**
+ * 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_HS_ATOMIC_
+#define H_BLE_HS_ATOMIC_
+
+int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_cfg.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_cfg.c b/net/nimble/host/src/ble_hs_cfg.c
index 860ef3c..0aa966a 100644
--- a/net/nimble/host/src/ble_hs_cfg.c
+++ b/net/nimble/host/src/ble_hs_cfg.c
@@ -22,7 +22,6 @@
const struct ble_hs_cfg ble_hs_cfg_dflt = {
/** HCI settings. */
.max_hci_bufs = 8,
- .max_hci_tx_slots = 8,
/** Connection settings. */
.max_outstanding_pkts_per_conn = 5,
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.c b/net/nimble/host/src/ble_hs_conn.c
index 4d04a24..7c505ba 100644
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@ -28,41 +28,6 @@ static struct os_mempool ble_hs_conn_pool;
static os_membuf_t *ble_hs_conn_elem_mem;
-static struct os_mutex ble_hs_conn_mutex;
-
-void
-ble_hs_conn_lock(void)
-{
- struct os_task *owner;
- int rc;
-
- owner = ble_hs_conn_mutex.mu_owner;
- if (owner != NULL) {
- BLE_HS_DBG_ASSERT_EVAL(owner != os_sched_get_current_task());
- }
-
- rc = os_mutex_pend(&ble_hs_conn_mutex, 0xffffffff);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-void
-ble_hs_conn_unlock(void)
-{
- int rc;
-
- rc = os_mutex_release(&ble_hs_conn_mutex);
- BLE_HS_DBG_ASSERT_EVAL(rc == 0 || rc == OS_NOT_STARTED);
-}
-
-int
-ble_hs_conn_locked_by_cur_task(void)
-{
- struct os_task *owner;
-
- owner = ble_hs_conn_mutex.mu_owner;
- return owner != NULL && owner == os_sched_get_current_task();
-}
-
/**
* Lock restrictions: none.
*/
@@ -255,12 +220,8 @@ ble_hs_conn_insert(struct ble_hs_conn *conn)
return;
#endif
- ble_hs_conn_lock();
-
BLE_HS_DBG_ASSERT_EVAL(ble_hs_conn_find(conn->bhc_handle) == NULL);
SLIST_INSERT_HEAD(&ble_hs_conns, conn, bhc_next);
-
- ble_hs_conn_unlock();
}
/**
@@ -297,23 +258,13 @@ ble_hs_conn_find(uint16_t conn_handle)
return NULL;
}
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
int
ble_hs_conn_exists(uint16_t conn_handle)
{
#if !NIMBLE_OPT_CONNECT
return 0;
#endif
-
- struct ble_hs_conn *conn;
-
- ble_hs_conn_lock();
- conn = ble_hs_conn_find(conn_handle);
- ble_hs_conn_unlock();
-
- return conn != NULL;
+ return ble_hs_conn_find(conn_handle) != NULL;
}
/**
@@ -326,7 +277,7 @@ ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
struct ble_hs_conn *conn;
int rc;
- ble_hs_conn_lock();
+ ble_hs_lock();
conn = ble_hs_conn_find(conn_handle);
if (conn == NULL) {
@@ -336,7 +287,7 @@ ble_hs_conn_flags(uint16_t conn_handle, ble_hs_conn_flags_t *out_flags)
*out_flags = conn->bhc_flags;
}
- ble_hs_conn_unlock();
+ ble_hs_unlock();
return rc;
}
@@ -357,65 +308,6 @@ ble_hs_conn_first(void)
}
/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
-static void
-ble_hs_conn_txable_transition(struct ble_hs_conn *conn)
-{
- ble_gattc_connection_txable(conn->bhc_handle);
-}
-
-/**
- * Lock restrictions: Caller must NOT lock ble_hs_conn mutex.
- */
-void
-ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts)
-{
-#if !NIMBLE_OPT_CONNECT
- return;
-#endif
-
- struct ble_hs_conn *conn;
- int could_tx;
- int can_tx;
-
- ble_hs_conn_lock();
-
- conn = ble_hs_conn_find(handle);
- if (conn != NULL) {
- could_tx = ble_hs_conn_can_tx(conn);
-
- if (num_pkts > conn->bhc_outstanding_pkts) {
- num_pkts = conn->bhc_outstanding_pkts;
- }
- conn->bhc_outstanding_pkts -= num_pkts;
-
- can_tx = ble_hs_conn_can_tx(conn);
-
- if (!could_tx && can_tx) {
- ble_hs_conn_txable_transition(conn);
- }
- }
-
- ble_hs_conn_unlock();
-}
-
-/**
- * Lock restrictions: Caller must lock ble_hs_conn mutex.
- */
-int
-ble_hs_conn_can_tx(struct ble_hs_conn *conn)
-{
-#if !NIMBLE_OPT_CONNECT
- return 0;
-#endif
-
- return ble_hs_cfg.max_outstanding_pkts_per_conn == 0 ||
- conn->bhc_outstanding_pkts <
- ble_hs_cfg.max_outstanding_pkts_per_conn;
-}
-
-/**
* Lock restrictions: None.
*/
static void
@@ -435,12 +327,6 @@ ble_hs_conn_init(void)
ble_hs_conn_free_mem();
- rc = os_mutex_init(&ble_hs_conn_mutex);
- if (rc != 0) {
- rc = BLE_HS_EOS;
- goto err;
- }
-
ble_hs_conn_elem_mem = malloc(
OS_MEMPOOL_BYTES(ble_hs_cfg.max_connections,
sizeof (struct ble_hs_conn)));
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_conn.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_conn.h b/net/nimble/host/src/ble_hs_conn.h
index dc1acc3..0dd7bf6 100644
--- a/net/nimble/host/src/ble_hs_conn.h
+++ b/net/nimble/host/src/ble_hs_conn.h
@@ -30,6 +30,7 @@ struct ble_l2cap_chan;
typedef uint8_t ble_hs_conn_flags_t;
#define BLE_HS_CONN_F_MASTER 0x01
+#define BLE_HS_CONN_F_UPDATE 0x02
struct ble_hs_conn {
SLIST_ENTRY(ble_hs_conn) bhc_next;
@@ -56,9 +57,6 @@ struct ble_hs_conn {
void *bhc_cb_arg;
};
-void ble_hs_conn_lock(void);
-void ble_hs_conn_unlock(void);
-int ble_hs_conn_locked_by_cur_task(void);
int ble_hs_conn_can_alloc(void);
struct ble_hs_conn *ble_hs_conn_alloc(void);
void ble_hs_conn_free(struct ble_hs_conn *conn);
@@ -72,8 +70,6 @@ struct ble_l2cap_chan *ble_hs_conn_chan_find(struct ble_hs_conn *conn,
uint16_t cid);
int ble_hs_conn_chan_insert(struct ble_hs_conn *conn,
struct ble_l2cap_chan *chan);
-void ble_hs_conn_rx_num_completed_pkts(uint16_t handle, uint16_t num_pkts);
-int ble_hs_conn_can_tx(struct ble_hs_conn *conn);
int ble_hs_conn_init(void);
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_misc.c b/net/nimble/host/src/ble_hs_misc.c
index 8335196..ab130bb 100644
--- a/net/nimble/host/src/ble_hs_misc.c
+++ b/net/nimble/host/src/ble_hs_misc.c
@@ -68,15 +68,9 @@ ble_hs_misc_log_flat_buf(void *data, int len)
}
void
-ble_hs_misc_assert_no_locks(void)
+ble_hs_misc_assert_not_locked(void)
{
- if (os_started()) {
- assert(!ble_hs_conn_locked_by_cur_task() &&
- !ble_gattc_locked_by_cur_task() &&
- !ble_gap_locked_by_cur_task() &&
- !ble_hci_sched_locked_by_cur_task() &&
- !ble_l2cap_sm_locked_by_cur_task());
- }
+ assert(!ble_hs_locked());
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_priv.h b/net/nimble/host/src/ble_hs_priv.h
index c9a5f86..09e9ef4 100644
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@ -24,10 +24,8 @@
#include <inttypes.h>
#include "ble_att_cmd.h"
#include "ble_att_priv.h"
-#include "ble_fsm_priv.h"
#include "ble_gap_priv.h"
#include "ble_gatt_priv.h"
-#include "ble_hci_sched.h"
#include "ble_hs_adv_priv.h"
#include "ble_hs_conn.h"
#include "ble_hs_endian.h"
@@ -35,6 +33,7 @@
#include "ble_l2cap_priv.h"
#include "ble_l2cap_sig.h"
#include "ble_l2cap_sm.h"
+#include "ble_hci_util.h"
#include "host/ble_hs.h"
#include "log/log.h"
#include "nimble/nimble_opt.h"
@@ -45,10 +44,6 @@ struct os_mbuf;
struct os_mempool;
#define BLE_HOST_HCI_EVENT_CTLR_EVENT (OS_EVENT_T_PERUSER + 0)
-#define BLE_HS_KICK_HCI_EVENT (OS_EVENT_T_PERUSER + 1)
-#define BLE_HS_KICK_GATT_EVENT (OS_EVENT_T_PERUSER + 2)
-#define BLE_HS_KICK_L2CAP_SIG_EVENT (OS_EVENT_T_PERUSER + 3)
-#define BLE_HS_KICK_L2CAP_SM_EVENT (OS_EVENT_T_PERUSER + 4)
STATS_SECT_START(ble_hs_stats)
STATS_SECT_ENTRY(conn_create)
@@ -67,23 +62,24 @@ struct ble_hs_dev {
unsigned has_random_addr:1;
};
-extern struct os_task ble_hs_task;
+struct ble_hci_ack {
+ int bha_status; /* A BLE_HS_E<...> error; NOT a naked HCI code. */
+ uint8_t *bha_params;
+ int bha_params_len;
+ uint16_t bha_opcode;
+ uint8_t bha_hci_handle;
+};
extern struct ble_hs_dev ble_hs_our_dev;
extern struct ble_hs_cfg ble_hs_cfg;
extern struct os_mbuf_pool ble_hs_mbuf_pool;
-extern struct os_eventq ble_hs_evq;
extern struct log ble_hs_log;
void ble_hs_process_tx_data_queue(void);
int ble_hs_rx_data(struct os_mbuf *om);
int ble_hs_tx_data(struct os_mbuf *om);
-void ble_hs_kick_hci(void);
-void ble_hs_kick_gatt(void);
-void ble_hs_kick_l2cap_sig(void);
-void ble_hs_kick_l2cap_sm(void);
int ble_hs_misc_malloc_mempool(void **mem, struct os_mempool *pool,
int num_entries, int entry_size, char *name);
@@ -96,30 +92,30 @@ int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
struct ble_hs_conn **out_conn,
struct ble_l2cap_chan **out_chan);
+int ble_hs_atomic_conn_delete(uint16_t conn_handle);
+void ble_hs_atomic_conn_insert(struct ble_hs_conn *conn);
+
void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
-void ble_hs_misc_assert_no_locks(void);
+void ble_hs_lock(void);
+void ble_hs_unlock(void);
+int ble_hs_locked(void);
+void ble_hs_misc_assert_not_locked(void);
struct os_mbuf *ble_hs_misc_pkthdr(void);
int ble_hs_misc_pullup_base(struct os_mbuf **om, int base_len);
-struct ble_hci_block_result {
- uint8_t evt_buf_len;
- uint8_t evt_total_len;
-};
+int ble_hci_tx_cmd(void *cmd, void *evt_buf, uint8_t evt_buf_len,
+ uint8_t *out_evt_buf_len);
+int ble_hci_tx_cmd_empty_ack(void *cmd);
#if PHONY_HCI_ACKS
-typedef int ble_hci_block_phony_ack_fn(void *cmd, uint8_t *ack,
- int ack_buf_len);
+typedef int ble_hci_phony_ack_fn(uint8_t *ack, int ack_buf_len);
-void ble_hci_block_set_phony_ack_cb(ble_hci_block_phony_ack_fn *cb);
+void ble_hci_set_phony_ack_cb(ble_hci_phony_ack_fn *cb);
#endif
-int ble_hci_block_tx(void *cmd, void *evt_buf, uint8_t evt_buf_len,
- struct ble_hci_block_result *result);
-void ble_hci_block_init(void);
-
#define BLE_HS_LOG(lvl, ...) \
LOG_ ## lvl(&ble_hs_log, LOG_MODULE_NIMBLE_HOST, __VA_ARGS__)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_hs_startup.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_hs_startup.c b/net/nimble/host/src/ble_hs_startup.c
index b7cefb6..98be26c 100644
--- a/net/nimble/host/src/ble_hs_startup.c
+++ b/net/nimble/host/src/ble_hs_startup.c
@@ -23,159 +23,69 @@
#include "host/ble_hs.h"
#include "ble_hs_priv.h"
-#define BLE_HS_STARTUP_STATE_IDLE 0
-#define BLE_HS_STARTUP_STATE_RESET 1
-/* XXX: Read local supported commands. */
-/* XXX: Read local supported features. */
-#define BLE_HS_STARTUP_STATE_SET_EVMASK 2
-#define BLE_HS_STARTUP_STATE_LE_SET_EVMASK 3
-#define BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ 4
-/* XXX: Read buffer size. */
-#define BLE_HS_STARTUP_STATE_LE_READ_SUP_F 5
-/* XXX: Read BD_ADDR. */
-#define BLE_HS_STARTUP_STATE_MAX 6
-
-static uint8_t ble_hs_startup_state;
-
-static int ble_hs_startup_reset_tx(void *arg);
-static int ble_hs_startup_set_evmask_tx(void *arg);
-static int ble_hs_startup_le_set_evmask_tx(void *arg);
-static int ble_hs_startup_le_read_buf_sz_tx(void *arg);
-static int ble_hs_startup_le_read_sup_f_tx(void *arg);
-
-static ble_hci_sched_tx_fn * const
- ble_hs_startup_dispatch[BLE_HS_STARTUP_STATE_MAX] = {
-
- [BLE_HS_STARTUP_STATE_IDLE] = NULL,
- [BLE_HS_STARTUP_STATE_RESET] = ble_hs_startup_reset_tx,
- [BLE_HS_STARTUP_STATE_SET_EVMASK] = ble_hs_startup_set_evmask_tx,
- [BLE_HS_STARTUP_STATE_LE_SET_EVMASK] = ble_hs_startup_le_set_evmask_tx,
- [BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ] = ble_hs_startup_le_read_buf_sz_tx,
- [BLE_HS_STARTUP_STATE_LE_READ_SUP_F] = ble_hs_startup_le_read_sup_f_tx,
-};
-
-static void
-ble_hs_startup_failure(int status)
-{
- ble_hs_startup_state = BLE_HS_STARTUP_STATE_IDLE;
- /* XXX: Signal failure. */
-}
-
static int
-ble_hs_startup_enqueue_tx(void)
+ble_hs_startup_le_read_sup_f_tx(void)
{
- ble_hci_sched_tx_fn *tx_fn;
+ uint8_t ack_params[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+ uint8_t ack_params_len;
int rc;
- if (ble_hs_startup_state == BLE_HS_STARTUP_STATE_MAX) {
- return 0;
- }
-
- tx_fn = ble_hs_startup_dispatch[ble_hs_startup_state];
- BLE_HS_DBG_ASSERT(tx_fn != NULL);
-
- rc = ble_hci_sched_enqueue(tx_fn, NULL, NULL);
+ host_hci_cmd_build_le_read_loc_supp_feat(buf, sizeof buf);
+ rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
if (rc != 0) {
- ble_hs_startup_failure(rc);
return rc;
}
- return 0;
-}
-
-static void
-ble_hs_startup_gen_ack(struct ble_hci_ack *ack, void *arg)
-{
- BLE_HS_DBG_ASSERT(ble_hs_startup_state < BLE_HS_STARTUP_STATE_MAX);
-
- if (ack->bha_status != 0) {
- ble_hs_startup_failure(ack->bha_status);
- return;
- }
-
- ble_hs_startup_state++;
- ble_hs_startup_enqueue_tx();
-}
-
-static void
-ble_hs_startup_le_read_sup_f_ack(struct ble_hci_ack *ack, void *arg)
-{
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_LE_READ_SUP_F);
-
- if (ack->bha_status != 0) {
- ble_hs_startup_failure(ack->bha_status);
- return;
- }
-
- if (ack->bha_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
- ble_hs_startup_failure(BLE_HS_ECONTROLLER);
- return;
+ if (ack_params_len != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
+ return BLE_HS_ECONTROLLER;
}
/* XXX: Do something with the supported features bit map. */
-}
-
-static int
-ble_hs_startup_le_read_sup_f_tx(void *arg)
-{
- int rc;
-
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_LE_READ_SUP_F);
-
- ble_hci_sched_set_ack_cb(ble_hs_startup_le_read_sup_f_ack, NULL);
- rc = host_hci_cmd_le_read_loc_supp_feat();
- if (rc != 0) {
- return rc;
- }
return 0;
}
-static void
-ble_hs_startup_le_read_buf_size_ack(struct ble_hci_ack *ack, void *arg)
+static int
+ble_hs_startup_le_read_buf_sz_tx(void)
{
uint16_t pktlen;
+ uint8_t ack_params[BLE_HCI_RD_BUF_SIZE_RSPLEN];
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN];
+ uint8_t ack_params_len;
uint8_t max_pkts;
int rc;
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ);
-
- if (ack->bha_status != 0) {
- ble_hs_startup_failure(ack->bha_status);
- return;
+ host_hci_cmd_build_le_read_buffer_size(buf, sizeof buf);
+ rc = ble_hci_tx_cmd(buf, ack_params, sizeof ack_params, &ack_params_len);
+ if (rc != 0) {
+ return rc;
}
- if (ack->bha_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN + 1) {
- ble_hs_startup_failure(BLE_HS_ECONTROLLER);
- return;
+ if (ack_params_len != BLE_HCI_RD_BUF_SIZE_RSPLEN) {
+ return BLE_HS_ECONTROLLER;
}
- pktlen = le16toh(ack->bha_params + 1);
- max_pkts = ack->bha_params[3];
+ pktlen = le16toh(ack_params + 0);
+ max_pkts = ack_params[2];
rc = host_hci_set_buf_size(pktlen, max_pkts);
if (rc != 0) {
- ble_hs_startup_failure(rc);
- return;
+ return rc;
}
- ble_hs_startup_state++;
- ble_hs_startup_enqueue_tx();
+ return 0;
}
static int
-ble_hs_startup_le_read_buf_sz_tx(void *arg)
+ble_hs_startup_le_set_evmask_tx(void)
{
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_LE_EVENT_MASK_LEN];
int rc;
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_LE_READ_BUF_SZ);
-
- ble_hci_sched_set_ack_cb(ble_hs_startup_le_read_buf_size_ack, NULL);
- rc = host_hci_cmd_le_read_buffer_size();
+ /* [ Default event set ]. */
+ host_hci_cmd_build_le_set_event_mask(0x000000000000001f, buf, sizeof buf);
+ rc = ble_hci_tx_cmd_empty_ack(buf);
if (rc != 0) {
return rc;
}
@@ -184,15 +94,14 @@ ble_hs_startup_le_read_buf_sz_tx(void *arg)
}
static int
-ble_hs_startup_le_set_evmask_tx(void *arg)
+ble_hs_startup_set_evmask_tx(void)
{
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN];
int rc;
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_LE_SET_EVMASK);
-
- ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
- rc = host_hci_cmd_le_set_event_mask(0x000000000000001f);
+ /* [ Default event set | LE-meta event ]. */
+ host_hci_cmd_build_set_event_mask(0x20001fffffffffff, buf, sizeof buf);
+ rc = ble_hci_tx_cmd_empty_ack(buf);
if (rc != 0) {
return rc;
}
@@ -201,17 +110,13 @@ ble_hs_startup_le_set_evmask_tx(void *arg)
}
static int
-ble_hs_startup_set_evmask_tx(void *arg)
+ble_hs_startup_reset_tx(void)
{
+ uint8_t buf[BLE_HCI_CMD_HDR_LEN];
int rc;
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_SET_EVMASK);
-
- ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
-
- /* Default set + LE-meta event. */
- rc = host_hci_cmd_set_event_mask(0x20001fffffffffff);
+ host_hci_cmd_build_reset(buf, sizeof buf);
+ rc = ble_hci_tx_cmd_empty_ack(buf);
if (rc != 0) {
return rc;
}
@@ -219,33 +124,47 @@ ble_hs_startup_set_evmask_tx(void *arg)
return 0;
}
-static int
-ble_hs_startup_reset_tx(void *arg)
+int
+ble_hs_startup_go(void)
{
int rc;
- BLE_HS_DBG_ASSERT(ble_hs_startup_state ==
- BLE_HS_STARTUP_STATE_RESET);
+ rc = ble_hs_startup_reset_tx();
+ if (rc != 0) {
+ return rc;
+ }
+
+ /* XXX: Read local supported commands. */
+ /* XXX: Read local supported features. */
- ble_hci_sched_set_ack_cb(ble_hs_startup_gen_ack, NULL);
- rc = host_hci_cmd_reset();
+ rc = ble_hs_startup_set_evmask_tx();
if (rc != 0) {
+ assert(0);
return rc;
}
- return 0;
-}
+ rc = ble_hs_startup_le_set_evmask_tx();
+ if (rc != 0) {
+ assert(0);
+ return rc;
+ }
-int
-ble_hs_startup_go(void)
-{
- int rc;
+ rc = ble_hs_startup_le_read_buf_sz_tx();
+ if (rc != 0) {
+ assert(0);
+ return rc;
+ }
+
+ /* XXX: Read buffer size. */
- ble_hs_startup_state = BLE_HS_STARTUP_STATE_RESET;
+ rc = ble_hs_startup_le_read_sup_f_tx();
+ if (rc != 0) {
+ assert(0);
+ return rc;
+ }
- /* XXX: Until we support reading the address from the controller. */
+ /* XXX: Read BD_ADDR. */
memcpy(ble_hs_our_dev.public_addr, g_dev_addr, sizeof g_dev_addr);
- rc = ble_hs_startup_enqueue_tx();
return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_ibeacon.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_ibeacon.c b/net/nimble/host/src/ble_ibeacon.c
index 9f610d2..896dc10 100644
--- a/net/nimble/host/src/ble_ibeacon.c
+++ b/net/nimble/host/src/ble_ibeacon.c
@@ -25,10 +25,9 @@
int
ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor)
{
- struct ble_hci_block_result result;
struct ble_hs_adv_fields fields;
uint8_t buf[BLE_IBEACON_MFG_DATA_SIZE];
- uint8_t hci_cmd[BLE_HCI_CMD_HDR_LEN];
+ int8_t tx_pwr;
int rc;
/** Company identifier (Apple). */
@@ -48,13 +47,11 @@ ble_ibeacon_set_adv_data(void *uuid128, uint16_t major, uint16_t minor)
/** Last byte (tx power level) filled in after HCI exchange. */
- host_hci_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR, 0,
- hci_cmd);
-
- rc = ble_hci_block_tx(hci_cmd, buf + 24, 1, &result);
+ rc = ble_hci_util_read_adv_tx_pwr(&tx_pwr);
if (rc != 0) {
return rc;
}
+ buf[24] = tx_pwr;
memset(&fields, 0, sizeof fields);
fields.mfg_data = buf;
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_priv.h b/net/nimble/host/src/ble_l2cap_priv.h
index 9db54ea..2a728fc 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -111,7 +111,6 @@ struct ble_l2cap_chan
SLIST_HEAD(ble_l2cap_chan_list, ble_l2cap_chan);
-int ble_l2cap_sig_locked_by_cur_task(void);
int ble_l2cap_parse_hdr(struct os_mbuf *om, int off,
struct ble_l2cap_hdr *l2cap_hdr);
struct os_mbuf *ble_l2cap_prepend_hdr(struct os_mbuf *om, uint16_t cid,
@@ -151,7 +150,7 @@ int ble_l2cap_rx(struct ble_hs_conn *conn,
int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
struct os_mbuf *om);
-void ble_l2cap_sig_wakeup(void);
+void ble_l2cap_sig_heartbeat(void);
int ble_l2cap_sig_init(void);
int ble_l2cap_init(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig.c b/net/nimble/host/src/ble_l2cap_sig.c
index e4a20b5..2f6b692 100644
--- a/net/nimble/host/src/ble_l2cap_sig.c
+++ b/net/nimble/host/src/ble_l2cap_sig.c
@@ -27,48 +27,38 @@
* $definitions / declarations *
*****************************************************************************/
-#define BLE_L2CAP_SIG_HEARTBEAT_PERIOD 1000 /* Milliseconds. */
#define BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT 30000 /* Milliseconds. */
#define BLE_L2CAP_SIG_PROC_OP_UPDATE 0
#define BLE_L2CAP_SIG_PROC_OP_MAX 1
struct ble_l2cap_sig_proc {
- struct ble_fsm_proc fsm_proc;
+ STAILQ_ENTRY(ble_l2cap_sig_proc) next;
+
+ uint32_t exp_os_ticks;
+ uint16_t conn_handle;
+ uint8_t op;
uint8_t id;
union {
struct {
- struct ble_l2cap_sig_update_params params;
ble_l2cap_sig_update_fn *cb;
void *cb_arg;
} update;
};
};
-/**
- * Handles unresponsive timeouts and periodic retries in case of resource
- * shortage.
- */
-static struct os_callout_func ble_l2cap_sig_heartbeat_timer;
+STAILQ_HEAD(ble_l2cap_sig_proc_list, ble_l2cap_sig_proc);
-typedef int ble_l2cap_sig_kick_fn(struct ble_l2cap_sig_proc *proc);
+static struct ble_l2cap_sig_proc_list ble_l2cap_sig_procs;
typedef int ble_l2cap_sig_rx_fn(uint16_t conn_handle,
struct ble_l2cap_sig_hdr *hdr,
struct os_mbuf **om);
-static int ble_l2cap_sig_rx_noop(uint16_t conn_handle,
- struct ble_l2cap_sig_hdr *hdr,
- struct os_mbuf **om);
-static int ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
- struct ble_l2cap_sig_hdr *hdr,
- struct os_mbuf **om);
-static int ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
- struct ble_l2cap_sig_hdr *hdr,
- struct os_mbuf **om);
-
-static int ble_l2cap_sig_update_kick(struct ble_l2cap_sig_proc *proc);
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_rx_noop;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_req_rx;
+static ble_l2cap_sig_rx_fn ble_l2cap_sig_update_rsp_rx;
static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
[BLE_L2CAP_SIG_OP_REJECT] = ble_l2cap_sig_rx_noop,
@@ -85,72 +75,15 @@ static ble_l2cap_sig_rx_fn * const ble_l2cap_sig_dispatch[] = {
[BLE_L2CAP_SIG_OP_CREDIT_CONNECT_RSP] = ble_l2cap_sig_rx_noop,
};
-static ble_l2cap_sig_kick_fn * const ble_l2cap_sig_kick[] = {
- [BLE_L2CAP_SIG_PROC_OP_UPDATE] = ble_l2cap_sig_update_kick,
-};
-
static uint8_t ble_l2cap_sig_cur_id;
static void *ble_l2cap_sig_proc_mem;
static struct os_mempool ble_l2cap_sig_proc_pool;
-static struct ble_fsm ble_l2cap_sig_fsm;
-
-/*****************************************************************************
- * $mutex *
- *****************************************************************************/
-
-void
-ble_l2cap_sig_lock(void)
-{
- ble_fsm_lock(&ble_l2cap_sig_fsm);
-}
-
-void
-ble_l2cap_sig_unlock(void)
-{
- ble_fsm_unlock(&ble_l2cap_sig_fsm);
-}
-
-int
-ble_l2cap_sig_locked_by_cur_task(void)
-{
- return ble_fsm_locked_by_cur_task(&ble_l2cap_sig_fsm);
-}
-
/*****************************************************************************
* $misc *
*****************************************************************************/
-/**
- * Lock restrictions: None.
- */
-static ble_l2cap_sig_kick_fn *
-ble_l2cap_sig_kick_get(uint8_t op)
-{
- if (op > BLE_L2CAP_SIG_PROC_OP_MAX) {
- return NULL;
- }
-
- return ble_l2cap_sig_kick[op];
-}
-
-static int
-ble_l2cap_sig_proc_kick(struct ble_fsm_proc *proc)
-{
- ble_l2cap_sig_kick_fn *kick_cb;
- int rc;
-
- kick_cb = ble_l2cap_sig_kick_get(proc->op);
- rc = kick_cb((struct ble_l2cap_sig_proc *)proc);
-
- return rc;
-}
-
-/**
- * Lock restrictions:
- * o Caller locks ble_hs_conn.
- */
static int
ble_l2cap_sig_conn_chan_find(uint16_t conn_handle,
struct ble_hs_conn **out_conn,
@@ -163,9 +96,6 @@ ble_l2cap_sig_conn_chan_find(uint16_t conn_handle,
return rc;
}
-/**
- * Lock restrictions: None.
- */
static uint8_t
ble_l2cap_sig_next_id(void)
{
@@ -178,9 +108,6 @@ ble_l2cap_sig_next_id(void)
return ble_l2cap_sig_cur_id;
}
-/**
- * Lock restrictions: None.
- */
static ble_l2cap_sig_rx_fn *
ble_l2cap_sig_dispatch_get(uint8_t op)
{
@@ -194,8 +121,6 @@ ble_l2cap_sig_dispatch_get(uint8_t op)
/**
* Allocates a proc entry.
*
- * Lock restrictions: None.
- *
* @return An entry on success; null on failure.
*/
static struct ble_l2cap_sig_proc *
@@ -213,11 +138,9 @@ ble_l2cap_sig_proc_alloc(void)
/**
* Frees the specified proc entry. No-op if passed a null pointer.
- *
- * Lock restrictions: None.
*/
static void
-ble_l2cap_sig_proc_free(struct ble_fsm_proc *proc)
+ble_l2cap_sig_proc_free(struct ble_l2cap_sig_proc *proc)
{
int rc;
@@ -227,52 +150,34 @@ ble_l2cap_sig_proc_free(struct ble_fsm_proc *proc)
}
}
-/**
- * Lock restrictions: None.
- */
-static int
-ble_l2cap_sig_new_proc(uint16_t conn_handle, uint8_t op,
- struct ble_l2cap_sig_proc **out_proc)
+static void
+ble_l2cap_sig_proc_insert(struct ble_l2cap_sig_proc *proc)
{
- *out_proc = ble_l2cap_sig_proc_alloc();
- if (*out_proc == NULL) {
- return BLE_HS_ENOMEM;
- }
-
- memset(*out_proc, 0, sizeof **out_proc);
- (*out_proc)->fsm_proc.op = op;
- (*out_proc)->fsm_proc.conn_handle = conn_handle;
- (*out_proc)->fsm_proc.tx_time = os_time_get();
-
- STAILQ_INSERT_TAIL(&ble_l2cap_sig_fsm.procs, &(*out_proc)->fsm_proc, next);
-
- return 0;
+ ble_hs_lock();
+ STAILQ_INSERT_HEAD(&ble_l2cap_sig_procs, proc, next);
+ ble_hs_unlock();
}
/**
* Tests if a proc entry fits the specified criteria.
*
- * Lock restrictions: None.
- *
* @param proc The procedure to test.
* @param conn_handle The connection handle to match against.
* @param op The op code to match against/
* @param id The identifier to match against.
- * @param expecting_only 1=Only match entries expecting a response;
* 0=Ignore this criterion.
*
* @return 1 if the proc matches; 0 otherwise.
*/
static int
ble_l2cap_sig_proc_matches(struct ble_l2cap_sig_proc *proc,
- uint16_t conn_handle, uint8_t op, uint8_t id,
- int expecting_only)
+ uint16_t conn_handle, uint8_t op, uint8_t id)
{
- if (conn_handle != proc->fsm_proc.conn_handle) {
+ if (conn_handle != proc->conn_handle) {
return 0;
}
- if (op != proc->fsm_proc.op) {
+ if (op != proc->op) {
return 0;
}
@@ -280,43 +185,14 @@ ble_l2cap_sig_proc_matches(struct ble_l2cap_sig_proc *proc,
return 0;
}
- if (expecting_only && !(proc->fsm_proc.flags & BLE_FSM_PROC_F_EXPECTING)) {
- return 0;
- }
-
return 1;
}
-struct ble_l2cap_sig_proc_extract_arg {
- uint16_t conn_handle;
- uint8_t op;
- uint8_t id;
-};
-
-static int
-ble_l2cap_sig_proc_extract_cb(struct ble_fsm_proc *proc, void *arg)
-{
- struct ble_l2cap_sig_proc_extract_arg *extract_arg;
-
- extract_arg = arg;
-
- if (ble_l2cap_sig_proc_matches((struct ble_l2cap_sig_proc *)proc,
- extract_arg->conn_handle, extract_arg->op,
- extract_arg->id, 1)) {
- return BLE_FSM_EXTRACT_EMOVE_STOP;
- } else {
- return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
- }
-}
-
/**
* Searches the main proc list for an "expecting" entry whose connection handle
* and op code match those specified. If a matching entry is found, it is
* removed from the list and returned.
*
- * Lock restrictions:
- * o Caller unlocks l2cap_sig.
- *
* @param conn_handle The connection handle to match against.
* @param op The op code to match against.
* @param identifier The identifier to match against.
@@ -328,61 +204,44 @@ static struct ble_l2cap_sig_proc *
ble_l2cap_sig_proc_extract(uint16_t conn_handle, uint8_t op,
uint8_t identifier)
{
- struct ble_l2cap_sig_proc_extract_arg extract_arg;
struct ble_l2cap_sig_proc *proc;
- int rc;
-
- extract_arg.conn_handle = conn_handle;
- extract_arg.op = op;
- extract_arg.id = identifier;
-
- rc = ble_fsm_proc_extract(&ble_l2cap_sig_fsm,
- (struct ble_fsm_proc **)&proc,
- ble_l2cap_sig_proc_extract_cb, &extract_arg);
-
- if (rc != 0) {
- proc = NULL;
+ struct ble_l2cap_sig_proc *prev;
+
+ ble_hs_lock();
+
+ prev = NULL;
+ STAILQ_FOREACH(proc, &ble_l2cap_sig_procs, next) {
+ if (ble_l2cap_sig_proc_matches(proc, conn_handle, op, identifier)) {
+ if (prev == NULL) {
+ STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next);
+ } else {
+ STAILQ_REMOVE_AFTER(&ble_l2cap_sig_procs, prev, next);
+ }
+ break;
+ }
}
- return proc;
-}
+ ble_hs_unlock();
-/**
- * Sets the specified proc entry's "pending" flag (i.e., indicates that the
- * L2CAP sig procedure is stalled until it transmits its next request).
- *
- * Lock restrictions: None.
- */
-static void
-ble_l2cap_sig_proc_set_pending(struct ble_l2cap_sig_proc *proc)
-{
- ble_fsm_proc_set_pending(&proc->fsm_proc);
- ble_hs_kick_l2cap_sig();
+ return proc;
}
-/**
- * Lock restrictions: None.
- */
static int
ble_l2cap_sig_rx_noop(uint16_t conn_handle,
struct ble_l2cap_sig_hdr *hdr,
struct os_mbuf **om)
{
- return 0;
+ return BLE_HS_ENOTSUP;
}
/*****************************************************************************
* $update *
*****************************************************************************/
-/**
- * Lock restrictions:
- * o Caller unlocks ble_hs_conn.
- */
static void
ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
{
- BLE_HS_DBG_ASSERT(!ble_hs_conn_locked_by_cur_task());
+ ble_hs_misc_assert_not_locked();
if (status != 0) {
STATS_INC(ble_l2cap_stats, update_fail);
@@ -393,10 +252,6 @@ ble_l2cap_sig_update_call_cb(struct ble_l2cap_sig_proc *proc, int status)
}
}
-/**
- * Lock restrictions:
- * o Caller unlocks ble_hs_conn.
- */
int
ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
struct ble_l2cap_sig_hdr *hdr,
@@ -415,12 +270,12 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
return rc;
}
- ble_hs_conn_lock();
+ ble_hs_lock();
rc = ble_l2cap_sig_conn_chan_find(conn_handle, &conn, &chan);
if (rc == 0) {
is_master = conn->bhc_flags & BLE_HS_CONN_F_MASTER;
}
- ble_hs_conn_unlock();
+ ble_hs_unlock();
if (rc != 0) {
return rc;
@@ -458,13 +313,13 @@ ble_l2cap_sig_update_req_rx(uint16_t conn_handle,
/* Send L2CAP response. */
rc = ble_l2cap_sig_update_rsp_tx(conn_handle, hdr->identifier,
l2cap_result);
- return rc;
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
}
-/**
- * Lock restrictions:
- * o Caller unlocks all ble_hs mutexes.
- */
static int
ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
struct ble_l2cap_sig_hdr *hdr,
@@ -475,12 +330,10 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
int cb_status;
int rc;
- ble_hs_misc_assert_no_locks();
-
proc = ble_l2cap_sig_proc_extract(conn_handle,
BLE_L2CAP_SIG_PROC_OP_UPDATE,
hdr->identifier);
- if (proc == NULL) {
+ if (proc == NULL) {
return BLE_HS_ENOENT;
}
@@ -511,82 +364,69 @@ ble_l2cap_sig_update_rsp_rx(uint16_t conn_handle,
done:
ble_l2cap_sig_update_call_cb(proc, cb_status);
- ble_l2cap_sig_proc_free(&proc->fsm_proc);
- return rc;
-}
-
-/**
- * Lock restrictions:
- * o Caller locks ble_hs_conn.
- */
-static int
-ble_l2cap_sig_update_kick(struct ble_l2cap_sig_proc *proc)
-{
- struct ble_l2cap_sig_update_req req;
- ble_hs_conn_flags_t flags;
- int rc;
-
- rc = ble_hs_conn_flags(proc->fsm_proc.conn_handle, &flags);
- if (rc == 0) {
- if (flags & BLE_HS_CONN_F_MASTER) {
- /* Only the slave can initiate the L2CAP connection update
- * procedure.
- */
- rc = BLE_HS_EINVAL;
- }
- }
-
- if (rc == 0) {
- proc->id = ble_l2cap_sig_next_id();
- req.itvl_min = proc->update.params.itvl_min;
- req.itvl_max = proc->update.params.itvl_max;
- req.slave_latency = proc->update.params.slave_latency;
- req.timeout_multiplier = proc->update.params.timeout_multiplier;
-
- rc = ble_l2cap_sig_update_req_tx(proc->fsm_proc.conn_handle,
- proc->id, &req);
- }
-
- if (rc != 0) {
- ble_l2cap_sig_update_call_cb(proc, rc);
- rc = BLE_HS_EDONE;
- }
-
+ ble_l2cap_sig_proc_free(proc);
return rc;
}
-/**
- * Lock restrictions: None.
- */
int
ble_l2cap_sig_update(uint16_t conn_handle,
struct ble_l2cap_sig_update_params *params,
ble_l2cap_sig_update_fn *cb, void *cb_arg)
{
+ struct ble_l2cap_sig_update_req req;
struct ble_l2cap_sig_proc *proc;
+ ble_hs_conn_flags_t conn_flags;
int rc;
+ proc = NULL;
+
STATS_INC(ble_l2cap_stats, update_init);
- rc = ble_l2cap_sig_new_proc(conn_handle, BLE_L2CAP_SIG_PROC_OP_UPDATE,
- &proc);
- if (rc == 0) {
- proc->update.params = *params;
- proc->update.cb = cb;
- proc->update.cb_arg = cb_arg;
+ rc = ble_hs_conn_flags(conn_handle, &conn_flags);
+ if (rc != 0) {
+ return rc;
+ }
+ if (conn_flags & BLE_HS_CONN_F_MASTER) {
+ /* Only the slave can initiate the L2CAP connection update
+ * procedure.
+ */
+ rc = BLE_HS_EINVAL;
+ goto err;
+ }
- ble_l2cap_sig_proc_set_pending(proc);
- } else {
+ proc = ble_l2cap_sig_proc_alloc();
+ if (proc == NULL) {
STATS_INC(ble_l2cap_stats, update_fail);
+ rc = BLE_HS_ENOMEM;
+ goto err;
+ }
+
+ proc->op = BLE_L2CAP_SIG_PROC_OP_UPDATE;
+ proc->id = ble_l2cap_sig_next_id();
+ proc->conn_handle = conn_handle;
+ proc->exp_os_ticks = os_time_get() + BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT;
+ proc->update.cb = cb;
+ proc->update.cb_arg = cb_arg;
+
+ req.itvl_min = params->itvl_min;
+ req.itvl_max = params->itvl_max;
+ req.slave_latency = params->slave_latency;
+ req.timeout_multiplier = params->timeout_multiplier;
+
+ rc = ble_l2cap_sig_update_req_tx(conn_handle, proc->id, &req);
+ if (rc != 0) {
+ goto err;
}
+ ble_l2cap_sig_proc_insert(proc);
+
return 0;
+
+err:
+ ble_l2cap_sig_proc_free(proc);
+ return rc;
}
-/**
- * Lock restrictions:
- * o Caller unlocks ble_hs_conn.
- */
static int
ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
{
@@ -625,9 +465,6 @@ ble_l2cap_sig_rx(uint16_t conn_handle, struct os_mbuf **om)
return rc;
}
-/**
- * Lock restrictions: None.
- */
struct ble_l2cap_chan *
ble_l2cap_sig_create_chan(void)
{
@@ -646,30 +483,39 @@ ble_l2cap_sig_create_chan(void)
return chan;
}
-static int
-ble_l2cap_sig_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
+static void
+ble_l2cap_sig_extract_expired(struct ble_l2cap_sig_proc_list *dst_list)
{
- uint32_t *now;
-
- now = arg;
+ struct ble_l2cap_sig_proc *proc;
+ struct ble_l2cap_sig_proc *prev;
+ struct ble_l2cap_sig_proc *next;
+ uint32_t now;
+ int32_t time_diff;
- if (proc->flags & BLE_FSM_PROC_F_EXPECTING) {
- if (*now - proc->tx_time >= BLE_L2CAP_SIG_UNRESPONSIVE_TIMEOUT) {
- return BLE_FSM_EXTRACT_EMOVE_CONTINUE;
+ now = os_time_get();
+ STAILQ_INIT(dst_list);
+
+ ble_hs_lock();
+
+ prev = NULL;
+ proc = STAILQ_FIRST(&ble_l2cap_sig_procs);
+ while (proc != NULL) {
+ next = STAILQ_NEXT(proc, next);
+
+ time_diff = now - proc->exp_os_ticks;
+ if (time_diff >= 0) {
+ if (prev == NULL) {
+ STAILQ_REMOVE_HEAD(&ble_l2cap_sig_procs, next);
+ } else {
+ STAILQ_REMOVE_AFTER(&ble_l2cap_sig_procs, prev, next);
+ }
+ STAILQ_INSERT_TAIL(dst_list, proc, next);
}
- }
- /* If a proc failed due to low memory, don't extract it, but set its
- * pending bit.
- */
- if (proc->flags & BLE_FSM_PROC_F_NO_MEM) {
- proc->flags &= ~BLE_FSM_PROC_F_NO_MEM;
- if (ble_fsm_proc_can_pend(proc)) {
- ble_fsm_proc_set_pending(proc);
- }
+ proc = next;
}
- return BLE_FSM_EXTRACT_EKEEP_CONTINUE;
+ ble_hs_unlock();
}
/**
@@ -682,59 +528,25 @@ ble_l2cap_sig_heartbeat_extract_cb(struct ble_fsm_proc *proc, void *arg)
* seconds are aborted, and their corresponding connection is terminated.
*
* Called by the heartbeat timer; executed every second.
- *
- * Lock restrictions: None.
*/
-static void
-ble_l2cap_sig_heartbeat(void *unused)
+void
+ble_l2cap_sig_heartbeat(void)
{
- struct ble_fsm_proc_list temp_list;
- struct ble_fsm_proc *proc;
- uint32_t ticks;
- uint32_t now;
- int rc;
-
- ble_hs_misc_assert_no_locks();
-
- now = os_time_get();
+ struct ble_l2cap_sig_proc_list temp_list;
+ struct ble_l2cap_sig_proc *proc;
/* Remove timed-out procedures from the main list and insert them into a
- * temporary list. For any stalled procedures, set their pending bit so
- * they can be retried.
+ * temporary list.
*/
- ble_fsm_proc_extract_list(&ble_l2cap_sig_fsm, &temp_list,
- ble_l2cap_sig_heartbeat_extract_cb, &now);
+ ble_l2cap_sig_extract_expired(&temp_list);
/* Terminate the connection associated with each timed-out procedure. */
STAILQ_FOREACH(proc, &temp_list, next) {
STATS_INC(ble_l2cap_stats, proc_timeout);
ble_gap_terminate(proc->conn_handle);
}
-
- /* Concatenate the list of timed out procedures back onto the end of the
- * main list.
- */
- ble_fsm_proc_concat(&ble_l2cap_sig_fsm, &temp_list);
-
- ticks = BLE_L2CAP_SIG_HEARTBEAT_PERIOD * OS_TICKS_PER_SEC / 1000;
- rc = os_callout_reset(&ble_l2cap_sig_heartbeat_timer.cf_c, ticks);
-
- BLE_HS_DBG_ASSERT_EVAL(rc == 0);
}
-/**
- * Lock restrictions:
- * o Caller unlocks ble_hs_conn.
- */
-void
-ble_l2cap_sig_wakeup(void)
-{
- ble_fsm_wakeup(&ble_l2cap_sig_fsm);
-}
-
-/**
- * Lock restrictions: None.
- */
int
ble_l2cap_sig_init(void)
{
@@ -742,11 +554,7 @@ ble_l2cap_sig_init(void)
free(ble_l2cap_sig_proc_mem);
- rc = ble_fsm_new(&ble_l2cap_sig_fsm, ble_l2cap_sig_proc_kick,
- ble_l2cap_sig_proc_free);
- if (rc != 0) {
- goto err;
- }
+ STAILQ_INIT(&ble_l2cap_sig_procs);
if (ble_hs_cfg.max_l2cap_sig_procs > 0) {
ble_l2cap_sig_proc_mem = malloc(
@@ -767,9 +575,6 @@ ble_l2cap_sig_init(void)
}
}
- os_callout_func_init(&ble_l2cap_sig_heartbeat_timer, &ble_hs_evq,
- ble_l2cap_sig_heartbeat, NULL);
-
return 0;
err:
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e32f9f9f/net/nimble/host/src/ble_l2cap_sig_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_l2cap_sig_cmd.c b/net/nimble/host/src/ble_l2cap_sig_cmd.c
index f5f6fa1..290dc43 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -65,7 +65,7 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
STATS_INC(ble_l2cap_stats, sig_tx);
- ble_hs_conn_lock();
+ ble_hs_lock();
rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SIG,
&conn, &chan);
@@ -73,7 +73,7 @@ ble_l2cap_sig_tx(uint16_t conn_handle, struct os_mbuf *txom)
rc = ble_l2cap_tx(conn, chan, txom);
}
- ble_hs_conn_unlock();
+ ble_hs_unlock();
return rc;
}