diff --git a/openflow/barrier.go b/openflow/barrier.go
new file mode 100644
index 0000000..7b631fe
--- /dev/null
+++ b/openflow/barrier.go
@@ -0,0 +1,31 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleBarrierRequest(request *ofp.BarrierRequest, client *Client) {
+	jsonRequest, _ := json.Marshal(request)
+	log.Printf("handleBarrierRequest called with %s", jsonRequest)
+	reply := ofp.NewBarrierReply()
+	reply.SetXid(request.GetXid())
+	client.SendMessage(reply)
+}
diff --git a/openflow/echo.go b/openflow/echo.go
new file mode 100644
index 0000000..51d09df
--- /dev/null
+++ b/openflow/echo.go
@@ -0,0 +1,33 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleEchoRequest(request *ofp.EchoRequest, client *Client) {
+	jsonMessage, _ := json.Marshal(request)
+	log.Printf("handleEchoRequest called with %s", jsonMessage)
+	reply := ofp.NewEchoReply()
+	reply.SetXid(request.GetXid())
+	reply.SetVersion(request.GetVersion())
+	client.SendMessage(reply)
+
+}
diff --git a/openflow/feature.go b/openflow/feature.go
new file mode 100644
index 0000000..2c01f73
--- /dev/null
+++ b/openflow/feature.go
@@ -0,0 +1,50 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/opencord/voltha-protos/go/common"
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleFeatureRequest(request *ofp.FeaturesRequest, deviceId string, client *Client) error {
+	message, _ := json.Marshal(request)
+	log.Printf("handleFeatureRequest called with %s\n ", message)
+	var grpcClient = *getGrpcClient()
+	var id = common.ID{Id: deviceId}
+	logicalDevice, err := grpcClient.GetLogicalDevice(context.Background(), &id)
+	reply := createFeaturesRequestReply(request.GetXid(), logicalDevice)
+	err = client.SendMessage(reply)
+	return err
+}
+func createFeaturesRequestReply(xid uint32, device *pb.LogicalDevice) *ofp.FeaturesReply {
+
+	featureReply := ofp.NewFeaturesReply()
+	featureReply.SetXid(xid)
+	features := device.GetSwitchFeatures()
+	featureReply.SetDatapathId(device.GetDatapathId())
+	featureReply.SetNBuffers(features.GetNBuffers())
+	featureReply.SetNTables(uint8(features.GetNTables()))
+	featureReply.SetAuxiliaryId(uint8(features.GetAuxiliaryId()))
+	capabilities := features.GetCapabilities()
+	featureReply.SetCapabilities(ofp.Capabilities(capabilities))
+	return featureReply
+}
diff --git a/openflow/flowMod.go b/openflow/flowMod.go
new file mode 100644
index 0000000..37e6864
--- /dev/null
+++ b/openflow/flowMod.go
@@ -0,0 +1,283 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/opencord/voltha-protos/go/openflow_13"
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+var oxmMap = map[string]int32{
+	"in_port":        0,
+	"in_phy_port":    1,
+	"metadata":       2,
+	"eth_dst":        3,
+	"eth_src":        4,
+	"eth_type":       5,
+	"vlan_vid":       6,
+	"vlan_pcp":       7,
+	"ip_dscp":        8,
+	"ip_ecn":         9,
+	"ip_proto":       10,
+	"ipv4_src":       11,
+	"ipv4_dst":       12,
+	"tcp_src":        13,
+	"tcp_dst":        14,
+	"udp_src":        15,
+	"udp_dst":        16,
+	"sctp_src":       17,
+	"sctp_dst":       18,
+	"icmpv4_type":    19,
+	"icmpv4_code":    20,
+	"arp_op":         21,
+	"arp_spa":        22,
+	"arp_tpa":        23,
+	"arp_sha":        24,
+	"arp_tha":        25,
+	"ipv6_src":       26,
+	"ipv6_dst":       27,
+	"ipv6_flabel":    28,
+	"icmpv6_type":    29,
+	"icmpv6_code":    30,
+	"ipv6_nd_target": 31,
+	"ipv6_nd_sll":    32,
+	"ipv6_nd_tll":    33,
+	"mpls_label":     34,
+	"mpls_tc":        35,
+	"mpls_bos":       36,
+	"pbb_isid":       37,
+	"tunnel_id":      38,
+	"ipv6_exthdr":    39,
+}
+
+func handleFlowAdd(flowAdd *ofp.FlowAdd, deviceId string) {
+	js, _ := json.Marshal(flowAdd)
+	log.Printf("handleFlowAdd called with %s", js)
+
+	var flowUpdate openflow_13.FlowTableUpdate
+	flowUpdate.Id = deviceId
+	var flowMod pb.OfpFlowMod
+	flowMod.Cookie = flowAdd.Cookie
+	flowMod.CookieMask = flowAdd.CookieMask
+	flowMod.TableId = uint32(flowAdd.TableId)
+	flowMod.Command = pb.OfpFlowModCommand_OFPFC_ADD
+	flowMod.IdleTimeout = uint32(flowAdd.IdleTimeout)
+	flowMod.HardTimeout = uint32(flowAdd.HardTimeout)
+	flowMod.Priority = uint32(flowAdd.Priority)
+	flowMod.BufferId = flowAdd.BufferId
+	flowMod.OutPort = uint32(flowAdd.OutPort)
+	flowMod.OutGroup = uint32(flowAdd.OutGroup)
+	flowMod.Flags = uint32(flowAdd.Flags)
+	inMatch := flowAdd.Match
+	var flowMatch pb.OfpMatch
+	flowMatch.Type = pb.OfpMatchType(inMatch.GetType())
+	var oxmList []*pb.OfpOxmField
+	inOxmList := inMatch.GetOxmList()
+	for i := 0; i < len(inOxmList); i++ {
+		oxmField := inOxmList[i]
+		j, _ := json.Marshal(oxmField)
+
+		name := oxmMap[oxmField.GetOXMName()]
+		log.Printf("\n\n\n %s  %d  %s\n\n\n", j, name, oxmField.GetOXMName())
+
+		val := oxmField.GetOXMValue()
+		var ofpOxmField pb.OfpOxmField
+		ofpOxmField.OxmClass = ofp.OFPXMCOpenflowBasic
+		var field pb.OfpOxmOfbField
+
+		field.Type = pb.OxmOfbFieldTypes(name)
+		log.Println("****\nFieldType: " + openflow_13.OxmOfbFieldTypes_name[name] + "\n\n\n\n")
+
+		var x openflow_13.OfpOxmField_OfbField
+		x.OfbField = &field
+		ofpOxmField.Field = &x
+
+		switch pb.OxmOfbFieldTypes(name) {
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
+			port := val.(ofp.Port)
+			var value pb.OfpOxmOfbField_Port
+			value.Port = uint32(port)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
+			phyPort := val.(uint32)
+			var value pb.OfpOxmOfbField_PhysicalPort
+			value.PhysicalPort = phyPort
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_METADATA:
+			metadata := val.(uint64)
+			var value pb.OfpOxmOfbField_TableMetadata
+			value.TableMetadata = metadata
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_ETH_TYPE:
+			ethType := val.(ofp.EthernetType)
+			var value pb.OfpOxmOfbField_EthType
+			value.EthType = uint32(ethType)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
+			proto := val.(ofp.IpPrototype)
+			var value pb.OfpOxmOfbField_IpProto
+			value.IpProto = uint32(proto)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
+			udpSrc := val.(uint16)
+			var value pb.OfpOxmOfbField_UdpSrc
+			value.UdpSrc = uint32(udpSrc)
+			log.Printf("udpSrc %v", udpSrc)
+			field.Value = &value
+		case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
+			udpDst := val.(uint16)
+			var value pb.OfpOxmOfbField_UdpDst
+			value.UdpDst = uint32(udpDst)
+			field.Value = &value
+		}
+		oxmList = append(oxmList, &ofpOxmField)
+	}
+	flowMatch.OxmFields = oxmList
+	flowMod.Match = &flowMatch
+	var instructions []*pb.OfpInstruction
+	ofpInstructions := flowAdd.GetInstructions()
+	for i := 0; i < len(ofpInstructions); i++ {
+		var instruction pb.OfpInstruction
+		ofpInstruction := ofpInstructions[i]
+		instructionType := ofpInstruction.GetType()
+		instruction.Type = uint32(instructionType)
+		switch instructionType {
+		case 1:
+			goToTable := ofpInstruction.(ofp.IInstructionGotoTable)
+			var ofpGoToTable openflow_13.OfpInstruction_GotoTable
+			ofpGoToTable.GotoTable.TableId = uint32(goToTable.GetTableId())
+			instruction.Data = &ofpGoToTable
+		case 2:
+			writeMetaData := ofpInstruction.(ofp.IInstructionWriteMetadata)
+			var ofpWriteMetadata openflow_13.OfpInstruction_WriteMetadata
+			ofpWriteMetadata.WriteMetadata.Metadata = writeMetaData.GetMetadata()
+			ofpWriteMetadata.WriteMetadata.MetadataMask = writeMetaData.GetMetadataMask()
+			instruction.Data = &ofpWriteMetadata
+		case 3:
+			writeAction := ofpInstruction.(ofp.IInstructionWriteActions)
+			var ofpInstructionActions openflow_13.OfpInstruction_Actions
+			var ofpActions []*openflow_13.OfpAction
+			actions := writeAction.GetActions()
+			for i := 0; i < len(actions); i++ {
+				action := actions[i]
+				ofpAction := extractAction(action)
+				ofpActions = append(ofpActions, ofpAction)
+			}
+			instruction.Data = &ofpInstructionActions
+		case 4:
+			applyAction := ofpInstruction.(ofp.IInstructionApplyActions)
+			var ofpInstructionActions openflow_13.OfpInstruction_Actions
+			var ofpActions []*openflow_13.OfpAction
+			actions := applyAction.GetActions()
+			for i := 0; i < len(actions); i++ {
+				action := actions[i]
+				ofpAction := extractAction(action)
+				ofpActions = append(ofpActions, ofpAction)
+			}
+			var actionsHolder openflow_13.OfpInstructionActions
+			actionsHolder.Actions = ofpActions
+			ofpInstructionActions.Actions = &actionsHolder
+			instruction.Data = &ofpInstructionActions
+
+		}
+		instructions = append(instructions, &instruction)
+	}
+
+	flowMod.Instructions = instructions
+	flowUpdate.FlowMod = &flowMod
+	grpcClient := *getGrpcClient()
+	flowUpdateJs, _ := json.Marshal(flowUpdate)
+	log.Printf("FLOW UPDATE %s", flowUpdateJs)
+	empty, err := grpcClient.UpdateLogicalDeviceFlowTable(context.Background(), &flowUpdate)
+	if err != nil {
+		log.Printf("ERROR DOING FLOW MOD ADD %v", err)
+	}
+	emptyJs, _ := json.Marshal(empty)
+	log.Printf("FLOW MOD RESPONSE %s", emptyJs)
+
+}
+
+func handleFlowMod(flowMod *ofp.FlowMod, deviceId string) {
+	js, _ := json.Marshal(flowMod)
+	log.Printf("handleFlowMod called with %s", js)
+}
+
+func handleFlowModStrict(flowModStrict *ofp.FlowModifyStrict, deviceId string) {
+	js, _ := json.Marshal(flowModStrict)
+	log.Printf("handleFlowModStrict called with %s", js)
+}
+func handleFlowDelete(flowDelete *ofp.FlowDelete, deviceId string) {
+	js, _ := json.Marshal(flowDelete)
+	log.Printf("handleFlowDelete called with %s", js)
+
+}
+func handleFlowDeleteStrict(flowDeleteStrict *ofp.FlowDeleteStrict, deviceId string) {
+	js, _ := json.Marshal(flowDeleteStrict)
+	log.Printf("handleFlowDeleteStrict called with %s", js)
+
+}
+func extractAction(action ofp.IAction) *openflow_13.OfpAction {
+	var ofpAction openflow_13.OfpAction
+	switch action.GetType() {
+	case 0: // Output
+		var outputAction openflow_13.OfpAction_Output
+		loxiOutputAction := action.(*ofp.ActionOutput)
+		var output openflow_13.OfpActionOutput
+		output.Port = uint32(loxiOutputAction.Port)
+		output.MaxLen = uint32(loxiOutputAction.MaxLen)
+		outputAction.Output = &output
+		ofpAction.Action = &outputAction
+	case 11: //CopyTtlOut
+	case 12: //CopyTtlIn
+	case 15: //SetMplsTtl
+	case 16: //DecMplsTtl
+	case 17: //PushVlan
+		var pushVlan openflow_13.OfpAction_Push
+		loxiPushAction := action.(*ofp.ActionPopVlan)
+		fields := loxiPushAction.GetActionFields()
+		fieldsJS, _ := json.Marshal(fields)
+		log.Printf("\n\nPushVlan fields %s\n\n", fieldsJS)
+		pushVlan.Push.Ethertype = 0x8100 //TODO This should be available in the fields
+		ofpAction.Type = openflow_13.OfpActionType_OFPAT_PUSH_VLAN
+	case 18: //PopVlan
+		ofpAction.Type = openflow_13.OfpActionType_OFPAT_POP_VLAN
+	case 19: //PushMpls
+	case 20: //PopMpls
+	case 21: //SetQueue
+	case 22: //ActionGroup
+	case 23: //SetNwTtl
+	case 24: //DecNwTtl
+	case 25: //SetField
+		var setField openflow_13.OfpAction_SetField
+		loxiSetField := action.(*ofp.ActionSetField)
+		fields := loxiSetField.GetActionFields()
+		fieldsJS, _ := json.Marshal(fields)
+		log.Printf("\n\nSet Fields fields %s\n\n", fieldsJS)
+
+		ofpAction.Action = &setField
+	case 26: //PushPbb
+	case 27: //PopPbb
+	case 65535: //Experimenter
+
+	}
+	return &ofpAction
+
+}
diff --git a/openflow/getConfig.go b/openflow/getConfig.go
new file mode 100644
index 0000000..6d4444f
--- /dev/null
+++ b/openflow/getConfig.go
@@ -0,0 +1,32 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleGetConfigRequest(request *ofp.GetConfigRequest, client *Client) {
+	jsonReq, _ := json.Marshal(request)
+	log.Printf("handleGetConfigRequest called with %s", jsonReq)
+	reply := ofp.NewGetConfigReply()
+	reply.SetXid(request.GetXid())
+	reply.SetMissSendLen(ofp.OFPCMLNoBuffer)
+	client.SendMessage(reply)
+}
diff --git a/openflow/ofError.go b/openflow/ofError.go
new file mode 100644
index 0000000..c4329e1
--- /dev/null
+++ b/openflow/ofError.go
@@ -0,0 +1,29 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleErrMsg(message *ofp.ErrorMsg) {
+	jsonMessage, _ := json.Marshal(message)
+	log.Printf("handleErrMsg called with %s", jsonMessage)
+	//Not sure yet what if anything to do here
+}
diff --git a/openflow/openflowClient.go b/openflow/openflowClient.go
new file mode 100644
index 0000000..b07e36d
--- /dev/null
+++ b/openflow/openflowClient.go
@@ -0,0 +1,258 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	"fmt"
+	"time"
+
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	"github.com/skydive-project/goloxi"
+	ofp "github.com/skydive-project/goloxi/of13"
+
+	"log"
+	"net"
+)
+
+var conn net.Conn
+var volthaClient *pb.VolthaServiceClient
+var packetOutChannel chan pb.PacketOut
+
+type Client struct {
+	OfServerAddress string
+	Port            uint16
+	DeviceId        string
+	KeepRunning     bool
+}
+
+func NewClient(ofServerAddress string, port uint16, deviceId string, keepRunning bool) *Client {
+	client := Client{OfServerAddress: ofServerAddress, Port: port, DeviceId: deviceId, KeepRunning: keepRunning}
+	go client.Start()
+	return &client
+}
+
+func (client *Client) End() {
+	client.KeepRunning = false
+}
+func (client *Client) Start() {
+	addressLine := fmt.Sprintf("%s:%d", client.OfServerAddress, client.Port)
+	raddr, e := net.ResolveTCPAddr("tcp", addressLine)
+	if e != nil {
+		errMessage := fmt.Errorf("Unable to resolve %s", addressLine)
+		fmt.Println(errMessage)
+	}
+	for {
+		if client.KeepRunning {
+			connection, e := net.DialTCP("tcp", nil, raddr)
+			conn = connection
+			if e != nil {
+				log.Fatalf("unable to connect to %v", raddr)
+			}
+			defer conn.Close()
+			hello := ofp.NewHello()
+			hello.Xid = uint32(GetXid())
+			var elements []ofp.IHelloElem
+
+			elem := ofp.NewHelloElemVersionbitmap()
+			elem.SetType(ofp.OFPHETVersionbitmap)
+			elem.SetLength(8)
+			var bitmap = ofp.Uint32{Value: 16}
+			bitmaps := []*ofp.Uint32{&bitmap}
+
+			elem.SetBitmaps(bitmaps)
+
+			elements = append(elements, elem)
+
+			hello.SetElements(elements)
+			e = client.SendMessage(hello)
+			if e != nil {
+				log.Fatal(e)
+			}
+			for {
+				buf := make([]byte, 1500)
+				read, e := conn.Read(buf)
+				if e != nil {
+					log.Printf("Connection has died %v", e)
+					break
+				}
+				decoder := goloxi.NewDecoder(buf)
+				log.Printf("decoder offset %d baseOffset %d", decoder.Offset(), decoder.BaseOffset())
+				header, e := ofp.DecodeHeader(decoder)
+				log.Printf("received packet read: %d", read)
+
+				if e != nil {
+					log.Printf("decodeheader threw error %v", e)
+				}
+				message, _ := json.Marshal(header)
+				log.Printf("message %s\n", message)
+				client.parseHeader(header, buf) //first one is ready
+				len := header.GetLength()
+				if len < uint16(read) {
+					log.Printf("Len %d was less than read %d", len, read)
+					for {
+						read = read - int(len)
+						newBuf := buf[len:]
+						decoder = goloxi.NewDecoder(newBuf)
+						newHeader, e := ofp.DecodeHeader(decoder)
+						message, _ := json.Marshal(newHeader)
+						log.Printf("message %s\n", message)
+						if e != nil {
+
+						}
+						len = newHeader.GetLength()
+						client.parseHeader(newHeader, newBuf)
+						if read == int(len) {
+							log.Printf(" not continuing read %d len %d", read, len)
+							break
+						} else {
+							log.Printf("continuing read %d len %d", read, len)
+						}
+						buf = newBuf
+					}
+				}
+				if e != nil {
+					log.Println("Decode Header error ", e)
+				}
+			}
+		}
+		break
+	}
+}
+
+func (client *Client) parseHeader(header ofp.IHeader, buf []byte) {
+
+	log.Printf("parseHeader called with type %d", header.GetType())
+	switch header.GetType() {
+	case 0:
+		x := header.(*ofp.Hello)
+		log.Printf("helloMessage : %+v", x)
+		//nothing real to do
+	case 1:
+		errMsg := header.(*ofp.ErrorMsg)
+		go handleErrMsg(errMsg)
+	case 2:
+		echoReq := header.(*ofp.EchoRequest)
+		go handleEchoRequest(echoReq, client)
+	case 3:
+		//EchoReply
+	case 4:
+		//Expirementer
+	case 5:
+		featReq := header.(*ofp.FeaturesRequest)
+		go handleFeatureRequest(featReq, client.DeviceId, client)
+	case 6:
+		//feature reply
+	case 7:
+		configReq := header.(*ofp.GetConfigRequest)
+		go handleGetConfigRequest(configReq, client)
+	case 8:
+		//GetConfigReply
+	case 9:
+		setConf := header.(*ofp.SetConfig)
+		go handleSetConfig(setConf)
+	case 10:
+		//packetIn := header.(*ofp.PacketIn)
+		//go handlePacketIn(packetIn)
+	case 11:
+		//FlowRemoved
+	case 12:
+		//portStatus
+	case 13:
+		packetOut := header.(*ofp.PacketOut)
+		go handlePacketOut(packetOut, client.DeviceId)
+	case 14:
+		flowModType := uint8(buf[25])
+		switch flowModType {
+		case 0:
+			flowAdd := header.(*ofp.FlowAdd)
+			go handleFlowAdd(flowAdd, client.DeviceId)
+			//return DecodeFlowAdd(_flowmod, decoder)
+		case 1:
+			flowMod := header.(*ofp.FlowMod)
+			go handleFlowMod(flowMod, client.DeviceId)
+			//return DecodeFlowModify(_flowmod, decoder)
+		case 2:
+			flowModStrict := header.(*ofp.FlowModifyStrict)
+			go handleFlowModStrict(flowModStrict, client.DeviceId)
+			//return DecodeFlowModifyStrict(_flowmod, decoder)
+		case 3:
+			flowDelete := header.(*ofp.FlowDelete)
+			go handleFlowDelete(flowDelete, client.DeviceId)
+			//return DecodeFlowDelete(_flowmod, decoder)
+		case 4:
+			flowDeleteStrict := header.(*ofp.FlowDeleteStrict)
+			go handleFlowDeleteStrict(flowDeleteStrict, client.DeviceId)
+			//return DecodeFlowDeleteStrict(_flowmod, decoder)
+		default:
+			//return nil, fmt.Errorf("Invalid type '%d' for 'FlowMod'", _flowmod.Command)
+
+		}
+	case 18:
+		var statType = uint16(buf[8])<<8 + uint16(buf[9])
+		log.Println("statsType", statType)
+		go handleStatsRequest(header, statType, client.DeviceId, client)
+	case 20:
+		barRequest := header.(*ofp.BarrierRequest)
+		go handleBarrierRequest(barRequest, client)
+	case 24:
+		roleReq := header.(*ofp.RoleRequest)
+		go handleRoleRequest(roleReq, client)
+
+	}
+}
+
+//openFlowMessage created to allow for a single SendMessage
+type OpenFlowMessage interface {
+	Serialize(encoder *goloxi.Encoder) error
+}
+
+func (client *Client) SendMessage(message OpenFlowMessage) error {
+	jsonMessage, _ := json.Marshal(message)
+	log.Printf("send message called %s\n", jsonMessage)
+	enc := goloxi.NewEncoder()
+	message.Serialize(enc)
+	jMessage, _ := json.Marshal(message)
+	log.Printf("message after serialize %s", jMessage)
+
+	for {
+		if conn == nil {
+			log.Println("CONN IS NIL")
+			time.Sleep(10 * time.Millisecond)
+		} else {
+			break
+		}
+	}
+	_, err := conn.Write(enc.Bytes())
+	if err != nil {
+		log.Printf("SendMessage had error %s", err)
+		return err
+	}
+	return nil
+}
+func SetGrpcClient(client *pb.VolthaServiceClient) {
+	volthaClient = client
+}
+func getGrpcClient() *pb.VolthaServiceClient {
+	return volthaClient
+}
+func test(hello ofp.IHello) {
+	fmt.Println("works")
+}
+func SetPacketOutChannel(pktOutChan chan pb.PacketOut) {
+	packetOutChannel = pktOutChan
+}
diff --git a/openflow/packet.go b/openflow/packet.go
new file mode 100644
index 0000000..2bd46cd
--- /dev/null
+++ b/openflow/packet.go
@@ -0,0 +1,46 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handlePacketOut(packetOut *ofp.PacketOut, deviceId string) {
+	jsonMessage, _ := json.Marshal(packetOut)
+	log.Printf("handlePacketOut called with %s", jsonMessage)
+	pktOut := pb.OfpPacketOut{}
+	pktOut.BufferId = packetOut.GetBufferId()
+	pktOut.InPort = uint32(packetOut.GetInPort())
+	var actions []*pb.OfpAction
+	inActions := packetOut.GetActions()
+	for i := 0; i < len(inActions); i++ {
+		action := inActions[i]
+		var newAction = pb.OfpAction{}
+		newAction.Type = pb.OfpActionType(action.GetType())
+		actions = append(actions, &newAction)
+	}
+	pktOut.Actions = actions
+	pktOut.Data = packetOut.GetData()
+	pbPacketOut := pb.PacketOut{}
+	pbPacketOut.PacketOut = &pktOut
+	pbPacketOut.Id = deviceId
+	packetOutChannel <- pbPacketOut
+}
diff --git a/openflow/role.go b/openflow/role.go
new file mode 100644
index 0000000..08cf457
--- /dev/null
+++ b/openflow/role.go
@@ -0,0 +1,35 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleRoleRequest(request *ofp.RoleRequest, client *Client) {
+	jsonMessage, _ := json.Marshal(request)
+	log.Printf("handleRoleRequest called with %s", jsonMessage)
+
+	reply := ofp.NewRoleReply()
+	reply.SetXid(request.GetXid())
+	reply.SetVersion(request.GetVersion())
+	reply.SetRole(request.GetRole())
+	reply.SetGenerationId(request.GetGenerationId())
+	client.SendMessage(reply)
+}
diff --git a/openflow/setConfig.go b/openflow/setConfig.go
new file mode 100644
index 0000000..c429f46
--- /dev/null
+++ b/openflow/setConfig.go
@@ -0,0 +1,28 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"encoding/json"
+	ofp "github.com/skydive-project/goloxi/of13"
+	"log"
+)
+
+func handleSetConfig(request *ofp.SetConfig) {
+	jsonMessage, _ := json.Marshal(request)
+	log.Printf("handleSetConfig %s\n", jsonMessage)
+}
diff --git a/openflow/stats.go b/openflow/stats.go
new file mode 100644
index 0000000..46fe2f2
--- /dev/null
+++ b/openflow/stats.go
@@ -0,0 +1,518 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"context"
+	"encoding/json"
+	"github.com/opencord/voltha-protos/go/openflow_13"
+	"github.com/skydive-project/goloxi"
+	"log"
+	"net"
+	"unsafe"
+
+	"github.com/opencord/voltha-protos/go/common"
+	pb "github.com/opencord/voltha-protos/go/voltha"
+	ofp "github.com/skydive-project/goloxi/of13"
+)
+
+func handleStatsRequest(request ofp.IHeader, statType uint16, deviceId string, client *Client) error {
+	message, _ := json.Marshal(request)
+	log.Printf("handleStatsRequest called with %s\n ", message)
+	var id = common.ID{Id: deviceId}
+
+	switch statType {
+	case 0:
+		statsReq := request.(*ofp.DescStatsRequest)
+		response, err := handleDescStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+
+	case 1:
+		statsReq := request.(*ofp.FlowStatsRequest)
+		response, _ := handleFlowStatsRequest(statsReq, id)
+		err := client.SendMessage(response)
+		if err != nil {
+			return err
+		}
+
+	case 2:
+		statsReq := request.(*ofp.AggregateStatsRequest)
+		aggregateStatsReply, err := handleAggregateStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(aggregateStatsReply)
+	case 3:
+		statsReq := request.(*ofp.TableStatsRequest)
+		tableStatsReply, e := handleTableStatsRequest(statsReq, id)
+		if e != nil {
+			return e
+		}
+		client.SendMessage(tableStatsReply)
+	case 4:
+		statsReq := request.(*ofp.PortStatsRequest)
+		response, err := handlePortStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+
+	case 5:
+		statsReq := request.(*ofp.QueueStatsRequest)
+		response, err := handleQueueStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 6:
+		statsReq := request.(*ofp.GroupStatsRequest)
+		response, err := handleGroupStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 7:
+		statsReq := request.(*ofp.GroupDescStatsRequest)
+		response, err := handleGroupStatsDescRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 8:
+		statsReq := request.(*ofp.GroupFeaturesStatsRequest)
+		response, err := handleGroupFeatureStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 9:
+		statsReq := request.(*ofp.MeterStatsRequest)
+		response, err := handleMeterStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 10:
+		statsReq := request.(*ofp.MeterConfigStatsRequest)
+		response, err := handleMeterConfigStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 11:
+		statsReq := request.(*ofp.MeterFeaturesStatsRequest)
+		response, err := handleMeterFeatureStatsRequest(statsReq)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 12:
+		statsReq := request.(*ofp.TableFeaturesStatsRequest)
+		response, err := handleTableFeaturesStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	case 13:
+		statsReq := request.(*ofp.PortDescStatsRequest)
+		response, err := handlePortDescStatsRequest(statsReq, deviceId)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+
+	case 65535:
+		statsReq := request.(*ofp.ExperimenterStatsRequest)
+		response, err := handleExperimenterStatsRequest(statsReq, id)
+		if err != nil {
+			return err
+		}
+		client.SendMessage(response)
+	}
+	return nil
+}
+
+func handleDescStatsRequest(request *ofp.DescStatsRequest, id common.ID) (*ofp.DescStatsReply, error) {
+	response := ofp.NewDescStatsReply()
+	response.SetXid(request.GetXid())
+	response.SetVersion(request.GetVersion())
+	client := *getGrpcClient()
+	resp, err := client.GetLogicalDevice(context.Background(), &id)
+	if err != nil {
+		return nil, err
+	}
+	desc := resp.GetDesc()
+
+	response.SetMfrDesc(PadString(desc.GetMfrDesc(), 256))
+	response.SetHwDesc(PadString(desc.GetHwDesc(), 256))
+	response.SetSwDesc(PadString(desc.GetSwDesc(), 256))
+	response.SetSerialNum(PadString(desc.GetSerialNum(), 32))
+	response.SetDpDesc(PadString(desc.GetDpDesc(), 256))
+	//jsonRes,_ := json.Marshal(response)
+	//log.Printf("handleDescStatsRequest response : %s",jsonRes)
+	return response, nil
+}
+func handleFlowStatsRequest(request *ofp.FlowStatsRequest, id common.ID) (*ofp.FlowStatsReply, error) {
+	log.Println("****************************************\n***********************************")
+	response := ofp.NewFlowStatsReply()
+	response.SetXid(request.GetXid())
+	response.SetVersion(request.GetVersion())
+	client := *getGrpcClient()
+	resp, err := client.ListLogicalDeviceFlows(context.Background(), &id)
+	if err != nil {
+		log.Println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
+		log.Printf("err in handleFlowStatsRequest calling ListLogicalDeviceFlows %v", err)
+		return nil, err
+	}
+	log.Println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++")
+	js, _ := json.Marshal(resp.GetItems())
+	log.Printf("||||||||||||||||||||||||||||||||||||HandFlowStat %s|||||||||||||||||||||||||||||||||||||||||", js)
+	var flow []*ofp.FlowStatsEntry
+	items := resp.GetItems()
+
+	for i := 0; i < len(items); i++ {
+		item := items[1]
+		var entry ofp.FlowStatsEntry
+
+		entry.SetTableId(uint8(item.GetId()))
+		entry.SetDurationSec(item.GetDurationSec())
+		entry.SetDurationNsec(item.GetDurationNsec())
+		entry.SetPriority(uint16(item.GetPriority()))
+		entry.SetIdleTimeout(uint16(item.GetIdleTimeout()))
+		entry.SetHardTimeout(uint16(item.GetHardTimeout()))
+		entry.SetFlags(ofp.FlowModFlags(item.GetFlags()))
+		entry.SetCookie(item.GetCookie())
+		entry.SetPacketCount(item.GetPacketCount())
+		entry.SetByteCount(item.GetByteCount())
+		var match ofp.Match
+		pbMatch := item.GetMatch()
+
+		var fields []goloxi.IOxm
+		match.SetType(uint16(pbMatch.GetType()))
+		oxFields := pbMatch.GetOxmFields()
+		for i := 0; i < len(oxFields); i++ {
+			js, _ := json.Marshal(oxFields[i])
+			log.Printf("oxfields %s", js)
+			oxmField := oxFields[i]
+			field := oxmField.GetField()
+			ofbField := field.(*openflow_13.OfpOxmField_OfbField).OfbField
+			switch ofbField.Type {
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PORT:
+				ofpInPort := ofp.NewOxmInPort()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_Port)
+				ofpInPort.Value = ofp.Port(val.Port)
+				fields = append(fields, ofpInPort)
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_IN_PHY_PORT:
+				ofpInPhyPort := ofp.NewOxmInPhyPort()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_PhysicalPort)
+				ofpInPhyPort.Value = ofp.Port(val.PhysicalPort)
+				fields = append(fields, ofpInPhyPort)
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_IP_PROTO:
+				ofpIpProto := ofp.NewOxmIpProto()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_IpProto)
+				ofpIpProto.Value = ofp.IpPrototype(val.IpProto)
+				fields = append(fields, ofpIpProto)
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_SRC:
+				ofpUdpSrc := ofp.NewOxmUdpSrc()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpSrc)
+				ofpUdpSrc.Value = uint16(val.UdpSrc)
+				fields = append(fields, ofpUdpSrc)
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_UDP_DST:
+				ofpUdpDst := ofp.NewOxmUdpSrc()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_UdpDst)
+				ofpUdpDst.Value = uint16(val.UdpDst)
+				fields = append(fields, ofpUdpDst)
+			case pb.OxmOfbFieldTypes_OFPXMT_OFB_VLAN_VID:
+				ofpVlanVid := ofp.NewOxmVlanVid()
+				val := ofbField.GetValue().(*openflow_13.OfpOxmOfbField_VlanVid)
+				ofpVlanVid.Value = uint16(val.VlanVid)
+				fields = append(fields, ofpVlanVid)
+			default:
+				log.Printf("handleFlowStatsRequest   Unhandled OxmField %v", ofbField.Type)
+			}
+
+		}
+		match.OxmList = fields
+		match.Length = uint16(unsafe.Sizeof(match))
+		entry.SetMatch(match)
+		var instructions []ofp.IInstruction
+		ofpInstructions := item.Instructions
+		for i := 0; i < len(ofpInstructions); i++ {
+			ofpInstruction := ofpInstructions[i]
+			instType := ofpInstruction.Type
+			switch instType {
+			case uint32(openflow_13.OfpInstructionType_OFPIT_APPLY_ACTIONS):
+				ofpActions := ofpInstruction.GetActions().Actions
+				for i := 0; i < len(ofpActions); i++ {
+					ofpAction := ofpActions[i]
+					var actions []*ofp.Action
+					switch ofpAction.Type {
+					case openflow_13.OfpActionType_OFPAT_OUTPUT:
+						ofpOutputAction := ofpAction.GetOutput()
+						outputAction := ofp.NewActionOutput()
+						outputAction.Port = ofp.Port(ofpOutputAction.Port)
+						outputAction.MaxLen = uint16(ofpOutputAction.MaxLen)
+						actions = append(actions, outputAction.Action)
+					}
+				}
+				instruction := ofp.NewInstruction(uint16(instType))
+				instructions = append(instructions, instruction)
+			}
+
+		}
+		entry.Instructions = instructions
+		entry.Length = uint16(unsafe.Sizeof(entry))
+		flow = append(flow, &entry)
+
+	}
+	response.SetEntries(flow)
+	return response, nil
+}
+func handleAggregateStatsRequest(request *ofp.AggregateStatsRequest, id common.ID) (*ofp.AggregateStatsReply, error) {
+	response := ofp.NewAggregateStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	response.SetFlowCount(0)
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+func handleGroupStatsRequest(request *ofp.GroupStatsRequest, id common.ID) (*ofp.GroupStatsReply, error) {
+	response := ofp.NewGroupStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	client := *getGrpcClient()
+	reply, err := client.ListLogicalDeviceFlowGroups(context.Background(), &id)
+	if err != nil {
+		return nil, err
+	}
+
+	var groupStatsEntries []*ofp.GroupStatsEntry
+	items := reply.GetItems()
+	for i := 0; i < len(items); i++ {
+		item := items[i].GetStats()
+		var entry ofp.GroupStatsEntry
+		entry.SetByteCount(item.GetByteCount())
+		entry.SetPacketCount(item.GetPacketCount())
+		entry.SetDurationNsec(item.GetDurationNsec())
+		entry.SetDurationSec(item.GetDurationSec())
+		entry.SetRefCount(item.GetRefCount())
+		entry.SetGroupId(item.GetGroupId())
+		bucketStats := item.GetBucketStats()
+		var bucketStatsList []*ofp.BucketCounter
+		for j := 0; j < len(bucketStats); j++ {
+			bucketStat := bucketStats[i]
+			var bucketCounter ofp.BucketCounter
+			bucketCounter.SetPacketCount(bucketStat.GetPacketCount())
+			bucketCounter.SetByteCount(bucketStat.GetByteCount())
+			bucketStatsList = append(bucketStatsList, &bucketCounter)
+		}
+		entry.SetBucketStats(bucketStatsList)
+		groupStatsEntries = append(groupStatsEntries, &entry)
+	}
+	response.SetEntries(groupStatsEntries)
+	return response, nil
+}
+func handleGroupStatsDescRequest(request *ofp.GroupDescStatsRequest, id common.ID) (*ofp.GroupDescStatsReply, error) {
+	response := ofp.NewGroupDescStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	client := *getGrpcClient()
+	reply, err := client.ListLogicalDeviceFlowGroups(context.Background(), &id)
+	if err != nil {
+		return nil, err
+	}
+	entries := reply.GetItems()
+	var groupDescStatsEntries []*ofp.GroupDescStatsEntry
+	for i := 0; i < len(entries); i++ {
+		item := entries[i].GetStats()
+		var groupDesc ofp.GroupDescStatsEntry
+		groupDesc.SetGroupId(item.GetGroupId())
+		/*
+			buckets := item.g
+			var bucketList []*ofp.Bucket
+			for j:=0;j<len(buckets);j++{
+
+			}
+
+			groupDesc.SetBuckets(bucketList)
+		*/
+		groupDescStatsEntries = append(groupDescStatsEntries, &groupDesc)
+	}
+	response.SetEntries(groupDescStatsEntries)
+	return response, nil
+}
+func handleGroupFeatureStatsRequest(request *ofp.GroupFeaturesStatsRequest, id common.ID) (*ofp.GroupFeaturesStatsReply, error) {
+	response := ofp.NewGroupFeaturesStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+func handleMeterStatsRequest(request *ofp.MeterStatsRequest, id common.ID) (*ofp.MeterStatsReply, error) {
+	response := ofp.NewMeterStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+
+//statsReq := request.(*ofp.MeterConfigStatsRequest)
+func handleMeterConfigStatsRequest(request *ofp.MeterConfigStatsRequest, id common.ID) (*ofp.MeterConfigStatsReply, error) {
+	response := ofp.NewMeterConfigStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+
+//statsReq := request.(*ofp.TableFeaturesStatsRequest)
+func handleTableFeaturesStatsRequest(request *ofp.TableFeaturesStatsRequest, id common.ID) (*ofp.TableFeaturesStatsReply, error) {
+	response := ofp.NewTableFeaturesStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+func handleTableStatsRequest(request *ofp.TableStatsRequest, id common.ID) (*ofp.TableStatsReply, error) {
+	var tableStatsReply = ofp.NewTableStatsReply()
+	tableStatsReply.SetFlags(ofp.StatsReplyFlags(request.GetFlags()))
+	tableStatsReply.SetVersion(request.GetVersion())
+	tableStatsReply.SetXid(request.GetXid())
+	return tableStatsReply, nil
+}
+func handleQueueStatsRequest(request *ofp.QueueStatsRequest, id common.ID) (*ofp.QueueStatsReply, error) {
+	response := ofp.NewQueueStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
+func handlePortStatsRequest(request *ofp.PortStatsRequest, id common.ID) (*ofp.PortStatsReply, error) {
+	log.Println("HERE")
+	response := ofp.NewPortStatsReply()
+	response.SetXid(request.GetXid())
+	response.SetVersion(request.GetVersion())
+	//response.SetFlags(ofp.flagsrequest.GetFlags())
+	client := *getGrpcClient()
+	reply, err := client.ListLogicalDevicePorts(context.Background(), &id)
+	//reply,err := client.GetLogicalDevicePort(context.Background(),&id)
+	if err != nil {
+		log.Printf("error calling ListDevicePorts %v", err)
+		return nil, err
+	}
+	js, _ := json.Marshal(reply)
+	log.Printf("PORT STATS REPLY %s", js)
+	ports := reply.GetItems()
+	var entries []*ofp.PortStatsEntry
+	if request.GetPortNo() == 0xffffffff { //all ports
+		for i := 0; i < len(ports); i++ {
+			port := ports[i]
+			entry := parsePortStats(port)
+			entries = append(entries, &entry)
+		}
+	} else { //find right port that is requested
+		for i := 0; i < len(ports); i++ {
+			if ports[i].GetOfpPortStats().GetPortNo() == uint32(request.GetPortNo()) {
+				entry := parsePortStats(ports[i])
+				entries = append(entries, &entry)
+			}
+		}
+	}
+	response.SetEntries(entries)
+	js, _ = json.Marshal(response)
+	log.Printf("handlePortStatsResponse %s", js)
+	return response, nil
+
+}
+func parsePortStats(port *pb.LogicalPort) ofp.PortStatsEntry {
+	stats := port.OfpPortStats
+	var entry ofp.PortStatsEntry
+	entry.SetPortNo(ofp.Port(stats.GetPortNo()))
+	entry.SetRxPackets(stats.GetRxPackets())
+	entry.SetTxPackets(stats.GetTxPackets())
+	entry.SetRxBytes(stats.GetRxBytes())
+	entry.SetTxBytes(stats.GetTxBytes())
+	entry.SetRxDropped(stats.GetRxDropped())
+	entry.SetTxDropped(stats.GetTxDropped())
+	entry.SetRxErrors(stats.GetRxErrors())
+	entry.SetTxErrors(stats.GetTxErrors())
+	entry.SetRxFrameErr(stats.GetRxFrameErr())
+	entry.SetRxOverErr(stats.GetRxOverErr())
+	entry.SetRxCrcErr(stats.GetRxCrcErr())
+	entry.SetCollisions(stats.GetCollisions())
+	entry.SetDurationSec(stats.GetDurationSec())
+	entry.SetDurationNsec(stats.GetDurationNsec())
+	return entry
+}
+func handlePortDescStatsRequest(request *ofp.PortDescStatsRequest, deviceId string) (*ofp.PortDescStatsReply, error) {
+	response := ofp.NewPortDescStatsReply()
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	var grpcClient = *getGrpcClient()
+	var id = common.ID{Id: deviceId}
+	logicalDevice, err := grpcClient.GetLogicalDevice(context.Background(), &id)
+	if err != nil {
+		return nil, err
+	}
+	ports := logicalDevice.GetPorts()
+	var entries []*ofp.PortDesc
+	for i := 0; i < len(ports); i++ {
+		var entry ofp.PortDesc
+		port := ports[i].GetOfpPort()
+		entry.SetPortNo(ofp.Port(port.GetPortNo()))
+
+		intArray := port.GetHwAddr()
+		var octets []byte
+		for i := 0; i < len(intArray); i++ {
+			octets = append(octets, byte(intArray[i]))
+		}
+		hwAddr := net.HardwareAddr(octets)
+		entry.SetHwAddr(hwAddr)
+		entry.SetName(PadString(port.GetName(), 16))
+		entry.SetConfig(ofp.PortConfig(port.GetConfig()))
+		entry.SetState(ofp.PortState(port.GetState()))
+		entry.SetCurr(ofp.PortFeatures(port.GetCurr()))
+		entry.SetAdvertised(ofp.PortFeatures(port.GetAdvertised()))
+		entry.SetSupported(ofp.PortFeatures(port.GetSupported()))
+		entry.SetPeer(ofp.PortFeatures(port.GetPeer()))
+		entry.SetCurrSpeed(port.GetCurrSpeed())
+		entry.SetMaxSpeed(port.GetMaxSpeed())
+
+		entries = append(entries, &entry)
+	}
+
+	response.SetEntries(entries)
+	//TODO call voltha and get port descriptions etc
+	return response, nil
+
+}
+func handleMeterFeatureStatsRequest(request *ofp.MeterFeaturesStatsRequest) (*ofp.MeterFeaturesStatsReply, error) {
+	response := ofp.NewMeterFeaturesStatsReply()
+	response.SetXid(request.GetXid())
+	response.SetVersion(request.GetVersion())
+	return response, nil
+}
+func handleExperimenterStatsRequest(request *ofp.ExperimenterStatsRequest, id common.ID) (*ofp.ExperimenterStatsReply, error) {
+	response := ofp.NewExperimenterStatsReply(request.GetExperimenter())
+	response.SetVersion(request.GetVersion())
+	response.SetXid(request.GetXid())
+	//TODO wire this to voltha core when it implements
+	return response, nil
+}
diff --git a/openflow/utils.go b/openflow/utils.go
new file mode 100644
index 0000000..160b2ab
--- /dev/null
+++ b/openflow/utils.go
@@ -0,0 +1,40 @@
+/*
+   Copyright 2017 the original author or authors.
+
+   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 openflow
+
+import (
+	"fmt"
+	"strings"
+	"sync"
+)
+
+var mu sync.Mutex
+var xid uint32 = 1
+
+func GetXid() uint32 {
+	mu.Lock()
+	defer mu.Unlock()
+	xid++
+	return xid
+}
+func PadString(value string, padSize int) string {
+	size := len(value)
+	nullsNeeded := padSize - size
+	null := fmt.Sprintf("%c", '\000')
+	padded := strings.Repeat(null, nullsNeeded)
+	return fmt.Sprintf("%s%s", value, padded)
+}
