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/07/28 02:11:09 UTC

[3/5] incubator-mynewt-core git commit: BLE Host - Remove double indirection from tx API.

BLE Host - Remove double indirection from tx API.

Prior to this change, data buffers for tx operations were passed as type
(struct os_mbuf **).  The second pointer was used so that the host could
set the caller's pointer to NULL, indicating that the mbuf had been
consumed and preventing a double-free.

This was useful, but confusing.  Using a single pointer is simpler and
consistent with the other networking libraries in core.  It is up to the
caller to read the function spec and understand that ownership of the
mbuf is transferred.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/f4796bc3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/f4796bc3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/f4796bc3

Branch: refs/heads/develop
Commit: f4796bc366a1e7a682e150e8775e8c2a80ef33f9
Parents: 7f3c681
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Jul 27 17:30:34 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Wed Jul 27 19:06:38 2016 -0700

----------------------------------------------------------------------
 net/nimble/host/include/host/ble_att.h      |   2 +-
 net/nimble/host/include/host/ble_gatt.h     |   8 +-
 net/nimble/host/include/host/ble_hs.h       |   2 +-
 net/nimble/host/include/host/host_hci.h     |   2 +-
 net/nimble/host/src/ble_att_clt.c           | 171 +++++++++++------------
 net/nimble/host/src/ble_att_priv.h          |  14 +-
 net/nimble/host/src/ble_att_svr.c           |  90 ++++++------
 net/nimble/host/src/ble_gatt_priv.h         |   8 +-
 net/nimble/host/src/ble_gattc.c             |  78 +++++------
 net/nimble/host/src/ble_hs.c                |  13 +-
 net/nimble/host/src/ble_l2cap.c             |  24 +---
 net/nimble/host/src/ble_l2cap_priv.h        |   5 +-
 net/nimble/host/src/ble_l2cap_sig_cmd.c     |   6 +-
 net/nimble/host/src/ble_sm_cmd.c            | 151 ++++++++------------
 net/nimble/host/src/ble_sm_priv.h           |   5 +-
 net/nimble/host/src/host_hci.c              |  30 ++--
 net/nimble/host/src/test/ble_att_clt_test.c |  11 +-
 net/nimble/host/src/test/ble_hs_test_util.c |  13 +-
 18 files changed, 276 insertions(+), 357 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 e5eb820..6afca97 100644
--- a/net/nimble/host/include/host/ble_att.h
+++ b/net/nimble/host/include/host/ble_att.h
@@ -95,7 +95,7 @@ struct os_mbuf;
 #define BLE_ATT_MTU_PREFERRED_DFLT      240
 
 int ble_att_svr_read_local(uint16_t attr_handle, struct os_mbuf **out_om);
-int ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf **om);
+int ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om);
 
 uint16_t ble_att_mtu(uint16_t conn_handle);
 int ble_att_set_preferred_mtu(uint16_t mtu);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/include/host/ble_gatt.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_gatt.h b/net/nimble/host/include/host/ble_gatt.h
index 8aab982..fbc32a2 100644
--- a/net/nimble/host/include/host/ble_gatt.h
+++ b/net/nimble/host/include/host/ble_gatt.h
@@ -164,24 +164,24 @@ int ble_gattc_read_mult(uint16_t conn_handle, const uint16_t *handles,
                         uint8_t num_handles, ble_gatt_attr_fn *cb,
                         void *cb_arg);
 int ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
-                           struct os_mbuf **om);
+                           struct os_mbuf *om);
 int ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle,
                                 const void *data, uint16_t data_len);
 int ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle,
-                    struct os_mbuf **om,
+                    struct os_mbuf *om,
                     ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle,
                          const void *data, uint16_t data_len,
                          ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle,
-                         struct os_mbuf **om,
+                         struct os_mbuf *om,
                          ble_gatt_attr_fn *cb, void *cb_arg);
 int ble_gattc_write_reliable(uint16_t conn_handle,
                              struct ble_gatt_attr *attrs,
                              int num_attrs, ble_gatt_reliable_attr_fn *cb,
                              void *cb_arg);
 int ble_gattc_notify_custom(uint16_t conn_handle, uint16_t att_handle,
-                            struct os_mbuf **om);
+                            struct os_mbuf *om);
 int ble_gattc_notify(uint16_t conn_handle, uint16_t chr_val_handle);
 int ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/include/host/ble_hs.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/ble_hs.h b/net/nimble/host/include/host/ble_hs.h
index 56fbc2b..5cdf863 100644
--- a/net/nimble/host/include/host/ble_hs.h
+++ b/net/nimble/host/include/host/ble_hs.h
@@ -230,7 +230,7 @@ struct ble_hs_cfg {
 
 extern const struct ble_hs_cfg ble_hs_cfg_dflt;
 
-int ble_hs_rx_data(struct os_mbuf **om);
+int ble_hs_rx_data(struct os_mbuf *om);
 int ble_hs_start(void);
 void ble_hs_event_enqueue(struct os_event *ev);
 int ble_hs_init(struct os_eventq *app_evq, struct ble_hs_cfg *cfg);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/include/host/host_hci.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/include/host/host_hci.h b/net/nimble/host/include/host/host_hci.h
index bcec2ef..f92c1a9 100644
--- a/net/nimble/host/include/host/host_hci.h
+++ b/net/nimble/host/include/host/host_hci.h
@@ -104,7 +104,7 @@ int host_hci_set_buf_size(uint16_t pktlen, uint8_t max_pkts);
 uint16_t host_hci_handle_pb_bc_join(uint16_t handle, uint8_t pb, uint8_t bc);
 
 int host_hci_data_rx(struct os_mbuf *om);
-int host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf **txom);
+int host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *txom);
 
 int host_hci_cmd_build_set_data_len(uint16_t connection_handle,
                                     uint16_t tx_octets, uint16_t tx_time,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 5687a99..87e2f44 100644
--- a/net/nimble/host/src/ble_att_clt.c
+++ b/net/nimble/host/src/ble_att_clt.c
@@ -59,31 +59,29 @@ err:
 }
 
 static int
-ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf **txom)
+ble_att_clt_tx_req(uint16_t conn_handle, struct os_mbuf *txom)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
-    BLE_HS_DBG_ASSERT_EVAL(om->om_len >= 1);
-    ble_att_inc_tx_stat(om->om_data[0]);
+    BLE_HS_DBG_ASSERT_EVAL(txom->om_len >= 1);
+    ble_att_inc_tx_stat(txom->om_data[0]);
 
     ble_hs_lock();
 
     rc = ble_att_conn_chan_find(conn_handle, &conn, &chan);
     if (rc == 0) {
-        ble_att_truncate_to_mtu(chan, om);
-        rc = ble_l2cap_tx(conn, chan, &om);
+        ble_att_truncate_to_mtu(chan, txom);
+        rc = ble_l2cap_tx(conn, chan, txom);
     }
 
     ble_hs_unlock();
 
-    os_mbuf_free_chain(om);
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+    }
+
     return rc;
 }
 
@@ -134,7 +132,7 @@ ble_att_clt_tx_mtu(uint16_t conn_handle, const struct ble_att_mtu_cmd *req)
     }
     ble_att_mtu_req_write(txom->om_data, txom->om_len, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -211,7 +209,7 @@ ble_att_clt_tx_find_info(uint16_t conn_handle,
     }
     ble_att_find_info_req_write(txom->om_data, txom->om_len, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -338,27 +336,30 @@ ble_att_clt_tx_find_type_value(uint16_t conn_handle,
         req->bavq_start_handle > req->bavq_end_handle) {
 
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
     rc = ble_att_clt_init_req(BLE_ATT_FIND_TYPE_VALUE_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
     ble_att_find_type_value_req_write(txom->om_data, txom->om_len, req);
     rc = os_mbuf_append(txom, attribute_value, value_len);
     if (rc != 0) {
         rc = BLE_HS_ENOMEM;
-        goto done;
+        goto err;
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-done:
+    return 0;
+
+err:
     os_mbuf_free_chain(txom);
     return rc;
 }
@@ -441,27 +442,30 @@ ble_att_clt_tx_read_type(uint16_t conn_handle,
         req->batq_start_handle > req->batq_end_handle) {
 
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
     rc = ble_att_clt_init_req(BLE_ATT_READ_TYPE_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
     ble_att_read_type_req_write(txom->om_data, txom->om_len, req);
     rc = ble_uuid_append(txom, uuid128);
     if (rc != 0) {
         rc = BLE_HS_ENOMEM;
-        goto done;
+        goto err;
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-done:
+    return 0;
+
+err:
     os_mbuf_free_chain(txom);
     return 0;
 }
@@ -551,7 +555,7 @@ ble_att_clt_tx_read(uint16_t conn_handle, const struct ble_att_read_req *req)
     }
     ble_att_read_req_write(txom->om_data, txom->om_len, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -606,7 +610,7 @@ ble_att_clt_tx_read_blob(uint16_t conn_handle,
     }
     ble_att_read_blob_req_write(txom->om_data, txom->om_len, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -695,7 +699,7 @@ ble_att_clt_tx_read_mult(uint16_t conn_handle, const uint16_t *att_handles,
         return rc;
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -747,26 +751,29 @@ ble_att_clt_tx_read_group_type(uint16_t conn_handle,
         req->bagq_start_handle > req->bagq_end_handle) {
 
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
     rc = ble_att_clt_init_req(BLE_ATT_READ_GROUP_TYPE_REQ_BASE_SZ, &txom);
     if (rc != 0) {
-        goto done;
+        goto err;
     }
     ble_att_read_group_type_req_write(txom->om_data, txom->om_len, req);
 
     rc = ble_uuid_append(txom, uuid128);
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-done:
+    return 0;
+
+err:
     os_mbuf_free_chain(txom);
     return rc;
 }
@@ -843,27 +850,22 @@ done:
 static int
 ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
                                 const struct ble_att_write_req *req,
-                                struct os_mbuf **txom, int is_req)
+                                struct os_mbuf *txom, int is_req)
 {
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
-    om = os_mbuf_prepend_pullup(om, BLE_ATT_WRITE_REQ_BASE_SZ);
-    if (om == NULL) {
+    txom = os_mbuf_prepend_pullup(txom, BLE_ATT_WRITE_REQ_BASE_SZ);
+    if (txom == NULL) {
         return BLE_HS_ENOMEM;
     }
 
     if (is_req) {
-        ble_att_write_req_write(om->om_data, BLE_ATT_WRITE_REQ_BASE_SZ, req);
+        ble_att_write_req_write(txom->om_data, BLE_ATT_WRITE_REQ_BASE_SZ, req);
     } else {
-        ble_att_write_cmd_write(om->om_data, BLE_ATT_WRITE_REQ_BASE_SZ, req);
+        ble_att_write_cmd_write(txom->om_data, BLE_ATT_WRITE_REQ_BASE_SZ, req);
     }
 
-    rc = ble_att_clt_tx_req(conn_handle, &om);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -874,7 +876,7 @@ ble_att_clt_tx_write_req_or_cmd(uint16_t conn_handle,
 int
 ble_att_clt_tx_write_req(uint16_t conn_handle,
                          const struct ble_att_write_req *req,
-                         struct os_mbuf **txom)
+                         struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(ATT_CLT_WRITE)
     return BLE_HS_ENOTSUP;
@@ -891,7 +893,7 @@ ble_att_clt_tx_write_req(uint16_t conn_handle,
 int
 ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                          const struct ble_att_write_req *req,
-                         struct os_mbuf **txom)
+                         struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(ATT_CLT_WRITE_NO_RSP)
     return BLE_HS_ENOTSUP;
@@ -926,55 +928,53 @@ ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
 int
 ble_att_clt_tx_prep_write(uint16_t conn_handle,
                           const struct ble_att_prep_write_cmd *req,
-                          struct os_mbuf **txom)
+                          struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(ATT_CLT_PREP_WRITE)
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
     BLE_ATT_LOG_CMD(1, "prep write req", conn_handle,
                     ble_att_prep_write_cmd_log, req);
 
     if (req->bapc_handle == 0) {
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
-    if (req->bapc_offset + OS_MBUF_PKTLEN(om) > BLE_ATT_ATTR_MAX_LEN) {
+    if (req->bapc_offset + OS_MBUF_PKTLEN(txom) > BLE_ATT_ATTR_MAX_LEN) {
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
-    if (OS_MBUF_PKTLEN(om) >
+    if (OS_MBUF_PKTLEN(txom) >
         ble_att_mtu(conn_handle) - BLE_ATT_PREP_WRITE_CMD_BASE_SZ) {
 
         rc = BLE_HS_EINVAL;
-        goto done;
+        goto err;
     }
 
-    om = os_mbuf_prepend_pullup(om, BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
-    if (om == NULL) {
+    txom = os_mbuf_prepend_pullup(txom, BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
+    if (txom == NULL) {
         rc = BLE_HS_ENOMEM;
-        goto done;
+        goto err;
     }
 
-    ble_att_prep_write_req_write(om->om_data, BLE_ATT_PREP_WRITE_CMD_BASE_SZ,
+    ble_att_prep_write_req_write(txom->om_data, BLE_ATT_PREP_WRITE_CMD_BASE_SZ,
                                  req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &om);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-done:
-    os_mbuf_free_chain(om);
+    return 0;
+
+err:
+    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1037,7 +1037,7 @@ ble_att_clt_tx_exec_write(uint16_t conn_handle,
     }
     ble_att_exec_write_req_write(txom->om_data, txom->om_len, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &txom);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
     if (rc != 0) {
         return rc;
     }
@@ -1072,19 +1072,14 @@ ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom)
 int
 ble_att_clt_tx_notify(uint16_t conn_handle,
                       const struct ble_att_notify_req *req,
-                      struct os_mbuf **txom)
+                      struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(ATT_CLT_NOTIFY)
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
     BLE_ATT_LOG_CMD(1, "notify req", conn_handle, ble_att_notify_req_log, req);
 
     if (req->banq_handle == 0) {
@@ -1092,14 +1087,15 @@ ble_att_clt_tx_notify(uint16_t conn_handle,
         goto err;
     }
 
-    om = os_mbuf_prepend_pullup(om, BLE_ATT_NOTIFY_REQ_BASE_SZ);
-    if (om == NULL) {
+    txom = os_mbuf_prepend_pullup(txom, BLE_ATT_NOTIFY_REQ_BASE_SZ);
+    if (txom == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
-    ble_att_notify_req_write(om->om_data, BLE_ATT_NOTIFY_REQ_BASE_SZ, req);
+    ble_att_notify_req_write(txom->om_data, BLE_ATT_NOTIFY_REQ_BASE_SZ, req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &om);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
         goto err;
     }
@@ -1107,7 +1103,7 @@ ble_att_clt_tx_notify(uint16_t conn_handle,
     return 0;
 
 err:
-    os_mbuf_free_chain(om);
+    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1118,19 +1114,14 @@ err:
 int
 ble_att_clt_tx_indicate(uint16_t conn_handle,
                         const struct ble_att_indicate_req *req,
-                        struct os_mbuf **txom)
+                        struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(ATT_CLT_INDICATE)
     return BLE_HS_ENOTSUP;
 #endif
 
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
     BLE_ATT_LOG_CMD(1, "indicate req", conn_handle, ble_att_indicate_req_log,
                     req);
 
@@ -1139,15 +1130,17 @@ ble_att_clt_tx_indicate(uint16_t conn_handle,
         goto err;
     }
 
-    om = os_mbuf_prepend_pullup(om, BLE_ATT_INDICATE_REQ_BASE_SZ);
-    if (om == NULL) {
+    txom = os_mbuf_prepend_pullup(txom, BLE_ATT_INDICATE_REQ_BASE_SZ);
+    if (txom == NULL) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
 
-    ble_att_indicate_req_write(om->om_data, BLE_ATT_INDICATE_REQ_BASE_SZ, req);
+    ble_att_indicate_req_write(txom->om_data, BLE_ATT_INDICATE_REQ_BASE_SZ,
+                               req);
 
-    rc = ble_att_clt_tx_req(conn_handle, &om);
+    rc = ble_att_clt_tx_req(conn_handle, txom);
+    txom = NULL;
     if (rc != 0) {
         goto err;
     }
@@ -1155,7 +1148,7 @@ ble_att_clt_tx_indicate(uint16_t conn_handle,
     return 0;
 
 err:
-    os_mbuf_free_chain(om);
+    os_mbuf_free_chain(txom);
     return rc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 f20817c..edf9dce 100644
--- a/net/nimble/host/src/ble_att_priv.h
+++ b/net/nimble/host/src/ble_att_priv.h
@@ -179,7 +179,7 @@ ble_att_svr_find_by_uuid(struct ble_att_svr_entry *start_at,
                          const uint8_t *uuid,
                          uint16_t end_handle);
 uint16_t ble_att_svr_prev_handle(void);
-int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **om);
+int ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom);
 struct ble_att_svr_entry *ble_att_svr_find_by_handle(uint16_t handle_id);
 int ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_svr_rx_find_type_value(uint16_t conn_handle,
@@ -266,7 +266,7 @@ int ble_att_clt_rx_read_group_type(uint16_t conn_handle,
                                    struct os_mbuf **rxom);
 int ble_att_clt_tx_find_info(uint16_t conn_handle,
                              const struct ble_att_find_info_req *req);
-int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **om);
+int ble_att_clt_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_clt_tx_find_type_value(
     uint16_t conn_handle, const struct ble_att_find_type_value_req *req,
     const void *attribute_value, int value_len);
@@ -274,13 +274,13 @@ int ble_att_clt_rx_find_type_value(uint16_t conn_handle,
                                    struct os_mbuf **rxom);
 int ble_att_clt_tx_write_req(uint16_t conn_handle,
                              const struct ble_att_write_req *req,
-                             struct os_mbuf **txom);
+                             struct os_mbuf *txom);
 int ble_att_clt_tx_write_cmd(uint16_t conn_handle,
                              const struct ble_att_write_req *req,
-                             struct os_mbuf **txom);
+                             struct os_mbuf *txom);
 int ble_att_clt_tx_prep_write(uint16_t conn_handle,
                               const struct ble_att_prep_write_cmd *req,
-                              struct os_mbuf **om);
+                              struct os_mbuf *txom);
 int ble_att_clt_rx_prep_write(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_clt_tx_exec_write(uint16_t conn_handle,
                               const struct ble_att_exec_write_req *req);
@@ -288,10 +288,10 @@ int ble_att_clt_rx_exec_write(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_clt_rx_write(uint16_t conn_handle, struct os_mbuf **rxom);
 int ble_att_clt_tx_notify(uint16_t conn_handle,
                           const struct ble_att_notify_req *req,
-                          struct os_mbuf **txom);
+                          struct os_mbuf *txom);
 int ble_att_clt_tx_indicate(uint16_t conn_handle,
                             const struct ble_att_indicate_req *req,
-                            struct os_mbuf **txom);
+                            struct os_mbuf *txom);
 int ble_att_clt_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom);
 
 #endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 a9f5409..7ccae06 100644
--- a/net/nimble/host/src/ble_att_svr.c
+++ b/net/nimble/host/src/ble_att_svr.c
@@ -502,7 +502,7 @@ ble_att_svr_write_handle(uint16_t conn_handle, uint16_t attr_handle,
 
 static int
 ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                         struct os_mbuf **om, uint8_t req_op,
+                         struct os_mbuf *txom, uint8_t req_op,
                          uint16_t handle, uint8_t error_code)
 {
     struct ble_att_error_rsp rsp;
@@ -510,11 +510,12 @@ ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     int rc;
 
     BLE_HS_DBG_ASSERT(error_code != 0);
-    BLE_HS_DBG_ASSERT(OS_MBUF_PKTLEN(*om) == 0);
+    BLE_HS_DBG_ASSERT(OS_MBUF_PKTLEN(txom) == 0);
 
-    dst = os_mbuf_extend(*om, BLE_ATT_ERROR_RSP_SZ);
+    dst = os_mbuf_extend(txom, BLE_ATT_ERROR_RSP_SZ);
     if (dst == NULL) {
-        return BLE_HS_ENOMEM;
+        rc = BLE_HS_ENOMEM;
+        goto err;
     }
 
     rsp.baep_req_op = req_op;
@@ -525,12 +526,17 @@ ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
     BLE_ATT_LOG_CMD(1, "error rsp", conn->bhc_handle,
                     ble_att_error_rsp_log, &rsp);
 
-    rc = ble_l2cap_tx(conn, chan, om);
+    rc = ble_l2cap_tx(conn, chan, txom);
+    txom = NULL;
     if (rc != 0) {
-        return rc;
+        goto err;
     }
 
     return 0;
+
+err:
+    os_mbuf_free_chain(txom);
+    return rc;
 }
 
 /**
@@ -557,15 +563,13 @@ ble_att_svr_tx_error_rsp(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
  *                                  field.
  */
 static int
-ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf **om,
+ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf *om,
                    uint8_t att_op, uint8_t err_status, uint16_t err_handle)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
     int do_tx;
 
-    BLE_HS_DBG_ASSERT(om != NULL);
-
     if (rc == BLE_HS_ENOTCONN) {
         /* No connection; tx is not possible. */
         do_tx = 0;
@@ -584,11 +588,10 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf **om,
             rc = BLE_HS_ENOTCONN;
         } else {
             if (rc == 0) {
-                BLE_HS_DBG_ASSERT(*om != NULL);
-
-                ble_att_inc_tx_stat((*om)->om_data[0]);
-                ble_att_truncate_to_mtu(chan, *om);
+                ble_att_inc_tx_stat(om->om_data[0]);
+                ble_att_truncate_to_mtu(chan, om);
                 rc = ble_l2cap_tx(conn, chan, om);
+                om = NULL;
                 if (rc != 0) {
                     err_status = BLE_ATT_ERR_UNLIKELY;
                 }
@@ -598,15 +601,15 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf **om,
                 STATS_INC(ble_att_stats, error_rsp_tx);
 
                 /* Reuse om for error response. */
-                if (*om == NULL) {
-                    *om = ble_hs_mbuf_l2cap_pkt();
+                if (om == NULL) {
+                    om = ble_hs_mbuf_l2cap_pkt();
                 } else {
-                    /* Remove response from mbuf. */
-                    os_mbuf_adj(*om, OS_MBUF_PKTLEN(*om));
+                    os_mbuf_adj(om, OS_MBUF_PKTLEN(om));
                 }
                 if (om != NULL) {
                     ble_att_svr_tx_error_rsp(conn, chan, om, att_op,
                                              err_handle, err_status);
+                    om = NULL;
                 }
             }
         }
@@ -614,6 +617,9 @@ ble_att_svr_tx_rsp(uint16_t conn_handle, int rc, struct os_mbuf **om,
         ble_hs_unlock();
     }
 
+    /* Free mbuf if it was not consumed (send failed). */
+    os_mbuf_free_chain(om);
+
     return rc;
 }
 
@@ -696,10 +702,8 @@ ble_att_svr_rx_mtu(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_MTU_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_MTU_REQ,
                             att_err, 0);
-    os_mbuf_free_chain(txom);
-
     if (rc == 0) {
         ble_hs_lock();
         ble_att_conn_chan_find(conn_handle, &conn, &chan);
@@ -916,9 +920,8 @@ ble_att_svr_rx_find_info(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_FIND_INFO_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_FIND_INFO_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1236,10 +1239,9 @@ ble_att_svr_rx_find_type_value(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom,
                             BLE_ATT_OP_FIND_TYPE_VALUE_REQ, att_err,
                             err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1444,9 +1446,8 @@ ble_att_svr_rx_read_type(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_READ_TYPE_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_TYPE_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1501,9 +1502,8 @@ ble_att_svr_rx_read(uint16_t conn_handle, struct os_mbuf **rxom)
     }
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_READ_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1570,9 +1570,8 @@ ble_att_svr_rx_read_blob(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_READ_BLOB_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_BLOB_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -1689,9 +1688,8 @@ ble_att_svr_rx_read_mult(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_READ_MULT_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_READ_MULT_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -2027,10 +2025,9 @@ ble_att_svr_rx_read_group_type(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom,
                             BLE_ATT_OP_READ_GROUP_TYPE_REQ, att_err,
                             err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -2113,9 +2110,8 @@ ble_att_svr_rx_write(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_WRITE_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_WRITE_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -2159,9 +2155,7 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
  * performed by calling the registered GATT access callback.
  *
  * @param attr_handle           The 16-bit handle of the attribute to write.
- * @param om                    The value to write to the attribute.  Double
- *                                  indirection is used to effect a transfer of
- *                                  ownership from the caller.
+ * @param om                    The value to write to the attribute.
  *
  * @return                      0 on success;
  *                              NimBLE host ATT return code if the attribute
@@ -2170,16 +2164,15 @@ ble_att_svr_rx_write_no_rsp(uint16_t conn_handle, struct os_mbuf **rxom)
  *                                  error.
  */
 int
-ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf **om)
+ble_att_svr_write_local(uint16_t attr_handle, struct os_mbuf *om)
 {
     int rc;
 
     rc = ble_att_svr_write_handle(BLE_HS_CONN_HANDLE_NONE, attr_handle, 0,
-                                  om, NULL);
+                                  &om, NULL);
 
-    /* Free the mbuf in case it wasn't consumed (i.e., something failed). */
-    os_mbuf_free_chain(*om);
-    *om = NULL;
+    /* Free the mbuf if it wasn't relinquished to the application. */
+    os_mbuf_free_chain(om);
 
     return rc;
 }
@@ -2505,9 +2498,8 @@ done:
         ble_hs_unlock();
     }
 
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_PREP_WRITE_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_PREP_WRITE_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
 
     return rc;
 }
@@ -2614,9 +2606,8 @@ done:
         }
     }
 
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_EXEC_WRITE_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_EXEC_WRITE_REQ,
                             att_err, err_handle);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 
@@ -2735,9 +2726,8 @@ ble_att_svr_rx_indicate(uint16_t conn_handle, struct os_mbuf **rxom)
     rc = 0;
 
 done:
-    rc = ble_att_svr_tx_rsp(conn_handle, rc, &txom, BLE_ATT_OP_INDICATE_REQ,
+    rc = ble_att_svr_tx_rsp(conn_handle, rc, txom, BLE_ATT_OP_INDICATE_REQ,
                             0, 0);
-    os_mbuf_free_chain(txom);
     return rc;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/src/ble_gatt_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gatt_priv.h b/net/nimble/host/src/ble_gatt_priv.h
index c33d5c6..7c0f020 100644
--- a/net/nimble/host/src/ble_gatt_priv.h
+++ b/net/nimble/host/src/ble_gatt_priv.h
@@ -103,11 +103,11 @@ void ble_gattc_rx_read_type_adata(uint16_t conn_handle,
                                   struct ble_att_read_type_adata *adata);
 void ble_gattc_rx_read_type_complete(uint16_t conn_handle, int status);
 void ble_gattc_rx_read_rsp(uint16_t conn_handle, int status,
-                           struct os_mbuf **om);
+                           struct os_mbuf **rxom);
 void ble_gattc_rx_read_blob_rsp(uint16_t conn_handle, int status,
-                                struct os_mbuf **om);
+                                struct os_mbuf **rxom);
 void ble_gattc_rx_read_mult_rsp(uint16_t conn_handle, int status,
-                                struct os_mbuf **om);
+                                struct os_mbuf **rxom);
 void ble_gattc_rx_read_group_type_adata(
     uint16_t conn_handle, struct ble_att_read_group_type_adata *adata);
 void ble_gattc_rx_read_group_type_complete(uint16_t conn_handle, int rc);
@@ -117,7 +117,7 @@ void ble_gattc_rx_find_type_value_complete(uint16_t conn_handle, int status);
 void ble_gattc_rx_write_rsp(uint16_t conn_handle);
 void ble_gattc_rx_prep_write_rsp(uint16_t conn_handle, int status,
                                  struct ble_att_prep_write_cmd *rsp,
-                                 struct os_mbuf **om);
+                                 struct os_mbuf **rxom);
 void ble_gattc_rx_exec_write_rsp(uint16_t conn_handle, int status);
 void ble_gattc_rx_indicate_rsp(uint16_t conn_handle);
 void ble_gattc_rx_find_info_idata(uint16_t conn_handle,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_gattc.c b/net/nimble/host/src/ble_gattc.c
index 323c7f2..49c432f 100644
--- a/net/nimble/host/src/ble_gattc.c
+++ b/net/nimble/host/src/ble_gattc.c
@@ -3112,14 +3112,12 @@ done:
  * @param attr_handle           The handle of the characteristic value to write
  *                                  to.
  * @param txom                  The value to write to the characteristic.
- *                                  Double indirection is used to effect a
- *                                  transfer of ownership from the caller.
  *
  * @return                      0 on success; nonzero on failure.
  */
 int
 ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
-                       struct os_mbuf **txom)
+                       struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(GATT_WRITE_NO_RSP)
     return BLE_HS_ENOTSUP;
@@ -3130,7 +3128,7 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
 
     STATS_INC(ble_gattc_stats, write_no_rsp);
 
-    ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(*txom), 0);
+    ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 0);
 
     req.bawq_handle = attr_handle;
     rc = ble_att_clt_tx_write_cmd(conn_handle, &req, txom);
@@ -3138,10 +3136,6 @@ ble_gattc_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
         STATS_INC(ble_gattc_stats, write);
     }
 
-    /* Free the mbuf in case the send failed. */
-    os_mbuf_free_chain(*txom);
-    *txom = NULL;
-
     return rc;
 }
 
@@ -3170,7 +3164,7 @@ ble_gattc_write_no_rsp_flat(uint16_t conn_handle, uint16_t attr_handle,
         return BLE_HS_ENOMEM;
     }
 
-    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, &om);
+    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, om);
     if (rc != 0) {
         return rc;
     }
@@ -3237,8 +3231,6 @@ ble_gattc_write_err(struct ble_gattc_proc *proc, int status,
  * @param attr_handle           The handle of the characteristic value to write
  *                                  to.
  * @param txom                  The value to write to the characteristic.
- *                                  Double indirection is used to effect a
- *                                  transfer of ownership from the caller.
  * @param cb                    The function to call to report procedure status
  *                                  updates; null for no callback.
  * @param cb_arg                The optional argument to pass to the callback
@@ -3248,7 +3240,7 @@ ble_gattc_write_err(struct ble_gattc_proc *proc, int status,
  */
 int
 ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle,
-                struct os_mbuf **txom, ble_gatt_attr_fn *cb, void *cb_arg)
+                struct os_mbuf *txom, ble_gatt_attr_fn *cb, void *cb_arg)
 {
 #if !NIMBLE_OPT(GATT_WRITE)
     return BLE_HS_ENOTSUP;
@@ -3272,10 +3264,11 @@ ble_gattc_write(uint16_t conn_handle, uint16_t attr_handle,
     proc->write.cb = cb;
     proc->write.cb_arg = cb_arg;
 
-    ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(*txom), 1);
+    ble_gattc_log_write(attr_handle, OS_MBUF_PKTLEN(txom), 1);
 
     req.bawq_handle = attr_handle;
     rc = ble_att_clt_tx_write_req(conn_handle, &req, txom);
+    txom = NULL;
     if (rc != 0) {
         goto done;
     }
@@ -3286,8 +3279,7 @@ done:
     }
 
     /* Free the mbuf in case the send failed. */
-    os_mbuf_free_chain(*txom);
-    *txom = NULL;
+    os_mbuf_free_chain(txom);
 
     ble_gattc_process_status(proc, rc);
     return rc;
@@ -3322,7 +3314,7 @@ ble_gattc_write_flat(uint16_t conn_handle, uint16_t attr_handle,
         return BLE_HS_ENOMEM;
     }
 
-    rc = ble_gattc_write(conn_handle, attr_handle, &om, cb, cb_arg);
+    rc = ble_gattc_write(conn_handle, attr_handle, om, cb, cb_arg);
     if (rc != 0) {
         return rc;
     }
@@ -3421,7 +3413,8 @@ ble_gattc_write_long_go(struct ble_gattc_proc *proc, int cb_on_err)
     prep_req.bapc_handle = proc->write_long.attr.handle;
     prep_req.bapc_offset = proc->write_long.attr.offset;
 
-    rc = ble_att_clt_tx_prep_write(proc->conn_handle, &prep_req, &om);
+    rc = ble_att_clt_tx_prep_write(proc->conn_handle, &prep_req, om);
+    om = NULL;
     if (rc != 0) {
         goto done;
     }
@@ -3548,8 +3541,6 @@ ble_gattc_write_long_rx_exec(struct ble_gattc_proc *proc, int status)
  * @param attr_handle           The handle of the characteristic value to write
  *                                  to.
  * @param txom                  The value to write to the characteristic.
- *                                  Double indirection is used to effect a
- *                                  transfer of ownership from the caller.
  * @param cb                    The function to call to report procedure status
  *                                  updates; null for no callback.
  * @param cb_arg                The optional argument to pass to the callback
@@ -3559,7 +3550,7 @@ ble_gattc_write_long_rx_exec(struct ble_gattc_proc *proc, int status)
  */
 int
 ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle,
-                     struct os_mbuf **txom, ble_gatt_attr_fn *cb, void *cb_arg)
+                     struct os_mbuf *txom, ble_gatt_attr_fn *cb, void *cb_arg)
 {
 #if !NIMBLE_OPT(GATT_WRITE_LONG)
     return BLE_HS_ENOTSUP;
@@ -3580,12 +3571,12 @@ ble_gattc_write_long(uint16_t conn_handle, uint16_t attr_handle,
     proc->conn_handle = conn_handle;
     proc->write_long.attr.handle = attr_handle;
     proc->write_long.attr.offset = 0;
-    proc->write_long.attr.om = *txom;
+    proc->write_long.attr.om = txom;
     proc->write_long.cb = cb;
     proc->write_long.cb_arg = cb_arg;
 
     /* The mbuf is consumed by the procedure. */
-    *txom = NULL;
+    txom = NULL;
 
     ble_gattc_log_write_long(proc);
 
@@ -3600,8 +3591,7 @@ done:
     }
 
     /* Free the mbuf in case of failure. */
-    os_mbuf_free_chain(*txom);
-    *txom = NULL;
+    os_mbuf_free_chain(txom);
 
     ble_gattc_process_status(proc, rc);
     return rc;
@@ -3699,7 +3689,8 @@ ble_gattc_write_reliable_go(struct ble_gattc_proc *proc, int cb_on_err)
     prep_req.bapc_handle = attr->handle;
     prep_req.bapc_offset = attr->offset;
 
-    rc = ble_att_clt_tx_prep_write(proc->conn_handle, &prep_req, &om);
+    rc = ble_att_clt_tx_prep_write(proc->conn_handle, &prep_req, om);
+    om = NULL;
     if (rc != 0) {
         goto done;
     }
@@ -3914,63 +3905,57 @@ done:
  * @param chr_val_handle        The attribute handle to indicate in the
  *                                  outgoing notification.
  * @param txom                  The value to write to the characteristic.
- *                                  Double indirection is used to effect a
- *                                  transfer of ownership from the caller.
  *
  * @return                      0 on success; nonzero on failure.
  */
 int
 ble_gattc_notify_custom(uint16_t conn_handle, uint16_t chr_val_handle,
-                        struct os_mbuf **txom)
+                        struct os_mbuf *txom)
 {
 #if !NIMBLE_OPT(GATT_NOTIFY)
     return BLE_HS_ENOTSUP;
 #endif
 
     struct ble_att_notify_req req;
-    struct os_mbuf *om;
     int rc;
 
     STATS_INC(ble_gattc_stats, notify);
 
     ble_gattc_log_notify(chr_val_handle);
 
-    if (txom != NULL) {
-        /* Consume mbuf from caller. */
-        om = *txom;
-        *txom = NULL;
-    } else {
+    if (txom == NULL) {
         /* No custom attribute data; read the value from the specified
          * attribute.
          */
-        om = ble_hs_mbuf_att_pkt();
-        if (om == NULL) {
+        txom = ble_hs_mbuf_att_pkt();
+        if (txom == NULL) {
             rc = BLE_HS_ENOMEM;
-            goto done;
+            goto err;
         }
         rc = ble_att_svr_read_handle(BLE_HS_CONN_HANDLE_NONE,
-                                     chr_val_handle, 0, om, NULL);
+                                     chr_val_handle, 0, txom, NULL);
         if (rc != 0) {
             /* Fatal error; application disallowed attribute read. */
             rc = BLE_HS_EAPP;
-            goto done;
+            goto err;
         }
     }
 
     req.banq_handle = chr_val_handle;
-    rc = ble_att_clt_tx_notify(conn_handle, &req, &om);
+    rc = ble_att_clt_tx_notify(conn_handle, &req, txom);
+    txom = NULL;
     if (rc != 0) {
-        goto done;
+        goto err;
     }
 
-    rc = 0;
+    return 0;
 
-done:
+err:
     if (rc != 0) {
         STATS_INC(ble_gattc_stats, notify_fail);
     }
 
-    os_mbuf_free_chain(om);
+    os_mbuf_free_chain(txom);
 
     return rc;
 }
@@ -4100,6 +4085,8 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle)
 
     STATS_INC(ble_gattc_stats, indicate);
 
+    om = NULL;
+
     proc = ble_gattc_proc_alloc();
     if (proc == NULL) {
         rc = BLE_HS_ENOMEM;
@@ -4128,7 +4115,8 @@ ble_gattc_indicate(uint16_t conn_handle, uint16_t chr_val_handle)
     }
 
     req.baiq_handle = chr_val_handle;
-    rc = ble_att_clt_tx_indicate(conn_handle, &req, &om);
+    rc = ble_att_clt_tx_indicate(conn_handle, &req, om);
+    om = NULL;
     if (rc != 0) {
         goto done;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 3d37c47..aeba768 100644
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@ -343,19 +343,18 @@ ble_hs_start(void)
  * @return                      0 on success; nonzero on failure.
  */
 int
-ble_hs_rx_data(struct os_mbuf **om)
+ble_hs_rx_data(struct os_mbuf *om)
 {
     int rc;
 
-    rc = os_mqueue_put(&ble_hs_rx_q, &ble_hs_evq, *om);
-    if (rc == 0) {
-        *om = NULL;
-    } else {
-        rc = BLE_HS_EOS;
+    rc = os_mqueue_put(&ble_hs_rx_q, &ble_hs_evq, om);
+    if (rc != 0) {
+        os_mbuf_free_chain(om);
+        return BLE_HS_EOS;
     }
+
     os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
 
-    os_mbuf_free_chain(*om);
     return 0;
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 7f284f5..a25c364 100644
--- a/net/nimble/host/src/ble_l2cap.c
+++ b/net/nimble/host/src/ble_l2cap.c
@@ -272,37 +272,27 @@ err:
  * mbuf is consumed, regardless of the outcome of the function call.
  * 
  * @param chan                  The L2CAP channel to transmit over.
- * @param om                    The data to transmit.
+ * @param txom                  The data to transmit.
  *
  * @return                      0 on success; nonzero on error.
  */
 int
 ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-             struct os_mbuf **txom)
+             struct os_mbuf *txom)
 {
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
-    om = ble_l2cap_prepend_hdr(om, chan->blc_cid, OS_MBUF_PKTLEN(om));
-    if (om == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
+    txom = ble_l2cap_prepend_hdr(txom, chan->blc_cid, OS_MBUF_PKTLEN(txom));
+    if (txom == NULL) {
+        return BLE_HS_ENOMEM;
     }
 
-    rc = host_hci_data_tx(conn, &om);
+    rc = host_hci_data_tx(conn, txom);
     if (rc != 0) {
-        goto err;
+        return rc;
     }
 
     return 0;
-
-err:
-    os_mbuf_free_chain(om);
-    return rc;
 }
 
 static void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 3eaf245..ce19218 100644
--- a/net/nimble/host/src/ble_l2cap_priv.h
+++ b/net/nimble/host/src/ble_l2cap_priv.h
@@ -57,8 +57,7 @@ extern struct os_mempool ble_l2cap_chan_pool;
 
 typedef uint8_t ble_l2cap_chan_flags;
 
-typedef int ble_l2cap_rx_fn(uint16_t conn_handle,
-                            struct os_mbuf **om);
+typedef int ble_l2cap_rx_fn(uint16_t conn_handle, struct os_mbuf **rxom);
 
 struct ble_l2cap_chan {
     SLIST_ENTRY(ble_l2cap_chan) blc_next;
@@ -103,7 +102,7 @@ int ble_l2cap_rx(struct ble_hs_conn *conn,
                  ble_l2cap_rx_fn **out_rx_cb,
                  struct os_mbuf **out_rx_buf);
 int ble_l2cap_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
-                 struct os_mbuf **txom);
+                 struct os_mbuf *txom);
 
 int ble_l2cap_init(void);
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 6b08a2b..d822032 100644
--- a/net/nimble/host/src/ble_l2cap_sig_cmd.c
+++ b/net/nimble/host/src/ble_l2cap_sig_cmd.c
@@ -129,7 +129,7 @@ ble_l2cap_sig_reject_tx(struct ble_hs_conn *conn, struct ble_l2cap_chan *chan,
                                data, data_len);
 
     STATS_INC(ble_l2cap_stats, sig_rx);
-    rc = ble_l2cap_tx(conn, chan, &txom);
+    rc = ble_l2cap_tx(conn, chan, txom);
     if (rc != 0) {
         return rc;
     }
@@ -203,7 +203,7 @@ ble_l2cap_sig_update_req_tx(struct ble_hs_conn *conn,
     ble_l2cap_sig_update_req_write(payload_buf, BLE_L2CAP_SIG_UPDATE_REQ_SZ,
                                    req);
 
-    rc = ble_l2cap_tx(conn, chan, &txom);
+    rc = ble_l2cap_tx(conn, chan, txom);
     if (rc != 0) {
         return rc;
     }
@@ -255,7 +255,7 @@ ble_l2cap_sig_update_rsp_tx(struct ble_hs_conn *conn,
     ble_l2cap_sig_update_rsp_write(payload_buf, BLE_L2CAP_SIG_UPDATE_RSP_SZ,
                                    &rsp);
 
-    rc = ble_l2cap_tx(conn, chan, &txom);
+    rc = ble_l2cap_tx(conn, chan, txom);
     if (rc != 0) {
         return rc;
     }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/src/ble_sm_cmd.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_cmd.c b/net/nimble/host/src/ble_sm_cmd.c
index 86b0c7b..9854bde 100644
--- a/net/nimble/host/src/ble_sm_cmd.c
+++ b/net/nimble/host/src/ble_sm_cmd.c
@@ -28,28 +28,29 @@
 #if NIMBLE_OPT(SM)
 
 static int
-ble_sm_tx(uint16_t conn_handle, struct os_mbuf **txom)
+ble_sm_tx(uint16_t conn_handle, struct os_mbuf *txom)
 {
     struct ble_l2cap_chan *chan;
     struct ble_hs_conn *conn;
-    struct os_mbuf *om;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
     BLE_HS_DBG_ASSERT(ble_hs_locked_by_cur_task());
 
     STATS_INC(ble_l2cap_stats, sm_tx);
 
     rc = ble_hs_misc_conn_chan_find_reqd(conn_handle, BLE_L2CAP_CID_SM,
                                          &conn, &chan);
-    if (rc == 0) {
-        rc = ble_l2cap_tx(conn, chan, &om);
+    if (rc != 0) {
+        os_mbuf_free_chain(txom);
+        return rc;
     }
 
-    return rc;
+    rc = ble_l2cap_tx(conn, chan, txom);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
 }
 
 static int
@@ -153,8 +154,7 @@ ble_sm_pair_cmd_tx(uint16_t conn_handle, int is_req,
 
     rc = ble_sm_init_req(BLE_SM_PAIR_CMD_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_pair_cmd_write(txom->om_data, txom->om_len, is_req, cmd);
@@ -162,14 +162,12 @@ ble_sm_pair_cmd_tx(uint16_t conn_handle, int is_req,
                    ble_sm_pair_cmd_log, cmd);
     BLE_HS_DBG_ASSERT(ble_sm_pair_cmd_is_valid(cmd));
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -213,21 +211,18 @@ ble_sm_pair_confirm_tx(uint16_t conn_handle, struct ble_sm_pair_confirm *cmd)
 
     rc = ble_sm_init_req(BLE_SM_PAIR_CONFIRM_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_pair_confirm_write(txom->om_data, txom->om_len, cmd);
     BLE_SM_LOG_CMD(1, "confirm", conn_handle, ble_sm_pair_confirm_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -268,21 +263,18 @@ ble_sm_pair_random_tx(uint16_t conn_handle, struct ble_sm_pair_random *cmd)
 
     rc = ble_sm_init_req(BLE_SM_PAIR_RANDOM_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_pair_random_write(txom->om_data, txom->om_len, cmd);
     BLE_SM_LOG_CMD(1, "random", conn_handle, ble_sm_pair_random_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -328,8 +320,7 @@ ble_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason)
 
     rc = ble_sm_init_req(BLE_SM_PAIR_FAIL_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     cmd.reason = reason;
@@ -337,14 +328,12 @@ ble_sm_pair_fail_tx(uint16_t conn_handle, uint8_t reason)
     ble_sm_pair_fail_write(txom->om_data, txom->om_len, &cmd);
     BLE_SM_LOG_CMD(1, "fail", conn_handle, ble_sm_pair_fail_log, &cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -380,22 +369,19 @@ ble_sm_enc_info_tx(uint16_t conn_handle, struct ble_sm_enc_info *cmd)
 
     rc = ble_sm_init_req(BLE_SM_ENC_INFO_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_enc_info_write(txom->om_data, txom->om_len, cmd);
 
     BLE_SM_LOG_CMD(1, "enc info", conn_handle, ble_sm_enc_info_log, cmd);
     
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -438,8 +424,7 @@ ble_sm_master_id_tx(uint16_t conn_handle, struct ble_sm_master_id *cmd)
 
     rc = ble_sm_init_req(BLE_SM_MASTER_ID_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     txom->om_data[0] = BLE_SM_OP_MASTER_ID;
@@ -448,14 +433,12 @@ ble_sm_master_id_tx(uint16_t conn_handle, struct ble_sm_master_id *cmd)
 
     BLE_SM_LOG_CMD(1, "master id", conn_handle, ble_sm_master_id_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -497,20 +480,17 @@ ble_sm_id_info_tx(uint16_t conn_handle, struct ble_sm_id_info *cmd)
 
     rc = ble_sm_init_req(BLE_SM_ID_INFO_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_id_info_write(txom->om_data, txom->om_len, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -555,20 +535,17 @@ ble_sm_id_addr_info_tx(uint16_t conn_handle, struct ble_sm_id_addr_info *cmd)
 
     rc = ble_sm_init_req(BLE_SM_ID_ADDR_INFO_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_id_addr_info_write(txom->om_data, txom->om_len, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -607,20 +584,17 @@ ble_sm_sign_info_tx(uint16_t conn_handle, struct ble_sm_sign_info *cmd)
 
     rc = ble_sm_init_req(BLE_SM_SIGN_INFO_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_sign_info_write(txom->om_data, txom->om_len, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -662,22 +636,19 @@ ble_sm_sec_req_tx(uint16_t conn_handle, struct ble_sm_sec_req *cmd)
 
     rc = ble_sm_init_req(BLE_SM_SEC_REQ_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     ble_sm_sec_req_write(txom->om_data, txom->om_len, cmd);
 
     BLE_SM_LOG_CMD(1, "sec req", conn_handle, ble_sm_sec_req_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -728,8 +699,7 @@ ble_sm_public_key_tx(uint16_t conn_handle, struct ble_sm_public_key *cmd)
 
     rc = ble_sm_init_req(BLE_SM_PUBLIC_KEY_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     rc = ble_sm_public_key_write(txom->om_data, txom->om_len, cmd);
@@ -737,14 +707,12 @@ ble_sm_public_key_tx(uint16_t conn_handle, struct ble_sm_public_key *cmd)
 
     BLE_SM_LOG_CMD(1, "public key", conn_handle, ble_sm_public_key_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void
@@ -791,8 +759,7 @@ ble_sm_dhkey_check_tx(uint16_t conn_handle, struct ble_sm_dhkey_check *cmd)
 
     rc = ble_sm_init_req(BLE_SM_DHKEY_CHECK_SZ, &txom);
     if (rc != 0) {
-        rc = BLE_HS_ENOMEM;
-        goto done;
+        return BLE_HS_ENOMEM;
     }
 
     rc = ble_sm_dhkey_check_write(txom->om_data, txom->om_len, cmd);
@@ -800,14 +767,12 @@ ble_sm_dhkey_check_tx(uint16_t conn_handle, struct ble_sm_dhkey_check *cmd)
 
     BLE_SM_LOG_CMD(1, "dhkey check", conn_handle, ble_sm_dhkey_check_log, cmd);
 
-    rc = ble_sm_tx(conn_handle, &txom);
+    rc = ble_sm_tx(conn_handle, txom);
     if (rc != 0) {
-        goto done;
+        return rc;
     }
 
-done:
-    os_mbuf_free_chain(txom);
-    return rc;
+    return 0;
 }
 
 void

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/src/ble_sm_priv.h
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/ble_sm_priv.h b/net/nimble/host/src/ble_sm_priv.h
index fbc7139..80798e1 100644
--- a/net/nimble/host/src/ble_sm_priv.h
+++ b/net/nimble/host/src/ble_sm_priv.h
@@ -417,11 +417,12 @@ void ble_sm_sc_public_key_exec(struct ble_sm_proc *proc,
                                struct ble_sm_result *res,
                                void *arg);
 void ble_sm_sc_public_key_rx(uint16_t conn_handle, uint8_t op,
-                             struct os_mbuf **om, struct ble_sm_result *res);
+                             struct os_mbuf **rxom, struct ble_sm_result *res);
 void ble_sm_sc_dhkey_check_exec(struct ble_sm_proc *proc,
                                 struct ble_sm_result *res, void *arg);
 void ble_sm_sc_dhkey_check_rx(uint16_t conn_handle, uint8_t op,
-                              struct os_mbuf **om, struct ble_sm_result *res);
+                              struct os_mbuf **rxom,
+                              struct ble_sm_result *res);
 void ble_sm_sc_init(void);
 #else
 #define ble_sm_sc_io_action(proc) (BLE_SM_IOACT_NONE)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 44d83b3..791aec2 100644
--- a/net/nimble/host/src/host_hci.c
+++ b/net/nimble/host/src/host_hci.c
@@ -801,14 +801,15 @@ host_hci_data_hdr_prepend(struct os_mbuf *om, uint16_t handle, uint8_t pb_flag)
  *                              Other BLE host core return code on error.
  */
 int
-host_hci_split_frag(struct os_mbuf *om, struct os_mbuf **out_frag)
+host_hci_split_frag(struct os_mbuf **om, struct os_mbuf **out_frag)
 {
     struct os_mbuf *frag;
     int rc;
 
-    if (OS_MBUF_PKTLEN(om) <= host_hci_buffer_sz) {
+    if (OS_MBUF_PKTLEN(*om) <= host_hci_buffer_sz) {
         /* Final fragment. */
-        *out_frag = om;
+        *out_frag = *om;
+        *om = NULL;
         return BLE_HS_EDONE;
     }
 
@@ -819,12 +820,12 @@ host_hci_split_frag(struct os_mbuf *om, struct os_mbuf **out_frag)
     }
 
     /* Move data from the front of the packet into the fragment mbuf. */
-    rc = os_mbuf_appendfrom(frag, om, 0, host_hci_buffer_sz);
+    rc = os_mbuf_appendfrom(frag, *om, 0, host_hci_buffer_sz);
     if (rc != 0) {
         rc = BLE_HS_ENOMEM;
         goto err;
     }
-    os_mbuf_adj(om, host_hci_buffer_sz);
+    os_mbuf_adj(*om, host_hci_buffer_sz);
 
     /* More fragments to follow. */
     *out_frag = frag;
@@ -843,18 +844,13 @@ err:
  * fragments.
  */
 int
-host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf **txom)
+host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf *txom)
 {
     struct os_mbuf *frag;
-    struct os_mbuf *om;
     uint8_t pb;
     int done;
     int rc;
 
-    /* Consume mbuf from caller. */
-    om = *txom;
-    *txom = NULL;
-
     /* The first fragment uses the first-non-flush packet boundary value.
      * After sending the first fragment, pb gets set appropriately for all
      * subsequent fragments in this packet.
@@ -864,12 +860,11 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf **txom)
     /* Send fragments until the entire packet has been sent. */
     done = 0;
     while (!done) {
-        rc = host_hci_split_frag(om, &frag);
+        rc = host_hci_split_frag(&txom, &frag);
         switch (rc) {
         case BLE_HS_EDONE:
             /* This is the final fragment. */
             done = 1;
-            om = NULL;
             break;
 
         case BLE_HS_EAGAIN:
@@ -891,12 +886,17 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf **txom)
         ble_hs_log_mbuf(frag);
         BLE_HS_LOG(DEBUG, "\n");
 
-        /* Next fragment */
+        /* XXX: Try to pullup the entire fragment.  The controller currently
+         * requires the entire fragment to fit in a single buffer.  When this
+         * restriction is removed from the controller, this operation can be
+         * removed.
+         */
         frag = os_mbuf_pullup(frag, OS_MBUF_PKTLEN(frag));
         if (frag == NULL) {
             rc = BLE_HS_ENOMEM;
             goto err;
         }
+
         rc = ble_hs_tx_data(frag);
         if (rc != 0) {
             goto err;
@@ -910,6 +910,6 @@ host_hci_data_tx(struct ble_hs_conn *connection, struct os_mbuf **txom)
 err:
     BLE_HS_DBG_ASSERT(rc != 0);
 
-    os_mbuf_free_chain(om);
+    os_mbuf_free_chain(txom);
     return rc;
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/net/nimble/host/src/test/ble_att_clt_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/src/test/ble_att_clt_test.c b/net/nimble/host/src/test/ble_att_clt_test.c
index 869fb19..9461337 100644
--- a/net/nimble/host/src/test/ble_att_clt_test.c
+++ b/net/nimble/host/src/test/ble_att_clt_test.c
@@ -68,12 +68,11 @@ ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle,
 
     om = ble_hs_test_util_om_from_flat(value, value_len);
     if (is_req) {
-        rc = ble_att_clt_tx_write_req(conn_handle, req, &om);
+        rc = ble_att_clt_tx_write_req(conn_handle, req, om);
     } else {
-        rc = ble_att_clt_tx_write_cmd(conn_handle, req, &om);
+        rc = ble_att_clt_tx_write_cmd(conn_handle, req, om);
     }
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(om == NULL);
 }
 
 TEST_CASE(ble_att_clt_test_tx_find_info)
@@ -216,9 +215,8 @@ ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset,
     req.bapc_handle = handle;
     req.bapc_offset = offset;
     om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len);
-    rc = ble_att_clt_tx_prep_write(conn_handle, &req, &om);
+    rc = ble_att_clt_tx_prep_write(conn_handle, &req, om);
     TEST_ASSERT(rc == 0);
-    TEST_ASSERT(om == NULL);
 
     ble_hs_test_util_tx_all();
     om = ble_hs_test_util_prev_tx_dequeue_pullup();
@@ -273,9 +271,8 @@ ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t offset,
 
     req.bapc_handle = handle;
     req.bapc_offset = offset;
-    rc = ble_att_clt_tx_prep_write(conn_handle, &req, &om);
+    rc = ble_att_clt_tx_prep_write(conn_handle, &req, om);
     TEST_ASSERT(rc == status);
-    TEST_ASSERT(om == NULL);
 }
 
 TEST_CASE(ble_att_clt_test_tx_write)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f4796bc3/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 3877174..2fbe0ef 100644
--- a/net/nimble/host/src/test/ble_hs_test_util.c
+++ b/net/nimble/host/src/test/ble_hs_test_util.c
@@ -1064,8 +1064,7 @@ ble_hs_test_util_write_local_flat(uint16_t attr_handle,
     int rc;
 
     om = ble_hs_test_util_om_from_flat(buf, buf_len);
-    rc = ble_att_svr_write_local(attr_handle, &om);
-    TEST_ASSERT(om == NULL);
+    rc = ble_att_svr_write_local(attr_handle, om);
     return rc;
 }
 
@@ -1078,8 +1077,7 @@ ble_hs_test_util_gatt_write_flat(uint16_t conn_handle, uint16_t attr_handle,
     int rc;
 
     om = ble_hs_test_util_om_from_flat(data, data_len);
-    rc = ble_gattc_write(conn_handle, attr_handle, &om, cb, cb_arg);
-    TEST_ASSERT(om == NULL);
+    rc = ble_gattc_write(conn_handle, attr_handle, om, cb, cb_arg);
 
     return rc;
 }
@@ -1093,8 +1091,7 @@ ble_hs_test_util_gatt_write_no_rsp_flat(uint16_t conn_handle,
     int rc;
 
     om = ble_hs_test_util_om_from_flat(data, data_len);
-    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, &om);
-    TEST_ASSERT(om == NULL);
+    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, om);
 
     return rc;
 }
@@ -1109,8 +1106,8 @@ ble_hs_test_util_gatt_write_long_flat(uint16_t conn_handle,
     int rc;
 
     om = ble_hs_test_util_om_from_flat(data, data_len);
-    rc = ble_gattc_write_long(conn_handle, attr_handle, &om, cb, cb_arg);
-    TEST_ASSERT(om == NULL);
+    rc = ble_gattc_write_long(conn_handle, attr_handle, om, cb, cb_arg);
+
     return rc;
 }