Loading go-apps/meep-rnis/sbi/rnis-sbi.go +16 −49 Original line number Diff line number Diff line Loading @@ -31,10 +31,10 @@ const moduleName string = "meep-rnis-sbi" type SbiCfg struct { SandboxName string RedisAddr string UeDataCb func(string, string, string, string, string, bool) UeDataCb func(string, string, string, string, string, bool, []string) MeasInfoCb func(string, string, []string, []int32, []int32) PoaInfoCb func(string, string, string, string, string) AppEcgiInfoCb func(string, string, string, string) AppInfoCb func(string, string, string) DomainDataCb func(string, string, string, string) ScenarioNameCb func(string) CleanUpCb func() Loading @@ -47,10 +47,10 @@ type RnisSbi struct { activeModel *mod.Model gisCache *gc.GisCache refreshTicker *time.Ticker updateUeDataCB func(string, string, string, string, string, bool) updateUeDataCB func(string, string, string, string, string, bool, []string) updateMeasInfoCB func(string, string, []string, []int32, []int32) updatePoaInfoCB func(string, string, string, string, string) updateAppEcgiInfoCB func(string, string, string, string) updateAppInfoCB func(string, string, string) updateDomainDataCB func(string, string, string, string) updateScenarioNameCB func(string) cleanUpCB func() Loading @@ -70,7 +70,7 @@ func Init(cfg SbiCfg) (err error) { sbi.updateUeDataCB = cfg.UeDataCb sbi.updateMeasInfoCB = cfg.MeasInfoCb sbi.updatePoaInfoCB = cfg.PoaInfoCb sbi.updateAppEcgiInfoCB = cfg.AppEcgiInfoCb sbi.updateAppInfoCB = cfg.AppInfoCb sbi.updateDomainDataCB = cfg.DomainDataCb sbi.updateScenarioNameCB = cfg.ScenarioNameCb sbi.cleanUpCB = cfg.CleanUpCb Loading Loading @@ -230,7 +230,6 @@ func processActiveScenarioUpdate() { continue } ueNames = append(ueNames, name) ueParent := sbi.activeModel.GetNodeParent(name) if poa, ok := ueParent.(*dataModel.NetworkLocation); ok { poaParent := sbi.activeModel.GetNodeParent(poa.Name) Loading Loading @@ -270,7 +269,14 @@ func processActiveScenarioUpdate() { cellId = "" } sbi.updateUeDataCB(name, mnc, mcc, cellId, nrcellId, erabIdValid) node := sbi.activeModel.GetNodeChild(name) apps := node.(*[]dataModel.Process) var appNames []string for _, process := range *apps { appNames = append(appNames, process.Name) } sbi.updateUeDataCB(name, mnc, mcc, cellId, nrcellId, erabIdValid, appNames) } } } Loading @@ -286,7 +292,7 @@ func processActiveScenarioUpdate() { } } if !found { sbi.updateUeDataCB(prevUeName, "", "", "", "", false) sbi.updateUeDataCB(prevUeName, "", "", "", "", false, nil) log.Info("Ue removed : ", prevUeName) } } Loading @@ -307,46 +313,7 @@ func processActiveScenarioUpdate() { continue } appNames = append(appNames, appName) plParent := sbi.activeModel.GetNodeParent(pl.Name) if nl, ok := plParent.(*dataModel.NetworkLocation); ok { //nl can be either POA for {FOG or UE} or Zone Default for {Edge nlParent := sbi.activeModel.GetNodeParent(nl.Name) if zone, ok := nlParent.(*dataModel.Zone); ok { zoneParent := sbi.activeModel.GetNodeParent(zone.Name) if domain, ok := zoneParent.(*dataModel.Domain); ok { mnc := "" mcc := "" cellId := "" if domain.CellularDomainConfig != nil { mnc = domain.CellularDomainConfig.Mnc mcc = domain.CellularDomainConfig.Mcc cellId = domain.CellularDomainConfig.DefaultCellId } switch nl.Type_ { case mod.NodeTypePoa4G: if nl.Poa4GConfig != nil { if nl.Poa4GConfig.CellId != "" { cellId = nl.Poa4GConfig.CellId } } /*no support for RNIS on 5G elements anymore case mod.NodeTypePoa5G: if nl.Poa5GConfig != nil { if nl.Poa5GConfig.CellId != "" { cellId = nl.Poa5GConfig.CellId } } */ default: //empty cells for POAs not supporting RNIS cellId = "" } sbi.updateAppEcgiInfoCB(appName, mnc, mcc, cellId) } } } sbi.updateAppInfoCB(appName, pl.Type_, pl.Name) } } Loading @@ -360,7 +327,7 @@ func processActiveScenarioUpdate() { } } if !found { sbi.updateAppEcgiInfoCB(prevApp, "", "", "") sbi.updateAppInfoCB(prevApp, "", "") log.Info("App removed : ", prevApp) } } Loading go-apps/meep-rnis/server/api_rni.go +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import ( ) func Layer2MeasInfoGET(w http.ResponseWriter, r *http.Request) { notImplemented(w, r) layer2MeasInfoGet(w, r) } func PlmnInfoGET(w http.ResponseWriter, r *http.Request) { Loading go-apps/meep-rnis/server/convert.go +3 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ import ( log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" ) func convertJsonToEcgi(jsonInfo string) *Ecgi { func convertJsonToAppInfo(jsonInfo string) *AppInfo { var obj Ecgi var obj AppInfo err := json.Unmarshal([]byte(jsonInfo), &obj) if err != nil { log.Error(err.Error()) Loading @@ -33,7 +33,7 @@ func convertJsonToEcgi(jsonInfo string) *Ecgi { return &obj } func convertEcgiToJson(obj *Ecgi) string { func convertAppInfoToJson(obj *AppInfo) string { jsonInfo, err := json.Marshal(*obj) if err != nil { Loading go-apps/meep-rnis/server/rnis.go +263 −27 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ const measRepUeSubscriptionType = "meas_rep_ue" const nrMeasRepUeSubscriptionType = "nr_meas_rep_ue" const poaType4G = "POA-4G" const poaType5G = "POA-5G" const plTypeUE = "UE" var ccSubscriptionMap = map[int]*CellChangeSubscription{} var reSubscriptionMap = map[int]*RabEstSubscription{} Loading Loading @@ -105,6 +106,12 @@ type RabInfoData struct { rabInfo *RabInfo } type L2MeasData struct { queryCellIds []string queryIpv4Addresses []string l2Meas *L2Meas } type UeData struct { Name string `json:"name"` ErabId int32 `json:"erabId"` Loading @@ -113,6 +120,7 @@ type UeData struct { Qci int32 `json:"qci"` ParentPoaName string `json:"parentPoaName"` InRangePoas []InRangePoa `json:"inRangePoas"` AppNames []string `json:"appNames"` } type InRangePoa struct { Loading @@ -127,6 +135,11 @@ type PoaInfo struct { Nrcgi NRcgi `json:"nrcgi"` } type AppInfo struct { ParentType string `json:"parentType"` ParentName string `json:"parentName"` } type DomainData struct { Mcc string `json:"mcc"` Mnc string `json:"mnc"` Loading Loading @@ -221,7 +234,7 @@ func Init() (err error) { UeDataCb: updateUeData, MeasInfoCb: updateMeasInfo, PoaInfoCb: updatePoaInfo, AppEcgiInfoCb: updateAppEcgiInfo, AppInfoCb: updateAppInfo, DomainDataCb: updateDomainData, ScenarioNameCb: updateStoreName, CleanUpCb: cleanUp, Loading Loading @@ -261,7 +274,7 @@ func Stop() (err error) { return sbi.Stop() } func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId string, erabIdValid bool) { func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId string, erabIdValid bool, appNames []string) { var plmn Plmn var newEcgi Ecgi Loading @@ -279,6 +292,7 @@ func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId s ueData.Nrcgi = &newNrcgi ueData.Name = name ueData.Qci = defaultSupportedQci //only supporting one value ueData.AppNames = appNames oldPlmn := new(Plmn) oldPlmnMnc := "" Loading Loading @@ -405,35 +419,32 @@ func updatePoaInfo(name string, poaType string, mnc string, mcc string, cellId s _ = rc.JSONSetEntry(baseKey+"POA:"+name, ".", convertPoaInfoToJson(&poaInfo)) } func updateAppEcgiInfo(name string, mnc string, mcc string, cellId string) { var plmn Plmn var newEcgi Ecgi plmn.Mnc = mnc plmn.Mcc = mcc newEcgi.CellId = cellId newEcgi.Plmn = &plmn func updateAppInfo(name string, parentType string, parentName string) { //get from DB jsonAppEcgiInfo, _ := rc.JSONGetEntry(baseKey+"APP:"+name, ".") jsonAppInfo, _ := rc.JSONGetEntry(baseKey+"APP:"+name+"*", ".") oldPlmnMnc := "" oldPlmnMcc := "" oldCellId := "" if jsonAppEcgiInfo != "" { ecgiInfo := convertJsonToEcgi(jsonAppEcgiInfo) oldPlmnMnc = ecgiInfo.Plmn.Mnc oldPlmnMcc = ecgiInfo.Plmn.Mcc oldCellId = ecgiInfo.CellId if jsonAppInfo != "" { //delete entry if parent name is different; means it moved currentAppInfo := convertJsonToAppInfo(jsonAppInfo) if currentAppInfo.ParentName != parentName { if currentAppInfo.ParentType == plTypeUE { _ = rc.JSONDelEntry(baseKey+"APP:"+name+":"+currentAppInfo.ParentName, ".") } } else { //no changes.. just get out return } } //updateDB if changes occur if newEcgi.Plmn.Mnc != oldPlmnMnc || newEcgi.Plmn.Mcc != oldPlmnMcc || newEcgi.CellId != oldCellId { //updateDB _ = rc.JSONSetEntry(baseKey+"APP:"+name, ".", convertEcgiToJson(&newEcgi)) var appInfo AppInfo appInfo.ParentType = parentType appInfo.ParentName = parentName if parentType == plTypeUE { _ = rc.JSONSetEntry(baseKey+"APP:"+name+":"+parentName, ".", convertAppInfoToJson(&appInfo)) } else { _ = rc.JSONSetEntry(baseKey+"APP:"+name, ".", convertAppInfoToJson(&appInfo)) } } Loading Loading @@ -2482,6 +2493,231 @@ func populatePlmnInfo(key string, jsonInfo string, response interface{}) error { return nil } func layer2MeasInfoGet(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") var l2MeasData L2MeasData u, _ := url.Parse(r.URL.String()) log.Info("url: ", u.RequestURI()) q := u.Query() //meAppName := q.Get("app_ins_id") l2MeasData.queryCellIds = q["cell_id"] l2MeasData.queryIpv4Addresses = q["ue_ipv4_address"] seconds := time.Now().Unix() var timeStamp TimeStamp timeStamp.Seconds = int32(seconds) //meApp is ignored, we use the whole network var l2Meas L2Meas l2MeasData.l2Meas = &l2Meas //get from DB //loop through each UE keyName := baseKey + "UE:*" err := rc.ForEachJSONEntry(keyName, populateL2Meas, &l2MeasData) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } //loop through each POA keyName = baseKey + "POA:*" err = rc.ForEachJSONEntry(keyName, populateL2MeasPOA, &l2MeasData) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } l2Meas.TimeStamp = &timeStamp // Send response jsonResponse, err := json.Marshal(l2Meas) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, string(jsonResponse)) } func populateL2MeasPOA(key string, jsonInfo string, l2MeasData interface{}) error { // Get query params & userlist from user data data := l2MeasData.(*L2MeasData) if data == nil || data.l2Meas == nil { return errors.New("l2Meas not found in l2MeasData") } // Retrieve user info from DB var poaData PoaInfo err := json.Unmarshal([]byte(jsonInfo), &poaData) if err != nil { return err } //only applies for 4G poas if poaData.Type != poaType4G { return nil } partOfFilter := true for _, cellId := range data.queryCellIds { if cellId != "" { partOfFilter = false if cellId == poaData.Ecgi.CellId { partOfFilter = true break } } } if !partOfFilter { return nil } found := false //find if cellInfo already exists for _, currentCellInfo := range data.l2Meas.CellInfo { if currentCellInfo.Ecgi.Plmn.Mcc == poaData.Ecgi.Plmn.Mcc && currentCellInfo.Ecgi.Plmn.Mnc == poaData.Ecgi.Plmn.Mnc && currentCellInfo.Ecgi.CellId == poaData.Ecgi.CellId { //add ue into the existing cellUserInfo found = true } } if !found { newCellInfo := new(L2MeasCellInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = poaData.Ecgi.Plmn.Mcc newPlmn.Mnc = poaData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = poaData.Ecgi.CellId newCellInfo.Ecgi = newEcgi data.l2Meas.CellInfo = append(data.l2Meas.CellInfo, *newCellInfo) } return nil } func populateL2Meas(key string, jsonInfo string, l2MeasData interface{}) error { // Get query params & userlist from user data data := l2MeasData.(*L2MeasData) if data == nil || data.l2Meas == nil { return errors.New("l2Meas not found in l2MeasData") } // Retrieve user info from DB var ueData UeData err := json.Unmarshal([]byte(jsonInfo), &ueData) if err != nil { return err } // Ignore entries with no rabId, meaning only applies if connected to POA-4G, no need to check for ecgi if ueData.ErabId == -1 { return nil } partOfFilter := true for _, cellId := range data.queryCellIds { if cellId != "" { partOfFilter = false if cellId == ueData.Ecgi.CellId { partOfFilter = true break } } } if !partOfFilter { return nil } //name of the element is used as the ipv4 address at the moment partOfFilter = true for _, address := range data.queryIpv4Addresses { if address != "" { partOfFilter = false if address == ueData.Name { partOfFilter = true break } } } if !partOfFilter { return nil } found := false //find if cellUeInfo already exists assocId := new(AssociateId) assocId.Type_ = 1 //UE_IPV4_ADDRESS subKeys := strings.Split(key, ":") assocId.Value = subKeys[len(subKeys)-1] for _, currentCellUeInfo := range data.l2Meas.CellUEInfo { if assocId.Type_ == currentCellUeInfo.AssociateId.Type_ && assocId.Value == currentCellUeInfo.AssociateId.Value { found = true } } if !found { newCellUeInfo := new(L2MeasCellUeInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = ueData.Ecgi.Plmn.Mcc newPlmn.Mnc = ueData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = ueData.Ecgi.CellId newCellUeInfo.Ecgi = newEcgi newCellUeInfo.AssociateId = assocId data.l2Meas.CellUEInfo = append(data.l2Meas.CellUEInfo, *newCellUeInfo) } //find if cellInfo already exists var cellIndex int for index, currentCellInfo := range data.l2Meas.CellInfo { if currentCellInfo.Ecgi.Plmn.Mcc == ueData.Ecgi.Plmn.Mcc && currentCellInfo.Ecgi.Plmn.Mnc == ueData.Ecgi.Plmn.Mnc && currentCellInfo.Ecgi.CellId == ueData.Ecgi.CellId { //add ue into the existing cellUserInfo found = true cellIndex = index } } if !found { newCellInfo := new(L2MeasCellInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = ueData.Ecgi.Plmn.Mcc newPlmn.Mnc = ueData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = ueData.Ecgi.CellId newCellInfo.Ecgi = newEcgi data.l2Meas.CellInfo = append(data.l2Meas.CellInfo, *newCellInfo) cellIndex = len(data.l2Meas.CellInfo) - 1 } //need to do a qci mapping... since qci can only be 80 for now, using the one that correlates to that data.l2Meas.CellInfo[cellIndex].NumberOfActiveUeDlNongbrCell++ data.l2Meas.CellInfo[cellIndex].NumberOfActiveUeUlNongbrCell++ return nil } func rabInfoGet(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") Loading go-apps/meep-rnis/server/rnis_test.go +2 −2 Original line number Diff line number Diff line Loading @@ -2179,8 +2179,8 @@ func TestSbi(t *testing.T) { ******************************/ var expectedUeDataStr [2]string var expectedUeData [2]UeData expectedUeData[INITIAL] = UeData{ueName, 1, &Ecgi{"2345678", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil} expectedUeData[UPDATED] = UeData{ueName, -1, &Ecgi{"", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil} expectedUeData[INITIAL] = UeData{ueName, 1, &Ecgi{"2345678", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil, nil} expectedUeData[UPDATED] = UeData{ueName, -1, &Ecgi{"", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil, nil} var expectedAppEcgiStr [2]string var expectedAppEcgi [2]Ecgi Loading Loading
go-apps/meep-rnis/sbi/rnis-sbi.go +16 −49 Original line number Diff line number Diff line Loading @@ -31,10 +31,10 @@ const moduleName string = "meep-rnis-sbi" type SbiCfg struct { SandboxName string RedisAddr string UeDataCb func(string, string, string, string, string, bool) UeDataCb func(string, string, string, string, string, bool, []string) MeasInfoCb func(string, string, []string, []int32, []int32) PoaInfoCb func(string, string, string, string, string) AppEcgiInfoCb func(string, string, string, string) AppInfoCb func(string, string, string) DomainDataCb func(string, string, string, string) ScenarioNameCb func(string) CleanUpCb func() Loading @@ -47,10 +47,10 @@ type RnisSbi struct { activeModel *mod.Model gisCache *gc.GisCache refreshTicker *time.Ticker updateUeDataCB func(string, string, string, string, string, bool) updateUeDataCB func(string, string, string, string, string, bool, []string) updateMeasInfoCB func(string, string, []string, []int32, []int32) updatePoaInfoCB func(string, string, string, string, string) updateAppEcgiInfoCB func(string, string, string, string) updateAppInfoCB func(string, string, string) updateDomainDataCB func(string, string, string, string) updateScenarioNameCB func(string) cleanUpCB func() Loading @@ -70,7 +70,7 @@ func Init(cfg SbiCfg) (err error) { sbi.updateUeDataCB = cfg.UeDataCb sbi.updateMeasInfoCB = cfg.MeasInfoCb sbi.updatePoaInfoCB = cfg.PoaInfoCb sbi.updateAppEcgiInfoCB = cfg.AppEcgiInfoCb sbi.updateAppInfoCB = cfg.AppInfoCb sbi.updateDomainDataCB = cfg.DomainDataCb sbi.updateScenarioNameCB = cfg.ScenarioNameCb sbi.cleanUpCB = cfg.CleanUpCb Loading Loading @@ -230,7 +230,6 @@ func processActiveScenarioUpdate() { continue } ueNames = append(ueNames, name) ueParent := sbi.activeModel.GetNodeParent(name) if poa, ok := ueParent.(*dataModel.NetworkLocation); ok { poaParent := sbi.activeModel.GetNodeParent(poa.Name) Loading Loading @@ -270,7 +269,14 @@ func processActiveScenarioUpdate() { cellId = "" } sbi.updateUeDataCB(name, mnc, mcc, cellId, nrcellId, erabIdValid) node := sbi.activeModel.GetNodeChild(name) apps := node.(*[]dataModel.Process) var appNames []string for _, process := range *apps { appNames = append(appNames, process.Name) } sbi.updateUeDataCB(name, mnc, mcc, cellId, nrcellId, erabIdValid, appNames) } } } Loading @@ -286,7 +292,7 @@ func processActiveScenarioUpdate() { } } if !found { sbi.updateUeDataCB(prevUeName, "", "", "", "", false) sbi.updateUeDataCB(prevUeName, "", "", "", "", false, nil) log.Info("Ue removed : ", prevUeName) } } Loading @@ -307,46 +313,7 @@ func processActiveScenarioUpdate() { continue } appNames = append(appNames, appName) plParent := sbi.activeModel.GetNodeParent(pl.Name) if nl, ok := plParent.(*dataModel.NetworkLocation); ok { //nl can be either POA for {FOG or UE} or Zone Default for {Edge nlParent := sbi.activeModel.GetNodeParent(nl.Name) if zone, ok := nlParent.(*dataModel.Zone); ok { zoneParent := sbi.activeModel.GetNodeParent(zone.Name) if domain, ok := zoneParent.(*dataModel.Domain); ok { mnc := "" mcc := "" cellId := "" if domain.CellularDomainConfig != nil { mnc = domain.CellularDomainConfig.Mnc mcc = domain.CellularDomainConfig.Mcc cellId = domain.CellularDomainConfig.DefaultCellId } switch nl.Type_ { case mod.NodeTypePoa4G: if nl.Poa4GConfig != nil { if nl.Poa4GConfig.CellId != "" { cellId = nl.Poa4GConfig.CellId } } /*no support for RNIS on 5G elements anymore case mod.NodeTypePoa5G: if nl.Poa5GConfig != nil { if nl.Poa5GConfig.CellId != "" { cellId = nl.Poa5GConfig.CellId } } */ default: //empty cells for POAs not supporting RNIS cellId = "" } sbi.updateAppEcgiInfoCB(appName, mnc, mcc, cellId) } } } sbi.updateAppInfoCB(appName, pl.Type_, pl.Name) } } Loading @@ -360,7 +327,7 @@ func processActiveScenarioUpdate() { } } if !found { sbi.updateAppEcgiInfoCB(prevApp, "", "", "") sbi.updateAppInfoCB(prevApp, "", "") log.Info("App removed : ", prevApp) } } Loading
go-apps/meep-rnis/server/api_rni.go +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import ( ) func Layer2MeasInfoGET(w http.ResponseWriter, r *http.Request) { notImplemented(w, r) layer2MeasInfoGet(w, r) } func PlmnInfoGET(w http.ResponseWriter, r *http.Request) { Loading
go-apps/meep-rnis/server/convert.go +3 −3 Original line number Diff line number Diff line Loading @@ -22,9 +22,9 @@ import ( log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" ) func convertJsonToEcgi(jsonInfo string) *Ecgi { func convertJsonToAppInfo(jsonInfo string) *AppInfo { var obj Ecgi var obj AppInfo err := json.Unmarshal([]byte(jsonInfo), &obj) if err != nil { log.Error(err.Error()) Loading @@ -33,7 +33,7 @@ func convertJsonToEcgi(jsonInfo string) *Ecgi { return &obj } func convertEcgiToJson(obj *Ecgi) string { func convertAppInfoToJson(obj *AppInfo) string { jsonInfo, err := json.Marshal(*obj) if err != nil { Loading
go-apps/meep-rnis/server/rnis.go +263 −27 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ const measRepUeSubscriptionType = "meas_rep_ue" const nrMeasRepUeSubscriptionType = "nr_meas_rep_ue" const poaType4G = "POA-4G" const poaType5G = "POA-5G" const plTypeUE = "UE" var ccSubscriptionMap = map[int]*CellChangeSubscription{} var reSubscriptionMap = map[int]*RabEstSubscription{} Loading Loading @@ -105,6 +106,12 @@ type RabInfoData struct { rabInfo *RabInfo } type L2MeasData struct { queryCellIds []string queryIpv4Addresses []string l2Meas *L2Meas } type UeData struct { Name string `json:"name"` ErabId int32 `json:"erabId"` Loading @@ -113,6 +120,7 @@ type UeData struct { Qci int32 `json:"qci"` ParentPoaName string `json:"parentPoaName"` InRangePoas []InRangePoa `json:"inRangePoas"` AppNames []string `json:"appNames"` } type InRangePoa struct { Loading @@ -127,6 +135,11 @@ type PoaInfo struct { Nrcgi NRcgi `json:"nrcgi"` } type AppInfo struct { ParentType string `json:"parentType"` ParentName string `json:"parentName"` } type DomainData struct { Mcc string `json:"mcc"` Mnc string `json:"mnc"` Loading Loading @@ -221,7 +234,7 @@ func Init() (err error) { UeDataCb: updateUeData, MeasInfoCb: updateMeasInfo, PoaInfoCb: updatePoaInfo, AppEcgiInfoCb: updateAppEcgiInfo, AppInfoCb: updateAppInfo, DomainDataCb: updateDomainData, ScenarioNameCb: updateStoreName, CleanUpCb: cleanUp, Loading Loading @@ -261,7 +274,7 @@ func Stop() (err error) { return sbi.Stop() } func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId string, erabIdValid bool) { func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId string, erabIdValid bool, appNames []string) { var plmn Plmn var newEcgi Ecgi Loading @@ -279,6 +292,7 @@ func updateUeData(name string, mnc string, mcc string, cellId string, nrcellId s ueData.Nrcgi = &newNrcgi ueData.Name = name ueData.Qci = defaultSupportedQci //only supporting one value ueData.AppNames = appNames oldPlmn := new(Plmn) oldPlmnMnc := "" Loading Loading @@ -405,35 +419,32 @@ func updatePoaInfo(name string, poaType string, mnc string, mcc string, cellId s _ = rc.JSONSetEntry(baseKey+"POA:"+name, ".", convertPoaInfoToJson(&poaInfo)) } func updateAppEcgiInfo(name string, mnc string, mcc string, cellId string) { var plmn Plmn var newEcgi Ecgi plmn.Mnc = mnc plmn.Mcc = mcc newEcgi.CellId = cellId newEcgi.Plmn = &plmn func updateAppInfo(name string, parentType string, parentName string) { //get from DB jsonAppEcgiInfo, _ := rc.JSONGetEntry(baseKey+"APP:"+name, ".") jsonAppInfo, _ := rc.JSONGetEntry(baseKey+"APP:"+name+"*", ".") oldPlmnMnc := "" oldPlmnMcc := "" oldCellId := "" if jsonAppEcgiInfo != "" { ecgiInfo := convertJsonToEcgi(jsonAppEcgiInfo) oldPlmnMnc = ecgiInfo.Plmn.Mnc oldPlmnMcc = ecgiInfo.Plmn.Mcc oldCellId = ecgiInfo.CellId if jsonAppInfo != "" { //delete entry if parent name is different; means it moved currentAppInfo := convertJsonToAppInfo(jsonAppInfo) if currentAppInfo.ParentName != parentName { if currentAppInfo.ParentType == plTypeUE { _ = rc.JSONDelEntry(baseKey+"APP:"+name+":"+currentAppInfo.ParentName, ".") } } else { //no changes.. just get out return } } //updateDB if changes occur if newEcgi.Plmn.Mnc != oldPlmnMnc || newEcgi.Plmn.Mcc != oldPlmnMcc || newEcgi.CellId != oldCellId { //updateDB _ = rc.JSONSetEntry(baseKey+"APP:"+name, ".", convertEcgiToJson(&newEcgi)) var appInfo AppInfo appInfo.ParentType = parentType appInfo.ParentName = parentName if parentType == plTypeUE { _ = rc.JSONSetEntry(baseKey+"APP:"+name+":"+parentName, ".", convertAppInfoToJson(&appInfo)) } else { _ = rc.JSONSetEntry(baseKey+"APP:"+name, ".", convertAppInfoToJson(&appInfo)) } } Loading Loading @@ -2482,6 +2493,231 @@ func populatePlmnInfo(key string, jsonInfo string, response interface{}) error { return nil } func layer2MeasInfoGet(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") var l2MeasData L2MeasData u, _ := url.Parse(r.URL.String()) log.Info("url: ", u.RequestURI()) q := u.Query() //meAppName := q.Get("app_ins_id") l2MeasData.queryCellIds = q["cell_id"] l2MeasData.queryIpv4Addresses = q["ue_ipv4_address"] seconds := time.Now().Unix() var timeStamp TimeStamp timeStamp.Seconds = int32(seconds) //meApp is ignored, we use the whole network var l2Meas L2Meas l2MeasData.l2Meas = &l2Meas //get from DB //loop through each UE keyName := baseKey + "UE:*" err := rc.ForEachJSONEntry(keyName, populateL2Meas, &l2MeasData) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } //loop through each POA keyName = baseKey + "POA:*" err = rc.ForEachJSONEntry(keyName, populateL2MeasPOA, &l2MeasData) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } l2Meas.TimeStamp = &timeStamp // Send response jsonResponse, err := json.Marshal(l2Meas) if err != nil { log.Error(err.Error()) http.Error(w, err.Error(), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) fmt.Fprintf(w, string(jsonResponse)) } func populateL2MeasPOA(key string, jsonInfo string, l2MeasData interface{}) error { // Get query params & userlist from user data data := l2MeasData.(*L2MeasData) if data == nil || data.l2Meas == nil { return errors.New("l2Meas not found in l2MeasData") } // Retrieve user info from DB var poaData PoaInfo err := json.Unmarshal([]byte(jsonInfo), &poaData) if err != nil { return err } //only applies for 4G poas if poaData.Type != poaType4G { return nil } partOfFilter := true for _, cellId := range data.queryCellIds { if cellId != "" { partOfFilter = false if cellId == poaData.Ecgi.CellId { partOfFilter = true break } } } if !partOfFilter { return nil } found := false //find if cellInfo already exists for _, currentCellInfo := range data.l2Meas.CellInfo { if currentCellInfo.Ecgi.Plmn.Mcc == poaData.Ecgi.Plmn.Mcc && currentCellInfo.Ecgi.Plmn.Mnc == poaData.Ecgi.Plmn.Mnc && currentCellInfo.Ecgi.CellId == poaData.Ecgi.CellId { //add ue into the existing cellUserInfo found = true } } if !found { newCellInfo := new(L2MeasCellInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = poaData.Ecgi.Plmn.Mcc newPlmn.Mnc = poaData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = poaData.Ecgi.CellId newCellInfo.Ecgi = newEcgi data.l2Meas.CellInfo = append(data.l2Meas.CellInfo, *newCellInfo) } return nil } func populateL2Meas(key string, jsonInfo string, l2MeasData interface{}) error { // Get query params & userlist from user data data := l2MeasData.(*L2MeasData) if data == nil || data.l2Meas == nil { return errors.New("l2Meas not found in l2MeasData") } // Retrieve user info from DB var ueData UeData err := json.Unmarshal([]byte(jsonInfo), &ueData) if err != nil { return err } // Ignore entries with no rabId, meaning only applies if connected to POA-4G, no need to check for ecgi if ueData.ErabId == -1 { return nil } partOfFilter := true for _, cellId := range data.queryCellIds { if cellId != "" { partOfFilter = false if cellId == ueData.Ecgi.CellId { partOfFilter = true break } } } if !partOfFilter { return nil } //name of the element is used as the ipv4 address at the moment partOfFilter = true for _, address := range data.queryIpv4Addresses { if address != "" { partOfFilter = false if address == ueData.Name { partOfFilter = true break } } } if !partOfFilter { return nil } found := false //find if cellUeInfo already exists assocId := new(AssociateId) assocId.Type_ = 1 //UE_IPV4_ADDRESS subKeys := strings.Split(key, ":") assocId.Value = subKeys[len(subKeys)-1] for _, currentCellUeInfo := range data.l2Meas.CellUEInfo { if assocId.Type_ == currentCellUeInfo.AssociateId.Type_ && assocId.Value == currentCellUeInfo.AssociateId.Value { found = true } } if !found { newCellUeInfo := new(L2MeasCellUeInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = ueData.Ecgi.Plmn.Mcc newPlmn.Mnc = ueData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = ueData.Ecgi.CellId newCellUeInfo.Ecgi = newEcgi newCellUeInfo.AssociateId = assocId data.l2Meas.CellUEInfo = append(data.l2Meas.CellUEInfo, *newCellUeInfo) } //find if cellInfo already exists var cellIndex int for index, currentCellInfo := range data.l2Meas.CellInfo { if currentCellInfo.Ecgi.Plmn.Mcc == ueData.Ecgi.Plmn.Mcc && currentCellInfo.Ecgi.Plmn.Mnc == ueData.Ecgi.Plmn.Mnc && currentCellInfo.Ecgi.CellId == ueData.Ecgi.CellId { //add ue into the existing cellUserInfo found = true cellIndex = index } } if !found { newCellInfo := new(L2MeasCellInfo) newEcgi := new(Ecgi) newPlmn := new(Plmn) newPlmn.Mcc = ueData.Ecgi.Plmn.Mcc newPlmn.Mnc = ueData.Ecgi.Plmn.Mnc newEcgi.Plmn = newPlmn newEcgi.CellId = ueData.Ecgi.CellId newCellInfo.Ecgi = newEcgi data.l2Meas.CellInfo = append(data.l2Meas.CellInfo, *newCellInfo) cellIndex = len(data.l2Meas.CellInfo) - 1 } //need to do a qci mapping... since qci can only be 80 for now, using the one that correlates to that data.l2Meas.CellInfo[cellIndex].NumberOfActiveUeDlNongbrCell++ data.l2Meas.CellInfo[cellIndex].NumberOfActiveUeUlNongbrCell++ return nil } func rabInfoGet(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") Loading
go-apps/meep-rnis/server/rnis_test.go +2 −2 Original line number Diff line number Diff line Loading @@ -2179,8 +2179,8 @@ func TestSbi(t *testing.T) { ******************************/ var expectedUeDataStr [2]string var expectedUeData [2]UeData expectedUeData[INITIAL] = UeData{ueName, 1, &Ecgi{"2345678", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil} expectedUeData[UPDATED] = UeData{ueName, -1, &Ecgi{"", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil} expectedUeData[INITIAL] = UeData{ueName, 1, &Ecgi{"2345678", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil, nil} expectedUeData[UPDATED] = UeData{ueName, -1, &Ecgi{"", &Plmn{"123", "456"}}, &NRcgi{"", &Plmn{"123", "456"}}, 80, "", nil, nil} var expectedAppEcgiStr [2]string var expectedAppEcgi [2]Ecgi Loading