http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h ---------------------------------------------------------------------- diff --cc net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h index 415b320,7b6a817..9d5b7c9 --- a/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h +++ b/net/nimble/transport/uart/include/transport/uart/ble_hci_uart.h @@@ -1,19 -1,22 +1,25 @@@ ++/** ++ * Licensed to the Apache Software Foundation (ASF) under one ++ * or more contributor license agreements. See the NOTICE file ++ * distributed with this work for additional information ++ * regarding copyright ownership. The ASF licenses this file ++ * to you under the Apache License, Version 2.0 (the ++ * "License"); you may not use this file except in compliance ++ * with the License. You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, ++ * software distributed under the License is distributed on an ++ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ++ * KIND, either express or implied. See the License for the ++ * specific language governing permissions and limitations ++ * under the License. ++ */ ++ #ifndef H_BLE_HCI_UART_ #define H_BLE_HCI_UART_ --struct ble_hci_uart_cfg { -- uint32_t baud; - uint16_t num_evt_bufs; - uint16_t num_evt_hi_bufs; - uint16_t num_evt_lo_bufs; -- uint16_t evt_buf_sz; - uint16_t num_acl_bufs; - uint16_t num_msys_bufs; -- uint8_t uart_port; -- uint8_t flow_ctrl; -- uint8_t data_bits; -- uint8_t stop_bits; -- uint8_t parity; --}; -- --extern const struct ble_hci_uart_cfg ble_hci_uart_cfg_dflt; -- -int ble_hci_uart_init(const struct ble_hci_uart_cfg *cfg); +int ble_hci_uart_init(void); #endif
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/transport/uart/pkg.yml ---------------------------------------------------------------------- diff --cc net/nimble/transport/uart/pkg.yml index 56f0cda,cce429c..252feba --- a/net/nimble/transport/uart/pkg.yml +++ b/net/nimble/transport/uart/pkg.yml @@@ -32,35 -32,3 +32,41 @@@ pkg.deps pkg.apis: - ble_transport + +pkg.syscfg_defs: ++ BLE_HCI_EVT_BUF_SIZE: ++ description: 'TBD' ++ # The largest event the nimble controller will send is 70 bytes. ++ value: 70 + BLE_HCI_EVT_HI_BUF_COUNT: + description: 'TBD' - value: 8 ++ value: 8 + BLE_HCI_EVT_LO_BUF_COUNT: + description: 'TBD' - value: 0 ++ value: 8 ++ BLE_HCI_ACL_BUF_COUNT: ++ description: 'TBD' ++ value: 4 + - BLE_HCI_UART_BUF_SIZE: ++ BLE_HCI_ACL_OUT_COUNT: + description: 'TBD' - value: 260 ++ value: 4 + + BLE_HCI_UART_PORT: + description: 'TBD' + value: 0 + BLE_HCI_UART_BAUD: + description: 'TBD' + value: 1000000 + BLE_HCI_UART_DATA_BITS: + description: 'TBD' + value: 8 + BLE_HCI_UART_STOP_BITS: + description: 'TBD' + value: 1 + BLE_HCI_UART_PARITY: + description: 'TBD' + value: HAL_UART_PARITY_NONE + BLE_HCI_UART_FLOW_CTRL: + description: 'TBD' + value: HAL_UART_FLOW_CTL_RTS_CTS - http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/net/nimble/transport/uart/src/ble_hci_uart.c ---------------------------------------------------------------------- diff --cc net/nimble/transport/uart/src/ble_hci_uart.c index e7e07a1,663c817..d660e4c --- a/net/nimble/transport/uart/src/ble_hci_uart.c +++ b/net/nimble/transport/uart/src/ble_hci_uart.c @@@ -36,21 -36,50 +36,38 @@@ #include "transport/uart/ble_hci_uart.h" +#define BLE_HCI_UART_EVT_COUNT \ + (MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT) + MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT)) + +/*** + * NOTE: + * The UART HCI transport doesn't use event buffer priorities. All incoming + * and outgoing events and commands use buffers from the same pool. + */ + + /* XXX: for now, define this here */ + #ifdef FEATURE_BLE_DEVICE + extern void ble_ll_data_buffer_overflow(void); + extern void ble_ll_hw_error(uint8_t err); + + static const uint8_t ble_hci_uart_reset_cmd[4] = { 0x01, 0x03, 0x0C, 0x00 }; + #endif + + /*** + * NOTES: - * The UART HCI transport doesn't use event buffer priorities. All incoming - * and outgoing events use buffers from the same pool. - * + * The "skip" definitions are here so that when buffers cannot be allocated, + * the command or acl packets are simply skipped so that the HCI interface + * does not lose synchronization and resets dont (necessarily) occur. + */ #define BLE_HCI_UART_H4_NONE 0x00 #define BLE_HCI_UART_H4_CMD 0x01 #define BLE_HCI_UART_H4_ACL 0x02 #define BLE_HCI_UART_H4_SCO 0x03 #define BLE_HCI_UART_H4_EVT 0x04 + #define BLE_HCI_UART_H4_SYNC_LOSS 0x80 + #define BLE_HCI_UART_H4_SKIP_CMD 0x81 + #define BLE_HCI_UART_H4_SKIP_ACL 0x82 -/** Default configuration. */ -const struct ble_hci_uart_cfg ble_hci_uart_cfg_dflt = { - .uart_port = 0, - .baud = 1000000, - .flow_ctrl = HAL_UART_FLOW_CTL_RTS_CTS, - .data_bits = 8, - .stop_bits = 1, - .parity = HAL_UART_PARITY_NONE, - - .num_evt_hi_bufs = 8, - .num_evt_lo_bufs = 8, - - /* The largest event the nimble controller will send is 70 bytes. */ - .evt_buf_sz = 70, - - .num_acl_bufs = 4 -}; - static ble_hci_trans_rx_cmd_fn *ble_hci_uart_rx_cmd_cb; static void *ble_hci_uart_rx_cmd_arg; @@@ -107,6 -147,29 +135,28 @@@ static struct STAILQ_HEAD(, ble_hci_uart_pkt) tx_pkts; /* Packet queue to send to UART */ } ble_hci_uart_state; -static struct ble_hci_uart_cfg ble_hci_uart_cfg; + static uint16_t ble_hci_uart_max_acl_datalen; + + /** + * Allocates a buffer (mbuf) for ACL operation. + * + * @return The allocated buffer on success; + * NULL on buffer exhaustion. + */ + static struct os_mbuf * + ble_hci_trans_acl_buf_alloc(void) + { + struct os_mbuf *m; + + /* + * XXX: note that for host only there would be no need to allocate + * a user header. Address this later. + */ + m = os_mbuf_get_pkthdr(&ble_hci_uart_acl_mbuf_pool, + sizeof(struct ble_mbuf_hdr)); + return m; + } + static int ble_hci_uart_acl_tx(struct os_mbuf *om) { @@@ -248,6 -311,26 +298,26 @@@ ble_hci_uart_tx_char(void *arg return rc; } + #ifdef FEATURE_BLE_DEVICE + /** - * HCI uart sync loss. ++ * HCI uart sync lost. + * + * This occurs when the controller receives an invalid packet type or a length + * field that is out of range. The controller needs to send a HW error to the + * host and wait to find a LL reset command. + */ + static void + ble_hci_uart_sync_lost(void) + { + ble_hci_uart_state.rx_cmd.len = 0; + ble_hci_uart_state.rx_cmd.cur = 0; + ble_hci_uart_state.rx_cmd.data = + ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_CMD); + ble_ll_hw_error(BLE_HW_ERR_HCI_SYNC_LOSS); + ble_hci_uart_state.rx_type = BLE_HCI_UART_H4_SYNC_LOSS; + } + #endif + /** * @return The type of packet to follow success; * -1 if there is no valid packet to receive. @@@ -682,26 -969,86 +953,91 @@@ ble_hci_trans_reset(void * A BLE_ERR_[...] error code on failure. */ int -ble_hci_uart_init(const struct ble_hci_uart_cfg *cfg) +ble_hci_uart_init(void) { - int rc; + int acl_block_size; + int rc; ble_hci_uart_free_mem(); - ble_hci_uart_cfg = *cfg; + /* Create memory pool of HCI command / event buffers */ + rc = mem_malloc_mempool(&ble_hci_uart_evt_pool, + BLE_HCI_UART_EVT_COUNT, + MYNEWT_VAL(BLE_HCI_UART_BUF_SIZE), + "ble_hci_uart_evt_pool", + &ble_hci_uart_evt_buf); + + /* + * XXX: For now, we will keep the ACL buffer size such that it can + * accommodate BLE_MBUF_PAYLOAD_SIZE. It should be possible to make this + * user defined but more testing would need to be done in that case. The + * MBUF payload size must accommodate the HCI data header size plus the + * maximum ACL data packet length. + * + * XXX: Should the max acl data length be part of config? + */ + acl_block_size = BLE_MBUF_PAYLOAD_SIZE + BLE_MBUF_MEMBLOCK_OVERHEAD; + acl_block_size = OS_ALIGN(acl_block_size, OS_ALIGNMENT); + ble_hci_uart_max_acl_datalen = BLE_MBUF_PAYLOAD_SIZE - BLE_HCI_DATA_HDR_SZ; + rc = mem_malloc_mempool(&ble_hci_uart_acl_pool, - cfg->num_acl_bufs, ++ MYNEWT_VAL(BLE_HCI_ACL_BUF_COUNT), + acl_block_size, + "ble_hci_uart_acl_pool", + &ble_hci_uart_acl_buf); if (rc != 0) { rc = ble_err_from_os(rc); goto err; } - /* Create memory pool of packet list nodes. */ + rc = os_mbuf_pool_init(&ble_hci_uart_acl_mbuf_pool, &ble_hci_uart_acl_pool, - acl_block_size, cfg->num_acl_bufs); ++ acl_block_size, MYNEWT_VAL(BLE_HCI_ACL_BUF_COUNT)); + assert(rc == 0); + + /* + * Create memory pool of HCI command buffers. NOTE: we currently dont + * allow this to be configured. The controller will only allow one + * outstanding command. We decided to keep this a pool in case we allow + * allow the controller to handle more than one outstanding command. + */ + rc = mem_malloc_mempool(&ble_hci_uart_cmd_pool, + 1, + BLE_HCI_TRANS_CMD_SZ, + "ble_hci_uart_cmd_pool", + &ble_hci_uart_cmd_buf); + if (rc != 0) { + rc = ble_err_from_os(rc); + goto err; + } + + rc = mem_malloc_mempool(&ble_hci_uart_evt_hi_pool, - cfg->num_evt_hi_bufs, - cfg->evt_buf_sz, ++ MYNEWT_VAL(BLE_HCI_EVT_HI_BUF_COUNT), ++ MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + "ble_hci_uart_evt_hi_pool", + &ble_hci_uart_evt_hi_buf); + if (rc != 0) { + rc = ble_err_from_os(rc); + goto err; + } + + rc = mem_malloc_mempool(&ble_hci_uart_evt_lo_pool, - cfg->num_evt_lo_bufs, - cfg->evt_buf_sz, ++ MYNEWT_VAL(BLE_HCI_EVT_LO_BUF_COUNT), ++ MYNEWT_VAL(BLE_HCI_EVT_BUF_SIZE), + "ble_hci_uart_evt_lo_pool", + &ble_hci_uart_evt_lo_buf); + if (rc != 0) { + rc = ble_err_from_os(rc); + goto err; + } + + /* + * Create memory pool of packet list nodes. NOTE: the number of these + * buffers should be, at least, the total number of event buffers (hi + * and lo), the number of command buffers (currently 1) and the total + * number of buffers that the controller could possibly hand to the host. + */ rc = mem_malloc_mempool(&ble_hci_uart_pkt_pool, - BLE_HCI_UART_EVT_COUNT, - cfg->num_evt_hi_bufs + cfg->num_evt_lo_bufs + 1 + - cfg->num_msys_bufs, ++ BLE_HCI_UART_EVT_COUNT + 1 + ++ MYNEWT_VAL(BLE_HCI_ACL_OUT_COUNT), sizeof (struct ble_hci_uart_pkt), "ble_hci_uart_pkt_pool", &ble_hci_uart_pkt_buf); http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/config/include/config/config.h ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/config/src/config.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/config/src/config_nmgr.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/log/include/log/log.h ---------------------------------------------------------------------- diff --cc sys/log/include/log/log.h index 1dc2a7e,80d61e6..48deb0b --- a/sys/log/include/log/log.h +++ b/sys/log/include/log/log.h @@@ -178,17 -197,13 +193,13 @@@ int log_walk(struct log *log, log_walk_ int log_flush(struct log *log); int log_rtr_erase(struct log *log, void *arg); - - /* Handler exports */ - int log_cbmem_handler_init(struct log_handler *, struct cbmem *); - int log_console_handler_init(struct log_handler *); - struct fcb; - int log_fcb_handler_init(struct log_handler *, struct fcb *, - uint8_t entries); + extern const struct log_handler log_console_handler; + extern const struct log_handler log_cbmem_handler; + extern const struct log_handler log_fcb_handler; /* Private */ -#ifdef NEWTMGR_PRESENT +#if MYNEWT_VAL(LOG_NEWTMGR) int log_nmgr_register_group(void); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/log/src/log.c ---------------------------------------------------------------------- diff --cc sys/log/src/log.c index eb841e7,7bdc0fc..6160626 --- a/sys/log/src/log.c +++ b/sys/log/src/log.c @@@ -22,16 -24,17 +22,18 @@@ #include <stdio.h> #include <stdarg.h> -#ifdef SHELL_PRESENT -#include <shell/shell.h> +#include "sysinit/sysinit.h" +#include "syscfg/syscfg.h" +#include "os/os.h" +#include "util/cbmem.h" +#include "log/log.h" + +#if MYNEWT_VAL(LOG_CLI) +#include "shell/shell.h" #endif + struct log_info g_log_info; + static STAILQ_HEAD(, log) g_log_list = STAILQ_HEAD_INITIALIZER(g_log_list); static uint8_t log_inited; @@@ -43,19 -46,25 +45,25 @@@ struct shell_cmd g_shell_log_cmd = }; #endif + char *log_modules[LOG_MODULE_MAX]; + -int +void log_init(void) { -#ifdef NEWTMGR_PRESENT int rc; -#endif + + (void)rc; if (log_inited) { - return (0); + return; } log_inited = 1; + g_log_info.li_version = LOG_VERSION_V2; + g_log_info.li_index = 0; + g_log_info.li_timestamp = 0; + -#ifdef SHELL_PRESENT +#if MYNEWT_VAL(LOG_CLI) shell_cmd_register(&g_shell_log_cmd); #endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/log/src/log_fcb.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/log/src/log_nmgr.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/log/test/src/log_test.c ---------------------------------------------------------------------- diff --cc sys/log/test/src/log_test.c index 6f83c57,0000000..b0f71ad mode 100644,000000..100644 --- a/sys/log/test/src/log_test.c +++ b/sys/log/test/src/log_test.c @@@ -1,163 -1,0 +1,160 @@@ +/** + * 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 "syscfg/syscfg.h" +#include "os/os.h" +#include "testutil/testutil.h" +#include "fcb/fcb.h" +#include "log/log.h" + +static struct flash_area fcb_areas[] = { + [0] = { + .fa_off = 0x00000000, + .fa_size = 16 * 1024 + }, + [1] = { + .fa_off = 0x00004000, + .fa_size = 16 * 1024 + } +}; - static struct log_handler log_fcb_handler; +static struct fcb log_fcb; +static struct log my_log; + +static char *str_logs[] = { + "testdata", + "1testdata2", + NULL +}; +static int str_idx = 0; +static int str_max_idx = 0; + +TEST_CASE(log_setup_fcb) +{ + int rc; + int i; + + log_fcb.f_sectors = fcb_areas; + log_fcb.f_sector_cnt = sizeof(fcb_areas) / sizeof(fcb_areas[0]); + log_fcb.f_magic = 0x7EADBADF; + log_fcb.f_version = 0; + + for (i = 0; i < log_fcb.f_sector_cnt; i++) { + rc = flash_area_erase(&fcb_areas[i], 0, fcb_areas[i].fa_size); + TEST_ASSERT(rc == 0); + } + rc = fcb_init(&log_fcb); + TEST_ASSERT(rc == 0); - rc = log_fcb_handler_init(&log_fcb_handler, &log_fcb, 0); - TEST_ASSERT(rc == 0); + - log_register("log", &my_log, &log_fcb_handler); ++ log_register("log", &my_log, &log_fcb_handler, &log_fcb); +} + +TEST_CASE(log_append_fcb) +{ + char *str; + + while (1) { + str = str_logs[str_max_idx]; + if (!str) { + break; + } + log_printf(&my_log, 0, 0, str, strlen(str)); + str_max_idx++; + } +} + +static int +log_test_walk1(struct log *log, void *arg, void *dptr, uint16_t len) +{ + int rc; + struct log_entry_hdr ueh; + char data[128]; + int dlen; + + TEST_ASSERT(str_idx < str_max_idx); + + rc = log_read(log, dptr, &ueh, 0, sizeof(ueh)); + TEST_ASSERT(rc == sizeof(ueh)); + + dlen = len - sizeof(ueh); + TEST_ASSERT(dlen < sizeof(data)); + + rc = log_read(log, dptr, data, sizeof(ueh), dlen); + TEST_ASSERT(rc == dlen); + + data[rc] = '\0'; + + TEST_ASSERT(strlen(str_logs[str_idx]) == dlen); + TEST_ASSERT(!memcmp(str_logs[str_idx], data, dlen)); + str_idx++; + + return 0; +} + +TEST_CASE(log_walk_fcb) +{ + int rc; + + str_idx = 0; + + rc = log_walk(&my_log, log_test_walk1, NULL); + TEST_ASSERT(rc == 0); +} + +static int +log_test_walk2(struct log *log, void *arg, void *dptr, uint16_t len) +{ + TEST_ASSERT(0); + return 0; +} + +TEST_CASE(log_flush_fcb) +{ + int rc; + + rc = log_flush(&my_log); + TEST_ASSERT(rc == 0); + + rc = log_walk(&my_log, log_test_walk2, NULL); + TEST_ASSERT(rc == 0); +} + +TEST_SUITE(log_test_all) +{ + log_setup_fcb(); + log_append_fcb(); + log_walk_fcb(); + log_flush_fcb(); +} + +#if MYNEWT_VAL(SELFTEST) + +int +main(int argc, char **argv) +{ + tu_config.tc_print_results = 1; + tu_init(); + + log_init(); + log_test_all(); + + return tu_any_failed; +} + +#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/mn_socket/test/src/mn_sock_test.c ---------------------------------------------------------------------- diff --cc sys/mn_socket/test/src/mn_sock_test.c index 4babb33,0000000..a1e7177 mode 100644,000000..100644 --- a/sys/mn_socket/test/src/mn_sock_test.c +++ b/sys/mn_socket/test/src/mn_sock_test.c @@@ -1,83 -1,0 +1,895 @@@ +/** + * 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 "syscfg/syscfg.h" +#include "os/os.h" +#include "testutil/testutil.h" + +#include "mn_socket/mn_socket.h" ++#include "mn_socket/arch/sim/native_sock.h" ++ ++#define TEST_STACK_SIZE 4096 ++#define TEST_PRIO 22 ++static os_stack_t test_stack[OS_STACK_ALIGN(TEST_STACK_SIZE)]; ++static struct os_task test_task; ++ ++static struct os_sem test_sem; ++ ++#define MB_CNT 10 ++#define MB_SZ 512 ++static uint8_t test_mbuf_area[MB_CNT * MB_SZ]; ++static struct os_mempool test_mbuf_mpool; ++static struct os_mbuf_pool test_mbuf_pool; + +TEST_CASE(inet_pton_test) +{ + int rc; + uint8_t addr[8]; + struct test_vec { + char *str; + uint8_t cmp[4]; + }; + struct test_vec ok_vec[] = { + { "1.1.1.1", { 1, 1, 1, 1 } }, + { "1.2.3.4", { 1, 2, 3, 4 } }, + { "010.001.255.255", { 10, 1, 255, 255 } }, + { "001.002.005.006", { 1, 2, 5, 6 } } + }; + struct test_vec invalid_vec[] = { + { "a.b.c.d" }, + { "1a.b3.4.2" }, + { "1.3.4.2a" }, + { "1111.3.4.2" }, + { "3.256.1.0" }, + }; + int i; + + for (i = 0; i < sizeof(ok_vec) / sizeof(ok_vec[0]); i++) { + memset(addr, 0xa5, sizeof(addr)); + rc = mn_inet_pton(MN_PF_INET, ok_vec[i].str, addr); + TEST_ASSERT(rc == 1); + TEST_ASSERT(!memcmp(ok_vec[i].cmp, addr, sizeof(uint32_t))); + TEST_ASSERT(addr[5] == 0xa5); + } + for (i = 0; i < sizeof(invalid_vec) / sizeof(invalid_vec[0]); i++) { + rc = mn_inet_pton(MN_PF_INET, invalid_vec[i].str, addr); + TEST_ASSERT(rc == 0); + } +} + ++TEST_CASE(inet_ntop_test) ++{ ++ const char *rstr; ++ char addr[48]; ++ struct test_vec { ++ char *str; ++ uint8_t cmp[4]; ++ }; ++ struct test_vec ok_vec[] = { ++ { "1.1.1.1", { 1, 1, 1, 1 } }, ++ { "1.2.3.4", { 1, 2, 3, 4 } }, ++ { "255.1.255.255", { 255, 1, 255, 255 } }, ++ { "1.2.5.6", { 1, 2, 5, 6 } } ++ }; ++ int i; ++ ++ for (i = 0; i < sizeof(ok_vec) / sizeof(ok_vec[0]); i++) { ++ memset(addr, 0xa5, sizeof(addr)); ++ rstr = mn_inet_ntop(MN_PF_INET, ok_vec[i].cmp, addr, sizeof(addr)); ++ TEST_ASSERT(rstr); ++ TEST_ASSERT(!strcmp(ok_vec[i].str, addr)); ++ } ++ rstr = mn_inet_ntop(MN_PF_INET, ok_vec[0].cmp, addr, 1); ++ TEST_ASSERT(rstr == NULL); ++ ++ /* does not have space to null terminate */ ++ rstr = mn_inet_ntop(MN_PF_INET, ok_vec[0].cmp, addr, 7); ++ TEST_ASSERT(rstr == NULL); ++} ++ ++void ++sock_open_close(void) ++{ ++ struct mn_socket *sock; ++ int rc; ++ ++ rc = mn_socket(&sock, MN_PF_INET, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(sock); ++ TEST_ASSERT(rc == 0); ++ mn_close(sock); ++ ++ rc = mn_socket(&sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(sock); ++ TEST_ASSERT(rc == 0); ++ mn_close(sock); ++ ++ rc = mn_socket(&sock, MN_PF_INET6, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(sock); ++ TEST_ASSERT(rc == 0); ++ mn_close(sock); ++ ++ rc = mn_socket(&sock, MN_PF_INET6, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(sock); ++ TEST_ASSERT(rc == 0); ++ mn_close(sock); ++} ++ ++void ++sock_listen(void) ++{ ++ struct mn_socket *sock; ++ struct mn_sockaddr_in msin; ++ int rc; ++ ++ rc = mn_socket(&sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ msin.msin_family = MN_PF_INET; ++ msin.msin_len = sizeof(msin); ++ msin.msin_port = htons(12444); ++ ++ mn_inet_pton(MN_PF_INET, "127.0.0.1", &msin.msin_addr); ++ ++ rc = mn_bind(sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_listen(sock, 2); ++ TEST_ASSERT(rc == 0); ++ ++ mn_close(sock); ++} ++ ++void ++stc_writable(void *cb_arg, int err) ++{ ++ int *i; ++ ++ TEST_ASSERT(err == 0); ++ i = (int *)cb_arg; ++ *i = *i + 1; ++} ++ ++int ++stc_newconn(void *cb_arg, struct mn_socket *new) ++{ ++ struct mn_socket **r_sock; ++ ++ r_sock = cb_arg; ++ *r_sock = new; ++ ++ os_sem_release(&test_sem); ++ return 0; ++} ++ ++void ++sock_tcp_connect(void) ++{ ++ struct mn_socket *listen_sock; ++ struct mn_socket *sock; ++ struct mn_sockaddr_in msin; ++ struct mn_sockaddr_in msin2; ++ int rc; ++ union mn_socket_cb listen_cbs = { ++ .listen.newconn = stc_newconn, ++ }; ++ union mn_socket_cb sock_cbs = { ++ .socket.writable = stc_writable ++ }; ++ int connected = 0; ++ struct mn_socket *new_sock = NULL; ++ ++ rc = mn_socket(&listen_sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ msin.msin_family = MN_PF_INET; ++ msin.msin_len = sizeof(msin); ++ msin.msin_port = htons(12445); ++ ++ mn_inet_pton(MN_PF_INET, "127.0.0.1", &msin.msin_addr); ++ ++ mn_socket_set_cbs(listen_sock, &new_sock, &listen_cbs); ++ rc = mn_bind(listen_sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_listen(listen_sock, 2); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_socket(&sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ mn_socket_set_cbs(sock, &connected, &sock_cbs); ++ ++ rc = mn_connect(sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(connected == 1); ++ TEST_ASSERT(new_sock != NULL); ++ ++ /* ++ * Check endpoint data matches ++ */ ++ rc = mn_getsockname(sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ rc = mn_getpeername(new_sock, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(!memcmp(&msin, &msin2, sizeof(msin))); ++ ++ rc = mn_getsockname(new_sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ rc = mn_getpeername(sock, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(!memcmp(&msin, &msin2, sizeof(msin))); ++ ++ ++ if (new_sock) { ++ mn_close(new_sock); ++ } ++ mn_close(sock); ++ mn_close(listen_sock); ++} ++ ++void ++sud_readable(void *cb_arg, int err) ++{ ++ os_sem_release(&test_sem); ++} ++ ++void ++sock_udp_data(void) ++{ ++ struct mn_socket *sock1; ++ struct mn_socket *sock2; ++ struct mn_sockaddr_in msin; ++ struct mn_sockaddr_in msin2; ++ int rc; ++ union mn_socket_cb sock_cbs = { ++ .socket.readable = sud_readable ++ }; ++ struct os_mbuf *m; ++ char data[] = "1234567890"; ++ ++ rc = mn_socket(&sock1, MN_PF_INET, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(sock1, NULL, &sock_cbs); ++ ++ rc = mn_socket(&sock2, MN_PF_INET, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(sock2, NULL, &sock_cbs); ++ ++ msin.msin_family = MN_PF_INET; ++ msin.msin_len = sizeof(msin); ++ msin.msin_port = htons(12445); ++ ++ mn_inet_pton(MN_PF_INET, "127.0.0.1", &msin.msin_addr); ++ ++ rc = mn_bind(sock1, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ msin2.msin_family = MN_PF_INET; ++ msin2.msin_len = sizeof(msin2); ++ msin2.msin_port = 0; ++ msin2.msin_addr.s_addr = 0; ++ rc = mn_bind(sock2, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ TEST_ASSERT(m); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ rc = mn_sendto(sock2, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * Wait for the packet. ++ */ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_recvfrom(sock1, &m, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ TEST_ASSERT(msin2.msin_family == MN_AF_INET); ++ TEST_ASSERT(msin2.msin_len == sizeof(msin2)); ++ TEST_ASSERT(msin2.msin_port != 0); ++ TEST_ASSERT(msin2.msin_addr.s_addr != 0); ++ ++ if (m) { ++ TEST_ASSERT(OS_MBUF_IS_PKTHDR(m)); ++ TEST_ASSERT(OS_MBUF_PKTLEN(m) == sizeof(data)); ++ TEST_ASSERT(m->om_len == sizeof(data)); ++ TEST_ASSERT(!memcmp(m->om_data, data, sizeof(data))); ++ } ++ ++ rc = mn_sendto(sock1, m, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_recvfrom(sock2, &m, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ if (m) { ++ TEST_ASSERT(OS_MBUF_IS_PKTHDR(m)); ++ TEST_ASSERT(OS_MBUF_PKTLEN(m) == sizeof(data)); ++ TEST_ASSERT(m->om_len == sizeof(data)); ++ TEST_ASSERT(!memcmp(m->om_data, data, sizeof(data))); ++ os_mbuf_free_chain(m); ++ } ++ ++ mn_close(sock1); ++ mn_close(sock2); ++} ++ ++void ++std_writable(void *cb_arg, int err) ++{ ++ int *i; ++ ++ TEST_ASSERT(err == 0); ++ i = (int *)cb_arg; ++ if (i) { ++ *i = *i + 1; ++ } ++} ++ ++void ++std_readable(void *cb_arg, int err) ++{ ++ os_sem_release(&test_sem); ++} ++ ++static union mn_socket_cb sud_sock_cbs = { ++ .socket.writable = std_writable, ++ .socket.readable = std_readable ++}; ++ ++int ++std_newconn(void *cb_arg, struct mn_socket *new) ++{ ++ struct mn_socket **r_sock; ++ ++ r_sock = cb_arg; ++ *r_sock = new; ++ ++ mn_socket_set_cbs(new, NULL, &sud_sock_cbs); ++ ++ os_sem_release(&test_sem); ++ return 0; ++} ++ ++void ++sock_tcp_data(void) ++{ ++ struct mn_socket *listen_sock; ++ struct mn_socket *sock; ++ struct mn_sockaddr_in msin; ++ int rc; ++ union mn_socket_cb listen_cbs = { ++ .listen.newconn = std_newconn, ++ }; ++ int connected = 0; ++ struct mn_socket *new_sock = NULL; ++ struct os_mbuf *m; ++ char data[] = "1234567890"; ++ ++ rc = mn_socket(&listen_sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ msin.msin_family = MN_PF_INET; ++ msin.msin_len = sizeof(msin); ++ msin.msin_port = htons(12447); ++ ++ mn_inet_pton(MN_PF_INET, "127.0.0.1", &msin.msin_addr); ++ ++ mn_socket_set_cbs(listen_sock, &new_sock, &listen_cbs); ++ rc = mn_bind(listen_sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_listen(listen_sock, 2); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_socket(&sock, MN_PF_INET, MN_SOCK_STREAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ mn_socket_set_cbs(sock, &connected, &sud_sock_cbs); ++ ++ rc = mn_connect(sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(connected == 1); ++ TEST_ASSERT(new_sock != NULL); ++ ++ m = os_msys_get(sizeof(data), 0); ++ TEST_ASSERT(m); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ rc = mn_sendto(new_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * Wait for the packet. ++ */ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ memset(&msin, 0, sizeof(msin)); ++ rc = mn_recvfrom(sock, &m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ TEST_ASSERT(msin.msin_family == MN_AF_INET); ++ TEST_ASSERT(msin.msin_len == sizeof(msin)); ++ TEST_ASSERT(msin.msin_port != 0); ++ TEST_ASSERT(msin.msin_addr.s_addr != 0); ++ os_mbuf_free_chain(m); ++ ++ if (new_sock) { ++ mn_close(new_sock); ++ } ++ mn_close(sock); ++ mn_close(listen_sock); ++} ++ ++void ++sock_itf_list(void) ++{ ++ struct mn_itf itf; ++ struct mn_itf_addr itf_addr; ++ int if_cnt = 0; ++ int seen_127; ++ struct mn_in_addr addr127; ++ char addr_str[64]; ++ int rc; ++ ++ mn_inet_pton(MN_PF_INET, "127.0.0.1", &addr127); ++ ++ memset(&itf, 0, sizeof(itf)); ++ ++ while (1) { ++ rc = mn_itf_getnext(&itf); ++ if (rc) { ++ break; ++ } ++ printf("%d: %x %s\n", itf.mif_idx, itf.mif_flags, itf.mif_name); ++ memset(&itf_addr, 0, sizeof(itf_addr)); ++ while (1) { ++ rc = mn_itf_addr_getnext(&itf, &itf_addr); ++ if (rc) { ++ break; ++ } ++ if (itf_addr.mifa_family == MN_AF_INET && ++ !memcmp(&itf_addr.mifa_addr, &addr127, sizeof(addr127))) { ++ seen_127 = 1; ++ } ++ addr_str[0] = '\0'; ++ mn_inet_ntop(itf_addr.mifa_family, &itf_addr.mifa_addr, ++ addr_str, sizeof(addr_str)); ++ printf(" %s/%d\n", addr_str, itf_addr.mifa_plen); ++ } ++ if_cnt++; ++ } ++ TEST_ASSERT(if_cnt > 0); ++ TEST_ASSERT(seen_127); ++} ++ ++static int ++first_ll_addr(struct mn_sockaddr_in6 *ra) ++{ ++ struct mn_itf itf; ++ struct mn_itf_addr itf_addr; ++ int rc; ++ struct mn_in6_addr *addr; ++ ++ memset(&itf, 0, sizeof(itf)); ++ addr = (struct mn_in6_addr *)&itf_addr.mifa_addr; ++ while (1) { ++ rc = mn_itf_getnext(&itf); ++ if (rc) { ++ break; ++ } ++ memset(&itf_addr, 0, sizeof(itf_addr)); ++ while (1) { ++ rc = mn_itf_addr_getnext(&itf, &itf_addr); ++ if (rc) { ++ break; ++ } ++ if (itf_addr.mifa_family == MN_AF_INET6 && ++ addr->s_addr[0] == 0xfe && addr->s_addr[1] == 0x80) { ++ memset(ra, 0, sizeof(*ra)); ++ ra->msin6_family = MN_AF_INET6; ++ ra->msin6_len = sizeof(*ra); ++ ra->msin6_scope_id = itf.mif_idx; ++ memcpy(&ra->msin6_addr, addr, sizeof(*addr)); ++ return 0; ++ } ++ } ++ } ++ return -1; ++} ++ ++void ++sul_readable(void *cb_arg, int err) ++{ ++ os_sem_release(&test_sem); ++} ++ ++void ++sock_udp_ll(void) ++{ ++ struct mn_socket *sock1; ++ struct mn_socket *sock2; ++ struct mn_sockaddr_in6 msin; ++ struct mn_sockaddr_in6 msin2; ++ int rc; ++ union mn_socket_cb sock_cbs = { ++ .socket.readable = sul_readable ++ }; ++ struct os_mbuf *m; ++ char data[] = "1234567890"; ++ ++ rc = mn_socket(&sock1, MN_PF_INET6, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(sock1, NULL, &sock_cbs); ++ ++ rc = mn_socket(&sock2, MN_PF_INET6, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(sock2, NULL, &sock_cbs); ++ ++ rc = first_ll_addr(&msin); ++ if (rc != 0) { ++ printf("No ipv6 address present?\n"); ++ return; ++ } ++ msin.msin6_port = htons(12445); ++ ++ rc = mn_bind(sock1, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_getsockname(sock1, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ TEST_ASSERT(m); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ rc = mn_sendto(sock2, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin2); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * Wait for the packet. ++ */ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_recvfrom(sock1, &m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ ++ if (m) { ++ TEST_ASSERT(OS_MBUF_IS_PKTHDR(m)); ++ TEST_ASSERT(OS_MBUF_PKTLEN(m) == sizeof(data)); ++ TEST_ASSERT(m->om_len == sizeof(data)); ++ TEST_ASSERT(!memcmp(m->om_data, data, sizeof(data))); ++ os_mbuf_free_chain(m); ++ } ++ ++ mn_close(sock1); ++ mn_close(sock2); ++} ++ ++static int ++sock_find_multicast_if(void) ++{ ++ struct mn_itf itf; ++ ++ memset(&itf, 0, sizeof(itf)); ++ ++ while (1) { ++ if (mn_itf_getnext(&itf)) { ++ break; ++ } ++ if ((itf.mif_flags & MN_ITF_F_UP) == 0) { ++ continue; ++ } ++ if (itf.mif_flags & MN_ITF_F_MULTICAST) { ++ return itf.mif_idx; ++ } ++ } ++ return -1; ++} ++ ++void ++sum4_readable(void *cb_arg, int err) ++{ ++ os_sem_release(&test_sem); ++} ++ ++static void ++sock_udp_mcast_v4(void) ++{ ++ int loop_if_idx; ++ struct mn_socket *rx_sock; ++ struct mn_socket *tx_sock; ++ struct mn_sockaddr_in msin; ++ union mn_socket_cb sock_cbs = { ++ .socket.readable = sum4_readable ++ }; ++ struct os_mbuf *m; ++ char data[] = "1234567890"; ++ int rc; ++ struct mn_mreq mreq; ++ loop_if_idx = sock_find_multicast_if(); ++ TEST_ASSERT(loop_if_idx > 0); ++ ++ msin.msin_family = MN_AF_INET; ++ msin.msin_len = sizeof(msin); ++ msin.msin_port = htons(44344); ++ memset(&msin.msin_addr, 0, sizeof(msin.msin_addr)); ++ ++ rc = mn_socket(&rx_sock, MN_PF_INET, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(rx_sock, NULL, &sock_cbs); ++ ++ rc = mn_bind(rx_sock, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_socket(&tx_sock, MN_PF_INET, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_setsockopt(tx_sock, MN_SO_LEVEL, MN_MCAST_IF, &loop_if_idx); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * multicast tgt ++ */ ++ mn_inet_pton(MN_PF_INET, "224.0.2.241", &msin.msin_addr); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * RX socket has not joined group yet. ++ */ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC / 2); ++ TEST_ASSERT(rc == OS_TIMEOUT); ++ ++ mreq.mm_idx = loop_if_idx; ++ mreq.mm_family = MN_AF_INET; ++ mreq.mm_addr.v4.s_addr = msin.msin_addr.s_addr; ++ ++ /* ++ * Now join it. ++ */ ++ rc = mn_setsockopt(rx_sock, MN_SO_LEVEL, MN_MCAST_JOIN_GROUP, &mreq); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_recvfrom(rx_sock, &m, NULL); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ TEST_ASSERT(!memcmp(m->om_data, data, sizeof(data))); ++ os_mbuf_free_chain(m); ++ ++ /* ++ * Then leave ++ */ ++ rc = mn_setsockopt(rx_sock, MN_SO_LEVEL, MN_MCAST_LEAVE_GROUP, &mreq); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ TEST_ASSERT(m); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == OS_TIMEOUT); ++ ++ mn_close(rx_sock); ++ mn_close(tx_sock); ++} ++ ++static void ++sock_udp_mcast_v6(void) ++{ ++ int loop_if_idx; ++ struct mn_socket *rx_sock; ++ struct mn_socket *tx_sock; ++ struct mn_sockaddr_in6 msin6; ++ union mn_socket_cb sock_cbs = { ++ .socket.readable = sum4_readable ++ }; ++ struct os_mbuf *m; ++ char data[] = "1234567890"; ++ int rc; ++ struct mn_mreq mreq; ++ uint8_t mcast_addr[16] = { ++ 0xff, 2, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 0, ++ 0, 0, 0, 2 ++ }; ++ ++ loop_if_idx = sock_find_multicast_if(); ++ TEST_ASSERT(loop_if_idx > 0); ++ ++ msin6.msin6_family = MN_AF_INET6; ++ msin6.msin6_len = sizeof(msin6); ++ msin6.msin6_port = htons(44344); ++ memset(&msin6.msin6_addr, 0, sizeof(msin6.msin6_addr)); ++ ++ rc = mn_socket(&rx_sock, MN_PF_INET6, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ mn_socket_set_cbs(rx_sock, NULL, &sock_cbs); ++ ++ rc = mn_bind(rx_sock, (struct mn_sockaddr *)&msin6); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_socket(&tx_sock, MN_PF_INET6, MN_SOCK_DGRAM, 0); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_setsockopt(tx_sock, MN_SO_LEVEL, MN_MCAST_IF, &loop_if_idx); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * multicast tgt ++ */ ++ memcpy(&msin6.msin6_addr, mcast_addr, sizeof(mcast_addr)); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin6); ++ TEST_ASSERT(rc == 0); ++ ++ /* ++ * RX socket has not joined group yet. ++ */ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC / 2); ++ TEST_ASSERT(rc == OS_TIMEOUT); ++ ++ mreq.mm_idx = loop_if_idx; ++ mreq.mm_family = MN_AF_INET6; ++ memcpy(&mreq.mm_addr.v6.s_addr, msin6.msin6_addr.s_addr, ++ sizeof(msin6.msin6_addr.s_addr)); ++ ++ /* ++ * Now join it. ++ */ ++ rc = mn_setsockopt(rx_sock, MN_SO_LEVEL, MN_MCAST_JOIN_GROUP, &mreq); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin6); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_recvfrom(rx_sock, &m, NULL); ++ TEST_ASSERT(rc == 0); ++ TEST_ASSERT(m != NULL); ++ TEST_ASSERT(!memcmp(m->om_data, data, sizeof(data))); ++ os_mbuf_free_chain(m); ++ ++ /* ++ * Then leave ++ */ ++ rc = mn_setsockopt(rx_sock, MN_SO_LEVEL, MN_MCAST_LEAVE_GROUP, &mreq); ++ TEST_ASSERT(rc == 0); ++ ++ m = os_msys_get(sizeof(data), 0); ++ TEST_ASSERT(m); ++ rc = os_mbuf_copyinto(m, 0, data, sizeof(data)); ++ TEST_ASSERT(rc == 0); ++ ++ rc = mn_sendto(tx_sock, (struct os_mbuf *)m, (struct mn_sockaddr *)&msin6); ++ TEST_ASSERT(rc == 0); ++ ++ rc = os_sem_pend(&test_sem, OS_TICKS_PER_SEC); ++ TEST_ASSERT(rc == OS_TIMEOUT); ++ ++ mn_close(rx_sock); ++ mn_close(tx_sock); ++} ++ ++void ++mn_socket_test_handler(void *arg) ++{ ++ sock_open_close(); ++ sock_listen(); ++ sock_tcp_connect(); ++ sock_udp_data(); ++ sock_tcp_data(); ++ sock_itf_list(); ++ sock_udp_ll(); ++ sock_udp_mcast_v4(); ++ sock_udp_mcast_v6(); ++ os_test_restart(); ++} ++ ++TEST_CASE(socket_tests) ++{ ++ os_init(); ++ native_sock_init(); ++ ++ os_sem_init(&test_sem, 0); ++ ++ os_task_init(&test_task, "mn_socket_test", mn_socket_test_handler, NULL, ++ TEST_PRIO, OS_WAIT_FOREVER, test_stack, TEST_STACK_SIZE); ++ os_start(); ++} ++ +TEST_SUITE(mn_socket_test_all) +{ ++ int rc; ++ ++ rc = os_mempool_init(&test_mbuf_mpool, MB_CNT, MB_SZ, test_mbuf_area, "mb"); ++ TEST_ASSERT(rc == 0); ++ rc = os_mbuf_pool_init(&test_mbuf_pool, &test_mbuf_mpool, MB_CNT, MB_CNT); ++ TEST_ASSERT(rc == 0); ++ rc = os_msys_register(&test_mbuf_pool); ++ TEST_ASSERT(rc == 0); ++ + inet_pton_test(); ++ inet_ntop_test(); ++ ++ socket_tests(); +} + +#if MYNEWT_VAL(SELFTEST) + +int +main(int argc, char **argv) +{ + tu_config.tc_print_results = 1; + tu_init(); + + mn_socket_test_all(); + + return tu_any_failed; +} +#endif + http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/reboot/src/log_reboot.c ---------------------------------------------------------------------- diff --cc sys/reboot/src/log_reboot.c index c7c3bbe,8eff1e3..6a6bb63 --- a/sys/reboot/src/log_reboot.c +++ b/sys/reboot/src/log_reboot.c @@@ -17,24 -17,25 +17,23 @@@ * under the License. */ -#include <os/os.h> -#include <fcb/fcb.h> -#include <console/console.h> -#include "log/log.h" -#include <bootutil/image.h> -#include <bootutil/bootutil_misc.h> -#include <imgmgr/imgmgr.h> #include <string.h> -#include <config/config.h> -#include <config/config_file.h> -#include <reboot/log_reboot.h> -#include <bsp/bsp.h> #include <assert.h> - -#ifdef SHELL_PRESENT -#include <shell/shell.h> -#endif +#include "sysinit/sysinit.h" +#include "syscfg/syscfg.h" +#include "os/os.h" +#include "fcb/fcb.h" +#include "console/console.h" +#include "log/log.h" +#include "bootutil/image.h" +#include "bootutil/bootutil_misc.h" +#include "imgmgr/imgmgr.h" +#include "config/config.h" +#include "config/config_file.h" +#include "reboot/log_reboot.h" +#include "bsp/bsp.h" - static struct log_handler reboot_log_handler; - static struct fcb fcb; + static struct log_handler *reboot_log_handler; static struct log reboot_log; static uint16_t reboot_cnt; static uint16_t soft_reboot; http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/stats/src/stats.c ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/c5901fcc/sys/stats/src/stats_nmgr.c ----------------------------------------------------------------------