[esnacc-dev] [RFC v0] cxxlib: Add ROSE definitions

Aaron Conole aconole at bytheb.org
Tue Mar 28 20:16:20 UTC 2017


From: Aaron Conole <aconole at redhat.com>

This commit brings in the initial ROSE definitions for eSNACC.

Signed-off-by: Aaron Conole <aconole at redhat.com>
CC: Stephen Eckbauer <ste at estos.de>
---
NOTE: This is an early RFC.  The actual RPC side (invoke / etc) is not implemented.
      I want to make sure we get the interface and designs correct now before
      proceeding, since we'll be stuck with it for a long while

 cxx-lib/automake.mk      |  59 ++++++++++++++++--
 cxx-lib/inc/asn-rose.h   | 153 +++++++++++++++++++++++++++++++++++++++++++++++
 cxx-lib/snaccrose.asn    | 118 ++++++++++++++++++++++++++++++++++++
 cxx-lib/src/asn-rose.cpp |  62 +++++++++++++++++++
 4 files changed, 388 insertions(+), 4 deletions(-)
 create mode 100644 cxx-lib/inc/asn-rose.h
 create mode 100644 cxx-lib/snaccrose.asn
 create mode 100644 cxx-lib/src/asn-rose.cpp

diff --git a/cxx-lib/automake.mk b/cxx-lib/automake.mk
index 249f2dc..1fa9bb2 100644
--- a/cxx-lib/automake.mk
+++ b/cxx-lib/automake.mk
@@ -1,4 +1,5 @@
-lib_LTLIBRARIES += cxx-lib/libcxxasn1.la
+lib_LTLIBRARIES += cxx-lib/libcxxasn1.la \
+	cxx-lib/libcxxasn1rose.la
 
 nobase_include_HEADERS += cxx-lib/inc/asn-buf.h \
 	cxx-lib/inc/asn-chartraits.h \
@@ -7,11 +8,13 @@ nobase_include_HEADERS += cxx-lib/inc/asn-buf.h \
 	cxx-lib/inc/asn-iomanip.h \
 	cxx-lib/inc/asn-list.h \
 	cxx-lib/inc/asn-listset.h \
+	cxx-lib/inc/asn-rose.h \
 	cxx-lib/inc/asn-usefultypes.h \
 	cxx-lib/inc/init.h \
 	cxx-lib/inc/meta.h \
 	cxx-lib/inc/snaccdll.h \
 	cxx-lib/inc/snaccexcept.h \
+	cxx-lib/inc/snaccrose.h \
 	cxx-lib/inc/tcl-if.h
 
 cxx_lib_libcxxasn1_la_SOURCES = \
@@ -43,14 +46,27 @@ cxx_lib_libcxxasn1_la_SOURCES = \
 	cxx-lib/src/asn-bits.cpp \
 	cxx-lib/src/asn-len.cpp \
 	cxx-lib/src/asn-fileseg.cpp \
-	cxx-lib/src/asn-rvsbuf.cpp 
+	cxx-lib/src/asn-rvsbuf.cpp
+
+cxx_lib_libcxxasn1rose_la_SOURCES = \
+	cxx-lib/src/snaccrose.asn \
+	cxx-lib/src/snaccrose.cpp \
+	cxx-lib/src/asn-rose.cpp
 
 cxx_lib_libcxxasn1_la_WIN32_FLAGS=
 cxx_lib_libcxxasn1_la_WIN32_LIBADD=
 cxx_lib_libcxxasn1_la_WIN32_LDFLAGS=
+
+cxx_lib_libcxxasn1rose_la_WIN32_FLAGS=
+cxx_lib_libcxxasn1rose_la_WIN32_LIBADD=
+cxx_lib_libcxxasn1rose_la_WIN32_LDFLAGS=
+
 if WIN32
 cxx_lib_libcxxasn1_la_WIN32_FLAGS += -DSNACCDLL_EXPORTS=1 \
 	${PTHREAD_INCLUDES}
+
+cxx_lib_libcxxasn1rose_la_WIN32_FLAGS += -DSNACCDLL_EXPORTS=1 \
+	${PTHREAD_INCLUDES}
 endif
 
 cxx_lib_libcxxasn1_la_CXXFLAGS = \
@@ -79,8 +95,43 @@ cxx_lib_libcxxasn1_la_LDFLAGS = \
 	$(all_lib_LDFLAGS) \
 	$(cxx_lib_libcxxasn1_la_WIN32_LDFLAGS)
 
+cxx_lib_libcxxasn1rose_la_CXXFLAGS = \
+	$(PTHREAD_CFLAGS) \
+	$(cxx_lib_libcxxasn1rose_la_WIN32_FLAGS) \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/cxx-lib \
+	-I$(top_srcdir)/cxx-lib/src \
+	-I$(top_srcdir)/cxx-lib/inc
+
+cxx_lib_libcxxasn1rose_la_CFLAGS = \
+	$(PTHREAD_CFLAGS) \
+	$(cxx_lib_libcxxasn1rose_la_WIN32_FLAGS) \
+	-I$(top_srcdir) \
+	-I$(top_srcdir)/cxx-lib \
+	-I$(top_srcdir)/cxx-lib/src \
+	-I$(top_srcdir)/cxx-lib/inc
+
+cxx_lib_libcxxasn1rose_la_LIBADD = \
+	$(PTHREAD_LIBS) \
+	$(cxx_lib_libcxxasn1rose_la_WIN32_LIBADD)
+
+cxx_lib_libcxxasn1rose_la_LDFLAGS = \
+	$(LDFLAGS) \
+	$(PTHREAD_CFLAGS) \
+	$(all_lib_LDFLAGS) \
+	$(cxx_lib_libcxxasn1rose_la_WIN32_LDFLAGS)
+
 EXTRA_DIST += \
-	cxx-lib/libesnaccxx.pc.in
+	cxx-lib/libesnaccxx.pc.in \
+	cxx-lib/snaccrose.asn
 
 pkgconfig_DATA += cxx-lib/libesnaccxx.pc
-DISTCLEANFILES += cxx-lib/libesnaccxx.pc
+DISTCLEANFILES += cxx-lib/libesnaccxx.pc \
+	cxx-lib/src/snaccrose.cpp \
+	cxx-lib/inc/snaccrose.h
+
+cxx-lib/inc/snaccrose.h: cxx-lib/src/snaccrose.cpp
+	mv cxx-lib/src/snaccrose.h cxx-lib/inc/
+
+cxx-lib/src/snaccrose.cpp: cxx-lib/snaccrose.asn compiler/esnacc$(EXEEXT)
+	compiler/esnacc$(EXEEXT) -C -mo `dirname $@` $<
diff --git a/cxx-lib/inc/asn-rose.h b/cxx-lib/inc/asn-rose.h
new file mode 100644
index 0000000..de66037
--- /dev/null
+++ b/cxx-lib/inc/asn-rose.h
@@ -0,0 +1,153 @@
+/* asn-rose.h: Remote Operations Service Element support
+ *
+ * Copyright (C) 2017, Aaron Conole
+ *
+ * Dual licensed under both the esnacc public license, and the
+ * Lesser GNU Public License version 3 (lgpl v3).
+ *
+ * Portions of this file were contributed by estos GmbH, www.estos.com
+ */
+
+#include <stdint.h>
+#include <string>
+#include <map>
+#include <memory>
+#include <streambuf>
+
+#include "asn-buf.h"
+
+#ifndef ESNACC_ASN_ROSE_H__
+#define ESNACC_ASN_ROSE_H__
+
+#define ROSE_TRANSPORT_ERROR(code) (code & 0x000F)
+#define ROSE_RE(code)              (code & 0x00F0)
+#define ROSE_REJECT(code)          (code & 0x0F00)
+#define ROSE_ERROR(code)           (code & 0xF000)
+
+/* fwd decl. for this - implementation detail.  */
+class InitialMonitoredStreamCB;
+
+namespace SNACC {
+
+class AsnType;
+class ROSEMessage;
+class ROSEInvoke;
+class ROSEResult;
+class ROSEError;
+class ROSEReject;
+class InvokeProblem;
+class ROSEAuthRequest;
+class ROSEAuthResult;
+
+static const uint32_t ROSE_TRANSPORT_FAILED   = 0x1;
+static const uint32_t ROSE_TRANSPORT_SHUTDOWN = 0x2;
+static const uint32_t ROSE_TRANSPORT_TIMEOUT  = 0x3;
+
+static const uint32_t ROSE_RE_INVALID_ANSWER = 0x10;
+static const uint32_t ROSE_RE_DECODE_ERROR   = 0x20;
+
+static const uint32_t ROSE_REJECT_UNKNOWN_OPERATION = 0x100;
+static const uint32_t ROSE_REJECT_MISTYPED_ARGUMENT = 0x200;
+static const uint32_t ROSE_REJECT_FUNCTIONS_MISSING = 0x300;
+static const uint32_t ROSE_REJECT_INVALID_CODE      = 0x400;
+static const uint32_t ROSE_REJECT_INVALID_SESSION   = 0x500;
+static const uint32_t ROSE_REJECT_START_SSL_REQUIRED        = 0x600;
+static const uint32_t ROSE_REJECT_AUTHENTICATION_INCOMPLETE = 0x700;
+static const uint32_t ROSE_REJECT_AUTHENTICATION_FAILED     = 0x800;
+
+static const uint32_t ROSE_GENERIC_ERROR = 0x1000;
+
+static const uint64_t ROSE_TIMEOUT_INF = ~0ULL;
+
+enum SnaccInvokeResult {
+    returnResult,
+    returnError,
+    returnReject
+};
+
+struct AsnInvokeCtx
+{
+    AsnInvokeCtx() : rejectResult(0), invokeAuthReq(nullptr),
+                     invokeAuthRes(nullptr)
+    {
+    }
+
+    ~AsnInvokeCtx();
+
+    long rejectResult;
+    ROSEAuthRequest *invokeAuthReq;
+    ROSEAuthResult  *invokeAuthRes;
+};
+
+typedef long (*InvokeCB)(ROSEInvoke *, AsnInvokeCtx *);
+
+class OperationCoordinator
+{
+public:
+    typedef std::map<std::string, InvokeCB> ByNameMap;
+    typedef std::map<InvokeCB, std::string> ByOperationMap;
+
+    OperationCoordinator();
+    ~OperationCoordinator() { }
+
+    void SetInvokeCallback(const std::string &s, InvokeCB i)
+    {
+        nameMap[s] = i;
+        operationMap[i] = s;
+    }
+
+    InvokeCB FindInvoke(const std::string &s, bool &b) const
+    {
+        ByNameMap::const_iterator cit = nameMap.find(s);
+        b = false;
+        if (cit != nameMap.end()) {
+            b = true;
+            return cit->second;
+        }
+        return (InvokeCB)nullptr;
+    }
+
+    InvokeCB operator[](const std::string &s) const
+    {
+        InvokeCB i;
+        bool b;
+
+        i = FindInvoke(s, b);
+        if (!b || i == nullptr) {
+            throw std::runtime_error(std::string() +
+                                 "Invalid operation requested from directory");
+        }
+        return i;
+    }
+
+    void MonitorStreamBuf(std::streambuf *b);
+    void RemoveStreambuf(std::streambuf *b);
+
+    void monitor()
+    {
+        monbufs();
+    }
+
+    bool ReceiveMsg(const ROSEMessage & m);
+    bool SendMsg(std::streambuf *b, ROSEReject &r);
+
+protected:
+
+    ByNameMap      nameMap;
+    ByOperationMap operationMap;
+    InitialMonitoredStreamCB *cb;
+    StreambufMonitor monbufs;
+};
+
+}
+#endif
+
+
+
+
+
+
+
+
+
+
diff --git a/cxx-lib/snaccrose.asn b/cxx-lib/snaccrose.asn
new file mode 100644
index 0000000..16c227d
--- /dev/null
+++ b/cxx-lib/snaccrose.asn
@@ -0,0 +1,118 @@
+-- Copyright (C) 2017, Aaron Conole
+-- Portions Copright (C), estos GmbH and estos/stm
+
+SNACC-ROSE { joint-iso-itu-t remote-operations(4)
+             informationObjects(5)
+             version1(0) } DEFINITIONS ::= BEGIN
+
+-- Default ROSE message sent
+ROSEMessage ::= CHOICE {
+	invoke [1] IMPLICIT ROSEInvoke,
+	result [2] IMPLICIT ROSEResult,
+	error  [3] IMPLICIT ROSEError,
+	reject [4] IMPLICIT ROSEReject
+}
+
+-- Authentication
+
+ROSEAuth ::= SEQUENCE {
+    method   UTF8String,     -- Authentication Type ("Basic" is only supported)
+    authdata OCTET STRING    -- Authentication Data
+}
+
+ROSEAuthList ::= SEQUENCE OF ROSEAuth 
+
+ROSEAuthRequest ::= SEQUENCE {
+    auth    ROSEAuth,
+    context UTF8String OPTIONAL
+}
+
+ROSEAuthResult ::= SEQUENCE {
+  authList ROSEAuthList,
+  context  UTF8String OPTIONAL
+}
+
+
+-- ROSE messages
+
+ROSEInvoke		::=	SEQUENCE {
+    sessionID      [1]          UTF8String      OPTIONAL,
+    invokeID                    INTEGER,
+    linked-ID      [0] IMPLICIT INTEGER         OPTIONAL,
+    operationName  [2]          UTF8String      OPTIONAL,
+    authentication [3]          ROSEAuthRequest OPTIONAL,
+    operationID                 INTEGER,
+    argument                    ANY             OPTIONAL
+}
+					 
+ROSEResult ::= SEQUENCE {
+    sessionID [1] UTF8String OPTIONAL,
+    invokeID      INTEGER,
+    result        SEQUENCE {
+        resultValue INTEGER,
+        result      ANY
+    } OPTIONAL
+}
+
+ROSEError ::= SEQUENCE {
+    sessionID   [1] UTF8String OPTIONAL,
+    invokedID       INTEGER,
+    error-value     INTEGER,
+    error           ANY        OPTIONAL
+}
+
+ROSEReject ::= SEQUENCE {
+    sessionID      [1] UTF8String     OPTIONAL,
+    invokedID          CHOICE {
+        invokedID   INTEGER,
+        invokednull NULL
+    },
+    reject             RejectProblem  OPTIONAL,
+
+    -- the following are an etsos extension to reject for transmitting cause
+    details            UTF8String     OPTIONAL,
+    authentication [4] ROSEAuthResult OPTIONAL
+}
+
+RejectProblem ::= CHOICE {
+    generalProblem      [0] IMPLICIT GeneralProblem,
+    invokeProblem       [1] IMPLICIT InvokeProblem,
+    returnResultProblem [2] IMPLICIT ReturnResultProblem,
+    returnErrorProblem  [3] IMPLICIT ReturnErrorProblem
+}
+
+GeneralProblem ::= INTEGER { -- ROSE-provider detected
+	unrecognisedAPDU(0),
+	mistypedAPDU(1),
+	badlyStructuredAPDU(2)
+}
+
+InvokeProblem ::= INTEGER { -- ROSE-user detected
+    duplicateInvocation(0),
+    unrecognisedOperation(1),
+    mistypedArgument(2),
+    resourceLimitation(3),
+    initiatorReleasing(4),
+    unrecognisedLinkedID(5),
+    linkedResponseUnexpected(6),
+    unexpectedChildOperation(7),
+    invalidSessionID(8),          -- sessionID in Invoke is not valid
+    authenticationIncomplete(9),  -- Invoke Authentication failed
+    authenticationFailed(10)      -- Invoke Authentication failed  
+}
+
+ReturnResultProblem ::= INTEGER { -- ROSE-user detected
+    unrecognisedInvocation(0),
+    resultResponseUnexpected(1),
+    mistypedResult(2)
+}
+
+ReturnErrorProblem ::= INTEGER { -- ROSE-user detected
+    unrecognisedInvocation(0),
+    errorResponseUnexpected(1),
+    unrecognisedError(2),
+    unexpectedError(3),
+    mistypedParameter(4)
+}
+
+END
diff --git a/cxx-lib/src/asn-rose.cpp b/cxx-lib/src/asn-rose.cpp
new file mode 100644
index 0000000..80496d9
--- /dev/null
+++ b/cxx-lib/src/asn-rose.cpp
@@ -0,0 +1,62 @@
+#include "asn-rose.h"
+#include "snaccrose.h"
+
+using namespace SNACC;
+
+class InitialMonitoredStreamCB : public StreambufCallback
+{
+    OperationCoordinator &m_parent;
+
+    StreambufCallback::Streambuf_CB_RESULT callback(Streambuf_CB_STATUS status,
+                                                    std::streambuf *stream)
+    {
+        switch (status)
+        {
+        case StreambufCallback::CB_READ_OK:
+            {
+                AsnBuf buf(stream);
+                AsnLen l;
+                ROSEMessage rm;
+                try {
+                    rm.BDec(buf, l);
+                    m_parent.ReceiveMsg(rm);
+                } catch (SnaccException &e) {
+                    ROSEReject rejectMsg;
+                    rejectMsg.invokedID.choiceId =
+                        ROSERejectChoice::invokednullCid;
+                    rejectMsg.invokedID.invokednull = new AsnNull;
+                    m_parent.SendMsg(stream, rejectMsg);
+                }
+            }
+        case StreambufCallback::CB_WRITE_OK:
+        case StreambufCallback::CB_OPENED:
+            return StreambufCallback::CB_NONE;
+
+        case StreambufCallback::CB_CLOSED:
+        default:
+            return StreambufCallback::CB_DROP_STREAM;
+        }
+        return StreambufCallback::CB_NONE;
+    }
+
+public:
+    InitialMonitoredStreamCB(OperationCoordinator &p) :
+        m_parent(p) {}
+
+};
+
+OperationCoordinator::OperationCoordinator() :
+    nameMap(), operationMap(), cb(new InitialMonitoredStreamCB(*this))
+{
+
+}
+
+void OperationCoordinator::MonitorStreamBuf(std::streambuf *b)
+{
+    monbufs.push(b, *cb, false);
+}
+
+void OperationCoordinator::RemoveStreambuf(std::streambuf *b)
+{
+    monbufs.pop(b);
+}
-- 
2.9.3



More information about the dev mailing list