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/09/22 02:12:16 UTC

[09/59] [abbrv] incubator-mynewt-core git commit: syscfg / sysinit

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_gatts_reg_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_gatts_reg_test.c b/net/nimble/host/test/src/ble_gatts_reg_test.c
new file mode 100644
index 0000000..ad5f18f
--- /dev/null
+++ b/net/nimble/host/test/src/ble_gatts_reg_test.c
@@ -0,0 +1,718 @@
+/**
+ * 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 <errno.h>
+#include "testutil/testutil.h"
+#include "nimble/ble.h"
+#include "host/ble_uuid.h"
+#include "host/ble_hs_test.h"
+#include "ble_hs_test_util.h"
+
+#define BLE_GATTS_REG_TEST_MAX_ENTRIES  256
+
+struct ble_gatts_reg_test_entry {
+    uint8_t op;
+    uint8_t uuid128[16];
+    uint16_t handle;
+    uint16_t val_handle; /* If a characteristic. */
+
+    const struct ble_gatt_svc_def *svc;
+    const struct ble_gatt_chr_def *chr;
+    const struct ble_gatt_dsc_def *dsc;
+};
+
+static struct ble_gatts_reg_test_entry
+ble_gatts_reg_test_entries[BLE_GATTS_REG_TEST_MAX_ENTRIES];
+
+static int ble_gatts_reg_test_num_entries;
+
+static void
+ble_gatts_reg_test_init(void)
+{
+    ble_hs_test_util_init();
+    ble_gatts_reg_test_num_entries = 0;
+}
+
+static void
+ble_gatts_reg_test_misc_reg_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
+{
+    struct ble_gatts_reg_test_entry *entry;
+
+    TEST_ASSERT_FATAL(ble_gatts_reg_test_num_entries <
+                      BLE_GATTS_REG_TEST_MAX_ENTRIES);
+
+    entry = ble_gatts_reg_test_entries + ble_gatts_reg_test_num_entries++;
+    memset(entry, 0, sizeof *entry);
+
+    entry->op = ctxt->op;
+    switch (ctxt->op) {
+    case BLE_GATT_REGISTER_OP_SVC:
+        memcpy(entry->uuid128, ctxt->svc.svc_def->uuid128, 16);
+        entry->handle = ctxt->svc.handle;
+        entry->svc = ctxt->svc.svc_def;
+        break;
+
+    case BLE_GATT_REGISTER_OP_CHR:
+        memcpy(entry->uuid128, ctxt->chr.chr_def->uuid128, 16);
+        entry->handle = ctxt->chr.def_handle;
+        entry->val_handle = ctxt->chr.val_handle;
+        entry->svc = ctxt->chr.svc_def;
+        entry->chr = ctxt->chr.chr_def;
+        break;
+
+    case BLE_GATT_REGISTER_OP_DSC:
+        memcpy(entry->uuid128, ctxt->dsc.dsc_def->uuid128, 16);
+        entry->handle = ctxt->dsc.handle;
+        entry->svc = ctxt->dsc.svc_def;
+        entry->chr = ctxt->dsc.chr_def;
+        entry->dsc = ctxt->dsc.dsc_def;
+        break;
+
+    default:
+        TEST_ASSERT(0);
+        break;
+    }
+}
+
+static void
+ble_gatts_reg_test_misc_lookup_good(struct ble_gatts_reg_test_entry *entry)
+{
+    uint16_t chr_def_handle;
+    uint16_t chr_val_handle;
+    uint16_t svc_handle;
+    uint16_t dsc_handle;
+    int rc;
+
+    switch (entry->op) {
+    case BLE_GATT_REGISTER_OP_SVC:
+        rc = ble_gatts_find_svc(entry->uuid128, &svc_handle);
+        TEST_ASSERT_FATAL(rc == 0);
+        TEST_ASSERT(svc_handle == entry->handle);
+        break;
+
+    case BLE_GATT_REGISTER_OP_CHR:
+        rc = ble_gatts_find_chr(entry->svc->uuid128, entry->chr->uuid128,
+                                &chr_def_handle, &chr_val_handle);
+        TEST_ASSERT_FATAL(rc == 0);
+        TEST_ASSERT(chr_def_handle == entry->handle);
+        TEST_ASSERT(chr_val_handle == entry->val_handle);
+        break;
+
+    case BLE_GATT_REGISTER_OP_DSC:
+        rc = ble_gatts_find_dsc(entry->svc->uuid128, entry->chr->uuid128,
+                                entry->dsc->uuid128, &dsc_handle);
+        break;
+
+    default:
+        TEST_ASSERT(0);
+        break;
+    }
+}
+
+static void
+ble_gatts_reg_test_misc_lookup_bad(struct ble_gatts_reg_test_entry *entry)
+{
+    struct ble_gatts_reg_test_entry *cur;
+    uint8_t wrong_uuid[16];
+    int rc;
+    int i;
+
+    switch (entry->op) {
+    case BLE_GATT_REGISTER_OP_SVC:
+        /* Wrong service UUID. */
+        memcpy(wrong_uuid, entry->svc->uuid128, 16);
+        wrong_uuid[15]++;
+        rc = ble_gatts_find_svc(wrong_uuid, NULL);
+        TEST_ASSERT(rc == BLE_HS_ENOENT);
+        break;
+
+    case BLE_GATT_REGISTER_OP_CHR:
+        /* Correct service UUID, wrong characteristic UUID. */
+        memcpy(wrong_uuid, entry->chr->uuid128, 16);
+        wrong_uuid[15]++;
+        rc = ble_gatts_find_chr(entry->svc->uuid128, wrong_uuid, NULL, NULL);
+        TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+        /* Incorrect service UUID, correct characteristic UUID. */
+        memcpy(wrong_uuid, entry->svc->uuid128, 16);
+        wrong_uuid[15]++;
+        rc = ble_gatts_find_chr(wrong_uuid, entry->chr->uuid128, NULL, NULL);
+        TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+        /* Existing (but wrong) service, correct characteristic UUID. */
+        for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
+            cur = ble_gatts_reg_test_entries + i;
+            switch (cur->op) {
+            case BLE_GATT_REGISTER_OP_SVC:
+                if (cur->svc != entry->svc) {
+                    rc = ble_gatts_find_chr(cur->svc->uuid128,
+                                            entry->chr->uuid128,
+                                            NULL, NULL);
+                    TEST_ASSERT(rc == BLE_HS_ENOENT);
+                }
+                break;
+
+            case BLE_GATT_REGISTER_OP_CHR:
+                /* Characteristic that isn't in this service. */
+                if (cur->svc != entry->svc) {
+                    rc = ble_gatts_find_chr(entry->svc->uuid128,
+                                            cur->chr->uuid128,
+                                            NULL, NULL);
+                    TEST_ASSERT(rc == BLE_HS_ENOENT);
+                }
+                break;
+
+            case BLE_GATT_REGISTER_OP_DSC:
+                /* Use descriptor UUID instead of characteristic UUID. */
+                rc = ble_gatts_find_chr(entry->svc->uuid128,
+                                        cur->dsc->uuid128,
+                                        NULL, NULL);
+                TEST_ASSERT(rc == BLE_HS_ENOENT);
+                break;
+
+            default:
+                TEST_ASSERT(0);
+                break;
+            }
+        }
+        break;
+
+    case BLE_GATT_REGISTER_OP_DSC:
+        /* Correct svc/chr UUID, wrong dsc UUID. */
+        memcpy(wrong_uuid, entry->dsc->uuid128, 16);
+        wrong_uuid[15]++;
+        rc = ble_gatts_find_dsc(entry->svc->uuid128, entry->chr->uuid128,
+                                wrong_uuid, NULL);
+        TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+        /* Incorrect svc UUID, correct chr/dsc UUID. */
+        memcpy(wrong_uuid, entry->svc->uuid128, 16);
+        wrong_uuid[15]++;
+        rc = ble_gatts_find_dsc(wrong_uuid, entry->chr->uuid128,
+                                entry->dsc->uuid128, NULL);
+        TEST_ASSERT(rc == BLE_HS_ENOENT);
+
+        for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
+            cur = ble_gatts_reg_test_entries + i;
+            switch (cur->op) {
+            case BLE_GATT_REGISTER_OP_SVC:
+                /* Existing (but wrong) svc, correct chr/dsc UUID. */
+                if (cur->svc != entry->svc) {
+                    rc = ble_gatts_find_dsc(cur->svc->uuid128,
+                                            entry->chr->uuid128,
+                                            entry->dsc->uuid128,
+                                            NULL);
+                    TEST_ASSERT(rc == BLE_HS_ENOENT);
+                }
+                break;
+
+            case BLE_GATT_REGISTER_OP_CHR:
+                /* Existing (but wrong) svc/chr, correct dsc UUID. */
+                if (cur->chr != entry->chr) {
+                    rc = ble_gatts_find_dsc(cur->svc->uuid128,
+                                            cur->chr->uuid128,
+                                            entry->dsc->uuid128,
+                                            NULL);
+                    TEST_ASSERT(rc == BLE_HS_ENOENT);
+                }
+                break;
+
+            case BLE_GATT_REGISTER_OP_DSC:
+                /* Descriptor that isn't in this characteristic. */
+                if (cur->chr != entry->chr) {
+                    rc = ble_gatts_find_dsc(cur->svc->uuid128,
+                                            cur->chr->uuid128,
+                                            entry->dsc->uuid128,
+                                            NULL);
+                    TEST_ASSERT(rc == BLE_HS_ENOENT);
+                }
+                break;
+
+            default:
+                TEST_ASSERT(0);
+                break;
+            }
+        }
+        break;
+
+    default:
+        TEST_ASSERT(0);
+        break;
+    }
+}
+
+static void
+ble_gatts_reg_test_misc_verify_entry(uint8_t op, const uint8_t *uuid128)
+{
+    struct ble_gatts_reg_test_entry *entry;
+    int i;
+
+    for (i = 0; i < ble_gatts_reg_test_num_entries; i++) {
+        entry = ble_gatts_reg_test_entries + i;
+        if (entry->op == op && memcmp(entry->uuid128, uuid128, 16) == 0) {
+            break;
+        }
+    }
+    TEST_ASSERT_FATAL(entry != NULL);
+
+    /* Verify that characteristic value handle was properly assigned at
+     * registration.
+     */
+    if (op == BLE_GATT_REGISTER_OP_CHR) {
+        TEST_ASSERT(*entry->chr->val_handle == entry->val_handle);
+    }
+
+    /* Verify that the entry can be looked up. */
+    ble_gatts_reg_test_misc_lookup_good(entry);
+
+    /* Verify that "barely incorrect" UUID information doesn't retrieve any
+     * handles.
+     */
+    ble_gatts_reg_test_misc_lookup_bad(entry);
+}
+
+static int
+ble_gatts_reg_test_misc_dummy_access(uint16_t conn_handle,
+                                     uint16_t attr_handle,
+                                     struct ble_gatt_access_ctxt *ctxt,
+                                     void *arg)
+{
+    return 0;
+}
+
+TEST_CASE(ble_gatts_reg_test_svc_return)
+{
+    int rc;
+
+    /*** Missing UUID. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_no_uuid[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_no_uuid, NULL, NULL);
+    TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+    /*** Circular dependency. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_circ[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .includes = (const struct ble_gatt_svc_def*[]) { svcs_circ + 1, NULL },
+    }, {
+        .type = BLE_GATT_SVC_TYPE_SECONDARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .includes = (const struct ble_gatt_svc_def*[]) { svcs_circ + 0, NULL },
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_circ, NULL, NULL);
+    TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+    /*** Success. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_good[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .includes = (const struct ble_gatt_svc_def*[]) { svcs_good + 1, NULL },
+    }, {
+        .type = BLE_GATT_SVC_TYPE_SECONDARY,
+        .uuid128 = BLE_UUID16(0x1234),
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
+    TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_gatts_reg_test_chr_return)
+{
+    int rc;
+
+    /*** Missing callback. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_no_chr_cb[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            0
+        } },
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_no_chr_cb, NULL, NULL);
+    TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+    /*** Success. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_good[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+        }, {
+            0
+        } },
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
+    TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_gatts_reg_test_dsc_return)
+{
+    int rc;
+
+    /*** Missing callback. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_no_dsc_cb[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x8888),
+                .att_flags = 5,
+            }, {
+                0
+            } },
+        }, {
+            0
+        } },
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_no_dsc_cb, NULL, NULL);
+    TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+    /*** Success. */
+    ble_gatts_reg_test_init();
+    struct ble_gatt_svc_def svcs_good[] = { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x8888),
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+                .att_flags = 5,
+            }, {
+                0
+            } },
+        }, {
+            0
+        } },
+    }, {
+        0
+    } };
+
+    rc = ble_gatts_register_svcs(svcs_good, NULL, NULL);
+    TEST_ASSERT(rc == 0);
+}
+
+static void
+ble_gatts_reg_test_misc_svcs(struct ble_gatt_svc_def *svcs)
+{
+    const struct ble_gatt_svc_def *svc;
+    const struct ble_gatt_chr_def *chr;
+    const struct ble_gatt_dsc_def *dsc;
+    int rc;
+
+    ble_gatts_reg_test_init();
+
+    /* Register all the attributes. */
+    rc = ble_gatts_register_svcs(svcs, ble_gatts_reg_test_misc_reg_cb,
+                                 NULL);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Verify that the appropriate callbacks were executed. */
+    for (svc = svcs; svc->type != BLE_GATT_SVC_TYPE_END; svc++) {
+        ble_gatts_reg_test_misc_verify_entry(BLE_GATT_REGISTER_OP_SVC,
+                                             svc->uuid128);
+
+        if (svc->characteristics != NULL) {
+            for (chr = svc->characteristics; chr->uuid128 != NULL; chr++) {
+                ble_gatts_reg_test_misc_verify_entry(BLE_GATT_REGISTER_OP_CHR,
+                                                     chr->uuid128);
+
+                if (chr->descriptors != NULL) {
+                    for (dsc = chr->descriptors; dsc->uuid128 != NULL; dsc++) {
+                        ble_gatts_reg_test_misc_verify_entry(
+                            BLE_GATT_REGISTER_OP_DSC, dsc->uuid128);
+                    }
+                }
+            }
+        }
+    }
+}
+
+TEST_CASE(ble_gatts_reg_test_svc_cb)
+{
+    /*** 1 primary. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+    }, {
+        0
+    } });
+
+    /*** 3 primary. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+    }, {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x2234),
+    }, {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x3234),
+    }, {
+        0
+    } });
+
+
+    /*** 1 primary, 1 secondary. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+    }, {
+        .type = BLE_GATT_SVC_TYPE_SECONDARY,
+        .uuid128 = BLE_UUID16(0x2222),
+    }, {
+        0
+    } });
+
+    /*** 1 primary, 1 secondary, 1 include. */
+    struct ble_gatt_svc_def svcs[] = {
+        [0] = {
+            .type = BLE_GATT_SVC_TYPE_PRIMARY,
+            .uuid128 = BLE_UUID16(0x1234),
+            .includes = (const struct ble_gatt_svc_def*[]) { svcs + 1, NULL, },
+        },
+        [1] = {
+            .type = BLE_GATT_SVC_TYPE_SECONDARY,
+            .uuid128 = BLE_UUID16(0x2222),
+        }, {
+            0
+        }
+    };
+    ble_gatts_reg_test_misc_svcs(svcs);
+}
+
+TEST_CASE(ble_gatts_reg_test_chr_cb)
+{
+    uint16_t val_handles[16];
+
+    /*** 1 characteristic. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 0,
+        }, {
+            0
+        } },
+    }, {
+        0
+    } });
+
+    /*** 3 characteristics. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 0,
+        }, {
+            .uuid128 = BLE_UUID16(0x2222),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_WRITE,
+            .val_handle = val_handles + 1,
+        }, {
+            0
+        } },
+    }, {
+        .type = BLE_GATT_SVC_TYPE_SECONDARY,
+        .uuid128 = BLE_UUID16(0x5678),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x3333),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 2,
+        }, {
+            0
+        } },
+    }, {
+        0
+    } });
+}
+
+TEST_CASE(ble_gatts_reg_test_dsc_cb)
+{
+    uint16_t val_handles[16];
+
+    /*** 1 descriptor. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 0,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x111a),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                0
+            } },
+        }, {
+            0
+        } },
+    }, {
+        0
+    } });
+
+    /*** 5+ descriptors. */
+    ble_gatts_reg_test_misc_svcs((struct ble_gatt_svc_def[]) { {
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid128 = BLE_UUID16(0x1234),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x1111),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 0,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x111a),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                0
+            } },
+        }, {
+            .uuid128 = BLE_UUID16(0x2222),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_WRITE,
+            .val_handle = val_handles + 1,
+        }, {
+            0
+        } },
+    }, {
+        .type = BLE_GATT_SVC_TYPE_SECONDARY,
+        .uuid128 = BLE_UUID16(0x5678),
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            .uuid128 = BLE_UUID16(0x3333),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 2,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x333a),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x333b),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x333c),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x333e),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                0
+            } },
+        }, {
+            .uuid128 = BLE_UUID16(0x4444),
+            .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            .flags = BLE_GATT_CHR_F_READ,
+            .val_handle = val_handles + 3,
+            .descriptors = (struct ble_gatt_dsc_def[]) { {
+                .uuid128 = BLE_UUID16(0x444a),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x444b),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x444c),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                .uuid128 = BLE_UUID16(0x444e),
+                .att_flags = 5,
+                .access_cb = ble_gatts_reg_test_misc_dummy_access,
+            }, {
+                0
+            } },
+        }, {
+            0
+        } },
+    }, {
+        0
+    } });
+}
+
+TEST_SUITE(ble_gatts_reg_suite)
+{
+    tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+    ble_gatts_reg_test_svc_return();
+    ble_gatts_reg_test_chr_return();
+    ble_gatts_reg_test_dsc_return();
+
+    ble_gatts_reg_test_svc_cb();
+    ble_gatts_reg_test_chr_cb();
+    ble_gatts_reg_test_dsc_cb();
+}
+
+int
+ble_gatts_reg_test_all(void)
+{
+    ble_gatts_reg_suite();
+
+    return tu_any_failed;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_hs_adv_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_adv_test.c b/net/nimble/host/test/src/ble_hs_adv_test.c
new file mode 100644
index 0000000..e99fd5b
--- /dev/null
+++ b/net/nimble/host/test/src/ble_hs_adv_test.c
@@ -0,0 +1,1486 @@
+/**
+ * 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 <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include "testutil/testutil.h"
+#include "nimble/hci_common.h"
+#include "host/ble_hs_adv.h"
+#include "host/ble_hs_test.h"
+#include "ble_hs_test_util.h"
+
+#define BLE_ADV_TEST_DATA_OFF   4
+
+static void
+ble_hs_adv_test_misc_verify_tx_adv_data_hdr(uint8_t *cmd, int data_len)
+{
+    uint16_t opcode;
+
+    opcode = le16toh(cmd + 0);
+    TEST_ASSERT(BLE_HCI_OGF(opcode) == BLE_HCI_OGF_LE);
+    TEST_ASSERT(BLE_HCI_OCF(opcode) == BLE_HCI_OCF_LE_SET_ADV_DATA);
+
+    TEST_ASSERT(cmd[2] == BLE_HCI_SET_ADV_DATA_LEN);
+    TEST_ASSERT(cmd[3] == data_len);
+}
+
+static void
+ble_hs_adv_test_misc_verify_tx_rsp_data_hdr(uint8_t *cmd, int data_len)
+{
+    uint16_t opcode;
+
+    opcode = le16toh(cmd + 0);
+    TEST_ASSERT(BLE_HCI_OGF(opcode) == BLE_HCI_OGF_LE);
+    TEST_ASSERT(BLE_HCI_OCF(opcode) == BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA);
+
+    TEST_ASSERT(cmd[2] == BLE_HCI_SET_SCAN_RSP_DATA_LEN);
+    TEST_ASSERT(cmd[3] == data_len);
+}
+
+static void
+ble_hs_adv_test_misc_verify_tx_field(uint8_t *cmd, uint8_t type,
+                                     uint8_t val_len, void *val)
+{
+    TEST_ASSERT(cmd[0] == val_len + 1);
+    TEST_ASSERT(cmd[1] == type);
+    TEST_ASSERT(memcmp(cmd + 2, val, val_len) == 0);
+}
+
+struct ble_hs_adv_test_field {
+    uint8_t type;       /* 0 indicates end of array. */
+    uint8_t *val;
+    uint8_t val_len;
+};
+
+static int
+ble_hs_adv_test_misc_calc_data_len(struct ble_hs_adv_test_field *fields)
+{
+    struct ble_hs_adv_test_field *field;
+    int len;
+
+    len = 0;
+    if (fields != NULL) {
+        for (field = fields; field->type != 0; field++) {
+            len += 2 + field->val_len;
+        }
+    }
+
+    return len;
+}
+
+static void
+ble_hs_adv_test_misc_verify_tx_fields(uint8_t *cmd,
+                                      struct ble_hs_adv_test_field *fields)
+{
+    struct ble_hs_adv_test_field *field;
+
+    for (field = fields; field->type != 0; field++) {
+        ble_hs_adv_test_misc_verify_tx_field(cmd, field->type, field->val_len,
+                                             field->val);
+        cmd += 2 + field->val_len;
+    }
+}
+
+static void
+ble_hs_adv_test_misc_verify_tx_adv_data(struct ble_hs_adv_test_field *fields)
+{
+    int data_len;
+    uint8_t *cmd;
+
+    cmd = ble_hs_test_util_get_last_hci_tx();
+    TEST_ASSERT_FATAL(cmd != NULL);
+
+    data_len = ble_hs_adv_test_misc_calc_data_len(fields);
+    ble_hs_adv_test_misc_verify_tx_adv_data_hdr(cmd, data_len);
+    if (fields != NULL) {
+        ble_hs_adv_test_misc_verify_tx_fields(cmd + BLE_ADV_TEST_DATA_OFF,
+                                              fields);
+    }
+}
+
+static void
+ble_hs_adv_test_misc_verify_tx_rsp_data(struct ble_hs_adv_test_field *fields)
+{
+    int data_len;
+    uint8_t *cmd;
+
+    cmd = ble_hs_test_util_get_last_hci_tx();
+    TEST_ASSERT_FATAL(cmd != NULL);
+
+    data_len = ble_hs_adv_test_misc_calc_data_len(fields);
+    ble_hs_adv_test_misc_verify_tx_rsp_data_hdr(cmd, data_len);
+    if (fields != NULL) {
+        ble_hs_adv_test_misc_verify_tx_fields(cmd + BLE_ADV_TEST_DATA_OFF,
+                                              fields);
+    }
+}
+
+static void
+ble_hs_adv_test_misc_tx_and_verify_data(
+    uint8_t disc_mode,
+    struct ble_hs_adv_fields *adv_fields,
+    struct ble_hs_adv_test_field *test_adv_fields,
+    struct ble_hs_adv_fields *rsp_fields,
+    struct ble_hs_adv_test_field *test_rsp_fields)
+{
+    struct ble_gap_adv_params adv_params;
+    int rc;
+
+    ble_hs_test_util_init();
+
+    adv_params = ble_hs_test_util_adv_params;
+    adv_params.disc_mode = disc_mode;
+
+    rc = ble_hs_test_util_adv_set_fields(adv_fields, 0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    rc = ble_gap_adv_rsp_set_fields(rsp_fields);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    rc = ble_hs_test_util_adv_start(BLE_ADDR_TYPE_PUBLIC, 0, NULL, &adv_params,
+                                    NULL, NULL, 0, 0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Discard the adv-enable command. */
+    ble_hs_test_util_get_last_hci_tx();
+
+    ble_hs_adv_test_misc_verify_tx_rsp_data(test_rsp_fields);
+    ble_hs_adv_test_misc_verify_tx_adv_data(test_adv_fields);
+
+    /* Ensure the same data gets sent on repeated advertise procedures. */
+    rc = ble_hs_test_util_adv_stop(0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    rc = ble_hs_test_util_adv_start(BLE_ADDR_TYPE_PUBLIC, 0, NULL, &adv_params,
+                                    NULL, NULL, 0, 0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    /* Discard the adv-enable command. */
+    ble_hs_test_util_get_last_hci_tx();
+
+    ble_hs_adv_test_misc_verify_tx_rsp_data(test_rsp_fields);
+    ble_hs_adv_test_misc_verify_tx_adv_data(test_adv_fields);
+}
+
+TEST_CASE(ble_hs_adv_test_case_flags)
+{
+    struct ble_hs_adv_fields adv_fields;
+    struct ble_hs_adv_fields rsp_fields;
+
+    memset(&adv_fields, 0, sizeof adv_fields);
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+
+    /* Default flags. */
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON,
+        &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /* Flags |= limited discoverable. */
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_LTD, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]) {
+                    BLE_HS_ADV_F_DISC_LTD | BLE_HS_ADV_F_BREDR_UNSUP
+                 },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /* Flags = general discoverable. */
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_GEN, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]) {
+                    BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP
+                 },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+}
+
+TEST_CASE(ble_hs_adv_test_case_user)
+{
+    struct ble_hs_adv_fields adv_fields;
+    struct ble_hs_adv_fields rsp_fields;
+
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+
+    /*** Complete 16-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+    adv_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
+    adv_fields.num_uuids16 = 3;
+    adv_fields.uuids16_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS16,
+                .val = (uint8_t[]) { 0x01, 0x00, 0x34, 0x12, 0xab, 0x54 },
+                .val_len = 6,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Incomplete 16-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
+    adv_fields.num_uuids16 = 3;
+    adv_fields.uuids16_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS16,
+                .val = (uint8_t[]) { 0x01, 0x00, 0x34, 0x12, 0xab, 0x54 },
+                .val_len = 6,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Complete 32-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
+    adv_fields.num_uuids32 = 2;
+    adv_fields.uuids32_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS32,
+                .val = (uint8_t[]) { 0x78,0x56,0x34,0x12,0xae,0xad,0xac,0xab },
+                .val_len = 8,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Incomplete 32-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
+    adv_fields.num_uuids32 = 2;
+    adv_fields.uuids32_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS32,
+                .val = (uint8_t[]) { 0x78,0x56,0x34,0x12,0xae,0xad,0xac,0xab },
+                .val_len = 8,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Complete 128-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uuids128 = (uint8_t[]) {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    };
+    adv_fields.num_uuids128 = 1;
+    adv_fields.uuids128_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS128,
+                .val = (uint8_t[]) {
+                    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                },
+                .val_len = 16,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Incomplete 128-bit service class UUIDs. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uuids128 = (uint8_t[]) {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    };
+    adv_fields.num_uuids128 = 1;
+    adv_fields.uuids128_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS128,
+                .val = (uint8_t[]) {
+                    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                },
+                .val_len = 16,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Complete name. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.name = (uint8_t *)"myname";
+    adv_fields.name_len = 6;
+    adv_fields.name_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_NAME,
+                .val = (uint8_t*)"myname",
+                .val_len = 6,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Incomplete name. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.name = (uint8_t *)"myname";
+    adv_fields.name_len = 6;
+    adv_fields.name_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_NAME,
+                .val = (uint8_t*)"myname",
+                .val_len = 6,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Class of device. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.device_class = (uint8_t[]){ 1,2,3 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_DEVICE_CLASS,
+                .val = (uint8_t[]) { 1,2,3 },
+                .val_len = BLE_HS_ADV_DEVICE_CLASS_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Slave interval range. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.slave_itvl_range = (uint8_t[]){ 1,2,3,4 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x16 - Service data - 16-bit UUID. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.svc_data_uuid16 = (uint8_t[]){ 1,2,3,4 };
+    adv_fields.svc_data_uuid16_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x17 - Public target address. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.public_tgt_addr = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 };
+    adv_fields.num_public_tgt_addrs = 2;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
+                .val = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 },
+                .val_len = 2 * BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x19 - Appearance. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.appearance = 0x1234;
+    adv_fields.appearance_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_APPEARANCE,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_APPEARANCE_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x1a - Advertising interval. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.adv_itvl = 0x1234;
+    adv_fields.adv_itvl_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_ADV_ITVL,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_ADV_ITVL_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x1b - LE bluetooth device address. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.le_addr = (uint8_t[]){ 1,2,3,4,5,6,7 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_LE_ADDR,
+                .val = (uint8_t[]) { 1,2,3,4,5,6,7 },
+                .val_len = BLE_HS_ADV_LE_ADDR_LEN,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x1c - LE role. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.le_role = BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF;
+    adv_fields.le_role_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_LE_ROLE,
+                .val = (uint8_t[]) { BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x20 - Service data - 32-bit UUID. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.svc_data_uuid32 = (uint8_t[]){ 1,2,3,4,5 };
+    adv_fields.svc_data_uuid32_len = 5;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
+                .val = (uint8_t[]) { 1,2,3,4,5 },
+                .val_len = 5,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x21 - Service data - 128-bit UUID. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.svc_data_uuid128 =
+        (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
+    adv_fields.svc_data_uuid128_len = 18;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
+                .val = (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,
+                                    11,12,13,14,15,16,17,18 },
+                .val_len = 18,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0x24 - URI. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.uri = (uint8_t[]){ 1,2,3,4 };
+    adv_fields.uri_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_URI,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** 0xff - Manufacturer specific data. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    adv_fields.mfg_data = (uint8_t[]){ 1,2,3,4 };
+    adv_fields.mfg_data_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_MFG_DATA,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+}
+
+TEST_CASE(ble_hs_adv_test_case_user_rsp)
+{
+    struct ble_hs_adv_fields rsp_fields;
+    struct ble_hs_adv_fields adv_fields;
+
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.flags_is_present = 1;
+    adv_fields.tx_pwr_lvl_is_present = 1;
+
+    /*** Complete 16-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
+    rsp_fields.num_uuids16 = 3;
+    rsp_fields.uuids16_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS16,
+                .val = (uint8_t[]) { 0x01, 0x00, 0x34, 0x12, 0xab, 0x54 },
+                .val_len = 6,
+            },
+            { 0 },
+        });
+
+    /*** Incomplete 16-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids16 = (uint16_t[]) { 0x0001, 0x1234, 0x54ab };
+    rsp_fields.num_uuids16 = 3;
+    rsp_fields.uuids16_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS16,
+                .val = (uint8_t[]) { 0x01, 0x00, 0x34, 0x12, 0xab, 0x54 },
+                .val_len = 6,
+            },
+            { 0 },
+        });
+
+    /*** Complete 32-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
+    rsp_fields.num_uuids32 = 2;
+    rsp_fields.uuids32_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS32,
+                .val = (uint8_t[]) { 0x78,0x56,0x34,0x12,0xae,0xad,0xac,0xab },
+                .val_len = 8,
+            },
+            { 0 },
+        });
+
+    /*** Incomplete 32-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids32 = (uint32_t[]) { 0x12345678, 0xabacadae };
+    rsp_fields.num_uuids32 = 2;
+    rsp_fields.uuids32_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS32,
+                .val = (uint8_t[]) { 0x78,0x56,0x34,0x12,0xae,0xad,0xac,0xab },
+                .val_len = 8,
+            },
+            { 0 },
+        });
+
+    /*** Complete 128-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids128 = (uint8_t[]) {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    };
+    rsp_fields.num_uuids128 = 1;
+    rsp_fields.uuids128_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_UUIDS128,
+                .val = (uint8_t[]) {
+                    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                },
+                .val_len = 16,
+            },
+            { 0 },
+        });
+
+    /*** Incomplete 128-bit service class UUIDs. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uuids128 = (uint8_t[]) {
+        0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+        0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+    };
+    rsp_fields.num_uuids128 = 1;
+    rsp_fields.uuids128_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_UUIDS128,
+                .val = (uint8_t[]) {
+                    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                    0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
+                },
+                .val_len = 16,
+            },
+            { 0 },
+        });
+
+    /*** Complete name. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.name = (uint8_t *)"myname";
+    rsp_fields.name_len = 6;
+    rsp_fields.name_is_complete = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_COMP_NAME,
+                .val = (uint8_t*)"myname",
+                .val_len = 6,
+            },
+            { 0 },
+        });
+
+    /*** Incomplete name. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.name = (uint8_t *)"myname";
+    rsp_fields.name_len = 6;
+    rsp_fields.name_is_complete = 0;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_INCOMP_NAME,
+                .val = (uint8_t*)"myname",
+                .val_len = 6,
+            },
+            { 0 },
+        });
+
+    /*** Class of device. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.device_class = (uint8_t[]){ 1,2,3 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_DEVICE_CLASS,
+                .val = (uint8_t[]) { 1,2,3 },
+                .val_len = BLE_HS_ADV_DEVICE_CLASS_LEN,
+            },
+            { 0 },
+        });
+
+    /*** Slave interval range. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.slave_itvl_range = (uint8_t[]){ 1,2,3,4 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SLAVE_ITVL_RANGE,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN,
+            },
+            { 0 },
+        });
+
+    /*** 0x16 - Service data - 16-bit UUID. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.svc_data_uuid16 = (uint8_t[]){ 1,2,3,4 };
+    rsp_fields.svc_data_uuid16_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID16,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            { 0 },
+        });
+
+    /*** 0x17 - Public target address. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.public_tgt_addr = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 };
+    rsp_fields.num_public_tgt_addrs = 2;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_PUBLIC_TGT_ADDR,
+                .val = (uint8_t[]){ 1,2,3,4,5,6, 6,5,4,3,2,1 },
+                .val_len = 2 * BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN,
+            },
+            { 0 },
+        });
+
+    /*** 0x19 - Appearance. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.appearance = 0x1234;
+    rsp_fields.appearance_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_APPEARANCE,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_APPEARANCE_LEN,
+            },
+            { 0 },
+        });
+
+    /*** 0x1a - Advertising interval. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.adv_itvl = 0x1234;
+    rsp_fields.adv_itvl_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_ADV_ITVL,
+                .val = (uint8_t[]){ 0x34, 0x12 },
+                .val_len = BLE_HS_ADV_ADV_ITVL_LEN,
+            },
+            { 0 },
+        });
+
+    /*** 0x1b - LE bluetooth device address. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.le_addr = (uint8_t[]){ 1,2,3,4,5,6,7 };
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_LE_ADDR,
+                .val = (uint8_t[]) { 1,2,3,4,5,6,7 },
+                .val_len = BLE_HS_ADV_LE_ADDR_LEN,
+            },
+            { 0 },
+        });
+
+    /*** 0x1c - LE role. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.le_role = BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF;
+    rsp_fields.le_role_is_present = 1;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_LE_ROLE,
+                .val = (uint8_t[]) { BLE_HS_ADV_LE_ROLE_BOTH_PERIPH_PREF },
+                .val_len = 1,
+            },
+            { 0 },
+        });
+
+    /*** 0x20 - Service data - 32-bit UUID. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.svc_data_uuid32 = (uint8_t[]){ 1,2,3,4,5 };
+    rsp_fields.svc_data_uuid32_len = 5;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID32,
+                .val = (uint8_t[]) { 1,2,3,4,5 },
+                .val_len = 5,
+            },
+            { 0 },
+        });
+
+    /*** 0x21 - Service data - 128-bit UUID. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.svc_data_uuid128 =
+        (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18 };
+    rsp_fields.svc_data_uuid128_len = 18;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_SVC_DATA_UUID128,
+                .val = (uint8_t[]){ 1,2,3,4,5,6,7,8,9,10,
+                                    11,12,13,14,15,16,17,18 },
+                .val_len = 18,
+            },
+            { 0 },
+        });
+
+    /*** 0x24 - URI. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.uri = (uint8_t[]){ 1,2,3,4 };
+    rsp_fields.uri_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_URI,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            { 0 },
+        });
+
+    /*** 0xff - Manufacturer specific data. */
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+    rsp_fields.mfg_data = (uint8_t[]){ 1,2,3,4 };
+    rsp_fields.mfg_data_len = 4;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_TX_PWR_LVL,
+                .val = (uint8_t[]){ 0 },
+                .val_len = 1,
+            },
+            {
+                .type = BLE_HS_ADV_TYPE_FLAGS,
+                .val = (uint8_t[]){ BLE_HS_ADV_F_BREDR_UNSUP },
+                .val_len = 1,
+            },
+            { 0 },
+        },
+        &rsp_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_MFG_DATA,
+                .val = (uint8_t[]) { 1,2,3,4 },
+                .val_len = 4,
+            },
+            { 0 },
+        });
+}
+
+TEST_CASE(ble_hs_adv_test_case_user_full_payload)
+{
+    /* Intentionally allocate an extra byte. */
+    static const uint8_t mfg_data[30] = {
+        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+        0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+        0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+        0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e,
+    };
+
+    struct ble_hs_adv_fields adv_fields;
+    struct ble_hs_adv_fields rsp_fields;
+    int rc;
+
+    ble_hs_test_util_init();
+
+    memset(&rsp_fields, 0, sizeof rsp_fields);
+
+    /***
+     * An advertisement should allow 31 bytes of user data.  Each field has a
+     * two-byte header, leaving 29 bytes of payload.
+     */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.mfg_data = (void *)mfg_data;
+    adv_fields.mfg_data_len = 29;
+
+    ble_hs_adv_test_misc_tx_and_verify_data(BLE_GAP_DISC_MODE_NON, &adv_fields,
+        (struct ble_hs_adv_test_field[]) {
+            {
+                .type = BLE_HS_ADV_TYPE_MFG_DATA,
+                .val = (void *)mfg_data,
+                .val_len = 29,
+            },
+            { 0 },
+        }, &rsp_fields, NULL);
+
+    /*** Fail with 30 bytes. */
+    rc = ble_hs_test_util_adv_stop(0);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    adv_fields.mfg_data_len = 30;
+    rc = ble_gap_adv_set_fields(&adv_fields);
+    TEST_ASSERT(rc == BLE_HS_EMSGSIZE);
+}
+
+TEST_SUITE(ble_hs_adv_test_suite)
+{
+    tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+    ble_hs_adv_test_case_flags();
+    ble_hs_adv_test_case_user();
+    ble_hs_adv_test_case_user_rsp();
+    ble_hs_adv_test_case_user_full_payload();
+}
+
+int
+ble_hs_adv_test_all(void)
+{
+    ble_hs_adv_test_suite();
+
+    return tu_any_failed;
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_hs_conn_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_conn_test.c b/net/nimble/host/test/src/ble_hs_conn_test.c
new file mode 100644
index 0000000..c957446
--- /dev/null
+++ b/net/nimble/host/test/src/ble_hs_conn_test.c
@@ -0,0 +1,219 @@
+/**
+ * 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 <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include "testutil/testutil.h"
+#include "nimble/hci_common.h"
+#include "host/ble_hs_adv.h"
+#include "host/ble_hs_test.h"
+#include "ble_hs_test_util.h"
+
+static int
+ble_hs_conn_test_util_any()
+{
+    struct ble_hs_conn *conn;
+
+    ble_hs_lock();
+    conn = ble_hs_conn_first();
+    ble_hs_unlock();
+
+    return conn != NULL;
+}
+
+TEST_CASE(ble_hs_conn_test_direct_connect_success)
+{
+    struct hci_le_conn_complete evt;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
+    int rc;
+
+    ble_hs_test_util_init();
+
+    /* Ensure no current or pending connections. */
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
+
+    /* Initiate connection. */
+    rc = ble_hs_test_util_connect(BLE_ADDR_TYPE_PUBLIC,
+                                        BLE_ADDR_TYPE_PUBLIC,
+                                        addr, 0, NULL, NULL, NULL, 0);
+    TEST_ASSERT(rc == 0);
+
+    TEST_ASSERT(ble_gap_master_in_progress());
+
+    /* Receive successful connection complete event. */
+    memset(&evt, 0, sizeof evt);
+    evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
+    evt.status = BLE_ERR_SUCCESS;
+    evt.connection_handle = 2;
+    evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_MASTER;
+    memcpy(evt.peer_addr, addr, 6);
+    rc = ble_gap_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(!ble_gap_master_in_progress());
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_first();
+    TEST_ASSERT_FATAL(conn != NULL);
+    TEST_ASSERT(conn->bhc_handle == 2);
+    TEST_ASSERT(memcmp(conn->bhc_peer_addr, addr, 6) == 0);
+
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    TEST_ASSERT_FATAL(chan != NULL);
+    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->blc_peer_mtu == 0);
+    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
+}
+
+TEST_CASE(ble_hs_conn_test_direct_connectable_success)
+{
+    struct hci_le_conn_complete evt;
+    struct ble_gap_adv_params adv_params;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
+    int rc;
+
+    ble_hs_test_util_init();
+
+    /* Ensure no current or pending connections. */
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(!ble_gap_adv_active());
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
+
+    /* Initiate advertising. */
+    adv_params = ble_hs_test_util_adv_params;
+    adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
+    rc = ble_hs_test_util_adv_start(BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_PUBLIC,
+                                    addr, &adv_params, NULL, NULL, 0, 0);
+    TEST_ASSERT(rc == 0);
+
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(ble_gap_adv_active());
+
+    /* Receive successful connection complete event. */
+    memset(&evt, 0, sizeof evt);
+    evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
+    evt.status = BLE_ERR_SUCCESS;
+    evt.connection_handle = 2;
+    evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
+    memcpy(evt.peer_addr, addr, 6);
+    rc = ble_gap_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(!ble_gap_adv_active());
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_first();
+    TEST_ASSERT_FATAL(conn != NULL);
+    TEST_ASSERT(conn->bhc_handle == 2);
+    TEST_ASSERT(memcmp(conn->bhc_peer_addr, addr, 6) == 0);
+
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    TEST_ASSERT_FATAL(chan != NULL);
+    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->blc_peer_mtu == 0);
+    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
+}
+
+TEST_CASE(ble_hs_conn_test_undirect_connectable_success)
+{
+    struct ble_hs_adv_fields adv_fields;
+    struct hci_le_conn_complete evt;
+    struct ble_gap_adv_params adv_params;
+    struct ble_l2cap_chan *chan;
+    struct ble_hs_conn *conn;
+    uint8_t addr[6] = { 1, 2, 3, 4, 5, 6 };
+    int rc;
+
+    ble_hs_test_util_init();
+
+    /* Ensure no current or pending connections. */
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(!ble_gap_adv_active());
+    TEST_ASSERT(!ble_hs_conn_test_util_any());
+
+    /* Initiate advertising. */
+    memset(&adv_fields, 0, sizeof adv_fields);
+    adv_fields.tx_pwr_lvl_is_present = 1;
+    rc = ble_gap_adv_set_fields(&adv_fields);
+    TEST_ASSERT_FATAL(rc == 0);
+
+    adv_params = ble_hs_test_util_adv_params;
+    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
+    rc = ble_hs_test_util_adv_start(BLE_ADDR_TYPE_PUBLIC, BLE_ADDR_TYPE_PUBLIC,
+                                    addr, &adv_params, NULL, NULL, 0, 0);
+    TEST_ASSERT(rc == 0);
+
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(ble_gap_adv_active());
+
+    /* Receive successful connection complete event. */
+    memset(&evt, 0, sizeof evt);
+    evt.subevent_code = BLE_HCI_LE_SUBEV_CONN_COMPLETE;
+    evt.status = BLE_ERR_SUCCESS;
+    evt.connection_handle = 2;
+    evt.role = BLE_HCI_LE_CONN_COMPLETE_ROLE_SLAVE;
+    memcpy(evt.peer_addr, addr, 6);
+    rc = ble_gap_rx_conn_complete(&evt);
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(!ble_gap_master_in_progress());
+    TEST_ASSERT(!ble_gap_adv_active());
+
+    ble_hs_lock();
+
+    conn = ble_hs_conn_first();
+    TEST_ASSERT_FATAL(conn != NULL);
+    TEST_ASSERT(conn->bhc_handle == 2);
+    TEST_ASSERT(memcmp(conn->bhc_peer_addr, addr, 6) == 0);
+
+    chan = ble_hs_conn_chan_find(conn, BLE_L2CAP_CID_ATT);
+    TEST_ASSERT_FATAL(chan != NULL);
+    TEST_ASSERT(chan->blc_my_mtu == BLE_ATT_MTU_PREFERRED_DFLT);
+    TEST_ASSERT(chan->blc_peer_mtu == 0);
+    TEST_ASSERT(chan->blc_default_mtu == BLE_ATT_MTU_DFLT);
+
+    ble_hs_unlock();
+}
+
+TEST_SUITE(conn_suite)
+{
+    tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+    ble_hs_conn_test_direct_connect_success();
+    ble_hs_conn_test_direct_connectable_success();
+    ble_hs_conn_test_undirect_connectable_success();
+}
+
+int
+ble_hs_conn_test_all(void)
+{
+    conn_suite();
+
+    return tu_any_failed;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_hs_hci_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_hci_test.c b/net/nimble/host/test/src/ble_hs_hci_test.c
new file mode 100644
index 0000000..21184b8
--- /dev/null
+++ b/net/nimble/host/test/src/ble_hs_hci_test.c
@@ -0,0 +1,99 @@
+/**
+ * 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 <stddef.h>
+#include <errno.h>
+#include <string.h>
+#include "nimble/hci_common.h"
+#include "nimble/ble_hci_trans.h"
+#include "host/ble_hs_test.h"
+#include "testutil/testutil.h"
+#include "ble_hs_test_util.h"
+
+TEST_CASE(ble_hs_hci_test_event_bad)
+{
+    uint8_t *buf;
+    int rc;
+
+    /*** Invalid event code. */
+    buf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
+    TEST_ASSERT_FATAL(buf != NULL);
+
+    buf[0] = 0xff;
+    buf[1] = 0;
+    rc = ble_hs_hci_evt_process(buf);
+    TEST_ASSERT(rc == BLE_HS_ENOTSUP);
+}
+
+TEST_CASE(ble_hs_hci_test_rssi)
+{
+    uint8_t params[BLE_HCI_READ_RSSI_ACK_PARAM_LEN];
+    uint16_t opcode;
+    int8_t rssi;
+    int rc;
+
+    opcode = ble_hs_hci_util_opcode_join(BLE_HCI_OGF_STATUS_PARAMS,
+                                  BLE_HCI_OCF_RD_RSSI);
+
+    /*** Success. */
+    /* Connection handle. */
+    htole16(params + 0, 1);
+
+    /* RSSI. */
+    params[2] = -8;
+
+    ble_hs_test_util_set_ack_params(opcode, 0, params, sizeof params);
+
+    rc = ble_hs_hci_util_read_rssi(1, &rssi);
+    TEST_ASSERT_FATAL(rc == 0);
+    TEST_ASSERT(rssi == -8);
+
+    /*** Failure: incorrect connection handle. */
+    htole16(params + 0, 99);
+
+    ble_hs_test_util_set_ack_params(opcode, 0, params, sizeof params);
+
+    rc = ble_hs_hci_util_read_rssi(1, &rssi);
+    TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
+
+    /*** Failure: params too short. */
+    ble_hs_test_util_set_ack_params(opcode, 0, params, sizeof params - 1);
+    rc = ble_hs_hci_util_read_rssi(1, &rssi);
+    TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
+
+    /*** Failure: params too long. */
+    ble_hs_test_util_set_ack_params(opcode, 0, params, sizeof params + 1);
+    rc = ble_hs_hci_util_read_rssi(1, &rssi);
+    TEST_ASSERT(rc == BLE_HS_ECONTROLLER);
+}
+
+TEST_SUITE(ble_hs_hci_suite)
+{
+    tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+    ble_hs_hci_test_event_bad();
+    ble_hs_hci_test_rssi();
+}
+
+int
+ble_hs_hci_test_all(void)
+{
+    ble_hs_hci_suite();
+    return tu_any_failed;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/net/nimble/host/test/src/ble_hs_test.c
----------------------------------------------------------------------
diff --git a/net/nimble/host/test/src/ble_hs_test.c b/net/nimble/host/test/src/ble_hs_test.c
new file mode 100644
index 0000000..e1f4dad
--- /dev/null
+++ b/net/nimble/host/test/src/ble_hs_test.c
@@ -0,0 +1,61 @@
+/**
+ * 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 "syscfg/syscfg.h"
+#include "os/os.h"
+#include "nimble/hci_common.h"
+#include "host/ble_hs_test.h"
+#include "testutil/testutil.h"
+#include "ble_hs_test_util.h"
+
+#if MYNEWT_VAL(SELFTEST)
+
+int
+main(int argc, char **argv)
+{
+    tu_config.tc_print_results = 1;
+    tu_parse_args(argc, argv);
+
+    tu_init();
+
+    ble_att_clt_test_all();
+    ble_att_svr_test_all();
+    ble_gap_test_all();
+    ble_gatt_conn_test_all();
+    ble_gatt_disc_c_test_all();
+    ble_gatt_disc_d_test_all();
+    ble_gatt_disc_s_test_all();
+    ble_gatt_find_s_test_all();
+    ble_gatt_read_test_all();
+    ble_gatt_write_test_all();
+    ble_gatts_notify_test_all();
+    ble_gatts_read_test_suite();
+    ble_gatts_reg_test_all();
+    ble_hs_hci_test_all();
+    ble_hs_adv_test_all();
+    ble_hs_conn_test_all();
+    ble_l2cap_test_all();
+    ble_os_test_all();
+    ble_sm_test_all();
+    ble_uuid_test_all();
+
+    return tu_any_failed;
+}
+
+#endif