diff --git a/core/core_server.go b/core/core_server.go
new file mode 100644
index 0000000..39f4ca7
--- /dev/null
+++ b/core/core_server.go
@@ -0,0 +1,460 @@
+/*
+ * 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 core
+
+import (
+	"gerrit.opencord.org/voltha-bbsim/device"
+	"gerrit.opencord.org/voltha-bbsim/protos"
+	"gerrit.opencord.org/voltha-bbsim/setup"
+	"errors"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"github.com/google/gopacket/pcap"
+	"google.golang.org/grpc"
+	"log"
+	"strconv"
+	"sync"
+	"time"
+)
+
+type Mode int
+
+const MAX_ONUS_PER_PON = 64 // This value should be the same with the value in AdapterPlatrorm class
+
+const (
+	DEFAULT Mode = iota
+	AAA
+	BOTH
+)
+
+type Server struct {
+	Olt          *device.Olt
+	Onumap       map[uint32][]*device.Onu
+	Ioinfos      []*Ioinfo
+	Endchan      chan int
+	Mode         Mode
+	AAAWait      int
+	DhcpWait     int
+	DhcpServerIP string
+	gRPCserver   *grpc.Server
+}
+
+type Packet struct {
+	Info *Ioinfo
+	Pkt  gopacket.Packet
+}
+
+func CreateServer(oltid uint32, npon uint32, nonus uint32, aaawait int, dhcpwait int, ip string, g *grpc.Server, mode Mode, e chan int) *Server {
+	s := new(Server)
+	s.Olt = device.CreateOlt(oltid, npon, 1)
+	nnni := s.Olt.NumNniIntf
+	log.Printf("OLT ID: %d was retrieved.\n", s.Olt.ID)
+	s.Onumap = make(map[uint32][]*device.Onu)
+	s.AAAWait = aaawait
+	s.DhcpWait = dhcpwait
+	s.DhcpServerIP = ip
+	s.gRPCserver = g
+	s.Mode = mode
+	s.Endchan = e
+	for intfid := nnni; intfid < npon+nnni; intfid++ {
+		s.Onumap[intfid] = device.CreateOnus(oltid, intfid, nonus, nnni)
+	}
+	return s
+}
+
+func (s *Server) activateOLT(stream openolt.Openolt_EnableIndicationServer) error {
+	// Activate OLT
+	olt := s.Olt
+	oltid := olt.ID
+	vethenv := []string{}
+	wg := &sync.WaitGroup{}
+
+	if err := sendOltInd(stream, olt); err != nil {
+		return err
+	}
+	olt.OperState = "up"
+	olt.InternalState = device.OLT_UP
+	log.Printf("OLT %s sent OltInd.\n", olt.Name)
+
+	// OLT sends Interface Indication to Adapter
+	if err := sendIntfInd(stream, olt); err != nil {
+		log.Printf("[ERROR] Fail to sendIntfInd: %v\n", err)
+		return err
+	}
+	log.Printf("OLT %s sent IntfInd.\n", olt.Name)
+
+	// OLT sends Operation Indication to Adapter after activating each interface
+	//time.Sleep(IF_UP_TIME * time.Second)
+	olt.InternalState = device.PONIF_UP
+	if err := sendOperInd(stream, olt); err != nil {
+		log.Printf("[ERROR] Fail to sendOperInd: %v\n", err)
+		return err
+	}
+	log.Printf("OLT %s sent OperInd.\n", olt.Name)
+
+	// OLT sends ONU Discover Indication to Adapter after ONU discovery
+	for intfid, _ := range s.Onumap {
+		device.UpdateOnusOpStatus(intfid, s.Onumap[intfid], "up")
+	}
+
+	for intfid, _ := range s.Onumap {
+		sendOnuDiscInd(stream, s.Onumap[intfid])
+		log.Printf("OLT id:%d sent ONUDiscInd.\n", olt.ID)
+	}
+
+	// OLT Sends OnuInd after waiting all of those ONUs up
+	for {
+		if s.IsAllONUActive() {
+			break
+		}
+	}
+	for intfid, _ := range s.Onumap {
+		sendOnuInd(stream, s.Onumap[intfid])
+		log.Printf("OLT id:%d sent ONUInd.\n", olt.ID)
+	}
+
+	if s.Mode == DEFAULT {
+		//EnableIndication's stream should be kept even after activateOLT() is finished.
+		//Otherwise, OpenOLT adapter sends EnableIndication again.
+		<-s.Endchan
+		log.Println("core server thread receives close !")
+	} else if s.Mode == AAA || s.Mode == BOTH {
+		var err error
+		s.Ioinfos = []*Ioinfo{}
+		for intfid, _ := range s.Onumap {
+			for i := 0; i < len(s.Onumap[intfid]); i++ {
+				var handler *pcap.Handle
+				onuid := s.Onumap[intfid][i].OnuID
+				uniup, unidw := makeUniName(oltid, intfid, onuid)
+				if handler, vethenv, err = setupVethHandler(uniup, unidw, vethenv); err != nil {
+					return err
+				}
+				iinfo := Ioinfo{name: uniup, iotype: "uni", ioloc: "inside", intfid: intfid, onuid: onuid, handler: handler}
+				s.Ioinfos = append(s.Ioinfos, &iinfo)
+				oinfo := Ioinfo{name: unidw, iotype: "uni", ioloc: "outside", intfid: intfid, onuid: onuid, handler: nil}
+				s.Ioinfos = append(s.Ioinfos, &oinfo)
+			}
+		}
+		var handler *pcap.Handle
+		nniup, nnidw := makeNniName(oltid)
+		if handler, vethenv, err = setupVethHandler(nniup, nnidw, vethenv); err != nil {
+			return err
+		}
+		iinfo := Ioinfo{name: nnidw, iotype: "nni", ioloc: "inside", intfid: 1, handler: handler}
+		s.Ioinfos = append(s.Ioinfos, &iinfo)
+		oinfo := Ioinfo{name: nnidw, iotype: "nni", ioloc: "outside", intfid: 1, handler: nil}
+		s.Ioinfos = append(s.Ioinfos, &oinfo)
+
+		errchan := make(chan error)
+		go func() {
+			<-errchan
+			close(s.Endchan)
+		}()
+
+		wg.Add(1)
+		go func() {
+			defer func() {
+				log.Println("runPacketInDaemon Done")
+				wg.Done()
+			}()
+			err := s.runPacketInDaemon(stream)
+			if err != nil {
+				errchan <- err
+				return
+			}
+		}()
+
+		wg.Add(1)
+		go func() {
+			defer func() {
+				log.Println("exeAAATest Done")
+				wg.Done()
+			}()
+			infos, err := s.getUniIoinfos("outside")
+			if err != nil {
+				errchan <- err
+				return
+			}
+			univeths := []string{}
+			for _, info := range infos {
+				univeths = append(univeths, info.name)
+			}
+			err = s.exeAAATest(univeths)
+			if err != nil {
+				errchan <- err
+				return
+			}
+		}()
+		wg.Wait()
+		tearDown(vethenv) // Grace teardown
+		log.Println("Grace shutdown down")
+	}
+	return nil
+}
+
+func (s *Server) runPacketInDaemon(stream openolt.Openolt_EnableIndicationServer) error {
+	log.Println("runPacketInDaemon Start")
+	unichannel := make(chan Packet, 2048)
+	flag := false
+
+	for intfid, _ := range s.Onumap {
+		for _, onu := range s.Onumap[intfid] { //TODO: should be updated for multiple-Interface
+			onuid := onu.OnuID
+			ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
+			if err != nil {
+				log.Printf("[ERROR] Fail to identifyUniIoinfo (onuid: %d): %v\n", onuid, err)
+				return err
+			}
+			uhandler := ioinfo.handler
+			defer uhandler.Close()
+			go RecvWorker(ioinfo, uhandler, unichannel)
+		}
+	}
+
+	ioinfo, err := s.identifyNniIoinfo("inside")
+	if err != nil {
+		return err
+	}
+	nhandler := ioinfo.handler
+	defer nhandler.Close()
+	nnichannel := make(chan Packet, 32)
+	go RecvWorker(ioinfo, nhandler, nnichannel)
+
+	data := &openolt.Indication_PktInd{}
+	for {
+		select {
+		case unipkt := <-unichannel:
+			log.Println("Received packet in grpc Server from UNI.")
+			if unipkt.Info == nil || unipkt.Info.iotype != "uni" {
+				log.Println("[WARNING] This packet does not come from UNI !")
+				continue
+			}
+			intfid := unipkt.Info.intfid
+			onuid := unipkt.Info.onuid
+			gemid, _ := getGemPortID(intfid, onuid)
+			pkt := unipkt.Pkt
+			layerEth := pkt.Layer(layers.LayerTypeEthernet)
+			le, _ := layerEth.(*layers.Ethernet)
+			ethtype := le.EthernetType
+			if ethtype == 0x888e {
+				log.Printf("Received upstream packet is EAPOL.")
+				log.Println(unipkt.Pkt.Dump())
+				log.Println(pkt.Dump())
+			} else if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
+				log.Printf("Received upstream packet is DHCP.")
+				log.Println(unipkt.Pkt.Dump())
+				log.Println(pkt.Dump())
+			} else {
+				continue
+			}
+			log.Printf("sendPktInd intfid:%d (onuid: %d) gemid:%d\n", intfid, onuid, gemid)
+			data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "pon", IntfId: intfid, GemportId: gemid, Pkt: pkt.Data()}}
+			if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+				log.Printf("[ERROR] Failed to send PktInd indication. %v\n", err)
+				return err
+			}
+		case nnipkt := <-nnichannel:
+			if nnipkt.Info == nil || nnipkt.Info.iotype != "nni" {
+				log.Println("[WARNING] This packet does not come from NNI !")
+				continue
+			}
+			log.Println("Received packet in grpc Server from NNI.")
+			intfid := nnipkt.Info.intfid
+			pkt := nnipkt.Pkt
+			log.Printf("sendPktInd intfid:%d\n", intfid)
+			data = &openolt.Indication_PktInd{PktInd: &openolt.PacketIndication{IntfType: "nni", IntfId: intfid, Pkt: pkt.Data()}}
+			if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+				log.Printf("[ERROR] Failed to send PktInd indication. %v\n", err)
+				return err
+			}
+		case <-s.Endchan:
+			if flag == false {
+				log.Println("PacketInDaemon thread receives close !")
+				close(unichannel)
+				log.Println("Closed unichannel !")
+				close(nnichannel)
+				log.Println("Closed nnichannel !")
+				flag = true
+				return nil
+			}
+		}
+	}
+	return nil
+}
+
+func (s *Server) exeAAATest(vethenv []string) error {
+	log.Println("exeAAATest Start")
+	for i := 0; i < s.AAAWait; i++ {
+		select {
+		case <-s.Endchan:
+			log.Println("exeAAATest thread receives close !")
+			return nil
+		default:
+			log.Println("exeAAATest is now sleeping....")
+			time.Sleep(time.Second)
+		}
+	}
+	err := setup.ActivateWPASups(vethenv)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (s *Server) onuPacketOut(intfid uint32, onuid uint32, rawpkt gopacket.Packet) error {
+	layerEth := rawpkt.Layer(layers.LayerTypeEthernet)
+	if layerEth != nil {
+		pkt, _ := layerEth.(*layers.Ethernet)
+		ethtype := pkt.EthernetType
+		if ethtype == 0x888e {
+			log.Printf("Received downstream packet is EAPOL.")
+			log.Println(rawpkt.Dump())
+		} else if layerDHCP := rawpkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
+			log.Printf("Received downstream packet is DHCP.")
+			log.Println(rawpkt.Dump())
+			rawpkt, _, _ = PopVLAN(rawpkt)
+			rawpkt, _, _ = PopVLAN(rawpkt)
+		} else {
+			return nil
+		}
+		ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
+		if err != nil {
+			return err
+		}
+		handle := ioinfo.handler
+		SendUni(handle, rawpkt)
+		return nil
+	}
+	log.Printf("[WARNING] Received packet is not supported")
+	return nil
+}
+
+func (s *Server) uplinkPacketOut(rawpkt gopacket.Packet) error {
+	log.Println("")
+	poppkt, _, err := PopVLAN(rawpkt)
+	poppkt, _, err = PopVLAN(poppkt)
+	if err != nil {
+		log.Println(err)
+		return err
+	}
+	ioinfo, err := s.identifyNniIoinfo("inside")
+	if err != nil {
+		return err
+	}
+	handle := ioinfo.handler
+	SendNni(handle, poppkt)
+	return nil
+}
+
+func (s *Server) IsAllONUActive() bool {
+	for _, onus := range s.Onumap {
+		for _, onu := range onus {
+			if onu.InternalState != device.ONU_ACTIVATED {
+				return false
+			}
+		}
+	}
+	return true
+}
+
+func getVID(onuid uint32) (uint16, error) {
+	return uint16(onuid), nil
+}
+
+func getGemPortID(intfid uint32, onuid uint32) (uint32, error) {
+	idx := uint32(0)
+	return 1024 + (((MAX_ONUS_PER_PON*intfid + onuid - 1) * 7) + idx), nil
+	//return uint32(1032 + 8 * (vid - 1)), nil
+}
+
+func (s *Server) getOnuBySN(sn *openolt.SerialNumber) (*device.Onu, error) {
+	for _, onus := range s.Onumap {
+		for _, onu := range onus {
+			if device.ValidateSN(*sn, *onu.SerialNumber) {
+				return onu, nil
+			}
+		}
+	}
+	err := errors.New("No mathced SN is found !")
+	log.Println(err)
+	return nil, err
+}
+
+func (s *Server) getOnuByID(onuid uint32) (*device.Onu, error) {
+	for _, onus := range s.Onumap {
+		for _, onu := range onus {
+			if onu.OnuID == onuid {
+				return onu, nil
+			}
+		}
+	}
+	err := errors.New("No matched OnuID is found !")
+	log.Println(err)
+	return nil, err
+}
+
+func makeUniName(oltid uint32, intfid uint32, onuid uint32) (upif string, dwif string) {
+	upif = setup.UNI_VETH_UP_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
+	dwif = setup.UNI_VETH_DW_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
+	return
+}
+
+func makeNniName(oltid uint32) (upif string, dwif string) {
+	upif = setup.NNI_VETH_UP_PFX + strconv.Itoa(int(oltid))
+	dwif = setup.NNI_VETH_DW_PFX + strconv.Itoa(int(oltid))
+	return
+}
+
+func tearDown(vethenv []string) error {
+	log.Println("tearDown()")
+	setup.KillAllWPASups()
+	setup.KillAllDHCPClients()
+	setup.TearVethDown(vethenv)
+	return nil
+}
+
+func setupVethHandler(inveth string, outveth string, vethenv []string) (*pcap.Handle, []string, error) {
+	log.Printf("setupVethHandler: %s and %s\n", inveth, outveth)
+	err1 := setup.CreateVethPairs(inveth, outveth)
+	vethenv = append(vethenv, inveth)
+	if err1 != nil {
+		setup.RemoveVeths(vethenv)
+		return nil, vethenv, err1
+	}
+	handler, err2 := getVethHandler(inveth)
+	if err2 != nil {
+		setup.RemoveVeths(vethenv)
+		return nil, vethenv, err2
+	}
+	return handler, vethenv, nil
+}
+
+func getVethHandler(vethname string) (*pcap.Handle, error) {
+	var (
+		device       string = vethname
+		snapshot_len int32  = 1518
+		promiscuous  bool   = false
+		err          error
+		timeout      time.Duration = pcap.BlockForever
+	)
+	handle, err := pcap.OpenLive(device, snapshot_len, promiscuous, timeout)
+	if err != nil {
+		return nil, err
+	}
+	log.Printf("Server handle created for %s\n", vethname)
+	return handle, nil
+}
diff --git a/core/grpc_service.go b/core/grpc_service.go
new file mode 100644
index 0000000..a5bc3e5
--- /dev/null
+++ b/core/grpc_service.go
@@ -0,0 +1,154 @@
+/*
+ * 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 core
+
+import (
+	"gerrit.opencord.org/voltha-bbsim/device"
+	"gerrit.opencord.org/voltha-bbsim/protos"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	"log"
+	"net"
+)
+
+// gRPC Service
+func (s *Server) DisableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
+	log.Printf("OLT receives DisableOLT()\n")
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) ReenableOlt(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
+	log.Printf("OLT receives Reenable()\n")
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) CollectStatistics(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
+	log.Printf("OLT receives CollectStatistics()\n")
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) GetDeviceInfo(c context.Context, empty *openolt.Empty) (*openolt.DeviceInfo, error) {
+	log.Printf("OLT receives GetDeviceInfo()\n")
+	return new(openolt.DeviceInfo), nil
+}
+
+func (s *Server) ActivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
+	log.Printf("OLT receives ActivateONU()\n")
+	result := device.ValidateONU(*onu, s.Onumap)
+
+	if result == true {
+		matched, error := s.getOnuBySN(onu.SerialNumber)
+		if error != nil {
+			log.Fatalf("%s\n", error)
+		}
+		onuid := onu.OnuId
+		matched.OnuID = onuid
+		matched.InternalState = device.ONU_ACTIVATED
+		log.Printf("ONU IntfID: %d OnuID: %d activated succesufully.\n", onu.IntfId, onu.OnuId)
+	}
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) DeactivateOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
+	log.Printf("OLT receives DeactivateONU()\n")
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) DeleteOnu(c context.Context, onu *openolt.Onu) (*openolt.Empty, error) {
+	log.Printf("OLT receives DeleteONU()\n")
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) OmciMsgOut(c context.Context, msg *openolt.OmciMsg) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives OmciMsgOut to IF %v (ONU-ID: %v) pkt:%x.\n", s.Olt.ID, msg.IntfId, msg.OnuId, msg.Pkt)
+	//s.olt.Queue = append(s.olt.Queue, *msg)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) OnuPacketOut(c context.Context, packet *openolt.OnuPacket) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives OnuPacketOut () to IF-ID:%d ONU-ID %d.\n", s.Olt.ID, packet.IntfId, packet.OnuId)
+	onuid := packet.OnuId
+	intfid := packet.IntfId
+	rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
+	if err := s.onuPacketOut(intfid, onuid, rawpkt); err != nil {
+		return new(openolt.Empty), err
+	}
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) UplinkPacketOut(c context.Context, packet *openolt.UplinkPacket) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives UplinkPacketOut().\n", s.Olt.ID)
+	rawpkt := gopacket.NewPacket(packet.Pkt, layers.LayerTypeEthernet, gopacket.Default)
+	if err := s.uplinkPacketOut(rawpkt); err != nil {
+		return new(openolt.Empty), err
+	}
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) FlowAdd(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives FlowAdd().\n", s.Olt.ID)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) FlowRemove(c context.Context, flow *openolt.Flow) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives FlowRemove().\n", s.Olt.ID)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) HeartbeatCheck(c context.Context, empty *openolt.Empty) (*openolt.Heartbeat, error) {
+	log.Printf("OLT %d receives HeartbeatCheck().\n", s.Olt.ID)
+	signature := new(openolt.Heartbeat)
+	signature.HeartbeatSignature = s.Olt.HeartbeatSignature
+	return signature, nil
+}
+
+func (s *Server) EnablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives EnablePonIf().\n", s.Olt.ID)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) DisablePonIf(c context.Context, intf *openolt.Interface) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives DisablePonIf().\n", s.Olt.ID)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) Reboot(c context.Context, empty *openolt.Empty) (*openolt.Empty, error) {
+	log.Printf("OLT %d receives Reboot ().\n", s.Olt.ID)
+	return new(openolt.Empty), nil
+}
+
+func (s *Server) EnableIndication(empty *openolt.Empty, stream openolt.Openolt_EnableIndicationServer) error {
+	defer func() {
+		s.gRPCserver.Stop()
+	}()
+	log.Printf("OLT receives EnableInd.\n")
+	if err := s.activateOLT(stream); err != nil {
+		log.Printf("Failed to activate OLT: %v\n", err)
+		return err
+	}
+	log.Println("Core server down.")
+	return nil
+}
+
+func CreateGrpcServer(oltid uint32, npon uint32, nonus uint32, addrport string) (l net.Listener, g *grpc.Server, e error) {
+	log.Printf("Listening %s ...", addrport)
+	g = grpc.NewServer()
+	l, e = net.Listen("tcp", addrport)
+	return
+}
diff --git a/core/io_info.go b/core/io_info.go
new file mode 100644
index 0000000..4252509
--- /dev/null
+++ b/core/io_info.go
@@ -0,0 +1,69 @@
+/*
+ * 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 core
+
+import (
+	"errors"
+	"github.com/google/gopacket/pcap"
+	"log"
+)
+
+type Ioinfo struct {
+	name    string
+	iotype  string //nni or uni
+	ioloc   string //inside or outsode
+	intfid  uint32
+	onuid   uint32
+	handler *pcap.Handle
+}
+
+func (s *Server) identifyUniIoinfo(ioloc string, intfid uint32, onuid uint32) (*Ioinfo, error) {
+	for _, ioinfo := range s.Ioinfos {
+		if ioinfo.iotype == "uni" && ioinfo.intfid == intfid && ioinfo.onuid == onuid && ioinfo.ioloc == ioloc {
+			return ioinfo, nil
+		}
+	}
+	err := errors.New("No matched Ioinfo is found !")
+	log.Println(err)
+	return nil, err
+}
+
+func (s *Server) identifyNniIoinfo(ioloc string) (*Ioinfo, error) {
+	for _, ioinfo := range s.Ioinfos {
+		if ioinfo.iotype == "nni" && ioinfo.ioloc == ioloc {
+			return ioinfo, nil
+		}
+	}
+	err := errors.New("No matched Ioinfo is found !")
+	log.Println(err)
+	return nil, err
+}
+
+func (s *Server) getUniIoinfos(ioloc string) ([]*Ioinfo, error) {
+	ioinfos := []*Ioinfo{}
+	for _, ioinfo := range s.Ioinfos {
+		if ioinfo.iotype == "uni" && ioinfo.ioloc == ioloc {
+			ioinfos = append(ioinfos, ioinfo)
+		}
+	}
+	if len(ioinfos) == 0 {
+		err := errors.New("No matched Ioinfo is found !")
+		log.Println(err)
+		return nil, err
+	}
+	return ioinfos, nil
+}
diff --git a/core/io_worker.go b/core/io_worker.go
new file mode 100644
index 0000000..a535869
--- /dev/null
+++ b/core/io_worker.go
@@ -0,0 +1,135 @@
+/*
+ * 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 core
+
+import (
+	"errors"
+	"github.com/google/gopacket"
+	"github.com/google/gopacket/layers"
+	"github.com/google/gopacket/pcap"
+	"log"
+	"net"
+)
+
+func RecvWorker(io *Ioinfo, handler *pcap.Handle, r chan Packet) {
+	log.Printf("recvWorker runs. handler: %v", *handler)
+	packetSource := gopacket.NewPacketSource(handler, handler.LinkType())
+	for packet := range packetSource.Packets() {
+		log.Printf("recv packet from IF: %v \n", *handler)
+		//log.Println(packet.Dump())
+		pkt := Packet{}
+		pkt.Info = io
+		pkt.Pkt = packet
+		r <- pkt
+	}
+}
+
+func SendUni(handle *pcap.Handle, packet gopacket.Packet) {
+	handle.WritePacketData(packet.Data())
+	log.Printf("send packet to UNI-IF: %v \n", *handle)
+	//log.Println(packet.Dump())
+}
+
+func SendNni(handle *pcap.Handle, packet gopacket.Packet) {
+	handle.WritePacketData(packet.Data())
+	log.Printf("send packet to NNI-IF: %v \n", *handle)
+	//log.Println(packet.Dump())
+}
+
+func PopVLAN(pkt gopacket.Packet) (gopacket.Packet, uint16, error) {
+	if layer := getDot1QLayer(pkt); layer != nil {
+		if eth := getEthernetLayer(pkt); eth != nil {
+			ethernetLayer := &layers.Ethernet{
+				SrcMAC:       eth.SrcMAC,
+				DstMAC:       eth.DstMAC,
+				EthernetType: layer.Type,
+			}
+			buffer := gopacket.NewSerializeBuffer()
+			gopacket.SerializeLayers(buffer, gopacket.SerializeOptions{},
+				ethernetLayer,
+				gopacket.Payload(layer.Payload),
+			)
+			retpkt := gopacket.NewPacket(
+				buffer.Bytes(),
+				layers.LayerTypeEthernet,
+				gopacket.Default,
+			)
+			vid := uint16(4095 & layer.VLANIdentifier)
+			log.Printf("Pop the 802.1Q header (VID: %d)", vid)
+			return retpkt, vid, nil
+		}
+	}
+	//return pkt, 1, nil
+	return nil, 0, errors.New("failed to pop vlan")
+}
+
+func PushVLAN(pkt gopacket.Packet, vid uint16) (gopacket.Packet, error) {
+	if eth := getEthernetLayer(pkt); eth != nil {
+		ethernetLayer := &layers.Ethernet{
+			SrcMAC:       eth.SrcMAC,
+			DstMAC:       eth.DstMAC,
+			EthernetType: 0x8100,
+		}
+		dot1qLayer := &layers.Dot1Q{
+			Type:           eth.EthernetType,
+			VLANIdentifier: uint16(vid),
+		}
+
+		buffer := gopacket.NewSerializeBuffer()
+		gopacket.SerializeLayers(
+			buffer,
+			gopacket.SerializeOptions{
+				FixLengths: false,
+			},
+			ethernetLayer,
+			dot1qLayer,
+			gopacket.Payload(eth.Payload),
+		)
+		ret := gopacket.NewPacket(
+			buffer.Bytes(),
+			layers.LayerTypeEthernet,
+			gopacket.Default,
+		)
+		log.Printf("Push the 802.1Q header (VID: %d)", vid)
+		return ret, nil
+	}
+	return nil, errors.New("failed to push vlan")
+}
+
+func getEthernetLayer(pkt gopacket.Packet) *layers.Ethernet {
+	eth := &layers.Ethernet{}
+	if ethLayer := pkt.Layer(layers.LayerTypeEthernet); ethLayer != nil {
+		eth, _ = ethLayer.(*layers.Ethernet)
+	}
+	return eth
+}
+func getDot1QLayer(pkt gopacket.Packet) (dot1q *layers.Dot1Q) {
+	if dot1qLayer := pkt.Layer(layers.LayerTypeDot1Q); dot1qLayer != nil {
+		dot1q = dot1qLayer.(*layers.Dot1Q)
+	}
+	return dot1q
+}
+
+func getMacAddress(ifName string) net.HardwareAddr {
+	var err error
+	var netIf *net.Interface
+	var hwAddr net.HardwareAddr
+	if netIf, err = net.InterfaceByName(ifName); err == nil {
+		hwAddr = netIf.HardwareAddr
+	}
+	return hwAddr
+}
diff --git a/core/openolt_service.go b/core/openolt_service.go
new file mode 100644
index 0000000..3f0c311
--- /dev/null
+++ b/core/openolt_service.go
@@ -0,0 +1,82 @@
+/*
+ * 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 core
+
+import (
+	"gerrit.opencord.org/voltha-bbsim/protos"
+	"gerrit.opencord.org/voltha-bbsim/device"
+	"log"
+)
+
+func sendOltInd(stream openolt.Openolt_EnableIndicationServer, olt *device.Olt) error {
+	data := &openolt.Indication_OltInd{OltInd: &openolt.OltIndication{OperState: "up"}}
+	if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+		log.Printf("Failed to send OLT indication: %v\n", err)
+		return err
+	}
+	return nil
+}
+
+func sendIntfInd(stream openolt.Openolt_EnableIndicationServer, olt *device.Olt) error {
+	for i := uint32(0); i < olt.NumPonIntf+olt.NumNniIntf; i++ {
+		intf := olt.Intfs[i]
+		data := &openolt.Indication_IntfInd{&openolt.IntfIndication{IntfId: intf.IntfID, OperState: intf.OperState}}
+		if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+			log.Printf("Failed to send Intf [id: %d] indication : %v\n", i, err)
+			return err
+		}
+		log.Printf("SendIntfInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
+	}
+	return nil
+}
+
+func sendOperInd(stream openolt.Openolt_EnableIndicationServer, olt *device.Olt) error {
+	for i := uint32(0); i < olt.NumPonIntf+olt.NumNniIntf; i++ {
+		intf := olt.Intfs[i]
+		data := &openolt.Indication_IntfOperInd{&openolt.IntfOperIndication{Type: intf.Type, IntfId: intf.IntfID, OperState: intf.OperState}}
+		if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+			log.Printf("Failed to send IntfOper [id: %d] indication : %v\n", i, err)
+			return err
+		}
+		log.Printf("SendOperInd olt:%d intf:%d (%s)\n", olt.ID, intf.IntfID, intf.Type)
+	}
+	return nil
+}
+
+func sendOnuDiscInd(stream openolt.Openolt_EnableIndicationServer, onus []*device.Onu) error {
+	for i, onu := range onus {
+		data := &openolt.Indication_OnuDiscInd{&openolt.OnuDiscIndication{IntfId: onu.IntfID, SerialNumber: onu.SerialNumber}}
+		log.Printf("sendONUDiscInd Onuid: %d\n", i)
+		if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+			log.Printf("Failed to send ONUDiscInd [id: %d]: %v\n", i, err)
+			return err
+		}
+	}
+	return nil
+}
+
+func sendOnuInd(stream openolt.Openolt_EnableIndicationServer, onus []*device.Onu) error {
+	for i, onu := range onus {
+		data := &openolt.Indication_OnuInd{&openolt.OnuIndication{IntfId: onu.IntfID, OnuId: onu.OnuID, OperState: "up", AdminState: "up", SerialNumber: onu.SerialNumber}}
+		log.Printf("sendONUInd Onuid: %d\n", i)
+		if err := stream.Send(&openolt.Indication{Data: data}); err != nil {
+			log.Printf("Failed to send ONUInd [id: %d]: %v\n", i, err)
+			return err
+		}
+	}
+	return nil
+}
