sync from Azure to LF

Change-Id: I9daba071938fd021b277d8d17d3c0822d23ac100
Signed-off-by: ss412g <shuky.har-noy@intl.att.com>
diff --git a/tools/xapp_mock/Dockerfile b/tools/xapp_mock/Dockerfile
new file mode 100644
index 0000000..48c07ae
--- /dev/null
+++ b/tools/xapp_mock/Dockerfile
@@ -0,0 +1,45 @@
+##############################################################################
+#
+#   Copyright (c) 2019 AT&T Intellectual Property.
+#
+#   Licensed 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.
+#
+##############################################################################
+
+FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu16-c-go:1-u16.04-nng1.1.1 as ubuntu
+
+WORKDIR /opt/xapp_mock
+COPY . . 
+ENV PATH=$PATH:/usr/local/go/bin:/usr/lib/go-1.12/bin
+# Install RMr library and dev files
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/master/packages/debian/stretch/rmr_1.3.0_amd64.deb/download.deb
+RUN dpkg -i rmr_1.3.0_amd64.deb
+RUN wget --content-disposition https://packagecloud.io/o-ran-sc/master/packages/debian/stretch/rmr-dev_1.3.0_amd64.deb/download.deb
+RUN dpkg -i rmr-dev_1.3.0_amd64.deb
+
+RUN go get github.com/pkg/errors 
+RUN go build main/xapp_mock.go 
+    
+
+
+FROM ubuntu:16.04
+COPY --from=ubuntu /opt/xapp_mock/xapp_mock /opt/xapp_mock/xapp_mock
+COPY --from=ubuntu /opt/xapp_mock/resources /opt/xapp_mock/resources
+COPY --from=ubuntu /usr/local/lib/librmr_nng.so.1 /usr/local/lib/librmr_nng.so.1
+COPY --from=ubuntu /usr/local/lib/libnng.so.1 /usr/local/lib/libnng.so.1
+WORKDIR /opt/xapp_mock
+ENV LD_LIBRARY_PATH=/usr/local/lib 
+ENV RMR_SEED_RT=resources/router.txt
+ENV RMR_PORT=5001
+#CMD mkdir -p resources/conf  exec ./xapp_mock
+CMD mkdir -p resources/conf &&  exec /bin/bash 
diff --git a/tools/xapp_mock/configuration.json b/tools/xapp_mock/configuration.json
new file mode 100644
index 0000000..9df43a1
--- /dev/null
+++ b/tools/xapp_mock/configuration.json
@@ -0,0 +1,4 @@
+[ 
+	{“id”: “RIC_X2_SETUP_REQ” , “rmrMessageType”: 10060, “transactionId”: “e2e$”, “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”,  “packedPayload”: "3137322e31372e302e357c353537377c74657374327c34367c0006002a000002001500080013302300fffff000140017000001f700133023fffff0000000133023000000000001" },
+	{“id”: “RIC_ENB_CONF_UPDATE_ACK_positive” ,  “rmrMessageType”: 10081, “transactionId”: “e2e$”, “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”,  “packedPayload”: "2025000a00000100f70003000000" } 
+]
diff --git a/tools/xapp_mock/frontend/configfile.go b/tools/xapp_mock/frontend/configfile.go
new file mode 100644
index 0000000..f332a0c
--- /dev/null
+++ b/tools/xapp_mock/frontend/configfile.go
@@ -0,0 +1,56 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+package frontend
+
+import (
+	"github.com/pkg/errors"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+)
+
+func ProcessConfigurationFile(resourcesFolder, inputFolder,  suffix string, processor func(data []byte) error) error {
+	cwd, err := os.Getwd()
+	if err != nil {
+		return errors.New(err.Error())
+	}
+	inputDir := filepath.Join(cwd, resourcesFolder, inputFolder)
+
+	files, err := ioutil.ReadDir(inputDir)
+	if err != nil {
+		return errors.New(err.Error())
+	}
+
+	for _, file := range files {
+		if file.Mode().IsRegular() && strings.HasSuffix(strings.ToLower(file.Name()), suffix) {
+			filespec := filepath.Join(inputDir, file.Name())
+
+			data, err := ioutil.ReadFile(filespec)
+			if err != nil {
+				return errors.New(err.Error())
+			}
+
+			err = processor(data)
+			if err != nil {
+				return err
+			}
+		}
+	}
+
+	return nil
+}
diff --git a/tools/xapp_mock/frontend/jsonDecoder.go b/tools/xapp_mock/frontend/jsonDecoder.go
new file mode 100644
index 0000000..0609db2
--- /dev/null
+++ b/tools/xapp_mock/frontend/jsonDecoder.go
@@ -0,0 +1,80 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+package frontend
+
+import (
+	"bytes"
+	"encoding/json"
+	"fmt"
+	"github.com/pkg/errors"
+	"io"
+)
+
+const (
+	SendRmrMessage  = "send"
+	ReceiveRmrMessage  = "receive"
+)
+
+
+type JsonCommand struct {
+ Id string
+ RmrMessageType  string
+ TransactionId string
+ RanName string
+ RanIp string
+ RanPort int
+ PayloadHeader string
+ PackedPayload string
+ Payload string
+ Action string
+ WaitForRmrMessageType string
+}
+
+// Id -> Command
+var Configuration = make(map[string]*JsonCommand)
+// Rmr Message Id -> Command
+var WaitedForRmrMessageType = make(map[int]*JsonCommand)
+
+func JsonCommandDecoder(data []byte, processor func (*JsonCommand) error ) error {
+	dec := json.NewDecoder(bytes.NewReader(data))
+	var cmd JsonCommand
+	if err := dec.Decode(&cmd); err != nil && err != io.EOF {
+		return errors.New(err.Error())
+	}
+	if err := processor (&cmd); err != nil {
+		return err
+	}
+	return nil
+}
+
+func JsonCommandsDecoder(data []byte, processor func (*JsonCommand) error ) error {
+	dec := json.NewDecoder(bytes.NewReader(data))
+	for {
+		var commands []JsonCommand
+		if err := dec.Decode(&commands); err == io.EOF {
+			break
+		} else if err != nil {
+			return errors.New(err.Error())
+		}
+		for i, cmd := range commands {
+			if err := processor(&cmd); err != nil {
+				return errors.New(fmt.Sprintf("processing error at #%d, %s",i,err))
+			}
+		}
+	}
+	return nil
+}
diff --git a/tools/xapp_mock/main/xapp_mock.go b/tools/xapp_mock/main/xapp_mock.go
new file mode 100644
index 0000000..ae2c601
--- /dev/null
+++ b/tools/xapp_mock/main/xapp_mock.go
@@ -0,0 +1,109 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+package main
+
+import (
+	"../frontend"
+	"../rmr"
+	"../sender"
+	"flag"
+	"fmt"
+	"github.com/pkg/errors"
+	"log"
+	"os"
+	"strconv"
+)
+
+const (
+	ENV_RMR_PORT = "RMR_PORT"
+	RMR_PORT_DEFAULT = 5001
+)
+
+var rmrService *rmr.Service
+
+func main() {
+	var rmrContext *rmr.Context
+
+	var rmrConfig rmr.Config = rmr.Config{Port: RMR_PORT_DEFAULT, MaxMsgSize: rmr.RMR_MAX_MSG_SIZE, MaxRetries: 3, Flags: 0}
+	if port, err := strconv.ParseUint(os.Getenv(ENV_RMR_PORT), 10, 16); err == nil {
+		rmrConfig.Port = int(port)
+	} else {
+		log.Printf("%s: %s, using default (%d).", ENV_RMR_PORT, err,RMR_PORT_DEFAULT)
+	}
+	rmrService = rmr.NewService(rmrConfig, rmrContext)
+
+	/* Load configuration file*/
+	err := frontend.ProcessConfigurationFile("resources","conf",  ".json",
+		func(data []byte) error {
+			return  frontend.JsonCommandsDecoder(data,jsonCommandsDecoderCB)
+		})
+	if err != nil {
+		log.Fatalf("processing Error: %s", err)
+	}
+
+	log.Print("xapp_mock is up and running.")
+
+	cmd:= flag.Arg(0) /*first remaining argument after flags have been processed*/
+	if err :=  frontend.JsonCommandDecoder([]byte(cmd),jsonCommandDecoderCB); err != nil {
+		log.Printf("command processing Error: %s", err)
+	}
+
+	rmrService.CloseContext()
+
+	log.Print("xapp_mock is down.")
+}
+
+
+// TODO: move callbacks to Dispatcher.
+func jsonCommandsDecoderCB(command *frontend.JsonCommand) error {
+	if len(command.Id) == 0{
+		return errors.New(fmt.Sprintf("invalid command, no Id"))
+	}
+	frontend.Configuration[command.Id] = command
+	if rmrMsgId, err := rmr.MessageIdToUint(command.WaitForRmrMessageType); err != nil {
+		return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
+	} else {
+		frontend.WaitedForRmrMessageType[int(rmrMsgId)] = command
+	}
+	return nil
+}
+
+// TODO: merge command with configuration
+func jsonCommandDecoderCB(command *frontend.JsonCommand) error {
+	if len(command.Id) == 0{
+		return errors.New(fmt.Sprintf("invalid command, no Id"))
+	}
+	switch command.Action {
+	case frontend.SendRmrMessage:
+		if  err := sender.SendJsonRmrMessage(*command, nil, rmrService); err != nil {
+			return err
+		}
+		if len(command.WaitForRmrMessageType) > 0 {
+			rmrService.ListenAndHandle() //TODO: handle error
+		}
+	case frontend.ReceiveRmrMessage:
+		if rmrMsgId, err := rmr.MessageIdToUint(command.RmrMessageType); err != nil {
+			return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
+		} else {
+			frontend.WaitedForRmrMessageType[int(rmrMsgId)] = command
+		}
+		rmrService.ListenAndHandle() //TODO: handle error
+	default:
+		return errors.New(fmt.Sprintf("invalid command action %s", command.Action))
+	}
+	return nil
+}
\ No newline at end of file
diff --git a/tools/xapp_mock/resources/router.txt b/tools/xapp_mock/resources/router.txt
new file mode 100644
index 0000000..1d3fea3
--- /dev/null
+++ b/tools/xapp_mock/resources/router.txt
@@ -0,0 +1,4 @@
+newrt|start
+rte|1001|10.0.2.15:38000
+rte|2002|10.0.2.15:3801
+newrt|end
diff --git a/tools/xapp_mock/resp b/tools/xapp_mock/resp
new file mode 100644
index 0000000..01f2657
--- /dev/null
+++ b/tools/xapp_mock/resp
@@ -0,0 +1 @@
+20060043000002001500080002f82900007a8000140030010000630002f8290007ab50102002f8290000010001330000640002f9290007ac50203202f82902f929000002000344
diff --git a/tools/xapp_mock/rmr/rmrCgoApi.go b/tools/xapp_mock/rmr/rmrCgoApi.go
new file mode 100644
index 0000000..7686ea8
--- /dev/null
+++ b/tools/xapp_mock/rmr/rmrCgoApi.go
@@ -0,0 +1,104 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+
+package rmr
+
+// #cgo LDFLAGS: -L/usr/local/lib -lrmr_nng -lnng
+// #include <rmr/rmr.h>
+// #include <stdlib.h>
+import "C"
+import (
+	"fmt"
+	"github.com/pkg/errors"
+	"time"
+	"unsafe"
+)
+
+func (*Context) Init(port string, maxMsgSize int, maxRetries int, flags int) *Messenger {
+	pp := C.CString(port)
+	defer C.free(unsafe.Pointer(pp))
+	ctx := NewContext(maxMsgSize, maxRetries, flags, C.rmr_init(pp, C.int(maxMsgSize), C.int(flags)))
+	start := time.Now()
+	for !ctx.IsReady() {
+		time.Sleep(time.Second)
+		if time.Since(start) >= time.Minute {
+			start = time.Now()
+		}
+	}
+	// Configure the rmr to make rounds of attempts to send a message before notifying the application that it should retry.
+	// Each round is about 1000 attempts with a short sleep between each round.
+	C.rmr_set_stimeout(ctx.RmrCtx, C.int(0))
+	r := Messenger(ctx)
+	return &r
+}
+
+func (ctx *Context) SendMsg(msg *MBuf) (*MBuf, error) {
+
+	allocatedCMBuf, err := ctx.getAllocatedCRmrMBuf(msg, ctx.MaxMsgSize)
+	if err != nil{
+		return nil, err
+	}
+	if state := allocatedCMBuf.state; state != RMR_OK {
+		errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to get allocated message. state: %v - %s", state, states[int(state)])
+		return nil, errors.New(errorMessage)
+	}
+	defer C.rmr_free_msg(allocatedCMBuf)
+
+	for i:=0; i < ctx.MaxRetries; i++ {
+		currCMBuf := C.rmr_send_msg(ctx.RmrCtx, allocatedCMBuf)
+		if state := currCMBuf.state; state != RMR_OK {
+			if state != RMR_ERR_RETRY {
+				errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to send message. state: %v - %s", state, states[int(state)])
+				return nil, errors.New(errorMessage)
+			}
+			time.Sleep(100*time.Millisecond)
+			continue
+		}
+		return convertToMBuf(currCMBuf)
+	}
+
+	return nil, errors.New(fmt.Sprintf("#rmrCgoApi.SendMsg - Too many retries"))
+}
+
+func (ctx *Context) RecvMsg() (*MBuf, error) {
+	allocatedCMBuf, err :=C.rmr_alloc_msg(ctx.RmrCtx, C.int(ctx.MaxMsgSize))
+	if err != nil{
+		return nil, err
+	}
+	if state := allocatedCMBuf.state;state != RMR_OK {
+		errorMessage := fmt.Sprintf("#rmrCgoApi.SendMsg - Failed to get allocated message. state: %v - %s", state, states[int(state)])
+		return nil, errors.New(errorMessage)
+	}
+	defer C.rmr_free_msg(allocatedCMBuf)
+
+	currCMBuf := C.rmr_rcv_msg(ctx.RmrCtx, allocatedCMBuf)
+	if state := currCMBuf.state; state != RMR_OK {
+		errorMessage := fmt.Sprintf("#rmrCgoApi.RecvMsg - Failed to receive message. state: %v - %s", state, states[int(state)])
+		return nil, errors.New(errorMessage)
+	}
+
+	return convertToMBuf(currCMBuf)
+}
+
+
+func (ctx *Context) IsReady() bool {
+	return int(C.rmr_ready(ctx.RmrCtx)) != 0
+}
+
+func (ctx *Context) Close() {
+	C.rmr_close(ctx.RmrCtx)
+}
diff --git a/tools/xapp_mock/rmr/rmrCgoTypes.go b/tools/xapp_mock/rmr/rmrCgoTypes.go
new file mode 100644
index 0000000..54d4f8f
--- /dev/null
+++ b/tools/xapp_mock/rmr/rmrCgoTypes.go
@@ -0,0 +1,123 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+
+package rmr
+
+// #cgo LDFLAGS: -L/usr/local/lib -lrmr_nng -lnng
+// #include <rmr/rmr.h>
+// #include <stdlib.h>
+import "C"
+import (
+	"fmt"
+	"unsafe"
+)
+
+func NewMBuf(mType int, len int, payload []byte, xAction []byte) *MBuf {
+	return &MBuf{
+		MType:   mType,
+		Len:     len,
+		Payload: payload,
+		XAction: xAction,
+	}
+}
+
+func NewContext(maxMsgSize int, maxRetries, flags int, ctx unsafe.Pointer) *Context {
+	return &Context{
+		MaxMsgSize: maxMsgSize,
+		MaxRetries: maxRetries,
+		Flags:      flags,
+		RmrCtx:     ctx,
+	}
+}
+
+const (
+	RMR_MAX_XACTION_LEN = int(C.RMR_MAX_XID)
+	RMR_MAX_MSG_SIZE    = int(C.RMR_MAX_RCV_BYTES)
+	RMR_MAX_MEID_LEN    = int(C.RMR_MAX_MEID)
+
+	//states
+	RMR_OK             = C.RMR_OK
+	RMR_ERR_BADARG     = C.RMR_ERR_BADARG
+	RMR_ERR_NOENDPT    = C.RMR_ERR_NOENDPT
+	RMR_ERR_EMPTY      = C.RMR_ERR_EMPTY
+	RMR_ERR_NOHDR      = C.RMR_ERR_NOHDR
+	RMR_ERR_SENDFAILED = C.RMR_ERR_SENDFAILED
+	RMR_ERR_CALLFAILED = C.RMR_ERR_CALLFAILED
+	RMR_ERR_NOWHOPEN   = C.RMR_ERR_NOWHOPEN
+	RMR_ERR_WHID       = C.RMR_ERR_WHID
+	RMR_ERR_OVERFLOW   = C.RMR_ERR_OVERFLOW
+	RMR_ERR_RETRY      = C.RMR_ERR_RETRY
+	RMR_ERR_RCVFAILED  = C.RMR_ERR_RCVFAILED
+	RMR_ERR_TIMEOUT    = C.RMR_ERR_TIMEOUT
+	RMR_ERR_UNSET      = C.RMR_ERR_UNSET
+	RMR_ERR_TRUNC      = C.RMR_ERR_TRUNC
+	RMR_ERR_INITFAILED = C.RMR_ERR_INITFAILED
+)
+
+var states = map[int]string{
+	RMR_OK:             "state is good",
+	RMR_ERR_BADARG:     "argument passd to function was unusable",
+	RMR_ERR_NOENDPT:    "send/call could not find an endpoint based on msg type",
+	RMR_ERR_EMPTY:      "msg received had no payload; attempt to send an empty message",
+	RMR_ERR_NOHDR:      "message didn't contain a valid header",
+	RMR_ERR_SENDFAILED: "send failed; errno has nano reason",
+	RMR_ERR_CALLFAILED: "unable to send call() message",
+	RMR_ERR_NOWHOPEN:   "no wormholes are open",
+	RMR_ERR_WHID:       "wormhole id was invalid",
+	RMR_ERR_OVERFLOW:   "operation would have busted through a buffer/field size",
+	RMR_ERR_RETRY:      "request (send/call/rts) failed, but caller should retry (EAGAIN for wrappers)",
+	RMR_ERR_RCVFAILED:  "receive failed (hard error)",
+	RMR_ERR_TIMEOUT:    "message processing call timed out",
+	RMR_ERR_UNSET:      "the message hasn't been populated with a transport buffer",
+	RMR_ERR_TRUNC:      "received message likely truncated",
+	RMR_ERR_INITFAILED: "initialisation of something (probably message) failed",
+}
+
+type MBuf struct {
+	MType   int
+	Len     int
+	Meid    string //Managed entity id (RAN name)*/
+	Payload []byte
+	XAction []byte
+}
+
+
+func (m MBuf) String() string {
+	return fmt.Sprintf("{ MType: %d, Len: %d, Meid: %q, Xaction: %q, Payload: [%x] }", m.MType, m.Len, m.Meid, m.XAction, m.Payload)
+}
+
+
+type Context struct {
+	MaxMsgSize     int
+	MaxRetries     int
+	Flags          int
+	RmrCtx         unsafe.Pointer
+}
+
+type Messenger interface {
+	Init(port string, maxMsgSize int, maxRetries int, flags int) *Messenger
+	SendMsg(msg *MBuf) (*MBuf, error)
+	RecvMsg() (*MBuf, error)
+	IsReady() bool
+	Close()
+}
+type Config struct {
+	Port       int
+	MaxMsgSize int
+	MaxRetries int
+	Flags      int
+}
diff --git a/tools/xapp_mock/rmr/rmrCgoUtils.go b/tools/xapp_mock/rmr/rmrCgoUtils.go
new file mode 100644
index 0000000..9b56785
--- /dev/null
+++ b/tools/xapp_mock/rmr/rmrCgoUtils.go
@@ -0,0 +1,116 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+
+package rmr
+
+// #cgo LDFLAGS: -L/usr/local/lib -lrmr_nng -lnng
+// #include <rmr/rmr.h>
+// #include <stdlib.h>
+import "C"
+import (
+	"bytes"
+	"encoding/binary"
+	"fmt"
+	"github.com/pkg/errors"
+	"strconv"
+	"strings"
+	"unsafe"
+)
+
+/*
+Allocates an mBuf and initialize it with the content of C.rmr_mbuf_t.
+The xAction field is assigned a a value without trailing spaces.
+*/
+func convertToMBuf( m *C.rmr_mbuf_t) (*MBuf, error) {
+	payloadArr := C.GoBytes(unsafe.Pointer(m.payload),C.int(m.len))
+	xActionArr := C.GoBytes(unsafe.Pointer(m.xaction),C.int(RMR_MAX_XACTION_LEN))
+
+	// Trim padding (space and 0)
+	xActionStr := strings.TrimRight(string(xActionArr), "\040\000")
+	xActionArr = []byte(xActionStr)
+
+	mbuf := &MBuf{
+		MType: int(m.mtype),
+		Len:   int(m.len),
+		//Payload: (*[]byte)(unsafe.Pointer(m.payload)),
+		Payload: payloadArr,
+		//XAction: (*[]byte)(unsafe.Pointer(m.xaction)),
+		XAction: xActionArr,
+	}
+
+	meidBuf := make([]byte, RMR_MAX_MEID_LEN)
+	if meidCstr := C.rmr_get_meid(m, (*C.uchar)(unsafe.Pointer(&meidBuf[0]))); meidCstr != nil {
+		mbuf.Meid =	strings.TrimRight(string(meidBuf), "\000")
+	}
+
+	return mbuf, nil
+}
+
+/*
+Allocates an C.rmr_mbuf_t and initialize it with the content of mBuf.
+The xAction field is padded with trailing spaces upto capacity
+*/
+func (ctx *Context) getAllocatedCRmrMBuf( mBuf *MBuf, maxMsgSize int) (cMBuf *C.rmr_mbuf_t, rc error) {
+	var xActionBuf [RMR_MAX_XACTION_LEN]byte
+	var meidBuf[RMR_MAX_MEID_LEN]byte
+
+	cMBuf = C.rmr_alloc_msg(ctx.RmrCtx, C.int(maxMsgSize))
+	cMBuf.mtype = C.int(mBuf.MType)
+	cMBuf.len = C.int(mBuf.Len)
+
+	payloadLen := len(mBuf.Payload)
+	xActionLen := len(mBuf.XAction)
+
+	copy(xActionBuf[:], mBuf.XAction)
+	for i:= xActionLen; i < RMR_MAX_XACTION_LEN; i++{
+		xActionBuf[i] = '\040' //space
+	}
+
+	// Add padding
+	copy(meidBuf[:], mBuf.Meid)
+	for i:= len(mBuf.Meid); i < RMR_MAX_MEID_LEN; i++{
+		meidBuf[i] = 0
+	}
+
+	payloadArr := (*[1 << 30]byte)(unsafe.Pointer(cMBuf.payload))[:payloadLen:payloadLen]
+	xActionArr := (*[1 << 30]byte)(unsafe.Pointer(cMBuf.xaction))[:RMR_MAX_XACTION_LEN:RMR_MAX_XACTION_LEN]
+
+	err := binary.Read(bytes.NewReader(mBuf.Payload), binary.LittleEndian, payloadArr)
+	if err != nil {
+		return nil, errors.New(fmt.Sprintf("#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to read payload to allocated RMR message buffer, %s", err))
+	}
+	err = binary.Read(bytes.NewReader(xActionBuf[:]), binary.LittleEndian, xActionArr)
+	if err != nil {
+		return nil, errors.New(fmt.Sprintf("#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to read xAction data to allocated RMR message buffer, %s", err))
+	}
+
+	len := C.rmr_bytes2meid(cMBuf,  (*C.uchar)(unsafe.Pointer(&meidBuf[0])), C.int(RMR_MAX_XACTION_LEN))
+	if int(len) != RMR_MAX_MEID_LEN {
+		return nil, errors.New(
+			"#rmrCgoUtils.getAllocatedCRmrMBuf - Failed to copy meid data to allocated RMR message buffer")
+	}
+	return cMBuf,nil
+}
+
+func MessageIdToUint(id string) (msgId uint64, err error) {
+	if len(id) == 0 {
+		msgId, err = 0, nil
+	} else{
+		msgId, err = strconv.ParseUint(id, 10, 16)
+	}
+	return
+}
\ No newline at end of file
diff --git a/tools/xapp_mock/rmr/rmrEndPoint.go b/tools/xapp_mock/rmr/rmrEndPoint.go
new file mode 100644
index 0000000..fc599a5
--- /dev/null
+++ b/tools/xapp_mock/rmr/rmrEndPoint.go
@@ -0,0 +1,68 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+package rmr
+
+import (
+	"../frontend"
+	"log"
+	"strconv"
+)
+// RmrService holds an instance of RMR messenger as well as its configuration
+type Service struct {
+	messenger  *Messenger
+}
+
+// NewRmrService instantiates a new Rmr service instance
+func NewService(rmrConfig Config, messenger Messenger) *Service {
+	return &Service{
+		messenger: messenger.Init("tcp:"+strconv.Itoa(rmrConfig.Port), rmrConfig.MaxMsgSize, rmrConfig.MaxRetries, rmrConfig.Flags),
+	}
+}
+
+func (r *Service) SendMessage(messageType int, msg []byte, transactionId []byte) (*MBuf, error){
+	log.Printf( "SendMessage (type: %d, tid: %s, msg: %v", messageType, transactionId, msg)
+	mbuf := NewMBuf(messageType, len(msg), msg, transactionId)
+	return (*r.messenger).SendMsg(mbuf)
+}
+
+// ListenAndHandle waits for messages coming from rmr_rcv_msg and sends it to a designated message handler
+func (r *Service) ListenAndHandle() error {
+	for {
+		mbuf, err := (*r.messenger).RecvMsg()
+
+		if err != nil {
+			return err
+		}
+
+		if _, ok := frontend.WaitedForRmrMessageType[mbuf.MType]; ok {
+			log.Printf( "ListenAndHandle Expected msg: %s", mbuf)
+			break
+		} else {
+			log.Printf( "ListenAndHandle Unexpected msg: %s", mbuf)
+		}
+	}
+	return nil
+}
+
+
+func (r *Service) CloseContext() {
+	(*r.messenger).Close()
+
+}
+
+
+
diff --git a/tools/xapp_mock/sender/jsonSender.go b/tools/xapp_mock/sender/jsonSender.go
new file mode 100644
index 0000000..b68ee9d
--- /dev/null
+++ b/tools/xapp_mock/sender/jsonSender.go
@@ -0,0 +1,146 @@
+//
+// Copyright 2019 AT&T Intellectual Property
+// Copyright 2019 Nokia
+//
+// Licensed 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.
+//
+package sender
+
+import (
+	"../frontend"
+	"../rmr"
+	"fmt"
+	"github.com/pkg/errors"
+	"log"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync/atomic"
+	"time"
+	"unicode"
+)
+
+var counter uint64
+
+func SendJsonRmrMessage(command frontend.JsonCommand /*the copy is modified locally*/, xAction *[]byte, r *rmr.Service) error {
+	var payload []byte
+	_, err := fmt.Sscanf(command.PackedPayload, "%x", &payload)
+	if err != nil {
+		return errors.New(fmt.Sprintf("convert inputPayloadAsStr to payloadAsByte. Error: %v\n", err))
+	}
+	command.PackedPayload = string(payload)
+	command.TransactionId = expandTransactionId(command.TransactionId)
+	if len(command.TransactionId) == 0 {
+		command.TransactionId = string(*xAction)
+	}
+	command.PayloadHeader = expandPayloadHeader(command.PayloadHeader, &command)
+	rmrMsgId, err := rmr.MessageIdToUint(command.RmrMessageType)
+	if err != nil {
+		return errors.New(fmt.Sprintf("invalid rmr message id: %s",command.WaitForRmrMessageType))
+	}
+	_, err = r.SendMessage(int(rmrMsgId), append([]byte(command.PayloadHeader), payload...), []byte(command.TransactionId))
+	return err
+}
+
+/*
+ * transactionId (xAction): The value may have a fixed value or $ or <prefix>$.
+ * $ is replaced by a value generated at runtime (possibly unique per message sent).
+ * If the tag does not exist, then the mock shall use the value taken from the incoming message.
+ */
+func expandTransactionId(id string) string {
+	if len(id) == 1 && id[0] == '$' {
+		return fmt.Sprintf("%d", incAndGetCounter())
+	}
+	if len(id) > 1 && id[len(id)-1] == '$' {
+		return fmt.Sprintf("%s%d", id[:len(id)-1], incAndGetCounter())
+	}
+	return id
+}
+
+/*
+ * payloadHeader: A prefix to combine with the payload that will be the message’s payload. The value may include variables of the format $<name> or #<name> where:
+ *   $<name> expands to the value of <name> if it exists or the empty string if not.
+ *   #<name> expands to the length of the value of <name> if it exists or omitted if not.
+ * The intention is to allow the Mock to construct the payload header required by the setup messages (ranIp|ranPort|ranName|payload len|<payload>).
+ * Example: “payloadHeader”: “$ranIp|$ranPort|$ranName|#packedPayload|”
+ */
+
+func expandPayloadHeader(header string, command *frontend.JsonCommand) string {
+	var name strings.Builder
+	var expandedHeader strings.Builder
+
+	r := strings.NewReader(header)
+	ch, err := r.ReadByte()
+	for {
+		if err != nil {
+			break
+		}
+		switch ch {
+		case '$':
+			for {
+				ch, err = r.ReadByte()	//on error ch == 0
+				if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
+					name.WriteByte(ch)
+				} else {
+					if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
+						switch fieldValue.Kind() {
+						case reflect.String:
+							expandedHeader.WriteString(fieldValue.String())
+						case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+							expandedHeader.WriteString(strconv.FormatInt(fieldValue.Int(), 10))
+						case reflect.Bool:
+							expandedHeader.WriteString(strconv.FormatBool(fieldValue.Bool()))
+						case reflect.Float64, reflect.Float32:
+							expandedHeader.WriteString(fmt.Sprintf("%g", fieldValue.Float()))
+						default:
+							log.Fatalf("invalid type for $%s, value must be a string, an int, a bool or a float", name.String())
+						}
+					}
+					name.Reset()
+					break
+				}
+			}
+		case '#':
+			for {
+				ch, err = r.ReadByte()	//on error ch == 0
+				if unicode.IsDigit(rune(ch)) || unicode.IsLetter(rune(ch)) {
+					name.WriteByte(ch)
+				} else {
+					if fieldValue := reflect.Indirect(reflect.ValueOf(command)).FieldByName(name.String()); fieldValue.IsValid() {
+						if fieldValue.Kind() == reflect.String {
+							expandedHeader.WriteString(strconv.FormatInt(int64(len(fieldValue.String())), 10))
+						} else {
+							log.Fatalf("invalid type for #%s, value must be a string", name.String())
+						}
+					}
+					name.Reset()
+					break
+				}
+			}
+		default:
+			if unicode.IsPrint(rune(ch)) {
+				expandedHeader.WriteByte(ch)
+			}
+			ch, err = r.ReadByte()
+		}
+	}
+	return expandedHeader.String()
+}
+
+func incAndGetCounter() uint64 {
+	return atomic.AddUint64(&counter, 1)
+}
+
+func init() {
+	counter = uint64(time.Now().Second())
+}