SEBA-902/SEBA-903
Test cases and Makefile created to test importer API's.
Robot Framework suite was also created with 1 test case for now pending additional information of hardware availability.

Change-Id: I0e1b1e573a25c5eab36b7e18ee7c79deea294828
diff --git a/demo_test/cmd_client/Note b/demo_test/cmd_client/Note
index b72578a..4e2a6ba 100644
--- a/demo_test/cmd_client/Note
+++ b/demo_test/cmd_client/Note
@@ -58,7 +58,7 @@
 									delete 192.168.4.27:8888 192.168.4.26:8888
 --------------------------------------------------------------------------------------
 Get Current List of Devices monitored					showdevices
-									Return from server: 192.168.4.26:8888,192.168.4.27:8888
+									Return from server: 192.168.4.26:8888 192.168.4.27:8888
 --------------------------------------------------------------------------------------
 UnSubscribe all events(ResourceAdded/ResourceRemoved/Alert)		unsub:192.168.4.27:8888:add:rm:alert
 =======
diff --git a/demo_test/cmd_client/cmd_cl.go b/demo_test/cmd_client/cmd_cl.go
index 067f8f4..da19079 100644
--- a/demo_test/cmd_client/cmd_cl.go
+++ b/demo_test/cmd_client/cmd_cl.go
@@ -18,6 +18,7 @@
 import "fmt"
 import "bufio"
 import "os"
+import "strings"
 
 func main() {
 	// connect to this socket
@@ -27,7 +28,8 @@
 	for {
 		// read in input from stdin
 		fmt.Print("CMD to send : ")
-		text, _ := reader.ReadString('\n')
+		text, _ := reader.ReadString(';')
+		text = strings.TrimSuffix(text, ";")
 		// send to socket
 		fmt.Fprintf(conn, text+"\n")
 
diff --git a/demo_test/functional_test/Makefile b/demo_test/functional_test/Makefile
new file mode 100644
index 0000000..0775546
--- /dev/null
+++ b/demo_test/functional_test/Makefile
@@ -0,0 +1,52 @@
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+SHELL = /bin/bash
+DEMOTESTDIR = ..
+TESTSDIR = tests
+TESTTAG = tc
+TESTS := $(wildcard ${TESTSDIR}/*.$(TESTTAG))
+
+.PHONY : check-arg test demotest $(TESTS) clean
+
+.DEFAULT_GOAL := dm
+
+check-arg:
+ifeq ($(strip $(TESTS)),)
+	$(error no test found)
+endif
+ifeq "$(and $(IP1),$(PORT1),$(IP2),$(PORT2))" "" 
+	$(error IP1, PORT1, IP2, and PORT2 are not all defined)
+endif
+
+demotest:
+	@cd ${DEMOTESTDIR}; make demotest || exit 1; ./demotest & \
+	sleep 2
+
+dm: test_cli.go
+	go build -i -v -o $@
+
+test: check-arg dm demotest $(TESTS) clean
+	@echo "Alll tests passed!"
+
+$(TESTS): ${TESTSDIR}/%.${TESTTAG}:
+	@sed -e '/^\/\//d' -e 's/ip1/${IP1}/g; s/port1/${PORT1}/g; s/ip2/${IP2}/g; s/port2/${PORT2}/g' ${TESTSDIR}/$*.expected > ${TESTSDIR}/$*.e
+#	@sed -i '/^\/\//d' ${TESTSDIR}/$*.e
+	@echo "===== Running test $@"
+	@./$@ $(IP1) $(PORT1) $(IP2) $(PORT2) > /dev/null > ${TESTSDIR}/$*.out
+	@diff -q ${TESTSDIR}/$*.out ${TESTSDIR}/$*.e || (pkill demotest; exit 1)
+	@rm ${TESTSDIR}/*.out ${TESTSDIR}/*.e
+
+clean:
+	@pkill demotest
diff --git a/demo_test/functional_test/README b/demo_test/functional_test/README
new file mode 100644
index 0000000..f8dd0e6
--- /dev/null
+++ b/demo_test/functional_test/README
@@ -0,0 +1,120 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+
+
+'dm' is a command line wrapper of the test application 'demotest' serving the purpose of device-management API functional testing.
+
+It runs on top of the device-management container and 'demotest' requiring the accessibility of at least 2 separate devices running RedFish servers and can be utilized in either automated or manual testing. Either way, the device-mangement container needs to have been deployed (Please refer to Device Management Deployment Guide).
+
+1. Test Automation
+   Test cases utilizing 'dm' are provided in the tests/ sub-directory. They can be executed through either the Makefile or the Robot Framework test suite that are provided.
+
+   a) Makefile
+      At command line, type
+	make test IP1=<ip of 1st device> PORT1=<RF port # of 1st device> IP2=<ip of 2nd device> PORT2=<RF port # of 2nd device>
+
+   b) Robot Framework
+      i) Make and launch 'demotest', which ls located one level up, first.
+      ii) Modify the test suite with the appropriate ip's and port #'s of the RF servers
+      iii) At command line, type
+	robot importer.robot
+
+2. Manual testing at command line
+   To build 'dm', at command line, type
+	make
+   To run 'dm', please make and launch 'demotest' first then follow the syntax and examples below.
+
+-------------------------------------------------------------------------------
+register one device
+Example: Set IP 192.168.4.27 port 8888 freq 180
+./dm attach 192.168.4.27:8888:180
+
+-------------------------------------------------------------------------------
+register multiple devices
+Example: Set "IP 192.168.4.27 port 8888 freq 180" and "IP 192.168.4.26 port 8888 freq 120"
+./dm attach 192.168.4.27:8888:180 192.168.4.26:8888:120
+
+-------------------------------------------------------------------------------
+delete devices
+Example: Delete "IP 192.168.4.27" and "IP 192.168.3.34"
+./dm delete 192.168.4.27:8888 192.168.4.26:8888
+
+-------------------------------------------------------------------------------
+Get Current List of Devices monitored
+./dm showdevices
+Sample output: 192.168.4.26:8888 192.168.4.27:8888
+
+-------------------------------------------------------------------------------
+UnSubscribe all events(ResourceAdded/ResourceRemoved/Alert)
+./dm cleardeviceeventlist 192.168.4.27:8888
+
+-------------------------------------------------------------------------------
+Subscribe all events(ResourceAdded/ResourceRemoved/Alert)
+./dm sub 192.168.4.27:8888:add:rm:alert
+
+-------------------------------------------------------------------------------
+Subscribe and unsubscribe an event
+Example:
+Subscribe ResourceAdded event
+./dm sub 192.168.4.27:8888:add
+Subscribe ResourceRemoved event
+./dm sub 192.168.4.27:8888:rm
+Subscribe Alert event
+./dm sub 192.168.4.27:8888:alert
+Unsubscribe ResourceAdded event
+./dm unsub 192.168.4.27:8888:add
+Unsubscribe ResourceRemoved event
+./dm unsub 192.168.4.27:8888:rm
+Unsubscribe Alert event
+./dm unsub 192.168.4.27:8888:alert
+
+-------------------------------------------------------------------------------
+Subscribe an unsupported event
+./dm sub 192.168.4.27:8888:update
+
+-------------------------------------------------------------------------------
+Subscribe to an already subscribed event
+Example:
+./dm sub 192.168.4.27:8888:add
+./dm sub 192.168.4.27:8888:add
+
+-------------------------------------------------------------------------------
+Unsubscribe an unsupported event
+./dm unsub 192.168.4.27:8888:update
+
+-------------------------------------------------------------------------------
+Unsubscribe a supported but not-subscribed event
+Example:
+./dm unsub 192.168.4.27:8888:add:rm:alert
+./dm unsub 192.168.4.27:8888:add
+./dm unsub 192.168.4.27:8888:rm
+./dm unsub 192.168.4.27:8888:alert
+
+-------------------------------------------------------------------------------
+Change polling interval
+Example:
+Set frequecny to 30 seconds
+./dm period 192.168.4.27:8888:30
+
+-------------------------------------------------------------------------------
+Show list of supported event
+./dm showeventlist 192.168.4.27:8888
+
+-------------------------------------------------------------------------------
+Show current events subscribed by device
+showdeviceeventlist 192.168.4.27:8888
+
+-------------------------------------------------------------------------------
+Note: following command can be used to verify the list of events subscribed
+wget --no-check-certificate -qO- https://192.168.4.27:8888/redfish/v1/EventService/Subscriptions | python -m json.tool
diff --git a/demo_test/functional_test/importer.robot b/demo_test/functional_test/importer.robot
new file mode 100644
index 0000000..4abcd60
--- /dev/null
+++ b/demo_test/functional_test/importer.robot
@@ -0,0 +1,28 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+
+*** Settings ***
+Library           Process
+Library           OperatingSystem
+
+*** Test Cases ***
+List Supported Events
+    [Documentation]    This test case excercises the API, GetEventList, which is expected to list all supported Redfish events.
+    ${IP}    set variable    192.168.4.26
+    ${PORT}    set variable    8888
+    ${EXPECTED}=    RUN    sed -e '/^\\/\\//d' -e 's/ipaddr/${IP}:${PORT}/g' tests/list_supported_events.expected
+    Run Process    tests/list_supported_events.tc    ${IP}:${PORT}    shell=yes    alias=myproc
+    ${OUTPUT}=    get process result    myproc
+    Should Be Equal    ${EXPECTED}    ${OUTPUT.stdout}
+
diff --git a/demo_test/functional_test/test_cli.go b/demo_test/functional_test/test_cli.go
new file mode 100644
index 0000000..114c51b
--- /dev/null
+++ b/demo_test/functional_test/test_cli.go
@@ -0,0 +1,35 @@
+// Copyright 2018-present Open Networking Foundation
+//
+// 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 "net"
+import "fmt"
+import "bufio"
+import "os"
+import "strings"
+
+func main() {
+	// connect to this socket
+	var message string = ""
+	cmdstr := strings.Join(os.Args[1:], " ")
+	conn, _ := net.Dial("tcp", "127.0.0.1:9999")
+	// send to socket
+	fmt.Fprintf(conn, cmdstr + "\n")
+
+	// listen for reply
+	message, _ = bufio.NewReader(conn).ReadString(';')
+	message = strings.TrimSuffix(message, ";")
+	fmt.Print(message)
+}
diff --git a/demo_test/functional_test/tests/add_device_to_monitor.expected b/demo_test/functional_test/tests/add_device_to_monitor.expected
new file mode 100644
index 0000000..64812fb
--- /dev/null
+++ b/demo_test/functional_test/tests/add_device_to_monitor.expected
@@ -0,0 +1,18 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+ip1:port1 ip2:port2 attached
+Device ip ip1 already registered
+Device ip ip1 already registered
+invalid command ip1:88
+ip1:port1 ip2:port2 deleted
diff --git a/demo_test/functional_test/tests/add_device_to_monitor.tc b/demo_test/functional_test/tests/add_device_to_monitor.tc
new file mode 100755
index 0000000..4584e81
--- /dev/null
+++ b/demo_test/functional_test/tests/add_device_to_monitor.tc
@@ -0,0 +1,21 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm attach $1:$2:120 $3:$4:100
+./dm attach $1:$2:120
+./dm attach $1:88:120
+./dm attach $1:88
+./dm delete $1:$2 $3:$4
diff --git a/demo_test/functional_test/tests/clear_all_subscribed_events.expected b/demo_test/functional_test/tests/clear_all_subscribed_events.expected
new file mode 100644
index 0000000..25e732c
--- /dev/null
+++ b/demo_test/functional_test/tests/clear_all_subscribed_events.expected
@@ -0,0 +1,18 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+192.168.4.27:8888 attached
+Alert ResourceAdded ResourceRemoved
+192.168.4.27:8888 events cleared
+
+192.168.4.27:8888 deleted
diff --git a/demo_test/functional_test/tests/clear_all_subscribed_events.tc b/demo_test/functional_test/tests/clear_all_subscribed_events.tc
new file mode 100755
index 0000000..f5eef7a
--- /dev/null
+++ b/demo_test/functional_test/tests/clear_all_subscribed_events.tc
@@ -0,0 +1,21 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm attach 192.168.4.27:8888:120
+./dm showdeviceeventlist 192.168.4.27:8888
+./dm cleardeviceeventlist 192.168.4.27:8888
+./dm showdeviceeventlist 192.168.4.27:8888
+./dm delete 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/configure_data_polling_interval.expected b/demo_test/functional_test/tests/configure_data_polling_interval.expected
new file mode 100644
index 0000000..b3e56c1
--- /dev/null
+++ b/demo_test/functional_test/tests/configure_data_polling_interval.expected
@@ -0,0 +1,18 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+192.168.4.27:8888 attached
+data collection interval configured to 30 seconds
+Invalid interval
+data collection interval configured to 0 seconds
+192.168.4.27:8888 deleted
diff --git a/demo_test/functional_test/tests/configure_data_polling_interval.tc b/demo_test/functional_test/tests/configure_data_polling_interval.tc
new file mode 100755
index 0000000..0939a79
--- /dev/null
+++ b/demo_test/functional_test/tests/configure_data_polling_interval.tc
@@ -0,0 +1,21 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm attach 192.168.4.27:8888:120
+./dm period 192.168.4.27:8888:30
+./dm period 192.168.4.27:8888:3
+./dm period 192.168.4.27:8888:0
+./dm delete 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/delete_monitored_device.expected b/demo_test/functional_test/tests/delete_monitored_device.expected
new file mode 100644
index 0000000..8e1cc31
--- /dev/null
+++ b/demo_test/functional_test/tests/delete_monitored_device.expected
@@ -0,0 +1,16 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+192.168.4.26:8888 192.168.4.27:8888 attached
+192.168.4.26:8888 192.168.4.27:8888 deleted
+Device 192.168.4.27:8888 not found
diff --git a/demo_test/functional_test/tests/delete_monitored_device.tc b/demo_test/functional_test/tests/delete_monitored_device.tc
new file mode 100755
index 0000000..7860e0b
--- /dev/null
+++ b/demo_test/functional_test/tests/delete_monitored_device.tc
@@ -0,0 +1,19 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm attach 192.168.4.27:8888:120 192.168.4.26:8888:100
+./dm delete 192.168.4.27:8888 192.168.4.26:8888
+./dm delete 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/list_device_monitored.expected b/demo_test/functional_test/tests/list_device_monitored.expected
new file mode 100644
index 0000000..2f98be3
--- /dev/null
+++ b/demo_test/functional_test/tests/list_device_monitored.expected
@@ -0,0 +1,17 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+No Device found
+192.168.4.26:8888 192.168.4.27:8888 attached
+192.168.4.26:8888 192.168.4.27:8888
+192.168.4.26:8888 192.168.4.27:8888 deleted
diff --git a/demo_test/functional_test/tests/list_device_monitored.tc b/demo_test/functional_test/tests/list_device_monitored.tc
new file mode 100755
index 0000000..0016968
--- /dev/null
+++ b/demo_test/functional_test/tests/list_device_monitored.tc
@@ -0,0 +1,20 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm showdevices
+./dm attach 192.168.4.26:8888:120 192.168.4.27:8888:100
+./dm showdevices
+./dm delete 192.168.4.26:8888 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/list_subscribed_events.expected b/demo_test/functional_test/tests/list_subscribed_events.expected
new file mode 100644
index 0000000..ad6f141
--- /dev/null
+++ b/demo_test/functional_test/tests/list_subscribed_events.expected
@@ -0,0 +1,17 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+Device 192.168.4.26:8888 not registered
+192.168.4.26:8888 attached
+Alert ResourceAdded ResourceRemoved
+192.168.4.26:8888 deleted
diff --git a/demo_test/functional_test/tests/list_subscribed_events.tc b/demo_test/functional_test/tests/list_subscribed_events.tc
new file mode 100755
index 0000000..819aaeb
--- /dev/null
+++ b/demo_test/functional_test/tests/list_subscribed_events.tc
@@ -0,0 +1,20 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm showdeviceeventlist 192.168.4.26:8888
+./dm attach 192.168.4.26:8888:120
+./dm showdeviceeventlist 192.168.4.26:8888
+./dm delete 192.168.4.26:8888
diff --git a/demo_test/functional_test/tests/list_supported_events.expected b/demo_test/functional_test/tests/list_supported_events.expected
new file mode 100644
index 0000000..27a563f
--- /dev/null
+++ b/demo_test/functional_test/tests/list_supported_events.expected
@@ -0,0 +1,17 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+Device 192.168.4.27:8888 not registered
+192.168.4.26:8888 attached
+Alert ResourceAdded ResourceRemoved
+192.168.4.26:8888 deleted
diff --git a/demo_test/functional_test/tests/list_supported_events.tc b/demo_test/functional_test/tests/list_supported_events.tc
new file mode 100755
index 0000000..dff2eed
--- /dev/null
+++ b/demo_test/functional_test/tests/list_supported_events.tc
@@ -0,0 +1,20 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm showeventlist 192.168.4.27:8888
+./dm attach 192.168.4.26:8888:120
+./dm showeventlist 192.168.4.26:8888
+./dm delete 192.168.4.26:8888
diff --git a/demo_test/functional_test/tests/subscribe_events.expected b/demo_test/functional_test/tests/subscribe_events.expected
new file mode 100644
index 0000000..73e9325
--- /dev/null
+++ b/demo_test/functional_test/tests/subscribe_events.expected
@@ -0,0 +1,19 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+Device 192.168.4.27:8888 not registered
+192.168.4.27:8888 attached
+Alert ResourceAdded ResourceRemoved
+event ResourceAdded already subscribed
+event Update not supported
+192.168.4.27:8888 deleted
diff --git a/demo_test/functional_test/tests/subscribe_events.tc b/demo_test/functional_test/tests/subscribe_events.tc
new file mode 100755
index 0000000..41abd92
--- /dev/null
+++ b/demo_test/functional_test/tests/subscribe_events.tc
@@ -0,0 +1,22 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm sub 192.168.4.27:8888:add
+./dm attach 192.168.4.27:8888:120
+./dm showdeviceeventlist 192.168.4.27:8888
+./dm sub 192.168.4.27:8888:add
+./dm sub 192.168.4.27:8888:update
+./dm delete 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/unsubscribe_events.expected b/demo_test/functional_test/tests/unsubscribe_events.expected
new file mode 100644
index 0000000..eee0d10
--- /dev/null
+++ b/demo_test/functional_test/tests/unsubscribe_events.expected
@@ -0,0 +1,21 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+Device 192.168.4.27:8888 not registered
+192.168.4.27:8888 attached
+Alert ResourceAdded ResourceRemoved
+unsub successful
+Alert ResourceRemoved
+event ResourceAdded not found
+event Update not found
+192.168.4.27:8888 deleted
diff --git a/demo_test/functional_test/tests/unsubscribe_events.tc b/demo_test/functional_test/tests/unsubscribe_events.tc
new file mode 100755
index 0000000..df9d440
--- /dev/null
+++ b/demo_test/functional_test/tests/unsubscribe_events.tc
@@ -0,0 +1,24 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm unsub 192.168.4.27:8888:add
+./dm attach 192.168.4.27:8888:120
+./dm showdeviceeventlist 192.168.4.27:8888
+./dm unsub 192.168.4.27:8888:add
+./dm showdeviceeventlist 192.168.4.27:8888
+./dm unsub 192.168.4.27:8888:add
+./dm unsub 192.168.4.27:8888:update
+./dm delete 192.168.4.27:8888
diff --git a/demo_test/functional_test/tests/validate_ip.expected b/demo_test/functional_test/tests/validate_ip.expected
new file mode 100644
index 0000000..ab281ef
--- /dev/null
+++ b/demo_test/functional_test/tests/validate_ip.expected
@@ -0,0 +1,17 @@
+// Copyright 2018 Open Networking Foundation
+//
+// 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.
+Incorrect IP address format (<ip>:<port #>)
+Invalid IP address 192.168.4
+Port # 8a needs to be an integer
+Device 192.168.4.27:8888 not registered
diff --git a/demo_test/functional_test/tests/validate_ip.tc b/demo_test/functional_test/tests/validate_ip.tc
new file mode 100755
index 0000000..64bdd39
--- /dev/null
+++ b/demo_test/functional_test/tests/validate_ip.tc
@@ -0,0 +1,20 @@
+#!/bin/bash  
+
+# Copyrigh/ 2019-present Open Networking Foundation
+#
+# 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.
+
+./dm showeventlist 192.168.4.27
+./dm showeventlist 192.168.4:8
+./dm showeventlist 192.168.4.27:8a
+./dm showeventlist 192.168.4.27:8888
diff --git a/demo_test/test.go b/demo_test/test.go
index 9fcd888..e67f200 100644
--- a/demo_test/test.go
+++ b/demo_test/test.go
@@ -32,6 +32,7 @@
 	"os/signal"
 	"strconv"
 	"strings"
+	"sort"
 )
 
 var REDFISH_ROOT = "/redfish/v1"
@@ -133,11 +134,6 @@
 	}
 	defer ln.Close()
 
-	connS, err := ln.Accept()
-	if err != nil {
-		fmt.Println("Accept error")
-		log.Fatalf("Accept error: %v", err)
-	}
 	conn, err = grpc.Dial(default_address, grpc.WithInsecure())
 	if err != nil {
 		fmt.Println("could not connect")
@@ -151,6 +147,11 @@
 	loop := true
 
 	for loop == true {
+		connS, err := ln.Accept()
+		if err != nil {
+			fmt.Println("Accept error")
+			log.Fatal("Accept error: %v", err)
+		}
 		cmdstr, _ := bufio.NewReader(connS).ReadString('\n')
 		cmdstr = strings.TrimSuffix(cmdstr, "\n")
 		s := strings.Split(cmdstr, " ")
@@ -161,7 +162,7 @@
 
 		case "attach":
 			if len(s) < 2 {
-				newmessage = newmessage + "invalid command " + cmdstr + "\n"
+				newmessage = newmessage + "invalid command length" + cmdstr + "\n"
 				break
 			}
 			var devicelist importer.DeviceList
@@ -183,12 +184,16 @@
 				devicelist.Device = append(devicelist.Device, deviceinfo)
 				ipattached = append(ipattached, deviceinfo.IpAddress)
 			}
+			if len(devicelist.Device) == 0 {
+				break
+			}
 			_, err := cc.SendDeviceList(ctx, &devicelist)
 			if err != nil {
 				errStatus, _ := status.FromError(err)
-				newmessage = newmessage + errStatus.Message() + "\n"
+				newmessage = newmessage + errStatus.Message()
 				fmt.Printf("attach error - status code %v message %v", errStatus.Code(), errStatus.Message())
 			} else {
+				sort.Strings(ipattached)
 				ips := strings.Join(ipattached, " ")
 				newmessage = newmessage + ips + " attached\n"
 			}
@@ -199,14 +204,23 @@
 			}
 			var devicelist importer.DeviceListByIp
 			for _, ip := range s[1:] {
+				addr := strings.Split(ip, ":")
+				if len(addr) != 2 {
+					newmessage = newmessage + "invalid address " + ip + "\n"
+					continue
+				}
 				devicelist.Ip = append(devicelist.Ip, ip)
 			}
+			if len(devicelist.Ip) == 0 {
+				break
+			}
 			_, err := cc.DeleteDeviceList(ctx, &devicelist)
 			if err != nil {
 				errStatus, _ := status.FromError(err)
-				newmessage = newmessage + errStatus.Message() + "\n"
+				newmessage = newmessage + errStatus.Message()
 				fmt.Printf("delete error - status code %v message %v", errStatus.Code(), errStatus.Message())
 			} else {
+				sort.Strings(devicelist.Ip)
 				ips := strings.Join(devicelist.Ip, " ")
 				newmessage = newmessage + ips + " deleted\n"
 			}
@@ -256,11 +270,14 @@
 					giveneventlist.Events = append(giveneventlist.Events, value)
 				}
 			}
+			if len(giveneventlist.Events) == 0 {
+				newmessage = newmessage + "No valid event was given\n"
+			}
 			var err error
 			if cmd == "sub" {
-				_, err = cc.SubsrcribeGivenEvents(ctx, giveneventlist)
+				_, err = cc.SubscribeGivenEvents(ctx, giveneventlist)
 			} else {
-				_, err = cc.UnSubsrcribeGivenEvents(ctx, giveneventlist)
+				_, err = cc.UnsubscribeGivenEvents(ctx, giveneventlist)
 			}
 			if err != nil {
 				errStatus, _ := status.FromError(err)
@@ -271,7 +288,7 @@
 			}
 		case "showeventlist":
 			if len(s) != 2 {
-				newmessage = newmessage + "invalid command " + s[1] + "\n"
+				newmessage = newmessage + "invalid command " + cmdstr + "\n"
 				break
 			}
 			currentdeviceinfo := new(importer.Device)
@@ -283,7 +300,9 @@
 				fmt.Printf("showeventlist error - status code %v message %v", errStatus.Code(), errStatus.Message())
 			} else {
 				fmt.Print("showeventlist ", ret_msg.Events)
-				newmessage = strings.Join(ret_msg.Events[:], ",")
+				sort.Strings(ret_msg.Events[:])
+				newmessage = strings.Join(ret_msg.Events[:], " ")
+				newmessage = newmessage + "\n"
 			}
 		case "showdeviceeventlist":
 			if len(s) != 2 {
@@ -299,7 +318,9 @@
 				newmessage = newmessage + errStatus.Message()
 			} else {
 				fmt.Print("showdeviceeventlist ", ret_msg.Events)
-				newmessage = strings.Join(ret_msg.Events[:], ",")
+				sort.Strings(ret_msg.Events[:])
+				newmessage = strings.Join(ret_msg.Events[:], " ")
+				newmessage = newmessage + "\n"
 			}
 		case "cleardeviceeventlist":
 			if len(s) != 2 {
@@ -337,13 +358,15 @@
 					fmt.Print("showdevices error!!")
 				} else {
 					fmt.Print("showdevices ", currentlist)
-					newmessage = strings.Join(currentlist[:], ", ")
+					sort.Strings(currentlist[:])
+					newmessage = strings.Join(currentlist[:], " ")
+					newmessage = newmessage + "\n"
 				}
 			}
 		default:
 			newmessage = newmessage + "invalid command " + cmdstr + "\n"
 		}
-		// send string back to client
-		connS.Write([]byte(newmessage + "\n"))
+			// send string back to client
+		connS.Write([]byte(newmessage + ";"))
 	}
 }
diff --git a/main.go b/main.go
index 4f05c88..c17926c 100644
--- a/main.go
+++ b/main.go
@@ -33,6 +33,8 @@
 	"os/signal"
 	"path"
 	"time"
+	"strings"
+	"strconv"
 )
 
 //globals
@@ -76,9 +78,8 @@
 func (s *Server) ClearCurrentEventList(c context.Context, info *importer.Device) (*empty.Empty, error) {
 	fmt.Println("Received ClearCurrentEventList")
 	ip_address := info.IpAddress
-	_, found := s.devicemap[ip_address]
-	if !found {
-		return nil, status.Errorf(codes.NotFound, "Device not registered")
+	if msg, ok := s.validate_ip(ip_address, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
 	}
 	for event, _ := range s.devicemap[ip_address].Subscriptions {
 		rtn := s.remove_subscription(ip_address, event)
@@ -93,10 +94,9 @@
 }
 
 func (s *Server) GetCurrentEventList(c context.Context, info *importer.Device) (*importer.EventList, error) {
-	fmt.Println("Received GetCurrentEventList")
-	_, found := s.devicemap[info.IpAddress]
-	if !found {
-		return nil, status.Errorf(codes.NotFound, "Device not registered")
+	fmt.Println("Received GetCurrentEventList\n")
+	if msg, ok := s.validate_ip(info.IpAddress, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
 	}
 	currentevents := new(importer.EventList)
 	for event, _ := range s.devicemap[info.IpAddress].Subscriptions {
@@ -106,24 +106,26 @@
 }
 
 func (s *Server) GetEventList(c context.Context, info *importer.Device) (*importer.EventList, error) {
-	fmt.Println("Received GetEventList")
+	fmt.Println("Received GetEventList\n")
+	if msg, ok := s.validate_ip(info.IpAddress, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
+	}
 	eventstobesubscribed := new(importer.EventList)
-	//	eventstobesubscribed.Events = s.devicemap[info.IpAddress].Eventtypes
-	eventstobesubscribed.Events = s.get_event_types(info.IpAddress)
+//	eventstobesubscribed.Events = s.devicemap[info.IpAddress].Eventtypes
+	eventstobesubscribed.Events = s.devicemap[info.IpAddress].Eventtypes
 	if eventstobesubscribed.Events == nil {
-		return nil, status.Errorf(codes.NotFound, "No events found")
+		return nil, status.Errorf(codes.NotFound, "No events found\n")
 	}
 	return eventstobesubscribed, nil
 }
 
 func (s *Server) SetFrequency(c context.Context, info *importer.FreqInfo) (*empty.Empty, error) {
 	fmt.Println("Received SetFrequency")
-	_, found := s.devicemap[info.IpAddress]
-	if !found {
-		return nil, status.Errorf(codes.NotFound, "Device not registered")
+	if msg, ok := s.validate_ip(info.IpAddress, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
 	}
 	if info.Frequency > 0 && info.Frequency < RF_DATA_COLLECT_THRESHOLD {
-		return nil, status.Errorf(codes.InvalidArgument, "Invalid frequency")
+		return nil, status.Errorf(codes.InvalidArgument, "Invalid interval\n")
 	}
 	s.devicemap[info.IpAddress].Freqchan <- info.Frequency
 	s.devicemap[info.IpAddress].Freq = info.Frequency
@@ -131,26 +133,38 @@
 	return &empty.Empty{}, nil
 }
 
-func (s *Server) SubsrcribeGivenEvents(c context.Context, subeventlist *importer.GivenEventList) (*empty.Empty, error) {
+func (s *Server) SubscribeGivenEvents(c context.Context, subeventlist *importer.GivenEventList) (*empty.Empty, error) {
 	errstring := ""
 	fmt.Println("Received SubsrcribeEvents")
 	//Call API to subscribe events
 	ip_address := subeventlist.EventIpAddress
-	_, found := s.devicemap[ip_address]
-	if !found {
-		return nil, status.Errorf(codes.NotFound, "Device not registered")
+	if msg, ok := s.validate_ip(ip_address, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
 	}
 	if len(subeventlist.Events) <= 0 {
-		return nil, status.Errorf(codes.InvalidArgument, "Event list is empty")
+		return nil, status.Errorf(codes.InvalidArgument, "Event list is empty\n")
 	}
 	for _, event := range subeventlist.Events {
 		if _, ok := s.devicemap[ip_address].Subscriptions[event]; !ok {
-			rtn := s.add_subscription(ip_address, event)
-			if !rtn {
-				errstring = errstring + "failed to subscribe event " + ip_address + " " + event + "\n"
+			supported := false
+			for _, e := range s.devicemap[ip_address].Eventtypes{
+				if e == event {
+					supported = true
+					rtn := s.add_subscription(ip_address, event)
+					if !rtn {
+						errstring = errstring + "failed to subscribe event " + ip_address + " " + event + "\n"
+						log.WithFields(log.Fields{
+							"Event": event,
+						}).Info("Error adding  event")
+					}
+					break
+				}
+			}
+			if supported == false {
+				errstring = errstring + "event " + event + " not supported\n"
 				log.WithFields(log.Fields{
 					"Event": event,
-				}).Info("Error adding  event")
+				}).Info("not supported")
 			}
 		} else {
 			errstring = errstring + "event " + event + " already subscribed\n"
@@ -166,17 +180,16 @@
 	return &empty.Empty{}, nil
 }
 
-func (s *Server) UnSubsrcribeGivenEvents(c context.Context, unsubeventlist *importer.GivenEventList) (*empty.Empty, error) {
+func (s *Server) UnsubscribeGivenEvents(c context.Context, unsubeventlist *importer.GivenEventList) (*empty.Empty, error) {
 	errstring := ""
 	fmt.Println("Received UnSubsrcribeEvents")
 	ip_address := unsubeventlist.EventIpAddress
-	_, found := s.devicemap[ip_address]
-	if !found {
-		return nil, status.Errorf(codes.NotFound, "Device not registered")
+	if msg, ok := s.validate_ip(ip_address, true, true); !ok {
+		return nil, status.Errorf(codes.InvalidArgument, msg)
 	}
 
 	if len(unsubeventlist.Events) <= 0 {
-		return nil, status.Errorf(codes.InvalidArgument, "Event list is empty")
+		return nil, status.Errorf(codes.InvalidArgument, "Event list is empty\n")
 	}
 	//Call API to unsubscribe events
 	for _, event := range unsubeventlist.Events {
@@ -309,14 +322,12 @@
 	errstring := ""
 	for _, dev := range list.Device {
 		ip_address := dev.IpAddress
-		if _, ok := s.devicemap[dev.IpAddress]; ok {
-			fmt.Printf("Device %s already exists", ip_address)
-			errstring = errstring + "Device " + ip_address + " already exists\n"
+		if msg, ok := s.validate_ip(ip_address, false, false); !ok {
+			errstring = errstring + msg
 			continue
 		}
-
 		if dev.Frequency > 0 && dev.Frequency < RF_DATA_COLLECT_THRESHOLD {
-			fmt.Printf("Device %s data collection frequency %d out of range", ip_address, dev.Frequency)
+			fmt.Printf("Device %s data collection interval %d out of range", ip_address, dev.Frequency)
 			errstring = errstring + "Device " + ip_address + " data collection frequency out of range\n"
 			continue
 		}
@@ -365,7 +376,7 @@
 	fmt.Println("In Received GetCurrentDevices")
 
 	if len(s.devicemap) == 0 {
-		return nil, status.Errorf(codes.NotFound, "Devices not registered")
+		return nil, status.Errorf(codes.NotFound, "No Device found\n")
 	}
 	dl := new(importer.DeviceListByIp)
 	for k, v := range s.devicemap {
@@ -445,6 +456,60 @@
 	http.ListenAndServeTLS(":8080", "https-server.crt", "https-server.key", nil)
 }
 
+/* validate_ip() verifies if the ip and port are valid and already registered then return the truth value of the desired state specified by the following 2 switches,
+   want_registered: 'true' if the fact of an ip is registered is the desired state
+   include_port: 'true' further checks if <ip>:<port#> does exist in the devicemap in case an ip is found registered 
+*/
+func (s *Server) validate_ip(ip_address string, want_registered bool, include_port bool) (msg string, ok bool) {
+	msg = ""
+	ok = false
+	if !strings.Contains(ip_address, ":") {
+		fmt.Printf("Incorrect IP address %s, expected format <ip>:<port #>", ip_address)
+		msg = "Incorrect IP address format (<ip>:<port #>)\n"
+		return
+	}
+	splits := strings.Split(ip_address, ":")
+	ip, port := splits[0], splits[1]
+	if net.ParseIP(ip) == nil {
+		fmt.Printf("Invalid IP address %s", ip)
+		msg = "Invalid IP address " + ip + "\n"
+		return
+	}
+	if _, err := strconv.Atoi(port); err != nil {
+		fmt.Printf("Port # %s is not an integer", port)
+		msg = "Port # " + port + " needs to be an integer\n"
+		return
+	}
+	for k := range s.devicemap {
+		if strings.HasPrefix(k, ip) {
+			if !want_registered {
+				fmt.Printf("Device ip %s already registered", ip)
+				msg = "Device ip " + ip + " already registered\n"
+				return
+			} else if include_port {
+				if _, found := s.devicemap[ip_address]; found {
+					ok = true
+					return
+				} else {
+					fmt.Printf("Device %s not registered", ip_address)
+					msg = "Device " + ip_address + " not registered\n"
+					return
+				}
+			} else {
+				ok = true
+				return
+			}
+		}
+	}
+	if want_registered {
+		fmt.Printf("Device %s not registered", ip_address)
+		msg = "Device " + ip_address + " not registered\n"
+		return
+	}
+	ok = true
+	return
+}
+
 func (s *Server) init_data_persistence() {
 	fmt.Println("Retrieving persisted data")
 	subscriptionListPath = pvmount + "/subscriptions"
diff --git a/proto/importer.proto b/proto/importer.proto
index 58d8772..8056952 100644
--- a/proto/importer.proto
+++ b/proto/importer.proto
@@ -49,9 +49,9 @@
 
     rpc GetEventList(Device) returns (EventList) {}
 
-    rpc SubsrcribeGivenEvents(GivenEventList)  returns (google.protobuf.Empty) {}
+    rpc SubscribeGivenEvents(GivenEventList)  returns (google.protobuf.Empty) {}
 
-    rpc UnSubsrcribeGivenEvents(GivenEventList) returns (google.protobuf.Empty) {}
+    rpc UnsubscribeGivenEvents(GivenEventList) returns (google.protobuf.Empty) {}
 
     rpc GetCurrentEventList(Device) returns (EventList) {}