Commit 2f176409 authored by Yann Garcia's avatar Yann Garcia
Browse files

Enhance GIS engine to support simu5g

parent 3f7db7ba
Loading
Loading
Loading
Loading
+10 −3
Changes for go-apps/meep-gis-engine/server/gis-automation.go: 10 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -73,7 +73,10 @@ func setAutomation(automationType string, state bool) (err error) {
			ge.updateTime = time.Time{}
		}
	} else if automationType == AutoTypeNetChar {
		if !state && ge.automation[AutoTypeNetChar] {
		if state && usesExternalNwSimulator() {
			log.Warn("NETWORK-CHARACTERISTICS-UPDATE not started: Simu5G/OAI network characteristics come from the Network Emulation Stack")
			state = false
		} else if !state && ge.automation[AutoTypeNetChar] && !usesExternalNwSimulator() {
			resetAutoNetChar()
		}
	}
@@ -156,8 +159,9 @@ func runAutomation() {
		runAutoPoaInRange(ueMap)
	}

	// Network Characteristics
	if ge.automation[AutoTypeNetChar] {
	// Network Characteristics (distance-modulated throughput → sandbox-ctrl / TC).
	// Simu5G/OAI: the Network Emulation Stack owns latency/loss/throughput.
	if ge.automation[AutoTypeNetChar] && !usesExternalNwSimulator() {
		runAutoNetChar(ueMap, poaMap)
	}

@@ -261,6 +265,9 @@ func runAutoPoaInRange(ueMap map[string]*am.Ue) {
}

func runAutoNetChar(ueMap map[string]*am.Ue, poaMap map[string]*am.Poa) {
	if usesExternalNwSimulator() {
		return
	}
	for _, ue := range ueMap {
		// Get stored UE info
		ueInfo := getUeInfo(ue.Name)
+16 −10
Changes for go-apps/meep-gis-engine/server/gis-engine.go: 16 added lines, 10 removed lines.
Original line number Diff line number Diff line
@@ -941,25 +941,24 @@ func updateCache() {
		}

		// Update POA measurements if different from cached value
		externalRadio := usesExternalNwSimulator()
		for _, poaMeas := range ue.PoaMeasurements {
			updateRequired := false
			cachedPoaMeas, found := cachedPoaMeasMap[ue.Name]
			var cachedMeas *gc.PoaMeasurement
			if found {
				cachedMeas, found = cachedPoaMeas.Measurements[poaMeas.Poa]
			}
			if !found {
				updateRequired = true
			} else {
				cachedMeas, found := cachedPoaMeas.Measurements[poaMeas.Poa]
				if !found || cachedMeas.Distance != poaMeas.Distance || cachedMeas.Rssi != poaMeas.Rssi || cachedMeas.Rsrp != poaMeas.Rsrp || cachedMeas.Rsrq != poaMeas.Rsrq {
			} else if cachedMeas.Distance != poaMeas.Distance {
				updateRequired = true
			} else if !externalRadio && (cachedMeas.Rssi != poaMeas.Rssi || cachedMeas.Rsrp != poaMeas.Rsrp || cachedMeas.Rsrq != poaMeas.Rsrq) {
				updateRequired = true
				}
			}

			if updateRequired {
				measurement := &gc.PoaMeasurement{
					Rssi:     poaMeas.Rssi,
					Rsrp:     poaMeas.Rsrp,
					Rsrq:     poaMeas.Rsrq,
					Distance: poaMeas.Distance,
				}
				measurement := mergePoaMeasurementForCache(externalRadio, poaMeas.Distance, poaMeas.Rssi, poaMeas.Rsrp, poaMeas.Rsrq, cachedMeas)
				_ = ge.gisCache.SetPoaMeasurement(ue.Name, AssetTypeUe, poaMeas.Poa, poaMeas.SubType, measurement)
				cacheUpdated = true
			}
@@ -1737,6 +1736,13 @@ func geUpdateGeoDataByName(w http.ResponseWriter, r *http.Request) {
}

func geGetGeoDataPowerValues(w http.ResponseWriter, r *http.Request) {
	if usesExternalNwSimulator() {
		log.Info("cellularPower skipped: RSRP/RSRQ come from the Network Emulation Stack")
		w.Header().Set("Content-Type", "application/json; charset=UTF-8")
		w.WriteHeader(http.StatusOK)
		fmt.Fprint(w, `{"coordinatesPower":[]}`)
		return
	}
	// Retrieve coordinates to work with from request body
	var coordinates GeoCoordinateList
	if r.Body == nil {
+82 −0
Changes for go-apps/meep-gis-engine/server/gis_external_sim.go: 82 added lines, 0 removed lines.
Original line number Diff line number Diff line
package server

import (
	"encoding/json"
	"os"
	"strings"

	gc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-cache"
	mod "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model"
)

func isExternalNwSimulatorType(t string) bool {
	switch strings.ToLower(strings.TrimSpace(t)) {
	case "simu5g", "oai":
		return true
	default:
		return false
	}
}

func userMetaExternalNwSimulator(userMeta map[string]string) bool {
	if userMeta == nil {
		return false
	}
	if raw, ok := userMeta["network-info"]; ok && raw != "" {
		var info struct {
			Type string `json:"type"`
		}
		if json.Unmarshal([]byte(raw), &info) == nil && isExternalNwSimulatorType(info.Type) {
			return true
		}
	}
	if raw, ok := userMeta["mec-sandbox"]; ok && raw != "" {
		var ms struct {
			ConnectivityModel string `json:"connectivityModel"`
		}
		if json.Unmarshal([]byte(raw), &ms) == nil && isExternalNwSimulatorType(ms.ConnectivityModel) {
			return true
		}
	}
	return false
}

// usesExternalNwSimulator is true when the platform catalog is Simu5G/OAI
// or the active scenario userMeta says the Network Emulation Stack owns radio/net-char.
func usesExternalNwSimulator() bool {
	if isExternalNwSimulatorType(os.Getenv("MEEP_NW_SIMULATOR_TYPE")) {
		return true
	}
	if ge == nil || ge.activeModel == nil {
		return false
	}
	dep := ge.activeModel.GetDeployment(&mod.NodeFilter{ExcludeChildren: true})
	if dep == nil {
		return false
	}
	return userMetaExternalNwSimulator(dep.UserMeta)
}

// mergePoaMeasurementForCache keeps GIS-cache radio fields owned by the
// Network Emulation Stack (Simu5G/OAI). Distance still comes from PostGIS.
func mergePoaMeasurementForCache(external bool, distance, rssi, rsrp, rsrq float32, cached *gc.PoaMeasurement) *gc.PoaMeasurement {
	m := &gc.PoaMeasurement{
		Distance: distance,
		Rssi:     rssi,
		Rsrp:     rsrp,
		Rsrq:     rsrq,
	}
	if !external {
		return m
	}
	if cached != nil {
		m.Rssi = cached.Rssi
		m.Rsrp = cached.Rsrp
		m.Rsrq = cached.Rsrq
	} else {
		m.Rssi = 0
		m.Rsrp = 0
		m.Rsrq = 0
	}
	return m
}
+71 −0
Changes for go-apps/meep-gis-engine/server/gis_external_sim_test.go: 71 added lines, 0 removed lines.
Original line number Diff line number Diff line
package server

import (
	"os"
	"testing"

	gc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-cache"
)

func TestIsExternalNwSimulatorType(t *testing.T) {
	if !isExternalNwSimulatorType("simu5g") || !isExternalNwSimulatorType("OAI") {
		t.Fatal("simu5g/oai must be external")
	}
	if isExternalNwSimulatorType("internal") || isExternalNwSimulatorType("") {
		t.Fatal("internal must not be external")
	}
}

func TestUserMetaExternalNwSimulator(t *testing.T) {
	if !userMetaExternalNwSimulator(map[string]string{
		"network-info": `{"type": "simu5g", "path":""}`,
	}) {
		t.Fatal("network-info type simu5g")
	}
	if !userMetaExternalNwSimulator(map[string]string{
		"mec-sandbox": `{"connectivityModel": "oai"}`,
	}) {
		t.Fatal("mec-sandbox connectivityModel oai")
	}
	if userMetaExternalNwSimulator(map[string]string{
		"network-info": `{"type": "internal"}`,
	}) {
		t.Fatal("internal network-info")
	}
	if userMetaExternalNwSimulator(nil) {
		t.Fatal("nil userMeta")
	}
}

func TestMergePoaMeasurementForCache(t *testing.T) {
	cached := &gc.PoaMeasurement{Rssi: 11, Rsrp: -80, Rsrq: 12, Distance: 10}
	got := mergePoaMeasurementForCache(true, 50, 1, 2, 3, cached)
	if got.Distance != 50 || got.Rssi != 11 || got.Rsrp != -80 || got.Rsrq != 12 {
		t.Fatalf("external must keep cached radio and take new distance: %+v", got)
	}
	got = mergePoaMeasurementForCache(true, 50, 1, 2, 3, nil)
	if got.Distance != 50 || got.Rssi != 0 || got.Rsrp != 0 || got.Rsrq != 0 {
		t.Fatalf("external with empty cache must not store GIS-computed radio: %+v", got)
	}
	got = mergePoaMeasurementForCache(false, 50, 1, 2, 3, cached)
	if got.Distance != 50 || got.Rssi != 1 || got.Rsrp != 2 || got.Rsrq != 3 {
		t.Fatalf("internal must use GIS-computed radio: %+v", got)
	}
}

func TestUsesExternalNwSimulatorEnv(t *testing.T) {
	prev := os.Getenv("MEEP_NW_SIMULATOR_TYPE")
	defer os.Setenv("MEEP_NW_SIMULATOR_TYPE", prev)
	saved := ge
	ge = nil
	defer func() { ge = saved }()

	os.Setenv("MEEP_NW_SIMULATOR_TYPE", "simu5g")
	if !usesExternalNwSimulator() {
		t.Fatal("simu5g env must be external")
	}
	os.Setenv("MEEP_NW_SIMULATOR_TYPE", "internal")
	if usesExternalNwSimulator() {
		t.Fatal("internal env must not be external")
	}
}
+1 −1
Changes for go-apps/meep-platform-ctrl/server/platform-ctrl.go: 1 added line, 1 removed line.
Original line number Diff line number Diff line
@@ -422,7 +422,7 @@ func pcGetScenarioList(w http.ResponseWriter, r *http.Request) {
		nemList, nemErr = pfmCtrl.nwCatalog.ListNemScenarios(r.Context())
		if nemErr != nil {
			log.Error("NEM scenario catalog: ", nemErr.Error())
			http.Error(w, nemErr.Error(), http.StatusBadGateway)
			http.Error(w, nwcat.ErrMsgNemNotRunning, http.StatusBadGateway)
			return
		}
	}