diff --git a/config/isc-dhcp-server b/config/isc-dhcp-server
index 440f7b3..0501355 100644
--- a/config/isc-dhcp-server
+++ b/config/isc-dhcp-server
@@ -18,5 +18,5 @@
 
 # On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
 #	Separate multiple interfaces with spaces, e.g. "eth0 eth1".
-INTERFACES="sim_nu0"
+INTERFACES="nni_north"
 
diff --git a/core/core_server.go b/core/core_server.go
index 7cc1eed..dbda1c6 100644
--- a/core/core_server.go
+++ b/core/core_server.go
@@ -39,11 +39,9 @@
 )
 
 const (
-	UNI_VETH_UP_PFX  = "sim_uu"
-	UNI_VETH_DW_PFX  = "sim_ud"
-	NNI_VETH_UP_PFX  = "sim_nu"
-	NNI_VETH_DW_PFX  = "sim_nd"
-	MAX_ONUS_PER_PON = 64 // This value should be the same with the value in AdapterPlatrorm class
+	NNI_VETH_NORTH_PFX = "nni_north"
+	NNI_VETH_SOUTH_PFX = "nni_south"
+	MAX_ONUS_PER_PON   = 64 // This value should be the same with the value in AdapterPlatrorm class
 )
 
 type Server struct {
@@ -202,6 +200,7 @@
 }
 
 func (s *Server) updateDevIntState(dev device.Device, state device.DeviceState) {
+	logger.Debug("updateDevIntState called state:%d", state)
 	current := dev.GetIntState()
 	dev.UpdateIntState(state)
 	s.stateRepCh <- stateReport{device: dev, current: current, next: state}
@@ -286,7 +285,7 @@
 		logger.Debug("StartPktLoops () Done")
 	}()
 	s.wg.Add(1)
-	ioinfos, veths, err := createIoinfos(s.Olt.ID, s.Vethnames, s.Onumap)
+	ioinfos, veths, err := createIoinfos(s.Olt.ID, s.Vethnames)
 	if err != nil {
 		logger.Error("createIoinfos failed.", err)
 		return err
@@ -314,25 +313,9 @@
 	}
 }
 
-func createIoinfos(oltid uint32, Vethnames []string, onumap map[uint32][]*device.Onu) ([]*Ioinfo, []string, error) {
+func createIoinfos(oltid uint32, Vethnames []string) ([]*Ioinfo, []string, error) {
 	ioinfos := []*Ioinfo{}
 	var err error
-	for intfid, _ := range onumap {
-		for i := 0; i < len(onumap[intfid]); i++ {
-			var handler *pcap.Handle
-			onuid := onumap[intfid][i].OnuID
-			uniup, unidw := makeUniName(oltid, intfid, onuid)
-			if handler, Vethnames, err = setupVethHandler(uniup, unidw, Vethnames); err != nil {
-				logger.Error("setupVethHandler failed (onuid: %d)", onuid, err)
-				return ioinfos, Vethnames, err
-			}
-			iinfo := Ioinfo{Name: uniup, iotype: "uni", ioloc: "inside", intfid: intfid, onuid: onuid, handler: handler}
-			ioinfos = append(ioinfos, &iinfo)
-			oinfo := Ioinfo{Name: unidw, iotype: "uni", ioloc: "outside", intfid: intfid, onuid: onuid, handler: nil}
-			ioinfos = append(ioinfos, &oinfo)
-		}
-	}
-
 	var handler *pcap.Handle
 	nniup, nnidw := makeNniName(oltid)
 	if handler, Vethnames, err = setupVethHandler(nniup, nnidw, Vethnames); err != nil {
@@ -371,8 +354,6 @@
 			if ok { //Error
 				logger.Error("Error happend in Omci:%s", v)
 				return v
-			} else { //Close
-				s.updateDevIntState(s.Olt, device.OLT_ACTIVE)
 			}
 		case <-child.Done():
 			return nil
@@ -423,25 +404,10 @@
 }
 
 func (s *Server) runMainPktLoop(ctx context.Context, stream openolt.Openolt_EnableIndicationServer) error {
-	unichannel := make(chan Packet, 2048)
+	logger.Debug("runMainPktLoop Start")
 	defer func() {
-		close(unichannel)
-		logger.Debug("Closed unichannel ")
 		logger.Debug("runMainPktLoop Done")
 	}()
-	for intfid, _ := range s.Onumap {
-		for _, onu := range s.Onumap[intfid] {
-			onuid := onu.OnuID
-			ioinfo, err := s.identifyUniIoinfo("inside", intfid, onuid)
-			if err != nil {
-				utils.LoggerWithOnu(onu).Error("Fail to identifyUniIoinfo (onuid: %d): %v", onuid, err)
-				return err
-			}
-			uhandler := ioinfo.handler
-			go RecvWorker(ioinfo, uhandler, unichannel)
-		}
-	}
-
 	ioinfo, err := s.IdentifyNniIoinfo("inside")
 	if err != nil {
 		return err
@@ -451,7 +417,9 @@
 	defer func() {
 		close(nnichannel)
 	}()
-
+	logger.Debug("BEFORE OLT_ACTIVE")
+	s.updateDevIntState(s.Olt, device.OLT_ACTIVE)
+	logger.Debug("AFTER  OLT_ACTIVE")
 	data := &openolt.Indication_PktInd{}
 	for {
 		select {
@@ -521,65 +489,6 @@
 				return err
 			}
 
-		case unipkt := <-unichannel:
-			onuid := unipkt.Info.onuid
-			onu, _ := s.GetOnuByID(onuid)
-			utils.LoggerWithOnu(onu).Debug("Received packet from UNI in grpc Server")
-			if unipkt.Info == nil || unipkt.Info.iotype != "uni" {
-				logger.Debug("WARNING: This packet does not come from UNI ")
-				continue
-			}
-
-			intfid := unipkt.Info.intfid
-			gemid, err := getGemPortID(intfid, onuid)
-			if err != nil {
-				continue
-			}
-			pkt := unipkt.Pkt
-			layerEth := pkt.Layer(layers.LayerTypeEthernet)
-			le, _ := layerEth.(*layers.Ethernet)
-			ethtype := le.EthernetType
-
-			if ethtype == layers.EthernetTypeEAPOL {
-				utils.LoggerWithOnu(onu).WithFields(log.Fields{
-					"gemId": gemid,
-				}).Info("Received upstream packet is EAPOL.")
-			} else if layerDHCP := pkt.Layer(layers.LayerTypeDHCPv4); layerDHCP != nil {
-				utils.LoggerWithOnu(onu).WithFields(log.Fields{
-					"gemId": gemid,
-				}).Info("Received upstream packet is DHCP.")
-
-				//C-TAG
-				sn := convB2S(onu.SerialNumber.VendorSpecific)
-				if ctag, ok := s.CtagMap[sn]; ok == true {
-					tagpkt, err := PushVLAN(pkt, uint16(ctag), onu)
-					if err != nil {
-						utils.LoggerWithOnu(onu).WithFields(log.Fields{
-							"gemId": gemid,
-						}).Error("Fail to tag C-tag")
-					} else {
-						pkt = tagpkt
-					}
-				} else {
-					utils.LoggerWithOnu(onu).WithFields(log.Fields{
-						"gemId":   gemid,
-						"cTagMap": s.CtagMap,
-					}).Error("Could not find onuid in CtagMap", onuid, sn, s.CtagMap)
-				}
-			} else {
-				utils.LoggerWithOnu(onu).WithFields(log.Fields{
-					"gemId": gemid,
-				}).Info("Received upstream packet is of unknow type, skipping.")
-				continue
-			}
-
-			utils.LoggerWithOnu(onu).Info("sendPktInd - UNI Packet")
-			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 {
-				logger.Error("Fail to send PktInd indication.", err)
-				return err
-			}
-
 		case nnipkt := <-nnichannel:
 			logger.Debug("Received packet from NNI")
 			if nnipkt.Info == nil || nnipkt.Info.iotype != "nni" {
diff --git a/core/io_info.go b/core/io_info.go
index d104efc..7a272f4 100644
--- a/core/io_info.go
+++ b/core/io_info.go
@@ -56,21 +56,6 @@
 	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")
-		logger.Error("GetUniIoinfos %s", err)
-		return nil, err
-	}
-	return ioinfos, nil
-}
-
 func CreateVethPairs(veth1 string, veth2 string) (err error) {
 	err = exec.Command("ip", "link", "add", veth1, "type", "veth", "peer", "name", veth2).Run()
 	if err != nil {
diff --git a/core/io_worker.go b/core/io_worker.go
index 077b2c1..4d885b6 100644
--- a/core/io_worker.go
+++ b/core/io_worker.go
@@ -145,15 +145,9 @@
 	return hwAddr
 }
 
-func makeUniName(oltid uint32, intfid uint32, onuid uint32) (upif string, dwif string) {
-	upif = UNI_VETH_UP_PFX + strconv.Itoa(int(oltid)) + "_" + strconv.Itoa(int(intfid)) + "_" + strconv.Itoa(int(onuid))
-	dwif = 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 = NNI_VETH_UP_PFX + strconv.Itoa(int(oltid))
-	dwif = NNI_VETH_DW_PFX + strconv.Itoa(int(oltid))
+	upif = NNI_VETH_NORTH_PFX + strconv.Itoa(int(oltid))
+	dwif = NNI_VETH_SOUTH_PFX + strconv.Itoa(int(oltid))
 	return
 }
 
diff --git a/core/mediator.go b/core/mediator.go
index aea0e71..002ce6d 100644
--- a/core/mediator.go
+++ b/core/mediator.go
@@ -84,16 +84,10 @@
 	return o
 }
 
-type handler struct {
-	dst    device.DeviceState
-	src    device.DeviceState
-	method func(s *Server) error
-}
-
 type mediator struct {
-	opt    *option
-	server *Server
-	tester *Tester
+	opt         *option
+	server      *Server
+	testmanager *TestManager
 }
 
 func NewMediator(o *option) *mediator {
@@ -122,12 +116,11 @@
 		return
 	}()
 
-	tester := NewTester(opt)
+	tm := NewTestManager(opt)
 	m.server = server
-	m.tester = tester
-
+	m.testmanager = tm
 	go func() {
-		m.Mediate(server)
+		m.Mediate()
 	}()
 
 	c := make(chan os.Signal, 1)
@@ -141,8 +134,8 @@
 			wg.Add(1)
 			fmt.Println("SIGINT", sig)
 			close(c)
-			server.Stop()       //Non-blocking
-			tester.Stop(server) //Non-blocking
+			server.Stop() //Non-blocking
+			tm.Stop()     //Non-blocking
 			return
 		}
 	}()
@@ -150,7 +143,7 @@
 	logger.Debug("Reach to the end line")
 }
 
-func (m *mediator) Mediate(s *Server) {
+func (m *mediator) Mediate() {
 	defer logger.Debug("Mediate Done")
 	for sr := range m.server.stateRepCh {
 		next := sr.next
@@ -158,35 +151,42 @@
 		dev := sr.device
 		if reflect.TypeOf(dev) == reflect.TypeOf(&device.Olt{}){
 			logger.Debug("Received OLT Device %v Current: %d Next: %d", dev, current, next)
-			if err := transitOlt(s, current, next, m.tester, m.opt); err != nil {
+			if err := transitOlt(current, next, m.testmanager, m.opt); err != nil {
 				logger.Error("%v", err)
 			}
 		} else if reflect.TypeOf(dev) == reflect.TypeOf(&device.Onu{}) {
 			logger.Debug("Received ONU Device %v Current: %d Next: %d", dev, current, next)
 			key := dev.GetDevkey()
-			if err := transitOnu(s, key, current, next, m.tester, m.opt); err != nil {
+			if err := transitOnu(key, current, next, m.testmanager, m.opt); err != nil {
 				logger.Error("%v", err)
 			}
 		}
 	}
 }
 
-func transitOlt (s *Server, current device.DeviceState, next device.DeviceState, tester *Tester, o *option) error {
+func transitOlt (current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
+	logger.Debug("trnsitOlt called current:%d , next:%d", current, next)
 	if current == device.OLT_PREACTIVE && next == device.OLT_ACTIVE {
-
+		tm.Start()
+		activateDHCPServer("nni_north0", o.dhcpservip)
 	} else if current == device.OLT_ACTIVE && next == device.OLT_PREACTIVE{
-		tester.Stop(s)
+		tm.Stop()
 	}
 	return nil
 }
 
-func transitOnu (s *Server, key device.Devkey, current device.DeviceState, next device.DeviceState, tester *Tester, o *option) error {
+func transitOnu (key device.Devkey, current device.DeviceState, next device.DeviceState, tm *TestManager, o *option) error {
+	logger.Debug("trnsitOnu called with key:%s,  current:%d , next:%d", key, current, next)
 	if current == device.ONU_ACTIVE && next == device.ONU_OMCIACTIVE {
-		if s.isAllOnuOmciActive(){	//TODO: This should be per-ONU control, not by cheking All ONU's status
-			tester.Start(s)
+		t := tm.CreateTester(o, key)
+		if err := tm.StartTester(key, t); err != nil {
+			logger.Error("Cannot Start Executer error:%v", err)
 		}
 	} else if (current == device.ONU_OMCIACTIVE || current == device.ONU_ACTIVE) &&
 		next == device.ONU_INACTIVE {
+		if err := tm.StopTester(key); err != nil {
+			logger.Error("Cannot Start Executer error:%v", err)
+		}
 	}
 	return nil
 }
diff --git a/core/tester.go b/core/tester.go
index 5ca3e5a..a2d9a7d 100644
--- a/core/tester.go
+++ b/core/tester.go
@@ -19,13 +19,12 @@
 import (
 	"context"
 	"os/exec"
-	"sync"
-	"time"
-
 	"gerrit.opencord.org/voltha-bbsim/common/logger"
-	"gerrit.opencord.org/voltha-bbsim/common/utils"
-	log "github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
+	"time"
+	"strconv"
+	"gerrit.opencord.org/voltha-bbsim/device"
+	"fmt"
 )
 
 const (
@@ -36,296 +35,158 @@
 
 type Mode int
 
-type Tester struct {
-	Mode         Mode
-	AAAWait      int
-	DhcpWait     int
+type TestManager struct {
 	DhcpServerIP string
-	Processes    []string
+	Pid          []int
 	Intvl        int
+	testers      map[device.Devkey]*Tester
+	ctx          context.Context
 	cancel       context.CancelFunc
 }
 
-func NewTester(opt *option) *Tester {
-	t := new(Tester)
-	t.AAAWait = opt.aaawait
-	t.DhcpWait = opt.dhcpwait
+type Tester struct {
+	Key device.Devkey
+	Mode Mode
+	ctx          context.Context
+	cancel       context.CancelFunc
+}
+
+func NewTestManager(opt *option) *TestManager {
+	t := new(TestManager)
 	t.DhcpServerIP = opt.dhcpservip
 	t.Intvl = opt.intvl_test
+	return t
+}
+
+func (*TestManager) CreateTester(opt *option, key device.Devkey) *Tester{
+	logger.Debug("CreateTester() called")
+	t := new(Tester)
 	t.Mode = opt.Mode
+	t.Key = key
 	return t
 }
 
 //Blocking
-func (t *Tester) Start(s *Server) error {
-	ctx := context.Background()
-	ctx, cancel := context.WithCancel(ctx)
-	t.cancel = cancel
-	defer func() {
-		cancel()
-		t.Initialize()
-		logger.Debug("Tester Done")
-	}()
-	logger.Info("Tester Run() start")
+func (tm *TestManager) Start() error {
+	ctx, cancel := context.WithCancel(context.Background())
+	tm.ctx = ctx
+	tm.cancel = cancel
+	tm.testers = map[device.Devkey]*Tester{}
+	logger.Info("TestManager start")
+	return nil
+}
+
+func (tm *TestManager) Stop() error {
+	if tm.cancel != nil {
+		tm.cancel()
+	}
+	tm.Initialize()
+	logger.Debug("TestManager Done")
+	return nil
+}
+
+func (tm *TestManager) StartTester (key device.Devkey, t *Tester) error {
+	logger.Debug("StartTester called with key:%v", key)
 	if t.Mode == DEFAULT {
 		//Empty
 	} else if t.Mode == AAA || t.Mode == BOTH {
-		eg, child := errgroup.WithContext(ctx)
+		eg, child := errgroup.WithContext(tm.ctx)
 		child, cancel := context.WithCancel(child)
+		t.ctx = child
+		t.cancel = cancel
 		eg.Go(func() error {
-			defer func() {
-				logger.Debug("exeAAATest Done")
-			}()
-			err := t.exeAAATest(child, s, t.AAAWait)
-			return err
+			err := activateWPASupplicant(key)
+			if err != nil {
+				return err
+			}
+			return nil
 		})
 
 		if t.Mode == BOTH {
+			waitForDHCP := 3
 			eg.Go(func() error {
+				tick := time.NewTicker(time.Second)
+				counter := 0
 				defer func() {
+					tick.Stop()
 					logger.Debug("exeDHCPTest Done")
 				}()
 
-				err := t.exeDHCPTest(ctx, s, t.DhcpWait)
-				return err
+			L:
+				for counter < waitForDHCP {
+					select{
+					case <-tick.C:
+						counter ++
+						if counter == waitForDHCP {	// TODO: This should be fixed
+							break L
+						}
+					case <-child.Done():
+						return nil
+					}
+				}
+				err := activateDHCPClient(key)
+				if err != nil {
+					return err
+				}
+				return nil
 			})
 		}
 		if err := eg.Wait(); err != nil {
-			logger.Error("Error happened in tester: %s", err)
-			cancel()
 			return err
-		} else {
-			logger.Debug("Test successfully finished")
 		}
 	}
+	tm.testers[key] = t
 	return nil
 }
 
-func (t *Tester) Stop(s *Server) error {
-	if t.cancel != nil {
-		t.cancel()
-	}
+func (tm *TestManager) StopTester (key device.Devkey) error {
+	ts := tm.testers[key]
+	ts.cancel()
+	delete(tm.testers, key)
 	return nil
 }
 
-func (t *Tester) Initialize() {
-	logger.Info("Tester Initialize () called")
-	processes := t.Processes
-	logger.Debug("Runnig Process: %s", processes)
-	KillProcesses(processes)
+func (tm *TestManager) Initialize() {
+	logger.Info("TestManager Initialize () called")
+	pids := tm.Pid
+	logger.Debug("Runnig Process: %v", pids)
+	KillProcesses(pids)
 	exec.Command("rm", "/var/run/dhcpd.pid").Run()    //This is for DHCP server activation
 	exec.Command("touch", "/var/run/dhcpd.pid").Run() //This is for DHCP server activation
 }
 
-type UniVeth struct {
-	OnuId uint32
-	Veth  string
-}
-
-func (t *Tester) exeAAATest(ctx context.Context, s *Server, wait int) error {
-	tick := time.NewTicker(time.Second)
-	defer tick.Stop()
-	logger.Info("exeAAATest stands by....")
-	infos, err := s.GetUniIoinfos("outside")
-	if err != nil {
-		return err
-	}
-
-	univeths := []UniVeth{}
-	for _, info := range infos {
-		uv := UniVeth{
-			OnuId: info.onuid,
-			Veth:  info.Name,
-		}
-		univeths = append(univeths, uv)
-	}
-
-	for sec := 1; sec <= wait; sec++ {
-		select {
-		case <-ctx.Done():
-			logger.Debug("exeAAATest thread receives close ")
-			return nil
-		case <-tick.C:
-			logger.WithField("seconds", wait-sec).Info("exeAAATest stands by ... ", wait-sec)
-			if sec == wait {
-				wg := sync.WaitGroup{}
-				wg.Add(1)
-				go func() error {
-					defer wg.Done()
-					err = activateWPASups(ctx, univeths, t.Intvl, s)
-					if err != nil {
-						return err
-					}
-					logger.Info("WPA supplicants are successfully activated ")
-					t.Processes = append(t.Processes, "wpa_supplicant")
-					logger.Debug("Running Process:%s", t.Processes)
-					return nil
-				}()
-				wg.Wait()
-			}
-		}
-	}
-	return nil
-}
-
-func (t *Tester) exeDHCPTest(ctx context.Context, s *Server, wait int) error {
-	tick := time.NewTicker(time.Second)
-	defer tick.Stop()
-	logger.Info("exeDHCPTest stands by....")
-	info, err := s.IdentifyNniIoinfo("outside")
-	if err != nil {
-		return err
-	}
-
-	err = activateDHCPServer(info.Name, t.DhcpServerIP)
-	if err != nil {
-		return err
-	}
-	t.Processes = append(t.Processes, "dhcpd")
-	logger.Debug("Running Process:%s", t.Processes)
-
-	infos, err := s.GetUniIoinfos("outside")
-	if err != nil {
-		return err
-	}
-
-	univeths := []UniVeth{}
-	for _, info := range infos {
-		uv := UniVeth{
-			OnuId: info.onuid,
-			Veth:  info.Name,
-		}
-		univeths = append(univeths, uv)
-	}
-
-	for sec := 1; sec <= wait; sec++ {
-		select {
-		case <-ctx.Done():
-			logger.Debug("exeDHCPTest thread receives close ")
-			return nil
-		case <-tick.C:
-			logger.WithField("seconds", wait-sec).Info("exeDHCPTest stands by ... ", wait-sec)
-			if sec == wait {
-				wg := sync.WaitGroup{}
-				wg.Add(1)
-				go func() error {
-					defer wg.Done()
-					err = activateDHCPClients(ctx, univeths, t.Intvl, s)
-					if err != nil {
-						return err
-					}
-					logger.WithFields(log.Fields{
-						"univeths": univeths,
-					}).Info("DHCP clients are successfully activated")
-					t.Processes = append(t.Processes, "dhclient")
-					logger.Debug("Running Process: ", t.Processes)
-					return nil
-				}()
-				wg.Wait()
-			}
-		}
-	}
-	return nil
-}
-
-func KillProcesses(pnames []string) error {
-	for _, pname := range pnames {
+func KillProcesses(pids []int) error {
+	for _, pname := range pids {
 		killProcess(pname)
 	}
 	return nil
 }
 
-func activateWPASups(ctx context.Context, vethnames []UniVeth, intvl int, s *Server) error {
-	tick := time.NewTicker(time.Duration(intvl) * time.Second)
-	defer tick.Stop()
-	i := 0
-	for {
-		select {
-		case <-tick.C:
-			if i < len(vethnames) {
-				vethname := vethnames[i]
-				if err := activateWPASupplicant(vethname, s); err != nil {
-					return err
-				}
-				i++
-			}
-		case <-ctx.Done():
-			logger.Debug("activateWPASups was canceled by context.")
-			return nil
-		}
-	}
-	return nil
-}
-
-func activateDHCPClients(ctx context.Context, vethnames []UniVeth, intvl int, s *Server) error {
-	tick := time.NewTicker(time.Duration(intvl) * time.Second)
-	defer tick.Stop()
-	i := 0
-	for {
-		select {
-		case <-tick.C:
-			if i < len(vethnames) {
-				vethname := vethnames[i]
-				if err := activateDHCPClient(vethname, s); err != nil {
-					return err
-				}
-				i++
-			}
-		case <-ctx.Done():
-			logger.Debug("activateDHCPClients was canceled by context.")
-			return nil
-		}
-	}
-	return nil
-}
-
-func killProcess(name string) error {
-	err := exec.Command("pkill", name).Run()
+func killProcess(pid int) error {
+	err := exec.Command("kill", strconv.Itoa(pid)).Run()
 	if err != nil {
-		logger.Error("Fail to pkill %s: %v", name, err)
+		logger.Error("Fail to kill %d: %v", pid, err)
 		return err
 	}
-	logger.Info("Successfully killed %s", name)
+	logger.Info("Successfully killed %d", pid)
 	return nil
 }
 
-func activateWPASupplicant(univeth UniVeth, s *Server) (err error) {
-	/*
-	cmd := "/sbin/wpa_supplicant"
-	conf := "/etc/wpa_supplicant/wpa_supplicant.conf"
-	err = exec.Command(cmd, "-D", "wired", "-i", univeth.Veth, "-c", conf).Start()
-	*/
-	onu, _ := s.GetOnuByID(univeth.OnuId)
-	if err = startEAPClient(onu.IntfID, onu.OnuID); err != nil {
-		logger.Error("%s", err)
+func activateWPASupplicant(key device.Devkey) (err error) {
+	if err = startEAPClient(key.Intfid, key.ID); err != nil {
+		errmsg := fmt.Sprintf("Failed to activate WPA Supplicant intfid: %d onuid: %d", key.Intfid, key.ID)
+		logger.Error(errmsg)
 	}
-	if err != nil {
-		utils.LoggerWithOnu(onu).WithFields(log.Fields{
-			"err":  err,
-			"veth": univeth.Veth,
-		}).Error("Fail to activateWPASupplicant()", err)
-		return
-	}
-	logger.Info("activateWPASupplicant() for :%s", univeth.Veth)
-	return
+	logger.Info("Successfuly activateWPASupplicant() for intfid:%d onuid:%d", key.Intfid, key.ID)
+	return nil
 }
 
-func activateDHCPClient(univeth UniVeth, s *Server) (err error) {
-	onu, _ := s.GetOnuByID(univeth.OnuId)
-	if err = startDHCPClient(onu.IntfID, onu.OnuID); err != nil {
-		logger.Error("%s", err)
+func activateDHCPClient(key device.Devkey) (err error) {
+	if err = startDHCPClient(key.Intfid, key.ID); err != nil {
+		errmsg := fmt.Sprintf("Failed to activate DHCP client intfid: %d onuid: %d", key.Intfid, key.ID)
+		logger.Error(errmsg)
 	}
-	/*
-	cmd := exec.Command("/usr/local/bin/dhclient", univeth.Veth)
-	if err := cmd.Start(); err != nil {
-		logger.Error("Fail to activateDHCPClient() for: %s", univeth.Veth)
-		logger.Panic("activateDHCPClient %s", err)
-	}*/
-
-	utils.LoggerWithOnu(onu).WithFields(log.Fields{
-		"veth": univeth.Veth,
-	}).Infof("activateDHCPClient() start for: %s", univeth.Veth)
-	return
+	return nil
 }
 
 func activateDHCPServer (veth string, serverip string) error {
@@ -349,4 +210,4 @@
 	}
 	logger.Info("DHCP Server is successfully activated !")
 	return err
-}
+}
\ No newline at end of file
