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:13:02 UTC
[55/59] [abbrv] incubator-mynewt-core git commit: Merge branch
'develop' into sterly_refactor
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/os/test/src/sem_test.c
----------------------------------------------------------------------
diff --cc libs/os/test/src/sem_test.c
index ec79185,0000000..6b40069
mode 100644,000000..100644
--- a/libs/os/test/src/sem_test.c
+++ b/libs/os/test/src/sem_test.c
@@@ -1,401 -1,0 +1,401 @@@
+/**
+ * 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 <stdio.h>
+#include <string.h>
+#include "testutil/testutil.h"
+#include "os/os.h"
+#include "os/os_cfg.h"
+#include "os/os_sem.h"
+#include "os_test_priv.h"
+
+#ifdef ARCH_sim
+#define SEM_TEST_STACK_SIZE 1024
+#else
+#define SEM_TEST_STACK_SIZE 512
+#endif
+
+struct os_task task1;
+os_stack_t stack1[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)];
+
+struct os_task task2;
+os_stack_t stack2[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)];
+
+struct os_task task3;
+os_stack_t stack3[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)];
+
+struct os_task task4;
+os_stack_t stack4[OS_STACK_ALIGN(SEM_TEST_STACK_SIZE)];
+
+#define TASK1_PRIO (1)
+#define TASK2_PRIO (2)
+#define TASK3_PRIO (3)
+#define TASK4_PRIO (4)
+
+struct os_sem g_sem1;
+
+/*
+ * TEST NUMBERS:
+ * 10: In this test we have the highest priority task getting the semaphore
+ * then sleeping. Two lower priority tasks then wake up and attempt to get
+ * the semaphore. They are blocked until the higher priority task releases
+ * the semaphore, at which point the lower priority tasks should wake up in
+ * order, get the semaphore, then release it and go back to sleep.
+ *
+ */
+
+/**
+ * sem test disp sem
+ *
+ * Display semaphore contents
+ *
+ * @param sem
+ */
+static const char *
+sem_test_sem_to_s(const struct os_sem *sem)
+{
+ static char buf[128];
+
+ snprintf(buf, sizeof buf, "\tSemaphore: tokens=%u head=%p",
+ sem->sem_tokens, SLIST_FIRST(&sem->sem_head));
+
+ return buf;
+}
+
+static void
+sem_test_sleep_task_handler(void *arg)
+{
+ struct os_task *t;
+
+ t = os_sched_get_current_task();
+ TEST_ASSERT(t->t_func == sem_test_sleep_task_handler);
+
- os_time_delay(2000);
++ os_time_delay(2 * OS_TICKS_PER_SEC);
+ os_test_restart();
+}
+
+static void
+sem_test_pend_release_loop(int delay, int timeout, int itvl)
+{
+ os_error_t err;
+
+ os_time_delay(delay);
+
+ while (1) {
+ err = os_sem_pend(&g_sem1, timeout);
+ TEST_ASSERT((err == OS_OK) || (err == OS_TIMEOUT));
+
+ err = os_sem_release(&g_sem1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_time_delay(itvl);
+ }
+}
+
+/**
+ * sem test basic
+ *
+ * Basic semaphore tests
+ *
+ * @return int
+ */
+static void
+sem_test_basic_handler(void *arg)
+{
+ struct os_task *t;
+ struct os_sem *sem;
+ os_error_t err;
+
+ sem = &g_sem1;
+ t = os_sched_get_current_task();
+
+ /* Test some error cases */
+ TEST_ASSERT(os_sem_init(NULL, 1) == OS_INVALID_PARM);
+ TEST_ASSERT(os_sem_release(NULL) == OS_INVALID_PARM);
+ TEST_ASSERT(os_sem_pend(NULL, 1) == OS_INVALID_PARM);
+
+ /* Get the semaphore */
+ err = os_sem_pend(sem, 0);
+ TEST_ASSERT(err == 0,
+ "Did not get free semaphore immediately (err=%d)", err);
+
+ /* Check semaphore internals */
+ TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head),
+ "Semaphore internals wrong after getting semaphore\n"
+ "%s\n"
+ "Task: task=%p prio=%u", sem_test_sem_to_s(sem), t, t->t_prio);
+
+ /* Get the semaphore again; should fail */
+ err = os_sem_pend(sem, 0);
+ TEST_ASSERT(err == OS_TIMEOUT,
+ "Did not time out waiting for semaphore (err=%d)", err);
+
+ /* Check semaphore internals */
+ TEST_ASSERT(sem->sem_tokens == 0 && SLIST_EMPTY(&sem->sem_head),
+ "Semaphore internals wrong after getting semaphore\n"
+ "%s\n"
+ "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t,
+ t->t_prio);
+
+ /* Release semaphore */
+ err = os_sem_release(sem);
+ TEST_ASSERT(err == 0,
+ "Could not release semaphore I own (err=%d)", err);
+
+ /* Check semaphore internals */
+ TEST_ASSERT(sem->sem_tokens == 1 && SLIST_EMPTY(&sem->sem_head),
+ "Semaphore internals wrong after releasing semaphore\n"
+ "%s\n"
+ "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t,
+ t->t_prio);
+
+ /* Release it again */
+ err = os_sem_release(sem);
+ TEST_ASSERT(err == 0,
+ "Could not release semaphore again (err=%d)\n", err);
+
+ /* Check semaphore internals */
+ TEST_ASSERT(sem->sem_tokens == 2 && SLIST_EMPTY(&sem->sem_head),
+ "Semaphore internals wrong after releasing semaphore\n"
+ "%s\n"
+ "Task: task=%p prio=%u\n", sem_test_sem_to_s(sem), t,
+ t->t_prio);
+
+ os_test_restart();
+}
+
+static void
+sem_test_1_task1_handler(void *arg)
+{
+ os_error_t err;
+ struct os_task *t;
+ int i;;
+
+ for (i = 0; i < 3; i++) {
+ t = os_sched_get_current_task();
+ TEST_ASSERT(t->t_func == sem_test_1_task1_handler);
+
+
+ err = os_sem_pend(&g_sem1, 0);
+ TEST_ASSERT(err == OS_OK);
+
+ /* Sleep to let other tasks run */
- os_time_delay(100);
++ os_time_delay(OS_TICKS_PER_SEC / 10);
+
+ /* Release the semaphore */
+ err = os_sem_release(&g_sem1);
+ TEST_ASSERT(err == OS_OK);
+
+ /* Sleep to let other tasks run */
- os_time_delay(100);
++ os_time_delay(OS_TICKS_PER_SEC / 10);
+ }
+
+ os_test_restart();
+}
+
+TEST_CASE(os_sem_test_basic)
+{
+ os_error_t err;
+
+ os_init();
+
+ err = os_sem_init(&g_sem1, 1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_task_init(&task1, "task1", sem_test_basic_handler, NULL, TASK1_PRIO,
+ OS_WAIT_FOREVER, stack1, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_start();
+}
+
+static void
+sem_test_1_task2_handler(void *arg)
+{
- sem_test_pend_release_loop(0, 100, 100);
++ sem_test_pend_release_loop(0, OS_TICKS_PER_SEC / 10, OS_TICKS_PER_SEC / 10);
+}
+
+static void
+sem_test_1_task3_handler(void *arg)
+{
- sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000);
++ sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, OS_TICKS_PER_SEC * 2);
+}
+
+TEST_CASE(os_sem_test_case_1)
+{
+ os_error_t err;
+
+ os_init();
+
+ err = os_sem_init(&g_sem1, 1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_task_init(&task1, "task1", sem_test_1_task1_handler, NULL,
+ TASK1_PRIO, OS_WAIT_FOREVER, stack1,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task2, "task2", sem_test_1_task2_handler, NULL,
+ TASK2_PRIO, OS_WAIT_FOREVER, stack2,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task3, "task3", sem_test_1_task3_handler, NULL, TASK3_PRIO,
+ OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_start();
+}
+
+static void
+sem_test_2_task2_handler(void *arg)
+{
+ sem_test_pend_release_loop(0, 2000, 2000);
+}
+
+static void
+sem_test_2_task3_handler(void *arg)
+{
+ sem_test_pend_release_loop(0, OS_TIMEOUT_NEVER, 2000);
+}
+
+static void
+sem_test_2_task4_handler(void *arg)
+{
+ sem_test_pend_release_loop(0, 2000, 2000);
+}
+
+TEST_CASE(os_sem_test_case_2)
+{
+ os_error_t err;
+
+ os_init();
+
+ err = os_sem_init(&g_sem1, 1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL,
+ TASK1_PRIO, OS_WAIT_FOREVER, stack1,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task2, "task2", sem_test_2_task2_handler, NULL,
+ TASK2_PRIO, OS_WAIT_FOREVER, stack2,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task3, "task3", sem_test_2_task3_handler, NULL, TASK3_PRIO,
+ OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task4, "task4", sem_test_2_task4_handler, NULL, TASK4_PRIO,
+ OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_start();
+}
+
+static void
+sem_test_3_task2_handler(void *arg)
+{
+ sem_test_pend_release_loop(100, 2000, 2000);
+}
+
+static void
+sem_test_3_task3_handler(void *arg)
+{
+ sem_test_pend_release_loop(150, 2000, 2000);
+}
+
+static void
+sem_test_3_task4_handler(void *arg)
+{
+ sem_test_pend_release_loop(0, 2000, 2000);
+}
+
+TEST_CASE(os_sem_test_case_3)
+{
+ os_error_t err;
+
+ os_init();
+
+ err = os_sem_init(&g_sem1, 1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL,
+ TASK1_PRIO, OS_WAIT_FOREVER, stack1,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task2, "task2", sem_test_3_task2_handler, NULL,
+ TASK2_PRIO, OS_WAIT_FOREVER, stack2,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task3, "task3", sem_test_3_task3_handler, NULL, TASK3_PRIO,
+ OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task4, "task4", sem_test_3_task4_handler, NULL, TASK4_PRIO,
+ OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_start();
+}
+
+static void
+sem_test_4_task2_handler(void *arg)
+{
+ sem_test_pend_release_loop(60, 2000, 2000);
+}
+
+static void
+sem_test_4_task3_handler(void *arg)
+{
+ sem_test_pend_release_loop(60, 2000, 2000);
+}
+
+static void
+sem_test_4_task4_handler(void *arg)
+{
+ sem_test_pend_release_loop(0, 2000, 2000);
+}
+
+
+TEST_CASE(os_sem_test_case_4)
+{
+ os_error_t err;
+
+ os_init();
+
+ err = os_sem_init(&g_sem1, 1);
+ TEST_ASSERT(err == OS_OK);
+
+ os_task_init(&task1, "task1", sem_test_sleep_task_handler, NULL,
+ TASK1_PRIO, OS_WAIT_FOREVER, stack1,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task2, "task2", sem_test_4_task2_handler, NULL,
+ TASK2_PRIO, OS_WAIT_FOREVER, stack2,
+ OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task3, "task3", sem_test_4_task3_handler, NULL, TASK3_PRIO,
+ OS_WAIT_FOREVER, stack3, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_task_init(&task4, "task4", sem_test_4_task4_handler, NULL, TASK4_PRIO,
+ OS_WAIT_FOREVER, stack4, OS_STACK_ALIGN(SEM_TEST_STACK_SIZE));
+
+ os_start();
+}
+
+TEST_SUITE(os_sem_test_suite)
+{
+ os_sem_test_basic();
+ os_sem_test_case_1();
+ os_sem_test_case_2();
+ os_sem_test_case_3();
+ os_sem_test_case_4();
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/shell/include/shell/shell.h
----------------------------------------------------------------------
diff --cc libs/shell/include/shell/shell.h
index 6b89740,1d98148..48351a0
--- a/libs/shell/include/shell/shell.h
+++ b/libs/shell/include/shell/shell.h
@@@ -40,6 -40,10 +40,9 @@@ int shell_nlip_input_register(shell_nli
int shell_nlip_output(struct os_mbuf *m);
void shell_console_rx_cb(void);
-int shell_task_init(uint8_t prio, os_stack_t *stack, uint16_t stack_size,
- int max_input_length);
+void shell_init(void);
+ int shell_cmd_list_lock(void);
+ int shell_cmd_list_unlock(void);
+
#endif /* __SHELL_H__ */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/shell/src/shell.c
----------------------------------------------------------------------
diff --cc libs/shell/src/shell.c
index 7fe15e5,8c904ec..18f040a
--- a/libs/shell/src/shell.c
+++ b/libs/shell/src/shell.c
@@@ -17,22 -17,23 +17,20 @@@
* under the License.
*/
-#include <os/os.h>
-
-#include <console/console.h>
-#include <console/prompt.h>
-
-#include "shell/shell.h"
-#include "shell_priv.h"
-#include "shell/shell_prompt.h"
-
-#include <os/endian.h>
-#include <util/base64.h>
-#include <util/crc16.h>
--
#include <stdio.h>
#include <string.h>
#include <assert.h>
- #include <errno.h>
+#include "sysinit/sysinit.h"
+#include "syscfg/syscfg.h"
+#include "console/console.h"
+#include "os/os.h"
+#include "os/endian.h"
+#include "util/base64.h"
+#include "util/crc16.h"
+#include "shell/shell.h"
+#include "shell_priv.h"
+
static shell_nlip_input_func_t g_shell_nlip_in_func;
static void *g_shell_nlip_in_arg;
@@@ -42,10 -43,9 +40,11 @@@ static struct os_mqueue g_shell_nlip_mq
#define SHELL_HELP_PER_LINE 6
#define SHELL_MAX_ARGS 20
+static os_stack_t shell_stack[OS_STACK_ALIGN(MYNEWT_VAL(SHELL_STACK_SIZE))];
+
static int shell_echo_cmd(int argc, char **argv);
static int shell_help_cmd(int argc, char **argv);
+ int shell_prompt_cmd(int argc, char **argv);
static struct shell_cmd g_shell_echo_cmd = {
.sc_cmd = "echo",
@@@ -530,30 -539,50 +537,35 @@@ shell_init(void
int rc;
free(shell_line);
+ shell_line = NULL;
- if (max_input_length > 0) {
- shell_line = malloc(max_input_length);
- if (shell_line == NULL) {
- rc = OS_ENOMEM;
- goto err;
- }
- }
- shell_line_capacity = max_input_length;
+#if MYNEWT_VAL(SHELL_MAX_INPUT_LEN) > 0
+ shell_line = malloc(MYNEWT_VAL(SHELL_MAX_INPUT_LEN));
+ SYSINIT_PANIC_ASSERT(shell_line != NULL);
+#endif
rc = os_mutex_init(&g_shell_cmd_list_lock);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
rc = shell_cmd_register(&g_shell_echo_cmd);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
rc = shell_cmd_register(&g_shell_help_cmd);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
+ rc = shell_cmd_register(&g_shell_prompt_cmd);
+ if (rc != 0) {
+ goto err;
+ }
+
rc = shell_cmd_register(&g_shell_os_tasks_display_cmd);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
rc = shell_cmd_register(&g_shell_os_mpool_display_cmd);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
rc = shell_cmd_register(&g_shell_os_date_cmd);
- if (rc != 0) {
- goto err;
- }
+ SYSINIT_PANIC_ASSERT(rc == 0);
os_eventq_init(&shell_evq);
os_mqueue_init(&g_shell_nlip_mq, NULL);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/util/test/src/util_test.c
----------------------------------------------------------------------
diff --cc libs/util/test/src/util_test.c
index d528568,0000000..4e21a9a
mode 100644,000000..100644
--- a/libs/util/test/src/util_test.c
+++ b/libs/util/test/src/util_test.c
@@@ -1,46 -1,0 +1,53 @@@
+/**
+ * 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 <assert.h>
+#include <stddef.h>
+#include "syscfg/syscfg.h"
+#include "testutil/testutil.h"
+#include "util_test_priv.h"
+
+int
+util_test_all(void)
+{
+ cbmem_test_suite();
+ return tu_case_failed;
+}
+
++int
++hex_fmt_test_all(void)
++{
++ hex_fmt_test_suite();
++ return tu_case_failed;
++}
++
+#if MYNEWT_VAL(SELFTEST)
+
+int
+main(int argc, char **argv)
+{
+ tu_config.tc_print_results = 1;
+ tu_init();
+
+ util_test_all();
-
++ hex_fmt_test_all();
+ return tu_any_failed;
+}
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/util/test/src/util_test_priv.h
----------------------------------------------------------------------
diff --cc libs/util/test/src/util_test_priv.h
index cc5533d,0000000..c82df29
mode 100644,000000..100644
--- a/libs/util/test/src/util_test_priv.h
+++ b/libs/util/test/src/util_test_priv.h
@@@ -1,25 -1,0 +1,26 @@@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef __UTIL_TEST_PRIV_
+#define __UTIL_TEST_PRIV_
+
+int cbmem_test_suite(void);
++int hex_fmt_test_suite(void);
+
+#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/libs/wifi_mgmt/src/wifi_cli.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/include/controller/ble_ll.h
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_adv.c
----------------------------------------------------------------------
diff --cc net/nimble/controller/src/ble_ll_adv.c
index 01de299,3e2ce1f..64f5e23
--- a/net/nimble/controller/src/ble_ll_adv.c
+++ b/net/nimble/controller/src/ble_ll_adv.c
@@@ -121,7 -122,24 +123,24 @@@ struct ble_ll_adv_sm g_ble_ll_adv_sm
#define BLE_LL_ADV_DIRECT_SCHED_MAX_USECS (502)
-#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
+ /**
+ * Called to change advertisers ADVA and INITA (for directed advertisements)
+ * as an advertiser needs to adhere to the resolvable private address generation
+ * timer.
+ *
+ * NOTE: the resolvable private address code uses its own timer to regenerate
+ * local resolvable private addresses. The advertising code uses its own
+ * timer to reset the INITA (for directed advertisements). This code also sets
+ * the appropriate txadd and rxadd bits that will go into the advertisement.
+ *
+ * Another thing to note: it is possible that an IRK is all zeroes in the
+ * resolving list. That is why we need to check if the generated address is
+ * in fact a RPA as a resolving list entry with all zeroes will use the
+ * identity address (which may be a private address or public).
+ *
+ * @param advsm
+ */
void
ble_ll_adv_chk_rpa_timeout(struct ble_ll_adv_sm *advsm)
{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_conn.c
----------------------------------------------------------------------
diff --cc net/nimble/controller/src/ble_ll_conn.c
index 8ec6bca,43944a8..ba8fbc4
--- a/net/nimble/controller/src/ble_ll_conn.c
+++ b/net/nimble/controller/src/ble_ll_conn.c
@@@ -212,7 -215,25 +216,25 @@@ STATS_NAME_START(ble_ll_conn_stats
STATS_NAME(ble_ll_conn_stats, mic_failures)
STATS_NAME_END(ble_ll_conn_stats)
+ /**
+ * Get the event buffer allocated to send the connection complete event
+ * when we are initiating.
+ *
+ * @return uint8_t*
+ */
+ static uint8_t *
+ ble_ll_init_get_conn_comp_ev(void)
+ {
+ uint8_t *evbuf;
+
+ evbuf = g_ble_ll_conn_comp_ev;
+ assert(evbuf != NULL);
+ g_ble_ll_conn_comp_ev = NULL;
+
+ return evbuf;
+ }
+
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
/**
* Called to determine if the received PDU is an empty PDU or not.
*/
@@@ -593,13 -620,11 +621,11 @@@ ble_ll_conn_wait_txend(void *arg
{
struct ble_ll_conn_sm *connsm;
- ble_ll_conn_current_sm_over();
-
connsm = (struct ble_ll_conn_sm *)arg;
- ble_ll_event_send(&connsm->conn_ev_end);
+ ble_ll_conn_current_sm_over(connsm);
}
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
static void
ble_ll_conn_start_rx_encrypt(void *arg)
{
@@@ -2681,10 -2737,10 +2738,10 @@@ ble_ll_conn_rx_isr_end(uint8_t *rxbuf,
*/
hdr_sn = hdr_byte & BLE_LL_DATA_HDR_SN_MASK;
conn_nesn = connsm->next_exp_seqnum;
- if ((hdr_sn && conn_nesn) || (!hdr_sn && !conn_nesn)) {
+ if (rxpdu && ((hdr_sn && conn_nesn) || (!hdr_sn && !conn_nesn))) {
connsm->next_exp_seqnum ^= 1;
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
- if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxbuf)) {
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
+ if (CONN_F_ENCRYPTED(connsm) && !ble_ll_conn_is_empty_pdu(rxpdu)) {
++connsm->enc_data.rx_pkt_cntr;
}
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_conn_hci.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_conn_priv.h
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_hci.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_hci_ev.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_resolv.c
----------------------------------------------------------------------
diff --cc net/nimble/controller/src/ble_ll_resolv.c
index 608da8c,903c95f..a507d19
--- a/net/nimble/controller/src/ble_ll_resolv.c
+++ b/net/nimble/controller/src/ble_ll_resolv.c
@@@ -31,15 -30,18 +31,18 @@@
#include "controller/ble_hw.h"
#include "ble_ll_conn_priv.h"
-#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-
- /* Flag denoting whether or not address translation is enabled. */
- uint8_t g_ble_ll_addr_res_enabled;
- uint8_t g_ble_ll_resolv_list_size;
- uint8_t g_ble_ll_resolv_list_cnt;
- uint32_t g_ble_ll_resolv_rpa_tmo;
+ struct ble_ll_resolv_data
+ {
+ uint8_t addr_res_enabled;
+ uint8_t rl_size;
+ uint8_t rl_cnt;
+ uint32_t rpa_tmo;
+ struct os_callout_func rpa_timer;
+ };
+ struct ble_ll_resolv_data g_ble_ll_resolv_data;
-struct ble_ll_resolv_entry g_ble_ll_resolv_list[NIMBLE_OPT_LL_RESOLV_LIST_SIZE];
+struct ble_ll_resolv_entry g_ble_ll_resolv_list[MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)];
/**
* Called to determine if a change is allowed to the resolving list at this
@@@ -455,15 -553,19 +554,19 @@@ ble_ll_resolv_init(void
uint8_t hw_size;
/* Default is 15 minutes */
- g_ble_ll_resolv_rpa_tmo = 15 * 60 * OS_TICKS_PER_SEC;
+ g_ble_ll_resolv_data.rpa_tmo = 15 * 60 * OS_TICKS_PER_SEC;
hw_size = ble_hw_resolv_list_size();
- if (hw_size > NIMBLE_OPT_LL_RESOLV_LIST_SIZE) {
- hw_size = NIMBLE_OPT_LL_RESOLV_LIST_SIZE;
+ if (hw_size > MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE)) {
+ hw_size = MYNEWT_VAL(BLE_LL_RESOLV_LIST_SIZE);
}
- g_ble_ll_resolv_list_size = hw_size;
+ g_ble_ll_resolv_data.rl_size = hw_size;
+ os_callout_func_init(&g_ble_ll_resolv_data.rpa_timer,
+ &g_ble_ll_data.ll_evq,
+ ble_ll_resolv_rpa_timer_cb,
+ NULL);
}
-#endif /* if BLE_LL_CFG_FEAT_LL_PRIVACY == 1 */
+#endif /* if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1 */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/controller/src/ble_ll_scan.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/drivers/native/src/ble_phy.c
----------------------------------------------------------------------
diff --cc net/nimble/drivers/native/src/ble_phy.c
index d19e54b,ff195fc..0f1ef5a
--- a/net/nimble/drivers/native/src/ble_phy.c
+++ b/net/nimble/drivers/native/src/ble_phy.c
@@@ -18,10 -18,12 +18,13 @@@
*/
#include <stdint.h>
+ #include <string.h>
#include <assert.h>
+#include "syscfg/syscfg.h"
#include "os/os.h"
- #include "nimble/ble.h" /* XXX: needed for ble mbuf header.*/
+ #include "ble/xcvr.h"
+ #include "nimble/ble.h"
+ #include "nimble/nimble_opt.h"
#include "controller/ble_phy.h"
#include "controller/ble_ll.h"
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/drivers/nrf51/src/ble_phy.c
----------------------------------------------------------------------
diff --cc net/nimble/drivers/nrf51/src/ble_phy.c
index db6618f,a24a434..b8d2f6b
--- a/net/nimble/drivers/nrf51/src/ble_phy.c
+++ b/net/nimble/drivers/nrf51/src/ble_phy.c
@@@ -27,13 -26,8 +27,8 @@@
#include "nimble/nimble_opt.h"
#include "controller/ble_phy.h"
#include "controller/ble_ll.h"
-#include "mcu/nrf51_bitfields.h"
+#include "nrf51_bitfields.h"
- /*
- * XXX: need to make the copy from mbuf into the PHY data structures 32-bit
- * copies or we are screwed.
- */
-
/* XXX: 4) Make sure RF is higher priority interrupt than schedule */
/*
@@@ -93,9 -88,10 +89,10 @@@ struct ble_phy_obj g_ble_phy_data
/* XXX: if 27 byte packets desired we can make this smaller */
/* Global transmit/receive buffer */
- static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+ static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+ static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
/* Make sure word-aligned for faster copies */
static uint32_t g_ble_phy_enc_buf[(NRF_ENC_BUF_SIZE + 3) / 4];
#endif
@@@ -242,11 -284,16 +285,16 @@@ nrf_wait_disabled(void
static void
ble_phy_rx_xcvr_setup(void)
{
- #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
+ uint8_t *dptr;
+
+ dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
+
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
++#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
if (g_ble_phy_data.phy_encrypted) {
+ dptr += 3;
NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_CCM->OUTPTR = (uint32_t)dptr;
NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
NRF_CCM->MODE = CCM_MODE_MODE_Decryption;
NRF_CCM->CNFPTR = (uint32_t)&g_nrf_ccm_data;
@@@ -255,14 -302,16 +303,16 @@@
NRF_CCM->EVENTS_ENDCRYPT = 0;
NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
} else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_RADIO->PACKETPTR = (uint32_t)dptr;
}
#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_RADIO->PACKETPTR = (uint32_t)dptr;
#endif
- #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
++#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
if (g_ble_phy_data.phy_privacy) {
+ dptr += 3;
+ NRF_RADIO->PACKETPTR = (uint32_t)dptr;
NRF_RADIO->PCNF0 = (6 << RADIO_PCNF0_LFLEN_Pos) |
(2 << RADIO_PCNF0_S1LEN_Pos) |
(NRF_S0_LEN << RADIO_PCNF0_S0LEN_Pos);
@@@ -411,7 -464,7 +465,7 @@@ ble_phy_rx_end_isr(void
} else {
STATS_INC(ble_phy_stats, rx_valid);
ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_CRC_OK;
- #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
++#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
if (g_ble_phy_data.phy_encrypted) {
/* Only set MIC failure flag if frame is not zero length */
if ((dptr[1] != 0) && (NRF_CCM->MICSTATUS == 0)) {
@@@ -442,11 -495,7 +496,7 @@@
#endif
}
- /* Call Link Layer receive payload function */
- rxpdu = g_ble_phy_data.rxpdu;
- g_ble_phy_data.rxpdu = NULL;
-
- #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1) || (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1) || (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
++#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) || MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY)
if (g_ble_phy_data.phy_encrypted || g_ble_phy_data.phy_privacy) {
/*
* XXX: This is a horrible ugly hack to deal with the RAM S1 byte.
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/drivers/nrf52/src/ble_phy.c
----------------------------------------------------------------------
diff --cc net/nimble/drivers/nrf52/src/ble_phy.c
index 46bb39a,2e34669..6498a06
--- a/net/nimble/drivers/nrf52/src/ble_phy.c
+++ b/net/nimble/drivers/nrf52/src/ble_phy.c
@@@ -28,13 -27,8 +28,8 @@@
#include "nimble/nimble_opt.h"
#include "controller/ble_phy.h"
#include "controller/ble_ll.h"
-#include "mcu/nrf52_bitfields.h"
+#include "nrf52_bitfields.h"
- /*
- * XXX: need to make the copy from mbuf into the PHY data structures 32-bit
- * copies or we are screwed.
- */
-
/* XXX: 4) Make sure RF is higher priority interrupt than schedule */
/*
@@@ -88,9 -82,10 +83,10 @@@ struct ble_phy_obj g_ble_phy_data
/* XXX: if 27 byte packets desired we can make this smaller */
/* Global transmit/receive buffer */
- static uint32_t g_ble_phy_txrx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+ static uint32_t g_ble_phy_tx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
+ static uint32_t g_ble_phy_rx_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
/* Make sure word-aligned for faster copies */
static uint32_t g_ble_phy_enc_buf[(BLE_PHY_MAX_PDU_LEN + 3) / 4];
#endif
@@@ -244,7 -285,12 +286,12 @@@ nrf_wait_disabled(void
static void
ble_phy_rx_xcvr_setup(void)
{
- #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
+ uint8_t *dptr;
+
+ dptr = (uint8_t *)&g_ble_phy_rx_buf[0];
+ dptr += 3;
+
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
++#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION)
if (g_ble_phy_data.phy_encrypted) {
NRF_RADIO->PACKETPTR = (uint32_t)&g_ble_phy_enc_buf[0];
NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
@@@ -257,13 -303,13 +304,13 @@@
NRF_CCM->EVENTS_ENDCRYPT = 0;
NRF_PPI->CHENSET = PPI_CHEN_CH24_Msk | PPI_CHEN_CH25_Msk;
} else {
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_RADIO->PACKETPTR = (uint32_t)dptr;
}
#else
- NRF_RADIO->PACKETPTR = (uint32_t)g_ble_phy_data.rxpdu->om_data;
+ NRF_RADIO->PACKETPTR = (uint32_t)dptr;
#endif
-#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
if (g_ble_phy_data.phy_privacy) {
NRF_AAR->ENABLE = AAR_ENABLE_ENABLE_Enabled;
NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
@@@ -827,12 -870,14 +871,14 @@@ ble_phy_tx(struct os_mbuf *txpdu, uint8
ble_hdr = BLE_MBUF_HDR_PTR(txpdu);
payload_len = ble_hdr->txinfo.pyld_len;
-#if (BLE_LL_CFG_FEAT_LE_ENCRYPTION == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
if (g_ble_phy_data.phy_encrypted) {
dptr = (uint8_t *)&g_ble_phy_enc_buf[0];
+ ++dptr;
+ pktptr = (uint8_t *)&g_ble_phy_tx_buf[0];
NRF_CCM->SHORTS = 1;
- NRF_CCM->INPTR = (uint32_t)&g_ble_phy_enc_buf[0];
- NRF_CCM->OUTPTR = (uint32_t)&g_ble_phy_txrx_buf[0];
+ NRF_CCM->INPTR = (uint32_t)dptr;
+ NRF_CCM->OUTPTR = (uint32_t)pktptr;
NRF_CCM->SCRATCHPTR = (uint32_t)&g_nrf_encrypt_scratchpad[0];
NRF_CCM->EVENTS_ERROR = 0;
NRF_CCM->MODE = CCM_MODE_LENGTH_Msk;
@@@ -844,13 -889,17 +890,17 @@@
NRF_PPI->CHENCLR = PPI_CHEN_CH23_Msk;
NRF_AAR->IRKPTR = (uint32_t)&g_nrf_irk_list[0];
#endif
- dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+ dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
+ ++dptr;
+ pktptr = dptr;
}
#else
-#if (BLE_LL_CFG_FEAT_LL_PRIVACY == 1)
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
NRF_PPI->CHENCLR = PPI_CHEN_CH23_Msk;
#endif
- dptr = (uint8_t *)&g_ble_phy_txrx_buf[0];
+ dptr = (uint8_t *)&g_ble_phy_tx_buf[0];
+ ++dptr;
+ pktptr = dptr;
#endif
/* RAM representation has S0, LENGTH and S1 fields. (3 bytes) */
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/services/gap/include/services/gap/ble_svc_gap.h
----------------------------------------------------------------------
diff --cc net/nimble/host/services/gap/include/services/gap/ble_svc_gap.h
index 0000000,95d4226..dcc2712
mode 000000,100644..100644
--- a/net/nimble/host/services/gap/include/services/gap/ble_svc_gap.h
+++ b/net/nimble/host/services/gap/include/services/gap/ble_svc_gap.h
@@@ -1,0 -1,39 +1,39 @@@
+ /**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+ #ifndef H_BLE_SVC_GAP_
+ #define H_BLE_SVC_GAP_
+
+ struct ble_hs_cfg;
+
+ #define BLE_SVC_GAP_UUID16 0x1800
+ #define BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME 0x2a00
+ #define BLE_SVC_GAP_CHR_UUID16_APPEARANCE 0x2a01
+ #define BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG 0x2a02
+ #define BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR 0x2a03
+ #define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS 0x2a04
+
+ #define BLE_SVC_GAP_APPEARANCE_GEN_COMPUTER 128
+
+ const char *ble_svc_gap_device_name(void);
+ int ble_svc_gap_device_name_set(const char *name);
+
-int ble_svc_gap_init(struct ble_hs_cfg *cfg);
++int ble_svc_gap_init(void);
+
+ #endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/services/gap/src/ble_svc_gap.c
----------------------------------------------------------------------
diff --cc net/nimble/host/services/gap/src/ble_svc_gap.c
index 0000000,1a2e8a4..eb67b6c
mode 000000,100644..100644
--- a/net/nimble/host/services/gap/src/ble_svc_gap.c
+++ b/net/nimble/host/services/gap/src/ble_svc_gap.c
@@@ -1,0 -1,167 +1,167 @@@
+ /**
+ * 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 <assert.h>
+ #include <string.h>
+ #include "host/ble_hs.h"
+ #include "services/gap/ble_svc_gap.h"
+
+ /* XXX: This should be configurable. */
+ #define BLE_SVC_GAP_NAME_MAX_LEN 31
+
+ static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] = "nimble";
+ static uint16_t ble_svc_gap_appearance;
+ static uint8_t ble_svc_gap_privacy_flag;
+ static uint8_t ble_svc_gap_reconnect_addr[6];
+ static uint8_t ble_svc_gap_pref_conn_params[8];
+
+ static int
+ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = {
+ {
+ /*** Service: GAP. */
+ .type = BLE_GATT_SVC_TYPE_PRIMARY,
+ .uuid128 = BLE_UUID16(BLE_SVC_GAP_UUID16),
+ .characteristics = (struct ble_gatt_chr_def[]) { {
+ /*** Characteristic: Device Name. */
+ .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME),
+ .access_cb = ble_svc_gap_access,
+ .flags = BLE_GATT_CHR_F_READ,
+ }, {
+ /*** Characteristic: Appearance. */
+ .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_APPEARANCE),
+ .access_cb = ble_svc_gap_access,
+ .flags = BLE_GATT_CHR_F_READ,
+ }, {
+ /*** Characteristic: Peripheral Privacy Flag. */
+ .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG),
+ .access_cb = ble_svc_gap_access,
+ .flags = BLE_GATT_CHR_F_READ,
+ }, {
+ /*** Characteristic: Reconnection Address. */
+ .uuid128 = BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR),
+ .access_cb = ble_svc_gap_access,
+ .flags = BLE_GATT_CHR_F_WRITE,
+ }, {
+ /*** Characteristic: Peripheral Preferred Connection Parameters. */
+ .uuid128 =
+ BLE_UUID16(BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS),
+ .access_cb = ble_svc_gap_access,
+ .flags = BLE_GATT_CHR_F_READ,
+ }, {
+ 0, /* No more characteristics in this service. */
+ } },
+ },
+
+ {
+ 0, /* No more services. */
+ },
+ };
+
+ static int
+ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg)
+ {
+ uint16_t uuid16;
+ int rc;
+
+ uuid16 = ble_uuid_128_to_16(ctxt->chr->uuid128);
+ assert(uuid16 != 0);
+
+ switch (uuid16) {
+ case BLE_SVC_GAP_CHR_UUID16_DEVICE_NAME:
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+ rc = os_mbuf_append(ctxt->om, ble_svc_gap_name,
+ strlen(ble_svc_gap_name));
+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
+ case BLE_SVC_GAP_CHR_UUID16_APPEARANCE:
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+ rc = os_mbuf_append(ctxt->om, &ble_svc_gap_appearance,
+ sizeof ble_svc_gap_appearance);
+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
+ case BLE_SVC_GAP_CHR_UUID16_PERIPH_PRIV_FLAG:
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+ rc = os_mbuf_append(ctxt->om, &ble_svc_gap_privacy_flag,
+ sizeof ble_svc_gap_privacy_flag);
+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
+ case BLE_SVC_GAP_CHR_UUID16_RECONNECT_ADDR:
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);
+ if (OS_MBUF_PKTLEN(ctxt->om) != sizeof ble_svc_gap_reconnect_addr) {
+ return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
+ }
+ ble_hs_mbuf_to_flat(ctxt->om, ble_svc_gap_reconnect_addr,
+ sizeof ble_svc_gap_reconnect_addr, NULL);
+ return 0;
+
+ case BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+ rc = os_mbuf_append(ctxt->om, &ble_svc_gap_pref_conn_params,
+ sizeof ble_svc_gap_pref_conn_params);
+ return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
+
+ default:
+ assert(0);
+ return BLE_ATT_ERR_UNLIKELY;
+ }
+ }
+
+ const char *
+ ble_svc_gap_device_name(void)
+ {
+ return ble_svc_gap_name;
+ }
+
+ int
+ ble_svc_gap_device_name_set(const char *name)
+ {
+ int len;
+
+ len = strlen(name);
+ if (len > BLE_SVC_GAP_NAME_MAX_LEN) {
+ return BLE_HS_EINVAL;
+ }
+
+ memcpy(ble_svc_gap_name, name, len);
+ ble_svc_gap_name[len] = '\0';
+
+ return 0;
+ }
+
+ int
-ble_svc_gap_init(struct ble_hs_cfg *cfg)
++ble_svc_gap_init(void)
+ {
+ int rc;
+
- rc = ble_gatts_count_cfg(ble_svc_gap_defs, cfg);
++ rc = ble_gatts_count_cfg(ble_svc_gap_defs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = ble_gatts_add_svcs(ble_svc_gap_defs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+ }
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/services/gatt/pkg.yml
----------------------------------------------------------------------
diff --cc net/nimble/host/services/gatt/pkg.yml
index 0000000,b8fdabe..54343bd
mode 000000,100644..100644
--- a/net/nimble/host/services/gatt/pkg.yml
+++ b/net/nimble/host/services/gatt/pkg.yml
@@@ -1,0 -1,31 +1,34 @@@
+ #
+ # Licensed to the Apache Software Foundation (ASF) under one
+ # or more contributor license agreements. See the NOTICE file
+ # distributed with this work for additional information
+ # regarding copyright ownership. The ASF licenses this file
+ # to you under the Apache License, Version 2.0 (the
+ # "License"); you may not use this file except in compliance
+ # with the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing,
+ # software distributed under the License is distributed on an
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ # KIND, either express or implied. See the License for the
+ # specific language governing permissions and limitations
+ # under the License.
+ #
+
+ pkg.name: net/nimble/host/services/gatt
+ pkg.description: Implements the GATT service.
+ pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+ pkg.homepage: "http://mynewt.apache.org/"
+ pkg.keywords:
+ - ble
+ - bluetooth
+ - nimble
+ - gatt
+
+ pkg.deps:
+ - net/nimble/host
++
++pkg.init_function: ble_svc_mandatory_pkg_init
++pkg.init_stage: 3
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/services/gatt/src/ble_svc_gatt.c
----------------------------------------------------------------------
diff --cc net/nimble/host/services/gatt/src/ble_svc_gatt.c
index 0000000,74d3ac9..c6426f0
mode 000000,100644..100644
--- a/net/nimble/host/services/gatt/src/ble_svc_gatt.c
+++ b/net/nimble/host/services/gatt/src/ble_svc_gatt.c
@@@ -1,0 -1,90 +1,90 @@@
+ /**
+ * 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 <assert.h>
+
+ #include "host/ble_hs.h"
+ #include "services/gatt/ble_svc_gatt.h"
+
+ static int
+ ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg);
+
+ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = {
+ {
+ /*** Service: GATT */
+ .type = BLE_GATT_SVC_TYPE_PRIMARY,
+ .uuid128 = BLE_UUID16(BLE_GATT_SVC_UUID16),
+ .characteristics = (struct ble_gatt_chr_def[]) { {
+ .uuid128 = BLE_UUID16(BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16),
+ .access_cb = ble_svc_gatt_access,
+ .flags = BLE_GATT_CHR_F_INDICATE,
+ }, {
+ 0, /* No more characteristics in this service. */
+ } },
+ },
+
+ {
+ 0, /* No more services. */
+ },
+ };
+
+ static int
+ ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt, void *arg)
+ {
+ uint8_t *u8;
+
+ /* The only operation allowed for this characteristic is indicate. This
+ * access callback gets called by the stack when it needs to read the
+ * characteristic value to populate the outgoing indication command.
+ * Therefore, this callback should only get called during an attempt to
+ * read the characteristic.
+ */
+ assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
+ assert(ctxt->chr == &ble_svc_gatt_defs[0].characteristics[0]);
+
+ /* XXX: For now, always respond with 0 (unchanged). */
+ u8 = os_mbuf_extend(ctxt->om, 1);
+ if (u8 == NULL) {
+ return BLE_ATT_ERR_INSUFFICIENT_RES;
+ }
+
+ *u8 = 0;
+
+ return 0;
+ }
+
+ int
-ble_svc_gatt_init(struct ble_hs_cfg *cfg)
++ble_svc_gatt_init(void)
+ {
+ int rc;
+
- rc = ble_gatts_count_cfg(ble_svc_gatt_defs, cfg);
++ rc = ble_gatts_count_cfg(ble_svc_gatt_defs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = ble_gatts_add_svcs(ble_svc_gatt_defs);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return 0;
+ }
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_att_clt.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_att_priv.h
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_att_svr.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_gap.c
----------------------------------------------------------------------
diff --cc net/nimble/host/src/ble_gap.c
index 81be873,2699e72..5014a86
--- a/net/nimble/host/src/ble_gap.c
+++ b/net/nimble/host/src/ble_gap.c
@@@ -770,8 -897,12 +895,13 @@@ ble_gap_rx_update_complete(struct hci_l
return;
#endif
++ struct ble_gap_update_entry *entry;
+ struct ble_l2cap_sig_update_params l2cap_params;
struct ble_gap_event event;
struct ble_hs_conn *conn;
+ int cb_status;
+ int call_cb;
+ int rc;
STATS_INC(ble_gap_stats, rx_update_complete);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_gattc.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_gatts.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_hs.c
----------------------------------------------------------------------
diff --cc net/nimble/host/src/ble_hs.c
index 84a69a6,1899a74..85b524b
--- a/net/nimble/host/src/ble_hs.c
+++ b/net/nimble/host/src/ble_hs.c
@@@ -60,13 -50,15 +60,15 @@@ static struct os_event ble_hs_event_res
uint8_t ble_hs_sync_state;
static int ble_hs_reset_reason;
-#if MYNEWT_SELFTEST
-/** Use a higher frequency timer to allow tests to run faster. */
-#define BLE_HS_HEARTBEAT_OS_TICKS (OS_TICKS_PER_SEC / 10)
-#else
-#define BLE_HS_HEARTBEAT_OS_TICKS OS_TICKS_PER_SEC
-#endif
+#define BLE_HS_HEARTBEAT_OS_TICKS \
+ (MYNEWT_VAL(BLE_HS_HEARTBEAT_FREQ) * OS_TICKS_PER_SEC / 1000)
+
+#define BLE_HS_SYNC_RETRY_RATE (OS_TICKS_PER_SEC / 10)
+
+static struct os_task *ble_hs_parent_task;
+ #define BLE_HS_SYNC_RETRY_RATE (OS_TICKS_PER_SEC / 10)
+
/**
* Handles unresponsive timeouts and periodic retries in case of resource
* shortage.
@@@ -406,25 -394,25 +409,41 @@@ voi
ble_hs_event_enqueue(struct os_event *ev)
{
os_eventq_put(&ble_hs_evq, ev);
- os_eventq_put(ble_hs_parent_evq, &ble_hs_event_co.cf_c.c_ev);
+ os_eventq_put(ble_hs_cfg.parent_evq, &ble_hs_event_co.cf_c.c_ev);
+}
+
+void
+ble_hs_enqueue_hci_event(uint8_t *hci_evt)
+{
+ struct os_event *ev;
+
+ ev = os_memblock_get(&ble_hs_hci_ev_pool);
+ if (ev == NULL) {
+ ble_hci_trans_buf_free(ev->ev_arg);
+ } else {
+ ev->ev_queued = 0;
+ ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
+ ev->ev_arg = hci_evt;
+ ble_hs_event_enqueue(ev);
+ }
}
+ void
+ ble_hs_enqueue_hci_event(uint8_t *hci_evt)
+ {
+ struct os_event *ev;
+
+ ev = os_memblock_get(&ble_hs_hci_ev_pool);
+ if (ev == NULL) {
+ ble_hci_trans_buf_free(hci_evt);
+ } else {
+ ev->ev_queued = 0;
+ ev->ev_type = BLE_HOST_HCI_EVENT_CTLR_EVENT;
+ ev->ev_arg = hci_evt;
+ ble_hs_event_enqueue(ev);
+ }
+ }
+
/**
* Schedules for all pending notifications and indications to be sent in the
* host parent task.
@@@ -562,15 -548,31 +581,14 @@@ ble_hs_init(void
{
int rc;
- ble_hs_free_mem();
-
- if (app_evq == NULL) {
- rc = BLE_HS_EINVAL;
- goto err;
- }
- ble_hs_parent_evq = app_evq;
-
- ble_hs_cfg_init(cfg);
-
log_init();
- log_console_handler_init(&ble_hs_log_console_handler);
- log_register("ble_hs", &ble_hs_log, &ble_hs_log_console_handler);
+ log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL);
- ble_hs_hci_os_event_buf = malloc(
- OS_MEMPOOL_BYTES(ble_hs_cfg.max_hci_bufs, sizeof (struct os_event)));
- if (ble_hs_hci_os_event_buf == NULL) {
- rc = BLE_HS_ENOMEM;
- goto err;
- }
-
/* Create memory pool of OS events */
- rc = os_mempool_init(&ble_hs_hci_ev_pool, ble_hs_cfg.max_hci_bufs,
+ rc = os_mempool_init(&ble_hs_hci_ev_pool, BLE_HS_HCI_EVT_COUNT,
sizeof (struct os_event), ble_hs_hci_os_event_buf,
"ble_hs_hci_ev_pool");
- assert(rc == 0);
+ SYSINIT_PANIC_ASSERT(rc == 0);
/* Initialize eventq */
os_eventq_init(&ble_hs_evq);
@@@ -619,6 -649,9 +637,5 @@@
/* Configure the HCI transport to communicate with a host. */
ble_hci_trans_cfg_hs(ble_hs_hci_rx_evt, NULL, ble_hs_rx_data, NULL);
- /* Configure storage mechanism. */
- /* XXX */
+ return 0;
-
-err:
- ble_hs_free_mem();
- return rc;
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_hs_adv.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_hs_conn.c
----------------------------------------------------------------------
diff --cc net/nimble/host/src/ble_hs_conn.c
index c0d08d0,34d9590..4d1f60c
--- a/net/nimble/host/src/ble_hs_conn.c
+++ b/net/nimble/host/src/ble_hs_conn.c
@@@ -249,9 -245,20 +249,20 @@@ ble_hs_conn_find(uint16_t conn_handle
}
struct ble_hs_conn *
+ ble_hs_conn_find_assert(uint16_t conn_handle)
+ {
+ struct ble_hs_conn *conn;
+
+ conn = ble_hs_conn_find(conn_handle);
+ BLE_HS_DBG_ASSERT(conn != NULL);
+
+ return conn;
+ }
+
+ struct ble_hs_conn *
ble_hs_conn_find_by_addr(uint8_t addr_type, uint8_t *addr)
{
-#if !NIMBLE_OPT(CONNECT)
+#if !NIMBLE_BLE_CONNECT
return NULL;
#endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_hs_misc.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_hs_priv.h
----------------------------------------------------------------------
diff --cc net/nimble/host/src/ble_hs_priv.h
index 1d77ae6,6bebec9..2a3ce20
--- a/net/nimble/host/src/ble_hs_priv.h
+++ b/net/nimble/host/src/ble_hs_priv.h
@@@ -98,11 -89,15 +98,11 @@@ int ble_hs_hci_evt_acl_process(struct o
int ble_hs_misc_conn_chan_find(uint16_t conn_handle, uint16_t cid,
struct ble_hs_conn **out_conn,
struct ble_l2cap_chan **out_chan);
- int ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
- struct ble_hs_conn **out_conn,
- struct ble_l2cap_chan **out_chan);
+ void ble_hs_misc_conn_chan_find_reqd(uint16_t conn_handle, uint16_t cid,
+ struct ble_hs_conn **out_conn,
+ struct ble_l2cap_chan **out_chan);
uint8_t ble_hs_misc_addr_type_to_id(uint8_t addr_type);
-void ble_hs_cfg_init(struct ble_hs_cfg *cfg);
-
int ble_hs_locked_by_cur_task(void);
int ble_hs_is_parent_task(void);
void ble_hs_lock(void);
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_l2cap_sig.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_sm.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_sm_cmd.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_sm_lgcy.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_sm_priv.h
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/src/ble_sm_sc.c
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/host/test/src/ble_att_clt_test.c
----------------------------------------------------------------------
diff --cc net/nimble/host/test/src/ble_att_clt_test.c
index ab89e9d,0000000..14d66f6
mode 100644,000000..100644
--- a/net/nimble/host/test/src/ble_att_clt_test.c
+++ b/net/nimble/host/test/src/ble_att_clt_test.c
@@@ -1,536 -1,0 +1,567 @@@
+/**
+ * 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_hs_test.h"
+#include "ble_hs_test_util.h"
+
+/**
+ * @return The handle of the new test connection.
+ */
+static uint16_t
+ble_att_clt_test_misc_init(void)
+{
+ ble_hs_test_util_init();
+ ble_hs_test_util_create_conn(2, ((uint8_t[]){2,3,4,5,6,7,8,9}), NULL,
+ NULL);
+ return 2;
+}
+
+static void
+ble_att_clt_test_misc_verify_tx_write(uint16_t handle_id, void *value,
+ int value_len, int is_req)
+{
+ struct ble_att_write_req req;
+ struct os_mbuf *om;
+
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+
+ if (is_req) {
+ ble_att_write_req_parse(om->om_data, om->om_len, &req);
+ } else {
+ ble_att_write_cmd_parse(om->om_data, om->om_len, &req);
+ }
+
+ TEST_ASSERT(req.bawq_handle == handle_id);
+ TEST_ASSERT(om->om_len == BLE_ATT_WRITE_REQ_BASE_SZ + value_len);
+ TEST_ASSERT(memcmp(om->om_data + BLE_ATT_WRITE_REQ_BASE_SZ, value,
+ value_len) == 0);
+}
+
+static void
+ble_att_clt_test_tx_write_req_or_cmd(uint16_t conn_handle,
+ struct ble_att_write_req *req,
+ void *value, int value_len, int is_req)
+{
+ struct os_mbuf *om;
+ int rc;
+
+ 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);
+ } else {
+ rc = ble_att_clt_tx_write_cmd(conn_handle, req, om);
+ }
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_tx_find_info)
+{
+ struct ble_att_find_info_req req;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Success. */
+ req.bafq_start_handle = 1;
+ req.bafq_end_handle = 0xffff;
+ rc = ble_att_clt_tx_find_info(conn_handle, &req);
+ TEST_ASSERT(rc == 0);
+
+ /*** Error: start handle of 0. */
+ req.bafq_start_handle = 0;
+ req.bafq_end_handle = 0xffff;
+ rc = ble_att_clt_tx_find_info(conn_handle, &req);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+ /*** Error: start handle greater than end handle. */
+ req.bafq_start_handle = 500;
+ req.bafq_end_handle = 499;
+ rc = ble_att_clt_tx_find_info(conn_handle, &req);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+
+ /*** Success; start and end handles equal. */
+ req.bafq_start_handle = 500;
+ req.bafq_end_handle = 500;
+ rc = ble_att_clt_tx_find_info(conn_handle, &req);
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_rx_find_info)
+{
+ struct ble_att_find_info_rsp rsp;
+ uint16_t conn_handle;
+ uint8_t buf[1024];
+ uint8_t uuid128_1[16] = { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
+ int off;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** One 128-bit UUID. */
+ /* Receive response with attribute mapping. */
+ off = 0;
+ rsp.bafp_format = BLE_ATT_FIND_INFO_RSP_FORMAT_128BIT;
+ ble_att_find_info_rsp_write(buf + off, sizeof buf - off, &rsp);
+ off += BLE_ATT_FIND_INFO_RSP_BASE_SZ;
+
+ htole16(buf + off, 1);
+ off += 2;
+ memcpy(buf + off, uuid128_1, 16);
+ off += 16;
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ /*** One 16-bit UUID. */
+ /* Receive response with attribute mapping. */
+ off = 0;
+ rsp.bafp_format = BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT;
+ ble_att_find_info_rsp_write(buf + off, sizeof buf - off, &rsp);
+ off += BLE_ATT_FIND_INFO_RSP_BASE_SZ;
+
+ htole16(buf + off, 2);
+ off += 2;
+ htole16(buf + off, 0x000f);
+ off += 2;
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+
+ /*** Two 16-bit UUIDs. */
+ /* Receive response with attribute mappings. */
+ off = 0;
+ rsp.bafp_format = BLE_ATT_FIND_INFO_RSP_FORMAT_16BIT;
+ ble_att_find_info_rsp_write(buf + off, sizeof buf - off, &rsp);
+ off += BLE_ATT_FIND_INFO_RSP_BASE_SZ;
+
+ htole16(buf + off, 3);
+ off += 2;
+ htole16(buf + off, 0x0010);
+ off += 2;
+
+ htole16(buf + off, 4);
+ off += 2;
+ htole16(buf + off, 0x0011);
+ off += 2;
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, off);
+ TEST_ASSERT(rc == 0);
+}
+
+static void
+ble_att_clt_test_case_tx_write_req_or_cmd(int is_req)
+{
+ struct ble_att_write_req req;
+ uint16_t conn_handle;
+ uint8_t value300[500] = { 0 };
+ uint8_t value5[5] = { 6, 7, 54, 34, 8 };
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** 5-byte write. */
+ req.bawq_handle = 0x1234;
+ ble_att_clt_test_tx_write_req_or_cmd(conn_handle, &req, value5,
+ sizeof value5, is_req);
+ ble_hs_test_util_tx_all();
+ ble_att_clt_test_misc_verify_tx_write(0x1234, value5, sizeof value5,
+ is_req);
+
+ /*** Overlong write; verify command truncated to ATT MTU. */
+ req.bawq_handle = 0xab83;
+ ble_att_clt_test_tx_write_req_or_cmd(conn_handle, &req, value300,
+ sizeof value300, is_req);
+ ble_hs_test_util_tx_all();
+ ble_att_clt_test_misc_verify_tx_write(0xab83, value300,
+ BLE_ATT_MTU_DFLT - 3, is_req);
+}
+
+static void
+ble_att_clt_test_misc_prep_good(uint16_t handle, uint16_t offset,
+ uint8_t *attr_data, uint16_t attr_data_len)
+{
+ struct ble_att_prep_write_cmd req;
+ struct os_mbuf *om;
+ uint16_t conn_handle;
+ int rc;
+ int i;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ 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);
+ TEST_ASSERT(rc == 0);
+
+ ble_hs_test_util_tx_all();
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+ TEST_ASSERT(om->om_len == BLE_ATT_PREP_WRITE_CMD_BASE_SZ + attr_data_len);
+
+ ble_att_prep_write_req_parse(om->om_data, om->om_len, &req);
+ TEST_ASSERT(req.bapc_handle == handle);
+ TEST_ASSERT(req.bapc_offset == offset);
+ for (i = 0; i < attr_data_len; i++) {
+ TEST_ASSERT(om->om_data[BLE_ATT_PREP_WRITE_CMD_BASE_SZ + i] ==
+ attr_data[i]);
+ }
+}
+
+static void
+ble_att_clt_test_misc_exec_good(uint8_t flags)
+{
+ struct ble_att_exec_write_req req;
+ struct os_mbuf *om;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ req.baeq_flags = flags;
+ rc = ble_att_clt_tx_exec_write(conn_handle, &req);
+ TEST_ASSERT(rc == 0);
+
+ ble_hs_test_util_tx_all();
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+ TEST_ASSERT(om->om_len == BLE_ATT_EXEC_WRITE_REQ_SZ);
+
+ ble_att_exec_write_req_parse(om->om_data, om->om_len, &req);
+ TEST_ASSERT(req.baeq_flags == flags);
+}
+
+static void
+ble_att_clt_test_misc_prep_bad(uint16_t handle, uint16_t offset,
+ uint8_t *attr_data, uint16_t attr_data_len,
+ int status)
+{
+ struct ble_att_prep_write_cmd req;
+ struct os_mbuf *om;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ om = ble_hs_test_util_om_from_flat(attr_data, attr_data_len);
+
+ req.bapc_handle = handle;
+ req.bapc_offset = offset;
+ rc = ble_att_clt_tx_prep_write(conn_handle, &req, om);
+ TEST_ASSERT(rc == status);
+}
+
++static void
++ble_att_clt_test_misc_tx_mtu(uint16_t conn_handle, uint16_t mtu, int status)
++{
++ struct ble_att_mtu_cmd req;
++ int rc;
++
++ req.bamc_mtu = mtu;
++ rc = ble_att_clt_tx_mtu(conn_handle, &req);
++ TEST_ASSERT(rc == status);
++
++ if (rc == 0) {
++ ble_hs_test_util_verify_tx_mtu_cmd(1, mtu);
++ }
++}
++
++
+TEST_CASE(ble_att_clt_test_tx_write)
+{
+ ble_att_clt_test_case_tx_write_req_or_cmd(0);
+ ble_att_clt_test_case_tx_write_req_or_cmd(1);
+}
+
+TEST_CASE(ble_att_clt_test_tx_read)
+{
+ struct ble_att_read_req req;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Success. */
+ req.barq_handle = 1;
+ rc = ble_att_clt_tx_read(conn_handle, &req);
+ TEST_ASSERT(rc == 0);
+
+ /*** Error: handle of 0. */
+ req.barq_handle = 0;
+ rc = ble_att_clt_tx_read(conn_handle, &req);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+}
+
+TEST_CASE(ble_att_clt_test_rx_read)
+{
+ uint16_t conn_handle;
+ uint8_t buf[1024];
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Basic success. */
+ buf[0] = BLE_ATT_OP_READ_RSP;
+ buf[1] = 0;
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 2);
+ TEST_ASSERT(rc == 0);
+
+ /*** Larger response. */
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 20);
+ TEST_ASSERT(rc == 0);
+
+ /*** Zero-length response. */
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 1);
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_tx_read_blob)
+{
+ struct ble_att_read_blob_req req;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Success. */
+ req.babq_handle = 1;
+ req.babq_offset = 0;
+ rc = ble_att_clt_tx_read_blob(conn_handle, &req);
+ TEST_ASSERT(rc == 0);
+
+ /*** Error: handle of 0. */
+ req.babq_handle = 0;
+ req.babq_offset = 0;
+ rc = ble_att_clt_tx_read_blob(conn_handle, &req);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+}
+
+TEST_CASE(ble_att_clt_test_rx_read_blob)
+{
+ uint16_t conn_handle;
+ uint8_t buf[1024];
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Basic success. */
+ buf[0] = BLE_ATT_OP_READ_BLOB_RSP;
+ buf[1] = 0;
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 2);
+ TEST_ASSERT(rc == 0);
+
+ /*** Larger response. */
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 20);
+ TEST_ASSERT(rc == 0);
+
+ /*** Zero-length response. */
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(conn_handle, BLE_L2CAP_CID_ATT,
+ buf, 1);
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_tx_read_mult)
+{
+ struct os_mbuf *om;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Success. */
+ rc = ble_att_clt_tx_read_mult(conn_handle, ((uint16_t[]){ 1, 2 }), 2);
+ TEST_ASSERT(rc == 0);
+
+ ble_hs_test_util_tx_all();
+ om = ble_hs_test_util_prev_tx_dequeue_pullup();
+ TEST_ASSERT_FATAL(om != NULL);
+ TEST_ASSERT(om->om_len == BLE_ATT_READ_MULT_REQ_BASE_SZ + 4);
+
+ ble_att_read_mult_req_parse(om->om_data, om->om_len);
+ TEST_ASSERT(le16toh(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ) == 1);
+ TEST_ASSERT(le16toh(om->om_data + BLE_ATT_READ_MULT_REQ_BASE_SZ + 2) == 2);
+
+ /*** Error: no handles. */
+ rc = ble_att_clt_tx_read_mult(conn_handle, NULL, 0);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+}
+
+TEST_CASE(ble_att_clt_test_rx_read_mult)
+{
+ uint16_t conn_handle;
+ uint8_t buf[1024];
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Basic success. */
+ ble_att_read_mult_rsp_write(buf, sizeof buf);
+ htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 0, 12);
+
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(
+ conn_handle, BLE_L2CAP_CID_ATT, buf,
+ BLE_ATT_READ_MULT_RSP_BASE_SZ + 2);
+ TEST_ASSERT(rc == 0);
+
+ /*** Larger response. */
+ htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 0, 12);
+ htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 2, 43);
+ htole16(buf + BLE_ATT_READ_MULT_RSP_BASE_SZ + 4, 91);
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(
+ conn_handle, BLE_L2CAP_CID_ATT, buf,
+ BLE_ATT_READ_MULT_RSP_BASE_SZ + 6);
+ TEST_ASSERT(rc == 0);
+
+ /*** Zero-length response. */
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(
+ conn_handle, BLE_L2CAP_CID_ATT, buf,
+ BLE_ATT_READ_MULT_RSP_BASE_SZ + 0);
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_tx_prep_write)
+{
+ uint8_t attr_data[512];
+ int i;
+
+ for (i = 0; i < sizeof attr_data; i++) {
+ attr_data[i] = i;
+ }
+
+ /*** Success. */
+ ble_att_clt_test_misc_prep_good(123, 0, attr_data, 16);
+ ble_att_clt_test_misc_prep_good(5432, 100, attr_data, 2);
+ ble_att_clt_test_misc_prep_good(0x1234, 400, attr_data, 0);
+ ble_att_clt_test_misc_prep_good(5432, 0, attr_data,
+ BLE_ATT_MTU_DFLT -
+ BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
+ ble_att_clt_test_misc_prep_good(0x1234, 507, attr_data, 5);
+
+ /*** Error: handle of 0. */
+ ble_att_clt_test_misc_prep_bad(0, 0, attr_data, 16, BLE_HS_EINVAL);
+
+ /*** Error: offset + length greater than maximum attribute size. */
+ ble_att_clt_test_misc_prep_bad(1, 507, attr_data, 6, BLE_HS_EINVAL);
+
+ /*** Error: packet larger than MTU. */
+ ble_att_clt_test_misc_prep_bad(1, 0, attr_data,
+ BLE_ATT_MTU_DFLT -
+ BLE_ATT_PREP_WRITE_CMD_BASE_SZ + 1,
+ BLE_HS_EINVAL);
+}
+
+TEST_CASE(ble_att_clt_test_rx_prep_write)
+{
+ struct ble_att_prep_write_cmd rsp;
+ uint16_t conn_handle;
+ uint8_t buf[1024];
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Basic success. */
+ rsp.bapc_handle = 0x1234;
+ rsp.bapc_offset = 0;
+ ble_att_prep_write_rsp_write(buf, sizeof buf, &rsp);
+ memset(buf + BLE_ATT_PREP_WRITE_CMD_BASE_SZ, 1, 5);
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(
+ conn_handle, BLE_L2CAP_CID_ATT, buf,
+ BLE_ATT_PREP_WRITE_CMD_BASE_SZ + 5);
+ TEST_ASSERT(rc == 0);
+
+ /*** 0-length write. */
+ rsp.bapc_handle = 0x1234;
+ rsp.bapc_offset = 0;
+ ble_att_prep_write_rsp_write(buf, sizeof buf, &rsp);
+ rc = ble_hs_test_util_l2cap_rx_payload_flat(
+ conn_handle, BLE_L2CAP_CID_ATT, buf, BLE_ATT_PREP_WRITE_CMD_BASE_SZ);
+ TEST_ASSERT(rc == 0);
+}
+
+TEST_CASE(ble_att_clt_test_tx_exec_write)
+{
+ struct ble_att_exec_write_req req;
+ uint16_t conn_handle;
+ int rc;
+
+ conn_handle = ble_att_clt_test_misc_init();
+
+ /*** Success. */
+ ble_att_clt_test_misc_exec_good(0);
+ ble_att_clt_test_misc_exec_good(BLE_ATT_EXEC_WRITE_F_CONFIRM);
+
+ /*** Error: invalid flags value. */
+ req.baeq_flags = 0x02;
+ rc = ble_att_clt_tx_exec_write(conn_handle, &req);
+ TEST_ASSERT(rc == BLE_HS_EINVAL);
+}
+
++TEST_CASE(ble_att_clt_test_tx_mtu)
++{
++ uint16_t conn_handle;
++
++ conn_handle = ble_att_clt_test_misc_init();
++
++ /*** Success. */
++ ble_att_clt_test_misc_tx_mtu(conn_handle, 50, 0);
++
++ /*** Error: repeated sends. */
++ ble_att_clt_test_misc_tx_mtu(conn_handle, 50, BLE_HS_EALREADY);
++ ble_att_clt_test_misc_tx_mtu(conn_handle, 60, BLE_HS_EALREADY);
++}
++
+TEST_SUITE(ble_att_clt_suite)
+{
+ tu_suite_set_post_test_cb(ble_hs_test_util_post_test, NULL);
+
+ ble_att_clt_test_tx_find_info();
+ ble_att_clt_test_rx_find_info();
+ ble_att_clt_test_tx_read();
+ ble_att_clt_test_rx_read();
+ ble_att_clt_test_tx_read_blob();
+ ble_att_clt_test_rx_read_blob();
+ ble_att_clt_test_tx_read_mult();
+ ble_att_clt_test_rx_read_mult();
+ ble_att_clt_test_tx_write();
+ ble_att_clt_test_tx_prep_write();
+ ble_att_clt_test_rx_prep_write();
+ ble_att_clt_test_tx_exec_write();
++ ble_att_clt_test_tx_mtu();
+}
+
+int
+ble_att_clt_test_all(void)
+{
+ ble_att_clt_suite();
+
+ return tu_any_failed;
+}