You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/09/22 02:12:56 UTC

[49/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/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
----------------------------------------------------------------------