Skip to content
wais.go 35.7 KiB
Newer Older
Simon Pastor's avatar
Simon Pastor committed

	if subsIdStr != subIdParamStr {
		log.Error("SubscriptionId in endpoint and in body not matching")
		http.Error(w, "SubscriptionId in endpoint and in body not matching", http.StatusBadRequest)
Simon Pastor's avatar
Simon Pastor committed
		return
	}

	alreadyRegistered := false
	var jsonResponse []byte

	switch subscriptionType {
	case ASSOC_STA_SUBSCRIPTION:
		var subscription AssocStaSubscription
		err = json.Unmarshal(bodyBytes, &subscription)
		if err != nil {
			log.Error(err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}
Simon Pastor's avatar
Simon Pastor committed

		//only support one subscription
Simon Pastor's avatar
Simon Pastor committed
		if isSubscriptionIdRegisteredAssocSta(subsIdStr) {
			registerAssocSta(&subscription, subsIdStr)

			_ = rc.JSONSetEntry(baseKey+"subscriptions:"+subsIdStr, ".", convertAssocStaSubscriptionToJson(&subscription))
			alreadyRegistered = true
			jsonResponse, err = json.Marshal(subscription)
		}
	case STA_DATA_RATE_SUBSCRIPTION:
		var subscription StaDataRateSubscription
		err = json.Unmarshal(bodyBytes, &subscription)
		if err != nil {
			log.Error(err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
		}

		//only support one subscription
		if isSubscriptionIdRegisteredStaDataRate(subsIdStr) {
			registerStaDataRate(&subscription, subsIdStr)

			_ = rc.JSONSetEntry(baseKey+"subscriptions:"+subsIdStr, ".", convertStaDataRateSubscriptionToJson(&subscription))
			alreadyRegistered = true
			jsonResponse, err = json.Marshal(subscription)
		}
Simon Pastor's avatar
Simon Pastor committed
	default:
		w.WriteHeader(http.StatusBadRequest)
		return
	}
Simon Pastor's avatar
Simon Pastor committed

Simon Pastor's avatar
Simon Pastor committed
	if alreadyRegistered {
		if err != nil {
			log.Error(err.Error())
			http.Error(w, err.Error(), http.StatusInternalServerError)
			return
Simon Pastor's avatar
Simon Pastor committed
		w.WriteHeader(http.StatusOK)
		fmt.Fprintf(w, string(jsonResponse))
	} else {
		w.WriteHeader(http.StatusNotFound)
	}
func delSubscription(keyPrefix string, subsId string, mutexTaken bool) error {
Simon Pastor's avatar
Simon Pastor committed

	err := rc.JSONDelEntry(keyPrefix+":"+subsId, ".")
Simon Pastor's avatar
Simon Pastor committed
	deregisterAssocSta(subsId, mutexTaken)
	deregisterStaDataRate(subsId, mutexTaken)
Simon Pastor's avatar
Simon Pastor committed
	return err
}

func subscriptionsDELETE(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
	vars := mux.Vars(r)

Simon Pastor's avatar
Simon Pastor committed
	subIdParamStr := vars["subscriptionId"]
	jsonRespDB, _ := rc.JSONGetEntry(baseKey+"subscriptions:"+subIdParamStr, ".")
	if jsonRespDB == "" {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	err := delSubscription(baseKey+"subscriptions", subIdParamStr, false)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
Simon Pastor's avatar
Simon Pastor committed

Simon Pastor's avatar
Simon Pastor committed
	w.WriteHeader(http.StatusNoContent)
Simon Pastor's avatar
Simon Pastor committed
}

func populateApInfo(key string, jsonInfo string, response interface{}) error {
Simon Pastor's avatar
Simon Pastor committed
	resp := response.(*ApInfoResp)
Simon Pastor's avatar
Simon Pastor committed
	if resp == nil {
		return errors.New("Response not defined")
	}

	// Retrieve user info from DB
	var apInfoComplete ApInfoComplete
	err := json.Unmarshal([]byte(jsonInfo), &apInfoComplete)
	if err != nil {
		return err
	}

Simon Pastor's avatar
Simon Pastor committed
	//timeStamp is optional, commenting the code
	//seconds := time.Now().Unix()
	//var timeStamp TimeStamp
	//timeStamp.Seconds = int32(seconds)
Simon Pastor's avatar
Simon Pastor committed

	var apInfo ApInfo
Simon Pastor's avatar
Simon Pastor committed
	//apInfo.TimeStamp = &timeStamp
Simon Pastor's avatar
Simon Pastor committed

	apInfo.ApId = &apInfoComplete.ApId
Simon Pastor's avatar
Simon Pastor committed

	var bssLoad BssLoad
	bssLoad.StaCount = int32(len(apInfoComplete.StaMacIds))
	bssLoad.ChannelUtilization = 0
	bssLoad.AvailAdmCap = 0
	apInfo.BssLoad = &bssLoad

	var apLocation ApLocation
	var geoLocation GeoLocation
Simon Pastor's avatar
Simon Pastor committed
	if apInfoComplete.ApLocation.Geolocation != nil {
		geoLocation.Lat = apInfoComplete.ApLocation.Geolocation.Lat
		geoLocation.Long = apInfoComplete.ApLocation.Geolocation.Long
Simon Pastor's avatar
Simon Pastor committed
		geoLocation.Datum = 1
Simon Pastor's avatar
Simon Pastor committed
		apLocation.Geolocation = &geoLocation
Simon Pastor's avatar
Simon Pastor committed
		apInfo.ApLocation = &apLocation
	}

Simon Pastor's avatar
Simon Pastor committed
	resp.ApInfoList = append(resp.ApInfoList, apInfo)
Simon Pastor's avatar
Simon Pastor committed

	return nil
}

func apInfoGET(w http.ResponseWriter, r *http.Request) {

	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

Simon Pastor's avatar
Simon Pastor committed
	var response ApInfoResp
	//initialise array to make sure Marshal processes it properly if it is empty
	response.ApInfoList = make([]ApInfo, 0)
Simon Pastor's avatar
Simon Pastor committed

	//loop through each AP
	keyName := baseKey + "AP:*"
	err := rc.ForEachJSONEntry(keyName, populateApInfo, &response)
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

Simon Pastor's avatar
Simon Pastor committed
	jsonResponse, err := json.Marshal(response.ApInfoList)
Simon Pastor's avatar
Simon Pastor committed
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	w.WriteHeader(http.StatusOK)
Simon Pastor's avatar
Simon Pastor committed
	fmt.Fprintf(w, string(jsonResponse))
}

func populateStaData(key string, jsonInfo string, response interface{}) error {
Simon Pastor's avatar
Simon Pastor committed
	resp := response.(*StaInfoResp)
Simon Pastor's avatar
Simon Pastor committed
	if resp == nil {
		return errors.New("Response not defined")
	}

	// Add STA info to reponse (ignore if not associated to a wifi AP)
	staData := convertJsonToStaData(jsonInfo)
	if staData.StaInfo.ApAssociated != nil {
Simon Pastor's avatar
Simon Pastor committed
		//timeStamp is optional, commenting the code
		//seconds := time.Now().Unix()
		//var timeStamp TimeStamp
		//timeStamp.Seconds = int32(seconds)
		//staInfo.TimeStamp = &timeStamp
		resp.StaInfoList = append(resp.StaInfoList, *staData.StaInfo)
Simon Pastor's avatar
Simon Pastor committed
	}
	return nil
Simon Pastor's avatar
Simon Pastor committed

Simon Pastor's avatar
Simon Pastor committed
}

func staInfoGET(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Simon Pastor's avatar
Simon Pastor committed
	var response StaInfoResp
	//initialise array to make sure Marshal processes it properly if it is empty
	response.StaInfoList = make([]StaInfo, 0)
	// Loop through each STA
Simon Pastor's avatar
Simon Pastor committed
	keyName := baseKey + "UE:*"
	err := rc.ForEachJSONEntry(keyName, populateStaData, &response)
Simon Pastor's avatar
Simon Pastor committed
	if err != nil {
		log.Error(err.Error())
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

Simon Pastor's avatar
Simon Pastor committed
	jsonResponse, err := json.Marshal(response.StaInfoList)
Simon Pastor's avatar
Simon Pastor committed
	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 createSubscriptionLinkList(subType string) *SubscriptionLinkList {

	subscriptionLinkList := new(SubscriptionLinkList)

Simon Pastor's avatar
Simon Pastor committed
	link := new(SubscriptionLinkListLinks)
	self := new(LinkType)
	self.Href = hostUrl.String() + basePath + "subscriptions"
Simon Pastor's avatar
Simon Pastor committed
	link.Self = self
Simon Pastor's avatar
Simon Pastor committed
	subscriptionLinkList.Links = link

	//loop through all different types of subscription

	mutex.Lock()
	defer mutex.Unlock()

Simon Pastor's avatar
Simon Pastor committed
	if subType == "" || subType == assocStaSubscriptionType {
		//loop through assocSta map
		for _, assocStaSubscription := range assocStaSubscriptionMap {
			if assocStaSubscription != nil {
				var subscription SubscriptionLinkListSubscription
				subscription.Href = assocStaSubscription.Links.Self.Href
				subscription.SubscriptionType = ASSOC_STA_SUBSCRIPTION
				subscriptionLinkList.Subscription = append(subscriptionLinkList.Subscription, subscription)
			}
		}
	}
	if subType == "" || subType == staDataRateSubscriptionType {
		//loop through assocSta map
		for _, staDataRateSubscription := range staDataRateSubscriptionMap {
			if staDataRateSubscription != nil {
				var subscription SubscriptionLinkListSubscription
				subscription.Href = staDataRateSubscription.Links.Self.Href
				subscription.SubscriptionType = STA_DATA_RATE_SUBSCRIPTION
				subscriptionLinkList.Subscription = append(subscriptionLinkList.Subscription, subscription)
Simon Pastor's avatar
Simon Pastor committed
	//no other maps to go through

	return subscriptionLinkList
}

func subscriptionLinkListSubscriptionsGET(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json; charset=UTF-8")

Simon Pastor's avatar
Simon Pastor committed
	//for now we return anything, was not defined in spec so not sure if subscription_type is a query param like in MEC012
	response := createSubscriptionLinkList("")
Simon Pastor's avatar
Simon Pastor committed

	jsonResponse, err := json.Marshal(response)
	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 cleanUp() {
	log.Info("Terminate all")
	rc.DBFlush(baseKey)
	nextSubscriptionIdAvailable = 1

	mutex.Lock()
	defer mutex.Unlock()

Simon Pastor's avatar
Simon Pastor committed
	assocStaSubscriptionMap = map[int]*AssocStaSubscription{}
	staDataRateSubscriptionMap = map[int]*StaDataRateSubscription{}
Simon Pastor's avatar
Simon Pastor committed

	subscriptionExpiryMap = map[int][]int{}
	updateStoreName("")
func updateStoreName(storeName string) {
	_ = httpLog.ReInit(logModuleWAIS, sandboxName, storeName, redisAddr, influxAddr)