diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 32278fb..764d144 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -1,3 +1,52 @@ export function toHex(v: number | undefined): string { return ("00" + v?.toString(16).toUpperCase()).substr(-2); } + +function parseDataRate(rate: string | undefined): number { + if (!rate) return 0; + + const match = rate.match(/^(\d+)\s*(Gbps|Mbps|Kbps|bps)$/i); + if (!match) return 0; + + const [, value, unit] = match; + const numValue = parseFloat(value); + + switch (unit.toLowerCase()) { + case 'gbps': + return numValue * 1000000; + case 'mbps': + return numValue * 1000; + case 'kbps': + return numValue; + case 'bps': + return numValue / 1000; + default: + return 0; + } +} + +export function validateMBRGreaterThanGBR(QosFlows: any[]): { isValid: boolean; error?: string } { + for (let i = 0; i < QosFlows.length; i++) { + const qosFlow = QosFlows[i]; + const gbrDL = parseDataRate(qosFlow.gbrDL); + const mbrDL = parseDataRate(qosFlow.mbrDL); + const gbrUL = parseDataRate(qosFlow.gbrUL); + const mbrUL = parseDataRate(qosFlow.mbrUL); + + if (gbrDL && mbrDL && gbrDL >= mbrDL) { + return { + isValid: false, + error: `In S-NSSAI ${qosFlow.snssai}'s Flow Rule ${i+1}\nDownlink MBR must be greater than Downlink GBR` + }; + } + + if (gbrUL && mbrUL && gbrUL >= mbrUL) { + return { + isValid: false, + error: `In S-NSSAI ${qosFlow.snssai}'s Flow Rule ${i+1}\nUplink MBR must be greater than Uplink GBR` + }; + } + } + + return { isValid: true }; +} \ No newline at end of file diff --git a/frontend/src/pages/ProfileCreate/index.tsx b/frontend/src/pages/ProfileCreate/index.tsx index a34b215..aaedde2 100644 --- a/frontend/src/pages/ProfileCreate/index.tsx +++ b/frontend/src/pages/ProfileCreate/index.tsx @@ -11,6 +11,8 @@ import ProfileFormBasic from "./ProfileFormBasic"; import ProfileFormUeAmbr from "./ProfileFormUeAmbr"; import ProfileFormSessions from "./ProfileFormSessions"; import { ProfileMapperImpl, FlowsMapperImpl } from "../../lib/dtos/profile"; +import { validateMBRGreaterThanGBR } from "../../lib/utils"; + function FormHOC(Component: React.ComponentType) { return function (props: any) { return ( @@ -66,6 +68,12 @@ function ProfileCreate() { const profileMapper = new ProfileMapperImpl(new FlowsMapperImpl()); const profile = profileMapper.mapFromDto(data); + const validation = validateMBRGreaterThanGBR(profile.QosFlows); + if (!validation.isValid) { + alert(validation.error); + return; + } + axios .post("/api/profile", profile) .then(() => { @@ -96,6 +104,12 @@ function ProfileCreate() { const profileMapper = new ProfileMapperImpl(new FlowsMapperImpl()); const profile = profileMapper.mapFromDto(data); + const validation = validateMBRGreaterThanGBR(profile.QosFlows); + if (!validation.isValid) { + alert(validation.error); + return; + } + axios .put("/api/profile/" + profile.profileName, profile) .then(() => { diff --git a/frontend/src/pages/SubscriberCreate/index.tsx b/frontend/src/pages/SubscriberCreate/index.tsx index 8f687e1..b483ede 100644 --- a/frontend/src/pages/SubscriberCreate/index.tsx +++ b/frontend/src/pages/SubscriberCreate/index.tsx @@ -12,6 +12,8 @@ import SubscriberFormUeAmbr from "./SubscriberFormUeAmbr"; import SubscriberFormSessions from "./SubscriberFormSessions"; import { FlowsMapperImpl as SubscriptionFlowsMapperImpl, SubscriptionMapperImpl } from "../../lib/dtos/subscription"; import { FlowsMapperImpl as ProfileFlowsMapperImpl, ProfileMapperImpl } from "../../lib/dtos/profile"; +import { validateMBRGreaterThanGBR } from "../../lib/utils"; + function FormHOC(Component: React.ComponentType) { return function (props: any) { return ( @@ -91,6 +93,12 @@ function SubscriberCreate() { const subscriberMapper = new SubscriptionMapperImpl(new SubscriptionFlowsMapperImpl()); const subscription = subscriberMapper.mapFromDto(data); + const validation = validateMBRGreaterThanGBR(subscription.QosFlows); + if (!validation.isValid) { + alert(validation.error); + return; + } + // Iterate subscriber data number. let supi = subscription.ueId; for (let i = 0; i < subscription.userNumber!; i++) { @@ -127,6 +135,12 @@ function SubscriberCreate() { const subscriberMapper = new SubscriptionMapperImpl(new SubscriptionFlowsMapperImpl()); const subscription = subscriberMapper.mapFromDto(data); + const validation = validateMBRGreaterThanGBR(subscription.QosFlows); + if (!validation.isValid) { + alert(validation.error); + return; + } + axios .put("/api/subscriber/" + subscription.ueId + "/" + subscription.plmnID, subscription) .then(() => {