Skip to content

Commit

Permalink
chore: sync for release
Browse files Browse the repository at this point in the history
  • Loading branch information
LightDestory committed Jan 3, 2025
1 parent 3df89c4 commit 5636ebb
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 177 deletions.
2 changes: 1 addition & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func main() {
// Check if the verbose flag is set to true, and if so, enable verbose logging.
if cfg.Verbose {
shared.Verbose = true
log.Println("Verbose logging enabled")
shared.DebugPrint("Verbose mode enabled")
}
// Create a new simulator controller and repository.
simulatorRepository := repo.NewSimulatorRepository()
Expand Down
8 changes: 8 additions & 0 deletions shared/shared.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package shared

import "log"

// Verbose flag
var Verbose bool = false

func DebugPrint(msg string) {
if Verbose {
log.Printf("[DEBUG]: %s", msg)
}
}
98 changes: 30 additions & 68 deletions simulator/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package simulator

import (
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/arslab/lwnsimulator/shared"
"log"
"strings"

Expand All @@ -24,20 +24,19 @@ import (
)

func GetInstance() *Simulator {

var s Simulator

shared.DebugPrint("Init new Simulator instance")
// Initial state of the simulator is stopped
s.State = util.Stopped

// Load saved data
s.loadData()

// Initialized the active devices and gateways maps
s.ActiveDevices = make(map[int]int)
s.ActiveGateways = make(map[int]int)

// Init Forwarder
s.Forwarder = *f.Setup()

// Attach console
s.Console = c.Console{}

return &s
}

Expand All @@ -47,152 +46,115 @@ func (s *Simulator) AddWebSocket(WebSocket *socketio.Conn) {
s.SetupConsole()
}

// Run starts the simulation environment
func (s *Simulator) Run() {

shared.DebugPrint("Executing Run")
s.State = util.Running
s.setup()

s.Print("START", nil, util.PrintBoth)

shared.DebugPrint("Turning ON active components")
for _, id := range s.ActiveGateways {
s.turnONGateway(id)
}

for _, id := range s.ActiveDevices {
s.turnONDevice(id)
}
}

// Stop terminates the simulation environment
func (s *Simulator) Stop() {

shared.DebugPrint("Executing Stop")
s.State = util.Stopped
s.Resources.ExitGroup.Add(len(s.ActiveGateways) + len(s.ActiveDevices) - s.ComponentsInactiveTmp)

shared.DebugPrint("Turning OFF active components")
for _, id := range s.ActiveGateways {
s.Gateways[id].TurnOFF()
}

for _, id := range s.ActiveDevices {
s.Devices[id].TurnOFF()
}

s.Resources.ExitGroup.Wait()

s.saveStatus()

s.Forwarder.Reset()

s.Print("STOPPED", nil, util.PrintBoth)

s.reset()

}

// SaveBridgeAddress stores the bridge address in the simulator struct and saves it to the simulator.json file
func (s *Simulator) SaveBridgeAddress(remoteAddr models.AddressIP) error {

// Store the bridge address in the simulator struct
s.BridgeAddress = fmt.Sprintf("%v:%v", remoteAddr.Address, remoteAddr.Port)

pathDir, err := util.GetPath()
if err != nil {
log.Fatal(err)
}

path := pathDir + "/simulator.json"

bytes, err := json.MarshalIndent(&s, "", "\t")
if err != nil {
log.Fatal(err)
}

err = util.WriteConfigFile(path, bytes)
if err != nil {
log.Fatal(err)
}

s.saveComponent(path, &s)
s.Print("Gateway Bridge Address saved", nil, util.PrintOnlyConsole)

return nil
}

// GetBridgeAddress returns the bridge address stored in the simulator struct
func (s *Simulator) GetBridgeAddress() models.AddressIP {

// Create an empty AddressIP struct with default values
var rServer models.AddressIP
if s.BridgeAddress == "" {
return rServer
}

// Split the bridge address into address and port
parts := strings.Split(s.BridgeAddress, ":")

rServer.Address = parts[0]
rServer.Port = parts[1]

return rServer
}

// GetGateways returns an array of all gateways in the simulator
func (s *Simulator) GetGateways() []gw.Gateway {

var gateways []gw.Gateway

for _, g := range s.Gateways {
gateways = append(gateways, *g)
}

return gateways

}

// GetDevices returns an array of all devices in the simulator
func (s *Simulator) GetDevices() []dev.Device {

var devices []dev.Device

for _, d := range s.Devices {
devices = append(devices, *d)
}

return devices

}

// SetGateway adds or updates a gateway
func (s *Simulator) SetGateway(gateway *gw.Gateway, update bool) (int, int, error) {

shared.DebugPrint(fmt.Sprintf("Adding/Updating Gateway [%s]", gateway.Info.MACAddress.String()))
emptyAddr := lorawan.EUI64{0, 0, 0, 0, 0, 0, 0, 0}

// Check if the MAC address is valid
if gateway.Info.MACAddress == emptyAddr {

s.Print("Error: MAC Address invalid", nil, util.PrintOnlyConsole)
return codes.CodeErrorAddress, -1, errors.New("Error: MAC Address invalid")

}

if !update { //new

// If the gateway is new, assign a new ID
if !update {
gateway.Id = s.NextIDGw
s.NextIDGw++

} else {

} else { // If the gateway is being updated, it must be turned off
if s.Gateways[gateway.Id].IsOn() {
return codes.CodeErrorDeviceActive, -1, errors.New("Gateway is running, unable update")
}

}

// Check if the name is already used
code, err := s.searchName(gateway.Info.Name, gateway.Id, true)
if err != nil {

s.Print("Name already used", nil, util.PrintOnlyConsole)
return code, -1, err

}

// Check if the name is already used
code, err = s.searchAddress(gateway.Info.MACAddress, gateway.Id, true)
if err != nil {

s.Print("DevEUI already used", nil, util.PrintOnlyConsole)
return code, -1, err

}

if !gateway.Info.TypeGateway {

if s.BridgeAddress == "" {
Expand Down Expand Up @@ -230,7 +192,7 @@ func (s *Simulator) SetGateway(gateway *gw.Gateway, update bool) (int, int, erro
delete(s.ActiveGateways, gateway.Id)
}
}

s.NextIDGw++
return codes.CodeOK, gateway.Id, nil
}

Expand Down
50 changes: 23 additions & 27 deletions simulator/components/forwarder/api.go
Original file line number Diff line number Diff line change
@@ -1,89 +1,80 @@
package forwarder

import (
"fmt"
"github.com/arslab/lwnsimulator/shared"
dl "github.com/arslab/lwnsimulator/simulator/components/device/frames/downlink"
m "github.com/arslab/lwnsimulator/simulator/components/forwarder/models"
"github.com/arslab/lwnsimulator/simulator/resources/communication/buffer"
pkt "github.com/arslab/lwnsimulator/simulator/resources/communication/packets"
"github.com/brocaar/lorawan"
)

// Setup initializes the Forwarder by initializing the maps and returning a pointer to the Forwarder
func Setup() *Forwarder {

shared.DebugPrint("Init new Forwarder instance")
f := Forwarder{
DevToGw: make(map[lorawan.EUI64]map[lorawan.EUI64]*buffer.BufferUplink), //1[devEUI] 2 [macAddress]
GwtoDev: make(map[uint32]map[lorawan.EUI64]map[lorawan.EUI64]*dl.ReceivedDownlink), //1[fre1] 2 [macAddress] 3[devEUI]
Devices: make(map[lorawan.EUI64]m.InfoDevice),
Gateways: make(map[lorawan.EUI64]m.InfoGateway),
}

return &f

}

// AddDevice adds a device to the Forwarder and update the DevToGw map
func (f *Forwarder) AddDevice(d m.InfoDevice) {

f.Mutex.Lock()
defer f.Mutex.Unlock()

shared.DebugPrint(fmt.Sprintf("Add device %v to Forwarder", d.DevEUI))
f.Devices[d.DevEUI] = d

inner := make(map[lorawan.EUI64]*buffer.BufferUplink)
f.DevToGw[d.DevEUI] = inner

for _, g := range f.Gateways {

if inRange(d, g) {
shared.DebugPrint(fmt.Sprintf("Adding communication link with %s", g.MACAddress))
f.DevToGw[d.DevEUI][g.MACAddress] = g.Buffer
}

}

}

// AddGateway adds a gateway to the Forwarder and update the DevToGw map
func (f *Forwarder) AddGateway(g m.InfoGateway) {

f.Mutex.Lock()
defer f.Mutex.Unlock()

shared.DebugPrint(fmt.Sprintf("Add/Update gateway %v to Forwarder", g.MACAddress))
f.Gateways[g.MACAddress] = g

for _, d := range f.Devices {

if inRange(d, g) {
shared.DebugPrint(fmt.Sprintf("Adding communication link with %s", d.DevEUI))
f.DevToGw[d.DevEUI][g.MACAddress] = g.Buffer
}

}
}

// DeleteDevice removes a device from the Forwarder and update the DevToGw map
func (f *Forwarder) DeleteDevice(DevEUI lorawan.EUI64) {

f.Mutex.Lock()
defer f.Mutex.Unlock()

for key := range f.DevToGw[DevEUI] {
delete(f.DevToGw[DevEUI], key)
}

shared.DebugPrint(fmt.Sprintf("Delete device %v from Forwarder", DevEUI))
clear(f.DevToGw[DevEUI])
delete(f.DevToGw, DevEUI)
delete(f.Devices, DevEUI)

}

// DeleteGateway removes a gateway from the Forwarder and update the DevToGw map
func (f *Forwarder) DeleteGateway(g m.InfoGateway) {

f.Mutex.Lock()
defer f.Mutex.Unlock()

shared.DebugPrint(fmt.Sprintf("Delete gateway %v from Forwarder", g.MACAddress))
for _, d := range f.Devices {
shared.DebugPrint(fmt.Sprintf("Removing communication link with %s", d.DevEUI))
delete(f.DevToGw[d.DevEUI], g.MACAddress)
}

delete(f.Gateways, g.MACAddress)

}

// UpdateDevice updates a device in the Forwarder
func (f *Forwarder) UpdateDevice(d m.InfoDevice) {
f.AddDevice(d)
}
Expand Down Expand Up @@ -161,6 +152,11 @@ func (f *Forwarder) Downlink(data *lorawan.PHYPayload, freq uint32, macAddress l

}

// Reset resets the Forwarder by creating a new instance of the Forwarder
func (f *Forwarder) Reset() {
f = Setup()
shared.DebugPrint("Reset Forwarder")
clear(f.DevToGw)
clear(f.GwtoDev)
clear(f.Devices)
clear(f.Gateways)
}
4 changes: 4 additions & 0 deletions simulator/console/console.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ import (
socketio "github.com/googollee/go-socket.io"
)

// Console represents a socket connection to send messages to the web terminal
type Console struct {
WebSocket socketio.Conn
}

// PrintLog prints a message to the command line stdout
func (c *Console) PrintLog(message string) {
log.Println(message)
}

// PrintSocket prints a message to the web terminal via a socket connection
func (c *Console) PrintSocket(eventName string, data ...interface{}) {
if c.WebSocket != nil {
c.WebSocket.Emit(eventName, data...)
}
}

// SetupWebSocket sets the socket connection for the Console
func (c *Console) SetupWebSocket(WebSocket *socketio.Conn) {
c.WebSocket = *WebSocket
}
Loading

0 comments on commit 5636ebb

Please # to comment.