You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/09/14 20:06:20 UTC

[1/3] incubator-mynewt-core git commit: os unittests; use OS_TICKS_PER_SEC instead of hardcoded tick counts.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 2dfc9bd9b -> 0b82d070c


os unittests; use OS_TICKS_PER_SEC instead of hardcoded tick counts.


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

Branch: refs/heads/develop
Commit: 066c8c8f8e5efde33c9a45ca08f3dcfeae0f0181
Parents: 2dfc9bd
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Wed Sep 14 13:03:12 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Wed Sep 14 13:03:12 2016 -0700

----------------------------------------------------------------------
 libs/os/src/test/eventq_test.c |  4 ++--
 libs/os/src/test/mutex_test.c  | 36 ++++++++++++++++++------------------
 libs/os/src/test/sem_test.c    | 10 +++++-----
 3 files changed, 25 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/066c8c8f/libs/os/src/test/eventq_test.c
----------------------------------------------------------------------
diff --git a/libs/os/src/test/eventq_test.c b/libs/os/src/test/eventq_test.c
index cb1ed94..3fceb0e 100644
--- a/libs/os/src/test/eventq_test.c
+++ b/libs/os/src/test/eventq_test.c
@@ -185,7 +185,7 @@ eventq_task_poll_timeout_send(void *arg)
     }
 
     for (i = 0; i < SIZE_MULTI_EVENT; i++){
-         os_time_delay(1000);
+         os_time_delay(OS_TICKS_PER_SEC);
 
         /* Put and send */
         os_eventq_put(eventqs[i], &m_event[i]);
@@ -211,7 +211,7 @@ eventq_task_poll_timeout_receive(void *arg)
 
     /* Recieving using the os_eventq_poll_timeout*/
     for (i = 0; i < SIZE_MULTI_EVENT; i++) {
-        event = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, 200);
+        event = os_eventq_poll(eventqs, SIZE_MULTI_EVENT, OS_TICKS_PER_SEC / 5);
         TEST_ASSERT(event == NULL);
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/066c8c8f/libs/os/src/test/mutex_test.c
----------------------------------------------------------------------
diff --git a/libs/os/src/test/mutex_test.c b/libs/os/src/test/mutex_test.c
index ef6a08d..d23f099 100644
--- a/libs/os/src/test/mutex_test.c
+++ b/libs/os/src/test/mutex_test.c
@@ -149,15 +149,15 @@ mutex_test1_task14_handler(void *arg)
     TEST_ASSERT(t->t_func == mutex_test1_task14_handler);
 
     for (iters = 0; iters < 3; iters++) {
-        os_time_delay(100);
+        os_time_delay(OS_TICKS_PER_SEC / 10);
 
         g_task14_val = 1;
 
-        err = os_mutex_pend(&g_mutex1, 100);
+        err = os_mutex_pend(&g_mutex1, OS_TICKS_PER_SEC / 10);
         TEST_ASSERT(err == OS_OK);
         TEST_ASSERT(g_task16_val == 1);
 
-        os_time_delay(100);
+        os_time_delay(OS_TICKS_PER_SEC / 10);
     }
 
     os_test_restart();
@@ -178,7 +178,7 @@ mutex_test2_task14_handler(void *arg)
         TEST_ASSERT(err == OS_OK, "err=%d", err);
 
         g_task14_val = 1;
-        os_time_delay(100);
+        os_time_delay(OS_TICKS_PER_SEC / 10);
 
         /* 
          * Task17 should have its mutex wait flag set; at least the first time
@@ -193,7 +193,7 @@ mutex_test2_task14_handler(void *arg)
         }
 
         os_mutex_release(&g_mutex1);
-        os_time_delay(100);
+        os_time_delay(OS_TICKS_PER_SEC / 10);
     }
 
     os_test_restart();
@@ -210,7 +210,7 @@ task15_handler(void *arg)
             t = os_sched_get_current_task();
             TEST_ASSERT(t->t_func == task15_handler);
 
-            os_time_delay(50);
+            os_time_delay(OS_TICKS_PER_SEC / 20);
             while (1) {
                 /* Wait here forever */
             }
@@ -219,25 +219,25 @@ task15_handler(void *arg)
         if (g_mutex_test == 2) {
             /* Sleep for 3 seconds */
             t = os_sched_get_current_task();
-            os_time_delay(500);
+            os_time_delay(OS_TICKS_PER_SEC / 2);
         } else if (g_mutex_test == 3) {
             /* Sleep for 3 seconds */
             t = os_sched_get_current_task();
-            os_time_delay(30);
+            os_time_delay(OS_TICKS_PER_SEC / 33);
         }
 
         while (1) {
             t = os_sched_get_current_task();
             TEST_ASSERT(t->t_func == task15_handler);
 
-            err = os_mutex_pend(&g_mutex1, 10000);
+            err = os_mutex_pend(&g_mutex1, OS_TICKS_PER_SEC * 10);
             if (g_mutex_test == 4) {
                 TEST_ASSERT(err == OS_TIMEOUT);
             } else {
                 TEST_ASSERT(err == OS_OK);
             }
 
-            os_time_delay(100);
+            os_time_delay(OS_TICKS_PER_SEC / 10);
         }
     }
 }
@@ -254,7 +254,7 @@ task16_handler(void *arg)
             TEST_ASSERT(t->t_func == task16_handler);
 
             /* Get mutex 1 */
-            err = os_mutex_pend(&g_mutex1, 0xFFFFFFFF);
+            err = os_mutex_pend(&g_mutex1, OS_TIMEOUT_NEVER);
             TEST_ASSERT(err == OS_OK);
 
             while (g_task14_val != 1) {
@@ -270,18 +270,18 @@ task16_handler(void *arg)
         if (g_mutex_test == 2) {
             /* Sleep for 3 seconds */
             t = os_sched_get_current_task();
-            os_time_delay(30);
+            os_time_delay(OS_TICKS_PER_SEC / 33);
         } else if (g_mutex_test == 3) {
             /* Sleep for 3 seconds */
             t = os_sched_get_current_task();
-            os_time_delay(50);
+            os_time_delay(OS_TICKS_PER_SEC / 20);
         }
 
         while (1) {
             t = os_sched_get_current_task();
             TEST_ASSERT(t->t_func == task16_handler);
 
-            err = os_mutex_pend(&g_mutex1, 10000);
+            err = os_mutex_pend(&g_mutex1, OS_TICKS_PER_SEC * 10);
             if (g_mutex_test == 4) {
                 TEST_ASSERT(err == OS_TIMEOUT);
             } else {
@@ -293,7 +293,7 @@ task16_handler(void *arg)
                 TEST_ASSERT(err == OS_OK);
             }
 
-            os_time_delay(10000);
+            os_time_delay(OS_TICKS_PER_SEC * 10);
         }
     }
 }
@@ -309,9 +309,9 @@ task17_handler(void *arg)
         TEST_ASSERT(t->t_func == task17_handler);
 
         if (g_mutex_test == 5) {
-            err = os_mutex_pend(&g_mutex1, 10);
+            err = os_mutex_pend(&g_mutex1, OS_TICKS_PER_SEC / 10);
         } else {
-            err = os_mutex_pend(&g_mutex1, 10000);
+            err = os_mutex_pend(&g_mutex1, OS_TICKS_PER_SEC * 10);
             TEST_ASSERT((t->t_flags & OS_TASK_FLAG_MUTEX_WAIT) == 0);
         }
 
@@ -326,7 +326,7 @@ task17_handler(void *arg)
             TEST_ASSERT(err == OS_OK);
         }
 
-        os_time_delay(10000);
+        os_time_delay(OS_TICKS_PER_SEC * 10);
     }
 }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/066c8c8f/libs/os/src/test/sem_test.c
----------------------------------------------------------------------
diff --git a/libs/os/src/test/sem_test.c b/libs/os/src/test/sem_test.c
index ec79185..6b40069 100644
--- a/libs/os/src/test/sem_test.c
+++ b/libs/os/src/test/sem_test.c
@@ -85,7 +85,7 @@ sem_test_sleep_task_handler(void *arg)
     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();
 }
 
@@ -195,14 +195,14 @@ sem_test_1_task1_handler(void *arg)
         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();
@@ -226,13 +226,13 @@ TEST_CASE(os_sem_test_basic)
 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)


[3/3] incubator-mynewt-core git commit: native; reduce OS_TICKS_PER_SEC to 100.

Posted by ma...@apache.org.
native; reduce OS_TICKS_PER_SEC to 100.


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

Branch: refs/heads/develop
Commit: 0b82d070ceaa05e59f6a9dcfa7f512bbe9d9ccbb
Parents: 673e361
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Wed Sep 14 13:05:36 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Wed Sep 14 13:05:36 2016 -0700

----------------------------------------------------------------------
 hw/mcu/native/include/mcu/mcu_sim.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0b82d070/hw/mcu/native/include/mcu/mcu_sim.h
----------------------------------------------------------------------
diff --git a/hw/mcu/native/include/mcu/mcu_sim.h b/hw/mcu/native/include/mcu/mcu_sim.h
index 5aab337..105ba9d 100644
--- a/hw/mcu/native/include/mcu/mcu_sim.h
+++ b/hw/mcu/native/include/mcu/mcu_sim.h
@@ -19,7 +19,7 @@
 #ifndef __MCU_SIM_H__
 #define __MCU_SIM_H__
 
-#define OS_TICKS_PER_SEC    (1000)
+#define OS_TICKS_PER_SEC    (100)
 
 extern char *native_flash_file;
 extern char *native_uart_log_file;


[2/3] incubator-mynewt-core git commit: mn_socket for native; UDP/TCP and UDP datapath.

Posted by ma...@apache.org.
mn_socket for native; UDP/TCP and UDP datapath.


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

Branch: refs/heads/develop
Commit: 673e3619795505dabb7ea454378f32f9be472808
Parents: 066c8c8
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Wed Sep 14 13:04:44 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Wed Sep 14 13:04:44 2016 -0700

----------------------------------------------------------------------
 .../include/mn_socket/arch/sim/native_sock.h    |  25 +
 sys/mn_socket/src/arch/sim/native_sock.c        | 550 +++++++++++++++++++
 sys/mn_socket/src/test/mn_sock_test.c           | 267 +++++++++
 3 files changed, 842 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673e3619/sys/mn_socket/include/mn_socket/arch/sim/native_sock.h
----------------------------------------------------------------------
diff --git a/sys/mn_socket/include/mn_socket/arch/sim/native_sock.h b/sys/mn_socket/include/mn_socket/arch/sim/native_sock.h
new file mode 100644
index 0000000..66e8016
--- /dev/null
+++ b/sys/mn_socket/include/mn_socket/arch/sim/native_sock.h
@@ -0,0 +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 __NATIVE_SOCK_H_
+#define __NATIVE_SOCK_H_
+
+int native_sock_init(void);
+
+#endif /* __NATIVE_SOCK_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673e3619/sys/mn_socket/src/arch/sim/native_sock.c
----------------------------------------------------------------------
diff --git a/sys/mn_socket/src/arch/sim/native_sock.c b/sys/mn_socket/src/arch/sim/native_sock.c
new file mode 100644
index 0000000..d21438e
--- /dev/null
+++ b/sys/mn_socket/src/arch/sim/native_sock.c
@@ -0,0 +1,550 @@
+/**
+ * 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 <sys/socket.h>
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <string.h>
+#include <poll.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+
+#include <os/os.h>
+#include <os/os_mbuf.h>
+#include "mn_socket/mn_socket.h"
+#include "mn_socket/mn_socket_ops.h"
+
+#define NATIVE_SOCK_MAX 8
+#define NATIVE_SOCK_MAX_UDP 2048
+#define NATIVE_SOCK_POLL_ITVL (OS_TICKS_PER_SEC / 5)
+#define SOCK_STACK_SZ   4096
+#define SOCK_PRIO       2
+
+static int native_sock_create(struct mn_socket **sp, uint8_t domain,
+  uint8_t type, uint8_t proto);
+static int native_sock_close(struct mn_socket *);
+static int native_sock_connect(struct mn_socket *, struct mn_sockaddr *);
+static int native_sock_bind(struct mn_socket *, struct mn_sockaddr *);
+static int native_sock_listen(struct mn_socket *, uint8_t qlen);
+static int native_sock_sendto(struct mn_socket *, struct os_mbuf *,
+  struct mn_sockaddr *);
+static int native_sock_recvfrom(struct mn_socket *, struct os_mbuf **,
+  struct mn_sockaddr *);
+static int native_sock_getpeername(struct mn_socket *, struct mn_sockaddr *);
+
+static struct native_sock {
+    struct mn_socket ns_sock;
+    int ns_fd;
+    unsigned int ns_poll:1;
+    unsigned int ns_listen:1;
+    uint8_t ns_type;
+    struct os_sem ns_sem;
+    STAILQ_HEAD(, os_mbuf_pkthdr) ns_rx;
+    struct os_mbuf *ns_tx;
+} native_socks[NATIVE_SOCK_MAX];
+
+static struct native_sock_state {
+    struct pollfd poll_fds[NATIVE_SOCK_MAX];
+    int poll_fd_cnt;
+    struct os_mutex mtx;
+    struct os_task task;
+} native_sock_state;
+
+static const struct mn_socket_ops native_sock_ops = {
+    .mso_create = native_sock_create,
+    .mso_close = native_sock_close,
+
+    .mso_bind = native_sock_bind,
+    .mso_connect = native_sock_connect,
+    .mso_listen = native_sock_listen,
+
+    .mso_sendto = native_sock_sendto,
+    .mso_recvfrom = native_sock_recvfrom,
+
+    .mso_getpeername = native_sock_getpeername,
+
+};
+
+static struct native_sock *
+native_get_sock(void)
+{
+    int i;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        if (native_socks[i].ns_fd < 0) {
+            return &native_socks[i];
+        }
+    }
+    return NULL;
+}
+
+static struct native_sock *
+native_find_sock(int fd)
+{
+    int i;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        if (native_socks[i].ns_fd == fd) {
+            return &native_socks[i];
+        }
+    }
+    return NULL;
+}
+
+static void
+native_sock_poll_rebuild(struct native_sock_state *nss)
+{
+    struct native_sock *ns;
+    int i;
+    int j;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    for (i = 0, j = 0; i < NATIVE_SOCK_MAX; i++) {
+        ns = &native_socks[i];
+        if (ns->ns_fd < 0) {
+            continue;
+        }
+        if (!ns->ns_poll) {
+            continue;
+        }
+        nss->poll_fds[j].fd = ns->ns_fd;
+        nss->poll_fds[j].events = POLLIN;
+        nss->poll_fds[j].revents = 0;
+        j++;
+    }
+    nss->poll_fd_cnt = j;
+    os_mutex_release(&nss->mtx);
+}
+
+static int
+native_sock_err_to_mn_err(int err)
+{
+    switch (err) {
+    case 0:
+        return 0;
+    case ENOMEM:
+        return MN_ENOBUFS;
+    case EADDRINUSE:
+    case EADDRNOTAVAIL:
+        return MN_EADDRINUSE;
+    default:
+        return MN_EINVAL;
+    }
+}
+
+static int
+native_sock_mn_addr_to_addr(struct mn_sockaddr *ms, struct sockaddr *sa)
+{
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
+    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
+
+    switch (ms->msa_family) {
+    case MN_AF_INET:
+        sin->sin_family = AF_INET;
+        sin->sin_len = sizeof(*sin);
+        sin->sin_addr.s_addr = msin->msin_addr;
+        sin->sin_port = msin->msin_port;
+        break;
+    case MN_AF_INET6:
+        sin6->sin6_family = AF_INET6;
+        sin6->sin6_len = sizeof(*sin6);
+        sin6->sin6_port = msin6->msin6_port;
+        sin6->sin6_flowinfo = msin6->msin6_flowinfo;
+        sin6->sin6_scope_id = 0; /* XXX need this */
+        memcpy(&sin6->sin6_addr, msin6->msin6_addr, sizeof(msin6->msin6_addr));
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+    return 0;
+}
+
+static int
+native_sock_addr_to_mn_addr( struct sockaddr *sa, struct mn_sockaddr *ms)
+{
+    struct mn_sockaddr_in *msin = (struct mn_sockaddr_in *)ms;
+    struct mn_sockaddr_in6 *msin6 = (struct mn_sockaddr_in6 *)ms;
+    struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+    struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
+
+    switch (sa->sa_family) {
+    case AF_INET:
+        msin->msin_family = MN_AF_INET;
+        msin->msin_len = sizeof(*msin);
+        msin->msin_addr = sin->sin_addr.s_addr;
+        msin->msin_port = sin->sin_port;
+        break;
+    case AF_INET6:
+        msin6->msin6_family = MN_AF_INET6;
+        msin6->msin6_len = sizeof(*msin6);
+        msin6->msin6_port = sin6->sin6_port;
+        msin6->msin6_flowinfo = sin6->sin6_flowinfo;
+        memcpy(msin6->msin6_addr, &sin6->sin6_addr, sizeof(msin6->msin6_addr));
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+    return 0;
+}
+
+static int
+native_sock_create(struct mn_socket **sp, uint8_t domain,
+  uint8_t type, uint8_t proto)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns;
+    int idx;
+
+    switch (domain) {
+    case MN_PF_INET:
+        domain = PF_INET;
+        break;
+    case MN_PF_INET6:
+        domain = PF_INET6;
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+
+    switch (type) {
+    case MN_SOCK_DGRAM:
+        type = SOCK_DGRAM;
+        break;
+    case MN_SOCK_STREAM:
+        type = SOCK_STREAM;
+        break;
+    case 0:
+        break;
+    default:
+        return MN_EPROTONOSUPPORT;
+    }
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    ns = native_get_sock();
+    if (!ns) {
+        os_mutex_release(&nss->mtx);
+        return MN_ENOBUFS;
+    }
+    os_sem_init(&ns->ns_sem, 0);
+    idx = socket(domain, type, proto);
+    ns->ns_fd = idx;
+    ns->ns_type = type;
+    ns->ns_poll = 0;
+    ns->ns_listen = 0;
+    os_mutex_release(&nss->mtx);
+    if (idx < 0) {
+        return MN_ENOBUFS;
+    }
+    *sp = &ns->ns_sock;
+    return 0;
+}
+
+static int
+native_sock_close(struct mn_socket *s)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct os_mbuf_pkthdr *m;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    close(ns->ns_fd);
+    ns->ns_fd = -1;
+
+    /*
+     * When socket is closed, we must free all mbufs which might be
+     * queued in it.
+     */
+    while ((m = STAILQ_FIRST(&ns->ns_rx))) {
+        STAILQ_REMOVE_HEAD(&ns->ns_rx, omp_next);
+        os_mbuf_free_chain(OS_MBUF_PKTHDR_TO_MBUF(m));
+    }
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    return 0;
+}
+
+static int
+native_sock_connect(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int rc;
+
+    rc = native_sock_mn_addr_to_addr(addr, sa);
+    if (rc) {
+        return rc;
+    }
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (connect(ns->ns_fd, sa, sa->sa_len)) {
+        rc = errno;
+        os_mutex_release(&nss->mtx);
+        return native_sock_err_to_mn_err(rc);
+    }
+    ns->ns_poll = 1;
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    mn_socket_writable(s, 0);
+    return 0;
+}
+
+static int
+native_sock_bind(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int rc;
+    int val = 1;
+
+    rc = native_sock_mn_addr_to_addr(addr, sa);
+    if (rc) {
+        return rc;
+    }
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (ns->ns_type == SOCK_STREAM) {
+        rc = setsockopt(ns->ns_fd, SOL_SOCKET, SO_REUSEADDR, &val,
+          sizeof(val));
+        if (rc) {
+            goto err;
+        }
+    }
+    rc = ioctl(ns->ns_fd, FIONBIO, (char *)&val);
+    if (rc) {
+        goto err;
+    }
+    if (bind(ns->ns_fd, sa, sa->sa_len)) {
+        goto err;
+    }
+    if (ns->ns_type == SOCK_DGRAM) {
+        ns->ns_poll = 1;
+        native_sock_poll_rebuild(nss);
+    }
+    os_mutex_release(&nss->mtx);
+    return 0;
+err:
+    rc = errno;
+    os_mutex_release(&nss->mtx);
+    return native_sock_err_to_mn_err(rc);
+}
+
+static int
+native_sock_listen(struct mn_socket *s, uint8_t qlen)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    struct native_sock *ns = (struct native_sock *)s;
+    int rc;
+
+    os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+    if (listen(ns->ns_fd, qlen)) {
+        rc = errno;
+        os_mutex_release(&nss->mtx);
+        return native_sock_err_to_mn_err(rc);
+    }
+    ns->ns_poll = 1;
+    ns->ns_listen = 1;
+    native_sock_poll_rebuild(nss);
+    os_mutex_release(&nss->mtx);
+    return 0;
+}
+
+static int
+native_sock_sendto(struct mn_socket *s, struct os_mbuf *m,
+  struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
+    struct os_mbuf *o;
+    int off;
+    int rc;
+
+    if (ns->ns_type == SOCK_DGRAM) {
+        rc = native_sock_mn_addr_to_addr(addr, sa);
+        if (rc) {
+            return rc;
+        }
+        off = 0;
+        for (o = m; o; o = SLIST_NEXT(o, om_next)) {
+            if (off + o->om_len > sizeof(tmpbuf)) {
+                return MN_ENOBUFS;
+            }
+            os_mbuf_copydata(o, 0, o->om_len, &tmpbuf[off]);
+            off += o->om_len;
+        }
+        rc = sendto(ns->ns_fd, tmpbuf, off, 0, sa, sa->sa_len);
+        if (rc != off) {
+            return native_sock_err_to_mn_err(errno);
+        }
+        os_mbuf_free_chain(m);
+        return 0;
+    }
+    return MN_EINVAL;
+}
+
+static int
+native_sock_recvfrom(struct mn_socket *s, struct os_mbuf **mp,
+  struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    uint8_t tmpbuf[NATIVE_SOCK_MAX_UDP];
+    struct os_mbuf *m;
+    socklen_t slen;
+    int rc;
+
+    if (ns->ns_type == SOCK_DGRAM) {
+        slen = sizeof(ss);
+        rc = recvfrom(ns->ns_fd, tmpbuf, sizeof(tmpbuf), 0, sa, &slen);
+        if (rc < 0) {
+            return native_sock_err_to_mn_err(errno);
+        }
+
+        m = os_msys_get_pkthdr(rc, 0);
+        if (!m) {
+            return MN_ENOBUFS;
+        }
+        os_mbuf_copyinto(m, 0, tmpbuf, rc);
+        *mp = m;
+        native_sock_addr_to_mn_addr(sa, addr);
+        return 0;
+    }
+    return MN_EINVAL;
+}
+
+static int
+native_sock_getpeername(struct mn_socket *s, struct mn_sockaddr *addr)
+{
+    struct native_sock *ns = (struct native_sock *)s;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    socklen_t len;
+    int rc;
+
+    len = sizeof(struct sockaddr_storage);
+    rc = getpeername(ns->ns_fd, sa, &len);
+    if (rc) {
+        return native_sock_err_to_mn_err(errno);
+    }
+    rc = native_sock_addr_to_mn_addr(sa, addr);
+    if (rc) {
+        return rc;
+    }
+    return 0;
+}
+
+/*
+ * XXX should do this task with SIGIO as well.
+ */
+static void
+socket_task(void *arg)
+{
+    struct native_sock_state *nss = arg;
+    struct native_sock *ns, *new_ns;
+    struct sockaddr_storage ss;
+    struct sockaddr *sa = (struct sockaddr *)&ss;
+    int i;
+    socklen_t slen;
+    int rc;
+
+    while (1) {
+        os_time_delay(NATIVE_SOCK_POLL_ITVL);
+        os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+        if (nss->poll_fd_cnt) {
+            rc = poll(nss->poll_fds, nss->poll_fd_cnt, 0);
+        } else {
+            rc = 0;
+        }
+        if (rc == 0) {
+            continue;
+        }
+        printf("events %d\n", rc);
+        for (i = 0; i < nss->poll_fd_cnt; i++) {
+            if (!nss->poll_fds[i].revents) {
+                continue;
+            }
+            printf("  on %d - %d\n", i, nss->poll_fds[i].fd);
+            nss->poll_fds[i].revents = 0;
+            ns = native_find_sock(nss->poll_fds[i].fd);
+            assert(ns);
+            if (ns->ns_listen) {
+                new_ns = native_get_sock();
+                if (!new_ns) {
+                    continue;
+                }
+                slen = sizeof(ss);
+                new_ns->ns_fd = accept(ns->ns_fd, sa, &slen);
+                if (new_ns->ns_fd < 0) {
+                    continue;
+                }
+                new_ns->ns_poll = 1;
+                new_ns->ns_type = ns->ns_type;
+                new_ns->ns_sock.ms_ops = &native_sock_ops;
+                os_mutex_release(&nss->mtx);
+                if (mn_socket_newconn(&ns->ns_sock, &new_ns->ns_sock)) {
+                    /*
+                     * should close
+                     */
+                }
+                os_mutex_pend(&nss->mtx, OS_WAIT_FOREVER);
+            } else {
+                mn_socket_readable(&ns->ns_sock, 0);
+            }
+        }
+        os_mutex_release(&nss->mtx);
+    }
+}
+
+int
+native_sock_init(void)
+{
+    struct native_sock_state *nss = &native_sock_state;
+    int i;
+    os_stack_t *sp;
+
+    for (i = 0; i < NATIVE_SOCK_MAX; i++) {
+        native_socks[i].ns_fd = -1;
+        STAILQ_INIT(&native_socks[i].ns_rx);
+    }
+    sp = malloc(sizeof(os_stack_t) * SOCK_STACK_SZ);
+    if (!sp) {
+        return -1;
+    }
+    os_mutex_init(&nss->mtx);
+    i = os_task_init(&nss->task, "socket", socket_task, &native_sock_state,
+      SOCK_PRIO, OS_WAIT_FOREVER, sp, SOCK_STACK_SZ);
+    if (i) {
+        return -1;
+    }
+    i = mn_socket_ops_reg(&native_sock_ops);
+    if (i) {
+        return -1;
+    }
+
+    return 0;
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/673e3619/sys/mn_socket/src/test/mn_sock_test.c
----------------------------------------------------------------------
diff --git a/sys/mn_socket/src/test/mn_sock_test.c b/sys/mn_socket/src/test/mn_sock_test.c
index d49fab0..f8874e0 100644
--- a/sys/mn_socket/src/test/mn_sock_test.c
+++ b/sys/mn_socket/src/test/mn_sock_test.c
@@ -21,9 +21,24 @@
 #include <string.h>
 
 #include <os/os.h>
+#include <os/../../src/test/os_test_priv.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)
 {
@@ -91,10 +106,262 @@ TEST_CASE(inet_ntop_test)
     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;
+    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);
+
+    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 = 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 != 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
+mn_socket_test_handler(void *arg)
+{
+    sock_open_close();
+    sock_listen();
+    sock_tcp_connect();
+    sock_udp_data();
+    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();
 }
 
 #ifdef MYNEWT_SELFTEST