Source files added
diff --git a/demo/MongoDBTest.ttcn b/demo/MongoDBTest.ttcn
new file mode 100644
index 0000000..d7d6c00
--- /dev/null
+++ b/demo/MongoDBTest.ttcn
@@ -0,0 +1,453 @@
+// ==================================================================================
+// Copyright (c) 2017  Ericsson AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// ==================================================================================
+// Contributors:
+//  Krisztian Gulyas - initial implementation and initial documentation
+//
+//  File:               MongoDBTest.ttcn
+//  Rev:                R1A
+//  Prodnr:             CNL 0
+// ==================================================================================
+
+module MongoDBTest
+{
+    // ==============================================================================
+    //
+    // Import(s)
+    //
+    // ==============================================================================
+
+    // mongoDB prototol messages and helper functions
+    import from MongoDB_Types all;
+    import from MongoDB_Functions all;
+
+    // import basic defitions for TCP/IP communication
+    import from IPL4asp_Types all;
+	import from IPL4asp_PortType all;
+    import from SimpleTCP all;
+
+    // ==============================================================================
+    //
+    // Module parameter(s)
+    //
+    // ==============================================================================
+
+    // local and remote TCP host/port
+    modulepar { SimpleTCP.ConnectionData LocalTCPConnection, RemoteTCPConnection }
+
+    // ==============================================================================
+    //
+    // Component(s)
+    //
+    // ==============================================================================
+
+    // test component type definition
+    type component testComponent
+    {
+        port IPL4asp_PT testPort;
+    }
+
+    // ==============================================================================
+    //
+    // Additional types and functions
+    //
+    // ==============================================================================
+
+    // Wrapper function for MongoDB message length function
+    function IPL4asp_MsgLen(in octetstring stream, inout ro_integer args) return integer {
+        var integer l := MsgLen(stream)
+        log ("  [::] TCP (mongoDB) message length: ", l);
+        return l;
+    }
+
+    // ------------------------------------------------------------------------------
+    // Generic function testing mongoDB wire protocol (using testComponent):
+    //
+    // 1) encoding the given mongoDB wire message
+    // 2) sending message (via TCP)
+    // 3) if necessary:
+    //  - catching reply message
+    //  - decoding and evaluating it
+    //
+    // parameters:
+    //      - Msg               mongoDB message template
+    //      - expectResponse    expect response message [true/false]
+    // ------------------------------------------------------------------------------
+    function testMongoDB (
+        in template Msg     mongo_msg,          // mongoDB test message template
+        boolean             expectResponse)     // expect response message [true/false]
+        runs on testComponent
+    {
+        var octetstring pduOut, pduIn;
+
+        @try {
+            // trying to encode the outgoing message
+            pduOut := encMsg(valueof(mongo_msg));
+        }
+        @catch(err) {
+            log("[!!] Unable to encode the outgoing message | error: ", err);
+            setverdict(fail);
+        }
+
+        // logging the encoded message (encoder updates some fields)
+        log("[=>] MongoDB message encoded and sent: ", decMsg(pduOut));
+
+        if (SimpleTCP.sendReceiveMsg (
+            testPort,
+            refers(IPL4asp_MsgLen),
+            LocalTCPConnection,
+            RemoteTCPConnection,
+            pduOut,
+            pduIn,
+            expectResponse)) {
+
+            if (expectResponse) {
+                // initalize a mongoDB query message
+                var Msg mongo_reply_msg;
+
+                // trying to decode the incomming message
+                @try {
+                    mongo_reply_msg := decMsg(pduIn);
+
+                    var JSONRecords json;
+                    var integer error_code := bsonStream2json(mongo_reply_msg.reply_.documents.octets, json);
+                    // check return value of bson stream conversion
+                    if (error_code != 0) {
+                        setverdict(fail);
+                    }
+                    else {
+                        mongo_reply_msg.reply_.documents.json := json;
+                    }
+                }
+                @catch(err) {
+                    log("[!!] Unable to decode incomming message | error: ", err);
+                    setverdict(fail);
+                }
+
+                // compare received message with reply template
+                if (match(mongo_reply_msg, replyMsgTemplate)) {
+                    log("[<=] MongoDB reply message received: ", mongo_reply_msg);
+                    setverdict(pass);
+                }
+                else {
+                    log("[<=] Response does not match.");
+                    setverdict(fail);
+                }
+            }
+            else {
+                setverdict(pass);
+            }
+        }
+        else {
+            // TCP communication error
+            setverdict(fail);
+        }
+    }
+
+    // ==============================================================================
+    //
+    // mongoDB message template definitions (based on the message definitions)
+    //
+    // ==============================================================================
+
+    // ------------------------------------------------------------------------------
+    // mongoDB insert template
+    // ------------------------------------------------------------------------------
+    template Msg insertMsgTemplate (
+        universal charstring    fullConnectionName_,
+        integer                 flag_bytes_,
+        octetstring             documents_
+        ) :=
+    {
+        insert := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED },
+            flags :=                { bytes := flag_bytes_ },
+            fullCollectionName :=   fullConnectionName_,
+            documents :=            documents_
+        }
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB update template
+    // ------------------------------------------------------------------------------
+    template Msg updateMsgTemplate (
+        universal charstring    fullConnectionName_,
+        integer                 flag_bytes_,
+        octetstring             selector_,
+        octetstring             update_
+    ) :=
+    {
+        update := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED },
+            ZERO :=                 0,
+            fullCollectionName :=   fullConnectionName_,
+            flags :=                { bytes := flag_bytes_ },
+            selector :=             selector_,
+            update :=               update_
+        }
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB query template
+    // ------------------------------------------------------------------------------
+    template Msg queryMsgTemplate (
+        universal charstring    fullConnectionName_,
+        integer                 flag_bytes_,
+        integer                 numberToSkip_,
+        integer                 numberToReturn_,
+        octetstring             query_
+        ) :=
+    {
+        query := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED},
+            flags :=                { bytes := flag_bytes_ },
+            fullCollectionName :=   fullConnectionName_,
+            numberToSkip :=         numberToSkip_,
+            numberToReturn :=       numberToReturn_,
+            query :=                query_,
+            returnFieldsSelector := omit
+        }
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB get more template
+    // ------------------------------------------------------------------------------
+    template Msg getMoreMsgTemplate (
+        universal charstring    fullConnectionName_,
+        integer                 numberToReturn_,
+        integer                 cursorID_
+        ) :=
+    {
+        getMore := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED},
+            ZERO :=                 0,
+            fullCollectionName :=   fullConnectionName_,
+            numberToReturn :=       numberToReturn_,
+            cursorID :=             cursorID_
+        }
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB delete template
+    // ------------------------------------------------------------------------------
+    template Msg deleteMsgTemplate (
+        universal charstring    fullConnectionName_,
+        integer                 flag_bytes_,
+        octetstring             selector_
+        ) :=
+    {
+        delete := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED },
+            ZERO :=                 0,
+            fullCollectionName :=   fullConnectionName_,
+            flags :=                { bytes := flag_bytes_ },
+            selector :=             selector_
+        }
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB kill cursor template
+    // ------------------------------------------------------------------------------
+    // record of integer
+    type record of integer roInteger;
+
+    template Msg killCursorMsgTemplate (
+        integer                 numberOfCursorIDs_,
+        roInteger               cursorID_
+        ) :=
+    {
+        killCursor := {
+            header :=               { messageLength := 0, requestId := 1, responseTo := 0, opCode := OP_UNDEFINED },
+            ZERO :=                 0,
+            numberOfCursorIDs :=    numberOfCursorIDs_,
+            cursorIDs :=            cursorID_
+        }
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB reply message template
+    // ------------------------------------------------------------------------------
+    template Msg replyMsgTemplate :=
+    {
+        reply_ := {
+            header :=           { messageLength := ?, requestId := ?, responseTo := ?, opCode := OP_REPLY },
+            responseFlags :=    ?,
+            cursorID :=         ?,
+            startingFrom :=     ?,
+            numberReturned :=   ?,
+            documents :=        ?
+        }
+    }
+
+    // ==============================================================================
+    //
+    // Test cases
+    //
+    // ==============================================================================
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB insert message (no reply message)
+    // ------------------------------------------------------------------------------
+    testcase TC_Insert(in universal charstring data) runs on testComponent
+    {
+        log("===================================================================================");
+        log("[::] TC: Insert message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(
+            insertMsgTemplate(
+                "test.ttcn",        // dbname.collectionname
+                1,                  // insert flags as byte
+                // one or more BSON documents to insert into the collection
+                json2bson("{ \"command\": \"insert\", \"data\": " & data & "}")
+            ),
+            false);
+
+        log("");
+    }
+
+
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB update message (no reply message)
+    // ------------------------------------------------------------------------------
+    testcase TC_Update() runs on testComponent
+    {
+        log("===================================================================================");
+        log("[::] TC Update message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(
+            updateMsgTemplate(
+                "test.ttcn",        // dbname.collectionname
+                1,                  // update flags as byte
+                // BSON document that specifies the query for selection of the document to update
+                json2bson("{}"),
+                // BSON document that specifies the update to be performed
+                json2bson("{ \"command\": \"update\", \"data\": \"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. \"}")
+            ),
+            false);
+
+        log("");
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB query message
+    // ------------------------------------------------------------------------------
+    testcase TC_Query() runs on testComponent
+    {
+        log("===================================================================================");
+        log("[::] TC: Query message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(
+            queryMsgTemplate(
+                "test.ttcn",        // dbname.collectionname
+                0,                  // query flags as byte
+                0,                  // number of documents to skip
+                0,                  // number of documents to return in the first OP_REPLY batch
+                // BSON document that represents the query
+                json2bson("{}")
+            ),
+            true);
+
+        log("");
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB get more message
+    // ------------------------------------------------------------------------------
+    testcase TC_GetMore() runs on testComponent
+    {
+        log("===================================================================================");
+        log("[::] TC: Get More message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(
+            getMoreMsgTemplate(
+                "test.ttcn",        // dbname.collectionname
+                0,                  // number of documents to return
+                0                   // cursor id from OP_REPLY
+            ),
+            true);
+
+        log("");
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB delete message (no reply message)
+    // ------------------------------------------------------------------------------
+    testcase TC_Delete() runs on testComponent
+    {
+        log("===================================================================================");
+        log("[::] TC: Delete message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(
+            deleteMsgTemplate(
+                "test.ttcn",        // dbname.collectionname
+                0,                  // query flags as byte
+                // BSON document that represent the query used to select the documents to be removed.
+                json2bson("{\"data\": 17}")
+            ),
+            false);
+
+        log("");
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // Testing MongoDB delete message (no reply message)
+    // ------------------------------------------------------------------------------
+    testcase TC_KillCursor() runs on testComponent
+    {
+
+        log("===================================================================================");
+        log("[::] TC: KillCursor message test");
+
+        map(mtc:testPort, system:testPort);
+
+        testMongoDB(valueof(
+            killCursorMsgTemplate(
+                    1,              // number of cursorIDs in message
+                    {1, 2, 3}       // sequence of cursorIDs
+                )),
+            false);
+
+        log("");
+    }
+
+    // ==============================================================================
+    //
+    // Run the following testcases
+    //
+    // ==============================================================================
+    control
+    {
+
+        // insert 20 records
+        for (var integer i := 0; i < 20; i := i + 1) {
+            execute(TC_Insert(int2str(i)));
+        }
+        execute(TC_Update());
+        execute(TC_Query());
+        execute(TC_GetMore());
+        execute(TC_Delete());
+        execute(TC_KillCursor());
+        execute(TC_Query());
+
+    }
+}
diff --git a/demo/README b/demo/README
new file mode 100644
index 0000000..2d38910
--- /dev/null
+++ b/demo/README
@@ -0,0 +1,57 @@
+mongoDB protocol module test info  
+
+  ________________________________________________________________________
+
+  1) Prerequisites
+  ________________________________________________________________________
+
+   -mongoDB access (local or remote)
+   -wireshark (https://www.wireshark.org/) [optional]
+   -https://github.com/eclipse/titan.TestPorts.Common_Components.Socket-API
+   -https://github.com/eclipse/titan.TestPorts.IPL4asp
+
+
+  ________________________________________________________________________
+
+  2) Prepare your TTCN mongoDB test
+  ________________________________________________________________________
+
+  - unpack mongoDBTest.zip file, then create symbolic links with:
+
+  > cd MongoDBTest/bin
+  > ../src/install.script
+
+  - set up your mongoDB connection parameters (host/port) in
+    cfg/mongoDB.cfg file:
+
+    ...
+
+    // Local TCP connection address
+    LocalTCPConnection := { "127.0.0.1", 3000 };
+
+    // Remote TCP connection address (mongoDB database)
+    RemoteTCPConnection := { "127.0.0.1", 27017 };
+
+    ...
+
+  ________________________________________________________________________
+
+  3) Build and run test(s)
+  ________________________________________________________________________
+
+  > make
+  > ./mongoDBTest ../cfg/mongoDB.cfg
+
+  ________________________________________________________________________
+
+  Additional info/help
+  ________________________________________________________________________
+
+  - The Makefile was generated with:
+
+  > makefilegen -s -e mongoDBTest *.ttcn *.cc *.hh
+
+  - Installing mongoDB:
+    https://docs.mongodb.com/manual/administration/install-community/
+
+
diff --git a/demo/SimpleTCP.ttcn b/demo/SimpleTCP.ttcn
new file mode 100644
index 0000000..12f5315
--- /dev/null
+++ b/demo/SimpleTCP.ttcn
@@ -0,0 +1,145 @@
+// ==================================================================================
+// Copyright (c) 2017  Ericsson AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// ==================================================================================
+// Contributors:
+//  Krisztian Gulyas - initial implementation and initial documentation
+//
+//  File:               SimpleTCP.ttcn
+//  Rev:                 
+//  Prodnr:              
+// ==================================================================================
+
+// ==============================================================================
+//
+// Helper module for simple TCP/IP communication using the IPL4asp library
+//
+// ==============================================================================
+module SimpleTCP
+{
+    // import basic definitions of TCP/IP communication
+    import from IPL4asp_Types all;
+	import from IPL4asp_PortType all;
+
+    // basic TCP connection data type
+    type record ConnectionData {
+        charstring  host,           // host name [string]
+        integer     portNumber      // port number [integer]
+    }
+
+    // ------------------------------------------------------------------------------
+    // Helper function for simple TCP message send and receive
+    //
+    // 0) Register message lenght callback (function)
+    // 1) Initalize TCP connection
+    // 2) Sending out TCP message with given PDU
+    // 3) if necessary: catching reply message, get PDU
+    //
+    // parameters:
+    //      - testPort          // IPL4asp_PT type TCP/IP testport [IPL4asp_PT]
+    //      - msgLenCallback    // message length function callback
+    //      - local             // local host/port  [ConnectionData]
+    //      - remote            // remote host/port [ConnectionData]
+    //      - pduOut            // these octets will be sent out as the part of TCP message [octets]
+    //      - pduIn             // these octets are received from incomming TCP message [octets]
+    //      - expectResponse    // expected response message from host/port [true/false]
+    // return:
+    //      - TCP communication was success [true/false]
+    //
+    // ------------------------------------------------------------------------------
+
+    function sendReceiveMsg (
+        IPL4asp_PT              testPort,       // IPL4asp_PT type TCP/IP testport [IPL4asp_PT]
+        f_IPL4_getMsgLen        msgLenCallback,
+        ConnectionData          local,
+        ConnectionData          remote,
+        in octetstring          pduOut,
+        inout octetstring       pduIn,
+        boolean                 expectResponse
+        ) return boolean                        // TCP commution result
+    {
+        var boolean res := false;               // send/receive result, default = false
+
+        var Result connectionResult, closingResult;
+
+        // register message lenght callback
+        f_IPL4_setGetMsgLen(testPort, -1, msgLenCallback, {});
+
+        // connect to the socket and check result
+        connectionResult := f_IPL4_connect(
+            testPort,
+            remote.host, remote.portNumber,
+            local.host, local.portNumber,
+            -1,
+            { tcp := {}},
+            {
+                { reuseAddress := {enable := true} }
+            });
+
+        if (ispresent(connectionResult.errorCode)) {
+            log("  [!!] TCP port connection error: ", connectionResult);
+        }
+        else {
+            // successfully connected to the given host/port
+            log("  [::] TCP port [", remote.host, "/", remote.portNumber, "] connected.");
+
+            // send and receive TCP message
+            var ASP_SendTo      tcp_msg_send;
+            var ASP_RecvFrom    tcp_msg_received;
+
+            // Timer with 0.1 s duration
+            timer T := 0.1;
+
+            // set up TCP message
+            tcp_msg_send := { connectionResult.connId, remote.host, remote.portNumber, { tcp := {} }, pduOut }
+
+            // send out TCP message to the given port
+            testPort.send(tcp_msg_send);
+            log("  [=>] TCP message sent...");
+
+            // process received message if needed
+            if (expectResponse) {
+
+                // start timer with 0.1 s
+                T.start;
+
+                alt
+                {
+                    [] testPort.receive(ASP_RecvFrom : ?) -> value tcp_msg_received
+                    {
+                        log("  [<=] TCP message received ");
+                        pduIn := tcp_msg_received.msg;
+                        res := true;
+                    }
+                    [] T.timeout {
+                        log("  [!!] Timeout (no response) ");
+                    }
+                }
+            }
+            else {
+                log("  [::] Expecting no response");
+                res := true;
+            }
+
+            // close the connection and check result
+            closingResult := f_IPL4_close(testPort, connectionResult.connId, { unspecified := {} });
+
+            if (ispresent(closingResult.errorCode)) {
+                log("  [!!] TCP port closing error: ", connectionResult.errorCode);
+            }
+            else {
+                log("  [::] TCP port [", remote.host, "/", remote.portNumber, "] closed");
+            }
+
+            // 0.1 second delay (proper closing of TCP operations)
+            T.start; T.timeout;
+
+        }
+
+        return res;
+    }
+
+}
diff --git a/demo/mongoDB.cfg b/demo/mongoDB.cfg
new file mode 100644
index 0000000..5a1c384
--- /dev/null
+++ b/demo/mongoDB.cfg
@@ -0,0 +1,21 @@
+

+// Module parameters

+[MODULE_PARAMETERS]

+

+// Local TCP connection address

+LocalTCPConnection := { "127.0.0.1", 3000 };

+

+// Remote TCP connection address (mongoDB database)

+RemoteTCPConnection := { "127.0.0.1", 27017 };

+

+// Logging settings

+[LOGGING]

+LogFile := "logs/%e.%h-%r.%s"

+FileMask := LOG_ALL | DEBUG | MATCHING

+ConsoleMask := ERROR | WARNING | TESTCASE | STATISTICS | PORTEVENT

+LogSourceInfo := No

+AppendFile := No

+TimeStampFormat := DateTime

+LogEventTypes := Yes

+SourceInfoFormat := None

+LogEntityName := Yes

diff --git a/doc/README b/doc/README
new file mode 100644
index 0000000..e826933
--- /dev/null
+++ b/doc/README
@@ -0,0 +1,5 @@
+MongoDB protocol module 
+
+Based on: MongoDB Wire Protocol — MongoDB Manual 3.4
+ 
+https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/
diff --git a/src/MongoDB_Functions.ttcn b/src/MongoDB_Functions.ttcn
new file mode 100644
index 0000000..331abc3
--- /dev/null
+++ b/src/MongoDB_Functions.ttcn
@@ -0,0 +1,97 @@
+// ==================================================================================
+// Copyright (c) 2017  Ericsson AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// ==================================================================================
+// Contributors:
+//  Krisztian Gulyas - initial implementation and initial documentation
+//
+//  File:               MongoDBProtocolHelper.ttcn
+//  Rev:                R1A
+//  Prodnr:             CNL 0
+// ==================================================================================
+module MongoDB_Functions
+{
+    // ==============================================================================
+    //
+    // mongoDB wire protocol helper definitions
+    // please refer to MongoDBProtocol.ttcn for MongoDBProtocol defitions
+    //
+    // ==============================================================================
+
+    import from MongoDB_Types all;              // mongoDB protocol description
+
+    // ------------------------------------------------------------------------------
+    // Helper function for TCP protocol, returns with the length of message
+    //
+    // - first 4 octets (32 bits) (of any MongoDB message) shows the length of
+    //    the message (please refer to the MsgHeader definition in MongoDBProtocol)
+    //
+    // - definition of int32 (raw encoding/decoding) provides a simple decoding
+    //    function (please refer to the definition of int32 in MongoDBProtocol)
+    //
+    // parameters:
+    //      - stream    octets
+    // return:
+    //      - length of the message (read it from the message header)
+    //
+    // ------------------------------------------------------------------------------
+    function MsgLen(in octetstring stream) return integer {
+        return decInt32(substr(stream, 0, 4));
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // Helper function to serialize a BSON stream.
+    //
+    // Finds and converts each BSON documents (of the given stream) to a JSON string.
+    // parameters:
+    //      - json  array of the converted JSON string
+    // return:
+    //      - 0     no error
+    //      - 1     BSON to JSON conversion error (error type logged)
+    //      - 2     buffer cut error (error type logged)
+    //
+    // ------------------------------------------------------------------------------
+    function bsonStream2json(in octetstring stream, inout JSONRecords json) return integer {
+
+        var integer streamLength :=     lengthof(stream),
+                    noDocs :=           0,
+                    docLength;
+
+        // initalize records
+        json := {""};
+
+        while (streamLength > 0) {
+            // length of BSON document
+            docLength := decInt32(substr(stream, 0, 4));
+
+            // convert bson octects to json string
+            @try {
+                json[noDocs] := bson2json(substr(stream, 0, docLength));
+            }
+            @catch(err) {
+                log("[!!] Unable to encode bson message | error: ", err);
+                return 1;
+            }
+
+            // cut current octects, update number of docs and stream length
+            @try {
+                stream := substr(stream, docLength, streamLength - docLength);
+            }
+            @catch(err) {
+                log("[!!] Unable to cut buffer properly | error: ", err);
+                return 2;
+            }
+
+            noDocs := noDocs + 1;
+            streamLength := lengthof(stream);
+        }
+
+        log ("[::] " & int2str(noDocs) & " documents serialized from the incomming BSON stream");
+        return 0;
+    }
+
+} with { encode "RAW" }
diff --git a/src/MongoDB_Types.ttcn b/src/MongoDB_Types.ttcn
new file mode 100644
index 0000000..152d6b2
--- /dev/null
+++ b/src/MongoDB_Types.ttcn
@@ -0,0 +1,440 @@
+// ==================================================================================
+// Copyright (c) 2017  Ericsson AB
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// which accompanies this distribution, and is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// ==================================================================================
+// Contributors:
+//  Krisztian Gulyas - initial implementation and initial documentation
+//
+//  File:               MongoDBProtocol.ttcn
+//  Rev:                R1A
+//  Prodnr:             CNL 0
+// ==================================================================================
+module MongoDB_Types
+{
+    // ==============================================================================
+    //
+    // mongoDB wire protocol definitions
+    // reference: https://docs.mongodb.com/manual/reference/mongodb-wire-protocol/
+    // version: mongoDB version 3.4
+    //
+    // ==============================================================================
+
+    // ------------------------------------------------------------------------------
+    // general definitions
+    // ------------------------------------------------------------------------------
+
+    // 32 bit integer (little endian encoding) and decoding function
+    type integer int32 with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    // decoding int32 value from octetstring
+    external function decInt32 (in octetstring stream) return int32 with { extension "prototype(convert) decode(RAW)" }
+
+    // 64 bit integer (little endian encoding)
+    type integer int64 with { variant "FIELDLENGTH(64), COMP(signbit), BYTEORDER(first)" };
+
+    // record of int64 type
+    type record of int64 roInt64;
+
+    /// null terminaged string
+    type universal charstring cstring with { variant "FIELDLENGTH(null_terminated)"};
+
+    // different size of bit fields
+    type bitstring BIT1 with  { variant "BITORDER(lsb), FIELDLENGTH(1)"  };
+    type bitstring BIT24 with { variant "BITORDER(lsb), FIELDLENGTH(24)" };
+    type bitstring BIT28 with { variant "BITORDER(lsb), FIELDLENGTH(28)" };
+    type bitstring BIT30 with { variant "BITORDER(lsb), FIELDLENGTH(30)" };
+    type bitstring BIT31 with { variant "BITORDER(lsb), FIELDLENGTH(31)" };
+
+    // record of JSON documents
+    type record of universal charstring JSONRecords;
+
+    // ------------------------------------------------------------------------------
+    // mongoDB message header definitions (common part of the message)
+    // ------------------------------------------------------------------------------
+
+    // code of the operations: 32 bit integer (little endian encoding)
+    type enumerated OpCode
+    {
+        OP_REPLY            (1),    //	Reply to a client request. responseTo is set.
+        OP_MSG	         (1000), 	// Generic msg command followed by a string.
+        OP_UPDATE 	     (2001), 	// Update document.
+        OP_INSERT 	     (2002), 	// Insert new document.
+        OP_QUERY 	     (2004), 	// Query a collection.
+        OP_GET_MORE 	 (2005), 	// Get more data from a query. See Cursors.
+        OP_DELETE 	     (2006), 	// Delete documents.
+        OP_KILL_CURSORS  (2007), 	// Notify database that the client has finished with the cursor.
+        OP_COMMAND 	     (2010), 	// Cluster internal protocol representing a command request.
+        OP_COMMANDREPLY  (2011), 	// Cluster internal protocol representing a reply to an OP_COMMAND.
+        OP_UNDEFINED        (0)     // Undefined value for ttcn test cases
+    } with { variant "BYTEORDER(first), FIELDLENGTH(32)" };
+
+    // header structure
+    type record MsgHeader
+    {
+        // The total size of the message in bytes. This total includes the 4 bytes that holds the message length.
+        int32   messageLength,
+
+        // A client or database-generated identifier that uniquely identifies this message.
+        // For the case of client-generated messages (e.g. OP_QUERY and OP_GET_MORE), it will be returned in the responseTo
+        // field of the OP_REPLY message. Clients can use the requestID and the responseTo fields to associate query
+        //  responses with the originating query.
+        int32   requestId,
+
+        // In the case of a message from the database, this will be the requestID taken from the OP_QUERY or OP_GET_MORE
+        // messages from the client. Clients can use the requestID and the responseTo fields to associate query responses
+        // with the originating query.
+        int32   responseTo,
+
+        // Type of message. See Request Opcodes above
+        OpCode   opCode
+    } with { variant "" }
+
+    // ==============================================================================
+    //
+    // mongoDB client request messages
+    //
+    // ==============================================================================
+
+    // ------------------------------------------------------------------------------
+    // mongoDB insert message,
+    // ------------------------------------------------------------------------------
+
+    // flags: definitions of bits
+    type record InsertMsgFlagsBits {
+        // If set, the database will not stop processing a bulk insert if one fails (eg due to duplicate IDs).
+        // This makes bulk insert behave similarly to a series of single inserts, except lastError will be set
+        // if any insert fails, not just the last one. If multiple errors occur, only the most recent will be
+        // reported by getLastError. (new in 1.9.1)
+        BIT1        ContinueOnError,
+        // 1-31 bits are reserved. Must be set to 0
+        BIT31       Reserved0
+    } with { variant "" }
+
+    // flags can be accessed via bits or value
+    type union InsertMsgFlags {
+        InsertMsgFlagsBits  bits,
+        int32               bytes
+    } with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    // message structure
+    type record InsertMsg
+    {
+        MsgHeader       header,             // standard message header
+        InsertMsgFlags  flags,              // bit vector of insert options.
+        cstring         fullCollectionName, // "dbname.collectionname"
+        octetstring     documents           // one or more BSON documents to insert into the collection
+    } with {
+        variant "TAG (header, opCode = OP_INSERT)";
+        variant (header) "LENGTHTO(header, flags, fullCollectionName, documents)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB update message,
+    // ------------------------------------------------------------------------------
+
+    // flags: definitions of bits
+    type record UpdateMsgFlagsBits {
+        // If set, the database will insert the supplied object into the collection if no matching document is found.
+        BIT1        Upsert,
+
+        // If set, the database will update all matching objects in the collection. Otherwise only updates first matching document.
+        BIT1        MultiUpdate,
+
+        // 2-31 bits are reserved. Must be set to 0
+        BIT30       Reserved0
+    } with { variant "" }
+
+    // flags can be accessed via bits or value
+    type union UpdateMsgFlags {
+        UpdateMsgFlagsBits  bits,
+        int32               bytes
+    } with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    // message structure
+    type record UpdateMsg
+    {
+        MsgHeader       header,             // standard message header
+        int32           ZERO,               // 0 - reserved for future use
+        cstring         fullCollectionName, // "dbname.collectionname"
+        UpdateMsgFlags  flags,              // bit vector of update options.
+        octetstring     selector,           // BSON document that specifies the query for selection of the document to update
+        octetstring     update              // BSON document that specifies the update to be performed
+    } with {
+        variant "TAG (header, opCode = OP_UPDATE)";
+        variant (header) "LENGTHTO(header, ZERO, fullCollectionName, flags, selector, update)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB query message,
+    // ------------------------------------------------------------------------------
+
+    // flags: definitions of bits
+    type record QueryMsgFlagsBits {
+        // Reserved. Must be set to 0.
+        BIT1        Reserved0,
+
+        // Tailable means cursor is not closed when the last data is retrieved. Rather, the cursor marks the final
+        // object’s position. You can resume using the cursor later, from where it was located, if more data were received.
+        // Like any “latent cursor”, the cursor may become invalid at some point (CursorNotFound) – for example if the
+        // final object it references were deleted.
+        BIT1        TailableCursor,
+
+        // Allow query of replica slave. Normally these return an error except for namespace “local”.
+        BIT1        SlaveOK,
+
+        // Internal replication use only - driver should not set.
+        BIT1        OplogReplay,
+
+        // The server normally times out idle cursors after an inactivity period (10 minutes) to prevent excess memory use.
+        // Set this option to prevent that.The server normally times out idle cursors after an inactivity period (10 minutes)
+        // to prevent excess memory use. Set this option to prevent that.
+        BIT1        NoCursorTimeout,
+
+        // Use with TailableCursor. If we are at the end of the data, block for a while rather than returning no data.
+        // After a timeout period, we do return as normal.
+        BIT1        AwaitData,
+
+        // Stream the data down full blast in multiple “more” packages, on the assumption that the client will fully read all
+        // data queried. Faster when you are pulling a lot of data and know you want to pull it all down. Note: the client is
+        // not allowed to not read all the data unless it closes the connection.Stream the data down full blast in multiple “more” packages,
+        // on the assumption that the client will fully read all data queried. Faster when you are pulling a lot of data and know you want
+        // to pull it all down. Note: the client is not allowed to not read all the data unless it closes the connection.
+        BIT1        Exhaust,
+
+        // Get partial results from a mongos if some shards are down (instead of throwing an error)
+        BIT1        Partial,
+
+        // 8-31 bits are reserved. Must be set to 0.
+        BIT24       Reserved1
+    } with { variant "" }
+
+    // flags can be accessed via bits or value
+    type union QueryMsgFlags {
+        QueryMsgFlagsBits   bits,
+        int32               bytes
+    } with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    // message structure
+    type record QueryMsg
+    {
+        MsgHeader       header,                         // standard message header
+        QueryMsgFlags   flags,                          // bit vector of query options.
+        cstring         fullCollectionName,             // "dbname.collectionname"
+        int32           numberToSkip,                   // number of documents to skip
+        int32           numberToReturn,                 // number of documents to return in the first OP_REPLY batch
+        octetstring     query,                          // BSON document that represents the query
+        octetstring     returnFieldsSelector optional   // BSON document that limits the fields in the returned documents.
+    } with {
+        variant "TAG (header, opCode = OP_QUERY)";
+        variant (header) "LENGTHTO(header, flags, fullCollectionName, numberToSkip, numberToReturn, query, returnFieldsSelector)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB get more message,
+    // ------------------------------------------------------------------------------
+
+    // message structure
+    type record GetMoreMsg
+    {
+        MsgHeader       header,             // standard message header
+        int32           ZERO,               // 0 - reserved for future use
+        cstring         fullCollectionName, // "dbname.collectionname"
+        int32           numberToReturn,     // number of documents to return
+        int64           cursorID            // cursor id from OP_REPLY
+    } with {
+        variant "TAG (header, opCode = OP_GET_MORE)";
+        variant (header) "LENGTHTO(header, ZERO, fullCollectionName, numberToReturn, cursorID)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB delete message,
+    // ------------------------------------------------------------------------------
+
+    // flags: definitions of bits
+    type record DeleteMsgFlagsBits {
+        // If set, the database will remove only the first matching document in the collection.
+        // Otherwise all matching documents will be removed.
+        BIT1        SingleRemove,
+
+        // 1-31 bits are reserved. Must be set to 0.
+        BIT31       Reserved1
+    } with { variant "" }
+
+    // flags can be accessed via bits or value
+    type union DeleteMsgFlags {
+        DeleteMsgFlagsBits   bits,
+        int32                bytes
+    } with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    // message structure
+    type record DeleteMsg
+    {
+        MsgHeader       header,             // standard message header
+        int32           ZERO,               // 0 - reserved for future use
+        cstring         fullCollectionName, // "dbname.collectionname"
+        DeleteMsgFlags  flags,              // bit vector of delete options.
+        octetstring     selector            // BSON document that represent the query used to select the documents to be removed
+    } with {
+        variant "TAG (header, opCode = OP_DELETE)";
+        variant (header) "LENGTHTO(header, ZERO, fullCollectionName, flags, selector)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB kill cursor message
+    // ------------------------------------------------------------------------------
+
+    // message structure
+    type record KillCursorMsg
+    {
+        MsgHeader       header,             // standard message header
+        int32           ZERO,               // 0 - reserved for future use
+        int32           numberOfCursorIDs,  // number of cursorIDs in message
+        roInt64         cursorIDs           // sequence of cursorIDs
+    } with {
+        variant "TAG (header, opCode = OP_KILL_CURSORS)";
+        variant (header) "LENGTHTO(header, ZERO, numberOfCursorIDs, cursorIDs)";
+        variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB command message,
+    // ------------------------------------------------------------------------------
+
+    // command message structure
+    type record CommandMsg
+    {
+       MsgHeader   header,             // standard message header
+       cstring     database,
+       cstring     commandName,
+       octetstring metadata,
+       octetstring commandArgs,
+       octetstring inputDocs optional
+    }
+    with {
+       variant "TAG (header, opCode = OP_COMMAND)";
+       variant (header) "LENGTHTO(header, database, commandName, metadata, commandArgs, inputDocs)";
+       variant (header) "LENGTHINDEX(messageLength)"
+    }
+
+
+    // ==============================================================================
+    //
+    // mongoDB response messages
+    //
+    // ==============================================================================
+
+
+    // ------------------------------------------------------------------------------
+    // mongoDB reply message,
+    // ------------------------------------------------------------------------------
+
+    // flags: definitions of bits
+    type record ReplyMsgFlagsBits {
+        // Is set when getMore is called but the cursor id is not valid at the server. Returned with zero results.
+        BIT1        CursorNotFound,
+
+        // Is set when query failed. Results consist of one document containing an “$err” field describing the failure.
+        BIT1        QueryFailure,
+
+        // Drivers should ignore this. Only mongos will ever see this set, in which case, it needs to update config from the server.
+        BIT1        ShardConfigStale,
+
+        // Is set when the server supports the AwaitData Query option. If it doesn’t, a client should sleep a little
+        // between getMore’s of a Tailable cursor. Mongod version 1.6 supports AwaitData and thus always sets AwaitCapable.
+        BIT1        AwaitCapable,
+
+        // 4-31 bits are reserved. Ignore.
+        BIT28       Reserved
+    } with { variant "" }
+
+    // flags can be accessed via bits or value
+    type union ReplyMsgFlags {
+        ReplyMsgFlagsBits   bits,
+        int32               bytes
+    } with { variant "FIELDLENGTH(32), COMP(signbit), BYTEORDER(first)" };
+
+    type union ReplyMsgDocuments {
+        octetstring             octets,
+        JSONRecords             json
+    } with { variant "" };
+
+    // command message structure
+    type record ReplyMsg
+    {
+        MsgHeader           header,             // standard message header
+        ReplyMsgFlags       responseFlags,      // bit vector - see details below
+        int64               cursorID,           // cursor id if client needs to do get more's
+        int32               startingFrom,       // where in the cursor this reply is starting
+        int32               numberReturned,     // number of documents in the reply
+        ReplyMsgDocuments   documents           // documents
+    } with {
+        variant "TAG (header, opCode = OP_REPLY)";
+    }
+
+    // ------------------------------------------------------------------------------
+    // mongoDB command reply message
+    // ------------------------------------------------------------------------------
+    type record CommandReplyMsg
+    {
+        MsgHeader   header,             // standard message header
+        octetstring metadata,           // A BSON document containing any required metadata
+        octetstring commandArgs,        // A BSON document containing the command reply
+        octetstring inputDocs optional  // A variable number of BSON documents
+    }
+    with { variant "" }
+
+    // ==============================================================================
+    //
+    // Generic mongoDB message definitions
+    //
+    // ==============================================================================
+
+    // ------------------------------------------------------------------------------
+    // generic mongoDB message (union of all message types)
+    // ------------------------------------------------------------------------------
+    type union Msg {
+        InsertMsg       insert,
+        UpdateMsg       update,
+        QueryMsg        query,
+        GetMoreMsg      getMore,
+        DeleteMsg       delete,
+        KillCursorMsg   killCursor,
+        CommandMsg      command,
+        ReplyMsg        reply_,
+        CommandReplyMsg commandReply,
+        octetstring     octects
+    } with {
+        variant (insert)        "TAG (header, opCode = OP_INSERT)";
+        variant (update)        "TAG (header, opCode = OP_UPDATE)";
+        variant (query)         "TAG (header, opCode = OP_QUERY)";
+        variant (getMore)       "TAG (header, opCode = OP_GET_MORE)";
+        variant (delete)        "TAG (header, opCode = OP_DELETE)";
+        variant (killCursor)    "TAG (header, opCode = OP_KILL_CURSORS)";
+        variant (command)       "TAG (header, opCode = OP_COMMAND)";
+        variant (reply_)        "TAG (header, opCode = OP_REPLY)";
+        variant (commandReply)  "TAG (header, opCode = OP_COMMANDREPLY)";
+    }
+
+    // ------------------------------------------------------------------------------
+    // generic encode and decode function for generic message type
+    // ------------------------------------------------------------------------------
+    external function encMsg (in Msg msg) return octetstring
+    with { extension "prototype(convert) encode(RAW)" }
+
+    external function decMsg (in octetstring octets) return Msg
+    with { extension "prototype(convert) decode(RAW)" }
+
+} with { encode "RAW" }