newtmgr_oic; run OIC server, and newtmgr protocol over it.

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/63dfa915
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/63dfa915
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/63dfa915

Branch: refs/heads/sterly_refactor
Commit: 63dfa915288fc48f9ae265b31979900fafb49d6a
Parents: 3ba8d18
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Tue Sep 20 17:54:12 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Tue Sep 20 17:54:12 2016 -0700

----------------------------------------------------------------------
 libs/newtmgr_oic/include/newtmgr/newtmgr.h      | 112 +++++
 libs/newtmgr_oic/include/newtmgr/newtmgr_priv.h |  24 +
 libs/newtmgr_oic/pkg.yml                        |  44 ++
 libs/newtmgr_oic/src/newtmgr.c                  | 504 +++++++++++++++++++
 4 files changed, 684 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/63dfa915/libs/newtmgr_oic/include/newtmgr/newtmgr.h
----------------------------------------------------------------------
diff --git a/libs/newtmgr_oic/include/newtmgr/newtmgr.h 
b/libs/newtmgr_oic/include/newtmgr/newtmgr.h
new file mode 100644
index 0000000..dec4a5a
--- /dev/null
+++ b/libs/newtmgr_oic/include/newtmgr/newtmgr.h
@@ -0,0 +1,112 @@
+/**
+ * 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 _NEWTMGR_H_
+#define _NEWTMGR_H_
+
+#include <json/json.h>
+#include <inttypes.h>
+#include <os/os.h>
+
+/* MTU for newtmgr responses */
+#define NMGR_MAX_MTU 1024
+
+#ifndef STR
+/* Stringification of constants */
+#define STR(x) #x
+#endif
+
+/* First 64 groups are reserved for system level newtmgr commands.
+ * Per-user commands are then defined after group 64.
+ */
+#define NMGR_GROUP_ID_DEFAULT   (0)
+#define NMGR_GROUP_ID_IMAGE     (1)
+#define NMGR_GROUP_ID_STATS     (2)
+#define NMGR_GROUP_ID_CONFIG    (3)
+#define NMGR_GROUP_ID_LOGS      (4)
+#define NMGR_GROUP_ID_CRASH     (5)
+#define NMGR_GROUP_ID_SPLIT     (6)
+#define NMGR_GROUP_ID_PERUSER   (64)
+
+#define NMGR_OP_READ            (0)
+#define NMGR_OP_READ_RSP        (1)
+#define NMGR_OP_WRITE           (2)
+#define NMGR_OP_WRITE_RSP       (3)
+
+
+/**
+ * Newtmgr JSON error codes
+ */
+#define NMGR_ERR_EOK      (0)
+#define NMGR_ERR_EUNKNOWN (1)
+#define NMGR_ERR_ENOMEM   (2)
+#define NMGR_ERR_EINVAL   (3)
+#define NMGR_ERR_ETIMEOUT (4)
+#define NMGR_ERR_ENOENT   (5)
+#define NMGR_ERR_EPERUSER (256)
+
+struct nmgr_hdr {
+    uint8_t  nh_op;             /* NMGR_OP_XXX */
+    uint8_t  nh_flags;
+    uint16_t nh_len;            /* length of the payload */
+    uint16_t nh_group;          /* NMGR_GROUP_XXX */
+    uint8_t  nh_seq;            /* sequence number */
+    uint8_t  nh_id;             /* message ID within group */
+};
+
+struct nmgr_jbuf {
+    /* json_buffer must be first element in the structure */
+    struct json_buffer njb_buf;
+    struct json_encoder njb_enc;
+    char *njb_in;
+    uint16_t njb_in_off;
+    uint16_t njb_in_end;
+    char *njb_out;
+    uint16_t njb_out_off;
+    uint16_t njb_out_end;
+};
+int nmgr_jbuf_setoerr(struct nmgr_jbuf *njb, int errcode);
+
+typedef int (*nmgr_handler_func_t)(struct nmgr_jbuf *);
+
+#define NMGR_HANDLER_FUNC(__name)                                           \
+    int __name(struct nmgr_hdr *nmr, struct os_mbuf *req, uint16_t srcoff,  \
+            struct os_mbuf *rsp)
+
+struct nmgr_handler {
+    nmgr_handler_func_t nh_read;
+    nmgr_handler_func_t nh_write;
+};
+
+struct nmgr_group {
+    struct nmgr_handler *ng_handlers;
+    uint16_t ng_handlers_count;
+    uint16_t ng_group_id;
+    STAILQ_ENTRY(nmgr_group) ng_next;
+};
+
+#define NMGR_GROUP_SET_HANDLERS(__group, __handlers)       \
+    (__group)->ng_handlers = (__handlers);                 \
+    (__group)->ng_handlers_count = (sizeof((__handlers)) / \
+            sizeof(struct nmgr_handler));
+
+int nmgr_oic_init(uint8_t, os_stack_t *, uint16_t);
+int nmgr_group_register(struct nmgr_group *group);
+
+#endif /* _NETMGR_H */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/63dfa915/libs/newtmgr_oic/include/newtmgr/newtmgr_priv.h
----------------------------------------------------------------------
diff --git a/libs/newtmgr_oic/include/newtmgr/newtmgr_priv.h 
b/libs/newtmgr_oic/include/newtmgr/newtmgr_priv.h
new file mode 100644
index 0000000..7217711
--- /dev/null
+++ b/libs/newtmgr_oic/include/newtmgr/newtmgr_priv.h
@@ -0,0 +1,24 @@
+/**
+ * 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 __NETMGR_PRIV_H_
+#define __NETMGR_PRIV_H_
+
+extern struct os_eventq g_nmgr_evq;
+
+#endif

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/63dfa915/libs/newtmgr_oic/pkg.yml
----------------------------------------------------------------------
diff --git a/libs/newtmgr_oic/pkg.yml b/libs/newtmgr_oic/pkg.yml
new file mode 100644
index 0000000..75d20f5
--- /dev/null
+++ b/libs/newtmgr_oic/pkg.yml
@@ -0,0 +1,44 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: libs/newtmgr_oic
+pkg.description: Server-side newtmgr functionality for OIC
+pkg.author: "Apache Mynewt <d...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/";
+pkg.keywords:
+
+pkg.deps:
+    - libs/os
+    - libs/iotivity
+    - libs/json
+    - libs/newtmgr/nmgr_os
+    - libs/util
+    - libs/testutil
+    - libs/shell
+    - sys/reboot
+
+pkg.cflags:
+    - -DOC_SERVER
+
+pkg.apis:
+    - newtmgr
+
+pkg.features:
+    - NEWTMGR
+    - OC_SERVER

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/63dfa915/libs/newtmgr_oic/src/newtmgr.c
----------------------------------------------------------------------
diff --git a/libs/newtmgr_oic/src/newtmgr.c b/libs/newtmgr_oic/src/newtmgr.c
new file mode 100644
index 0000000..434bf46
--- /dev/null
+++ b/libs/newtmgr_oic/src/newtmgr.c
@@ -0,0 +1,504 @@
+/**
+ * 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 <os/os.h>
+#include <os/endian.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <newtmgr/newtmgr.h>
+#include <nmgr_os/nmgr_os.h>
+
+#include <iotivity/oc_api.h>
+
+#include "newtmgr/newtmgr_priv.h"
+
+#define NMGR_OC_EVENT  (OS_EVENT_T_PERUSER)
+#define NMGR_OC_TIMER  (OS_EVENT_T_PERUSER + 1)
+
+struct nmgr_state {
+    struct os_mutex ns_group_lock;
+    STAILQ_HEAD(, nmgr_group) ns_groups;
+    struct os_event ns_oc_event;
+    struct os_callout ns_oc_timer;
+    struct os_task ns_task;
+    struct nmgr_jbuf ns_jbuf;
+    char ns_rsp[NMGR_MAX_MTU];
+};
+
+static struct nmgr_state nmgr_state = {
+  .ns_groups = STAILQ_HEAD_INITIALIZER(nmgr_state.ns_groups),
+  .ns_oc_event.ev_type = NMGR_OC_EVENT,
+  .ns_oc_timer.c_ev.ev_type = NMGR_OC_TIMER,
+  .ns_oc_timer.c_evq = &g_nmgr_evq
+};
+struct os_eventq g_nmgr_evq;
+
+/* JSON buffer for NMGR task
+ */
+
+
+static void nmgr_oic_get(oc_request_t *request, oc_interface_mask_t interface);
+static void nmgr_oic_put(oc_request_t *request, oc_interface_mask_t interface);
+
+int
+nmgr_group_list_lock(void)
+{
+    int rc;
+
+    if (!os_started()) {
+        return (0);
+    }
+
+    rc = os_mutex_pend(&nmgr_state.ns_group_lock, OS_WAIT_FOREVER);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+nmgr_group_list_unlock(void)
+{
+    int rc;
+
+    if (!os_started()) {
+        return (0);
+    }
+
+    rc = os_mutex_release(&nmgr_state.ns_group_lock);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+
+int
+nmgr_group_register(struct nmgr_group *group)
+{
+    int rc;
+
+    rc = nmgr_group_list_lock();
+    if (rc != 0) {
+        goto err;
+    }
+
+    STAILQ_INSERT_TAIL(&nmgr_state.ns_groups, group, ng_next);
+
+    rc = nmgr_group_list_unlock();
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+static struct nmgr_group *
+nmgr_find_group(uint16_t group_id)
+{
+    struct nmgr_group *group;
+    int rc;
+
+    group = NULL;
+
+    rc = nmgr_group_list_lock();
+    if (rc != 0) {
+        goto err;
+    }
+
+    STAILQ_FOREACH(group, &nmgr_state.ns_groups, ng_next) {
+        if (group->ng_group_id == group_id) {
+            break;
+        }
+    }
+
+    rc = nmgr_group_list_unlock();
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (group);
+err:
+    return (NULL);
+}
+
+static struct nmgr_handler *
+nmgr_find_handler(uint16_t group_id, uint16_t handler_id)
+{
+    struct nmgr_group *group;
+    struct nmgr_handler *handler;
+
+    group = nmgr_find_group(group_id);
+    if (!group) {
+        goto err;
+    }
+
+    if (handler_id >= group->ng_handlers_count) {
+        goto err;
+    }
+
+    handler = &group->ng_handlers[handler_id];
+
+    return (handler);
+err:
+    return (NULL);
+}
+
+int
+nmgr_rsp_extend(struct nmgr_hdr *hdr, struct os_mbuf *rsp, void *data,
+        uint16_t len)
+{
+    int rc;
+
+    rc = os_mbuf_append(rsp, data, len);
+    if (rc != 0) {
+        goto err;
+    }
+    hdr->nh_len += len;
+
+    return (0);
+err:
+    return (rc);
+}
+
+static char
+nmgr_jbuf_read_next(struct json_buffer *jb)
+{
+    struct nmgr_jbuf *njb;
+    char c;
+
+    njb = (struct nmgr_jbuf *) jb;
+
+    if (njb->njb_in_off + 1 > njb->njb_in_end) {
+        return '\0';
+    }
+
+    c = njb->njb_in[njb->njb_in_off];
+    ++njb->njb_in_off;
+
+    return (c);
+}
+
+static char
+nmgr_jbuf_read_prev(struct json_buffer *jb)
+{
+    struct nmgr_jbuf *njb;
+    char c;
+
+    njb = (struct nmgr_jbuf *) jb;
+
+    if (njb->njb_in_off == 0) {
+        return '\0';
+    }
+
+    --njb->njb_in_off;
+    c = njb->njb_in[njb->njb_in_off];
+
+    return (c);
+}
+
+static int
+nmgr_jbuf_readn(struct json_buffer *jb, char *buf, int size)
+{
+    struct nmgr_jbuf *njb;
+    int read;
+    int left;
+
+    njb = (struct nmgr_jbuf *) jb;
+
+    left = njb->njb_in_end - njb->njb_in_off;
+    read = size > left ? left : size;
+
+    memcpy(buf, njb->njb_in + njb->njb_in_off, read);
+
+    return (read);
+}
+
+static int
+nmgr_jbuf_write(void *arg, char *data, int len)
+{
+    struct nmgr_jbuf *njb;
+    int rc;
+
+    njb = (struct nmgr_jbuf *) arg;
+
+    if (njb->njb_out_off + len >= njb->njb_out_end) {
+        assert(0);
+        goto err;
+    }
+    memcpy(njb->njb_out + njb->njb_out_off, data, len);
+    njb->njb_out_off += len;
+    njb->njb_out[njb->njb_out_off] = '\0';
+
+    return (0);
+err:
+    return (rc);
+}
+
+static void
+nmgr_jbuf_init(struct nmgr_jbuf *njb)
+{
+    memset(njb, 0, sizeof(*njb));
+
+    njb->njb_buf.jb_read_next = nmgr_jbuf_read_next;
+    njb->njb_buf.jb_read_prev = nmgr_jbuf_read_prev;
+    njb->njb_buf.jb_readn = nmgr_jbuf_readn;
+    njb->njb_enc.je_write = nmgr_jbuf_write;
+    njb->njb_enc.je_arg = njb;
+}
+
+static void
+nmgr_jbuf_setibuf(struct nmgr_jbuf *njb, char *ptr, uint16_t len)
+{
+    njb->njb_in_off = 0;
+    njb->njb_in_end = len;
+    njb->njb_in = ptr;
+    njb->njb_enc.je_wr_commas = 0;
+}
+
+static void
+nmgr_jbuf_setobuf(struct nmgr_jbuf *njb, char *ptr, uint16_t maxlen)
+{
+    njb->njb_out = ptr;
+    njb->njb_out_off = 0;
+    njb->njb_out_end = maxlen;
+    njb->njb_out[0] = '\0';
+}
+
+int
+nmgr_jbuf_setoerr(struct nmgr_jbuf *njb, int errcode)
+{
+    struct json_value jv;
+
+    json_encode_object_start(&njb->njb_enc);
+    JSON_VALUE_INT(&jv, errcode);
+    json_encode_object_entry(&njb->njb_enc, "rc", &jv);
+    json_encode_object_finish(&njb->njb_enc);
+
+    return (0);
+}
+
+static struct nmgr_handler *
+nmgr_oic_find_handler(const char *q, int qlen)
+{
+    int grp;
+    int id;
+    char *str;
+    char *eptr;
+    int slen;
+
+    slen = oc_ri_get_query_value(q, qlen, "gr", &str);
+    if (slen > 0) {
+        grp = strtoul(str, &eptr, 0);
+        if (*eptr != '\0' && *eptr != '&') {
+            return NULL;
+        }
+    }
+    slen = oc_ri_get_query_value(q, qlen, "id", &str);
+    if (slen > 0) {
+        id = strtoul(str, &eptr, 0);
+        if (*eptr != '\0' && *eptr != '&') {
+            return NULL;
+        }
+    }
+    return nmgr_find_handler(grp, id);
+}
+
+static void
+nmgr_oic_op(oc_request_t *req, oc_interface_mask_t mask, int isset)
+{
+    struct nmgr_state *ns = &nmgr_state;
+    struct nmgr_handler *handler;
+    oc_rep_t *data;
+    int rc;
+
+    if (!req->query_len) {
+        goto bad_req;
+    }
+
+    handler = nmgr_oic_find_handler(req->query, req->query_len);
+    if (!handler) {
+        goto bad_req;
+    }
+
+    /*
+     * Setup state for JSON encoding.
+     */
+    nmgr_jbuf_setobuf(&ns->ns_jbuf, ns->ns_rsp, sizeof(ns->ns_rsp));
+
+    data = req->request_payload;
+    if (data) {
+        if (data->type != STRING) {
+            goto bad_req;
+        }
+        nmgr_jbuf_setibuf(&ns->ns_jbuf, oc_string(data->value_string),
+          oc_string_len(data->value_string));
+    } else {
+        nmgr_jbuf_setibuf(&ns->ns_jbuf, NULL, 0);
+    }
+
+    if (!isset) {
+        if (handler->nh_read) {
+            rc = handler->nh_read(&ns->ns_jbuf);
+        } else {
+            goto bad_req;
+        }
+    } else {
+        if (handler->nh_write) {
+            rc = handler->nh_write(&ns->ns_jbuf);
+        } else {
+            goto bad_req;
+        }
+    }
+    if (rc) {
+        goto bad_req;
+    }
+
+    oc_rep_start_root_object();
+    switch (mask) {
+    case OC_IF_BASELINE:
+        oc_process_baseline_interface(req->resource);
+    case OC_IF_RW:
+        oc_rep_set_text_string(root, "key", ns->ns_rsp);
+        break;
+    default:
+        break;
+    }
+    oc_rep_end_root_object();
+    oc_send_response(req, OC_STATUS_OK);
+
+    return;
+bad_req:
+    oc_send_response(req, OC_STATUS_BAD_REQUEST);
+}
+
+static void
+nmgr_oic_get(oc_request_t *req, oc_interface_mask_t mask)
+{
+    nmgr_oic_op(req, mask, 0);
+}
+
+static void
+nmgr_oic_put(oc_request_t *req, oc_interface_mask_t mask)
+{
+    nmgr_oic_op(req, mask, 1);
+}
+
+static void
+nmgr_app_init(void)
+{
+    oc_init_platform("MyNewt", NULL, NULL);
+    oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL,
+      NULL);
+}
+
+static void
+nmgr_register_resources(void)
+{
+    uint8_t mode;
+    oc_resource_t *res = NULL;
+    char name[12];
+
+    snprintf(name, sizeof(name), "/nmgr");
+    res = oc_new_resource(name, 1, 0);
+    oc_resource_bind_resource_type(res, "x.mynewt.nmgr");
+    mode = OC_IF_RW;
+    oc_resource_bind_resource_interface(res, mode);
+    oc_resource_set_default_interface(res, mode);
+    oc_resource_set_discoverable(res);
+    oc_resource_set_request_handler(res, OC_GET, nmgr_oic_get);
+    oc_resource_set_request_handler(res, OC_PUT, nmgr_oic_put);
+    oc_add_resource(res);
+}
+
+static const oc_handler_t nmgr_oc_handler = {
+    .init = nmgr_app_init,
+    .register_resources = nmgr_register_resources
+};
+
+void
+oc_signal_main_loop(void)
+{
+    os_eventq_put(&g_nmgr_evq, &nmgr_state.ns_oc_event);
+}
+
+void
+nmgr_oic_task(void *arg)
+{
+    struct nmgr_state *ns = &nmgr_state;
+    struct os_event *ev;
+    struct os_callout_func *ocf;
+    os_time_t next_event;
+
+    nmgr_jbuf_init(&ns->ns_jbuf);
+
+    oc_main_init((oc_handler_t *)&nmgr_oc_handler);
+    while (1) {
+        ev = os_eventq_get(&g_nmgr_evq);
+        switch (ev->ev_type) {
+        case NMGR_OC_EVENT:
+        case NMGR_OC_TIMER:
+            next_event = oc_main_poll();
+            if (next_event) {
+                os_callout_reset(&ns->ns_oc_timer, next_event - os_time_get());
+            } else {
+                os_callout_stop(&ns->ns_oc_timer);
+            }
+            break;
+        case OS_EVENT_T_TIMER:
+            ocf = (struct os_callout_func *)ev;
+            ocf->cf_func(CF_ARG(ocf));
+            break;
+        }
+    }
+}
+
+int
+nmgr_oic_init(uint8_t prio, os_stack_t *stack_ptr, uint16_t stack_len)
+{
+    struct nmgr_state *ns = &nmgr_state;
+    int rc;
+
+    os_eventq_init(&g_nmgr_evq);
+
+    rc = os_task_init(&ns->ns_task, "newtmgr_oic", nmgr_oic_task, NULL, prio,
+            OS_WAIT_FOREVER, stack_ptr, stack_len);
+    if (rc != 0) {
+        goto err;
+    }
+
+    rc = nmgr_os_groups_register();
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}

Reply via email to