| /* |
| * 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 ( |
| "context" |
| "os/exec" |
| "gerrit.opencord.org/voltha-bbsim/common/logger" |
| "golang.org/x/sync/errgroup" |
| "time" |
| "strconv" |
| "gerrit.opencord.org/voltha-bbsim/device" |
| "fmt" |
| ) |
| |
| const ( |
| DEFAULT Mode = iota |
| AAA |
| BOTH |
| ) |
| |
| type Mode int |
| |
| type TestManager struct { |
| DhcpServerIP string |
| Pid []int |
| testers map[device.Devkey]*Tester |
| ctx context.Context |
| cancel context.CancelFunc |
| } |
| |
| 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 |
| 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 (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 { |
| _, child := errgroup.WithContext(tm.ctx) |
| child, cancel := context.WithCancel(child) |
| t.ctx = child |
| t.cancel = cancel |
| } else if t.Mode == AAA || t.Mode == BOTH { |
| eg, child := errgroup.WithContext(tm.ctx) |
| child, cancel := context.WithCancel(child) |
| t.ctx = child |
| t.cancel = cancel |
| eg.Go(func() error { |
| 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") |
| }() |
| |
| 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 { |
| return err |
| } |
| } |
| tm.testers[key] = t |
| return nil |
| } |
| |
| func (tm *TestManager) StopTester (key device.Devkey) error { |
| ts := tm.testers[key] |
| ts.cancel() |
| delete(tm.testers, key) |
| return nil |
| } |
| |
| 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 |
| } |
| |
| func KillProcesses(pids []int) error { |
| for _, pname := range pids { |
| killProcess(pname) |
| } |
| return nil |
| } |
| |
| func killProcess(pid int) error { |
| err := exec.Command("kill", strconv.Itoa(pid)).Run() |
| if err != nil { |
| logger.Error("Fail to kill %d: %v", pid, err) |
| return err |
| } |
| logger.Info("Successfully killed %d", pid) |
| return nil |
| } |
| |
| 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) |
| } |
| logger.Info("Successfuly activateWPASupplicant() for intfid:%d onuid:%d", key.Intfid, key.ID) |
| return nil |
| } |
| |
| 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) |
| } |
| return nil |
| } |
| |
| func activateDHCPServer (veth string, serverip string) error { |
| err := exec.Command("ip", "addr", "add", serverip, "dev", veth).Run() |
| if err != nil { |
| logger.Error("Fail to add ip to %s address: %s", veth, err) |
| return err |
| } |
| err = exec.Command("ip", "link", "set", veth, "up").Run() |
| if err != nil { |
| logger.Error("Fail to set %s up: %s", veth, err) |
| return err |
| } |
| cmd := "/usr/local/bin/dhcpd" |
| conf := "/etc/dhcp/dhcpd.conf" |
| logfile := "/tmp/dhcplog" |
| err = exec.Command(cmd, "-cf", conf, veth, "-tf", logfile).Run() |
| if err != nil { |
| logger.Error("Fail to activateDHCP Server (): %s", err) |
| return err |
| } |
| logger.Info("DHCP Server is successfully activated !") |
| return err |
| } |