VOL-1552 - inital stub
remove extra file

Change-Id: I9f5c93eefbde51c64a7c1b13244eca3a16de8a41
diff --git a/cli/main.go b/cli/main.go
new file mode 100644
index 0000000..a20fbf4
--- /dev/null
+++ b/cli/main.go
@@ -0,0 +1,63 @@
+/*
+   * 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 (
+	"flag"
+	"fmt"
+	"log"
+	"os/exec"
+
+	"github.com/opencord/voltha-go/cli/menu/mainmenu"
+	"google.golang.org/grpc"
+)
+
+func main() {
+
+	// disable input buffering
+	exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
+	// do not display entered characters on the screen
+	exec.Command("stty", "-F", "/dev/tty", "-echo").Run()
+	printHeader()
+
+	volthaAddress := flag.String("voltha_address", "localhost:6161", "IP/Hostname:Port for Voltha Core")
+	h := flag.Bool("h", false, "Print help")
+	help := flag.Bool("help", false, "Print help")
+	flag.Parse()
+	if *h || *help {
+		fmt.Println("cli -h(elp) print this message")
+		fmt.Println("cli -voltha_address=$VOLTHA_ADDRESS:PORT default localhost:6161")
+		return
+	}
+	conn, err := grpc.Dial(*volthaAddress, grpc.WithInsecure())
+	if err != nil {
+		log.Fatalf("did not connect: %s", err)
+	}
+	defer conn.Close()
+	fmt.Println("Connecting to " + *volthaAddress)
+
+	mainmenu.MainLoop(conn)
+}
+func printHeader() {
+	header :=
+		`         _ _   _            ___ _    ___
+__ _____| | |_| |_  __ _   / __| |  |_ _|
+\ V / _ \ |  _| ' \/ _' | | (__| |__ | |
+ \_/\___/_|\__|_||_\__,_|  \___|____|___|
+`
+	fmt.Println(header)
+}
diff --git a/cli/menu/devicemenu/deviceMenu.go b/cli/menu/devicemenu/deviceMenu.go
new file mode 100644
index 0000000..a435f16
--- /dev/null
+++ b/cli/menu/devicemenu/deviceMenu.go
@@ -0,0 +1,84 @@
+/*
+   * 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 devicemenu
+
+import (
+	"fmt"
+
+	"github.com/bclicn/color"
+	"github.com/opencord/voltha-go/cli/util"
+	"google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var (
+	Conn        *grpc.ClientConn
+	DeviceId    *string
+	InputPrompt *string
+	Commands    *[]string
+)
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn, deviceId string) {
+
+	DeviceId = &deviceId
+	inputPrompt := fmt.Sprint("(" + color.LightRed("device "+deviceId) + ") ")
+	InputPrompt = &inputPrompt
+	funcTable := make(map[string]func(bool))
+	//	inputPromptSize := len(inputPrompt)
+	Conn = conn
+	funcTable["quit"] = util.Exit
+	funcTable["exit"] = nil
+	funcTable["edit"] = doEdit
+	funcTable["history"] = doHistory
+	funcTable["img_dnld_request"] = doImgDnldRequest
+	funcTable["perf_config"] = doPerfConfig
+	funcTable["save"] = doSave
+	funcTable["eof"] = doEof
+	funcTable["images"] = doImages
+	funcTable["img_dnld_status"] = doImgDnldStatus
+	funcTable["ports"] = doPorts
+	funcTable["set"] = doSet
+	funcTable["img_activate"] = doImgActivate
+	funcTable["img_revert"] = doImgRevert
+	funcTable["py"] = doPy
+	funcTable["shell"] = doShell
+	funcTable["flows"] = doFlows
+	funcTable["img_dnld_canel"] = doImgDnldCancel
+	funcTable["list"] = doList
+	funcTable["shortcuts"] = doShortCuts
+	funcTable["help"] = doHelp
+	funcTable["img_dnld_list"] = doImgDnldList
+	funcTable["pause"] = doPause
+	funcTable["run"] = doRun
+	funcTable["show"] = doShow
+
+	commands := make([]string, len(funcTable))
+	i := 0
+	for key, _ := range funcTable {
+		commands[i] = key
+		i++
+	}
+	Commands = &commands
+
+	util.ProcessTable(funcTable, inputPrompt)
+
+}
diff --git a/cli/menu/devicemenu/edit.go b/cli/menu/devicemenu/edit.go
new file mode 100644
index 0000000..c5c1e8e
--- /dev/null
+++ b/cli/menu/devicemenu/edit.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doEdit(enterPressed bool) {
+	fmt.Println("doEdit")
+}
diff --git a/cli/menu/devicemenu/eof.go b/cli/menu/devicemenu/eof.go
new file mode 100644
index 0000000..4d752fb
--- /dev/null
+++ b/cli/menu/devicemenu/eof.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doEof(enterPressed bool) {
+	fmt.Println("doEof")
+}
diff --git a/cli/menu/devicemenu/flows.go b/cli/menu/devicemenu/flows.go
new file mode 100644
index 0000000..9a648b2
--- /dev/null
+++ b/cli/menu/devicemenu/flows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doFlows(enterPressed bool) {
+	fmt.Println("doFlows")
+}
diff --git a/cli/menu/devicemenu/help.go b/cli/menu/devicemenu/help.go
new file mode 100644
index 0000000..340817d
--- /dev/null
+++ b/cli/menu/devicemenu/help.go
@@ -0,0 +1,96 @@
+/*
+   * 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 devicemenu
+
+import (
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/opencord/voltha-go/cli/util"
+)
+
+func doHelp(enterPressed bool) {
+	input := ""
+	var b = make([]byte, 1)
+	inputPrompt := *InputPrompt + "help "
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			if enterPressed {
+				baseHelp()
+				return
+			}
+
+			fmt.Println("")
+			ret, prompt := util.Test(input, *Commands)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "quit" {
+					util.Exit(true)
+				} else if input == "exit" {
+					return
+				}
+
+				MainLoop(Conn, input)
+				return
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Print("Invalid Input \n" + inputPrompt)
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print(prompt + inputPrompt)
+			}
+		} else if b[0] == 127 || char == "\b" {
+
+			sz := len(input)
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+			if !(strings.HasPrefix(input, "device")) {
+				return
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+}
+func baseHelp() {
+	message := `
+Documented commands (type help <topic>):
+========================================
+edit   help          img_dnld_cancel   img_revert   ports  set
+eof    history       img_dnld_list     list         py     shell
+exit   images        img_dnld_request  pause        run    shortcuts
+flows  img_activate  img_dnld_status   perf_config  save   show
+
+Miscellaneous help topics:
+==========================
+load
+
+Undocumented commands:
+======================
+quit
+
+`
+	fmt.Println(message)
+}
diff --git a/cli/menu/devicemenu/history.go b/cli/menu/devicemenu/history.go
new file mode 100644
index 0000000..b4d2423
--- /dev/null
+++ b/cli/menu/devicemenu/history.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doHistory(enterPressed bool) {
+	fmt.Println("doHistory")
+}
diff --git a/cli/menu/devicemenu/images.go b/cli/menu/devicemenu/images.go
new file mode 100644
index 0000000..dc2105e
--- /dev/null
+++ b/cli/menu/devicemenu/images.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImages(enterPressed bool) {
+	fmt.Println("doImages")
+}
diff --git a/cli/menu/devicemenu/img_activate.go b/cli/menu/devicemenu/img_activate.go
new file mode 100644
index 0000000..b615c1b
--- /dev/null
+++ b/cli/menu/devicemenu/img_activate.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgActivate(enterPressed bool) {
+	fmt.Println("doImgActivate")
+}
diff --git a/cli/menu/devicemenu/img_dnld_cancel.go b/cli/menu/devicemenu/img_dnld_cancel.go
new file mode 100644
index 0000000..cc9881d
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_cancel.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldCancel(enterPressed bool) {
+	fmt.Println("doImgDnldCancel")
+}
diff --git a/cli/menu/devicemenu/img_dnld_list.go b/cli/menu/devicemenu/img_dnld_list.go
new file mode 100644
index 0000000..ea6d31f
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_list.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldList(enterPressed bool) {
+	fmt.Println("doImgDnldList")
+}
diff --git a/cli/menu/devicemenu/img_dnld_request.go b/cli/menu/devicemenu/img_dnld_request.go
new file mode 100644
index 0000000..1a0ee98
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_request.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldRequest(enterPressed bool) {
+	fmt.Println("doImgDnldRequest")
+}
diff --git a/cli/menu/devicemenu/img_dnld_status.go b/cli/menu/devicemenu/img_dnld_status.go
new file mode 100644
index 0000000..2177996
--- /dev/null
+++ b/cli/menu/devicemenu/img_dnld_status.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgDnldStatus(enterPressed bool) {
+	fmt.Println("doImgDnldStatus")
+}
diff --git a/cli/menu/devicemenu/img_revert.go b/cli/menu/devicemenu/img_revert.go
new file mode 100644
index 0000000..bac7b37
--- /dev/null
+++ b/cli/menu/devicemenu/img_revert.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doImgRevert(enterPressed bool) {
+	fmt.Println("doImgRevert")
+}
diff --git a/cli/menu/devicemenu/list.go b/cli/menu/devicemenu/list.go
new file mode 100644
index 0000000..053fec9
--- /dev/null
+++ b/cli/menu/devicemenu/list.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doList(enterPressed bool) {
+	fmt.Println("doList")
+}
diff --git a/cli/menu/devicemenu/pause.go b/cli/menu/devicemenu/pause.go
new file mode 100644
index 0000000..6fec137
--- /dev/null
+++ b/cli/menu/devicemenu/pause.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPause(enterPressed bool) {
+	fmt.Println("doPause")
+}
diff --git a/cli/menu/devicemenu/perf_config.go b/cli/menu/devicemenu/perf_config.go
new file mode 100644
index 0000000..bdc9ab4
--- /dev/null
+++ b/cli/menu/devicemenu/perf_config.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPerfConfig(enterPressed bool) {
+	fmt.Println("doPrefConfig")
+}
diff --git a/cli/menu/devicemenu/ports.go b/cli/menu/devicemenu/ports.go
new file mode 100644
index 0000000..4b1aefb
--- /dev/null
+++ b/cli/menu/devicemenu/ports.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPorts(enterPressed bool) {
+	fmt.Println("doPorts")
+}
diff --git a/cli/menu/devicemenu/py.go b/cli/menu/devicemenu/py.go
new file mode 100644
index 0000000..8a489fd
--- /dev/null
+++ b/cli/menu/devicemenu/py.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doPy(enterPressed bool) {
+	fmt.Println("doPy")
+}
diff --git a/cli/menu/devicemenu/run.go b/cli/menu/devicemenu/run.go
new file mode 100644
index 0000000..081fddb
--- /dev/null
+++ b/cli/menu/devicemenu/run.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doRun(enterPressed bool) {
+	fmt.Println("doRun")
+}
diff --git a/cli/menu/devicemenu/save.go b/cli/menu/devicemenu/save.go
new file mode 100644
index 0000000..ba4ef89
--- /dev/null
+++ b/cli/menu/devicemenu/save.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doSave(enterPressed bool) {
+	fmt.Println("doSave")
+}
diff --git a/cli/menu/devicemenu/set.go b/cli/menu/devicemenu/set.go
new file mode 100644
index 0000000..c8d8a15
--- /dev/null
+++ b/cli/menu/devicemenu/set.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doSet(enterPressed bool) {
+	fmt.Println("doSet")
+}
diff --git a/cli/menu/devicemenu/shell.go b/cli/menu/devicemenu/shell.go
new file mode 100644
index 0000000..cffbcbd
--- /dev/null
+++ b/cli/menu/devicemenu/shell.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doShell(enterPressed bool) {
+	fmt.Println("doShell")
+}
diff --git a/cli/menu/devicemenu/shortcuts.go b/cli/menu/devicemenu/shortcuts.go
new file mode 100644
index 0000000..14596d0
--- /dev/null
+++ b/cli/menu/devicemenu/shortcuts.go
@@ -0,0 +1,23 @@
+/*
+   * 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 devicemenu
+
+import "fmt"
+
+func doShortCuts(enterPressed bool) {
+	fmt.Println("doShortCuts")
+}
diff --git a/cli/menu/devicemenu/show.go b/cli/menu/devicemenu/show.go
new file mode 100644
index 0000000..b9e22bd
--- /dev/null
+++ b/cli/menu/devicemenu/show.go
@@ -0,0 +1,88 @@
+/*
+   * 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 devicemenu
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/common"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doShow(enterPressed bool) {
+	client := voltha.NewVolthaServiceClient(Conn)
+	fmt.Println(*DeviceId)
+	device, err := client.GetDevice(context.Background(), &common.ID{Id: *DeviceId})
+	if err != nil {
+		fmt.Println(err)
+	}
+	fields := []string{"field", "value"}
+	var rows []map[string]string
+
+	id := make(map[string]string)
+	id["field"] = "id"
+	id["value"] = device.Id
+	rows = append(rows, id)
+
+	Type := make(map[string]string)
+	Type["field"] = "type"
+	Type["value"] = device.Type
+	rows = append(rows, Type)
+
+	parentId := make(map[string]string)
+	parentId["field"] = "parent_id"
+	parentId["value"] = device.ParentId
+	rows = append(rows, parentId)
+
+	vlan := make(map[string]string)
+	vlan["field"] = "vlan"
+	vlan["value"] = strconv.FormatUint(uint64(device.Vlan), 10)
+	rows = append(rows, vlan)
+
+	adminState := make(map[string]string)
+	adminState["field"] = "admin_state"
+	adminState["value"] = strconv.FormatUint(uint64(device.AdminState), 10)
+	rows = append(rows, adminState)
+
+	proxyAddress := device.GetProxyAddress()
+	proxyDeviceId := make(map[string]string)
+	proxyDeviceId["field"] = "proxy_address.device_id"
+	proxyDeviceId["value"] = proxyAddress.DeviceId
+	rows = append(rows, proxyDeviceId)
+
+	proxyDeviceType := make(map[string]string)
+	proxyDeviceType["field"] = "proxy_address.device_type"
+	proxyDeviceType["value"] = proxyAddress.DeviceType
+	rows = append(rows, proxyDeviceType)
+
+	proxyChannelId := make(map[string]string)
+	proxyChannelId["field"] = "proxy_address.channel_id"
+	proxyChannelId["value"] = strconv.FormatUint(uint64(proxyAddress.ChannelId), 10)
+	rows = append(rows, proxyChannelId)
+
+	parentPortNumber := make(map[string]string)
+	parentPortNumber["field"] = "parent_port_no"
+	parentPortNumber["value"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+	rows = append(rows, parentPortNumber)
+
+	output, _ := util.BuildTable(fields, rows)
+
+	fmt.Println(output)
+}
diff --git a/cli/menu/mainmenu/Makefile b/cli/menu/mainmenu/Makefile
new file mode 100644
index 0000000..fd522a5
--- /dev/null
+++ b/cli/menu/mainmenu/Makefile
@@ -0,0 +1,13 @@
+VOLTHA_PROTO_PATH := protos/voltha_protos
+VOLTHA_PROTO_FILES := $(wildcard protos/voltha_protos/*.proto)
+VOLTHA_PROTO_GO_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.pb.go,$(f)))
+VOLTHA_PROTO_DESC_FILES := $(foreach f,$(VOLTHA_PROTO_FILES),$(subst .proto,.desc,$(f)))
+
+voltha-api: $(VOLTHA_PROTO_GO_FILES)
+
+%.pb.go: %.proto
+	@protoc -I ${VOLTHA_PROTO_PATH} \
+                --go_out=plugins=grpc:${VOLTHA_PROTO_PATH} \
+                -I${GOPATH}/src \
+                -I${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
+                $<
diff --git a/cli/menu/mainmenu/alarmFilters.go b/cli/menu/mainmenu/alarmFilters.go
new file mode 100644
index 0000000..4a1b274
--- /dev/null
+++ b/cli/menu/mainmenu/alarmFilters.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doAlarmFilters(enterPressed bool) {
+	fmt.Print("input: alarm_filters>")
+}
diff --git a/cli/menu/mainmenu/arriveOnus.go b/cli/menu/mainmenu/arriveOnus.go
new file mode 100644
index 0000000..75e6263
--- /dev/null
+++ b/cli/menu/mainmenu/arriveOnus.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doArriveOnus(enterPressed bool) {
+	fmt.Print("input: arrive_onus>")
+}
diff --git a/cli/menu/mainmenu/cmdEnvironment.go b/cli/menu/mainmenu/cmdEnvironment.go
new file mode 100644
index 0000000..0342e87
--- /dev/null
+++ b/cli/menu/mainmenu/cmdEnvironment.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doCmdEnvironment(enterPressed bool) {
+	fmt.Println("input: doCmdEnvironment> ")
+}
diff --git a/cli/menu/mainmenu/delete.go b/cli/menu/mainmenu/delete.go
new file mode 100644
index 0000000..9b9f49b
--- /dev/null
+++ b/cli/menu/mainmenu/delete.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDelete(enterPressed bool) {
+	fmt.Println("input: delete > ")
+}
diff --git a/cli/menu/mainmenu/deleteAllFlows.go b/cli/menu/mainmenu/deleteAllFlows.go
new file mode 100644
index 0000000..9888fa9
--- /dev/null
+++ b/cli/menu/mainmenu/deleteAllFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDeleteAllFlows(enterPressed bool) {
+	fmt.Print("input: delete_all_flows>")
+}
diff --git a/cli/menu/mainmenu/device.go b/cli/menu/mainmenu/device.go
new file mode 100644
index 0000000..45b35a9
--- /dev/null
+++ b/cli/menu/mainmenu/device.go
@@ -0,0 +1,87 @@
+/*
+   * 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 mainmenu
+
+import (
+	"context"
+	"fmt"
+	"os"
+	"strings"
+
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/cli/menu/devicemenu"
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+func doDevice(enterPressed bool) {
+	fmt.Print(" ")
+	client := voltha.NewVolthaServiceClient(Conn)
+	devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+	items := devices.GetItems()
+	if err != nil {
+		fmt.Println(err)
+	}
+	deviceIds := []string{"exit", "quit"}
+	for i := 0; i < len(items); i++ {
+		deviceIds = append(deviceIds, items[i].Id)
+	}
+	var b = make([]byte, 1)
+	input := ""
+
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			fmt.Println("")
+			ret, prompt := util.Test(input, deviceIds)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "quit" {
+					util.Exit(true)
+				} else if input == "exit" {
+					return
+				}
+
+				devicemenu.MainLoop(Conn, input)
+				return
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Print("Invalid Input \ninput:")
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print("input: " + prompt)
+			}
+		} else if b[0] == 127 || char == "\b" {
+
+			sz := len(input)
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+			if !(strings.HasPrefix(input, "device")) {
+				return
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+
+}
diff --git a/cli/menu/mainmenu/devices.go b/cli/menu/mainmenu/devices.go
new file mode 100644
index 0000000..f5ef716
--- /dev/null
+++ b/cli/menu/mainmenu/devices.go
@@ -0,0 +1,78 @@
+/*
+   * 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 mainmenu
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	"github.com/golang/protobuf/ptypes/empty"
+	"github.com/opencord/voltha-go/cli/util"
+	"github.com/opencord/voltha-protos/go/voltha"
+)
+
+/*
+ reason | proxy_address.device_id | proxy_address.onu_id | proxy_address.onu_session_id |
+*/
+func doDevices(enterPressed bool) {
+
+	client := voltha.NewVolthaServiceClient(Conn)
+	devices, err := client.ListDevices(context.Background(), &empty.Empty{})
+	if err != nil {
+		fmt.Println(err)
+	}
+	var rows []map[string]string
+	items := devices.GetItems()
+	var fields = []string{"id", "type", "root", "parent_id", "serial_number", "admin_state", "oper_status", "connect_status", "parent_port_no", "host_and_port", "reason",
+		"proxy_address.device_id", "proxy_address.onu_id", "proxy_address.onu_session_id"}
+
+	for i := 0; i < len(items); i++ {
+		//fmt.Println(items[i])
+		device := items[i]
+		row := make(map[string]string)
+		row["id"] = device.Id
+		row["type"] = device.Type
+		row["root"] = strconv.FormatBool(device.Root)
+		row["parent_id"] = device.ParentId
+		row["serial_number"] = device.SerialNumber
+		row["admin_state"] = device.AdminState.String()
+		row["oper_status"] = device.OperStatus.String()
+		row["connect_status"] = device.ConnectStatus.String()
+		row["parent_port_no"] = strconv.FormatUint(uint64(device.GetParentPortNo()), 10)
+		row["host_and_port"] = device.GetHostAndPort()
+		row["reason"] = device.Reason
+		proxyAddress := device.GetProxyAddress()
+		if proxyAddress != nil {
+			row["proxy_address.device_id"] = proxyAddress.DeviceId
+			row["proxy_address.onu_id"] = strconv.FormatUint(uint64(proxyAddress.OnuId), 10)
+			row["proxy_address.onu_session_id"] = strconv.FormatUint(uint64(proxyAddress.OnuSessionId), 10)
+		} else {
+			row["proxy_address.device_id"] = ""
+			row["proxy_address.onu_id"] = ""
+			row["proxy_address.onu_session_id"] = ""
+		}
+
+		rows = append(rows, row)
+	}
+	output, err := util.BuildTable(fields, rows)
+	if err != nil {
+		fmt.Println(err)
+	}
+	fmt.Print(output)
+
+}
diff --git a/cli/menu/mainmenu/disable.go b/cli/menu/mainmenu/disable.go
new file mode 100644
index 0000000..45d86af
--- /dev/null
+++ b/cli/menu/mainmenu/disable.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doDisable(enterPressed bool) {
+	fmt.Print("input: disable>")
+}
diff --git a/cli/menu/mainmenu/enable.go b/cli/menu/mainmenu/enable.go
new file mode 100644
index 0000000..3068c72
--- /dev/null
+++ b/cli/menu/mainmenu/enable.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doEnable(enterPressed bool) {
+	fmt.Print("input: enable>")
+}
diff --git a/cli/menu/mainmenu/health.go b/cli/menu/mainmenu/health.go
new file mode 100644
index 0000000..562ff9b
--- /dev/null
+++ b/cli/menu/mainmenu/health.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doHealth(enterPressed bool) {
+	fmt.Print("input: health>")
+}
diff --git a/cli/menu/mainmenu/injectEapolStart.go b/cli/menu/mainmenu/injectEapolStart.go
new file mode 100644
index 0000000..8015013
--- /dev/null
+++ b/cli/menu/mainmenu/injectEapolStart.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInjectEapolStart(enterPressed bool) {
+	fmt.Print("input: inject_eapol_start>")
+}
diff --git a/cli/menu/mainmenu/installAllControllerBoundFlows.go b/cli/menu/mainmenu/installAllControllerBoundFlows.go
new file mode 100644
index 0000000..c994831
--- /dev/null
+++ b/cli/menu/mainmenu/installAllControllerBoundFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallAllControllerBoundFlows(enterPressed bool) {
+	fmt.Print("input: install_all_controller_bound_flows>")
+}
diff --git a/cli/menu/mainmenu/installAllSampleFlows.go b/cli/menu/mainmenu/installAllSampleFlows.go
new file mode 100644
index 0000000..a9d08e4
--- /dev/null
+++ b/cli/menu/mainmenu/installAllSampleFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallAllSampleFlows(enterPressed bool) {
+	fmt.Print("input: install_all_sample_flows>")
+}
diff --git a/cli/menu/mainmenu/installDhcpFlows.go b/cli/menu/mainmenu/installDhcpFlows.go
new file mode 100644
index 0000000..799867d
--- /dev/null
+++ b/cli/menu/mainmenu/installDhcpFlows.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallDhcpFlows(enterPressed bool) {
+	fmt.Print("input: install_dhcp_flows>")
+}
diff --git a/cli/menu/mainmenu/installEapolFlow.go b/cli/menu/mainmenu/installEapolFlow.go
new file mode 100644
index 0000000..2a76bae
--- /dev/null
+++ b/cli/menu/mainmenu/installEapolFlow.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doInstallEapolFlow(enterPressed bool) {
+	fmt.Print("input: install_eapol_flow>")
+}
diff --git a/cli/menu/mainmenu/launch.go b/cli/menu/mainmenu/launch.go
new file mode 100644
index 0000000..818e5a4
--- /dev/null
+++ b/cli/menu/mainmenu/launch.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLaunch(enterPressed bool) {
+	fmt.Print("input: launch")
+}
diff --git a/cli/menu/mainmenu/load.go b/cli/menu/mainmenu/load.go
new file mode 100644
index 0000000..20fd7c7
--- /dev/null
+++ b/cli/menu/mainmenu/load.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLoad(enterPressed bool) {
+	fmt.Println("input: load>")
+}
diff --git a/cli/menu/mainmenu/log.go b/cli/menu/mainmenu/log.go
new file mode 100644
index 0000000..d94c4cf
--- /dev/null
+++ b/cli/menu/mainmenu/log.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLog(enterPressed bool) {
+	fmt.Print("input: log>")
+}
diff --git a/cli/menu/mainmenu/logicalDevice.go b/cli/menu/mainmenu/logicalDevice.go
new file mode 100644
index 0000000..9e306ec
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevice.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLogicalDevice(enterPressed bool) {
+	fmt.Print("input: logical_device>")
+}
diff --git a/cli/menu/mainmenu/logicalDevices.go b/cli/menu/mainmenu/logicalDevices.go
new file mode 100644
index 0000000..5d6f2fc
--- /dev/null
+++ b/cli/menu/mainmenu/logicalDevices.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doLogicalDevices(enterPressed bool) {
+	fmt.Print("input: logical_devices>")
+}
diff --git a/cli/menu/mainmenu/mainMenu.go b/cli/menu/mainmenu/mainMenu.go
new file mode 100644
index 0000000..3d57892
--- /dev/null
+++ b/cli/menu/mainmenu/mainMenu.go
@@ -0,0 +1,75 @@
+/*
+   * 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 mainmenu
+
+import (
+	"fmt"
+
+	"github.com/bclicn/color"
+	"github.com/opencord/voltha-go/cli/util"
+	"google.golang.org/grpc"
+)
+
+/*
+Conn - the grpc connection to use for making calls to voltha core
+*/
+var Conn *grpc.ClientConn
+
+/*
+MainLoop - the loop which processes commands at the main level
+*/
+func MainLoop(conn *grpc.ClientConn) {
+
+	inputPrompt := fmt.Sprint("(" + color.LightBlue("voltha") + ") ")
+	//	inputPromptSize := len(inputPrompt)
+	Conn = conn
+	mainFuncTable := make(map[string]func(bool))
+	mainFuncTable["quit"] = util.Exit
+	mainFuncTable["exit"] = nil
+	mainFuncTable["cmdenvironment"] = doCmdEnvironment
+	mainFuncTable["load"] = doLoad
+	mainFuncTable["relative_load"] = doRelativeLoad
+	mainFuncTable["reset_history"] = doResetHistory
+	mainFuncTable["log"] = doLog
+	mainFuncTable["launch"] = doLaunch
+	mainFuncTable["restart"] = doRestart
+	mainFuncTable["devices"] = doDevices
+	mainFuncTable["device"] = doDevice
+	mainFuncTable["logical_devices"] = doLogicalDevices
+	mainFuncTable["logical_device"] = doLogicalDevice
+	mainFuncTable["omci"] = doOmci
+	mainFuncTable["pdb"] = doPdb
+	mainFuncTable["version"] = doVersion
+	mainFuncTable["health"] = doHealth
+	mainFuncTable["preprovison_olt"] = doPreprovisionOlt
+	mainFuncTable["enable"] = doEnable
+	mainFuncTable["reboot"] = doReboot
+	mainFuncTable["self_test"] = doSelfTest
+	mainFuncTable["delete"] = doDelete
+	mainFuncTable["disable"] = doDisable
+	mainFuncTable["test"] = doTest
+	mainFuncTable["alarm_filters"] = doAlarmFilters
+	mainFuncTable["arrive_onus"] = doArriveOnus
+	mainFuncTable["install_eapol_flow"] = doInstallEapolFlow
+	mainFuncTable["install_all_controller_bound_flows"] = doInstallAllControllerBoundFlows
+	mainFuncTable["install_all_sample_flows"] = doInstallAllSampleFlows
+	mainFuncTable["install_dhcp_flows"] = doInstallDhcpFlows
+	mainFuncTable["delete_all_flows"] = doDeleteAllFlows
+	mainFuncTable["send_simulated_upstream_eapol"] = doSendSimulatedUpstreamEapol
+	mainFuncTable["inject_eapol_start"] = doInjectEapolStart
+	util.ProcessTable(mainFuncTable, inputPrompt)
+}
diff --git a/cli/menu/mainmenu/omci.go b/cli/menu/mainmenu/omci.go
new file mode 100644
index 0000000..98d3328
--- /dev/null
+++ b/cli/menu/mainmenu/omci.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doOmci(enterPressed bool) {
+	fmt.Print("input: ocmi>")
+}
diff --git a/cli/menu/mainmenu/pdb.go b/cli/menu/mainmenu/pdb.go
new file mode 100644
index 0000000..32b9035
--- /dev/null
+++ b/cli/menu/mainmenu/pdb.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doPdb(enterPressed bool) {
+	fmt.Print("input: pdb>")
+}
diff --git a/cli/menu/mainmenu/preprovisionOlt.go b/cli/menu/mainmenu/preprovisionOlt.go
new file mode 100644
index 0000000..f185b14
--- /dev/null
+++ b/cli/menu/mainmenu/preprovisionOlt.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doPreprovisionOlt(enterPressed bool) {
+	fmt.Print("input preprovision_olt>")
+}
diff --git a/cli/menu/mainmenu/reboot.go b/cli/menu/mainmenu/reboot.go
new file mode 100644
index 0000000..a0a4b12
--- /dev/null
+++ b/cli/menu/mainmenu/reboot.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doReboot(enterPressed bool) {
+	fmt.Print("input: reboot>")
+}
diff --git a/cli/menu/mainmenu/relativeLoad.go b/cli/menu/mainmenu/relativeLoad.go
new file mode 100644
index 0000000..ab492b4
--- /dev/null
+++ b/cli/menu/mainmenu/relativeLoad.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doRelativeLoad(enterPressed bool) {
+	fmt.Print("input: relative_load>")
+}
diff --git a/cli/menu/mainmenu/resetHistory.go b/cli/menu/mainmenu/resetHistory.go
new file mode 100644
index 0000000..61187a5
--- /dev/null
+++ b/cli/menu/mainmenu/resetHistory.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doResetHistory(enterPressed bool) {
+	fmt.Print("input: reset_history>")
+}
diff --git a/cli/menu/mainmenu/restart.go b/cli/menu/mainmenu/restart.go
new file mode 100644
index 0000000..62ce7e1
--- /dev/null
+++ b/cli/menu/mainmenu/restart.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doRestart(enterPressed bool) {
+	fmt.Print("input: restart>")
+}
diff --git a/cli/menu/mainmenu/selfTest.go b/cli/menu/mainmenu/selfTest.go
new file mode 100644
index 0000000..f25e6fb
--- /dev/null
+++ b/cli/menu/mainmenu/selfTest.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doSelfTest(enterPressed bool) {
+	fmt.Print("input: self_test>")
+}
diff --git a/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
new file mode 100644
index 0000000..c82b0df
--- /dev/null
+++ b/cli/menu/mainmenu/sendSimulatedUpstreamEapol.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doSendSimulatedUpstreamEapol(enterPressed bool) {
+	fmt.Print("input: send_simulated_upstream_eapol>")
+}
diff --git a/cli/menu/mainmenu/test.go b/cli/menu/mainmenu/test.go
new file mode 100644
index 0000000..96e3f0a
--- /dev/null
+++ b/cli/menu/mainmenu/test.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doTest(enterPressed bool) {
+	fmt.Print("input: test>")
+}
diff --git a/cli/menu/mainmenu/version.go b/cli/menu/mainmenu/version.go
new file mode 100644
index 0000000..7464c1b
--- /dev/null
+++ b/cli/menu/mainmenu/version.go
@@ -0,0 +1,23 @@
+/*
+   * 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 mainmenu
+
+import "fmt"
+
+func doVersion(enterPressed bool) {
+	fmt.Print("input: version>")
+}
diff --git a/cli/util/menuProcessor.go b/cli/util/menuProcessor.go
new file mode 100644
index 0000000..c9ba837
--- /dev/null
+++ b/cli/util/menuProcessor.go
@@ -0,0 +1,102 @@
+/*
+   * 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 util
+
+import (
+	"fmt"
+	"os"
+)
+
+/*
+ProcessTable parses table structure and executes functions
+*/
+func ProcessTable(functionTable map[string]func(bool), inputPrompt string) {
+	keys := []string{}
+	for k := range functionTable {
+		keys = append(keys, k)
+	}
+	var b = make([]byte, 1)
+	input := ""
+	fmt.Print(inputPrompt)
+	for {
+		os.Stdin.Read(b)
+		char := string(b)
+		if char == "\t" || char == "\n" || char == "?" {
+			fmt.Println("")
+			ret, prompt := Test(input, keys)
+			if len(ret) == 1 {
+				input = ret[0]
+				if input == "exit" {
+					return
+				}
+				if char == "\n" {
+					Route(input, functionTable, true)
+				} else {
+					Route(input, functionTable, false)
+				}
+				input = ""
+				fmt.Print(inputPrompt)
+			} else if len(ret) == 0 {
+				input = ""
+				fmt.Println("\nInvalid Input ")
+				fmt.Print(inputPrompt)
+			} else if len(ret) == 0 {
+			} else {
+
+				fmt.Println(ret)
+				input = prompt
+				fmt.Print(inputPrompt)
+				fmt.Print(prompt)
+			}
+		} else if char == " " {
+			_, ok := functionTable[input]
+			if ok {
+				Route(input, functionTable, false)
+				fmt.Print(inputPrompt)
+				input = ""
+			} else {
+				ret, prompt := Test(input, keys)
+				if len(ret) == 1 {
+					input = ret[0]
+					Route(input, functionTable, false)
+					input = ""
+					fmt.Print(inputPrompt)
+				} else if len(ret) == 0 {
+					input = ""
+					fmt.Println("\nInvalid Input ")
+					fmt.Print(inputPrompt)
+				} else {
+
+					fmt.Println(ret)
+					input = prompt
+					fmt.Print(inputPrompt + input)
+				}
+			}
+
+		} else if b[0] == 127 || char == "\b" {
+			sz := len(input)
+
+			if sz > 0 {
+				fmt.Print("\b \b")
+				input = input[:sz-1]
+			}
+		} else {
+			fmt.Print(char)
+			input += char
+		}
+	}
+}
diff --git a/cli/util/parseCmd.go b/cli/util/parseCmd.go
new file mode 100644
index 0000000..06ad8b8
--- /dev/null
+++ b/cli/util/parseCmd.go
@@ -0,0 +1,67 @@
+/*
+   * 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 util
+
+import (
+	"os"
+	"strings"
+)
+
+func Test(chars string, values []string) ([]string, string) {
+
+	var ret []string
+	for i := 0; i < len(values); i++ {
+		if strings.HasPrefix(values[i], chars) {
+			ret = append(ret, values[i])
+		}
+	}
+	if len(ret) == 0 {
+		return ret, ""
+	}
+	shortIndex := 0
+	if len(ret) > 1 {
+		for i := 0; i < len(ret); i++ {
+			if len(ret[i]) < len(ret[shortIndex]) {
+				shortIndex = i
+			}
+		}
+	}
+	for i := len(chars); i < len(ret[shortIndex]); i++ {
+		inAllWords := true
+		for j := 0; j < len(ret); j++ {
+			inAllWords = inAllWords && ret[j][i] == ret[shortIndex][i]
+		}
+		if inAllWords {
+			chars += string(ret[shortIndex][i])
+		} else {
+			return ret, chars
+		}
+
+	}
+
+	return ret, chars
+}
+
+func Route(command string, table map[string]func(bool), enterPressed bool) {
+	cmd := table[command]
+	cmd(enterPressed)
+
+}
+
+func Exit(notUsed bool) {
+	os.Exit(0)
+}
diff --git a/cli/util/tableGen.go b/cli/util/tableGen.go
new file mode 100644
index 0000000..3b07ef0
--- /dev/null
+++ b/cli/util/tableGen.go
@@ -0,0 +1,73 @@
+/*
+   * 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 util
+
+import (
+	"fmt"
+	"strings"
+)
+
+func BuildTable(keys []string, rows []map[string]string) (string, error) {
+	var returnString string
+	fieldSizes := make(map[string]int)
+
+	for i := 0; i < len(rows); i++ {
+		for key, value := range rows[i] {
+			currentSize := len(value)
+			if currentSize > fieldSizes[key] {
+				fieldSizes[key] = currentSize
+			}
+
+		}
+	}
+	for i := 0; i < len(keys); i++ {
+		currentSize := len(keys[i])
+		if currentSize > fieldSizes[keys[i]] {
+			fieldSizes[keys[i]] = currentSize
+		}
+	}
+	bottom := "+"
+
+	for i := 0; i < len(rows); i++ {
+		header := "|"
+		line := "|"
+		for j := 0; j < len(keys); j++ {
+			key := keys[j]
+			value := rows[i][key]
+			if i == 0 {
+				pad := 2 + fieldSizes[key] - len(key)
+				field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), key)
+				spacer := fmt.Sprintf("%s+", strings.Repeat("-", fieldSizes[key]+2))
+				header = header + field
+				bottom = bottom + spacer
+			}
+			pad := 2 + fieldSizes[key] - len(value)
+			field := fmt.Sprintf("%s%s|", strings.Repeat(" ", pad), value)
+			line = line + field
+
+		}
+		if i == 0 {
+			returnString = bottom + "\n" + header + "\n" + bottom + "\n"
+		}
+
+		returnString = returnString + line + "\n"
+	}
+	returnString = returnString + bottom + "\n"
+
+	return returnString, nil
+
+}